linux/include/linux/thread_info.h
<<
>>
Prefs
   1/* thread_info.h: common low-level thread information accessors
   2 *
   3 * Copyright (C) 2002  David Howells (dhowells@redhat.com)
   4 * - Incorporating suggestions made by Linus Torvalds
   5 */
   6
   7#ifndef _LINUX_THREAD_INFO_H
   8#define _LINUX_THREAD_INFO_H
   9
  10#include <linux/types.h>
  11#include <linux/bug.h>
  12#include <linux/restart_block.h>
  13
  14#ifdef CONFIG_THREAD_INFO_IN_TASK
  15/*
  16 * For CONFIG_THREAD_INFO_IN_TASK kernels we need <asm/current.h> for the
  17 * definition of current, but for !CONFIG_THREAD_INFO_IN_TASK kernels,
  18 * including <asm/current.h> can cause a circular dependency on some platforms.
  19 */
  20#include <asm/current.h>
  21#define current_thread_info() ((struct thread_info *)current)
  22#endif
  23
  24#include <linux/bitops.h>
  25
  26/*
  27 * For per-arch arch_within_stack_frames() implementations, defined in
  28 * asm/thread_info.h.
  29 */
  30enum {
  31        BAD_STACK = -1,
  32        NOT_STACK = 0,
  33        GOOD_FRAME,
  34        GOOD_STACK,
  35};
  36
  37#include <asm/thread_info.h>
  38
  39#ifdef __KERNEL__
  40
  41#ifdef CONFIG_DEBUG_STACK_USAGE
  42# define THREADINFO_GFP         (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK | \
  43                                 __GFP_ZERO)
  44#else
  45# define THREADINFO_GFP         (GFP_KERNEL_ACCOUNT | __GFP_NOTRACK)
  46#endif
  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 int test_and_set_ti_thread_flag(struct thread_info *ti, int flag)
  64{
  65        return test_and_set_bit(flag, (unsigned long *)&ti->flags);
  66}
  67
  68static inline int test_and_clear_ti_thread_flag(struct thread_info *ti, int flag)
  69{
  70        return test_and_clear_bit(flag, (unsigned long *)&ti->flags);
  71}
  72
  73static inline int test_ti_thread_flag(struct thread_info *ti, int flag)
  74{
  75        return test_bit(flag, (unsigned long *)&ti->flags);
  76}
  77
  78#define set_thread_flag(flag) \
  79        set_ti_thread_flag(current_thread_info(), flag)
  80#define clear_thread_flag(flag) \
  81        clear_ti_thread_flag(current_thread_info(), flag)
  82#define test_and_set_thread_flag(flag) \
  83        test_and_set_ti_thread_flag(current_thread_info(), flag)
  84#define test_and_clear_thread_flag(flag) \
  85        test_and_clear_ti_thread_flag(current_thread_info(), flag)
  86#define test_thread_flag(flag) \
  87        test_ti_thread_flag(current_thread_info(), flag)
  88
  89#define tif_need_resched() test_thread_flag(TIF_NEED_RESCHED)
  90
  91#ifndef CONFIG_HAVE_ARCH_WITHIN_STACK_FRAMES
  92static inline int arch_within_stack_frames(const void * const stack,
  93                                           const void * const stackend,
  94                                           const void *obj, unsigned long len)
  95{
  96        return 0;
  97}
  98#endif
  99
 100#ifdef CONFIG_HARDENED_USERCOPY
 101extern void __check_object_size(const void *ptr, unsigned long n,
 102                                        bool to_user);
 103
 104static __always_inline void check_object_size(const void *ptr, unsigned long n,
 105                                              bool to_user)
 106{
 107        if (!__builtin_constant_p(n))
 108                __check_object_size(ptr, n, to_user);
 109}
 110#else
 111static inline void check_object_size(const void *ptr, unsigned long n,
 112                                     bool to_user)
 113{ }
 114#endif /* CONFIG_HARDENED_USERCOPY */
 115
 116extern void __compiletime_error("copy source size is too small")
 117__bad_copy_from(void);
 118extern void __compiletime_error("copy destination size is too small")
 119__bad_copy_to(void);
 120
 121static inline void copy_overflow(int size, unsigned long count)
 122{
 123        WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
 124}
 125
 126static __always_inline bool
 127check_copy_size(const void *addr, size_t bytes, bool is_source)
 128{
 129        int sz = __compiletime_object_size(addr);
 130        if (unlikely(sz >= 0 && sz < bytes)) {
 131                if (!__builtin_constant_p(bytes))
 132                        copy_overflow(sz, bytes);
 133                else if (is_source)
 134                        __bad_copy_from();
 135                else
 136                        __bad_copy_to();
 137                return false;
 138        }
 139        check_object_size(addr, bytes, is_source);
 140        return true;
 141}
 142
 143#ifndef arch_setup_new_exec
 144static inline void arch_setup_new_exec(void) { }
 145#endif
 146
 147#endif  /* __KERNEL__ */
 148
 149#endif /* _LINUX_THREAD_INFO_H */
 150