From 23b62ec342ea4bf7cda7f8ce5aade1f5347d717a Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Tue, 18 Apr 2023 13:06:56 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Map MMIO donation as device at EL2 We now support donations of MMIO ranges to the hypervisor. Make sure to update the donation logic to correctly map these pages with device mappings. Bug: 264070847 Change-Id: I36558f05ed47d1e3dc06e4e24151241474b4ff77 Signed-off-by: Quentin Perret --- arch/arm64/kvm/hyp/nvhe/mem_protect.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 099b25bfcbbe..41c7f55df964 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -487,6 +487,11 @@ static enum kvm_pgtable_prot default_host_prot(bool is_memory) return is_memory ? PKVM_HOST_MEM_PROT : PKVM_HOST_MMIO_PROT; } +static enum kvm_pgtable_prot default_hyp_prot(phys_addr_t phys) +{ + return addr_is_memory(phys) ? PAGE_HYP : PAGE_HYP_DEVICE; +} + bool addr_is_memory(phys_addr_t phys) { struct kvm_mem_range range; @@ -1211,8 +1216,10 @@ static int hyp_ack_share(u64 addr, const struct pkvm_mem_transition *tx, enum kvm_pgtable_prot perms) { u64 size = tx->nr_pages * PAGE_SIZE; + phys_addr_t phys = hyp_virt_to_phys((void *)addr); + enum kvm_pgtable_prot prot = default_hyp_prot(phys); - if (perms != PAGE_HYP) + if (perms != prot) return -EPERM; if (__hyp_ack_skip_pgtable_check(tx)) @@ -1267,8 +1274,10 @@ static int hyp_complete_donation(u64 addr, const struct pkvm_mem_transition *tx) { void *start = (void *)addr, *end = start + (tx->nr_pages * PAGE_SIZE); - enum kvm_pgtable_prot prot = pkvm_mkstate(PAGE_HYP, PKVM_PAGE_OWNED); + phys_addr_t phys = hyp_virt_to_phys(start); + enum kvm_pgtable_prot prot = default_hyp_prot(phys); + prot = pkvm_mkstate(prot, PKVM_PAGE_OWNED); return pkvm_create_mappings_locked(start, end, prot); } @@ -1801,7 +1810,7 @@ int __pkvm_host_share_hyp(u64 pfn) .id = PKVM_ID_HYP, }, }, - .completer_prot = PAGE_HYP, + .completer_prot = default_hyp_prot(host_addr), }; host_lock_component(); @@ -1898,7 +1907,7 @@ int __pkvm_host_unshare_hyp(u64 pfn) .id = PKVM_ID_HYP, }, }, - .completer_prot = PAGE_HYP, + .completer_prot = default_hyp_prot(host_addr), }; host_lock_component();