All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark McLoughlin <markmc@redhat.com>
To: muli@il.ibm.com
Cc: avi@redhat.com, kvm@vger.kernel.org, anthony@codemonkey.ws,
	weidong.han@intel.com, 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: Tue, 28 Oct 2008 16:55:22 +0000	[thread overview]
Message-ID: <1225212922.11515.85.camel@blaa> (raw)
In-Reply-To: <1225188410-2222-6-git-send-email-muli@il.ibm.com>

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;

> +        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()

> +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() ?

> +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]

> + *
> + * 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.

> +    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?

> +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.

> +#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.

> +	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)

> +
>      end = address + len;
>      if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
>          /* if the command register is modified, we must modify the mappings */
> diff --git a/qemu/qemu-kvm.c b/qemu/qemu-kvm.c
> index c5f3f29..5e66832 100644
> --- a/qemu/qemu-kvm.c
> +++ b/qemu/qemu-kvm.c
> @@ -20,6 +20,7 @@ int kvm_pit = 1;
>  #include "console.h"
>  #include "block.h"
>  #include "compatfd.h"
> +#include "hw/device-assignment.h"
>  
>  #include "qemu-kvm.h"
>  #include <libkvm.h>
> @@ -27,6 +28,7 @@ int kvm_pit = 1;
>  #include <sys/utsname.h>
>  #include <sys/syscall.h>
>  #include <sys/mman.h>
> +#include <sys/io.h>
>  
>  #define bool _Bool
>  #define false 0
> @@ -1047,3 +1049,15 @@ int qemu_kvm_unregister_coalesced_mmio(target_phys_addr_t addr,
>  {
>      return kvm_unregister_coalesced_mmio(kvm_context, addr, size);
>  }
> +
> +static void kvm_do_ioperm(void *_data)
> +{
> +	struct ioperm_data *data = _data;
> +	ioperm(data->start_port, data->num, data->turn_on);
> +}
> +
> +void kvm_ioperm(CPUState *env, void *data)
> +{
> +	if (kvm_enabled() && qemu_system_ready)
> +		on_vcpu(env, kvm_do_ioperm, data);
> +}
> diff --git a/qemu/qemu-kvm.h b/qemu/qemu-kvm.h
> index a1d6646..92d921d 100644
> --- a/qemu/qemu-kvm.h
> +++ b/qemu/qemu-kvm.h
> @@ -93,6 +93,8 @@ int qemu_kvm_unregister_coalesced_mmio(target_phys_addr_t addr,
>  
>  void qemu_kvm_system_reset_request(void);
>  
> +void kvm_ioperm(CPUState *env, void *data);
> +
>  #ifdef TARGET_PPC
>  int handle_powerpc_dcr_read(int vcpu, uint32_t dcrn, uint32_t *data);
>  int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data);
> @@ -107,6 +109,12 @@ int handle_powerpc_dcr_write(int vcpu,uint32_t dcrn, uint32_t data);
>  extern int kvm_allowed;
>  extern kvm_context_t kvm_context;
>  
> +struct ioperm_data {
> +	unsigned long start_port;
> +	unsigned long num;
> +	int turn_on;
> +};
> +
>  #define kvm_enabled() (kvm_allowed)
>  #define qemu_kvm_irqchip_in_kernel() kvm_irqchip_in_kernel(kvm_context)
>  #define qemu_kvm_pit_in_kernel() kvm_pit_in_kernel(kvm_context)
> diff --git a/qemu/vl.c b/qemu/vl.c
> index 388e79d..9dda2f9 100644
> --- a/qemu/vl.c
> +++ b/qemu/vl.c
> @@ -38,6 +38,7 @@
>  #include "qemu-char.h"
>  #include "block.h"
>  #include "audio/audio.h"
> +#include "hw/device-assignment.h"
>  #include "migration.h"
>  #include "balloon.h"
>  #include "qemu-kvm.h"
> @@ -215,6 +216,9 @@ CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
>  int win2k_install_hack = 0;
>  #endif
>  int usb_enabled = 0;
> +int device_assignment_enabled = 0;
> +const char *assigned_devices[MAX_DEV_ASSIGN_CMDLINE];
> +int assigned_devices_index;
>  static VLANState *first_vlan;
>  int smp_cpus = 1;
>  const char *vnc_display;
> @@ -8692,6 +8696,12 @@ static void help(int exitcode)
>  #endif
>  	   "-no-kvm-irqchip disable KVM kernel mode PIC/IOAPIC/LAPIC\n"
>  	   "-no-kvm-pit	    disable KVM kernel mode PIT\n"
> +#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(__linux__)
> +           "-pcidevice host=bus:dev.func[,dma=none][,name=\"string\"]\n"

name="string" isn't correct, is it? e.g. this won't work

  -pcidevice host=04:08.0,name="Foo Bar"

but this will:

  -pcidevice "host=04:08.0,name=Foo Bar"

...

Cheers,
Mark.


  parent reply	other threads:[~2008-10-28 17:00 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 [this message]
2008-10-29 10:31             ` Muli Ben-Yehuda
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=1225212922.11515.85.camel@blaa \
    --to=markmc@redhat.com \
    --cc=allen.m.kay@intel.com \
    --cc=amit.shah@redhat.com \
    --cc=anthony@codemonkey.ws \
    --cc=avi@redhat.com \
    --cc=benami@il.ibm.com \
    --cc=kvm@vger.kernel.org \
    --cc=muli@il.ibm.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 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.