public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Muli Ben-Yehuda <muli@il.ibm.com>
To: Mark McLoughlin <markmc@redhat.com>
Cc: avi@redhat.com, kvm@vger.kernel.org, anthony@codemonkey.ws,
	weidong.han@intel.com, Ben-Ami Yassour1 <BENAMI@il.ibm.com>,
	amit.shah@redhat.com, allen.m.kay@intel.com
Subject: Re: [PATCH 5/6] device assignment: support for assigning PCI devices to guests
Date: Wed, 29 Oct 2008 12:31:02 +0200	[thread overview]
Message-ID: <20081029103102.GQ6737@il.ibm.com> (raw)
In-Reply-To: <1225212922.11515.85.camel@blaa>

On Tue, Oct 28, 2008 at 04:55:22PM +0000, Mark McLoughlin wrote:
> On Tue, 2008-10-28 at 12:06 +0200, muli@il.ibm.com wrote:
> ...
> > +static int get_real_device(AssignedDevice *pci_dev, uint8_t r_bus,
> > +                           uint8_t r_dev, uint8_t r_func)
> > +{
> > +    char dir[128], name[128];
> > +    int fd, r = 0;
> > +    FILE *f;
> > +    unsigned long long start, end, size, flags;
> > +    PCIRegion *rp;
> > +    PCIDevRegions *dev = &pci_dev->real_device;
> > +
> > +    dev->region_number = 0;
> > +
> > +    snprintf(dir, sizeof(dir), "/sys/bus/pci/devices/0000:%02x:%02x.%x/",
> > +	     r_bus, r_dev, r_func);
> > +
> > +    snprintf(name, sizeof(name), "%sconfig", dir);
> > +
> > +    fd = open(name, O_RDWR);
> > +    if (fd == -1) {
> > +        fprintf(stderr, "%s: %s: %m\n", __func__, name);
> > +        return 1;
> > +    }
> > +    dev->config_fd = fd;
> > +again:
> > +    r = read(fd, pci_dev->dev.config, sizeof(pci_dev->dev.config));
> > +    if (r < 0) {
> > +        if (errno == EINTR || errno == EAGAIN)
> > +            goto again;
> > +        fprintf(stderr, "%s: read failed, errno = %d\n", __func__, errno);
> > +    }
> > +
> > +    snprintf(name, sizeof(name), "%sresource", dir);
> > +
> > +    f = fopen(name, "r");
> > +    if (f == NULL) {
> > +        fprintf(stderr, "%s: %s: %m\n", __func__, name);
> > +        return 1;
> > +    }
> > +    r = -1;
> > +    while (fscanf(f, "%lli %lli %lli\n", &start, &end, &flags) == 3) {
> > +        r++;
> > +        rp = dev->regions + r;
> 
> Could, in theory, overflow dev->regions here. Suggest:
> 
> +    for (r = 0; r < MAX_IO_REGIONS; r++) {
> +        if (fscanf(f, "%lli %lli %lli\n", &start, &end, &flags) != 3)
> +            break;

Fixed, thanks Mark. I think it also uncovered a buglet where we would
skip the last region with the original code, which should be ok now.

> > +        rp->valid = 0;
> > +        size = end - start + 1;
> > +        flags &= IORESOURCE_IO | IORESOURCE_MEM | IORESOURCE_PREFETCH;
> > +        if (size == 0 || (flags & ~IORESOURCE_PREFETCH) == 0)
> > +            continue;
> > +        if (flags & IORESOURCE_MEM) {
> > +            flags &= ~IORESOURCE_IO;
> > +	    snprintf(name, sizeof(name), "%sresource%d", dir, r);
> > +            fd = open(name, O_RDWR);
> > +            if (fd == -1)
> > +                continue;       /* probably ROM */
> > +            rp->resource_fd = fd;
> > +        } else
> > +            flags &= ~IORESOURCE_PREFETCH;
> > +
> > +        rp->type = flags;
> > +        rp->valid = 1;
> > +        rp->base_addr = start;
> > +        rp->size = size;
> > +        DEBUG("region %d size %d start 0x%x type %d resource_fd %d\n",
> > +              r, rp->size, start, rp->type, rp->resource_fd);
> > +    }
> > +    fclose(f);
> > +
> > +    dev->region_number = r;
> > +    return 0;
> > +}
> > +
> > +static int disable_iommu;
> 
> Why is this global?
> 
> The flag is set per-device on the command-line and only affects whether
> we pass KVM_DEV_ASSIGN_ENABLE_IOMMU to kvm_assign_pci_device()

Made per-device by moving it to struct AssignedDevInfo.

> > +int nr_assigned_devices;
> > +static LIST_HEAD(, AssignedDevInfo) adev_head;
> > +
> > +static uint32_t calc_assigned_dev_id(uint8_t bus, uint8_t devfn)
> > +{
> > +    return (uint32_t)bus << 8 | (uint32_t)devfn;
> > +}
> > +
> > +static AssignedDevice *register_real_device(PCIBus *e_bus,
> > +                                            const char *e_dev_name,
> > +                                            int e_devfn, uint8_t r_bus,
> > +                                            uint8_t r_dev, uint8_t r_func)
> > +{
> > +    int r;
> > +    AssignedDevice *pci_dev;
> > +    uint8_t e_device, e_intx;
> > +
> > +    DEBUG("Registering real physical device %s (devfn=0x%x)\n",
> > +          e_dev_name, e_devfn);
> > +
> > +    pci_dev = (AssignedDevice *)
> > +        pci_register_device(e_bus, e_dev_name, sizeof(AssignedDevice),
> > +                            e_devfn, assigned_dev_pci_read_config,
> > +                            assigned_dev_pci_write_config);
> > +    if (NULL == pci_dev) {
> > +        fprintf(stderr, "%s: Error: Couldn't register real device %s\n",
> > +                __func__, e_dev_name);
> > +        return NULL;
> > +    }
> > +    if (get_real_device(pci_dev, r_bus, r_dev, r_func)) {
> > +        fprintf(stderr, "%s: Error: Couldn't get real device (%s)!\n",
> > +                __func__, e_dev_name);
> > +        goto out;
> > +    }
> > +
> > +    /* handle real device's MMIO/PIO BARs */
> > +    if (assigned_dev_register_regions(pci_dev->real_device.regions,
> > +                                      pci_dev->real_device.region_number,
> > +                                      pci_dev))
> > +        goto out;
> > +
> > +    /* handle interrupt routing */
> > +    e_device = (pci_dev->dev.devfn >> 3) & 0x1f;
> > +    e_intx = pci_dev->dev.config[0x3d] - 1;
> > +    pci_dev->intpin = e_intx;
> > +    pci_dev->run = 0;
> > +    pci_dev->girq = 0;
> > +    pci_dev->h_busnr = r_bus;
> > +    pci_dev->h_devfn = PCI_DEVFN(r_dev, r_func);
> > +
> > +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> > +    if (kvm_enabled()) {
> > +        struct kvm_assigned_pci_dev assigned_dev_data;
> > +
> > +        memset(&assigned_dev_data, 0, sizeof(assigned_dev_data));
> > +        assigned_dev_data.assigned_dev_id  =
> > +            calc_assigned_dev_id(pci_dev->h_busnr,
> > +                                 (uint32_t)pci_dev->h_devfn);
> > +        assigned_dev_data.busnr = pci_dev->h_busnr;
> > +        assigned_dev_data.devfn = pci_dev->h_devfn;
> > +
> > +#ifdef KVM_CAP_IOMMU
> > +        /* We always enable the IOMMU if present
> > +         * (or when not disabled on the command line)
> > +         */
> > +        r = kvm_check_extension(kvm_context, KVM_CAP_IOMMU);
> > +        if (r && !disable_iommu)
> > +            assigned_dev_data.flags |= KVM_DEV_ASSIGN_ENABLE_IOMMU;
> > +#endif
> > +        r = kvm_assign_pci_device(kvm_context, &assigned_dev_data);
> > +        if (r < 0) {
> > +            fprintf(stderr, "Could not notify kernel about "
> > +                "assigned device \"%s\"\n", e_dev_name);
> > +            perror("register_real_device");
> > +            goto out;
> > +        }
> > +    }
> > +#endif
> > +    term_printf("Registered host PCI device %02x:%02x.%1x "
> > +		"(\"%s\") as guest device %02x:%02x.%1x\n",
> > +		r_bus, r_dev, r_func, e_dev_name,
> > +		pci_bus_num(e_bus), e_device, r_func);
> > +
> > +    return pci_dev;
> > +out:
> > +/*    pci_unregister_device(&pci_dev->dev); */
> > +    return NULL;
> > +}
> > +
> > +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> > +/* The pci config space got updated. Check if irq numbers have changed
> > + * for our devices
> > + */
> > +void assigned_dev_update_irq(PCIDevice *d)
> > +{
> > +    int irq, r;
> > +    AssignedDevice *assigned_dev;
> > +    AssignedDevInfo *adev;
> > +
> > +    LIST_FOREACH(adev, &adev_head, next) {
> > +        assigned_dev = adev->assigned_dev;
> > +        irq = pci_map_irq(&assigned_dev->dev, assigned_dev->intpin);
> > +        irq = piix_get_irq(irq);
> > +
> > +        if (irq != assigned_dev->girq) {
> > +            struct kvm_assigned_irq assigned_irq_data;
> > +
> > +            memset(&assigned_irq_data, 0, sizeof(assigned_irq_data));
> > +            assigned_irq_data.assigned_dev_id  =
> > +                calc_assigned_dev_id(assigned_dev->h_busnr,
> > +                                     (uint8_t) assigned_dev->h_devfn);
> > +            assigned_irq_data.guest_irq = irq;
> > +            assigned_irq_data.host_irq = assigned_dev->real_device.irq;
> > +            r = kvm_assign_irq(kvm_context, &assigned_irq_data);
> > +            if (r < 0) {
> > +                perror("assigned_dev_update_irq");
> > +                fprintf(stderr, "Are you assigning a device "
> > +                        "that shares IRQ with some other device?\n");
> > +                pci_unregister_device(&assigned_dev->dev);
> > +                /* FIXME: Delete node from list */
> > +                continue;
> > +            }
> > +            assigned_dev->girq = irq;
> > +        }
> > +    }
> > +}
> > +#endif
> > +
> > +struct PCIDevice *init_assigned_device(AssignedDevInfo *adev, PCIBus *bus)
> > +{
> > +    adev->assigned_dev = register_real_device(bus,
> > +                                              adev->name, -1,
> > +                                              adev->bus,
> > +                                              adev->dev,
> > +                                              adev->func);
> > +    return &adev->assigned_dev->dev;
> > +}
> 
> This looks unnecessary - register_real_device() isn't used anywhere
> else.
> 
> Why not just move register_real_device() into init_assigned_device()
> ?

Done.

> 
> > +int init_all_assigned_devices(PCIBus *bus)
> > +{
> > +    struct AssignedDevInfo *adev;
> > +
> > +    LIST_FOREACH(adev, &adev_head, next)
> > +        if (init_assigned_device(adev, bus) == NULL)
> > +            return -1;
> > +
> > +    return 0;
> > +}
> > +
> > +/*
> > + * Syntax to assign device:
> > + *
> > + * -pcidevice dev=bus:dev.func,dma=dma
>                  ^^^                  ^^^
> 
> Should be:
> 
>   -pcidevice host=bus:dev.func[,dma=none][,name=string]

Fixed (as well as the other -pcidevice bogosities you pointed).

> 
> > + *
> > + * Example:
> > + * -pcidevice host=00:13.0,dma=pvdma
>                                   ^^^^^
> 
> Should be:
> 
>   -pcidevice host=00:13.0,dma=none,name=Foo
>   
> > + *
> > + * dma can currently only be 'none' to disable iommu support.
> > + */
> > +AssignedDevInfo *add_assigned_device(const char *arg)
> > +{
> > +    char *cp, *cp1;
> > +    char device[8];
> > +    char dma[6];
> > +    int r;
> > +    AssignedDevInfo *adev;
> > +
> > +    adev = qemu_mallocz(sizeof(AssignedDevInfo));
> > +    if (adev == NULL) {
> > +        fprintf(stderr, "%s: Out of memory\n", __func__);
> > +        return NULL;
> > +    }
> > +    r = get_param_value(device, sizeof(device), "host", arg);
> > +    r = get_param_value(adev->name, sizeof(adev->name), "name", arg);
> > +    if (!r)
> > +	snprintf(adev->name, sizeof(adev->name), "%s", device);
> > +
> > +#ifdef KVM_CAP_IOMMU
> > +    r = get_param_value(dma, sizeof(dma), "dma", arg);
> > +    if (r && !strncmp(dma, "none", 4))
> > +        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);
> > +
> > +    nr_assigned_devices++;
> 
> nr_assigned_devices isn't actually used anywhere.

Nuked.

> 
> > +    LIST_INSERT_HEAD(&adev_head, adev, next);
> > +    return adev;
> > +bad:
> > +    fprintf(stderr, "pcidevice argument parse error; "
> > +            "please check the help text for usage\n");
> > +    qemu_free(adev);
> > +    return NULL;
> > +}
> > diff --git a/qemu/hw/device-assignment.h b/qemu/hw/device-assignment.h
> > new file mode 100644
> > index 0000000..ebc0b50
> > --- /dev/null
> > +++ b/qemu/hw/device-assignment.h
> > @@ -0,0 +1,117 @@
> > +/*
> > + * Copyright (c) 2007, Neocleus Corporation.
> > + * Copyright (c) 2007, Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along with
> > + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
> > + * Place - Suite 330, Boston, MA 02111-1307 USA.
> > + *
> > + *  Data structures for storing PCI state
> > + *
> > + *  Adapted to kvm by Qumranet
> > + *
> > + *  Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com)
> > + *  Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com)
> > + *  Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com)
> > + *  Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com)
> > + */
> > +
> > +#ifndef __DEVICE_ASSIGNMENT_H__
> > +#define __DEVICE_ASSIGNMENT_H__
> > +
> > +#include <sys/mman.h>
> > +#include "qemu-common.h"
> > +#include "sys-queue.h"
> > +#include "pci.h"
> > +
> > +/* From include/linux/pci.h in the kernel sources */
> > +#define PCI_DEVFN(slot, func)   ((((slot) & 0x1f) << 3) | ((func) & 0x07))
> > +
> > +#define MAX_IO_REGIONS (6)
> 
> Perhaps a comment to say this is the number of BARs in the config space
> header?

