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

[PATCH] xen/pci: fix phantom error path in assign_device()


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
  • Date: Mon, 11 Dec 2023 10:05:18 -0500
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • 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=w6ZvA4TdDKNhBzcSXy8oJC5F2iCDXLgeBpL0NTM19/4=; b=US5hjk7U7PIDFPTuIuz61pPAgpK1IuYqNO1sb6+Ale5VcvSGx15Q87rjYNZHSS613i8WKzDdSHJVl6Q9KZRC8Ew6KJ67KkKbrkeSLpb7Mcz/TvroD7Q9Qk0/zvUY9LyV29FVZcbpH2qPpU1tulQY31WncHY85zvRqVSwCGXh4uXeGl7I5ejaYG/J+EdXYramZaZr9330xS6n2hkpOzvSyUNpidPhdFqzi5+1oi6wW7GFgrjUWn43repLnDUemNUqtxnAsMFoQAmmkslDGQGG3y1Jgrciv6AvXyvLNKKxBTvw/vMDsTnDvRmr8IjSdNt1/QpAbR+0je8DFUGBEzesPA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=N7eWvePlw1rD8vIPVYLqLRe7BXjhitnWH4S+rJsSB6t06m47K+YT5YWMLYV+xr6/bd8j7v9FdOpzH7lOej4md/Ljx+J53Jx7aFi9O+UAxROGtZSWDj0EkRmQAA85J2802XXALiMoiUTdx3tVnXuSRUsvRIq/qQsntwfHl0AFNKgb3S5KPdzJ86lOcGU7TEVj5x+shPaorWCn8JrQpj3eNqNajWiW6cUFFEMfpV0dkbaYOglashJVv1QJrI6FwnER+hC9ETLGnOq7E7coMPGE7Mu1OZ0UYRp7RAB6q6NEgjs7NuZv/Ntd+lTEzLRCedKXEq61MgI8sz5efo43iIap7w==
  • Cc: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Paul Durrant <paul@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Mon, 11 Dec 2023 15:05:43 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Currently if an iommu_call() for a phantom function fails, there is no
indication of the failure. Propagate (but don't return) the error code
from the most recently failed iommu_call() and emit a warning. While
here, add a comment to clarify that the loop keeps iterating even when
failure is encountered.

Fixes: cd7dedad8209 ("passthrough: simplify locking and logging")
Signed-off-by: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
---
Unlike assign_device(), deassign_device() breaks out of the phantom loop
when a failure is encountered and returns the error code. I'm curious
why assign_device() and deassign_device() behave differently? It looks
like it's been that way since
4e9950dc1bd2 ("IOMMU: add phantom function support"). I was initially
inclined to break out of the loop and return the error code in
assign_device(), but adhering to the principle of Chesterton's fence,
I'd first like to understand why this is not currently being done.

I'm aware that I could have avoided introducing a tmp local variable by
using the conditional operator with omitted middle operand:

    rc_nonfatal = iommu_call(...) ?: rc_nonfatal;

However, I explicitly chose not to do this to avoid relying on a GNU
extension in yet another place.
---
 xen/drivers/passthrough/pci.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index 28ed8ea8172a..71072efceb7a 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -1407,7 +1407,7 @@ static int assign_device(struct domain *d, u16 seg, u8 
bus, u8 devfn, u32 flag)
 {
     const struct domain_iommu *hd = dom_iommu(d);
     struct pci_dev *pdev;
-    int rc = 0;
+    int rc = 0, rc_nonfatal = 0;
 
     if ( !is_iommu_enabled(d) )
         return 0;
@@ -1443,21 +1443,28 @@ static int assign_device(struct domain *d, u16 seg, u8 
bus, u8 devfn, u32 flag)
                           pci_to_dev(pdev), flag)) )
         goto done;
 
-    for ( ; pdev->phantom_stride; rc = 0 )
+    while ( pdev->phantom_stride )
     {
+        int tmp;
+
         devfn += pdev->phantom_stride;
         if ( PCI_SLOT(devfn) != PCI_SLOT(pdev->devfn) )
+        {
+            devfn -= pdev->phantom_stride; /* Adjust for printing */
             break;
+        }
-        rc = iommu_call(hd->platform_ops, assign_device, d, devfn,
-                        pci_to_dev(pdev), flag);
+        tmp = iommu_call(hd->platform_ops, assign_device, d, devfn,
+                         pci_to_dev(pdev), flag);
+        rc_nonfatal = tmp ? tmp : rc_nonfatal;
+        /* Keep iterating even if the iommu call failed. */
     }
 
  done:
-    if ( rc )
+    if ( rc || rc_nonfatal )
         printk(XENLOG_G_WARNING "%pd: assign (%pp) failed (%d)\n",
-               d, &PCI_SBDF(seg, bus, devfn), rc);
+               d, &PCI_SBDF(seg, bus, devfn), rc ? rc : rc_nonfatal);
     /* The device is assigned to dom_io so mark it as quarantined */
-    else if ( d == dom_io )
+    if ( !rc && d == dom_io )
         pdev->quarantine = true;
 
     return rc;

base-commit: 1403131596fa77663708f6baa0fee8bf7b95eb5a
-- 
2.43.0




 


Rackspace

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