x86/mm changes for v4.8
Subsystems (22)
Linus,
Please pull the latest x86-mm-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-mm-for-linus
# HEAD: 55920d31f1e3fea06702c74271dd56c4fc9b70ca x86/mm/cpa: Add missing comment in populate_pdg()
Various x86 low level modifications:
- Preparatory work to support virtually mapped kernel stacks (Andy Lutomirski)
- Support for 64-bit __get_user() on 32-bit kernels (Benjamin LaHaise)
- (Involved) workaround for Knights Landing CPU erratum (Dave Hansen)
- MPX enhancements (Dave Hansen)
- mremap() extension to allow remapping of the special VDSO vma, for purposes of user level context save/restore. (Dmitry Safonov)
- hweight and entry code cleanups (Borislav Petkov)
- bitops code generation optimizations and cleanups with modern GCC (H. Peter Anvin)
- syscall entry code optimizations (Paolo Bonzini)
out-of-topic modifications in x86-mm-for-linus:
-------------------------------------------------
drivers/pnp/isapnp/proc.c # 13d4ea097d18: x86/uaccess: Move thread_inf
fs/read_write.c # 3ebfd81f7fb3: x86/syscalls: Add compat_sys
include/linux/context_tracking.h # 2e9d1e150abf: x86/entry: Avoid interrupt f
include/linux/mm_types.h # b059a453b1cf: x86/vdso: Add mremap hook to
include/linux/random.h # 117780eef774: x86, asm: use bool for bitop
lib/Makefile # f5967101e9de: x86/hweight: Get rid of the
lib/bitmap.c # 13d4ea097d18: x86/uaccess: Move thread_inf
lib/hweight.c # f5967101e9de: x86/hweight: Get rid of the
mm/mmap.c # b059a453b1cf: x86/vdso: Add mremap hook to
tools/testing/selftests/x86/Makefile# f80fd3a5fff8: selftests/x86: Add vDSO mrem
# e754aedc26ef: x86/mpx, selftests: Add MPX tools/testing/selftests/x86/mpx-debug.h# e754aedc26ef: x86/mpx, selftests: Add MPX tools/testing/selftests/x86/mpx-dig.c# e754aedc26ef: x86/mpx, selftests: Add MPX tools/testing/selftests/x86/mpx-hw.h# e754aedc26ef: x86/mpx, selftests: Add MPX tools/testing/selftests/x86/mpx-mini-test.c# e754aedc26ef: x86/mpx, selftests: Add MPX tools/testing/selftests/x86/mpx-mm.h# e754aedc26ef: x86/mpx, selftests: Add MPX tools/testing/selftests/x86/test_mremap_vdso.c# f80fd3a5fff8: selftests/x86: Add vDSO mrem
Thanks,
Ingo
------------------>
Andy Lutomirski (14):
x86/xen: Simplify set_aliased_prot()
x86/vdso/32: Assemble sigreturn.S separately
x86/mm/cpa: In populate_pgd(), don't set the PGD entry until it's populated x86/mm: Remove kernel_unmap_pages_in_pgd() and efi_cleanup_page_tables() x86/dumpstack: Try harder to get a call trace on stack overflow x86/dumpstack/64: Handle faults when printing the "Stack: " part of an OOPS x86/mm/64: In vmalloc_fault(), use CR3 instead of current->active_mm x86/dumpstack: When OOPSing, rewind the stack before do_exit()
x86/uaccess: Move thread_info::uaccess_err and thread_info::sig_on_uaccess_err to thread_struct x86/uaccess: Move thread_info::addr_limit to thread_struct
x86/smp: Remove stack_smp_processor_id()
x86/smp: Remove unnecessary initialization of thread_info::cpu
x86/mm/cpa: Fix populate_pgd(): Stop trying to deallocate failed PUDs x86/mm/cpa: Add missing comment in populate_pdg()
Benjamin LaHaise (1):
x86/mm/32: Add support for 64-bit __get_user() on 32-bit kernels
Borislav Petkov (2):
x86/hweight: Get rid of the special calling convention x86/asm/entry: Make thunk's restore a local label
Dave Hansen (7):
x86/signals: Add missing signal_compat code for x86 features x86/signals: Add build-time checks to the siginfo compat code x86/mpx, selftests: Add MPX self test
x86/mm: Move swap offset/type up in PTE to work around erratum x86/mm: Ignore A/D bits in pte/pmd/pud_none()
x86/mm: Disallow running with 32-bit PTEs to work around erratum x86/mm: Use pte_none() to test for empty PTE
Dmitry Safonov (2):
x86/vdso: Add mremap hook to vm_special_mapping selftests/x86: Add vDSO mremap() test
H. Peter Anvin (10):
x86, bitops: remove use of "sbb" to return CF
x86, asm: use bool for bitops and other assembly outputs x86, asm: change the GEN_*_RMWcc() macros to not quote the condition x86, asm: define CC_SET() and CC_OUT() macros
x86, asm: change GEN_*_RMWcc() to use CC_SET()/CC_OUT() x86, asm: Use CC_SET()/CC_OUT() in <asm/bitops.h>
x86, asm: Use CC_SET()/CC_OUT() in <asm/percpu.h>
x86, asm: Use CC_SET()/CC_OUT() in <asm/rwsem.h>
x86, asm, boot: Use CC_SET()/CC_OUT() in arch/x86/boot/boot.h x86, asm: Use CC_SET()/CC_OUT() and static_cpu_has() in archrandom.h
H.J. Lu (1):
x86/syscalls: Add compat_sys_preadv64v2/compat_sys_pwritev64v2
Ingo Molnar (2):
x86/mm/hotplug: Don't remove PGD entries in remove_pagetable() x86/dumpstack: Rename thread_struct::sig_on_uaccess_error to sig_on_uaccess_err
Jiri Kosina (1):
x86/mm/pat, /dev/mem: Remove superfluous error message
Mathias Krause (1):
x86/extable: Ensure entries are swapped completely when sorting
Paolo Bonzini (2):
x86/entry: Avoid interrupt flag save and restore x86/entry: Inline enter_from_user_mode()
arch/x86/Kconfig | 5 - arch/x86/boot/bitops.h | 8 +- arch/x86/boot/boot.h | 18 +- arch/x86/boot/cpu.c | 2 + arch/x86/boot/cpucheck.c | 33 + arch/x86/boot/cpuflags.c | 1 + arch/x86/boot/cpuflags.h | 1 + arch/x86/boot/string.c | 2 +- arch/x86/entry/common.c | 6 +- arch/x86/entry/entry_32.S | 11 + arch/x86/entry/entry_64.S | 11 + arch/x86/entry/syscalls/syscall_64.tbl | 4 +- arch/x86/entry/thunk_64.S | 6 +- arch/x86/entry/vdso/Makefile | 5 +- arch/x86/entry/vdso/vdso32/sigreturn.S | 8 - arch/x86/entry/vdso/vdso32/system_call.S | 7 +- arch/x86/entry/vdso/vma.c | 47 +- arch/x86/entry/vsyscall/vsyscall_64.c | 10 +- arch/x86/include/asm/apm.h | 6 +- arch/x86/include/asm/arch_hweight.h | 24 +- arch/x86/include/asm/archrandom.h | 132 +- arch/x86/include/asm/asm.h | 12 + arch/x86/include/asm/atomic.h | 16 +- arch/x86/include/asm/atomic64_64.h | 18 +- arch/x86/include/asm/bitops.h | 50 +- arch/x86/include/asm/checksum_32.h | 3 +- arch/x86/include/asm/compat.h | 11 + arch/x86/include/asm/cpu.h | 1 - arch/x86/include/asm/efi.h | 1 - arch/x86/include/asm/local.h | 16 +- arch/x86/include/asm/percpu.h | 17 +- arch/x86/include/asm/pgtable.h | 13 +- arch/x86/include/asm/pgtable_64.h | 26 +- arch/x86/include/asm/pgtable_types.h | 8 +- arch/x86/include/asm/preempt.h | 2 +- arch/x86/include/asm/processor.h | 20 +- arch/x86/include/asm/rmwcc.h | 20 +- arch/x86/include/asm/rwsem.h | 17 +- arch/x86/include/asm/signal.h | 6 +- arch/x86/include/asm/smp.h | 6 - arch/x86/include/asm/sync_bitops.h | 18 +- arch/x86/include/asm/thread_info.h | 9 - arch/x86/include/asm/uaccess.h | 33 +- arch/x86/include/asm/unistd.h | 2 + arch/x86/kernel/asm-offsets.c | 4 +- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/cpu/rdrand.c | 4 +- arch/x86/kernel/dumpstack.c | 20 +- arch/x86/kernel/dumpstack_64.c | 12 +- arch/x86/kernel/i386_ksyms_32.c | 2 + arch/x86/kernel/signal_compat.c | 108 ++ arch/x86/kernel/smpboot.c | 1 - arch/x86/kernel/vm86_32.c | 5 +- arch/x86/kernel/x8664_ksyms_64.c | 3 + arch/x86/lib/Makefile | 2 +- arch/x86/lib/copy_user_64.S | 8 +- arch/x86/lib/csum-wrappers_64.c | 1 + arch/x86/lib/getuser.S | 20 +- arch/x86/lib/hweight.S | 77 ++ arch/x86/lib/putuser.S | 10 +- arch/x86/lib/usercopy_64.c | 2 +- arch/x86/mm/extable.c | 2 +- arch/x86/mm/fault.c | 4 +- arch/x86/mm/init_64.c | 37 +- arch/x86/mm/pageattr.c | 37 +- arch/x86/mm/pat.c | 5 +- arch/x86/mm/pgtable_32.c | 2 +- arch/x86/platform/efi/efi.c | 2 - arch/x86/platform/efi/efi_32.c | 3 - arch/x86/platform/efi/efi_64.c | 5 - arch/x86/xen/enlighten.c | 4 +- drivers/char/mem.c | 6 +- drivers/pnp/isapnp/proc.c | 2 +- fs/read_write.c | 18 + include/linux/context_tracking.h | 15 + include/linux/mm_types.h | 3 + include/linux/random.h | 12 +- lib/Makefile | 5 - lib/bitmap.c | 2 +- lib/hweight.c | 4 + mm/mmap.c | 10 + tools/testing/selftests/x86/Makefile | 4 +- tools/testing/selftests/x86/mpx-debug.h | 14 + tools/testing/selftests/x86/mpx-dig.c | 498 ++++++++ tools/testing/selftests/x86/mpx-hw.h | 123 ++ tools/testing/selftests/x86/mpx-mini-test.c | 1585 ++++++++++++++++++++++++ tools/testing/selftests/x86/mpx-mm.h | 9 + tools/testing/selftests/x86/test_mremap_vdso.c | 111 ++ 88 files changed, 3069 insertions(+), 406 deletions(-) create mode 100644 arch/x86/lib/hweight.S create mode 100644 tools/testing/selftests/x86/mpx-debug.h create mode 100644 tools/testing/selftests/x86/mpx-dig.c create mode 100644 tools/testing/selftests/x86/mpx-hw.h create mode 100644 tools/testing/selftests/x86/mpx-mini-test.c create mode 100644 tools/testing/selftests/x86/mpx-mm.h create mode 100644 tools/testing/selftests/x86/test_mremap_vdso.c
arch/x86/Kconfig +0 -5
@@ -294,11 +294,6 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR -config ARCH_HWEIGHT_CFLAGS - string - default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 - default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 - config ARCH_SUPPORTS_UPROBES def_bool y
arch/x86/boot/bitops.h +5 -3
@@ -16,14 +16,16 @@#define BOOT_BITOPS_H #define _LINUX_BITOPS_H/* Inhibit inclusion of <linux/bitops.h> */ -static inline int constant_test_bit (int nr,const void *addr) +#include <linux/types.h> + +static inline bool constant_test_bit (int nr,const void *addr) {const u32 *p = (const u32 *)addr;return ((1UL << (nr &31 )) & (p[nr >>5 ])) !=0 ; } -static inline int variable_test_bit (int nr,const void *addr) +static inline bool variable_test_bit (int nr,const void *addr) { -u8 v; +bool v;const u32 *p = (const u32 *)addr; asm("btl %2,%1; setc %0" :"=qm" (v) :"m" (*p),"Ir" (nr));
arch/x86/boot/boot.h +10 -8
@@ -24,6 +24,7 @@#include <linux/types.h> #include <linux/edd.h> #include <asm/setup.h> +#include <asm/asm.h> #include "bitops.h" #include "ctype.h" #include "cpuflags.h"
@@ -176,18 +177,18 @@ static inline void wrgs32(u32 v, addr_t addr) }/* Note: these only return true/false, not a signed return value! */ -static inline int memcmp_fs (const void *s1,addr_t s2,size_t len) +static inline bool memcmp_fs (const void *s1,addr_t s2,size_t len) { -u8 diff; - asmvolatile ("fs; repe; cmpsb; setnz %0" - :"=qm" (diff),"+D" (s1),"+S" (s2),"+c" (len)); +bool diff; + asm volatile("fs; repe; cmpsb" CC_SET(nz) + : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));return diff; } -static inline int memcmp_gs (const void *s1,addr_t s2,size_t len) +static inline bool memcmp_gs (const void *s1,addr_t s2,size_t len) { -u8 diff; - asmvolatile ("gs; repe; cmpsb; setnz %0" - :"=qm" (diff),"+D" (s1),"+S" (s2),"+c" (len)); +bool diff; + asm volatile("gs; repe; cmpsb" CC_SET(nz) + : CC_OUT(nz) (diff), "+D" (s1), "+S" (s2), "+c" (len));return diff; }
@@ -294,6 +295,7 @@ static inline int cmdline_find_option_bool(const char *option)/* cpu.c, cpucheck.c */ int check_cpu (int *cpu_level_ptr,int *req_level_ptr,u32 **err_flags_ptr); +int check_knl_erratum (void );int validate_cpu (void );/* early_serial_console.c */
arch/x86/boot/cpu.c +2 -0
@@ -93,6 +93,8 @@ int validate_cpu(void)show_cap_strs (err_flags);putchar ('\n' );return -1 ; + }else if (check_knl_erratum ()) { +return -1 ; }else {return 0 ; }
arch/x86/boot/cpucheck.c +33 -0
@@ -24,6 +24,7 @@# include "boot.h" #endif #include <linux/types.h> +#include <asm/intel-family.h> #include <asm/processor-flags.h> #include <asm/required-features.h> #include <asm/msr-index.h>
@@ -175,6 +176,8 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)puts ("WARNING: PAE disabled. Use parameter 'forcepae' to enable at your own risk!\n" ); } } +if (!err) + err =check_knl_erratum ();if (err_flags_ptr) *err_flags_ptr = err ? err_flags :NULL ;
@@ -185,3 +188,33 @@ int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr)return (cpu.level < req_level || err) ?-1 :0 ; } + +int check_knl_erratum (void ) +{ +/* +* First check for the affected model/family: +*/ +if (!is_intel () || + cpu.family !=6 || + cpu.model !=INTEL_FAM6_XEON_PHI_KNL ) +return 0 ; + +/* +* This erratum affects the Accessed/Dirty bits, and can +* cause stray bits to be set in !Present PTEs. We have +* enough bits in our 64-bit PTEs (which we have on real +* 64-bit mode or PAE) to avoid using these troublesome +* bits. But, we do not have enough space in our 32-bit +* PTEs. So, refuse to run on 32-bit non-PAE kernels. +*/ +if (IS_ENABLED (CONFIG_X86_64 ) ||IS_ENABLED (CONFIG_X86_PAE )) +return 0 ; + +puts ("This 32-bit kernel can not run on this Xeon Phi x200\n" +"processor due to a processor erratum. Use a 64-bit\n" +"kernel, or enable PAE in this 32-bit kernel.\n\n" ); + +return -1 ; +} + +
arch/x86/boot/cpuflags.c +1 -0
@@ -102,6 +102,7 @@ void get_cpuflags(void)cpuid (0x1 , &tfms, &ignored, &cpu.flags[4 ], &cpu.flags[0 ]); cpu.level = (tfms >>8 ) &15 ; + cpu.family = cpu.level; cpu.model = (tfms >>4 ) &15 ;if (cpu.level >=6 ) cpu.model += ((tfms >>16 ) &0xf ) <<4 ;
arch/x86/boot/cpuflags.h +1 -0
@@ -6,6 +6,7 @@struct cpu_features {int level;/* Family, or 64 for x86-64 */ +int family;/* Family, always */ int model;u32 flags[NCAPINTS ]; };
arch/x86/boot/string.c +1 -1
@@ -17,7 +17,7 @@int memcmp (const void *s1,const void *s2,size_t len) { -u8 diff; +bool diff; asm("repe; cmpsb; setnz %0" :"=qm" (diff),"+D" (s1),"+S" (s2),"+c" (len));return diff;
arch/x86/entry/common.c +3 -3
@@ -40,10 +40,10 @@ static struct thread_info *pt_regs_to_thread_info(struct pt_regs *regs)#ifdef CONFIG_CONTEXT_TRACKING /* Called on entry from user mode with IRQs off. */ -__visible void enter_from_user_mode(void) +__visible inline void enter_from_user_mode(void) {CT_WARN_ON (ct_state () !=CONTEXT_USER ); -user_exit (); +user_exit_irqoff (); }#else static inline void enter_from_user_mode (void ) {}
@@ -274,7 +274,7 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) ti->status &= ~TS_COMPAT ;#endif -user_enter (); +user_enter_irqoff (); }#define SYSCALL_EXIT_WORK_FLAGS \
arch/x86/entry/entry_32.S +11 -0
@@ -1153,3 +1153,14 @@ ENTRY(async_page_fault) jmp error_code END(async_page_fault) #endif + +ENTRY(rewind_stack_do_exit) + /* Prevent any naive code from trying to unwind to our caller. */ + xorl %ebp, %ebp + + movl PER_CPU_VAR(cpu_current_top_of_stack), %esi + leal -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%esi), %esp + + call do_exit +1: jmp 1b +END(rewind_stack_do_exit)
arch/x86/entry/entry_64.S +11 -0
@@ -1423,3 +1423,14 @@ ENTRY(ignore_sysret) mov $-ENOSYS, %eax sysret END(ignore_sysret) + +ENTRY(rewind_stack_do_exit) + /* Prevent any naive code from trying to unwind to our caller. */ + xorl %ebp, %ebp + + movq PER_CPU_VAR(cpu_current_top_of_stack), %rax + leaq -TOP_OF_KERNEL_STACK_PADDING-PTREGS_SIZE(%rax), %rsp + + call do_exit +1: jmp 1b +END(rewind_stack_do_exit)
arch/x86/entry/syscalls/syscall_64.tbl +2 -2
@@ -374,5 +374,5 @@ 543 x32 io_setup compat_sys_io_setup 544 x32 io_submit compat_sys_io_submit 545 x32 execveat compat_sys_execveat/ptregs -534 x32 preadv2 compat_sys_preadv2 -535 x32 pwritev2 compat_sys_pwritev2 +546 x32 preadv2 compat_sys_preadv64v2 +547 x32 pwritev2 compat_sys_pwritev64v2
arch/x86/entry/thunk_64.S +3 -3
@@ -33,7 +33,7 @@ .endif call \func - jmp restore + jmp .L_restore _ASM_NOKPROBE(\name) .endm
@@ -54,7 +54,7 @@ #if defined(CONFIG_TRACE_IRQFLAGS) \ || defined(CONFIG_DEBUG_LOCK_ALLOC) \ || defined(CONFIG_PREEMPT) -restore: +.L_restore: popq %r11 popq %r10 popq %r9
@@ -66,5 +66,5 @@ popq %rdi popq %rbp ret - _ASM_NOKPROBE(restore) + _ASM_NOKPROBE(.L_restore) #endif
arch/x86/entry/vdso/Makefile +3 -2
@@ -134,7 +134,7 @@ VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-m,elf_i386 -Wl,-soname=linux-gate.so.1 override obj-dirs = $(dir $(obj)) $(obj)/vdso32/ targets += vdso32/vdso32.lds -targets += vdso32/note.o vdso32/vclock_gettime.o vdso32/system_call.o +targets += vdso32/note.o vdso32/system_call.o vdso32/sigreturn.o targets += vdso32/vclock_gettime.o KBUILD_AFLAGS_32 := $(filter-out -m64,$(KBUILD_AFLAGS)) -DBUILD_VDSO
@@ -156,7 +156,8 @@ $(obj)/vdso32.so.dbg: FORCE \ $(obj)/vdso32/vdso32.lds \ $(obj)/vdso32/vclock_gettime.o \ $(obj)/vdso32/note.o \ - $(obj)/vdso32/system_call.o + $(obj)/vdso32/system_call.o \ + $(obj)/vdso32/sigreturn.o $(call if_changed,vdso) #
arch/x86/entry/vdso/vdso32/sigreturn.S +0 -8
@@ -1,11 +1,3 @@ -/* - * Common code for the sigreturn entry points in vDSO images. - * So far this code is the same for both int80 and sysenter versions. - * This file is #include'd by int80.S et al to define them first thing. - * The kernel assumes that the addresses of these routines are constant - * for all vDSO implementations. - */ - #include <linux/linkage.h> #include <asm/unistd_32.h> #include <asm/asm-offsets.h>
arch/x86/entry/vdso/vdso32/system_call.S +1 -6
@@ -2,16 +2,11 @@ * AT_SYSINFO entry point */ +#include <linux/linkage.h> #include <asm/dwarf2.h> #include <asm/cpufeatures.h> #include <asm/alternative-asm.h> -/* - * First get the common code for the sigreturn entry points. - * This must come first. - */ -#include "sigreturn.S" - .text .globl __kernel_vsyscall .type __kernel_vsyscall,@function
arch/x86/entry/vdso/vma.c +42 -5
71 lines not on this page · raw message
arch/x86/entry/vsyscall/vsyscall_64.c +5 -5
@@ -96,7 +96,7 @@ static bool write_ok_or_segv(unsigned long ptr, size_t size) {/* * XXX: if access_ok, get_user, and put_user handled -* sig_on_uaccess_error, this could go away. +* sig_on_uaccess_err, this could go away. */ if (!access_ok (VERIFY_WRITE , (void __user *)ptr, size)) {
@@ -125,7 +125,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)struct task_struct *tsk;unsigned long caller;int vsyscall_nr, syscall_nr, tmp; -int prev_sig_on_uaccess_error; +int prev_sig_on_uaccess_err;long ret;/*
@@ -221,8 +221,8 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)* With a real vsyscall, page faults cause SIGSEGV. We want to * preserve that behavior to make writing exploits harder. */ - prev_sig_on_uaccess_error =current_thread_info ()->sig_on_uaccess_error; -current_thread_info ()->sig_on_uaccess_error =1 ; + prev_sig_on_uaccess_err = current->thread.sig_on_uaccess_err; + current->thread.sig_on_uaccess_err =1 ; ret = -EFAULT ;switch (vsyscall_nr) {
@@ -243,7 +243,7 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address)break ; } -current_thread_info ()->sig_on_uaccess_error = prev_sig_on_uaccess_error; + current->thread.sig_on_uaccess_err = prev_sig_on_uaccess_err; check_fault:if (ret == -EFAULT ) {
arch/x86/include/asm/apm.h +3 -3
@@ -45,11 +45,11 @@ static inline void apm_bios_call_asm(u32 func, u32 ebx_in, u32 ecx_in, : "memory", "cc"); } -static inline u8 apm_bios_call_simple_asm (u32 func,u32 ebx_in, -u32 ecx_in,u32 *eax) +static inline bool apm_bios_call_simple_asm (u32 func,u32 ebx_in, +u32 ecx_in,u32 *eax) {int cx, dx, si; -u8 error; +bool error;/* * N.B. We do NOT need a cld after the BIOS call
arch/x86/include/asm/arch_hweight.h +10 -14
@@ -4,8 +4,8 @@#include <asm/cpufeatures.h> #ifdef CONFIG_64BIT -/* popcnt %edi, %eax -- redundant REX prefix for alignment */ -#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" +/* popcnt %edi, %eax */ +#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7"/* popcnt %rdi, %rax */ #define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"#define REG_IN "D"
@@ -17,19 +17,15 @@#define REG_OUT "a"#endif -/* -* __sw_hweightXX are called from within the alternatives below -* and callee-clobbered registers need to be taken care of. See -* ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective -* compiler switches. -*/ +#define __HAVE_ARCH_SW_HWEIGHT + static __always_inline unsigned int __arch_hweight32(unsigned int w) { -unsigned int res =0 ; +unsigned int res; asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); + : "="REG_OUT (res) + : REG_IN (w));return res; }
@@ -53,11 +49,11 @@ static inline unsigned long __arch_hweight64(__u64 w)#else static __always_inline unsigned long __arch_hweight64 (__u64 w) { -unsigned long res =0 ; +unsigned long res; asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); + : "="REG_OUT (res) + : REG_IN (w));return res; }
arch/x86/include/asm/archrandom.h +62 -70
167 lines not on this page · raw message
arch/x86/include/asm/asm.h +12 -0
@@ -42,6 +42,18 @@#define _ASM_SI __ASM_REG(si)#define _ASM_DI __ASM_REG(di) +/* +* Macros to generate condition code outputs from inline assembly, +* The output operand must be type "bool". +*/ +#ifdef __GCC_ASM_FLAG_OUTPUTS__ +# define CC_SET(c) "\n\t/* output condition code " #c "*/\n" +# define CC_OUT (c) "=@cc" #c +#else +# define CC_SET (c) "\n\tset" #c " %[_cc_" #c "]\n" +# define CC_OUT (c) [_cc_ ## c] "=qm" +#endif +/* Exception table entry */ #ifdef __ASSEMBLY__# define _ASM_EXTABLE_HANDLE (from, to, handler) \
arch/x86/include/asm/atomic.h +8 -8
@@ -75,9 +75,9 @@ static __always_inline void atomic_sub(int i, atomic_t *v)* true if the result is zero, or false for all * other cases. */ -static __always_inline int atomic_sub_and_test(int i, atomic_t *v) +static __always_inline bool atomic_sub_and_test(int i, atomic_t *v) { -GEN_BINARY_RMWcc (LOCK_PREFIX "subl" , v->counter,"er" , i,"%0" ,"e" ); +GEN_BINARY_RMWcc (LOCK_PREFIX "subl" , v->counter,"er" , i,"%0" , e); }/**
@@ -112,9 +112,9 @@ static __always_inline void atomic_dec(atomic_t *v)* returns true if the result is 0, or false for all other * cases. */ -static __always_inline int atomic_dec_and_test(atomic_t *v) +static __always_inline bool atomic_dec_and_test(atomic_t *v) { -GEN_UNARY_RMWcc (LOCK_PREFIX "decl" , v->counter,"%0" ,"e" ); +GEN_UNARY_RMWcc (LOCK_PREFIX "decl" , v->counter,"%0" , e); }/**
@@ -125,9 +125,9 @@ static __always_inline int atomic_dec_and_test(atomic_t *v)* and returns true if the result is zero, or false for all * other cases. */ -static __always_inline int atomic_inc_and_test(atomic_t *v) +static __always_inline bool atomic_inc_and_test(atomic_t *v) { -GEN_UNARY_RMWcc (LOCK_PREFIX "incl" , v->counter,"%0" ,"e" ); +GEN_UNARY_RMWcc (LOCK_PREFIX "incl" , v->counter,"%0" , e); }/**
@@ -139,9 +139,9 @@ static __always_inline int atomic_inc_and_test(atomic_t *v)* if the result is negative, or false when * result is greater than or equal to zero. */ -static __always_inline int atomic_add_negative(int i, atomic_t *v) +static __always_inline bool atomic_add_negative(int i, atomic_t *v) { -GEN_BINARY_RMWcc (LOCK_PREFIX "addl" , v->counter,"er" , i,"%0" ,"s" ); +GEN_BINARY_RMWcc (LOCK_PREFIX "addl" , v->counter,"er" , i,"%0" , s); }/**
arch/x86/include/asm/atomic64_64.h +9 -9
@@ -70,9 +70,9 @@ static inline void atomic64_sub(long i, atomic64_t *v)* true if the result is zero, or false for all * other cases. */ -static inline int atomic64_sub_and_test (long i,atomic64_t *v) +static inline bool atomic64_sub_and_test (long i,atomic64_t *v) { -GEN_BINARY_RMWcc (LOCK_PREFIX "subq" , v->counter,"er" , i,"%0" ,"e" ); +GEN_BINARY_RMWcc (LOCK_PREFIX "subq" , v->counter,"er" , i,"%0" , e); }/**
@@ -109,9 +109,9 @@ static __always_inline void atomic64_dec(atomic64_t *v)* returns true if the result is 0, or false for all other * cases. */ -static inline int atomic64_dec_and_test (atomic64_t *v) +static inline bool atomic64_dec_and_test (atomic64_t *v) { -GEN_UNARY_RMWcc (LOCK_PREFIX "decq" , v->counter,"%0" ,"e" ); +GEN_UNARY_RMWcc (LOCK_PREFIX "decq" , v->counter,"%0" , e); }/**
@@ -122,9 +122,9 @@ static inline int atomic64_dec_and_test(atomic64_t *v)* and returns true if the result is zero, or false for all * other cases. */ -static inline int atomic64_inc_and_test (atomic64_t *v) +static inline bool atomic64_inc_and_test (atomic64_t *v) { -GEN_UNARY_RMWcc (LOCK_PREFIX "incq" , v->counter,"%0" ,"e" ); +GEN_UNARY_RMWcc (LOCK_PREFIX "incq" , v->counter,"%0" , e); }/**
@@ -136,9 +136,9 @@ static inline int atomic64_inc_and_test(atomic64_t *v)* if the result is negative, or false when * result is greater than or equal to zero. */ -static inline int atomic64_add_negative (long i,atomic64_t *v) +static inline bool atomic64_add_negative (long i,atomic64_t *v) { -GEN_BINARY_RMWcc (LOCK_PREFIX "addq" , v->counter,"er" , i,"%0" ,"s" ); +GEN_BINARY_RMWcc (LOCK_PREFIX "addq" , v->counter,"er" , i,"%0" , s); }/**
@@ -180,7 +180,7 @@ static inline long atomic64_xchg(atomic64_t *v, long new)* Atomically adds @a to @v, so long as it was not @u. * Returns the old value of @v. */ -static inline int atomic64_add_unless (atomic64_t *v,long a,long u) +static inline bool atomic64_add_unless (atomic64_t *v,long a,long u) {long c, old; c =atomic64_read (v);
arch/x86/include/asm/bitops.h +25 -25
119 lines not on this page · raw message
arch/x86/include/asm/checksum_32.h +1 -2
@@ -2,8 +2,7 @@#define _ASM_X86_CHECKSUM_32_H#include <linux/in6.h> - -#include <asm/uaccess.h> +#include <linux/uaccess.h> /* * computes the checksum of a memory block at buff, length len,
arch/x86/include/asm/compat.h +11 -0
@@ -40,6 +40,7 @@ typedef s32 compat_long_t; typedef s64 __attribute__((aligned(4))) compat_s64;typedef u32 compat_uint_t ;typedef u32 compat_ulong_t ; +typedef u32 compat_u32 ; typedef u64 __attribute__((aligned(4))) compat_u64;typedef u32 compat_uptr_t ;
@@ -181,6 +182,16 @@ typedef struct compat_siginfo {/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ struct {unsigned int _addr;/* faulting insn/memory ref. */ +short int _addr_lsb;/* Valid LSB of the reported address. */ +union { +/* used when si_code=SEGV_BNDERR */ +struct { +compat_uptr_t _lower; +compat_uptr_t _upper; + } _addr_bnd; +/* used when si_code=SEGV_PKUERR */ +compat_u32 _pkey; + }; } _sigfault;/* SIGPOLL */
arch/x86/include/asm/cpu.h +0 -1
@@ -17,7 +17,6 @@ static inline void prefill_possible_map(void) {}#define cpu_physical_id (cpu) boot_cpu_physical_apicid#define safe_smp_processor_id () 0 -#define stack_smp_processor_id () 0#endif /* CONFIG_SMP */
arch/x86/include/asm/efi.h +0 -1
@@ -125,7 +125,6 @@ extern void __init efi_map_region_fixed(efi_memory_desc_t *md);extern void efi_sync_low_kernel_mappings (void );extern int __init efi_alloc_page_tables (void );extern int __init efi_setup_page_tables (unsigned long pa_memmap,unsigned num_pages); -extern void __init efi_cleanup_page_tables (unsigned long pa_memmap,unsigned num_pages);extern void __init old_map_region (efi_memory_desc_t *md);extern void __init runtime_code_page_mkexec (void );extern void __init efi_runtime_update_mappings (void );
arch/x86/include/asm/local.h +8 -8
@@ -50,9 +50,9 @@ static inline void local_sub(long i, local_t *l)* true if the result is zero, or false for all * other cases. */ -static inline int local_sub_and_test (long i,local_t *l) +static inline bool local_sub_and_test (long i,local_t *l) { -GEN_BINARY_RMWcc (_ASM_SUB, l->a.counter,"er" , i,"%0" ,"e" ); +GEN_BINARY_RMWcc (_ASM_SUB, l->a.counter,"er" , i,"%0" , e); }/**
@@ -63,9 +63,9 @@ static inline int local_sub_and_test(long i, local_t *l)* returns true if the result is 0, or false for all other * cases. */ -static inline int local_dec_and_test (local_t *l) +static inline bool local_dec_and_test (local_t *l) { -GEN_UNARY_RMWcc (_ASM_DEC, l->a.counter,"%0" ,"e" ); +GEN_UNARY_RMWcc (_ASM_DEC, l->a.counter,"%0" , e); }/**
@@ -76,9 +76,9 @@ static inline int local_dec_and_test(local_t *l)* and returns true if the result is zero, or false for all * other cases. */ -static inline int local_inc_and_test (local_t *l) +static inline bool local_inc_and_test (local_t *l) { -GEN_UNARY_RMWcc (_ASM_INC, l->a.counter,"%0" ,"e" ); +GEN_UNARY_RMWcc (_ASM_INC, l->a.counter,"%0" , e); }/**
@@ -90,9 +90,9 @@ static inline int local_inc_and_test(local_t *l)* if the result is negative, or false when * result is greater than or equal to zero. */ -static inline int local_add_negative (long i,local_t *l) +static inline bool local_add_negative (long i,local_t *l) { -GEN_BINARY_RMWcc (_ASM_ADD, l->a.counter,"er" , i,"%0" ,"s" ); +GEN_BINARY_RMWcc (_ASM_ADD, l->a.counter,"er" , i,"%0" , s); }/**
arch/x86/include/asm/percpu.h +9 -8
@@ -510,14 +510,15 @@ do { \/* This is not atomic against other CPUs -- CPU preemption needs to be off */ #define x86_test_and_clear_bit_percpu (bit, var) \ ({ \ - int old__; \ - asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0" \ - : "=r" (old__), "+m" (var) \ + bool old__; \ + asm volatile("btr %2,"__percpu_arg(1)"\n\t" \ + CC_SET(c) \ + : CC_OUT(c) (old__), "+m" (var) \ : "dIr" (bit)); \ old__; \ }) -static __always_inline int x86_this_cpu_constant_test_bit(unsigned int nr, +static __always_inline bool x86_this_cpu_constant_test_bit(unsigned int nr,const unsigned long __percpu *addr) {unsigned long __percpu *a = (unsigned long *)addr + nr /BITS_PER_LONG ;
@@ -529,14 +530,14 @@ static __always_inline int x86_this_cpu_constant_test_bit(unsigned int nr,#endif } -static inline int x86_this_cpu_variable_test_bit (int nr, +static inline bool x86_this_cpu_variable_test_bit (int nr,const unsigned long __percpu *addr) { -int oldbit; +bool oldbit; asm volatile("bt "__percpu_arg(2)",%1\n\t" - "sbb %0,%0" - : "=r" (oldbit) + CC_SET(c) + : CC_OUT(c) (oldbit) : "m" (*(unsigned long *)addr), "Ir" (nr));return oldbit;
arch/x86/include/asm/pgtable.h +10 -3
@@ -480,7 +480,7 @@ pte_t *populate_extra_pte(unsigned long vaddr);static inline int pte_none (pte_t pte) { -return !pte.pte; +return !(pte.pte & ~(_PAGE_KNL_ERRATUM_MASK)); }#define __HAVE_ARCH_PTE_SAME
@@ -552,7 +552,8 @@ static inline int pmd_none(pmd_t pmd) {/* Only check low word on 32-bit platforms, since it might be out of sync with upper half. */ -return (unsigned long )native_pmd_val (pmd) ==0 ; +unsigned long val =native_pmd_val (pmd); +return (val & ~_PAGE_KNL_ERRATUM_MASK) ==0 ; }static inline unsigned long pmd_page_vaddr (pmd_t pmd)
@@ -616,7 +617,7 @@ static inline unsigned long pages_to_mb(unsigned long npg)#if CONFIG_PGTABLE_LEVELS >2 static inline int pud_none (pud_t pud) { -return native_pud_val (pud) ==0 ; +return (native_pud_val (pud) & ~(_PAGE_KNL_ERRATUM_MASK)) ==0 ; }static inline int pud_present (pud_t pud)
@@ -694,6 +695,12 @@ static inline int pgd_bad(pgd_t pgd)static inline int pgd_none (pgd_t pgd) { +/* +* There is no need to do a workaround for the KNL stray +* A/D bit erratum here. PGDs only point to page tables +* except on 32-bit non-PAE which is not supported on +* KNL. +*/ return !native_pgd_val (pgd); }#endif /* CONFIG_PGTABLE_LEVELS > 3 */
arch/x86/include/asm/pgtable_64.h +20 -6
@@ -140,18 +140,32 @@ static inline int pgd_large(pgd_t pgd) { return 0; }#define pte_offset_map (dir, address) pte_offset_kernel((dir), (address))#define pte_unmap (pte) ((void)(pte))/* NOP */ -/* Encode and de-code a swap entry */ +/* +* Encode and de-code a swap entry +* +* | ... | 11| 10| 9|8|7|6|5| 4| 3|2|1|0| <- bit number +* | ... |SW3|SW2|SW1|G|L|D|A|CD|WT|U|W|P| <- bit names +* | OFFSET (14->63) | TYPE (10-13) |0|X|X|X| X| X|X|X|0| <- swp entry +* +* G (8) is aliased and used as a PROT_NONE indicator for +* !present ptes. We need to start storing swap entries above +* there. We also need to avoid using A and D because of an +* erratum where they can be incorrectly set by hardware on +* non-present PTEs. +*/ +#define SWP_TYPE_FIRST_BIT (_PAGE_BIT_PROTNONE + 1)#define SWP_TYPE_BITS 5 -#define SWP_OFFSET_SHIFT (_PAGE_BIT_PROTNONE + 1) +/* Place the offset above the type: */ +#define SWP_OFFSET_FIRST_BIT (SWP_TYPE_FIRST_BIT + SWP_TYPE_BITS + 1)#define MAX_SWAPFILES_CHECK () BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > SWP_TYPE_BITS) -#define __swp_type (x) (((x).val >> (_PAGE_BIT_PRESENT + 1)) \ +#define __swp_type (x) (((x).val >> (SWP_TYPE_FIRST_BIT)) \ & ((1U << SWP_TYPE_BITS) - 1)) -#define __swp_offset (x) ((x).val >> SWP_OFFSET_SHIFT) +#define __swp_offset (x) ((x).val >> SWP_OFFSET_FIRST_BIT)#define __swp_entry (type, offset) ((swp_entry_t) { \ - ((type) << (_PAGE_BIT_PRESENT + 1)) \ - | ((offset) << SWP_OFFSET_SHIFT) }) + ((type) << (SWP_TYPE_FIRST_BIT)) \ + | ((offset) << SWP_OFFSET_FIRST_BIT) })#define __pte_to_swp_entry (pte) ((swp_entry_t) { pte_val((pte)) })#define __swp_entry_to_pte (x) ((pte_t) { .pte = (x).val })
arch/x86/include/asm/pgtable_types.h +6 -2
@@ -70,6 +70,12 @@ _PAGE_PKEY_BIT2 | \ _PAGE_PKEY_BIT3) +#if defined(CONFIG_X86_64 ) || defined(CONFIG_X86_PAE ) +#define _PAGE_KNL_ERRATUM_MASK (_PAGE_DIRTY | _PAGE_ACCESSED) +#else +#define _PAGE_KNL_ERRATUM_MASK 0 +#endif +#ifdef CONFIG_KMEMCHECK #define _PAGE_HIDDEN (_AT(pteval_t, 1) << _PAGE_BIT_HIDDEN)#else
@@ -475,8 +481,6 @@ extern pmd_t *lookup_pmd_address(unsigned long address);extern phys_addr_t slow_virt_to_phys (void *__address);extern int kernel_map_pages_in_pgd (pgd_t *pgd,u64 pfn,unsigned long address,unsigned numpages,unsigned long page_flags); -void kernel_unmap_pages_in_pgd (pgd_t *root,unsigned long address, -unsigned numpages);#endif /* !__ASSEMBLY__ */ #endif /* _ASM_X86_PGTABLE_DEFS_H */
arch/x86/include/asm/preempt.h +1 -1
@@ -81,7 +81,7 @@ static __always_inline void __preempt_count_sub(int val)*/ static __always_inline bool __preempt_count_dec_and_test(void) { -GEN_UNARY_RMWcc ("decl" , __preempt_count,__percpu_arg (0 ),"e" ); +GEN_UNARY_RMWcc ("decl" , __preempt_count,__percpu_arg (0 ), e); }/*
arch/x86/include/asm/processor.h +13 -7
@@ -371,6 +371,10 @@ extern unsigned int xstate_size;struct perf_event ; +typedef struct { +unsigned long seg; +}mm_segment_t ; +struct thread_struct {/* Cached TLS descriptors: */ struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES ];
@@ -419,6 +423,11 @@ struct thread_struct {/* Max allowed port in the bitmap, in bytes: */ unsigned io_bitmap_max; +mm_segment_t addr_limit; + + unsigned int sig_on_uaccess_err:1; + unsigned int uaccess_err:1; /* uaccess failed */ +/* Floating point and extended processor state */ struct fpu fpu;/*
@@ -490,11 +499,6 @@ static inline void load_sp0(struct tss_struct *tss,#define set_iopl_mask native_set_iopl_mask#endif /* CONFIG_PARAVIRT */ -typedef struct { -unsigned long seg; -}mm_segment_t ; - -/* Free all resources held by a thread. */ extern void release_thread (struct task_struct *);
@@ -716,6 +720,7 @@ static inline void spin_lock_prefetch(const void *x) .sp0 = TOP_OF_INIT_STACK, \ .sysenter_cs = __KERNEL_CS, \ .io_bitmap_ptr = NULL, \ + .addr_limit = KERNEL_DS, \ }extern unsigned long thread_saved_pc (struct task_struct *tsk);
@@ -765,8 +770,9 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk);#define STACK_TOP TASK_SIZE#define STACK_TOP_MAX TASK_SIZE_MAX -#define INIT_THREAD { \ - .sp0 = TOP_OF_INIT_STACK \ +#define INIT_THREAD { \ + .sp0 = TOP_OF_INIT_STACK, \ + .addr_limit = KERNEL_DS, \ }/*
arch/x86/include/asm/rmwcc.h +12 -8
@@ -1,11 +1,13 @@#ifndef _ASM_X86_RMWcc#define _ASM_X86_RMWcc -#ifdef CC_HAVE_ASM_GOTO +#if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO ) + +/* Use asm goto */ #define __GEN_RMWcc (fullop, var, cc, ...) \ do { \ - asm_volatile_goto (fullop "; j" cc " %l[cc_label]" \ + asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \ : : "m" (var), ## __VA_ARGS__ \ : "memory" : cc_label); \ return 0; \
@@ -19,15 +21,17 @@ cc_label: \#define GEN_BINARY_RMWcc (op, var, vcon, val, arg0, cc) \ __GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val)) -#else /* !CC_HAVE_ASM_GOTO */ +#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ + +/* Use flags output or a set instruction */ #define __GEN_RMWcc (fullop, var, cc, ...) \ do { \ - char c; \ - asm volatile (fullop "; set" cc " %1" \ - : "+m" (var), "=qm" (c) \ + bool c; \ + asm volatile (fullop ";" CC_SET(cc) \ + : "+m" (var), CC_OUT(cc) (c) \ : __VA_ARGS__ : "memory"); \ - return c != 0; \ + return c; \ } while (0)#define GEN_UNARY_RMWcc (op, var, arg0, cc) \
@@ -36,6 +40,6 @@ do { \#define GEN_BINARY_RMWcc (op, var, vcon, val, arg0, cc) \ __GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val)) -#endif /* CC_HAVE_ASM_GOTO */ +#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */ #endif /* _ASM_X86_RMWcc */
arch/x86/include/asm/rwsem.h +9 -8
@@ -77,7 +77,7 @@ static inline void __down_read(struct rw_semaphore *sem)/* * trylock for reading -- returns 1 if successful, 0 if contention */ -static inline int __down_read_trylock (struct rw_semaphore *sem) +static inline bool __down_read_trylock (struct rw_semaphore *sem) {long result, tmp; asm volatile("# beginning __down_read_trylock\n\t"
@@ -93,7 +93,7 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) : "+m" (sem->count), "=&a" (result), "=&r" (tmp) : "i" (RWSEM_ACTIVE_READ_BIAS) : "memory", "cc"); -return result >=0 ?1 :0 ; +return result >=0 ; }/*
@@ -134,9 +134,10 @@ static inline int __down_write_killable(struct rw_semaphore *sem)/* * trylock for writing -- returns 1 if successful, 0 if contention */ -static inline int __down_write_trylock (struct rw_semaphore *sem) +static inline bool __down_write_trylock (struct rw_semaphore *sem) { -long result, tmp; +bool result; +long tmp0, tmp1; asmvolatile ("# beginning __down_write_trylock\n\t" " mov %0,%1\n\t" "1:\n\t"
@@ -144,14 +145,14 @@ static inline int __down_write_trylock(struct rw_semaphore *sem)/* was the active mask 0 before? */ " jnz 2f\n\t" " mov %1,%2\n\t" -" add %3,%2\n\t" +" add %4,%2\n\t" LOCK_PREFIX " cmpxchg %2,%0\n\t" " jnz 1b\n\t" "2:\n\t" -" sete %b1\n\t" -" movzbl %b1, %k1\n\t" + CC_SET(e) "# ending __down_write_trylock\n\t" - : "+m" (sem->count), "=&a" (result), "=&r" (tmp) + : "+m" (sem->count), "=&a" (tmp0), "=&r" (tmp1), + CC_OUT(e) (result) : "er" (RWSEM_ACTIVE_WRITE_BIAS) : "memory", "cc");return result;
arch/x86/include/asm/signal.h +3 -3
@@ -81,9 +81,9 @@ static inline int __const_sigismember(sigset_t *set, int _sig)static inline int __gen_sigismember (sigset_t *set,int _sig) { -int ret; - asm("btl %2,%1\n\tsbbl %0,%0" - :"=r" (ret) :"m" (*set),"Ir" (_sig-1 ) :"cc" ); +unsigned char ret; + asm("btl %2,%1\n\tsetc %0" + :"=qm" (ret) :"m" (*set),"Ir" (_sig-1 ) :"cc" );return ret; }
arch/x86/include/asm/smp.h +0 -6
@@ -172,12 +172,6 @@ extern int safe_smp_processor_id(void);#elif defined(CONFIG_X86_64_SMP )#define raw_smp_processor_id () (this_cpu_read(cpu_number)) -#define stack_smp_processor_id () \ -({ \ - struct thread_info *ti; \ - __asm__("andq %%rsp,%0; ":"=r" (ti) : "0" (CURRENT_MASK)); \ - ti->cpu; \ -})#define safe_smp_processor_id () smp_processor_id()#endif
arch/x86/include/asm/sync_bitops.h +9 -9
@@ -79,10 +79,10 @@ static inline void sync_change_bit(long nr, volatile unsigned long *addr)*/ static inline int sync_test_and_set_bit (long nr,volatile unsigned long *addr) { -int oldbit; +unsigned char oldbit; - asmvolatile ("lock; bts %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR ) + asmvolatile ("lock; bts %2,%1\n\tsetc %0" + :"=qm" (oldbit),"+m" (ADDR ) :"Ir" (nr) :"memory" );return oldbit; }
@@ -97,10 +97,10 @@ static inline int sync_test_and_set_bit(long nr, volatile unsigned long *addr)*/ static inline int sync_test_and_clear_bit (long nr,volatile unsigned long *addr) { -int oldbit; +unsigned char oldbit; - asmvolatile ("lock; btr %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR ) + asmvolatile ("lock; btr %2,%1\n\tsetc %0" + :"=qm" (oldbit),"+m" (ADDR ) :"Ir" (nr) :"memory" );return oldbit; }
@@ -115,10 +115,10 @@ static inline int sync_test_and_clear_bit(long nr, volatile unsigned long *addr)*/ static inline int sync_test_and_change_bit (long nr,volatile unsigned long *addr) { -int oldbit; +unsigned char oldbit; - asmvolatile ("lock; btc %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit),"+m" (ADDR ) + asmvolatile ("lock; btc %2,%1\n\tsetc %0" + :"=qm" (oldbit),"+m" (ADDR ) :"Ir" (nr) :"memory" );return oldbit; }
arch/x86/include/asm/thread_info.h +0 -9
@@ -57,9 +57,6 @@ struct thread_info {__u32 flags;/* low level flags */ __u32 status;/* thread synchronous flags */ __u32 cpu;/* current CPU */ -mm_segment_t addr_limit; - unsigned int sig_on_uaccess_error:1; - unsigned int uaccess_err:1; /* uaccess failed */ };#define INIT_THREAD_INFO (tsk) \
@@ -67,7 +64,6 @@ struct thread_info { .task = &tsk, \ .flags = 0, \ .cpu = 0, \ - .addr_limit = KERNEL_DS, \ }#define init_thread_info (init_thread_union.thread_info)
@@ -186,11 +182,6 @@ static inline unsigned long current_stack_pointer(void)# define cpu_current_top_of_stack (cpu_tss + TSS_sp0)#endif -/* Load thread_info address into "reg" */ -#define GET_THREAD_INFO (reg) \ - _ASM_MOV PER_CPU_VAR(cpu_current_top_of_stack),reg ; \ - _ASM_SUB $(THREAD_SIZE),reg ; -/* * ASM operand which evaluates to a 'thread_info' address of * the current task, if it is known that "reg" is exactly "off"
arch/x86/include/asm/uaccess.h +26 -7
@@ -29,12 +29,12 @@#define USER_DS MAKE_MM_SEG(TASK_SIZE_MAX)#define get_ds () (KERNEL_DS) -#define get_fs () (current_thread_info()->addr_limit) -#define set_fs (x) (current_thread_info()->addr_limit = (x)) +#define get_fs () (current->thread.addr_limit) +#define set_fs (x) (current->thread.addr_limit = (x))#define segment_eq (a, b) ((a).seg == (b).seg) -#define user_addr_max () (current_thread_info()->addr_limit.seg) +#define user_addr_max () (current->thread.addr_limit.seg)#define __addr_ok (addr) \ ((unsigned long __force)(addr) < user_addr_max())
@@ -342,7 +342,26 @@ do { \ } while (0)#ifdef CONFIG_X86_32 -#define __get_user_asm_u64 (x, ptr, retval, errret) (x) = __get_user_bad() +#define __get_user_asm_u64 (x, ptr, retval, errret) \ +({ \ + __typeof__(ptr) __ptr = (ptr); \ + asm volatile(ASM_STAC "\n" \ + "1: movl %2,%%eax\n" \ + "2: movl %3,%%edx\n" \ + "3: " ASM_CLAC "\n" \ + ".section .fixup,\"ax\"\n" \ + "4: mov %4,%0\n" \ + " xorl %%eax,%%eax\n" \ + " xorl %%edx,%%edx\n" \ + " jmp 3b\n" \ + ".previous\n" \ + _ASM_EXTABLE(1b, 4b) \ + _ASM_EXTABLE(2b, 4b) \ + : "=r" (retval), "=A"(x) \ + : "m" (__m(__ptr)), "m" __m(((u32 *)(__ptr)) + 1), \ + "i" (errret), "0" (retval)); \ +}) +#define __get_user_asm_ex_u64 (x, ptr) (x) = __get_user_bad()#else #define __get_user_asm_u64 (x, ptr, retval, errret) \
@@ -429,7 +448,7 @@ do { \#define __get_user_nocheck (x, ptr, size) \ ({ \ int __gu_err; \ - unsigned long __gu_val; \ + __inttype(*(ptr)) __gu_val; \ __uaccess_begin(); \ __get_user_size(__gu_val, (ptr), (size), __gu_err, -EFAULT); \ __uaccess_end(); \
@@ -468,13 +487,13 @@ struct __large_struct { unsigned long buf[100]; };* uaccess_try and catch */ #define uaccess_try do { \ - current_thread_info()->uaccess_err = 0; \ + current->thread.uaccess_err = 0; \ __uaccess_begin(); \ barrier();#define uaccess_catch (err) \ __uaccess_end(); \ - (err) |= (current_thread_info()->uaccess_err ? -EFAULT : 0); \ + (err) |= (current->thread.uaccess_err ? -EFAULT : 0); \ } while (0)/**
arch/x86/include/asm/unistd.h +2 -0
@@ -26,6 +26,8 @@# define __ARCH_WANT_COMPAT_SYS_GETDENTS64# define __ARCH_WANT_COMPAT_SYS_PREADV64# define __ARCH_WANT_COMPAT_SYS_PWRITEV64 +# define __ARCH_WANT_COMPAT_SYS_PREADV64V2 +# define __ARCH_WANT_COMPAT_SYS_PWRITEV64V2# endif
arch/x86/kernel/asm-offsets.c +3 -1
@@ -31,7 +31,9 @@ void common(void) {BLANK ();OFFSET (TI_flags, thread_info, flags);OFFSET (TI_status, thread_info, status); -OFFSET (TI_addr_limit, thread_info, addr_limit); + +BLANK (); +OFFSET (TASK_addr_limit, task_struct, thread.addr_limit);BLANK ();OFFSET (crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
arch/x86/kernel/cpu/common.c +1 -1
@@ -1452,7 +1452,7 @@ void cpu_init(void)struct task_struct *me;struct tss_struct *t;unsigned long v; -int cpu =stack_smp_processor_id (); +int cpu =raw_smp_processor_id ();int i;wait_for_master_cpu (cpu);
arch/x86/kernel/cpu/rdrand.c +2 -2
@@ -39,9 +39,9 @@ __setup("nordrand", x86_rdrand_setup);*/ #define SANITY_CHECK_LOOPS 8 +#ifdef CONFIG_ARCH_RANDOM void x86_init_rdrand (struct cpuinfo_x86 *c) { -#ifdef CONFIG_ARCH_RANDOM unsigned long tmp;int i;
@@ -55,5 +55,5 @@ void x86_init_rdrand(struct cpuinfo_x86 *c) return; } } -#endif } +#endif
arch/x86/kernel/dumpstack.c +18 -2
@@ -87,7 +87,7 @@ static inline int valid_stack_ptr(struct task_struct *task,else return 0 ; } -return p > t && p < t +THREAD_SIZE - size; +return p >= t && p < t +THREAD_SIZE - size; }unsigned long
@@ -98,6 +98,14 @@ print_context_stack(struct task_struct *task, {struct stack_frame *frame = (struct stack_frame *)bp; +/* +* If we overflowed the stack into a guard page, jump back to the +* bottom of the usable stack. +*/ +if ((unsigned long )task_stack_page (task) - (unsigned long )stack < +PAGE_SIZE ) + stack = (unsigned long *)task_stack_page (task); +while (valid_stack_ptr (task, stack,sizeof (*stack), end)) {unsigned long addr;
@@ -226,6 +234,8 @@ unsigned long oops_begin(void)EXPORT_SYMBOL_GPL (oops_begin);NOKPROBE_SYMBOL (oops_begin); +void __noreturn rewind_stack_do_exit (int signr); +void oops_end (unsigned long flags,struct pt_regs *regs,int signr) {if (regs &&kexec_should_crash (current))
@@ -247,7 +257,13 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)panic ("Fatal exception in interrupt" );if (panic_on_oops)panic ("Fatal exception" ); -do_exit (signr); + +/* +* We're not going to return, but we might be on an IST stack or +* have very little stack space left. Rewind the stack and kill +* the task. +*/ +rewind_stack_do_exit (signr); }NOKPROBE_SYMBOL (oops_end);
arch/x86/kernel/dumpstack_64.c +10 -2
@@ -272,6 +272,8 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, stack = sp;for (i =0 ; i < kstack_depth_to_print; i++) { +unsigned long word; +if (stack >= irq_stack && stack <= irq_stack_end) {if (stack == irq_stack_end) { stack = (unsigned long *) (irq_stack_end[-1 ]);
@@ -281,12 +283,18 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,if (kstack_end (stack))break ; } + +if (probe_kernel_address (stack, word)) +break ; +if ((i %STACKSLOTS_PER_LINE ) ==0 ) {if (i !=0 )pr_cont ("\n" ); -printk ("%s %016lx" , log_lvl, *stack++); +printk ("%s %016lx" , log_lvl, word); }else -pr_cont (" %016lx" , *stack++); +pr_cont (" %016lx" , word); + + stack++;touch_nmi_watchdog (); }preempt_enable ();
arch/x86/kernel/i386_ksyms_32.c +2 -0
@@ -42,3 +42,5 @@ EXPORT_SYMBOL(empty_zero_page);EXPORT_SYMBOL (___preempt_schedule);EXPORT_SYMBOL (___preempt_schedule_notrace);#endif + +EXPORT_SYMBOL (__sw_hweight32);
arch/x86/kernel/signal_compat.c +108 -0
125 lines not on this page · raw message
arch/x86/kernel/smpboot.c +0 -1
@@ -1285,7 +1285,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)cpumask_copy (cpu_callin_mask,cpumask_of (0 ));mb (); -current_thread_info ()->cpu =0 ;/* needed? */ for_each_possible_cpu (i) {zalloc_cpumask_var (&per_cpu (cpu_sibling_map, i),GFP_KERNEL );zalloc_cpumask_var (&per_cpu (cpu_core_map, i),GFP_KERNEL );
arch/x86/kernel/vm86_32.c +1 -4
@@ -440,10 +440,7 @@ static inline unsigned long get_vflags(struct kernel_vm86_regs *regs)static inline int is_revectored (int nr,struct revectored_struct *bitmap) { - __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0" - :"=r" (nr) - :"m" (*bitmap),"r" (nr)); -return nr; +return test_bit (nr, bitmap->__map); }#define val_byte (val, n) (((__u8 *)&val)[n])
arch/x86/kernel/x8664_ksyms_64.c +3 -0
@@ -44,6 +44,9 @@ EXPORT_SYMBOL(clear_page);EXPORT_SYMBOL (csum_partial); +EXPORT_SYMBOL (__sw_hweight32); +EXPORT_SYMBOL (__sw_hweight64); +/* * Export string functions. We normally rely on gcc builtin for most of these, * but gcc sometimes decides not to inline them.
arch/x86/lib/Makefile +1 -1
@@ -25,7 +25,7 @@ lib-y += memcpy_$(BITS).o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o -obj-y += msr.o msr-reg.o msr-reg-export.o +obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o ifeq ($(CONFIG_X86_32),y) obj-y += atomic64_32.o
arch/x86/lib/copy_user_64.S +4 -4
@@ -17,11 +17,11 @@ /* Standard copy_to_user with segment limit checking */ ENTRY(_copy_to_user) - GET_THREAD_INFO(%rax) + mov PER_CPU_VAR(current_task), %rax movq %rdi,%rcx addq %rdx,%rcx jc bad_to_user - cmpq TI_addr_limit(%rax),%rcx + cmpq TASK_addr_limit(%rax),%rcx ja bad_to_user ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \ "jmp copy_user_generic_string", \
@@ -32,11 +32,11 @@ ENDPROC(_copy_to_user) /* Standard copy_from_user with segment limit checking */ ENTRY(_copy_from_user) - GET_THREAD_INFO(%rax) + mov PER_CPU_VAR(current_task), %rax movq %rsi,%rcx addq %rdx,%rcx jc bad_from_user - cmpq TI_addr_limit(%rax),%rcx + cmpq TASK_addr_limit(%rax),%rcx ja bad_from_user ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \ "jmp copy_user_generic_string", \
arch/x86/lib/csum-wrappers_64.c +1 -0
@@ -6,6 +6,7 @@*/ #include <asm/checksum.h> #include <linux/module.h> +#include <linux/uaccess.h> #include <asm/smap.h> /**
arch/x86/lib/getuser.S +10 -10
@@ -35,8 +35,8 @@ .text ENTRY(__get_user_1) - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + mov PER_CPU_VAR(current_task), %_ASM_DX + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user ASM_STAC 1: movzbl (%_ASM_AX),%edx
@@ -48,8 +48,8 @@ ENDPROC(__get_user_1) ENTRY(__get_user_2) add $1,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + mov PER_CPU_VAR(current_task), %_ASM_DX + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user ASM_STAC 2: movzwl -1(%_ASM_AX),%edx
@@ -61,8 +61,8 @@ ENDPROC(__get_user_2) ENTRY(__get_user_4) add $3,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + mov PER_CPU_VAR(current_task), %_ASM_DX + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user ASM_STAC 3: movl -3(%_ASM_AX),%edx
@@ -75,8 +75,8 @@ ENTRY(__get_user_8) #ifdef CONFIG_X86_64 add $7,%_ASM_AX jc bad_get_user - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + mov PER_CPU_VAR(current_task), %_ASM_DX + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user ASM_STAC 4: movq -7(%_ASM_AX),%rdx
@@ -86,8 +86,8 @@ ENTRY(__get_user_8) #else add $7,%_ASM_AX jc bad_get_user_8 - GET_THREAD_INFO(%_ASM_DX) - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX + mov PER_CPU_VAR(current_task), %_ASM_DX + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX jae bad_get_user_8 ASM_STAC 4: movl -7(%_ASM_AX),%edx
arch/x86/lib/hweight.S new file +77 -0
77 lines not on this page · raw message
arch/x86/lib/putuser.S +5 -5
@@ -29,14 +29,14 @@ * as they get called from within inline assembly. */ -#define ENTER GET_THREAD_INFO(%_ASM_BX) +#define ENTER mov PER_CPU_VAR(current_task), %_ASM_BX #define EXIT ASM_CLAC ; \ ret .text ENTRY(__put_user_1) ENTER - cmp TI_addr_limit(%_ASM_BX),%_ASM_CX + cmp TASK_addr_limit(%_ASM_BX),%_ASM_CX jae bad_put_user ASM_STAC 1: movb %al,(%_ASM_CX)
@@ -46,7 +46,7 @@ ENDPROC(__put_user_1) ENTRY(__put_user_2) ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX + mov TASK_addr_limit(%_ASM_BX),%_ASM_BX sub $1,%_ASM_BX cmp %_ASM_BX,%_ASM_CX jae bad_put_user
@@ -58,7 +58,7 @@ ENDPROC(__put_user_2) ENTRY(__put_user_4) ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX + mov TASK_addr_limit(%_ASM_BX),%_ASM_BX sub $3,%_ASM_BX cmp %_ASM_BX,%_ASM_CX jae bad_put_user
@@ -70,7 +70,7 @@ ENDPROC(__put_user_4) ENTRY(__put_user_8) ENTER - mov TI_addr_limit(%_ASM_BX),%_ASM_BX + mov TASK_addr_limit(%_ASM_BX),%_ASM_BX sub $7,%_ASM_BX cmp %_ASM_BX,%_ASM_CX jae bad_put_user
arch/x86/lib/usercopy_64.c +1 -1
@@ -6,7 +6,7 @@* Copyright 2002 Andi Kleen <[email protected]> */ #include <linux/module.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> /* * Zero Userspace
arch/x86/mm/extable.c +1 -1
@@ -37,7 +37,7 @@ bool ex_handler_ext(const struct exception_table_entry *fixup, struct pt_regs *regs, int trapnr) {/* Special hack for uaccess_err */ -current_thread_info ()->uaccess_err =1 ; + current->thread.uaccess_err =1 ; regs->ip =ex_fixup_addr (fixup);return true; }
arch/x86/mm/fault.c +2 -2
@@ -439,7 +439,7 @@ static noinline int vmalloc_fault(unsigned long address)* happen within a race in page table update. In the later * case just flush: */ - pgd =pgd_offset (current->active_mm, address); + pgd = (pgd_t *)__va (read_cr3 ()) +pgd_index (address); pgd_ref =pgd_offset_k (address);if (pgd_none (*pgd_ref))return -1 ;
@@ -737,7 +737,7 @@ no_context(struct pt_regs *regs, unsigned long error_code,* In this case we need to make sure we're not recursively * faulting through the emulate_vsyscall() logic. */ -if (current_thread_info ()->sig_on_uaccess_error && signal) { +if (current->thread.sig_on_uaccess_err && signal) { tsk->thread.trap_nr =X86_TRAP_PF ; tsk->thread.error_code = error_code |PF_USER ; tsk->thread.cr2 = address;
arch/x86/mm/init_64.c +5 -32
@@ -354,7 +354,7 @@ phys_pte_init(pte_t *pte_page, unsigned long addr, unsigned long end,* pagetable pages as RO. So assume someone who pre-setup * these mappings are more intelligent. */ -if (pte_val (*pte)) { +if (!pte_none (*pte)) {if (!after_bootmem) pages++;continue ;
@@ -396,7 +396,7 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,continue ; } -if (pmd_val (*pmd)) { +if (!pmd_none (*pmd)) {if (!pmd_large (*pmd)) {spin_lock (&init_mm.page_table_lock); pte = (pte_t *)pmd_page_vaddr (*pmd);
@@ -470,7 +470,7 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,continue ; } -if (pud_val (*pud)) { +if (!pud_none (*pud)) {if (!pud_large (*pud)) { pmd =pmd_offset (pud,0 ); last_map_addr = phys_pmd_init(pmd, addr, end,
@@ -673,7 +673,7 @@ static void __meminit free_pte_table(pte_t *pte_start, pmd_t *pmd)for (i =0 ; i <PTRS_PER_PTE ; i++) { pte = pte_start + i; -if (pte_val (*pte)) +if (!pte_none (*pte))return ; }
@@ -691,7 +691,7 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)for (i =0 ; i <PTRS_PER_PMD ; i++) { pmd = pmd_start + i; -if (pmd_val (*pmd)) +if (!pmd_none (*pmd))return ; }
@@ -702,27 +702,6 @@ static void __meminit free_pmd_table(pmd_t *pmd_start, pud_t *pud)spin_unlock (&init_mm.page_table_lock); } -/* Return true if pgd is changed, otherwise return false. */ -static bool __meminit free_pud_table (pud_t *pud_start,pgd_t *pgd) -{ -pud_t *pud; -int i; - -for (i =0 ; i <PTRS_PER_PUD ; i++) { - pud = pud_start + i; -if (pud_val (*pud)) -return false; - } - -/* free a pud table */ -free_pagetable (pgd_page (*pgd),0 ); -spin_lock (&init_mm.page_table_lock); -pgd_clear (pgd); -spin_unlock (&init_mm.page_table_lock); - -return true; -} -static void __meminit remove_pte_table (pte_t *pte_start,unsigned long addr,unsigned long end,bool direct)
@@ -913,7 +892,6 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct)unsigned long addr;pgd_t *pgd;pud_t *pud; -bool pgd_changed = false;for (addr = start; addr < end; addr = next) { next =pgd_addr_end (addr, end);
@@ -924,13 +902,8 @@ remove_pagetable(unsigned long start, unsigned long end, bool direct) pud = (pud_t *)pgd_page_vaddr (*pgd);remove_pud_table (pud, addr, next, direct); -if (free_pud_table (pud, pgd)) - pgd_changed = true; } -if (pgd_changed) -sync_global_pgds (start, end -1 ,1 ); -flush_tlb_all (); }
arch/x86/mm/pageattr.c +7 -30
@@ -746,18 +746,6 @@ static bool try_to_free_pmd_page(pmd_t *pmd)return true; } -static bool try_to_free_pud_page (pud_t *pud) -{ -int i; - -for (i =0 ; i <PTRS_PER_PUD ; i++) -if (!pud_none (pud[i])) -return false; - -free_page ((unsigned long )pud); -return true; -} -static bool unmap_pte_range (pmd_t *pmd,unsigned long start,unsigned long end) {pte_t *pte =pte_offset_kernel (pmd, start);
@@ -871,16 +859,6 @@ static void unmap_pud_range(pgd_t *pgd, unsigned long start, unsigned long end)*/ } -static void unmap_pgd_range (pgd_t *root,unsigned long addr,unsigned long end) -{ -pgd_t *pgd_entry = root +pgd_index (addr); - -unmap_pud_range (pgd_entry, addr, end); - -if (try_to_free_pud_page ((pud_t *)pgd_page_vaddr (*pgd_entry))) -pgd_clear (pgd_entry); -} -static int alloc_pte_page (pmd_t *pmd) {pte_t *pte = (pte_t *)get_zeroed_page (GFP_KERNEL | __GFP_NOTRACK);
@@ -1113,7 +1091,12 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) ret =populate_pud (cpa, addr, pgd_entry, pgprot);if (ret <0 ) { -unmap_pgd_range (cpa->pgd, addr, +/* +* Leave the PUD page in place in case some other CPU or thread +* already found it, but remove any useless entries we just +* added to it. +*/ +unmap_pud_range (pgd_entry, addr, addr + (cpa->numpages <<PAGE_SHIFT ));return ret; }
@@ -1185,7 +1168,7 @@ static int __change_page_attr(struct cpa_data *cpa, int primary)return __cpa_process_fault (cpa, address, primary); old_pte = *kpte; -if (!pte_val (old_pte)) +if (pte_none (old_pte))return __cpa_process_fault (cpa, address, primary);if (level ==PG_LEVEL_4K ) {
@@ -1991,12 +1974,6 @@ int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,return retval; } -void kernel_unmap_pages_in_pgd (pgd_t *root,unsigned long address, -unsigned numpages) -{ -unmap_pgd_range (root, address, address + (numpages <<PAGE_SHIFT )); -} -/* * The testcases use internal knowledge of the implementation that shouldn't * be exposed to the rest of the kernel. Include these directly here.
arch/x86/mm/pat.c +1 -4
@@ -755,11 +755,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)return 1 ;while (cursor < to) { -if (!devmem_is_allowed (pfn)) { -pr_info ("x86/PAT: Program %s tried to access /dev/mem between [mem %#010Lx-%#010Lx], PAT prevents it\n" , - current->comm, from, to -1 ); +if (!devmem_is_allowed (pfn))return 0 ; - } cursor +=PAGE_SIZE ; pfn++; }
arch/x86/mm/pgtable_32.c +1 -1
@@ -47,7 +47,7 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pteval)return ; } pte =pte_offset_kernel (pmd, vaddr); -if (pte_val (pteval)) +if (!pte_none (pteval))set_pte_at (&init_mm, vaddr, pte, pteval);else pte_clear (&init_mm, vaddr, pte);
arch/x86/platform/efi/efi.c +0 -2
@@ -978,8 +978,6 @@ static void __init __efi_enter_virtual_mode(void)* EFI mixed mode we need all of memory to be accessible when * we pass parameters to the EFI runtime services in the * thunking code. -* -* efi_cleanup_page_tables(__pa(new_memmap), 1 << pg_shift); */ free_pages ((unsigned long )new_memmap, pg_shift);
arch/x86/platform/efi/efi_32.c +0 -3
@@ -49,9 +49,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) {return 0 ; } -void __init efi_cleanup_page_tables (unsigned long pa_memmap,unsigned num_pages) -{ -}void __init efi_map_region (efi_memory_desc_t *md) {
arch/x86/platform/efi/efi_64.c +0 -5
@@ -285,11 +285,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)return 0 ; } -void __init efi_cleanup_page_tables (unsigned long pa_memmap,unsigned num_pages) -{ -kernel_unmap_pages_in_pgd (efi_pgd, pa_memmap, num_pages); -} -static void __init __map_region (efi_memory_desc_t *md,u64 va) {unsigned long flags = _PAGE_RW;
arch/x86/xen/enlighten.c +1 -3
@@ -521,9 +521,7 @@ static void set_aliased_prot(void *v, pgprot_t prot)preempt_disable (); -pagefault_disable ();/* Avoid warnings due to being atomic. */ -__get_user (dummy, (unsigned char __user __force *)v); -pagefault_enable (); +probe_kernel_read (&dummy, v,1 );if (HYPERVISOR_update_va_mapping ((unsigned long )v, pte,0 ))BUG ();
drivers/char/mem.c +1 -5
@@ -66,12 +66,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)u64 cursor = from;while (cursor < to) { -if (!devmem_is_allowed (pfn)) { -printk (KERN_INFO -"Program %s tried to access /dev/mem between %Lx->%Lx.\n" , - current->comm, from, to); +if (!devmem_is_allowed (pfn))return 0 ; - } cursor +=PAGE_SIZE ; pfn++; }
drivers/pnp/isapnp/proc.c +1 -1
@@ -21,7 +21,7 @@#include <linux/isapnp.h> #include <linux/proc_fs.h> #include <linux/init.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> extern struct pnp_protocol isapnp_protocol;
fs/read_write.c +18 -0
@@ -1168,6 +1168,15 @@ COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,return do_compat_preadv64 (fd, vec, vlen, pos,0 ); } +#ifdef __ARCH_WANT_COMPAT_SYS_PREADV64V2 +COMPAT_SYSCALL_DEFINE5(preadv64v2, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, loff_t, pos, int, flags) +{ +return do_compat_preadv64 (fd, vec, vlen, pos, flags); +} +#endif + COMPAT_SYSCALL_DEFINE6(preadv2, compat_ulong_t, fd, const struct compat_iovec __user *,vec, compat_ulong_t, vlen, u32, pos_low, u32, pos_high,
@@ -1265,6 +1274,15 @@ COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,return do_compat_pwritev64 (fd, vec, vlen, pos,0 ); } +#ifdef __ARCH_WANT_COMPAT_SYS_PWRITEV64V2 +COMPAT_SYSCALL_DEFINE5(pwritev64v2, unsigned long, fd, + const struct compat_iovec __user *,vec, + unsigned long, vlen, loff_t, pos, int, flags) +{ +return do_compat_pwritev64 (fd, vec, vlen, pos, flags); +} +#endif +COMPAT_SYSCALL_DEFINE6 (pwritev2, compat_ulong_t, fd, const struct compat_iovec __user *,vec, compat_ulong_t, vlen, u32, pos_low, u32, pos_high, int, flags)
include/linux/context_tracking.h +15 -0
@@ -31,6 +31,19 @@ static inline void user_exit(void)context_tracking_exit (CONTEXT_USER ); } +/* Called with interrupts disabled. */ +static inline void user_enter_irqoff (void ) +{ +if (context_tracking_is_enabled ()) +__context_tracking_enter (CONTEXT_USER ); + +} +static inline void user_exit_irqoff (void ) +{ +if (context_tracking_is_enabled ()) +__context_tracking_exit (CONTEXT_USER ); +} +static inline enum ctx_state exception_enter (void ) {enum ctx_state prev_ctx;
@@ -69,6 +82,8 @@ static inline enum ctx_state ct_state(void)#else static inline void user_enter (void ) { }static inline void user_exit (void ) { } +static inline void user_enter_irqoff (void ) { } +static inline void user_exit_irqoff (void ) { }static inline enum ctx_state exception_enter (void ) {return 0 ; }static inline void exception_exit (enum ctx_state prev_ctx) { }static inline enum ctx_state ct_state (void ) {return CONTEXT_DISABLED ; }
include/linux/mm_types.h +3 -0
@@ -594,6 +594,9 @@ struct vm_special_mapping {int (*fault)(const struct vm_special_mapping *sm,struct vm_area_struct *vma,struct vm_fault *vmf); + +int (*mremap)(const struct vm_special_mapping *sm, +struct vm_area_struct *new_vma); };enum tlb_flush_reason {
include/linux/random.h +6 -6
@@ -95,27 +95,27 @@ static inline void prandom_seed_state(struct rnd_state *state, u64 seed)#ifdef CONFIG_ARCH_RANDOM # include <asm/archrandom.h> #else -static inline int arch_get_random_long (unsigned long *v) +static inline bool arch_get_random_long (unsigned long *v) {return 0 ; } -static inline int arch_get_random_int (unsigned int *v) +static inline bool arch_get_random_int (unsigned int *v) {return 0 ; } -static inline int arch_has_random (void ) +static inline bool arch_has_random (void ) {return 0 ; } -static inline int arch_get_random_seed_long (unsigned long *v) +static inline bool arch_get_random_seed_long (unsigned long *v) {return 0 ; } -static inline int arch_get_random_seed_int (unsigned int *v) +static inline bool arch_get_random_seed_int (unsigned int *v) {return 0 ; } -static inline int arch_has_random_seed (void ) +static inline bool arch_has_random_seed (void ) {return 0 ; }
lib/Makefile +0 -5
@@ -15,9 +15,6 @@ KCOV_INSTRUMENT_rbtree.o := n KCOV_INSTRUMENT_list_debug.o := n KCOV_INSTRUMENT_debugobjects.o := n KCOV_INSTRUMENT_dynamic_debug.o := n -# Kernel does not boot if we instrument this file as it uses custom calling -# convention (see CONFIG_ARCH_HWEIGHT_CFLAGS). -KCOV_INSTRUMENT_hweight.o := n lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o timerqueue.o\
@@ -74,8 +71,6 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o -GCOV_PROFILE_hweight.o := n -CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o
lib/bitmap.c +1 -1
@@ -14,9 +14,9 @@#include <linux/bug.h> #include <linux/kernel.h> #include <linux/string.h> +#include <linux/uaccess.h> #include <asm/page.h> -#include <asm/uaccess.h> /* * bitmaps provide an array of bits, implemented using an an
lib/hweight.c +4 -0
@@ -9,6 +9,7 @@* The Hamming Weight of a number is the total number of bits set in it. */ +#ifndef __HAVE_ARCH_SW_HWEIGHTunsigned int __sw_hweight32 (unsigned int w) {#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
@@ -25,6 +26,7 @@ unsigned int __sw_hweight32(unsigned int w) #endif }EXPORT_SYMBOL (__sw_hweight32); +#endif unsigned int __sw_hweight16 (unsigned int w) {
@@ -43,6 +45,7 @@ unsigned int __sw_hweight8(unsigned int w) }EXPORT_SYMBOL (__sw_hweight8); +#ifndef __HAVE_ARCH_SW_HWEIGHTunsigned long __sw_hweight64 (__u64 w) {#if BITS_PER_LONG ==32
@@ -65,3 +68,4 @@ unsigned long __sw_hweight64(__u64 w) #endif }EXPORT_SYMBOL (__sw_hweight64); +#endif
mm/mmap.c +10 -0
@@ -2943,9 +2943,19 @@ static const char *special_mapping_name(struct vm_area_struct *vma)return ((struct vm_special_mapping *)vma->vm_private_data)->name; } +static int special_mapping_mremap (struct vm_area_struct *new_vma) +{ +struct vm_special_mapping *sm = new_vma->vm_private_data; + +if (sm->mremap) +return sm->mremap (sm, new_vma); +return 0 ; +} +static const struct vm_operations_struct special_mapping_vmops = { .close = special_mapping_close, .fault = special_mapping_fault, + .mremap = special_mapping_mremap, .name = special_mapping_name, };
tools/testing/selftests/x86/Makefile +2 -2
@@ -4,8 +4,8 @@ include ../lib.mk .PHONY: all all_32 all_64 warn_32bit_failure clean -TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall \ - check_initial_reg_state sigreturn ldt_gdt iopl +TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \ + check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ vdso_restorer
tools/testing/selftests/x86/mpx-debug.h new file +14 -0
@@ -0,0 +1,14 @@ +#ifndef _MPX_DEBUG_H +#define _MPX_DEBUG_H + +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL 0 +#endif +#define dprintf_level(level, args...) do { if(level <= DEBUG_LEVEL) printf(args); } while(0) +#define dprintf1(args...) dprintf_level(1, args) +#define dprintf2(args...) dprintf_level(2, args) +#define dprintf3(args...) dprintf_level(3, args) +#define dprintf4(args...) dprintf_level(4, args) +#define dprintf5(args...) dprintf_level(5, args) + +#endif /* _MPX_DEBUG_H */
tools/testing/selftests/x86/mpx-dig.c new file +498 -0
498 lines not on this page · raw message
tools/testing/selftests/x86/mpx-hw.h new file +123 -0
123 lines not on this page · raw message
tools/testing/selftests/x86/mpx-mini-test.c new file +1585 -0
79 lines not on this page · raw message
tools/testing/selftests/x86/mpx-mm.h new file +9 -0
Lines of this file are not shown. View the raw message.
tools/testing/selftests/x86/test_mremap_vdso.c new file +111 -0
111 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.