mirror of https://github.com/xemu-project/xemu.git
VFIO updates 2017-02-23
- Report qdev_unplug errors (Alex Williamson) - Fix ecap ID 0 handling, improve comment (Alex Williamson) - Disable IGD stolen memory in UPT mode too (Xiong Zhang) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJYrzIxAAoJECObm247sIsiqAEQAJjhWb9dpgiKwQzBJmNQ2LTU MBXD78SyNlR8T6wnZI42hNVYMFIdQY5bt926K7VSBlwMno0HiAy5IRJ49Sb1+2CI dopKKEqThLfZf8UR8FBYf/IAcewMIEabeggXW52ufXE9VP6iMeOcgO2/WZSc6ldz ui3wv3vq7ZO/Zwm/PDkOKz+onmBavEbWnfhUve06h9cqeuYCFtK0gOR/6mSp+ytU qabTYtc4SNueHJYT0BONN8GE/g0FzOwzDuM1nsVN0HfC7fwrPnuROQeR/9QRRncu Dtpet9pOEUwCGNpNj5gdCP8DCFabZ1XuGVau6yBpbcKYBDTlKeUDowoCo6Ca+5HT N9Tgc/Z+yJL/j2fJ40a5c1A0OtdF/v3UC7LcJXs1sKVRoC9VAm/CyWL/8dWHh6AZ CE2gVDkwaYIMhl1rgUoxfftgYYxpvh+Szk1N0bh5sFiLyiCUQmqhBPzGotke1+A3 L5C3N9fbjTYvUmjJVMQRQoFXwE8nTQvywkEZjJelNYDgQb/lfeIHrxpDQcLKL3k+ J/ZVVCR5bBWWZmTRLaqxI5SF+GVUVUTOmWEsva5Lqki+p282/JQjIL8wo3qMZHJg h+hmXMqxlG8HR1HP9S/3A2NoiH++0Bz3NCeBwu4xweQLG6PoXwA5sNsmGsG5gtfg QpMuO91IoipA7v6kF9w6 =Uh+q -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20170223.0' into staging VFIO updates 2017-02-23 - Report qdev_unplug errors (Alex Williamson) - Fix ecap ID 0 handling, improve comment (Alex Williamson) - Disable IGD stolen memory in UPT mode too (Xiong Zhang) # gpg: Signature made Thu 23 Feb 2017 19:04:17 GMT # gpg: using RSA key 0x239B9B6E3BB08B22 # 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>" # Primary key fingerprint: 42F6 C04E 540B D1A9 9E7B 8A90 239B 9B6E 3BB0 8B22 * remotes/awilliam/tags/vfio-updates-20170223.0: vfio/pci-quirks.c: Disable stolen memory for igd VFIO vfio/pci: Improve extended capability comments, skip masked caps vfio/pci: Report errors from qdev_unplug() via device request Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
6959e4523e
|
@ -1367,14 +1367,45 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
uint16_t cmd_orig, cmd;
|
uint16_t cmd_orig, cmd;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
/*
|
/* This must be an Intel VGA device. */
|
||||||
* This must be an Intel VGA device at address 00:02.0 for us to even
|
|
||||||
* consider enabling legacy mode. The vBIOS has dependencies on the
|
|
||||||
* PCI bus address.
|
|
||||||
*/
|
|
||||||
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
|
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) ||
|
||||||
!vfio_is_vga(vdev) || nr != 4 ||
|
!vfio_is_vga(vdev) || nr != 4) {
|
||||||
&vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* IGD is not a standard, they like to change their specs often. We
|
||||||
|
* only attempt to support back to SandBridge and we hope that newer
|
||||||
|
* devices maintain compatibility with generation 8.
|
||||||
|
*/
|
||||||
|
gen = igd_gen(vdev);
|
||||||
|
if (gen != 6 && gen != 8) {
|
||||||
|
error_report("IGD device %s is unsupported by IGD quirks, "
|
||||||
|
"try SandyBridge or newer", vdev->vbasedev.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Regardless of running in UPT or legacy mode, the guest graphics
|
||||||
|
* driver may attempt to use stolen memory, however only legacy mode
|
||||||
|
* has BIOS support for reserving stolen memory in the guest VM.
|
||||||
|
* Emulate the GMCH register in all cases and zero out the stolen
|
||||||
|
* memory size here. Legacy mode may request allocation and re-write
|
||||||
|
* this below.
|
||||||
|
*/
|
||||||
|
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
|
||||||
|
gmch &= ~((gen < 8 ? 0x1f : 0xff) << (gen < 8 ? 3 : 8));
|
||||||
|
|
||||||
|
/* GMCH is read-only, emulated */
|
||||||
|
pci_set_long(vdev->pdev.config + IGD_GMCH, gmch);
|
||||||
|
pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0);
|
||||||
|
pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This must be at address 00:02.0 for us to even onsider enabling
|
||||||
|
* legacy mode. The vBIOS has dependencies on the PCI bus address.
|
||||||
|
*/
|
||||||
|
if (&vdev->pdev != pci_find_device(pci_device_root_bus(&vdev->pdev),
|
||||||
0, PCI_DEVFN(0x2, 0))) {
|
0, PCI_DEVFN(0x2, 0))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1393,18 +1424,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* IGD is not a standard, they like to change their specs often. We
|
|
||||||
* only attempt to support back to SandBridge and we hope that newer
|
|
||||||
* devices maintain compatibility with generation 8.
|
|
||||||
*/
|
|
||||||
gen = igd_gen(vdev);
|
|
||||||
if (gen != 6 && gen != 8) {
|
|
||||||
error_report("IGD device %s is unsupported in legacy mode, "
|
|
||||||
"try SandyBridge or newer", vdev->vbasedev.name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Most of what we're doing here is to enable the ROM to run, so if
|
* Most of what we're doing here is to enable the ROM to run, so if
|
||||||
* there's no ROM, there's no point in setting up this quirk.
|
* there's no ROM, there's no point in setting up this quirk.
|
||||||
|
@ -1460,8 +1479,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If IGD VGA Disable is clear (expected) and VGA is not already enabled,
|
* If IGD VGA Disable is clear (expected) and VGA is not already enabled,
|
||||||
* try to enable it. Probably shouldn't be using legacy mode without VGA,
|
* try to enable it. Probably shouldn't be using legacy mode without VGA,
|
||||||
|
@ -1532,12 +1549,11 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
* when IVD (IGD VGA Disable) is clear, but the claim is that it's unused,
|
* when IVD (IGD VGA Disable) is clear, but the claim is that it's unused,
|
||||||
* so let's not waste VM memory for it.
|
* so let's not waste VM memory for it.
|
||||||
*/
|
*/
|
||||||
gmch &= ~((gen < 8 ? 0x1f : 0xff) << (gen < 8 ? 3 : 8));
|
|
||||||
|
|
||||||
if (vdev->igd_gms) {
|
if (vdev->igd_gms) {
|
||||||
if (vdev->igd_gms <= 0x10) {
|
if (vdev->igd_gms <= 0x10) {
|
||||||
gms_mb = vdev->igd_gms * 32;
|
gms_mb = vdev->igd_gms * 32;
|
||||||
gmch |= vdev->igd_gms << (gen < 8 ? 3 : 8);
|
gmch |= vdev->igd_gms << (gen < 8 ? 3 : 8);
|
||||||
|
pci_set_long(vdev->pdev.config + IGD_GMCH, gmch);
|
||||||
} else {
|
} else {
|
||||||
error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms);
|
error_report("Unsupported IGD GMS value 0x%x", vdev->igd_gms);
|
||||||
vdev->igd_gms = 0;
|
vdev->igd_gms = 0;
|
||||||
|
@ -1557,11 +1573,6 @@ static void vfio_probe_igd_bar4_quirk(VFIOPCIDevice *vdev, int nr)
|
||||||
fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size",
|
fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size",
|
||||||
bdsm_size, sizeof(*bdsm_size));
|
bdsm_size, sizeof(*bdsm_size));
|
||||||
|
|
||||||
/* GMCH is read-only, emulated */
|
|
||||||
pci_set_long(vdev->pdev.config + IGD_GMCH, gmch);
|
|
||||||
pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0);
|
|
||||||
pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0);
|
|
||||||
|
|
||||||
/* BDSM is read-write, emulated. The BIOS needs to be able to write it */
|
/* BDSM is read-write, emulated. The BIOS needs to be able to write it */
|
||||||
pci_set_long(vdev->pdev.config + IGD_BDSM, 0);
|
pci_set_long(vdev->pdev.config + IGD_BDSM, 0);
|
||||||
pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0);
|
pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0);
|
||||||
|
|
|
@ -1880,16 +1880,26 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
|
||||||
/*
|
/*
|
||||||
* Extended capabilities are chained with each pointing to the next, so we
|
* Extended capabilities are chained with each pointing to the next, so we
|
||||||
* can drop anything other than the head of the chain simply by modifying
|
* can drop anything other than the head of the chain simply by modifying
|
||||||
* the previous next pointer. For the head of the chain, we can modify the
|
* the previous next pointer. Seed the head of the chain here such that
|
||||||
* capability ID to something that cannot match a valid capability. ID
|
* we can simply skip any capabilities we want to drop below, regardless
|
||||||
* 0 is reserved for this since absence of capabilities is indicated by
|
* of their position in the chain. If this stub capability still exists
|
||||||
* 0 for the ID, version, AND next pointer. However, pcie_add_capability()
|
* after we add the capabilities we want to expose, update the capability
|
||||||
* uses ID 0 as reserved for list management and will incorrectly match and
|
* ID to zero. Note that we cannot seed with the capability header being
|
||||||
* assert if we attempt to pre-load the head of the chain with this ID.
|
* zero as this conflicts with definition of an absent capability chain
|
||||||
* Use ID 0xFFFF temporarily since it is also seems to be reserved in
|
* and prevents capabilities beyond the head of the list from being added.
|
||||||
* part for identifying absence of capabilities in a root complex register
|
* By replacing the dummy capability ID with zero after walking the device
|
||||||
* block. If the ID still exists after adding capabilities, switch back to
|
* chain, we also transparently mark extended capabilities as absent if
|
||||||
* zero. We'll mark this entire first dword as emulated for this purpose.
|
* no capabilities were added. Note that the PCIe spec defines an absence
|
||||||
|
* of extended capabilities to be determined by a value of zero for the
|
||||||
|
* capability ID, version, AND next pointer. A non-zero next pointer
|
||||||
|
* should be sufficient to indicate additional capabilities are present,
|
||||||
|
* which will occur if we call pcie_add_capability() below. The entire
|
||||||
|
* first dword is emulated to support this.
|
||||||
|
*
|
||||||
|
* NB. The kernel side does similar masking, so be prepared that our
|
||||||
|
* view of the device may also contain a capability ID zero in the head
|
||||||
|
* of the chain. Skip it for the same reason that we cannot seed the
|
||||||
|
* chain with a zero capability.
|
||||||
*/
|
*/
|
||||||
pci_set_long(pdev->config + PCI_CONFIG_SPACE_SIZE,
|
pci_set_long(pdev->config + PCI_CONFIG_SPACE_SIZE,
|
||||||
PCI_EXT_CAP(0xFFFF, 0, 0));
|
PCI_EXT_CAP(0xFFFF, 0, 0));
|
||||||
|
@ -1915,6 +1925,7 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev)
|
||||||
PCI_EXT_CAP_NEXT_MASK);
|
PCI_EXT_CAP_NEXT_MASK);
|
||||||
|
|
||||||
switch (cap_id) {
|
switch (cap_id) {
|
||||||
|
case 0: /* kernel masked capability */
|
||||||
case PCI_EXT_CAP_ID_SRIOV: /* Read-only VF BARs confuse OVMF */
|
case PCI_EXT_CAP_ID_SRIOV: /* Read-only VF BARs confuse OVMF */
|
||||||
case PCI_EXT_CAP_ID_ARI: /* XXX Needs next function virtualization */
|
case PCI_EXT_CAP_ID_ARI: /* XXX Needs next function virtualization */
|
||||||
trace_vfio_add_ext_cap_dropped(vdev->vbasedev.name, cap_id, next);
|
trace_vfio_add_ext_cap_dropped(vdev->vbasedev.name, cap_id, next);
|
||||||
|
@ -2506,12 +2517,16 @@ static void vfio_unregister_err_notifier(VFIOPCIDevice *vdev)
|
||||||
static void vfio_req_notifier_handler(void *opaque)
|
static void vfio_req_notifier_handler(void *opaque)
|
||||||
{
|
{
|
||||||
VFIOPCIDevice *vdev = opaque;
|
VFIOPCIDevice *vdev = opaque;
|
||||||
|
Error *err = NULL;
|
||||||
|
|
||||||
if (!event_notifier_test_and_clear(&vdev->req_notifier)) {
|
if (!event_notifier_test_and_clear(&vdev->req_notifier)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qdev_unplug(&vdev->pdev.qdev, NULL);
|
qdev_unplug(&vdev->pdev.qdev, &err);
|
||||||
|
if (err) {
|
||||||
|
error_reportf_err(err, WARN_PREFIX, vdev->vbasedev.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vfio_register_req_notifier(VFIOPCIDevice *vdev)
|
static void vfio_register_req_notifier(VFIOPCIDevice *vdev)
|
||||||
|
|
Loading…
Reference in New Issue