Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 546

kvm-83-164.el5_5.9.src.rpm

From 0011cb273045f8c68529393478e14509b856517d Mon Sep 17 00:00:00 2001
From: Han, Weidong <weidong.han@intel.com>
Date: Thu, 21 May 2009 17:08:55 -0700
Subject: [PATCH 17/25] kvm: qemu: improve pci host device address parsing

pci_parse_devaddr parses [[<domain>:][<bus>:]<slot>, it's valid when even
enter only slot, whereas it must be bus:slot.func in device assignment
command  (-pcidevice host=bus:slot.func). So I implemented a dedicated
function to parse device bdf in device assignment command, rather than
mix two parsing function together.

Signed-off-by: Weidong Han <weidong.han@intel.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
(cherry picked from commit 7b2f76964d71b091bcf27f74bbd50b00a054900d)
Signed-off-by: Chris Wright <chrisw@redhat.com>
Bugzilla: 498085
Message-Id: <1242950943-30180-18-git-send-email-chrisw@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Upstream-status: applied
Acked-by: Juan Quintela <quintela@redhat.com>
Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
Acked-by: Don Dutile <ddutile@redhat.com>
---
 qemu/hw/device-assignment.c |   22 +++++++------------
 qemu/hw/pci.c               |   50 +++++++++++++++++++++++++++++++++++++++++++
 qemu/hw/pci.h               |    3 ++
 3 files changed, 61 insertions(+), 14 deletions(-)

diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c
index 573c150..80ced75 100644
--- a/qemu/hw/device-assignment.c
+++ b/qemu/hw/device-assignment.c
@@ -1191,8 +1191,7 @@ out:
  */
 AssignedDevInfo *add_assigned_device(const char *arg)
 {
-    char *cp, *cp1;
-    char device[8];
+    char device[16];
     char dma[6];
     int r;
     AssignedDevInfo *adev;
@@ -1203,6 +1202,13 @@ AssignedDevInfo *add_assigned_device(const char *arg)
         return NULL;
     }
     r = get_param_value(device, sizeof(device), "host", arg);
+    if (!r)
+         goto bad;
+
+    r = pci_parse_host_devaddr(device, &adev->bus, &adev->dev, &adev->func);
+    if (r)
+        goto bad;
+
     r = get_param_value(adev->name, sizeof(adev->name), "name", arg);
     if (!r)
 	snprintf(adev->name, sizeof(adev->name), "%s", device);
@@ -1212,18 +1218,6 @@ AssignedDevInfo *add_assigned_device(const char *arg)
     if (r && !strncmp(dma, "none", 4))
         adev->disable_iommu = 1;
 #endif
-    cp = device;
-    adev->bus = strtoul(cp, &cp1, 16);
-    if (*cp1 != ':')
-        goto bad;
-    cp = cp1 + 1;
-
-    adev->dev = strtoul(cp, &cp1, 16);
-    if (*cp1 != '.')
-        goto bad;
-    cp = cp1 + 1;
-
-    adev->func = strtoul(cp, &cp1, 16);
 
     LIST_INSERT_HEAD(&adev_head, adev, next);
     return adev;
diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
index 2ce9e72..07e72eb 100644
--- a/qemu/hw/pci.c
+++ b/qemu/hw/pci.c
@@ -163,6 +163,7 @@ static int pci_set_default_subsystem_id(PCIDevice *pci_dev)
 }
 
 /*
+ * Parse pci address in qemu command
  * Parse [[<domain>:]<bus>:]<slot>, return -1 on error
  */
 static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
@@ -211,6 +212,55 @@ static int pci_parse_devaddr(const char *addr, int *domp, int *busp, unsigned *s
     return 0;
 }
 
+/*
+ * Parse device bdf in device assignment command:
+ *
+ * -pcidevice host=bus:dev.func
+ *
+ * Parse <bus>:<slot>.<func> return -1 on error
+ */
+int pci_parse_host_devaddr(const char *addr, int *busp,
+                           int *slotp, int *funcp)
+{
+    const char *p;
+    char *e;
+    int val;
+    int bus = 0, slot = 0, func = 0;
+
+    p = addr;
+    val = strtoul(p, &e, 16);
+    if (e == p)
+	return -1;
+    if (*e == ':') {
+	bus = val;
+	p = e + 1;
+	val = strtoul(p, &e, 16);
+	if (e == p)
+	    return -1;
+	if (*e == '.') {
+	    slot = val;
+	    p = e + 1;
+	    val = strtoul(p, &e, 16);
+	    if (e == p)
+		return -1;
+	    func = val;
+	} else
+	    return -1;
+    } else
+	return -1;
+
+    if (bus > 0xff || slot > 0x1f || func > 0x7)
+	return -1;
+
+    if (*e)
+	return -1;
+
+    *busp = bus;
+    *slotp = slot;
+    *funcp = func;
+    return 0;
+}
+
 int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp)
 {
     char devaddr[32];
diff --git a/qemu/hw/pci.h b/qemu/hw/pci.h
index 3b3af33..0ac2520 100644
--- a/qemu/hw/pci.h
+++ b/qemu/hw/pci.h
@@ -180,6 +180,9 @@ PCIDevice *pci_find_device(int bus_num, int slot);
 int pci_read_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp);
 int pci_assign_devaddr(const char *addr, int *domp, int *busp, unsigned *slotp);
 
+int pci_parse_host_devaddr(const char *addr, int *busp,
+                           int *slotp, int *funcp);
+
 void pci_info(void);
 PCIBus *pci_bridge_init(PCIBus *bus, int devfn, uint32_t id,
                         pci_map_irq_fn map_irq, const char *name);
-- 
1.6.3.rc4.29.g8146