]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - arch/s390/mm/pgtable.c
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm into next
[karo-tx-linux.git] / arch / s390 / mm / pgtable.c
index ea4a31b9599000648741bc40caad87f16f5433a0..37b8241ec784ae8c2f9e32eb8a9868bb41e72e8a 100644 (file)
@@ -53,8 +53,10 @@ static void __crst_table_upgrade(void *arg)
 {
        struct mm_struct *mm = arg;
 
-       if (current->active_mm == mm)
-               update_user_asce(mm, 1);
+       if (current->active_mm == mm) {
+               clear_user_asce();
+               set_user_asce(mm);
+       }
        __tlb_flush_local();
 }
 
@@ -108,7 +110,7 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
        pgd_t *pgd;
 
        if (current->active_mm == mm) {
-               clear_user_asce(mm, 1);
+               clear_user_asce();
                __tlb_flush_mm(mm);
        }
        while (mm->context.asce_limit > limit) {
@@ -134,7 +136,7 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
                crst_table_free(mm, (unsigned long *) pgd);
        }
        if (current->active_mm == mm)
-               update_user_asce(mm, 1);
+               set_user_asce(mm);
 }
 #endif
 
@@ -958,8 +960,10 @@ void page_table_reset_pgste(struct mm_struct *mm, unsigned long start,
        unsigned long addr, next;
        pgd_t *pgd;
 
+       down_write(&mm->mmap_sem);
+       if (init_skey && mm_use_skey(mm))
+               goto out_up;
        addr = start;
-       down_read(&mm->mmap_sem);
        pgd = pgd_offset(mm, addr);
        do {
                next = pgd_addr_end(addr, end);
@@ -967,7 +971,10 @@ void page_table_reset_pgste(struct mm_struct *mm, unsigned long start,
                        continue;
                next = page_table_reset_pud(mm, pgd, addr, next, init_skey);
        } while (pgd++, addr = next, addr != end);
-       up_read(&mm->mmap_sem);
+       if (init_skey)
+               current->mm->context.use_skey = 1;
+out_up:
+       up_write(&mm->mmap_sem);
 }
 EXPORT_SYMBOL(page_table_reset_pgste);
 
@@ -1384,19 +1391,6 @@ EXPORT_SYMBOL_GPL(s390_enable_sie);
  */
 void s390_enable_skey(void)
 {
-       /*
-        * To avoid races between multiple vcpus, ending in calling
-        * page_table_reset twice or more,
-        * the page_table_lock is taken for serialization.
-        */
-       spin_lock(&current->mm->page_table_lock);
-       if (mm_use_skey(current->mm)) {
-               spin_unlock(&current->mm->page_table_lock);
-               return;
-       }
-
-       current->mm->context.use_skey = 1;
-       spin_unlock(&current->mm->page_table_lock);
        page_table_reset_pgste(current->mm, 0, TASK_SIZE, true);
 }
 EXPORT_SYMBOL_GPL(s390_enable_skey);