From 5ae1450bd01df9ee677a22bb6208819c6e6a277f Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Thu, 24 Feb 2022 14:46:45 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Clear pvmfw pages on clean host shutdown When the host shuts down cleanly under pKVM, it is EL2's responsibility to clear the pvmfw pages before forwarding the PSCI call onto EL3. Wipe the pvmfw pages on SYSTEM_OFF, SYSTEM_RESET and SYSTEM_RESET2 calls from the host, cleaning the zeroed memory to the PoC for good measure. Signed-off-by: Will Deacon Signed-off-by: Will Deacon Bug: 254819795 Change-Id: I0dd2757e355f384813319034c6eed0fa2c2328c2 Signed-off-by: Quentin Perret --- arch/arm64/kvm/hyp/include/nvhe/pkvm.h | 2 ++ arch/arm64/kvm/hyp/nvhe/pkvm.c | 8 ++++++++ arch/arm64/kvm/hyp/nvhe/psci-relay.c | 6 +++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h index 6160d1a34fa2..69f33647ce05 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/pkvm.h +++ b/arch/arm64/kvm/hyp/include/nvhe/pkvm.h @@ -109,4 +109,6 @@ bool kvm_handle_pvm_hvc64(struct kvm_vcpu *vcpu, u64 *exit_code); struct pkvm_hyp_vcpu *pkvm_mpidr_to_hyp_vcpu(struct pkvm_hyp_vm *vm, u64 mpidr); +void pkvm_clear_pvmfw_pages(void); + #endif /* __ARM64_KVM_NVHE_PKVM_H__ */ diff --git a/arch/arm64/kvm/hyp/nvhe/pkvm.c b/arch/arm64/kvm/hyp/nvhe/pkvm.c index 52e45f42e1ec..1f15646c3f98 100644 --- a/arch/arm64/kvm/hyp/nvhe/pkvm.c +++ b/arch/arm64/kvm/hyp/nvhe/pkvm.c @@ -825,6 +825,14 @@ err_unlock: return err; } +void pkvm_clear_pvmfw_pages(void) +{ + void *addr = hyp_phys_to_virt(pvmfw_base); + + memset(addr, 0, pvmfw_size); + kvm_flush_dcache_to_poc(addr, pvmfw_size); +} + /* * This function sets the registers on the vcpu to their architecturally defined * reset values. diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c index 08508783ec3d..cee6d4a2821f 100644 --- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c +++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c @@ -12,6 +12,7 @@ #include #include +#include #include void kvm_hyp_cpu_entry(unsigned long r0); @@ -249,6 +250,7 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ */ case PSCI_0_2_FN_SYSTEM_OFF: case PSCI_0_2_FN_SYSTEM_RESET: + pkvm_clear_pvmfw_pages(); return psci_forward(host_ctxt); case PSCI_0_2_FN64_CPU_SUSPEND: return psci_cpu_suspend(func_id, host_ctxt); @@ -262,9 +264,11 @@ static unsigned long psci_0_2_handler(u64 func_id, struct kvm_cpu_context *host_ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_ctxt) { switch (func_id) { + case PSCI_1_1_FN64_SYSTEM_RESET2: + pkvm_clear_pvmfw_pages(); + fallthrough; case PSCI_1_0_FN_PSCI_FEATURES: case PSCI_1_0_FN_SET_SUSPEND_MODE: - case PSCI_1_1_FN64_SYSTEM_RESET2: return psci_forward(host_ctxt); case PSCI_1_0_FN64_SYSTEM_SUSPEND: return psci_system_suspend(func_id, host_ctxt);