iommu/amd: Add support for hw_info for iommu capability query

AMD IOMMU Extended Feature (EFR) and Extended Feature 2 (EFR2) registers
specify features supported by each IOMMU hardware instance.
The IOMMU driver checks each feature-specific bits before enabling
each feature at run time.

For IOMMUFD, the hypervisor passes the raw value of amd_iommu_efr and
amd_iommu_efr2 to VMM via iommufd IOMMU_DEVICE_GET_HW_INFO ioctl.

Reviewed-by: Nicolin Chen <nicolinc@nvidia.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
This commit is contained in:
Suravee Suthikulpanit 2026-01-15 06:08:02 +00:00 committed by Joerg Roedel
parent 2e66659565
commit 7d8b06ecc4
6 changed files with 87 additions and 0 deletions

View File

@ -30,6 +30,16 @@ config AMD_IOMMU
your BIOS for an option to enable it or if you have an IVRS ACPI your BIOS for an option to enable it or if you have an IVRS ACPI
table. table.
config AMD_IOMMU_IOMMUFD
bool "Enable IOMMUFD features for AMD IOMMU (EXPERIMENTAL)"
depends on IOMMUFD
depends on AMD_IOMMU
help
Support for IOMMUFD features intended to support virtual machines
with accelerated virtual IOMMUs.
Say Y here if you are doing development and testing on this feature.
config AMD_IOMMU_DEBUGFS config AMD_IOMMU_DEBUGFS
bool "Enable AMD IOMMU internals in DebugFS" bool "Enable AMD IOMMU internals in DebugFS"
depends on AMD_IOMMU && IOMMU_DEBUGFS depends on AMD_IOMMU && IOMMU_DEBUGFS

View File

@ -1,3 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only # SPDX-License-Identifier: GPL-2.0-only
obj-y += iommu.o init.o quirks.o ppr.o pasid.o obj-y += iommu.o init.o quirks.o ppr.o pasid.o
obj-$(CONFIG_AMD_IOMMU_IOMMUFD) += iommufd.o
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o

View File

@ -43,6 +43,7 @@
#include <linux/generic_pt/iommu.h> #include <linux/generic_pt/iommu.h>
#include "amd_iommu.h" #include "amd_iommu.h"
#include "iommufd.h"
#include "../irq_remapping.h" #include "../irq_remapping.h"
#include "../iommu-pages.h" #include "../iommu-pages.h"
@ -3083,6 +3084,7 @@ static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain)
const struct iommu_ops amd_iommu_ops = { const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable, .capable = amd_iommu_capable,
.hw_info = amd_iommufd_hw_info,
.blocked_domain = &blocked_domain, .blocked_domain = &blocked_domain,
.release_domain = &blocked_domain, .release_domain = &blocked_domain,
.identity_domain = &identity_domain.domain, .identity_domain = &identity_domain.domain,

View File

@ -0,0 +1,31 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2025 Advanced Micro Devices, Inc.
*/
#include <linux/iommu.h>
#include "iommufd.h"
#include "amd_iommu.h"
#include "amd_iommu_types.h"
void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type)
{
struct iommu_hw_info_amd *hwinfo;
if (*type != IOMMU_HW_INFO_TYPE_DEFAULT &&
*type != IOMMU_HW_INFO_TYPE_AMD)
return ERR_PTR(-EOPNOTSUPP);
hwinfo = kzalloc(sizeof(*hwinfo), GFP_KERNEL);
if (!hwinfo)
return ERR_PTR(-ENOMEM);
*length = sizeof(*hwinfo);
*type = IOMMU_HW_INFO_TYPE_AMD;
hwinfo->efr = amd_iommu_efr;
hwinfo->efr2 = amd_iommu_efr2;
return hwinfo;
}

View File

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2025 Advanced Micro Devices, Inc.
*/
#ifndef AMD_IOMMUFD_H
#define AMD_IOMMUFD_H
#if IS_ENABLED(CONFIG_AMD_IOMMU_IOMMUFD)
void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type);
#else
#define amd_iommufd_hw_info NULL
#endif /* CONFIG_AMD_IOMMU_IOMMUFD */
#endif /* AMD_IOMMUFD_H */

View File

@ -623,6 +623,32 @@ struct iommu_hw_info_tegra241_cmdqv {
__u8 __reserved; __u8 __reserved;
}; };
/**
* struct iommu_hw_info_amd - AMD IOMMU device info
*
* @efr : Value of AMD IOMMU Extended Feature Register (EFR)
* @efr2: Value of AMD IOMMU Extended Feature 2 Register (EFR2)
*
* Please See description of these registers in the following sections of
* the AMD I/O Virtualization Technology (IOMMU) Specification.
* (https://docs.amd.com/v/u/en-US/48882_3.10_PUB)
*
* - MMIO Offset 0030h IOMMU Extended Feature Register
* - MMIO Offset 01A0h IOMMU Extended Feature 2 Register
*
* Note: The EFR and EFR2 are raw values reported by hardware.
* VMM is responsible to determine the appropriate flags to be exposed to
* the VM since cetertain features are not currently supported by the kernel
* for HW-vIOMMU.
*
* Current VMM-allowed list of feature flags are:
* - EFR[GTSup, GASup, GioSup, PPRSup, EPHSup, GATS, GLX, PASmax]
*/
struct iommu_hw_info_amd {
__aligned_u64 efr;
__aligned_u64 efr2;
};
/** /**
* enum iommu_hw_info_type - IOMMU Hardware Info Types * enum iommu_hw_info_type - IOMMU Hardware Info Types
* @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware * @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware
@ -632,6 +658,7 @@ struct iommu_hw_info_tegra241_cmdqv {
* @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type
* @IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM * @IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM
* SMMUv3) info type * SMMUv3) info type
* @IOMMU_HW_INFO_TYPE_AMD: AMD IOMMU info type
*/ */
enum iommu_hw_info_type { enum iommu_hw_info_type {
IOMMU_HW_INFO_TYPE_NONE = 0, IOMMU_HW_INFO_TYPE_NONE = 0,
@ -639,6 +666,7 @@ enum iommu_hw_info_type {
IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, IOMMU_HW_INFO_TYPE_INTEL_VTD = 1,
IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2,
IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3, IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3,
IOMMU_HW_INFO_TYPE_AMD = 4,
}; };
/** /**