This adds a way to force the removal/unplug of previously added pci devices when ACPI-based hotplug mechanism is not present.
Signed-off-by: Marcos Oviedo <movi...@gmail.com> --- hw/pci-hotplug.c | 16 +++++++++++++--- qemu-monitor.hx | 4 ++-- sysemu.h | 2 +- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c index a8f3df1..1007e5b 100644 --- a/hw/pci-hotplug.c +++ b/hw/pci-hotplug.c @@ -260,11 +260,12 @@ void pci_device_hot_add(Monitor *mon, const QDict *qdict) } #endif -int pci_device_hot_remove(Monitor *mon, const char *pci_addr) +int pci_device_hot_remove(Monitor *mon, const char *pci_addr, const int forced) { PCIDevice *d; int dom, bus; unsigned slot; + int ret = -1; if (pci_read_devaddr(mon, pci_addr, &dom, &bus, &slot)) { return -1; @@ -275,10 +276,19 @@ int pci_device_hot_remove(Monitor *mon, const char *pci_addr) monitor_printf(mon, "slot %d empty\n", slot); return -1; } - return qdev_unplug(&d->qdev); + + if (forced) { + qdev_free(&d->qdev); + ret = 0; + } + else { + ret = qdev_unplug(&d->qdev); + } + + return ret; } void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict) { - pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr")); + pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"), qdict_get_int(qdict, "force")); } diff --git a/qemu-monitor.hx b/qemu-monitor.hx index f6a94f2..ce8cddd 100644 --- a/qemu-monitor.hx +++ b/qemu-monitor.hx @@ -1140,8 +1140,8 @@ ETEXI #if defined(TARGET_I386) { .name = "pci_del", - .args_type = "pci_addr:s", - .params = "[[<domain>:]<bus>:]<slot>", + .args_type = "pci_addr:s,force:-f", + .params = "[[<domain>:]<bus>:]<slot> [-f]", .help = "hot remove PCI device", .mhandler.cmd = do_pci_device_hot_remove, }, diff --git a/sysemu.h b/sysemu.h index 879446a..22303b3 100644 --- a/sysemu.h +++ b/sysemu.h @@ -202,7 +202,7 @@ DriveInfo *add_init_drive(const char *opts); /* pci-hotplug */ void pci_device_hot_add(Monitor *mon, const QDict *qdict); void drive_hot_add(Monitor *mon, const QDict *qdict); -int pci_device_hot_remove(Monitor *mon, const char *pci_addr); +int pci_device_hot_remove(Monitor *mon, const char *pci_addr, const int forced); void do_pci_device_hot_remove(Monitor *mon, const QDict *qdict); /* serial ports */ -- 1.5.6.5