drivers/iommu/amd/Makefile | 2 +- drivers/iommu/amd/iommu.c | 2 ++ drivers/iommu/amd/iommufd.c | 34 ++++++++++++++++++++++++++++++++++ drivers/iommu/amd/iommufd.h | 11 +++++++++++ include/uapi/linux/iommufd.h | 19 +++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 drivers/iommu/amd/iommufd.c create mode 100644 drivers/iommu/amd/iommufd.h
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.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
---
Change in v2:
* Do not mask the EFR/EFR2 and simply return the value reported by hardware
* Move amd_iommufd_hw_info() to drivers/iommu/amd/iommufd.c
* Also support IOMMU_HW_INFO_TYPE_DEFAULT
drivers/iommu/amd/Makefile | 2 +-
drivers/iommu/amd/iommu.c | 2 ++
drivers/iommu/amd/iommufd.c | 34 ++++++++++++++++++++++++++++++++++
drivers/iommu/amd/iommufd.h | 11 +++++++++++
include/uapi/linux/iommufd.h | 19 +++++++++++++++++++
5 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 drivers/iommu/amd/iommufd.c
create mode 100644 drivers/iommu/amd/iommufd.h
diff --git a/drivers/iommu/amd/Makefile b/drivers/iommu/amd/Makefile
index 59c04a67f398..b74384465594 100644
--- a/drivers/iommu/amd/Makefile
+++ b/drivers/iommu/amd/Makefile
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-y += iommu.o init.o quirks.o io_pgtable.o io_pgtable_v2.o ppr.o pasid.o
+obj-y += iommu.o init.o quirks.o io_pgtable.o io_pgtable_v2.o ppr.o pasid.o iommufd.o
obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index eb348c63a8d0..344364ef94f8 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -42,6 +42,7 @@
#include <uapi/linux/iommufd.h>
#include "amd_iommu.h"
+#include "iommufd.h"
#include "../dma-iommu.h"
#include "../irq_remapping.h"
#include "../iommu-pages.h"
@@ -3040,6 +3041,7 @@ static const struct iommu_dirty_ops amd_dirty_ops = {
const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
+ .hw_info = amd_iommufd_hw_info,
.blocked_domain = &blocked_domain,
.release_domain = &release_domain,
.identity_domain = &identity_domain.domain,
diff --git a/drivers/iommu/amd/iommufd.c b/drivers/iommu/amd/iommufd.c
new file mode 100644
index 000000000000..08deccf9d35a
--- /dev/null
+++ b/drivers/iommu/amd/iommufd.c
@@ -0,0 +1,34 @@
+// 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;
+
+ pr_debug("%s: efr=%#llx, efr2=%#llx\n", __func__,
+ hwinfo->efr, hwinfo->efr2);
+
+ return hwinfo;
+}
diff --git a/drivers/iommu/amd/iommufd.h b/drivers/iommu/amd/iommufd.h
new file mode 100644
index 000000000000..7c30dcc66a59
--- /dev/null
+++ b/drivers/iommu/amd/iommufd.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2025 Advanced Micro Devices, Inc.
+ */
+
+#ifndef AMD_IOMMUFD_H
+#define AMD_IOMMUFD_H
+
+extern void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type);
+
+#endif /* AMD_IOMMUFD_H */
diff --git a/include/uapi/linux/iommufd.h b/include/uapi/linux/iommufd.h
index c218c89e0e2e..1adbcc89eccf 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -613,6 +613,24 @@ struct iommu_hw_info_tegra241_cmdqv {
__u8 __reserved;
};
+/**
+ * struct iommu_hw_info_amd - AMD IOMMU device info
+ *
+ * @efr : Value of AMD IOMMU Extended Feature Register (EFR) reported by hardware
+ * @efr2: Value of AMD IOMMU Extended Feature 2 Register (EFR2) reported by hardware
+ *
+ * Please See description of these registers in the following sections of
+ * the AMD I/O Virtualization Technology (IOMMU) Specification.
+ * (https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_IOMMU.pdf)
+ *
+ * - MMIO Offset 0030h IOMMU Extended Feature Register
+ * - MMIO Offset 01A0h IOMMU Extended Feature 2 Register
+ */
+struct iommu_hw_info_amd {
+ __aligned_u64 efr;
+ __aligned_u64 efr2;
+};
+
/**
* enum iommu_hw_info_type - IOMMU Hardware Info Types
* @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware
@@ -629,6 +647,7 @@ enum iommu_hw_info_type {
IOMMU_HW_INFO_TYPE_INTEL_VTD = 1,
IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2,
IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3,
+ IOMMU_HW_INFO_TYPE_AMD = 4,
};
/**
--
2.34.1
On Wed, Aug 27, 2025 at 02:22:50PM +0000, Suravee Suthikulpanit wrote: > 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. > > Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> With some nits: > diff --git a/drivers/iommu/amd/iommufd.h b/drivers/iommu/amd/iommufd.h > new file mode 100644 > index 000000000000..7c30dcc66a59 > --- /dev/null > +++ b/drivers/iommu/amd/iommufd.h > @@ -0,0 +1,11 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +/* > + * Copyright (C) 2025 Advanced Micro Devices, Inc. > + */ > + > +#ifndef AMD_IOMMUFD_H > +#define AMD_IOMMUFD_H > + > +extern void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type); No need of "extern"? > +/** > + * struct iommu_hw_info_amd - AMD IOMMU device info > + * > + * @efr : Value of AMD IOMMU Extended Feature Register (EFR) reported by hardware > + * @efr2: Value of AMD IOMMU Extended Feature 2 Register (EFR2) reported by hardware > + * > + * Please See description of these registers in the following sections of > + * the AMD I/O Virtualization Technology (IOMMU) Specification. > + * (https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_IOMMU.pdf) The link gives me: 404: Page Not Found Sorry, we couldn’t find that page. :-/ > /** > * enum iommu_hw_info_type - IOMMU Hardware Info Types > * @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware > @@ -629,6 +647,7 @@ enum iommu_hw_info_type { > IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, > IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, > IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3, > + IOMMU_HW_INFO_TYPE_AMD = 4, Missing an update in the kdoc above. Nicolin
On 8/27/2025 10:47 AM, Nicolin Chen wrote: > On Wed, Aug 27, 2025 at 02:22:50PM +0000, Suravee Suthikulpanit wrote: >> 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. >> >> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com> > > Reviewed-by: Nicolin Chen <nicolinc@nvidia.com> > > With some nits: > >> diff --git a/drivers/iommu/amd/iommufd.h b/drivers/iommu/amd/iommufd.h >> new file mode 100644 >> index 000000000000..7c30dcc66a59 >> --- /dev/null >> +++ b/drivers/iommu/amd/iommufd.h >> @@ -0,0 +1,11 @@ >> +/* SPDX-License-Identifier: GPL-2.0-only */ >> +/* >> + * Copyright (C) 2025 Advanced Micro Devices, Inc. >> + */ >> + >> +#ifndef AMD_IOMMUFD_H >> +#define AMD_IOMMUFD_H >> + >> +extern void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type); > > No need of "extern"? Ok >> +/** >> + * struct iommu_hw_info_amd - AMD IOMMU device info >> + * >> + * @efr : Value of AMD IOMMU Extended Feature Register (EFR) reported by hardware >> + * @efr2: Value of AMD IOMMU Extended Feature 2 Register (EFR2) reported by hardware >> + * >> + * Please See description of these registers in the following sections of >> + * the AMD I/O Virtualization Technology (IOMMU) Specification. >> + * (https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/specifications/48882_IOMMU.pdf) > > The link gives me: > > 404: Page Not Found > Sorry, we couldn’t find that page. > > :-/ Ah they just update the link recently. I will include a new one. >> /** >> * enum iommu_hw_info_type - IOMMU Hardware Info Types >> * @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware >> @@ -629,6 +647,7 @@ enum iommu_hw_info_type { >> IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, >> IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, >> IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3, >> + IOMMU_HW_INFO_TYPE_AMD = 4, > > Missing an update in the kdoc above. Fixed. I will update and send out v3 soon. Thank you, Suravee
© 2016 - 2025 Red Hat, Inc.