linux/include/linux/thread_info.h
<<
>>
Prefs
   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/bug.h>
  13#include <linux/restart_block.h>
  14
  15#ifdef CONFIG_THREAD_INFO_IN_TASK
  16/*
  17 * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
  18 * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
  19 * including <asm/current.h> can cause a circular dependency on some platforms.
  20 */
  21#include <asm/current.h>
  22#define current_thread_info() ((struct thread_info *)current)
  23#endif
  24
  25#include <linux/bitops.h>
  26
  27/*
  28 * For per-arch arch_within_stack_frames() implementations, defined in
  29 * asm/thread_info.h.
  30 */
  31enum {
  32        BAD_STACK = -1,
  33        NOT_STACK = 0,
  34        GOOD_FRAME,
  35        GOOD_STACK,
  36};
  37
  38#include <asm/thread_info.h>
  39
  40#ifdef __KERNEL__
  41
  42#ifndef THREAD_ALIGN
  43#define THREAD_ALIGN    THREAD_SIZE
  44#endif
  45
  46#define THREADINFO_GFP          (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
  47
  48/*
  49 * flag set/clear/test wrappers
  50 * - pass TIF_xxxx constants to these functions
  51 */
  52
  53static inline void set_ti_thread_flag(struct thread_info *ti, int flag)
  54{
  55        set_bit(flag, (unsigned long *)&ti->flags);
  56}
  57
  58static inline void clear_ti_thread_flag(struct thread_info *ti, int flag)
  59{
  60        clear_bit(flag, (unsigned long *)&ti->flags);
  61}
  62
  63static inline void update_ti_thread_flag(struct thread_info *ti, int flag,
  64                                         bool value)
  65{
  66        if (value)
  67                set_ti_thread_flag(ti, flag);
  68        else
  69                clear_ti_thread_flag(ti, flag);
  70}
  71
  72static inline int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
  73{
  74        return test_and_set_bit(flag, (unsigned long *)&ti->flags);
  75}
  76
  77static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag)
  78{
  79        return test_and_clear_bit(flag, (unsigned long *)&ti->flags);
  80}
  81
  82static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
  83{
  84        return test_bit(flag, (unsigned long *)&ti->flags);
  85}
  86
  87#define set_thread_flag(flag) \
  88        set_ti_thread_flag(current_thread_info(), flag)
  89#define clear_thread_flag(flag) \
  90        clear_ti_thread_flag(current_thread_info(), flag)
  91#define update_thread_flag(flag, value) \
  92        update_ti_thread_flag(current_thread_info(), flag, value)
  93#define test_and_set_thread_flag(flag) \
  94        test_and_set_ti_thread_flag(current_thread_info(), flag)
  95#define test_and_clear_thread_flag(flag) \
  96        test_and_clear_ti_thread_flag(current_thread_info(), flag)
  97#define test_thread_flag(flag) \
  98        test_ti_thread_flag(current_thread_info(), flag)
  99
 100#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)
 101
 102#ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES
 103static inline int arch_within_stack_frames(const void * const stack,
 104                                           const void * const stackend,
 105                                           const void *obj, unsigned long len)
 106{
 107        return 0;
 108}
 109#endif
 110
 111#ifdef CONFIG_HARDENED_USERCOPY
 112extern void __check_object_size(const void *ptr, unsigned long n,
 113                                        bool to_user);
 114
 115static __always_inline void check_object_size(const void *ptr, unsigned long n,
 116                                              bool to_user)
 117{
 118        if (!__builtin_constant_p(n))
 119                __check_object_size(ptr, n, to_user);
 120}
 121#else
 122static inline void check_object_size(const void *ptr, unsigned long n,
 123                                     bool to_user)
 124{ }
 125#endif /* CONFIG_HARDENED_USERCOPY */
 126
 127extern void __compiletime_error("copy source size is too small")
 128__bad_copy_from(void);
 129extern void __compiletime_error("copy destination size is too small")
 130__bad_copy_to(void);
 131
 132static inline void copy_overflow(int size, unsigned long count)
 133{
 134        WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
 135}
 136
 137static __always_inline bool
 138check_copy_size(const void *addr, size_t bytes, bool is_source)
 139{
 140        int sz = __compiletime_object_size(addr);
 141        if (unlikely(sz >= 0 && sz < bytes)) {
 142                if (!__builtin_constant_p(bytes))
 143                        copy_overflow(sz, bytes);
 144                else if (is_source)
 145                        __bad_copy_from();
 146                else
 147                        __bad_copy_to();
 148                return false;
 149        }
 150        check_object_size(addr, bytes, is_source);
 151        return true;
 152}
 153
 154#ifndef arch_setup_new_exec
 155static inline void arch_setup_new_exec(void) { }
 156#endif
 157
 158#endif  /* __KERNEL__ */
 159
 160#endif /* _LINUX_THREAD_INFO_H */
 161