diff options
Diffstat (limited to 'module/spl/spl-proc.c')
-rw-r--r-- | module/spl/spl-proc.c | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/module/spl/spl-proc.c b/module/spl/spl-proc.c index 90c89ce31..d0ce23194 100644 --- a/module/spl/spl-proc.c +++ b/module/spl/spl-proc.c @@ -68,6 +68,7 @@ struct proc_dir_entry *proc_spl_kstat = NULL; #define CTL_VERSION CTL_UNNUMBERED /* Version */ #define CTL_HOSTID CTL_UNNUMBERED /* Host id by /usr/bin/hostid */ #define CTL_HW_SERIAL CTL_UNNUMBERED /* HW serial number by hostid */ +#define CTL_KALLSYMS CTL_UNNUMBERED /* kallsyms_lookup_name addr */ #define CTL_DEBUG_SUBSYS CTL_UNNUMBERED /* Debug subsystem */ #define CTL_DEBUG_MASK CTL_UNNUMBERED /* Debug mask */ @@ -123,6 +124,7 @@ enum { CTL_VERSION = 1, /* Version */ CTL_HOSTID, /* Host id reported by /usr/bin/hostid */ CTL_HW_SERIAL, /* Hardware serial number from hostid */ + CTL_KALLSYMS, /* Address of kallsyms_lookup_name */ CTL_DEBUG_SUBSYS, /* Debug subsystem */ CTL_DEBUG_MASK, /* Debug mask */ @@ -489,6 +491,51 @@ proc_dohostid(struct ctl_table *table, int write, struct file *filp, RETURN(rc); } +#ifndef HAVE_KALLSYMS_LOOKUP_NAME +static int +proc_dokallsyms_lookup_name(struct ctl_table *table, int write, + struct file *filp, void __user *buffer, + size_t *lenp, loff_t *ppos) { + int len, rc = 0; + char *end, str[32]; + ENTRY; + + if (write) { + /* This may only be set once at module load time */ + if (spl_kallsyms_lookup_name_fn) + RETURN(-EEXIST); + + /* We can't use proc_doulongvec_minmax() in the write + * case hear because the address while a hex value has no + * leading 0x which confuses the helper function. */ + rc = proc_copyin_string(str, sizeof(str), buffer, *lenp); + if (rc < 0) + RETURN(rc); + + spl_kallsyms_lookup_name_fn = + (kallsyms_lookup_name_t)simple_strtoul(str, &end, 16); + if (str == end) + RETURN(-EINVAL); + + *ppos += *lenp; + } else { + len = snprintf(str, sizeof(str), "%lx", + (unsigned long)spl_kallsyms_lookup_name_fn); + if (*ppos >= len) + rc = 0; + else + rc = proc_copyout_string(buffer,*lenp,str+*ppos,"\n"); + + if (rc >= 0) { + *lenp = rc; + *ppos += rc; + } + } + + RETURN(rc); +} +#endif /* HAVE_KALLSYMS_LOOKUP_NAME */ + static int proc_doavailrmem(struct ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos) @@ -1018,6 +1065,16 @@ static struct ctl_table spl_table[] = { .mode = 0444, .proc_handler = &proc_dostring, }, +#ifndef HAVE_KALLSYMS_LOOKUP_NAME + { + .ctl_name = CTL_KALLSYMS, + .procname = "kallsyms_lookup_name", + .data = &spl_kallsyms_lookup_name_fn, + .maxlen = sizeof(unsigned long), + .mode = 0644, + .proc_handler = &proc_dokallsyms_lookup_name, + }, +#endif { .ctl_name = CTL_SPL_DEBUG, .procname = "debug", |