lkml.org 
[lkml]   [2016]   [Jan]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 04/31] x86, pkeys: cpuid bit definition
    From
    Date

    From: Dave Hansen <dave.hansen@linux.intel.com>

    There are two CPUID bits for protection keys. One is for whether
    the CPU contains the feature, and the other will appear set once
    the OS enables protection keys. Specifically:

    Bit 04: OSPKE. If 1, OS has set CR4.PKE to enable
    Protection keys (and the RDPKRU/WRPKRU instructions)

    This is because userspace can not see CR4 contents, but it can
    see CPUID contents.

    X86_FEATURE_PKU is referred to as "PKU" in the hardware documentation:

    CPUID.(EAX=07H,ECX=0H):ECX.PKU [bit 3]

    X86_FEATURE_OSPKE is "OSPKU":

    CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4]

    These are the first CPU features which need to look at the
    ECX word in CPUID leaf 0x7, so this patch also includes
    fetching that word in to the cpuinfo->x86_capability[] array.

    Add it to the disabled-features mask when its config option is
    off. Even though we are not using it here, we also extend the
    REQUIRED_MASK_BIT_SET() macro to keep it mirroring the
    DISABLED_MASK_BIT_SET() version.

    This means that in almost all code, you should use:

    cpu_has(c, X86_FEATURE_PKU)

    and *not* the CONFIG option.

    Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
    Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
    ---

    b/arch/x86/include/asm/cpufeature.h | 56 ++++++++++++++++++-----------
    b/arch/x86/include/asm/disabled-features.h | 13 ++++++
    b/arch/x86/include/asm/required-features.h | 5 ++
    b/arch/x86/kernel/cpu/common.c | 1
    4 files changed, 54 insertions(+), 21 deletions(-)

    diff -puN arch/x86/include/asm/cpufeature.h~pkeys-01-cpuid arch/x86/include/asm/cpufeature.h
    --- a/arch/x86/include/asm/cpufeature.h~pkeys-01-cpuid 2016-01-06 15:50:04.310097377 -0800
    +++ b/arch/x86/include/asm/cpufeature.h 2016-01-06 15:50:04.318097738 -0800
    @@ -12,7 +12,7 @@
    #include <asm/disabled-features.h>
    #endif

    -#define NCAPINTS 14 /* N 32-bit words worth of info */
    +#define NCAPINTS 15 /* N 32-bit words worth of info */
    #define NBUGINTS 1 /* N 32-bit bug flags */

    /*
    @@ -258,6 +258,10 @@
    /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */
    #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */

    +/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 13 */
    +#define X86_FEATURE_PKU (14*32+ 3) /* Protection Keys for Userspace */
    +#define X86_FEATURE_OSPKE (14*32+ 4) /* OS Protection Keys Enable */
    +
    /*
    * BUG word(s)
    */
    @@ -298,28 +302,38 @@ extern const char * const x86_bug_flags[
    test_bit(bit, (unsigned long *)((c)->x86_capability))

    #define REQUIRED_MASK_BIT_SET(bit) \
    - ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \
    - (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \
    - (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \
    - (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \
    - (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \
    - (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \
    - (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \
    - (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) || \
    - (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) || \
    - (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )
    + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0 )) || \
    + (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1 )) || \
    + (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2 )) || \
    + (((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3 )) || \
    + (((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4 )) || \
    + (((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5 )) || \
    + (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6 )) || \
    + (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7 )) || \
    + (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8 )) || \
    + (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9 )) || \
    + (((bit)>>5)==10 && (1UL<<((bit)&31) & REQUIRED_MASK10)) || \
    + (((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \
    + (((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \
    + (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \
    + (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) )

    #define DISABLED_MASK_BIT_SET(bit) \
    - ( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0)) || \
    - (((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1)) || \
    - (((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2)) || \
    - (((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3)) || \
    - (((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4)) || \
    - (((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5)) || \
    - (((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6)) || \
    - (((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7)) || \
    - (((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8)) || \
    - (((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9)) )
    + ( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \
    + (((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1 )) || \
    + (((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2 )) || \
    + (((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3 )) || \
    + (((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4 )) || \
    + (((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5 )) || \
    + (((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6 )) || \
    + (((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7 )) || \
    + (((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8 )) || \
    + (((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9 )) || \
    + (((bit)>>5)==10 && (1UL<<((bit)&31) & DISABLED_MASK10)) || \
    + (((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \
    + (((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \
    + (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \
    + (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) )

    #define cpu_has(c, bit) \
    (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
    diff -puN arch/x86/include/asm/disabled-features.h~pkeys-01-cpuid arch/x86/include/asm/disabled-features.h
    --- a/arch/x86/include/asm/disabled-features.h~pkeys-01-cpuid 2016-01-06 15:50:04.311097422 -0800
    +++ b/arch/x86/include/asm/disabled-features.h 2016-01-06 15:50:04.318097738 -0800
    @@ -28,6 +28,14 @@
    # define DISABLE_CENTAUR_MCR 0
    #endif /* CONFIG_X86_64 */

    +#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
    +# define DISABLE_PKU (1<<(X86_FEATURE_PKU))
    +# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE))
    +#else
    +# define DISABLE_PKU 0
    +# define DISABLE_OSPKE 0
    +#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
    +
    /*
    * Make sure to add features to the correct mask
    */
    @@ -41,5 +49,10 @@
    #define DISABLED_MASK7 0
    #define DISABLED_MASK8 0
    #define DISABLED_MASK9 (DISABLE_MPX)
    +#define DISABLED_MASK10 0
    +#define DISABLED_MASK11 0
    +#define DISABLED_MASK12 0
    +#define DISABLED_MASK13 0
    +#define DISABLED_MASK14 (DISABLE_PKU|DISABLE_OSPKE)

    #endif /* _ASM_X86_DISABLED_FEATURES_H */
    diff -puN arch/x86/include/asm/required-features.h~pkeys-01-cpuid arch/x86/include/asm/required-features.h
    --- a/arch/x86/include/asm/required-features.h~pkeys-01-cpuid 2016-01-06 15:50:04.313097512 -0800
    +++ b/arch/x86/include/asm/required-features.h 2016-01-06 15:50:04.318097738 -0800
    @@ -92,5 +92,10 @@
    #define REQUIRED_MASK7 0
    #define REQUIRED_MASK8 0
    #define REQUIRED_MASK9 0
    +#define REQUIRED_MASK10 0
    +#define REQUIRED_MASK11 0
    +#define REQUIRED_MASK12 0
    +#define REQUIRED_MASK13 0
    +#define REQUIRED_MASK14 0

    #endif /* _ASM_X86_REQUIRED_FEATURES_H */
    diff -puN arch/x86/kernel/cpu/common.c~pkeys-01-cpuid arch/x86/kernel/cpu/common.c
    --- a/arch/x86/kernel/cpu/common.c~pkeys-01-cpuid 2016-01-06 15:50:04.314097557 -0800
    +++ b/arch/x86/kernel/cpu/common.c 2016-01-06 15:50:04.319097783 -0800
    @@ -619,6 +619,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
    cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);

    c->x86_capability[9] = ebx;
    + c->x86_capability[14] = ecx;
    }

    /* Extended state features: level 0x0000000d */
    _

    \
     
     \ /
      Last update: 2016-01-07 02:01    [W:4.359 / U:0.144 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site