From: Chen Fan <chen.fan.f...@cn.fujitsu.com> The secondary bus reset in bridge control register setting trigger a hot reset, Specially for vfio device, we usually need to do a hot reset for the host bus other than the device reset.
Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- hw/core/qdev.c | 24 ++++++++++++++++++++++++ hw/pci/pci_bridge.c | 2 +- include/hw/qdev-core.h | 3 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/hw/core/qdev.c b/hw/core/qdev.c index b3ad467..9c48bae 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -311,6 +311,13 @@ static int qdev_reset_one(DeviceState *dev, void *opaque) return 0; } +static int qdev_hot_reset_one(DeviceState *dev, void *opaque) +{ + device_hot_reset(dev); + + return 0; +} + static int qbus_reset_one(BusState *bus, void *opaque) { BusClass *bc = BUS_GET_CLASS(bus); @@ -335,6 +342,11 @@ void qbus_reset_all(BusState *bus) qbus_walk_children(bus, NULL, NULL, qdev_reset_one, qbus_reset_one, NULL); } +void qbus_hot_reset_all(BusState *bus) +{ + qbus_walk_children(bus, NULL, NULL, qdev_hot_reset_one, qbus_reset_one, NULL); +} + void qbus_reset_all_fn(void *opaque) { BusState *bus = opaque; @@ -1284,6 +1296,18 @@ void device_reset(DeviceState *dev) } } +void device_hot_reset(DeviceState *dev) +{ + DeviceClass *klass = DEVICE_GET_CLASS(dev); + + if (klass->hot_reset) { + klass->hot_reset(dev); + return; + } + + device_reset(dev); +} + Object *qdev_get_machine(void) { static Object *dev; diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 40c97b1..f1903db 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -268,7 +268,7 @@ void pci_bridge_write_config(PCIDevice *d, newctl = pci_get_word(d->config + PCI_BRIDGE_CONTROL); if (~oldctl & newctl & PCI_BRIDGE_CTL_BUS_RESET) { /* Trigger hot reset on 0->1 transition. */ - qbus_reset_all(&s->sec_bus.qbus); + qbus_hot_reset_all(&s->sec_bus.qbus); } } diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index c537969..e9fe4b3 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -131,6 +131,7 @@ typedef struct DeviceClass { /* callbacks */ void (*reset)(DeviceState *dev); + void (*hot_reset)(DeviceState *dev); DeviceRealize realize; DeviceUnrealize unrealize; @@ -351,6 +352,7 @@ void qdev_reset_all_fn(void *opaque); */ void qbus_reset_all(BusState *bus); void qbus_reset_all_fn(void *opaque); +void qbus_hot_reset_all(BusState *bus); /* This should go away once we get rid of the NULL bus hack */ BusState *sysbus_get_default(void); @@ -372,6 +374,7 @@ void qdev_machine_init(void); * Reset a single device (by calling the reset method). */ void device_reset(DeviceState *dev); +void device_hot_reset(DeviceState *dev); const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev); -- 1.9.3