module: pass struct find_symbol_args to find_symbol

Simplify the calling convention by passing the find_symbol_args structure
to find_symbol instead of initializing it inside the function.

Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jessica Yu <jeyu@kernel.org>
This commit is contained in:
Christoph Hellwig 2021-01-20 14:58:27 +01:00 committed by Jessica Yu
parent 71e4b309dc
commit 0b96615cdc

View file

@ -531,12 +531,7 @@ 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)
static bool find_symbol(struct find_symbol_arg *fsa)
{
static const struct symsearch arr[] = {
{ __start___ksymtab, __stop___ksymtab, __start___kcrctab,
@ -556,19 +551,14 @@ static const struct kernel_symbol *find_symbol(const char *name,
GPL_ONLY, true },
#endif
};
struct find_symbol_arg fsa = {
.name = name,
.gplok = gplok,
.warn = warn,
};
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))
goto found;
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)) {
@ -598,21 +588,12 @@ static const struct kernel_symbol *find_symbol(const char *name,
continue;
for (i = 0; i < ARRAY_SIZE(arr); i++)
if (find_exported_symbol_in_section(&arr[i], mod, &fsa))
goto found;
if (find_exported_symbol_in_section(&arr[i], mod, fsa))
return true;
}
pr_debug("Failed to find symbol %s\n", name);
return NULL;
found:
if (owner)
*owner = fsa.owner;
if (crc)
*crc = fsa.crc;
if (license)
*license = fsa.license;
return fsa.sym;
pr_debug("Failed to find symbol %s\n", fsa->name);
return false;
}
/*
@ -1074,12 +1055,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);
@ -1348,19 +1332,22 @@ static int check_version(const struct load_info *info,
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. */
@ -1454,10 +1441,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;
/*
@ -1467,42 +1455,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 *
@ -2263,16 +2249,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);
@ -2285,7 +2274,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;
@ -2302,12 +2290,15 @@ static int verify_exported_symbols(struct module *mod)
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;
}
}