Message ID | 1501964858-5159-5-git-send-email-zuban32s@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 05/08/2017 23:27, Aleksandr Bezzubikov wrote: > To enable hotplugging of a newly created pcie-pci-bridge, > we need to tell firmware (SeaBIOS in this case) to reserve > additional buses or IO/MEM/PREF space for pcie-root-port. > Additional bus reservation allows us to hotplug pcie-pci-bridge into this root port. > The number of buses to reserve is provided to the device via a corresponding > property, and to the firmware via new PCI capability. > The properties' default value is -1 to keep default behavior unchanged. > > Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> > --- > hw/pci-bridge/gen_pcie_root_port.c | 33 +++++++++++++++++++++++++++++++++ > include/hw/pci/pcie_port.h | 1 + > 2 files changed, 34 insertions(+) > > diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c > index cb694d6..ff8d04c 100644 > --- a/hw/pci-bridge/gen_pcie_root_port.c > +++ b/hw/pci-bridge/gen_pcie_root_port.c > @@ -16,6 +16,8 @@ > #include "hw/pci/pcie_port.h" > > #define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" > +#define GEN_PCIE_ROOT_PORT(obj) \ > + OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT) > > #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 > #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 > @@ -26,6 +28,12 @@ typedef struct GenPCIERootPort { > /*< public >*/ > > bool migrate_msix; > + > + /* additional buses to reserve on firmware init */ > + uint32_t bus_reserve; > + uint64_t io_reserve; > + uint64_t mem_reserve; > + uint64_t pref_reserve; > } GenPCIERootPort; > > static uint8_t gen_rp_aer_vector(const PCIDevice *d) > @@ -60,6 +68,23 @@ static bool gen_rp_test_migrate_msix(void *opaque, int version_id) > return rp->migrate_msix; > } > > +static void gen_rp_realize(DeviceState *dev, Error **errp) > +{ > + PCIDevice *d = PCI_DEVICE(dev); > + GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d); > + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); > + > + rpc->parent_realize(dev, errp); > + > + int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve, > + grp->io_reserve, grp->mem_reserve, grp->pref_reserve, errp); > + > + if (rc < 0) { > + rpc->parent_class.exit(d); > + return; > + } > +} > + > static const VMStateDescription vmstate_rp_dev = { > .name = "pcie-root-port", > .version_id = 1, > @@ -78,6 +103,10 @@ static const VMStateDescription vmstate_rp_dev = { > > static Property gen_rp_props[] = { > DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true), > + DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1), > + DEFINE_PROP_UINT64("io-reserve", GenPCIERootPort, io_reserve, -1), > + DEFINE_PROP_UINT64("mem-reserve", GenPCIERootPort, mem_reserve, -1), > + DEFINE_PROP_UINT64("pref-reserve", GenPCIERootPort, pref_reserve, -1), > DEFINE_PROP_END_OF_LIST() > }; > > @@ -92,6 +121,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void *data) > dc->desc = "PCI Express Root Port"; > dc->vmsd = &vmstate_rp_dev; > dc->props = gen_rp_props; > + > + rpc->parent_realize = dc->realize; > + dc->realize = gen_rp_realize; > + > rpc->aer_vector = gen_rp_aer_vector; > rpc->interrupts_init = gen_rp_interrupts_init; > rpc->interrupts_uninit = gen_rp_interrupts_uninit; > diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h > index 1333266..0736014 100644 > --- a/include/hw/pci/pcie_port.h > +++ b/include/hw/pci/pcie_port.h > @@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s); > > typedef struct PCIERootPortClass { > PCIDeviceClass parent_class; > + DeviceRealize parent_realize; > > uint8_t (*aer_vector)(const PCIDevice *dev); > int (*interrupts_init)(PCIDevice *dev, Error **errp); > Reviewed-by: Marcel Apfelbaum <marcel@redhat.com> Thanks, Marcel
On Sat, Aug 05, 2017 at 11:27:37PM +0300, Aleksandr Bezzubikov wrote: > To enable hotplugging of a newly created pcie-pci-bridge, > we need to tell firmware (SeaBIOS in this case) Why SeaBIOS is this case? > to reserve > additional buses or IO/MEM/PREF space for pcie-root-port. > Additional bus reservation allows us to hotplug pcie-pci-bridge into this root port. > The number of buses to reserve is provided to the device via a corresponding > property, and to the firmware via new PCI capability. > The properties' default value is -1 to keep default behavior unchanged. > > Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> > --- > hw/pci-bridge/gen_pcie_root_port.c | 33 +++++++++++++++++++++++++++++++++ > include/hw/pci/pcie_port.h | 1 + > 2 files changed, 34 insertions(+) > > diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c > index cb694d6..ff8d04c 100644 > --- a/hw/pci-bridge/gen_pcie_root_port.c > +++ b/hw/pci-bridge/gen_pcie_root_port.c > @@ -16,6 +16,8 @@ > #include "hw/pci/pcie_port.h" > > #define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" > +#define GEN_PCIE_ROOT_PORT(obj) \ > + OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT) > > #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 > #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 > @@ -26,6 +28,12 @@ typedef struct GenPCIERootPort { > /*< public >*/ > > bool migrate_msix; > + > + /* additional buses to reserve on firmware init */ > + uint32_t bus_reserve; > + uint64_t io_reserve; > + uint64_t mem_reserve; > + uint64_t pref_reserve; > } GenPCIERootPort; > > static uint8_t gen_rp_aer_vector(const PCIDevice *d) > @@ -60,6 +68,23 @@ static bool gen_rp_test_migrate_msix(void *opaque, int version_id) > return rp->migrate_msix; > } > > +static void gen_rp_realize(DeviceState *dev, Error **errp) > +{ > + PCIDevice *d = PCI_DEVICE(dev); > + GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d); > + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); > + > + rpc->parent_realize(dev, errp); > + > + int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve, > + grp->io_reserve, grp->mem_reserve, grp->pref_reserve, errp); You have to skip adding this capability by default to avoid breaking migration to/from old QEMU. A simple way to do this is to check whether any have been specified as != -1. > + > + if (rc < 0) { > + rpc->parent_class.exit(d); > + return; > + } > +} > + > static const VMStateDescription vmstate_rp_dev = { > .name = "pcie-root-port", > .version_id = 1, > @@ -78,6 +103,10 @@ static const VMStateDescription vmstate_rp_dev = { > > static Property gen_rp_props[] = { > DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true), > + DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1), > + DEFINE_PROP_UINT64("io-reserve", GenPCIERootPort, io_reserve, -1), > + DEFINE_PROP_UINT64("mem-reserve", GenPCIERootPort, mem_reserve, -1), > + DEFINE_PROP_UINT64("pref-reserve", GenPCIERootPort, pref_reserve, -1), > DEFINE_PROP_END_OF_LIST() > }; > > @@ -92,6 +121,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void *data) > dc->desc = "PCI Express Root Port"; > dc->vmsd = &vmstate_rp_dev; > dc->props = gen_rp_props; > + > + rpc->parent_realize = dc->realize; > + dc->realize = gen_rp_realize; > + > rpc->aer_vector = gen_rp_aer_vector; > rpc->interrupts_init = gen_rp_interrupts_init; > rpc->interrupts_uninit = gen_rp_interrupts_uninit; > diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h > index 1333266..0736014 100644 > --- a/include/hw/pci/pcie_port.h > +++ b/include/hw/pci/pcie_port.h > @@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s); > > typedef struct PCIERootPortClass { > PCIDeviceClass parent_class; > + DeviceRealize parent_realize; > > uint8_t (*aer_vector)(const PCIDevice *dev); > int (*interrupts_init)(PCIDevice *dev, Error **errp); > -- > 2.7.4
2017-08-08 22:54 GMT+03:00 Michael S. Tsirkin <mst@redhat.com>: > On Sat, Aug 05, 2017 at 11:27:37PM +0300, Aleksandr Bezzubikov wrote: >> To enable hotplugging of a newly created pcie-pci-bridge, >> we need to tell firmware (SeaBIOS in this case) > > Why SeaBIOS is this case? > It is the default BIOS for QEMU and therefore it is the best place to try out a new feature like this reservation cap. >> to reserve >> additional buses or IO/MEM/PREF space for pcie-root-port. >> Additional bus reservation allows us to hotplug pcie-pci-bridge into this root port. >> The number of buses to reserve is provided to the device via a corresponding >> property, and to the firmware via new PCI capability. >> The properties' default value is -1 to keep default behavior unchanged. >> >> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> >> --- >> hw/pci-bridge/gen_pcie_root_port.c | 33 +++++++++++++++++++++++++++++++++ >> include/hw/pci/pcie_port.h | 1 + >> 2 files changed, 34 insertions(+) >> >> diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c >> index cb694d6..ff8d04c 100644 >> --- a/hw/pci-bridge/gen_pcie_root_port.c >> +++ b/hw/pci-bridge/gen_pcie_root_port.c >> @@ -16,6 +16,8 @@ >> #include "hw/pci/pcie_port.h" >> >> #define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" >> +#define GEN_PCIE_ROOT_PORT(obj) \ >> + OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT) >> >> #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 >> #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 >> @@ -26,6 +28,12 @@ typedef struct GenPCIERootPort { >> /*< public >*/ >> >> bool migrate_msix; >> + >> + /* additional buses to reserve on firmware init */ >> + uint32_t bus_reserve; >> + uint64_t io_reserve; >> + uint64_t mem_reserve; >> + uint64_t pref_reserve; >> } GenPCIERootPort; >> >> static uint8_t gen_rp_aer_vector(const PCIDevice *d) >> @@ -60,6 +68,23 @@ static bool gen_rp_test_migrate_msix(void *opaque, int version_id) >> return rp->migrate_msix; >> } >> >> +static void gen_rp_realize(DeviceState *dev, Error **errp) >> +{ >> + PCIDevice *d = PCI_DEVICE(dev); >> + GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d); >> + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); >> + >> + rpc->parent_realize(dev, errp); >> + >> + int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve, >> + grp->io_reserve, grp->mem_reserve, grp->pref_reserve, errp); > > You have to skip adding this capability by default to avoid > breaking migration to/from old QEMU. A simple way to do this is > to check whether any have been specified as != -1. > Agreed, I can't understand how the capability that is brand new and unused by another code except mine can break migration. >> + >> + if (rc < 0) { >> + rpc->parent_class.exit(d); >> + return; >> + } >> +} >> + >> static const VMStateDescription vmstate_rp_dev = { >> .name = "pcie-root-port", >> .version_id = 1, >> @@ -78,6 +103,10 @@ static const VMStateDescription vmstate_rp_dev = { >> >> static Property gen_rp_props[] = { >> DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true), >> + DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1), >> + DEFINE_PROP_UINT64("io-reserve", GenPCIERootPort, io_reserve, -1), >> + DEFINE_PROP_UINT64("mem-reserve", GenPCIERootPort, mem_reserve, -1), >> + DEFINE_PROP_UINT64("pref-reserve", GenPCIERootPort, pref_reserve, -1), >> DEFINE_PROP_END_OF_LIST() >> }; >> >> @@ -92,6 +121,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void *data) >> dc->desc = "PCI Express Root Port"; >> dc->vmsd = &vmstate_rp_dev; >> dc->props = gen_rp_props; >> + >> + rpc->parent_realize = dc->realize; >> + dc->realize = gen_rp_realize; >> + >> rpc->aer_vector = gen_rp_aer_vector; >> rpc->interrupts_init = gen_rp_interrupts_init; >> rpc->interrupts_uninit = gen_rp_interrupts_uninit; >> diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h >> index 1333266..0736014 100644 >> --- a/include/hw/pci/pcie_port.h >> +++ b/include/hw/pci/pcie_port.h >> @@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s); >> >> typedef struct PCIERootPortClass { >> PCIDeviceClass parent_class; >> + DeviceRealize parent_realize; >> >> uint8_t (*aer_vector)(const PCIDevice *dev); >> int (*interrupts_init)(PCIDevice *dev, Error **errp); >> -- >> 2.7.4
On Tue, Aug 08, 2017 at 11:10:58PM +0300, Aleksandr Bezzubikov wrote: > 2017-08-08 22:54 GMT+03:00 Michael S. Tsirkin <mst@redhat.com>: > > On Sat, Aug 05, 2017 at 11:27:37PM +0300, Aleksandr Bezzubikov wrote: > >> To enable hotplugging of a newly created pcie-pci-bridge, > >> we need to tell firmware (SeaBIOS in this case) > > > > Why SeaBIOS is this case? > > > > It is the default BIOS for QEMU and therefore it is the best place to > try out a new feature like this reservation cap. So "e.g. SeaBIOS" would be more appropriate then. > >> to reserve > >> additional buses or IO/MEM/PREF space for pcie-root-port. > >> Additional bus reservation allows us to hotplug pcie-pci-bridge into this root port. > >> The number of buses to reserve is provided to the device via a corresponding > >> property, and to the firmware via new PCI capability. > >> The properties' default value is -1 to keep default behavior unchanged. > >> > >> Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> > >> --- > >> hw/pci-bridge/gen_pcie_root_port.c | 33 +++++++++++++++++++++++++++++++++ > >> include/hw/pci/pcie_port.h | 1 + > >> 2 files changed, 34 insertions(+) > >> > >> diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c > >> index cb694d6..ff8d04c 100644 > >> --- a/hw/pci-bridge/gen_pcie_root_port.c > >> +++ b/hw/pci-bridge/gen_pcie_root_port.c > >> @@ -16,6 +16,8 @@ > >> #include "hw/pci/pcie_port.h" > >> > >> #define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" > >> +#define GEN_PCIE_ROOT_PORT(obj) \ > >> + OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT) > >> > >> #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 > >> #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 > >> @@ -26,6 +28,12 @@ typedef struct GenPCIERootPort { > >> /*< public >*/ > >> > >> bool migrate_msix; > >> + > >> + /* additional buses to reserve on firmware init */ > >> + uint32_t bus_reserve; > >> + uint64_t io_reserve; > >> + uint64_t mem_reserve; > >> + uint64_t pref_reserve; > >> } GenPCIERootPort; > >> > >> static uint8_t gen_rp_aer_vector(const PCIDevice *d) > >> @@ -60,6 +68,23 @@ static bool gen_rp_test_migrate_msix(void *opaque, int version_id) > >> return rp->migrate_msix; > >> } > >> > >> +static void gen_rp_realize(DeviceState *dev, Error **errp) > >> +{ > >> + PCIDevice *d = PCI_DEVICE(dev); > >> + GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d); > >> + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); > >> + > >> + rpc->parent_realize(dev, errp); > >> + > >> + int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve, > >> + grp->io_reserve, grp->mem_reserve, grp->pref_reserve, errp); > > > > You have to skip adding this capability by default to avoid > > breaking migration to/from old QEMU. A simple way to do this is > > to check whether any have been specified as != -1. > > > > Agreed, I can't understand how the capability that is brand new > and unused by another code except mine can break migration. Any guest-visible behaviour change across the migration boundary is prohibited. In this case, any code that walks a capability list while you migrate will end up in the wrong place in config space. > >> + > >> + if (rc < 0) { > >> + rpc->parent_class.exit(d); > >> + return; > >> + } > >> +} > >> + > >> static const VMStateDescription vmstate_rp_dev = { > >> .name = "pcie-root-port", > >> .version_id = 1, > >> @@ -78,6 +103,10 @@ static const VMStateDescription vmstate_rp_dev = { > >> > >> static Property gen_rp_props[] = { > >> DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true), > >> + DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1), > >> + DEFINE_PROP_UINT64("io-reserve", GenPCIERootPort, io_reserve, -1), > >> + DEFINE_PROP_UINT64("mem-reserve", GenPCIERootPort, mem_reserve, -1), > >> + DEFINE_PROP_UINT64("pref-reserve", GenPCIERootPort, pref_reserve, -1), > >> DEFINE_PROP_END_OF_LIST() > >> }; > >> > >> @@ -92,6 +121,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void *data) > >> dc->desc = "PCI Express Root Port"; > >> dc->vmsd = &vmstate_rp_dev; > >> dc->props = gen_rp_props; > >> + > >> + rpc->parent_realize = dc->realize; > >> + dc->realize = gen_rp_realize; > >> + > >> rpc->aer_vector = gen_rp_aer_vector; > >> rpc->interrupts_init = gen_rp_interrupts_init; > >> rpc->interrupts_uninit = gen_rp_interrupts_uninit; > >> diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h > >> index 1333266..0736014 100644 > >> --- a/include/hw/pci/pcie_port.h > >> +++ b/include/hw/pci/pcie_port.h > >> @@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s); > >> > >> typedef struct PCIERootPortClass { > >> PCIDeviceClass parent_class; > >> + DeviceRealize parent_realize; > >> > >> uint8_t (*aer_vector)(const PCIDevice *dev); > >> int (*interrupts_init)(PCIDevice *dev, Error **errp); > >> -- > >> 2.7.4 > > > > -- > Aleksandr Bezzubikov
diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c index cb694d6..ff8d04c 100644 --- a/hw/pci-bridge/gen_pcie_root_port.c +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -16,6 +16,8 @@ #include "hw/pci/pcie_port.h" #define TYPE_GEN_PCIE_ROOT_PORT "pcie-root-port" +#define GEN_PCIE_ROOT_PORT(obj) \ + OBJECT_CHECK(GenPCIERootPort, (obj), TYPE_GEN_PCIE_ROOT_PORT) #define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 #define GEN_PCIE_ROOT_PORT_MSIX_NR_VECTOR 1 @@ -26,6 +28,12 @@ typedef struct GenPCIERootPort { /*< public >*/ bool migrate_msix; + + /* additional buses to reserve on firmware init */ + uint32_t bus_reserve; + uint64_t io_reserve; + uint64_t mem_reserve; + uint64_t pref_reserve; } GenPCIERootPort; static uint8_t gen_rp_aer_vector(const PCIDevice *d) @@ -60,6 +68,23 @@ static bool gen_rp_test_migrate_msix(void *opaque, int version_id) return rp->migrate_msix; } +static void gen_rp_realize(DeviceState *dev, Error **errp) +{ + PCIDevice *d = PCI_DEVICE(dev); + GenPCIERootPort *grp = GEN_PCIE_ROOT_PORT(d); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(d); + + rpc->parent_realize(dev, errp); + + int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve, + grp->io_reserve, grp->mem_reserve, grp->pref_reserve, errp); + + if (rc < 0) { + rpc->parent_class.exit(d); + return; + } +} + static const VMStateDescription vmstate_rp_dev = { .name = "pcie-root-port", .version_id = 1, @@ -78,6 +103,10 @@ static const VMStateDescription vmstate_rp_dev = { static Property gen_rp_props[] = { DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true), + DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1), + DEFINE_PROP_UINT64("io-reserve", GenPCIERootPort, io_reserve, -1), + DEFINE_PROP_UINT64("mem-reserve", GenPCIERootPort, mem_reserve, -1), + DEFINE_PROP_UINT64("pref-reserve", GenPCIERootPort, pref_reserve, -1), DEFINE_PROP_END_OF_LIST() }; @@ -92,6 +121,10 @@ static void gen_rp_dev_class_init(ObjectClass *klass, void *data) dc->desc = "PCI Express Root Port"; dc->vmsd = &vmstate_rp_dev; dc->props = gen_rp_props; + + rpc->parent_realize = dc->realize; + dc->realize = gen_rp_realize; + rpc->aer_vector = gen_rp_aer_vector; rpc->interrupts_init = gen_rp_interrupts_init; rpc->interrupts_uninit = gen_rp_interrupts_uninit; diff --git a/include/hw/pci/pcie_port.h b/include/hw/pci/pcie_port.h index 1333266..0736014 100644 --- a/include/hw/pci/pcie_port.h +++ b/include/hw/pci/pcie_port.h @@ -65,6 +65,7 @@ void pcie_chassis_del_slot(PCIESlot *s); typedef struct PCIERootPortClass { PCIDeviceClass parent_class; + DeviceRealize parent_realize; uint8_t (*aer_vector)(const PCIDevice *dev); int (*interrupts_init)(PCIDevice *dev, Error **errp);
To enable hotplugging of a newly created pcie-pci-bridge, we need to tell firmware (SeaBIOS in this case) to reserve additional buses or IO/MEM/PREF space for pcie-root-port. Additional bus reservation allows us to hotplug pcie-pci-bridge into this root port. The number of buses to reserve is provided to the device via a corresponding property, and to the firmware via new PCI capability. The properties' default value is -1 to keep default behavior unchanged. Signed-off-by: Aleksandr Bezzubikov <zuban32s@gmail.com> --- hw/pci-bridge/gen_pcie_root_port.c | 33 +++++++++++++++++++++++++++++++++ include/hw/pci/pcie_port.h | 1 + 2 files changed, 34 insertions(+)