From 7a67d424c13ec7a545b4cd5a5af9bb77fd43f638 Mon Sep 17 00:00:00 2001 From: Will Deacon Date: Tue, 12 Apr 2022 09:50:23 +0100 Subject: [PATCH] ANDROID: KVM: arm64: Pin FFA mailboxes shared by the host Gulshan reports that the hypervisor is not pinning the host FFA mailbox pages, therefore allowing the host to unshare them after registration and to later donate them for things like page-table pages. Pin the host FFA mailboxes to prevent the host from unsharing them while they are in use. Bug: 228931886 Reported-by: Gulshan Singh Signed-off-by: Will Deacon Change-Id: I18ecad6ccaa3ef89015a71d97890fad55f0568f2 --- arch/arm64/kvm/hyp/nvhe/ffa.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c index 4dbd42a86756..2e5016399513 100644 --- a/arch/arm64/kvm/hyp/nvhe/ffa.c +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c @@ -176,6 +176,7 @@ static void do_ffa_rxtx_map(struct arm_smccc_res *res, DECLARE_REG(phys_addr_t, rx, ctxt, 2); DECLARE_REG(u32, npages, ctxt, 3); int ret = 0; + void *rx_virt, *tx_virt; if (npages != (KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) / FFA_PAGE_SIZE) { ret = FFA_RET_INVALID_PARAMETERS; @@ -209,8 +210,22 @@ static void do_ffa_rxtx_map(struct arm_smccc_res *res, goto err_unshare_tx; } - host_kvm.ffa.tx = hyp_phys_to_virt(tx); - host_kvm.ffa.rx = hyp_phys_to_virt(rx); + tx_virt = hyp_phys_to_virt(tx); + ret = hyp_pin_shared_mem(tx_virt, tx_virt + 1); + if (ret) { + ret = FFA_RET_INVALID_PARAMETERS; + goto err_unshare_rx; + } + + rx_virt = hyp_phys_to_virt(rx); + ret = hyp_pin_shared_mem(rx_virt, rx_virt + 1); + if (ret) { + ret = FFA_RET_INVALID_PARAMETERS; + goto err_unpin_tx; + } + + host_kvm.ffa.tx = tx_virt; + host_kvm.ffa.rx = rx_virt; out_unlock: hyp_spin_unlock(&host_kvm.ffa.lock); @@ -218,6 +233,10 @@ out: ffa_to_smccc_res(res, ret); return; +err_unpin_tx: + hyp_unpin_shared_mem(tx_virt, tx_virt + 1); +err_unshare_rx: + __pkvm_host_unshare_hyp(hyp_phys_to_pfn(rx)); err_unshare_tx: __pkvm_host_unshare_hyp(hyp_phys_to_pfn(tx)); err_unmap: @@ -242,9 +261,11 @@ static void do_ffa_rxtx_unmap(struct arm_smccc_res *res, goto out_unlock; } + hyp_unpin_shared_mem(host_kvm.ffa.tx, host_kvm.ffa.tx + 1); WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_kvm.ffa.tx))); host_kvm.ffa.tx = NULL; + hyp_unpin_shared_mem(host_kvm.ffa.rx, host_kvm.ffa.rx + 1); WARN_ON(__pkvm_host_unshare_hyp(hyp_virt_to_pfn(host_kvm.ffa.rx))); host_kvm.ffa.rx = NULL;