5-level paging support is required from hardware when compiled with
CONFIG_X86_5LEVEL=y. We may implement runtime switch support later.

Signed-off-by: Kirill A. Shutemov <kirill.shute...@linux.intel.com>
---
 arch/x86/boot/cpucheck.c                 |  9 +++++++++
 arch/x86/boot/cpuflags.c                 | 16 ++++++++++++++++
 arch/x86/include/asm/cpufeatures.h       |  1 +
 arch/x86/include/asm/disabled-features.h |  8 +++++++-
 arch/x86/include/asm/required-features.h |  8 +++++++-
 5 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/arch/x86/boot/cpucheck.c b/arch/x86/boot/cpucheck.c
index 4ad7d70e8739..8f0c4c9fc904 100644
--- a/arch/x86/boot/cpucheck.c
+++ b/arch/x86/boot/cpucheck.c
@@ -44,6 +44,15 @@ static const u32 req_flags[NCAPINTS] =
        0, /* REQUIRED_MASK5 not implemented in this file */
        REQUIRED_MASK6,
        0, /* REQUIRED_MASK7 not implemented in this file */
+       0, /* REQUIRED_MASK8 not implemented in this file */
+       0, /* REQUIRED_MASK9 not implemented in this file */
+       0, /* REQUIRED_MASK10 not implemented in this file */
+       0, /* REQUIRED_MASK11 not implemented in this file */
+       0, /* REQUIRED_MASK12 not implemented in this file */
+       0, /* REQUIRED_MASK13 not implemented in this file */
+       0, /* REQUIRED_MASK14 not implemented in this file */
+       0, /* REQUIRED_MASK15 not implemented in this file */
+       REQUIRED_MASK16,
 };
 
 #define A32(a, b, c, d) (((d) << 24)+((c) << 16)+((b) << 8)+(a))
diff --git a/arch/x86/boot/cpuflags.c b/arch/x86/boot/cpuflags.c
index 6687ab953257..26e9a287805f 100644
--- a/arch/x86/boot/cpuflags.c
+++ b/arch/x86/boot/cpuflags.c
@@ -80,6 +80,17 @@ static inline void cpuid(u32 id, u32 *a, u32 *b, u32 *c, u32 
*d)
        );
 }
 
+static inline void cpuid_count(u32 id, u32 count,
+               u32 *a, u32 *b, u32 *c, u32 *d)
+{
+       asm volatile(".ifnc %%ebx,%3 ; movl  %%ebx,%3 ; .endif  \n\t"
+                    "cpuid                                     \n\t"
+                    ".ifnc %%ebx,%3 ; xchgl %%ebx,%3 ; .endif  \n\t"
+                   : "=a" (*a), "=c" (*c), "=d" (*d), EBX_REG (*b)
+                   : "a" (id), "c" (count)
+       );
+}
+
 void get_cpuflags(void)
 {
        u32 max_intel_level, max_amd_level;
@@ -108,6 +119,11 @@ void get_cpuflags(void)
                                cpu.model += ((tfms >> 16) & 0xf) << 4;
                }
 
+               if (max_intel_level >= 0x00000007) {
+                       cpuid_count(0x00000007, 0, &ignored, &ignored,
+                                       &cpu.flags[16], &ignored);
+               }
+
                cpuid(0x80000000, &max_amd_level, &ignored, &ignored,
                      &ignored);
 
diff --git a/arch/x86/include/asm/cpufeatures.h 
b/arch/x86/include/asm/cpufeatures.h
index 92a8308b96f6..388f1277880f 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h
@@ -280,6 +280,7 @@
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx), word 16 */
 #define X86_FEATURE_PKU                (16*32+ 3) /* Protection Keys for 
Userspace */
 #define X86_FEATURE_OSPKE      (16*32+ 4) /* OS Protection Keys Enable */
+#define X86_FEATURE_LA57       (16*32+16) /* 5-level page tables */
 
 /* AMD-defined CPU features, CPUID level 0x80000007 (ebx), word 17 */
 #define X86_FEATURE_OVERFLOW_RECOV (17*32+0) /* MCA overflow recovery support 
*/
diff --git a/arch/x86/include/asm/disabled-features.h 
b/arch/x86/include/asm/disabled-features.h
index 85599ad4d024..fc0960236fc3 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -36,6 +36,12 @@
 # define DISABLE_OSPKE         (1<<(X86_FEATURE_OSPKE & 31))
 #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
 
+#ifdef CONFIG_X86_5LEVEL
+#define DISABLE_LA57   0
+#else
+#define DISABLE_LA57   (1<<(X86_FEATURE_LA57 & 31))
+#endif
+
 /*
  * Make sure to add features to the correct mask
  */
@@ -55,7 +61,7 @@
 #define DISABLED_MASK13        0
 #define DISABLED_MASK14        0
 #define DISABLED_MASK15        0
-#define DISABLED_MASK16        (DISABLE_PKU|DISABLE_OSPKE)
+#define DISABLED_MASK16        (DISABLE_PKU|DISABLE_OSPKE|DISABLE_LA57)
 #define DISABLED_MASK17        0
 #define DISABLED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
 
diff --git a/arch/x86/include/asm/required-features.h 
b/arch/x86/include/asm/required-features.h
index fac9a5c0abe9..d91ba04dd007 100644
--- a/arch/x86/include/asm/required-features.h
+++ b/arch/x86/include/asm/required-features.h
@@ -53,6 +53,12 @@
 # define NEED_MOVBE    0
 #endif
 
+#ifdef CONFIG_X86_5LEVEL
+# define NEED_LA57     (1<<(X86_FEATURE_LA57 & 31))
+#else
+# define NEED_LA57     0
+#endif
+
 #ifdef CONFIG_X86_64
 #ifdef CONFIG_PARAVIRT
 /* Paravirtualized systems may not have PSE or PGE available */
@@ -98,7 +104,7 @@
 #define REQUIRED_MASK13        0
 #define REQUIRED_MASK14        0
 #define REQUIRED_MASK15        0
-#define REQUIRED_MASK16        0
+#define REQUIRED_MASK16        (NEED_LA57)
 #define REQUIRED_MASK17        0
 #define REQUIRED_MASK_CHECK BUILD_BUG_ON_ZERO(NCAPINTS != 18)
 
-- 
2.10.2

Reply via email to