aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 19:13:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-03 19:13:28 -0400
commit1a4a2bc460721bc8f91e4c1294d39b38e5af132f (patch)
treefe646d05f6e17f05601e0a32cc796bec718ab6e7 /include
parent110a9e42b68719f584879c5c5c727bbae90d15f9 (diff)
parent1ef55be16ed69538f89e0a6508be5e62fdc9851c (diff)
Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull low-level x86 updates from Ingo Molnar: "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)" [ The virtually mapped stack changes are pretty fundamental, and not x86-specific per se, even if they are only used on x86 right now. ] * 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (70 commits) x86/asm: Get rid of __read_cr4_safe() thread_info: Use unsigned long for flags x86/alternatives: Add stack frame dependency to alternative_call_2() x86/dumpstack: Fix show_stack() task pointer regression x86/dumpstack: Remove dump_trace() and related callbacks x86/dumpstack: Convert show_trace_log_lvl() to use the new unwinder oprofile/x86: Convert x86_backtrace() to use the new unwinder x86/stacktrace: Convert save_stack_trace_*() to use the new unwinder perf/x86: Convert perf_callchain_kernel() to use the new unwinder x86/unwind: Add new unwind interface and implementations x86/dumpstack: Remove NULL task pointer convention fork: Optimize task creation by caching two thread stacks per CPU if CONFIG_VMAP_STACK=y sched/core: Free the stack early if CONFIG_THREAD_INFO_IN_TASK lib/syscall: Pin the task stack in collect_syscall() x86/process: Pin the target stack in get_wchan() x86/dumpstack: Pin the target stack when dumping it kthread: Pin the stack via try_get_task_stack()/put_task_stack() in to_live_kthread() function sched/core: Add try_get_task_stack() and put_task_stack() x86/entry/64: Fix a minor comment rebase error iommu/amd: Don't put completion-wait semaphore on stack ...
Diffstat (limited to 'include')
-rw-r--r--include/linux/ftrace.h17
-rw-r--r--include/linux/init_task.h11
-rw-r--r--include/linux/sched.h81
-rw-r--r--include/linux/thread_info.h15
4 files changed, 121 insertions, 3 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 7d565afe35d2..6f93ac46e7f0 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -795,7 +795,12 @@ struct ftrace_ret_stack {
795 unsigned long func; 795 unsigned long func;
796 unsigned long long calltime; 796 unsigned long long calltime;
797 unsigned long long subtime; 797 unsigned long long subtime;
798#ifdef HAVE_FUNCTION_GRAPH_FP_TEST
798 unsigned long fp; 799 unsigned long fp;
800#endif
801#ifdef HAVE_FUNCTION_GRAPH_RET_ADDR_PTR
802 unsigned long *retp;
803#endif
799}; 804};
800 805
801/* 806/*
@@ -807,7 +812,10 @@ extern void return_to_handler(void);
807 812
808extern int 813extern int
809ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth, 814ftrace_push_return_trace(unsigned long ret, unsigned long func, int *depth,
810 unsigned long frame_pointer); 815 unsigned long frame_pointer, unsigned long *retp);
816
817unsigned long ftrace_graph_ret_addr(struct task_struct *task, int *idx,
818 unsigned long ret, unsigned long *retp);
811 819
812/* 820/*
813 * Sometimes we don't want to trace a function with the function 821 * Sometimes we don't want to trace a function with the function
@@ -870,6 +878,13 @@ static inline int task_curr_ret_stack(struct task_struct *tsk)
870 return -1; 878 return -1;
871} 879}
872 880
881static inline unsigned long
882ftrace_graph_ret_addr(struct task_struct *task, int *idx, unsigned long ret,
883 unsigned long *retp)
884{
885 return ret;
886}
887
873static inline void pause_graph_tracing(void) { } 888static inline void pause_graph_tracing(void) { }
874static inline void unpause_graph_tracing(void) { } 889static inline void unpause_graph_tracing(void) { }
875#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ 890#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index f8834f820ec2..325f649d77ff 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -15,6 +15,8 @@
15#include <net/net_namespace.h> 15#include <net/net_namespace.h>
16#include <linux/sched/rt.h> 16#include <linux/sched/rt.h>
17 17
18#include <asm/thread_info.h>
19
18#ifdef CONFIG_SMP 20#ifdef CONFIG_SMP
19# define INIT_PUSHABLE_TASKS(tsk) \ 21# define INIT_PUSHABLE_TASKS(tsk) \
20 .pushable_tasks = PLIST_NODE_INIT(tsk.pushable_tasks, MAX_PRIO), 22 .pushable_tasks = PLIST_NODE_INIT(tsk.pushable_tasks, MAX_PRIO),
@@ -183,12 +185,21 @@ extern struct task_group root_task_group;
183# define INIT_KASAN(tsk) 185# define INIT_KASAN(tsk)
184#endif 186#endif
185 187
188#ifdef CONFIG_THREAD_INFO_IN_TASK
189# define INIT_TASK_TI(tsk) \
190 .thread_info = INIT_THREAD_INFO(tsk), \
191 .stack_refcount = ATOMIC_INIT(1),
192#else
193# define INIT_TASK_TI(tsk)
194#endif
195
186/* 196/*
187 * INIT_TASK is used to set up the first task table, touch at 197 * INIT_TASK is used to set up the first task table, touch at
188 * your own risk!. Base=0, limit=0x1fffff (=2MB) 198 * your own risk!. Base=0, limit=0x1fffff (=2MB)
189 */ 199 */
190#define INIT_TASK(tsk) \ 200#define INIT_TASK(tsk) \
191{ \ 201{ \
202 INIT_TASK_TI(tsk) \
192 .state = 0, \ 203 .state = 0, \
193 .stack = init_stack, \ 204 .stack = init_stack, \
194 .usage = ATOMIC_INIT(2), \ 205 .usage = ATOMIC_INIT(2), \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index f76d75fc9eaf..7543a476178b 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1471,6 +1471,13 @@ struct tlbflush_unmap_batch {
1471}; 1471};
1472 1472
1473struct task_struct { 1473struct task_struct {
1474#ifdef CONFIG_THREAD_INFO_IN_TASK
1475 /*
1476 * For reasons of header soup (see current_thread_info()), this
1477 * must be the first element of task_struct.
1478 */
1479 struct thread_info thread_info;
1480#endif
1474 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ 1481 volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
1475 void *stack; 1482 void *stack;
1476 atomic_t usage; 1483 atomic_t usage;
@@ -1480,6 +1487,9 @@ struct task_struct {
1480#ifdef CONFIG_SMP 1487#ifdef CONFIG_SMP
1481 struct llist_node wake_entry; 1488 struct llist_node wake_entry;
1482 int on_cpu; 1489 int on_cpu;
1490#ifdef CONFIG_THREAD_INFO_IN_TASK
1491 unsigned int cpu; /* current CPU */
1492#endif
1483 unsigned int wakee_flips; 1493 unsigned int wakee_flips;
1484 unsigned long wakee_flip_decay_ts; 1494 unsigned long wakee_flip_decay_ts;
1485 struct task_struct *last_wakee; 1495 struct task_struct *last_wakee;
@@ -1936,6 +1946,13 @@ struct task_struct {
1936#ifdef CONFIG_MMU 1946#ifdef CONFIG_MMU
1937 struct task_struct *oom_reaper_list; 1947 struct task_struct *oom_reaper_list;
1938#endif 1948#endif
1949#ifdef CONFIG_VMAP_STACK
1950 struct vm_struct *stack_vm_area;
1951#endif
1952#ifdef CONFIG_THREAD_INFO_IN_TASK
1953 /* A live task holds one reference. */
1954 atomic_t stack_refcount;
1955#endif
1939/* CPU-specific state of this task */ 1956/* CPU-specific state of this task */
1940 struct thread_struct thread; 1957 struct thread_struct thread;
1941/* 1958/*
@@ -1952,6 +1969,18 @@ extern int arch_task_struct_size __read_mostly;
1952# define arch_task_struct_size (sizeof(struct task_struct)) 1969# define arch_task_struct_size (sizeof(struct task_struct))
1953#endif 1970#endif
1954 1971
1972#ifdef CONFIG_VMAP_STACK
1973static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
1974{
1975 return t->stack_vm_area;
1976}
1977#else
1978static inline struct vm_struct *task_stack_vm_area(const struct task_struct *t)
1979{
1980 return NULL;
1981}
1982#endif
1983
1955/* Future-safe accessor for struct task_struct's cpus_allowed. */ 1984/* Future-safe accessor for struct task_struct's cpus_allowed. */
1956#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) 1985#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
1957 1986
@@ -2586,7 +2615,9 @@ extern void ia64_set_curr_task(int cpu, struct task_struct *p);
2586void yield(void); 2615void yield(void);
2587 2616
2588union thread_union { 2617union thread_union {
2618#ifndef CONFIG_THREAD_INFO_IN_TASK
2589 struct thread_info thread_info; 2619 struct thread_info thread_info;
2620#endif
2590 unsigned long stack[THREAD_SIZE/sizeof(long)]; 2621 unsigned long stack[THREAD_SIZE/sizeof(long)];
2591}; 2622};
2592 2623
@@ -3074,10 +3105,34 @@ static inline void threadgroup_change_end(struct task_struct *tsk)
3074 cgroup_threadgroup_change_end(tsk); 3105 cgroup_threadgroup_change_end(tsk);
3075} 3106}
3076 3107
3077#ifndef __HAVE_THREAD_FUNCTIONS 3108#ifdef CONFIG_THREAD_INFO_IN_TASK
3109
3110static inline struct thread_info *task_thread_info(struct task_struct *task)
3111{
3112 return &task->thread_info;
3113}
3114
3115/*
3116 * When accessing the stack of a non-current task that might exit, use
3117 * try_get_task_stack() instead. task_stack_page will return a pointer
3118 * that could get freed out from under you.
3119 */
3120static inline void *task_stack_page(const struct task_struct *task)
3121{
3122 return task->stack;
3123}
3124
3125#define setup_thread_stack(new,old) do { } while(0)
3126
3127static inline unsigned long *end_of_stack(const struct task_struct *task)
3128{
3129 return task->stack;
3130}
3131
3132#elif !defined(__HAVE_THREAD_FUNCTIONS)
3078 3133
3079#define task_thread_info(task) ((struct thread_info *)(task)->stack) 3134#define task_thread_info(task) ((struct thread_info *)(task)->stack)
3080#define task_stack_page(task) ((task)->stack) 3135#define task_stack_page(task) ((void *)(task)->stack)
3081 3136
3082static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org) 3137static inline void setup_thread_stack(struct task_struct *p, struct task_struct *org)
3083{ 3138{
@@ -3104,6 +3159,24 @@ static inline unsigned long *end_of_stack(struct task_struct *p)
3104} 3159}
3105 3160
3106#endif 3161#endif
3162
3163#ifdef CONFIG_THREAD_INFO_IN_TASK
3164static inline void *try_get_task_stack(struct task_struct *tsk)
3165{
3166 return atomic_inc_not_zero(&tsk->stack_refcount) ?
3167 task_stack_page(tsk) : NULL;
3168}
3169
3170extern void put_task_stack(struct task_struct *tsk);
3171#else
3172static inline void *try_get_task_stack(struct task_struct *tsk)
3173{
3174 return task_stack_page(tsk);
3175}
3176
3177static inline void put_task_stack(struct task_struct *tsk) {}
3178#endif
3179
3107#define task_stack_end_corrupted(task) \ 3180#define task_stack_end_corrupted(task) \
3108 (*(end_of_stack(task)) != STACK_END_MAGIC) 3181 (*(end_of_stack(task)) != STACK_END_MAGIC)
3109 3182
@@ -3390,7 +3463,11 @@ static inline void ptrace_signal_wake_up(struct task_struct *t, bool resume)
3390 3463
3391static inline unsigned int task_cpu(const struct task_struct *p) 3464static inline unsigned int task_cpu(const struct task_struct *p)
3392{ 3465{
3466#ifdef CONFIG_THREAD_INFO_IN_TASK
3467 return p->cpu;
3468#else
3393 return task_thread_info(p)->cpu; 3469 return task_thread_info(p)->cpu;
3470#endif
3394} 3471}
3395 3472
3396static inline int task_node(const struct task_struct *p) 3473static inline int task_node(const struct task_struct *p)
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index 2b5b10eed74f..45f004e9cc59 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -13,6 +13,21 @@
13struct timespec; 13struct timespec;
14struct compat_timespec; 14struct compat_timespec;
15 15
16#ifdef CONFIG_THREAD_INFO_IN_TASK
17struct thread_info {
18 unsigned long flags; /* low level flags */
19};
20
21#define INIT_THREAD_INFO(tsk) \
22{ \
23 .flags = 0, \
24}
25#endif
26
27#ifdef CONFIG_THREAD_INFO_IN_TASK
28#define current_thread_info() ((struct thread_info *)current)
29#endif
30
16/* 31/*
17 * System call restart block. 32 * System call restart block.
18 */ 33 */