mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
![Yonghong Song](/assets/img/avatar_default.png)
The __user attribute is currently mainly used by sparse for type checking. The attribute indicates whether a memory access is in user memory address space or not. Such information is important during tracing kernel internal functions or data structures as accessing user memory often has different mechanisms compared to accessing kernel memory. For example, the perf-probe needs explicit command line specification to indicate a particular argument or string in user-space memory ([1], [2], [3]). Currently, vmlinux BTF is available in kernel with many distributions. If __user attribute information is available in vmlinux BTF, the explicit user memory access information from users will not be necessary as the kernel can figure it out by itself with vmlinux BTF. Besides the above possible use for perf/probe, another use case is for bpf verifier. Currently, for bpf BPF_PROG_TYPE_TRACING type of bpf programs, users can write direct code like p->m1->m2 and "p" could be a function parameter. Without __user information in BTF, the verifier will assume p->m1 accessing kernel memory and will generate normal loads. Let us say "p" actually tagged with __user in the source code. In such cases, p->m1 is actually accessing user memory and direct load is not right and may produce incorrect result. For such cases, bpf_probe_read_user() will be the correct way to read p->m1. To support encoding __user information in BTF, a new attribute __attribute__((btf_type_tag("<arbitrary_string>"))) is implemented in clang ([4]). For example, if we have #define __user __attribute__((btf_type_tag("user"))) during kernel compilation, the attribute "user" information will be preserved in dwarf. After pahole converting dwarf to BTF, __user information will be available in vmlinux BTF. The following is an example with latest upstream clang (clang14) and pahole 1.23: [$ ~] cat test.c #define __user __attribute__((btf_type_tag("user"))) int foo(int __user *arg) { return *arg; } [$ ~] clang -O2 -g -c test.c [$ ~] pahole -JV test.o ... [1] INT int size=4 nr_bits=32 encoding=SIGNED [2] TYPE_TAG user type_id=1 [3] PTR (anon) type_id=2 [4] FUNC_PROTO (anon) return=1 args=(3 arg) [5] FUNC foo type_id=4 [$ ~] You can see for the function argument "int __user *arg", its type is described as PTR -> TYPE_TAG(user) -> INT The kernel can use this information for bpf verification or other use cases. Current btf_type_tag is only supported in clang (>= clang14) and pahole (>= 1.23). gcc support is also proposed and under development ([5]). [1] http://lkml.kernel.org/r/155789874562.26965.10836126971405890891.stgit@devnote2 [2] http://lkml.kernel.org/r/155789872187.26965.4468456816590888687.stgit@devnote2 [3] http://lkml.kernel.org/r/155789871009.26965.14167558859557329331.stgit@devnote2 [4] https://reviews.llvm.org/D111199 [5] https://lore.kernel.org/bpf/0cbeb2fb-1a18-f690-e360-24b1c90c2a91@fb.com/ Signed-off-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/r/20220127154600.652613-1-yhs@fb.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
374 lines
12 KiB
C
374 lines
12 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef __LINUX_COMPILER_TYPES_H
|
|
#define __LINUX_COMPILER_TYPES_H
|
|
|
|
#ifndef __ASSEMBLY__
|
|
|
|
#ifdef __CHECKER__
|
|
/* address spaces */
|
|
# define __kernel __attribute__((address_space(0)))
|
|
# define __user __attribute__((noderef, address_space(__user)))
|
|
# define __iomem __attribute__((noderef, address_space(__iomem)))
|
|
# define __percpu __attribute__((noderef, address_space(__percpu)))
|
|
# define __rcu __attribute__((noderef, address_space(__rcu)))
|
|
static inline void __chk_user_ptr(const volatile void __user *ptr) { }
|
|
static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
|
|
/* context/locking */
|
|
# define __must_hold(x) __attribute__((context(x,1,1)))
|
|
# define __acquires(x) __attribute__((context(x,0,1)))
|
|
# define __releases(x) __attribute__((context(x,1,0)))
|
|
# define __acquire(x) __context__(x,1)
|
|
# define __release(x) __context__(x,-1)
|
|
# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0)
|
|
/* other */
|
|
# define __force __attribute__((force))
|
|
# define __nocast __attribute__((nocast))
|
|
# define __safe __attribute__((safe))
|
|
# define __private __attribute__((noderef))
|
|
# define ACCESS_PRIVATE(p, member) (*((typeof((p)->member) __force *) &(p)->member))
|
|
#else /* __CHECKER__ */
|
|
/* address spaces */
|
|
# define __kernel
|
|
# ifdef STRUCTLEAK_PLUGIN
|
|
# define __user __attribute__((user))
|
|
# elif defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
|
|
__has_attribute(btf_type_tag)
|
|
# define __user __attribute__((btf_type_tag("user")))
|
|
# else
|
|
# define __user
|
|
# endif
|
|
# define __iomem
|
|
# define __percpu
|
|
# define __rcu
|
|
# define __chk_user_ptr(x) (void)0
|
|
# define __chk_io_ptr(x) (void)0
|
|
/* context/locking */
|
|
# define __must_hold(x)
|
|
# define __acquires(x)
|
|
# define __releases(x)
|
|
# define __acquire(x) (void)0
|
|
# define __release(x) (void)0
|
|
# define __cond_lock(x,c) (c)
|
|
/* other */
|
|
# define __force
|
|
# define __nocast
|
|
# define __safe
|
|
# define __private
|
|
# define ACCESS_PRIVATE(p, member) ((p)->member)
|
|
# define __builtin_warning(x, y...) (1)
|
|
#endif /* __CHECKER__ */
|
|
|
|
/* Indirect macros required for expanded argument pasting, eg. __LINE__. */
|
|
#define ___PASTE(a,b) a##b
|
|
#define __PASTE(a,b) ___PASTE(a,b)
|
|
|
|
#ifdef __KERNEL__
|
|
|
|
/* Attributes */
|
|
#include <linux/compiler_attributes.h>
|
|
|
|
/* Builtins */
|
|
|
|
/*
|
|
* __has_builtin is supported on gcc >= 10, clang >= 3 and icc >= 21.
|
|
* In the meantime, to support gcc < 10, we implement __has_builtin
|
|
* by hand.
|
|
*/
|
|
#ifndef __has_builtin
|
|
#define __has_builtin(x) (0)
|
|
#endif
|
|
|
|
/* Compiler specific macros. */
|
|
#ifdef __clang__
|
|
#include <linux/compiler-clang.h>
|
|
#elif defined(__INTEL_COMPILER)
|
|
#include <linux/compiler-intel.h>
|
|
#elif defined(__GNUC__)
|
|
/* The above compilers also define __GNUC__, so order is important here. */
|
|
#include <linux/compiler-gcc.h>
|
|
#else
|
|
#error "Unknown compiler"
|
|
#endif
|
|
|
|
/*
|
|
* Some architectures need to provide custom definitions of macros provided
|
|
* by linux/compiler-*.h, and can do so using asm/compiler.h. We include that
|
|
* conditionally rather than using an asm-generic wrapper in order to avoid
|
|
* build failures if any C compilation, which will include this file via an
|
|
* -include argument in c_flags, occurs prior to the asm-generic wrappers being
|
|
* generated.
|
|
*/
|
|
#ifdef CONFIG_HAVE_ARCH_COMPILER_H
|
|
#include <asm/compiler.h>
|
|
#endif
|
|
|
|
struct ftrace_branch_data {
|
|
const char *func;
|
|
const char *file;
|
|
unsigned line;
|
|
union {
|
|
struct {
|
|
unsigned long correct;
|
|
unsigned long incorrect;
|
|
};
|
|
struct {
|
|
unsigned long miss;
|
|
unsigned long hit;
|
|
};
|
|
unsigned long miss_hit[2];
|
|
};
|
|
};
|
|
|
|
struct ftrace_likely_data {
|
|
struct ftrace_branch_data data;
|
|
unsigned long constant;
|
|
};
|
|
|
|
#if defined(CC_USING_HOTPATCH)
|
|
#define notrace __attribute__((hotpatch(0, 0)))
|
|
#elif defined(CC_USING_PATCHABLE_FUNCTION_ENTRY)
|
|
#define notrace __attribute__((patchable_function_entry(0, 0)))
|
|
#else
|
|
#define notrace __attribute__((__no_instrument_function__))
|
|
#endif
|
|
|
|
/*
|
|
* it doesn't make sense on ARM (currently the only user of __naked)
|
|
* to trace naked functions because then mcount is called without
|
|
* stack and frame pointer being set up and there is no chance to
|
|
* restore the lr register to the value before mcount was called.
|
|
*/
|
|
#define __naked __attribute__((__naked__)) notrace
|
|
|
|
#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
|
|
|
|
/*
|
|
* Prefer gnu_inline, so that extern inline functions do not emit an
|
|
* externally visible function. This makes extern inline behave as per gnu89
|
|
* semantics rather than c99. This prevents multiple symbol definition errors
|
|
* of extern inline functions at link time.
|
|
* A lot of inline functions can cause havoc with function tracing.
|
|
*/
|
|
#define inline inline __gnu_inline __inline_maybe_unused notrace
|
|
|
|
/*
|
|
* gcc provides both __inline__ and __inline as alternate spellings of
|
|
* the inline keyword, though the latter is undocumented. New kernel
|
|
* code should only use the inline spelling, but some existing code
|
|
* uses __inline__. Since we #define inline above, to ensure
|
|
* __inline__ has the same semantics, we need this #define.
|
|
*
|
|
* However, the spelling __inline is strictly reserved for referring
|
|
* to the bare keyword.
|
|
*/
|
|
#define __inline__ inline
|
|
|
|
/*
|
|
* GCC does not warn about unused static inline functions for -Wunused-function.
|
|
* Suppress the warning in clang as well by using __maybe_unused, but enable it
|
|
* for W=1 build. This will allow clang to find unused functions. Remove the
|
|
* __inline_maybe_unused entirely after fixing most of -Wunused-function warnings.
|
|
*/
|
|
#ifdef KBUILD_EXTRA_WARN1
|
|
#define __inline_maybe_unused
|
|
#else
|
|
#define __inline_maybe_unused __maybe_unused
|
|
#endif
|
|
|
|
/*
|
|
* Rather then using noinline to prevent stack consumption, use
|
|
* noinline_for_stack instead. For documentation reasons.
|
|
*/
|
|
#define noinline_for_stack noinline
|
|
|
|
/*
|
|
* Sanitizer helper attributes: Because using __always_inline and
|
|
* __no_sanitize_* conflict, provide helper attributes that will either expand
|
|
* to __no_sanitize_* in compilation units where instrumentation is enabled
|
|
* (__SANITIZE_*__), or __always_inline in compilation units without
|
|
* instrumentation (__SANITIZE_*__ undefined).
|
|
*/
|
|
#ifdef __SANITIZE_ADDRESS__
|
|
/*
|
|
* We can't declare function 'inline' because __no_sanitize_address conflicts
|
|
* with inlining. Attempt to inline it may cause a build failure.
|
|
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368
|
|
* '__maybe_unused' allows us to avoid defined-but-not-used warnings.
|
|
*/
|
|
# define __no_kasan_or_inline __no_sanitize_address notrace __maybe_unused
|
|
# define __no_sanitize_or_inline __no_kasan_or_inline
|
|
#else
|
|
# define __no_kasan_or_inline __always_inline
|
|
#endif
|
|
|
|
#ifdef __SANITIZE_THREAD__
|
|
/*
|
|
* Clang still emits instrumentation for __tsan_func_{entry,exit}() and builtin
|
|
* atomics even with __no_sanitize_thread (to avoid false positives in userspace
|
|
* ThreadSanitizer). The kernel's requirements are stricter and we really do not
|
|
* want any instrumentation with __no_kcsan.
|
|
*
|
|
* Therefore we add __disable_sanitizer_instrumentation where available to
|
|
* disable all instrumentation. See Kconfig.kcsan where this is mandatory.
|
|
*/
|
|
# define __no_kcsan __no_sanitize_thread __disable_sanitizer_instrumentation
|
|
# define __no_sanitize_or_inline __no_kcsan notrace __maybe_unused
|
|
#else
|
|
# define __no_kcsan
|
|
#endif
|
|
|
|
#ifndef __no_sanitize_or_inline
|
|
#define __no_sanitize_or_inline __always_inline
|
|
#endif
|
|
|
|
/* Section for code which can't be instrumented at all */
|
|
#define noinstr \
|
|
noinline notrace __attribute((__section__(".noinstr.text"))) \
|
|
__no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
/*
|
|
* The below symbols may be defined for one or more, but not ALL, of the above
|
|
* compilers. We don't consider that to be an error, so set them to nothing.
|
|
* For example, some of them are for compiler specific plugins.
|
|
*/
|
|
#ifndef __latent_entropy
|
|
# define __latent_entropy
|
|
#endif
|
|
|
|
#ifndef __randomize_layout
|
|
# define __randomize_layout __designated_init
|
|
#endif
|
|
|
|
#ifndef __no_randomize_layout
|
|
# define __no_randomize_layout
|
|
#endif
|
|
|
|
#ifndef randomized_struct_fields_start
|
|
# define randomized_struct_fields_start
|
|
# define randomized_struct_fields_end
|
|
#endif
|
|
|
|
#ifndef __noscs
|
|
# define __noscs
|
|
#endif
|
|
|
|
#ifndef __nocfi
|
|
# define __nocfi
|
|
#endif
|
|
|
|
#ifndef __cficanonical
|
|
# define __cficanonical
|
|
#endif
|
|
|
|
/*
|
|
* Any place that could be marked with the "alloc_size" attribute is also
|
|
* a place to be marked with the "malloc" attribute. Do this as part of the
|
|
* __alloc_size macro to avoid redundant attributes and to avoid missing a
|
|
* __malloc marking.
|
|
*/
|
|
#ifdef __alloc_size__
|
|
# define __alloc_size(x, ...) __alloc_size__(x, ## __VA_ARGS__) __malloc
|
|
#else
|
|
# define __alloc_size(x, ...) __malloc
|
|
#endif
|
|
|
|
#ifndef asm_volatile_goto
|
|
#define asm_volatile_goto(x...) asm goto(x)
|
|
#endif
|
|
|
|
#ifdef CONFIG_CC_HAS_ASM_INLINE
|
|
#define asm_inline asm __inline
|
|
#else
|
|
#define asm_inline asm
|
|
#endif
|
|
|
|
/* Are two types/vars the same type (ignoring qualifiers)? */
|
|
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
|
|
|
|
/*
|
|
* __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
|
|
* non-scalar types unchanged.
|
|
*/
|
|
/*
|
|
* Prefer C11 _Generic for better compile-times and simpler code. Note: 'char'
|
|
* is not type-compatible with 'signed char', and we define a separate case.
|
|
*/
|
|
#define __scalar_type_to_expr_cases(type) \
|
|
unsigned type: (unsigned type)0, \
|
|
signed type: (signed type)0
|
|
|
|
#define __unqual_scalar_typeof(x) typeof( \
|
|
_Generic((x), \
|
|
char: (char)0, \
|
|
__scalar_type_to_expr_cases(char), \
|
|
__scalar_type_to_expr_cases(short), \
|
|
__scalar_type_to_expr_cases(int), \
|
|
__scalar_type_to_expr_cases(long), \
|
|
__scalar_type_to_expr_cases(long long), \
|
|
default: (x)))
|
|
|
|
/* Is this type a native word size -- useful for atomic operations */
|
|
#define __native_word(t) \
|
|
(sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \
|
|
sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
|
|
|
|
#ifdef __OPTIMIZE__
|
|
# define __compiletime_assert(condition, msg, prefix, suffix) \
|
|
do { \
|
|
/* \
|
|
* __noreturn is needed to give the compiler enough \
|
|
* information to avoid certain possibly-uninitialized \
|
|
* warnings (regardless of the build failing). \
|
|
*/ \
|
|
__noreturn extern void prefix ## suffix(void) \
|
|
__compiletime_error(msg); \
|
|
if (!(condition)) \
|
|
prefix ## suffix(); \
|
|
} while (0)
|
|
#else
|
|
# define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0)
|
|
#endif
|
|
|
|
#define _compiletime_assert(condition, msg, prefix, suffix) \
|
|
__compiletime_assert(condition, msg, prefix, suffix)
|
|
|
|
/**
|
|
* compiletime_assert - break build and emit msg if condition is false
|
|
* @condition: a compile-time constant condition to check
|
|
* @msg: a message to emit if condition is false
|
|
*
|
|
* In tradition of POSIX assert, this macro will break the build if the
|
|
* supplied condition is *false*, emitting the supplied error message if the
|
|
* compiler has support to do so.
|
|
*/
|
|
#define compiletime_assert(condition, msg) \
|
|
_compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
|
|
|
|
#define compiletime_assert_atomic_type(t) \
|
|
compiletime_assert(__native_word(t), \
|
|
"Need native word sized stores/loads for atomicity.")
|
|
|
|
/* Helpers for emitting diagnostics in pragmas. */
|
|
#ifndef __diag
|
|
#define __diag(string)
|
|
#endif
|
|
|
|
#ifndef __diag_GCC
|
|
#define __diag_GCC(version, severity, string)
|
|
#endif
|
|
|
|
#define __diag_push() __diag(push)
|
|
#define __diag_pop() __diag(pop)
|
|
|
|
#define __diag_ignore(compiler, version, option, comment) \
|
|
__diag_ ## compiler(version, ignore, option)
|
|
#define __diag_warn(compiler, version, option, comment) \
|
|
__diag_ ## compiler(version, warn, option)
|
|
#define __diag_error(compiler, version, option, comment) \
|
|
__diag_ ## compiler(version, error, option)
|
|
|
|
#endif /* __LINUX_COMPILER_TYPES_H */
|