tools headers UAPI: Sync openat2.h with the kernel sources
[linux-2.6-microblaze.git] / kernel / module.c
index 8c0a42c..3047935 100644 (file)
@@ -408,19 +408,8 @@ extern const struct kernel_symbol __start___ksymtab[];
 extern const struct kernel_symbol __stop___ksymtab[];
 extern const struct kernel_symbol __start___ksymtab_gpl[];
 extern const struct kernel_symbol __stop___ksymtab_gpl[];
-extern const struct kernel_symbol __start___ksymtab_gpl_future[];
-extern const struct kernel_symbol __stop___ksymtab_gpl_future[];
 extern const s32 __start___kcrctab[];
 extern const s32 __start___kcrctab_gpl[];
-extern const s32 __start___kcrctab_gpl_future[];
-#ifdef CONFIG_UNUSED_SYMBOLS
-extern const struct kernel_symbol __start___ksymtab_unused[];
-extern const struct kernel_symbol __stop___ksymtab_unused[];
-extern const struct kernel_symbol __start___ksymtab_unused_gpl[];
-extern const struct kernel_symbol __stop___ksymtab_unused_gpl[];
-extern const s32 __start___kcrctab_unused[];
-extern const s32 __start___kcrctab_unused_gpl[];
-#endif
 
 #ifndef CONFIG_MODVERSIONS
 #define symversion(base, idx) NULL
@@ -428,72 +417,14 @@ extern const s32 __start___kcrctab_unused_gpl[];
 #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
 #endif
 
