Skip to contentSkip to conversation

x86/asm changes for v4.9

GIT PULL Ingo Molnar 1 participant 1 message Oct 3, 2016

Subsystems (35)
lore
Share & tools
lore
#0 lore raw

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
index dd5f916b351d..a273dd0bbaaa 100644
@@ -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
index fd6e9712af81..180ea33164dc 100644
@@ -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
index 709ee1d6d4df..3f1759411d51 100644
@@ -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
index 0f03a8fe2314..aef02d2af3b5 100644
@@ -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
index ebecf9aa33d1..40ad08ac569a 100644
@@ -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
index 28d059540424..3b8bdcbb7da3 100644
@@ -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
index 095de0fa044d..8dad7589b843 100644
@@ -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
index 29bd59790d6c..c7026429816b 100644
@@ -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
index fc7b48a52cd5..d57563c58a26 100644
@@ -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
index 937c54bc8ccc..30a3b75e88eb 100644
@@ -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
index a828a0adf52c..5a5506a35395 100644
@@ -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
index cc52d9795f88..a95639b8d4ac 100644
@@ -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
index 0f7bfeba6da6..60a8a4e207ed 100644
@@ -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
index 38993e09ef03..95eccd49672f 100644
@@ -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
index 59b09600dd32..f5d60f14a0bc 100644
@@ -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
index 3192a8e42fd6..62755a339a59 100644
@@ -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
index 0a2d2ddff543..6bcff698069b 100644
@@ -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
index 4a572088b270..b827a418b155 100644
@@ -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
index 2a1f0ce7c59a..2a83bc8b24c6 100644
@@ -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
index 1433f6b4607d..bdd9cc59d20f 100644
@@ -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
index d0efb5cb1b00..0a8bd7fcdbed 100644
@@ -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
index e77a6443104f..1b020381ab38 100644
@@ -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
index 4e10d73cf018..12080d87da3b 100644
@@ -36,7 +36,7 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in
 
 extern 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
