[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2] pci/ats: do not allow broken devices to be assigned to guests


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • Date: Thu, 24 Feb 2022 17:37:01 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=Yeyjqo6BAR6+mndrcxmXz+lkFiDgi+mh4YsAir/cbrI=; b=AzV9FTrRBv2o4E0UwqOI0GJVSqUH39Y3I5N9G/dVWjS+Vsjoe0zQL9aIefwf9JB/Ie23ijs5Z57Ts+A/5VbNMnVg6tuZXMXRK1kaJBPchQbBnWO3WtauiaIgatoxyvGz80cL6JATvKAlzQY++dDTw1Lvxjd5H8FEFg6Bbwosthf7BlhlgXw7yTYuxAh/GJaxJF/5YFUdKCnWJL4UEyCQWBUuamCh4OMimsHlRFX3wxHKSbWpiBxiPrmnF9n2VsuiQjVYCCME+4QIDCT9p3tRvwq0dGSEIw4jr5Mf01knYEBccPvOtym5WS0R3fizRKcO1TD7DEECsuNzddvnDfelGw==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KXkrGviOt2pG4WfAHMClrh6Ik3H0DNSnOn99ENfvzmZ5F8vCJLW5AcdE9DcyyqqfHUlTAYQr7JXp7HEpldBW12AoNtS9VMDZhG0wofnBaeIw59lW9AqlyX+wGlOKHxQwFZoMXxrtpplarrRoptm9x0FMVR8VQ/PzE/Zguu9gDiGjqfGOORkjnUjfq3fBBk0/cEZD5MvCFQ5oZq0iuishErfGFa3u6ZD7boP4PRaq6y9ReUOq7GbWhkLsN3ZVe5sNVRAnISAo3QTYAKY05Ib2uXwK0M/ftUNXb15PgreyzYOgYL4D5O2lFCtjRtPHggS61WHz2DLzXJWq+L74Xh7N7A==
  • Authentication-results: esa4.hc3370-68.iphmx.com; dkim=pass (signature verified) header.i=@citrix.onmicrosoft.com
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Paul Durrant <paul@xxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, George Dunlap <george.dunlap@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Kevin Tian <kevin.tian@xxxxxxxxx>, Oleksandr Andrushchenko <andr2000@xxxxxxxxx>
  • Delivery-date: Thu, 24 Feb 2022 16:37:34 +0000
  • Ironport-data: A9a23:jdxGlqKOs49YKtNoFE+RJpUlxSXFcZb7ZxGr2PjKsXjdYENSgjdWy 2IdWjvTbq7cM2OkL49yPovjpB9SvMfcxoUwGlBlqX01Q3x08seUXt7xwmUcns+xwm8vaGo9s q3yv/GZdJhcokf0/0vrav67xZVF/fngqoDUUYYoAQgsA148IMsdoUg7wbRh2NQ02YPR7z6l4 rseneWOYDdJ5BYsWo4kw/rrRMRH5amaVJsw5zTSVNgT1LPsvyB94KE3fMldG0DQUIhMdtNWc s6YpF2PEsE1yD92Yj+tuu6TnkTn2dc+NyDW4pZdc/DKbhSvOkXee0v0XRYRQR4/ttmHozx+4 NQRvMCXZgMLApePt+oYehB7MA1kJLITrdcrIVDn2SCS50jPcn+qyPRyFkAme4Yf/46bA0kXq 6ZecmpUKEne2aTmm9pXScE17ignBNPsM44F/Glp0BnSDOo8QICFSKLPjTNd9Glv35AVQ66BD yYfQWVvTB+eQAdDBk4GKJIGkuyFr3fEdCIN/Tp5ooJoujOOnWSdyoPFL979atGMA8JPkS6wv Xna9m70BhUbMt23yjef9H+owOjVkkvTUYQeDufgrqZCj1iax2hVAxoTPXO4rOe4jAiiWttZA 00S5icq66M18SSDTNPwQhm5q36spQMHVpxbFOhSwBGAzO/Y7hiUAkAATyVdc5o2uckuXzso2 1SV2dTzClRHsqCRSH+b3qeZq3W1Iyd9BXcLeCssXQYDpd75r+kOYgnnF4g5VvTv15usRG+2k 2viQDUCa6s7jJICi4KU+XL7uXGDqJ3gRy0Wyh/OQTfwhu9mX7KNa4ut4FndyP9PKoeFU1WM1 EQ5d9iiAPMmVs/UynHUKAkZNPTwvqvebmWA6bJ6N8R5r1yQF2ifkZe8Cd2UDGNgKY46dDDge yc/UisBtcYIbBNGgUKaCr9d6vjGL4C9TbwJtdiON7Kih6SdkifdokmCgmbKggjQfLAEy/1XB HtiWZ/E4YwmIapm1iGqYOwWzKUmwCszrUuKG8ymkUj9jeDFOybOIVvgDLdoRrpnhE9jiF+Im +uzyuPQk0kPOAEASnO/HXEvwaAiciFgWMGeRz1/fe+fOAt2cFzN+NeKqY7Nj7dNxvwP/s+Rp ynVchYBlDLX2C2WQS3XOysLQO6+Av5CQYcTYHVE0aCAgCN4P+5CLc43KvMKQFXQ3LY9laUtF 6FdIa1twJ1nE1z6xtjUVrGkxKRKfxW3nwOeeS2jZTk0ZZl7QALVvNTje2PSGOMmV0JbaeNWT 2Wc6z7m
  • Ironport-hdrordr: A9a23:g9xeUaov9XioBRaDGViMpT4aV5oveYIsimQD101hICG9Ffbo8P xG/c5rsSMc7Qx7ZJhOo7y90cW7Lk80lqQU3WByB9mftWDd0QPDQb2KhrGC/xTQXwH46+5Bxe NBXsFFebjN5IFB/KXHCd+DYrQd/OU=
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Introduce a new field to mark devices as broken: having it set
prevents the device from being assigned to guests. Use the field in
order to mark ATS devices that have failed a flush as broken, thus
preventing them to be assigned to any guest.

