Skip to content

Commit b42a4bf

Browse files
hansendcZhengShunQian
authored andcommitted
x86/cpufeature, x86/mm/pkeys: Add protection keys related CPUID definitions
commit dfb4a70 upstream 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 <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Cc: Andrew Morton <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Rik van Riel <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]> Signed-off-by: Srivatsa S. Bhat <[email protected]> Reviewed-by: Matt Helsley (VMware) <[email protected]> Reviewed-by: Alexey Makhalov <[email protected]> Reviewed-by: Bo Gan <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent cf62120 commit b42a4bf

File tree

5 files changed

+63
-21
lines changed

5 files changed

+63
-21
lines changed

arch/x86/include/asm/cpufeature.h

Lines changed: 39 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ enum cpuid_leafs
2626
CPUID_8000_0008_EBX,
2727
CPUID_6_EAX,
2828
CPUID_8000_000A_EDX,
29+
CPUID_7_ECX,
2930
};
3031

3132
#ifdef CONFIG_X86_FEATURE_NAMES
@@ -48,28 +49,42 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
4849
test_bit(bit, (unsigned long *)((c)->x86_capability))
4950

5051
#define REQUIRED_MASK_BIT_SET(bit) \
51-
( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) || \
52-
(((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) || \
53-
(((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) || \
54-
(((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3)) || \
55-
(((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4)) || \
56-
(((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5)) || \
57-
(((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) || \
58-
(((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) || \
59-
(((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) || \
60-
(((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )
52+
( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0 )) || \
53+
(((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1 )) || \
54+
(((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2 )) || \
55+
(((bit)>>5)==3 && (1UL<<((bit)&31) & REQUIRED_MASK3 )) || \
56+
(((bit)>>5)==4 && (1UL<<((bit)&31) & REQUIRED_MASK4 )) || \
57+
(((bit)>>5)==5 && (1UL<<((bit)&31) & REQUIRED_MASK5 )) || \
58+
(((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6 )) || \
59+
(((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7 )) || \
60+
(((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8 )) || \
61+
(((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9 )) || \
62+
(((bit)>>5)==10 && (1UL<<((bit)&31) & REQUIRED_MASK10)) || \
63+
(((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \
64+
(((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \
65+
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \
66+
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \
67+
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \
68+
(((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
6169

6270
#define DISABLED_MASK_BIT_SET(bit) \
63-
( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0)) || \
64-
(((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1)) || \
65-
(((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2)) || \
66-
(((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3)) || \
67-
(((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4)) || \
68-
(((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5)) || \
69-
(((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6)) || \
70-
(((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7)) || \
71-
(((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8)) || \
72-
(((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9)) )
71+
( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \
72+
(((bit)>>5)==1 && (1UL<<((bit)&31) & DISABLED_MASK1 )) || \
73+
(((bit)>>5)==2 && (1UL<<((bit)&31) & DISABLED_MASK2 )) || \
74+
(((bit)>>5)==3 && (1UL<<((bit)&31) & DISABLED_MASK3 )) || \
75+
(((bit)>>5)==4 && (1UL<<((bit)&31) & DISABLED_MASK4 )) || \
76+
(((bit)>>5)==5 && (1UL<<((bit)&31) & DISABLED_MASK5 )) || \
77+
(((bit)>>5)==6 && (1UL<<((bit)&31) & DISABLED_MASK6 )) || \
78+
(((bit)>>5)==7 && (1UL<<((bit)&31) & DISABLED_MASK7 )) || \
79+
(((bit)>>5)==8 && (1UL<<((bit)&31) & DISABLED_MASK8 )) || \
80+
(((bit)>>5)==9 && (1UL<<((bit)&31) & DISABLED_MASK9 )) || \
81+
(((bit)>>5)==10 && (1UL<<((bit)&31) & DISABLED_MASK10)) || \
82+
(((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \
83+
(((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \
84+
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \
85+
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \
86+
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \
87+
(((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
7388

7489
#define cpu_has(c, bit) \
7590
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
@@ -79,6 +94,10 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
7994
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
8095
x86_this_cpu_test_bit(bit, (unsigned long *)&cpu_info.x86_capability))
8196

97+
/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
98+
#define X86_FEATURE_PKU (16*32+ 3) /* Protection Keys for Userspace */
99+
#define X86_FEATURE_OSPKE (16*32+ 4) /* OS Protection Keys Enable */
100+
82101
/*
83102
* This macro is for detection of features which need kernel
84103
* infrastructure to be used. It may *not* directly test the CPU

arch/x86/include/asm/cpufeatures.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/*
1313
* Defines x86 CPU feature bits
1414
*/
15-
#define NCAPINTS 16 /* N 32-bit words worth of info */
15+
#define NCAPINTS 17 /* N 32-bit words worth of info */
1616
#define NBUGINTS 1 /* N 32-bit bug flags */
1717

1818
/*

arch/x86/include/asm/disabled-features.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@
3030
# define DISABLE_PCID (1<<(X86_FEATURE_PCID & 31))
3131
#endif /* CONFIG_X86_64 */
3232

33+
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
34+
# define DISABLE_PKU (1<<(X86_FEATURE_PKU))
35+
# define DISABLE_OSPKE (1<<(X86_FEATURE_OSPKE))
36+
#else
37+
# define DISABLE_PKU 0
38+
# define DISABLE_OSPKE 0
39+
#endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
40+
3341
/*
3442
* Make sure to add features to the correct mask
3543
*/
@@ -43,5 +51,12 @@
4351
#define DISABLED_MASK7 0
4452
#define DISABLED_MASK8 0
4553
#define DISABLED_MASK9 (DISABLE_MPX)
54+
#define DISABLED_MASK10 0
55+
#define DISABLED_MASK11 0
56+
#define DISABLED_MASK12 0
57+
#define DISABLED_MASK13 0
58+
#define DISABLED_MASK14 0
59+
#define DISABLED_MASK15 0
60+
#define DISABLED_MASK16 (DISABLE_PKU|DISABLE_OSPKE)
4661

4762
#endif /* _ASM_X86_DISABLED_FEATURES_H */

arch/x86/include/asm/required-features.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,12 @@
9292
#define REQUIRED_MASK7 0
9393
#define REQUIRED_MASK8 0
9494
#define REQUIRED_MASK9 0
95+
#define REQUIRED_MASK10 0
96+
#define REQUIRED_MASK11 0
97+
#define REQUIRED_MASK12 0
98+
#define REQUIRED_MASK13 0
99+
#define REQUIRED_MASK14 0
100+
#define REQUIRED_MASK15 0
101+
#define REQUIRED_MASK16 0
95102

96103
#endif /* _ASM_X86_REQUIRED_FEATURES_H */

arch/x86/kernel/cpu/common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
693693
c->x86_capability[CPUID_7_0_EBX] = ebx;
694694

695695
c->x86_capability[CPUID_6_EAX] = cpuid_eax(0x00000006);
696+
c->x86_capability[CPUID_7_ECX] = ecx;
696697
}
697698

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

0 commit comments

Comments
 (0)