From 4aedc102c3a31f590f8d3894d2b1fdf01f9585f3 Mon Sep 17 00:00:00 2001 From: Prakruthi Deepak Heragu Date: Mon, 5 Feb 2024 11:50:47 -0800 Subject: [PATCH] ANDROID: arm64: virt: Make the page_relinquish call generic Move out the kvm specific page_relinquish call and introduce a generic hypervisor_ops structure. Based on the hypervisor running underneath the guest, populate the operations to make specific hypercalls. Bug: 315173520 Change-Id: I93d5a92553a04d56811b0666dec6eacc1ca168e7 Signed-off-by: Prakruthi Deepak Heragu --- arch/arm64/include/asm/hypervisor.h | 11 ++++++++ arch/arm64/kernel/setup.c | 1 + arch/arm64/mm/mem_relinquish.c | 40 +++++++++++++++++------------ 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/arch/arm64/include/asm/hypervisor.h b/arch/arm64/include/asm/hypervisor.h index 9b4e4ed79623..9ad85b15dab0 100644 --- a/arch/arm64/include/asm/hypervisor.h +++ b/arch/arm64/include/asm/hypervisor.h @@ -2,6 +2,9 @@ #ifndef _ASM_ARM64_HYPERVISOR_H #define _ASM_ARM64_HYPERVISOR_H +#include +#include + #include void kvm_init_hyp_services(void); @@ -10,6 +13,14 @@ void kvm_arm_init_hyp_services(void); void kvm_init_memshare_services(void); void kvm_init_ioremap_services(void); +struct hypervisor_ops { +#ifdef CONFIG_MEMORY_RELINQUISH + void (*page_relinquish)(struct page *page); +#endif +}; + +extern struct hypervisor_ops hyp_ops; + #ifdef CONFIG_MEMORY_RELINQUISH void kvm_init_memrelinquish_services(void); #else diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index a0bc75b721e0..20ca892d5e5c 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -58,6 +58,7 @@ static int num_standard_resources; static struct resource *standard_resources; +struct hypervisor_ops hyp_ops; phys_addr_t __fdt_pointer __initdata; diff --git a/arch/arm64/mm/mem_relinquish.c b/arch/arm64/mm/mem_relinquish.c index 7948098288e3..08bf966c7fc5 100644 --- a/arch/arm64/mm/mem_relinquish.c +++ b/arch/arm64/mm/mem_relinquish.c @@ -14,6 +14,24 @@ static unsigned long memshare_granule_sz; +static void kvm_page_relinquish(struct page *page) +{ + phys_addr_t phys, end; + u32 func_id = ARM_SMCCC_VENDOR_HYP_KVM_MEM_RELINQUISH_FUNC_ID; + + phys = page_to_phys(page); + end = phys + PAGE_SIZE; + + while (phys < end) { + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(func_id, phys, 0, 0, &res); + BUG_ON(res.a0 != SMCCC_RET_SUCCESS); + + phys += memshare_granule_sz; + } +} + void kvm_init_memrelinquish_services(void) { int i; @@ -34,6 +52,9 @@ void kvm_init_memrelinquish_services(void) return; memshare_granule_sz = res.a0; + + if (memshare_granule_sz) + hyp_ops.page_relinquish = kvm_page_relinquish; } bool kvm_has_memrelinquish_services(void) @@ -44,22 +65,7 @@ EXPORT_SYMBOL_GPL(kvm_has_memrelinquish_services); void page_relinquish(struct page *page) { - phys_addr_t phys, end; - u32 func_id = ARM_SMCCC_VENDOR_HYP_KVM_MEM_RELINQUISH_FUNC_ID; - - if (!memshare_granule_sz) - return; - - phys = page_to_phys(page); - end = phys + PAGE_SIZE; - - while (phys < end) { - struct arm_smccc_res res; - - arm_smccc_1_1_invoke(func_id, phys, 0, 0, &res); - BUG_ON(res.a0 != SMCCC_RET_SUCCESS); - - phys += memshare_granule_sz; - } + if (hyp_ops.page_relinquish) + hyp_ops.page_relinquish(page); } EXPORT_SYMBOL_GPL(page_relinquish);