VFIO updates 2017-10-03
- NVIDIA GPUDirect Cliques experimental support (Alex Williamson) -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iQIcBAABAgAGBQJZ1AELAAoJECObm247sIsi4lsP/2s49kaWYdR4UilhMVJuVUkw 09l374WBDtiLcyc5BMyb+A4gWfNUKzp9NWBkcYorGtaXJU9/dgm1k2iI7fEPT8EY sTcsE+QbsYW2umWL+6tIq5JXNMynpz6jFDNsJaFCTsp597N4QA0Yhnk3CaTUxwAm lxv0+8CxShERd79PFF9ODOfSeTapEMgc7upOVMfq57aOiuqOMSLfqB7nsPuYijn2 sxMZAOp7NISlDFTg3d/hm1jx6HOmlOaWSFFrYk/9RI1JTuP8uKVH2LpyPwI25iDR TTvHbyKQk5dCsVqhnJaxqeTlQ7gbIjdXgY8cbEt+8ti5KXyV90hQsI3sM8qIv8Cl 2iYAdDPOCmQCWJ+arEmefwJbnRgnO5cTh2kMDxw6yAKQYuLWEe8VeeMl1NBnz+TE Ne1VFMR6yQ1T0uV/RX1djTNImACxXi6eadN92Gg9gwhBLeSvmAq1MF9VP1OEa1qh nZSyDVG9EB1bMVkj7OOMbJ3WX9nokkNn9QN88R6s+4XJqif4eYVIiQhfbMfpFEM2 oy4H7JgL7OysfBO1oirEGbnusZ/HhVbwVTjws63hpfSwiAEIfjbz3ht4Uz246Hy7 V2FSEgffOTjJQ8J7e+yyw+qXxcpW59Hrp5hfjq8vJWFNJsum7sjDhK2MVlPQ5Jty m3WSOvHN19hUJ6Ai71IH =0HfI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/awilliam/tags/vfio-updates-20171003.0' into staging VFIO updates 2017-10-03 - NVIDIA GPUDirect Cliques experimental support (Alex Williamson) # gpg: Signature made Tue 03 Oct 2017 22:28:43 BST # 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-20171003.0: vfio/pci: Add NVIDIA GPUDirect Cliques support vfio/pci: Add virtual capabilities quirk infrastructure vfio/pci: Do not unwind on error Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
90586a78ff
@ -14,6 +14,7 @@
|
||||
#include "qemu/error-report.h"
|
||||
#include "qemu/range.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qapi/visitor.h"
|
||||
#include "hw/nvram/fw_cfg.h"
|
||||
#include "pci.h"
|
||||
#include "trace.h"
|
||||
@ -1850,3 +1851,116 @@ void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The NVIDIA GPUDirect P2P Vendor capability allows the user to specify
|
||||
* devices as a member of a clique. Devices within the same clique ID
|
||||
* are capable of direct P2P. It's the user's responsibility that this
|
||||
* is correct. The spec says that this may reside at any unused config
|
||||
* offset, but reserves and recommends hypervisors place this at C8h.
|
||||
* The spec also states that the hypervisor should place this capability
|
||||
* at the end of the capability list, thus next is defined as 0h.
|
||||
*
|
||||
* +----------------+----------------+----------------+----------------+
|
||||
* | sig 7:0 ('P') | vndr len (8h) | next (0h) | cap id (9h) |
|
||||
* +----------------+----------------+----------------+----------------+
|
||||
* | rsvd 15:7(0h),id 6:3,ver 2:0(0h)| sig 23:8 ('P2') |
|
||||
* +---------------------------------+---------------------------------+
|
||||
*
|
||||
* https://lists.gnu.org/archive/html/qemu-devel/2017-08/pdfUda5iEpgOS.pdf
|
||||
*/
|
||||
static void get_nv_gpudirect_clique_id(Object *obj, Visitor *v,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
Property *prop = opaque;
|
||||
uint8_t *ptr = qdev_get_prop_ptr(dev, prop);
|
||||
|
||||
visit_type_uint8(v, name, ptr, errp);
|
||||
}
|
||||
|
||||
static void set_nv_gpudirect_clique_id(Object *obj, Visitor *v,
|
||||
const char *name, void *opaque,
|
||||
Error **errp)
|
||||
{
|
||||
DeviceState *dev = DEVICE(obj);
|
||||
Property *prop = opaque;
|
||||
uint8_t value, *ptr = qdev_get_prop_ptr(dev, prop);
|
||||
Error *local_err = NULL;
|
||||
|
||||
if (dev->realized) {
|
||||
qdev_prop_set_after_realize(dev, name, errp);
|
||||
return;
|
||||
}
|
||||
|
||||
visit_type_uint8(v, name, &value, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value & ~0xF) {
|
||||
error_setg(errp, "Property %s: valid range 0-15", name);
|
||||
return;
|
||||
}
|
||||
|
||||
*ptr = value;
|
||||
}
|
||||
|
||||
const PropertyInfo qdev_prop_nv_gpudirect_clique = {
|
||||
.name = "uint4",
|
||||
.description = "NVIDIA GPUDirect Clique ID (0 - 15)",
|
||||
.get = get_nv_gpudirect_clique_id,
|
||||
.set = set_nv_gpudirect_clique_id,
|
||||
};
|
||||
|
||||
static int vfio_add_nv_gpudirect_cap(VFIOPCIDevice *vdev, Error **errp)
|
||||
{
|
||||
PCIDevice *pdev = &vdev->pdev;
|
||||
int ret, pos = 0xC8;
|
||||
|
||||
if (vdev->nv_gpudirect_clique == 0xFF) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!vfio_pci_is(vdev, PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID)) {
|
||||
error_setg(errp, "NVIDIA GPUDirect Clique ID: invalid device vendor");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pci_get_byte(pdev->config + PCI_CLASS_DEVICE + 1) !=
|
||||
PCI_BASE_CLASS_DISPLAY) {
|
||||
error_setg(errp, "NVIDIA GPUDirect Clique ID: unsupported PCI class");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = pci_add_capability(pdev, PCI_CAP_ID_VNDR, pos, 8, errp);
|
||||
if (ret < 0) {
|
||||
error_prepend(errp, "Failed to add NVIDIA GPUDirect cap: ");
|
||||
return ret;
|
||||
}
|
||||
|
||||
memset(vdev->emulated_config_bits + pos, 0xFF, 8);
|
||||
pos += PCI_CAP_FLAGS;
|
||||
pci_set_byte(pdev->config + pos++, 8);
|
||||
pci_set_byte(pdev->config + pos++, 'P');
|
||||
pci_set_byte(pdev->config + pos++, '2');
|
||||
pci_set_byte(pdev->config + pos++, 'P');
|
||||
pci_set_byte(pdev->config + pos++, vdev->nv_gpudirect_clique << 3);
|
||||
pci_set_byte(pdev->config + pos, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = vfio_add_nv_gpudirect_cap(vdev, errp);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1826,14 +1826,22 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t pos, Error **errp)
|
||||
if (next) {
|
||||
ret = vfio_add_std_cap(vdev, next, errp);
|
||||
if (ret) {
|
||||
goto out;
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
/* Begin the rebuild, use QEMU emulated list bits */
|
||||
pdev->config[PCI_CAPABILITY_LIST] = 0;
|
||||
vdev->emulated_config_bits[PCI_CAPABILITY_LIST] = 0xff;
|
||||
vdev->emulated_config_bits[PCI_STATUS] |= PCI_STATUS_CAP_LIST;
|
||||
|
||||
ret = vfio_add_virt_caps(vdev, errp);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Scale down size, esp in case virt caps were added above */
|
||||
size = MIN(size, vfio_std_cap_max_size(pdev, pos));
|
||||
|
||||
/* Use emulated next pointer to allow dropping caps */
|
||||
pci_set_byte(vdev->emulated_config_bits + pos + PCI_CAP_LIST_NEXT, 0xff);
|
||||
@ -1862,7 +1870,7 @@ static int vfio_add_std_cap(VFIOPCIDevice *vdev, uint8_t pos, Error **errp)
|
||||
ret = pci_add_capability(pdev, cap_id, pos, size, errp);
|
||||
break;
|
||||
}
|
||||
out:
|
||||
|
||||
if (ret < 0) {
|
||||
error_prepend(errp,
|
||||
"failed to add PCI capability 0x%x[0x%x]@0x%x: ",
|
||||
@ -2962,6 +2970,8 @@ static void vfio_instance_init(Object *obj)
|
||||
vdev->host.bus = ~0U;
|
||||
vdev->host.slot = ~0U;
|
||||
vdev->host.function = ~0U;
|
||||
|
||||
vdev->nv_gpudirect_clique = 0xFF;
|
||||
}
|
||||
|
||||
static Property vfio_pci_dev_properties[] = {
|
||||
@ -2986,6 +2996,9 @@ static Property vfio_pci_dev_properties[] = {
|
||||
DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice,
|
||||
sub_device_id, PCI_ANY_ID),
|
||||
DEFINE_PROP_UINT32("x-igd-gms", VFIOPCIDevice, igd_gms, 0),
|
||||
DEFINE_PROP_UNSIGNED_NODEFAULT("x-nv-gpudirect-clique", VFIOPCIDevice,
|
||||
nv_gpudirect_clique,
|
||||
qdev_prop_nv_gpudirect_clique, uint8_t),
|
||||
/*
|
||||
* TODO - support passed fds... is this necessary?
|
||||
* DEFINE_PROP_STRING("vfiofd", VFIOPCIDevice, vfiofd_name),
|
||||
|
@ -135,6 +135,7 @@ typedef struct VFIOPCIDevice {
|
||||
int32_t bootindex;
|
||||
uint32_t igd_gms;
|
||||
uint8_t pm_cap;
|
||||
uint8_t nv_gpudirect_clique;
|
||||
bool pci_aer;
|
||||
bool req_enabled;
|
||||
bool has_flr;
|
||||
@ -160,6 +161,9 @@ void vfio_bar_quirk_setup(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_bar_quirk_exit(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_bar_quirk_finalize(VFIOPCIDevice *vdev, int nr);
|
||||
void vfio_setup_resetfn_quirk(VFIOPCIDevice *vdev);
|
||||
int vfio_add_virt_caps(VFIOPCIDevice *vdev, Error **errp);
|
||||
|
||||
extern const PropertyInfo qdev_prop_nv_gpudirect_clique;
|
||||
|
||||
int vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user