Merge tag 'mm-stable-2022-08-03' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / s390 / mm / fault.c
index 973dcd0..1344994 100644 (file)
@@ -766,6 +766,7 @@ void do_secure_storage_access(struct pt_regs *regs)
        struct vm_area_struct *vma;
        struct mm_struct *mm;
        struct page *page;
+       struct gmap *gmap;
        int rc;
 
        /*
@@ -795,6 +796,17 @@ void do_secure_storage_access(struct pt_regs *regs)
        }
 
        switch (get_fault_type(regs)) {
+       case GMAP_FAULT:
+               mm = current->mm;
+               gmap = (struct gmap *)S390_lowcore.gmap;
+               mmap_read_lock(mm);
+               addr = __gmap_translate(gmap, addr);
+               mmap_read_unlock(mm);
+               if (IS_ERR_VALUE(addr)) {
+                       do_fault_error(regs, VM_ACCESS_FLAGS, VM_FAULT_BADMAP);
+                       break;
+               }
+               fallthrough;
        case USER_FAULT:
                mm = current->mm;
                mmap_read_lock(mm);
@@ -823,7 +835,6 @@ void do_secure_storage_access(struct pt_regs *regs)
                if (rc)
                        BUG();
                break;
-       case GMAP_FAULT:
        default:
                do_fault_error(regs, VM_READ | VM_WRITE, VM_FAULT_BADMAP);
                WARN_ON_ONCE(1);
@@ -849,6 +860,16 @@ NOKPROBE_SYMBOL(do_non_secure_storage_access);
 
 void do_secure_storage_violation(struct pt_regs *regs)
 {
+       unsigned long gaddr = regs->int_parm_long & __FAIL_ADDR_MASK;
+       struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
+
+       /*
+        * If the VM has been rebooted, its address space might still contain
+        * secure pages from the previous boot.
+        * Clear the page so it can be reused.
+        */
+       if (!gmap_destroy_page(gmap, gaddr))
+               return;
        /*
         * Either KVM messed up the secure guest mapping or the same
         * page is mapped into multiple secure guests.