diff --git a/acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch b/acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch new file mode 100644 index 0000000..12a279e --- /dev/null +++ b/acpi-ged-Extend-ACPI-GED-to-support-CPU-hotplug.patch @@ -0,0 +1,205 @@ +From 603cbcc5efdd35f518a5bd0a5067d40c2c4eb8d6 Mon Sep 17 00:00:00 2001 +From: Keqian Zhu +Date: Fri, 3 Apr 2020 15:41:01 +0800 +Subject: [PATCH] acpi/ged: Extend ACPI GED to support CPU hotplug + +This adds a new GED event called ACPI_GED_CPU_HOTPLUG_EVT. +The basic workflow is that: GED sends this event to guest, +then ACPI driver in guest will call _EVT method of GED aml, +then _EVT will call CSCN method in cpus aml to get status of +all cpus. + +The status of cpus is maintained by CPUHotplugState in GED and +is made accessable to guest through memory region. + +This also adds migration support to CPUHotplugState. + +Signed-off-by: Keqian Zhu +Signed-off-by: Salil Mehta +--- + docs/specs/acpi_hw_reduced_hotplug.rst | 3 ++- + hw/acpi/cpu.c | 1 - + hw/acpi/generic_event_device.c | 35 ++++++++++++++++++++++++++ + hw/arm/Kconfig | 1 + + include/hw/acpi/cpu.h | 2 ++ + include/hw/acpi/generic_event_device.h | 4 +++ + 6 files changed, 44 insertions(+), 2 deletions(-) + +diff --git a/docs/specs/acpi_hw_reduced_hotplug.rst b/docs/specs/acpi_hw_reduced_hotplug.rst +index 0bd3f9399f..3acd6fcd8b 100644 +--- a/docs/specs/acpi_hw_reduced_hotplug.rst ++++ b/docs/specs/acpi_hw_reduced_hotplug.rst +@@ -64,7 +64,8 @@ GED IO interface (4 byte access) + 0: Memory hotplug event + 1: System power down event + 2: NVDIMM hotplug event +- 3-31: Reserved ++ 3: CPU hotplug event ++ 4-31: Reserved + + **write_access:** + +diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c +index a9c2ee952a..f9ce0a7f41 100644 +--- a/hw/acpi/cpu.c ++++ b/hw/acpi/cpu.c +@@ -6,7 +6,6 @@ + #include "trace.h" + #include "sysemu/numa.h" + +-#define ACPI_CPU_HOTPLUG_REG_LEN 12 + #define ACPI_CPU_SELECTOR_OFFSET_WR 0 + #define ACPI_CPU_FLAGS_OFFSET_RW 4 + #define ACPI_CPU_CMD_OFFSET_WR 5 +diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c +index e28457a7d1..042a8ef8a5 100644 +--- a/hw/acpi/generic_event_device.c ++++ b/hw/acpi/generic_event_device.c +@@ -25,6 +25,7 @@ static const uint32_t ged_supported_events[] = { + ACPI_GED_MEM_HOTPLUG_EVT, + ACPI_GED_PWR_DOWN_EVT, + ACPI_GED_NVDIMM_HOTPLUG_EVT, ++ ACPI_GED_CPU_HOTPLUG_EVT, + }; + + /* +@@ -117,6 +118,9 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev, + aml_notify(aml_name("\\_SB.NVDR"), + aml_int(0x80))); + break; ++ case ACPI_GED_CPU_HOTPLUG_EVT: ++ aml_append(if_ctx, aml_call0("\\_SB.CPUS.CSCN")); ++ break; + default: + /* + * Please make sure all the events in ged_supported_events[] +@@ -234,6 +238,8 @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev, + } else { + acpi_memory_plug_cb(hotplug_dev, &s->memhp_state, dev, errp); + } ++ } else if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { ++ acpi_cpu_plug_cb(hotplug_dev, &s->cpuhp_state, dev, errp); + } else { + error_setg(errp, "virt: device plug request for unsupported device" + " type: %s", object_get_typename(OBJECT(dev))); +@@ -279,6 +285,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev) + sel = ACPI_GED_PWR_DOWN_EVT; + } else if (ev & ACPI_NVDIMM_HOTPLUG_STATUS) { + sel = ACPI_GED_NVDIMM_HOTPLUG_EVT; ++ } else if (ev & ACPI_CPU_HOTPLUG_STATUS) { ++ sel = ACPI_GED_CPU_HOTPLUG_EVT; + } else { + /* Unknown event. Return without generating interrupt. */ + warn_report("GED: Unsupported event %d. No irq injected", ev); +@@ -311,6 +319,16 @@ static const VMStateDescription vmstate_memhp_state = { + } + }; + ++static const VMStateDescription vmstate_cpuhp_state = { ++ .name = "acpi-ged/cpuhp", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_CPU_HOTPLUG(cpuhp_state, AcpiGedState), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static const VMStateDescription vmstate_ged_state = { + .name = "acpi-ged-state", + .version_id = 1, +@@ -360,6 +378,7 @@ static const VMStateDescription vmstate_acpi_ged = { + .subsections = (const VMStateDescription * []) { + &vmstate_memhp_state, + &vmstate_ghes_state, ++ &vmstate_cpuhp_state, + NULL + } + }; +@@ -370,6 +389,7 @@ static void acpi_ged_initfn(Object *obj) + AcpiGedState *s = ACPI_GED(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + GEDState *ged_st = &s->ged_state; ++ MachineClass *mc; + + memory_region_init_io(&ged_st->evt, obj, &ged_evt_ops, ged_st, + TYPE_ACPI_GED, ACPI_GED_EVT_SEL_LEN); +@@ -393,6 +413,21 @@ static void acpi_ged_initfn(Object *obj) + memory_region_init_io(&ged_st->regs, obj, &ged_regs_ops, ged_st, + TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT); + sysbus_init_mmio(sbd, &ged_st->regs); ++ ++ mc = MACHINE_GET_CLASS(qdev_get_machine()); ++ if (!mc->possible_cpu_arch_ids) { ++ /* ++ * MachineClass should support possible_cpu_arch_ids in ++ * cpu_hotplug_hw_init below. ++ */ ++ return; ++ } ++ ++ memory_region_init(&s->container_cpuhp, OBJECT(dev), "cpuhp container", ++ ACPI_CPU_HOTPLUG_REG_LEN); ++ sysbus_init_mmio(sbd, &s->container_cpuhp); ++ cpu_hotplug_hw_init(&s->container_cpuhp, OBJECT(dev), ++ &s->cpuhp_state, 0); + } + + static void acpi_ged_class_init(ObjectClass *class, void *data) +diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig +index 2d37d29f02..006a4b4c4b 100644 +--- a/hw/arm/Kconfig ++++ b/hw/arm/Kconfig +@@ -27,6 +27,7 @@ config ARM_VIRT + select DIMM + select ACPI_HW_REDUCED + select ACPI_APEI ++ select ACPI_CPU_HOTPLUG + + config CHEETAH + bool +diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h +index a0fdc44bdd..d521025830 100644 +--- a/include/hw/acpi/cpu.h ++++ b/include/hw/acpi/cpu.h +@@ -17,6 +17,8 @@ + #include "hw/acpi/aml-build.h" + #include "hw/hotplug.h" + ++#define ACPI_CPU_HOTPLUG_REG_LEN 12 ++ + typedef struct AcpiCpuStatus { + struct CPUState *cpu; + uint64_t arch_id; +diff --git a/include/hw/acpi/generic_event_device.h b/include/hw/acpi/generic_event_device.h +index d49217c445..6bb2ade385 100644 +--- a/include/hw/acpi/generic_event_device.h ++++ b/include/hw/acpi/generic_event_device.h +@@ -63,6 +63,7 @@ + #include "hw/acpi/memory_hotplug.h" + #include "hw/acpi/ghes.h" + #include "qom/object.h" ++#include "hw/acpi/cpu.h" + + #define ACPI_POWER_BUTTON_DEVICE "PWRB" + +@@ -97,6 +98,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) + #define ACPI_GED_MEM_HOTPLUG_EVT 0x1 + #define ACPI_GED_PWR_DOWN_EVT 0x2 + #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 ++#define ACPI_GED_CPU_HOTPLUG_EVT 0x8 + + typedef struct GEDState { + MemoryRegion evt; +@@ -108,6 +110,8 @@ struct AcpiGedState { + SysBusDevice parent_obj; + MemHotplugState memhp_state; + MemoryRegion container_memhp; ++ CPUHotplugState cpuhp_state; ++ MemoryRegion container_cpuhp; + GEDState ged_state; + uint32_t ged_event_bitmap; + qemu_irq irq; +-- +2.27.0 +