x86: misc prep patches for virtually mapped stacks
Subsystems (10)
Andy Lutomirski
maintainerPATCH 3/11 x86/mm: Remove kernel_unmap_pages_in_pgd() and efi_cleanup_page_tables()
In reply to Andy Lutomirskikernel_unmap_pages_in_pgd() is dangerous: if a pgd entry in init_mm.pgd were to be cleared, callers would need to ensure that the pgd entry hadn't been propagated to any other pgd.
Its only caller was efi_cleanup_page_tables(), and that, in turn, was unused, so just delete both functions. This leaves a couple of other helpers unused, so delete them, too.
--- arch/x86/include/asm/efi.h | 1 - arch/x86/include/asm/pgtable_types.h | 2 -- arch/x86/mm/pageattr.c | 28 ---------------------------- arch/x86/platform/efi/efi.c | 2 -- arch/x86/platform/efi/efi_32.c | 3 --- arch/x86/platform/efi/efi_64.c | 5 ----- 6 files changed, 41 deletions(-)
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/pgtable_types.h +0 -2
@@ -475,8 +475,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/mm/pageattr.c +0 -28
@@ -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);
@@ -1994,12 +1972,6 @@ out: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/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;
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 1/11 x86/mm/hotplug: Don't remove PGD entries in remove_pagetable()
In reply to Andy LutomirskiFrom: Ingo Molnar <[email protected]>
So when memory hotplug removes a piece of physical memory from pagetable mappings, it also frees the underlying PGD entry.
This complicates PGD management, so don't do this. We can keep the PGD mapped and the PUD table all clear - it's only a single 4K page per 512 GB of memory hotplugged.
Message-Id: <[email protected]>
--- arch/x86/mm/init_64.c | 27 --------------------------- 1 file changed, 27 deletions(-)
arch/x86/mm/init_64.c +0 -27
@@ -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 (); }
Signature · 7 lines
2.7.4 -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Andy Lutomirski
maintainercover x86: misc prep patches for virtually mapped stacks
Hi Ingo-
Here are eleven miscellaneous, mostly standalone x86 patches that I pulled from the virtually mapped stack patch set. They're based on 4.7-rc6, and I imagine they apply cleanly on most or all -tip branches.
Once these land, I'll see if the THREAD_INFO_IN_TASK stuff splits out cleanly as well. That code certainly needs a couple of these patches, but I think it might get stuck behind "signal: Consolidate {TS,TLF}_RESTORE_SIGMASK code", and I asked akpm to queue that one for -mm.
Andy Lutomirski (10):
x86/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: Move uaccess_err and sig_on_uaccess_err to thread_struct
x86: Move addr_limit to thread_struct
x86/smp: Remove stack_smp_processor_id()
x86/smp: Remove unnecessary initialization of thread_info::cpu
Ingo Molnar (1):
x86/mm/hotplug: Don't remove PGD entries in remove_pagetable()
arch/x86/entry/entry_32.S | 11 +++++++++++ arch/x86/entry/entry_64.S | 11 +++++++++++ arch/x86/entry/vsyscall/vsyscall_64.c | 6 +++--- arch/x86/include/asm/checksum_32.h | 3 +-- arch/x86/include/asm/cpu.h | 1 - arch/x86/include/asm/efi.h | 1 - arch/x86/include/asm/pgtable_types.h | 2 -- arch/x86/include/asm/processor.h | 20 ++++++++++++------- arch/x86/include/asm/smp.h | 6 ------ arch/x86/include/asm/thread_info.h | 9 --------- arch/x86/include/asm/uaccess.h | 10 +++++----- arch/x86/kernel/asm-offsets.c | 4 +++- arch/x86/kernel/cpu/common.c | 2 +- arch/x86/kernel/dumpstack.c | 20 +++++++++++++++++-- arch/x86/kernel/dumpstack_64.c | 12 ++++++++++-- arch/x86/kernel/smpboot.c | 1 - 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/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 | 27 ------------------------- arch/x86/mm/pageattr.c | 37 ++++++----------------------------- arch/x86/platform/efi/efi.c | 2 -- arch/x86/platform/efi/efi_32.c | 3 --- arch/x86/platform/efi/efi_64.c | 5 ----- drivers/pnp/isapnp/proc.c | 2 +- lib/bitmap.c | 2 +- 30 files changed, 108 insertions(+), 136 deletions(-)
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 5/11 x86/dumpstack/64: Handle faults when printing the "Stack:" part of an OOPS
If we overflow the stack into a guard page, we'll recursively fault when trying to dump the contents of the guard page. Use probe_kernel_address so we can recover if this happens.
--- arch/x86/kernel/dumpstack_64.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
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 ();
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 6/11 x86/mm/64: In vmalloc_fault(), use CR3 instead of current->active_mm
In reply to Andy LutomirskiIf we get a vmalloc fault while current->active_mm->pgd doesn't match CR3, we'll crash without this change. I've seen this failure mode on heavily instrumented kernels with virtually mapped stacks.
--- arch/x86/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/mm/fault.c +1 -1
@@ -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 ;
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 8/11 x86: Move uaccess_err and sig_on_uaccess_err to thread_struct
In reply to Andy Lutomirskithread_info is a legacy mess. To prepare for its partial removal, move the uaccess control fields out -- they're straightforward.
--- arch/x86/entry/vsyscall/vsyscall_64.c | 6 +++--- arch/x86/include/asm/processor.h | 3 +++ arch/x86/include/asm/thread_info.h | 2 -- arch/x86/include/asm/uaccess.h | 4 ++-- arch/x86/mm/extable.c | 2 +- arch/x86/mm/fault.c | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-)
arch/x86/entry/vsyscall/vsyscall_64.c +3 -3
@@ -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_error = current->thread.sig_on_uaccess_error; + current->thread.sig_on_uaccess_error =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_error = prev_sig_on_uaccess_error; check_fault:if (ret == -EFAULT ) {
arch/x86/include/asm/processor.h +3 -0
@@ -419,6 +419,9 @@ struct thread_struct {/* Max allowed port in the bitmap, in bytes: */ unsigned io_bitmap_max; + unsigned int sig_on_uaccess_error:1; + unsigned int uaccess_err:1; /* uaccess failed */ +/* Floating point and extended processor state */ struct fpu fpu;/*
arch/x86/include/asm/thread_info.h +0 -2
@@ -58,8 +58,6 @@ struct thread_info {__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) \
arch/x86/include/asm/uaccess.h +2 -2
@@ -468,13 +468,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/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 +1 -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_error && signal) { tsk->thread.trap_nr =X86_TRAP_PF ; tsk->thread.error_code = error_code |PF_USER ; tsk->thread.cr2 = address;
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 9/11 x86: Move addr_limit to thread_struct
In reply to Andy Lutomirskithread_info is a legacy mess. To prepare for its partial removal, move addr_limit out.
As an added benefit, this way is simpler.
--- arch/x86/include/asm/checksum_32.h | 3 +-- arch/x86/include/asm/processor.h | 17 ++++++++++------- arch/x86/include/asm/thread_info.h | 7 ------- arch/x86/include/asm/uaccess.h | 6 +++--- arch/x86/kernel/asm-offsets.c | 4 +++- 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/putuser.S | 10 +++++----- arch/x86/lib/usercopy_64.c | 2 +- drivers/pnp/isapnp/proc.c | 2 +- lib/bitmap.c | 2 +- 12 files changed, 40 insertions(+), 42 deletions(-)
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/processor.h +10 -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,8 @@ 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_error:1; unsigned int uaccess_err:1; /* uaccess failed */
@@ -493,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 *);
@@ -719,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);
@@ -768,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/thread_info.h +0 -7
@@ -57,7 +57,6 @@ struct thread_info {__u32 flags;/* low level flags */ __u32 status;/* thread synchronous flags */ __u32 cpu;/* current CPU */ -mm_segment_t addr_limit; };#define INIT_THREAD_INFO (tsk) \
@@ -65,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)
@@ -184,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 +3 -3
@@ -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())
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/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/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
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;
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
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 11/11 x86/smp: Remove unnecessary initialization of thread_info::cpu
In reply to Andy LutomirskiIt's statically initialized to zero -- no need to dynamically initialize it to zero as well.
--- arch/x86/kernel/smpboot.c | 1 - 1 file changed, 1 deletion(-)
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 );
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 10/11 x86/smp: Remove stack_smp_processor_id()
In reply to Andy LutomirskiIt serves no purpose -- raw_smp_processor_id() works fine. This change will be needed to move thread_info off the stack.
--- arch/x86/include/asm/cpu.h | 1 - arch/x86/include/asm/smp.h | 6 ------ arch/x86/kernel/cpu/common.c | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-)
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/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/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);
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 7/11 x86/dumpstack: When OOPSing, rewind the stack before do_exit()
In reply to Andy LutomirskiIf we call do_exit() with a clean stack, we greatly reduce the risk of recursive oopses due to stack overflow in do_exit, and we allow do_exit to work even if we OOPS from an IST stack. The latter gives us a much better chance of surviving long enough after we detect a stack overflow to write out our logs.
--- arch/x86/entry/entry_32.S | 11 +++++++++++ arch/x86/entry/entry_64.S | 11 +++++++++++ arch/x86/kernel/dumpstack.c | 10 +++++++++- 3 files changed, 31 insertions(+), 1 deletion(-)
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/kernel/dumpstack.c +9 -1
@@ -234,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))
@@ -255,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);
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 4/11 x86/dumpstack: Try harder to get a call trace on stack overflow
In reply to Andy LutomirskiIf we overflow the stack, print_context_stack will abort. Detect this case and rewind back into the valid part of the stack so that we can trace it.
--- arch/x86/kernel/dumpstack.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
arch/x86/kernel/dumpstack.c +9 -1
@@ -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;
Signature · 1 line
2.7.4
Andy Lutomirski
maintainerPATCH 2/11 x86/cpa: In populate_pgd, don't set the pgd entry until it's populated
In reply to Andy LutomirskiThis avoids pointless races in which another CPU or task might see a partially populated global pgd entry. These races should normally be harmless, but, if another CPU propagates the entry via vmalloc_fault and then populate_pgd fails (due to memory allocation failure, for example), this prevents a use-after-free of the pgd entry.
--- arch/x86/mm/pageattr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/x86/mm/pageattr.c +6 -3
@@ -1104,8 +1104,6 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) pud = (pud_t *)get_zeroed_page (GFP_KERNEL | __GFP_NOTRACK);if (!pud)return -1 ; - -set_pgd (pgd_entry,__pgd (__pa (pud) | _KERNPG_TABLE)); }pgprot_val (pgprot) &= ~pgprot_val (cpa->mask_clr);
@@ -1113,11 +1111,16 @@ 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, +if (pud) +free_page ((unsigned long )pud); +unmap_pud_range (pgd_entry, addr, addr + (cpa->numpages <<PAGE_SHIFT ));return ret; } +if (pud) +set_pgd (pgd_entry,__pgd (__pa (pud) | _KERNPG_TABLE)); + cpa->numpages = ret;return 0 ; }
Signature · 1 line
2.7.4
Re: [PATCH 08/11] x86: Move uaccess_err and sig_on_uaccess_err to thread_struct
In reply to Andy LutomirskiQuoted 42 lines · Andy Lutomirski
thread_infois a legacy mess. To prepare for its partial removal, move the uaccess control fields out -- they're straightforward.Signed-off-by Andy Lutomirski <[email protected]>--- arch/x86/entry/vsyscall/vsyscall_64.c | 6 +++--- arch/x86/include/asm/processor.h | 3 +++ arch/x86/include/asm/thread_info.h | 2 -- arch/x86/include/asm/uaccess.h | 4 ++-- arch/x86/mm/extable.c | 2 +- arch/x86/mm/fault.c | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-)arch/x86/entry/vsyscall/vsyscall_64.c +3
-3@@ -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_error = current->thread.sig_on_uaccess_error; + current->thread.sig_on_uaccess_error =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_error = prev_sig_on_uaccess_error; check_fault:if (ret == -EFAULT ) {arch/x86/include/asm/processor.h +0
-0
arch/x86/include/asm/processor.h struct thread_struct { · line 423
Quoted 5 lines
arch/x86/include/asm/processor.h +2
-0@@ -419,6 +419,9 @@ struct thread_struct {/* Max allowed port in the bitmap, in bytes: */ unsigned io_bitmap_max; + unsigned int sig_on_uaccess_error:1; + unsigned int uaccess_err:1; /* uaccess failed */
Btw., while at it I've renamed 'sig_on_uaccess_error' to 'sig_on_uaccess_err' to make the two names consistent.
Thanks,
Ingo
tip-bot for Ingo Molnar
merge bot[tip:x86/mm] x86/mm/hotplug: Don't remove PGD entries in remove_pagetable()
In reply to Andy Lutomirskix86/mm/hotplug: Don't remove PGD entries in remove_pagetable()
Commit-ID: af2cf278ef4f9289f88504c3e03cb12f76027575 Gitweb: http://git.kernel.org/tip/af2cf278ef4f9289f88504c3e03cb12f76027575 Author: Ingo Molnar <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:49 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:24 +0200
x86/mm/hotplug: Don't remove PGD entries in remove_pagetable()
So when memory hotplug removes a piece of physical memory from pagetable mappings, it also frees the underlying PGD entry.
This complicates PGD management, so don't do this. We can keep the PGD mapped and the PUD table all clear - it's only a single 4K page per 512 GB of memory hotplugged.
--- arch/x86/mm/init_64.c | 27 --------------------------- 1 file changed, 27 deletions(-)
arch/x86/mm/init_64.c +0 -27
@@ -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_none (*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 (); }
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/mm/cpa: In populate_pgd(), don't set the PGD entry until it's populated
In reply to Andy Lutomirskix86/mm/cpa: In populate_pgd(), don't set the PGD entry until it's populated
Commit-ID: 360cb4d15567a7eca07a5f3ade6de308bbfb4e70 Gitweb: http://git.kernel.org/tip/360cb4d15567a7eca07a5f3ade6de308bbfb4e70 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:50 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:25 +0200
x86/mm/cpa: In populate_pgd(), don't set the PGD entry until it's populated
This avoids pointless races in which another CPU or task might see a partially populated global PGD entry. These races should normally be harmless, but, if another CPU propagates the entry via vmalloc_fault() and then populate_pgd() fails (due to memory allocation failure, for example), this prevents a use-after-free of the PGD entry.
--- arch/x86/mm/pageattr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
arch/x86/mm/pageattr.c +6 -3
@@ -1104,8 +1104,6 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr) pud = (pud_t *)get_zeroed_page (GFP_KERNEL | __GFP_NOTRACK);if (!pud)return -1 ; - -set_pgd (pgd_entry,__pgd (__pa (pud) | _KERNPG_TABLE)); }pgprot_val (pgprot) &= ~pgprot_val (cpa->mask_clr);
@@ -1113,11 +1111,16 @@ 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, +if (pud) +free_page ((unsigned long )pud); +unmap_pud_range (pgd_entry, addr, addr + (cpa->numpages <<PAGE_SHIFT ));return ret; } +if (pud) +set_pgd (pgd_entry,__pgd (__pa (pud) | _KERNPG_TABLE)); + cpa->numpages = ret;return 0 ; }
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/mm: Remove kernel_unmap_pages_in_pgd() and efi_cleanup_page_tables()
In reply to Andy Lutomirskix86/mm: Remove kernel_unmap_pages_in_pgd() and efi_cleanup_page_tables()
Commit-ID: d92fc69ccac4c0a20679fdbdc81b2010685a6f33 Gitweb: http://git.kernel.org/tip/d92fc69ccac4c0a20679fdbdc81b2010685a6f33 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:51 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:26 +0200
x86/mm: Remove kernel_unmap_pages_in_pgd() and efi_cleanup_page_tables()
kernel_unmap_pages_in_pgd() is dangerous: if a PGD entry in init_mm.pgd were to be cleared, callers would need to ensure that the pgd entry hadn't been propagated to any other pgd.
Its only caller was efi_cleanup_page_tables(), and that, in turn, was unused, so just delete both functions. This leaves a couple of other helpers unused, so delete them, too.
--- arch/x86/include/asm/efi.h | 1 - arch/x86/include/asm/pgtable_types.h | 2 -- arch/x86/mm/pageattr.c | 28 ---------------------------- arch/x86/platform/efi/efi.c | 2 -- arch/x86/platform/efi/efi_32.c | 3 --- arch/x86/platform/efi/efi_64.c | 5 ----- 6 files changed, 41 deletions(-)
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/pgtable_types.h +0 -2
@@ -481,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/mm/pageattr.c +0 -28
@@ -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);
@@ -1994,12 +1972,6 @@ out: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/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;
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/dumpstack: Try harder to get a call trace on stack overflow
In reply to Andy Lutomirskix86/dumpstack: Try harder to get a call trace on stack overflow
Commit-ID: 9a2e9da3e003112399f2863b7b6b911043c01895 Gitweb: http://git.kernel.org/tip/9a2e9da3e003112399f2863b7b6b911043c01895 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:52 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:26 +0200
x86/dumpstack: Try harder to get a call trace on stack overflow
If we overflow the stack, print_context_stack() will abort. Detect this case and rewind back into the valid part of the stack so that we can trace it.
--- arch/x86/kernel/dumpstack.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
arch/x86/kernel/dumpstack.c +9 -1
@@ -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;
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/dumpstack/64: Handle faults when printing the "Stack: " part of an OOPS
In reply to Andy Lutomirskix86/dumpstack/64: Handle faults when printing the "Stack: " part of an OOPS
Commit-ID: 98f30b1207932b6553ea605c99393d8afca12324 Gitweb: http://git.kernel.org/tip/98f30b1207932b6553ea605c99393d8afca12324 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:53 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:27 +0200
x86/dumpstack/64: Handle faults when printing the "Stack: " part of an OOPS
If we overflow the stack into a guard page, we'll recursively fault when trying to dump the contents of the guard page. Use probe_kernel_address() so we can recover if this happens.
--- arch/x86/kernel/dumpstack_64.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
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 ();
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/mm/64: In vmalloc_fault(), use CR3 instead of current->active_mm
In reply to Andy Lutomirskix86/mm/64: In vmalloc_fault(), use CR3 instead of current->active_mm
Commit-ID: 46aea3873401836abb7f01200e7946e7d518b359 Gitweb: http://git.kernel.org/tip/46aea3873401836abb7f01200e7946e7d518b359 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:54 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:27 +0200
x86/mm/64: In vmalloc_fault(), use CR3 instead of current->active_mm
If we get a vmalloc fault while current->active_mm->pgd doesn't match CR3, we'll crash without this change. I've seen this failure mode on heavily instrumented kernels with virtually mapped stacks.
--- arch/x86/mm/fault.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/mm/fault.c +1 -1
@@ -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 ;
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/dumpstack: When OOPSing, rewind the stack before do_exit()
In reply to Andy Lutomirskix86/dumpstack: When OOPSing, rewind the stack before do_exit()
Commit-ID: 2deb4be28077638591fe5fc593b7f8aabc140f42 Gitweb: http://git.kernel.org/tip/2deb4be28077638591fe5fc593b7f8aabc140f42 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:55 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:28 +0200
x86/dumpstack: When OOPSing, rewind the stack before do_exit()
If we call do_exit() with a clean stack, we greatly reduce the risk of recursive oopses due to stack overflow in do_exit, and we allow do_exit to work even if we OOPS from an IST stack. The latter gives us a much better chance of surviving long enough after we detect a stack overflow to write out our logs.
--- arch/x86/entry/entry_32.S | 11 +++++++++++ arch/x86/entry/entry_64.S | 11 +++++++++++ arch/x86/kernel/dumpstack.c | 10 +++++++++- 3 files changed, 31 insertions(+), 1 deletion(-)
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/kernel/dumpstack.c +9 -1
@@ -234,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))
@@ -255,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);
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/uaccess: Move thread_info::uaccess_err and thread_info::sig_on_uaccess_err to thread_struct
In reply to Andy Lutomirskix86/uaccess: Move thread_info::uaccess_err and thread_info::sig_on_uaccess_err to thread_struct
Commit-ID: dfa9a942fd7951c8f333cf3f377dde51ebd21685 Gitweb: http://git.kernel.org/tip/dfa9a942fd7951c8f333cf3f377dde51ebd21685 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:56 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:28 +0200
x86/uaccess: Move thread_info::uaccess_err and thread_info::sig_on_uaccess_err to thread_struct
struct thread_info is a legacy mess. To prepare for its partial removal, move the uaccess control fields out -- they're straightforward.
--- arch/x86/entry/vsyscall/vsyscall_64.c | 6 +++--- arch/x86/include/asm/processor.h | 3 +++ arch/x86/include/asm/thread_info.h | 2 -- arch/x86/include/asm/uaccess.h | 4 ++-- arch/x86/mm/extable.c | 2 +- arch/x86/mm/fault.c | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-)
arch/x86/entry/vsyscall/vsyscall_64.c +3 -3
@@ -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_error = current->thread.sig_on_uaccess_error; + current->thread.sig_on_uaccess_error =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_error = prev_sig_on_uaccess_error; check_fault:if (ret == -EFAULT ) {
arch/x86/include/asm/processor.h +3 -0
@@ -419,6 +419,9 @@ struct thread_struct {/* Max allowed port in the bitmap, in bytes: */ unsigned io_bitmap_max; + unsigned int sig_on_uaccess_error:1; + unsigned int uaccess_err:1; /* uaccess failed */ +/* Floating point and extended processor state */ struct fpu fpu;/*
arch/x86/include/asm/thread_info.h +0 -2
@@ -58,8 +58,6 @@ struct thread_info {__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) \
arch/x86/include/asm/uaccess.h +2 -2
@@ -487,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/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 +1 -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_error && signal) { tsk->thread.trap_nr =X86_TRAP_PF ; tsk->thread.error_code = error_code |PF_USER ; tsk->thread.cr2 = address;
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/uaccess: Move thread_info::addr_limit to thread_struct
In reply to Andy Lutomirskix86/uaccess: Move thread_info::addr_limit to thread_struct
Commit-ID: 13d4ea097d18b419ad2a2b696063d44bf59acec0 Gitweb: http://git.kernel.org/tip/13d4ea097d18b419ad2a2b696063d44bf59acec0 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:57 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:30 +0200
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.
--- arch/x86/include/asm/checksum_32.h | 3 +-- arch/x86/include/asm/processor.h | 17 ++++++++++------- arch/x86/include/asm/thread_info.h | 7 ------- arch/x86/include/asm/uaccess.h | 6 +++--- arch/x86/kernel/asm-offsets.c | 4 +++- 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/putuser.S | 10 +++++----- arch/x86/lib/usercopy_64.c | 2 +- drivers/pnp/isapnp/proc.c | 2 +- lib/bitmap.c | 2 +- 12 files changed, 40 insertions(+), 42 deletions(-)
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/processor.h +10 -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,8 @@ 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 */
@@ -493,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 *);
@@ -719,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);
@@ -768,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/thread_info.h +0 -7
@@ -57,7 +57,6 @@ struct thread_info {__u32 flags;/* low level flags */ __u32 status;/* thread synchronous flags */ __u32 cpu;/* current CPU */ -mm_segment_t addr_limit; };#define INIT_THREAD_INFO (tsk) \
@@ -65,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)
@@ -184,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 +3 -3
@@ -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())
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/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/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
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;
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
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/smp: Remove stack_smp_processor_id()
In reply to Andy Lutomirskix86/smp: Remove stack_smp_processor_id()
Commit-ID: fb59831b496a5bb7d0a06c7e702d88d1757edfca Gitweb: http://git.kernel.org/tip/fb59831b496a5bb7d0a06c7e702d88d1757edfca Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:58 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:30 +0200
x86/smp: Remove stack_smp_processor_id()
It serves no purpose -- raw_smp_processor_id() works fine. This change will be needed to move thread_info off the stack.
--- arch/x86/include/asm/cpu.h | 1 - arch/x86/include/asm/smp.h | 6 ------ arch/x86/kernel/cpu/common.c | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-)
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/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/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);
tip-bot for Andy Lutomirski
merge bot[tip:x86/mm] x86/smp: Remove unnecessary initialization of thread_info::cpu
In reply to Andy Lutomirskix86/smp: Remove unnecessary initialization of thread_info::cpu
Commit-ID: eb43e8f85fffc1ba535e0362a872101dfe48abe3 Gitweb: http://git.kernel.org/tip/eb43e8f85fffc1ba535e0362a872101dfe48abe3 Author: Andy Lutomirski <[email protected]> AuthorDate: Thu, 14 Jul 2016 13:22:59 -0700 Committer: Ingo Molnar <[email protected]> CommitDate: Fri, 15 Jul 2016 10:26:31 +0200
x86/smp: Remove unnecessary initialization of thread_info::cpu
It's statically initialized to zero -- no need to dynamically initialize it to zero as well.
--- arch/x86/kernel/smpboot.c | 1 - 1 file changed, 1 deletion(-)
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 );