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

[xen stable-4.18] x86/iommu: check for CMPXCHG16B when enabling IOMMU



commit 413945d3eeebba66b2613d24192f53f73117717c
Author:     Teddy Astie <teddy.astie@xxxxxxxxxx>
AuthorDate: Mon Feb 17 13:29:27 2025 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Mon Feb 17 13:29:27 2025 +0100

    x86/iommu: check for CMPXCHG16B when enabling IOMMU
    
    All hardware with VT-d/AMD-Vi has CMPXCHG16B support. Check this at
    initialisation time, and otherwise refuse to use the IOMMU.
    
    If the local APICs support x2APIC mode the IOMMU support for interrupt
    remapping will be checked earlier using a specific helper.  If no support
    for CX16 is detected by that earlier hook disable the IOMMU at that point
    and prevent further poking for CX16 later in the boot process, which would
    also fail.
    
    There's a possible corner case when running virtualized, and the underlying
    hypervisor exposing an IOMMU but no CMPXCHG16B support.  In which case
    ignoring the IOMMU is fine, albeit the most natural would be for the
    underlying hypervisor to also expose CMPXCHG16B support if an IOMMU is
    available to the VM.
    
    Note this change only introduces the checks, but doesn't remove the now
    stale checks for CX16 support sprinkled in the IOMMU code.  Further changes
    will take care of that.
    
    Suggested-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    master commit: 2636fcdc15c707d5e097770133f0afb69e8d70c9
    master date: 2025-01-27 13:05:11 +0100
---
 xen/drivers/passthrough/amd/iommu_intr.c    | 13 +++++++++++++
 xen/drivers/passthrough/amd/pci_amd_iommu.c |  6 ++++++
 xen/drivers/passthrough/vtd/intremap.c      | 13 +++++++++++++
 xen/drivers/passthrough/vtd/iommu.c         |  7 +++++++
 4 files changed, 39 insertions(+)

diff --git a/xen/drivers/passthrough/amd/iommu_intr.c 
b/xen/drivers/passthrough/amd/iommu_intr.c
index d9eefcd8e4..040927b6d0 100644
--- a/xen/drivers/passthrough/amd/iommu_intr.c
+++ b/xen/drivers/passthrough/amd/iommu_intr.c
@@ -648,6 +648,19 @@ bool __init cf_check iov_supports_xt(void)
     if ( !iommu_enable || !iommu_intremap )
         return false;
 
+    if ( unlikely(!cpu_has_cx16) )
+    {
+        AMD_IOMMU_ERROR("no CMPXCHG16B support, disabling IOMMU\n");
+        /*
+         * Disable IOMMU support at once: there's no reason to check for CX16
+         * yet again when attempting to initialize IOMMU DMA remapping
+         * functionality or interrupt remapping without x2APIC support.
+         */
+        iommu_enable = false;
+        iommu_intremap = iommu_intremap_off;
+        return false;
+    }
+
     if ( amd_iommu_prepare(true) )
         return false;
 
diff --git a/xen/drivers/passthrough/amd/pci_amd_iommu.c 
b/xen/drivers/passthrough/amd/pci_amd_iommu.c
index 6bc73dc210..40a56008aa 100644
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
@@ -305,6 +305,12 @@ static int __init cf_check iov_detect(void)
     if ( !iommu_enable && !iommu_intremap )
         return 0;
 
+    if ( unlikely(!cpu_has_cx16) )
+    {
+        AMD_IOMMU_ERROR("no CMPXCHG16B support, disabling IOMMU\n");
+        return -ENODEV;
+    }
+
     if ( (init_done ? amd_iommu_init_late()
                     : amd_iommu_init(false)) != 0 )
     {
diff --git a/xen/drivers/passthrough/vtd/intremap.c 
b/xen/drivers/passthrough/vtd/intremap.c
index c504852eb8..233db5cb64 100644
--- a/xen/drivers/passthrough/vtd/intremap.c
+++ b/xen/drivers/passthrough/vtd/intremap.c
@@ -150,6 +150,19 @@ bool __init cf_check intel_iommu_supports_eim(void)
     if ( !iommu_qinval || !iommu_intremap || list_empty(&acpi_drhd_units) )
         return false;
 
+    if ( unlikely(!cpu_has_cx16) )
+    {
+        printk(XENLOG_ERR VTDPREFIX "no CMPXCHG16B support, disabling 
IOMMU\n");
+        /*
+         * Disable IOMMU support at once: there's no reason to check for CX16
+         * yet again when attempting to initialize IOMMU DMA remapping
+         * functionality or interrupt remapping without x2APIC support.
+         */
+        iommu_enable = false;
+        iommu_intremap = iommu_intremap_off;
+        return false;
+    }
+
     /* We MUST have a DRHD unit for each IOAPIC. */
     for ( apic = 0; apic < nr_ioapics; apic++ )
         if ( !ioapic_to_drhd(IO_APIC_ID(apic)) )
diff --git a/xen/drivers/passthrough/vtd/iommu.c 
b/xen/drivers/passthrough/vtd/iommu.c
index 9ed616e211..a6f0071fe9 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -2631,6 +2631,13 @@ static int __init cf_check vtd_setup(void)
     int ret;
     bool reg_inval_supported = true;
 
+    if ( unlikely(!cpu_has_cx16) )
+    {
+        printk(XENLOG_ERR VTDPREFIX "no CMPXCHG16B support, disabling 
IOMMU\n");
+        ret = -ENODEV;
+        goto error;
+    }
+
     if ( list_empty(&acpi_drhd_units) )
     {
         ret = -ENODEV;
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.18



 


Rackspace

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