diff mbox

[3.13.y.z,extended,stable] Patch "KVM: s390/mm: try a cow on read only pages for key ops" has been added to staging queue

Message ID 1412112582-25953-1-git-send-email-kamal@canonical.com
State New
Headers show

Commit Message

Kamal Mostafa Sept. 30, 2014, 9:29 p.m. UTC
This is a note to let you know that I have just added a patch titled

    KVM: s390/mm: try a cow on read only pages for key ops

to the linux-3.13.y-queue branch of the 3.13.y.z extended stable tree 
which can be found at:

 http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.13.y-queue

This patch is scheduled to be released in version 3.13.11.8.

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.13.y.z tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable

Thanks.
-Kamal

------

From afc3eae1dbdfe880492d496b76aa0078dacc24d4 Mon Sep 17 00:00:00 2001
From: Christian Borntraeger <borntraeger@de.ibm.com>
Date: Tue, 19 Aug 2014 16:19:35 +0200
Subject: KVM: s390/mm: try a cow on read only pages for key ops

commit ab3f285f227fec62868037e9b1b1fd18294a83b8 upstream.

The PFMF instruction handler  blindly wrote the storage key even if
the page was mapped R/O in the host. Lets try a COW before continuing
and bail out in case of errors.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Dominik Dingel <dingel@linux.vnet.ibm.com>
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
---
 arch/s390/mm/pgtable.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

--
1.9.1
diff mbox

Patch

diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index e794c88..9cffb96 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -810,11 +810,21 @@  int set_guest_storage_key(struct mm_struct *mm, unsigned long addr,
 	pte_t *ptep;

 	down_read(&mm->mmap_sem);
+retry:
 	ptep = get_locked_pte(current->mm, addr, &ptl);
 	if (unlikely(!ptep)) {
 		up_read(&mm->mmap_sem);
 		return -EFAULT;
 	}
+	if (!(pte_val(*ptep) & _PAGE_INVALID) &&
+	     (pte_val(*ptep) & _PAGE_PROTECT)) {
+			pte_unmap_unlock(*ptep, ptl);
+			if (fixup_user_fault(current, mm, addr, FAULT_FLAG_WRITE)) {
+				up_read(&mm->mmap_sem);
+				return -EFAULT;
+			}
+			goto retry;
+		}

 	new = old = pgste_get_lock(ptep);
 	pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT |