History

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.

Suravee Suthikulpanit committed 10 months ago

Commit 7d8b06e1 parent 2e666596 files · +87 −0Browse files

Unified · Split

6 files
  1. drivers/iommu/amd/Kconfig +10 −0
  2. drivers/iommu/amd/Makefile +1 −0
  3. drivers/iommu/amd/iommu.c +2 −0
  4. drivers/iommu/amd/iommufd.c +31 −0
  5. drivers/iommu/amd/iommufd.h +15 −0
  6. include/uapi/linux/iommufd.h +28 −0
drivers/iommu/amd/Kconfig+10−0
@@ -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 ACPI30 your BIOS for an option to enable it or if you have an IVRS ACPI
31 table.31 table.
32 32
33config 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
33config AMD_IOMMU_DEBUGFS43config 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_DEBUGFS45 depends on AMD_IOMMU && IOMMU_DEBUGFS
drivers/iommu/amd/Makefile+1−0
@@ -1,3 +1,4 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2obj-y += iommu.o init.o quirks.o ppr.o pasid.o2obj-y += iommu.o init.o quirks.o ppr.o pasid.o
3obj-$(CONFIG_AMD_IOMMU_IOMMUFD) += iommufd.o
3obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o4obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += debugfs.o
drivers/iommu/amd/iommu.c+2−0
@@ -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
3084const struct iommu_ops amd_iommu_ops = {3085const 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,
drivers/iommu/amd/iommufd.c+31−0
@@ -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
12void *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}
drivers/iommu/amd/iommufd.h+15−0
@@ -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)
10void *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 */
include/uapi/linux/iommufd.h+28−0
@@ -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 */
647struct 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 Types653 * enum iommu_hw_info_type - IOMMU Hardware Info Types
628 * @IOMMU_HW_INFO_TYPE_NONE: Output by the drivers that do not report hardware654 * @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 type658 * @IOMMU_HW_INFO_TYPE_ARM_SMMUV3: ARM SMMUv3 iommu info type
633 * @IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM659 * @IOMMU_HW_INFO_TYPE_TEGRA241_CMDQV: NVIDIA Tegra241 CMDQV (extension for ARM
634 * SMMUv3) info type660 * SMMUv3) info type
661 * @IOMMU_HW_INFO_TYPE_AMD: AMD IOMMU info type
635 */662 */
636enum iommu_hw_info_type {663enum 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/**