xref: /linux/include/linux/thread_info.h (revision 6589b3d76db2d6adbf8f2084c303fb24252a0dc6)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* thread_info.h: common low-level thread information accessors
3  *
4  * Copyright (C) 2002  David Howells (dhowells@redhat.com)
5  * - Incorporating suggestions made by Linus Torvalds
6  */
7 
8 #ifndef _LINUX_THREAD_INFO_H
9 #define _LINUX_THREAD_INFO_H
10 
11 #include <linux/types.h>
12 #include <linux/limits.h>
13 #include <linux/bug.h>
14 #include <linux/restart_block.h>
15 #include <linux/errno.h>
16 
17 #ifdef CONFIG_THREAD_INFO_IN_TASK
18 /*
19  * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
20  * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
21  * including <asm/current.h> can cause a circular dependency on some platforms.
22  */
23 #include <asm/current.h>
24 #define current_thread_info() ((struct thread_info *)current)
25 #endif
26 
27 #include <linux/bitops.h>
28 
29 /*
30  * For per-arch arch_within_stack_frames() implementations, defined in
31  * asm/thread_info.h.
32  */
33 enum {
34 	BAD_STACK = -1,
35 	NOT_STACK = 0,
36 	GOOD_FRAME,
37 	GOOD_STACK,
38 };
39 
40 #ifdef CONFIG_GENERIC_ENTRY
41 enum syscall_work_bit {
42 	SYSCALL_WORK_BIT_SECCOMP,
43 	SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT,
44 	SYSCALL_WORK_BIT_SYSCALL_TRACE,
45 	SYSCALL_WORK_BIT_SYSCALL_EMU,
46 	SYSCALL_WORK_BIT_SYSCALL_AUDIT,
47 	SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH,
48 	SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP,
49 	SYSCALL_WORK_BIT_SYSCALL_RSEQ_SLICE,
50 };
51 
52 #define SYSCALL_WORK_SECCOMP			BIT(SYSCALL_WORK_BIT_SECCOMP)
53 #define SYSCALL_WORK_SYSCALL_TRACEPOINT		BIT(SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT)
54 #define SYSCALL_WORK_SYSCALL_TRACE		BIT(SYSCALL_WORK_BIT_SYSCALL_TRACE)
55 #define SYSCALL_WORK_SYSCALL_EMU		BIT(SYSCALL_WORK_BIT_SYSCALL_EMU)
56 #define SYSCALL_WORK_SYSCALL_AUDIT		BIT(SYSCALL_WORK_BIT_SYSCALL_AUDIT)
57 #define SYSCALL_WORK_SYSCALL_USER_DISPATCH	BIT(SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH)
58 #define SYSCALL_WORK_SYSCALL_EXIT_TRAP		BIT(SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP)
59 #define SYSCALL_WORK_SYSCALL_RSEQ_SLICE		BIT(SYSCALL_WORK_BIT_SYSCALL_RSEQ_SLICE)
60 #endif
61 
62 #include <asm/thread_info.h>
63 
64 #ifndef TIF_NEED_RESCHED_LAZY
65 #ifdef CONFIG_ARCH_HAS_PREEMPT_LAZY
66 #error Inconsistent PREEMPT_LAZY
67 #endif
68 #define TIF_NEED_RESCHED_LAZY TIF_NEED_RESCHED
69 #define _TIF_NEED_RESCHED_LAZY _TIF_NEED_RESCHED
70 #endif
71 
72 #ifndef TIF_RSEQ
73 # define TIF_RSEQ	TIF_NOTIFY_RESUME
74 # define _TIF_RSEQ	_TIF_NOTIFY_RESUME
75 #endif
76 
77 #ifdef __KERNEL__
78 
79 #ifndef arch_set_restart_data
80 #define arch_set_restart_data(restart) do { } while (0)
81 #endif
82 
83 static inline long set_restart_fn(struct restart_block *restart,
84 					long (*fn)(struct restart_block *))
85 {
86 	restart->fn = fn;
87 	arch_set_restart_data(restart);
88 	return -ERESTART_RESTARTBLOCK;
89 }
90 
91 #ifndef THREAD_ALIGN
92 #define THREAD_ALIGN	THREAD_SIZE
93 #endif
94 
95 #define THREADINFO_GFP		(GFP_KERNEL_ACCOUNT | __GFP_ZERO)
96 
97 /*
98  * flag set/clear/test wrappers
99  * - pass TIF_xxxx constants to these functions
100  */
101 
102 static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
103 {
104 	set_bit(flag, (unsigned long *)&ti->flags);
105 }
106 
107 static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
108 {
109 	clear_bit(flag, (unsigned long *)&ti->flags);
110 }
111 
112 static inline void update_ti_thread_flag(struct thread_info *ti, int flag,
113 					 bool value)
114 {
115 	if (value)
116 		set_ti_thread_flag(ti, flag);
117 	else
118 		clear_ti_thread_flag(ti, flag);
119 }
120 
121 static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
122 {
123 	return test_and_set_bit(flag, (unsigned long *)&ti->flags);
124 }
125 
126 static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag)
127 {
128 	return test_and_clear_bit(flag, (unsigned long *)&ti->flags);
129 }
130 
131 static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
132 {
133 	return test_bit(flag, (unsigned long *)&ti->flags);
134 }
135 
136 /*
137  * This may be used in noinstr code, and needs to be __always_inline to prevent
138  * inadvertent instrumentation.
139  */
140 static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti)
141 {
142 	return READ_ONCE(ti->flags);
143 }
144 
145 #define set_thread_flag(flag) \
146 	set_ti_thread_flag(current_thread_info(), flag)
147 #define clear_thread_flag(flag) \
148 	clear_ti_thread_flag(current_thread_info(), flag)
149 #define update_thread_flag(flag, value) \
150 	update_ti_thread_flag(current_thread_info(), flag, value)
151 #define test_and_set_thread_flag(flag) \
152 	test_and_set_ti_thread_flag(current_thread_info(), flag)
153 #define test_and_clear_thread_flag(flag) \
154 	test_and_clear_ti_thread_flag(current_thread_info(), flag)
155 #define test_thread_flag(flag) \
156 	test_ti_thread_flag(current_thread_info(), flag)
157 #define read_thread_flags() \
158 	read_ti_thread_flags(current_thread_info())
159 
160 #define read_task_thread_flags(t) \
161 	read_ti_thread_flags(task_thread_info(t))
162 
163 #ifdef CONFIG_GENERIC_ENTRY
164 #define set_syscall_work(fl) \
165 	set_bit(SYSCALL_WORK_BIT_##fl, &current_thread_info()->syscall_work)
166 #define test_syscall_work(fl) \
167 	test_bit(SYSCALL_WORK_BIT_##fl, &current_thread_info()->syscall_work)
168 #define clear_syscall_work(fl) \
169 	clear_bit(SYSCALL_WORK_BIT_##fl, &current_thread_info()->syscall_work)
170 
171 #define set_task_syscall_work(t, fl) \
172 	set_bit(SYSCALL_WORK_BIT_##fl, &task_thread_info(t)->syscall_work)
173 #define test_task_syscall_work(t, fl) \
174 	test_bit(SYSCALL_WORK_BIT_##fl, &task_thread_info(t)->syscall_work)
175 #define clear_task_syscall_work(t, fl) \
176 	clear_bit(SYSCALL_WORK_BIT_##fl, &task_thread_info(t)->syscall_work)
177 
178 #else /* CONFIG_GENERIC_ENTRY */
179 
180 #define set_syscall_work(fl)						\
181 	set_ti_thread_flag(current_thread_info(), TIF_##fl)
182 #define test_syscall_work(fl) \
183 	test_ti_thread_flag(current_thread_info(), TIF_##fl)
184 #define clear_syscall_work(fl) \
185 	clear_ti_thread_flag(current_thread_info(), TIF_##fl)
186 
187 #define set_task_syscall_work(t, fl) \
188 	set_ti_thread_flag(task_thread_info(t), TIF_##fl)
189 #define test_task_syscall_work(t, fl) \
190 	test_ti_thread_flag(task_thread_info(t), TIF_##fl)
191 #define clear_task_syscall_work(t, fl) \
192 	clear_ti_thread_flag(task_thread_info(t), TIF_##fl)
193 #endif /* !CONFIG_GENERIC_ENTRY */
194 
195 #ifdef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
196 
197 static __always_inline bool tif_test_bit(int bit)
198 {
199 	return arch_test_bit(bit,
200 			     (unsigned long *)(&current_thread_info()->flags));
201 }
202 
203 #else
204 
205 static __always_inline bool tif_test_bit(int bit)
206 {
207 	return test_bit(bit,
208 			(unsigned long *)(&current_thread_info()->flags));
209 }
210 
211 #endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
212 
213 static __always_inline bool tif_need_resched(void)
214 {
215 	return tif_test_bit(TIF_NEED_RESCHED);
216 }
217 
218 #ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES
219 static inline int arch_within_stack_frames(const void * const stack,
220 					   const void * const stackend,
221 					   const void *obj, unsigned long len)
222 {
223 	return 0;
224 }
225 #endif
226 
227 #ifndef arch_setup_new_exec
228 static inline void arch_setup_new_exec(void) { }
229 #endif
230 
231 void arch_task_cache_init(void); /* for CONFIG_SH */
232 void arch_release_task_struct(struct task_struct *tsk);
233 int arch_dup_task_struct(struct task_struct *dst,
234 				struct task_struct *src);
235 
236 #endif	/* __KERNEL__ */
237 
238 #endif /* _LINUX_THREAD_INFO_H */
239