summaryrefslogtreecommitdiff
path: root/drivers/iommu/amd
AgeCommit message (Collapse)Author
8 daysMerge branches 'apple/dart', 'arm/smmu/updates', 'arm/smmu/bindings', ↵Joerg Roedel
'hyper-v', 'samsung/exynos', 'riscv', 'broadcom', 'intel/vt-d', 'amd/amd-vi' and 'core' into next
14 daysiommu/amd: Don't allocate kdump device table from DMA32Matt Fleming
Booting a kdump kernel with crashkernel=X,high crashkernel=0,low on an AMD system fails the per-segment device table allocation because there is no memory below 4G: swapper/0: page allocation failure: order:9, mode:0x40104(GFP_DMA32|__GFP_ZERO|__GFP_COMP) iommu_alloc_pages_node_sz+0x7f/0x150 alloc_pci_segment+0x4bd/0x650 iommu_go_to_state+0x213d/0x34e0 amd_iommu_prepare+0x39/0xa0 irq_remapping_prepare+0x83/0xd0 enable_IR_x2apic+0x61/0x370 On our E810 systems, the kdump kernel booted but ice MSI-X interrupts never fired and the TX queues timed out. Commit b336781b82cc ("iommu/amd: Allocate memory below 4G for dev table if translation pre-enabled") allocated device tables below 4G. At the time, the kdump kernel programmed a copy of the old table into the base register with the IOMMU still enabled. The 64-bit register is updated as two 32-bit halves, so the running IOMMU could see a half-written, invalid table pointer. Keeping both tables below 4G leaves the upper half zero throughout the update, so the pointer stays valid. Since commit 38e5f33ee359 ("iommu/amd: Reuse device table for kdump") the kdump kernel reuses the previous kernel's table without writing the base register, so its newly allocated table is discarded when reuse succeeds. If reuse fails, the previous patch programs the new table only after disabling the IOMMU. Either way, the kdump kernel's table doesn't need to be below 4G. The previous kernel still allocates its table from DMA32, so the kdump kernel's check that the old table is below 4G still works. Drop GFP_DMA32 for kdump kernels only. Cc: stable@vger.kernel.org # 6.18.x Reviewed-by: Ashish Kalra <ashish.kalra@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Matt Fleming <mfleming@cloudflare.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Matt Fleming <mfleming@cloudflare.com> Reviewed-by: Ashish Kalra <ashish.kalra@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
14 daysiommu/amd: Program device table when kdump reuse failsMatt Fleming
Commit 38e5f33ee359 ("iommu/amd: Reuse device table for kdump") made iommu_set_device_table() return early in every kdump kernel. That is needed when the previous kernel's device table is reused: the base register already points at it, and on SNP-enabled systems the register is locked. But if reuse isn't possible, early_enable_iommus() falls back to the freshly allocated table and calls early_enable_iommu(). Because of the early return, that table is never written to the base register. The IOMMU keeps using whatever table the register pointed at before, while the driver writes entries into the new one. Only skip the write when the previous kernel's table was reused. Fixes: 38e5f33ee359 ("iommu/amd: Reuse device table for kdump") Cc: stable@vger.kernel.org Reviewed-by: Ashish Kalra <ashish.kalra@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Matt Fleming <mfleming@cloudflare.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
14 daysRevert "iommu/amd: Remove redundant check in irq_remapping_select()"Joerg Roedel
This reverts commit 5e1afd4ea1d6a9bbaecf3e28707dac9c8b56bd45. This commit caused a regression with GPU devices on some platforms. Revert it for now. Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-10-09iommu/x86: Add architectural MSI reserved region helperYu Zhang
Intel and AMD IOMMU drivers both reserve the x86 architectural MSI address window from normal IOVA mappings, but each open-codes the range, allocation attributes, and insertion into the reserved-region list. Add iommu_add_resv_x86_msi_region() to encapsulate those operations, and convert the Intel and AMD drivers to use it. Return an error on allocation failure so callers can preserve their existing error paths. Signed-off-by: Yu Zhang <zhangyu1@linux.microsoft.com> Reviewed-by: Michael Kelley <mhklinux@outlook.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-25iommu/amd: Add PerfOpt IOMMU performance optimization supportMario Limonciello
Add support for the AMD IOMMU Performance Optimization (PerfOpt) feature as defined in the AMD I/O Virtualization Technology (IOMMU) Specification, Section 3.4.9 (MMIO Offset 016Ch). This feature allows privileged integrated I/O devices (GPUs) to bypass the IOMMU when directly accessing system memory. The IOMMU only enforces the IR/IW permission bits without GPA->SPA translations. amd_iommu_enable_perfopt() performs a detach/reattach cycle to rehome devices already on the identity domain with ATS/PRI/PASID/GCR3 disabled (skip_caps path). amd_iommu_disable_perfopt() restores those capabilities. The per-device dev_data->perfopt flag tracks state. PERF_OPT_EN is a single control bit per IOMMU, shared by every device behind that IOMMU, while enablement is requested per device. It is therefore reference counted (amd_iommu->perfopt_refcount): armed on the first requesting device and cleared on the last, so one device's teardown never clears the bit while a peer behind the same IOMMU still needs it. The per-device flag is cleared on every teardown path (blocked_domain_attach, release_device, and amd_iommu_disable_perfopt), dropping the reference with it, so a reused dev_data never carries stale PerfOpt state onto its next bind. On suspend/resume the hardware is reprogrammed from scratch: amd_iommu_perfopt_clear() forces the bit off without touching the reference count, and amd_iommu_perfopt_restore() re-asserts it from the count after early_enable_iommu(), so armed devices keep the optimization across resume without relying on each consumer driver to re-arm. The exported amd_iommu_enable_perfopt()/amd_iommu_disable_perfopt() run only from a consumer driver's bind/unbind path. group->mutex is not exposed to drivers, but a device bound to its native driver cannot have its IOMMU domain changed concurrently by the core, which serializes the detach/attach pair against core-driven attach. PerfOpt is opt-in -- only enabled when explicitly requested by a driver. Tested-by: Derek J. Clark <derekjohn.clark@gmail.com> Co-developed-by: Jatin Kataria <jkataria@netflix.com> Signed-off-by: Jatin Kataria <jkataria@netflix.com> Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Tested-by: Boqun Feng (Netflix) <boqun@kernel.org> Acked-by: Alex Deucher <alexander.deucher@amd.com> [joerg.roedel@amd.com: Fixed build failure on i386] Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Fix leak of data->entry in irq_remapping_alloc() error pathLi RongQing
In irq_remapping_alloc() each per-IRQ iteration allocates two objects: the amd_ir_data (chip_data) and its data->entry (union irte / struct irte_ga). The out_free_data error path only freed chip_data via kfree(irq_data->chip_data), leaking data->entry for every already initialized IRQ. Free data->entry alongside data on the error path. Signed-off-by: Li RongQing <lirongqing@baidu.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Move GA log allocation to initVasant Hegde
Currently GA log buffer allocation is done at the time of enabling ga log. This mixes capability checking, resource allocation, and hardware enablement into a single late stage code path. Move capability checking and buffer allocation to init path: - check_vapic_support(): Checks AVIC support - alloc_ga_log(): Rename iommu_init_ga_log() as alloc_ga_log(). It will allocate the GA log and GA log tail buffers for a given IOMMU. Remove redundant checks inside alloc_ga_log(). - enable_iommus_vapic() is simplified - it handles enabling GA log and GAM/SNPAVIC support for IOMMUs. Finally update iommu_ga_log_enable() return value from int to bool as return value is used in boolean context only. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Fail probe on ATS configuration failurePranjal Shrivastava
Update the driver to call pci_prepare_ats() after checking if pci_ats_supported() and fail the probe_device if pci_prepare_ats() returns an error. Additionally, update pdev_enable_cap_ats() to WARN_ON() a failure in pci_enable_ats(). Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Samiullah Khawaja <skhawaja@google.com> Signed-off-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Remove iommu_ignore_device()Pranjal Shrivastava
The iommu_ignore_device() helper was historically called on device initialization failure to clear the primary Device Table Entry (DTE) via memset() and nullify the rlookup_table entry. However, clearing the DTE on probe failure is problematic: 1. During normal boot, DTEs start out unconfigured (blocking DMA), making clearing redundant. 2. During kdump boot, pre-existing translations should be kept running until deferred attach rather than abruptly clearing them, which risks breaking in-flight transfers. 3. Writing to the DTE table via memset without flushing the hardware DTE cache risks aliasing & torn writes. 4. Clearing the rlookup_table entry breaks interrupt remapping for devices that fail probe or operate in translation-less modes. Remove iommu_ignore_device() entirely and simplify the error return paths in amd_iommu_probe_device(). Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Suggested-by: Vasant Hegde <vasant.hegde@amd.com> Reported-by: sashiko-bot@kernel.org Closes: https://lore.kernel.org/all/20260529153216.2AD1E1F00899@smtp.kernel.org/ Signed-off-by: Pranjal Shrivastava <praan@google.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Refactor device probe and capability initializationPranjal Shrivastava
Restructure the device probe path to improve readability and prepare for cleaner error handling. Refactor check_device() into lookup_device to explicitly validate and return the amd_iommu ptr & devid. Refactor iommu_init_device() to return the allocated dev_data. Consolidate all PCI cap inits (MSI domains, PASID, ATS) into a new helper: iommu_init_device_caps(). Suggested-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Pranjal Shrivastava <praan@google.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Force identity mode for selected GPUs onlyVasant Hegde
Certain AMD GPUs must always operate in IOMMU identity mode. This was previously enforced using a PASID check, which happened to work because these specific GPUs are PASID-capable. However, this approach incorrectly applies identity mode enforcement to all PASID-capable devices, not just the GPUs that require it. This made sense in the past because the domain allocation API (iommu_ops->domain_alloc()) only received the domain type, so the driver had no way to inspect device capabilities and pick the most suitable page table format (v1 or v2). With the recent driver enhancement to use domain_alloc_paging_flags() for all paging domain allocations, the driver can now inspect the device and flags directly and choose the appropriate page table type per device. Update amd_iommu_def_domain_type() to force identity mapping only for the specific GPUs that require it, via a new quirks_force_identity_mapping(). With this change, a system booting in DMA translation mode will now select: * Guest (v2) page table for PASID-capable devices * Host (v1) page table for non-PASID-capable devices Also drop the amd_iommu_snp_en check, as SNP enforces paging domain, which doesn't work with the identity requirement of these GPUs. Link: https://lore.kernel.org/all/20200824105415.21000-1-joro@8bytes.org/ Link: https://lore.kernel.org/linux-iommu/20260723061548.10187-1-vasant.hegde@amd.com/ Cc: Alex Deucher <alexander.deucher@amd.com> Cc: Mario Limonciello <mario.limonciello@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Remove ad-hoc checks that are never trueRong Zhang
The state transitions of the AMD IOMMU Initialization State Machine imply that some ad-hoc checks will never be true. In detail, they are only reachable if the previous state transitions have succeeded, but the conditions are only true if the previous state transitions have failed. Therefore, remove the redundant ad-hoc checks. Signed-off-by: Rong Zhang <i@rong.moe> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Disallow implicit START_STATE => IVRS_DETECTED transitionRong Zhang
Xen PV intentionally skips calling amd_iommu_detect() in order to gate IOMMU initialization, as the Xen hypervisor has taken over the hardware. However, due to amd_iommu_prepare() requesting ACPI_FINISHED while setting up APIC, the state machine is still progressed, only to be stopped midway due to the `!amd_iommu_detected' check in early_amd_iommu_init(). This is worthless and fragile. It unnecessarily calls detect_ivrs(), which leads to extra overhead, i.e., getting the IVRS table and accessing the PCI config space. Disallow implicit START_STATE => IVRS_DETECTED transition, so that amd_iommu_prepare() and other paths no longer progress the state machine accidentally. This should also help prevent potential bugs if more housekeeping work is added to amd_iommu_detect() in the future. Signed-off-by: Rong Zhang <i@rong.moe> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-24iommu/amd: Do not request ACS when IOMMU is not going to be initializedRong Zhang
The AMD IOMMU Initialization State Machine has the following state transition diagram (only the very first states are showed, and the `IOMMU_' prefix is omitted): START_STATE | v [0] detect_ivrs() --> NOT_FOUND | ok v IVRS_DETECTED | v [1] amd_iommu_disabled? (amd_iommu=off) --> IOMMU_CMDLINE_DISABLED | no v [2] early_amd_iommu_init() | +-- [3] amd_iommu_detected? (!iommu=off && ...) -+ | yes | +-- ... --> IOMMU_INIT_ERROR <-------------------+ | ok v IOMMU_ACPI_FINISHED | v ... [0] always calls pci_request_acs() as long as there's a valid IVRS table and no Stoney Ridge graphics. This is not optimal as ACS is not required in an [amd_]iommu=off boot. In a normal boot, ACS is requested due to amd_iommu_detect() requesting IVRS_DETECTED. pci_request_acs+0x9/0x18 iommu_go_to_state+0x106/0x1a20 amd_iommu_detect+0x1c/0x50 pci_iommu_alloc+0x26/0x40 mm_core_init+0xa/0x120 start_kernel+0x527/0x7a0 x86_64_start_reservations+0x24/0x30 x86_64_start_kernel+0xd1/0xe0 common_startup_64+0x13e/0x158 This is intended to ensure ACS is requested before the PCI core initialization, or else a !CONFIG_IRQ_REMAP, nointremap or intremap=off boot would be broken. However, in an amd_iommu=off boot, the state machine still requests ACS at the exact same time, as amd_iommu_detect() has nothing to do with amd_iommu_disabled. Even worse, in an iommu=off boot, though amd_iommu_detect() bails out early, ACS is still requested due to amd_iommu_prepare() requesting IOMMU_ACPI_FINISHED, which is called by irq_remapping_prepare() thanks to CONFIG_X86_LOCAL_APIC (always set on X86_64) and CONFIG_IRQ_REMAP (enabled by defconfig), unless nointremap or intremap=off is also passed to cmdline. pci_request_acs+0x9/0x18 iommu_go_to_state+0x106/0x1a20 amd_iommu_prepare+0x15/0x40 irq_remapping_prepare+0x43/0x60 enable_IR_x2apic+0x22/0x190 x86_64_probe_apic+0xa/0x50 apic_intr_mode_init+0x70/0xd0 x86_late_time_init+0x28/0x40 start_kernel+0x6f9/0x7a0 ... In both cases, [2] is still gated due to the [1] or [3] check, so that IOMMU can be disabled per cmdline. Technically, it makes no sense to detect IVRS at all in an [amd_]iommu=off boot or if IOMMU is not supported due to platform settings. This is probably why amd_iommu_detect() bails out before requesting IVRS_DETECTED. Apparently only bailing out there is not sufficient, and the bailing-out paths should really have been parts of the state machine. Clean up the initialization routines by moving the bailing-out paths and [1] to the right place in the state machine (i.e., before [0]), and always requesting IVRS_DETECTED in amd_iommu_detect() to initialize the state machine early and properly. Note that the condition (iommu_detected && !gart_iommu_aperture) is dropped as it's dead code since the relevant code being removed. It meant to detect what commit 6631ee9d0099 ("x86, AMD IOMMU: add dma_ops initialization function") had introduced, but commit d7f077697533 ("x86/amd-iommu: Fall back to GART if initialization fails") has removed it. Later, commit 78013eaadf69 ("x86: remove the IOMMU table infrastructure") ensured AMD IOMMU being detected before Intel's and led to iommu_detected == gart_iommu_aperture in any case. Signed-off-by: Rong Zhang <i@rong.moe> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-11iommu/amd: Remove unused macroVasant Hegde
Remove unsed device range capability related macros. No functional changes. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-11iommu/amd: Remove redundant checks from interrupt handler pathVasant Hegde
PPR and GAlog interrupt is enabled only if buffer is allocated. (See amd_iommu_enable_ppr_log() and iommu_ga_log_enable()). The duplicate check in interrupt hanlder path is unnecessary and can be removed. No functional changes. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-11iommu/amd: Remove redundant check in irq_remapping_select()Vasant Hegde
The amd_iommu_irq_remap flag is already validated during irq remapping domain creation (before calling amd_iommu_create_irq_domain()). The duplicate check in irq_remapping_select() is unnecessary and can be removed. Additionally, mark amd_iommu_irq_remap as static. No functional changes. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-11iommu/amd: Make iommu_sva_set_dev_pasid as staticVasant Hegde
Its used inside pasid.c only. No functional changes. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-07iommu/amd: Fix ineffective error check in nested domain allocationHemanth Selam
amd_iommu_pdom_id_alloc() returns an int: a domain ID on success, or the negative errno from ida_alloc_range() when the ID space is exhausted or memory is short. amd_iommu_alloc_domain_nested() stores that return value in gdom_info->hdom_id, which is a u32, and only then tests it: gdom_info->hdom_id = amd_iommu_pdom_id_alloc(); if (gdom_info->hdom_id <= 0) { The assignment discards the sign, so -ENOSPC becomes 0xffffffe4 and the test never fires. The nested domain is then set up with a host domain ID that was never allocated, instead of the allocation failing with -ENOSPC. Keep the value in an int, test it there, and store it only once it is known to be valid, which is what the other amd_iommu_pdom_id_alloc() callers already do. Fixes: 757d2b1fdf5b ("iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation") Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-07iommu/amd: Fix premature break in init_iommu_one() againVasant Hegde
Commit 283d245468a2 ("iommu/amd: Fix premature break in init_iommu_one()") unintentionally broke older platforms - such as the ASRockRack B550D4-4L - where the BIOS advertises incorrect IOMMU features. Move the HATDis check ahead of the GASup check, and re-introduce the break inside the GASup check to restore correct behavior on affected platforms. This is a short-term fix to resolve the regression. Longer term, we should rework how EFRs are tracked and prioritize the MMIO-advertised EFR over the one reported via IVRS. That requires more extensive changes and will be addressed separately. Fixes: 283d245468a2 ("iommu/amd: Fix premature break in init_iommu_one()") Reported-by: Andreas Juch <andreas@juch.cc> Closes: https://lore.kernel.org/linux-iommu/07b2d390-f7a0-47e2-bc2c-eb0853acf52e@juch.cc/ Tested-by: Andreas Juch <andreas@juch.cc> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-09-07iommu/amd: Do not reallocate GA log buffers on resumeKarl Mehltretter
Commit c5e1a1eb9279 ("iommu/amd: Simplify and Consolidate Virtual APIC (AVIC) Enablement") moved the GA log allocation from iommu_init_pci() to enable_iommus_vapic(), which is called on every resume. iommu_init_ga_log() assigns iommu->ga_log and iommu->ga_log_tail unconditionally. Each resume therefore replaces the boot-time pointers and leaks both old allocations. The function also uses GFP_KERNEL from a syscore resume callback, where interrupts are disabled and the non-boot CPUs are offline. Return early if both buffers are already allocated. Clear the pointers in free_ga_log() so a partial allocation failure cannot leave ga_log dangling. Fixes: c5e1a1eb9279 ("iommu/amd: Simplify and Consolidate Virtual APIC (AVIC) Enablement") Assisted-by: Claude:claude-opus-5 Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-08-11Merge branches 'arm/smmu/updates', 'arm/smmu/bindings', 'mediatek', ↵Joerg Roedel
'qualcomm/msm', 'rockchip', 'ti/omap', 'riscv', 'intel/vt-d', 'amd/amd-vi', 'core' and 'typos' into next
2026-08-11iommu/amd: Add SNP page mode 0 supportVasant Hegde
Newer AMD IOMMUs supports DTE[Mode]=0 for SNP-enabled system. This is detected using new feature bit (EFR2[SNP_Page_Mode_0_Sup]). If this feature is enabled, then IOMMU supports: - Passthrough mode (i.e. iommu=pt) - amd_iommu=pgtbl_v2: Forcing Linux DMA-API to use IOMMU v2 page table - Setting up device for SVA mode in the host. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Tested-by: Amandeep Kaur Longia <AmandeepKaur.Longia@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-08-11iommu/amd: Fix GN bit setting in COMPLETE_PPR_REQUEST commandVasant Hegde
The GN bit in the COMPLETE_PPR_REQUEST command indicates whether the device is operating under a guest (v2) page table. Currently, dev_data->pri_tlp is incorrectly used to derive this bit. However, pri_tlp indicates whether the device uses PRI TLP which is unrelated to page table mode. Fix this by refactoring amd_iommu_complete_ppr() into a static internal helper __amd_iommu_complete_ppr() that accepts an explicit 'gn' argument. The amd_iommu_complete_ppr() wrapper then derives the GN bit correctly from the device's active protection domain via pdom_is_v2_pgtbl_mode(). In the INVALID_PPR_REQUEST error handling path, the device's protection domain may not be accessible, so derive the GN bit directly from the EVENT_FLAG_PPR_GN flag in the event log entry instead. While at it, change the 'gn' parameter type in build_complete_ppr() from u8 to bool to better reflect its semantics. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-08-11iommu/amd: Rate limit INVALID_PPR_REQUEST error loggingVasant Hegde
The amd_iommu_report_ppr_err() function logs an error message for every INVALID_PPR_REQUEST event. Under certain fault conditions, a misbehaving or malicious device can flood the IOMMU event log with PPR faults, causing the kernel log to be overwhelmed with repeated error messages. Switch from dev_err() to dev_err_ratelimited() to suppress duplicate messages when INVALID_PPR_REQUEST events occur at a high rate. Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-08-11iommu/amd: Fix missing CMD_COMPLETE_PPR response for invalid PPR requestsVasant Hegde
The AMD IOMMU spec, requires the host to respond with a CMD_COMPLETE_PPR command when an EVENT_TYPE_INV_PPR_REQ event is received with the RX bit cleared. This response was missing in the current implementation, leaving invalid PPR requests unacknowledged. Introduce amd_iommu_report_ppr_err() to handle EVENT_TYPE_INV_PPR_REQ events. The new function logs the invalid PPR request and when the RX bit is cleared, sends CMD_COMPLETE_PPR response. Reported-by: Gaultier Delbarre <Gaultier.Delbarre@amd.com> Co-developed-by: Wei Huang <wei.huang2@amd.com> Signed-off-by: Wei Huang <wei.huang2@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-08-11iommu/amd: Introduce PPR_TAG_LAST_PAGE() macroVasant Hegde
The PPR tag field (PPRtag) encodes two distinct fields: the 9-bit tag value (bits 8-0) and the last-page indicator L bit (bit 9). Fix PPR_TAG() to mask only the 9-bit tag field and introduce PPR_TAG_LAST_PAGE to explicitly extract the L bit. This way it becomes easy to read. Cc: Wei Huang <wei.huang2@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-08-11iommu/amd: Fix incorrect device ID in invalid PASID error messageVasant Hegde
The IO page fault notifier handler logs pdev->dev.id when reporting an invalid PASID, but pdev->dev.id is the kernel-internal device ID and not the IOMMU device ID (BDF). Use dev_data->devid instead, which reflects actual devid. Fixes: 978d626b8f1a ("iommu/amd: Add IO page fault notifier handler") Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-07-30iommu/amd: Put PCI device after handling PPR faultsShuai Xue
iommu_call_iopf_notifier() looks up the requester with pci_get_domain_bus_and_slot(), which returns a PCI device with its reference count incremented. Neither the successful iommu_report_device_fault() path nor the abort path drops that reference, so every handled PPR request leaks a PCI device reference. This is the same ownership rule that was fixed for the old iommu_v2 ppr_notifier() path by commit 6cf0981c2233 ("iommu/amd: Fix pci device refcount leak in ppr_notifier()"), but iommu_call_iopf_notifier() was added later as a separate PPR/IOPF notifier path. Drop the PCI device reference after handling the PPR entry. Fixes: 978d626b8f1a ("iommu/amd: Add IO page fault notifier handler") Cc: stable@vger.kernel.org Assisted-by: Qoder:Qwen-3.8-MAX-Preview Signed-off-by: Shuai Xue <xueshuai@linux.alibaba.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-07-22iommu/amd: Fix undefined behavior in devid_write debugfs functionLi RongQing
When for_each_pci_segment() loop completes without finding a matching segment, the pci_seg pointer is not NULL but points to an invalid memory location (the list head). Accessing pci_seg->id after the loop causes undefined behavior. Fix this by handling the successful case inside the loop and returning -EINVAL after the loop if no matching segment is found. Fixes: 2e98940f123d9 ("iommu/amd: Add support for device id user input") Signed-off-by: Li RongQing <lirongqing@baidu.com> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Will Deacon <will@kernel.org>
2026-07-22iommu/amd: Fix grammar and typos in commentsxiongweimin
Correct possessive "its", article before acpihid, and a couple of mangled sentences in IOMMU flush/irq comments. Signed-off-by: xiongweimin <xiongweimin@kylinos.cn> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Will Deacon <will@kernel.org>
2026-07-21iommu/amd: Bound the early ACPI HID mapPengpeng Hou
The ivrs_acpihid command-line parser appends entries to a fixed four-element early_acpihid_map array. Unlike the sibling IOAPIC and HPET parsers, it does not reject a fifth entry before incrementing the map size. Check the capacity at the common found label before parsing the HID and UID or writing the entry. Fixes: ca3bf5d47cec ("iommu/amd: Introduces ivrs_acpihid kernel parameter") Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Will Deacon <will@kernel.org>
2026-07-21iommu/amd: Wait for completion instead of returning early in ↵Guanghui Feng
iommu_completion_wait() need_sync is a per-IOMMU flag shared by all domains and devices behind that IOMMU. It is set whenever a command is queued with sync == true and cleared when a completion-wait (CWAIT) command is queued. However, a cleared need_sync only means that a covering CWAIT has been queued, not that all previously queued commands have actually completed in hardware. iommu_completion_wait() read need_sync locklessly and returned early when it was false. This breaks the "block until all previously queued commands have completed" contract in a multi-CPU scenario: CPU2: queue inv-B => need_sync = true CPU1: queue CWAIT(N); need_sync = false; then wait_on_sem(N) CPU2: read need_sync == false => return 0 (no wait!) CPU2 returns without waiting for any sequence number even though its inv-B may not have completed yet (CWAIT(N), queued after inv-B, has not been signaled). CPU2 then proceeds to, for example, free page-table pages while the IOMMU can still walk stale translations, opening a use-after-free window. This is a logical race in the meaning of the flag, not a memory-visibility issue, so barriers alone do not help. Fix it without losing the optimization of avoiding redundant CWAIT commands: take iommu->lock before testing need_sync, and when it is false do not return early but wait for the last allocated sequence number (cmd_sem_val). Since need_sync == false implies no sync command was queued after the last CWAIT, that CWAIT is FIFO-ordered after every not-yet-completed command, so waiting for its sequence number guarantees all prior commands (possibly queued by another CPU) have completed. The common path with pending work is unchanged and no extra hardware command is issued. Signed-off-by: Guanghui Feng <guanghuifeng@linux.alibaba.com> Fixes: 815b33fdc279 ("x86/amd-iommu: Cleanup completion-wait handling") Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Will Deacon <will@kernel.org>
2026-07-15iommu/amd: Fix nested domain leakTycho Andersen (AMD)
A couple of runs of different AI tools have generated something like the following bug report: In nested_domain_free(), when refcount_dec_and_test() returns false (other nested domains still reference the same gdom_info), the function returns without calling kfree(ndom), leaking the nested_domain structure. This problem wasn't introduced by this patch, but exists in the code from commit 757d2b1fdf5b that the patch modifies. Each nested_domain (ndom) is allocated individually in amd_iommu_alloc_domain_nested() via kzalloc_obj(*ndom). The .free callback is the sole point responsible for freeing this domain. When the refcount is > 0, only the xa_unlock_irqrestore is performed and the function returns, leaving ndom permanently allocated. This leak occurs every time a nested domain sharing a gDomID is destroyed while other domains still use that gDomID. There is a similar leak later in this function in the WARN_ON() test when the mapping is already NULL. Switch to a RAII-based cleanup for ndom, since it should always be freed in this function. Fixes: 757d2b1fdf5b ("iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation") Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Will Deacon <will@kernel.org>
2026-07-15iommu/amd: Fix IRQ unsafe locking in gdom allocationTycho Andersen (AMD)
Lockdep complains: [ 259.410489] ===================================================== [ 259.417287] WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected [ 259.424667] 7.0.0-g51db1d8d2113 #54 Not tainted [ 259.429718] ----------------------------------------------------- [ 259.436516] qemu-system-x86/10143 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: [ 259.444670] ff3b2b1c60305170 (&xa->xa_lock#25){+.+.}-{3:3}, at: __domain_flush_pages+0x17c/0x4b0 [ 259.454485] and this task is already holding: [ 259.460991] ff3b2b1c98504cc0 (&domain->lock){-.-.}-{3:3}, at: amd_iommu_iotlb_sync+0x25/0x60 [ 259.470408] which would create a new lock dependency: [ 259.476041] (&domain->lock){-.-.}-{3:3} -> (&xa->xa_lock#25){+.+.}-{3:3} [ 259.483615] but this new dependency connects a HARDIRQ-irq-safe lock: [ 259.492447] (&domain->lock){-.-.}-{3:3} [ 259.492449] ... which became HARDIRQ-irq-safe at: [ 259.503705] lock_acquire+0xb6/0x2e0 [ 259.507790] _raw_spin_lock_irqsave+0x3e/0x60 [ 259.512748] amd_iommu_flush_iotlb_all+0x20/0x50 [ 259.517996] iommu_dma_free_iova.isra.0+0x1b8/0x1e0 [ 259.523534] __iommu_dma_unmap+0xc2/0x140 [ 259.528100] iommu_dma_unmap_phys+0x55/0xc0 [ 259.532863] dma_unmap_phys+0x274/0x2e0 [ 259.537238] dma_unmap_page_attrs+0x17/0x30 [ 259.542000] nvme_unmap_data+0x13e/0x280 [ 259.546473] nvme_pci_complete_batch+0x45/0x70 [ 259.551524] nvme_irq+0x83/0x90 [ 259.555123] __handle_irq_event_percpu+0x92/0x360 [ 259.560466] handle_irq_event+0x39/0x80 [ 259.564841] handle_edge_irq+0xb2/0x1a0 [ 259.569214] __common_interrupt+0x4e/0x130 [ 259.573882] common_interrupt+0x88/0xa0 [ 259.578256] asm_common_interrupt+0x27/0x40 [ 259.583019] cpuidle_enter_state+0x119/0x5d0 [ 259.587877] cpuidle_enter+0x2e/0x50 [ 259.591962] do_idle+0x153/0x2c0 [ 259.595657] cpu_startup_entry+0x29/0x30 [ 259.600128] start_secondary+0x118/0x150 [ 259.604601] common_startup_64+0x13e/0x141 [ 259.609266] to a HARDIRQ-irq-unsafe lock: [ 259.615384] (&xa->xa_lock#25){+.+.}-{3:3} [ 259.615386] ... which became HARDIRQ-irq-unsafe at: [ 259.627039] ... [ 259.627039] lock_acquire+0xb6/0x2e0 [ 259.633071] _raw_spin_lock+0x2f/0x50 [ 259.637250] amd_iommu_alloc_domain_nested+0x140/0x3c0 [ 259.643078] iommufd_hwpt_alloc+0x272/0x800 [iommufd] [ 259.648813] iommufd_fops_ioctl+0x14e/0x200 [iommufd] [ 259.654547] __x64_sys_ioctl+0x9d/0xf0 ... Since amd_iommu_domain_flush_pages() necessarily holds domain->lock to do the flush, switch the allocation side in gdom_info_load_or_alloc_locked() to HARDIRQ-safe allocation. The IOMMU_DESTROY->free path has the same issue, so switch that path to HARDIRQ-safe locking as well. Fixes: 757d2b1fdf5b ("iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation") Signed-off-by: Tycho Andersen (AMD) <tycho@kernel.org> Reviewed-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Will Deacon <will@kernel.org>
2026-07-09iommu/amd: Dynamically verify Southbridge IOAPIC via PCI config spaceWei Wang
check_ioapic_information() verifies whether the BIOS has provided a valid device ID for the Southbridge (SB) IOAPIC in the IVRS table. Currently, if the SB IOAPIC entry in the IVRS table does not match a historically hardcoded device ID (00:14.0), interrupt remapping is forcibly disabled. This hardcoded expectation does not scale to newer architectures. For example, recent Hygon Gen 4 servers use 00:0b.0 for the SB IOAPIC, which originally caused the validation to fail and interrupt remapping to be disabled until this device ID was added upstream. Instead of maintaining per-vendor/per-generation hardcoded device IDs, dynamically verify the SB IOAPIC by reading its PCI configuration space. Because the SB IOAPIC is embedded within the FCH (Fusion Controller Hub) and shares its device ID, we can inspect the PCI class code of the given device ID to confirm it is an actual FCH device (a SMBus controller or ISA Bridge). Signed-off-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Yongwei Xu <xuyongwei@open-hieco.net> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-07-09iommu/amd: Fix false positive in SB IOAPIC IVRS validationWei Wang
The check_ioapic_information() function is designed to prevent boot hangs by ensuring the Southbridge (SB) IOAPIC is properly mapped in the IVRS table before enabling Interrupt Remapping. Currently, this check passes if *any* enumerated IOAPIC matches the expected SB IOAPIC device ID. If a buggy BIOS incorrectly assigns the SB IOAPIC's device ID to a secondary IOAPIC in the IVRS, while scrambling the true SB IOAPIC's mapping, the check hits a false positive and succeeds. This erroneously enables Interrupt Remapping. Consequently, the IOMMU blocks unmapped interrupts from the actual SB IOAPIC, dropping the system timer and leading to a silent kernel boot hang. Tighten the validation to verify the device ID specifically against the SB IOAPIC by matching their APIC IDs first. This prevents the validation check from being bypassed via device ID aliasing. Fixes: c2ff5cf5294b ("iommu/amd: Work around wrong IOAPIC device-id in IVRS table") Signed-off-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Yongwei Xu <xuyongwei@open-hieco.net> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-07-09iommu/amd: Prevent SB IOAPIC from overriding IVRS validation errorsWei Wang
The check_ioapic_information() function validates IOAPICs against the IVRS table to safely disable Interrupt Remapping (IR) if the BIOS provides a broken topology. Currently, the validation loop contains a bug: If an unmapped secondary IOAPIC is encountered, 'ret' is set to false. But if the Southbridge (SB) IOAPIC is enumerated after it in the MADT, the loop overwrites 'ret' to true. This bypasses the validation failure and leaves IR enabled. When devices attached to the unmapped secondary IOAPIC fire interrupts, the IOMMU drops them due to the missing Requestor ID, leading to localized device hangs. Fix this by initializing 'ret' to true and only toggling it to false upon encountering a validation error, ensuring failures are never erased. Fixes: c2ff5cf5294b ("iommu/amd: Work around wrong IOAPIC device-id in IVRS table") Signed-off-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Yongwei Xu <xuyongwei@open-hieco.net> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-06-12Merge branches 'apple/dart', 'arm/smmu/updates', 'arm/smmu/bindings', ↵Joerg Roedel
'rockchip', 'verisilicon', 'riscv', 'intel/vt-d', 'amd/amd-vi' and 'core' into next
2026-06-12iommu/amd: Control INVALIDATE_IOMMU_PAGES PDE from the gatherJason Gunthorpe
Now that AMD uses iommupt, it is easy to make use of the PDE bit. If the gather has no free list then no page directory entries were changed. Pass GN/PDE through the invalidation call chain in a u32 flags field that is OR'd into data[2] and set it properly from the gather. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-06-12iommu/amd: Make CMD_INV_IOMMU_ALL_PAGES_ADDRESS match the specJason Gunthorpe
The spec in Table 14 defines the "Entire Cache" case as having the low 12 bits as zero. Indeed the command format doesn't even have the low 12 bits. Since there is only one user now, fix the constant to have 0 in the low 12 bits instead of 1 and remove the masking. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-06-12iommu/amd: Have amd_iommu_domain_flush_pages() use lastJason Gunthorpe
Finish clearing out the size/last/end switching by converting amd_iommu_domain_flush_pages() to use last-based logic. This algorithm is simpler than the previous. Ultimately all this wants to do is select powers of two that are aligned to address and not longer than the distance to last. The new version is fully safe for size = U64_MAX and last = U64_MAX. Finally, the gather can be passed through natively without risking an overflow in (gather->end - gather->start + 1). Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-06-12iommu/amd: Pass last in through to build_inv_address()Jason Gunthorpe
This is the trivial call chain below amd_iommu_domain_flush_pages(). Cases that are doing a full invalidate will pass a last of U64_MAX. This avoids converting between size and last, and type confusion with size_t, unsigned long and u64 all being used in different places along the driver's invalidation path. Consistently use u64 in the internals. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-06-12iommu/amd: Simplify build_inv_address()Jason Gunthorpe
This function is doing more work than it needs to: - iommu_num_pages() is pointless, the fls() is going to compute the required page size already. - It is easier to understand as sz_lg2, which is 12 if size is 4K, than msb_diff which is 11 if size is 4K. - Simplify the control flow to early exit on the out of range cases. - Use the usual last instead of end to signify an inclusive last address. - Use GENMASK to compute the 1's mask. - Use GENMASK to compute the address mask for the command layout, not PAGE_MASK. - Directly reference the spec language that defines the 52 bit limit. No functional change intended. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Wei Wang <wei.w.wang@hotmail.com> Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-06-02iommu/amd: Don't split flush for amd_iommu_domain_flush_all()Weinan Liu
We have observed multiple full invalidations occurring during device detach when we are done using the vfio-device. blocked_domain_attach_device() -> detach_device() -> amd_iommu_domain_flush_all() -> amd_iommu_domain_flush_pages(..., CMD_INV_IOMMU_ALL_PAGES_ADDRESS) while (size != 0) { -> __domain_flush_pages( flush_size /* power of 2 flush_size */) -> domain_flush_pages_v1() -> build_inv_iommu_pages() -> build_inv_address() } build_inv_address() will trigger a full invalidation if the chunk size > (1 << 51). Consequently, the guest will issue multiple full invalidations for a single call to amd_iommu_domain_flush_all() Without this patch, we will see 10 time instead of 1 time full invalidations for every amd_iommu_domain_flush_all(). Cc: stable@vger.kernel.org Fixes: a270be1b3fdf ("iommu/amd: Use only natural aligned flushes in a VM") Suggested-by: Josef Bacik <josef@toxicpanda.com> Suggested-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Weinan Liu <wnliu@google.com> Reviewed-by: Wei Wang <wei.w.wang@hotmail.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Samiullah Khawaja <skhawaja@google.com> Reviewed-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-05-28iommu/amd: Fix premature break in init_iommu_one()Vasant Hegde
In init_iommu_one(), when processing IOMMU EFR attributes, the code checks whether GASUP is enabled. If GASUP is not enabled, the code falls back to legacy guest IR mode and then breaks out of the switch statement. This break incorrectly skips the subsequent initialization steps that follow the GASUP check. These initializations are independent of GASUP support and must always be performed. Fix this by replacing the early break with a conditional else block, ensuring that the XTSUP check is only skipped when GASUP is not available. Fixes: a44092e326d4 ("iommu/amd: Use IVHD EFR for early initialization of IOMMU features") Reported-by: Sudheer Dantuluri <dantuluris@google.com> Tested-by: Dheeraj Kumar Srivastava <dheerajkumar.srivastava@amd.com> Signed-off-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-05-19iommu/amd: Adhere to IVINFO[VASIZE] for address limitsAnkit Soni
ACPI IVRS IVHD’s IVINFO field reports the maximum virtual address size (VASIZE) supported by the IOMMU. The AMD IOMMU driver currently caps this with pagetable level reported by EFR[HATS] when configuring paging domains (hw_max_vasz_lg2). On systems where firmware or VM advertises smaller or different limits, the driver may over-advertise capabilities and create domains outside the hardware’s actual bounds. Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Reviewed-by: Vasant Hegde <vasant.hegde@amd.com> Signed-off-by: Ankit Soni <Ankit.Soni@amd.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-05-11iommu/amd: Bounds-check devid in __rlookup_amd_iommu()Jose Fernandez (Anthropic)
iommu_device_register() walks every device on the PCI bus via bus_for_each_dev() and calls amd_iommu_probe_device() for each. The inlined check_device() path computes the device's sbdf, calls rlookup_amd_iommu() to find the owning IOMMU, and only afterwards verifies devid <= pci_seg->last_bdf. __rlookup_amd_iommu() indexes rlookup_table[devid] with no bounds check of its own, so for a PCI device whose BDF is not described by the IVRS, the lookup reads past the end of the allocation before the caller's bounds check can run. This was harmless before commit e874c666b15b ("iommu/amd: Change rlookup, irq_lookup, and alias to use kvalloc()"): the table was a zeroed page-order allocation, so the over-read returned NULL and the caller's NULL check skipped the device. After that commit the table is a tight kvcalloc() and the over-read returns adjacent slab contents, which check_device() then dereferences as a struct amd_iommu *, causing a boot-time GPF. Seen on Google Compute Engine ct6e VMs, where the virtualized IVRS describes only the four TPU endpoints 00:04.0-07.0; the gVNIC at 00:08.0 (devid 0x40) indexes 56 bytes past the 456-byte allocation, into the adjacent kmalloc-512 slab object: pci 0000:00:04.0: Adding to iommu group 0 pci 0000:00:05.0: Adding to iommu group 1 pci 0000:00:06.0: Adding to iommu group 2 pci 0000:00:07.0: Adding to iommu group 3 Oops: general protection fault, probably for non-canonical address 0x3a64695f78746382: 0000 [#1] SMP NOPTI CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.22 #1 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 12/06/2025 RIP: 0010:amd_iommu_probe_device+0x54/0x3a0 Call Trace: __iommu_probe_device+0x107/0x520 probe_iommu_group+0x29/0x50 bus_for_each_dev+0x7e/0xe0 iommu_device_register+0xc9/0x240 iommu_go_to_state+0x9c0/0x1c60 amd_iommu_init+0x14/0x40 pci_iommu_init+0x16/0x60 do_one_initcall+0x47/0x2f0 Guard the array access in __rlookup_amd_iommu(). With the fix applied on 6.18.22, the gVNIC at 00:08.0 is skipped cleanly and the VM boots. Fixes: e874c666b15b ("iommu/amd: Change rlookup, irq_lookup, and alias to use kvalloc()") Cc: stable@vger.kernel.org Reported-by: Ziyuan Chen <zc@anthropic.com> Tested-by: Ziyuan Chen <zc@anthropic.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Assisted-by: Claude:unspecified Signed-off-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
2026-05-11iommu/amd: Remove unused IOMMU_IN/OUT_ADDR_BIT_SIZE macrosWei Wang
The macros IOMMU_IN/OUT_ADDR_BIT_SIZE became unused after commit 2fdf6db436e3 ("iommu/amd: Remove AMD io_pgtable support"), which removed the last references in io_pgtable.c and io_pgtable_v2.c. Remove them to clean up unused definitions. Signed-off-by: Wei Wang <wei.w.wang@hotmail.com> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com> Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>