qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v4 7/7] hw/i386/pc_q35: advertise broadcast SMI if V


From: Laszlo Ersek
Subject: [Qemu-devel] [PATCH v4 7/7] hw/i386/pc_q35: advertise broadcast SMI if VCPU hotplug is turned off
Date: Thu, 1 Dec 2016 18:06:24 +0100

For the time being, we cannot handle SMIs in OVMF if VCPUs can show up
after boot. Otherwise, advertise ICH9_LPC_SMI_F_BROADCAST.

Implement this generally, by introducing a new PCMachineClass method,
namely get_smi_host_features(), and implement the above logic for
pc-q35-2.9 and later. The idea is that future machine types might want to
calculate (the same or different) SMI host features from different
information, and that shouldn't affect earlier machine types.

In turn, validating guest feature requests (inter-feature dependencies)
should be possible purely based on the available host feature set. For
example, in the future we might enforce that the guest select
ICH9_LPC_SMI_F_VCPU_PARKING as a prerequisite for
ICH9_LPC_SMI_F_BROADCAST, but only if the machine type itself advertises
ICH9_LPC_SMI_F_VCPU_PARKING.

Cc: "Michael S. Tsirkin" <address@hidden>
Cc: Eduardo Habkost <address@hidden>
Cc: Gerd Hoffmann <address@hidden>
Cc: Igor Mammedov <address@hidden>
Cc: Paolo Bonzini <address@hidden>
Signed-off-by: Laszlo Ersek <address@hidden>
---
 include/hw/i386/pc.h |  1 +
 hw/i386/pc_q35.c     | 24 +++++++++++++++++++++++-
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 430735e501dd..e164947116b6 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -116,10 +116,11 @@ struct PCMachineClass {
     /*< public >*/
 
     /* Methods: */
     HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
                                            DeviceState *dev);
+    uint64_t (*get_smi_host_features)(void);
 
     /* Device configuration: */
     bool pci_enabled;
     bool kvmclock_enabled;
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index eb0953bb6b16..bc1ab48d2c4f 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -228,11 +228,13 @@ static void pc_q35_init(MachineState *machine)
     /* init basic PC hardware */
     pc_basic_device_init(isa_bus, pcms->gsi, &rtc_state, !mc->no_floppy,
                          (pcms->vmport != ON_OFF_AUTO_ON), 0xff0104);
 
     /* connect pm stuff to lpc */
-    ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms), 0);
+    ich9_lpc_pm_init(lpc, pc_machine_is_smm_enabled(pcms),
+                     pcmc->get_smi_host_features == NULL ? 0 :
+                     pcmc->get_smi_host_features());
 
     /* ahci and SATA device, for q35 1 ahci controller is built-in */
     ahci = pci_create_simple_multifunction(host_bus,
                                            PCI_DEVFN(ICH9_SATA1_DEV,
                                                      ICH9_SATA1_FUNC),
@@ -267,10 +269,26 @@ static void pc_q35_init(MachineState *machine)
         nvdimm_init_acpi_state(&pcms->acpi_nvdimm_state, system_io,
                                pcms->fw_cfg, OBJECT(pcms));
     }
 }
 
+static uint64_t pc_q35_get_smi_host_features(void)
+{
+    uint64_t host_features = 0;
+
+    /* The host features are computed only at startup, they don't depend on
+     * guest actions. For now we only advertise SMI broadcast if VCPU hot-plug
+     * / hot-unplug are disabled. In the future we might advertise it
+     * unconditionally, but negotiate it only if VCPU hot-plug / hot-unplug are
+     * disabled, or if the guest negotiates another feature bit (VCPU parking).
+     */
+    if (smp_cpus == max_cpus) {
+        host_features |= ICH9_LPC_SMI_F_BROADCAST;
+    }
+    return host_features;
+}
+
 #define DEFINE_Q35_MACHINE(suffix, name, compatfn, optionfn) \
     static void pc_init_##suffix(MachineState *machine) \
     { \
         void (*compat)(MachineState *m) = (compatfn); \
         if (compat) { \
@@ -281,19 +299,21 @@ static void pc_q35_init(MachineState *machine)
     DEFINE_PC_MACHINE(suffix, name, pc_init_##suffix, optionfn)
 
 
 static void pc_q35_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     m->family = "pc_q35";
     m->desc = "Standard PC (Q35 + ICH9, 2009)";
     m->hot_add_cpu = pc_hot_add_cpu;
     m->units_per_default_bus = 1;
     m->default_machine_opts = "firmware=bios-256k.bin";
     m->default_display = "std";
     m->no_floppy = 1;
     m->has_dynamic_sysbus = true;
     m->max_cpus = 288;
+    pcmc->get_smi_host_features = pc_q35_get_smi_host_features;
 }
 
 static void pc_q35_2_9_machine_options(MachineClass *m)
 {
     pc_q35_machine_options(m);
@@ -303,12 +323,14 @@ static void pc_q35_2_9_machine_options(MachineClass *m)
 DEFINE_Q35_MACHINE(v2_9, "pc-q35-2.9", NULL,
                    pc_q35_2_9_machine_options);
 
 static void pc_q35_2_8_machine_options(MachineClass *m)
 {
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
     pc_q35_2_9_machine_options(m);
     m->alias = NULL;
+    pcmc->get_smi_host_features = NULL;
     SET_MACHINE_COMPAT(m, PC_COMPAT_2_8);
 }
 
 DEFINE_Q35_MACHINE(v2_8, "pc-q35-2.8", NULL,
                    pc_q35_2_8_machine_options);
-- 
2.9.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]