pr_info(__VA_ARGS__);                   \
        } while (0)
 
+static bool __init is_enabled(struct lsm_info *lsm)
+{
+       if (!lsm->enabled || *lsm->enabled)
+               return true;
+
+       return false;
+}
+
+/* Mark an LSM's enabled flag. */
+static int lsm_enabled_true __initdata = 1;
+static int lsm_enabled_false __initdata = 0;
+static void __init set_enabled(struct lsm_info *lsm, bool enabled)
+{
+       /*
+        * When an LSM hasn't configured an enable variable, we can use
+        * a hard-coded location for storing the default enabled state.
+        */
+       if (!lsm->enabled) {
+               if (enabled)
+                       lsm->enabled = &lsm_enabled_true;
+               else
+                       lsm->enabled = &lsm_enabled_false;
+       } else if (lsm->enabled == &lsm_enabled_true) {
+               if (!enabled)
+                       lsm->enabled = &lsm_enabled_false;
+       } else if (lsm->enabled == &lsm_enabled_false) {
+               if (enabled)
+                       lsm->enabled = &lsm_enabled_true;
+       } else {
+               *lsm->enabled = enabled;
+       }
+}
+
+/* Is an LSM allowed to be initialized? */
+static bool __init lsm_allowed(struct lsm_info *lsm)
+{
+       /* Skip if the LSM is disabled. */
+       if (!is_enabled(lsm))
+               return false;
+
+       /* Skip major-specific checks if not a major LSM. */
+       if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
+               return true;
+
+       /* Disabled if this LSM isn't the chosen one. */
+       if (strcmp(lsm->name, chosen_lsm) != 0)
+               return false;
+
+       return true;
+}
+
+/* Check if LSM should be initialized. */
+static void __init maybe_initialize_lsm(struct lsm_info *lsm)
+{
+       int enabled = lsm_allowed(lsm);
+
+       /* Record enablement (to handle any following exclusive LSMs). */
+       set_enabled(lsm, enabled);
+
+       /* If selected, initialize the LSM. */
+       if (enabled) {
+               int ret;
+
+               init_debug("initializing %s\n", lsm->name);
+               ret = lsm->init();
+               WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+       }
+}
+
 static void __init ordered_lsm_init(void)
 {
        struct lsm_info *lsm;
-       int ret;
 
        for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
                if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0)
                        continue;
 
-               init_debug("initializing %s\n", lsm->name);
-               ret = lsm->init();
-               WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+               maybe_initialize_lsm(lsm);
        }
 }
 
 static void __init major_lsm_init(void)
 {
        struct lsm_info *lsm;
-       int ret;
 
        for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
                if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
                        continue;
 
-               init_debug("initializing %s\n", lsm->name);
-               ret = lsm->init();
-               WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+               maybe_initialize_lsm(lsm);
        }
 }
 
        return 0;
 }
 
-/**
- * security_module_enable - Load given security module on boot ?
- * @module: the name of the module
- *
- * Each LSM must pass this method before registering its own operations
- * to avoid security registration races. This method may also be used
- * to check if your LSM is currently loaded during kernel initialization.
- *
- * Returns:
- *
- * true if:
- *
- * - The passed LSM is the one chosen by user at boot time,
- * - or the passed LSM is configured as the default and the user did not
- *   choose an alternate LSM at boot time.
- *
- * Otherwise, return false.
- */
-int __init security_module_enable(const char *module)
-{
-       return !strcmp(module, chosen_lsm);
-}
-
 /**
  * security_add_hooks - Add a modules hooks to the hook lists.
  * @hooks: the hooks to add