lkml.org 
[lkml]   [2022]   [Feb]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 05/29] x86: Base IBT bits
    Add Kconfig, Makefile and basic instruction support for x86 IBT.

    TODO: clang

    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    ---
    arch/x86/Kconfig | 15 ++++++++++++
    arch/x86/Makefile | 5 +++-
    arch/x86/include/asm/ibt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++
    3 files changed, 72 insertions(+), 1 deletion(-)

    --- a/arch/x86/Kconfig
    +++ b/arch/x86/Kconfig
    @@ -1861,6 +1861,21 @@ config X86_UMIP
    specific cases in protected and virtual-8086 modes. Emulated
    results are dummy.

    +config CC_HAS_IBT
    + # GCC >= 9 and binutils >= 2.29
    + # Retpoline check to work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93654
    + def_bool $(cc-option, -fcf-protection=branch -mindirect-branch-register) && $(as-instr,endbr64)
    +
    +config X86_IBT
    + prompt "Indirect Branch Tracking"
    + bool
    + depends on X86_64 && CC_HAS_IBT
    + help
    + Build the kernel with support for Indirect Branch Tracking, a
    + hardware supported CFI scheme. Any indirect call must land on
    + an ENDBR instruction, as such, the compiler will litter the
    + code with them to make this happen.
    +
    config X86_INTEL_MEMORY_PROTECTION_KEYS
    prompt "Memory Protection Keys"
    def_bool y
    --- a/arch/x86/Makefile
    +++ b/arch/x86/Makefile
    @@ -62,8 +62,11 @@ export BITS
    #
    KBUILD_CFLAGS += -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx

    -# Intel CET isn't enabled in the kernel
    +ifeq ($(CONFIG_X86_IBT),y)
    +KBUILD_CFLAGS += $(call cc-option,-fcf-protection=branch)
    +else
    KBUILD_CFLAGS += $(call cc-option,-fcf-protection=none)
    +endif

    ifeq ($(CONFIG_X86_32),y)
    BITS := 32
    --- /dev/null
    +++ b/arch/x86/include/asm/ibt.h
    @@ -0,0 +1,53 @@
    +/* SPDX-License-Identifier: GPL-2.0 */
    +#ifndef _ASM_X86_IBT_H
    +#define _ASM_X86_IBT_H
    +
    +#ifdef CONFIG_X86_IBT
    +
    +#ifndef __ASSEMBLY__
    +
    +#ifdef CONFIG_X86_64
    +#define ASM_ENDBR "endbr64\n\t"
    +#else
    +#define ASM_ENDBR "endbr32\n\t"
    +#endif
    +
    +#define __noendbr __attribute__((nocf_check))
    +
    +/*
    + * A bit convoluted, but matches both endbr32 and endbr64 without
    + * having either as literal in the text.
    + */
    +static inline bool is_endbr(const void *addr)
    +{
    + unsigned int val = ~*(unsigned int *)addr;
    + val |= 0x01000000U;
    + return val == ~0xfa1e0ff3;
    +}
    +
    +#else /* __ASSEMBLY__ */
    +
    +#ifdef CONFIG_X86_64
    +#define ENDBR endbr64
    +#else
    +#define ENDBR endbr32
    +#endif
    +
    +#endif /* __ASSEMBLY__ */
    +
    +#else /* !IBT */
    +
    +#ifndef __ASSEMBLY__
    +
    +#define ASM_ENDBR
    +
    +#define __noendbr
    +
    +#else /* __ASSEMBLY__ */
    +
    +#define ENDBR
    +
    +#endif /* __ASSEMBLY__ */
    +
    +#endif /* CONFIG_X86_IBT */
    +#endif /* _ASM_X86_IBT_H */

    \
     
     \ /
      Last update: 2022-02-18 18:16    [W:4.121 / U:0.072 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site