summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/uv.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-05-17 14:02:08 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-05-17 14:02:08 +0200
commite6a62f955681c58f49b1ce74222d6670fb55bb33 (patch)
treeb7122202e22b1bbd8bd0e9b762e1675de8d2ea42 /arch/s390/kernel/uv.c
parent7e55399235e88fa56bc2763d1d900e75e582d114 (diff)
parent170014a900a54d2c44ba6aacd3acda1733018c69 (diff)
downloadlinux-stable-linux-rolling-stable.tar.gz
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/s390/kernel/uv.c')
-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);