mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
KVM: pfncache: Precisely track refcounted pages
Track refcounted struct page memory using kvm_follow_pfn.refcounted_page instead of relying on kvm_release_pfn_clean() to correctly detect that the pfn is associated with a struct page. Tested-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Sean Christopherson <seanjc@google.com> Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-ID: <20241010182427.1434605-30-seanjc@google.com>
This commit is contained in:
parent
775e3ff7bf
commit
3154ddcb6a
|
@ -159,11 +159,14 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_cache *gpc)
|
||||||
kvm_pfn_t new_pfn = KVM_PFN_ERR_FAULT;
|
kvm_pfn_t new_pfn = KVM_PFN_ERR_FAULT;
|
||||||
void *new_khva = NULL;
|
void *new_khva = NULL;
|
||||||
unsigned long mmu_seq;
|
unsigned long mmu_seq;
|
||||||
|
struct page *page;
|
||||||
|
|
||||||
struct kvm_follow_pfn kfp = {
|
struct kvm_follow_pfn kfp = {
|
||||||
.slot = gpc->memslot,
|
.slot = gpc->memslot,
|
||||||
.gfn = gpa_to_gfn(gpc->gpa),
|
.gfn = gpa_to_gfn(gpc->gpa),
|
||||||
.flags = FOLL_WRITE,
|
.flags = FOLL_WRITE,
|
||||||
.hva = gpc->uhva,
|
.hva = gpc->uhva,
|
||||||
|
.refcounted_page = &page,
|
||||||
};
|
};
|
||||||
|
|
||||||
lockdep_assert_held(&gpc->refresh_lock);
|
lockdep_assert_held(&gpc->refresh_lock);
|
||||||
|
@ -198,7 +201,7 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_cache *gpc)
|
||||||
if (new_khva != old_khva)
|
if (new_khva != old_khva)
|
||||||
gpc_unmap(new_pfn, new_khva);
|
gpc_unmap(new_pfn, new_khva);
|
||||||
|
|
||||||
kvm_release_pfn_clean(new_pfn);
|
kvm_release_page_unused(page);
|
||||||
|
|
||||||
cond_resched();
|
cond_resched();
|
||||||
}
|
}
|
||||||
|
@ -218,7 +221,7 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_cache *gpc)
|
||||||
new_khva = gpc_map(new_pfn);
|
new_khva = gpc_map(new_pfn);
|
||||||
|
|
||||||
if (!new_khva) {
|
if (!new_khva) {
|
||||||
kvm_release_pfn_clean(new_pfn);
|
kvm_release_page_unused(page);
|
||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,11 +239,11 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_cache *gpc)
|
||||||
gpc->khva = new_khva + offset_in_page(gpc->uhva);
|
gpc->khva = new_khva + offset_in_page(gpc->uhva);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Put the reference to the _new_ pfn. The pfn is now tracked by the
|
* Put the reference to the _new_ page. The page is now tracked by the
|
||||||
* cache and can be safely migrated, swapped, etc... as the cache will
|
* cache and can be safely migrated, swapped, etc... as the cache will
|
||||||
* invalidate any mappings in response to relevant mmu_notifier events.
|
* invalidate any mappings in response to relevant mmu_notifier events.
|
||||||
*/
|
*/
|
||||||
kvm_release_pfn_clean(new_pfn);
|
kvm_release_page_clean(page);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user