qemu: add vbus pci-device
PATCH 1/1 qemu: add vbus pci-device
Add support for shiming a userspace PCI object in qemu-kvm to represent the VBUS object located in the kernel. This presents a PCI bridge to the system using standard PCI mechanisms such as MSI interrupt routing. A guest may then optionally install a PCI driver for this bridge to gain access to the virtual-devices behind it.
This is the userspace support for the kernel VBUS project, release v3 which you can find here:
http://lkml.org/lkml/2009/4/21/408
Note that this patch uses MSIs, which has several implications:
1) This patch has a prerequisite on:
At the time of this writing, this patch has been accepted upstream into Avi's tree, but has not yet synced out to kernel.org
2) We need to surface 8 IRQ vectors on the bridge to fully represent 8 levels of priority. However, we utilize multi-MSI which may have spotty support in the guests (in fact x86 linux doesnt support multi-MSI). In these cases, the guest will only see one queue and therefore only have one flat priority. We will move to surfacing these GSIs as MSI-X in a future release to work around this issue.
---
libkvm/libkvm.c | 14 ++++ libkvm/libkvm.h | 2 + qemu/Makefile.target | 1 qemu/hw/pc.c | 5 ++ qemu/hw/pci.h | 3 + qemu/hw/vbus.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++ qemu/hw/vbus.h | 2 + 7 files changed, 183 insertions(+), 0 deletions(-) create mode 100644 qemu/hw/vbus.c create mode 100644 qemu/hw/vbus.h
libkvm/libkvm.c +14 -0
@@ -1440,3 +1440,17 @@ int kvm_assign_set_msix_entry(kvm_context_t kvm, return ret; }#endif + +int kvm_vbus_assign_gsi (kvm_context_t kvm,int queue,int gsi) +{ +int r; +struct kvm_vbus_gsi data = { + .queue = queue, + .gsi = gsi, + }; + + r =ioctl (kvm->vm_fd,KVM_VBUS_ASSIGN_GSI , &data); +if (r ==-1 ) + r = -errno; +return r; +}
libkvm/libkvm.h +2 -0
@@ -856,6 +856,8 @@ int kvm_commit_irq_routes(kvm_context_t kvm);*/ int kvm_get_irq_route_gsi (kvm_context_t kvm); +int kvm_vbus_assign_gsi (kvm_context_t kvm,int queue,int gsi); +#ifdef KVM_CAP_DEVICE_MSIX int kvm_assign_set_msix_nr (kvm_context_t kvm,struct kvm_assigned_msix_nr *msix_nr);
qemu/Makefile.target +1 -0
@@ -547,6 +547,7 @@ OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o machine.o dma-helpers.o # virtio has to be here due to weird dependency between PCI and virtio-net. # need to fix this properly OBJS+=virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-console.o +OBJS+=vbus.o OBJS+=fw_cfg.o ifdef CONFIG_KVM OBJS+=kvm.o kvm-all.o
qemu/hw/pc.c +5 -0
@@ -38,6 +38,7 @@#include "virtio-console.h" #include "hpet_emul.h" #include "device-assignment.h" +#include "vbus.h" #include "qemu-kvm.h"
@@ -1076,6 +1077,10 @@ vga_bios_error: } } +if (pci_enabled) { +pci_vbus_init (pci_bus); + } +for (i =0 ; i < nb_nics; i++) {NICInfo *nd = &nd_table[i];
qemu/hw/pci.h +3 -0
@@ -71,6 +71,9 @@ extern target_phys_addr_t pci_mem_base;#define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002#define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003 +#define PCI_VENDOR_ID_NOVELL 0x11da +#define PCI_DEVICE_ID_VIRTUAL_BUS 0x2000 +typedef void PCIConfigWriteFunc (PCIDevice *pci_dev,uint32_t address,uint32_t data,int len); typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
qemu/hw/vbus.c new file +156 -0
156 lines not on this page · raw message
qemu/hw/vbus.h new file +2 -0
@@ -0,0 +1,2 @@ + +void pci_vbus_init (PCIBus *bus);