Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/uaccess: Move thread_info::addr_limit to thread_struct

struct thread_info is a legacy mess. To prepare for its partial removal,
move thread_info::addr_limit out.

As an added benefit, this way is simpler.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/15bee834d09402b47ac86f2feccdf6529f9bc5b0.1468527351.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Andy Lutomirski and committed by
Ingo Molnar
13d4ea09 2a53ccbc

+40 -42
+1 -2
arch/x86/include/asm/checksum_32.h
··· 2 2 #define _ASM_X86_CHECKSUM_32_H 3 3 4 4 #include <linux/in6.h> 5 - 6 - #include <asm/uaccess.h> 5 + #include <linux/uaccess.h> 7 6 8 7 /* 9 8 * computes the checksum of a memory block at buff, length len,
+10 -7
arch/x86/include/asm/processor.h
··· 371 371 372 372 struct perf_event; 373 373 374 + typedef struct { 375 + unsigned long seg; 376 + } mm_segment_t; 377 + 374 378 struct thread_struct { 375 379 /* Cached TLS descriptors: */ 376 380 struct desc_struct tls_array[GDT_ENTRY_TLS_ENTRIES]; ··· 422 418 unsigned long iopl; 423 419 /* Max allowed port in the bitmap, in bytes: */ 424 420 unsigned io_bitmap_max; 421 + 422 + mm_segment_t addr_limit; 425 423 426 424 unsigned int sig_on_uaccess_err:1; 427 425 unsigned int uaccess_err:1; /* uaccess failed */ ··· 498 492 499 493 #define set_iopl_mask native_set_iopl_mask 500 494 #endif /* CONFIG_PARAVIRT */ 501 - 502 - typedef struct { 503 - unsigned long seg; 504 - } mm_segment_t; 505 - 506 495 507 496 /* Free all resources held by a thread. */ 508 497 extern void release_thread(struct task_struct *); ··· 720 719 .sp0 = TOP_OF_INIT_STACK, \ 721 720 .sysenter_cs = __KERNEL_CS, \ 722 721 .io_bitmap_ptr = NULL, \ 722 + .addr_limit = KERNEL_DS, \ 723 723 } 724 724 725 725 extern unsigned long thread_saved_pc(struct task_struct *tsk); ··· 770 768 #define STACK_TOP TASK_SIZE 771 769 #define STACK_TOP_MAX TASK_SIZE_MAX 772 770 773 - #define INIT_THREAD { \ 774 - .sp0 = TOP_OF_INIT_STACK \ 771 + #define INIT_THREAD { \ 772 + .sp0 = TOP_OF_INIT_STACK, \ 773 + .addr_limit = KERNEL_DS, \ 775 774 } 776 775 777 776 /*
-7
arch/x86/include/asm/thread_info.h
··· 57 57 __u32 flags; /* low level flags */ 58 58 __u32 status; /* thread synchronous flags */ 59 59 __u32 cpu; /* current CPU */ 60 - mm_segment_t addr_limit; 61 60 }; 62 61 63 62 #define INIT_THREAD_INFO(tsk) \ ··· 64 65 .task = &tsk, \ 65 66 .flags = 0, \ 66 67 .cpu = 0, \ 67 - .addr_limit = KERNEL_DS, \ 68 68 } 69 69 70 70 #define init_thread_info (init_thread_union.thread_info) ··· 181 183 #ifdef CONFIG_X86_64 182 184 # define cpu_current_top_of_stack (cpu_tss + TSS_sp0) 183 185 #endif 184 - 185 - /* Load thread_info address into "reg" */ 186 - #define GET_THREAD_INFO(reg) \ 187 - _ASM_MOV PER_CPU_VAR(cpu_current_top_of_stack),reg ; \ 188 - _ASM_SUB $(THREAD_SIZE),reg ; 189 186 190 187 /* 191 188 * ASM operand which evaluates to a 'thread_info' address of
+3 -3
arch/x86/include/asm/uaccess.h
··· 29 29 #define USER_DS MAKE_MM_SEG(TASK_SIZE_MAX) 30 30 31 31 #define get_ds() (KERNEL_DS) 32 - #define get_fs() (current_thread_info()->addr_limit) 33 - #define set_fs(x) (current_thread_info()->addr_limit = (x)) 32 + #define get_fs() (current->thread.addr_limit) 33 + #define set_fs(x) (current->thread.addr_limit = (x)) 34 34 35 35 #define segment_eq(a, b) ((a).seg == (b).seg) 36 36 37 - #define user_addr_max() (current_thread_info()->addr_limit.seg) 37 + #define user_addr_max() (current->thread.addr_limit.seg) 38 38 #define __addr_ok(addr) \ 39 39 ((unsigned long __force)(addr) < user_addr_max()) 40 40
+3 -1
arch/x86/kernel/asm-offsets.c
··· 31 31 BLANK(); 32 32 OFFSET(TI_flags, thread_info, flags); 33 33 OFFSET(TI_status, thread_info, status); 34 - OFFSET(TI_addr_limit, thread_info, addr_limit); 34 + 35 + BLANK(); 36 + OFFSET(TASK_addr_limit, task_struct, thread.addr_limit); 35 37 36 38 BLANK(); 37 39 OFFSET(crypto_tfm_ctx_offset, crypto_tfm, __crt_ctx);
+4 -4
arch/x86/lib/copy_user_64.S
··· 17 17 18 18 /* Standard copy_to_user with segment limit checking */ 19 19 ENTRY(_copy_to_user) 20 - GET_THREAD_INFO(%rax) 20 + mov PER_CPU_VAR(current_task), %rax 21 21 movq %rdi,%rcx 22 22 addq %rdx,%rcx 23 23 jc bad_to_user 24 - cmpq TI_addr_limit(%rax),%rcx 24 + cmpq TASK_addr_limit(%rax),%rcx 25 25 ja bad_to_user 26 26 ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \ 27 27 "jmp copy_user_generic_string", \ ··· 32 32 33 33 /* Standard copy_from_user with segment limit checking */ 34 34 ENTRY(_copy_from_user) 35 - GET_THREAD_INFO(%rax) 35 + mov PER_CPU_VAR(current_task), %rax 36 36 movq %rsi,%rcx 37 37 addq %rdx,%rcx 38 38 jc bad_from_user 39 - cmpq TI_addr_limit(%rax),%rcx 39 + cmpq TASK_addr_limit(%rax),%rcx 40 40 ja bad_from_user 41 41 ALTERNATIVE_2 "jmp copy_user_generic_unrolled", \ 42 42 "jmp copy_user_generic_string", \
+1
arch/x86/lib/csum-wrappers_64.c
··· 6 6 */ 7 7 #include <asm/checksum.h> 8 8 #include <linux/module.h> 9 + #include <linux/uaccess.h> 9 10 #include <asm/smap.h> 10 11 11 12 /**
+10 -10
arch/x86/lib/getuser.S
··· 35 35 36 36 .text 37 37 ENTRY(__get_user_1) 38 - GET_THREAD_INFO(%_ASM_DX) 39 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 38 + mov PER_CPU_VAR(current_task), %_ASM_DX 39 + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX 40 40 jae bad_get_user 41 41 ASM_STAC 42 42 1: movzbl (%_ASM_AX),%edx ··· 48 48 ENTRY(__get_user_2) 49 49 add $1,%_ASM_AX 50 50 jc bad_get_user 51 - GET_THREAD_INFO(%_ASM_DX) 52 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 51 + mov PER_CPU_VAR(current_task), %_ASM_DX 52 + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX 53 53 jae bad_get_user 54 54 ASM_STAC 55 55 2: movzwl -1(%_ASM_AX),%edx ··· 61 61 ENTRY(__get_user_4) 62 62 add $3,%_ASM_AX 63 63 jc bad_get_user 64 - GET_THREAD_INFO(%_ASM_DX) 65 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 64 + mov PER_CPU_VAR(current_task), %_ASM_DX 65 + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX 66 66 jae bad_get_user 67 67 ASM_STAC 68 68 3: movl -3(%_ASM_AX),%edx ··· 75 75 #ifdef CONFIG_X86_64 76 76 add $7,%_ASM_AX 77 77 jc bad_get_user 78 - GET_THREAD_INFO(%_ASM_DX) 79 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 78 + mov PER_CPU_VAR(current_task), %_ASM_DX 79 + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX 80 80 jae bad_get_user 81 81 ASM_STAC 82 82 4: movq -7(%_ASM_AX),%rdx ··· 86 86 #else 87 87 add $7,%_ASM_AX 88 88 jc bad_get_user_8 89 - GET_THREAD_INFO(%_ASM_DX) 90 - cmp TI_addr_limit(%_ASM_DX),%_ASM_AX 89 + mov PER_CPU_VAR(current_task), %_ASM_DX 90 + cmp TASK_addr_limit(%_ASM_DX),%_ASM_AX 91 91 jae bad_get_user_8 92 92 ASM_STAC 93 93 4: movl -7(%_ASM_AX),%edx
+5 -5
arch/x86/lib/putuser.S
··· 29 29 * as they get called from within inline assembly. 30 30 */ 31 31 32 - #define ENTER GET_THREAD_INFO(%_ASM_BX) 32 + #define ENTER mov PER_CPU_VAR(current_task), %_ASM_BX 33 33 #define EXIT ASM_CLAC ; \ 34 34 ret 35 35 36 36 .text 37 37 ENTRY(__put_user_1) 38 38 ENTER 39 - cmp TI_addr_limit(%_ASM_BX),%_ASM_CX 39 + cmp TASK_addr_limit(%_ASM_BX),%_ASM_CX 40 40 jae bad_put_user 41 41 ASM_STAC 42 42 1: movb %al,(%_ASM_CX) ··· 46 46 47 47 ENTRY(__put_user_2) 48 48 ENTER 49 - mov TI_addr_limit(%_ASM_BX),%_ASM_BX 49 + mov TASK_addr_limit(%_ASM_BX),%_ASM_BX 50 50 sub $1,%_ASM_BX 51 51 cmp %_ASM_BX,%_ASM_CX 52 52 jae bad_put_user ··· 58 58 59 59 ENTRY(__put_user_4) 60 60 ENTER 61 - mov TI_addr_limit(%_ASM_BX),%_ASM_BX 61 + mov TASK_addr_limit(%_ASM_BX),%_ASM_BX 62 62 sub $3,%_ASM_BX 63 63 cmp %_ASM_BX,%_ASM_CX 64 64 jae bad_put_user ··· 70 70 71 71 ENTRY(__put_user_8) 72 72 ENTER 73 - mov TI_addr_limit(%_ASM_BX),%_ASM_BX 73 + mov TASK_addr_limit(%_ASM_BX),%_ASM_BX 74 74 sub $7,%_ASM_BX 75 75 cmp %_ASM_BX,%_ASM_CX 76 76 jae bad_put_user
+1 -1
arch/x86/lib/usercopy_64.c
··· 6 6 * Copyright 2002 Andi Kleen <ak@suse.de> 7 7 */ 8 8 #include <linux/module.h> 9 - #include <asm/uaccess.h> 9 + #include <linux/uaccess.h> 10 10 11 11 /* 12 12 * Zero Userspace
+1 -1
drivers/pnp/isapnp/proc.c
··· 21 21 #include <linux/isapnp.h> 22 22 #include <linux/proc_fs.h> 23 23 #include <linux/init.h> 24 - #include <asm/uaccess.h> 24 + #include <linux/uaccess.h> 25 25 26 26 extern struct pnp_protocol isapnp_protocol; 27 27
+1 -1
lib/bitmap.c
··· 14 14 #include <linux/bug.h> 15 15 #include <linux/kernel.h> 16 16 #include <linux/string.h> 17 + #include <linux/uaccess.h> 17 18 18 19 #include <asm/page.h> 19 - #include <asm/uaccess.h> 20 20 21 21 /* 22 22 * bitmaps provide an array of bits, implemented using an an