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

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


  • To: Jan Beulich <jbeulich@xxxxxxxx>
  • From: Stewart Hildebrand <stewart.hildebrand@xxxxxxx>
  • Date: Mon, 11 Dec 2023 14:24:08 -0500
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=suse.com 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=X/cKIi6ylbISZGHYXDyEq2YiEkA7ShrGAbD3/GG60vQ=; b=EizNXBAxxmeB7FLrXEEUkFtprFbtunIECzHcsHfIkHzkodhc5dN1ZIQ27FroToNjfsztAzMU4amwjghmX5gZIqgmpGG8XyiwVci6yn0pcnYyltrX2evAtdgDN/8AzD/MuDmXA+m+5OBCQVJvPmi2wxurYIqR5Tjtpp08n0+XNN/Qc/JaMo3g7Cn4s26nFbyVABiqFAs0ACCd0RuPVjGQQhTMF/2NknjSAuReIVbHOv9qFYmQzTR5lSMY1V2eTddDSSDNoSAa2/Ucs+NaOz5RpmlCZ3szQg0poxQr1O7cAXN4868psq2T+eE967So51m/H7TMYbbRaZQi4NzLy4Jm0g==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cNc2CJ6EdKmnjycIWpOw4rGYl1d9KJIXxehYgrIaRf4i4ahpbmiPMraRavAA70N4wxIp7OYERyhQ4CpSB0pnUB8/V05YhI2soM9BDqh/F8BIsx1xsBD/mlAfMq6op7n25IzrQutXaypVm1SOWIjZidiSJwm1MuuFRQXlwdhbMXCJ+xiYuD1gtG/zEaqCyOzr/sbaZ7lP5HDS318ACJPW5rL2C8HVnuAZgZWcq+i+WQTqqwuqKZm0iiAYYRKm/MzGTARz7TyZUIAxXya697vLwq1gEPh3qPHoCACZwoOiF0ExSy8oDoIWLNhyVpR91w0kX1BisfLNjfquQXNK0Ma3WQ==
  • Cc: Paul Durrant <paul@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>, <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • Delivery-date: Mon, 11 Dec 2023 19:24:26 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

On 12/11/23 11:21, Jan Beulich wrote:
> On 11.12.2023 16:05, Stewart Hildebrand wrote:
>> 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.
> 
> It's been a long time, but seeing the same pattern for add/remove I think
> the idea was that a device may still work with its phantom functions not
> properly mapped in the IOMMU, whereas failure to unmap means a domain may
> retain (partial) access to a device.

Thanks for the info. I'll add something about this to the in-code comment (see 
below).

> 
>> 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.
> 
> Introducing a helper variable is certainly okay, if you think that's
> better. However, in cases like ...
> 
>> --- 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;
> 
> ... this, I'm relatively certain most maintainers would agree that using
> the extension will yield easier to read code. Plus there's no reason to
> avoid extensions we use widely anyway, as long as there's no (reasonably
> neat) way to express the same without using extensions.

OK, I'll use the extension.

> 
> Jan
> 
>> +        /* Keep iterating even if the iommu call failed. */

I'll change this in-code comment to:

        /*
         * Keep going in case of iommu_call failure for phantom functions. The
         * device may still be usable without phantom functions mapped in the
         * IOMMU.
         */

>>      }
>>  
>>   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
> 



 


Rackspace

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