diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index 37ffb74ca5..1811653aac 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -640,6 +640,42 @@ static void spapr_xive_dt(SpaprInterruptController *intc, uint32_t nr_servers, plat_res_int_priorities, sizeof(plat_res_int_priorities))); } +static int spapr_xive_activate(SpaprInterruptController *intc, Error **errp) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + CPUState *cs; + + CPU_FOREACH(cs) { + PowerPCCPU *cpu = POWERPC_CPU(cs); + + /* (TCG) Set the OS CAM line of the thread interrupt context. */ + spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); + } + + if (kvm_enabled()) { + int rc = spapr_irq_init_kvm(kvmppc_xive_connect, intc, errp); + if (rc < 0) { + return rc; + } + } + + /* Activate the XIVE MMIOs */ + spapr_xive_mmio_set_enabled(xive, true); + + return 0; +} + +static void spapr_xive_deactivate(SpaprInterruptController *intc) +{ + SpaprXive *xive = SPAPR_XIVE(intc); + + spapr_xive_mmio_set_enabled(xive, false); + + if (kvm_irqchip_in_kernel()) { + kvmppc_xive_disconnect(intc); + } +} + static void spapr_xive_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -658,6 +694,8 @@ static void spapr_xive_class_init(ObjectClass *klass, void *data) xrc->write_nvt = spapr_xive_write_nvt; xrc->get_tctx = spapr_xive_get_tctx; + sicc->activate = spapr_xive_activate; + sicc->deactivate = spapr_xive_deactivate; sicc->cpu_intc_create = spapr_xive_cpu_intc_create; sicc->claim_irq = spapr_xive_claim_irq; sicc->free_irq = spapr_xive_free_irq; diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index 4eabafc7e1..90b4d48877 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -395,6 +395,21 @@ static void xics_spapr_print_info(SpaprInterruptController *intc, Monitor *mon) ics_pic_print_info(ics, mon); } +static int xics_spapr_activate(SpaprInterruptController *intc, Error **errp) +{ + if (kvm_enabled()) { + return spapr_irq_init_kvm(xics_kvm_connect, intc, errp); + } + return 0; +} + +static void xics_spapr_deactivate(SpaprInterruptController *intc) +{ + if (kvm_irqchip_in_kernel()) { + xics_kvm_disconnect(intc); + } +} + static void ics_spapr_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -403,6 +418,8 @@ static void ics_spapr_class_init(ObjectClass *klass, void *data) device_class_set_parent_realize(dc, ics_spapr_realize, &isc->parent_realize); + sicc->activate = xics_spapr_activate; + sicc->deactivate = xics_spapr_deactivate; sicc->cpu_intc_create = xics_spapr_cpu_intc_create; sicc->claim_irq = xics_spapr_claim_irq; sicc->free_irq = xics_spapr_free_irq; diff --git a/hw/ppc/spapr_irq.c b/hw/ppc/spapr_irq.c index 7cd18e5b15..f70b331f44 100644 --- a/hw/ppc/spapr_irq.c +++ b/hw/ppc/spapr_irq.c @@ -65,9 +65,9 @@ void spapr_irq_msi_free(SpaprMachineState *spapr, int irq, uint32_t num) bitmap_clear(spapr->irq_map, irq - SPAPR_IRQ_MSI, num); } -static int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), - SpaprInterruptController *intc, - Error **errp) +int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), + SpaprInterruptController *intc, + Error **errp) { MachineState *machine = MACHINE(qdev_get_machine()); Error *local_err = NULL; @@ -112,11 +112,6 @@ static int spapr_irq_post_load_xics(SpaprMachineState *spapr, int version_id) return 0; } -static void spapr_irq_reset_xics(SpaprMachineState *spapr, Error **errp) -{ - spapr_irq_init_kvm(xics_kvm_connect, SPAPR_INTC(spapr->ics), errp); -} - SpaprIrq spapr_irq_xics = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, @@ -124,7 +119,6 @@ SpaprIrq spapr_irq_xics = { .xive = false, .post_load = spapr_irq_post_load_xics, - .reset = spapr_irq_reset_xics, }; /* @@ -136,26 +130,6 @@ static int spapr_irq_post_load_xive(SpaprMachineState *spapr, int version_id) return spapr_xive_post_load(spapr->xive, version_id); } -static void spapr_irq_reset_xive(SpaprMachineState *spapr, Error **errp) -{ - CPUState *cs; - - CPU_FOREACH(cs) { - PowerPCCPU *cpu = POWERPC_CPU(cs); - - /* (TCG) Set the OS CAM line of the thread interrupt context. */ - spapr_xive_set_tctx_os_cam(spapr_cpu_state(cpu)->tctx); - } - - if (spapr_irq_init_kvm(kvmppc_xive_connect, - SPAPR_INTC(spapr->xive), errp) < 0) { - return; - } - - /* Activate the XIVE MMIOs */ - spapr_xive_mmio_set_enabled(spapr->xive, true); -} - SpaprIrq spapr_irq_xive = { .nr_xirqs = SPAPR_NR_XIRQS, .nr_msis = SPAPR_NR_MSIS, @@ -163,7 +137,6 @@ SpaprIrq spapr_irq_xive = { .xive = true, .post_load = spapr_irq_post_load_xive, - .reset = spapr_irq_reset_xive, }; /* @@ -187,37 +160,9 @@ static SpaprIrq *spapr_irq_current(SpaprMachineState *spapr) static int spapr_irq_post_load_dual(SpaprMachineState *spapr, int version_id) { - /* - * Force a reset of the XIVE backend after migration. The machine - * defaults to XICS at startup. - */ - if (spapr_ovec_test(spapr->ov5_cas, OV5_XIVE_EXPLOIT)) { - if (kvm_irqchip_in_kernel()) { - xics_kvm_disconnect(SPAPR_INTC(spapr->ics)); - } - spapr_irq_xive.reset(spapr, &error_fatal); - } - return spapr_irq_current(spapr)->post_load(spapr, version_id); } -static void spapr_irq_reset_dual(SpaprMachineState *spapr, Error **errp) -{ - /* - * Deactivate the XIVE MMIOs. The XIVE backend will reenable them - * if selected. - */ - spapr_xive_mmio_set_enabled(spapr->xive, false); - - /* Destroy all KVM devices */ - if (kvm_irqchip_in_kernel()) { - xics_kvm_disconnect(SPAPR_INTC(spapr->ics)); - kvmppc_xive_disconnect(SPAPR_INTC(spapr->xive)); - } - - spapr_irq_current(spapr)->reset(spapr, errp); -} - /* * Define values in sync with the XIVE and XICS backend */ @@ -228,7 +173,6 @@ SpaprIrq spapr_irq_dual = { .xive = true, .post_load = spapr_irq_post_load_dual, - .reset = spapr_irq_reset_dual, }; @@ -512,10 +456,6 @@ void spapr_irq_reset(SpaprMachineState *spapr, Error **errp) assert(!spapr->irq_map || bitmap_empty(spapr->irq_map, spapr->irq_map_nr)); spapr_irq_update_active_intc(spapr); - - if (spapr->irq->reset) { - spapr->irq->reset(spapr, errp); - } } int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp) @@ -651,7 +591,6 @@ SpaprIrq spapr_irq_xics_legacy = { .xive = false, .post_load = spapr_irq_post_load_xics, - .reset = spapr_irq_reset_xics, }; static void spapr_irq_register_types(void) diff --git a/include/hw/ppc/spapr_irq.h b/include/hw/ppc/spapr_irq.h index 06179b271f..e02e44624b 100644 --- a/include/hw/ppc/spapr_irq.h +++ b/include/hw/ppc/spapr_irq.h @@ -84,7 +84,6 @@ typedef struct SpaprIrq { bool xive; int (*post_load)(SpaprMachineState *spapr, int version_id); - void (*reset)(SpaprMachineState *spapr, Error **errp); } SpaprIrq; extern SpaprIrq spapr_irq_xics; @@ -99,6 +98,9 @@ qemu_irq spapr_qirq(SpaprMachineState *spapr, int irq); int spapr_irq_post_load(SpaprMachineState *spapr, int version_id); void spapr_irq_reset(SpaprMachineState *spapr, Error **errp); int spapr_irq_get_phandle(SpaprMachineState *spapr, void *fdt, Error **errp); +int spapr_irq_init_kvm(int (*fn)(SpaprInterruptController *, Error **), + SpaprInterruptController *intc, + Error **errp); /* * XICS legacy routines