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 <quic_pheragu@quicinc.com>
This commit is contained in:
Prakruthi Deepak Heragu 2024-02-05 11:50:47 -08:00 committed by Keir Fraser
parent d3f73f0452
commit 4aedc102c3
3 changed files with 35 additions and 17 deletions

View File

@ -2,6 +2,9 @@
#ifndef _ASM_ARM64_HYPERVISOR_H
#define _ASM_ARM64_HYPERVISOR_H
#include <linux/memory.h>
#include <linux/mm.h>
#include <asm/xen/hypervisor.h>
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

View File

@ -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;

View File

@ -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);