Re: [PATCH v2] iommu: Skip mapping at address 0x0 if it already exists
From: Antheas Kapenekakis
Date: Thu Feb 26 2026 - 15:52:35 EST
On Thu, 26 Feb 2026 at 21:44, Antheas Kapenekakis <lkml@xxxxxxxxxxx> wrote:
>
> Commit 789a5913b29c ("iommu/amd: Use the generic iommu page table")
> introduces the shared iommu page table for AMD IOMMU. Some bioses
> contain an identity mapping for address 0x0, which is not parsed
> properly (e.g., certain Strix Halo devices). This causes the DMA
> components of the device to fail to initialize (e.g., the NVMe SSD
> controller), leading to a failed post.
>
> Specifically, on the GPD Win 5, the NVME and SSD GPU fail to mount,
> making collecting errors difficult. While debugging, it was found that
> a -EADDRINUSE error was emitted and its source was traced to
> iommu_iova_to_phys(). After adding some debug prints, it was found that
> phys_addr becomes 0, which causes the code to try to re-map the 0
> address and fail, causing a cascade leading to a failed post. This is
> because the GPD Win 5 contains a 0x0-0x1 identity mapping for DMA
> devices, causing it to be repeated for each device.
>
> The cause of this failure is the following check in
> iommu_create_device_direct_mappings(), where address aliasing is handled
> via the following check:
>
> ```
> phys_addr = iommu_iova_to_phys(domain, addr);
> if (!phys_addr) {
> map_size += pg_size;
> continue;
> }
> ````
>
> Obviously, the iommu_iova_to_phys() signature is faulty and aliases
> unmapped and 0 together, causing the allocation code to try to
> re-allocate the 0 address per device. However, it has too many
> instantiations to fix. Therefore, catch ret == -EADDRINUSE from
> iommu_map() and, instead of bailing, skip the mapping.
>
> Fixes: 789a5913b29c ("iommu/amd: Use the generic iommu page table")
> Signed-off-by: Antheas Kapenekakis <lkml@xxxxxxxxxxx>
>
> ---
> V1: https://lore.kernel.org/lkml/20260221235050.2558321-1-lkml@xxxxxxxxxxx/
>
> Changes since V1:
> - Remove closes tag. Turns out there are multiple compounding bugs.
> See [1]
> - Remove warn log
> - Remove the addr check and make skipping universal
> - Cleanup commit message
>
> [1] https://github.com/CachyOS/linux-cachyos/issues/704
> ---
> drivers/iommu/iommu.c | 8 ++++++++
> 1 file changed, 8 insertions(+)
>
> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index 2ca990dfbb88..0a15c22df94f 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -1218,6 +1218,14 @@ static int iommu_create_device_direct_mappings(struct iommu_domain *domain,
> ret = iommu_map(domain, addr - map_size,
> addr - map_size, map_size,
> entry->prot, GFP_KERNEL);
> + /*
> + * iommu_iova_to_phys() may return 0 for allicated addresses,
*allocated, whoops
> + * e.g., for the 0 address, causing iommu_map to fail. Since
> + * the intent of the code is to allow aliasing of reserved
> + * regions, ignore the EADDRINUSE error.
> + */
> + if (ret == -EADDRINUSE)
> + ret = 0;
> if (ret)
> goto out;
> map_size = 0;
>
> base-commit: f14faaf3a1fb3b9e4cf2e56269711fb85fba9458
> --
> 2.52.0
>
>