From: Fenghua Yu <fenghua...@intel.com>

Protection Keys for Supervisor pages (PKS) enables fast, hardware thread
specific, manipulation of permission restrictions on supervisor page
mappings.  It uses the same mechanism of Protection Keys as those on
User mappings but applies that mechanism to supervisor mappings using a
supervisor specific MSR.

Kernel users can thus defines 'domains' of page mappings which have an
extra level of protection beyond those specified in the supervisor page
table entries.

Enable PKS on supported CPUS.

Co-developed-by: Ira Weiny <ira.we...@intel.com>
Signed-off-by: Ira Weiny <ira.we...@intel.com>
Signed-off-by: Fenghua Yu <fenghua...@intel.com>

---
Changes from V2
        From Thomas: Make this patch last so PKS is not enabled until
        all the PKS mechanisms are in place.  Specifically:
                1) Modify setup_pks() to call write_pkrs() to properly
                   set up the initial value when enabled.

                2) Split this patch into two. 1) a precursor patch with
                   the required defines/config options and 2) this patch
                   which actually enables feature on CPUs which support
                   it.

Changes since RFC V3
        Per Dave Hansen
                Update comment
                Add X86_FEATURE_PKS to disabled-features.h
        Rebase based on latest TIP tree
---
 arch/x86/include/asm/disabled-features.h |  6 +++++-
 arch/x86/kernel/cpu/common.c             | 15 +++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/disabled-features.h 
b/arch/x86/include/asm/disabled-features.h
index 164587177152..82540f0c5b6c 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -44,7 +44,11 @@
 # define DISABLE_OSPKE         (1<<(X86_FEATURE_OSPKE & 31))
 #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
 
-#define DISABLE_PKS           (1<<(X86_FEATURE_PKS & 31))
+#ifdef CONFIG_ARCH_HAS_SUPERVISOR_PKEYS
+# define DISABLE_PKS           0
+#else
+# define DISABLE_PKS           (1<<(X86_FEATURE_PKS & 31))
+#endif
 
 #ifdef CONFIG_X86_5LEVEL
 # define DISABLE_LA57  0
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 35ad8480c464..f8929a557d72 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -58,6 +58,7 @@
 #include <asm/intel-family.h>
 #include <asm/cpu_device_id.h>
 #include <asm/uv/uv.h>
+#include <linux/pkeys.h>
 
 #include "cpu.h"
 
@@ -1494,6 +1495,19 @@ static void validate_apic_and_package_id(struct 
cpuinfo_x86 *c)
 #endif
 }
 
+/*
+ * PKS is independent of PKU and either or both may be supported on a CPU.
+ * Configure PKS if the CPU supports the feature.
+ */
+static void setup_pks(void)
+{
+       if (!cpu_feature_enabled(X86_FEATURE_PKS))
+               return;
+
+       write_pkrs(INIT_PKRS_VALUE);
+       cr4_set_bits(X86_CR4_PKS);
+}
+
 /*
  * This does the hard work of actually picking apart the CPU stuff...
  */
@@ -1591,6 +1605,7 @@ static void identify_cpu(struct cpuinfo_x86 *c)
 
        x86_init_rdrand(c);
        setup_pku(c);
+       setup_pks();
 
        /*
         * Clear/Set all flags overridden by options, need do it
-- 
2.28.0.rc0.12.gb6a658bd00c9

Reply via email to