mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
In preparation for the objtool klp diff subcommand, add annotations for special section entries. This will enable objtool to determine the size and location of the entries and to extract them when needed. Acked-by: Petr Mladek <pmladek@suse.com> Tested-by: Joe Lawrence <joe.lawrence@redhat.com> Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
143 lines
4.0 KiB
C
143 lines
4.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_X86_CPUFEATURE_H
|
|
#define _ASM_X86_CPUFEATURE_H
|
|
|
|
#include <asm/processor.h>
|
|
|
|
#if defined(__KERNEL__) && !defined(__ASSEMBLER__)
|
|
|
|
#include <asm/asm.h>
|
|
#include <linux/bitops.h>
|
|
#include <asm/alternative.h>
|
|
#include <asm/cpufeaturemasks.h>
|
|
|
|
enum cpuid_leafs
|
|
{
|
|
CPUID_1_EDX = 0,
|
|
CPUID_8000_0001_EDX,
|
|
CPUID_8086_0001_EDX,
|
|
CPUID_LNX_1,
|
|
CPUID_1_ECX,
|
|
CPUID_C000_0001_EDX,
|
|
CPUID_8000_0001_ECX,
|
|
CPUID_LNX_2,
|
|
CPUID_LNX_3,
|
|
CPUID_7_0_EBX,
|
|
CPUID_D_1_EAX,
|
|
CPUID_LNX_4,
|
|
CPUID_7_1_EAX,
|
|
CPUID_8000_0008_EBX,
|
|
CPUID_6_EAX,
|
|
CPUID_8000_000A_EDX,
|
|
CPUID_7_ECX,
|
|
CPUID_8000_0007_EBX,
|
|
CPUID_7_EDX,
|
|
CPUID_8000_001F_EAX,
|
|
CPUID_8000_0021_EAX,
|
|
CPUID_LNX_5,
|
|
NR_CPUID_WORDS,
|
|
};
|
|
|
|
extern const char * const x86_cap_flags[NCAPINTS*32];
|
|
extern const char * const x86_power_flags[32];
|
|
|
|
/*
|
|
* In order to save room, we index into this array by doing
|
|
* X86_BUG_<name> - NCAPINTS*32.
|
|
*/
|
|
extern const char * const x86_bug_flags[NBUGINTS*32];
|
|
#define x86_bug_flag(flag) x86_bug_flags[flag]
|
|
|
|
#define test_cpu_cap(c, bit) \
|
|
arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
|
|
|
|
#define cpu_has(c, bit) \
|
|
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
|
|
test_cpu_cap(c, bit))
|
|
|
|
#define this_cpu_has(bit) \
|
|
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
|
|
x86_this_cpu_test_bit(bit, cpu_info.x86_capability))
|
|
|
|
/*
|
|
* This is the default CPU features testing macro to use in code.
|
|
*
|
|
* It is for detection of features which need kernel infrastructure to be
|
|
* used. It may *not* directly test the CPU itself. Use the cpu_has() family
|
|
* if you want true runtime testing of CPU features, like in hypervisor code
|
|
* where you are supporting a possible guest feature where host support for it
|
|
* is not relevant.
|
|
*/
|
|
#define cpu_feature_enabled(bit) \
|
|
(__builtin_constant_p(bit) && DISABLED_MASK_BIT_SET(bit) ? 0 : static_cpu_has(bit))
|
|
|
|
#define boot_cpu_has(bit) cpu_has(&boot_cpu_data, bit)
|
|
|
|
#define set_cpu_cap(c, bit) set_bit(bit, (unsigned long *)((c)->x86_capability))
|
|
|
|
extern void setup_clear_cpu_cap(unsigned int bit);
|
|
extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
|
|
void check_cpufeature_deps(struct cpuinfo_x86 *c);
|
|
|
|
#define setup_force_cpu_cap(bit) do { \
|
|
\
|
|
if (!boot_cpu_has(bit)) \
|
|
WARN_ON(alternatives_patched); \
|
|
\
|
|
set_cpu_cap(&boot_cpu_data, bit); \
|
|
set_bit(bit, (unsigned long *)cpu_caps_set); \
|
|
} while (0)
|
|
|
|
#define setup_force_cpu_bug(bit) setup_force_cpu_cap(bit)
|
|
|
|
/*
|
|
* Do not use an "m" constraint for [cap_byte] here: gcc doesn't know
|
|
* that this is only used on a fallback path and will sometimes cause
|
|
* it to manifest the address of boot_cpu_data in a register, fouling
|
|
* the mainline (post-initialization) code.
|
|
*/
|
|
static __always_inline bool _static_cpu_has(u16 bit)
|
|
{
|
|
asm goto(ALTERNATIVE_TERNARY("jmp 6f", %c[feature], "", "jmp %l[t_no]")
|
|
".pushsection .altinstr_aux,\"ax\"\n"
|
|
"6:\n"
|
|
ANNOTATE_DATA_SPECIAL
|
|
" testb %[bitnum], %a[cap_byte]\n"
|
|
" jnz %l[t_yes]\n"
|
|
" jmp %l[t_no]\n"
|
|
".popsection\n"
|
|
: : [feature] "i" (bit),
|
|
[bitnum] "i" (1 << (bit & 7)),
|
|
[cap_byte] "i" (&((const char *)boot_cpu_data.x86_capability)[bit >> 3])
|
|
: : t_yes, t_no);
|
|
t_yes:
|
|
return true;
|
|
t_no:
|
|
return false;
|
|
}
|
|
|
|
#define static_cpu_has(bit) \
|
|
( \
|
|
__builtin_constant_p(boot_cpu_has(bit)) ? \
|
|
boot_cpu_has(bit) : \
|
|
_static_cpu_has(bit) \
|
|
)
|
|
|
|
#define cpu_has_bug(c, bit) cpu_has(c, (bit))
|
|
#define set_cpu_bug(c, bit) set_cpu_cap(c, (bit))
|
|
#define clear_cpu_bug(c, bit) clear_cpu_cap(c, (bit))
|
|
|
|
#define static_cpu_has_bug(bit) static_cpu_has((bit))
|
|
#define boot_cpu_has_bug(bit) cpu_has_bug(&boot_cpu_data, (bit))
|
|
#define boot_cpu_set_bug(bit) set_cpu_cap(&boot_cpu_data, (bit))
|
|
|
|
#define MAX_CPU_FEATURES (NCAPINTS * 32)
|
|
#define cpu_have_feature boot_cpu_has
|
|
|
|
#define CPU_FEATURE_TYPEFMT "x86,ven%04Xfam%04Xmod%04X"
|
|
#define CPU_FEATURE_TYPEVAL boot_cpu_data.x86_vendor, boot_cpu_data.x86, \
|
|
boot_cpu_data.x86_model
|
|
|
|
#endif /* defined(__KERNEL__) && !defined(__ASSEMBLER__) */
|
|
#endif /* _ASM_X86_CPUFEATURE_H */
|