From c4d2c4f644c993b715082abf28259be84717bc57 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Wed, 7 Jul 2021 14:54:24 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Create empty S2MPU driver Create a skeleton driver for the S2MPU - an EL1 portion called during KVM init which will parse the DT and configure the kernel, and an EL2 portion which will program the S2MPUs later at runtime. The code is behind CONFIG_KVM_S2MPU. Test: builds, boots Bug: 190463801 Change-Id: I58206535f3493e1d989576a9db2112d370a1cb4d Signed-off-by: David Brazdil (cherry picked from commit b2de5483b7c5977dccfa85bde756e47f53a0ab42) Signed-off-by: Mostafa Saleh Signed-off-by: Quentin Perret --- arch/arm64/include/asm/kvm_host.h | 7 +++++++ arch/arm64/include/asm/kvm_hyp.h | 1 + arch/arm64/kvm/Kconfig | 9 +++++++++ arch/arm64/kvm/Makefile | 2 +- arch/arm64/kvm/arm.c | 8 +++++++- arch/arm64/kvm/hyp/nvhe/Makefile | 2 ++ arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c | 11 +++++++++++ arch/arm64/kvm/hyp/nvhe/setup.c | 6 ++++++ arch/arm64/kvm/iommu/Makefile | 6 ++++++ arch/arm64/kvm/iommu/s2mpu.c | 13 +++++++++++++ 10 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/s2mpu.c create mode 100644 arch/arm64/kvm/iommu/Makefile create mode 100644 arch/arm64/kvm/iommu/s2mpu.c diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index 41337d5ae41a..36daec0bbb0f 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -381,8 +381,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 4728b1321d51..4c343db80324 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -143,5 +143,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 815cc118c675..9d7b7718e3f0 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -69,4 +69,13 @@ config PROTECTED_NVHE_STACKTRACE If unsure, or not using protected nVHE (pKVM), 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 5e33c2d4645a..ccec383ad673 100644 --- a/arch/arm64/kvm/Makefile +++ b/arch/arm64/kvm/Makefile @@ -8,7 +8,7 @@ ccflags-y += -I $(srctree)/$(src) include $(srctree)/virt/kvm/Makefile.kvm obj-$(CONFIG_KVM) += kvm.o -obj-$(CONFIG_KVM) += hyp/ +obj-$(CONFIG_KVM) += hyp/ iommu/ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \ inject_fault.o va_layout.o handle_exit.o \ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index 977a58b4c8a7..efeeb56e823c 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1921,7 +1921,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 1b34d3ff57f3..7086c6134331 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -28,6 +28,8 @@ hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ hyp-obj-$(CONFIG_DEBUG_LIST) += list_debug.o hyp-obj-y += $(lib-objs) +hyp-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 16363765ffec..1716b70f9286 100644 --- a/arch/arm64/kvm/hyp/nvhe/setup.c +++ b/arch/arm64/kvm/hyp/nvhe/setup.c @@ -306,6 +306,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; +}