|
@@ -2214,29 +2214,34 @@ static const char *get_ksymbol(struct module *mod,
|
|
/* For kallsyms to ask for address resolution. NULL means not found.
|
|
/* For kallsyms to ask for address resolution. NULL means not found.
|
|
We don't lock, as this is used for oops resolution and races are a
|
|
We don't lock, as this is used for oops resolution and races are a
|
|
lesser concern. */
|
|
lesser concern. */
|
|
|
|
+/* FIXME: Risky: returns a pointer into a module w/o lock */
|
|
const char *module_address_lookup(unsigned long addr,
|
|
const char *module_address_lookup(unsigned long addr,
|
|
unsigned long *size,
|
|
unsigned long *size,
|
|
unsigned long *offset,
|
|
unsigned long *offset,
|
|
char **modname)
|
|
char **modname)
|
|
{
|
|
{
|
|
struct module *mod;
|
|
struct module *mod;
|
|
|
|
+ const char *ret = NULL;
|
|
|
|
|
|
|
|
+ preempt_disable();
|
|
list_for_each_entry(mod, &modules, list) {
|
|
list_for_each_entry(mod, &modules, list) {
|
|
if (within(addr, mod->module_init, mod->init_size)
|
|
if (within(addr, mod->module_init, mod->init_size)
|
|
|| within(addr, mod->module_core, mod->core_size)) {
|
|
|| within(addr, mod->module_core, mod->core_size)) {
|
|
if (modname)
|
|
if (modname)
|
|
*modname = mod->name;
|
|
*modname = mod->name;
|
|
- return get_ksymbol(mod, addr, size, offset);
|
|
|
|
|
|
+ ret = get_ksymbol(mod, addr, size, offset);
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return NULL;
|
|
|
|
|
|
+ preempt_enable();
|
|
|
|
+ return ret;
|
|
}
|
|
}
|
|
|
|
|
|
int lookup_module_symbol_name(unsigned long addr, char *symname)
|
|
int lookup_module_symbol_name(unsigned long addr, char *symname)
|
|
{
|
|
{
|
|
struct module *mod;
|
|
struct module *mod;
|
|
|
|
|
|
- mutex_lock(&module_mutex);
|
|
|
|
|
|
+ preempt_disable();
|
|
list_for_each_entry(mod, &modules, list) {
|
|
list_for_each_entry(mod, &modules, list) {
|
|
if (within(addr, mod->module_init, mod->init_size) ||
|
|
if (within(addr, mod->module_init, mod->init_size) ||
|
|
within(addr, mod->module_core, mod->core_size)) {
|
|
within(addr, mod->module_core, mod->core_size)) {
|
|
@@ -2246,12 +2251,12 @@ int lookup_module_symbol_name(unsigned long addr, char *symname)
|
|
if (!sym)
|
|
if (!sym)
|
|
goto out;
|
|
goto out;
|
|
strlcpy(symname, sym, KSYM_NAME_LEN);
|
|
strlcpy(symname, sym, KSYM_NAME_LEN);
|
|
- mutex_unlock(&module_mutex);
|
|
|
|
|
|
+ preempt_enable();
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
out:
|
|
- mutex_unlock(&module_mutex);
|
|
|
|
|
|
+ preempt_enable();
|
|
return -ERANGE;
|
|
return -ERANGE;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2260,7 +2265,7 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
|
|
{
|
|
{
|
|
struct module *mod;
|
|
struct module *mod;
|
|
|
|
|
|
- mutex_lock(&module_mutex);
|
|
|
|
|
|
+ preempt_disable();
|
|
list_for_each_entry(mod, &modules, list) {
|
|
list_for_each_entry(mod, &modules, list) {
|
|
if (within(addr, mod->module_init, mod->init_size) ||
|
|
if (within(addr, mod->module_init, mod->init_size) ||
|
|
within(addr, mod->module_core, mod->core_size)) {
|
|
within(addr, mod->module_core, mod->core_size)) {
|
|
@@ -2273,12 +2278,12 @@ int lookup_module_symbol_attrs(unsigned long addr, unsigned long *size,
|
|
strlcpy(modname, mod->name, MODULE_NAME_LEN);
|
|
strlcpy(modname, mod->name, MODULE_NAME_LEN);
|
|
if (name)
|
|
if (name)
|
|
strlcpy(name, sym, KSYM_NAME_LEN);
|
|
strlcpy(name, sym, KSYM_NAME_LEN);
|
|
- mutex_unlock(&module_mutex);
|
|
|
|
|
|
+ preempt_enable();
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
out:
|
|
- mutex_unlock(&module_mutex);
|
|
|
|
|
|
+ preempt_enable();
|
|
return -ERANGE;
|
|
return -ERANGE;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2287,7 +2292,7 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
|
|
{
|
|
{
|
|
struct module *mod;
|
|
struct module *mod;
|
|
|
|
|
|
- mutex_lock(&module_mutex);
|
|
|
|
|
|
+ preempt_disable();
|
|
list_for_each_entry(mod, &modules, list) {
|
|
list_for_each_entry(mod, &modules, list) {
|
|
if (symnum < mod->num_symtab) {
|
|
if (symnum < mod->num_symtab) {
|
|
*value = mod->symtab[symnum].st_value;
|
|
*value = mod->symtab[symnum].st_value;
|
|
@@ -2296,12 +2301,12 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
|
|
KSYM_NAME_LEN);
|
|
KSYM_NAME_LEN);
|
|
strlcpy(module_name, mod->name, MODULE_NAME_LEN);
|
|
strlcpy(module_name, mod->name, MODULE_NAME_LEN);
|
|
*exported = is_exported(name, mod);
|
|
*exported = is_exported(name, mod);
|
|
- mutex_unlock(&module_mutex);
|
|
|
|
|
|
+ preempt_enable();
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
symnum -= mod->num_symtab;
|
|
symnum -= mod->num_symtab;
|
|
}
|
|
}
|
|
- mutex_unlock(&module_mutex);
|
|
|
|
|
|
+ preempt_enable();
|
|
return -ERANGE;
|
|
return -ERANGE;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2324,6 +2329,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
|
|
unsigned long ret = 0;
|
|
unsigned long ret = 0;
|
|
|
|
|
|
/* Don't lock: we're in enough trouble already. */
|
|
/* Don't lock: we're in enough trouble already. */
|
|
|
|
+ preempt_disable();
|
|
if ((colon = strchr(name, ':')) != NULL) {
|
|
if ((colon = strchr(name, ':')) != NULL) {
|
|
*colon = '\0';
|
|
*colon = '\0';
|
|
if ((mod = find_module(name)) != NULL)
|
|
if ((mod = find_module(name)) != NULL)
|
|
@@ -2334,6 +2340,7 @@ unsigned long module_kallsyms_lookup_name(const char *name)
|
|
if ((ret = mod_find_symname(mod, name)) != 0)
|
|
if ((ret = mod_find_symname(mod, name)) != 0)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ preempt_enable();
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
#endif /* CONFIG_KALLSYMS */
|
|
#endif /* CONFIG_KALLSYMS */
|