iommu/amd: Force identity mode for selected GPUs only

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>
This commit is contained in:
Vasant Hegde 2026-08-24 08:58:21 +00:00 committed by Joerg Roedel
parent 567e74ce4d
commit bf5bdfd1f8

View File

@ -3162,6 +3162,26 @@ static bool amd_iommu_is_attach_deferred(struct device *dev)
return dev_data->defer_attach; return dev_data->defer_attach;
} }
static bool quirks_force_identity_mapping(struct pci_dev *pdev)
{
int class = pdev->class >> 8;
/* AMD GPU vendor ID */
if (pdev->vendor != PCI_VENDOR_ID_ATI)
return false;
/* GPU class */
if (class != PCI_CLASS_DISPLAY_VGA &&
class != PCI_CLASS_DISPLAY_OTHER)
return false;
if (pci_upstream_bridge(pdev)->vendor == PCI_VENDOR_ID_ATI)
return false;
/* It is the GPU in an APU, force identity domain */
return true;
}
static int amd_iommu_def_domain_type(struct device *dev) static int amd_iommu_def_domain_type(struct device *dev)
{ {
struct iommu_dev_data *dev_data; struct iommu_dev_data *dev_data;
@ -3170,20 +3190,23 @@ static int amd_iommu_def_domain_type(struct device *dev)
if (!dev_data) if (!dev_data)
return 0; return 0;
if (!dev_is_pci(dev))
return 0;
/* Always use DMA domain for untrusted device */ /* Always use DMA domain for untrusted device */
if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted) if (to_pci_dev(dev)->untrusted)
return IOMMU_DOMAIN_DMA; return IOMMU_DOMAIN_DMA;
/* Apply device specific quirks */
if (quirks_force_identity_mapping(to_pci_dev(dev))) {
/* /*
* Do not identity map IOMMUv2 capable devices when: * When memory encryption is active, some of these devices
* - memory encryption is active, because some of those devices * don't have the encryption bit in their DMA-mask and
* (AMD GPUs) don't have the encryption bit in their DMA-mask * require remapping.
* and require remapping.
* - SNP is enabled, because it prohibits DTE[Mode]=0.
*/ */
if (pdev_pasid_supported(dev_data) && if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
!cc_platform_has(CC_ATTR_MEM_ENCRYPT) && return 0;
!amd_iommu_snp_en) {
return IOMMU_DOMAIN_IDENTITY; return IOMMU_DOMAIN_IDENTITY;
} }