ANDROID: KVM: arm64: Cleanup unused ppage->pins
Since 10a77358c7 ("ANDROID: KVM: arm64: Allow relinqush for p-guest
with huge-mappings"), pKVM issues a hyp_req to ask for a huge-mapping
split before a page relinquish happens. This made the ppage->pins field
deprecated. This field was meant to handle the previous broken approach
of relinquish where the kvm_pinned_page tree wasn't updated on a block
split.
While at it, remove the now unnecessary error handling in
pkvm_call_hyp_nvhe_ppage(). The hypervisor can only split blocks behind
the back of the host in the guest_share_host case.
Bug: 439812370
Bug: 357781595
Bug: 278011447
Change-Id: I705a010be8afaaadc9ba15a2b2c02eb1efa2194c
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
This commit is contained in:
@@ -281,7 +281,6 @@ struct kvm_pinned_page {
|
||||
u64 ipa;
|
||||
u64 __subtree_last;
|
||||
u8 order;
|
||||
u16 pins;
|
||||
};
|
||||
|
||||
struct kvm_pinned_page
|
||||
|
||||
@@ -512,10 +512,6 @@ struct pkvm_ptdump_log_hdr {
|
||||
u64 w_index: 16;
|
||||
};
|
||||
|
||||
int pkvm_call_hyp_nvhe_ppage(struct kvm_pinned_page *ppage,
|
||||
int (*call_hyp_nvhe)(u64, u64, u8, void*),
|
||||
void *args, bool unmap);
|
||||
|
||||
struct pkvm_mapping {
|
||||
struct rb_node node;
|
||||
u64 gfn;
|
||||
|
||||
@@ -1758,9 +1758,8 @@ __pkvm_pages_to_ppages(struct kvm *kvm, struct kvm_memory_slot *memslot, gfn_t g
|
||||
ppage->page = pfn_to_page(pfn);
|
||||
ppage->ipa = ipa;
|
||||
ppage->order = get_order(page_size);
|
||||
ppage->pins = 1 << ppage->order;
|
||||
list_add_tail(&ppage->list_node, ppages);
|
||||
nr_ppages += ppage->pins;
|
||||
nr_ppages += 1 << ppage->order;
|
||||
|
||||
next:
|
||||
/* Number of pages to skip (covered by a THP) */
|
||||
@@ -2081,7 +2080,6 @@ int __pkvm_pgtable_stage2_split(struct kvm_vcpu *vcpu, phys_addr_t ipa, size_t s
|
||||
goto end;
|
||||
|
||||
ppage->order = 0;
|
||||
ppage->pins = 1;
|
||||
|
||||
pfn = page_to_pfn(ppage->page) + 1;
|
||||
ipa = ipa + PAGE_SIZE;
|
||||
@@ -2093,7 +2091,6 @@ int __pkvm_pgtable_stage2_split(struct kvm_vcpu *vcpu, phys_addr_t ipa, size_t s
|
||||
ppage->page = pfn_to_page(pfn);
|
||||
ppage->ipa = ipa;
|
||||
ppage->order = 0;
|
||||
ppage->pins = 1;
|
||||
insert_ppage(kvm, ppage);
|
||||
|
||||
pfn += 1;
|
||||
|
||||
+12
-43
@@ -327,27 +327,21 @@ err_free_reqs:
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle broken down huge pages which have not been reported to the
|
||||
* kvm_pinned_page.
|
||||
* Handle split huge pages which have not been reported to the kvm_pinned_page tree.
|
||||
*/
|
||||
int pkvm_call_hyp_nvhe_ppage(struct kvm_pinned_page *ppage,
|
||||
int (*call_hyp_nvhe)(u64 pfn, u64 gfn, u8 order, void* args),
|
||||
void *args, bool unmap)
|
||||
static int pkvm_call_hyp_nvhe_ppage(struct kvm_pinned_page *ppage,
|
||||
int (*call_hyp_nvhe)(u64 pfn, u64 gfn, u8 order, void *args),
|
||||
void *args)
|
||||
{
|
||||
size_t page_size, size = PAGE_SIZE << ppage->order;
|
||||
u64 pfn = page_to_pfn(ppage->page);
|
||||
u8 order = ppage->order;
|
||||
u64 gfn = ppage->ipa >> PAGE_SHIFT;
|
||||
|
||||
/* We already know this huge-page has been broken down in the stage-2 */
|
||||
if (ppage->pins < (1 << order))
|
||||
order = 0;
|
||||
|
||||
while (size) {
|
||||
int err = call_hyp_nvhe(pfn, gfn, order, args);
|
||||
|
||||
switch (err) {
|
||||
/* The stage-2 huge page has been broken down */
|
||||
case -E2BIG:
|
||||
if (order)
|
||||
order = 0;
|
||||
@@ -355,16 +349,6 @@ int pkvm_call_hyp_nvhe_ppage(struct kvm_pinned_page *ppage,
|
||||
/* Something is really wrong ... */
|
||||
return -EINVAL;
|
||||
break;
|
||||
/* This has been unmapped already */
|
||||
case -ENOENT:
|
||||
/*
|
||||
* We are not supposed to lose track of PAGE_SIZE pinned
|
||||
* page.
|
||||
*/
|
||||
if (!ppage->order)
|
||||
return -EINVAL;
|
||||
|
||||
fallthrough;
|
||||
case 0:
|
||||
page_size = PAGE_SIZE << order;
|
||||
gfn += 1 << order;
|
||||
@@ -373,13 +357,6 @@ int pkvm_call_hyp_nvhe_ppage(struct kvm_pinned_page *ppage,
|
||||
if (page_size > size)
|
||||
return -EINVAL;
|
||||
|
||||
/* If -ENOENT, the pin was already dropped. */
|
||||
if (unmap && !err)
|
||||
ppage->pins -= 1 << order;
|
||||
|
||||
if (!ppage->pins)
|
||||
return 0;
|
||||
|
||||
size -= page_size;
|
||||
break;
|
||||
default:
|
||||
@@ -466,11 +443,9 @@ retry:
|
||||
ppage = kvm_pinned_pages_iter_first(&host_kvm->arch.pkvm.pinned_pages, 0, ~(0UL));
|
||||
while (ppage) {
|
||||
struct kvm_pinned_page *next;
|
||||
u16 pins = ppage->pins;
|
||||
|
||||
ret = pkvm_call_hyp_nvhe_ppage(ppage,
|
||||
__reclaim_dying_guest_page_call,
|
||||
host_kvm, true);
|
||||
ret = pkvm_call_hyp_nvhe_ppage(ppage, __reclaim_dying_guest_page_call,
|
||||
host_kvm);
|
||||
cond_resched();
|
||||
if (ret == -EBUSY) {
|
||||
nr_busy++;
|
||||
@@ -483,7 +458,7 @@ retry:
|
||||
unpin_user_pages_dirty_lock(&ppage->page, 1, true);
|
||||
next = kvm_pinned_pages_iter_next(ppage, 0, ~(0UL));
|
||||
kvm_pinned_pages_remove(ppage, &host_kvm->arch.pkvm.pinned_pages);
|
||||
pages += pins;
|
||||
pages += 1 << ppage->order;
|
||||
kfree(ppage);
|
||||
ppage = next;
|
||||
}
|
||||
@@ -816,25 +791,19 @@ void pkvm_host_reclaim_page(struct kvm *host_kvm, phys_addr_t ipa)
|
||||
{
|
||||
struct mm_struct *mm = current->mm;
|
||||
struct kvm_pinned_page *ppage;
|
||||
u16 pins;
|
||||
u8 order;
|
||||
|
||||
write_lock(&host_kvm->mmu_lock);
|
||||
ppage = kvm_pinned_pages_iter_first(&host_kvm->arch.pkvm.pinned_pages,
|
||||
ipa, ipa + PAGE_SIZE - 1);
|
||||
if (ppage) {
|
||||
WARN_ON_ONCE(ppage->pins != 1);
|
||||
|
||||
if (ppage->pins)
|
||||
ppage->pins--;
|
||||
|
||||
pins = ppage->pins;
|
||||
if (!pins)
|
||||
kvm_pinned_pages_remove(ppage,
|
||||
&host_kvm->arch.pkvm.pinned_pages);
|
||||
order = ppage->order;
|
||||
if (!order)
|
||||
kvm_pinned_pages_remove(ppage, &host_kvm->arch.pkvm.pinned_pages);
|
||||
}
|
||||
write_unlock(&host_kvm->mmu_lock);
|
||||
|
||||
if (WARN_ON(!ppage) || pins)
|
||||
if (WARN_ON(!ppage || order))
|
||||
return;
|
||||
|
||||
account_locked_vm(mm, 1 << ppage->order, false);
|
||||
|
||||
Reference in New Issue
Block a user