ANDROID: KVM: arm64: Allow relinqush for p-guest with huge-mappings

Issue a hyp_request SPLIT to the host whenever a huge-mapping is hit by
the relinquish path. We can then let the guest retry to relinquish the
memory.

Bug: 419548963
Bug: 278011447
Change-Id: I171499f23c253f1244d9967d9b0a9bfbde922d34
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
This commit is contained in:
Vincent Donnefort
2025-05-22 18:19:04 +01:00
parent 297e1ff805
commit 17daf81bcc
2 changed files with 13 additions and 3 deletions

View File

@@ -389,7 +389,7 @@ static int relinquish_walker(const struct kvm_pgtable_visit_ctx *ctx,
/* We don't support splitting non-leaf mappings */
if (ctx->level != (KVM_PGTABLE_MAX_LEVELS - 1))
return 0;
return -E2BIG;
state = pkvm_getstate(kvm_pgtable_stage2_pte_prot(pte));
if (state != data->expected_state)

View File

@@ -1588,9 +1588,19 @@ static bool pkvm_memrelinquish_call(struct pkvm_hyp_vcpu *hyp_vcpu,
goto out_guest_err;
ret = __pkvm_guest_relinquish_to_host(hyp_vcpu, ipa, &pa);
if (ret == -ENOMEM) {
if (pkvm_handle_empty_memcache(hyp_vcpu, exit_code))
if (ret == -E2BIG) {
struct kvm_hyp_req *req = pkvm_hyp_req_reserve(hyp_vcpu, KVM_HYP_REQ_TYPE_SPLIT);
if (!req) {
ret = -ENOMEM;
goto out_guest_err;
}
req->split.guest_ipa = ALIGN_DOWN(ipa, PMD_SIZE);
req->split.size = PMD_SIZE;
write_sysreg_el2(read_sysreg_el2(SYS_ELR) - 4, SYS_ELR);
*exit_code = ARM_EXCEPTION_HYP_REQ;
return false;
} else if (ret) {