All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alex Williamson <alex.williamson@redhat.com>
To: kvm@vger.kernel.org
Cc: chrisw@redhat.com, alex.williamson@redhat.com
Subject: [PATCH] device-assignment: Don't use libpci
Date: Thu, 20 May 2010 09:56:04 -0400	[thread overview]
Message-ID: <20100520135537.18663.70947.stgit@virtlab9.virt.bos.redhat.com> (raw)

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)


             reply	other threads:[~2010-05-20 21:57 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-20 13:56 Alex Williamson [this message]
2010-05-20 22:06 ` [PATCH] device-assignment: Don't use libpci 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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20100520135537.18663.70947.stgit@virtlab9.virt.bos.redhat.com \
    --to=alex.williamson@redhat.com \
    --cc=chrisw@redhat.com \
    --cc=kvm@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.