Merge branches 'akpm' and 'akpm-hotfixes' (patches from Andrew)
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Sep 2021 01:52:05 +0000 (18:52 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 Sep 2021 01:52:05 +0000 (18:52 -0700)
Merge yet more updates and hotfixes from Andrew Morton:
 "Post-linux-next material, based upon latest upstream to catch the
  now-merged dependencies:

   - 10 patches.

     Subsystems affected by this patch series: mm (vmstat and migration)
     and compat.

  And bunch of hotfixes, mostly cc:stable:

   - 8 patches.

     Subsystems affected by this patch series: mm (hmm, hugetlb, vmscan,
     pagealloc, pagemap, kmemleak, mempolicy, and memblock)"

* emailed patches from Andrew Morton <akpm@linux-foundation.org>:
  arch: remove compat_alloc_user_space
  compat: remove some compat entry points
  mm: simplify compat numa syscalls
  mm: simplify compat_sys_move_pages
  kexec: avoid compat_alloc_user_space
  kexec: move locking into do_kexec_load
  mm: migrate: change to use bool type for 'page_was_mapped'
  mm: migrate: fix the incorrect function name in comments
  mm: migrate: introduce a local variable to get the number of pages
  mm/vmstat: protect per cpu variables with preempt disable on RT

* emailed hotfixes from Andrew Morton <akpm@linux-foundation.org>:
  nds32/setup: remove unused memblock_region variable in setup_memory()
  mm/mempolicy: fix a race between offset_il_node and mpol_rebind_task
  mm/kmemleak: allow __GFP_NOLOCKDEP passed to kmemleak's gfp
  mmap_lock: change trace and locking order
  mm/page_alloc.c: avoid accessing uninitialized pcp page migratetype
  mm,vmscan: fix divide by zero in get_scan_count
  mm/hugetlb: initialize hugetlb_usage in mm_init
  mm/hmm: bypass devmap pte when all pfn requested flags are fulfilled

47 files changed:
arch/arm64/include/asm/compat.h
arch/arm64/include/asm/uaccess.h
arch/arm64/include/asm/unistd32.h
arch/arm64/lib/Makefile
arch/arm64/lib/copy_in_user.S [deleted file]
arch/mips/cavium-octeon/octeon-memcpy.S
arch/mips/include/asm/compat.h
arch/mips/include/asm/uaccess.h
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/mips/lib/memcpy.S
arch/nds32/kernel/setup.c
arch/parisc/include/asm/compat.h
arch/parisc/include/asm/uaccess.h
arch/parisc/kernel/syscalls/syscall.tbl
arch/parisc/lib/memcpy.c
arch/powerpc/include/asm/compat.h
arch/powerpc/kernel/syscalls/syscall.tbl
arch/s390/include/asm/compat.h
arch/s390/include/asm/uaccess.h
arch/s390/kernel/syscalls/syscall.tbl
arch/s390/lib/uaccess.c
arch/sparc/include/asm/compat.h
arch/sparc/kernel/process_64.c
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_64.c
arch/sparc/kernel/syscalls/syscall.tbl
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/syscalls/syscall_64.tbl
arch/x86/include/asm/compat.h
arch/x86/include/asm/uaccess_64.h
include/linux/compat.h
include/linux/hugetlb.h
include/linux/mmap_lock.h
include/linux/uaccess.h
include/uapi/asm-generic/unistd.h
kernel/compat.c
kernel/fork.c
kernel/kexec.c
kernel/sys_ni.c
mm/hmm.c
mm/kmemleak.c
mm/mempolicy.c
mm/migrate.c
mm/page_alloc.c
mm/vmscan.c
mm/vmstat.c

index 79c1a75..eaa6ca0 100644 (file)
@@ -107,11 +107,6 @@ struct compat_statfs {
 #define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
 #define COMPAT_MINSIGSTKSZ     2048
 
-static inline void __user *arch_compat_alloc_user_space(long len)
-{
-       return (void __user *)compat_user_stack_pointer() - len;
-}
-
 struct compat_ipc64_perm {
        compat_key_t key;
        __compat_uid32_t uid;
index b5f0862..190b494 100644 (file)
@@ -430,17 +430,6 @@ extern unsigned long __must_check __arch_copy_to_user(void __user *to, const voi
        __actu_ret;                                                     \
 })
 
-extern unsigned long __must_check __arch_copy_in_user(void __user *to, const void __user *from, unsigned long n);
-#define raw_copy_in_user(to, from, n)                                  \
-({                                                                     \
-       unsigned long __aciu_ret;                                       \
-       uaccess_ttbr0_enable();                                         \
-       __aciu_ret = __arch_copy_in_user(__uaccess_mask_ptr(to),        \
-                                   __uaccess_mask_ptr(from), (n));     \
-       uaccess_ttbr0_disable();                                        \
-       __aciu_ret;                                                     \
-})
-
 #define INLINE_COPY_TO_USER
 #define INLINE_COPY_FROM_USER
 
index 4e99e4b..844f6ae 100644 (file)
@@ -649,11 +649,11 @@ __SYSCALL(__NR_inotify_add_watch, sys_inotify_add_watch)
 #define __NR_inotify_rm_watch 318
 __SYSCALL(__NR_inotify_rm_watch, sys_inotify_rm_watch)
 #define __NR_mbind 319
-__SYSCALL(__NR_mbind, compat_sys_mbind)
+__SYSCALL(__NR_mbind, sys_mbind)
 #define __NR_get_mempolicy 320
-__SYSCALL(__NR_get_mempolicy, compat_sys_get_mempolicy)
+__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
 #define __NR_set_mempolicy 321
-__SYSCALL(__NR_set_mempolicy, compat_sys_set_mempolicy)
+__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
 #define __NR_openat 322
 __SYSCALL(__NR_openat, compat_sys_openat)
 #define __NR_mkdirat 323
@@ -699,7 +699,7 @@ __SYSCALL(__NR_tee, sys_tee)
 #define __NR_vmsplice 343
 __SYSCALL(__NR_vmsplice, sys_vmsplice)
 #define __NR_move_pages 344
-__SYSCALL(__NR_move_pages, compat_sys_move_pages)
+__SYSCALL(__NR_move_pages, sys_move_pages)
 #define __NR_getcpu 345
 __SYSCALL(__NR_getcpu, sys_getcpu)
 #define __NR_epoll_pwait 346
@@ -811,7 +811,7 @@ __SYSCALL(__NR_rseq, sys_rseq)
 #define __NR_io_pgetevents 399
 __SYSCALL(__NR_io_pgetevents, compat_sys_io_pgetevents)
 #define __NR_migrate_pages 400
-__SYSCALL(__NR_migrate_pages, compat_sys_migrate_pages)
+__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
 #define __NR_kexec_file_load 401
 __SYSCALL(__NR_kexec_file_load, sys_kexec_file_load)
 /* 402 is unused */
index 6dd56a4..0941180 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 lib-y          := clear_user.o delay.o copy_from_user.o                \
-                  copy_to_user.o copy_in_user.o copy_page.o            \
+                  copy_to_user.o copy_page.o                           \
                   clear_page.o csum.o insn.o memchr.o memcpy.o         \
                   memset.o memcmp.o strcmp.o strncmp.o strlen.o        \
                   strnlen.o strchr.o strrchr.o tishift.o
diff --git a/arch/arm64/lib/copy_in_user.S b/arch/arm64/lib/copy_in_user.S
deleted file mode 100644 (file)
index dbea379..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copy from user space to user space
- *
- * Copyright (C) 2012 ARM Ltd.
- */
-
-#include <linux/linkage.h>
-
-#include <asm/asm-uaccess.h>
-#include <asm/assembler.h>
-#include <asm/cache.h>
-
-/*
- * Copy from user space to user space (alignment handled by the hardware)
- *
- * Parameters:
- *     x0 - to
- *     x1 - from
- *     x2 - n
- * Returns:
- *     x0 - bytes not copied
- */
-       .macro ldrb1 reg, ptr, val
-       user_ldst 9998f, ldtrb, \reg, \ptr, \val
-       .endm
-
-       .macro strb1 reg, ptr, val
-       user_ldst 9998f, sttrb, \reg, \ptr, \val
-       .endm
-
-       .macro ldrh1 reg, ptr, val
-       user_ldst 9997f, ldtrh, \reg, \ptr, \val
-       .endm
-
-       .macro strh1 reg, ptr, val
-       user_ldst 9997f, sttrh, \reg, \ptr, \val
-       .endm
-
-       .macro ldr1 reg, ptr, val
-       user_ldst 9997f, ldtr, \reg, \ptr, \val
-       .endm
-
-       .macro str1 reg, ptr, val
-       user_ldst 9997f, sttr, \reg, \ptr, \val
-       .endm
-
-       .macro ldp1 reg1, reg2, ptr, val
-       user_ldp 9997f, \reg1, \reg2, \ptr, \val
-       .endm
-
-       .macro stp1 reg1, reg2, ptr, val
-       user_stp 9997f, \reg1, \reg2, \ptr, \val
-       .endm
-
-end    .req    x5
-srcin  .req    x15
-SYM_FUNC_START(__arch_copy_in_user)
-       add     end, x0, x2
-       mov     srcin, x1
-#include "copy_template.S"
-       mov     x0, #0
-       ret
-SYM_FUNC_END(__arch_copy_in_user)
-EXPORT_SYMBOL(__arch_copy_in_user)
-
-       .section .fixup,"ax"
-       .align  2
-9997:  cmp     dst, dstin
-       b.ne    9998f
-       // Before being absolutely sure we couldn't copy anything, try harder
-USER(9998f, ldtrb tmp1w, [srcin])
-USER(9998f, sttrb tmp1w, [dst])
-       add     dst, dst, #1
-9998:  sub     x0, end, dst                    // bytes not copied
-       ret
-       .previous
index 600d018..0a515cd 100644 (file)
@@ -154,8 +154,6 @@ FEXPORT(__raw_copy_from_user)
 EXPORT_SYMBOL(__raw_copy_from_user)
 FEXPORT(__raw_copy_to_user)
 EXPORT_SYMBOL(__raw_copy_to_user)
-FEXPORT(__raw_copy_in_user)
-EXPORT_SYMBOL(__raw_copy_in_user)
        /*
         * Note: dst & src may be unaligned, len may be 0
         * Temps
index 53f015a..bbb3bc5 100644 (file)
@@ -96,14 +96,6 @@ struct compat_statfs {
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
 
-static inline void __user *arch_compat_alloc_user_space(long len)
-{
-       struct pt_regs *regs = (struct pt_regs *)
-               ((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
-
-       return (void __user *) (regs->regs[29] - len);
-}
-
 struct compat_ipc64_perm {
        compat_key_t key;
        __compat_uid32_t uid;
index 783fecc..f8f74f9 100644 (file)
@@ -428,7 +428,6 @@ do {                                                                        \
 
 extern size_t __raw_copy_from_user(void *__to, const void *__from, size_t __n);
 extern size_t __raw_copy_to_user(void *__to, const void *__from, size_t __n);
-extern size_t __raw_copy_in_user(void *__to, const void *__from, size_t __n);
 
 static inline unsigned long
 raw_copy_from_user(void *to, const void __user *from, unsigned long n)
@@ -480,31 +479,6 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
 #define INLINE_COPY_FROM_USER
 #define INLINE_COPY_TO_USER
 
-static inline unsigned long
-raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
-{
-       register void __user *__cu_to_r __asm__("$4");
-       register const void __user *__cu_from_r __asm__("$5");
-       register long __cu_len_r __asm__("$6");
-
-       __cu_to_r = to;
-       __cu_from_r = from;
-       __cu_len_r = n;
-
-       __asm__ __volatile__(
-               ".set\tnoreorder\n\t"
-               __MODULE_JAL(__raw_copy_in_user)
-               ".set\tnoat\n\t"
-               __UA_ADDU "\t$1, %1, %2\n\t"
-               ".set\tat\n\t"
-               ".set\treorder"
-               : "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
-               :
-               : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
-                 DADDI_SCRATCH, "memory");
-       return __cu_len_r;
-}
-
 extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size);
 
 /*
index 56c8d3c..70e32de 100644 (file)
 228    n32     clock_nanosleep                 sys_clock_nanosleep_time32
 229    n32     tgkill                          sys_tgkill
 230    n32     utimes                          sys_utimes_time32
-231    n32     mbind                           compat_sys_mbind
-232    n32     get_mempolicy                   compat_sys_get_mempolicy
-233    n32     set_mempolicy                   compat_sys_set_mempolicy
+231    n32     mbind                           sys_mbind
+232    n32     get_mempolicy                   sys_get_mempolicy
+233    n32     set_mempolicy                   sys_set_mempolicy
 234    n32     mq_open                         compat_sys_mq_open
 235    n32     mq_unlink                       sys_mq_unlink
 236    n32     mq_timedsend                    sys_mq_timedsend_time32
 247    n32     inotify_init                    sys_inotify_init
 248    n32     inotify_add_watch               sys_inotify_add_watch
 249    n32     inotify_rm_watch                sys_inotify_rm_watch
-250    n32     migrate_pages                   compat_sys_migrate_pages
+250    n32     migrate_pages                   sys_migrate_pages
 251    n32     openat                          sys_openat
 252    n32     mkdirat                         sys_mkdirat
 253    n32     mknodat                         sys_mknodat
 268    n32     sync_file_range                 sys_sync_file_range
 269    n32     tee                             sys_tee
 270    n32     vmsplice                        sys_vmsplice
-271    n32     move_pages                      compat_sys_move_pages
+271    n32     move_pages                      sys_move_pages
 272    n32     set_robust_list                 compat_sys_set_robust_list
 273    n32     get_robust_list                 compat_sys_get_robust_list
 274    n32     kexec_load                      compat_sys_kexec_load
index 201237f..a61c35e 100644 (file)
 265    o32     clock_nanosleep                 sys_clock_nanosleep_time32
 266    o32     tgkill                          sys_tgkill
 267    o32     utimes                          sys_utimes_time32
-268    o32     mbind                           sys_mbind                       compat_sys_mbind
-269    o32     get_mempolicy                   sys_get_mempolicy               compat_sys_get_mempolicy
-270    o32     set_mempolicy                   sys_set_mempolicy               compat_sys_set_mempolicy
+268    o32     mbind                           sys_mbind
+269    o32     get_mempolicy                   sys_get_mempolicy
+270    o32     set_mempolicy                   sys_set_mempolicy
 271    o32     mq_open                         sys_mq_open                     compat_sys_mq_open
 272    o32     mq_unlink                       sys_mq_unlink
 273    o32     mq_timedsend                    sys_mq_timedsend_time32
 284    o32     inotify_init                    sys_inotify_init
 285    o32     inotify_add_watch               sys_inotify_add_watch
 286    o32     inotify_rm_watch                sys_inotify_rm_watch
-287    o32     migrate_pages                   sys_migrate_pages               compat_sys_migrate_pages
+287    o32     migrate_pages                   sys_migrate_pages
 288    o32     openat                          sys_openat                      compat_sys_openat
 289    o32     mkdirat                         sys_mkdirat
 290    o32     mknodat                         sys_mknodat
 305    o32     sync_file_range                 sys_sync_file_range             sys32_sync_file_range
 306    o32     tee                             sys_tee
 307    o32     vmsplice                        sys_vmsplice
-308    o32     move_pages                      sys_move_pages                  compat_sys_move_pages
+308    o32     move_pages                      sys_move_pages
 309    o32     set_robust_list                 sys_set_robust_list             compat_sys_set_robust_list
 310    o32     get_robust_list                 sys_get_robust_list             compat_sys_get_robust_list
 311    o32     kexec_load                      sys_kexec_load                  compat_sys_kexec_load
index e19fb98..277c322 100644 (file)
@@ -666,8 +666,6 @@ FEXPORT(__raw_copy_from_user)
 EXPORT_SYMBOL(__raw_copy_from_user)
 FEXPORT(__raw_copy_to_user)
 EXPORT_SYMBOL(__raw_copy_to_user)
-FEXPORT(__raw_copy_in_user)
-EXPORT_SYMBOL(__raw_copy_in_user)
 #endif
        /* Legacy Mode, user <-> user */
        __BUILD_COPY_USER LEGACY_MODE USEROP USEROP
@@ -703,13 +701,4 @@ EXPORT_SYMBOL(__raw_copy_to_user)
 __BUILD_COPY_USER EVA_MODE KERNELOP USEROP
 END(__raw_copy_to_user)
 
-/*
- * __copy_in_user (EVA)
- */
-
-LEAF(__raw_copy_in_user)
-EXPORT_SYMBOL(__raw_copy_in_user)
-__BUILD_COPY_USER EVA_MODE USEROP USEROP
-END(__raw_copy_in_user)
-
 #endif
index 41725ea..b3d34d6 100644 (file)
@@ -244,7 +244,6 @@ static void __init setup_memory(void)
        unsigned long ram_start_pfn;
        unsigned long free_ram_start_pfn;
        phys_addr_t memory_start, memory_end;
-       struct memblock_region *region;
 
        memory_end = memory_start = 0;
 
index b5d90e8..c04f5a6 100644 (file)
@@ -163,12 +163,6 @@ struct compat_shmid64_ds {
 #define COMPAT_ELF_NGREG 80
 typedef compat_ulong_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
 
-static __inline__ void __user *arch_compat_alloc_user_space(long len)
-{
-       struct pt_regs *regs = &current->thread.regs;
-       return (void __user *)regs->gr[30];
-}
-
 static inline int __is_compat_task(struct task_struct *t)
 {
        return test_tsk_thread_flag(t, TIF_32BIT);
index ed2cd4f..7c13314 100644 (file)
@@ -215,8 +215,6 @@ unsigned long __must_check raw_copy_to_user(void __user *dst, const void *src,
                                            unsigned long len);
 unsigned long __must_check raw_copy_from_user(void *dst, const void __user *src,
                                            unsigned long len);
-unsigned long __must_check raw_copy_in_user(void __user *dst, const void __user *src,
-                                           unsigned long len);
 #define INLINE_COPY_TO_USER
 #define INLINE_COPY_FROM_USER
 
index 0bf854b..bf751e0 100644 (file)
 258    32      clock_nanosleep         sys_clock_nanosleep_time32
 258    64      clock_nanosleep         sys_clock_nanosleep
 259    common  tgkill                  sys_tgkill
-260    common  mbind                   sys_mbind                       compat_sys_mbind
-261    common  get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
-262    common  set_mempolicy           sys_set_mempolicy               compat_sys_set_mempolicy
+260    common  mbind                   sys_mbind
+261    common  get_mempolicy           sys_get_mempolicy
+262    common  set_mempolicy           sys_set_mempolicy
 # 263 was vserver
 264    common  add_key                 sys_add_key
 265    common  request_key             sys_request_key
 292    64      sync_file_range         sys_sync_file_range
 293    common  tee                     sys_tee
 294    common  vmsplice                sys_vmsplice
-295    common  move_pages              sys_move_pages                  compat_sys_move_pages
+295    common  move_pages              sys_move_pages
 296    common  getcpu                  sys_getcpu
 297    common  epoll_pwait             sys_epoll_pwait                 compat_sys_epoll_pwait
 298    common  statfs64                sys_statfs64                    compat_sys_statfs64
index 4b75388..ea70a0e 100644 (file)
@@ -38,14 +38,6 @@ unsigned long raw_copy_from_user(void *dst, const void __user *src,
 }
 EXPORT_SYMBOL(raw_copy_from_user);
 
-unsigned long raw_copy_in_user(void __user *dst, const void __user *src, unsigned long len)
-{
-       mtsp(get_user_space(), 1);
-       mtsp(get_user_space(), 2);
-       return pa_memcpy((void __force *)dst, (void __force *)src, len);
-}
-
-
 void * memcpy(void * dst,const void *src, size_t count)
 {
        mtsp(get_kernel_space(), 1);
@@ -54,7 +46,6 @@ void * memcpy(void * dst,const void *src, size_t count)
        return dst;
 }
 
-EXPORT_SYMBOL(raw_copy_in_user);
 EXPORT_SYMBOL(memcpy);
 
 bool copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size)
index e33dcf1..7afc96f 100644 (file)
@@ -83,22 +83,6 @@ struct compat_statfs {
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
 
-static inline void __user *arch_compat_alloc_user_space(long len)
-{
-       struct pt_regs *regs = current->thread.regs;
-       unsigned long usp = regs->gpr[1];
-
-       /*
-        * We can't access below the stack pointer in the 32bit ABI and
-        * can access 288 bytes in the 64bit big-endian ABI,
-        * or 512 bytes with the new ELFv2 little-endian ABI.
-        */
-       if (!is_32bit_task())
-               usp -= USER_REDZONE_SIZE;
-
-       return (void __user *) (usp - len);
-}
-
 /*
  * ipc64_perm is actually 32/64bit clean but since the compat layer refers to
  * it we may as well define it.
index 29b55e2..7bef917 100644 (file)
 256    64      sys_debug_setcontext            sys_ni_syscall
 256    spu     sys_debug_setcontext            sys_ni_syscall
 # 257 reserved for vserver
-258    nospu   migrate_pages                   sys_migrate_pages               compat_sys_migrate_pages
-259    nospu   mbind                           sys_mbind                       compat_sys_mbind
-260    nospu   get_mempolicy                   sys_get_mempolicy               compat_sys_get_mempolicy
-261    nospu   set_mempolicy                   sys_set_mempolicy               compat_sys_set_mempolicy
+258    nospu   migrate_pages                   sys_migrate_pages
+259    nospu   mbind                           sys_mbind
+260    nospu   get_mempolicy                   sys_get_mempolicy
+261    nospu   set_mempolicy                   sys_set_mempolicy
 262    nospu   mq_open                         sys_mq_open                     compat_sys_mq_open
 263    nospu   mq_unlink                       sys_mq_unlink
 264    32      mq_timedsend                    sys_mq_timedsend_time32
 298    common  faccessat                       sys_faccessat
 299    common  get_robust_list                 sys_get_robust_list             compat_sys_get_robust_list
 300    common  set_robust_list                 sys_set_robust_list             compat_sys_set_robust_list
-301    common  move_pages                      sys_move_pages                  compat_sys_move_pages
+301    common  move_pages                      sys_move_pages
 302    common  getcpu                          sys_getcpu
 303    nospu   epoll_pwait                     sys_epoll_pwait                 compat_sys_epoll_pwait
 304    32      utimensat                       sys_utimensat_time32
index 8d49505..cdc7ae7 100644 (file)
@@ -176,16 +176,6 @@ static inline int is_compat_task(void)
        return test_thread_flag(TIF_31BIT);
 }
 
-static inline void __user *arch_compat_alloc_user_space(long len)
-{
-       unsigned long stack;
-
-       stack = KSTK_ESP(current);
-       if (is_compat_task())
-               stack &= 0x7fffffffUL;
-       return (void __user *) (stack - len);
-}
-
 #endif
 
 struct compat_ipc64_perm {
index 9ed9aa3..ce550d0 100644 (file)
@@ -227,9 +227,6 @@ static inline int __get_user_fn(void *x, const void __user *ptr, unsigned long s
        __get_user(x, ptr);                                     \
 })
 
-unsigned long __must_check
-raw_copy_in_user(void __user *to, const void __user *from, unsigned long n);
-
 /*
  * Copy a null terminated string from userspace.
  */
index aa9d68b..df5261e 100644 (file)
 265  common    statfs64                sys_statfs64                    compat_sys_statfs64
 266  common    fstatfs64               sys_fstatfs64                   compat_sys_fstatfs64
 267  common    remap_file_pages        sys_remap_file_pages            sys_remap_file_pages
-268  common    mbind                   sys_mbind                       compat_sys_mbind
-269  common    get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
-270  common    set_mempolicy           sys_set_mempolicy               compat_sys_set_mempolicy
+268  common    mbind                   sys_mbind                       sys_mbind
+269  common    get_mempolicy           sys_get_mempolicy               sys_get_mempolicy
+270  common    set_mempolicy           sys_set_mempolicy               sys_set_mempolicy
 271  common    mq_open                 sys_mq_open                     compat_sys_mq_open
 272  common    mq_unlink               sys_mq_unlink                   sys_mq_unlink
 273  common    mq_timedsend            sys_mq_timedsend                sys_mq_timedsend_time32
 284  common    inotify_init            sys_inotify_init                sys_inotify_init
 285  common    inotify_add_watch       sys_inotify_add_watch           sys_inotify_add_watch
 286  common    inotify_rm_watch        sys_inotify_rm_watch            sys_inotify_rm_watch
-287  common    migrate_pages           sys_migrate_pages               compat_sys_migrate_pages
+287  common    migrate_pages           sys_migrate_pages               sys_migrate_pages
 288  common    openat                  sys_openat                      compat_sys_openat
 289  common    mkdirat                 sys_mkdirat                     sys_mkdirat
 290  common    mknodat                 sys_mknodat                     sys_mknodat
 307  common    sync_file_range         sys_sync_file_range             compat_sys_s390_sync_file_range
 308  common    tee                     sys_tee                         sys_tee
 309  common    vmsplice                sys_vmsplice                    sys_vmsplice
-310  common    move_pages              sys_move_pages                  compat_sys_move_pages
+310  common    move_pages              sys_move_pages                  sys_move_pages
 311  common    getcpu                  sys_getcpu                      sys_getcpu
 312  common    epoll_pwait             sys_epoll_pwait                 compat_sys_epoll_pwait
 313  common    utimes                  sys_utimes                      sys_utimes_time32
index 94ca99b..a596e69 100644 (file)
@@ -204,69 +204,6 @@ unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long
 }
 EXPORT_SYMBOL(raw_copy_to_user);
 
-static inline unsigned long copy_in_user_mvcos(void __user *to, const void __user *from,
-                                              unsigned long size)
-{
-       unsigned long tmp1, tmp2;
-
-       tmp1 = -4096UL;
-       /* FIXME: copy with reduced length. */
-       asm volatile(
-               "   lgr   0,%[spec]\n"
-               "0: .insn ss,0xc80000000000,0(%0,%1),0(%2),0\n"
-               "   jz    2f\n"
-               "1: algr  %0,%3\n"
-               "   slgr  %1,%3\n"
-               "   slgr  %2,%3\n"
-               "   j     0b\n"
-               "2:slgr  %0,%0\n"
-               "3: \n"
-               EX_TABLE(0b,3b)
-               : "+a" (size), "+a" (to), "+a" (from), "+a" (tmp1), "=a" (tmp2)
-               : [spec] "d" (0x810081UL)
-               : "cc", "memory", "0");
-       return size;
-}
-
-static inline unsigned long copy_in_user_mvc(void __user *to, const void __user *from,
-                                            unsigned long size)
-{
-       unsigned long tmp1;
-
-       asm volatile(
-               "   sacf  256\n"
-               "   aghi  %0,-1\n"
-               "   jo    5f\n"
-               "   bras  %3,3f\n"
-               "0: aghi  %0,257\n"
-               "1: mvc   0(1,%1),0(%2)\n"
-               "   la    %1,1(%1)\n"
-               "   la    %2,1(%2)\n"
-               "   aghi  %0,-1\n"
-               "   jnz   1b\n"
-               "   j     5f\n"
-               "2: mvc   0(256,%1),0(%2)\n"
-               "   la    %1,256(%1)\n"
-               "   la    %2,256(%2)\n"
-               "3: aghi  %0,-256\n"
-               "   jnm   2b\n"
-               "4: ex    %0,1b-0b(%3)\n"
-               "5: slgr  %0,%0\n"
-               "6: sacf  768\n"
-               EX_TABLE(1b,6b) EX_TABLE(2b,0b) EX_TABLE(4b,0b)
-               : "+a" (size), "+a" (to), "+a" (from), "=a" (tmp1)
-               : : "cc", "memory");
-       return size;
-}
-
-unsigned long raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
-{
-       if (copy_with_mvcos())
-               return copy_in_user_mvcos(to, from, n);
-       return copy_in_user_mvc(to, from, n);
-}
-EXPORT_SYMBOL(raw_copy_in_user);
-
 static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
 {
        unsigned long tmp1, tmp2;
index 8b63410..bd949fc 100644 (file)
@@ -116,25 +116,6 @@ struct compat_statfs {
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
 
-#ifdef CONFIG_COMPAT
-static inline void __user *arch_compat_alloc_user_space(long len)
-{
-       struct pt_regs *regs = current_thread_info()->kregs;
-       unsigned long usp = regs->u_regs[UREG_I6];
-
-       if (test_thread_64bit_stack(usp))
-               usp += STACK_BIAS;
-
-       if (test_thread_flag(TIF_32BIT))
-               usp &= 0xffffffffUL;
-
-       usp -= len;
-       usp &= ~0x7UL;
-
-       return (void __user *) usp;
-}
-#endif
-
 struct compat_ipc64_perm {
        compat_key_t key;
        __compat_uid32_t uid;
index 093849b..d1cc410 100644 (file)
@@ -455,7 +455,7 @@ static unsigned long clone_stackframe(unsigned long csp, unsigned long psp)
 
        distance = fp - psp;
        rval = (csp - distance);
-       if (copy_in_user((void __user *) rval, (void __user *) psp, distance))
+       if (raw_copy_in_user((void __user *)rval, (void __user *)psp, distance))
                rval = 0;
        else if (!stack_64bit) {
                if (put_user(((u32)csp),
index 4276b9e..6cc124a 100644 (file)
@@ -435,9 +435,9 @@ static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
 
        if (!wsaved) {
-               err |= copy_in_user((u32 __user *)sf,
-                                   (u32 __user *)(regs->u_regs[UREG_FP]),
-                                   sizeof(struct reg_window32));
+               err |= raw_copy_in_user((u32 __user *)sf,
+                                       (u32 __user *)(regs->u_regs[UREG_FP]),
+                                       sizeof(struct reg_window32));
        } else {
                struct reg_window *rp;
 
@@ -567,9 +567,9 @@ static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
        err |= put_compat_sigset(&sf->mask, oldset, sizeof(compat_sigset_t));
 
        if (!wsaved) {
-               err |= copy_in_user((u32 __user *)sf,
-                                   (u32 __user *)(regs->u_regs[UREG_FP]),
-                                   sizeof(struct reg_window32));
+               err |= raw_copy_in_user((u32 __user *)sf,
+                                       (u32 __user *)(regs->u_regs[UREG_FP]),
+                                       sizeof(struct reg_window32));
        } else {
                struct reg_window *rp;
 
index cea23cf..2a78d2a 100644 (file)
@@ -406,10 +406,10 @@ setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
        err |= copy_to_user(&sf->mask, sigmask_to_save(), sizeof(sigset_t));
 
        if (!wsaved) {
-               err |= copy_in_user((u64 __user *)sf,
-                                   (u64 __user *)(regs->u_regs[UREG_FP] +
-                                                  STACK_BIAS),
-                                   sizeof(struct reg_window));
+               err |= raw_copy_in_user((u64 __user *)sf,
+                                       (u64 __user *)(regs->u_regs[UREG_FP] +
+                                          STACK_BIAS),
+                                       sizeof(struct reg_window));
        } else {
                struct reg_window *rp;
 
index 7893104..c37764d 100644 (file)
 299    common  unshare                 sys_unshare
 300    common  set_robust_list         sys_set_robust_list             compat_sys_set_robust_list
 301    common  get_robust_list         sys_get_robust_list             compat_sys_get_robust_list
-302    common  migrate_pages           sys_migrate_pages               compat_sys_migrate_pages
-303    common  mbind                   sys_mbind                       compat_sys_mbind
-304    common  get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
-305    common  set_mempolicy           sys_set_mempolicy               compat_sys_set_mempolicy
+302    common  migrate_pages           sys_migrate_pages
+303    common  mbind                   sys_mbind
+304    common  get_mempolicy           sys_get_mempolicy
+305    common  set_mempolicy           sys_set_mempolicy
 306    common  kexec_load              sys_kexec_load                  compat_sys_kexec_load
-307    common  move_pages              sys_move_pages                  compat_sys_move_pages
+307    common  move_pages              sys_move_pages
 308    common  getcpu                  sys_getcpu
 309    common  epoll_pwait             sys_epoll_pwait                 compat_sys_epoll_pwait
 310    32      utimensat               sys_utimensat_time32
index 61f18b7..960a021 100644 (file)
 272    i386    fadvise64_64            sys_ia32_fadvise64_64
 273    i386    vserver
 274    i386    mbind                   sys_mbind
-275    i386    get_mempolicy           sys_get_mempolicy               compat_sys_get_mempolicy
+275    i386    get_mempolicy           sys_get_mempolicy
 276    i386    set_mempolicy           sys_set_mempolicy
 277    i386    mq_open                 sys_mq_open                     compat_sys_mq_open
 278    i386    mq_unlink               sys_mq_unlink
 314    i386    sync_file_range         sys_ia32_sync_file_range
 315    i386    tee                     sys_tee
 316    i386    vmsplice                sys_vmsplice
-317    i386    move_pages              sys_move_pages                  compat_sys_move_pages
+317    i386    move_pages              sys_move_pages
 318    i386    getcpu                  sys_getcpu
 319    i386    epoll_pwait             sys_epoll_pwait
 320    i386    utimensat               sys_utimensat_time32
index 807b6a1..18b5500 100644 (file)
 530    x32     set_robust_list         compat_sys_set_robust_list
 531    x32     get_robust_list         compat_sys_get_robust_list
 532    x32     vmsplice                sys_vmsplice
-533    x32     move_pages              compat_sys_move_pages
+533    x32     move_pages              sys_move_pages
 534    x32     preadv                  compat_sys_preadv64
 535    x32     pwritev                 compat_sys_pwritev64
 536    x32     rt_tgsigqueueinfo       compat_sys_rt_tgsigqueueinfo
index 4ae01cd..7516e41 100644 (file)
@@ -156,19 +156,6 @@ struct compat_shmid64_ds {
        (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
 #endif
 
-static inline void __user *arch_compat_alloc_user_space(long len)
-{
-       compat_uptr_t sp = task_pt_regs(current)->sp;
-
-       /*
-        * -128 for the x32 ABI redzone.  For IA32, it is not strictly
-        * necessary, but not harmful.
-        */
-       sp -= 128;
-
-       return (void __user *)round_down(sp - len, 16);
-}
-
 static inline bool in_x32_syscall(void)
 {
 #ifdef CONFIG_X86_X32_ABI
index e7265a5..45697e0 100644 (file)
@@ -58,13 +58,6 @@ raw_copy_to_user(void __user *dst, const void *src, unsigned long size)
        return copy_user_generic((__force void *)dst, src, size);
 }
 
-static __always_inline __must_check
-unsigned long raw_copy_in_user(void __user *dst, const void __user *src, unsigned long size)
-{
-       return copy_user_generic((__force void *)dst,
-                                (__force void *)src, size);
-}
-
 extern long __copy_user_nocache(void *dst, const void __user *src,
                                unsigned size, int zerorest);
 
index 8e0598c..1c758b0 100644 (file)
@@ -395,14 +395,6 @@ struct compat_kexec_segment;
 struct compat_mq_attr;
 struct compat_msgbuf;
 
-#define BITS_PER_COMPAT_LONG    (8*sizeof(compat_long_t))
-
-#define BITS_TO_COMPAT_LONGS(bits) DIV_ROUND_UP(bits, BITS_PER_COMPAT_LONG)
-
-long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
-                      unsigned long bitmap_size);
-long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
-                      unsigned long bitmap_size);
 void copy_siginfo_to_external32(struct compat_siginfo *to,
                const struct kernel_siginfo *from);
 int copy_siginfo_from_user32(kernel_siginfo_t *to,
@@ -519,8 +511,6 @@ extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
 struct epoll_event;    /* fortunately, this one is fixed-layout */
 
-extern void __user *compat_alloc_user_space(unsigned long len);
-
 int compat_restore_altstack(const compat_stack_t __user *uss);
 int __compat_save_altstack(compat_stack_t __user *, unsigned long);
 #define unsafe_compat_save_altstack(uss, sp, label) do { \
@@ -807,26 +797,6 @@ asmlinkage long compat_sys_execve(const char __user *filename, const compat_uptr
 /* mm/fadvise.c: No generic prototype for fadvise64_64 */
 
 /* mm/, CONFIG_MMU only */
-asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
-                                compat_ulong_t mode,
-                                compat_ulong_t __user *nmask,
-                                compat_ulong_t maxnode, compat_ulong_t flags);
-asmlinkage long compat_sys_get_mempolicy(int __user *policy,
-                                        compat_ulong_t __user *nmask,
-                                        compat_ulong_t maxnode,
-                                        compat_ulong_t addr,
-                                        compat_ulong_t flags);
-asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
-                                        compat_ulong_t maxnode);
-asmlinkage long compat_sys_migrate_pages(compat_pid_t pid,
-               compat_ulong_t maxnode, const compat_ulong_t __user *old_nodes,
-               const compat_ulong_t __user *new_nodes);
-asmlinkage long compat_sys_move_pages(pid_t pid, compat_ulong_t nr_pages,
-                                     __u32 __user *pages,
-                                     const int __user *nodes,
-                                     int __user *status,
-                                     int flags);
-
 asmlinkage long compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid,
                                        compat_pid_t pid, int sig,
                                        struct compat_siginfo __user *uinfo);
@@ -976,6 +946,15 @@ static inline bool in_compat_syscall(void) { return false; }
 
 #endif /* CONFIG_COMPAT */
 
+#define BITS_PER_COMPAT_LONG    (8*sizeof(compat_long_t))
+
+#define BITS_TO_COMPAT_LONGS(bits) DIV_ROUND_UP(bits, BITS_PER_COMPAT_LONG)
+
+long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
+                      unsigned long bitmap_size);
+long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
+                      unsigned long bitmap_size);
+
 /*
  * Some legacy ABIs like the i386 one use less than natural alignment for 64-bit
  * types, and will need special compat treatment for that.  Most architectures
index f7ca1a3..1faebe1 100644 (file)
@@ -858,6 +858,11 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
 
 void hugetlb_report_usage(struct seq_file *m, struct mm_struct *mm);
 
+static inline void hugetlb_count_init(struct mm_struct *mm)
+{
+       atomic_long_set(&mm->hugetlb_usage, 0);
+}
+
 static inline void hugetlb_count_add(long l, struct mm_struct *mm)
 {
        atomic_long_add(l, &mm->hugetlb_usage);
@@ -1042,6 +1047,10 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
        return &mm->page_table_lock;
 }
 
+static inline void hugetlb_count_init(struct mm_struct *mm)
+{
+}
+
 static inline void hugetlb_report_usage(struct seq_file *f, struct mm_struct *m)
 {
 }
index 0540f01..b179f1e 100644 (file)
@@ -101,14 +101,14 @@ static inline bool mmap_write_trylock(struct mm_struct *mm)
 
 static inline void mmap_write_unlock(struct mm_struct *mm)
 {
-       up_write(&mm->mmap_lock);
        __mmap_lock_trace_released(mm, true);
+       up_write(&mm->mmap_lock);
 }
 
 static inline void mmap_write_downgrade(struct mm_struct *mm)
 {
-       downgrade_write(&mm->mmap_lock);
        __mmap_lock_trace_acquire_returned(mm, false, true);
+       downgrade_write(&mm->mmap_lock);
 }
 
 static inline void mmap_read_lock(struct mm_struct *mm)
@@ -140,8 +140,8 @@ static inline bool mmap_read_trylock(struct mm_struct *mm)
 
 static inline void mmap_read_unlock(struct mm_struct *mm)
 {
-       up_read(&mm->mmap_lock);
        __mmap_lock_trace_released(mm, false);
+       up_read(&mm->mmap_lock);
 }
 
 static inline bool mmap_read_trylock_non_owner(struct mm_struct *mm)
@@ -155,8 +155,8 @@ static inline bool mmap_read_trylock_non_owner(struct mm_struct *mm)
 
 static inline void mmap_read_unlock_non_owner(struct mm_struct *mm)
 {
-       up_read_non_owner(&mm->mmap_lock);
        __mmap_lock_trace_released(mm, false);
+       up_read_non_owner(&mm->mmap_lock);
 }
 
 static inline void mmap_assert_locked(struct mm_struct *mm)
index c05e903..ac03940 100644 (file)
@@ -200,16 +200,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
                n = _copy_to_user(to, from, n);
        return n;
 }
-#ifdef CONFIG_COMPAT
-static __always_inline unsigned long __must_check
-copy_in_user(void __user *to, const void __user *from, unsigned long n)
-{
-       might_fault();
-       if (access_ok(to, n) && access_ok(from, n))
-               n = raw_copy_in_user(to, from, n);
-       return n;
-}
-#endif
 
 #ifndef copy_mc_to_kernel
 /*
index 14c8fe8..1c5fb86 100644 (file)
@@ -673,15 +673,15 @@ __SYSCALL(__NR_madvise, sys_madvise)
 #define __NR_remap_file_pages 234
 __SYSCALL(__NR_remap_file_pages, sys_remap_file_pages)
 #define __NR_mbind 235
-__SC_COMP(__NR_mbind, sys_mbind, compat_sys_mbind)
+__SYSCALL(__NR_mbind, sys_mbind)
 #define __NR_get_mempolicy 236
-__SC_COMP(__NR_get_mempolicy, sys_get_mempolicy, compat_sys_get_mempolicy)
+__SYSCALL(__NR_get_mempolicy, sys_get_mempolicy)
 #define __NR_set_mempolicy 237
-__SC_COMP(__NR_set_mempolicy, sys_set_mempolicy, compat_sys_set_mempolicy)
+__SYSCALL(__NR_set_mempolicy, sys_set_mempolicy)
 #define __NR_migrate_pages 238
-__SC_COMP(__NR_migrate_pages, sys_migrate_pages, compat_sys_migrate_pages)
+__SYSCALL(__NR_migrate_pages, sys_migrate_pages)
 #define __NR_move_pages 239
-__SC_COMP(__NR_move_pages, sys_move_pages, compat_sys_move_pages)
+__SYSCALL(__NR_move_pages, sys_move_pages)
 #endif
 
 #define __NR_rt_tgsigqueueinfo 240
index 05adfd6..5555198 100644 (file)
@@ -269,24 +269,3 @@ get_compat_sigset(sigset_t *set, const compat_sigset_t __user *compat)
        return 0;
 }
 EXPORT_SYMBOL_GPL(get_compat_sigset);
-
-/*
- * Allocate user-space memory for the duration of a single system call,
- * in order to marshall parameters inside a compat thunk.
- */
-void __user *compat_alloc_user_space(unsigned long len)
-{
-       void __user *ptr;
-
-       /* If len would occupy more than half of the entire compat space... */
-       if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
-               return NULL;
-
-       ptr = arch_compat_alloc_user_space(len);
-
-       if (unlikely(!access_ok(ptr, len)))
-               return NULL;
-
-       return ptr;
-}
-EXPORT_SYMBOL_GPL(compat_alloc_user_space);
index ff5be23..38681ad 100644 (file)
@@ -1063,6 +1063,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
        mm->pmd_huge_pte = NULL;
 #endif
        mm_init_uprobes_state(mm);
+       hugetlb_count_init(mm);
 
        if (current->mm) {
                mm->flags = current->mm->flags & MMF_INIT_MASK;
index c82c6c0..b5e40f0 100644 (file)
 
 #include "kexec_internal.h"
 
-static int copy_user_segment_list(struct kimage *image,
-                                 unsigned long nr_segments,
-                                 struct kexec_segment __user *segments)
-{
-       int ret;
-       size_t segment_bytes;
-
-       /* Read in the segments */
-       image->nr_segments = nr_segments;
-       segment_bytes = nr_segments * sizeof(*segments);
-       ret = copy_from_user(image->segment, segments, segment_bytes);
-       if (ret)
-               ret = -EFAULT;
-
-       return ret;
-}
-
 static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
                             unsigned long nr_segments,
-                            struct kexec_segment __user *segments,
+                            struct kexec_segment *segments,
                             unsigned long flags)
 {
        int ret;
@@ -58,10 +41,8 @@ static int kimage_alloc_init(struct kimage **rimage, unsigned long entry,
                return -ENOMEM;
 
        image->start = entry;
-
-       ret = copy_user_segment_list(image, nr_segments, segments);
-       if (ret)
-               goto out_free_image;
+       image->nr_segments = nr_segments;
+       memcpy(image->segment, segments, nr_segments * sizeof(*segments));
 
        if (kexec_on_panic) {
                /* Enable special crash kernel control page alloc policy. */
@@ -104,12 +85,23 @@ out_free_image:
 }
 
 static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
-               struct kexec_segment __user *segments, unsigned long flags)
+               struct kexec_segment *segments, unsigned long flags)
 {
        struct kimage **dest_image, *image;
        unsigned long i;
        int ret;
 
+       /*
+        * Because we write directly to the reserved memory region when loading
+        * crash kernels we need a mutex here to prevent multiple crash kernels
+        * from attempting to load simultaneously, and to prevent a crash kernel
+        * from loading over the top of a in use crash kernel.
+        *
+        * KISS: always take the mutex.
+        */
+       if (!mutex_trylock(&kexec_mutex))
+               return -EBUSY;
+
        if (flags & KEXEC_ON_CRASH) {
                dest_image = &kexec_crash_image;
                if (kexec_crash_image)
@@ -121,7 +113,8 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
        if (nr_segments == 0) {
                /* Uninstall image */
                kimage_free(xchg(dest_image, NULL));
-               return 0;
+               ret = 0;
+               goto out_unlock;
        }
        if (flags & KEXEC_ON_CRASH) {
                /*
@@ -134,7 +127,7 @@ static int do_kexec_load(unsigned long entry, unsigned long nr_segments,
 
        ret = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
        if (ret)
-               return ret;
+               goto out_unlock;
 
        if (flags & KEXEC_PRESERVE_CONTEXT)
                image->preserve_context = 1;
@@ -171,6 +164,8 @@ out:
                arch_kexec_protect_crashkres();
 
        kimage_free(image);
+out_unlock:
+       mutex_unlock(&kexec_mutex);
        return ret;
 }
 
@@ -236,7 +231,8 @@ static inline int kexec_load_check(unsigned long nr_segments,
 SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
                struct kexec_segment __user *, segments, unsigned long, flags)
 {
-       int result;
+       struct kexec_segment *ksegments;
+       unsigned long result;
 
        result = kexec_load_check(nr_segments, flags);
        if (result)
@@ -247,20 +243,12 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
                ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
                return -EINVAL;
 
-       /* Because we write directly to the reserved memory
-        * region when loading crash kernels we need a mutex here to
-        * prevent multiple crash  kernels from attempting to load
-        * simultaneously, and to prevent a crash kernel from loading
-        * over the top of a in use crash kernel.
-        *
-        * KISS: always take the mutex.
-        */
-       if (!mutex_trylock(&kexec_mutex))
-               return -EBUSY;
+       ksegments = memdup_user(segments, nr_segments * sizeof(ksegments[0]));
+       if (IS_ERR(ksegments))
+               return PTR_ERR(ksegments);
 
-       result = do_kexec_load(entry, nr_segments, segments, flags);
-
-       mutex_unlock(&kexec_mutex);
+       result = do_kexec_load(entry, nr_segments, ksegments, flags);
+       kfree(ksegments);
 
        return result;
 }
@@ -272,7 +260,7 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry,
                       compat_ulong_t, flags)
 {
        struct compat_kexec_segment in;
-       struct kexec_segment out, __user *ksegments;
+       struct kexec_segment *ksegments;
        unsigned long i, result;
 
        result = kexec_load_check(nr_segments, flags);
@@ -285,37 +273,26 @@ COMPAT_SYSCALL_DEFINE4(kexec_load, compat_ulong_t, entry,
        if ((flags & KEXEC_ARCH_MASK) == KEXEC_ARCH_DEFAULT)
                return -EINVAL;
 
-       ksegments = compat_alloc_user_space(nr_segments * sizeof(out));
+       ksegments = kmalloc_array(nr_segments, sizeof(ksegments[0]),
+                       GFP_KERNEL);
+       if (!ksegments)
+               return -ENOMEM;
+
        for (i = 0; i < nr_segments; i++) {
                result = copy_from_user(&in, &segments[i], sizeof(in));
                if (result)
-                       return -EFAULT;
+                       goto fail;
 
-               out.buf   = compat_ptr(in.buf);
-               out.bufsz = in.bufsz;
-               out.mem   = in.mem;
-               out.memsz = in.memsz;
-
-               result = copy_to_user(&ksegments[i], &out, sizeof(out));
-               if (result)
-                       return -EFAULT;
+               ksegments[i].buf   = compat_ptr(in.buf);
+               ksegments[i].bufsz = in.bufsz;
+               ksegments[i].mem   = in.mem;
+               ksegments[i].memsz = in.memsz;
        }
 
-       /* Because we write directly to the reserved memory
-        * region when loading crash kernels we need a mutex here to
-        * prevent multiple crash  kernels from attempting to load
-        * simultaneously, and to prevent a crash kernel from loading
-        * over the top of a in use crash kernel.
-        *
-        * KISS: always take the mutex.
-        */
-       if (!mutex_trylock(&kexec_mutex))
-               return -EBUSY;
-
        result = do_kexec_load(entry, nr_segments, ksegments, flags);
 
-       mutex_unlock(&kexec_mutex);
-
+fail:
+       kfree(ksegments);
        return result;
 }
 #endif
index 64578ad..f43d89d 100644 (file)
@@ -292,15 +292,10 @@ COND_SYSCALL(process_madvise);
 COND_SYSCALL(process_mrelease);
 COND_SYSCALL(remap_file_pages);
 COND_SYSCALL(mbind);
-COND_SYSCALL_COMPAT(mbind);
 COND_SYSCALL(get_mempolicy);
-COND_SYSCALL_COMPAT(get_mempolicy);
 COND_SYSCALL(set_mempolicy);
-COND_SYSCALL_COMPAT(set_mempolicy);
 COND_SYSCALL(migrate_pages);
-COND_SYSCALL_COMPAT(migrate_pages);
 COND_SYSCALL(move_pages);
-COND_SYSCALL_COMPAT(move_pages);
 
 COND_SYSCALL(perf_event_open);
 COND_SYSCALL(accept4);
index fad6be2..842e265 100644 (file)
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -295,10 +295,13 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr,
                goto fault;
 
        /*
+        * Bypass devmap pte such as DAX page when all pfn requested
+        * flags(pfn_req_flags) are fulfilled.
         * Since each architecture defines a struct page for the zero page, just
         * fall through and treat it like a normal page.
         */
-       if (pte_special(pte) && !is_zero_pfn(pte_pfn(pte))) {
+       if (pte_special(pte) && !pte_devmap(pte) &&
+           !is_zero_pfn(pte_pfn(pte))) {
                if (hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, 0)) {
                        pte_unmap(ptep);
                        return -EFAULT;
index b59f176..b57383c 100644 (file)
 #define BYTES_PER_POINTER      sizeof(void *)
 
 /* GFP bitmask for kmemleak internal allocations */
-#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC)) | \
+#define gfp_kmemleak_mask(gfp) (((gfp) & (GFP_KERNEL | GFP_ATOMIC | \
+                                          __GFP_NOLOCKDEP)) | \
                                 __GFP_NORETRY | __GFP_NOMEMALLOC | \
                                 __GFP_NOWARN)
 
index 5e90b3f..1592b08 100644 (file)
@@ -1362,16 +1362,33 @@ mpol_out:
 /*
  * User space interface with variable sized bitmaps for nodelists.
  */
+static int get_bitmap(unsigned long *mask, const unsigned long __user *nmask,
+                     unsigned long maxnode)
+{
+       unsigned long nlongs = BITS_TO_LONGS(maxnode);
+       int ret;
+
+       if (in_compat_syscall())
+               ret = compat_get_bitmap(mask,
+                                       (const compat_ulong_t __user *)nmask,
+                                       maxnode);
+       else
+               ret = copy_from_user(mask, nmask,
+                                    nlongs * sizeof(unsigned long));
+
+       if (ret)
+               return -EFAULT;
+
+       if (maxnode % BITS_PER_LONG)
+               mask[nlongs - 1] &= (1UL << (maxnode % BITS_PER_LONG)) - 1;
+
+       return 0;
+}
 
 /* Copy a node mask from user space. */
 static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask,
                     unsigned long maxnode)
 {
-       unsigned long k;
-       unsigned long t;
-       unsigned long nlongs;
-       unsigned long endmask;
-
        --maxnode;
        nodes_clear(*nodes);
        if (maxnode == 0 || !nmask)
@@ -1379,49 +1396,29 @@ static int get_nodes(nodemask_t *nodes, const unsigned long __user *nmask,
        if (maxnode > PAGE_SIZE*BITS_PER_BYTE)
                return -EINVAL;
 
-       nlongs = BITS_TO_LONGS(maxnode);
-       if ((maxnode % BITS_PER_LONG) == 0)
-               endmask = ~0UL;
-       else
-               endmask = (1UL << (maxnode % BITS_PER_LONG)) - 1;
-
        /*
         * When the user specified more nodes than supported just check
-        * if the non supported part is all zero.
-        *
-        * If maxnode have more longs than MAX_NUMNODES, check
-        * the bits in that area first. And then go through to
-        * check the rest bits which equal or bigger than MAX_NUMNODES.
-        * Otherwise, just check bits [MAX_NUMNODES, maxnode).
+        * if the non supported part is all zero, one word at a time,
+        * starting at the end.
         */
-       if (nlongs > BITS_TO_LONGS(MAX_NUMNODES)) {
-               for (k = BITS_TO_LONGS(MAX_NUMNODES); k < nlongs; k++) {
-                       if (get_user(t, nmask + k))
-                               return -EFAULT;
-                       if (k == nlongs - 1) {
-                               if (t & endmask)
-                                       return -EINVAL;
-                       } else if (t)
-                               return -EINVAL;
-               }
-               nlongs = BITS_TO_LONGS(MAX_NUMNODES);
-               endmask = ~0UL;
-       }
+       while (maxnode > MAX_NUMNODES) {
+               unsigned long bits = min_t(unsigned long, maxnode, BITS_PER_LONG);
+               unsigned long t;
 
-       if (maxnode > MAX_NUMNODES && MAX_NUMNODES % BITS_PER_LONG != 0) {
-               unsigned long valid_mask = endmask;
-
-               valid_mask &= ~((1UL << (MAX_NUMNODES % BITS_PER_LONG)) - 1);
-               if (get_user(t, nmask + nlongs - 1))
+               if (get_bitmap(&t, &nmask[maxnode / BITS_PER_LONG], bits))
                        return -EFAULT;
-               if (t & valid_mask)
+
+               if (maxnode - bits >= MAX_NUMNODES) {
+                       maxnode -= bits;
+               } else {
+                       maxnode = MAX_NUMNODES;
+                       t &= ~((1UL << (MAX_NUMNODES % BITS_PER_LONG)) - 1);
+               }
+               if (t)
                        return -EINVAL;
        }
 
-       if (copy_from_user(nodes_addr(*nodes), nmask, nlongs*sizeof(unsigned long)))
-               return -EFAULT;
-       nodes_addr(*nodes)[nlongs-1] &= endmask;
-       return 0;
+       return get_bitmap(nodes_addr(*nodes), nmask, maxnode);
 }
 
 /* Copy a kernel node mask to user space */
@@ -1430,6 +1427,10 @@ static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
 {
        unsigned long copy = ALIGN(maxnode-1, 64) / 8;
        unsigned int nbytes = BITS_TO_LONGS(nr_node_ids) * sizeof(long);
+       bool compat = in_compat_syscall();
+
+       if (compat)
+               nbytes = BITS_TO_COMPAT_LONGS(nr_node_ids) * sizeof(compat_long_t);
 
        if (copy > nbytes) {
                if (copy > PAGE_SIZE)
@@ -1437,7 +1438,13 @@ static int copy_nodes_to_user(unsigned long __user *mask, unsigned long maxnode,
                if (clear_user((char __user *)mask + nbytes, copy - nbytes))
                        return -EFAULT;
                copy = nbytes;
+               maxnode = nr_node_ids;
        }
+
+       if (compat)
+               return compat_put_bitmap((compat_ulong_t __user *)mask,
+                                        nodes_addr(*nodes), maxnode);
+
        return copy_to_user(mask, nodes_addr(*nodes), copy) ? -EFAULT : 0;
 }
 
@@ -1642,116 +1649,6 @@ SYSCALL_DEFINE5(get_mempolicy, int __user *, policy,
        return kernel_get_mempolicy(policy, nmask, maxnode, addr, flags);
 }
 
-#ifdef CONFIG_COMPAT
-
-COMPAT_SYSCALL_DEFINE5(get_mempolicy, int __user *, policy,
-                      compat_ulong_t __user *, nmask,
-                      compat_ulong_t, maxnode,
-                      compat_ulong_t, addr, compat_ulong_t, flags)
-{
-       long err;
-       unsigned long __user *nm = NULL;
-       unsigned long nr_bits, alloc_size;
-       DECLARE_BITMAP(bm, MAX_NUMNODES);
-
-       nr_bits = min_t(unsigned long, maxnode-1, nr_node_ids);
-       alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
-
-       if (nmask)
-               nm = compat_alloc_user_space(alloc_size);
-
-       err = kernel_get_mempolicy(policy, nm, nr_bits+1, addr, flags);
-
-       if (!err && nmask) {
-               unsigned long copy_size;
-               copy_size = min_t(unsigned long, sizeof(bm), alloc_size);
-               err = copy_from_user(bm, nm, copy_size);
-               /* ensure entire bitmap is zeroed */
-               err |= clear_user(nmask, ALIGN(maxnode-1, 8) / 8);
-               err |= compat_put_bitmap(nmask, bm, nr_bits);
-       }
-
-       return err;
-}
-
-COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask,
-                      compat_ulong_t, maxnode)
-{
-       unsigned long __user *nm = NULL;
-       unsigned long nr_bits, alloc_size;
-       DECLARE_BITMAP(bm, MAX_NUMNODES);
-
-       nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
-       alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
-
-       if (nmask) {
-               if (compat_get_bitmap(bm, nmask, nr_bits))
-                       return -EFAULT;
-               nm = compat_alloc_user_space(alloc_size);
-               if (copy_to_user(nm, bm, alloc_size))
-                       return -EFAULT;
-       }
-
-       return kernel_set_mempolicy(mode, nm, nr_bits+1);
-}
-
-COMPAT_SYSCALL_DEFINE6(mbind, compat_ulong_t, start, compat_ulong_t, len,
-                      compat_ulong_t, mode, compat_ulong_t __user *, nmask,
-                      compat_ulong_t, maxnode, compat_ulong_t, flags)
-{
-       unsigned long __user *nm = NULL;
-       unsigned long nr_bits, alloc_size;
-       nodemask_t bm;
-
-       nr_bits = min_t(unsigned long, maxnode-1, MAX_NUMNODES);
-       alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
-
-       if (nmask) {
-               if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits))
-                       return -EFAULT;
-               nm = compat_alloc_user_space(alloc_size);
-               if (copy_to_user(nm, nodes_addr(bm), alloc_size))
-                       return -EFAULT;
-       }
-
-       return kernel_mbind(start, len, mode, nm, nr_bits+1, flags);
-}
-
-COMPAT_SYSCALL_DEFINE4(migrate_pages, compat_pid_t, pid,
-                      compat_ulong_t, maxnode,
-                      const compat_ulong_t __user *, old_nodes,
-                      const compat_ulong_t __user *, new_nodes)
-{
-       unsigned long __user *old = NULL;
-       unsigned long __user *new = NULL;
-       nodemask_t tmp_mask;
-       unsigned long nr_bits;
-       unsigned long size;
-
-       nr_bits = min_t(unsigned long, maxnode - 1, MAX_NUMNODES);
-       size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
-       if (old_nodes) {
-               if (compat_get_bitmap(nodes_addr(tmp_mask), old_nodes, nr_bits))
-                       return -EFAULT;
-               old = compat_alloc_user_space(new_nodes ? size * 2 : size);
-               if (new_nodes)
-                       new = old + size / sizeof(unsigned long);
-               if (copy_to_user(old, nodes_addr(tmp_mask), size))
-                       return -EFAULT;
-       }
-       if (new_nodes) {
-               if (compat_get_bitmap(nodes_addr(tmp_mask), new_nodes, nr_bits))
-                       return -EFAULT;
-               if (new == NULL)
-                       new = compat_alloc_user_space(size);
-               if (copy_to_user(new, nodes_addr(tmp_mask), size))
-                       return -EFAULT;
-       }
-       return kernel_migrate_pages(pid, nr_bits + 1, old, new);
-}
-
-#endif /* CONFIG_COMPAT */
-
 bool vma_migratable(struct vm_area_struct *vma)
 {
        if (vma->vm_flags & (VM_IO | VM_PFNMAP))
@@ -1979,17 +1876,26 @@ unsigned int mempolicy_slab_node(void)
  */
 static unsigned offset_il_node(struct mempolicy *pol, unsigned long n)
 {
-       unsigned nnodes = nodes_weight(pol->nodes);
-       unsigned target;
+       nodemask_t nodemask = pol->nodes;
+       unsigned int target, nnodes;
        int i;
        int nid;
+       /*
+        * The barrier will stabilize the nodemask in a register or on
+        * the stack so that it will stop changing under the code.
+        *
+        * Between first_node() and next_node(), pol->nodes could be changed
+        * by other threads. So we put pol->nodes in a local stack.
+        */
+       barrier();
 
+       nnodes = nodes_weight(nodemask);
        if (!nnodes)
                return numa_node_id();
        target = (unsigned int)n % nnodes;
-       nid = first_node(pol->nodes);
+       nid = first_node(nodemask);
        for (i = 0; i < target; i++)
-               nid = next_node(nid, pol->nodes);
+               nid = next_node(nid, nodemask);
        return nid;
 }
 
index a0aeb3f..a6a7743 100644 (file)
@@ -960,7 +960,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
                                int force, enum migrate_mode mode)
 {
        int rc = -EAGAIN;
-       int page_was_mapped = 0;
+       bool page_was_mapped = false;
        struct anon_vma *anon_vma = NULL;
        bool is_lru = !__PageMovable(page);
 
@@ -1008,7 +1008,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
        }
 
        /*
-        * By try_to_unmap(), page->mapcount goes down to 0 here. In this case,
+        * By try_to_migrate(), page->mapcount goes down to 0 here. In this case,
         * we cannot notice that anon_vma is freed while we migrates a page.
         * This get_anon_vma() delays freeing anon_vma pointer until the end
         * of migration. File cache pages are no problem because of page_lock()
@@ -1063,7 +1063,7 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
                VM_BUG_ON_PAGE(PageAnon(page) && !PageKsm(page) && !anon_vma,
                                page);
                try_to_migrate(page, 0);
-               page_was_mapped = 1;
+               page_was_mapped = true;
        }
 
        if (!page_mapped(page))
@@ -1900,6 +1900,23 @@ set_status:
        mmap_read_unlock(mm);
 }
 
+static int get_compat_pages_array(const void __user *chunk_pages[],
+                                 const void __user * __user *pages,
+                                 unsigned long chunk_nr)
+{
+       compat_uptr_t __user *pages32 = (compat_uptr_t __user *)pages;
+       compat_uptr_t p;
+       int i;
+
+       for (i = 0; i < chunk_nr; i++) {
+               if (get_user(p, pages32 + i))
+                       return -EFAULT;
+               chunk_pages[i] = compat_ptr(p);
+       }
+
+       return 0;
+}
+
 /*
  * Determine the nodes of a user array of pages and store it in
  * a user array of status.
@@ -1919,8 +1936,15 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
                if (chunk_nr > DO_PAGES_STAT_CHUNK_NR)
                        chunk_nr = DO_PAGES_STAT_CHUNK_NR;
 
-               if (copy_from_user(chunk_pages, pages, chunk_nr * sizeof(*chunk_pages)))
-                       break;
+               if (in_compat_syscall()) {
+                       if (get_compat_pages_array(chunk_pages, pages,
+                                                  chunk_nr))
+                               break;
+               } else {
+                       if (copy_from_user(chunk_pages, pages,
+                                     chunk_nr * sizeof(*chunk_pages)))
+                               break;
+               }
 
                do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status);
 
@@ -2023,28 +2047,6 @@ SYSCALL_DEFINE6(move_pages, pid_t, pid, unsigned long, nr_pages,
        return kernel_move_pages(pid, nr_pages, pages, nodes, status, flags);
 }
 
-#ifdef CONFIG_COMPAT
-COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
-                      compat_uptr_t __user *, pages32,
-                      const int __user *, nodes,
-                      int __user *, status,
-                      int, flags)
-{
-       const void __user * __user *pages;
-       int i;
-
-       pages = compat_alloc_user_space(nr_pages * sizeof(void *));
-       for (i = 0; i < nr_pages; i++) {
-               compat_uptr_t p;
-
-               if (get_user(p, pages32 + i) ||
-                       put_user(compat_ptr(p), pages + i))
-                       return -EFAULT;
-       }
-       return kernel_move_pages(pid, nr_pages, pages, nodes, status, flags);
-}
-#endif /* CONFIG_COMPAT */
-
 #ifdef CONFIG_NUMA_BALANCING
 /*
  * Returns true if this is a safe migration target node for misplaced NUMA
@@ -2107,6 +2109,7 @@ out:
 static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
 {
        int page_lru;
+       int nr_pages = thp_nr_pages(page);
 
        VM_BUG_ON_PAGE(compound_order(page) && !PageTransHuge(page), page);
 
@@ -2115,7 +2118,7 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
                return 0;
 
        /* Avoid migrating to a node that is nearly full */
-       if (!migrate_balanced_pgdat(pgdat, compound_nr(page)))
+       if (!migrate_balanced_pgdat(pgdat, nr_pages))
                return 0;
 
        if (isolate_lru_page(page))
@@ -2123,7 +2126,7 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
 
        page_lru = page_is_file_lru(page);
        mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + page_lru,
-                               thp_nr_pages(page));
+                           nr_pages);
 
        /*
         * Isolating the page has taken another reference, so the
index de309a1..b37435c 100644 (file)
@@ -3428,8 +3428,10 @@ void free_unref_page_list(struct list_head *list)
        /* Prepare pages for freeing */
        list_for_each_entry_safe(page, next, list, lru) {
                pfn = page_to_pfn(page);
-               if (!free_unref_page_prepare(page, pfn, 0))
+               if (!free_unref_page_prepare(page, pfn, 0)) {
                        list_del(&page->lru);
+                       continue;
+               }
 
                /*
                 * Free isolated pages directly to the allocator, see
index 740d03e..74296c2 100644 (file)
@@ -2715,7 +2715,7 @@ out:
                        cgroup_size = max(cgroup_size, protection);
 
                        scan = lruvec_size - lruvec_size * protection /
-                               cgroup_size;
+                               (cgroup_size + 1);
 
                        /*
                         * Minimally target SWAP_CLUSTER_MAX pages to keep
index 0885a34..8ce2620 100644 (file)
@@ -319,6 +319,16 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
        long x;
        long t;
 
+       /*
+        * Accurate vmstat updates require a RMW. On !PREEMPT_RT kernels,
+        * atomicity is provided by IRQs being disabled -- either explicitly
+        * or via local_lock_irq. On PREEMPT_RT, local_lock_irq only disables
+        * CPU migrations and preemption potentially corrupts a counter so
+        * disable preemption.
+        */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
+
        x = delta + __this_cpu_read(*p);
 
        t = __this_cpu_read(pcp->stat_threshold);
@@ -328,6 +338,9 @@ void __mod_zone_page_state(struct zone *zone, enum zone_stat_item item,
                x = 0;
        }
        __this_cpu_write(*p, x);
+
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable();
 }
 EXPORT_SYMBOL(__mod_zone_page_state);
 
@@ -350,6 +363,10 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
                delta >>= PAGE_SHIFT;
        }
 
+       /* See __mod_node_page_state */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
+
        x = delta + __this_cpu_read(*p);
 
        t = __this_cpu_read(pcp->stat_threshold);
@@ -359,6 +376,9 @@ void __mod_node_page_state(struct pglist_data *pgdat, enum node_stat_item item,
                x = 0;
        }
        __this_cpu_write(*p, x);
+
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable();
 }
 EXPORT_SYMBOL(__mod_node_page_state);
 
@@ -391,6 +411,10 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
        s8 __percpu *p = pcp->vm_stat_diff + item;
        s8 v, t;
 
+       /* See __mod_node_page_state */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
+
        v = __this_cpu_inc_return(*p);
        t = __this_cpu_read(pcp->stat_threshold);
        if (unlikely(v > t)) {
@@ -399,6 +423,9 @@ void __inc_zone_state(struct zone *zone, enum zone_stat_item item)
                zone_page_state_add(v + overstep, zone, item);
                __this_cpu_write(*p, -overstep);
        }
+
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable();
 }
 
 void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
@@ -409,6 +436,10 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
 
        VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));
 
+       /* See __mod_node_page_state */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
+
        v = __this_cpu_inc_return(*p);
        t = __this_cpu_read(pcp->stat_threshold);
        if (unlikely(v > t)) {
@@ -417,6 +448,9 @@ void __inc_node_state(struct pglist_data *pgdat, enum node_stat_item item)
                node_page_state_add(v + overstep, pgdat, item);
                __this_cpu_write(*p, -overstep);
        }
+
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable();
 }
 
 void __inc_zone_page_state(struct page *page, enum zone_stat_item item)
@@ -437,6 +471,10 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
        s8 __percpu *p = pcp->vm_stat_diff + item;
        s8 v, t;
 
+       /* See __mod_node_page_state */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
+
        v = __this_cpu_dec_return(*p);
        t = __this_cpu_read(pcp->stat_threshold);
        if (unlikely(v < - t)) {
@@ -445,6 +483,9 @@ void __dec_zone_state(struct zone *zone, enum zone_stat_item item)
                zone_page_state_add(v - overstep, zone, item);
                __this_cpu_write(*p, overstep);
        }
+
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable();
 }
 
 void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item)
@@ -455,6 +496,10 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item)
 
        VM_WARN_ON_ONCE(vmstat_item_in_bytes(item));
 
+       /* See __mod_node_page_state */
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_disable();
+
        v = __this_cpu_dec_return(*p);
        t = __this_cpu_read(pcp->stat_threshold);
        if (unlikely(v < - t)) {
@@ -463,6 +508,9 @@ void __dec_node_state(struct pglist_data *pgdat, enum node_stat_item item)
                node_page_state_add(v - overstep, pgdat, item);
                __this_cpu_write(*p, overstep);
        }
+
+       if (IS_ENABLED(CONFIG_PREEMPT_RT))
+               preempt_enable();
 }
 
 void __dec_zone_page_state(struct page *page, enum zone_stat_item item)