s390/mm: take the mmap_sem in kvm_s390_shadow_fault()
authorDavid Hildenbrand <dahi@linux.vnet.ibm.com>
Tue, 2 Feb 2016 11:26:00 +0000 (12:26 +0100)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Mon, 20 Jun 2016 07:54:33 +0000 (09:54 +0200)
Instead of doing it in the caller, let's just take the mmap_sem
in kvm_s390_shadow_fault(). By taking it as read, we allow parallel
faulting on shadow page tables, gmap shadow code is prepared for that.

Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
arch/s390/kvm/gaccess.c

index c5f79c1..5b5eee2 100644 (file)
@@ -1091,26 +1091,24 @@ int kvm_s390_shadow_fault(struct gmap *sg, unsigned long saddr, int write)
        int dat_protection;
        int rc;
 
+       down_read(&sg->mm->mmap_sem);
+
        rc = gmap_shadow_pgt_lookup(sg, saddr, &pgt, &dat_protection);
-       if (rc) {
+       if (rc)
                rc = kvm_s390_shadow_tables(sg, saddr, &pgt, &dat_protection);
-               if (rc)
-                       return rc;
-       }
 
        vaddr.addr = saddr;
-       rc = gmap_read_table(sg->parent, pgt + vaddr.px * 8, &pte.val);
-       if (rc)
-               return rc;
-       if (pte.i)
-               return PGM_PAGE_TRANSLATION;
-       if (pte.z || pte.co)
-               return PGM_TRANSLATION_SPEC;
+       if (!rc)
+               rc = gmap_read_table(sg->parent, pgt + vaddr.px * 8, &pte.val);
+       if (!rc && pte.i)
+               rc = PGM_PAGE_TRANSLATION;
+       if (!rc && (pte.z || pte.co))
+               rc = PGM_TRANSLATION_SPEC;
        dat_protection |= pte.p;
-       if (write && dat_protection)
-               return PGM_PROTECTION;
-       rc = gmap_shadow_page(sg, saddr, __pte(pte.val));
-       if (rc)
-               return rc;
-       return 0;
+       if (!rc && write && dat_protection)
+               rc = PGM_PROTECTION;
+       if (!rc)
+               rc = gmap_shadow_page(sg, saddr, __pte(pte.val));
+       up_read(&sg->mm->mmap_sem);
+       return rc;
 }