Sure, comments are cheap.

> 
> > +typedef struct {
> > +    int type;           /* Memory or port I/O */
> > +    int valid;
> > +    uint32_t base_addr;
> > +    uint32_t size;    /* size of the region */
> > +    int resource_fd;
> > +} PCIRegion;
> > +
> > +typedef struct {
> > +    uint8_t bus, dev, func; /* Bus inside domain, device and function */
> > +    int irq;                /* IRQ number */
> > +    uint16_t region_number; /* number of active regions */
> > +
> > +    /* Port I/O or MMIO Regions */
> > +    PCIRegion regions[MAX_IO_REGIONS];
> > +    int config_fd;
> > +} PCIDevRegions;
> > +
> > +typedef struct {
> > +    target_phys_addr_t e_physbase;
> > +    uint32_t memory_index;
> > +    union {
> > +        void *r_virtbase;    /* mmapped access address for memory regions */
> > +        uint32_t r_baseport; /* the base guest port for I/O regions */
> > +    } u;
> > +    int num;            /* our index within v_addrs[] */
> > +    uint32_t e_size;    /* emulated size of region in bytes */
> > +    uint32_t r_size;    /* real size of region in bytes */
> > +} AssignedDevRegion;
> > +
> > +typedef struct {
> > +    PCIDevice dev;
> > +    int intpin;
> > +    uint8_t debug_flags;
> > +    AssignedDevRegion v_addrs[PCI_NUM_REGIONS];
> > +    PCIDevRegions real_device;
> > +    int run;
> > +    int girq;
> > +    unsigned char h_busnr;
> > +    unsigned int h_devfn;
> > +    int bound;
> > +} AssignedDevice;
> > +
> > +typedef struct AssignedDevInfo AssignedDevInfo;
> > +
> > +struct AssignedDevInfo {
> > +    char name[15];
> > +    int bus;
> > +    int dev;
> > +    int func;
> > +    AssignedDevice *assigned_dev;
> > +    LIST_ENTRY(AssignedDevInfo) next;
> > +};
> > +
> > +PCIDevice *init_assigned_device(AssignedDevInfo *adev, PCIBus *bus);
> > +AssignedDevInfo *add_assigned_device(const char *arg);
> > +void assigned_dev_set_vector(int irq, int vector);
> > +void assigned_dev_ack_mirq(int vector);
> > +
> > +
> > +#ifdef USE_KVM
> > +int init_all_assigned_devices(PCIBus *bus);
> > +#else /* not using kvm */
> > +static inline int init_all_assigned_devices(PCIBus *bus)
> > +{
> > +    return 0;
> > +}
> > +#endif /* !USE_KVM */
> > +
> > +
> > +#define MAX_DEV_ASSIGN_CMDLINE 8
> > +
> > +extern int device_assignment_enabled;
> 
> > +extern const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
> > +extern int assigned_devices_index;
> 
> Neither of these two are implemented anywhere.

