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

[PATCH v2 2/2] iommu/amd-vi: do not zero IOMMU MMIO region


  • To: xen-devel@xxxxxxxxxxxxxxxxxxxx
  • From: Roger Pau Monne <roger.pau@xxxxxxxxxx>
  • Date: Wed, 6 May 2026 15:55:14 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; 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=xrwxSKkv7rRh6ev0v8/Wi7eDOFVfG4pmI1FUsQ+FFwI=; b=AAO5IAYZxj3gKj06n84P+d/bu/qLuE+XrNvYrVZmjpWJHQA1RMNuOr1jWYfPGbRMc2rtSgDNA6INlBMsoNIR+AKkgpc7pEGp8MBNYNGpjGWX0RtpZxV6WrhxGtLzZa2jsUL5ZlZf4IbfoMmZ0LRK17qvm681pT7Z11jnrmuFijIKqSTe6YZWyIhwHd/L9y4Ho/jZ5v0YMTS93lgCXuT8/kXOr2r6NAXeXYqU1mSVwuevNvmcIPARUKTWUbOmiVDNe20hkA82aUMpF17tbxGsAJgqvMAwgqF1i1/uRzmTE59yx2RWFkvTuaAxC4Gqm1UDcNwRAXdhFAeChmfJyT/afg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=pcter3EntOVvhI+c3ux5PGR/jI59fiaXgVhOTif97OtoZ5q4qFG5JTLvXk1H0+Oqr0XOgWDaXb8LDZsczlPE6pfX4wRA1y7zIUkvX4v60B4l6JDzPCyDVUduwmTiPVPDUeKwFZ3DBsVhBv23+etRljTctD8rYVvScumuiukEN2BeRd3T+Hb/1rRnjePX6zJA49juG1RD1NkC31h46gZcUdBDuQazVkmAaNXQMsn7PSjkm9w9paYJfrEOk2gLJ+ZtotbXFq9VnGgMbmSck8yr8mTSeOAEZV2msO+HV//CN9xdcRGDtWDLvURLKc0fdxQsaygZ8Mo+Bbgo+FD4USAVOQ==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=citrix.com header.i="@citrix.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: Roger Pau Monne <roger.pau@xxxxxxxxxx>, Jan Beulich <jbeulich@xxxxxxxx>, Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Jason Andryuk <jason.andryuk@xxxxxxx>, Teddy Astie <teddy.astie@xxxxxxxxxx>
  • Delivery-date: Wed, 06 May 2026 13:56:28 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Attempting to memset the whole IOMMU MMIO region to zero is dangerous to
say the least.  We don't know what 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 attempt to forcefully disable the IOMMU ahead of enabling it.  Fold
map_iommu_mmio_region() into it's 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>
---
Changes since v1:
 - Zero the control register after calling disable_iommu().
 - Print a warning message if the IOMMU is handed enabled to Xen from
   firmware.
 - Fix commit log grammar issues.
---
 xen/drivers/passthrough/amd/iommu_init.c | 31 +++++++++++++-----------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/xen/drivers/passthrough/amd/iommu_init.c 
b/xen/drivers/passthrough/amd/iommu_init.c
index 76ae78e5ea53..ffc041211fb5 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,18 @@ static int __init amd_iommu_prepare_one(struct amd_iommu 
*iommu)
     if ( amd_iommu_max_paging_mode < amd_iommu_min_paging_mode )
         return -ERANGE;
 
+    /* Read current control register and forcefully disable the IOMMU. */
+    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 (%016lx)\n",
+               &iommu->sbdf, iommu->ctrl.raw);
+    disable_iommu(iommu, true);
+
+    /* With the IOMMU disabled zero the control register. */
+    iommu->ctrl.raw = 0;
+    writeq(0, iommu->mmio_base + IOMMU_CONTROL_MMIO_OFFSET);
+
     return 0;
 }
 
-- 
2.53.0




 


Rackspace

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