|
@@ -33,9 +33,8 @@
|
|
|
|
|
|
#define PCI_CFG_SPACE_SIZE 256
|
|
|
|
|
|
-/* Useful "pseudo" capabilities */
|
|
|
+/* Fake capability ID for standard config space */
|
|
|
#define PCI_CAP_ID_BASIC 0
|
|
|
-#define PCI_CAP_ID_INVALID 0xFF
|
|
|
|
|
|
#define is_bar(offset) \
|
|
|
((offset >= PCI_BASE_ADDRESS_0 && offset < PCI_BASE_ADDRESS_5 + 4) || \
|
|
@@ -301,6 +300,23 @@ static int vfio_raw_config_read(struct vfio_pci_device *vdev, int pos,
|
|
|
return count;
|
|
|
}
|
|
|
|
|
|
+/* Virt access uses only virtualization */
|
|
|
+static int vfio_virt_config_write(struct vfio_pci_device *vdev, int pos,
|
|
|
+ int count, struct perm_bits *perm,
|
|
|
+ int offset, __le32 val)
|
|
|
+{
|
|
|
+ memcpy(vdev->vconfig + pos, &val, count);
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
+static int vfio_virt_config_read(struct vfio_pci_device *vdev, int pos,
|
|
|
+ int count, struct perm_bits *perm,
|
|
|
+ int offset, __le32 *val)
|
|
|
+{
|
|
|
+ memcpy(val, vdev->vconfig + pos, count);
|
|
|
+ return count;
|
|
|
+}
|
|
|
+
|
|
|
/* Default capability regions to read-only, no-virtualization */
|
|
|
static struct perm_bits cap_perms[PCI_CAP_ID_MAX + 1] = {
|
|
|
[0 ... PCI_CAP_ID_MAX] = { .readfn = vfio_direct_config_read }
|
|
@@ -319,6 +335,11 @@ static struct perm_bits unassigned_perms = {
|
|
|
.writefn = vfio_raw_config_write
|
|
|
};
|
|
|
|
|
|
+static struct perm_bits virt_perms = {
|
|
|
+ .readfn = vfio_virt_config_read,
|
|
|
+ .writefn = vfio_virt_config_write
|
|
|
+};
|
|
|
+
|
|
|
static void free_perm_bits(struct perm_bits *perm)
|
|
|
{
|
|
|
kfree(perm->virt);
|
|
@@ -1332,6 +1353,8 @@ static int vfio_cap_init(struct vfio_pci_device *vdev)
|
|
|
pos + i, map[pos + i], cap);
|
|
|
}
|
|
|
|
|
|
+ BUILD_BUG_ON(PCI_CAP_ID_MAX >= PCI_CAP_ID_INVALID_VIRT);
|
|
|
+
|
|
|
memset(map + pos, cap, len);
|
|
|
ret = vfio_fill_vconfig_bytes(vdev, pos, len);
|
|
|
if (ret)
|
|
@@ -1419,9 +1442,9 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev)
|
|
|
/*
|
|
|
* Even though ecap is 2 bytes, we're currently a long way
|
|
|
* from exceeding 1 byte capabilities. If we ever make it
|
|
|
- * up to 0xFF we'll need to up this to a two-byte, byte map.
|
|
|
+ * up to 0xFE we'll need to up this to a two-byte, byte map.
|
|
|
*/
|
|
|
- BUILD_BUG_ON(PCI_EXT_CAP_ID_MAX >= PCI_CAP_ID_INVALID);
|
|
|
+ BUILD_BUG_ON(PCI_EXT_CAP_ID_MAX >= PCI_CAP_ID_INVALID_VIRT);
|
|
|
|
|
|
memset(map + epos, ecap, len);
|
|
|
ret = vfio_fill_vconfig_bytes(vdev, epos, len);
|
|
@@ -1597,6 +1620,9 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf,
|
|
|
if (cap_id == PCI_CAP_ID_INVALID) {
|
|
|
perm = &unassigned_perms;
|
|
|
cap_start = *ppos;
|
|
|
+ } else if (cap_id == PCI_CAP_ID_INVALID_VIRT) {
|
|
|
+ perm = &virt_perms;
|
|
|
+ cap_start = *ppos;
|
|
|
} else {
|
|
|
if (*ppos >= PCI_CFG_SPACE_SIZE) {
|
|
|
WARN_ON(cap_id > PCI_EXT_CAP_ID_MAX);
|