From: Christos Longros <chris.longros@gmail.com>
To: Joerg Roedel <joro@8bytes.org>
Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>,
Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
iommu@lists.linux.dev, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org,
Christos Longros <chris.longros@gmail.com>
Subject: [PATCH] iommu/amd: add amd_iommu=relax_unity option for VFIO passthrough
Date: Sat, 28 Mar 2026 22:32:28 +0100 [thread overview]
Message-ID: <20260328213228.12084-1-chris.longros@gmail.com> (raw)
On some AMD motherboards (Gigabyte B650 Gaming X AX V2, X870E and
others), VFIO passthrough of any PCI device fails with:
"Firmware has requested this device have a 1:1 IOMMU mapping,
rejecting configuring the device without a 1:1 mapping."
These boards' IVRS tables include IVMD type 0x22 (range) entries
spanning wide device ranges (e.g. devid 0x0000 to 0x0FFF, covering
PCI buses 0-15). The entries exist for platform devices like IOAPIC
and HPET, but they get applied to nearly every IOMMU group on the
system. Since commit a48ce36e2786 ("iommu: Prevent RESV_DIRECT
devices from blocking domains"), any device with IOMMU_RESV_DIRECT
regions has require_direct=1 set, which prevents VFIO from claiming
DMA ownership.
No PCI device can be passed through on affected boards -- not just
the platform devices that need the identity mappings, but also
endpoint devices like network adapters and GPUs.
Intel handles a similar firmware over-specification with
device_rmrr_is_relaxable(), which marks certain RMRR entries as
IOMMU_RESV_DIRECT_RELAXABLE so VFIO can claim them. AMD has no
equivalent.
Add an opt-in amd_iommu=relax_unity boot parameter. When set, IVRS
unity map entries are reported as IOMMU_RESV_DIRECT_RELAXABLE instead
of IOMMU_RESV_DIRECT. The IOMMU still creates the identity mappings,
preserving DMA for platform devices, but VFIO can take ownership of
individual devices for passthrough.
Tested by passing through an RTL8852CE WiFi adapter to a FreeBSD
QEMU/KVM guest via vfio-pci. Without the option, vfio_iommu_type1
fails to set up the container. With amd_iommu=relax_unity,
passthrough works.
Signed-off-by: Christos Longros <chris.longros@gmail.com>
---
Documentation/admin-guide/kernel-parameters.txt | 6 ++++++
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/init.c | 6 ++++++
drivers/iommu/amd/iommu.c | 7 ++++++-
4 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 03a550630..974506ad9 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -441,6 +441,12 @@ Kernel parameters
force_enable - Force enable the IOMMU on platforms known
to be buggy with IOMMU enabled. Use this
option with care.
+ relax_unity - Mark IVRS unity map entries as relaxable,
+ allowing VFIO to claim devices that have
+ firmware-declared identity mappings. Required
+ on some AMD motherboards where global unity
+ maps prevent any device passthrough. Use this
+ option with care.
pgtbl_v1 - Use v1 page table for DMA-API (Default).
pgtbl_v2 - Use v2 page table for DMA-API.
irtcachedis - Disable Interrupt Remapping Table (IRT) caching.
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index c685d3771..bc35d5016 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -907,6 +907,7 @@ struct unity_map_entry {
*/
extern bool amd_iommu_force_isolation;
+extern bool amd_iommu_unity_relaxed;
/* Max levels of glxval supported */
extern int amd_iommu_max_glx_val;
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index f3fd7f39e..a89120700 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -173,6 +173,9 @@ u64 amd_iommu_efr2;
/* Host (v1) page table is not supported*/
bool amd_iommu_hatdis;
+/* Relax unity map entries for VFIO passthrough */
+bool amd_iommu_unity_relaxed __read_mostly;
+
/* SNP is enabled on the system? */
bool amd_iommu_snp_en;
EXPORT_SYMBOL(amd_iommu_snp_en);
@@ -3676,6 +3679,9 @@ static int __init parse_amd_iommu_options(char *str)
amd_iommu_pgtable = PD_MODE_V2;
} else if (strncmp(str, "irtcachedis", 11) == 0) {
amd_iommu_irtcachedis = true;
+ } else if (strncmp(str, "relax_unity", 11) == 0) {
+ amd_iommu_unity_relaxed = true;
+ pr_warn("AMD IOMMU: unity map relaxation enabled\n");
} else if (strncmp(str, "nohugepages", 11) == 0) {
pr_info("Restricting V1 page-sizes to 4KiB");
amd_iommu_pgsize_bitmap = AMD_IOMMU_PGSIZES_4K;
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 760d5f462..4606fa6a4 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -3070,7 +3070,12 @@ static void amd_iommu_get_resv_regions(struct device *dev,
if (devid < entry->devid_start || devid > entry->devid_end)
continue;
- type = IOMMU_RESV_DIRECT;
+ /*
+ * When relax_unity is set, mark unity map entries as
+ * relaxable so VFIO can claim devices for passthrough.
+ */
+ type = amd_iommu_unity_relaxed ?
+ IOMMU_RESV_DIRECT_RELAXABLE : IOMMU_RESV_DIRECT;
length = entry->address_end - entry->address_start;
if (entry->prot & IOMMU_PROT_IR)
prot |= IOMMU_READ;
--
2.53.0
next reply other threads:[~2026-03-28 21:32 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-28 21:32 Christos Longros [this message]
2026-03-30 10:02 ` [PATCH] iommu/amd: add amd_iommu=relax_unity option for VFIO passthrough Vasant Hegde
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260328213228.12084-1-chris.longros@gmail.com \
--to=chris.longros@gmail.com \
--cc=corbet@lwn.net \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=robin.murphy@arm.com \
--cc=skhan@linuxfoundation.org \
--cc=suravee.suthikulpanit@amd.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox