qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	Igor Mammedov <imammedo@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Richard Henderson <rth@twiddle.net>,
	Eduardo Habkost <ehabkost@redhat.com>
Subject: [Qemu-devel] [PULL 26/34] pc: use new CPU hotplug interface since 2.7 machine type
Date: Fri, 24 Jun 2016 08:55:35 +0300	[thread overview]
Message-ID: <20160624085535-mutt-send-email-mst@redhat.com> (raw)
In-Reply-To: <1466747621-4342-1-git-send-email-mst@redhat.com>

From: Igor Mammedov <imammedo@redhat.com>

For compatibility reasons PC/Q35 will start with legacy
CPU hotplug interface by default but with new CPU hotplug
AML code since 2.7 machine type. That way legacy firmware
that doesn't use QEMU generated ACPI tables will be
able to continue using legacy CPU hotplug interface.

While new machine type, with firmware supporting QEMU
provided ACPI tables, will generate new CPU hotplug AML,
which will switch to new CPU hotplug interface when
guest OS executes its _INI method on ACPI tables
loading.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/hw/acpi/cpu.h         |  1 +
 include/hw/acpi/cpu_hotplug.h |  6 ++++++
 include/hw/i386/pc.h          |  2 ++
 hw/acpi/cpu.c                 |  9 +++++++++
 hw/acpi/cpu_hotplug.c         | 21 ++++++++++++++++++++-
 hw/acpi/ich9.c                | 33 +++++++++++++++++++++++++++++++++
 hw/acpi/piix4.c               | 32 ++++++++++++++++++++++++++++++++
 hw/i386/acpi-build.c          | 12 +++++++++++-
 hw/i386/pc_piix.c             |  2 ++
 hw/i386/pc_q35.c              |  2 ++
 10 files changed, 118 insertions(+), 2 deletions(-)

diff --git a/include/hw/acpi/cpu.h b/include/hw/acpi/cpu.h
index 980a83c..89ce172 100644
--- a/include/hw/acpi/cpu.h
+++ b/include/hw/acpi/cpu.h
@@ -49,6 +49,7 @@ void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner,
 
 typedef struct CPUHotplugFeatures {
     bool apci_1_compatible;
+    bool has_legacy_cphp;
 } CPUHotplugFeatures;
 
 void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 6fef67e..b995ef2 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -16,8 +16,10 @@
 #include "hw/acpi/pc-hotplug.h"
 #include "hw/acpi/aml-build.h"
 #include "hw/hotplug.h"
+#include "hw/acpi/cpu.h"
 
 typedef struct AcpiCpuHotplug {
+    Object *device;
     MemoryRegion io;
     uint8_t sts[ACPI_GPE_PROC_LEN];
 } AcpiCpuHotplug;
@@ -28,6 +30,10 @@ void legacy_acpi_cpu_plug_cb(HotplugHandler *hotplug_dev,
 void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
                                   AcpiCpuHotplug *gpe_cpu, uint16_t base);
 
+void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
+                                CPUHotplugState *cpuhp_state,
+                                uint16_t io_port);
+
 void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
                                   uint16_t io_base);
 #endif
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9e23929..884224e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -137,6 +137,8 @@ struct PCMachineClass {
 
     /* TSC rate migration: */
     bool save_tsc_khz;
+    /* generate legacy CPU hotplug AML */
+    bool legacy_cpu_hotplug;
 };
 
 #define TYPE_PC_MACHINE "generic-pc-machine"
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c
index 401ac0d..c13b65c 100644
--- a/hw/acpi/cpu.c
+++ b/hw/acpi/cpu.c
@@ -373,6 +373,15 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts,
         aml_append(field, aml_named_field(CPU_DATA, 32));
         aml_append(cpu_ctrl_dev, field);
 
