xref: /openbmc/linux/include/linux/thread_info.h (revision af0a76e1)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /* thread_info.h: common low-level thread information accessors
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  * Copyright (C) 2002  David Howells (dhowells@redhat.com)
51da177e4SLinus Torvalds  * - Incorporating suggestions made by Linus Torvalds
61da177e4SLinus Torvalds  */
71da177e4SLinus Torvalds 
81da177e4SLinus Torvalds #ifndef _LINUX_THREAD_INFO_H
91da177e4SLinus Torvalds #define _LINUX_THREAD_INFO_H
101da177e4SLinus Torvalds 
11ce6bd420SSteven Rostedt #include <linux/types.h>
12f39650deSAndy Shevchenko #include <linux/limits.h>
13edd63a27SAl Viro #include <linux/bug.h>
1453d74d05SMark Rutland #include <linux/restart_block.h>
155abbe51aSOleg Nesterov #include <linux/errno.h>
16a332d86dSThomas Gleixner 
17c65eacbeSAndy Lutomirski #ifdef CONFIG_THREAD_INFO_IN_TASK
18dc3d2a67SMark Rutland /*
19dc3d2a67SMark Rutland  * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
20dc3d2a67SMark Rutland  * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
21dc3d2a67SMark Rutland  * including <asm/current.h> can cause a circular dependency on some platforms.
22dc3d2a67SMark Rutland  */
23dc3d2a67SMark Rutland #include <asm/current.h>
24c65eacbeSAndy Lutomirski #define current_thread_info() ((struct thread_info *)current)
25c65eacbeSAndy Lutomirski #endif
26c65eacbeSAndy Lutomirski 
271da177e4SLinus Torvalds #include <linux/bitops.h>
2896dc4f9fSSahara 
2996dc4f9fSSahara /*
3096dc4f9fSSahara  * For per-arch arch_within_stack_frames() implementations, defined in
3196dc4f9fSSahara  * asm/thread_info.h.
3296dc4f9fSSahara  */
3396dc4f9fSSahara enum {
3496dc4f9fSSahara 	BAD_STACK = -1,
3596dc4f9fSSahara 	NOT_STACK = 0,
3696dc4f9fSSahara 	GOOD_FRAME,
3796dc4f9fSSahara 	GOOD_STACK,
3896dc4f9fSSahara };
3996dc4f9fSSahara 
405903f61eSGabriel Krisman Bertazi #ifdef CONFIG_GENERIC_ENTRY
4123d67a54SGabriel Krisman Bertazi enum syscall_work_bit {
4223d67a54SGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SECCOMP,
43524666cbSGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT,
4464c19ba2SGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SYSCALL_TRACE,
4564eb35f7SGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SYSCALL_EMU,
46785dc4ebSGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SYSCALL_AUDIT,
471446e1dfSGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH,
486342adcaSGabriel Krisman Bertazi 	SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP,
4923d67a54SGabriel Krisman Bertazi };
5023d67a54SGabriel Krisman Bertazi 
5123d67a54SGabriel Krisman Bertazi #define SYSCALL_WORK_SECCOMP		BIT(SYSCALL_WORK_BIT_SECCOMP)
52524666cbSGabriel Krisman Bertazi #define SYSCALL_WORK_SYSCALL_TRACEPOINT	BIT(SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT)
5364c19ba2SGabriel Krisman Bertazi #define SYSCALL_WORK_SYSCALL_TRACE	BIT(SYSCALL_WORK_BIT_SYSCALL_TRACE)
5464eb35f7SGabriel Krisman Bertazi #define SYSCALL_WORK_SYSCALL_EMU	BIT(SYSCALL_WORK_BIT_SYSCALL_EMU)
55785dc4ebSGabriel Krisman Bertazi #define SYSCALL_WORK_SYSCALL_AUDIT	BIT(SYSCALL_WORK_BIT_SYSCALL_AUDIT)
561446e1dfSGabriel Krisman Bertazi #define SYSCALL_WORK_SYSCALL_USER_DISPATCH BIT(SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH)
576342adcaSGabriel Krisman Bertazi #define SYSCALL_WORK_SYSCALL_EXIT_TRAP	BIT(SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP)
585903f61eSGabriel Krisman Bertazi #endif
5923d67a54SGabriel Krisman Bertazi 
601da177e4SLinus Torvalds #include <asm/thread_info.h>
611da177e4SLinus Torvalds 
621da177e4SLinus Torvalds #ifdef __KERNEL__
631da177e4SLinus Torvalds 
645abbe51aSOleg Nesterov #ifndef arch_set_restart_data
655abbe51aSOleg Nesterov #define arch_set_restart_data(restart) do { } while (0)
665abbe51aSOleg Nesterov #endif
675abbe51aSOleg Nesterov 
set_restart_fn(struct restart_block * restart,long (* fn)(struct restart_block *))685abbe51aSOleg Nesterov static inline long set_restart_fn(struct restart_block *restart,
695abbe51aSOleg Nesterov 					long (*fn)(struct restart_block *))
705abbe51aSOleg Nesterov {
715abbe51aSOleg Nesterov 	restart->fn = fn;
725abbe51aSOleg Nesterov 	arch_set_restart_data(restart);
735abbe51aSOleg Nesterov 	return -ERESTART_RESTARTBLOCK;
745abbe51aSOleg Nesterov }
755abbe51aSOleg Nesterov 
7648ac3c18SMark Rutland #ifndef THREAD_ALIGN
7748ac3c18SMark Rutland #define THREAD_ALIGN	THREAD_SIZE
7848ac3c18SMark Rutland #endif
7948ac3c18SMark Rutland 
8075f296d9SLevin, Alexander (Sasha Levin) #define THREADINFO_GFP		(GFP_KERNEL_ACCOUNT | __GFP_ZERO)
812889f608SThomas Gleixner 
821da177e4SLinus Torvalds /*
831da177e4SLinus Torvalds  * flag set/clear/test wrappers
841da177e4SLinus Torvalds  * - pass TIF_xxxx constants to these functions
851da177e4SLinus Torvalds  */
861da177e4SLinus Torvalds 
set_ti_thread_flag(struct thread_info * ti,int flag)871da177e4SLinus Torvalds static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
881da177e4SLinus Torvalds {
895548fecdSJeremy Fitzhardinge 	set_bit(flag, (unsigned long *)&ti->flags);
901da177e4SLinus Torvalds }
911da177e4SLinus Torvalds 
clear_ti_thread_flag(struct thread_info * ti,int flag)921da177e4SLinus Torvalds static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
931da177e4SLinus Torvalds {
945548fecdSJeremy Fitzhardinge 	clear_bit(flag, (unsigned long *)&ti->flags);
951da177e4SLinus Torvalds }
961da177e4SLinus Torvalds 
update_ti_thread_flag(struct thread_info * ti,int flag,bool value)9793ee37c2SDave Martin static inline void update_ti_thread_flag(struct thread_info *ti, int flag,
9893ee37c2SDave Martin 					 bool value)
9993ee37c2SDave Martin {
10093ee37c2SDave Martin 	if (value)
10193ee37c2SDave Martin 		set_ti_thread_flag(ti, flag);
10293ee37c2SDave Martin 	else
10393ee37c2SDave Martin 		clear_ti_thread_flag(ti, flag);
10493ee37c2SDave Martin }
10593ee37c2SDave Martin 
test_and_set_ti_thread_flag(struct thread_info * ti,int flag)1061da177e4SLinus Torvalds static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
1071da177e4SLinus Torvalds {
1085548fecdSJeremy Fitzhardinge 	return test_and_set_bit(flag, (unsigned long *)&ti->flags);
1091da177e4SLinus Torvalds }
1101da177e4SLinus Torvalds 
test_and_clear_ti_thread_flag(struct thread_info * ti,int flag)1111da177e4SLinus Torvalds static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag)
1121da177e4SLinus Torvalds {
1135548fecdSJeremy Fitzhardinge 	return test_and_clear_bit(flag, (unsigned long *)&ti->flags);
1141da177e4SLinus Torvalds }
1151da177e4SLinus Torvalds 
test_ti_thread_flag(struct thread_info * ti,int flag)1161da177e4SLinus Torvalds static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
1171da177e4SLinus Torvalds {
1185548fecdSJeremy Fitzhardinge 	return test_bit(flag, (unsigned long *)&ti->flags);
1191da177e4SLinus Torvalds }
1201da177e4SLinus Torvalds 
1217ad63984SMark Rutland /*
1227ad63984SMark Rutland  * This may be used in noinstr code, and needs to be __always_inline to prevent
1237ad63984SMark Rutland  * inadvertent instrumentation.
1247ad63984SMark Rutland  */
read_ti_thread_flags(struct thread_info * ti)1257ad63984SMark Rutland static __always_inline unsigned long read_ti_thread_flags(struct thread_info *ti)
1267ad63984SMark Rutland {
1277ad63984SMark Rutland 	return READ_ONCE(ti->flags);
1287ad63984SMark Rutland }
1297ad63984SMark Rutland 
1303b66a1edSRoman Zippel #define set_thread_flag(flag) \
1313b66a1edSRoman Zippel 	set_ti_thread_flag(current_thread_info(), flag)
1323b66a1edSRoman Zippel #define clear_thread_flag(flag) \
1333b66a1edSRoman Zippel 	clear_ti_thread_flag(current_thread_info(), flag)
13493ee37c2SDave Martin #define update_thread_flag(flag, value) \
13593ee37c2SDave Martin 	update_ti_thread_flag(current_thread_info(), flag, value)
1363b66a1edSRoman Zippel #define test_and_set_thread_flag(flag) \
1373b66a1edSRoman Zippel 	test_and_set_ti_thread_flag(current_thread_info(), flag)
1383b66a1edSRoman Zippel #define test_and_clear_thread_flag(flag) \
1393b66a1edSRoman Zippel 	test_and_clear_ti_thread_flag(current_thread_info(), flag)
1403b66a1edSRoman Zippel #define test_thread_flag(flag) \
1413b66a1edSRoman Zippel 	test_ti_thread_flag(current_thread_info(), flag)
1427ad63984SMark Rutland #define read_thread_flags() \
1437ad63984SMark Rutland 	read_ti_thread_flags(current_thread_info())
1447ad63984SMark Rutland 
1457ad63984SMark Rutland #define read_task_thread_flags(t) \
1467ad63984SMark Rutland 	read_ti_thread_flags(task_thread_info(t))
1471da177e4SLinus Torvalds 
1483136b93cSGabriel Krisman Bertazi #ifdef CONFIG_GENERIC_ENTRY
1493136b93cSGabriel Krisman Bertazi #define set_syscall_work(fl) \
1503136b93cSGabriel Krisman Bertazi 	set_bit(SYSCALL_WORK_BIT_##fl, &current_thread_info()->syscall_work)
1513136b93cSGabriel Krisman Bertazi #define test_syscall_work(fl) \
1523136b93cSGabriel Krisman Bertazi 	test_bit(SYSCALL_WORK_BIT_##fl, &current_thread_info()->syscall_work)
1533136b93cSGabriel Krisman Bertazi #define clear_syscall_work(fl) \
1543136b93cSGabriel Krisman Bertazi 	clear_bit(SYSCALL_WORK_BIT_##fl, &current_thread_info()->syscall_work)
1553136b93cSGabriel Krisman Bertazi 
1563136b93cSGabriel Krisman Bertazi #define set_task_syscall_work(t, fl) \
1573136b93cSGabriel Krisman Bertazi 	set_bit(SYSCALL_WORK_BIT_##fl, &task_thread_info(t)->syscall_work)
1583136b93cSGabriel Krisman Bertazi #define test_task_syscall_work(t, fl) \
1593136b93cSGabriel Krisman Bertazi 	test_bit(SYSCALL_WORK_BIT_##fl, &task_thread_info(t)->syscall_work)
1603136b93cSGabriel Krisman Bertazi #define clear_task_syscall_work(t, fl) \
1613136b93cSGabriel Krisman Bertazi 	clear_bit(SYSCALL_WORK_BIT_##fl, &task_thread_info(t)->syscall_work)
1623136b93cSGabriel Krisman Bertazi 
1633136b93cSGabriel Krisman Bertazi #else /* CONFIG_GENERIC_ENTRY */
1643136b93cSGabriel Krisman Bertazi 
1653136b93cSGabriel Krisman Bertazi #define set_syscall_work(fl)						\
1665903f61eSGabriel Krisman Bertazi 	set_ti_thread_flag(current_thread_info(), TIF_##fl)
1673136b93cSGabriel Krisman Bertazi #define test_syscall_work(fl) \
1685903f61eSGabriel Krisman Bertazi 	test_ti_thread_flag(current_thread_info(), TIF_##fl)
1693136b93cSGabriel Krisman Bertazi #define clear_syscall_work(fl) \
1705903f61eSGabriel Krisman Bertazi 	clear_ti_thread_flag(current_thread_info(), TIF_##fl)
1713136b93cSGabriel Krisman Bertazi 
1723136b93cSGabriel Krisman Bertazi #define set_task_syscall_work(t, fl) \
1733136b93cSGabriel Krisman Bertazi 	set_ti_thread_flag(task_thread_info(t), TIF_##fl)
1743136b93cSGabriel Krisman Bertazi #define test_task_syscall_work(t, fl) \
1753136b93cSGabriel Krisman Bertazi 	test_ti_thread_flag(task_thread_info(t), TIF_##fl)
1763136b93cSGabriel Krisman Bertazi #define clear_task_syscall_work(t, fl) \
1773136b93cSGabriel Krisman Bertazi 	clear_ti_thread_flag(task_thread_info(t), TIF_##fl)
1783136b93cSGabriel Krisman Bertazi #endif /* !CONFIG_GENERIC_ENTRY */
1793136b93cSGabriel Krisman Bertazi 
180e4df1511SPeter Zijlstra #ifdef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
181e4df1511SPeter Zijlstra 
tif_need_resched(void)182e4df1511SPeter Zijlstra static __always_inline bool tif_need_resched(void)
183e4df1511SPeter Zijlstra {
184e4df1511SPeter Zijlstra 	return arch_test_bit(TIF_NEED_RESCHED,
185e4df1511SPeter Zijlstra 			     (unsigned long *)(&current_thread_info()->flags));
186e4df1511SPeter Zijlstra }
187e4df1511SPeter Zijlstra 
188e4df1511SPeter Zijlstra #else
189e4df1511SPeter Zijlstra 
tif_need_resched(void)190e4df1511SPeter Zijlstra static __always_inline bool tif_need_resched(void)
191e4df1511SPeter Zijlstra {
192e4df1511SPeter Zijlstra 	return test_bit(TIF_NEED_RESCHED,
193e4df1511SPeter Zijlstra 			(unsigned long *)(&current_thread_info()->flags));
194e4df1511SPeter Zijlstra }
195e4df1511SPeter Zijlstra 
196e4df1511SPeter Zijlstra #endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
197ea811747SPeter Zijlstra 
1980f60a8efSKees Cook #ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES
arch_within_stack_frames(const void * const stack,const void * const stackend,const void * obj,unsigned long len)1990f60a8efSKees Cook static inline int arch_within_stack_frames(const void * const stack,
2000f60a8efSKees Cook 					   const void * const stackend,
2010f60a8efSKees Cook 					   const void *obj, unsigned long len)
2020f60a8efSKees Cook {
2030f60a8efSKees Cook 	return 0;
2040f60a8efSKees Cook }
2050f60a8efSKees Cook #endif
2060f60a8efSKees Cook 
207f5509cc1SKees Cook #ifdef CONFIG_HARDENED_USERCOPY
208f5509cc1SKees Cook extern void __check_object_size(const void *ptr, unsigned long n,
209f5509cc1SKees Cook 					bool to_user);
210f5509cc1SKees Cook 
check_object_size(const void * ptr,unsigned long n,bool to_user)211a85d6b82SKees Cook static __always_inline void check_object_size(const void *ptr, unsigned long n,
212f5509cc1SKees Cook 					      bool to_user)
213f5509cc1SKees Cook {
21481409e9eSKees Cook 	if (!__builtin_constant_p(n))
215f5509cc1SKees Cook 		__check_object_size(ptr, n, to_user);
216f5509cc1SKees Cook }
217f5509cc1SKees Cook #else
check_object_size(const void * ptr,unsigned long n,bool to_user)218f5509cc1SKees Cook static inline void check_object_size(const void *ptr, unsigned long n,
219f5509cc1SKees Cook 				     bool to_user)
220f5509cc1SKees Cook { }
221f5509cc1SKees Cook #endif /* CONFIG_HARDENED_USERCOPY */
222f5509cc1SKees Cook 
223b0377fedSAl Viro extern void __compiletime_error("copy source size is too small")
224b0377fedSAl Viro __bad_copy_from(void);
225b0377fedSAl Viro extern void __compiletime_error("copy destination size is too small")
226b0377fedSAl Viro __bad_copy_to(void);
227b0377fedSAl Viro 
228ad7489d5SChristophe Leroy void __copy_overflow(int size, unsigned long count);
229ad7489d5SChristophe Leroy 
copy_overflow(int size,unsigned long count)230b0377fedSAl Viro static inline void copy_overflow(int size, unsigned long count)
231b0377fedSAl Viro {
232ad7489d5SChristophe Leroy 	if (IS_ENABLED(CONFIG_BUG))
233ad7489d5SChristophe Leroy 		__copy_overflow(size, count);
234b0377fedSAl Viro }
235b0377fedSAl Viro 
2369dd819a1SKees Cook static __always_inline __must_check bool
check_copy_size(const void * addr,size_t bytes,bool is_source)237b0377fedSAl Viro check_copy_size(const void *addr, size_t bytes, bool is_source)
238b0377fedSAl Viro {
239c80d92fbSKees Cook 	int sz = __builtin_object_size(addr, 0);
240b0377fedSAl Viro 	if (unlikely(sz >= 0 && sz < bytes)) {
241b0377fedSAl Viro 		if (!__builtin_constant_p(bytes))
242b0377fedSAl Viro 			copy_overflow(sz, bytes);
243b0377fedSAl Viro 		else if (is_source)
244b0377fedSAl Viro 			__bad_copy_from();
245b0377fedSAl Viro 		else
246b0377fedSAl Viro 			__bad_copy_to();
247b0377fedSAl Viro 		return false;
248b0377fedSAl Viro 	}
2496d13de14SKees Cook 	if (WARN_ON_ONCE(bytes > INT_MAX))
2506d13de14SKees Cook 		return false;
251b0377fedSAl Viro 	check_object_size(addr, bytes, is_source);
252b0377fedSAl Viro 	return true;
253b0377fedSAl Viro }
254b0377fedSAl Viro 
255e9ea1e7fSKyle Huey #ifndef arch_setup_new_exec
arch_setup_new_exec(void)256e9ea1e7fSKyle Huey static inline void arch_setup_new_exec(void) { }
257e9ea1e7fSKyle Huey #endif
258e9ea1e7fSKyle Huey 
259*af0a76e1SArnd Bergmann void arch_task_cache_init(void); /* for CONFIG_SH */
260*af0a76e1SArnd Bergmann void arch_release_task_struct(struct task_struct *tsk);
261*af0a76e1SArnd Bergmann int arch_dup_task_struct(struct task_struct *dst,
262*af0a76e1SArnd Bergmann 				struct task_struct *src);
263*af0a76e1SArnd Bergmann 
2644e4c22c7SRoland McGrath #endif	/* __KERNEL__ */
2651da177e4SLinus Torvalds 
2661da177e4SLinus Torvalds #endif /* _LINUX_THREAD_INFO_H */
267