diff options
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/spapr_xive.c | 10 | ||||
-rw-r--r-- | hw/intc/xics.c | 22 | ||||
-rw-r--r-- | hw/intc/xics_spapr.c | 10 | ||||
-rw-r--r-- | hw/intc/xive.c | 20 |
4 files changed, 60 insertions, 2 deletions
diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index d8e1291905..9cb8d38a3b 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 6da05763f9..e7ac9ba618 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -44,7 +44,16 @@ void icp_pic_print_info(ICPState *icp, Monitor *mon) { - int cpu_index = icp->cs ? icp->cs->cpu_index : -1; + int cpu_index; + + /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs + * are hot plugged or unplugged. + */ + if (!icp) { + return; + } + + cpu_index = icp->cs ? icp->cs->cpu_index : -1; if (!icp->output) { return; @@ -388,8 +397,10 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp) obj = object_new(type); object_property_add_child(cpu, type, obj, &error_abort); object_unref(obj); + object_ref(OBJECT(xi)); object_property_add_const_link(obj, ICP_PROP_XICS, OBJECT(xi), &error_abort); + object_ref(cpu); object_property_add_const_link(obj, ICP_PROP_CPU, cpu, &error_abort); object_property_set_bool(obj, true, "realized", &local_err); if (local_err) { @@ -401,6 +412,15 @@ Object *icp_create(Object *cpu, const char *type, XICSFabric *xi, Error **errp) return obj; } +void icp_destroy(ICPState *icp) +{ + Object *obj = OBJECT(icp); + + object_unref(object_property_get_link(obj, ICP_PROP_CPU, &error_abort)); + object_unref(object_property_get_link(obj, ICP_PROP_XICS, &error_abort)); + object_unparent(obj); +} + /* * ICS: Source layer */ diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 7418fb9f37..b3705dab0e 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 f066be5eb5..75dce82fb2 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -523,9 +523,18 @@ static const char * const xive_tctx_ring_names[] = { void xive_tctx_pic_print_info(XiveTCTX *tctx, Monitor *mon) { - int cpu_index = tctx->cs ? tctx->cs->cpu_index : -1; + int cpu_index; int i; + /* Skip partially initialized vCPUs. This can happen on sPAPR when vCPUs + * are hot plugged or unplugged. + */ + if (!tctx) { + return; + } + + cpu_index = tctx->cs ? tctx->cs->cpu_index : -1; + if (kvm_irqchip_in_kernel()) { Error *local_err = NULL; @@ -682,6 +691,7 @@ Object *xive_tctx_create(Object *cpu, XiveRouter *xrtr, Error **errp) obj = object_new(TYPE_XIVE_TCTX); object_property_add_child(cpu, TYPE_XIVE_TCTX, obj, &error_abort); object_unref(obj); + object_ref(cpu); object_property_add_const_link(obj, "cpu", cpu, &error_abort); object_property_set_bool(obj, true, "realized", &local_err); if (local_err) { @@ -696,6 +706,14 @@ error: return NULL; } +void xive_tctx_destroy(XiveTCTX *tctx) +{ + Object *obj = OBJECT(tctx); + + object_unref(object_property_get_link(obj, "cpu", &error_abort)); + object_unparent(obj); +} + /* * XIVE ESB helpers */ |