Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-m…
Browse files Browse the repository at this point in the history
…odule-and-param

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-module-and-param:
  module: use strstarts()
  strstarts: helper function for !strncmp(str, prefix, strlen(prefix))
  arm: allow usage of string functions in linux/string.h
  module: don't use stop_machine on module load
  module: create a request_module_nowait()
  module: include other structures in module version check
  module: remove the SHF_ALLOC flag on the __versions section.
  module: clarify the force-loading taint message.
  module: Export symbols needed for Ksplice
  Ksplice: Add functions for walking kallsyms symbols
  module: remove module_text_address()
  module: __module_address
  module: Make find_symbol return a struct kernel_symbol
  kernel/module.c: fix an unused goto label
  param: fix charp parameters set via sysfs

Fix trivial conflicts in kernel/extable.c manually.
  • Loading branch information
torvalds committed Apr 5, 2009
2 parents 5412b53 + 4950267 commit cab4e4c
Show file tree
Hide file tree
Showing 13 changed files with 319 additions and 137 deletions.
5 changes: 4 additions & 1 deletion arch/arm/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

unsigned int __machine_arch_type;

#include <linux/string.h>
#include <linux/compiler.h> /* for inline */
#include <linux/types.h> /* for size_t */
#include <linux/stddef.h> /* for NULL */
#include <asm/string.h>

#ifdef STANDALONE_DEBUG
#define putstr printf
Expand Down
4 changes: 2 additions & 2 deletions drivers/mtd/nand/nand_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2720,14 +2720,14 @@ int nand_scan_tail(struct mtd_info *mtd)
return chip->scan_bbt(mtd);
}

/* module_text_address() isn't exported, and it's mostly a pointless
/* is_module_text_address() isn't exported, and it's mostly a pointless
test if this is a module _anyway_ -- they'd have to try _really_ hard
to call us from in-kernel code if the core NAND support is modular. */
#ifdef MODULE
#define caller_is_module() (1)
#else
#define caller_is_module() \
module_text_address((unsigned long)__builtin_return_address(0))
is_module_text_address((unsigned long)__builtin_return_address(0))
#endif

/**
Expand Down
15 changes: 15 additions & 0 deletions include/linux/kallsyms.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,17 @@
#define KSYM_SYMBOL_LEN (sizeof("%s+%#lx/%#lx [%s]") + (KSYM_NAME_LEN - 1) + \
2*(BITS_PER_LONG*3/10) + (MODULE_NAME_LEN - 1) + 1)

struct module;

#ifdef CONFIG_KALLSYMS
/* Lookup the address for a symbol. Returns 0 if not found. */
unsigned long kallsyms_lookup_name(const char *name);

/* Call a function on each kallsyms symbol in the core kernel */
int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
unsigned long),
void *data);

extern int kallsyms_lookup_size_offset(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset);
Expand All @@ -43,6 +50,14 @@ static inline unsigned long kallsyms_lookup_name(const char *name)
return 0;
}

static inline int kallsyms_on_each_symbol(int (*fn)(void *, const char *,
struct module *,
unsigned long),
void *data)
{
return 0;
}

static inline int kallsyms_lookup_size_offset(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset)
Expand Down
11 changes: 8 additions & 3 deletions include/linux/kmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,15 @@
#ifdef CONFIG_MODULES
/* modprobe exit status on success, -ve on error. Return value
* usually useless though. */
extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
#define try_then_request_module(x, mod...) ((x) ?: (request_module(mod), (x)))
extern int __request_module(bool wait, const char *name, ...) \
__attribute__((format(printf, 2, 3)));
#define request_module(mod...) __request_module(true, mod)
#define request_module_nowait(mod...) __request_module(false, mod)
#define try_then_request_module(x, mod...) \
((x) ?: (__request_module(false, mod), (x)))
#else
static inline int request_module(const char * name, ...) { return -ENOSYS; }
static inline int request_module(const char *name, ...) { return -ENOSYS; }
static inline int request_module_nowait(const char *name, ...) { return -ENOSYS; }
#define try_then_request_module(x, mod...) (x)
#endif

