aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2013-04-01 11:03:44 -0400
committerAlex Williamson <alex.williamson@redhat.com>2013-04-01 11:03:44 -0400
commit180b1381078924b2442a42cded514afd6faff458 (patch)
tree00799fef8be3d2afc75aaf0040159919f1031ece
parent0bced2f7280cd12b66229ba55d05c62a4eef6cfd (diff)
vfio-pci: Use byte granularity in config map
The config map previously used a byte per dword to map regions of config space to capabilities. Modulo a bug where we round the length of capabilities down instead of up, this theoretically works well and saves space so long as devices don't try to hide registers in the gaps between capabilities. Unfortunately they do exactly that so we need byte granularity on our config space map. Increase the allocation of the config map and split accesses at capability region boundaries. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Tested-by: Gavin Shan <shangw@linux.vnet.ibm.com>
-rw-r--r--drivers/vfio/pci/vfio_pci_config.c88
1 files changed, 47 insertions, 41 deletions
diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c
index 964ff22bf281..5d5fc75743ce 100644
--- a/drivers/vfio/pci/vfio_pci_config.c
+++ b/drivers/vfio/pci/vfio_pci_config.c
@@ -800,9 +800,6 @@ static int vfio_find_cap_start(struct vfio_pci_device *vdev, int pos)
800 u8 cap; 800 u8 cap;
801 int base = (pos >= PCI_CFG_SPACE_SIZE) ? PCI_CFG_SPACE_SIZE : 801 int base = (pos >= PCI_CFG_SPACE_SIZE) ? PCI_CFG_SPACE_SIZE :
802 PCI_STD_HEADER_SIZEOF; 802 PCI_STD_HEADER_SIZEOF;
803 base /= 4;
804 pos /= 4;
805
806 cap = vdev->pci_config_map[pos]; 803 cap = vdev->pci_config_map[pos];
807 804
808 if (cap == PCI_CAP_ID_BASIC) 805 if (cap == PCI_CAP_ID_BASIC)
@@ -812,7 +809,7 @@ static int vfio_find_cap_start(struct vfio_pci_device *vdev, int pos)
812 while (pos - 1 >= base && vdev->pci_config_map[pos - 1] == cap) 809 while (pos - 1 >= base && vdev->pci_config_map[pos - 1] == cap)
813 pos--; 810 pos--;
814 811
815 return pos * 4; 812 return pos;
816} 813}
817 814
818static int vfio_msi_config_read(struct vfio_pci_device *vdev, int pos, 815static int vfio_msi_config_read(struct vfio_pci_device *vdev, int pos,
@@ -1229,8 +1226,8 @@ static int vfio_cap_init(struct vfio_pci_device *vdev)
1229 } 1226 }
1230 1227
1231 /* Sanity check, do we overlap other capabilities? */ 1228 /* Sanity check, do we overlap other capabilities? */
1232 for (i = 0; i < len; i += 4) { 1229 for (i = 0; i < len; i++) {
1233 if (likely(map[(pos + i) / 4] == PCI_CAP_ID_INVALID)) 1230 if (likely(map[pos + i] == PCI_CAP_ID_INVALID))
1234 continue; 1231 continue;
1235 1232
1236 pr_warn("%s: %s pci config conflict @0x%x, was cap 0x%x now cap 0x%x\n", 1233 pr_warn("%s: %s pci config conflict @0x%x, was cap 0x%x now cap 0x%x\n",
@@ -1238,7 +1235,7 @@ static int vfio_cap_init(struct vfio_pci_device *vdev)
1238 pos + i, map[pos + i], cap); 1235 pos + i, map[pos + i], cap);
1239 } 1236 }
1240 1237
1241 memset(map + (pos / 4), cap, len / 4); 1238 memset(map + pos, cap, len);
1242 ret = vfio_fill_vconfig_bytes(vdev, pos, len); 1239 ret = vfio_fill_vconfig_bytes(vdev, pos, len);
1243 if (ret) 1240 if (ret)
1244 return ret; 1241 return ret;
@@ -1313,8 +1310,8 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev)
1313 hidden = true; 1310 hidden = true;
1314 } 1311 }
1315 1312
1316 for (i = 0; i < len; i += 4) { 1313 for (i = 0; i < len; i++) {
1317 if (likely(map[(epos + i) / 4] == PCI_CAP_ID_INVALID)) 1314 if (likely(map[epos + i] == PCI_CAP_ID_INVALID))
1318 continue; 1315 continue;
1319 1316
1320 pr_warn("%s: %s pci config conflict @0x%x, was ecap 0x%x now ecap 0x%x\n", 1317 pr_warn("%s: %s pci config conflict @0x%x, was ecap 0x%x now ecap 0x%x\n",
@@ -1329,7 +1326,7 @@ static int vfio_ecap_init(struct vfio_pci_device *vdev)
1329 */ 1326 */
1330 BUILD_BUG_ON(PCI_EXT_CAP_ID_MAX >= PCI_CAP_ID_INVALID); 1327 BUILD_BUG_ON(PCI_EXT_CAP_ID_MAX >= PCI_CAP_ID_INVALID);
1331 1328
1332 memset(map + (epos / 4), ecap, len / 4); 1329 memset(map + epos, ecap, len);
1333 ret = vfio_fill_vconfig_bytes(vdev, epos, len); 1330 ret = vfio_fill_vconfig_bytes(vdev, epos, len);
1334 if (ret) 1331 if (ret)
1335 return ret; 1332 return ret;
@@ -1376,10 +1373,12 @@ int vfio_config_init(struct vfio_pci_device *vdev)
1376 int ret; 1373 int ret;
1377 1374
1378 /* 1375 /*
1379 * Config space, caps and ecaps are all dword aligned, so we can 1376 * Config space, caps and ecaps are all dword aligned, so we could
1380 * use one byte per dword to record the type. 1377 * use one byte per dword to record the type. However, there are
1378 * no requiremenst on the length of a capability, so the gap between
1379 * capabilities needs byte granularity.
1381 */ 1380 */
1382 map = kmalloc(pdev->cfg_size / 4, GFP_KERNEL); 1381 map = kmalloc(pdev->cfg_size, GFP_KERNEL);
1383 if (!map) 1382 if (!map)
1384 return -ENOMEM; 1383 return -ENOMEM;
1385 1384
@@ -1392,9 +1391,9 @@ int vfio_config_init(struct vfio_pci_device *vdev)
1392 vdev->pci_config_map = map; 1391 vdev->pci_config_map = map;
1393 vdev->vconfig = vconfig; 1392 vdev->vconfig = vconfig;
1394 1393
1395 memset(map, PCI_CAP_ID_BASIC, PCI_STD_HEADER_SIZEOF / 4); 1394 memset(map, PCI_CAP_ID_BASIC, PCI_STD_HEADER_SIZEOF);
1396 memset(map + (PCI_STD_HEADER_SIZEOF / 4), PCI_CAP_ID_INVALID, 1395 memset(map + PCI_STD_HEADER_SIZEOF, PCI_CAP_ID_INVALID,
1397 (pdev->cfg_size - PCI_STD_HEADER_SIZEOF) / 4); 1396 pdev->cfg_size - PCI_STD_HEADER_SIZEOF);
1398 1397
1399 ret = vfio_fill_vconfig_bytes(vdev, 0, PCI_STD_HEADER_SIZEOF); 1398 ret = vfio_fill_vconfig_bytes(vdev, 0, PCI_STD_HEADER_SIZEOF);
1400 if (ret) 1399 if (ret)
@@ -1449,6 +1448,22 @@ void vfio_config_free(struct vfio_pci_device *vdev)
1449 vdev->msi_perm = NULL; 1448 vdev->msi_perm = NULL;
1450} 1449}
1451 1450
1451/*
1452 * Find the remaining number of bytes in a dword that match the given
1453 * position. Stop at either the end of the capability or the dword boundary.
1454 */
1455static size_t vfio_pci_cap_remaining_dword(struct vfio_pci_device *vdev,
1456 loff_t pos)
1457{
1458 u8 cap = vdev->pci_config_map[pos];
1459 size_t i;
1460
1461 for (i = 1; (pos + i) % 4 && vdev->pci_config_map[pos + i] == cap; i++)
1462 /* nop */;
1463
1464 return i;
1465}
1466
1452static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf, 1467static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf,
1453 size_t count, loff_t *ppos, bool iswrite) 1468 size_t count, loff_t *ppos, bool iswrite)
1454{ 1469{
@@ -1457,19 +1472,27 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf,
1457 __le32 val = 0; 1472 __le32 val = 0;
1458 int cap_start = 0, offset; 1473 int cap_start = 0, offset;
1459 u8 cap_id; 1474 u8 cap_id;
1460 ssize_t ret = count; 1475 ssize_t ret;
1461 1476
1462 if (*ppos < 0 || *ppos + count > pdev->cfg_size) 1477 if (*ppos < 0 || *ppos >= pdev->cfg_size ||
1478 *ppos + count > pdev->cfg_size)
1463 return -EFAULT; 1479 return -EFAULT;
1464 1480
1465 /* 1481 /*
1466 * gcc can't seem to figure out we're a static function, only called 1482 * Chop accesses into aligned chunks containing no more than a
1467 * with count of 1/2/4 and hits copy_from_user_overflow without this. 1483 * single capability. Caller increments to the next chunk.
1468 */ 1484 */
1469 if (count > sizeof(val)) 1485 count = min(count, vfio_pci_cap_remaining_dword(vdev, *ppos));
1470 return -EINVAL; 1486 if (count >= 4 && !(*ppos % 4))
1487 count = 4;
1488 else if (count >= 2 && !(*ppos % 2))
1489 count = 2;
1490 else
1491 count = 1;
1492
1493 ret = count;
1471 1494
1472 cap_id = vdev->pci_config_map[*ppos / 4]; 1495 cap_id = vdev->pci_config_map[*ppos];
1473 1496
1474 if (cap_id == PCI_CAP_ID_INVALID) { 1497 if (cap_id == PCI_CAP_ID_INVALID) {
1475 if (iswrite) 1498 if (iswrite)
@@ -1485,11 +1508,6 @@ static ssize_t vfio_config_do_rw(struct vfio_pci_device *vdev, char __user *buf,
1485 return ret; 1508 return ret;
1486 } 1509 }
1487 1510
1488 /*
1489 * All capabilities are minimum 4 bytes and aligned on dword
1490 * boundaries. Since we don't support unaligned accesses, we're
1491 * only ever accessing a single capability.
1492 */
1493 if (*ppos >= PCI_CFG_SPACE_SIZE) { 1511 if (*ppos >= PCI_CFG_SPACE_SIZE) {
1494 WARN_ON(cap_id > PCI_EXT_CAP_ID_MAX); 1512 WARN_ON(cap_id > PCI_EXT_CAP_ID_MAX);
1495 1513
@@ -1545,20 +1563,8 @@ ssize_t vfio_pci_config_rw(struct vfio_pci_device *vdev, char __user *buf,
1545 1563
1546 pos &= VFIO_PCI_OFFSET_MASK; 1564 pos &= VFIO_PCI_OFFSET_MASK;
1547 1565
1548 /*
1549 * We want to both keep the access size the caller users as well as
1550 * support reading large chunks of config space in a single call.
1551 * PCI doesn't support unaligned accesses, so we can safely break
1552 * those apart.
1553 */
1554 while (count) { 1566 while (count) {
1555 if (count >= 4 && !(pos % 4)) 1567 ret = vfio_config_do_rw(vdev, buf, count, &pos, iswrite);
1556 ret = vfio_config_do_rw(vdev, buf, 4, &pos, iswrite);
1557 else if (count >= 2 && !(pos % 2))
1558 ret = vfio_config_do_rw(vdev, buf, 2, &pos, iswrite);
1559 else
1560 ret = vfio_config_do_rw(vdev, buf, 1, &pos, iswrite);
1561
1562 if (ret < 0) 1568 if (ret < 0)
1563 return ret; 1569 return ret;
1564 1570