ANDROID: KVM: arm64: Clear error code when returning SMC error
Fix a small bug on the error code path of kvm_handle_pvm_smc64:
some of the FF-A handlers copy the internal error code into
the registers, then return that code. kvm_handle_pvm_smc64
interprets a returned error as "not an SMC call" and forwards
those arguments to EL3. Those registers should be returned to
the guest instead.
Bug: 280888743
Change-Id: Ifa9438ba87f64819040951ce2126cc8fa46d0a28
diff --git a/arch/arm64/kvm/hyp/include/nvhe/ffa.h b/arch/arm64/kvm/hyp/include/nvhe/ffa.h
index 5670b94..614d4a0 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/ffa.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/ffa.h
@@ -9,6 +9,8 @@
#include <asm/kvm_host.h>
#include <nvhe/pkvm.h>
+#include "trap_handler.h"
+
#define FFA_MIN_FUNC_NUM 0x60
#define FFA_MAX_FUNC_NUM 0x7F
@@ -30,6 +32,13 @@ static inline bool is_ffa_call(u64 func_id)
ARM_SMCCC_FUNC_NUM(func_id) <= FFA_MAX_FUNC_NUM;
}
+static inline bool is_ffa_error(struct kvm_vcpu *vcpu)
+{
+ struct kvm_cpu_context *ctxt = &vcpu->arch.ctxt;
+
+ return (cpu_reg(ctxt, 0) == FFA_ERROR);
+}
+
bool hyp_ffa_release_buffers(struct pkvm_hyp_vcpu *vcpu, int vmid, void *addr);
int guest_ffa_reclaim_memory(struct pkvm_hyp_vm *vm);
diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c
index eadcc5d..08c9869 100644
--- a/arch/arm64/kvm/hyp/nvhe/pkvm.c
+++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c
@@ -1521,7 +1521,7 @@ bool kvm_handle_pvm_smc64(struct kvm_vcpu *vcpu, u64 *exit_code)
* process the request.
*/
return false;
- } else if (ret > 0) {
+ } else if (ret > 0 && !is_ffa_error(vcpu)) {
handled = kvm_guest_filter_smc64(vcpu);
}