mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-23 07:23:12 +02:00
KVM: PPC: Explicitly require struct page memory for Ultravisor sharing
Explicitly require "struct page" memory when sharing memory between guest and host via an Ultravisor. Given the number of pfn_to_page() calls in the code, it's safe to assume that KVM already requires that the pfn returned by gfn_to_pfn() is backed by struct page, i.e. this is likely a bug fix, not a reduction in KVM capabilities. Switching to gfn_to_page() will eventually allow removing gfn_to_pfn() and kvm_pfn_to_refcounted_page(). 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-79-seanjc@google.com>
This commit is contained in:
parent
570d666c11
commit
040537ce87
|
@ -879,9 +879,8 @@ static unsigned long kvmppc_share_page(struct kvm *kvm, unsigned long gpa,
|
||||||
{
|
{
|
||||||
|
|
||||||
int ret = H_PARAMETER;
|
int ret = H_PARAMETER;
|
||||||
struct page *uvmem_page;
|
struct page *page, *uvmem_page;
|
||||||
struct kvmppc_uvmem_page_pvt *pvt;
|
struct kvmppc_uvmem_page_pvt *pvt;
|
||||||
unsigned long pfn;
|
|
||||||
unsigned long gfn = gpa >> page_shift;
|
unsigned long gfn = gpa >> page_shift;
|
||||||
int srcu_idx;
|
int srcu_idx;
|
||||||
unsigned long uvmem_pfn;
|
unsigned long uvmem_pfn;
|
||||||
|
@ -901,8 +900,8 @@ static unsigned long kvmppc_share_page(struct kvm *kvm, unsigned long gpa,
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
mutex_unlock(&kvm->arch.uvmem_lock);
|
mutex_unlock(&kvm->arch.uvmem_lock);
|
||||||
pfn = gfn_to_pfn(kvm, gfn);
|
page = gfn_to_page(kvm, gfn);
|
||||||
if (is_error_noslot_pfn(pfn))
|
if (!page)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
mutex_lock(&kvm->arch.uvmem_lock);
|
mutex_lock(&kvm->arch.uvmem_lock);
|
||||||
|
@ -911,16 +910,16 @@ retry:
|
||||||
pvt = uvmem_page->zone_device_data;
|
pvt = uvmem_page->zone_device_data;
|
||||||
pvt->skip_page_out = true;
|
pvt->skip_page_out = true;
|
||||||
pvt->remove_gfn = false; /* it continues to be a valid GFN */
|
pvt->remove_gfn = false; /* it continues to be a valid GFN */
|
||||||
kvm_release_pfn_clean(pfn);
|
kvm_release_page_unused(page);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uv_page_in(kvm->arch.lpid, pfn << page_shift, gpa, 0,
|
if (!uv_page_in(kvm->arch.lpid, page_to_pfn(page) << page_shift, gpa, 0,
|
||||||
page_shift)) {
|
page_shift)) {
|
||||||
kvmppc_gfn_shared(gfn, kvm);
|
kvmppc_gfn_shared(gfn, kvm);
|
||||||
ret = H_SUCCESS;
|
ret = H_SUCCESS;
|
||||||
}
|
}
|
||||||
kvm_release_pfn_clean(pfn);
|
kvm_release_page_clean(page);
|
||||||
mutex_unlock(&kvm->arch.uvmem_lock);
|
mutex_unlock(&kvm->arch.uvmem_lock);
|
||||||
out:
|
out:
|
||||||
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
srcu_read_unlock(&kvm->srcu, srcu_idx);
|
||||||
|
@ -1083,21 +1082,21 @@ out:
|
||||||
|
|
||||||
int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
|
int kvmppc_send_page_to_uv(struct kvm *kvm, unsigned long gfn)
|
||||||
{
|
{
|
||||||
unsigned long pfn;
|
struct page *page;
|
||||||
int ret = U_SUCCESS;
|
int ret = U_SUCCESS;
|
||||||
|
|
||||||
pfn = gfn_to_pfn(kvm, gfn);
|
page = gfn_to_page(kvm, gfn);
|
||||||
if (is_error_noslot_pfn(pfn))
|
if (!page)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
mutex_lock(&kvm->arch.uvmem_lock);
|
mutex_lock(&kvm->arch.uvmem_lock);
|
||||||
if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL))
|
if (kvmppc_gfn_is_uvmem_pfn(gfn, kvm, NULL))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ret = uv_page_in(kvm->arch.lpid, pfn << PAGE_SHIFT, gfn << PAGE_SHIFT,
|
ret = uv_page_in(kvm->arch.lpid, page_to_pfn(page) << PAGE_SHIFT,
|
||||||
0, PAGE_SHIFT);
|
gfn << PAGE_SHIFT, 0, PAGE_SHIFT);
|
||||||
out:
|
out:
|
||||||
kvm_release_pfn_clean(pfn);
|
kvm_release_page_clean(page);
|
||||||
mutex_unlock(&kvm->arch.uvmem_lock);
|
mutex_unlock(&kvm->arch.uvmem_lock);
|
||||||
return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT;
|
return (ret == U_SUCCESS) ? RESUME_GUEST : -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user