History

Merge branches 'v5.4/vfio/alexey-tce-memory-free-v1', 'v5.4/vfio/connie-re-arrange-v2', 'v5.4/vfio/hexin-pci-reset-v3', 'v5.4/vfio/parav-mtty-uuid-v2' and 'v5.4/vfio/shameer-iova-list-v8' into v5.4/vfio/next

Alex Williamson committed 7 years ago

Commit e6c5d726 parents e3fb13b 78becab db2cb96 92c8026 eee413e b09d6e45 files · +583 −71Browse files

Unified · Split

5 files
  1. drivers/vfio/pci/vfio_pci.c +13 −4
  2. drivers/vfio/vfio_iommu_spapr_tce.c +5 −4
  3. drivers/vfio/vfio_iommu_type1.c +506 −12
  4. include/uapi/linux/vfio.h +51 −20
  5. samples/vfio-mdev/mtty.c +8 −31
drivers/vfio/pci/vfio_pci.c+13−4
@@ -438,11 +438,20 @@ static void vfio_pci_disable(struct vfio_pci_device *vdev) · 437 unmodified lines
438438 pci_write_config_word(pdev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
439439
440440 /*
441− * Try to reset the device. The success of this is dependent on
442− * being able to lock the device, which is not always possible.
441+ * Try to get the locks ourselves to prevent a deadlock. The
442+ * success of this is dependent on being able to lock the device,
443+ * which is not always possible.
444+ * We can not use the "try" reset interface here, which will
445+ * overwrite the previously restored configuration information.
443446 */
444− if (vdev->reset_works && !pci_try_reset_function(pdev))
445− vdev->needs_reset = false;
447+ if (vdev->reset_works && pci_cfg_access_trylock(pdev)) {
448+ if (device_trylock(&pdev->dev)) {
449+ if (!__pci_reset_function_locked(pdev))
450+ vdev->needs_reset = false;
451+ device_unlock(&pdev->dev);
452+ }
453+ pci_cfg_access_unlock(pdev);
454+ }
446455
447456 pci_restore_state(pdev);
448457 out:
drivers/vfio/vfio_iommu_spapr_tce.c+5−4
@@ -1234,7 +1234,7 @@ release_exit: · 1233 unmodified lines
12341234 static int tce_iommu_attach_group(void *iommu_data,
12351235 struct iommu_group *iommu_group)
12361236 {
1237− int ret;
1237+ int ret = 0;
12381238 struct tce_container *container = iommu_data;
12391239 struct iommu_table_group *table_group;
12401240 struct tce_iommu_group *tcegrp = NULL;
@@ -1287,13 +1287,13 @@ static int tce_iommu_attach_group(void *iommu_data, · 46 unmodified lines
12871287 !table_group->ops->release_ownership) {
12881288 if (container->v2) {
12891289 ret = -EPERM;
1290− goto unlock_exit;
1290+ goto free_exit;
12911291 }
12921292 ret = tce_iommu_take_ownership(container, table_group);
12931293 } else {
12941294 if (!container->v2) {
12951295 ret = -EPERM;
1296− goto unlock_exit;
1296+ goto free_exit;
12971297 }
12981298 ret = tce_iommu_take_ownership_ddw(container, table_group);
12991299 if (!tce_groups_attached(container) && !container->tables[0])
@@ -1305,10 +1305,11 @@ static int tce_iommu_attach_group(void *iommu_data, · 5 unmodified lines
13051305 list_add(&tcegrp->next, &container->group_list);
13061306 }
13071307
1308−unlock_exit:
1308+free_exit:
13091309 if (ret && tcegrp)
13101310 kfree(tcegrp);
13111311
1312+unlock_exit:
13121313 mutex_unlock(&container->lock);
13131314
13141315 return ret;
drivers/vfio/vfio_iommu_type1.c+506−12
@@ -62,6 +62,7 @@ MODULE_PARM_DESC(dma_entry_limit, · 61 unmodified lines
6262
6363 struct vfio_iommu {
6464 struct list_head domain_list;
65+ struct list_head iova_list;
6566 struct vfio_domain *external_domain; /* domain for external user */
6667 struct mutex lock;
6768 struct rb_root dma_list;
@@ -97,6 +98,12 @@ struct vfio_group { · 29 unmodified lines
9798 bool mdev_group; /* An mdev group */
9899 };
99100
101+struct vfio_iova {
102+ struct list_head list;
103+ dma_addr_t start;
104+ dma_addr_t end;
105+};
106+
100107 /*
101108 * Guest RAM pinning working set or DMA target
102109 */
@@ -1031,6 +1038,27 @@ static int vfio_pin_map_dma(struct vfio_iommu *iommu, struct vfio_dma *dma, · 928 unmodified lines
10311038 return ret;
10321039 }
10331040
1041+/*
1042+ * Check dma map request is within a valid iova range
1043+ */
1044+static bool vfio_iommu_iova_dma_valid(struct vfio_iommu *iommu,
1045+ dma_addr_t start, dma_addr_t end)
1046+{
1047+ struct list_head *iova = &iommu->iova_list;
1048+ struct vfio_iova *node;
1049+
1050+ list_for_each_entry(node, iova, list) {
1051+ if (start >= node->start && end <= node->end)
1052+ return true;
1053+ }
1054+
1055+ /*
1056+ * Check for list_empty() as well since a container with
1057+ * a single mdev device will have an empty list.
1058+ */
1059+ return list_empty(iova);
1060+}
1061+
10341062 static int vfio_dma_do_map(struct vfio_iommu *iommu,
10351063 struct vfio_iommu_type1_dma_map *map)
10361064 {
@@ -1074,6 +1102,11 @@ static int vfio_dma_do_map(struct vfio_iommu *iommu, · 37 unmodified lines
10741102 goto out_unlock;
10751103 }
10761104
1105+ if (!vfio_iommu_iova_dma_valid(iommu, iova, iova + size - 1)) {
1106+ ret = -EINVAL;
1107+ goto out_unlock;
1108+ }
1109+
10771110 dma = kzalloc(sizeof(*dma), GFP_KERNEL);
10781111 if (!dma) {
10791112 ret = -ENOMEM;
@@ -1263,15 +1296,13 @@ static struct vfio_group *find_iommu_group(struct vfio_domain *domain, · 183 unmodified lines
12631296 return NULL;
12641297 }
12651298
1266−static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base)
1299+static bool vfio_iommu_has_sw_msi(struct list_head *group_resv_regions,
1300+ phys_addr_t *base)
12671301 {
1268− struct list_head group_resv_regions;
1269− struct iommu_resv_region *region, *next;
1302+ struct iommu_resv_region *region;
12701303 bool ret = false;
12711304
1272− INIT_LIST_HEAD(&group_resv_regions);
1273− iommu_get_group_resv_regions(group, &group_resv_regions);
1274− list_for_each_entry(region, &group_resv_regions, list) {
1305+ list_for_each_entry(region, group_resv_regions, list) {
12751306 /*
12761307 * The presence of any 'real' MSI regions should take
12771308 * precedence over the software-managed one if the
@@ -1287,8 +1318,7 @@ static bool vfio_iommu_has_sw_msi(struct iommu_group *group, phys_addr_t *base) · 9 unmodified lines
12871318 ret = true;
12881319 }
12891320 }
1290− list_for_each_entry_safe(region, next, &group_resv_regions, list)
1291− kfree(region);
1321+
12921322 return ret;
12931323 }
12941324
@@ -1388,6 +1418,228 @@ static int vfio_mdev_iommu_device(struct device *dev, void *data) · 93 unmodified lines
13881418 return 0;
13891419 }
13901420
1421+/*
1422+ * This is a helper function to insert an address range to iova list.
1423+ * The list is initially created with a single entry corresponding to
1424+ * the IOMMU domain geometry to which the device group is attached.
1425+ * The list aperture gets modified when a new domain is added to the
1426+ * container if the new aperture doesn't conflict with the current one
1427+ * or with any existing dma mappings. The list is also modified to
1428+ * exclude any reserved regions associated with the device group.
1429+ */
1430+static int vfio_iommu_iova_insert(struct list_head *head,
1431+ dma_addr_t start, dma_addr_t end)
1432+{
1433+ struct vfio_iova *region;
1434+
1435+ region = kmalloc(sizeof(*region), GFP_KERNEL);
1436+ if (!region)
1437+ return -ENOMEM;
1438+
1439+ INIT_LIST_HEAD(&region->list);
1440+ region->start = start;
1441+ region->end = end;
1442+
1443+ list_add_tail(&region->list, head);
1444+ return 0;
1445+}
1446+
1447+/*
1448+ * Check the new iommu aperture conflicts with existing aper or with any
1449+ * existing dma mappings.
1450+ */
1451+static bool vfio_iommu_aper_conflict(struct vfio_iommu *iommu,
1452+ dma_addr_t start, dma_addr_t end)
1453+{
1454+ struct vfio_iova *first, *last;
1455+ struct list_head *iova = &iommu->iova_list;
1456+
1457+ if (list_empty(iova))
1458+ return false;
1459+
1460+ /* Disjoint sets, return conflict */
1461+ first = list_first_entry(iova, struct vfio_iova, list);
1462+ last = list_last_entry(iova, struct vfio_iova, list);
1463+ if (start > last->end || end < first->start)
1464+ return true;
1465+
1466+ /* Check for any existing dma mappings below the new start */
1467+ if (start > first->start) {
1468+ if (vfio_find_dma(iommu, first->start, start - first->start))
1469+ return true;
1470+ }
1471+
1472+ /* Check for any existing dma mappings beyond the new end */
1473+ if (end < last->end) {
1474+ if (vfio_find_dma(iommu, end + 1, last->end - end))
1475+ return true;
1476+ }
1477+
1478+ return false;
1479+}
1480+
1481+/*
1482+ * Resize iommu iova aperture window. This is called only if the new
1483+ * aperture has no conflict with existing aperture and dma mappings.
1484+ */
1485+static int vfio_iommu_aper_resize(struct list_head *iova,
1486+ dma_addr_t start, dma_addr_t end)
1487+{
1488+ struct vfio_iova *node, *next;
1489+
1490+ if (list_empty(iova))
1491+ return vfio_iommu_iova_insert(iova, start, end);
1492+
1493+ /* Adjust iova list start */
1494+ list_for_each_entry_safe(node, next, iova, list) {
1495+ if (start < node->start)
1496+ break;
1497+ if (start >= node->start && start < node->end) {
1498+ node->start = start;
1499+ break;
1500+ }
1501+ /* Delete nodes before new start */
1502+ list_del(&node->list);
1503+ kfree(node);
1504+ }
1505+
1506+ /* Adjust iova list end */
1507+ list_for_each_entry_safe(node, next, iova, list) {
1508+ if (end > node->end)
1509+ continue;
1510+ if (end > node->start && end <= node->end) {
1511+ node->end = end;
1512+ continue;
1513+ }
1514+ /* Delete nodes after new end */
1515+ list_del(&node->list);
1516+ kfree(node);
1517+ }
1518+
1519+ return 0;
1520+}
1521+
1522+/*
1523+ * Check reserved region conflicts with existing dma mappings
1524+ */
1525+static bool vfio_iommu_resv_conflict(struct vfio_iommu *iommu,
1526+ struct list_head *resv_regions)
1527+{
1528+ struct iommu_resv_region *region;
1529+
1530+ /* Check for conflict with existing dma mappings */
1531+ list_for_each_entry(region, resv_regions, list) {
1532+ if (region->type == IOMMU_RESV_DIRECT_RELAXABLE)
1533+ continue;
1534+
1535+ if (vfio_find_dma(iommu, region->start, region->length))
1536+ return true;
1537+ }
1538+
1539+ return false;
1540+}
1541+
1542+/*
1543+ * Check iova region overlap with reserved regions and
1544+ * exclude them from the iommu iova range
1545+ */
1546+static int vfio_iommu_resv_exclude(struct list_head *iova,
1547+ struct list_head *resv_regions)
1548+{
1549+ struct iommu_resv_region *resv;
1550+ struct vfio_iova *n, *next;
1551+
1552+ list_for_each_entry(resv, resv_regions, list) {
1553+ phys_addr_t start, end;
1554+
1555+ if (resv->type == IOMMU_RESV_DIRECT_RELAXABLE)
1556+ continue;
1557+
1558+ start = resv->start;
1559+ end = resv->start + resv->length - 1;
1560+
1561+ list_for_each_entry_safe(n, next, iova, list) {
1562+ int ret = 0;
1563+
1564+ /* No overlap */
1565+ if (start > n->end || end < n->start)
1566+ continue;
1567+ /*
1568+ * Insert a new node if current node overlaps with the
1569+ * reserve region to exlude that from valid iova range.
1570+ * Note that, new node is inserted before the current
1571+ * node and finally the current node is deleted keeping
1572+ * the list updated and sorted.
1573+ */
1574+ if (start > n->start)
1575+ ret = vfio_iommu_iova_insert(&n->list, n->start,
1576+ start - 1);
1577+ if (!ret && end < n->end)
1578+ ret = vfio_iommu_iova_insert(&n->list, end + 1,
1579+ n->end);
1580+ if (ret)
1581+ return ret;
1582+
1583+ list_del(&n->list);
1584+ kfree(n);
1585+ }
1586+ }
1587+
1588+ if (list_empty(iova))
1589+ return -EINVAL;
1590+
1591+ return 0;
1592+}
1593+
1594+static void vfio_iommu_resv_free(struct list_head *resv_regions)
1595+{
1596+ struct iommu_resv_region *n, *next;
1597+
1598+ list_for_each_entry_safe(n, next, resv_regions, list) {
1599+ list_del(&n->list);
1600+ kfree(n);
1601+ }
1602+}
1603+
1604+static void vfio_iommu_iova_free(struct list_head *iova)
1605+{
1606+ struct vfio_iova *n, *next;
1607+
1608+ list_for_each_entry_safe(n, next, iova, list) {
1609+ list_del(&n->list);
1610+ kfree(n);
1611+ }
1612+}
1613+
1614+static int vfio_iommu_iova_get_copy(struct vfio_iommu *iommu,
1615+ struct list_head *iova_copy)
1616+{
1617+ struct list_head *iova = &iommu->iova_list;
1618+ struct vfio_iova *n;
1619+ int ret;
1620+
1621+ list_for_each_entry(n, iova, list) {
1622+ ret = vfio_iommu_iova_insert(iova_copy, n->start, n->end);
1623+ if (ret)
1624+ goto out_free;
1625+ }
1626+
1627+ return 0;
1628+
1629+out_free:
1630+ vfio_iommu_iova_free(iova_copy);
1631+ return ret;
1632+}
1633+
1634+static void vfio_iommu_iova_insert_copy(struct vfio_iommu *iommu,
1635+ struct list_head *iova_copy)
1636+{
1637+ struct list_head *iova = &iommu->iova_list;
1638+
1639+ vfio_iommu_iova_free(iova);
1640+
1641+ list_splice_tail(iova_copy, iova);
1642+}
13911643 static int vfio_iommu_type1_attach_group(void *iommu_data,
13921644 struct iommu_group *iommu_group)
13931645 {
@@ -1398,6 +1650,9 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, · 4 unmodified lines
13981650 int ret;
13991651 bool resv_msi, msi_remap;
14001652 phys_addr_t resv_msi_base;
1653+ struct iommu_domain_geometry geo;
1654+ LIST_HEAD(iova_copy);
1655+ LIST_HEAD(group_resv_regions);
14011656
14021657 mutex_lock(&iommu->lock);
14031658
@@ -1474,7 +1729,43 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, · 70 unmodified lines
14741729 if (ret)
14751730 goto out_domain;
14761731
1477− resv_msi = vfio_iommu_has_sw_msi(iommu_group, &resv_msi_base);
1732+ /* Get aperture info */
1733+ iommu_domain_get_attr(domain->domain, DOMAIN_ATTR_GEOMETRY, &geo);
1734+
1735+ if (vfio_iommu_aper_conflict(iommu, geo.aperture_start,
1736+ geo.aperture_end)) {
1737+ ret = -EINVAL;
1738+ goto out_detach;
1739+ }
1740+
1741+ ret = iommu_get_group_resv_regions(iommu_group, &group_resv_regions);
1742+ if (ret)
1743+ goto out_detach;
1744+
1745+ if (vfio_iommu_resv_conflict(iommu, &group_resv_regions)) {
1746+ ret = -EINVAL;
1747+ goto out_detach;
1748+ }
1749+
1750+ /*
1751+ * We don't want to work on the original iova list as the list
1752+ * gets modified and in case of failure we have to retain the
1753+ * original list. Get a copy here.
1754+ */
1755+ ret = vfio_iommu_iova_get_copy(iommu, &iova_copy);
1756+ if (ret)
1757+ goto out_detach;
1758+
1759+ ret = vfio_iommu_aper_resize(&iova_copy, geo.aperture_start,
1760+ geo.aperture_end);
1761+ if (ret)
1762+ goto out_detach;
1763+
1764+ ret = vfio_iommu_resv_exclude(&iova_copy, &group_resv_regions);
1765+ if (ret)
1766+ goto out_detach;
1767+
1768+ resv_msi = vfio_iommu_has_sw_msi(&group_resv_regions, &resv_msi_base);
14781769
14791770 INIT_LIST_HEAD(&domain->group_list);
14801771 list_add(&group->next, &domain->group_list);
@@ -1507,8 +1798,7 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, · 26 unmodified lines
15071798 list_add(&group->next, &d->group_list);
15081799 iommu_domain_free(domain->domain);
15091800 kfree(domain);
1510− mutex_unlock(&iommu->lock);
1511− return 0;
1801+ goto done;
15121802 }
15131803
15141804 ret = vfio_iommu_attach_group(domain, group);
@@ -1531,8 +1821,11 @@ static int vfio_iommu_type1_attach_group(void *iommu_data, · 16 unmodified lines
15311821 }
15321822
15331823 list_add(&domain->next, &iommu->domain_list);
1534−
1824+done:
1825+ /* Delete the old one and insert new iova list */
1826+ vfio_iommu_iova_insert_copy(iommu, &iova_copy);
15351827 mutex_unlock(&iommu->lock);
1828+ vfio_iommu_resv_free(&group_resv_regions);
15361829
15371830 return 0;
15381831
@@ -1540,6 +1833,8 @@ out_detach: · 1 unmodified line
15401833 vfio_iommu_detach_group(domain, group);
15411834 out_domain:
15421835 iommu_domain_free(domain->domain);
1836+ vfio_iommu_iova_free(&iova_copy);
1837+ vfio_iommu_resv_free(&group_resv_regions);
15431838 out_free:
15441839 kfree(domain);
15451840 kfree(group);
@@ -1595,12 +1890,93 @@ static void vfio_sanity_check_pfn_list(struct vfio_iommu *iommu) · 49 unmodified lines
15951890 WARN_ON(iommu->notifier.head);
15961891 }
15971892
1893+/*
1894+ * Called when a domain is removed in detach. It is possible that
1895+ * the removed domain decided the iova aperture window. Modify the
1896+ * iova aperture with the smallest window among existing domains.
1897+ */
1898+static void vfio_iommu_aper_expand(struct vfio_iommu *iommu,
1899+ struct list_head *iova_copy)
1900+{
1901+ struct vfio_domain *domain;
1902+ struct iommu_domain_geometry geo;
1903+ struct vfio_iova *node;
1904+ dma_addr_t start = 0;
1905+ dma_addr_t end = (dma_addr_t)~0;
1906+
1907+ if (list_empty(iova_copy))
1908+ return;
1909+
1910+ list_for_each_entry(domain, &iommu->domain_list, next) {
1911+ iommu_domain_get_attr(domain->domain, DOMAIN_ATTR_GEOMETRY,
1912+ &geo);
1913+ if (geo.aperture_start > start)
1914+ start = geo.aperture_start;
1915+ if (geo.aperture_end < end)
1916+ end = geo.aperture_end;
1917+ }
1918+
1919+ /* Modify aperture limits. The new aper is either same or bigger */
1920+ node = list_first_entry(iova_copy, struct vfio_iova, list);
1921+ node->start = start;
1922+ node = list_last_entry(iova_copy, struct vfio_iova, list);
1923+ node->end = end;
1924+}
1925+
1926+/*
1927+ * Called when a group is detached. The reserved regions for that
1928+ * group can be part of valid iova now. But since reserved regions
1929+ * may be duplicated among groups, populate the iova valid regions
1930+ * list again.
1931+ */
1932+static int vfio_iommu_resv_refresh(struct vfio_iommu *iommu,
1933+ struct list_head *iova_copy)
1934+{
1935+ struct vfio_domain *d;
1936+ struct vfio_group *g;
1937+ struct vfio_iova *node;
1938+ dma_addr_t start, end;
1939+ LIST_HEAD(resv_regions);
1940+ int ret;
1941+
1942+ if (list_empty(iova_copy))
1943+ return -EINVAL;
1944+
1945+ list_for_each_entry(d, &iommu->domain_list, next) {
1946+ list_for_each_entry(g, &d->group_list, next) {
1947+ ret = iommu_get_group_resv_regions(g->iommu_group,
1948+ &resv_regions);
1949+ if (ret)
1950+ goto done;
1951+ }
1952+ }
1953+
1954+ node = list_first_entry(iova_copy, struct vfio_iova, list);
1955+ start = node->start;
1956+ node = list_last_entry(iova_copy, struct vfio_iova, list);
1957+ end = node->end;
1958+
1959+ /* purge the iova list and create new one */
1960+ vfio_iommu_iova_free(iova_copy);
1961+
1962+ ret = vfio_iommu_aper_resize(iova_copy, start, end);
1963+ if (ret)
1964+ goto done;
1965+
1966+ /* Exclude current reserved regions from iova ranges */
1967+ ret = vfio_iommu_resv_exclude(iova_copy, &resv_regions);
1968+done:
1969+ vfio_iommu_resv_free(&resv_regions);
1970+ return ret;
1971+}
1972+
15981973 static void vfio_iommu_type1_detach_group(void *iommu_data,
15991974 struct iommu_group *iommu_group)
16001975 {
16011976 struct vfio_iommu *iommu = iommu_data;
16021977 struct vfio_domain *domain;
16031978 struct vfio_group *group;
1979+ LIST_HEAD(iova_copy);
16041980
16051981 mutex_lock(&iommu->lock);
16061982
@@ -1623,6 +1999,13 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, · 16 unmodified lines
16231999 }
16242000 }
16252001
2002+ /*
2003+ * Get a copy of iova list. This will be used to update
2004+ * and to replace the current one later. Please note that
2005+ * we will leave the original list as it is if update fails.
2006+ */
2007+ vfio_iommu_iova_get_copy(iommu, &iova_copy);
2008+
16262009 list_for_each_entry(domain, &iommu->domain_list, next) {
16272010 group = find_iommu_group(domain, iommu_group);
16282011 if (!group)
@@ -1648,10 +2031,16 @@ static void vfio_iommu_type1_detach_group(void *iommu_data, · 19 unmodified lines
16482031 iommu_domain_free(domain->domain);
16492032 list_del(&domain->next);
16502033 kfree(domain);
2034+ vfio_iommu_aper_expand(iommu, &iova_copy);
16512035 }
16522036 break;
16532037 }
16542038
2039+ if (!vfio_iommu_resv_refresh(iommu, &iova_copy))
2040+ vfio_iommu_iova_insert_copy(iommu, &iova_copy);
2041+ else
2042+ vfio_iommu_iova_free(&iova_copy);
2043+
16552044 detach_group_done:
16562045 mutex_unlock(&iommu->lock);
16572046 }
@@ -1679,6 +2068,7 @@ static void *vfio_iommu_type1_open(unsigned long arg) · 21 unmodified lines
16792068 }
16802069
16812070 INIT_LIST_HEAD(&iommu->domain_list);
2071+ INIT_LIST_HEAD(&iommu->iova_list);
16822072 iommu->dma_list = RB_ROOT;
16832073 iommu->dma_avail = dma_entry_limit;
16842074 mutex_init(&iommu->lock);
@@ -1722,6 +2112,9 @@ static void vfio_iommu_type1_release(void *iommu_data) · 37 unmodified lines
17222112 list_del(&domain->next);
17232113 kfree(domain);
17242114 }
2115+
2116+ vfio_iommu_iova_free(&iommu->iova_list);
2117+
17252118 kfree(iommu);
17262119 }
17272120
@@ -1742,6 +2135,73 @@ static int vfio_domains_have_iommu_cache(struct vfio_iommu *iommu) · 14 unmodified lines
17422135 return ret;
17432136 }
17442137
2138+static int vfio_iommu_iova_add_cap(struct vfio_info_cap *caps,
2139+ struct vfio_iommu_type1_info_cap_iova_range *cap_iovas,
2140+ size_t size)
2141+{
2142+ struct vfio_info_cap_header *header;
2143+ struct vfio_iommu_type1_info_cap_iova_range *iova_cap;
2144+
2145+ header = vfio_info_cap_add(caps, size,
2146+ VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE, 1);
2147+ if (IS_ERR(header))
2148+ return PTR_ERR(header);
2149+
2150+ iova_cap = container_of(header,
2151+ struct vfio_iommu_type1_info_cap_iova_range,
2152+ header);
2153+ iova_cap->nr_iovas = cap_iovas->nr_iovas;
2154+ memcpy(iova_cap->iova_ranges, cap_iovas->iova_ranges,
2155+ cap_iovas->nr_iovas * sizeof(*cap_iovas->iova_ranges));
2156+ return 0;
2157+}
2158+
2159+static int vfio_iommu_iova_build_caps(struct vfio_iommu *iommu,
2160+ struct vfio_info_cap *caps)
2161+{
2162+ struct vfio_iommu_type1_info_cap_iova_range *cap_iovas;
2163+ struct vfio_iova *iova;
2164+ size_t size;
2165+ int iovas = 0, i = 0, ret;
2166+
2167+ mutex_lock(&iommu->lock);
2168+
2169+ list_for_each_entry(iova, &iommu->iova_list, list)
2170+ iovas++;
2171+
2172+ if (!iovas) {
2173+ /*
2174+ * Return 0 as a container with a single mdev device
2175+ * will have an empty list
2176+ */
2177+ ret = 0;
2178+ goto out_unlock;
2179+ }
2180+
2181+ size = sizeof(*cap_iovas) + (iovas * sizeof(*cap_iovas->iova_ranges));
2182+
2183+ cap_iovas = kzalloc(size, GFP_KERNEL);
2184+ if (!cap_iovas) {
2185+ ret = -ENOMEM;
2186+ goto out_unlock;
2187+ }
2188+
2189+ cap_iovas->nr_iovas = iovas;
2190+
2191+ list_for_each_entry(iova, &iommu->iova_list, list) {
2192+ cap_iovas->iova_ranges[i].start = iova->start;
2193+ cap_iovas->iova_ranges[i].end = iova->end;
2194+ i++;
2195+ }
2196+
2197+ ret = vfio_iommu_iova_add_cap(caps, cap_iovas, size);
2198+
2199+ kfree(cap_iovas);
2200+out_unlock:
2201+ mutex_unlock(&iommu->lock);
2202+ return ret;
2203+}
2204+
17452205 static long vfio_iommu_type1_ioctl(void *iommu_data,
17462206 unsigned int cmd, unsigned long arg)
17472207 {
@@ -1763,19 +2223,53 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, · 15 unmodified lines
17632223 }
17642224 } else if (cmd == VFIO_IOMMU_GET_INFO) {
17652225 struct vfio_iommu_type1_info info;
2226+ struct vfio_info_cap caps = { .buf = NULL, .size = 0 };
2227+ unsigned long capsz;
2228+ int ret;
17662229
17672230 minsz = offsetofend(struct vfio_iommu_type1_info, iova_pgsizes);
17682231
2232+ /* For backward compatibility, cannot require this */
2233+ capsz = offsetofend(struct vfio_iommu_type1_info, cap_offset);
2234+
17692235 if (copy_from_user(&info, (void __user *)arg, minsz))
17702236 return -EFAULT;
17712237
17722238 if (info.argsz < minsz)
17732239 return -EINVAL;
17742240
2241+ if (info.argsz >= capsz) {
2242+ minsz = capsz;
2243+ info.cap_offset = 0; /* output, no-recopy necessary */
2244+ }
2245+
17752246 info.flags = VFIO_IOMMU_INFO_PGSIZES;
17762247
17772248 info.iova_pgsizes = vfio_pgsize_bitmap(iommu);
17782249
2250+ ret = vfio_iommu_iova_build_caps(iommu, &caps);
2251+ if (ret)
2252+ return ret;
2253+
2254+ if (caps.size) {
2255+ info.flags |= VFIO_IOMMU_INFO_CAPS;
2256+
2257+ if (info.argsz < sizeof(info) + caps.size) {
2258+ info.argsz = sizeof(info) + caps.size;
2259+ } else {
2260+ vfio_info_cap_shift(&caps, sizeof(info));
2261+ if (copy_to_user((void __user *)arg +
2262+ sizeof(info), caps.buf,
2263+ caps.size)) {
2264+ kfree(caps.buf);
2265+ return -EFAULT;
2266+ }
2267+ info.cap_offset = sizeof(info);
2268+ }
2269+
2270+ kfree(caps.buf);
2271+ }
2272+
17792273 return copy_to_user((void __user *)arg, &info, minsz) ?
17802274 -EFAULT : 0;
17812275
include/uapi/linux/vfio.h+51−20
@@ -295,15 +295,38 @@ struct vfio_region_info_cap_type { · 294 unmodified lines
295295 __u32 subtype; /* type specific */
296296 };
297297
298+/*
299+ * List of region types, global per bus driver.
300+ * If you introduce a new type, please add it here.
301+ */
302+
303+/* PCI region type containing a PCI vendor part */
298304 #define VFIO_REGION_TYPE_PCI_VENDOR_TYPE (1 << 31)
299305 #define VFIO_REGION_TYPE_PCI_VENDOR_MASK (0xffff)
306+#define VFIO_REGION_TYPE_GFX (1)
307+#define VFIO_REGION_TYPE_CCW (2)
308+
309+/* sub-types for VFIO_REGION_TYPE_PCI_* */
300310
301−/* 8086 Vendor sub-types */
311+/* 8086 vendor PCI sub-types */
302312 #define VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION (1)
303313 #define VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG (2)
304314 #define VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG (3)
305315
306−#define VFIO_REGION_TYPE_GFX (1)
316+/* 10de vendor PCI sub-types */
317+/*
318+ * NVIDIA GPU NVlink2 RAM is coherent RAM mapped onto the host address space.
319+ */
320+#define VFIO_REGION_SUBTYPE_NVIDIA_NVLINK2_RAM (1)
321+
322+/* 1014 vendor PCI sub-types */
323+/*
324+ * IBM NPU NVlink2 ATSD (Address Translation Shootdown) register of NPU
325+ * to do TLB invalidation on a GPU.
326+ */
327+#define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD (1)
328+
329+/* sub-types for VFIO_REGION_TYPE_GFX */
307330 #define VFIO_REGION_SUBTYPE_GFX_EDID (1)
308331
309332 /**
@@ -353,25 +376,9 @@ struct vfio_region_gfx_edid { · 43 unmodified lines
353376 #define VFIO_DEVICE_GFX_LINK_STATE_DOWN 2
354377 };
355378
356−#define VFIO_REGION_TYPE_CCW (2)
357−/* ccw sub-types */
379+/* sub-types for VFIO_REGION_TYPE_CCW */
358380 #define VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD (1)
359381
360−/*
361− * 10de vendor sub-type
362− *
363− * NVIDIA GPU NVlink2 RAM is coherent RAM mapped onto the host address space.
364− */
365−#define VFIO_REGION_SUBTYPE_NVIDIA_NVLINK2_RAM (1)
366−
367−/*
368− * 1014 vendor sub-type
369− *
370− * IBM NPU NVlink2 ATSD (Address Translation Shootdown) register of NPU
371− * to do TLB invalidation on a GPU.
372− */
373−#define VFIO_REGION_SUBTYPE_IBM_NVLINK2_ATSD (1)
374−
375382 /*
376383 * The MSIX mappable capability informs that MSIX data of a BAR can be mmapped
377384 * which allows direct access to non-MSIX registers which happened to be within
@@ -714,7 +721,31 @@ struct vfio_iommu_type1_info { · 336 unmodified lines
714721 __u32 argsz;
715722 __u32 flags;
716723 #define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */
717− __u64 iova_pgsizes; /* Bitmap of supported page sizes */
724+#define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */
725+ __u64 iova_pgsizes; /* Bitmap of supported page sizes */
726+ __u32 cap_offset; /* Offset within info struct of first cap */
727+};
728+
729+/*
730+ * The IOVA capability allows to report the valid IOVA range(s)
731+ * excluding any non-relaxable reserved regions exposed by
732+ * devices attached to the container. Any DMA map attempt
733+ * outside the valid iova range will return error.
734+ *
735+ * The structures below define version 1 of this capability.
736+ */
737+#define VFIO_IOMMU_TYPE1_INFO_CAP_IOVA_RANGE 1
738+
739+struct vfio_iova_range {
740+ __u64 start;
741+ __u64 end;
742+};
743+
744+struct vfio_iommu_type1_info_cap_iova_range {
745+ struct vfio_info_cap_header header;
746+ __u32 nr_iovas;
747+ __u32 reserved;
748+ struct vfio_iova_range iova_ranges[];
718749 };
719750
720751 #define VFIO_IOMMU_GET_INFO _IO(VFIO_TYPE, VFIO_BASE + 12)
samples/vfio-mdev/mtty.c+8−31
@@ -152,20 +152,9 @@ static const struct file_operations vd_fops = { · 151 unmodified lines
152152
153153 /* function prototypes */
154154
155−static int mtty_trigger_interrupt(const guid_t *uuid);
155+static int mtty_trigger_interrupt(struct mdev_state *mdev_state);
156156
157157 /* Helper functions */
158−static struct mdev_state *find_mdev_state_by_uuid(const guid_t *uuid)
159−{
160− struct mdev_state *mds;
161−
162− list_for_each_entry(mds, &mdev_devices_list, next) {
163− if (guid_equal(mdev_uuid(mds->mdev), uuid))
164− return mds;
165− }
166−
167− return NULL;
168−}
169158
170159 static void dump_buffer(u8 *buf, uint32_t count)
171160 {
@@ -337,8 +326,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, · 165 unmodified lines
337326 pr_err("Serial port %d: Fifo level trigger\n",
338327 index);
339328 #endif
340− mtty_trigger_interrupt(
341− mdev_uuid(mdev_state->mdev));
329+ mtty_trigger_interrupt(mdev_state);
342330 }
343331 } else {
344332 #if defined(DEBUG_INTR)
@@ -352,8 +340,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, · 7 unmodified lines
352340 */
353341 if (mdev_state->s[index].uart_reg[UART_IER] &
354342 UART_IER_RLSI)
355− mtty_trigger_interrupt(
356− mdev_uuid(mdev_state->mdev));
343+ mtty_trigger_interrupt(mdev_state);
357344 }
358345 mutex_unlock(&mdev_state->rxtx_lock);
359346 break;
@@ -372,8 +359,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, · 12 unmodified lines
372359 pr_err("Serial port %d: IER_THRI write\n",
373360 index);
374361 #endif
375− mtty_trigger_interrupt(
376− mdev_uuid(mdev_state->mdev));
362+ mtty_trigger_interrupt(mdev_state);
377363 }
378364
379365 mutex_unlock(&mdev_state->rxtx_lock);
@@ -444,7 +430,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, · 64 unmodified lines
444430 #if defined(DEBUG_INTR)
445431 pr_err("Serial port %d: MCR_OUT2 write\n", index);
446432 #endif
447− mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
433+ mtty_trigger_interrupt(mdev_state);
448434 }
449435
450436 if ((mdev_state->s[index].uart_reg[UART_IER] & UART_IER_MSI) &&
@@ -452,7 +438,7 @@ static void handle_bar_write(unsigned int index, struct mdev_state *mdev_state, · 1 unmodified line
452438 #if defined(DEBUG_INTR)
453439 pr_err("Serial port %d: MCR RTS/DTR write\n", index);
454440 #endif
455− mtty_trigger_interrupt(mdev_uuid(mdev_state->mdev));
441+ mtty_trigger_interrupt(mdev_state);
456442 }
457443 break;
458444
@@ -503,8 +489,7 @@ static void handle_bar_read(unsigned int index, struct mdev_state *mdev_state, · 44 unmodified lines
503489 #endif
504490 if (mdev_state->s[index].uart_reg[UART_IER] &
505491 UART_IER_THRI)
506− mtty_trigger_interrupt(
507− mdev_uuid(mdev_state->mdev));
492+ mtty_trigger_interrupt(mdev_state);
508493 }
509494 mutex_unlock(&mdev_state->rxtx_lock);
510495
@@ -1028,17 +1013,9 @@ static int mtty_set_irqs(struct mdev_device *mdev, uint32_t flags, · 517 unmodified lines
10281013 return ret;
10291014 }
10301015
1031−static int mtty_trigger_interrupt(const guid_t *uuid)
1016+static int mtty_trigger_interrupt(struct mdev_state *mdev_state)
10321017 {
10331018 int ret = -1;
1034− struct mdev_state *mdev_state;
1035−
1036− mdev_state = find_mdev_state_by_uuid(uuid);
1037−
1038− if (!mdev_state) {
1039− pr_info("%s: mdev not found\n", __func__);
1040− return -EINVAL;
1041− }
10421019
10431020 if ((mdev_state->irq_index == VFIO_PCI_MSI_IRQ_INDEX) &&
10441021 (!mdev_state->msi_evtfd))

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t