diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 99739c59de7e..73cb8102909f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -275,8 +275,15 @@ extern u64 kvm_nvhe_sym(hyp_cpu_logical_map)[NR_CPUS]; enum kvm_iommu_driver { KVM_IOMMU_DRIVER_NONE, + KVM_IOMMU_DRIVER_S2MPU, }; +#ifdef CONFIG_KVM_S2MPU +int kvm_s2mpu_init(void); +#else +static inline int kvm_s2mpu_init(void) { return -ENODEV; } +#endif + struct vcpu_reset_state { unsigned long pc; unsigned long r0; diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 083c4e5b0e27..67579d7fd9df 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -136,5 +136,6 @@ struct kvm_iommu_ops { }; extern struct kvm_iommu_ops kvm_iommu_ops; +extern const struct kvm_iommu_ops kvm_s2mpu_ops; #endif /* __ARM64_KVM_HYP_H__ */ diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig index ecec40c186a9..982337ba5332 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -56,4 +56,13 @@ config NVHE_EL2_DEBUG If unsure, say N. +config KVM_S2MPU + bool "Stage-2 Memory Protection Unit support" + depends on KVM + help + Support for the Stage-2 Memory Protection Unit (S2MPU) and Stream + Security Mapping Table (SSMT) devices in KVM. This allows the + hypervisor to restrict DMA access to its memory and the memory of + protected guests. + endif # VIRTUALIZATION diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile index 589921392cb1..06d3a37a9272 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -8,7 +8,7 @@ ccflags-y += -I $(srctree)/$(src) KVM=../../../virt/kvm obj-$(CONFIG_KVM) += kvm.o -obj-$(CONFIG_KVM) += hyp/ +obj-$(CONFIG_KVM) += hyp/ iommu/ kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \ $(KVM)/vfio.o $(KVM)/irqchip.o \ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index df3a04996152..9ebf35a70a6c 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1725,7 +1725,13 @@ static bool init_psci_relay(void) static int init_stage2_iommu(void) { - return KVM_IOMMU_DRIVER_NONE; + int ret; + + ret = kvm_s2mpu_init(); + if (!ret) + return KVM_IOMMU_DRIVER_S2MPU; + + return (ret == -ENODEV) ? KVM_IOMMU_DRIVER_NONE : ret; } static int init_subsystems(void) diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile index 2f8c165c60e4..2428f1719740 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -19,6 +19,8 @@ obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o obj-y += $(lib-objs) +obj-$(CONFIG_KVM_S2MPU) += iommu/s2mpu.o + ## ## Build rules for compiling nVHE hyp code ## Output of this folder is `kvm_nvhe.o`, a partially linked object diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c b/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c new file mode 100644 index 000000000000..1731300e0bec --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 - Google LLC + * Author: David Brazdil + */ + +#include + +#include + +const struct kvm_iommu_ops kvm_s2mpu_ops = (struct kvm_iommu_ops){}; diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c index a2a8adb7b77c..b8d250833b1c 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -216,6 +216,12 @@ int select_iommu_ops(enum kvm_iommu_driver driver) switch (driver) { case KVM_IOMMU_DRIVER_NONE: return 0; + case KVM_IOMMU_DRIVER_S2MPU: + if (IS_ENABLED(CONFIG_KVM_S2MPU)) { + kvm_iommu_ops = kvm_s2mpu_ops; + return 0; + } + break; } return -EINVAL; diff --git a/arch/arm64/kvm/iommu/Makefile b/arch/arm64/kvm/iommu/Makefile new file mode 100644 index 000000000000..2a51f8cb2848 --- /dev/null +++ b/arch/arm64/kvm/iommu/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Makefile for Kernel-based Virtual Machine module +# + +obj-$(CONFIG_KVM_S2MPU) += s2mpu.o diff --git a/arch/arm64/kvm/iommu/s2mpu.c b/arch/arm64/kvm/iommu/s2mpu.c new file mode 100644 index 000000000000..800d264e4be1 --- /dev/null +++ b/arch/arm64/kvm/iommu/s2mpu.c @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 - Google LLC + * Author: David Brazdil + */ + +#include + +int kvm_s2mpu_init(void) +{ + kvm_info("S2MPU driver initialized\n"); + return 0; +}