This allows the device IOMMU context entry to be cleaned up properly,
as calling _pci_hide_device will just change the ownership of the
device, but the IOMMU context entry of the device would be left as-is.
It would also leak a Domain ID, as removing the device from it's
previous owner will allow releasing the DID used by the device without
having cleaned up the context entry.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
Cc: Oleksandr Andrushchenko <andr2000@xxxxxxxxx>
---
Changes since v1:
 - Allow assigning broken devices to dom_io or the hardware domain.
---
 xen/drivers/passthrough/pci.c        | 11 +++++++----
 xen/drivers/passthrough/vtd/qinval.c |  8 +++++++-
 xen/include/xen/pci.h                |  3 +++
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 70b6684981..91b43a3f04 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -501,7 +501,7 @@ static void free_pdev(struct pci_seg *pseg, struct pci_dev 
*pdev)
     xfree(pdev);
 }
 
-static void _pci_hide_device(struct pci_dev *pdev)
+static void __init _pci_hide_device(struct pci_dev *pdev)
 {
     if ( pdev->domain )
         return;
@@ -1487,6 +1487,11 @@ static int assign_device(struct domain *d, u16 seg, u8 
bus, u8 devfn, u32 flag)
     ASSERT(pdev && (pdev->domain == hardware_domain ||
                     pdev->domain == dom_io));
 
+    /* Do not allow broken devices to be assigned to guests. */
+    rc = -EBADF;
+    if ( pdev->broken && d != hardware_domain && d != dom_io )
+        goto done;
+
     rc = pdev_msix_assign(d, pdev);
     if ( rc )
         goto done;
@@ -1585,9 +1590,7 @@ void iommu_dev_iotlb_flush_timeout(struct domain *d, 
struct pci_dev *pdev)
         return;
     }
 
-    list_del(&pdev->domain_list);
-    pdev->domain = NULL;
-    _pci_hide_device(pdev);
+    pdev->broken = true;
 
     if ( !d->is_shutting_down && printk_ratelimit() )
         printk(XENLOG_ERR "dom%d: ATS device %pp flush failed\n",
diff --git a/xen/drivers/passthrough/vtd/qinval.c 
b/xen/drivers/passthrough/vtd/qinval.c
index 9f291f47e5..510961a203 100644
--- a/xen/drivers/passthrough/vtd/qinval.c
+++ b/xen/drivers/passthrough/vtd/qinval.c
@@ -227,7 +227,7 @@ static int __must_check dev_invalidate_sync(struct 
vtd_iommu *iommu,
 
     ASSERT(iommu->qinval_maddr);
     rc = queue_invalidate_wait(iommu, 0, 1, 1, 1);
-    if ( rc == -ETIMEDOUT )
+    if ( rc == -ETIMEDOUT && !pdev->broken )
     {
         struct domain *d = rcu_lock_domain_by_id(did_to_domain_id(iommu, did));
 
@@ -241,6 +241,12 @@ static int __must_check dev_invalidate_sync(struct 
vtd_iommu *iommu,
         iommu_dev_iotlb_flush_timeout(d, pdev);
         rcu_unlock_domain(d);
     }
+    else if ( rc == -ETIMEDOUT )
+        /*
+         * The device is already marked as broken, ignore the error in order to
+         * allow {de,}assign to succeed.
+         */
+        rc = 0;
 
     return rc;
 }
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index b6d7e454f8..02b31f7259 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -108,6 +108,9 @@ struct pci_dev {
     /* Device with errata, ignore the BARs. */
     bool ignore_bars;
 
+    /* Device misbehaving, prevent assigning it to guests. */
+    bool broken;
+
     enum pdev_type {
         DEV_TYPE_PCI_UNKNOWN,
         DEV_TYPE_PCIe_ENDPOINT,
-- 
2.34.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.