index ae55a43e09c0..d4957ac72b48 100644
@@ -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
index a4820d4df617..eccd0ac6bc38 100644
@@ -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
index 2674ee3de748..1052a797d71d 100644
@@ -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
index 1ef9d581b5d9..d31881188431 100644
@@ -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
index 2970d22d7766..91b6f4eed3fd 100644
@@ -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
index 7fa9e7740ba3..fcf243f077ac 100644
@@ -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
index 6fdef9eef2d5..3a264200c62f 100644
@@ -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
index 63def9537a2d..984a7bf17f6a 100644
@@ -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
index b2988c0ed829..230e1903acf0 100644
@@ -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
index ebd0c164cd4e..19980b36f394 100644
@@ -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
index 587d7914ea4b..19a2224f9e16 100644
@@ -59,22 +59,19 @@ static inline void native_write_cr3(unsigned long val)
 static inline unsigned long native_read_cr4(void)
 {
 	unsigned long val;
-	asm volatile("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. */
+	asm volatile("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
index 4e23dd15c661..e3c95e8e61c5 100644
@@ -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
index dee8a70382ba..6fa85944af83 100644
@@ -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
index c3496619740a..01fd0a7f48cd 100644
@@ -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
index 0503f5bfb18d..45257cf84370 100644
@@ -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
index adb3eaf8fe2a..48587335ede8 100644
@@ -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
index 5b2ae106bd4a..8862da76ef6f 100644
@@ -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
index c05688b2deff..b109e4389c92 100644
@@ -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
index 06dbaa458bfe..56012010332c 100644
@@ -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
index ade25320df96..015bbf30e3e3 100644
@@ -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
index 7c43e716c158..e5fb2f086460 100644
@@ -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
index 54f35d988025..200af5ae9662 100644
@@ -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
index 4f13f54f1b1f..ff111f05a314 100644
@@ -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
index cb0673c1e940..b9f6157d4271 100644
@@ -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
index 2bd5c6ff7ee7..c62e015b126c 100644
@@ -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
index ecdc1d217dc0..880aa093268d 100644
@@ -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
index d875f97d4e0b..210927ee2e74 100644
@@ -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
index 809eda03c527..06919427d451 100644
@@ -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
index 28f1b54b7fad..24e87e74990d 100644
@@ -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
index 6c7ced07d16d..ad8bd763efa5 100644
@@ -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
index 93982aebb398..2f2b8c7ccb85 100644
@@ -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
index d036cfb4495d..8639bb2ae058 100644
@@ -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
index 6f8902b0d151..5f401262f12d 100644
@@ -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
index 9f8efc9f0075..c98a559c346e 100644
@@ -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
index 4a7903714065..9ebd0b0e73d9 100644
@@ -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
index 04cde527d728..8e36f249646e 100644
@@ -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
index c2bedaea11f7..4afc67f5facc 100644
@@ -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
index 3692249a70f1..60b9949f1e65 100644
@@ -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
index 1acfd76e3e26..bbf3d5933eaa 100644
@@ -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
index d86be29c38c7..bd7be8efdc4c 100644
@@ -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
index 63236d8f84bf..de9acaf2d371 100644
@@ -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
index f79576a541ff..ce94c38cf4d6 100644
@@ -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
index 63bf27d972b7..e244c19a2451 100644
@@ -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
index 98c9cd6f3b5d..3aabfdcbcb52 100644
@@ -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
index 7a40e068302d..2bbd27f89802 100644
@@ -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
index 04cb3212db2d..da20ecb5397a 100644
@@ -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
index 4296beb8fdd3..7e52f83d3a4b 100644
@@ -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;
[… more lines in the raw message]

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/kernel/x86_init.c +3 -3
index 76c5e52436c4..0bd9f1287f39 100644

Lines of this file are not shown. View the raw message.

arch/x86/kvm/svm.c +1 -1
index af523d84d102..1e6b84b96ea6 100644

Lines of this file are not shown. View the raw message.

arch/x86/kvm/vmx.c +1 -1
index 5cede40e2552..121fdf6e9ed0 100644

Lines of this file are not shown. View the raw message.

arch/x86/mm/fault.c +32 -0
index dc8023060456..0b92fce3e6c0 100644

Lines of this file are not shown. View the raw message.

arch/x86/mm/kaslr.c +24 -2
index bda8d5eef04d..ddd2661c4502 100644

Lines of this file are not shown. View the raw message.

arch/x86/mm/tlb.c +15 -0
index 4dbe65622810..a7655f6caf7d 100644

Lines of this file are not shown. View the raw message.

arch/x86/oprofile/backtrace.c +24 -25

49 lines not on this page · raw message

arch/x86/pci/pcbios.c +5 -2
index 9770e55e768f..1d97cea3b3a4 100644

Lines of this file are not shown. View the raw message.

arch/x86/power/cpu.c +1 -1
index b12c26e2e309..53cace2ec0e2 100644

Lines of this file are not shown. View the raw message.

arch/x86/um/ptrace_32.c +4 -4
index a7ef7b131e25..5766ead6fdb9 100644

Lines of this file are not shown. View the raw message.

arch/x86/xen/enlighten.c +0 -1
index b86ebb1a9a7f..e2cf8fcea6bb 100644

Lines of this file are not shown. View the raw message.

drivers/iommu/amd_iommu.c +35 -16

51 lines not on this page · raw message

drivers/iommu/amd_iommu_types.h +2 -0
index caf5e3822715..9652848e3155 100644

Lines of this file are not shown. View the raw message.

fs/proc/base.c +1 -1
index ac0df4dde823..3b792ab3c0dc 100644

Lines of this file are not shown. View the raw message.

include/linux/ftrace.h +16 -1
index 7d565afe35d2..6f93ac46e7f0 100644

Lines of this file are not shown. View the raw message.

include/linux/init_task.h +11 -0
index f8834f820ec2..325f649d77ff 100644

Lines of this file are not shown. View the raw message.

include/linux/sched.h +79 -2

81 lines not on this page · raw message

include/linux/thread_info.h +15 -0
index 2b5b10eed74f..45f004e9cc59 100644

Lines of this file are not shown. View the raw message.

init/Kconfig +10 -0
index cac3f096050d..3b9a47fe843b 100644

Lines of this file are not shown. View the raw message.

init/init_task.c +5 -2
index ba0a7f362d9e..11f83be1fa79 100644

Lines of this file are not shown. View the raw message.

kernel/fork.c +154 -21

175 lines not on this page · raw message

kernel/kthread.c +6 -2
index 9ff173dca1ae..4ab4c3766a80 100644

Lines of this file are not shown. View the raw message.

kernel/sched/core.c +4 -1
index 44817c640e99..23c6037e2d89 100644

Lines of this file are not shown. View the raw message.

kernel/sched/sched.h +4 -0
index c64fc5114004..3655c9625e5b 100644

Lines of this file are not shown. View the raw message.

kernel/trace/Kconfig +0 -5
index f4b86e8ca1e7..ba3326785ca4 100644

Lines of this file are not shown. View the raw message.

kernel/trace/trace_functions_graph.c +65 -2

67 lines not on this page · raw message

lib/dma-debug.c +30 -6
index fcfa1939ac41..06f02f6aecd2 100644

Lines of this file are not shown. View the raw message.

lib/syscall.c +13 -2
index e30e03932480..63239e097b13 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/x86/ptrace_syscall.c +2 -2
index 421456784bc6..b037ce9cf116 100644

Lines of this file are not shown. View the raw message.

tools/testing/selftests/x86/sigreturn.c +8 -8
index 8a577e7070c6..246145b84a12 100644

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.