diff options
author | Greg Kurz <groug@kaod.org> | 2020-10-15 23:18:32 +0200 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2020-10-28 01:08:53 +1100 |
commit | f1023d21e81b7bf523ddf2ac91a48117f20ef9d7 (patch) | |
tree | 4a9d14e1edec7b33f146cff745fb01419350225f | |
parent | 90689a32ce2b84580646956c2417343943e5df37 (diff) |
spapr: Unrealize vCPUs with qdev_unrealize()
Since we introduced CPU hot-unplug in sPAPR, we don't unrealize the
vCPU objects explicitly. Instead, we let QOM handle that for us under
object_property_del_all() when the CPU core object is finalized. The
only thing we do is calling cpu_remove_sync() to tear the vCPU thread
down.
This happens to work but it is ugly because:
- we call qdev_realize() but the corresponding qdev_unrealize() is
buried deep in the QOM code
- we call cpu_remove_sync() to undo qemu_init_vcpu() called by
ppc_cpu_realize() in target/ppc/translate_init.c.inc
- the CPU init and teardown paths aren't really symmetrical
The latter didn't bite us so far but a future patch that greatly
simplifies the CPU core realize path needs it to avoid a crash
in QOM.
For all these reasons, have ppc_cpu_unrealize() to undo the changes
of ppc_cpu_realize() by calling cpu_remove_sync() at the right place,
and have the sPAPR CPU core code to call qdev_unrealize().
This requires to add a missing stub because translate_init.c.inc is
also compiled for user mode.
Signed-off-by: Greg Kurz <groug@kaod.org>
Message-Id: <160279671236.1808373.14732005038172874990.stgit@bahia.lan>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r-- | accel/tcg/user-exec-stub.c | 4 | ||||
-rw-r--r-- | hw/ppc/spapr_cpu_core.c | 4 | ||||
-rw-r--r-- | target/ppc/translate_init.c.inc | 2 |
3 files changed, 8 insertions, 2 deletions
diff --git a/accel/tcg/user-exec-stub.c b/accel/tcg/user-exec-stub.c index f6d8c8fb6f..b876f5c1e4 100644 --- a/accel/tcg/user-exec-stub.c +++ b/accel/tcg/user-exec-stub.c @@ -9,6 +9,10 @@ void cpu_resume(CPUState *cpu) { } +void cpu_remove_sync(CPUState *cpu) +{ +} + void qemu_init_vcpu(CPUState *cpu) { } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index c552112145..e4aeb93c02 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -187,7 +187,7 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc) vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data); } spapr_irq_cpu_intc_destroy(SPAPR_MACHINE(qdev_get_machine()), cpu); - cpu_remove_sync(CPU(cpu)); + qdev_unrealize(DEVICE(cpu)); } /* @@ -255,7 +255,7 @@ static bool spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr, kvmppc_set_papr(cpu); if (spapr_irq_cpu_intc_create(spapr, cpu, errp) < 0) { - cpu_remove_sync(CPU(cpu)); + qdev_unrealize(DEVICE(cpu)); return false; } diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc index bb66526280..d2a8204d60 100644 --- a/target/ppc/translate_init.c.inc +++ b/target/ppc/translate_init.c.inc @@ -10328,6 +10328,8 @@ static void ppc_cpu_unrealize(DeviceState *dev) pcc->parent_unrealize(dev); + cpu_remove_sync(CPU(cpu)); + for (i = 0; i < PPC_CPU_OPCODES_LEN; i++) { if (cpu->opcodes[i] == &invalid_handler) { continue; |