aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorGreg Kurz <groug@kaod.org>2017-06-08 15:42:59 +0200
committerDavid Gibson <david@gibson.dropbear.id.au>2017-06-09 12:15:57 +1000
commit9ed656631d73a7564dfe178ca8c48bf049098aaf (patch)
tree8b0121c4ade2d731e07e873ed64a6ea9ef80e4c2 /hw
parent100f738850639a108d6767316ce4dcc1d1ea4ae4 (diff)
downloadqemu-9ed656631d73a7564dfe178ca8c48bf049098aaf.zip
qemu-9ed656631d73a7564dfe178ca8c48bf049098aaf.tar.gz
qemu-9ed656631d73a7564dfe178ca8c48bf049098aaf.tar.bz2
xics: setup cpu at realize time
Until recently, spapr used to allocate ICPState objects for the lifetime of the machine. They would only be associated to vCPUs in xics_cpu_setup() when plugging a CPU core. Now that ICPState objects have the same lifecycle as vCPUs, it is possible to associate them during realization. This patch hence open-codes xics_cpu_setup() in icp_realize(). The vCPU is passed as a property. Note that vCPU now needs to be realized first for the IRQs to be allocated. It also needs to resetted before ICPState realization in order to synchronize with KVM. Since ICPState objects are freed when unrealized, xics_cpu_destroy() isn't needed anymore and can be safely dropped. Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Cédric Le Goater <clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'hw')
-rw-r--r--hw/intc/xics.c76
-rw-r--r--hw/ppc/pnv_core.c18
-rw-r--r--hw/ppc/spapr_cpu_core.c23
3 files changed, 50 insertions, 67 deletions
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index f74a96e..fdbfddf 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -38,50 +38,6 @@
#include "monitor/monitor.h"
#include "hw/intc/intc.h"
-void xics_cpu_destroy(XICSFabric *xi, PowerPCCPU *cpu)
-{
- CPUState *cs = CPU(cpu);
- ICPState *icp = ICP(cpu->intc);
-
- assert(icp);
- assert(cs == icp->cs);
-
- icp->output = NULL;
- icp->cs = NULL;
-}
-
-void xics_cpu_setup(XICSFabric *xi, PowerPCCPU *cpu, ICPState *icp)
-{
- CPUState *cs = CPU(cpu);
- CPUPPCState *env = &cpu->env;
- ICPStateClass *icpc;
-
- assert(icp);
-
- cpu->intc = OBJECT(icp);
- icp->cs = cs;
-
- icpc = ICP_GET_CLASS(icp);
- if (icpc->cpu_setup) {
- icpc->cpu_setup(icp, cpu);
- }
-
- switch (PPC_INPUT(env)) {
- case PPC_FLAGS_INPUT_POWER7:
- icp->output = env->irq_inputs[POWER7_INPUT_INT];
- break;
-
- case PPC_FLAGS_INPUT_970:
- icp->output = env->irq_inputs[PPC970_INPUT_INT];
- break;
-
- default:
- error_report("XICS interrupt controller does not support this CPU "
- "bus model");
- abort();
- }
-}
-
void icp_pic_print_info(ICPState *icp, Monitor *mon)
{
int cpu_index = icp->cs ? icp->cs->cpu_index : -1;
@@ -343,6 +299,8 @@ static void icp_realize(DeviceState *dev, Error **errp)
{
ICPState *icp = ICP(dev);
ICPStateClass *icpc = ICP_GET_CLASS(dev);
+ PowerPCCPU *cpu;
+ CPUPPCState *env;
Object *obj;
Error *err = NULL;
@@ -355,6 +313,36 @@ static void icp_realize(DeviceState *dev, Error **errp)
icp->xics = XICS_FABRIC(obj);
+ obj = object_property_get_link(OBJECT(dev), ICP_PROP_CPU, &err);
+ if (!obj) {
+ error_setg(errp, "%s: required link '" ICP_PROP_CPU "' not found: %s",
+ __func__, error_get_pretty(err));
+ return;
+ }
+
+ cpu = POWERPC_CPU(obj);
+ cpu->intc = OBJECT(icp);
+ icp->cs = CPU(obj);
+
+ if (icpc->cpu_setup) {
+ icpc->cpu_setup(icp, cpu);
+ }
+
+ env = &cpu->env;
+ switch (PPC_INPUT(env)) {
+ case PPC_FLAGS_INPUT_POWER7:
+ icp->output = env->irq_inputs[POWER7_INPUT_INT];
+ break;
+
+ case PPC_FLAGS_INPUT_970:
+ icp->output = env->irq_inputs[PPC970_INPUT_INT];
+ break;
+
+ default:
+ error_setg(errp, "XICS interrupt controller does not support this CPU bus model");
+ return;
+ }
+
if (icpc->realize) {
icpc->realize(icp, errp);
}
diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c
index 0b6e729..c7b00b6 100644
--- a/hw/ppc/pnv_core.c
+++ b/hw/ppc/pnv_core.c
@@ -118,20 +118,20 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
PowerPCCPU *cpu = POWERPC_CPU(cs);
Object *obj;
- obj = object_new(TYPE_PNV_ICP);
- object_property_add_child(OBJECT(cpu), "icp", obj, &error_abort);
- object_unref(obj);
- object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
- &error_abort);
- object_property_set_bool(obj, true, "realized", &local_err);
+ object_property_set_bool(child, true, "realized", &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
- object_property_set_bool(child, true, "realized", &local_err);
+ obj = object_new(TYPE_PNV_ICP);
+ object_property_add_child(child, "icp", obj, NULL);
+ object_unref(obj);
+ object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi),
+ &error_abort);
+ object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort);
+ object_property_set_bool(obj, true, "realized", &local_err);
if (local_err) {
- object_unparent(obj);
error_propagate(errp, local_err);
return;
}
@@ -142,8 +142,6 @@ static void pnv_core_realize_child(Object *child, XICSFabric *xi, Error **errp)
error_propagate(errp, local_err);
return;
}
-
- xics_cpu_setup(xi, cpu, ICP(obj));
}
static void pnv_core_realize(DeviceState *dev, Error **errp)
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index e81879c..9fb896b 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -53,9 +53,6 @@ static void spapr_cpu_reset(void *opaque)
static void spapr_cpu_destroy(PowerPCCPU *cpu)
{
- sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
-
- xics_cpu_destroy(XICS_FABRIC(spapr), cpu);
qemu_unregister_reset(spapr_cpu_reset, cpu);
}
@@ -140,29 +137,29 @@ static void spapr_cpu_core_realize_child(Object *child, Error **errp)
sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
CPUState *cs = CPU(child);
PowerPCCPU *cpu = POWERPC_CPU(cs);
- Object *obj;
+ Object *obj = NULL;
- obj = object_new(spapr->icp_type);
- object_property_add_child(OBJECT(cpu), "icp", obj, &error_abort);
- object_unref(obj);
- object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(spapr),
- &error_abort);
- object_property_set_bool(obj, true, "realized", &local_err);
+ object_property_set_bool(child, true, "realized", &local_err);
if (local_err) {
goto error;
}
- object_property_set_bool(child, true, "realized", &local_err);
+ spapr_cpu_init(spapr, cpu, &local_err);
if (local_err) {
goto error;
}
- spapr_cpu_init(spapr, cpu, &local_err);
+ obj = object_new(spapr->icp_type);
+ object_property_add_child(child, "icp", obj, &error_abort);
+ object_unref(obj);
+ object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(spapr),
+ &error_abort);
+ object_property_add_const_link(obj, ICP_PROP_CPU, child, &error_abort);
+ object_property_set_bool(obj, true, "realized", &local_err);
if (local_err) {
goto error;
}
- xics_cpu_setup(XICS_FABRIC(spapr), cpu, ICP(obj));
return;
error: