Introduce a common cpu hotplug notifier(CPUNotifier) to support UNPLUG cpu notify.
Signed-off-by: Gu Zheng <guz.f...@cn.fujitsu.com> Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- hw/acpi/cpu_hotplug.c | 15 +++++++++++---- hw/acpi/ich9.c | 5 ++++- hw/acpi/piix4.c | 11 +++++++---- include/hw/acpi/cpu_hotplug.h | 13 ++++++++++++- qom/cpu.c | 7 ++++++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 2ad83a0..56cb316 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -36,15 +36,22 @@ static const MemoryRegionOps AcpiCpuHotplug_ops = { }, }; -void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu) +void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g, + CPUNotifier *notify) { - CPUClass *k = CPU_GET_CLASS(cpu); + CPUClass *k = CPU_GET_CLASS(notify->dev); + HotplugEventType type = notify->type; int64_t cpu_id; *gpe->sts = *gpe->sts | ACPI_CPU_HOTPLUG_STATUS; - cpu_id = k->get_arch_id(CPU(cpu)); + cpu_id = k->get_arch_id(CPU(notify->dev)); g_assert((cpu_id / 8) < ACPI_GPE_PROC_LEN); - g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); + + if (type == PLUG) { + g->sts[cpu_id / 8] |= (1 << (cpu_id % 8)); + } else { + g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8)); + } } void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index 804f774..2db491d 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -212,9 +212,12 @@ static void pm_powerdown_req(Notifier *n, void *opaque) static void ich9_cpu_hotplug_req(Notifier *n, void *opaque) { ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, cpu_hotplug_notifier); + CPUNotifier *notifier = (CPUNotifier *)opaque; assert(pm != NULL); - AcpiCpuHotplug_add(&pm->acpi_regs.gpe, &pm->gpe_cpu, CPU(opaque)); + + AcpiCpuHotplug_handle(&pm->acpi_regs.gpe, &pm->gpe_cpu, notifier); + acpi_update_sci(&pm->acpi_regs, pm->irq); } diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 5cd6300..cc15b60 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -93,7 +93,7 @@ typedef struct PIIX4PMState { #define PIIX4_PM(obj) \ OBJECT_CHECK(PIIX4PMState, (obj), TYPE_PIIX4_PM) -static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, +static void piix4_acpi_system_hotplug_init(MemoryRegion *parent, PCIBus *bus, PIIX4PMState *s); #define ACPI_ENABLE 0xf1 @@ -465,7 +465,7 @@ static int piix4_pm_initfn(PCIDevice *dev) qemu_add_machine_init_done_notifier(&s->machine_ready); qemu_register_reset(piix4_reset, s); - piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s); + piix4_acpi_system_hotplug_init(pci_address_space_io(dev), dev->bus, s); piix4_pm_add_propeties(s); return 0; @@ -547,13 +547,16 @@ static const MemoryRegionOps piix4_gpe_ops = { static void piix4_cpu_hotplug(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, cpu_hotplug_notifier); + CPUNotifier *notifier = (CPUNotifier *)opaque; assert(s != NULL); - AcpiCpuHotplug_add(&s->ar.gpe, &s->gpe_cpu, CPU(opaque)); + + AcpiCpuHotplug_handle(&s->ar.gpe, &s->gpe_cpu, notifier); + acpi_update_sci(&s->ar, s->irq); } -static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, +static void piix4_acpi_system_hotplug_init(MemoryRegion *parent, PCIBus *bus, PIIX4PMState *s) { memory_region_init_io(&s->io_gpe, OBJECT(s), &piix4_gpe_ops, s, diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h index 9e5d30c..4fe0066 100644 --- a/include/hw/acpi/cpu_hotplug.h +++ b/include/hw/acpi/cpu_hotplug.h @@ -15,12 +15,23 @@ #include "hw/acpi/acpi.h" #include "hw/acpi/pc-hotplug.h" +typedef enum { + PLUG, + UNPLUG, +} HotplugEventType; + +typedef struct CPUNotifier { + DeviceState *dev; + HotplugEventType type; +} CPUNotifier; + typedef struct AcpiCpuHotplug { MemoryRegion io; uint8_t sts[ACPI_GPE_PROC_LEN]; } AcpiCpuHotplug; -void AcpiCpuHotplug_add(ACPIGPE *gpe, AcpiCpuHotplug *g, CPUState *cpu); +void AcpiCpuHotplug_handle(ACPIGPE *gpe, AcpiCpuHotplug *g, + CPUNotifier *notify); void AcpiCpuHotplug_init(MemoryRegion *parent, Object *owner, AcpiCpuHotplug *gpe_cpu, uint16_t base); diff --git a/qom/cpu.c b/qom/cpu.c index add92b1..f921282 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -25,6 +25,7 @@ #include "qemu/log.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" +#include "hw/acpi/cpu_hotplug.h" bool cpu_exists(int64_t id) { @@ -304,8 +305,12 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp) cpu_vmstate_register(cpu); if (dev->hotplugged) { + CPUNotifier notifier; + + notifier.dev = dev; + notifier.type = PLUG; cpu_synchronize_post_init(cpu); - notifier_list_notify(&cpu_hotplug_notifiers, dev); + notifier_list_notify(&cpu_hotplug_notifiers, ¬ifier); cpu_resume(cpu); } } -- 1.7.7