spapr_cpu_core: Implement DeviceClass::reset
Since vCPUs aren't plugged into a bus, we manually register a reset handler for each vCPU. We also call this handler at realize time to ensure hot plugged vCPUs are reset before being exposed to the guest. This results in vCPUs being reset twice at machine reset. It doesn't break anything but it is slightly suboptimal and above all confusing. The hotplug path in device_set_realized() already knows how to reset a hotplugged device if the device reset handler is present. Implement one for sPAPR CPU cores that resets all vCPUs under a core. While here rename spapr_cpu_reset() to spapr_reset_vcpu() for consistency with spapr_realize_vcpu() and spapr_unrealize_vcpu(). Signed-off-by: Greg Kurz <groug@kaod.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> [clg: add documentation on the reset helper usage ] Signed-off-by: Cédric Le Goater <clg@kaod.org> Message-Id: <20191022163812.330-3-clg@kaod.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
90f8db52bb
commit
d1f2b4691a
@ -25,9 +25,8 @@
|
|||||||
#include "sysemu/hw_accel.h"
|
#include "sysemu/hw_accel.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
|
|
||||||
static void spapr_cpu_reset(void *opaque)
|
static void spapr_reset_vcpu(PowerPCCPU *cpu)
|
||||||
{
|
{
|
||||||
PowerPCCPU *cpu = opaque;
|
|
||||||
CPUState *cs = CPU(cpu);
|
CPUState *cs = CPU(cpu);
|
||||||
CPUPPCState *env = &cpu->env;
|
CPUPPCState *env = &cpu->env;
|
||||||
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
|
||||||
@ -193,7 +192,6 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
|
|||||||
if (!sc->pre_3_0_migration) {
|
if (!sc->pre_3_0_migration) {
|
||||||
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
|
vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data);
|
||||||
}
|
}
|
||||||
qemu_unregister_reset(spapr_cpu_reset, cpu);
|
|
||||||
if (spapr_cpu_state(cpu)->icp) {
|
if (spapr_cpu_state(cpu)->icp) {
|
||||||
object_unparent(OBJECT(spapr_cpu_state(cpu)->icp));
|
object_unparent(OBJECT(spapr_cpu_state(cpu)->icp));
|
||||||
}
|
}
|
||||||
@ -204,12 +202,36 @@ static void spapr_unrealize_vcpu(PowerPCCPU *cpu, SpaprCpuCore *sc)
|
|||||||
object_unparent(OBJECT(cpu));
|
object_unparent(OBJECT(cpu));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called when CPUs are hot-plugged.
|
||||||
|
*/
|
||||||
|
static void spapr_cpu_core_reset(DeviceState *dev)
|
||||||
|
{
|
||||||
|
CPUCore *cc = CPU_CORE(dev);
|
||||||
|
SpaprCpuCore *sc = SPAPR_CPU_CORE(dev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < cc->nr_threads; i++) {
|
||||||
|
spapr_reset_vcpu(sc->threads[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called by the machine reset.
|
||||||
|
*/
|
||||||
|
static void spapr_cpu_core_reset_handler(void *opaque)
|
||||||
|
{
|
||||||
|
spapr_cpu_core_reset(opaque);
|
||||||
|
}
|
||||||
|
|
||||||
static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
|
static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
|
||||||
CPUCore *cc = CPU_CORE(dev);
|
CPUCore *cc = CPU_CORE(dev);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
qemu_unregister_reset(spapr_cpu_core_reset_handler, sc);
|
||||||
|
|
||||||
for (i = 0; i < cc->nr_threads; i++) {
|
for (i = 0; i < cc->nr_threads; i++) {
|
||||||
spapr_unrealize_vcpu(sc->threads[i], sc);
|
spapr_unrealize_vcpu(sc->threads[i], sc);
|
||||||
}
|
}
|
||||||
@ -238,12 +260,6 @@ static void spapr_realize_vcpu(PowerPCCPU *cpu, SpaprMachineState *spapr,
|
|||||||
goto error_intc_create;
|
goto error_intc_create;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: Hot-plugged CPUs are not reset. Do it at realize.
|
|
||||||
*/
|
|
||||||
qemu_register_reset(spapr_cpu_reset, cpu);
|
|
||||||
spapr_cpu_reset(cpu);
|
|
||||||
|
|
||||||
if (!sc->pre_3_0_migration) {
|
if (!sc->pre_3_0_migration) {
|
||||||
vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state,
|
vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state,
|
||||||
cpu->machine_data);
|
cpu->machine_data);
|
||||||
@ -338,6 +354,8 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
|
|||||||
goto err_unrealize;
|
goto err_unrealize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qemu_register_reset(spapr_cpu_core_reset_handler, sc);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err_unrealize:
|
err_unrealize:
|
||||||
@ -366,6 +384,7 @@ static void spapr_cpu_core_class_init(ObjectClass *oc, void *data)
|
|||||||
|
|
||||||
dc->realize = spapr_cpu_core_realize;
|
dc->realize = spapr_cpu_core_realize;
|
||||||
dc->unrealize = spapr_cpu_core_unrealize;
|
dc->unrealize = spapr_cpu_core_unrealize;
|
||||||
|
dc->reset = spapr_cpu_core_reset;
|
||||||
dc->props = spapr_cpu_core_properties;
|
dc->props = spapr_cpu_core_properties;
|
||||||
scc->cpu_type = data;
|
scc->cpu_type = data;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user