Expand Down
63 changes: 55 additions & 8 deletions include/linux/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,10 @@ struct module
const unsigned long *crcs;
unsigned int num_syms;

/* Kernel parameters. */
struct kernel_param *kp;
unsigned int num_kp;

/* GPL-only exported symbols. */
unsigned int num_gpl_syms;
const struct kernel_symbol *gpl_syms;
Expand Down Expand Up @@ -350,6 +354,8 @@ struct module
#define MODULE_ARCH_INIT {}
#endif

extern struct mutex module_mutex;

/* FIXME: It'd be nice to isolate modules during init, too, so they
aren't used before they (may) fail. But presently too much code
(IDE & SCSI) require entry into the module during init.*/
Expand All @@ -358,10 +364,10 @@ static inline int module_is_live(struct module *mod)
return mod->state != MODULE_STATE_GOING;
}

/* Is this address in a module? (second is with no locks, for oops) */
struct module *module_text_address(unsigned long addr);
struct module *__module_text_address(unsigned long addr);
int is_module_address(unsigned long addr);
struct module *__module_address(unsigned long addr);
bool is_module_address(unsigned long addr);
bool is_module_text_address(unsigned long addr);

static inline int within_module_core(unsigned long addr, struct module *mod)
{
Expand All @@ -375,6 +381,31 @@ static inline int within_module_init(unsigned long addr, struct module *mod)
addr < (unsigned long)mod->module_init + mod->init_size;
}

/* Search for module by name: must hold module_mutex. */
struct module *find_module(const char *name);

struct symsearch {
const struct kernel_symbol *start, *stop;
const unsigned long *crcs;
enum {
NOT_GPL_ONLY,
GPL_ONLY,
WILL_BE_GPL_ONLY,
} licence;
bool unused;
};

/* Search for an exported symbol by name. */
const struct kernel_symbol *find_symbol(const char *name,
struct module **owner,
const unsigned long **crc,
bool gplok,
bool warn);

/* Walk the exported symbol table */
bool each_symbol(bool (*fn)(const struct symsearch *arr, struct module *owner,
unsigned int symnum, void *data), void *data);

/* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
symnum out of range. */
int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
Expand All @@ -383,6 +414,10 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
/* Look for this name: can be of form module:name. */
unsigned long module_kallsyms_lookup_name(const char *name);

int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
struct module *, unsigned long),
void *data);

extern void __module_put_and_exit(struct module *mod, long code)
__attribute__((noreturn));
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
Expand Down Expand Up @@ -444,6 +479,7 @@ static inline void __module_get(struct module *module)
#define symbol_put_addr(p) do { } while(0)

#endif /* CONFIG_MODULE_UNLOAD */
int use_module(struct module *a, struct module *b);

/* This is a #define so the string doesn't get put in every .o file */
#define module_name(mod) \
Expand Down Expand Up @@ -490,21 +526,24 @@ search_module_extables(unsigned long addr)
return NULL;
}

/* Is this address in a module? */
static inline struct module *module_text_address(unsigned long addr)
static inline struct module *__module_address(unsigned long addr)
{
return NULL;
}

/* Is this address in a module? (don't take a lock, we're oopsing) */
static inline struct module *__module_text_address(unsigned long addr)
{
return NULL;
}

static inline int is_module_address(unsigned long addr)
static inline bool is_module_address(unsigned long addr)
{
return 0;
return false;
}

static inline bool is_module_text_address(unsigned long addr)
{
return false;
}

/* Get/put a kernel symbol (calls should be symmetric) */
Expand Down Expand Up @@ -559,6 +598,14 @@ static inline unsigned long module_kallsyms_lookup_name(const char *name)
return 0;
}

static inline int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
struct module *,
unsigned long),
void *data)
{
return 0;
}

