aboutsummaryrefslogtreecommitdiff
path: root/hw/intc
diff options
context:
space:
mode:
authorGreg Kurz <groug@kaod.org>2019-10-24 16:27:22 +0200
committerLaurent Vivier <lvivier@redhat.com>2019-11-18 11:49:11 +0100
commit0990ce6a2e900d0bdda7f3ecdc991746f63551fb (patch)
tree38bc8fa17c3a2477949aabb8fc852c45795fe1e7 /hw/intc
parent36609b4fa36f0ac934874371874416f7533a5408 (diff)
downloadqemu-0990ce6a2e900d0bdda7f3ecdc991746f63551fb.zip
qemu-0990ce6a2e900d0bdda7f3ecdc991746f63551fb.tar.gz
qemu-0990ce6a2e900d0bdda7f3ecdc991746f63551fb.tar.bz2
ppc: Add intc_destroy() handlers to SpaprInterruptController/PnvChip
SpaprInterruptControllerClass and PnvChipClass have an intc_create() method that calls the appropriate routine, ie. icp_create() or xive_tctx_create(), to establish the link between the VCPU and the presenter component of the interrupt controller during realize. There aren't any symmetrical call to be called when the VCPU gets unrealized though. It is assumed that object_unparent() is the only thing to do. This is questionable because the parenting logic around the CPU and presenter objects is really an implementation detail of the interrupt controller. It shouldn't be open-coded in the machine code. Fix this by adding an intc_destroy() method that undoes what was done in intc_create(). Also NULLify the presenter pointers to avoid having stale pointers around. This will allow to reliably check if a vCPU has a valid presenter. Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <157192724208.3146912.7254684777515287626.stgit@bahia.lan> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/spapr_xive.c10
-rw-r--r--hw/intc/xics.c5
-rw-r--r--hw/intc/xics_spapr.c10
-rw-r--r--hw/intc/xive.c5
4 files changed, 30 insertions, 0 deletions
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c
index d8e1291..9cb8d38 100644
--- a/hw/intc/spapr_xive.c
+++ b/hw/intc/spapr_xive.c
@@ -555,6 +555,15 @@ static void spapr_xive_cpu_intc_reset(SpaprInterruptController *intc,
xive_tctx_set_os_cam(tctx, xive_nvt_cam_line(nvt_blk, nvt_idx));
}
+static void spapr_xive_cpu_intc_destroy(SpaprInterruptController *intc,
+ PowerPCCPU *cpu)
+{
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ xive_tctx_destroy(spapr_cpu->tctx);
+ spapr_cpu->tctx = NULL;
+}
+
static void spapr_xive_set_irq(SpaprInterruptController *intc, int irq, int val)
{
SpaprXive *xive = SPAPR_XIVE(intc);
@@ -692,6 +701,7 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data)
sicc->deactivate = spapr_xive_deactivate;
sicc->cpu_intc_create = spapr_xive_cpu_intc_create;
sicc->cpu_intc_reset = spapr_xive_cpu_intc_reset;
+ sicc->cpu_intc_destroy = spapr_xive_cpu_intc_destroy;
sicc->claim_irq = spapr_xive_claim_irq;
sicc->free_irq = spapr_xive_free_irq;
sicc->set_irq = spapr_xive_set_irq;
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 6da0576..935f325 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -401,6 +401,11 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp)
return obj;
}
+void icp_destroy(ICPState *icp)
+{
+ object_unparent(OBJECT(icp));
+}
+
/*
* ICS: Source layer
*/
diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c
index 7418fb9..b3705da 100644
--- a/hw/intc/xics_spapr.c
+++ b/hw/intc/xics_spapr.c
@@ -352,6 +352,15 @@ static void xics_spapr_cpu_intc_reset(SpaprInterruptController *intc,
icp_reset(spapr_cpu_state(cpu)->icp);
}
+static void xics_spapr_cpu_intc_destroy(SpaprInterruptController *intc,
+ PowerPCCPU *cpu)
+{
+ SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu);
+
+ icp_destroy(spapr_cpu->icp);
+ spapr_cpu->icp = NULL;
+}
+
static int xics_spapr_claim_irq(SpaprInterruptController *intc, int irq,
bool lsi, Error **errp)
{
@@ -440,6 +449,7 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data)
sicc->deactivate = xics_spapr_deactivate;
sicc->cpu_intc_create = xics_spapr_cpu_intc_create;
sicc->cpu_intc_reset = xics_spapr_cpu_intc_reset;
+ sicc->cpu_intc_destroy = xics_spapr_cpu_intc_destroy;
sicc->claim_irq = xics_spapr_claim_irq;
sicc->free_irq = xics_spapr_free_irq;
sicc->set_irq = xics_spapr_set_irq;
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index f066be5..38257aa 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -696,6 +696,11 @@ error:
return NULL;
}
+void xive_tctx_destroy(XiveTCTX *tctx)
+{
+ object_unparent(OBJECT(tctx));
+}
+
/*
* XIVE ESB helpers
*/