User-Mode Instruction Prevention (UMIP) is enabled by setting/clearing a
bit in %cr4.

It makes sense to enable UMIP at some point while booting, before user
spaces come up. Like SMAP and SMEP, is not critical to have it enabled
very early during boot. This is because UMIP is relevant only when there is
a userspace to be protected from. Given the similarities in relevance, it
makes sense to enable UMIP along with SMAP and SMEP.

UMIP is enabled by default. It can be disabled by adding clearcpuid=514
to the kernel parameters.

Cc: Andy Lutomirski <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: H. Peter Anvin <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Brian Gerst <[email protected]>
Cc: Chen Yucong <[email protected]>
Cc: Chris Metcalf <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: Fenghua Yu <[email protected]>
Cc: Huang Rui <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Jonathan Corbet <[email protected]>
Cc: Michael S. Tsirkin <[email protected]>
Cc: Paul Gortmaker <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Ravi V. Shankar <[email protected]>
Cc: Shuah Khan <[email protected]>
Cc: Vlastimil Babka <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Liang Z. Li <[email protected]>
Cc: [email protected]
Signed-off-by: Ricardo Neri <[email protected]>
---
 arch/x86/Kconfig             | 10 ++++++++++
 arch/x86/kernel/cpu/common.c | 25 ++++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ce3ed304288d..5c384d926937 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1801,6 +1801,16 @@ config X86_SMAP
 
          If unsure, say Y.
 
+config X86_INTEL_UMIP
+       def_bool n
+       depends on CPU_SUP_INTEL
+       prompt "Intel User Mode Instruction Prevention" if EXPERT
+       ---help---
+         The User Mode Instruction Prevention (UMIP) is a security
+         feature in newer Intel processors. If enabled, a general
+         protection fault is issued if the instructions SGDT, SLDT,
+         SIDT, SMSW and STR are executed in user mode.
+
 config X86_INTEL_MPX
        prompt "Intel MPX (Memory Protection Extensions)"
        def_bool n
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index b95cd94ca97b..5066d7ffa55e 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -348,6 +348,28 @@ static void setup_pcid(struct cpuinfo_x86 *c)
        }
 }
 
+static __always_inline void setup_umip(struct cpuinfo_x86 *c)
+{
+       /* Check the boot processor, plus build option for UMIP. */
+       if (!cpu_feature_enabled(X86_FEATURE_UMIP))
+               goto out;
+
+       /* Check the current processor's cpuid bits. */
+       if (!cpu_has(c, X86_FEATURE_UMIP))
+               goto out;
+
+       cr4_set_bits(X86_CR4_UMIP);
+
+       return;
+
+out:
+       /*
+        * Make sure UMIP is disabled in case it was enabled in a
+        * previous boot (e.g., via kexec).
+        */
+       cr4_clear_bits(X86_CR4_UMIP);
+}
+
 /*
  * Protection Keys are not available in 32-bit mode.
  */
@@ -1158,9 +1180,10 @@ static void identify_cpu(struct cpuinfo_x86 *c)
        /* Disable the PN if appropriate */
        squash_the_stupid_serial_number(c);
 
-       /* Set up SMEP/SMAP */
+       /* Set up SMEP/SMAP/UMIP */
        setup_smep(c);
        setup_smap(c);
+       setup_umip(c);
 
        /* Set up PCID */
        setup_pcid(c);
-- 
2.13.0

Reply via email to