]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
retpoline: move lock/unlock of spec_ctrl_mutex to check_modinfo()
authorChuck Anderson <chuck.anderson@oracle.com>
Mon, 26 Feb 2018 08:59:51 +0000 (00:59 -0800)
committerChuck Anderson <chuck.anderson@oracle.com>
Sat, 3 Mar 2018 01:58:37 +0000 (17:58 -0800)
Testing has found that check_modinfo() will call disable_retpoline()
concurrently for the same module.  Serialization through
spec_ctrl_mutex in disable_retpoline() keeps the retpoline state sane
but misleading messages are issued during the duplicate call.
Move the lock/unlock of spec_ctrl_mutex to check_modinfo() so that the
first call to disable_retpoline() will disable retpoline before the
duplicate call checks to see if retpoline is disabled.

Orabug: 27625404
Signed-off-by: Chuck Anderson <chuck.anderson@oracle.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: Darren Kenny <darren.kenny@oracle.com>
arch/x86/kernel/cpu/bugs_64.c
kernel/module.c

index 63c77b8ee8f6f7f3fe0955c40c32e78addcd2d95..21cad468d13e7bdf98fcb38a0371a925ed0ac941 100644 (file)
@@ -169,18 +169,16 @@ static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE;
  * If possible, fall back to IBRS and IBPB.
  * Failing that, indicate that we have no Spectre v2 mitigation.
  *
- * Obtains spec_ctrl_mutex before checking/changing Spectre v2 mitigation
- * state.
+ * Checks that spec_ctrl_mutex is held.
  */
 void disable_retpoline(void)
 {
-       mutex_lock(&spec_ctrl_mutex);
+       BUG_ON(!mutex_is_locked(&spec_ctrl_mutex));
 
        if (retpoline_enabled()) {
                pr_err("Disabling Spectre v2 mitigation retpoline.\n");
        } else {
                /* retpoline is not enabled.  Return */
-               mutex_unlock(&spec_ctrl_mutex);
                return;
        }
 
@@ -209,8 +207,6 @@ void disable_retpoline(void)
 
        if (spectre_v2_enabled == SPECTRE_V2_NONE)
                pr_err("system may be vulnerable to spectre\n");
-
-       mutex_unlock(&spec_ctrl_mutex);
 }
 
 bool retpoline_enabled(void)
index 634ecdbcb9ad25ee2d60fee7f5e37d3e8ea896eb..e0cd14d0e7cbdc02b4a2ef475f4119a8aa1abd54 100644 (file)
 #include <uapi/linux/module.h>
 #include "module-internal.h"
 
+#ifdef RETPOLINE
+#include <asm/spec_ctrl.h>
+#endif
+
 #define CREATE_TRACE_POINTS
 #include <trace/events/module.h>
 
@@ -2714,13 +2718,18 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
        if (!get_modinfo(info, "intree"))
                add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
 #ifdef RETPOLINE
+       mutex_lock(&spec_ctrl_mutex);
+
        if (retpoline_enabled() && !get_modinfo(info, "retpoline")) {
                if (!test_taint(TAINT_NO_RETPOLINE)) {
                        pr_warn("%s: loading module not compiled with retpoline compiler.\n",
                                mod->name);
                }
-               add_taint_module(mod, TAINT_NO_RETPOLINE, LOCKDEP_STILL_OK);
                disable_retpoline();
+               mutex_unlock(&spec_ctrl_mutex);
+               add_taint_module(mod, TAINT_NO_RETPOLINE, LOCKDEP_STILL_OK);
+       } else {
+               mutex_unlock(&spec_ctrl_mutex);
        }
 #endif
        if (get_modinfo(info, "staging")) {