@@ -410,6 +410,16 @@ config ARM_SMMU_V3_SVA
Say Y here if your system supports SVA extensions such as PCIe PASID
and PRI.
+config ARM_SMMU_V3_PKVM
+ bool "ARM SMMUv3 support for protected Virtual Machines"
+ depends on KVM && ARM64
+ select KVM_IOMMU
+ help
+ Enable a SMMUv3 driver in the KVM hypervisor, to protect VMs against
+ memory accesses from devices owned by the host.
+
+ Say Y here if you intend to enable KVM in protected mode.
+
config S390_IOMMU
def_bool y if S390 && PCI
depends on S390 && PCI
@@ -29,6 +29,7 @@ hyp-obj-$(CONFIG_DEBUG_LIST) += list_debug.o
hyp-obj-y += $(lib-objs)
hyp-obj-$(CONFIG_KVM_IOMMU) += iommu/iommu.o
+hyp-obj-$(CONFIG_ARM_SMMU_V3_PKVM) += iommu/arm-smmu-v3.o
##
## Build rules for compiling nVHE hyp code
@@ -379,6 +379,7 @@ extern u64 kvm_nvhe_sym(hyp_cpu_logical_map)[NR_CPUS];
enum kvm_iommu_driver {
KVM_IOMMU_DRIVER_NONE,
+ KVM_IOMMU_DRIVER_SMMUV3,
};
struct vcpu_reset_state {
@@ -5,6 +5,15 @@
#include <kvm/iommu.h>
#include <linux/io-pgtable.h>
+#if IS_ENABLED(CONFIG_ARM_SMMU_V3_PKVM)
+int kvm_arm_smmu_v3_register(void);
+#else /* CONFIG_ARM_SMMU_V3_PKVM */
+static inline int kvm_arm_smmu_v3_register(void)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_ARM_SMMU_V3_PKVM */
+
#if IS_ENABLED(CONFIG_KVM_IOMMU)
int kvm_iommu_init(void);
int kvm_iommu_init_device(struct kvm_hyp_iommu *iommu);
new file mode 100644
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __KVM_ARM_SMMU_V3_H
+#define __KVM_ARM_SMMU_V3_H
+
+#include <asm/kvm_asm.h>
+#include <kvm/iommu.h>
+
+#if IS_ENABLED(CONFIG_ARM_SMMU_V3_PKVM)
+
+struct hyp_arm_smmu_v3_device {
+ struct kvm_hyp_iommu iommu;
+};
+
+extern size_t kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count);
+#define kvm_hyp_arm_smmu_v3_count kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_count)
+
+extern struct hyp_arm_smmu_v3_device *kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus);
+#define kvm_hyp_arm_smmu_v3_smmus kvm_nvhe_sym(kvm_hyp_arm_smmu_v3_smmus)
+
+#endif /* CONFIG_ARM_SMMU_V3_PKVM */
+
+#endif /* __KVM_ARM_SMMU_V3_H */
new file mode 100644
@@ -0,0 +1,27 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * pKVM hyp driver for the Arm SMMUv3
+ *
+ * Copyright (C) 2022 Linaro Ltd.
+ */
+#include <asm/kvm_hyp.h>
+#include <kvm/arm_smmu_v3.h>
+#include <nvhe/iommu.h>
+
+size_t __ro_after_init kvm_hyp_arm_smmu_v3_count;
+struct hyp_arm_smmu_v3_device __ro_after_init *kvm_hyp_arm_smmu_v3_smmus;
+
+static int smmu_init(void)
+{
+ return -ENOSYS;
+}
+
+static struct kvm_iommu_ops smmu_ops = {
+ .init = smmu_init,
+};
+
+int kvm_arm_smmu_v3_register(void)
+{
+ kvm_iommu_ops = smmu_ops;
+ return 0;
+}
@@ -294,6 +294,8 @@ static int select_iommu_ops(enum kvm_iommu_driver driver)
switch (driver) {
case KVM_IOMMU_DRIVER_NONE:
return 0;
+ case KVM_IOMMU_DRIVER_SMMUV3:
+ return kvm_arm_smmu_v3_register();
}
return -EINVAL;
Add the skeleton for an Arm SMMUv3 driver at EL2. Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org> --- drivers/iommu/Kconfig | 10 ++++++++ arch/arm64/kvm/hyp/nvhe/Makefile | 1 + arch/arm64/include/asm/kvm_host.h | 1 + arch/arm64/kvm/hyp/include/nvhe/iommu.h | 9 +++++++ include/kvm/arm_smmu_v3.h | 22 +++++++++++++++++ arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c | 27 +++++++++++++++++++++ arch/arm64/kvm/hyp/nvhe/setup.c | 2 ++ 7 files changed, 72 insertions(+) create mode 100644 include/kvm/arm_smmu_v3.h create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/arm-smmu-v3.c