Message ID | 1390226872-781-20-git-send-email-mst@redhat.com |
---|---|
State | New |
Headers | show |
On Mon, Jan 20, 2014 at 04:10:25PM +0200, Michael S. Tsirkin wrote: > Add support for acpi pci hotplug using the > new infrastructure. > PIIX4 legacy interface is maintained as is for > machine types 1.6 and older. Actually that's wrong of course, should be off for 1.7 and older. I'll send v2. > > Signed-off-by: Michael S. Tsirkin <mst@redhat.com> > --- > include/hw/i386/pc.h | 5 ++++ > hw/acpi/piix4.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------- > 2 files changed, 70 insertions(+), 10 deletions(-) > > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h > index eb3da96..71653e8 100644 > --- a/include/hw/i386/pc.h > +++ b/include/hw/i386/pc.h > @@ -261,6 +261,11 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); > > #define PC_COMPAT_1_6 \ > {\ > + .driver = "PIIX4_PM",\ > + .property = "acpi-pci-hotplug-with-bridge-support",\ > + .value = "off",\ > + }, \ > + {\ > .driver = "e1000",\ > .property = "mitigation",\ > .value = "off",\ > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c > index 20353b9..1aa35bc 100644 > --- a/hw/acpi/piix4.c > +++ b/hw/acpi/piix4.c > @@ -30,6 +30,7 @@ > #include "hw/nvram/fw_cfg.h" > #include "exec/address-spaces.h" > #include "hw/acpi/piix4.h" > +#include "hw/acpi/pcihp.h" > > //#define DEBUG > > @@ -73,7 +74,6 @@ typedef struct PIIX4PMState { > uint32_t io_base; > > MemoryRegion io_gpe; > - MemoryRegion io_pci; > MemoryRegion io_cpu; > ACPIREGS ar; > > @@ -88,11 +88,16 @@ typedef struct PIIX4PMState { > Notifier machine_ready; > Notifier powerdown_notifier; > > - /* for pci hotplug */ > + /* for legacy pci hotplug (compatible with qemu 1.6 and older) */ > + MemoryRegion io_pci; > struct pci_status pci0_status; > uint32_t pci0_hotplug_enable; > uint32_t pci0_slot_device_present; > > + /* for new pci hotplug (with PCI2PCI bridge support) */ > + AcpiPciHpState acpi_pci_hotplug; > + bool use_acpi_pci_hotplug; > + > uint8_t disable_s3; > uint8_t disable_s4; > uint8_t s4_val; > @@ -263,6 +268,18 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) > return ret; > } > > +static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id) > +{ > + PIIX4PMState *s = opaque; > + return s->use_acpi_pci_hotplug; > +} > + > +static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id) > +{ > + PIIX4PMState *s = opaque; > + return !s->use_acpi_pci_hotplug; > +} > + > /* 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 > @@ -285,8 +302,12 @@ static const VMStateDescription vmstate_acpi = { > VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), > VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), > VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), > - VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, > - struct pci_status), > + VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState, > + vmstate_test_no_use_acpi_pci_hotplug, > + 2, vmstate_pci_status, > + struct pci_status), > + VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, > + vmstate_test_use_acpi_pci_hotplug), > VMSTATE_END_OF_LIST() > } > }; > @@ -364,7 +385,11 @@ static void piix4_reset(void *opaque) > pci_conf[0x5B] = 0x02; > } > pm_io_space_update(s); > - piix4_update_hotplug(s); > + if (s->use_acpi_pci_hotplug) { > + acpi_pcihp_reset(&s->acpi_pci_hotplug); > + } else { > + piix4_update_hotplug(s); > + } > } > > static void piix4_pm_powerdown_req(Notifier *n, void *opaque) > @@ -375,6 +400,26 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque) > acpi_pm1_evt_power_down(&s->ar); > } > > +static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev, > + PCIHotplugState state) > +{ > + PIIX4PMState *s = PIIX4_PM(qdev); > + int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, dev, state); > + if (ret < 0) { > + return ret; > + } > + s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; > + > + acpi_update_sci(&s->ar, s->irq); > + return 0; > +} > + > +static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque) > +{ > + PIIX4PMState *s = opaque; > + pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s)); > +} > + > static void piix4_pm_machine_ready(Notifier *n, void *opaque) > { > PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); > @@ -388,6 +433,10 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) > pci_conf[0x63] = 0x60; > pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) | > (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); > + > + if (s->use_acpi_pci_hotplug) { > + pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s); > + } > } > > static void piix4_pm_add_propeties(PIIX4PMState *s) > @@ -509,6 +558,8 @@ static Property piix4_pm_properties[] = { > DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), > DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), > DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), > + DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState, > + use_acpi_pci_hotplug, true), > DEFINE_PROP_END_OF_LIST(), > }; > > @@ -701,11 +752,15 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, > "acpi-gpe0", GPE_LEN); > memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe); > > - memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s, > - "acpi-pci-hotplug", PCI_HOTPLUG_SIZE); > - memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, > - &s->io_pci); > - pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); > + if (s->use_acpi_pci_hotplug) { > + acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent); > + } else { > + memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s, > + "acpi-pci-hotplug", PCI_HOTPLUG_SIZE); > + memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, > + &s->io_pci); > + pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); > + } > > CPU_FOREACH(cpu) { > CPUClass *cc = CPU_GET_CLASS(cpu); > -- > MST >
On Mon, Jan 20, 2014 at 06:16:59PM +0200, Michael S. Tsirkin wrote: > On Mon, Jan 20, 2014 at 04:10:25PM +0200, Michael S. Tsirkin wrote: > > Add support for acpi pci hotplug using the > > new infrastructure. > > PIIX4 legacy interface is maintained as is for > > machine types 1.6 and older. > > Actually that's wrong of course, should be off for 1.7 > and older. > I'll send v2. Actually seems like it's too painful to do now that everything has been pushed to a public branch. :( I'll just apply a fix on top. > > > > Signed-off-by: Michael S. Tsirkin <mst@redhat.com> > > --- > > include/hw/i386/pc.h | 5 ++++ > > hw/acpi/piix4.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------- > > 2 files changed, 70 insertions(+), 10 deletions(-) > > > > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h > > index eb3da96..71653e8 100644 > > --- a/include/hw/i386/pc.h > > +++ b/include/hw/i386/pc.h > > @@ -261,6 +261,11 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); > > > > #define PC_COMPAT_1_6 \ > > {\ > > + .driver = "PIIX4_PM",\ > > + .property = "acpi-pci-hotplug-with-bridge-support",\ > > + .value = "off",\ > > + }, \ > > + {\ > > .driver = "e1000",\ > > .property = "mitigation",\ > > .value = "off",\ > > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c > > index 20353b9..1aa35bc 100644 > > --- a/hw/acpi/piix4.c > > +++ b/hw/acpi/piix4.c > > @@ -30,6 +30,7 @@ > > #include "hw/nvram/fw_cfg.h" > > #include "exec/address-spaces.h" > > #include "hw/acpi/piix4.h" > > +#include "hw/acpi/pcihp.h" > > > > //#define DEBUG > > > > @@ -73,7 +74,6 @@ typedef struct PIIX4PMState { > > uint32_t io_base; > > > > MemoryRegion io_gpe; > > - MemoryRegion io_pci; > > MemoryRegion io_cpu; > > ACPIREGS ar; > > > > @@ -88,11 +88,16 @@ typedef struct PIIX4PMState { > > Notifier machine_ready; > > Notifier powerdown_notifier; > > > > - /* for pci hotplug */ > > + /* for legacy pci hotplug (compatible with qemu 1.6 and older) */ > > + MemoryRegion io_pci; > > struct pci_status pci0_status; > > uint32_t pci0_hotplug_enable; > > uint32_t pci0_slot_device_present; > > > > + /* for new pci hotplug (with PCI2PCI bridge support) */ > > + AcpiPciHpState acpi_pci_hotplug; > > + bool use_acpi_pci_hotplug; > > + > > uint8_t disable_s3; > > uint8_t disable_s4; > > uint8_t s4_val; > > @@ -263,6 +268,18 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) > > return ret; > > } > > > > +static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id) > > +{ > > + PIIX4PMState *s = opaque; > > + return s->use_acpi_pci_hotplug; > > +} > > + > > +static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id) > > +{ > > + PIIX4PMState *s = opaque; > > + return !s->use_acpi_pci_hotplug; > > +} > > + > > /* 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 > > @@ -285,8 +302,12 @@ static const VMStateDescription vmstate_acpi = { > > VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), > > VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), > > VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), > > - VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, > > - struct pci_status), > > + VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState, > > + vmstate_test_no_use_acpi_pci_hotplug, > > + 2, vmstate_pci_status, > > + struct pci_status), > > + VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, > > + vmstate_test_use_acpi_pci_hotplug), > > VMSTATE_END_OF_LIST() > > } > > }; > > @@ -364,7 +385,11 @@ static void piix4_reset(void *opaque) > > pci_conf[0x5B] = 0x02; > > } > > pm_io_space_update(s); > > - piix4_update_hotplug(s); > > + if (s->use_acpi_pci_hotplug) { > > + acpi_pcihp_reset(&s->acpi_pci_hotplug); > > + } else { > > + piix4_update_hotplug(s); > > + } > > } > > > > static void piix4_pm_powerdown_req(Notifier *n, void *opaque) > > @@ -375,6 +400,26 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque) > > acpi_pm1_evt_power_down(&s->ar); > > } > > > > +static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev, > > + PCIHotplugState state) > > +{ > > + PIIX4PMState *s = PIIX4_PM(qdev); > > + int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, dev, state); > > + if (ret < 0) { > > + return ret; > > + } > > + s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; > > + > > + acpi_update_sci(&s->ar, s->irq); > > + return 0; > > +} > > + > > +static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque) > > +{ > > + PIIX4PMState *s = opaque; > > + pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s)); > > +} > > + > > static void piix4_pm_machine_ready(Notifier *n, void *opaque) > > { > > PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); > > @@ -388,6 +433,10 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) > > pci_conf[0x63] = 0x60; > > pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) | > > (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); > > + > > + if (s->use_acpi_pci_hotplug) { > > + pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s); > > + } > > } > > > > static void piix4_pm_add_propeties(PIIX4PMState *s) > > @@ -509,6 +558,8 @@ static Property piix4_pm_properties[] = { > > DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), > > DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), > > DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), > > + DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState, > > + use_acpi_pci_hotplug, true), > > DEFINE_PROP_END_OF_LIST(), > > }; > > > > @@ -701,11 +752,15 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, > > "acpi-gpe0", GPE_LEN); > > memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe); > > > > - memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s, > > - "acpi-pci-hotplug", PCI_HOTPLUG_SIZE); > > - memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, > > - &s->io_pci); > > - pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); > > + if (s->use_acpi_pci_hotplug) { > > + acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent); > > + } else { > > + memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s, > > + "acpi-pci-hotplug", PCI_HOTPLUG_SIZE); > > + memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, > > + &s->io_pci); > > + pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); > > + } > > > > CPU_FOREACH(cpu) { > > CPUClass *cc = CPU_GET_CLASS(cpu); > > -- > > MST > >
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index eb3da96..71653e8 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -261,6 +261,11 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t); #define PC_COMPAT_1_6 \ {\ + .driver = "PIIX4_PM",\ + .property = "acpi-pci-hotplug-with-bridge-support",\ + .value = "off",\ + }, \ + {\ .driver = "e1000",\ .property = "mitigation",\ .value = "off",\ diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 20353b9..1aa35bc 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -30,6 +30,7 @@ #include "hw/nvram/fw_cfg.h" #include "exec/address-spaces.h" #include "hw/acpi/piix4.h" +#include "hw/acpi/pcihp.h" //#define DEBUG @@ -73,7 +74,6 @@ typedef struct PIIX4PMState { uint32_t io_base; MemoryRegion io_gpe; - MemoryRegion io_pci; MemoryRegion io_cpu; ACPIREGS ar; @@ -88,11 +88,16 @@ typedef struct PIIX4PMState { Notifier machine_ready; Notifier powerdown_notifier; - /* for pci hotplug */ + /* for legacy pci hotplug (compatible with qemu 1.6 and older) */ + MemoryRegion io_pci; struct pci_status pci0_status; uint32_t pci0_hotplug_enable; uint32_t pci0_slot_device_present; + /* for new pci hotplug (with PCI2PCI bridge support) */ + AcpiPciHpState acpi_pci_hotplug; + bool use_acpi_pci_hotplug; + uint8_t disable_s3; uint8_t disable_s4; uint8_t s4_val; @@ -263,6 +268,18 @@ static int acpi_load_old(QEMUFile *f, void *opaque, int version_id) return ret; } +static bool vmstate_test_use_acpi_pci_hotplug(void *opaque, int version_id) +{ + PIIX4PMState *s = opaque; + return s->use_acpi_pci_hotplug; +} + +static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id) +{ + PIIX4PMState *s = opaque; + return !s->use_acpi_pci_hotplug; +} + /* 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 @@ -285,8 +302,12 @@ static const VMStateDescription vmstate_acpi = { VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), - VMSTATE_STRUCT(pci0_status, PIIX4PMState, 2, vmstate_pci_status, - struct pci_status), + VMSTATE_STRUCT_TEST(pci0_status, PIIX4PMState, + vmstate_test_no_use_acpi_pci_hotplug, + 2, vmstate_pci_status, + struct pci_status), + VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, + vmstate_test_use_acpi_pci_hotplug), VMSTATE_END_OF_LIST() } }; @@ -364,7 +385,11 @@ static void piix4_reset(void *opaque) pci_conf[0x5B] = 0x02; } pm_io_space_update(s); - piix4_update_hotplug(s); + if (s->use_acpi_pci_hotplug) { + acpi_pcihp_reset(&s->acpi_pci_hotplug); + } else { + piix4_update_hotplug(s); + } } static void piix4_pm_powerdown_req(Notifier *n, void *opaque) @@ -375,6 +400,26 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque) acpi_pm1_evt_power_down(&s->ar); } +static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev, + PCIHotplugState state) +{ + PIIX4PMState *s = PIIX4_PM(qdev); + int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, dev, state); + if (ret < 0) { + return ret; + } + s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS; + + acpi_update_sci(&s->ar, s->irq); + return 0; +} + +static void piix4_update_bus_hotplug(PCIBus *bus, void *opaque) +{ + PIIX4PMState *s = opaque; + pci_bus_hotplug(bus, piix4_acpi_pci_hotplug, DEVICE(s)); +} + static void piix4_pm_machine_ready(Notifier *n, void *opaque) { PIIX4PMState *s = container_of(n, PIIX4PMState, machine_ready); @@ -388,6 +433,10 @@ static void piix4_pm_machine_ready(Notifier *n, void *opaque) pci_conf[0x63] = 0x60; pci_conf[0x67] = (memory_region_present(io_as, 0x3f8) ? 0x08 : 0) | (memory_region_present(io_as, 0x2f8) ? 0x90 : 0); + + if (s->use_acpi_pci_hotplug) { + pci_for_each_bus(d->bus, piix4_update_bus_hotplug, s); + } } static void piix4_pm_add_propeties(PIIX4PMState *s) @@ -509,6 +558,8 @@ static Property piix4_pm_properties[] = { DEFINE_PROP_UINT8(ACPI_PM_PROP_S3_DISABLED, PIIX4PMState, disable_s3, 0), DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_DISABLED, PIIX4PMState, disable_s4, 0), DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2), + DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState, + use_acpi_pci_hotplug, true), DEFINE_PROP_END_OF_LIST(), }; @@ -701,11 +752,15 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent, "acpi-gpe0", GPE_LEN); memory_region_add_subregion(parent, GPE_BASE, &s->io_gpe); - memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s, - "acpi-pci-hotplug", PCI_HOTPLUG_SIZE); - memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, - &s->io_pci); - pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); + if (s->use_acpi_pci_hotplug) { + acpi_pcihp_init(&s->acpi_pci_hotplug, bus, parent); + } else { + memory_region_init_io(&s->io_pci, OBJECT(s), &piix4_pci_ops, s, + "acpi-pci-hotplug", PCI_HOTPLUG_SIZE); + memory_region_add_subregion(parent, PCI_HOTPLUG_ADDR, + &s->io_pci); + pci_bus_hotplug(bus, piix4_device_hotplug, DEVICE(s)); + } CPU_FOREACH(cpu) { CPUClass *cc = CPU_GET_CLASS(cpu);
Add support for acpi pci hotplug using the new infrastructure. PIIX4 legacy interface is maintained as is for machine types 1.6 and older. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> --- include/hw/i386/pc.h | 5 ++++ hw/acpi/piix4.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 70 insertions(+), 10 deletions(-)