From 80fccb233cf783ca8bb26e294223a457ea4f8502 Mon Sep 17 00:00:00 2001 From: Mostafa Saleh Date: Sun, 16 Apr 2023 10:29:33 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Define pKVM HVCs for pvIOMMU pKVM exposes a paravirtualized IOMMU(pvIOMMU) to guests through hypercall ARM_SMCCC_KVM_FUNC_PVIOMMU_OP, where the operation is passes in X1 as: - map pages: Map pages for a domain. - unmap pages: Unmap pages for a domain. - attach dev: Attach an endpoint to a domain. - detach dev: Detach an endpoint from a domain. - alloc_domain: Allocate a translation regime and return its ID. - free_domain: free a domain. Bug: 357781595 Bug: 348382247 Bug: 236685427 Change-Id: I6d42339cd365f090567a099953e6324af6eea7dc Signed-off-by: Mostafa Saleh --- arch/arm64/kvm/hyp/include/nvhe/pviommu.h | 11 ++++ arch/arm64/kvm/hyp/nvhe/Makefile | 2 +- arch/arm64/kvm/hyp/nvhe/iommu/pviommu.c | 71 +++++++++++++++++++++++ arch/arm64/kvm/hyp/nvhe/pkvm.c | 3 + include/linux/arm-smccc.h | 15 ++++- 5 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 arch/arm64/kvm/hyp/include/nvhe/pviommu.h create mode 100644 arch/arm64/kvm/hyp/nvhe/iommu/pviommu.c diff --git a/arch/arm64/kvm/hyp/include/nvhe/pviommu.h b/arch/arm64/kvm/hyp/include/nvhe/pviommu.h new file mode 100644 index 000000000000..c0c51547c5a2 --- /dev/null +++ b/arch/arm64/kvm/hyp/include/nvhe/pviommu.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Google LLC + * Author: Mostafa Saleh + */ +#ifndef __ARM64_KVM_NVHE_PVIOMMU_H__ +#define __ARM64_KVM_NVHE_PVIOMMU_H__ + +bool kvm_handle_pviommu_hvc(struct kvm_vcpu *vcpu, u64 *exit_code); + +#endif /* __ARM64_KVM_NVHE_PVIOMMU_H__ */ diff --git a/arch/arm64/kvm/hyp/nvhe/Makefile b/arch/arm64/kvm/hyp/nvhe/Makefile index d4f6bbe1568e..81e0c8057048 100644 --- a/arch/arm64/kvm/hyp/nvhe/Makefile +++ b/arch/arm64/kvm/hyp/nvhe/Makefile @@ -10,7 +10,7 @@ hyp-obj-y := timer-sr.o sysreg-sr.o debug-sr.o switch.o tlb.o hyp-init.o host.o cache.o setup.o mm.o mem_protect.o sys_regs.o pkvm.o stacktrace.o ffa.o \ serial.o alloc_mgt.o iommu/iommu.o power/hvc.o power/scmi.o device/device.o hyp-obj-y += ../vgic-v3-sr.o ../aarch32.o ../vgic-v2-cpuif-proxy.o ../entry.o \ - ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o iommu/pviommu-host.o + ../fpsimd.o ../hyp-entry.o ../exception.o ../pgtable.o iommu/pviommu-host.o iommu/pviommu.o hyp-obj-$(CONFIG_LIST_HARDENED) += list_debug.o hyp-obj-$(CONFIG_TRACING) += clock.o events.o trace.o hyp-obj-$(CONFIG_PROTECTED_NVHE_FTRACE) += ftrace.o diff --git a/arch/arm64/kvm/hyp/nvhe/iommu/pviommu.c b/arch/arm64/kvm/hyp/nvhe/iommu/pviommu.c new file mode 100644 index 000000000000..e37f3f4086a1 --- /dev/null +++ b/arch/arm64/kvm/hyp/nvhe/iommu/pviommu.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2024 Google LLC + * Author: Mostafa Saleh + */ + +#include + +#include +#include +#include + +static bool pkvm_guest_iommu_map(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + return false; +} + +static bool pkvm_guest_iommu_unmap(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + return false; +} + +static bool pkvm_guest_iommu_attach_dev(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + return false; +} + +static bool pkvm_guest_iommu_detach_dev(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + return false; +} + +static bool pkvm_guest_iommu_alloc_domain(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + return false; +} + +static bool pkvm_guest_iommu_free_domain(struct pkvm_hyp_vcpu *hyp_vcpu) +{ + return false; +} + +bool kvm_handle_pviommu_hvc(struct kvm_vcpu *vcpu, u64 *exit_code) +{ + u64 iommu_op = smccc_get_arg1(vcpu); + struct pkvm_hyp_vcpu *hyp_vcpu = container_of(vcpu, struct pkvm_hyp_vcpu, vcpu); + struct pkvm_hyp_vm *vm = pkvm_hyp_vcpu_to_hyp_vm(hyp_vcpu); + + /* + * Eagerly fill the vm iommu pool to avoid deadlocks from donation path while + * doing IOMMU operations. + */ + refill_hyp_pool(&vm->iommu_pool, &hyp_vcpu->host_vcpu->arch.iommu_mc); + switch (iommu_op) { + case KVM_PVIOMMU_OP_ALLOC_DOMAIN: + return pkvm_guest_iommu_alloc_domain(hyp_vcpu); + case KVM_PVIOMMU_OP_FREE_DOMAIN: + return pkvm_guest_iommu_free_domain(hyp_vcpu); + case KVM_PVIOMMU_OP_ATTACH_DEV: + return pkvm_guest_iommu_attach_dev(hyp_vcpu); + case KVM_PVIOMMU_OP_DETACH_DEV: + return pkvm_guest_iommu_detach_dev(hyp_vcpu); + case KVM_PVIOMMU_OP_MAP_PAGES: + return pkvm_guest_iommu_map(hyp_vcpu); + case KVM_PVIOMMU_OP_UNMAP_PAGES: + return pkvm_guest_iommu_unmap(hyp_vcpu); + } + + smccc_set_retval(vcpu, SMCCC_RET_NOT_SUPPORTED, 0, 0, 0); + return true; +} diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index ed7b3f3137d7..a71b1e49d605 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1754,6 +1755,8 @@ bool kvm_handle_pvm_hvc64(struct kvm_vcpu *vcpu, u64 *exit_code) if (smccc_trng_available) return pkvm_forward_trng(vcpu); break; + case ARM_SMCCC_VENDOR_HYP_KVM_PVIOMMU_OP_FUNC_ID: + return kvm_handle_pviommu_hvc(vcpu, exit_code); case ARM_SMCCC_VENDOR_HYP_KVM_DEV_REQ_MMIO_FUNC_ID: return pkvm_device_request_mmio(hyp_vcpu, exit_code); default: diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index 2c956188c7cb..31bc5a81ac90 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -176,7 +176,7 @@ #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60 #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61 -#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62 +#define ARM_SMCCC_KVM_FUNC_PVIOMMU_OP 62 #define ARM_SMCCC_KVM_FUNC_DEV_REQ_MMIO 63 /* End of pKVM hypercall range */ #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 @@ -227,6 +227,19 @@ ARM_SMCCC_OWNER_VENDOR_HYP, \ ARM_SMCCC_KVM_FUNC_MEM_RELINQUISH) +#define KVM_PVIOMMU_OP_ATTACH_DEV 0 +#define KVM_PVIOMMU_OP_DETACH_DEV 1 +#define KVM_PVIOMMU_OP_ALLOC_DOMAIN 2 +#define KVM_PVIOMMU_OP_FREE_DOMAIN 3 +#define KVM_PVIOMMU_OP_MAP_PAGES 4 +#define KVM_PVIOMMU_OP_UNMAP_PAGES 5 + +#define ARM_SMCCC_VENDOR_HYP_KVM_PVIOMMU_OP_FUNC_ID \ + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_SMC_64, \ + ARM_SMCCC_OWNER_VENDOR_HYP, \ + ARM_SMCCC_KVM_FUNC_PVIOMMU_OP) + #define ARM_SMCCC_VENDOR_HYP_KVM_DEV_REQ_MMIO_FUNC_ID \ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ ARM_SMCCC_SMC_64, \