All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] device-assignment: Don't use libpci
@ 2010-05-20 13:56 Alex Williamson
  2010-05-20 22:06 ` Chris Wright
  0 siblings, 1 reply; 8+ messages in thread
From: Alex Williamson @ 2010-05-20 13:56 UTC (permalink / raw)
  To: kvm; +Cc: chrisw, alex.williamson

We've already got an open fd for PCI config space for the device, we
might as well use it.  This also makes sure that if we're making use of
a privileged file descriptor opened for us, we use it for all accesses
to the device.

Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
---

 configure              |   21 ---------------
 hw/device-assignment.c |   66 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/configure b/configure
index ed8e17b..632d4b0 100755
--- a/configure
+++ b/configure
@@ -1623,27 +1623,6 @@ EOF
 fi
 
 ##########################################
-# libpci probe for kvm_cap_device_assignment
-if test $kvm_cap_device_assignment = "yes" ; then
-  cat > $TMPC << EOF
-#include <pci/pci.h>
-#ifndef PCI_VENDOR_ID
-#error NO LIBPCI
-#endif
-int main(void) { struct pci_access a; pci_init(&a); return 0; }
-EOF
-  if compile_prog "" "-lpci -lz" ; then
-    libs_softmmu="-lpci -lz $libs_softmmu"
-  else
-    echo
-    echo "Error: libpci check failed"
-    echo "Disable KVM Device Assignment capability."
-    echo
-    kvm_cap_device_assignment=no
-  fi
-fi
-
-##########################################
 # test for vhost net
 
 if test "$vhost_net" != "no"; then
diff --git a/hw/device-assignment.c b/hw/device-assignment.c
index 172f0c9..e6b34ac 100644
--- a/hw/device-assignment.c
+++ b/hw/device-assignment.c
@@ -335,24 +335,61 @@ static void assigned_dev_ioport_map(PCIDevice *pci_dev, int region_num,
                           (r_dev->v_addrs + region_num));
 }
 
-static uint8_t pci_find_cap_offset(struct pci_dev *pci_dev, uint8_t cap)
+static uint32_t assigned_dev_pci_read(PCIDevice *d, int pos, int len)
+{
+    AssignedDevice *pci_dev = container_of(d, AssignedDevice, dev);
+    uint32_t val;
+    ssize_t ret;
+    int fd = pci_dev->real_device.config_fd;
+
+again:
+    ret = pread(fd, &val, len, pos);
+    if (ret != len) {
+	if ((ret < 0) && (errno == EINTR || errno == EAGAIN))
+	    goto again;
+
+	fprintf(stderr, "%s: pread failed, ret = %zd errno = %d\n",
+		__func__, ret, errno);
+
+	exit(1);
+    }
+
+    return val;
+}
+
+static uint8_t assigned_dev_pci_read_byte(PCIDevice *d, int pos)
+{
+    return (uint8_t)assigned_dev_pci_read(d, pos, 1);
+}
+
+static uint16_t assigned_dev_pci_read_word(PCIDevice *d, int pos)
+{
+    return (uint16_t)assigned_dev_pci_read(d, pos, 2);
+}
+
+static uint32_t assigned_dev_pci_read_long(PCIDevice *d, int pos)
+{
+    return assigned_dev_pci_read(d, pos, 4);
+}
+
+static uint8_t pci_find_cap_offset(PCIDevice *d, uint8_t cap)
 {
     int id;
     int max_cap = 48;
     int pos = PCI_CAPABILITY_LIST;
     int status;
 
-    status = pci_read_byte(pci_dev, PCI_STATUS);
+    status = assigned_dev_pci_read_byte(d, PCI_STATUS);
     if ((status & PCI_STATUS_CAP_LIST) == 0)
         return 0;
 
     while (max_cap--) {
-        pos = pci_read_byte(pci_dev, pos);
+        pos = assigned_dev_pci_read_byte(d, pos);
         if (pos < 0x40)
             break;
 
         pos &= ~3;
-        id = pci_read_byte(pci_dev, pos + PCI_CAP_LIST_ID);
+        id = assigned_dev_pci_read_byte(d, pos + PCI_CAP_LIST_ID);
 
         if (id == 0xff)
             break;
@@ -861,7 +898,7 @@ static int assign_irq(AssignedDevice *dev)
     int irq, r = 0;
 
     /* Interrupt PIN 0 means don't use INTx */
-    if (pci_read_byte(dev->pdev, PCI_INTERRUPT_PIN) == 0)
+    if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0)
         return 0;
 
     irq = pci_map_irq(&dev->dev, dev->intpin);
@@ -1199,7 +1236,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
 #ifdef KVM_CAP_DEVICE_MSI
     /* Expose MSI capability
      * MSI capability is the 1st capability in capability config */
-    if (pci_find_cap_offset(dev->pdev, PCI_CAP_ID_MSI)) {
+    if (pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI)) {
         dev->cap.available |= ASSIGNED_DEVICE_CAP_MSI;
         memset(&pci_dev->config[pci_dev->cap.start + pci_dev->cap.length],
                0, PCI_CAPABILITY_CONFIG_MSI_LENGTH);
@@ -1211,23 +1248,25 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev)
 #endif
 #ifdef KVM_CAP_DEVICE_MSIX
     /* Expose MSI-X capability */
-    if (pci_find_cap_offset(dev->pdev, PCI_CAP_ID_MSIX)) {
+    if (pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX)) {
         int pos, entry_nr, bar_nr;
         u32 msix_table_entry;
         dev->cap.available |= ASSIGNED_DEVICE_CAP_MSIX;
         memset(&pci_dev->config[pci_dev->cap.start + pci_dev->cap.length],
                0, PCI_CAPABILITY_CONFIG_MSIX_LENGTH);
-        pos = pci_find_cap_offset(dev->pdev, PCI_CAP_ID_MSIX);
-        entry_nr = pci_read_word(dev->pdev, pos + 2) & PCI_MSIX_TABSIZE;
+        pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSIX);
+        entry_nr = assigned_dev_pci_read_word(pci_dev, pos + 2) &
+                                                             PCI_MSIX_TABSIZE;
         pci_dev->config[pci_dev->cap.start + pci_dev->cap.length] = 0x11;
         pci_dev->config[pci_dev->cap.start +
                         pci_dev->cap.length + 2] = entry_nr;
-        msix_table_entry = pci_read_long(dev->pdev, pos + PCI_MSIX_TABLE);
+        msix_table_entry = assigned_dev_pci_read_long(pci_dev,
+                                                      pos + PCI_MSIX_TABLE);
         *(uint32_t *)(pci_dev->config + pci_dev->cap.start +
                       pci_dev->cap.length + PCI_MSIX_TABLE) = msix_table_entry;
         *(uint32_t *)(pci_dev->config + pci_dev->cap.start +
                       pci_dev->cap.length + PCI_MSIX_PBA) =
-                    pci_read_long(dev->pdev, pos + PCI_MSIX_PBA);
+                    assigned_dev_pci_read_byte(pci_dev, pos + PCI_MSIX_PBA);
         bar_nr = msix_table_entry & PCI_MSIX_BIR;
         msix_table_entry &= ~PCI_MSIX_BIR;
         dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry;
@@ -1322,7 +1361,6 @@ static int assigned_dev_register_msix_mmio(AssignedDevice *dev)
 static int assigned_initfn(struct PCIDevice *pci_dev)
 {
     AssignedDevice *dev = DO_UPCAST(AssignedDevice, dev, pci_dev);
-    struct pci_access *pacc;
     uint8_t e_device, e_intx;
     int r;
 
@@ -1354,10 +1392,6 @@ static int assigned_initfn(struct PCIDevice *pci_dev)
     dev->h_busnr = dev->host.bus;
     dev->h_devfn = PCI_DEVFN(dev->host.dev, dev->host.func);
 
-    pacc = pci_alloc();
-    pci_init(pacc);
-    dev->pdev = pci_get_dev(pacc, dev->host.seg, dev->host.bus, dev->host.dev, dev->host.func);
-
     if (pci_enable_capability_support(pci_dev, 0, NULL,
                     assigned_device_pci_cap_write_config,
                     assigned_device_pci_cap_init) < 0)


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2010-05-23 11:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-20 13:56 [PATCH] device-assignment: Don't use libpci Alex Williamson
2010-05-20 22:06 ` Chris Wright
2010-05-21  0:23   ` Chris Wright
2010-05-21  0:25     ` [PATCH qemu-kvm 1/2] device-assignment: use stdint types Chris Wright
2010-05-21  0:27       ` [PATCH qemu-kvm 2/2] device-assignment: Don't use libpci Chris Wright
2010-05-21  0:41         ` Alex Williamson
2010-05-23 11:08         ` Avi Kivity
2010-05-21  0:40       ` [PATCH qemu-kvm 1/2] device-assignment: use stdint types Alex Williamson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.