Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfio-v5.18-rc3' of https://github.com/awilliam/linux-vfio

Pull vfio fix from Alex Williamson:

- Fix VF token checking for vfio-pci variant drivers (Jason Gunthorpe)

* tag 'vfio-v5.18-rc3' of https://github.com/awilliam/linux-vfio:
vfio/pci: Fix vf_token mechanism when device-specific VF drivers are used

+76 -50
+74 -50
drivers/vfio/pci/vfio_pci_core.c
··· 36 36 static bool disable_vga; 37 37 static bool disable_idle_d3; 38 38 39 + /* List of PF's that vfio_pci_core_sriov_configure() has been called on */ 40 + static DEFINE_MUTEX(vfio_pci_sriov_pfs_mutex); 41 + static LIST_HEAD(vfio_pci_sriov_pfs); 42 + 39 43 static inline bool vfio_vga_disabled(void) 40 44 { 41 45 #ifdef CONFIG_VFIO_PCI_VGA ··· 438 434 } 439 435 EXPORT_SYMBOL_GPL(vfio_pci_core_disable); 440 436 441 - static struct vfio_pci_core_device *get_pf_vdev(struct vfio_pci_core_device *vdev) 442 - { 443 - struct pci_dev *physfn = pci_physfn(vdev->pdev); 444 - struct vfio_device *pf_dev; 445 - 446 - if (!vdev->pdev->is_virtfn) 447 - return NULL; 448 - 449 - pf_dev = vfio_device_get_from_dev(&physfn->dev); 450 - if (!pf_dev) 451 - return NULL; 452 - 453 - if (pci_dev_driver(physfn) != pci_dev_driver(vdev->pdev)) { 454 - vfio_device_put(pf_dev); 455 - return NULL; 456 - } 457 - 458 - return container_of(pf_dev, struct vfio_pci_core_device, vdev); 459 - } 460 - 461 - static void vfio_pci_vf_token_user_add(struct vfio_pci_core_device *vdev, int val) 462 - { 463 - struct vfio_pci_core_device *pf_vdev = get_pf_vdev(vdev); 464 - 465 - if (!pf_vdev) 466 - return; 467 - 468 - mutex_lock(&pf_vdev->vf_token->lock); 469 - pf_vdev->vf_token->users += val; 470 - WARN_ON(pf_vdev->vf_token->users < 0); 471 - mutex_unlock(&pf_vdev->vf_token->lock); 472 - 473 - vfio_device_put(&pf_vdev->vdev); 474 - } 475 - 476 437 void vfio_pci_core_close_device(struct vfio_device *core_vdev) 477 438 { 478 439 struct vfio_pci_core_device *vdev = 479 440 container_of(core_vdev, struct vfio_pci_core_device, vdev); 480 441 481 - vfio_pci_vf_token_user_add(vdev, -1); 442 + if (vdev->sriov_pf_core_dev) { 443 + mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock); 444 + WARN_ON(!vdev->sriov_pf_core_dev->vf_token->users); 445 + vdev->sriov_pf_core_dev->vf_token->users--; 446 + mutex_unlock(&vdev->sriov_pf_core_dev->vf_token->lock); 447 + } 482 448 vfio_spapr_pci_eeh_release(vdev->pdev); 483 449 vfio_pci_core_disable(vdev); 484 450 ··· 469 495 { 470 496 vfio_pci_probe_mmaps(vdev); 471 497 vfio_spapr_pci_eeh_open(vdev->pdev); 472 - vfio_pci_vf_token_user_add(vdev, 1); 498 + 499 + if (vdev->sriov_pf_core_dev) { 500 + mutex_lock(&vdev->sriov_pf_core_dev->vf_token->lock); 501 + vdev->sriov_pf_core_dev->vf_token->users++; 502 + mutex_unlock(&vdev->sriov_pf_core_dev->vf_token->lock); 503 + } 473 504 } 474 505 EXPORT_SYMBOL_GPL(vfio_pci_core_finish_enable); 475 506 ··· 1562 1583 * 1563 1584 * If the VF token is provided but unused, an error is generated. 1564 1585 */ 1565 - if (!vdev->pdev->is_virtfn && !vdev->vf_token && !vf_token) 1566 - return 0; /* No VF token provided or required */ 1567 - 1568 1586 if (vdev->pdev->is_virtfn) { 1569 - struct vfio_pci_core_device *pf_vdev = get_pf_vdev(vdev); 1587 + struct vfio_pci_core_device *pf_vdev = vdev->sriov_pf_core_dev; 1570 1588 bool match; 1571 1589 1572 1590 if (!pf_vdev) { ··· 1576 1600 } 1577 1601 1578 1602 if (!vf_token) { 1579 - vfio_device_put(&pf_vdev->vdev); 1580 1603 pci_info_ratelimited(vdev->pdev, 1581 1604 "VF token required to access device\n"); 1582 1605 return -EACCES; ··· 1584 1609 mutex_lock(&pf_vdev->vf_token->lock); 1585 1610 match = uuid_equal(uuid, &pf_vdev->vf_token->uuid); 1586 1611 mutex_unlock(&pf_vdev->vf_token->lock); 1587 - 1588 - vfio_device_put(&pf_vdev->vdev); 1589 1612 1590 1613 if (!match) { 1591 1614 pci_info_ratelimited(vdev->pdev, ··· 1705 1732 static int vfio_pci_vf_init(struct vfio_pci_core_device *vdev) 1706 1733 { 1707 1734 struct pci_dev *pdev = vdev->pdev; 1735 + struct vfio_pci_core_device *cur; 1736 + struct pci_dev *physfn; 1708 1737 int ret; 1709 1738 1739 + if (pdev->is_virtfn) { 1740 + /* 1741 + * If this VF was created by our vfio_pci_core_sriov_configure() 1742 + * then we can find the PF vfio_pci_core_device now, and due to 1743 + * the locking in pci_disable_sriov() it cannot change until 1744 + * this VF device driver is removed. 1745 + */ 1746 + physfn = pci_physfn(vdev->pdev); 1747 + mutex_lock(&vfio_pci_sriov_pfs_mutex); 1748 + list_for_each_entry(cur, &vfio_pci_sriov_pfs, sriov_pfs_item) { 1749 + if (cur->pdev == physfn) { 1750 + vdev->sriov_pf_core_dev = cur; 1751 + break; 1752 + } 1753 + } 1754 + mutex_unlock(&vfio_pci_sriov_pfs_mutex); 1755 + return 0; 1756 + } 1757 + 1758 + /* Not a SRIOV PF */ 1710 1759 if (!pdev->is_physfn) 1711 1760 return 0; 1712 1761 ··· 1800 1805 INIT_LIST_HEAD(&vdev->ioeventfds_list); 1801 1806 mutex_init(&vdev->vma_lock); 1802 1807 INIT_LIST_HEAD(&vdev->vma_list); 1808 + INIT_LIST_HEAD(&vdev->sriov_pfs_item); 1803 1809 init_rwsem(&vdev->memory_lock); 1804 1810 } 1805 1811 EXPORT_SYMBOL_GPL(vfio_pci_core_init_device); ··· 1892 1896 { 1893 1897 struct pci_dev *pdev = vdev->pdev; 1894 1898 1895 - pci_disable_sriov(pdev); 1899 + vfio_pci_core_sriov_configure(pdev, 0); 1896 1900 1897 1901 vfio_unregister_group_dev(&vdev->vdev); 1898 1902 ··· 1931 1935 1932 1936 int vfio_pci_core_sriov_configure(struct pci_dev *pdev, int nr_virtfn) 1933 1937 { 1938 + struct vfio_pci_core_device *vdev; 1934 1939 struct vfio_device *device; 1935 1940 int ret = 0; 1941 + 1942 + device_lock_assert(&pdev->dev); 1936 1943 1937 1944 device = vfio_device_get_from_dev(&pdev->dev); 1938 1945 if (!device) 1939 1946 return -ENODEV; 1940 1947 1941 - if (nr_virtfn == 0) 1942 - pci_disable_sriov(pdev); 1943 - else 1948 + vdev = container_of(device, struct vfio_pci_core_device, vdev); 1949 + 1950 + if (nr_virtfn) { 1951 + mutex_lock(&vfio_pci_sriov_pfs_mutex); 1952 + /* 1953 + * The thread that adds the vdev to the list is the only thread 1954 + * that gets to call pci_enable_sriov() and we will only allow 1955 + * it to be called once without going through 1956 + * pci_disable_sriov() 1957 + */ 1958 + if (!list_empty(&vdev->sriov_pfs_item)) { 1959 + ret = -EINVAL; 1960 + goto out_unlock; 1961 + } 1962 + list_add_tail(&vdev->sriov_pfs_item, &vfio_pci_sriov_pfs); 1963 + mutex_unlock(&vfio_pci_sriov_pfs_mutex); 1944 1964 ret = pci_enable_sriov(pdev, nr_virtfn); 1965 + if (ret) 1966 + goto out_del; 1967 + ret = nr_virtfn; 1968 + goto out_put; 1969 + } 1945 1970 1971 + pci_disable_sriov(pdev); 1972 + 1973 + out_del: 1974 + mutex_lock(&vfio_pci_sriov_pfs_mutex); 1975 + list_del_init(&vdev->sriov_pfs_item); 1976 + out_unlock: 1977 + mutex_unlock(&vfio_pci_sriov_pfs_mutex); 1978 + out_put: 1946 1979 vfio_device_put(device); 1947 - 1948 - return ret < 0 ? ret : nr_virtfn; 1980 + return ret; 1949 1981 } 1950 1982 EXPORT_SYMBOL_GPL(vfio_pci_core_sriov_configure); 1951 1983
+2
include/linux/vfio_pci_core.h
··· 133 133 struct mutex ioeventfds_lock; 134 134 struct list_head ioeventfds_list; 135 135 struct vfio_pci_vf_token *vf_token; 136 + struct list_head sriov_pfs_item; 137 + struct vfio_pci_core_device *sriov_pf_core_dev; 136 138 struct notifier_block nb; 137 139 struct mutex vma_lock; 138 140 struct list_head vma_list;