return false;
}
+int refresh_set_spectre_v2_enabled(void)
+{
+ if (retpoline_enabled())
+ return false;
+
+ if (check_ibrs_inuse())
+ spectre_v2_enabled = SPECTRE_V2_IBRS;
+ else {
+ /*
+ * If that didn't work (say no microcode or noibrs), we end up using
+ * lfence on system calls/exceptions/parameters.
+ */
+ if (lfence_inuse)
+ spectre_v2_enabled = SPECTRE_V2_IBRS_LFENCE;
+ else
+ spectre_v2_enabled = SPECTRE_V2_NONE;
+ }
+
+ return true;
+}
+
static void __init spec2_print_if_insecure(const char *reason)
{
if (boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2))
return sprintf(buf, "Not affected\n");
- return sprintf(buf, "%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
- ibrs_inuse ? "" /* As spectre_v2_strings has it. */ :
- lfence_inuse ? " lfence " : "",
+ return sprintf(buf, "%s%s\n", spectre_v2_strings[spectre_v2_enabled],
ibpb_inuse ? ", IBPB" : "");
}
#endif
if (!ibrs_supported)
return -ENODEV;
+ if (retpoline_enabled()) {
+ pr_warn("retpoline is enabled. Ignoring request to change ibrs state.\n");
+ return -EINVAL;
+ }
+
len = min(count, sizeof(buf) - 1);
if (copy_from_user(buf, user_buf, len))
return -EFAULT;
} else {
clear_ibrs_disabled();
}
+ refresh_set_spectre_v2_enabled();
mutex_unlock(&spec_ctrl_mutex);
return count;
else
clear_ibpb_disabled();
+ refresh_set_spectre_v2_enabled();
+
mutex_unlock(&spec_ctrl_mutex);
return count;
}
unsigned int enable;
/* You have to disable IBRS first. */
- if (ibrs_inuse) {
- pr_warn("IBRS is enabled. Ignoring request to change lfence_enabled state.");
+ if (ibrs_inuse || retpoline_enabled()) {
+ pr_warn("%s is enabled. Ignoring request to change lfence_enabled state.\n",
+ ibrs_inuse ? "IBRS" : "retpoline");
return -EINVAL;
}
else
clear_lfence_disabled();
+ refresh_set_spectre_v2_enabled();
+
mutex_unlock(&spec_ctrl_mutex);
return count;
}