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

[xen stable-4.21] iommu/amd-vi: do not zero IOMMU MMIO region



commit 088b93121e79a6b23b54ebe545913cdca9cba2a8
Author:     Roger Pau Monné <roger.pau@xxxxxxxxxx>
AuthorDate: Tue Jun 30 14:50:58 2026 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Jun 30 14:50:58 2026 +0200

    iommu/amd-vi: do not zero IOMMU MMIO region
    
    Attempting to memset the whole IOMMU MMIO region to zero is dangerous to
    say the least.  We don't know which registers might be there, nor which
    values might be safe for those registers.  On a forthcoming platform doing
    the zeroing of the MMIO region does put the IOMMU in a broken state, which
    is not recoverable by the IOMMU initialization procedure in Xen.
    
    Instead just zero the control register, which mimics the current behavior
    with regards to how the control register is handled, and ensures the IOMU
    setup is done with the unit disabled.  This approach will need revisiting
    in order to support Preboot DMA Protection.
    
    Fold map_iommu_mmio_region() into its only caller, as the function body is
    just an ioremap() call after the removal of the memset().
    
    Fixes: 0700c962ac2d ("Add AMD IOMMU support into hypervisor")
    Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper@xxxxxxxxxx>
    master commit: bdb30883f3528676f8b736e4ec0e475914289993
    master date: 2026-05-06 18:56:59 +0200
---
 xen/drivers/passthrough/amd/iommu_init.c | 33 ++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/xen/drivers/passthrough/amd/iommu_init.c 
b/xen/drivers/passthrough/amd/iommu_init.c
index 00d2c46cbc..708572a657 100644
--- a/xen/drivers/passthrough/amd/iommu_init.c
+++ b/xen/drivers/passthrough/amd/iommu_init.c
@@ -42,18 +42,6 @@ static bool iommu_has_ht_flag(struct amd_iommu *iommu, u8 
mask)
     return iommu->ht_flags & mask;
 }
 
-static int __init map_iommu_mmio_region(struct amd_iommu *iommu)
-{
-    iommu->mmio_base = ioremap(iommu->mmio_base_phys,
-                               IOMMU_MMIO_REGION_LENGTH);
-    if ( !iommu->mmio_base )
-        return -ENOMEM;
-
-    memset(iommu->mmio_base, 0, IOMMU_MMIO_REGION_LENGTH);
-
-    return 0;
-}
-
 static void __init unmap_iommu_mmio_region(struct amd_iommu *iommu)
 {
     if ( iommu->mmio_base )
@@ -1367,11 +1355,14 @@ static int __init amd_iommu_prepare_one(struct 
amd_iommu *iommu)
 {
     int rc = alloc_ivrs_mappings(iommu->sbdf.seg);
 
-    if ( !rc )
-        rc = map_iommu_mmio_region(iommu);
     if ( rc )
         return rc;
 
+    iommu->mmio_base = ioremap(iommu->mmio_base_phys,
+                               IOMMU_MMIO_REGION_LENGTH);
+    if ( !iommu->mmio_base )
+        return -ENOMEM;
+
     get_iommu_features(iommu);
 
     /*
@@ -1381,6 +1372,20 @@ static int __init amd_iommu_prepare_one(struct amd_iommu 
*iommu)
     if ( amd_iommu_max_paging_mode < amd_iommu_min_paging_mode )
         return -ERANGE;
 
+    /*
+     * Check whether the IOMMU is already enabled and unconditionally disable
+     * it (zero the control register) ahead of Xen setup.  Needs to be
+     * revisited to support Preboot DMA Protection.
+     */
+    iommu->ctrl.raw = readq(iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
+    if ( iommu->ctrl.iommu_en )
+        printk(XENLOG_WARNING
+               "AMD-Vi: IOMMU %pp enabled by firmware (ctrl %016lx)\n",
+               &iommu->sbdf, iommu->ctrl.raw);
+
+    iommu->ctrl.raw = 0;
+    writeq(0, iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
+
     return 0;
 }
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.21



 


Rackspace

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