x86/asm changes for v4.9
Subsystems (35)
Linus,
Please pull the latest x86-asm-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-asm-for-linus
# HEAD: 1ef55be16ed69538f89e0a6508be5e62fdc9851c x86/asm: Get rid of __read_cr4_safe()
In this cycle this topic tree has become one of those 'super topics' that accumulated a lot of changes:
- Add CONFIG_VMAP_STACK=y support to the core kernel and enable it on x86 - preceded by an array of changes. v4.8 saw preparatory changes in this area already - this is the rest of the work. Includes the thread stack caching performance optimization. (Andy Lutomirski)
- switch_to() cleanups and all around enhancements. (Brian Gerst)
- A large number of dumpstack infrastructure enhancements and an unwinder abstraction. The secret long term plan is safe(r) live patching plus maybe another attempt at debuginfo based unwinding - but all these current bits are standalone enhancements in a frame pointer based debug environment as well. (Josh Poimboeuf)
- More __ro_after_init and const annotations. (Kees Cook)
- Enable KASLR for the vmemmap memory region. (Thomas Garnier)
Thanks,
Ingo
------------------>
Andy Lutomirski (18):
fork: Add generic vmalloced stack support
dma-api: Teach the "DMA-from-stack" check about vmapped stacks
x86/mm/64: Enable vmapped stacks (CONFIG_HAVE_ARCH_VMAP_STACK=y)
x86/mm: Improve stack-overflow #PF handling
virtio_console: Stop doing DMA on the stack
selftests/x86/sigreturn: Use CX, not AX, as the scratch register x86/entry/64: Clean up and document espfix64 stack setup
x86/asm: Move the thread_info::status field to thread_struct
sched/core: Allow putting thread_info into task_struct
x86: Move thread_info into task_struct
x86/entry/64: Fix a minor comment rebase error
sched/core: Add try_get_task_stack() and put_task_stack()
x86/dumpstack: Pin the target stack when dumping it
x86/process: Pin the target stack in get_wchan()
lib/syscall: Pin the task stack in collect_syscall()
sched/core: Free the stack early if CONFIG_THREAD_INFO_IN_TASK
fork: Optimize task creation by caching two thread stacks per CPU if CONFIG_VMAP_STACK=y x86/asm: Get rid of __read_cr4_safe()
Borislav Petkov (2):
x86/entry: Remove duplicated comment x86/entry: Remove outdated comment about SYSCALL targets
Brian Gerst (7):
sched/x86/32, kgdb: Don't use thread.ip in sleeping_thread_to_gdb_regs() sched/x86/64, kgdb: Clear GDB_PS on 64-bit
sched/x86: Add 'struct inactive_task_frame' to better document the sleeping task stack frame sched/x86: Rewrite the switch_to() code
sched/x86: Pass kernel thread parameters in 'struct fork_frame'
sched/x86: Fix thread_saved_pc()
sched: Remove __schedule() non-standard frame annotation
Colin Ian King (1):
selftests/x86: Fix spelling mistake "preseve" -> "preserve"
Joerg Roedel (1):
iommu/amd: Don't put completion-wait semaphore on stack
Josh Poimboeuf (35):
x86/dumpstack: Remove show_trace()
x86/asm/head: Remove unused init_rsp variable extern
x86/asm/head: Rename 'stack_start' -> 'initial_stack'
x86/dumpstack: Remove extra brackets around "<EOE>"
x86/head: Remove useless zeroed word
x86/dumpstack: Fix x86_32 kernel_stack_pointer() previous stack access
proc: Fix return address printk conversion specifer in /proc/<pid>/stack x86/dumpstack: Remove 64-byte gap at end of irq stack
ftrace: Remove CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST from config
ftrace: Only allocate the ret_stack 'fp' field when needed
ftrace: Add return address pointer to ftrace_ret_stack
ftrace: Add ftrace_graph_ret_addr() stack unwinding helpers x86/dumpstack/ftrace: Convert dump_trace() callbacks to use ftrace_graph_ret_addr() ftrace/x86: Implement HAVE_FUNCTION_GRAPH_RET_ADDR_PTR x86/dumpstack/ftrace: Mark function graph handler function as unreliable x86/dumpstack/ftrace: Don't print unreliable addresses in print_context_stack_bp() perf/x86: Check perf_callchain_store() error
oprofile/x86: Add regs->ip to oprofile trace
x86/dumpstack: Make printk_stack_address() more generally useful x86/dumpstack: Add get_stack_pointer() and get_frame_pointer() x86/dumpstack: Remove unnecessary stack pointer arguments x86/dumpstack: Allow preemption in show_stack_log_lvl() and dump_trace() x86/dumpstack: Simplify in_exception_stack()
x86/dumpstack: Add get_stack_info() interface
x86/dumpstack: Add support for unwinding empty IRQ stacks x86/dumpstack: Add recursion checking for all stacks
x86/dumpstack: Remove NULL task pointer convention
x86/unwind: Add new unwind interface and implementations
perf/x86: Convert perf_callchain_kernel() to use the new unwinder x86/stacktrace: Convert save_stack_trace_*() to use the new unwinder oprofile/x86: Convert x86_backtrace() to use the new unwinder x86/dumpstack: Convert show_trace_log_lvl() to use the new unwinder x86/dumpstack: Remove dump_trace() and related callbacks x86/dumpstack: Fix show_stack() task pointer regression x86/alternatives: Add stack frame dependency to alternative_call_2()
Kees Cook (1):
x86: Apply more __ro_after_init and const
Linus Torvalds (2):
x86/entry: Get rid of pt_regs_to_thread_info() um/Stop conflating task_struct::stack with thread_info
Mark Rutland (1):
thread_info: Use unsigned long for flags
Oleg Nesterov (1):
kthread: Pin the stack via try_get_task_stack()/put_task_stack() in to_live_kthread() function
Thomas Garnier (1):
x86/mm/64: Enable KASLR for vmemmap memory region
Documentation/trace/ftrace-design.txt | 11 + arch/Kconfig | 34 +++ arch/arm/kernel/ftrace.c | 2 +- arch/arm64/kernel/entry-ftrace.S | 2 +- arch/arm64/kernel/ftrace.c | 2 +- arch/blackfin/kernel/ftrace-entry.S | 4 +- arch/blackfin/kernel/ftrace.c | 2 +- arch/ia64/include/asm/thread_info.h | 2 +- arch/microblaze/kernel/ftrace.c | 2 +- arch/mips/kernel/ftrace.c | 4 +- arch/parisc/kernel/ftrace.c | 2 +- arch/powerpc/kernel/ftrace.c | 3 +- arch/s390/kernel/ftrace.c | 3 +- arch/sh/kernel/ftrace.c | 2 +- arch/sparc/Kconfig | 1 - arch/sparc/include/asm/ftrace.h | 4 + arch/sparc/kernel/ftrace.c | 2 +- arch/tile/kernel/ftrace.c | 2 +- arch/x86/Kconfig | 3 +- arch/x86/entry/common.c | 24 +- arch/x86/entry/entry_32.S | 68 ++++-- arch/x86/entry/entry_64.S | 151 +++++++++---- arch/x86/events/core.c | 36 +-- arch/x86/include/asm/alternative.h | 8 +- arch/x86/include/asm/desc.h | 2 +- arch/x86/include/asm/fpu/xstate.h | 3 +- arch/x86/include/asm/ftrace.h | 3 + arch/x86/include/asm/kaslr.h | 1 + arch/x86/include/asm/kdebug.h | 2 - arch/x86/include/asm/paravirt.h | 4 - arch/x86/include/asm/paravirt_types.h | 1 - arch/x86/include/asm/pgtable_64_types.h | 4 +- arch/x86/include/asm/processor.h | 25 ++- arch/x86/include/asm/realmode.h | 2 +- arch/x86/include/asm/smp.h | 3 - arch/x86/include/asm/special_insns.h | 22 +- arch/x86/include/asm/stacktrace.h | 120 +++++----- arch/x86/include/asm/switch_to.h | 164 +++++--------- arch/x86/include/asm/syscall.h | 20 +- arch/x86/include/asm/thread_info.h | 71 +----- arch/x86/include/asm/tlbflush.h | 2 +- arch/x86/include/asm/traps.h | 6 + arch/x86/include/asm/unwind.h | 73 ++++++ arch/x86/kernel/Makefile | 6 + arch/x86/kernel/acpi/sleep.c | 2 +- arch/x86/kernel/apic/apic_flat_64.c | 6 +- arch/x86/kernel/apic/apic_noop.c | 2 +- arch/x86/kernel/apic/bigsmp_32.c | 2 +- arch/x86/kernel/apic/msi.c | 2 +- arch/x86/kernel/apic/probe_32.c | 4 +- arch/x86/kernel/apic/x2apic_cluster.c | 2 +- arch/x86/kernel/apic/x2apic_phys.c | 2 +- arch/x86/kernel/apic/x2apic_uv_x.c | 2 +- arch/x86/kernel/asm-offsets.c | 7 +- arch/x86/kernel/asm-offsets_32.c | 5 + arch/x86/kernel/asm-offsets_64.c | 5 + arch/x86/kernel/cpu/common.c | 18 +- arch/x86/kernel/cpu/mtrr/main.c | 4 +- arch/x86/kernel/cpu/mtrr/mtrr.h | 2 +- arch/x86/kernel/dumpstack.c | 258 +++++++++------------- arch/x86/kernel/dumpstack_32.c | 154 +++++++------ arch/x86/kernel/dumpstack_64.c | 318 +++++++++------------------ arch/x86/kernel/fpu/init.c | 1 - arch/x86/kernel/ftrace.c | 2 +- arch/x86/kernel/head_32.S | 8 +- arch/x86/kernel/head_64.S | 12 +- arch/x86/kernel/irq_64.c | 3 +- arch/x86/kernel/kgdb.c | 8 +- arch/x86/kernel/ksysfs.c | 2 +- arch/x86/kernel/kvmclock.c | 2 +- arch/x86/kernel/paravirt.c | 3 +- arch/x86/kernel/process.c | 42 +++- arch/x86/kernel/process_32.c | 33 +-- arch/x86/kernel/process_64.c | 25 +-- arch/x86/kernel/ptrace.c | 12 +- arch/x86/kernel/reboot.c | 2 +- arch/x86/kernel/setup.c | 6 +- arch/x86/kernel/setup_percpu.c | 4 +- arch/x86/kernel/signal.c | 2 +- arch/x86/kernel/smpboot.c | 3 +- arch/x86/kernel/stacktrace.c | 79 +++---- arch/x86/kernel/traps.c | 61 +++++ arch/x86/kernel/unwind_frame.c | 93 ++++++++ arch/x86/kernel/unwind_guess.c | 43 ++++ arch/x86/kernel/x86_init.c | 6 +- arch/x86/kvm/svm.c | 2 +- arch/x86/kvm/vmx.c | 2 +- arch/x86/mm/fault.c | 32 +++ arch/x86/mm/kaslr.c | 26 ++- arch/x86/mm/tlb.c | 15 ++ arch/x86/oprofile/backtrace.c | 49 ++--- arch/x86/pci/pcbios.c | 7 +- arch/x86/power/cpu.c | 2 +- arch/x86/um/ptrace_32.c | 8 +- arch/x86/xen/enlighten.c | 1 - drivers/iommu/amd_iommu.c | 51 +++-- drivers/iommu/amd_iommu_types.h | 2 + fs/proc/base.c | 2 +- include/linux/ftrace.h | 17 +- include/linux/init_task.h | 11 + include/linux/sched.h | 81 ++++++- include/linux/thread_info.h | 15 ++ init/Kconfig | 10 + init/init_task.c | 7 +- kernel/fork.c | 175 +++++++++++++-- kernel/kthread.c | 8 +- kernel/sched/core.c | 5 +- kernel/sched/sched.h | 4 + kernel/trace/Kconfig | 5 - kernel/trace/trace_functions_graph.c | 67 +++++- lib/dma-debug.c | 36 ++- lib/syscall.c | 15 +- tools/testing/selftests/x86/ptrace_syscall.c | 4 +- tools/testing/selftests/x86/sigreturn.c | 16 +- 114 files changed, 1722 insertions(+), 1108 deletions(-) create mode 100644 arch/x86/include/asm/unwind.h create mode 100644 arch/x86/kernel/unwind_frame.c create mode 100644 arch/x86/kernel/unwind_guess.c
Documentation/trace/ftrace-design.txt +11 -0
@@ -203,6 +203,17 @@ along to ftrace_push_return_trace() instead of a stub value of 0. Similarly, when you call ftrace_return_to_handler(), pass it the frame pointer. +HAVE_FUNCTION_GRAPH_RET_ADDR_PTR +-------------------------------- + +An arch may pass in a pointer to the return address on the stack. This +prevents potential stack unwinding issues where the unwinder gets out of +sync with ret_stack and the wrong addresses are reported by +ftrace_graph_ret_addr(). + +Adding support for it is easy: just define the macro in asm/ftrace.h and +pass the return address pointer as the 'retp' argument to +ftrace_push_return_trace(). HAVE_FTRACE_NMI_ENTER ---------------------
arch/Kconfig +34 -0
@@ -696,4 +696,38 @@ config ARCH_NO_COHERENT_DMA_MMAP config CPU_NO_EFFICIENT_FFS def_bool n +config HAVE_ARCH_VMAP_STACK + def_bool n + help + An arch should select this symbol if it can support kernel stacks + in vmalloc space. This means: + + - vmalloc space must be large enough to hold many kernel stacks. + This may rule out many 32-bit architectures. + + - Stacks in vmalloc space need to work reliably. For example, if + vmap page tables are created on demand, either this mechanism + needs to work while the stack points to a virtual address with + unpopulated page tables or arch code (switch_to() and switch_mm(), + most likely) needs to ensure that the stack's page table entries + are populated before running on a possibly unpopulated stack. + + - If the stack overflows into a guard page, something reasonable + should happen. The definition of "reasonable" is flexible, but + instantly rebooting without logging anything would be unfriendly. + +config VMAP_STACK + default y + bool "Use a virtually-mapped stack" + depends on HAVE_ARCH_VMAP_STACK && !KASAN + ---help--- + Enable this if you want the use virtually-mapped kernel stacks + with guard pages. This causes kernel stack overflows to be + caught immediately rather than causing difficult-to-diagnose + corruption. + + This is presently incompatible with KASAN because KASAN expects + the stack to map directly to the KASAN shadow map using a formula + that is incorrect if the stack is in vmalloc space. + source "kernel/gcov/Kconfig"
arch/arm/kernel/ftrace.c +1 -1
@@ -218,7 +218,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, } err =ftrace_push_return_trace (old, self_addr, &trace.depth, - frame_pointer); + frame_pointer,NULL );if (err == -EBUSY ) { *parent = old;return ;
arch/arm64/kernel/entry-ftrace.S +1 -1
@@ -219,7 +219,7 @@ ENDPROC(ftrace_graph_caller) * * Run ftrace_return_to_handler() before going back to parent. * @fp is checked against the value passed by ftrace_graph_caller() - * only when CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST is enabled. + * only when HAVE_FUNCTION_GRAPH_FP_TEST is enabled. */ ENTRY(return_to_handler) save_return_regs
arch/arm64/kernel/ftrace.c +1 -1
@@ -138,7 +138,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,return ; err =ftrace_push_return_trace (old, self_addr, &trace.depth, - frame_pointer); + frame_pointer,NULL );if (err == -EBUSY )return ;else
arch/blackfin/kernel/ftrace-entry.S +2 -2
@@ -169,7 +169,7 @@ ENTRY(_ftrace_graph_caller) r0 = sp; /* unsigned long *parent */ r1 = [sp]; /* unsigned long self_addr */ # endif -# ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +# ifdef HAVE_FUNCTION_GRAPH_FP_TEST r2 = fp; /* unsigned long frame_pointer */ # endif r0 += 16; /* skip the 4 local regs on stack */
@@ -190,7 +190,7 @@ ENTRY(_return_to_handler) [--sp] = r1; /* get original return address */ -# ifdef CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST +# ifdef HAVE_FUNCTION_GRAPH_FP_TEST r0 = fp; /* Blackfin is sane, so omit this */ # endif call _ftrace_return_to_handler;
arch/blackfin/kernel/ftrace.c +1 -1
@@ -107,7 +107,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,return ;if (ftrace_push_return_trace (*parent, self_addr, &trace.depth, - frame_pointer) == -EBUSY ) + frame_pointer,NULL ) == -EBUSY )return ; trace.func = self_addr;
arch/ia64/include/asm/thread_info.h +1 -1
@@ -56,7 +56,7 @@ struct thread_info {#define alloc_thread_stack_node (tsk, node) ((unsigned long *) 0)#define task_thread_info (tsk) ((struct thread_info *) 0)#endif -#define free_thread_stack (ti)/* nothing */ +#define free_thread_stack (tsk)/* nothing */ #define task_stack_page (tsk) ((void *)(tsk))#define __HAVE_THREAD_FUNCTIONS
arch/microblaze/kernel/ftrace.c +1 -1
@@ -63,7 +63,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)return ; } - err =ftrace_push_return_trace (old, self_addr, &trace.depth,0 ); + err =ftrace_push_return_trace (old, self_addr, &trace.depth,0 ,NULL );if (err == -EBUSY ) { *parent = old;return ;
arch/mips/kernel/ftrace.c +2 -2
@@ -382,8 +382,8 @@ void prepare_ftrace_return(unsigned long *parent_ra_addr, unsigned long self_ra,if (unlikely (faulted)) goto out; -if (ftrace_push_return_trace (old_parent_ra, self_ra, &trace.depth, fp) - == -EBUSY ) { +if (ftrace_push_return_trace (old_parent_ra, self_ra, &trace.depth, fp, +NULL ) == -EBUSY ) { *parent_ra_addr = old_parent_ra;return ; }
arch/parisc/kernel/ftrace.c +1 -1
@@ -48,7 +48,7 @@ static void __hot prepare_ftrace_return(unsigned long *parent,return ;if (ftrace_push_return_trace (old, self_addr, &trace.depth, -0 ) == -EBUSY ) +0 ,NULL ) == -EBUSY )return ;/* activate parisc_return_to_handler() as return point */
arch/powerpc/kernel/ftrace.c +2 -1
@@ -593,7 +593,8 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)if (!ftrace_graph_entry (&trace)) goto out; -if (ftrace_push_return_trace (parent, ip, &trace.depth,0 ) == -EBUSY ) +if (ftrace_push_return_trace (parent, ip, &trace.depth,0 , +NULL ) == -EBUSY ) goto out; parent = return_hooker;
arch/s390/kernel/ftrace.c +2 -1
@@ -209,7 +209,8 @@ unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip)/* Only trace if the calling function expects to. */ if (!ftrace_graph_entry (&trace)) goto out; -if (ftrace_push_return_trace (parent, ip, &trace.depth,0 ) == -EBUSY ) +if (ftrace_push_return_trace (parent, ip, &trace.depth,0 , +NULL ) == -EBUSY ) goto out; parent = (unsigned long ) return_to_handler; out:
arch/sh/kernel/ftrace.c +1 -1
@@ -382,7 +382,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)return ; } - err =ftrace_push_return_trace (old, self_addr, &trace.depth,0 ); + err =ftrace_push_return_trace (old, self_addr, &trace.depth,0 ,NULL );if (err == -EBUSY ) {__raw_writel (old, parent);return ;
arch/sparc/Kconfig +0 -1
@@ -56,7 +56,6 @@ config SPARC64 def_bool 64BIT select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER - select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_KRETPROBES select HAVE_KPROBES select HAVE_RCU_TABLE_FREE if SMP
arch/sparc/include/asm/ftrace.h +4 -0
@@ -9,6 +9,10 @@void _mcount (void );#endif +#endif /* CONFIG_MCOUNT */ + +#if defined(CONFIG_SPARC64 ) && !defined(CC_USE_FENTRY ) +#define HAVE_FUNCTION_GRAPH_FP_TEST #endif #ifdef CONFIG_DYNAMIC_FTRACE
arch/sparc/kernel/ftrace.c +1 -1
@@ -131,7 +131,7 @@ unsigned long prepare_ftrace_return(unsigned long parent,return parent +8UL ;if (ftrace_push_return_trace (parent, self_addr, &trace.depth, - frame_pointer) == -EBUSY ) + frame_pointer,NULL ) == -EBUSY )return parent +8UL ; trace.func = self_addr;
arch/tile/kernel/ftrace.c +1 -1
@@ -184,7 +184,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, *parent = return_hooker; err =ftrace_push_return_trace (old, self_addr, &trace.depth, - frame_pointer); + frame_pointer,NULL );if (err == -EBUSY ) { *parent = old;return ;
arch/x86/Kconfig +2 -1
@@ -93,6 +93,7 @@ config X86 select HAVE_ARCH_TRANSPARENT_HUGEPAGE select HAVE_ARCH_WITHIN_STACK_FRAMES select HAVE_EBPF_JIT if X86_64 + select HAVE_ARCH_VMAP_STACK if X86_64 select HAVE_CC_STACKPROTECTOR select HAVE_CMPXCHG_DOUBLE select HAVE_CMPXCHG_LOCAL
@@ -109,7 +110,6 @@ config X86 select HAVE_EXIT_THREAD select HAVE_FENTRY if X86_64 select HAVE_FTRACE_MCOUNT_RECORD - select HAVE_FUNCTION_GRAPH_FP_TEST select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GCC_PLUGINS
@@ -157,6 +157,7 @@ config X86 select SPARSE_IRQ select SRCU select SYSCTL_EXCEPTION_TRACE + select THREAD_INFO_IN_TASK select USER_STACKTRACE_SUPPORT select VIRT_TO_BUS select X86_DEV_DMA_OPS if X86_64
arch/x86/entry/common.c +8 -16
@@ -31,13 +31,6 @@#define CREATE_TRACE_POINTS #include <trace/events/syscalls.h> -static struct thread_info *pt_regs_to_thread_info (struct pt_regs *regs) -{ -unsigned long top_of_stack = - (unsigned long )(regs +1 ) +TOP_OF_KERNEL_STACK_PADDING ; -return (struct thread_info *)(top_of_stack -THREAD_SIZE ); -} -#ifdef CONFIG_CONTEXT_TRACKING /* Called on entry from user mode with IRQs off. */ __visible inline void enter_from_user_mode(void)
@@ -71,7 +64,7 @@ static long syscall_trace_enter(struct pt_regs *regs) {u32 arch =in_ia32_syscall () ?AUDIT_ARCH_I386 :AUDIT_ARCH_X86_64 ; -struct thread_info *ti =pt_regs_to_thread_info (regs); +struct thread_info *ti =current_thread_info ();unsigned long ret =0 ;bool emulated = false;u32 work;
@@ -173,18 +166,17 @@ static void exit_to_usermode_loop(struct pt_regs *regs, u32 cached_flags)/* Disable IRQs and retry */ local_irq_disable (); - cached_flags =READ_ONCE (pt_regs_to_thread_info (regs)->flags); + cached_flags =READ_ONCE (current_thread_info ()->flags);if (!(cached_flags &EXIT_TO_USERMODE_LOOP_FLAGS ))break ; - } }/* Called with IRQs disabled. */ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs) { -struct thread_info *ti =pt_regs_to_thread_info (regs); +struct thread_info *ti =current_thread_info ();u32 cached_flags;if (IS_ENABLED (CONFIG_PROVE_LOCKING ) &&WARN_ON (!irqs_disabled ()))
@@ -209,7 +201,7 @@ __visible inline void prepare_exit_to_usermode(struct pt_regs *regs)* special case only applies after poking regs and before the * very next return to user mode. */ - ti->status &= ~(TS_COMPAT |TS_I386_REGS_POKED ); + current->thread.status &= ~(TS_COMPAT |TS_I386_REGS_POKED );#endif user_enter_irqoff ();
@@ -247,7 +239,7 @@ static void syscall_slow_exit_work(struct pt_regs *regs, u32 cached_flags)*/ __visible inline void syscall_return_slowpath(struct pt_regs *regs) { -struct thread_info *ti =pt_regs_to_thread_info (regs); +struct thread_info *ti =current_thread_info ();u32 cached_flags =READ_ONCE (ti->flags);CT_WARN_ON (ct_state () !=CONTEXT_KERNEL );
@@ -270,7 +262,7 @@ __visible inline void syscall_return_slowpath(struct pt_regs *regs)#ifdef CONFIG_X86_64 __visible void do_syscall_64(struct pt_regs *regs) { -struct thread_info *ti =pt_regs_to_thread_info (regs); +struct thread_info *ti =current_thread_info ();unsigned long nr = regs->orig_ax;enter_from_user_mode ();
@@ -303,11 +295,11 @@ __visible void do_syscall_64(struct pt_regs *regs)*/ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs) { -struct thread_info *ti =pt_regs_to_thread_info (regs); +struct thread_info *ti =current_thread_info ();unsigned int nr = (unsigned int )regs->orig_ax;#ifdef CONFIG_IA32_EMULATION - ti->status |=TS_COMPAT ; + current->thread.status |=TS_COMPAT ;#endif if (READ_ONCE (ti->flags) & _TIF_WORK_SYSCALL_ENTRY) {
arch/x86/entry/entry_32.S +52 -16
86 lines not on this page · raw message
arch/x86/entry/entry_64.S +113 -38
203 lines not on this page · raw message
arch/x86/events/core.c +12 -24
@@ -37,6 +37,7 @@#include <asm/timer.h> #include <asm/desc.h> #include <asm/ldt.h> +#include <asm/unwind.h> #include "perf_event.h"
@@ -2247,39 +2248,26 @@ void arch_perf_update_userpage(struct perf_event *event,cyc2ns_read_end (data); } -/* -* callchain support -*/ - -static int backtrace_stack (void *data,char *name) -{ -return 0 ; -} - -static int backtrace_address (void *data,unsigned long addr,int reliable) -{ -struct perf_callchain_entry_ctx *entry = data; - -return perf_callchain_store (entry, addr); -} - -static const struct stacktrace_ops backtrace_ops = { - .stack = backtrace_stack, - .address = backtrace_address, - .walk_stack = print_context_stack_bp, -}; -void perf_callchain_kernel (struct perf_callchain_entry_ctx *entry,struct pt_regs *regs) { +struct unwind_state state; +unsigned long addr; +if (perf_guest_cbs && perf_guest_cbs->is_in_guest ()) {/* TODO: We don't support guest os callchain now */ return ; } -perf_callchain_store (entry, regs->ip); +if (perf_callchain_store (entry, regs->ip)) +return ; -dump_trace (NULL , regs,NULL ,0 , &backtrace_ops, entry); +for (unwind_start (&state, current, regs,NULL ); !unwind_done (&state); +unwind_next_frame (&state)) { + addr =unwind_get_return_address (&state); +if (!addr ||perf_callchain_store (entry, addr)) +return ; + } } static inline int
arch/x86/include/asm/alternative.h +6 -2
@@ -217,10 +217,14 @@ static inline int alternatives_text_reserved(void *start, void *end)*/ #define alternative_call_2 (oldfunc, newfunc1, feature1, newfunc2, feature2, \ output, input...) \ +{ \ + register void *__sp asm(_ASM_SP); \ asm volatile (ALTERNATIVE_2("call %P[old]", "call %P[new1]", feature1,\ "call %P[new2]", feature2) \ - : output : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ - [new2] "i" (newfunc2), ## input) + : output, "+r" (__sp) \ + : [old] "i" (oldfunc), [new1] "i" (newfunc1), \ + [new2] "i" (newfunc2), ## input); \ +}/* * use this macro(s) if you need more than one output parameter
arch/x86/include/asm/desc.h +1 -1
@@ -36,7 +36,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *inextern struct desc_ptr idt_descr;extern gate_desc idt_table[]; -extern struct desc_ptr debug_idt_descr; +extern const struct desc_ptr debug_idt_descr;extern gate_desc debug_idt_table[];struct gdt_page {
arch/x86/include/asm/fpu/xstate.h +2 -1
@@ -45,7 +45,8 @@extern u64 xfeatures_mask;extern u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS ]; -extern void update_regset_xstate_info (unsigned int size,u64 xstate_mask); +extern void __init update_regset_xstate_info (unsigned int size, +u64 xstate_mask);void fpu__xstate_clear_all_cpu_caps (void );void *get_xsave_addr (struct xregs_state *xsave,int xstate);
arch/x86/include/asm/ftrace.h +3 -0
@@ -6,6 +6,7 @@# define MCOUNT_ADDR ((unsigned long)(__fentry__))#else # define MCOUNT_ADDR ((unsigned long)(mcount)) +# define HAVE_FUNCTION_GRAPH_FP_TEST #endif #define MCOUNT_INSN_SIZE 5/* sizeof mcount call */
@@ -13,6 +14,8 @@#define ARCH_SUPPORTS_FTRACE_OPS 1#endif +#define HAVE_FUNCTION_GRAPH_RET_ADDR_PTR +#ifndef __ASSEMBLY__extern void mcount (void );extern atomic_t modifying_ftrace_code;
arch/x86/include/asm/kaslr.h +1 -0
@@ -6,6 +6,7 @@ unsigned long kaslr_get_random_long(const char *purpose);#ifdef CONFIG_RANDOMIZE_MEMORY extern unsigned long page_offset_base;extern unsigned long vmalloc_base; +extern unsigned long vmemmap_base;void kernel_randomize_memory (void );#else
arch/x86/include/asm/kdebug.h +0 -2
@@ -24,8 +24,6 @@ enum die_val {extern void printk_address (unsigned long address);extern void die (const char *,struct pt_regs *,long );extern int __must_check __die (const char *,struct pt_regs *,long ); -extern void show_trace (struct task_struct *t,struct pt_regs *regs, -unsigned long *sp,unsigned long bp);extern void show_stack_regs (struct pt_regs *regs);extern void __show_regs (struct pt_regs *regs,int all);extern unsigned long oops_begin (void );
arch/x86/include/asm/paravirt.h +0 -4
@@ -80,10 +80,6 @@ static inline unsigned long __read_cr4(void) { return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4); } -static inline unsigned long __read_cr4_safe (void ) -{ - return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4_safe); -}static inline void __write_cr4 (unsigned long x) {
arch/x86/include/asm/paravirt_types.h +0 -1
@@ -108,7 +108,6 @@ struct pv_cpu_ops {unsigned long (*read_cr0)(void );void (*write_cr0)(unsigned long ); -unsigned long (*read_cr4_safe)(void );unsigned long (*read_cr4)(void );void (*write_cr4)(unsigned long );
arch/x86/include/asm/pgtable_64_types.h +3 -1
@@ -57,11 +57,13 @@ typedef struct { pteval_t pte; } pte_t;#define MAXMEM _AC(__AC(1, UL) << MAX_PHYSMEM_BITS, UL)#define VMALLOC_SIZE_TB _AC(32, UL)#define __VMALLOC_BASE _AC(0xffffc90000000000, UL) -#define VMEMMAP_START _AC(0xffffea0000000000, UL) +#define __VMEMMAP_BASE _AC(0xffffea0000000000, UL)#ifdef CONFIG_RANDOMIZE_MEMORY #define VMALLOC_START vmalloc_base +#define VMEMMAP_START vmemmap_base#else #define VMALLOC_START __VMALLOC_BASE +#define VMEMMAP_START __VMEMMAP_BASE#endif /* CONFIG_RANDOMIZE_MEMORY */ #define VMALLOC_END (VMALLOC_START + _AC((VMALLOC_SIZE_TB << 40) - 1, UL))#define MODULES_VADDR (__START_KERNEL_map + KERNEL_IMAGE_SIZE)
arch/x86/include/asm/processor.h +14 -11
@@ -389,9 +389,9 @@ struct thread_struct {unsigned short fsindex;unsigned short gsindex;#endif -#ifdef CONFIG_X86_32 -unsigned long ip; -#endif + +u32 status;/* thread synchronous flags */ +#ifdef CONFIG_X86_64 unsigned long fsbase;unsigned long gsbase;
@@ -438,6 +438,15 @@ struct thread_struct { };/* +* Thread-synchronous status. +* +* This is different from the flags in that nobody else +* ever touches our thread-synchronous status, so we don't +* have to worry about atomic accesses. +*/ +#define TS_COMPAT 0x0002/* 32bit syscall active (64BIT)*/ + +/* * Set IOPL bits in EFLAGS from given mask */ static inline void native_set_iopl_mask (unsigned mask)
@@ -724,8 +733,6 @@ static inline void spin_lock_prefetch(const void *x) .addr_limit = KERNEL_DS, \ } -extern unsigned long thread_saved_pc (struct task_struct *tsk); -/* * TOP_OF_KERNEL_STACK_PADDING reserves 8 bytes on top of the ring0 stack. * This is necessary to guarantee that the entire "struct pt_regs"
@@ -776,17 +783,13 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); .addr_limit = KERNEL_DS, \ } -/* -* Return saved PC of a blocked thread. -* What is this good for? it will be always the scheduler or ret_from_fork. -*/ -#define thread_saved_pc (t) READ_ONCE_NOCHECK(*(unsigned long *)((t)->thread.sp - 8)) -#define task_pt_regs (tsk) ((struct pt_regs *)(tsk)->thread.sp0 - 1)extern unsigned long KSTK_ESP (struct task_struct *task);#endif /* CONFIG_X86_64 */ +extern unsigned long thread_saved_pc (struct task_struct *tsk); +extern void start_thread (struct pt_regs *regs,unsigned long new_ip,unsigned long new_sp);
arch/x86/include/asm/realmode.h +1 -1
@@ -44,9 +44,9 @@ struct trampoline_header {extern struct real_mode_header *real_mode_header;extern unsigned char real_mode_blob_end[]; -extern unsigned long init_rsp;extern unsigned long initial_code;extern unsigned long initial_gs; +extern unsigned long initial_stack;extern unsigned char real_mode_blob[];extern unsigned char real_mode_relocs[];
arch/x86/include/asm/smp.h +0 -3
@@ -39,9 +39,6 @@ DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);DECLARE_EARLY_PER_CPU_READ_MOSTLY (int, x86_cpu_to_logical_apicid);#endif -/* Static state in head.S used to set up a CPU */ -extern unsigned long stack_start;/* Initial stack pointer address */ -struct task_struct ;struct smp_ops {
arch/x86/include/asm/special_insns.h +7 -15
@@ -59,22 +59,19 @@ static inline void native_write_cr3(unsigned long val)static inline unsigned long native_read_cr4 (void ) {unsigned long val; - asmvolatile ("mov %%cr4,%0\n\t" :"=r" (val),"=m" (__force_order)); -return val; -} - -static inline unsigned long native_read_cr4_safe (void ) -{ -unsigned long val; -/* This could fault if %cr4 does not exist. In x86_64, a cr4 always -* exists, so it will never fail. */ #ifdef CONFIG_X86_32 +/* +* This could fault if CR4 does not exist. Non-existent CR4 +* is functionally equivalent to CR4 == 0. Keep it simple and pretend +* that CR4 == 0 on CPUs that don't have CR4. +*/ asm volatile("1: mov %%cr4, %0\n" "2:\n" _ASM_EXTABLE(1b, 2b) : "=r" (val), "=m" (__force_order) : "0" (0));#else - val =native_read_cr4 (); +/* CR4 always exists on x86_64. */ + asmvolatile ("mov %%cr4,%0\n\t" :"=r" (val),"=m" (__force_order));#endif return val; }
@@ -182,11 +179,6 @@ static inline unsigned long __read_cr4(void)return native_read_cr4 (); } -static inline unsigned long __read_cr4_safe (void ) -{ -return native_read_cr4_safe (); -} -static inline void __write_cr4 (unsigned long x) {native_write_cr4 (x);
arch/x86/include/asm/stacktrace.h +60 -60
153 lines not on this page · raw message
arch/x86/include/asm/switch_to.h +50 -114
180 lines not on this page · raw message
arch/x86/include/asm/syscall.h +5 -15
@@ -60,7 +60,7 @@ static inline long syscall_get_error(struct task_struct *task,* TS_COMPAT is set for 32-bit syscall entries and then * remains set until we return to user mode. */ -if (task_thread_info (task)->status & (TS_COMPAT |TS_I386_REGS_POKED )) +if (task->thread.status & (TS_COMPAT |TS_I386_REGS_POKED ))/* * Sign-extend the value so (int)-EFOO becomes (long)-EFOO * and will match correctly in comparisons.
@@ -116,7 +116,7 @@ static inline void syscall_get_arguments(struct task_struct *task, unsigned long *args) {# ifdef CONFIG_IA32_EMULATION -if (task_thread_info (task)->status &TS_COMPAT ) +if (task->thread.status &TS_COMPAT )switch (i) {case 0 :if (!n--)break ;
@@ -177,7 +177,7 @@ static inline void syscall_set_arguments(struct task_struct *task, const unsigned long *args) {# ifdef CONFIG_IA32_EMULATION -if (task_thread_info (task)->status &TS_COMPAT ) +if (task->thread.status &TS_COMPAT )switch (i) {case 0 :if (!n--)break ;
@@ -234,18 +234,8 @@ static inline void syscall_set_arguments(struct task_struct *task,static inline int syscall_get_arch (void ) { -#ifdef CONFIG_IA32_EMULATION -/* -* TS_COMPAT is set for 32-bit syscall entry and then -* remains set until we return to user mode. -* -* x32 tasks should be considered AUDIT_ARCH_X86_64. -*/ -if (task_thread_info (current)->status &TS_COMPAT ) -return AUDIT_ARCH_I386 ; -#endif -/* Both x32 and x86_64 are considered "64-bit". */ -return AUDIT_ARCH_X86_64 ; +/* x32 tasks should be considered AUDIT_ARCH_X86_64. */ +return in_ia32_syscall () ?AUDIT_ARCH_I386 :AUDIT_ARCH_X86_64 ; }#endif /* CONFIG_X86_32 */
arch/x86/include/asm/thread_info.h +4 -67
110 lines not on this page · raw message
arch/x86/include/asm/tlbflush.h +1 -1
@@ -81,7 +81,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);/* Initialize cr4 shadow for this CPU. */ static inline void cr4_init_shadow (void ) { -this_cpu_write (cpu_tlbstate.cr4,__read_cr4_safe ()); +this_cpu_write (cpu_tlbstate.cr4,__read_cr4 ()); }/* Set in this cpu's CR4. */
arch/x86/include/asm/traps.h +6 -0
@@ -117,6 +117,12 @@ extern void ist_exit(struct pt_regs *regs);extern void ist_begin_non_atomic (struct pt_regs *regs);extern void ist_end_non_atomic (void ); +#ifdef CONFIG_VMAP_STACK +void __noreturn handle_stack_overflow (const char *message, +struct pt_regs *regs, +unsigned long fault_address); +#endif +/* Interrupts/Exceptions */ enum {X86_TRAP_DE =0 ,/* 0, Divide-by-zero */
arch/x86/include/asm/unwind.h new file +73 -0
73 lines not on this page · raw message
arch/x86/kernel/Makefile +6 -0
@@ -125,6 +125,12 @@ obj-$(CONFIG_EFI) += sysfb_efi.o obj-$(CONFIG_PERF_EVENTS) += perf_regs.o obj-$(CONFIG_TRACING) += tracepoint.o +ifdef CONFIG_FRAME_POINTER +obj-y += unwind_frame.o +else +obj-y += unwind_guess.o +endif + ### # 64 bit specific files ifeq ($(CONFIG_X86_64),y)
arch/x86/kernel/acpi/sleep.c +1 -1
@@ -99,7 +99,7 @@ int x86_acpi_suspend_lowlevel(void) saved_magic =0x12345678 ;#else /* CONFIG_64BIT */ #ifdef CONFIG_SMP - stack_start = (unsigned long )temp_stack +sizeof (temp_stack); + initial_stack = (unsigned long )temp_stack +sizeof (temp_stack); early_gdt_descr.address = (unsigned long )get_cpu_gdt_table (smp_processor_id ()); initial_gs =per_cpu_offset (smp_processor_id ());
arch/x86/kernel/apic/apic_flat_64.c +3 -3
@@ -25,7 +25,7 @@static struct apic apic_physflat;static struct apic apic_flat; -struct apic __read_mostly *apic = &apic_flat; +struct apic *apic__ro_after_init = &apic_flat;EXPORT_SYMBOL_GPL (apic);static int flat_acpi_madt_oem_check (char *oem_id,char *oem_table_id)
@@ -154,7 +154,7 @@ static int flat_probe(void)return 1 ; } -static struct apic apic_flat = { +static struct apic apic_flat__ro_after_init = { .name ="flat" , .probe = flat_probe, .acpi_madt_oem_check = flat_acpi_madt_oem_check,
@@ -248,7 +248,7 @@ static int physflat_probe(void)return 0 ; } -static struct apic apic_physflat = { +static struct apic apic_physflat__ro_after_init = { .name ="physical flat" , .probe = physflat_probe,
arch/x86/kernel/apic/apic_noop.c +1 -1
@@ -108,7 +108,7 @@ static void noop_apic_write(u32 reg, u32 v)WARN_ON_ONCE (boot_cpu_has (X86_FEATURE_APIC ) && !disable_apic); } -struct apic apic_noop = { +struct apic apic_noop__ro_after_init = { .name ="noop" , .probe = noop_probe, .acpi_madt_oem_check =NULL ,
arch/x86/kernel/apic/bigsmp_32.c +1 -1
@@ -142,7 +142,7 @@ static int probe_bigsmp(void)return dmi_bigsmp; } -static struct apic apic_bigsmp = { +static struct apic apic_bigsmp__ro_after_init = { .name ="bigsmp" , .probe = probe_bigsmp,
arch/x86/kernel/apic/msi.c +1 -1
@@ -269,7 +269,7 @@ static void hpet_msi_write_msg(struct irq_data *data, struct msi_msg *msg)hpet_msi_write (irq_data_get_irq_handler_data (data), msg); } -static struct irq_chip hpet_msi_controller = { +static struct irq_chip hpet_msi_controller__ro_after_init = { .name ="HPET-MSI" , .irq_unmask = hpet_msi_unmask, .irq_mask = hpet_msi_mask,
arch/x86/kernel/apic/probe_32.c +2 -2
@@ -72,7 +72,7 @@ static int probe_default(void)return 1 ; } -static struct apic apic_default = { +static struct apic apic_default__ro_after_init = { .name ="default" , .probe = probe_default,
@@ -126,7 +126,7 @@ static struct apic apic_default = {apic_driver (apic_default); -struct apic *apic = &apic_default; +struct apic *apic__ro_after_init = &apic_default;EXPORT_SYMBOL_GPL (apic);static int cmdline_apic__initdata ;
arch/x86/kernel/apic/x2apic_cluster.c +1 -1
@@ -227,7 +227,7 @@ static void cluster_vector_allocation_domain(int cpu, struct cpumask *retmask,cpumask_and (retmask, mask,per_cpu (cpus_in_cluster, cpu)); } -static struct apic apic_x2apic_cluster = { +static struct apic apic_x2apic_cluster__ro_after_init = { .name ="cluster x2apic" , .probe = x2apic_cluster_probe,
arch/x86/kernel/apic/x2apic_phys.c +1 -1
@@ -98,7 +98,7 @@ static int x2apic_phys_probe(void)return apic == &apic_x2apic_phys; } -static struct apic apic_x2apic_phys = { +static struct apic apic_x2apic_phys__ro_after_init = { .name ="physical x2apic" , .probe = x2apic_phys_probe,
arch/x86/kernel/apic/x2apic_uv_x.c +1 -1
@@ -560,7 +560,7 @@ static int uv_probe(void)return apic == &apic_x2apic_uv_x; } -static struct apic __refdata apic_x2apic_uv_x = { +static struct apic apic_x2apic_uv_x__ro_after_init = { .name ="UV large system" , .probe = uv_probe,
arch/x86/kernel/asm-offsets.c +5 -2
@@ -29,10 +29,13 @@void common (void ) {BLANK (); -OFFSET (TI_flags, thread_info, flags); -OFFSET (TI_status, thread_info, status); +OFFSET (TASK_threadsp, task_struct, thread.sp); +#ifdef CONFIG_CC_STACKPROTECTOR +OFFSET (TASK_stack_canary, task_struct, stack_canary); +#endif BLANK (); +OFFSET (TASK_TI_flags, task_struct, thread_info.flags);OFFSET (TASK_addr_limit, task_struct, thread.addr_limit);BLANK ();
arch/x86/kernel/asm-offsets_32.c +5 -0
@@ -57,6 +57,11 @@ void foo(void)/* Size of SYSENTER_stack */ DEFINE (SIZEOF_SYSENTER_stack,sizeof (((struct tss_struct *)0 )->SYSENTER_stack)); +#ifdef CONFIG_CC_STACKPROTECTOR +BLANK (); +OFFSET (stack_canary_offset, stack_canary, canary); +#endif +#if defined(CONFIG_LGUEST ) || defined(CONFIG_LGUEST_GUEST ) || defined(CONFIG_LGUEST_MODULE )BLANK ();OFFSET (LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
arch/x86/kernel/asm-offsets_64.c +5 -0
@@ -56,6 +56,11 @@ int main(void)OFFSET (TSS_sp0, tss_struct, x86_tss.sp0);BLANK (); +#ifdef CONFIG_CC_STACKPROTECTOR +DEFINE (stack_canary_offset, offsetof(union irq_stack_union , stack_canary)); +BLANK (); +#endif +DEFINE (__NR_syscall_max,sizeof (syscalls_64) -1 );DEFINE (NR_syscalls,sizeof (syscalls_64));
arch/x86/kernel/cpu/common.c +9 -9
@@ -1265,9 +1265,14 @@ static __init int setup_disablecpuid(char *arg)__setup ("clearcpuid=" , setup_disablecpuid);#ifdef CONFIG_X86_64 -struct desc_ptr idt_descr = {NR_VECTORS *16 -1 , (unsigned long ) idt_table }; -struct desc_ptr debug_idt_descr = {NR_VECTORS *16 -1 , - (unsigned long ) debug_idt_table }; +struct desc_ptr idt_descr__ro_after_init = { + .size =NR_VECTORS *16 -1 , + .address = (unsigned long ) idt_table, +}; +const struct desc_ptr debug_idt_descr = { + .size =NR_VECTORS *16 -1 , + .address = (unsigned long ) debug_idt_table, +}; DEFINE_PER_CPU_FIRST(union irq_stack_union, irq_stack_union)__aligned(PAGE_SIZE) __visible;
@@ -1281,7 +1286,7 @@ DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned =EXPORT_PER_CPU_SYMBOL (current_task); DEFINE_PER_CPU(char *, irq_stack_ptr) = -init_per_cpu_var (irq_stack_union.irq_stack) +IRQ_STACK_SIZE -64 ; +init_per_cpu_var (irq_stack_union.irq_stack) +IRQ_STACK_SIZE ; DEFINE_PER_CPU(unsigned int, irq_count) __visible = -1;
@@ -1305,11 +1310,6 @@ static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks/* May not be marked __init: used by software suspend */ void syscall_init (void ) { -/* -* LSTAR and STAR live in a bit strange symbiosis. -* They both write to the same internal register. STAR allows to -* set CS/DS but only a 32bit target. LSTAR sets the 64bit rip. -*/ wrmsr (MSR_STAR ,0 , (__USER32_CS <<16 ) | __KERNEL_CS);wrmsrl (MSR_LSTAR , (unsigned long )entry_SYSCALL_64);
arch/x86/kernel/cpu/mtrr/main.c +2 -2
@@ -72,14 +72,14 @@ static DEFINE_MUTEX(mtrr_mutex);u64 size_or_mask, size_and_mask;static bool mtrr_aps_delayed_init; -static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM ]; +static const struct mtrr_ops *mtrr_ops[X86_VENDOR_NUM ]__ro_after_init ;const struct mtrr_ops *mtrr_if;static void set_mtrr (unsigned int reg,unsigned long base,unsigned long size,mtrr_type type); -void set_mtrr_ops (const struct mtrr_ops *ops) +void __init set_mtrr_ops (const struct mtrr_ops *ops) {if (ops->vendor && ops->vendor <X86_VENDOR_NUM ) mtrr_ops[ops->vendor] = ops;
arch/x86/kernel/cpu/mtrr/mtrr.h +1 -1
@@ -54,7 +54,7 @@ void fill_mtrr_var_range(unsigned int index,bool get_mtrr_state (void );void mtrr_bp_pat_init (void ); -extern void set_mtrr_ops (const struct mtrr_ops *ops); +extern void __init set_mtrr_ops (const struct mtrr_ops *ops);extern u64 size_or_mask, size_and_mask;extern const struct mtrr_ops *mtrr_if;
arch/x86/kernel/dumpstack.c +110 -148
304 lines not on this page · raw message
arch/x86/kernel/dumpstack_32.c +92 -62
199 lines not on this page · raw message
arch/x86/kernel/dumpstack_64.c +100 -218
387 lines not on this page · raw message
arch/x86/kernel/fpu/init.c +0 -1
@@ -317,7 +317,6 @@ static void __init fpu__init_system_ctx_switch(void) on_boot_cpu =0 ;WARN_ON_FPU (current->thread.fpu.fpstate_active); -current_thread_info ()->status =0 ;if (boot_cpu_has (X86_FEATURE_XSAVEOPT ) && eagerfpu !=DISABLE ) eagerfpu =ENABLE ;
arch/x86/kernel/ftrace.c +1 -1
@@ -1029,7 +1029,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, }if (ftrace_push_return_trace (old, self_addr, &trace.depth, - frame_pointer) == -EBUSY ) { + frame_pointer, parent) == -EBUSY ) { *parent = old;return ; }
arch/x86/kernel/head_32.S +4 -4
@@ -94,7 +94,7 @@ RESERVE_BRK(pagetables, INIT_MAP_SIZE) */ __HEAD ENTRY(startup_32) - movl pa(stack_start),%ecx + movl pa(initial_stack),%ecx /* test KEEP_SEGMENTS flag to see if the bootloader is asking us to not reload segments */
@@ -286,7 +286,7 @@ num_subarch_entries = (. - subarch_entries) / 4 * start_secondary(). */ ENTRY(start_cpu0) - movl stack_start, %ecx + movl initial_stack, %ecx movl %ecx, %esp jmp *(initial_code) ENDPROC(start_cpu0)
@@ -307,7 +307,7 @@ ENTRY(startup_32_smp) movl %eax,%es movl %eax,%fs movl %eax,%gs - movl pa(stack_start),%ecx + movl pa(initial_stack),%ecx movl %eax,%ss leal -__PAGE_OFFSET(%ecx),%esp
@@ -703,7 +703,7 @@ ENTRY(initial_page_table) .data .balign 4 -ENTRY(stack_start) +ENTRY(initial_stack) .long init_thread_union+THREAD_SIZE __INITRODATA
arch/x86/kernel/head_64.S +5 -7
@@ -66,7 +66,7 @@ L3_START_KERNEL = pud_index(__START_KERNEL_map) */ /* - * Setup stack for verify_cpu(). "-8" because stack_start is defined + * Setup stack for verify_cpu(). "-8" because initial_stack is defined * this way, see below. Our best guess is a NULL ptr for stack * termination heuristics and we don't want to break anything which * might depend on it (kgdb, ...).
@@ -226,7 +226,7 @@ ENTRY(secondary_startup_64) movq %rax, %cr0 /* Setup a boot time stack */ - movq stack_start(%rip), %rsp + movq initial_stack(%rip), %rsp /* zero EFLAGS after setting rsp */ pushq $0
@@ -310,7 +310,7 @@ ENDPROC(secondary_startup_64) * start_secondary(). */ ENTRY(start_cpu0) - movq stack_start(%rip),%rsp + movq initial_stack(%rip),%rsp movq initial_code(%rip),%rax pushq $0 # fake return address to stop unwinder pushq $__KERNEL_CS # set correct cs
@@ -319,17 +319,15 @@ ENTRY(start_cpu0) ENDPROC(start_cpu0) #endif - /* SMP bootup changes these two */ + /* Both SMP bootup and ACPI suspend change these variables */ __REFDATA .balign 8 GLOBAL(initial_code) .quad x86_64_start_kernel GLOBAL(initial_gs) .quad INIT_PER_CPU_VAR(irq_stack_union) - - GLOBAL(stack_start) + GLOBAL(initial_stack) .quad init_thread_union+THREAD_SIZE-8 - .word 0 __FINITDATA bad_address:
arch/x86/kernel/irq_64.c +1 -2
@@ -40,8 +40,7 @@ static inline void stack_overflow_check(struct pt_regs *regs)if (user_mode (regs))return ; -if (regs->sp >= curbase +sizeof (struct thread_info ) + -sizeof (struct pt_regs ) +STACK_TOP_MARGIN && +if (regs->sp >= curbase +sizeof (struct pt_regs ) +STACK_TOP_MARGIN && regs->sp <= curbase +THREAD_SIZE )return ;
arch/x86/kernel/kgdb.c +4 -4
@@ -50,6 +50,7 @@#include <asm/apicdef.h> #include <asm/apic.h> #include <asm/nmi.h> +#include <asm/switch_to.h> struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM ] = {
@@ -166,21 +167,19 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) gdb_regs[GDB_DX ] =0 ; gdb_regs[GDB_SI ] =0 ; gdb_regs[GDB_DI ] =0 ; - gdb_regs[GDB_BP ] = *(unsigned long *)p->thread.sp; + gdb_regs[GDB_BP ] = ((struct inactive_task_frame *)p->thread.sp)->bp;#ifdef CONFIG_X86_32 gdb_regs[GDB_DS ] = __KERNEL_DS; gdb_regs[GDB_ES ] = __KERNEL_DS; gdb_regs[GDB_PS ] =0 ; gdb_regs[GDB_CS ] = __KERNEL_CS; - gdb_regs[GDB_PC ] = p->thread.ip; gdb_regs[GDB_SS ] = __KERNEL_DS; gdb_regs[GDB_FS ] =0xFFFF ; gdb_regs[GDB_GS ] =0xFFFF ;#else - gdb_regs32[GDB_PS ] = *(unsigned long *)(p->thread.sp +8 ); + gdb_regs32[GDB_PS ] =0 ; gdb_regs32[GDB_CS ] = __KERNEL_CS; gdb_regs32[GDB_SS ] = __KERNEL_DS; - gdb_regs[GDB_PC ] =0 ; gdb_regs[GDB_R8 ] =0 ; gdb_regs[GDB_R9 ] =0 ; gdb_regs[GDB_R10 ] =0 ;
@@ -190,6 +189,7 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p) gdb_regs[GDB_R14 ] =0 ; gdb_regs[GDB_R15 ] =0 ;#endif + gdb_regs[GDB_PC ] =0 ; gdb_regs[GDB_SP ] = p->thread.sp; }
arch/x86/kernel/ksysfs.c +1 -1
@@ -184,7 +184,7 @@ static ssize_t setup_data_data_read(struct file *fp,static struct kobj_attribute type_attr =__ATTR_RO (type); -static struct bin_attribute data_attr = { +static struct bin_attribute data_attr__ro_after_init = { .attr = { .name ="data" , .mode =S_IRUGO ,
arch/x86/kernel/kvmclock.c +1 -1
@@ -29,7 +29,7 @@#include <asm/x86_init.h> #include <asm/reboot.h> -static int kvmclock =1 ; +static int kvmclock__ro_after_init =1 ;static int msr_kvm_system_time =MSR_KVM_SYSTEM_TIME ;static int msr_kvm_wall_clock =MSR_KVM_WALL_CLOCK ;static cycle_t kvm_sched_clock_offset;
arch/x86/kernel/paravirt.c +1 -2
@@ -332,7 +332,6 @@ __visible struct pv_cpu_ops pv_cpu_ops = { .read_cr0 = native_read_cr0, .write_cr0 = native_write_cr0, .read_cr4 = native_read_cr4, - .read_cr4_safe = native_read_cr4_safe, .write_cr4 = native_write_cr4, #ifdef CONFIG_X86_64 .read_cr8 = native_read_cr8,
@@ -389,7 +388,7 @@ NOKPROBE_SYMBOL(native_load_idt);#define PTE_IDENT __PV_IS_CALLEE_SAVE(_paravirt_ident_64)#endif -struct pv_mmu_ops pv_mmu_ops = { +struct pv_mmu_ops pv_mmu_ops__ro_after_init = { .read_cr2 = native_read_cr2, .write_cr2 = native_write_cr2,
arch/x86/kernel/process.c +30 -12
86 lines not on this page · raw message
arch/x86/kernel/process_32.c +9 -24
@@ -55,17 +55,6 @@#include <asm/switch_to.h> #include <asm/vm86.h> -asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -asmlinkage void ret_from_kernel_thread(void) __asm__("ret_from_kernel_thread"); - -/* -* Return saved PC of a blocked thread. -*/ -unsigned long thread_saved_pc (struct task_struct *tsk) -{ -return ((unsigned long *)tsk->thread.sp)[3 ]; -} -void __show_regs (struct pt_regs *regs,int all) {unsigned long cr0 =0L , cr2 =0L , cr3 =0L , cr4 =0L ;
@@ -101,7 +90,7 @@ void __show_regs(struct pt_regs *regs, int all) cr0 =read_cr0 (); cr2 =read_cr2 (); cr3 =read_cr3 (); - cr4 =__read_cr4_safe (); + cr4 =__read_cr4 ();printk (KERN_DEFAULT "CR0: %08lx CR2: %08lx CR3: %08lx CR4: %08lx\n" , cr0, cr2, cr3, cr4);
@@ -133,35 +122,31 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp, unsigned long arg, struct task_struct *p, unsigned long tls) { struct pt_regs *childregs = task_pt_regs(p); + struct fork_frame *fork_frame = container_of(childregs, struct fork_frame, regs); +struct inactive_task_frame *frame = &fork_frame->frame;struct task_struct *tsk;int err; - p->thread.sp = (unsigned long ) childregs; + frame->bp =0 ; + frame->ret_addr = (unsigned long ) ret_from_fork; + p->thread.sp = (unsigned long ) fork_frame; p->thread.sp0 = (unsigned long ) (childregs+1 );memset (p->thread.ptrace_bps,0 ,sizeof (p->thread.ptrace_bps));if (unlikely (p->flags &PF_KTHREAD )) {/* kernel thread */ memset (childregs,0 ,sizeof (struct pt_regs )); - p->thread.ip = (unsigned long ) ret_from_kernel_thread; -task_user_gs (p) = __KERNEL_STACK_CANARY; - childregs->ds = __USER_DS; - childregs->es = __USER_DS; - childregs->fs = __KERNEL_PERCPU; - childregs->bx = sp;/* function */ - childregs->bp = arg; - childregs->orig_ax =-1 ; - childregs->cs = __KERNEL_CS |get_kernel_rpl (); - childregs->flags =X86_EFLAGS_IF |X86_EFLAGS_FIXED ; + frame->bx = sp;/* function */ + frame->di = arg; p->thread.io_bitmap_ptr =NULL ;return 0 ; } + frame->bx =0 ; *childregs = *current_pt_regs (); childregs->ax =0 ;if (sp) childregs->sp = sp; - p->thread.ip = (unsigned long ) ret_from_fork;task_user_gs (p) =get_user_gs (current_pt_regs ()); p->thread.io_bitmap_ptr =NULL ;
arch/x86/kernel/process_64.c +12 -13
@@ -50,8 +50,6 @@#include <asm/switch_to.h> #include <asm/xen/hypervisor.h> -asmlinkage extern void ret_from_fork(void); -__visible DEFINE_PER_CPU (unsigned long ,rsp_scratch );/* Prints also some state that isn't saved in the pt_regs */
@@ -141,12 +139,17 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp, {int err;struct pt_regs *childregs; +struct fork_frame *fork_frame; +struct inactive_task_frame *frame;struct task_struct *me = current; p->thread.sp0 = (unsigned long )task_stack_page (p) +THREAD_SIZE ; childregs =task_pt_regs (p); - p->thread.sp = (unsigned long ) childregs; -set_tsk_thread_flag (p,TIF_FORK ); + fork_frame = container_of(childregs, struct fork_frame, regs); + frame = &fork_frame->frame; + frame->bp =0 ; + frame->ret_addr = (unsigned long ) ret_from_fork; + p->thread.sp = (unsigned long ) fork_frame; p->thread.io_bitmap_ptr =NULL ;savesegment (gs, p->thread.gsindex);
@@ -160,15 +163,11 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long sp,if (unlikely (p->flags &PF_KTHREAD )) {/* kernel thread */ memset (childregs,0 ,sizeof (struct pt_regs )); - childregs->sp = (unsigned long )childregs; - childregs->ss = __KERNEL_DS; - childregs->bx = sp;/* function */ - childregs->bp = arg; - childregs->orig_ax =-1 ; - childregs->cs = __KERNEL_CS |get_kernel_rpl (); - childregs->flags =X86_EFLAGS_IF |X86_EFLAGS_FIXED ; + frame->bx = sp;/* function */ + frame->r12 = arg;return 0 ; } + frame->bx =0 ; *childregs = *current_pt_regs (); childregs->ax =0 ;
@@ -511,7 +510,7 @@ void set_personality_ia32(bool x32) current->personality &= ~READ_IMPLIES_EXEC ;/* in_compat_syscall() uses the presence of the x32 syscall bit flag to determine compat status */ -current_thread_info ()->status &= ~TS_COMPAT ; + current->thread.status &= ~TS_COMPAT ; }else {set_thread_flag (TIF_IA32 );clear_thread_flag (TIF_X32 );
@@ -519,7 +518,7 @@ void set_personality_ia32(bool x32) current->mm->context.ia32_compat =TIF_IA32 ; current->personality |= force_personality32;/* Prepare the first "return" to user space */ -current_thread_info ()->status |=TS_COMPAT ; + current->thread.status |=TS_COMPAT ; } }EXPORT_SYMBOL_GPL (set_personality_ia32);
arch/x86/kernel/ptrace.c +6 -6
@@ -173,8 +173,8 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs)return sp; prev_esp = (u32 *)(context); -if (prev_esp) -return (unsigned long )prev_esp; +if (*prev_esp) +return (unsigned long )*prev_esp;return (unsigned long )regs; }
@@ -934,7 +934,7 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 value)*/ regs->orig_ax = value;if (syscall_get_nr (child, regs) >=0 ) -task_thread_info (child)->status |=TS_I386_REGS_POKED ; + child->thread.status |=TS_I386_REGS_POKED ;break ; case offsetof(struct user32, regs.eflags):
@@ -1250,7 +1250,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, #ifdef CONFIG_X86_64 -static struct user_regset x86_64_regsets[] __read_mostly = { +static struct user_regset x86_64_regsets[] __ro_after_init = { [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, .n = sizeof(struct user_regs_struct) / sizeof(long),
@@ -1291,7 +1291,7 @@ static const struct user_regset_view user_x86_64_view = {#endif /* CONFIG_X86_64 */ #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION -static struct user_regset x86_32_regsets[] __read_mostly = { +static struct user_regset x86_32_regsets[] __ro_after_init = { [REGSET_GENERAL] = { .core_note_type = NT_PRSTATUS, .n = sizeof(struct user_regs_struct32) / sizeof(u32),
@@ -1344,7 +1344,7 @@ static const struct user_regset_view user_x86_32_view = {*/ u64 xstate_fx_sw_bytes[USER_XSTATE_FX_SW_WORDS ]; -void update_regset_xstate_info (unsigned int size,u64 xstate_mask) +void __init update_regset_xstate_info (unsigned int size,u64 xstate_mask) {#ifdef CONFIG_X86_64 x86_64_regsets[REGSET_XSTATE ].n = size /sizeof (u64);
arch/x86/kernel/reboot.c +1 -1
@@ -705,7 +705,7 @@ static void native_machine_power_off(void)tboot_shutdown (TB_SHUTDOWN_HALT ); } -struct machine_ops machine_ops = { +struct machine_ops machine_ops__ro_after_init = { .power_off = native_machine_power_off, .shutdown = native_machine_shutdown, .emergency_restart = native_machine_emergency_restart,
arch/x86/kernel/setup.c +3 -3
@@ -210,9 +210,9 @@ EXPORT_SYMBOL(boot_cpu_data);#if !defined(CONFIG_X86_PAE ) || defined(CONFIG_X86_64 ) -__visible unsigned long mmu_cr4_features; +__visible unsigned long mmu_cr4_features__ro_after_init ;#else -__visible unsigned long mmu_cr4_features =X86_CR4_PAE ; +__visible unsigned long mmu_cr4_features__ro_after_init =X86_CR4_PAE ;#endif /* Boot loader ID and version as integers, for the benefit of proc_dointvec */
@@ -1137,7 +1137,7 @@ void __init setup_arch(char **cmdline_p)* auditing all the early-boot CR4 manipulation would be needed to * rule it out. */ - mmu_cr4_features =__read_cr4_safe (); + mmu_cr4_features =__read_cr4 ();memblock_set_current_limit (get_max_mapped ());
arch/x86/kernel/setup_percpu.c +2 -2
@@ -33,7 +33,7 @@ EXPORT_PER_CPU_SYMBOL(cpu_number); DEFINE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;EXPORT_PER_CPU_SYMBOL (this_cpu_off); -unsigned long __per_cpu_offset[NR_CPUS ]__read_mostly = { +unsigned long __per_cpu_offset[NR_CPUS ]__ro_after_init = { [0 ...NR_CPUS -1 ] =BOOT_PERCPU_OFFSET , };EXPORT_SYMBOL (__per_cpu_offset);
@@ -246,7 +246,7 @@ void __init setup_per_cpu_areas(void)#ifdef CONFIG_X86_64 per_cpu (irq_stack_ptr, cpu) =per_cpu (irq_stack_union.irq_stack, cpu) + -IRQ_STACK_SIZE -64 ; +IRQ_STACK_SIZE ;#endif #ifdef CONFIG_NUMA per_cpu(x86_cpu_to_node_map, cpu) =
arch/x86/kernel/signal.c +1 -1
@@ -783,7 +783,7 @@ static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)* than the tracee. */ #ifdef CONFIG_IA32_EMULATION -if (current_thread_info ()->status & (TS_COMPAT |TS_I386_REGS_POKED )) +if (current->thread.status & (TS_COMPAT |TS_I386_REGS_POKED ))return __NR_ia32_restart_syscall;#endif #ifdef CONFIG_X86_X32_ABI
arch/x86/kernel/smpboot.c +1 -2
@@ -942,7 +942,6 @@ void common_cpu_up(unsigned int cpu, struct task_struct *idle)per_cpu (cpu_current_top_of_stack, cpu) = (unsigned long )task_stack_page (idle) +THREAD_SIZE ;
Lines of this file are not shown. View the raw message.
arch/x86/kernel/stacktrace.c +34 -45
79 lines not on this page · raw message
arch/x86/kernel/traps.c +61 -0
61 lines not on this page · raw message
arch/x86/kernel/unwind_frame.c new file +93 -0
93 lines not on this page · raw message
arch/x86/kernel/unwind_guess.c new file +43 -0
43 lines not on this page · raw message
arch/x86/oprofile/backtrace.c +24 -25
49 lines not on this page · raw message
drivers/iommu/amd_iommu.c +35 -16
51 lines not on this page · raw message
include/linux/sched.h +79 -2
81 lines not on this page · raw message
kernel/fork.c +154 -21
175 lines not on this page · raw message
kernel/trace/trace_functions_graph.c +65 -2
67 lines not on this page · raw message
tools/testing/selftests/x86/ptrace_syscall.c +2 -2
Lines of this file are not shown. View the raw message.
tools/testing/selftests/x86/sigreturn.c +8 -8
Lines of this file are not shown. View the 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.