mirror of https://gitee.com/openkylin/qemu.git
VFIO updates 2015-11-10
- Make Windows happy with vfio-pci devices exposed on conventional PCI buses on q35 by hiding PCIe capability (Alex Williamson) - Convert to g_new() where appropriate (Markus Armbruster) -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWQkmhAAoJECObm247sIsizL0P+wSaFCeng85KNmzp6LWoqg8P /qqwokR32HdJ5NeLXQd1k6inEvI8Toz0K4ZUgOehscGAh8fJTj2MMhdk1B3vueCF g/gnW2EKxDfbJSqEG1+erOrIAyn1SPjZH1hm0jCcpTvXtjM81mIpiRRNaQ0XWLSp YdRvf8p6q/cjF4f5JAUVPA8ZIl1r1ZN3FbCMJt2xYKK4cZbhNAs4M1khfrpGXzHX 1RJkZx1x+phE604cplSDuVGHtacfHefX4D2qkYIXgeUQ+8stR2xx7dm5S30Q16Y+ u91TMmwcTo5kzHmxXmGur6UcO9dJax6hk2ENudr7qZAIwJPjyH2qBOznCwa1y9+q eK3gxrVsGyno0+t10XL8nauXP1CUYHm9M1d6uhii/o5eBtWHIofYQVtjotmqMKHQ kwDK8v06R+jlEIxhjMhn1qBf8+q50C1Z/7s5qTqRPNFZ9jurQA3OtvdC+3psIzHj ra70M4skvRKBEE82f0AoMT2ehEaYMEtMYlCpzOSo5OME+JmJIbCxvLzWO8XQs0im RYRc+ZszeGaaP2j+IqWzSdz+sCIlboQaqtqNW2REGB/ADHbBO2dD4OEQ5ZiA8Ze9 ZtXXEMW/BcwP1wkldj007YBTHHyU6eAmRNEBMp1A58BIlDyM2O8tHg0ICLLH6SCS MgaXsfeSVnwNt/bA86XV =qJ77 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20151110.0' into staging VFIO updates 2015-11-10 - Make Windows happy with vfio-pci devices exposed on conventional PCI buses on q35 by hiding PCIe capability (Alex Williamson) - Convert to g_new() where appropriate (Markus Armbruster) # gpg: Signature made Tue 10 Nov 2015 19:46:41 GMT using RSA key ID 3BB08B22 # gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>" # gpg: aka "Alex Williamson <alex@shazbot.org>" # gpg: aka "Alex Williamson <alwillia@redhat.com>" # gpg: aka "Alex Williamson <alex.l.williamson@gmail.com>" * remotes/awilliam/tags/vfio-update-20151110.0: vfio: Use g_new() & friends where that makes obvious sense vfio/pci: Hide device PCIe capability on non-express buses for PCIe VMs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d93ae5b696
|
@ -284,7 +284,7 @@ static void vfio_vga_probe_ati_3c3_quirk(VFIOPCIDevice *vdev)
|
|||
}
|
||||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
quirk->mem = g_malloc0(sizeof(MemoryRegion));
|
||||
quirk->mem = g_new0(MemoryRegion, 1);
|
||||
quirk->nr_mem = 1;
|
||||
|
||||
memory_region_init_io(quirk->mem, OBJECT(vdev), &vfio_ati_3c3_quirk, vdev,
|
||||
|
@ -319,7 +319,7 @@ static void vfio_probe_ati_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
}
|
||||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
quirk->mem = g_malloc0(sizeof(MemoryRegion) * 2);
|
||||
quirk->mem = g_new0(MemoryRegion, 2);
|
||||
quirk->nr_mem = 2;
|
||||
window = quirk->data = g_malloc0(sizeof(*window) +
|
||||
sizeof(VFIOConfigWindowMatch));
|
||||
|
@ -368,7 +368,7 @@ static void vfio_probe_ati_bar2_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
mirror = quirk->data = g_malloc0(sizeof(*mirror));
|
||||
mirror->mem = quirk->mem = g_malloc0(sizeof(MemoryRegion));
|
||||
mirror->mem = quirk->mem = g_new0(MemoryRegion, 1);
|
||||
quirk->nr_mem = 1;
|
||||
mirror->vdev = vdev;
|
||||
mirror->offset = 0x4000;
|
||||
|
@ -544,7 +544,7 @@ static void vfio_vga_probe_nvidia_3d0_quirk(VFIOPCIDevice *vdev)
|
|||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
quirk->data = data = g_malloc0(sizeof(*data));
|
||||
quirk->mem = g_malloc0(sizeof(MemoryRegion) * 2);
|
||||
quirk->mem = g_new0(MemoryRegion, 2);
|
||||
quirk->nr_mem = 2;
|
||||
data->vdev = vdev;
|
||||
|
||||
|
@ -661,7 +661,7 @@ static void vfio_probe_nvidia_bar5_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
}
|
||||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
quirk->mem = g_malloc0(sizeof(MemoryRegion) * 4);
|
||||
quirk->mem = g_new0(MemoryRegion, 4);
|
||||
quirk->nr_mem = 4;
|
||||
bar5 = quirk->data = g_malloc0(sizeof(*bar5) +
|
||||
(sizeof(VFIOConfigWindowMatch) * 2));
|
||||
|
@ -756,7 +756,7 @@ static void vfio_probe_nvidia_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
mirror = quirk->data = g_malloc0(sizeof(*mirror));
|
||||
mirror->mem = quirk->mem = g_malloc0(sizeof(MemoryRegion));
|
||||
mirror->mem = quirk->mem = g_new0(MemoryRegion, 1);
|
||||
quirk->nr_mem = 1;
|
||||
mirror->vdev = vdev;
|
||||
mirror->offset = 0x88000;
|
||||
|
@ -775,7 +775,7 @@ static void vfio_probe_nvidia_bar0_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
if (vdev->has_vga) {
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
mirror = quirk->data = g_malloc0(sizeof(*mirror));
|
||||
mirror->mem = quirk->mem = g_malloc0(sizeof(MemoryRegion));
|
||||
mirror->mem = quirk->mem = g_new0(MemoryRegion, 1);
|
||||
quirk->nr_mem = 1;
|
||||
mirror->vdev = vdev;
|
||||
mirror->offset = 0x1800;
|
||||
|
@ -938,7 +938,7 @@ static void vfio_probe_rtl8168_bar2_quirk(VFIOPCIDevice *vdev, int nr)
|
|||
}
|
||||
|
||||
quirk = g_malloc0(sizeof(*quirk));
|
||||
quirk->mem = g_malloc0(sizeof(MemoryRegion) * 2);
|
||||
quirk->mem = g_new0(MemoryRegion, 2);
|
||||
quirk->nr_mem = 2;
|
||||
quirk->data = rtl = g_malloc0(sizeof(*rtl));
|
||||
rtl->vdev = vdev;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "config.h"
|
||||
#include "hw/pci/msi.h"
|
||||
#include "hw/pci/msix.h"
|
||||
#include "hw/pci/pci_bridge.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/range.h"
|
||||
#include "sysemu/kvm.h"
|
||||
|
@ -586,7 +587,7 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev)
|
|||
{
|
||||
vfio_disable_interrupts(vdev);
|
||||
|
||||
vdev->msi_vectors = g_malloc0(vdev->msix->entries * sizeof(VFIOMSIVector));
|
||||
vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->msix->entries);
|
||||
|
||||
vdev->interrupt = VFIO_INT_MSIX;
|
||||
|
||||
|
@ -622,7 +623,7 @@ static void vfio_msi_enable(VFIOPCIDevice *vdev)
|
|||
|
||||
vdev->nr_vectors = msi_nr_vectors_allocated(&vdev->pdev);
|
||||
retry:
|
||||
vdev->msi_vectors = g_malloc0(vdev->nr_vectors * sizeof(VFIOMSIVector));
|
||||
vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->nr_vectors);
|
||||
|
||||
for (i = 0; i < vdev->nr_vectors; i++) {
|
||||
VFIOMSIVector *vector = &vdev->msi_vectors[i];
|
||||
|
@ -1524,13 +1525,38 @@ static int vfio_setup_pcie_cap(VFIOPCIDevice *vdev, int pos, uint8_t size)
|
|||
}
|
||||
|
||||
if (!pci_bus_is_express(vdev->pdev.bus)) {
|
||||
PCIBus *bus = vdev->pdev.bus;
|
||||
PCIDevice *bridge;
|
||||
|
||||
/*
|
||||
* Use express capability as-is on PCI bus. It doesn't make much
|
||||
* sense to even expose, but some drivers (ex. tg3) depend on it
|
||||
* and guests don't seem to be particular about it. We'll need
|
||||
* to revist this or force express devices to express buses if we
|
||||
* ever expose an IOMMU to the guest.
|
||||
* Traditionally PCI device assignment exposes the PCIe capability
|
||||
* as-is on non-express buses. The reason being that some drivers
|
||||
* simply assume that it's there, for example tg3. However when
|
||||
* we're running on a native PCIe machine type, like Q35, we need
|
||||
* to hide the PCIe capability. The reason for this is twofold;
|
||||
* first Windows guests get a Code 10 error when the PCIe capability
|
||||
* is exposed in this configuration. Therefore express devices won't
|
||||
* work at all unless they're attached to express buses in the VM.
|
||||
* Second, a native PCIe machine introduces the possibility of fine
|
||||
* granularity IOMMUs supporting both translation and isolation.
|
||||
* Guest code to discover the IOMMU visibility of a device, such as
|
||||
* IOMMU grouping code on Linux, is very aware of device types and
|
||||
* valid transitions between bus types. An express device on a non-
|
||||
* express bus is not a valid combination on bare metal systems.
|
||||
*
|
||||
* Drivers that require a PCIe capability to make the device
|
||||
* functional are simply going to need to have their devices placed
|
||||
* on a PCIe bus in the VM.
|
||||
*/
|
||||
while (!pci_bus_is_root(bus)) {
|
||||
bridge = pci_bridge_get_device(bus);
|
||||
bus = bridge->bus;
|
||||
}
|
||||
|
||||
if (pci_bus_is_express(bus)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if (pci_bus_is_root(vdev->pdev.bus)) {
|
||||
/*
|
||||
* On a Root Complex bus Endpoints become Root Complex Integrated
|
||||
|
|
|
@ -478,7 +478,7 @@ static int vfio_populate_device(VFIODevice *vbasedev)
|
|||
struct vfio_region_info reg_info = { .argsz = sizeof(reg_info) };
|
||||
VFIORegion *ptr;
|
||||
|
||||
vdev->regions[i] = g_malloc0(sizeof(VFIORegion));
|
||||
vdev->regions[i] = g_new0(VFIORegion, 1);
|
||||
ptr = vdev->regions[i];
|
||||
reg_info.index = i;
|
||||
ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, ®_info);
|
||||
|
|
Loading…
Reference in New Issue