From c4c48a21c0e632dba5cbfd37fa1416db405bd032 Mon Sep 17 00:00:00 2001 From: Vincent Donnefort Date: Thu, 6 Apr 2023 10:41:18 +0100 Subject: [PATCH] ANDROID: KVM: arm64: Handle permission issue while loading pKVM module pKVM module loading is disabled by rejecting the HVCs. This is a problem for kvm_call_hyp_nvhe(__pkvm_alloc_module_va). First a WARN will be trigger, then the res.a1 being very much likely non 0 the error will not be caught. The loading would then proceed (even though no EL2 code will be actually loaded). Fix this behaviour by catching when the HVC is blocked, so the user gets a meaningful error returned and the driver is not half-loaded. Bug: 254835242 Change-Id: Ieeca6eebb083d99f8d6b79ebbc486a7c9f7d334e Signed-off-by: Vincent Donnefort --- arch/arm64/kvm/pkvm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index ec613347f116..3ec32f19b4a9 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -773,6 +773,7 @@ int __pkvm_load_el2_module(struct module *this, unsigned long *token) { &mod->data, KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W }, }; void *start, *end, *hyp_va; + struct arm_smccc_res res; kvm_nvhe_reloc_t *endrel; int ret, i, secs_first; size_t offset, size; @@ -802,12 +803,14 @@ int __pkvm_load_el2_module(struct module *this, unsigned long *token) end = secs_map[ARRAY_SIZE(secs_map) - 1].sec->end; size = end - start; - hyp_va = (void *)kvm_call_hyp_nvhe(__pkvm_alloc_module_va, size >> PAGE_SHIFT); - if (!hyp_va) { + arm_smccc_1_1_hvc(KVM_HOST_SMCCC_FUNC(__pkvm_alloc_module_va), + size >> PAGE_SHIFT, &res); + if (res.a0 != SMCCC_RET_SUCCESS || !res.a1) { kvm_err("Failed to allocate hypervisor VA space for EL2 module\n"); module_put(this); - return -ENOMEM; + return res.a0 == SMCCC_RET_SUCCESS ? -ENOMEM : -EPERM; } + hyp_va = (void *)res.a1; /* * The token can be used for other calls related to this module.