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.
Unified · Split
| @@ -30,6 +30,16 @@ config AMD_IOMMU · 29 unmodified lines | |||
| 30 | your BIOS for an option to enable it or if you have an IVRS ACPI | 30 | your BIOS for an option to enable it or if you have an IVRS ACPI |
| 31 | table. | 31 | table. |
| 32 | 32 | ||
| 33 | config AMD_IOMMU_IOMMUFD | ||
| 34 | bool "Enable IOMMUFD features for AMD IOMMU (EXPERIMENTAL)" | ||
| 35 | depends on IOMMUFD | ||
| 36 | depends on AMD_IOMMU | ||
| 37 | help | ||
| 38 | Support for IOMMUFD features intended to support virtual machines | ||
| 39 | with accelerated virtual IOMMUs. | ||
| 40 | |||
| 41 | Say Y here if you are doing development and testing on this feature. | ||
| 42 | |||
| 33 | config AMD_IOMMU_DEBUGFS | 43 | config AMD_IOMMU_DEBUGFS |
| 34 | bool "Enable AMD IOMMU internals in DebugFS" | 44 | bool "Enable AMD IOMMU internals in DebugFS" |
| 35 | depends on AMD_IOMMU && IOMMU_DEBUGFS | 45 | depends on AMD_IOMMU && IOMMU_DEBUGFS |
| @@ -1,3 +1,4 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | obj-y += iommu.o init.o quirks.o ppr.o pasid.o | 2 | obj-y += iommu.o init.o quirks.o ppr.o pasid.o |
| 3 | obj-$(CONFIG_AMD_IOMMU_IOMMUFD) += iommufd.o | ||
| 3 | obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o | 4 | obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o |
| @@ -43,6 +43,7 @@ · 42 unmodified lines | |||
| 43 | #include <linux/generic_pt/iommu.h> | 43 | #include <linux/generic_pt/iommu.h> |
| 44 | 44 | ||
| 45 | #include "amd_iommu.h" | 45 | #include "amd_iommu.h" |
| 46 | #include "iommufd.h" | ||
| 46 | #include "../irq_remapping.h" | 47 | #include "../irq_remapping.h" |
| 47 | #include "../iommu-pages.h" | 48 | #include "../iommu-pages.h" |
| 48 | 49 | ||
| @@ -3083,6 +3084,7 @@ static bool amd_iommu_enforce_cache_coherency(struct iommu_domain *domain) · 3034 unmodified lines | |||
| 3083 | 3084 | ||
| 3084 | const struct iommu_ops amd_iommu_ops = { | 3085 | const struct iommu_ops amd_iommu_ops = { |
| 3085 | .capable = amd_iommu_capable, | 3086 | .capable = amd_iommu_capable, |
| 3087 | .hw_info = amd_iommufd_hw_info, | ||
| 3086 | .blocked_domain = &blocked_domain, | 3088 | .blocked_domain = &blocked_domain, |
| 3087 | .release_domain = &blocked_domain, | 3089 | .release_domain = &blocked_domain, |
| 3088 | .identity_domain = &identity_domain.domain, | 3090 | .identity_domain = &identity_domain.domain, |
| @@ -0,0 +1,31 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2025 Advanced Micro Devices, Inc. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #include <linux/iommu.h> | ||
| 7 | |||
| 8 | #include "iommufd.h" | ||
| 9 | #include "amd_iommu.h" | ||
| 10 | #include "amd_iommu_types.h" | ||
| 11 | |||
| 12 | void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type) | ||
| 13 | { | ||
| 14 | struct iommu_hw_info_amd *hwinfo; | ||
| 15 | |||
| 16 | if (*type != IOMMU_HW_INFO_TYPE_DEFAULT && | ||
| 17 | *type != IOMMU_HW_INFO_TYPE_AMD) | ||
| 18 | return ERR_PTR(-EOPNOTSUPP); | ||
| 19 | |||
| 20 | hwinfo = kzalloc(sizeof(*hwinfo), GFP_KERNEL); | ||
| 21 | if (!hwinfo) | ||
| 22 | return ERR_PTR(-ENOMEM); | ||
| 23 | |||
| 24 | *length = sizeof(*hwinfo); | ||
| 25 | *type = IOMMU_HW_INFO_TYPE_AMD; | ||
| 26 | |||
| 27 | hwinfo->efr = amd_iommu_efr; | ||
| 28 | hwinfo->efr2 = amd_iommu_efr2; | ||
| 29 | |||
| 30 | return hwinfo; | ||
| 31 | } | ||
| @@ -0,0 +1,15 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2025 Advanced Micro Devices, Inc. | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef AMD_IOMMUFD_H | ||
| 7 | #define AMD_IOMMUFD_H | ||
| 8 | |||
| 9 | #if IS_ENABLED(CONFIG_AMD_IOMMU_IOMMUFD) | ||
| 10 | void *amd_iommufd_hw_info(struct device *dev, u32 *length, u32 *type); | ||
| 11 | #else | ||
| 12 | #define amd_iommufd_hw_info NULL | ||
| 13 | #endif /* CONFIG_AMD_IOMMU_IOMMUFD */ | ||
| 14 | |||
| 15 | #endif /* AMD_IOMMUFD_H */ | ||
| @@ -623,6 +623,32 @@ struct iommu_hw_info_tegra241_cmdqv { · 622 unmodified lines | |||
| 623 | __u8 __reserved; | 623 | __u8 __reserved; |
| 624 | }; | 624 | }; |
| 625 | 625 | ||
| 626 | /** | ||
| 627 | * struct iommu_hw_info_amd - AMD IOMMU device info | ||
| 628 | * | ||
| 629 | * @efr : Value of AMD IOMMU Extended Feature Register (EFR) | ||
| 630 | * @efr2: Value of AMD IOMMU Extended Feature 2 Register (EFR2) | ||
| 631 | * | ||
| 632 | * Please See description of these registers in the following sections of | ||
| 633 | * the AMD I/O Virtualization Technology (IOMMU) Specification. | ||
| 634 | * (https://docs.amd.com/v/u/en-US/48882_3.10_PUB) | ||
| 635 | * | ||
| 636 | * - MMIO Offset 0030h IOMMU Extended Feature Register | ||
| 637 | * - MMIO Offset 01A0h IOMMU Extended Feature 2 Register | ||
| 638 | * | ||
| 639 | * Note: The EFR and EFR2 are raw values reported by hardware. | ||
| 640 | * VMM is responsible to determine the appropriate flags to be exposed to | ||
| 641 | * the VM since cetertain features are not currently supported by the kernel | ||
| 642 | * for HW-vIOMMU. | ||
| 643 | * | ||
| 644 | * Current VMM-allowed list of feature flags are: | ||
| 645 | * - EFR[GTSup, GASup, GioSup, PPRSup, EPHSup, GATS, GLX, PASmax] | ||
| 646 | */ | ||
| 647 | struct iommu_hw_info_amd { | ||
| 648 | __aligned_u64 efr; | ||
| 649 | __aligned_u64 efr2; | ||
| 650 | }; | ||
| 651 | |||
| 626 | /** | 652 | /** |
| 627 | * enum iommu_hw_info_type - IOMMU Hardware Info Types | 653 | * enum iommu_hw_info_type - IOMMU Hardware Info Types |
| 628 | * @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware | 654 | * @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware |
| @@ -632,6 +658,7 @@ struct iommu_hw_info_tegra241_cmdqv { · 3 unmodified lines | |||
| 632 | * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type | 658 | * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type |
| 633 | * @IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM | 659 | * @IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM |
| 634 | * SMMUv3) info type | 660 | * SMMUv3) info type |
| 661 | * @IOMMU_HW_INFO_TYPE_AMD: AMD IOMMU info type | ||
| 635 | */ | 662 | */ |
| 636 | enum iommu_hw_info_type { | 663 | enum iommu_hw_info_type { |
| 637 | IOMMU_HW_INFO_TYPE_NONE = 0, | 664 | IOMMU_HW_INFO_TYPE_NONE = 0, |
| @@ -639,6 +666,7 @@ enum iommu_hw_info_type { · 1 unmodified line | |||
| 639 | IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, | 666 | IOMMU_HW_INFO_TYPE_INTEL_VTD = 1, |
| 640 | IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, | 667 | IOMMU_HW_INFO_TYPE_ARM_SMMUV3 = 2, |
| 641 | IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3, | 668 | IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV = 3, |
| 669 | IOMMU_HW_INFO_TYPE_AMD = 4, | ||
| 642 | }; | 670 | }; |
| 643 | 671 | ||
| 644 | /** | 672 | /** |