]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/speculation: Keep enhanced IBRS on when prctl is used for SSBD control
authorAlejandro Jimenez <alejandro.j.jimenez@oracle.com>
Wed, 20 Mar 2019 15:00:49 +0000 (11:00 -0400)
committerBrian Maly <brian.maly@oracle.com>
Fri, 10 May 2019 23:11:37 +0000 (19:11 -0400)
When using the prctl system call to enable/disable SSBD mitigation for a
specific thread, it is necessary to update the SPEC_CTRL MSR on the CPU
running it. The value used as the base for the msr that will be written
is x86_spec_ctrl_base, which does not have the IBRS bit set. The relevant
SSBD bits are OR'd to this value before it is written to the MSR, but
the IBRS bit will remain unset.
As a result, the thread that requested the SSBD protection will run without
IBRS enabled, and when it is context switched out, IBRS will not be turned
back on again. This is not a problem in processors that use basic IBRS since
the bit is constantly toggled on kernel entry, but with enhanced IBRS this
is not necessary and therefore the bit remains unset.

Fix it by adding a check to detect when enhanced IBRS is in use, and add
the bit to the msr value that will be used as the baseline.

Orabug: 29526401

Signed-off-by: Alejandro Jimenez <alejandro.j.jimenez@oracle.com>
Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
arch/x86/include/asm/spec_ctrl.h
arch/x86/kernel/process.c

index ecfc951395606aa2d3c1e4942ad448c3c5451ff0..09e8b761a74dbedf8325802dde0a9adc0d905d41 100644 (file)
@@ -308,6 +308,16 @@ static inline int check_basic_ibrs_inuse(void)
        return 0;
 }
 
+static inline int check_enhanced_ibrs_inuse(void)
+{
+       if (use_ibrs & SPEC_CTRL_ENHCD_IBRS_INUSE)
+               return 1;
+
+       /* rmb to prevent wrong speculation for security */
+       rmb();
+       return 0;
+}
+
 static inline int check_ibrs_inuse(void)
 {
        if (use_ibrs & (SPEC_CTRL_BASIC_IBRS_INUSE |
index c6d19f35bb57ed9025cfd4b827fe390957dd5833..0d4f2a4c466dd25bbf466b3f014418fd88c91614 100644 (file)
@@ -350,7 +350,9 @@ static __always_inline void amd_set_ssb_virt_state(unsigned long tifn)
 
 static __always_inline void intel_set_ssb_state(unsigned long tifn)
 {
-       u64 msr = x86_spec_ctrl_base | ssbd_tif_to_spec_ctrl(tifn);
+       u64 msr = x86_spec_ctrl_base | (check_enhanced_ibrs_inuse() ?
+                                       SPEC_CTRL_FEATURE_ENABLE_IBRS : 0);
+       msr |= ssbd_tif_to_spec_ctrl(tifn);
 
        this_cpu_write(x86_spec_ctrl_restore,  msr);
        wrmsrl(MSR_IA32_SPEC_CTRL, msr);