Seems it lacks device-assignment.[c,h] ?
Xiantao

Amit Shah wrote:
> [This still doesn't include some fixes to review comments.
> I'm posting this just so that people can use this to test
> or base their work off the latest patch.]
> 
> From: Or Sagi <[EMAIL PROTECTED]>
> From: Nir Peleg <[EMAIL PROTECTED]>
> From: Amit Shah <[EMAIL PROTECTED]>
> From: Ben-Ami Yassour <[EMAIL PROTECTED]>
> From: Glauber de Oliveira Costa <[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.
> For example, to invoke it for a device sitting at PCI bus:dev.fn
> 04:08.0 with host IRQ 18, use this:
> 
>         -pcidevice host=04:08.0
> 
> The host driver for the device, if any, is to be removed before
> assigning the device.
> 
> This works only with the in-kernel irqchip method; to use the
> userspace irqchip, a kernel module (irqhook) and some extra changes
> are needed.
> 
> Signed-off-by: Amit Shah <[EMAIL PROTECTED]>
> ---
>  libkvm/libkvm-x86.c  |   14 ++++++++++++++
>  libkvm/libkvm.h      |   27 +++++++++++++++++++++++++++
>  qemu/Makefile.target |    1 +
>  qemu/hw/isa.h        |    2 ++
>  qemu/hw/pc.c         |    9 +++++++++
>  qemu/hw/pci.c        |   12 ++++++++++++
>  qemu/hw/pci.h        |    1 +
>  qemu/hw/piix_pci.c   |   19 +++++++++++++++++++
>  qemu/qemu-kvm-x86.c  |    3 +++
>  qemu/vl.c            |   18 ++++++++++++++++++
>  10 files changed, 106 insertions(+), 0 deletions(-)
> 
> diff --git a/libkvm/libkvm-x86.c b/libkvm/libkvm-x86.c
> index a8cca15..6157f75 100644
> --- a/libkvm/libkvm-x86.c
> +++ b/libkvm/libkvm-x86.c
> @@ -53,6 +53,20 @@ static int kvm_init_tss(kvm_context_t kvm)
>       return 0;
>  }
> 
> +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> +int kvm_assign_pci_device(kvm_context_t kvm,
> +                       struct kvm_assigned_pci_dev *assigned_dev)
> +{
> +     return ioctl(kvm->vm_fd, KVM_ASSIGN_PCI_DEVICE, assigned_dev);
> +}
> +
> +int kvm_assign_irq(kvm_context_t kvm,
> +                struct kvm_assigned_irq *assigned_irq)
> +{
> +     return ioctl(kvm->vm_fd, KVM_ASSIGN_IRQ, assigned_irq);
> +}
> +#endif
> +
>  int kvm_create_pit(kvm_context_t kvm)
>  {
>  #ifdef KVM_CAP_PIT
> diff --git a/libkvm/libkvm.h b/libkvm/libkvm.h
> index 79dd769..edf8e9e 100644
> --- a/libkvm/libkvm.h
> +++ b/libkvm/libkvm.h
> @@ -658,4 +658,31 @@ int kvm_s390_interrupt(kvm_context_t kvm, int
>  slot, int kvm_s390_set_initial_psw(kvm_context_t kvm, int slot,
>  psw_t psw); int kvm_s390_store_status(kvm_context_t kvm, int slot,
>  unsigned long addr); #endif
> +
> +#ifdef KVM_CAP_DEVICE_ASSIGNMENT
> +/*!
> + * \brief Notifies host kernel aboud a PCI device assigned to guest
> + *
> + * Used for PCI device assignment, this function notifies the host
> + * kernel about the assigning of the physical PCI device.
> + *
> + * \param kvm Pointer to the current kvm_context
> + * \param assigned_dev Parameters, like bus, devfn number, etc
> + */
> +int kvm_assign_pci_device(kvm_context_t kvm,
> +                       struct kvm_assigned_pci_dev *assigned_dev);
> +
> +/*!
> + * \brief Notifies host kernel about changes to a irq assignment
> + *
> + * Used for PCI device assignment, this function notifies the host
> + * kernel about the assigning of the irq for an assigned physical
> + * PCI device.
> + *
> + * \param kvm Pointer to the current kvm_context
> + * \param assigned_irq Parameters, like dev id, host irq, guest irq,
> etc + */
> +int kvm_assign_irq(kvm_context_t kvm,
> +                struct kvm_assigned_irq *assigned_irq);
> +#endif
>  #endif
> diff --git a/qemu/Makefile.target b/qemu/Makefile.target
> index 89814fd..958c33b 100644
> --- a/qemu/Makefile.target
> +++ b/qemu/Makefile.target
> @@ -611,6 +611,7 @@ 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
> +OBJS+= device-assignment.o
>  ifeq ($(USE_KVM_PIT), 1)
>  OBJS+= i8254-kvm.o
>  endif
> diff --git a/qemu/hw/isa.h b/qemu/hw/isa.h
> index 89b3004..c720f5e 100644
> --- a/qemu/hw/isa.h
> +++ b/qemu/hw/isa.h
> @@ -1,5 +1,7 @@
>  /* ISA bus */
> 
> +#include "hw.h"
> +
>  extern target_phys_addr_t isa_mem_base;
> 
>  int register_ioport_read(int start, int length, int size,
> diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
> index 8a50096..59c2098 100644
> --- a/qemu/hw/pc.c
> +++ b/qemu/hw/pc.c
> @@ -32,6 +32,7 @@
>  #include "smbus.h"
>  #include "boards.h"
>  #include "console.h"
> +#include "device-assignment.h"
> 
>  #include "qemu-kvm.h"
> 
> @@ -1013,6 +1014,14 @@ static void pc_init1(ram_addr_t ram_size, int
>          vga_ram_size, }
>      }
> 
> +    /* Initialize assigned devices */
> +    if (pci_enabled) {
> +        int r = -1;
> +        do {
> +            init_assigned_device(pci_bus, &r);
> +     } while (r >= 0);
> +    }
> +
>      rtc_state = rtc_init(0x70, i8259[8]);
> 
>      qemu_register_boot_set(pc_boot_set, rtc_state);
> diff --git a/qemu/hw/pci.c b/qemu/hw/pci.c
> index 07d37a8..e4e8386 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
> +
>      end = address + len;
>      if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) {
>          /* if the command register is modified, we must modify the
> mappings */ @@ -560,6 +567,11 @@ static void pci_set_irq(void
>      *opaque, int irq_num, int level) bus->set_irq(bus->irq_opaque,
>  irq_num, bus->irq_count[irq_num] != 0); }
> 
> +int pci_map_irq(PCIDevice *pci_dev, int pin)
> +{
> +     return pci_dev->bus->map_irq(pci_dev, pin);
> +}
> +
>  /***********************************************************/
>  /* monitor info on PCI */
> 
> diff --git a/qemu/hw/pci.h b/qemu/hw/pci.h
> index 60e4094..e11fbbf 100644
> --- a/qemu/hw/pci.h
> +++ b/qemu/hw/pci.h
> @@ -81,6 +81,7 @@ void pci_register_io_region(PCIDevice *pci_dev, int
>                              region_num, uint32_t size, int type,
>                              PCIMapIORegionFunc *map_func);
> 
> +int pci_map_irq(PCIDevice *pci_dev, int pin);
>  uint32_t pci_default_read_config(PCIDevice *d,
>                                   uint32_t address, int len);
>  void pci_default_write_config(PCIDevice *d,
> diff --git a/qemu/hw/piix_pci.c b/qemu/hw/piix_pci.c
> index 6fbf47b..dc12c8a 100644
> --- a/qemu/hw/piix_pci.c
> +++ b/qemu/hw/piix_pci.c
> @@ -243,6 +243,25 @@ static void piix3_set_irq(qemu_irq *pic, int
>      irq_num, int level) }
>  }
> 
> +int piix3_get_pin(int pic_irq)
> +{
> +    int i;
> +    for (i = 0; i < 4; i++)
> +        if (piix3_dev->config[0x60+i] == pic_irq)
> +            return i;
> +    return -1;
> +}
> +
> +int piix_get_irq(int pin)
> +{
> +    if (piix3_dev)
> +        return piix3_dev->config[0x60+pin];
> +    if (piix4_dev)
> +        return piix4_dev->config[0x60+pin];
> +
> +    return 0;
> +}
> +
>  static void piix3_reset(PCIDevice *d)
>  {
>      uint8_t *pci_conf = d->config;
> diff --git a/qemu/qemu-kvm-x86.c b/qemu/qemu-kvm-x86.c
> index 5daedd1..5123e52 100644
> --- a/qemu/qemu-kvm-x86.c
> +++ b/qemu/qemu-kvm-x86.c
> @@ -530,6 +530,9 @@ struct kvm_para_features {
>  #ifdef KVM_CAP_CR3_CACHE
>       { KVM_CAP_CR3_CACHE, KVM_FEATURE_CR3_CACHE },
>  #endif
> +#ifdef KVM_CAP_PV_DMA
> +     { KVM_CAP_PV_DMA, KVM_FEATURE_DMA_OP },
> +#endif
>       { -1, -1 }
>  };
> 
> diff --git a/qemu/vl.c b/qemu/vl.c
> index 022b3b8..bab720d 100644
> --- a/qemu/vl.c
> +++ b/qemu/vl.c
> @@ -37,6 +37,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"
> @@ -8478,6 +8479,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)
> +        "-pcidevice host=bus:dev.func[,dma=none][,name=\"string\"]\n"
> +        "                expose a PCI device to the guest OS.\n"
> +        "                dma=none: don't perform any dma translations
> (default is to use an iommu)\n" +        "                'string' is
> used in log output.\n" +#endif
>  #endif
>  #ifdef TARGET_I386
>             "-std-vga        simulate a standard VGA card with VESA
> Bochs Extensions\n" @@ -8601,6 +8608,9 @@ enum {
>      QEMU_OPTION_no_kvm,
>      QEMU_OPTION_no_kvm_irqchip,
>      QEMU_OPTION_no_kvm_pit,
> +#if defined(TARGET_I386) || defined(TARGET_X86_64)
> +    QEMU_OPTION_pcidevice,
> +#endif
>      QEMU_OPTION_no_reboot,
>      QEMU_OPTION_no_shutdown,
>      QEMU_OPTION_show_cursor,
> @@ -8689,6 +8699,9 @@ const QEMUOption qemu_options[] = {
>  #endif
>      { "no-kvm-irqchip", 0, QEMU_OPTION_no_kvm_irqchip },
>      { "no-kvm-pit", 0, QEMU_OPTION_no_kvm_pit },
> +#if defined(TARGET_I386) || defined(TARGET_X86_64)
> +    { "pcidevice", HAS_ARG, QEMU_OPTION_pcidevice },
> +#endif
>  #endif
>  #if defined(TARGET_PPC) || defined(TARGET_SPARC)
>      { "g", 1, QEMU_OPTION_g },
> @@ -9595,6 +9608,11 @@ int main(int argc, char **argv)
>               kvm_pit = 0;
>               break;
>           }
> +#if defined(TARGET_I386) || defined(TARGET_X86_64)
> +         case QEMU_OPTION_pcidevice:
> +             add_assigned_device(optarg);
> +             break;
> +#endif
>  #endif
>              case QEMU_OPTION_usb:
>                  usb_enabled = 1;
> --
> 1.5.4.3

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