static inline int register_module_notifier(struct notifier_block * nb)
{
/* no events will happen anyway, so this can always succeed */
Expand Down
10 changes: 10 additions & 0 deletions include/linux/moduleparam.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,16 @@ extern int parse_args(const char *name,
unsigned num,
int (*unknown)(char *param, char *val));

/* Called by module remove. */
#ifdef CONFIG_SYSFS
extern void destroy_params(const struct kernel_param *params, unsigned num);
#else
static inline void destroy_params(const struct kernel_param *params,
unsigned num)
{
}
#endif /* !CONFIG_SYSFS */

/* All the helper functions */
/* The macros to do compile-time type checking stolen from Jakub
Jelinek, who IIRC came up with this idea for the 2.4 module init code. */
Expand Down
9 changes: 9 additions & 0 deletions include/linux/string.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,5 +122,14 @@ int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
const void *from, size_t available);

/**
* strstarts - does @str start with @prefix?
* @str: string to examine
* @prefix: prefix to look for.
*/
static inline bool strstarts(const char *str, const char *prefix)
{
return strncmp(str, prefix, strlen(prefix)) == 0;
}
#endif
#endif /* _LINUX_STRING_H_ */
6 changes: 3 additions & 3 deletions kernel/extable.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ __notrace_funcgraph int __kernel_text_address(unsigned long addr)
{
if (core_kernel_text(addr))
return 1;
if (__module_text_address(addr))
if (is_module_text_address(addr))
return 1;
/*
* There might be init symbols in saved stacktraces.
Expand All @@ -84,7 +84,7 @@ int kernel_text_address(unsigned long addr)
{
if (core_kernel_text(addr))
return 1;
return module_text_address(addr) != NULL;
return is_module_text_address(addr);
}

/*
Expand All @@ -100,5 +100,5 @@ int func_ptr_is_kernel_text(void *ptr)
addr = (unsigned long) dereference_function_descriptor(ptr);
if (core_kernel_text(addr))
return 1;
return module_text_address(addr) != NULL;
return is_module_text_address(addr);
}
19 changes: 19 additions & 0 deletions kernel/kallsyms.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,25 @@ unsigned long kallsyms_lookup_name(const char *name)
return module_kallsyms_lookup_name(name);
}

int kallsyms_on_each_symbol(int (*fn)(void *, const char *, struct module *,
unsigned long),
void *data)
{
char namebuf[KSYM_NAME_LEN];
unsigned long i;
unsigned int off;
int ret;

for (i = 0, off = 0; i < kallsyms_num_syms; i++) {
off = kallsyms_expand_symbol(off, namebuf);
ret = fn(data, namebuf, NULL, kallsyms_addresses[i]);
if (ret != 0)
return ret;
}
return module_kallsyms_on_each_symbol(fn, data);
}
EXPORT_SYMBOL_GPL(kallsyms_on_each_symbol);

static unsigned long get_symbol_pos(unsigned long addr,
unsigned long *symbolsize,
unsigned long *offset)
Expand Down
10 changes: 6 additions & 4 deletions kernel/kmod.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ static struct workqueue_struct *khelper_wq;
char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";

/**
* request_module - try to load a kernel module
* __request_module - try to load a kernel module
* @wait: wait (or not) for the operation to complete
* @fmt: printf style format string for the name of the module
* @...: arguments as specified in the format string
*
Expand All @@ -63,7 +64,7 @@ char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
* If module auto-loading support is disabled then this function
* becomes a no-operation.
*/
int request_module(const char *fmt, ...)
int __request_module(bool wait, const char *fmt, ...)
{
va_list args;
char module_name[MODULE_NAME_LEN];
Expand Down Expand Up @@ -108,11 +109,12 @@ int request_module(const char *fmt, ...)
return -ENOMEM;
}

ret = call_usermodehelper(modprobe_path, argv, envp, 1);
ret = call_usermodehelper(modprobe_path, argv, envp,
wait ? UMH_WAIT_PROC : UMH_WAIT_EXEC);
atomic_dec(&kmod_concurrent);
return ret;
}
EXPORT_SYMBOL(request_module);
EXPORT_SYMBOL(__request_module);
#endif /* CONFIG_MODULES */

struct subprocess_info {
Expand Down
Loading

0 comments on commit cab4e4c

Please sign in to comment.