+        if (opts.has_legacy_cphp) {
+            method = aml_method("_INI", 0, AML_SERIALIZED);
+            /* switch off legacy CPU hotplug HW and use new one,
+             * on reboot system is in new mode and writing 0
+             * in CPU_SELECTOR selects BSP, which is NOP at
+             * the time _INI is called */
+            aml_append(method, aml_store(zero, aml_name(CPU_SELECTOR)));
+            aml_append(cpu_ctrl_dev, method);
+        }
     }
     aml_append(sb_scope, cpu_ctrl_dev);
 
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index fe75bd9..e19d902 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -34,7 +34,15 @@ static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size)
 static void cpu_status_write(void *opaque, hwaddr addr, uint64_t data,
                              unsigned int size)
 {
-    /* TODO: implement VCPU removal on guest signal that CPU can be removed */
+    /* firmware never used to write in CPU present bitmap so use
+       this fact as means to switch QEMU into modern CPU hotplug
+       mode by writing 0 at the beginning of legacy CPU bitmap
+     */
+    if (addr == 0 && data == 0) {
+        AcpiCpuHotplug *cpus = opaque;
+        object_property_set_bool(cpus->device, false, "cpu-hotplug-legacy",
+                                 &error_abort);
+    }
 }
 
 static const MemoryRegionOps AcpiCpuHotplug_ops = {
@@ -83,6 +91,17 @@ void legacy_acpi_cpu_hotplug_init(MemoryRegion *parent, Object *owner,
     memory_region_init_io(&gpe_cpu->io, owner, &AcpiCpuHotplug_ops,
                           gpe_cpu, "acpi-cpu-hotplug", ACPI_GPE_PROC_LEN);
     memory_region_add_subregion(parent, base, &gpe_cpu->io);
+    gpe_cpu->device = owner;
+}
+
+void acpi_switch_to_modern_cphp(AcpiCpuHotplug *gpe_cpu,
+                                CPUHotplugState *cpuhp_state,
+                                uint16_t io_port)
+{
+    MemoryRegion *parent = pci_address_space_io(PCI_DEVICE(gpe_cpu->device));
+
+    memory_region_del_subregion(parent, &gpe_cpu->io);
+    cpu_hotplug_hw_init(parent, gpe_cpu->device, cpuhp_state, io_port);
 }
 
 void build_legacy_cpu_hotplug_aml(Aml *ctx, MachineState *machine,
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index d12cc62..e5a3c18 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -189,6 +189,33 @@ static const VMStateDescription vmstate_tco_io_state = {
     }
 };
 
+static bool vmstate_test_use_cpuhp(void *opaque)
+{
+    ICH9LPCPMRegs *s = opaque;
+    return !s->cpu_hotplug_legacy;
+}
+
+static int vmstate_cpuhp_pre_load(void *opaque)
+{
+    ICH9LPCPMRegs *s = opaque;
+    Object *obj = OBJECT(s->gpe_cpu.device);
+    object_property_set_bool(obj, false, "cpu-hotplug-legacy", &error_abort);
+    return 0;
+}
+
+static const VMStateDescription vmstate_cpuhp_state = {
+    .name = "ich9_pm/cpuhp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .needed = vmstate_test_use_cpuhp,
+    .pre_load = vmstate_cpuhp_pre_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_CPU_HOTPLUG(cpuhp_state, ICH9LPCPMRegs),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_ich9_pm = {
     .name = "ich9_pm",
     .version_id = 1,
@@ -209,6 +236,7 @@ const VMStateDescription vmstate_ich9_pm = {
     .subsections = (const VMStateDescription*[]) {
         &vmstate_memhp_state,
         &vmstate_tco_io_state,
+        &vmstate_cpuhp_state,
         NULL
     }
 };
@@ -318,6 +346,11 @@ static void ich9_pm_set_cpu_hotplug_legacy(Object *obj, bool value,
 {
     ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
 
+    assert(!value);
+    if (s->pm.cpu_hotplug_legacy && value == false) {
+        acpi_switch_to_modern_cphp(&s->pm.gpe_cpu, &s->pm.cpuhp_state,
+                                   ICH9_CPU_HOTPLUG_IO_BASE);
+    }
     s->pm.cpu_hotplug_legacy = value;
 }
 
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 858244a..2adc246 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -276,6 +276,32 @@ static const VMStateDescription vmstate_memhp_state = {
     }
 };
 
+static bool vmstate_test_use_cpuhp(void *opaque)
+{
+    PIIX4PMState *s = opaque;
+    return !s->cpu_hotplug_legacy;
+}
+
+static int vmstate_cpuhp_pre_load(void *opaque)
+{
+    Object *obj = OBJECT(opaque);
+    object_property_set_bool(obj, false, "cpu-hotplug-legacy", &error_abort);
+    return 0;
+}
+
+static const VMStateDescription vmstate_cpuhp_state = {
+    .name = "piix4_pm/cpuhp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .needed = vmstate_test_use_cpuhp,
+    .pre_load = vmstate_cpuhp_pre_load,
+    .fields      = (VMStateField[]) {
+        VMSTATE_CPU_HOTPLUG(cpuhp_state, PIIX4PMState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 /* qemu-kvm 1.2 uses version 3 but advertised as 2
  * To support incoming qemu-kvm 1.2 migration, change version_id
  * and minimum_version_id to 2 below (which breaks migration from
@@ -310,6 +336,7 @@ static const VMStateDescription vmstate_acpi = {
     },
     .subsections = (const VMStateDescription*[]) {
          &vmstate_memhp_state,
+         &vmstate_cpuhp_state,
          NULL
     }
 };
@@ -585,6 +612,11 @@ static void piix4_set_cpu_hotplug_legacy(Object *obj, bool value, Error **errp)
 {
     PIIX4PMState *s = PIIX4_PM(obj);
 
+    assert(!value);
+    if (s->cpu_hotplug_legacy && value == false) {
+        acpi_switch_to_modern_cphp(&s->gpe_cpu, &s->cpuhp_state,
+                                   PIIX4_CPU_HOTPLUG_IO_BASE);
+    }
     s->cpu_hotplug_legacy = value;
 }
 
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index e35a446..20e5b49 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -33,6 +33,7 @@
 #include "hw/timer/hpet.h"
 #include "hw/acpi/acpi-defs.h"
 #include "hw/acpi/acpi.h"
+#include "hw/acpi/cpu.h"
 #include "hw/nvram/fw_cfg.h"
 #include "hw/acpi/bios-linker-loader.h"
 #include "hw/loader.h"
@@ -1895,6 +1896,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
     GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);
     PCMachineState *pcms = PC_MACHINE(machine);
+    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
     uint32_t nr_mem = machine->ram_slots;
     int root_bus_limit = 0xFF;
     PCIBus *bus = NULL;
@@ -1950,7 +1952,15 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
         build_q35_pci0_int(dsdt);
     }
 
-    build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base);
+    if (pcmc->legacy_cpu_hotplug) {
+        build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base);
+    } else {
+        CPUHotplugFeatures opts = {
+            .apci_1_compatible = true, .has_legacy_cphp = true
+        };
+        build_cpus_aml(dsdt, machine, opts, pm->cpu_hp_io_base,
+                       "\\_SB.PCI0", "\\_GPE._E02");
+    }
     build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base,
                              pm->mem_hp_io_len);
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 53bc968..c7d70af 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -445,9 +445,11 @@ DEFINE_I440FX_MACHINE(v2_7, "pc-i440fx-2.7", NULL,
 
 static void pc_i440fx_2_6_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_i440fx_2_7_machine_options(m);
     m->is_default = 0;
     m->alias = NULL;
+    pcmc->legacy_cpu_hotplug = true;
     SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index e4b541f..97a8835 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -294,8 +294,10 @@ DEFINE_Q35_MACHINE(v2_7, "pc-q35-2.7", NULL,
 
 static void pc_q35_2_6_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_q35_2_7_machine_options(m);
     m->alias = NULL;
+    pcmc->legacy_cpu_hotplug = true;
     SET_MACHINE_COMPAT(m, PC_COMPAT_2_6);
 }
 
-- 
MST

  parent reply	other threads:[~2016-06-24  5:55 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1466747621-4342-1-git-send-email-mst@redhat.com>
2016-06-24  5:54 ` [Qemu-devel] [PULL 01/34] smbios: Move table build tools into an include file Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 02/34] ipmi: Add SMBIOS table entry Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 03/34] acpi: Add IPMI table entries Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 04/34] bios: Add tests for the IPMI ACPI and SMBIOS entries Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 05/34] pc-dimm: introduce get_vmstate_memory_region callback Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 06/34] nvdimm: support nvdimm label Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 07/34] acpi: add aml_object_type Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 08/34] acpi: add aml_call5 Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 09/34] nvdimm acpi: set HDLE properly Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 10/34] nvdimm acpi: save arg3 of _DSM method Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 11/34] nvdimm acpi: check UUID Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 12/34] nvdimm acpi: abstract the operations for root & nvdimm devices Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 13/34] nvdimm acpi: check revision Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 14/34] nvdimm acpi: support Get Namespace Label Size function Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 15/34] nvdimm acpi: support Get Namespace Label Data function Michael S. Tsirkin
2016-06-24  5:54 ` [Qemu-devel] [PULL 16/34] nvdimm acpi: support Set " Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 17/34] docs: add NVDIMM ACPI documentation Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 18/34] i386: pci-assign: Fix MSI-X table size Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 19/34] docs: update ACPI CPU hotplug spec with new protocol Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 20/34] pc: piix4/ich9: add 'cpu-hotplug-legacy' property Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 21/34] acpi: cpuhp: add CPU devices AML with _STA method Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 22/34] pc: acpi: introduce AcpiDeviceIfClass.madt_cpu hook Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 23/34] acpi: cpuhp: implement hot-add parts of CPU hotplug interface Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 24/34] acpi: cpuhp: implement hot-remove " Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 25/34] acpi: cpuhp: add cpu._OST handling Michael S. Tsirkin
2016-06-24  5:55 ` Michael S. Tsirkin [this message]
2016-06-24  5:55 ` [Qemu-devel] [PULL 27/34] acpi-test-data: update expected Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 28/34] pc: acpi: drop intermediate PCMachineState.node_cpu Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 29/34] virtio-bus: common ioeventfd infrastructure Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 30/34] virtio-bus: have callers tolerate new host notifier api Michael S. Tsirkin
2016-06-29 11:37   ` Marc-André Lureau
2016-06-29 11:48     ` Cornelia Huck
2016-06-24  5:55 ` [Qemu-devel] [PULL 31/34] virtio-ccw: convert to ioeventfd callbacks Michael S. Tsirkin
2016-06-24  5:55 ` [Qemu-devel] [PULL 32/34] virtio-pci: " Michael S. Tsirkin
2016-06-24  5:56 ` [Qemu-devel] [PULL 33/34] virtio-mmio: " Michael S. Tsirkin
2016-06-24  5:56 ` [Qemu-devel] [PULL 34/34] virtio-bus: remove old set_host_notifier callback Michael S. Tsirkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160624085535-mutt-send-email-mst@redhat.com \
    --to=mst@redhat.com \
    --cc=ehabkost@redhat.com \
    --cc=imammedo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=rth@twiddle.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).