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>
#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>
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();