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

[xen staging] VT-d: correct ATS checking for root complex integrated devices



commit 04e31583bab97e5042a44a1d00fce2760272635f
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Mon May 6 09:22:45 2024 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon May 6 09:22:45 2024 +0200

    VT-d: correct ATS checking for root complex integrated devices
    
    Spec version 4.1 says
    
    "The ATSR structures identifies PCI Express Root-Ports supporting
     Address Translation Services (ATS) transactions. Software must enable
     ATS on endpoint devices behind a Root Port only if the Root Port is
     reported as supporting ATS transactions."
    
    Clearly root complex integrated devices aren't "behind root ports",
    matching my observation on a SapphireRapids system having an ATS-
    capable root complex integrated device. Hence for such devices we
    shouldn't try to locate a corresponding ATSR.
    
    Since both pci_find_ext_capability() and pci_find_cap_offset() return
    "unsigned int", change "pos" to that type at the same time.
    
    Fixes: 903b93211f56 ("[VTD] laying the ground work for ATS")
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
 xen/drivers/passthrough/vtd/x86/ats.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/xen/drivers/passthrough/vtd/x86/ats.c 
b/xen/drivers/passthrough/vtd/x86/ats.c
index 1f5913bed9..61052ef580 100644
--- a/xen/drivers/passthrough/vtd/x86/ats.c
+++ b/xen/drivers/passthrough/vtd/x86/ats.c
@@ -44,7 +44,7 @@ struct acpi_drhd_unit *find_ats_dev_drhd(struct vtd_iommu 
*iommu)
 int ats_device(const struct pci_dev *pdev, const struct acpi_drhd_unit *drhd)
 {
     struct acpi_drhd_unit *ats_drhd;
-    int pos;
+    unsigned int pos, expfl = 0;
 
     if ( !ats_enabled || !iommu_qinval )
         return 0;
@@ -53,7 +53,12 @@ int ats_device(const struct pci_dev *pdev, const struct 
acpi_drhd_unit *drhd)
          !ecap_dev_iotlb(drhd->iommu->ecap) )
         return 0;
 
-    if ( !acpi_find_matched_atsr_unit(pdev) )
+    pos = pci_find_cap_offset(pdev->sbdf, PCI_CAP_ID_EXP);
+    if ( pos )
+        expfl = pci_conf_read16(pdev->sbdf, pos + PCI_EXP_FLAGS);
+
+    if ( MASK_EXTR(expfl, PCI_EXP_FLAGS_TYPE) != PCI_EXP_TYPE_RC_END &&
+         !acpi_find_matched_atsr_unit(pdev) )
         return 0;
 
     ats_drhd = find_ats_dev_drhd(drhd->iommu);
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

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