]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
x86/spectre_v2: Disable IBRS if spectre_v2=off
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Fri, 9 Feb 2018 22:19:01 +0000 (17:19 -0500)
committerJack Vogel <jack.vogel@oracle.com>
Sat, 10 Feb 2018 01:05:20 +0000 (17:05 -0800)
We found some interesting behaviors when booting on IBRS enabled
hardware where 'spectre_v2=off' did not disable IBRS completely.

That is during the bootup we received some interrupts which
meant that we set the MSR 0x48 to 1.. and then when we got
to the code that handles 'spectre_v2=off' we would just
call 'set_ibrs_disabled' which would clear the in_use parameter.

But that would not clear the wedged MSR 048 being set to 1.

Which means we would continue on with both retpoline and IBRS on!

The fix is rather simple -  clear the MSR as well.

Note that if 'noibrs' was used - then we would have disabled the
IBRS _before_ we got the interrupt, as 'noibrs' is an early parameter.

OraBug: 27525754
Reported-by: Yao-Min Chen <yaomin.chen@oracle.com>
Reviewed-by: Mike Kravetz <mike.kravetz@oracle.com>
Reviewed-by: Khalid Aziz <khalid.aziz@oracle.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
arch/x86/kernel/cpu/bugs_64.c

index 4ff548da4cd1943802fcbade761fef327f08d7dc..6fbbdee42cfa47e594f166b6e14adaf8aa4ec157 100644 (file)
@@ -8,6 +8,7 @@
 #ifdef CONFIG_SYSFS
 #include <linux/device.h>
 #endif
+#include <linux/cpu.h>
 #include <asm/alternative.h>
 #include <asm/nospec-branch.h>
 #include <asm/cmdline.h>
@@ -295,6 +296,15 @@ static enum spectre_v2_mitigation __init ibrs_select(void)
 static void __init disable_ibrs_and_friends(bool disable_ibpb)
 {
        set_ibrs_disabled();
+       if (use_ibrs & SPEC_CTRL_IBRS_SUPPORTED) {
+               unsigned int cpu;
+
+               get_online_cpus();
+               for_each_online_cpu(cpu)
+                       wrmsrl_on_cpu(cpu, MSR_IA32_SPEC_CTRL, SPEC_CTRL_FEATURE_DISABLE_IBRS);
+
+               put_online_cpus();
+       }
        /* We need to use IBPB with retpoline if it is available. */
        if (disable_ibpb)
                set_ibpb_disabled();