From b7aff5c603429f73d44fce7c41b5d6034363454e Mon Sep 17 00:00:00 2001 From: Quentin Perret Date: Wed, 7 Jun 2023 13:50:26 +0000 Subject: [PATCH] ANDROID: KVM: arm64: Restrict host-to-hyp MMIO donations Nothing currently prevents the donation of an MMIO region to the hypervisor for backing e.g. guest stage-2 page-tables, tracing buffers, hyp vm and vcpu metadata, or any other donation to EL2. However, the only confirmed use-case for MMIO donations are for protecting the IOMMU registers as well as for vendor module usage. Restrict the donation of MMIO regions to these two paths only by introducing a new helper function. Bug: 264070847 Change-Id: I914508fb3e3547fcfabca8557bdf7948cb796099 Signed-off-by: Quentin Perret --- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 1 + arch/arm64/kvm/hyp/nvhe/mem_protect.c | 10 ++++++++++ arch/arm64/kvm/hyp/nvhe/modules.c | 7 ++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 19574e12566f..b0eabed053d2 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -72,6 +72,7 @@ int __pkvm_host_share_hyp(u64 pfn); int __pkvm_host_unshare_hyp(u64 pfn); int __pkvm_host_reclaim_page(struct pkvm_hyp_vm *vm, u64 pfn, u64 ipa); int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages); +int ___pkvm_host_donate_hyp(u64 pfn, u64 nr_pages, bool accept_mmio); int __pkvm_host_donate_hyp_locked(u64 pfn, u64 nr_pages); int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages); int __pkvm_host_share_guest(u64 pfn, u64 gfn, struct pkvm_hyp_vcpu *vcpu); diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c index 8bf6b8457a34..0242fa1b7c45 100644 --- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c +++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c @@ -1942,8 +1942,18 @@ int __pkvm_host_unshare_hyp(u64 pfn) int __pkvm_host_donate_hyp(u64 pfn, u64 nr_pages) { + return ___pkvm_host_donate_hyp(pfn, nr_pages, false); +} + +int ___pkvm_host_donate_hyp(u64 pfn, u64 nr_pages, bool accept_mmio) +{ + phys_addr_t start = hyp_pfn_to_phys(pfn); + phys_addr_t end = start + (nr_pages << PAGE_SHIFT); int ret; + if (!accept_mmio && !range_is_memory(start, end)) + return -EPERM; + host_lock_component(); ret = __pkvm_host_donate_hyp_locked(pfn, nr_pages); host_unlock_component(); diff --git a/arch/arm64/kvm/hyp/nvhe/modules.c b/arch/arm64/kvm/hyp/nvhe/modules.c index 3f7e7dbb67fa..49e6c2c2e2ae 100644 --- a/arch/arm64/kvm/hyp/nvhe/modules.c +++ b/arch/arm64/kvm/hyp/nvhe/modules.c @@ -77,6 +77,11 @@ void __pkvm_close_module_registration(void) */ } +static int __pkvm_module_host_donate_hyp(u64 pfn, u64 nr_pages) +{ + return ___pkvm_host_donate_hyp(pfn, nr_pages, true); +} + const struct pkvm_module_ops module_ops = { .create_private_mapping = __pkvm_create_private_mapping, .alloc_module_va = __pkvm_alloc_module_va, @@ -99,7 +104,7 @@ const struct pkvm_module_ops module_ops = { .register_illegal_abt_notifier = __pkvm_register_illegal_abt_notifier, .register_psci_notifier = __pkvm_register_psci_notifier, .register_hyp_panic_notifier = __pkvm_register_hyp_panic_notifier, - .host_donate_hyp = __pkvm_host_donate_hyp, + .host_donate_hyp = __pkvm_module_host_donate_hyp, .hyp_donate_host = __pkvm_hyp_donate_host, .host_share_hyp = __pkvm_host_share_hyp, .host_unshare_hyp = __pkvm_host_unshare_hyp,