Actually they are, we use them to pass the arguments from main to
pc.c.

> 
> > +#endif              /* __DEVICE_ASSIGNMENT_H__ */
> > diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
> > index d559f0c..5fdb726 100644
> > --- a/qemu/hw/pc.c
> > +++ b/qemu/hw/pc.c
> > @@ -33,6 +33,7 @@
> >  #include "boards.h"
> >  #include "console.h"
> >  #include "fw_cfg.h"
> > +#include "device-assignment.h"
> >  
> >  #include "qemu-kvm.h"
> >  
> > @@ -1157,6 +1158,21 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
> >  
> >      if (pci_enabled)
> >          virtio_balloon_init(pci_bus);
> > +
> > +    if (kvm_enabled() && device_assignment_enabled) {
> 
> The device_assignment_enabled flag looks like it shouldn't be needed.
> 
> If assigned_devices_index remains zero, nothing should happen
> anyway.

Nuked.

> 
> > +	int i;
> > +        for (i = 0; i < assigned_devices_index; i++) {
> > +            if (add_assigned_device(assigned_devices[i]) < 0) {
> > +                fprintf(stderr, "Warning: could not add assigned device %s\n",
> > +                        assigned_devices[i]);
> > +            }
> > +        }
> > +
> > +	if (init_all_assigned_devices(pci_bus)) {
> > +	    fprintf(stderr, "Failed to initialize assigned devices\n");
> > +	    exit (1);
> > +	}
> > +    }
> >  }
> >  
> >  static void pc_init_pci(ram_addr_t ram_size, int vga_ram_size,
> > diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
> > index c82cd20..f86a8a7 100644
> > --- a/qemu/hw/pci.c
> > +++ b/qemu/hw/pci.c
> > @@ -50,6 +50,7 @@ struct PCIBus {
> >  
> >  static void pci_update_mappings(PCIDevice *d);
> >  static void pci_set_irq(void *opaque, int irq_num, int level);
> > +void assigned_dev_update_irq(PCIDevice *d);
> >  
> >  target_phys_addr_t pci_mem_base;
> >  static int pci_irq_index;
> > @@ -453,6 +454,12 @@ void pci_default_write_config(PCIDevice *d,
> >          val >>= 8;
> >      }
> >  
> > +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> > +    if (kvm_enabled() && qemu_kvm_irqchip_in_kernel() &&
> > +        address >= 0x60 && address <= 0x63)
> > +        assigned_dev_update_irq(d);
> > +#endif
> 
> Outside of the context of piix_pci.c, it's difficult to figure out what
> the 0x60-0x63 register range relates to - i.e. you need to know to go
> digging in the PIIX spec.
> 
> How about something like in qemu/hw/pc.h:
> 
>   +/* config space register for IRQ routing */
>   +#define PIIX_CONFIG_IRQ_ROUTE 0x60
> 
> then:
> 
>      if (kvm_enabled() && qemu_kvm_irqchip_in_kernel() &&
>          address >= PIIX_CONFIG_IRQ_ROUTE &&
>          address < PIIX_CONFIG_IRQ_ROUTE + 4)

Ok. #define's are cheap too.

Cheers,
Muli
-- 
The First Workshop on I/O Virtualization (WIOV '08)
Dec 2008, San Diego, CA, http://www.usenix.org/wiov08/
                       <->
SYSTOR 2009---The Israeli Experimental Systems Conference
http://www.haifa.il.ibm.com/conferences/systor2009/

  reply	other threads:[~2008-10-29 10:31 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-28 10:06 [v8] Userspace patches for PCI device assignment muli
2008-10-28 10:06 ` [PATCH 1/6] device assignment: add ioctl wrappers muli
2008-10-28 10:06   ` [PATCH 2/6] device assignment: introduce pci_map_irq to get irq nr from pin number muli
2008-10-28 10:06     ` [PATCH 3/6] device assignment: introduce functions to correlate pin number and irq muli
2008-10-28 10:06       ` [PATCH 4/6] device assignment: build vtd.c for Intel IOMMU support muli
2008-10-28 10:06         ` [PATCH 5/6] device assignment: support for assigning PCI devices to guests muli
2008-10-28 10:06           ` [PATCH 6/6] device assignment: support for hot-plugging PCI devices muli
2008-10-28 14:10           ` [PATCH 5/6] device assignment: support for assigning PCI devices to guests Han, Weidong
2008-10-28 15:32             ` Muli Ben-Yehuda
     [not found]           ` <715D42877B251141A38726ABF5CABF2C018683D874@pdsmsx503.ccr.corp.intel.com>
2008-10-28 15:31             ` Han, Weidong
2008-10-28 15:36           ` Han, Weidong
2008-10-28 15:47             ` Muli Ben-Yehuda
2008-10-28 15:45           ` Anthony Liguori
2008-10-28 15:53             ` Muli Ben-Yehuda
2008-10-29  7:56               ` Zhang, Xiantao
2008-10-29 10:27                 ` Muli Ben-Yehuda
2008-10-29  8:22               ` Han, Weidong
2008-10-29 10:25               ` Muli Ben-Yehuda
2008-10-29 10:39                 ` Muli Ben-Yehuda
2008-10-28 16:55           ` Mark McLoughlin
2008-10-29 10:31             ` Muli Ben-Yehuda [this message]
2008-10-29 11:07               ` Mark McLoughlin
2008-10-29 11:15               ` Mark McLoughlin
2008-10-29 11:47                 ` Muli Ben-Yehuda
2008-10-29  7:38         ` [PATCH 4/6] device assignment: build vtd.c for Intel IOMMU support Zhang, Xiantao
  -- strict thread matches above, loose matches on Subject: below --
2008-10-29 10:22 [v9] Userspace patches for PCI device assignment muli
2008-10-29 10:22 ` [PATCH 1/6] device assignment: add ioctl wrappers muli
2008-10-29 10:22   ` [PATCH 2/6] device assignment: introduce pci_map_irq to get irq nr from pin number muli
2008-10-29 10:22     ` [PATCH 3/6] device assignment: introduce functions to correlate pin number and irq muli
2008-10-29 10:22       ` [PATCH 4/6] device assignment: build vtd.c for Intel IOMMU support muli
2008-10-29 10:22         ` [PATCH 5/6] device assignment: support for assigning PCI devices to guests muli
2008-10-29 12:19 [v10] Userspace patches for PCI device assignment muli
2008-10-29 12:19 ` [PATCH 1/6] device assignment: add ioctl wrappers muli
2008-10-29 12:19   ` [PATCH 2/6] device assignment: introduce pci_map_irq to get irq nr from pin number muli
2008-10-29 12:19     ` [PATCH 3/6] device assignment: introduce functions to correlate pin number and irq muli
2008-10-29 12:19       ` [PATCH 4/6] device assignment: build vtd.c for Intel IOMMU support muli
2008-10-29 12:20         ` [PATCH 5/6] device assignment: support for assigning PCI devices to guests muli
2008-10-29 12:27           ` Mark McLoughlin
2008-10-29 14:40             ` Muli Ben-Yehuda

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=20081029103102.GQ6737@il.ibm.com \
    --to=muli@il.ibm.com \
    --cc=BENAMI@il.ibm.com \
    --cc=allen.m.kay@intel.com \
    --cc=amit.shah@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=avi@redhat.com \
    --cc=kvm@vger.kernel.org \
    --cc=markmc@redhat.com \
    --cc=weidong.han@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox