lkml.org 
[lkml]   [2020]   [Dec]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v17 04/26] x86/cpufeatures: Introduce X86_FEATURE_CET and setup functions
    Date
    Introduce a software-defined X86_FEATURE_CET, which indicates either Shadow
    Stack or Indirect Branch Tracking (or both) is present. Also introduce
    related cpu init/setup functions.

    Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
    ---
    arch/x86/include/asm/cpufeatures.h | 2 +-
    arch/x86/include/asm/disabled-features.h | 5 ++-
    arch/x86/include/uapi/asm/processor-flags.h | 2 ++
    arch/x86/kernel/cpu/common.c | 40 ++++++++++++++++++++-
    4 files changed, 46 insertions(+), 3 deletions(-)

    diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
    index 292fe87b26b3..d1866659edbd 100644
    --- a/arch/x86/include/asm/cpufeatures.h
    +++ b/arch/x86/include/asm/cpufeatures.h
    @@ -108,7 +108,7 @@
    #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* Extended APICID (8 bits) */
    #define X86_FEATURE_AMD_DCM ( 3*32+27) /* AMD multi-node processor */
    #define X86_FEATURE_APERFMPERF ( 3*32+28) /* P-State hardware coordination feedback capability (APERF/MPERF MSRs) */
    -/* free ( 3*32+29) */
    +#define X86_FEATURE_CET ( 3*32+29) /* Control-flow enforcement */
    #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
    #define X86_FEATURE_TSC_KNOWN_FREQ ( 3*32+31) /* TSC has known frequency */

    diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
    index 4d3b7ce509e5..86ac4a1c6d81 100644
    --- a/arch/x86/include/asm/disabled-features.h
    +++ b/arch/x86/include/asm/disabled-features.h
    @@ -71,9 +71,11 @@
    #ifdef CONFIG_X86_CET_USER
    #define DISABLE_SHSTK 0
    #define DISABLE_IBT 0
    +#define DISABLE_CET 0
    #else
    #define DISABLE_SHSTK (1 << (X86_FEATURE_SHSTK & 31))
    #define DISABLE_IBT (1 << (X86_FEATURE_IBT & 31))
    +#define DISABLE_CET (1 << (X86_FEATURE_CET & 31))
    #endif

    /*
    @@ -82,7 +84,8 @@
    #define DISABLED_MASK0 (DISABLE_VME)
    #define DISABLED_MASK1 0
    #define DISABLED_MASK2 0
    -#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR)
    +#define DISABLED_MASK3 (DISABLE_CYRIX_ARR|DISABLE_CENTAUR_MCR|DISABLE_K6_MTRR| \
    + DISABLE_CET)
    #define DISABLED_MASK4 (DISABLE_PCID)
    #define DISABLED_MASK5 0
    #define DISABLED_MASK6 0
    diff --git a/arch/x86/include/uapi/asm/processor-flags.h b/arch/x86/include/uapi/asm/processor-flags.h
    index bcba3c643e63..a8df907e8017 100644
    --- a/arch/x86/include/uapi/asm/processor-flags.h
    +++ b/arch/x86/include/uapi/asm/processor-flags.h
    @@ -130,6 +130,8 @@
    #define X86_CR4_SMAP _BITUL(X86_CR4_SMAP_BIT)
    #define X86_CR4_PKE_BIT 22 /* enable Protection Keys support */
    #define X86_CR4_PKE _BITUL(X86_CR4_PKE_BIT)
    +#define X86_CR4_CET_BIT 23 /* enable Control-flow Enforcement */
    +#define X86_CR4_CET _BITUL(X86_CR4_CET_BIT)

    /*
    * x86-64 Task Priority Register, CR8
    diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
    index 35ad8480c464..03c367f79adc 100644
    --- a/arch/x86/kernel/cpu/common.c
    +++ b/arch/x86/kernel/cpu/common.c
    @@ -510,6 +510,14 @@ static __init int setup_disable_pku(char *arg)
    __setup("nopku", setup_disable_pku);
    #endif /* CONFIG_X86_64 */

    +static __always_inline void setup_cet(struct cpuinfo_x86 *c)
    +{
    + if (!cpu_feature_enabled(X86_FEATURE_CET))
    + return;
    +
    + cr4_set_bits(X86_CR4_CET);
    +}
    +
    /*
    * Some CPU features depend on higher CPUID levels, which may not always
    * be available due to CPUID level capping or broken virtualization
    @@ -895,6 +903,12 @@ static void init_speculation_control(struct cpuinfo_x86 *c)
    }
    }

    +static void init_cet_features(struct cpuinfo_x86 *c)
    +{
    + if (cpu_has(c, X86_FEATURE_SHSTK) || cpu_has(c, X86_FEATURE_IBT))
    + set_cpu_cap(c, X86_FEATURE_CET);
    +}
    +
    void get_cpu_cap(struct cpuinfo_x86 *c)
    {
    u32 eax, ebx, ecx, edx;
    @@ -960,6 +974,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
    if (c->extended_cpuid_level >= 0x8000000a)
    c->x86_capability[CPUID_8000_000A_EDX] = cpuid_edx(0x8000000a);

    + init_cet_features(c);
    init_scattered_cpuid_features(c);
    init_speculation_control(c);

    @@ -1221,6 +1236,15 @@ static void detect_nopl(void)
    #endif
    }

    +static void adjust_combined_cpu_features(void)
    +{
    +#ifdef CONFIG_X86_CET_USER
    + if (test_bit(X86_FEATURE_SHSTK, (unsigned long *)cpu_caps_cleared) &&
    + test_bit(X86_FEATURE_IBT, (unsigned long *)cpu_caps_cleared))
    + setup_clear_cpu_cap(X86_FEATURE_CET);
    +#endif
    +}
    +
    /*
    * We parse cpu parameters early because fpu__init_system() is executed
    * before parse_early_param().
    @@ -1252,9 +1276,19 @@ static void __init cpu_parse_early_param(void)
    if (cmdline_find_option_bool(boot_command_line, "noxsaves"))
    setup_clear_cpu_cap(X86_FEATURE_XSAVES);

    + /*
    + * CET states are XSAVES states and options must be parsed early.
    + */
    +#ifdef CONFIG_X86_CET_USER
    + if (cmdline_find_option_bool(boot_command_line, "no_user_shstk"))
    + setup_clear_cpu_cap(X86_FEATURE_SHSTK);
    + if (cmdline_find_option_bool(boot_command_line, "no_user_ibt"))
    + setup_clear_cpu_cap(X86_FEATURE_IBT);
    +#endif
    +
    arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg));
    if (arglen <= 0)
    - return;
    + goto done;

    pr_info("Clearing CPUID bits:");
    do {
    @@ -1272,6 +1306,9 @@ static void __init cpu_parse_early_param(void)
    }
    } while (res == 2);
    pr_cont("\n");
    +
    +done:
    + adjust_combined_cpu_features();
    }

    /*
    @@ -1591,6 +1628,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)

    x86_init_rdrand(c);
    setup_pku(c);
    + setup_cet(c);

    /*
    * Clear/Set all flags overridden by options, need do it
    --
    2.21.0
    \
     
     \ /
      Last update: 2020-12-29 22:35    [W:5.277 / U:0.396 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site