]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iommu/amd: Add support for hw_info for iommu capability query
authorSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Thu, 15 Jan 2026 06:08:02 +0000 (06:08 +0000)
committerJoerg Roedel <joerg.roedel@amd.com>
Sun, 18 Jan 2026 09:56:09 +0000 (10:56 +0100)
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>
drivers/iommu/amd/Kconfig
drivers/iommu/amd/Makefile
drivers/iommu/amd/iommu.c
drivers/iommu/amd/iommufd.c [new file with mode: 0644]
drivers/iommu/amd/iommufd.h [new file with mode: 0644]
include/uapi/linux/iommufd.h

index f2acf471cb5d9f11351b1dba4d1c62487b9f960e..588355ff7eb76de24296a519df5b2515b6798b5f 100644 (file)
@@ -30,6 +30,16 @@ config AMD_IOMMU
          your BIOS for an option to enable it or if you have an IVRS ACPI
          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
        bool "Enable AMD IOMMU internals in DebugFS"
        depends on AMD_IOMMU && IOMMU_DEBUGFS
index 5412a563c6979cb365773838542094bf59a5f284..41f053b49dce885bbe9d09ced614ac71074aa03b 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0-only
 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
index d7f457338de73a9e7f3ec67b83376ea59a79ab21..d550a7e431acc1248d78c3079339192b9add48b3 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/generic_pt/iommu.h>
 
 #include "amd_iommu.h"
+#include "iommufd.h"
 #include "../irq_remapping.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 = {
        .capable = amd_iommu_capable,
+       .hw_info = amd_iommufd_hw_info,
        .blocked_domain = &blocked_domain,
        .release_domain = &blocked_domain,
        .identity_domain = &identity_domain.domain,
diff --git a/drivers/iommu/amd/iommufd.c b/drivers/iommu/amd/iommufd.c
new file mode 100644 (file)
index 0000000..72eaaa9
--- /dev/null
@@ -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;
+}
diff --git a/drivers/iommu/amd/iommufd.h b/drivers/iommu/amd/iommufd.h
new file mode 100644 (file)
index 0000000..f880be8
--- /dev/null
@@ -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 */
index 2c41920b641dc13fa68effe66b4663f424262a5b..3db37f6042a09278e5928e92e999f1f163119c67 100644 (file)
@@ -623,6 +623,32 @@ 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)
+ * @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
  * @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_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM
  *                                     SMMUv3) info type
+ * @IOMMU_HW_INFO_TYPE_AMD: AMD IOMMU info type
  */
 enum iommu_hw_info_type {
        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_ARM_SMMUV3 = 2,
        IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3,
+       IOMMU_HW_INFO_TYPE_AMD = 4,
 };
 
 /**