From: Alex Williamson <alex.williamson@redhat.com>
To: Chris Wright <chrisw@redhat.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH qemu-kvm 2/2] device-assignment: Don't use libpci
Date: Thu, 20 May 2010 18:41:48 -0600 [thread overview]
Message-ID: <1274402508.19762.21.camel@localhost> (raw)
In-Reply-To: <20100521002715.GB13880@x200.localdomain>
On Thu, 2010-05-20 at 17:27 -0700, Chris Wright wrote:
> From: Alex Williamson <alex.williamson@redhat.com>
>
> 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>
> [chrisw: kill pci_dev, configure check for header, narrow header requirement]
> Signed-off-by: Chris Wright <chrisw@redhat.com>
Looks good, Thanks
Alex
> ---
> configure | 14 +++++-----
> hw/device-assignment.c | 68 ++++++++++++++++++++++++++++++++++++------------
> hw/device-assignment.h | 1 -
> 3 files changed, 58 insertions(+), 25 deletions(-)
>
> diff --git a/configure b/configure
> index ed8e17b..8ca9e1e 100755
> --- a/configure
> +++ b/configure
> @@ -1623,20 +1623,20 @@ EOF
> fi
>
> ##########################################
> -# libpci probe for kvm_cap_device_assignment
> +# libpci header probe for kvm_cap_device_assignment
> if test $kvm_cap_device_assignment = "yes" ; then
> cat > $TMPC << EOF
> -#include <pci/pci.h>
> +#include <pci/header.h>
> #ifndef PCI_VENDOR_ID
> -#error NO LIBPCI
> +#error NO LIBPCI HEADER
> #endif
> -int main(void) { struct pci_access a; pci_init(&a); return 0; }
> +int main(void) { return 0; }
> EOF
> - if compile_prog "" "-lpci -lz" ; then
> - libs_softmmu="-lpci -lz $libs_softmmu"
> + if compile_prog "" "" ; then
> + kvm_cap_device_assignment=yes
> else
> echo
> - echo "Error: libpci check failed"
> + echo "Error: libpci header check failed"
> echo "Disable KVM Device Assignment capability."
> echo
> kvm_cap_device_assignment=no
> diff --git a/hw/device-assignment.c b/hw/device-assignment.c
> index fd09ec3..d8e7cb4 100644
> --- a/hw/device-assignment.c
> +++ b/hw/device-assignment.c
> @@ -37,7 +37,7 @@
> #include "console.h"
> #include "device-assignment.h"
> #include "loader.h"
> -#include <pci/pci.h>
> +#include <pci/header.h>
>
> /* From linux/ioport.h */
> #define IORESOURCE_IO 0x00000100 /* Resource type */
> @@ -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;
> @@ -858,7 +895,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);
> @@ -1196,7 +1233,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);
> @@ -1208,23 +1245,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;
> uint32_t 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;
> @@ -1319,7 +1358,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;
>
> @@ -1351,10 +1389,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)
> diff --git a/hw/device-assignment.h b/hw/device-assignment.h
> index d561112..3accdcd 100644
> --- a/hw/device-assignment.h
> +++ b/hw/device-assignment.h
> @@ -88,7 +88,6 @@ typedef struct AssignedDevice {
> unsigned int h_devfn;
> int irq_requested_type;
> int bound;
> - struct pci_dev *pdev;
> struct {
> #define ASSIGNED_DEVICE_CAP_MSI (1 << 0)
> #define ASSIGNED_DEVICE_CAP_MSIX (1 << 1)
next prev parent reply other threads:[~2010-05-21 0:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
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=1274402508.19762.21.camel@localhost \
--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.