[EMAIL PROTECTED] wrote:
> From: Muli Ben-Yehuda <[EMAIL PROTECTED]>
> 
> This patch has been contributed to by the following people:
> 
> Or Sagi <[EMAIL PROTECTED]>
> Nir Peleg <[EMAIL PROTECTED]>
> Amit Shah <[EMAIL PROTECTED]>
> Ben-Ami Yassour <[EMAIL PROTECTED]>
> Weidong Han <[EMAIL PROTECTED]>
> Glauber de Oliveira Costa <[EMAIL PROTECTED]>
> Muli Ben-Yehuda <[EMAIL PROTECTED]>
> 
> With this patch, we can assign a device on the host machine to a
> guest.
> 
> A new command-line option, -pcidevice is added.
> To invoke it for a device sitting at PCI bus:dev.fn 04:08.0, use this:
> 
>         -pcidevice host=04:08.0
> 
> * The host driver for the device, if any, is to be removed before
> assigning the device (else device assignment will fail).
> 
> * A device that shares IRQ with another host device cannot currently
> be assigned.
> 
> * The RAW_IO capability is needed for this to work
> 
> This works only with the in-kernel irqchip method; to use the
> userspace irqchip, a kernel module (irqhook) and some extra changes
> are needed.
> 
> [muli: lots of small fixes from Muli and Weidong Han addressing all v7
> review comments]
> 
> Signed-off-by: Amit Shah <[EMAIL PROTECTED]>
> Signed-off-by: Muli Ben-Yehuda <[EMAIL PROTECTED]>
> ---
>  qemu/Makefile.target        |    3 +
>  qemu/hw/device-assignment.c |  641
>  +++++++++++++++++++++++++++++++++++++++++++
>  qemu/hw/device-assignment.h |  117 ++++++++ qemu/hw/pc.c            
>  |   16 + qemu/hw/pci.c               |    7 +
>  qemu/qemu-kvm.c             |   14 +
>  qemu/qemu-kvm.h             |    8 +
>  qemu/vl.c                   |   28 ++
>  8 files changed, 834 insertions(+), 0 deletions(-)
>  create mode 100644 qemu/hw/device-assignment.c
>  create mode 100644 qemu/hw/device-assignment.h
> 
> diff --git a/qemu/Makefile.target b/qemu/Makefile.target
> index d9bdeca..5d44e08 100644
> --- a/qemu/Makefile.target
> +++ b/qemu/Makefile.target
> @@ -621,6 +621,9 @@ OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o
>  OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
>  OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
>  OBJS+= usb-uhci.o vmmouse.o vmport.o vmware_vga.o extboot.o
> +ifeq ($(USE_KVM), 1)
> +OBJS+= device-assignment.o
> +endif
>  ifeq ($(USE_KVM_PIT), 1)
>  OBJS+= i8254-kvm.o
>  endif
> diff --git a/qemu/hw/device-assignment.c b/qemu/hw/device-assignment.c
> new file mode 100644
> index 0000000..89b05f9
> --- /dev/null
> +++ b/qemu/hw/device-assignment.c
> @@ -0,0 +1,641 @@
> +/*
> + * Copyright (c) 2007, Neocleus 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. + *
> + *
> + *  Assign a PCI device from the host to a guest VM.
> + *
> + *  Adapted for KVM by Qumranet.
> + *
> + *  Copyright (c) 2007, Neocleus, Alex Novik ([EMAIL PROTECTED])
> + *  Copyright (c) 2007, Neocleus, Guy Zana ([EMAIL PROTECTED])
> + *  Copyright (C) 2008, Qumranet, Amit Shah ([EMAIL PROTECTED])
> + *  Copyright (C) 2008, Red Hat, Amit Shah ([EMAIL PROTECTED])
> + *  Copyright (C) 2008, IBM, Muli Ben-Yehuda ([EMAIL PROTECTED])
> + */
> +#include <stdio.h>
> +#include <sys/io.h>
> +#include "qemu-kvm.h"
> +#include "hw.h"
> +#include "pc.h"
> +#include "sysemu.h"
> +#include "console.h"
> +#include "device-assignment.h"
> +
> +/* From linux/ioport.h */
> +#define IORESOURCE_IO       0x00000100  /* Resource type */
> +#define IORESOURCE_MEM      0x00000200
> +#define IORESOURCE_IRQ      0x00000400
> +#define IORESOURCE_DMA      0x00000800
> +#define IORESOURCE_PREFETCH 0x00001000  /* No side effects */
> +
> +/* #define DEVICE_ASSIGNMENT_DEBUG 1 */
> +
> +#ifdef DEVICE_ASSIGNMENT_DEBUG
> +#define DEBUG(fmt, ...)                                       \
> +    do {                                                      \
> +      fprintf(stderr, "%s: " fmt, __func__ , __VA_ARGS__);    \
> +    } while (0)
> +#else
> +#define DEBUG(fmt, ...) do { } while(0)
> +#endif
> +
> +static uint32_t guest_to_host_ioport(AssignedDevRegion *region,
> uint32_t addr) +{
> +    return region->u.r_baseport + (addr - region->e_physbase);
> +}
> +
> +static void assigned_dev_ioport_writeb(void *opaque, uint32_t addr,
> +                                       uint32_t value)
> +{
> +    AssignedDevRegion *r_access = opaque;
> +    uint32_t r_pio = guest_to_host_ioport(r_access, addr);
> +
> +    DEBUG("r_pio=%08x e_physbase=%08x r_virtbase=%08lx value=%08x\n",
> +       r_pio, (int)r_access->e_physbase,
> +       (unsigned long)r_access->r_virtbase, value);

should be (unsigned long)r_access->u.r_virtbase

> +
> +    outb(value, r_pio);
> +}
> +
> +static void assigned_dev_ioport_writew(void *opaque, uint32_t addr,
> +                                       uint32_t value)
> +{
> +    AssignedDevRegion *r_access = opaque;
> +    uint32_t r_pio = guest_to_host_ioport(r_access, addr);
> +
> +    DEBUG("r_pio=%08x e_physbase=%08x r_virtbase=%08lx value=%08x\n",
> +          __func__, r_pio, (int)r_access->e_physbase,
> +          (unsigned long)r_access->r_virtbase, value);

(unsigned long)r_access->u.r_virtbase

> +
> +    outw(value, r_pio);
> +}
> +
> +static void assigned_dev_ioport_writel(void *opaque, uint32_t addr,
> +                       uint32_t value)
> +{
> +    AssignedDevRegion *r_access = opaque;
> +    uint32_t r_pio = guest_to_host_ioport(r_access, addr);
> +
> +    DEBUG("%s: r_pio=%08x e_physbase=%08x r_virtbase=%08lx
> value=%08x\n", +        r_pio, (int)r_access->e_physbase,
> +          (unsigned long)r_access->r_virtbase, value);

(unsigned long)r_access->u.r_virtbase

> +
> +    outl(value, r_pio);
> +}
> +
> +static uint32_t assigned_dev_ioport_readb(void *opaque, uint32_t
> addr) +{
> +    AssignedDevRegion *r_access = opaque;
> +    uint32_t r_pio = guest_to_host_ioport(r_access, addr);
> +    uint32_t value;
> +
> +    value = inb(r_pio);
> +
> +    DEBUG("r_pio=%08x e_physbase=%08x r_virtbase=%08lx value=%08x\n",
> +          r_pio, (int)r_access->e_physbase,
> +          (unsigned long)r_access->r_virtbase, value);

(unsigned long)r_access->u.r_virtbase

> +
> +    return value;
> +}
> +
> +static uint32_t assigned_dev_ioport_readw(void *opaque, uint32_t
> addr) +{
> +    AssignedDevRegion *r_access = opaque;
> +    uint32_t r_pio = guest_to_host_ioport(r_access, addr);
> +    uint32_t value;
> +
> +    value = inw(r_pio);
> +
> +    DEBUG("r_pio=%08x e_physbase=%08x r_virtbase=%08lx value=%08x\n",
> +          r_pio, (int)r_access->e_physbase,
> +       (unsigned long)r_access->r_virtbase, value);

(unsigned long)r_access->u.r_virtbase

> +
> +    return value;
> +}
> +
> +static uint32_t assigned_dev_ioport_readl(void *opaque, uint32_t
> addr) +{
> +    AssignedDevRegion *r_access = opaque;
> +    uint32_t r_pio = guest_to_host_ioport(r_access, addr);
> +    uint32_t value;
> +
> +    value = inl(r_pio);
> +
> +    DEBUG("r_pio=%08x e_physbase=%08x r_virtbase=%08lx value=%08x\n",
> +          r_pio, (int)r_access->e_physbase,
> +          (unsigned long)r_access->r_virtbase, value);

(unsigned long)r_access->u.r_virtbase

> +
> +    return value;
> +}
> +
> +static void assigned_dev_iomem_map(PCIDevice *pci_dev, int
> region_num, +                                   uint32_t e_phys,
> uint32_t e_size, int type) +{
> +    AssignedDevice *r_dev = (AssignedDevice *) pci_dev;
> +    AssignedDevRegion *region = &r_dev->v_addrs[region_num];
> +    uint32_t old_ephys = region->e_physbase;
> +    uint32_t old_esize = region->e_size;
> +    int first_map = (region->e_size == 0);
> +    int ret = 0;
> +
> +    DEBUG("e_phys=%08x r_virt=%x type=%d len=%08x region_num=%d \n",
> +          e_phys, (uint32_t)region->r_virtbase, type, e_size,

(uint32_t)r_access->u.r_virtbase

Regards,
Weidong

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to