-/* Returns true as soon as fn returns true, otherwise false. */
-static bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
-                                   struct module *owner,
-                                   void *data),
-                        void *data)
-{
-       unsigned int i;
-       struct module *mod;
-       static const struct symsearch arr[] = {
-               { __start___ksymtab, __stop___ksymtab, __start___kcrctab,
-                 NOT_GPL_ONLY, false },
-               { __start___ksymtab_gpl, __stop___ksymtab_gpl,
-                 __start___kcrctab_gpl,
-                 GPL_ONLY, false },
-               { __start___ksymtab_gpl_future, __stop___ksymtab_gpl_future,
-                 __start___kcrctab_gpl_future,
-                 WILL_BE_GPL_ONLY, false },
-#ifdef CONFIG_UNUSED_SYMBOLS
-               { __start___ksymtab_unused, __stop___ksymtab_unused,
-                 __start___kcrctab_unused,
-                 NOT_GPL_ONLY, true },
-               { __start___ksymtab_unused_gpl, __stop___ksymtab_unused_gpl,
-                 __start___kcrctab_unused_gpl,
-                 GPL_ONLY, true },
-#endif
-       };
-
-       module_assert_mutex_or_preempt();
-
-       for (i = 0; i < ARRAY_SIZE(arr); i++)
-               if (fn(&arr[i], NULL, data))
-                       return true;
-
-       list_for_each_entry_rcu(mod, &modules, list,
-                               lockdep_is_held(&module_mutex)) {
-               struct symsearch arr[] = {
-                       { mod->syms, mod->syms + mod->num_syms, mod->crcs,
-                         NOT_GPL_ONLY, false },
-                       { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
-                         mod->gpl_crcs,
-                         GPL_ONLY, false },
-                       { mod->gpl_future_syms,
-                         mod->gpl_future_syms + mod->num_gpl_future_syms,
-                         mod->gpl_future_crcs,
-                         WILL_BE_GPL_ONLY, false },
-#ifdef CONFIG_UNUSED_SYMBOLS
-                       { mod->unused_syms,
-                         mod->unused_syms + mod->num_unused_syms,
-                         mod->unused_crcs,
-                         NOT_GPL_ONLY, true },
-                       { mod->unused_gpl_syms,
-                         mod->unused_gpl_syms + mod->num_unused_gpl_syms,
-                         mod->unused_gpl_crcs,
-                         GPL_ONLY, true },
-#endif
-               };
-
-               if (mod->state == MODULE_STATE_UNFORMED)
-                       continue;
-
-               for (i = 0; i < ARRAY_SIZE(arr); i++)
-                       if (fn(&arr[i], mod, data))
-                               return true;
-       }
-       return false;
-}
+struct symsearch {
+       const struct kernel_symbol *start, *stop;
+       const s32 *crcs;
+       enum mod_license {
+               NOT_GPL_ONLY,
+               GPL_ONLY,
+       } license;
+};
 
 struct find_symbol_arg {
        /* Input */
@@ -514,28 +445,8 @@ static bool check_exported_symbol(const struct symsearch *syms,
 {
        struct find_symbol_arg *fsa = data;
 
-       if (!fsa->gplok) {
-               if (syms->license == GPL_ONLY)
-                       return false;
-               if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) {
-                       pr_warn("Symbol %s is being used by a non-GPL module, "
-                               "which will not be allowed in the future\n",
-                               fsa->name);
-               }
-       }
-
-#ifdef CONFIG_UNUSED_SYMBOLS
-       if (syms->unused && fsa->warn) {
-               pr_warn("Symbol %s is marked as UNUSED, however this module is "
-                       "using it.\n", fsa->name);
-               pr_warn("This symbol will go away in the future.\n");
-               pr_warn("Please evaluate if this is the right api to use and "
-                       "if it really is, submit a report to the linux kernel "
-                       "mailing list together with submitting your code for "
-                       "inclusion.\n");
-       }
-#endif
-
+       if (!fsa->gplok && syms->license == GPL_ONLY)
+               return false;
        fsa->owner = owner;
        fsa->crc = symversion(syms->crcs, symnum);
        fsa->sym = &syms->start[symnum];
@@ -598,31 +509,44 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
  * Find an exported symbol and return it, along with, (optional) crc and
  * (optional) module which owns it.  Needs preempt disabled or module_mutex.
  */
-static const struct kernel_symbol *find_symbol(const char *name,
-                                       struct module **owner,
-                                       const s32 **crc,
-                                       enum mod_license *license,
-                                       bool gplok,
-                                       bool warn)
-{
-       struct find_symbol_arg fsa;
-
-       fsa.name = name;
-       fsa.gplok = gplok;
-       fsa.warn = warn;
-
-       if (each_symbol_section(find_exported_symbol_in_section, &fsa)) {
-               if (owner)
-                       *owner = fsa.owner;
-               if (crc)
-                       *crc = fsa.crc;
-               if (license)
-                       *license = fsa.license;
-               return fsa.sym;
+static bool find_symbol(struct find_symbol_arg *fsa)
+{
+       static const struct symsearch arr[] = {
+               { __start___ksymtab, __stop___ksymtab, __start___kcrctab,
+                 NOT_GPL_ONLY },
+               { __start___ksymtab_gpl, __stop___ksymtab_gpl,
+                 __start___kcrctab_gpl,
+                 GPL_ONLY },
+       };
+       struct module *mod;
+       unsigned int i;
+
+       module_assert_mutex_or_preempt();
+
+       for (i = 0; i < ARRAY_SIZE(arr); i++)
+               if (find_exported_symbol_in_section(&arr[i], NULL, fsa))
+                       return true;
+
+       list_for_each_entry_rcu(mod, &modules, list,
+                               lockdep_is_held(&module_mutex)) {
+               struct symsearch arr[] = {
+                       { mod->syms, mod->syms + mod->num_syms, mod->crcs,
+                         NOT_GPL_ONLY },
+                       { mod->gpl_syms, mod->gpl_syms + mod->num_gpl_syms,
+                         mod->gpl_crcs,
+                         GPL_ONLY },
+               };
+
+               if (mod->state == MODULE_STATE_UNFORMED)
+                       continue;
+
+               for (i = 0; i < ARRAY_SIZE(arr); i++)
+                       if (find_exported_symbol_in_section(&arr[i], mod, fsa))
+                               return true;
        }
 
-       pr_debug("Failed to find symbol %s\n", name);
-       return NULL;
+       pr_debug("Failed to find symbol %s\n", fsa->name);
+       return false;
 }
 
 /*
@@ -1084,12 +1008,15 @@ static inline void print_unload_info(struct seq_file *m, struct module *mod)
 
 void __symbol_put(const char *symbol)
 {
-       struct module *owner;
+       struct find_symbol_arg fsa = {
+               .name   = symbol,
+               .gplok  = true,
+       };
 
        preempt_disable();
-       if (!find_symbol(symbol, &owner, NULL, NULL, true, false))
+       if (!find_symbol(&fsa))
                BUG();
-       module_put(owner);
+       module_put(fsa.owner);
        preempt_enable();
 }
 EXPORT_SYMBOL(__symbol_put);
@@ -1358,19 +1285,22 @@ bad_version:
 static inline int check_modstruct_version(const struct load_info *info,
                                          struct module *mod)
 {
-       const s32 *crc;
+       struct find_symbol_arg fsa = {
+               .name   = "module_layout",
+               .gplok  = true,
+       };
 
        /*
         * Since this should be found in kernel (which can't be removed), no
         * locking is necessary -- use preempt_disable() to placate lockdep.
         */
        preempt_disable();
-       if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) {
+       if (!find_symbol(&fsa)) {
                preempt_enable();
                BUG();
        }
        preempt_enable();
-       return check_version(info, "module_layout", mod, crc);
+       return check_version(info, "module_layout", mod, fsa.crc);
 }
 
 /* First part is kernel version, which we ignore if module has crcs. */
@@ -1464,10 +1394,11 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
                                                  const char *name,
                                                  char ownername[])
 {
-       struct module *owner;
-       const struct kernel_symbol *sym;
-       const s32 *crc;
-       enum mod_license license;
+       struct find_symbol_arg fsa = {
+               .name   = name,
+               .gplok  = !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)),
+               .warn   = true,
+       };
        int err;
 
        /*
@@ -1477,42 +1408,40 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
         */
        sched_annotate_sleep();
        mutex_lock(&module_mutex);
-       sym = find_symbol(name, &owner, &crc, &license,
-                         !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
-       if (!sym)
+       if (!find_symbol(&fsa))
                goto unlock;
 
-       if (license == GPL_ONLY)
+       if (fsa.license == GPL_ONLY)
                mod->using_gplonly_symbols = true;
 
-       if (!inherit_taint(mod, owner)) {
-               sym = NULL;
+       if (!inherit_taint(mod, fsa.owner)) {
+               fsa.sym = NULL;
                goto getname;
        }
 
-       if (!check_version(info, name, mod, crc)) {
-               sym = ERR_PTR(-EINVAL);
+       if (!check_version(info, name, mod, fsa.crc)) {
+               fsa.sym = ERR_PTR(-EINVAL);
                goto getname;
        }
 
-       err = verify_namespace_is_imported(info, sym, mod);
+       err = verify_namespace_is_imported(info, fsa.sym, mod);
        if (err) {
-               sym = ERR_PTR(err);
+               fsa.sym = ERR_PTR(err);
                goto getname;
        }
 
-       err = ref_module(mod, owner);
+       err = ref_module(mod, fsa.owner);
        if (err) {
-               sym = ERR_PTR(err);
+               fsa.sym = ERR_PTR(err);
                goto getname;
        }
 
 getname:
        /* We must make copy under the lock if we failed to get ref. */
-       strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
+       strncpy(ownername, module_name(fsa.owner), MODULE_NAME_LEN);
 unlock:
        mutex_unlock(&module_mutex);
-       return sym;
+       return fsa.sym;
 }
 
 static const struct kernel_symbol *
@@ -2273,16 +2202,19 @@ static void free_module(struct module *mod)
 
 void *__symbol_get(const char *symbol)
 {
-       struct module *owner;
-       const struct kernel_symbol *sym;
+       struct find_symbol_arg fsa = {
+               .name   = symbol,
+               .gplok  = true,
+               .warn   = true,
+       };
 
        preempt_disable();
-       sym = find_symbol(symbol, &owner, NULL, NULL, true, true);
-       if (sym && strong_try_module_get(owner))
-               sym = NULL;
+       if (!find_symbol(&fsa) || strong_try_module_get(fsa.owner)) {
+               preempt_enable();
+               return NULL;
+       }
        preempt_enable();
-
-       return sym ? (void *)kernel_symbol_value(sym) : NULL;
+       return (void *)kernel_symbol_value(fsa.sym);
 }
 EXPORT_SYMBOL_GPL(__symbol_get);
 
@@ -2295,7 +2227,6 @@ EXPORT_SYMBOL_GPL(__symbol_get);
 static int verify_exported_symbols(struct module *mod)
 {
        unsigned int i;
-       struct module *owner;
        const struct kernel_symbol *s;
        struct {
                const struct kernel_symbol *sym;
@@ -2303,21 +2234,19 @@ static int verify_exported_symbols(struct module *mod)
        } arr[] = {
                { mod->syms, mod->num_syms },
                { mod->gpl_syms, mod->num_gpl_syms },
-               { mod->gpl_future_syms, mod->num_gpl_future_syms },
-#ifdef CONFIG_UNUSED_SYMBOLS
-               { mod->unused_syms, mod->num_unused_syms },
-               { mod->unused_gpl_syms, mod->num_unused_gpl_syms },
-#endif
        };
 
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
                for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
-                       if (find_symbol(kernel_symbol_name(s), &owner, NULL,
-                                       NULL, true, false)) {
+                       struct find_symbol_arg fsa = {
+                               .name   = kernel_symbol_name(s),
+                               .gplok  = true,
+                       };
+                       if (find_symbol(&fsa)) {
                                pr_err("%s: exports duplicate symbol %s"
                                       " (owned by %s)\n",
                                       mod->name, kernel_symbol_name(s),
-                                      module_name(owner));
+                                      module_name(fsa.owner));
                                return -ENOEXEC;
                        }
                }
@@ -3316,22 +3245,7 @@ static int find_module_sections(struct module *mod, struct load_info *info)
                                     sizeof(*mod->gpl_syms),
                                     &mod->num_gpl_syms);
        mod->gpl_crcs = section_addr(info, "__kcrctab_gpl");
-       mod->gpl_future_syms = section_objs(info,
-                                           "__ksymtab_gpl_future",
-                                           sizeof(*mod->gpl_future_syms),
-                                           &mod->num_gpl_future_syms);
-       mod->gpl_future_crcs = section_addr(info, "__kcrctab_gpl_future");
-
-#ifdef CONFIG_UNUSED_SYMBOLS
-       mod->unused_syms = section_objs(info, "__ksymtab_unused",
-                                       sizeof(*mod->unused_syms),
-                                       &mod->num_unused_syms);
-       mod->unused_crcs = section_addr(info, "__kcrctab_unused");
-       mod->unused_gpl_syms = section_objs(info, "__ksymtab_unused_gpl",
-                                           sizeof(*mod->unused_gpl_syms),
-                                           &mod->num_unused_gpl_syms);
-       mod->unused_gpl_crcs = section_addr(info, "__kcrctab_unused_gpl");
-#endif
+
 #ifdef CONFIG_CONSTRUCTORS
        mod->ctors = section_objs(info, ".ctors",
                                  sizeof(*mod->ctors), &mod->num_ctors);
@@ -3512,14 +3426,8 @@ static int check_module_license_and_versions(struct module *mod)
                pr_warn("%s: module license taints kernel.\n", mod->name);
 
 #ifdef CONFIG_MODVERSIONS
-       if ((mod->num_syms && !mod->crcs)
-           || (mod->num_gpl_syms && !mod->gpl_crcs)
-           || (mod->num_gpl_future_syms && !mod->gpl_future_crcs)
-#ifdef CONFIG_UNUSED_SYMBOLS
-           || (mod->num_unused_syms && !mod->unused_crcs)
-           || (mod->num_unused_gpl_syms && !mod->unused_gpl_crcs)
-#endif
-               ) {
+       if ((mod->num_syms && !mod->crcs) ||
+           (mod->num_gpl_syms && !mod->gpl_crcs)) {
                return try_to_force_load(mod,
                                         "no versions for exported symbols");
        }
@@ -4480,7 +4388,7 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
 {
        struct module *mod;
        unsigned int i;
-       int ret;
+       int ret = 0;
 
        mutex_lock(&module_mutex);
        list_for_each_entry(mod, &modules, list) {