summaryrefslogtreecommitdiff
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2023-05-05 13:15:09 +0300
committerPaolo Bonzini <pbonzini@redhat.com>2023-05-05 13:15:09 +0300
commit7a8016d95651fecce5708ed93a24a03a9ad91c80 (patch)
tree4f06d729d1832bc0e4ce6b0914f7d00a1247a5c2 /arch/s390/kernel
parent29b38e765016e7b99f6ced75b359ee2b44f17269 (diff)
parentc148dc8e2fa403be501612ee409db866eeed35c0 (diff)
downloadlinux-7a8016d95651fecce5708ed93a24a03a9ad91c80.tar.xz
Merge tag 'kvm-s390-next-6.4-2' of https://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
For 6.4
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/uv.c32
1 files changed, 11 insertions, 21 deletions
diff --git a/arch/s390/kernel/uv.c b/arch/s390/kernel/uv.c
index 9f18a4af9c13..cb2ee06df286 100644
--- a/arch/s390/kernel/uv.c
+++ b/arch/s390/kernel/uv.c
@@ -192,21 +192,10 @@ static int expected_page_refs(struct page *page)
return res;
}
-static int make_secure_pte(pte_t *ptep, unsigned long addr,
- struct page *exp_page, struct uv_cb_header *uvcb)
+static int make_page_secure(struct page *page, struct uv_cb_header *uvcb)
{
- pte_t entry = READ_ONCE(*ptep);
- struct page *page;
int expected, cc = 0;
- if (!pte_present(entry))
- return -ENXIO;
- if (pte_val(entry) & _PAGE_INVALID)
- return -ENXIO;
-
- page = pte_page(entry);
- if (page != exp_page)
- return -ENXIO;
if (PageWriteback(page))
return -EAGAIN;
expected = expected_page_refs(page);
@@ -304,17 +293,18 @@ again:
goto out;
rc = -ENXIO;
- page = follow_page(vma, uaddr, FOLL_WRITE);
- if (IS_ERR_OR_NULL(page))
- goto out;
-
- lock_page(page);
ptep = get_locked_pte(gmap->mm, uaddr, &ptelock);
- if (should_export_before_import(uvcb, gmap->mm))
- uv_convert_from_secure(page_to_phys(page));
- rc = make_secure_pte(ptep, uaddr, page, uvcb);
+ if (pte_present(*ptep) && !(pte_val(*ptep) & _PAGE_INVALID) && pte_write(*ptep)) {
+ page = pte_page(*ptep);
+ rc = -EAGAIN;
+ if (trylock_page(page)) {
+ if (should_export_before_import(uvcb, gmap->mm))
+ uv_convert_from_secure(page_to_phys(page));
+ rc = make_page_secure(page, uvcb);
+ unlock_page(page);
+ }
+ }
pte_unmap_unlock(ptep, ptelock);
- unlock_page(page);
out:
mmap_read_unlock(gmap->mm);