Patchwork [2/6] Fix pci_add storage not to exit on bad first argument

login
register
mail settings
Submitter Markus Armbruster
Date Sept. 25, 2009, 1:53 a.m.
Message ID <1f7e6a1805b4e87537d2626cd338981247fce316.1253843232.git.armbru@redhat.com>
Download mbox | patch
Permalink /patch/34245/
State Superseded
Headers show

Comments

Markus Armbruster - Sept. 25, 2009, 1:53 a.m.
Monitor command "pci_add ADDR storage ..." does its work in
qemu_pci_hot_add_nic().  It called pci_create(..., ADDR) to create the
device.  That's wrong, because pci_create() terminates the program
when ADDR is invalid.

Use pci_get_bus_devfn() and pci_create_noinit() instead.

Signed-off-by: Markus Armbruster <armbru@redhat.com>
---
 hw/pci-hotplug.c |   12 ++++++++++--
 hw/pci.c         |    2 +-
 hw/pci.h         |    1 +
 3 files changed, 12 insertions(+), 3 deletions(-)
Markus Armbruster - Sept. 25, 2009, 4:36 p.m.
Markus Armbruster <armbru@redhat.com> writes:

> Monitor command "pci_add ADDR storage ..." does its work in
> qemu_pci_hot_add_nic().  It called pci_create(..., ADDR) to create the

Oops, make that qmu_pci_hot_add_storage().

> device.  That's wrong, because pci_create() terminates the program
> when ADDR is invalid.
>
> Use pci_get_bus_devfn() and pci_create_noinit() instead.
>
> Signed-off-by: Markus Armbruster <armbru@redhat.com>

Patch

diff --git a/hw/pci-hotplug.c b/hw/pci-hotplug.c
index f3dc421..d6093ba 100644
--- a/hw/pci-hotplug.c
+++ b/hw/pci-hotplug.c
@@ -107,6 +107,8 @@  static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
     DriveInfo *dinfo = NULL;
     int type = -1;
     char buf[128];
+    PCIBus *bus;
+    int devfn;
 
     if (get_param_value(buf, sizeof(buf), "if", opts)) {
         if (!strcmp(buf, "scsi"))
@@ -134,16 +136,22 @@  static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
         dinfo = NULL;
     }
 
+    bus = pci_get_bus_devfn(&devfn, devaddr);
+    if (!bus) {
+        monitor_printf(mon, "Invalid PCI device address %s\n", devaddr);
+        return NULL;
+    }
+
     switch (type) {
     case IF_SCSI:
-        dev = pci_create("lsi53c895a", devaddr);
+        dev = pci_create_noinit(bus, devfn, "lsi53c895a");
         break;
     case IF_VIRTIO:
         if (!dinfo) {
             monitor_printf(mon, "virtio requires a backing file/device.\n");
             return NULL;
         }
-        dev = pci_create("virtio-blk-pci", devaddr);
+        dev = pci_create_noinit(bus, devfn, "virtio-blk-pci");
         qdev_prop_set_drive(&dev->qdev, "drive", dinfo);
         break;
     default:
diff --git a/hw/pci.c b/hw/pci.c
index 64d70ed..5be21d7 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -265,7 +265,7 @@  int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
     return 0;
 }
 
-static PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
+PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr)
 {
     int dom, bus;
     unsigned slot;
diff --git a/hw/pci.h b/hw/pci.h
index caba5c8..356405e 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -260,6 +260,7 @@  int pci_bus_num(PCIBus *s);
 void pci_for_each_device(int bus_num, void (*fn)(PCIDevice *d));
 PCIBus *pci_find_bus(int bus_num);
 PCIDevice *pci_find_device(int bus_num, int slot, int function);
+PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr);
 
 int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
                      unsigned *slotp);