diff mbox series

[PATCH-for-5.0,2/2] hw/acpi/piix4: Restrict system-hotplug-support to x86 i440fx PC machine

Message ID 20200318221531.22910-3-philmd@redhat.com (mailing list archive)
State New, archived
Headers show
Series hw/acpi/piix4: Restrict 'system hotplug' feature to i440fx PC machine | expand

Commit Message

Philippe Mathieu-Daudé March 18, 2020, 10:15 p.m. UTC
The PC (i440fx) machine is the only one using the PIIX4 PM
specific system-hotplug-support feature.

Enable this feature in pc_init1(), and let the callers of
piix4_create() get a simple PIIX4 device.
This is the case of the MIPS Malta board.

Doing so we fix a bug on the Malta where a guest writing to
I/O port 0xaf00 crashes QEMU:

  qemu-system-mips: hw/acpi/cpu.c:197: cpu_hotplug_hw_init: Assertion `mc->possible_cpu_arch_ids' failed.
  Aborted (core dumped)
  (gdb) bt
  #0 0x00007f6fd748957f in raise () at /lib64/libc.so.6
  #1 0x00007f6fd7473895 in abort () at /lib64/libc.so.6
  #2 0x00007f6fd7473769 in _nl_load_domain.cold.0 () at /lib64/libc.so.6
  #3 0x00007f6fd7481a26 in .annobin_assert.c_end () at /lib64/libc.so.6
  #4 0x00005646d58ca7bd in cpu_hotplug_hw_init (as=0x5646d6ae3300, owner=0x5646d6fd5b10, state=0x5646d6fd7a30, base_addr=44800) at hw/acpi/cpu.c:197
  #5 0x00005646d58c5284 in acpi_switch_to_modern_cphp (gpe_cpu=0x5646d6fd7910, cpuhp_state=0x5646d6fd7a30, io_port=44800) at hw/acpi/cpu_hotplug.c:107
  #6 0x00005646d58c3431 in piix4_set_cpu_hotplug_legacy (obj=0x5646d6fd5b10, value=false, errp=0x5646d61cdb28 <error_abort>) at hw/acpi/piix4.c:617
  #7 0x00005646d5b00c70 in property_set_bool (obj=0x5646d6fd5b10, v=0x5646d7697d30, name=0x5646d5cf3a90 "cpu-hotplug-legacy", opaque=0x5646d707d110, errp=0x5646d61cdb28 <error_abort>) at qom/object.c:2076
  #8 0x00005646d5afeee6 in object_property_set (obj=0x5646d6fd5b10, v=0x5646d7697d30, name=0x5646d5cf3a90 "cpu-hotplug-legacy", errp=0x5646d61cdb28 <error_abort>) at qom/object.c:1268
  #9 0x00005646d5b01fb8 in object_property_set_qobject (obj=0x5646d6fd5b10, value=0x5646d75b5450, name=0x5646d5cf3a90 "cpu-hotplug-legacy", errp=0x5646d61cdb28 <error_abort>) at qom/qom-qobject.c:26
  #10 0x00005646d5aff1cb in object_property_set_bool (obj=0x5646d6fd5b10, value=false, name=0x5646d5cf3a90 "cpu-hotplug-legacy", errp=0x5646d61cdb28 <error_abort>) at qom/object.c:1334
  #11 0x00005646d58c4fce in cpu_status_write (opaque=0x5646d6fd7910, addr=0, data=0, size=1) at hw/acpi/cpu_hotplug.c:44
  #12 0x00005646d569c707 in memory_region_write_accessor (mr=0x5646d6fd7920, addr=0, value=0x7ffc18053068, size=1, shift=0, mask=255, attrs=...) at memory.c:503
  #13 0x00005646d569c917 in access_with_adjusted_size (addr=0, value=0x7ffc18053068, size=1, access_size_min=1, access_size_max=4, access_fn=0x5646d569c61e <memory_region_write_accessor>, mr=0x5646d6fd7920, attrs=...) at memory.c:569
  #14 0x00005646d569f8f3 in memory_region_dispatch_write (mr=0x5646d6fd7920, addr=0, data=0, size=1, attrs=...) at memory.c:1497
  #15 0x00005646d563e5c5 in flatview_write_continue (fv=0x5646d751b000, addr=44800, attrs=..., buf=0x7ffc180531d4 "", len=4, addr1=0, l=1, mr=0x5646d6fd7920) at exec.c:3324
  #16 0x00005646d563e70a in flatview_write (fv=0x5646d751b000, addr=44800, attrs=..., buf=0x7ffc180531d4 "", len=4) at exec.c:3363
  #17 0x00005646d563ea0f in address_space_write (as=0x5646d618abc0 <address_space_io>, addr=44800, attrs=..., buf=0x7ffc180531d4 "", len=4) at exec.c:3453
  #18 0x00005646d5696ee5 in cpu_outl (addr=44800, val=0) at ioport.c:80

Buglink: https://bugs.launchpad.net/qemu/+bug/1835865
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
 include/hw/southbridge/piix.h | 3 ++-
 hw/acpi/piix4.c               | 4 +++-
 hw/i386/pc_piix.c             | 1 +
 hw/isa/piix4.c                | 2 +-
 4 files changed, 7 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/include/hw/southbridge/piix.h b/include/hw/southbridge/piix.h
index 152628c6d9..3a54409cab 100644
--- a/include/hw/southbridge/piix.h
+++ b/include/hw/southbridge/piix.h
@@ -18,7 +18,8 @@ 
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int smm_enabled, DeviceState **piix4_pm);
+                      int smm_enabled, bool system_hotplug_enabled,
+                      DeviceState **piix4_pm);
 
 /* PIRQRC[A:D]: PIRQx Route Control Registers */
 #define PIIX_PIRQCA 0x60
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 9c970336ac..ec4869452b 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -515,7 +515,8 @@  static void piix4_pm_realize(PCIDevice *dev, Error **errp)
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int smm_enabled, DeviceState **piix4_pm)
+                      int smm_enabled, bool system_hotplug_enabled,
+                      DeviceState **piix4_pm)
 {
     DeviceState *dev;
     PIIX4PMState *s;
@@ -533,6 +534,7 @@  I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
     if (xen_enabled()) {
         s->use_acpi_pci_hotplug = false;
     }
+    s->use_acpi_system_hotplug = system_hotplug_enabled;
 
     qdev_init_nofail(dev);
 
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index e2d98243bc..8441f44a14 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -283,6 +283,7 @@  else {
         pcms->smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                                     x86ms->gsi[9], smi_irq,
                                     x86_machine_is_smm_enabled(x86ms),
+                                    true,
                                     &piix4_pm);
         smbus_eeprom_init(pcms->smbus, 8, NULL, 0);
 
diff --git a/hw/isa/piix4.c b/hw/isa/piix4.c
index 7edec5e149..6d6802d15d 100644
--- a/hw/isa/piix4.c
+++ b/hw/isa/piix4.c
@@ -262,7 +262,7 @@  DeviceState *piix4_create(PCIBus *pci_bus, ISABus **isa_bus,
     pci_create_simple(pci_bus, pci->devfn + 2, "piix4-usb-uhci");
     if (smbus) {
         *smbus = piix4_pm_init(pci_bus, pci->devfn + 3, 0x1100,
-                               isa_get_irq(NULL, 9), NULL, 0, NULL);
+                               isa_get_irq(NULL, 9), NULL, 0, false, NULL);
    }
 
     return dev;