mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-01 03:54:02 +00:00
Mainly boring here, too. rmmod --wait finally removed, though.
Cheers, Rusty. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.14 (GNU/Linux) iQIcBAABAgAGBQJSe3ngAAoJENkgDmzRrbjxqkMP/jFwTIVy+tZbPL36xR4C7UI/ JZ9JU2c2HTyAtqp/T/bljA0QUDQWUASCfwG5WmRgyvMkEwhfuGrQ3dveQLRq5iKD Ln/LIN8JXXijhRr+ywhXLAcp1P5ysSJJYYS5lZTCmJ2Cv9jnAvmUl0KqdTEx+ZNH YsWBiI9+WmwhODiAdUlqtThDK37w8OsWeMq2agf97bBERlRYnRZvzwy3tSP2mf5j 4wx8viOdzPC7NVblyX1cj3gonFFQJtMI4s/e787QzkUpNQjvrN3XecPiQX6aBCX3 seVjuv6panv1tw1HqyU1KXWo7fs2uCc9mVR5Rr3Zok+8qpKWkj0dyCnF3A+ufsrO vlkrFLUsv/U1NUkWJM6mJKzMjKRD4iF702QsEEpNA5rlOsAMMGSSlju4eu6GvadI ZJ+ZDaNWUDPbWa9Xgjyp+DKWR6vybNgEHZmLmcCdeLt1u8Th1E/ujsKxv4SN6eIO 2v+lNPjGEivoNXUX52toRZ1324U3FFzburCSA0c55+r1sjPT6SXCfl8kISSKvVtt iFemsDxhaSwqVzqbsx3ztU010Z0f9uVbpZHAQgZ514Uk25HtwhkaQSdiIP+cPXE8 rClzj9m4gD+Jy0T+P0HjPlSxKCGSlgLiEBWEigX36/F4Isv+GL1HjvrGGCWM4VnO lIyw5ux/UH8USct9nH4x =xg2p -----END PGP SIGNATURE----- Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux Pull module updates from Rusty Russell: "Mainly boring here, too. rmmod --wait finally removed, though" * tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: modpost: fix bogus 'exported twice' warnings. init: fix in-place parameter modification regression asmlinkage, module: Make ksymtab and kcrctab symbols and __this_module __visible kernel: add support for init_array constructors modpost: Optionally ignore secondary errors seen if a single module build fails module: remove rmmod --wait option.
This commit is contained in:
commit
ce6513f758
7 changed files with 55 additions and 52 deletions
|
@ -473,6 +473,7 @@
|
||||||
#define KERNEL_CTORS() . = ALIGN(8); \
|
#define KERNEL_CTORS() . = ALIGN(8); \
|
||||||
VMLINUX_SYMBOL(__ctors_start) = .; \
|
VMLINUX_SYMBOL(__ctors_start) = .; \
|
||||||
*(.ctors) \
|
*(.ctors) \
|
||||||
|
*(.init_array) \
|
||||||
VMLINUX_SYMBOL(__ctors_end) = .;
|
VMLINUX_SYMBOL(__ctors_end) = .;
|
||||||
#else
|
#else
|
||||||
#define KERNEL_CTORS()
|
#define KERNEL_CTORS()
|
||||||
|
|
|
@ -43,7 +43,7 @@ extern struct module __this_module;
|
||||||
/* Mark the CRC weak since genksyms apparently decides not to
|
/* Mark the CRC weak since genksyms apparently decides not to
|
||||||
* generate a checksums for some symbols */
|
* generate a checksums for some symbols */
|
||||||
#define __CRC_SYMBOL(sym, sec) \
|
#define __CRC_SYMBOL(sym, sec) \
|
||||||
extern void *__crc_##sym __attribute__((weak)); \
|
extern __visible void *__crc_##sym __attribute__((weak)); \
|
||||||
static const unsigned long __kcrctab_##sym \
|
static const unsigned long __kcrctab_##sym \
|
||||||
__used \
|
__used \
|
||||||
__attribute__((section("___kcrctab" sec "+" #sym), unused)) \
|
__attribute__((section("___kcrctab" sec "+" #sym), unused)) \
|
||||||
|
@ -59,7 +59,7 @@ extern struct module __this_module;
|
||||||
static const char __kstrtab_##sym[] \
|
static const char __kstrtab_##sym[] \
|
||||||
__attribute__((section("__ksymtab_strings"), aligned(1))) \
|
__attribute__((section("__ksymtab_strings"), aligned(1))) \
|
||||||
= VMLINUX_SYMBOL_STR(sym); \
|
= VMLINUX_SYMBOL_STR(sym); \
|
||||||
static const struct kernel_symbol __ksymtab_##sym \
|
__visible const struct kernel_symbol __ksymtab_##sym \
|
||||||
__used \
|
__used \
|
||||||
__attribute__((section("___ksymtab" sec "+" #sym), unused)) \
|
__attribute__((section("___ksymtab" sec "+" #sym), unused)) \
|
||||||
= { (unsigned long)&sym, __kstrtab_##sym }
|
= { (unsigned long)&sym, __kstrtab_##sym }
|
||||||
|
|
|
@ -367,9 +367,6 @@ struct module
|
||||||
/* What modules do I depend on? */
|
/* What modules do I depend on? */
|
||||||
struct list_head target_list;
|
struct list_head target_list;
|
||||||
|
|
||||||
/* Who is waiting for us to be unloaded */
|
|
||||||
struct task_struct *waiter;
|
|
||||||
|
|
||||||
/* Destruction function. */
|
/* Destruction function. */
|
||||||
void (*exit)(void);
|
void (*exit)(void);
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,8 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE];
|
||||||
char *saved_command_line;
|
char *saved_command_line;
|
||||||
/* Command line for parameter parsing */
|
/* Command line for parameter parsing */
|
||||||
static char *static_command_line;
|
static char *static_command_line;
|
||||||
|
/* Command line for per-initcall parameter parsing */
|
||||||
|
static char *initcall_command_line;
|
||||||
|
|
||||||
static char *execute_command;
|
static char *execute_command;
|
||||||
static char *ramdisk_execute_command;
|
static char *ramdisk_execute_command;
|
||||||
|
@ -354,6 +356,7 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
|
||||||
static void __init setup_command_line(char *command_line)
|
static void __init setup_command_line(char *command_line)
|
||||||
{
|
{
|
||||||
saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
|
saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
|
||||||
|
initcall_command_line = alloc_bootmem(strlen (boot_command_line)+1);
|
||||||
static_command_line = alloc_bootmem(strlen (command_line)+1);
|
static_command_line = alloc_bootmem(strlen (command_line)+1);
|
||||||
strcpy (saved_command_line, boot_command_line);
|
strcpy (saved_command_line, boot_command_line);
|
||||||
strcpy (static_command_line, command_line);
|
strcpy (static_command_line, command_line);
|
||||||
|
@ -751,9 +754,9 @@ static void __init do_initcall_level(int level)
|
||||||
extern const struct kernel_param __start___param[], __stop___param[];
|
extern const struct kernel_param __start___param[], __stop___param[];
|
||||||
initcall_t *fn;
|
initcall_t *fn;
|
||||||
|
|
||||||
strcpy(static_command_line, saved_command_line);
|
strcpy(initcall_command_line, saved_command_line);
|
||||||
parse_args(initcall_level_names[level],
|
parse_args(initcall_level_names[level],
|
||||||
static_command_line, __start___param,
|
initcall_command_line, __start___param,
|
||||||
__stop___param - __start___param,
|
__stop___param - __start___param,
|
||||||
level, level,
|
level, level,
|
||||||
&repair_env_string);
|
&repair_env_string);
|
||||||
|
|
|
@ -641,8 +641,6 @@ static int module_unload_init(struct module *mod)
|
||||||
|
|
||||||
/* Hold reference count during initialization. */
|
/* Hold reference count during initialization. */
|
||||||
__this_cpu_write(mod->refptr->incs, 1);
|
__this_cpu_write(mod->refptr->incs, 1);
|
||||||
/* Backwards compatibility macros put refcount during init. */
|
|
||||||
mod->waiter = current;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -768,16 +766,9 @@ static int __try_stop_module(void *_sref)
|
||||||
|
|
||||||
static int try_stop_module(struct module *mod, int flags, int *forced)
|
static int try_stop_module(struct module *mod, int flags, int *forced)
|
||||||
{
|
{
|
||||||
if (flags & O_NONBLOCK) {
|
struct stopref sref = { mod, flags, forced };
|
||||||
struct stopref sref = { mod, flags, forced };
|
|
||||||
|
|
||||||
return stop_machine(__try_stop_module, &sref, NULL);
|
return stop_machine(__try_stop_module, &sref, NULL);
|
||||||
} else {
|
|
||||||
/* We don't need to stop the machine for this. */
|
|
||||||
mod->state = MODULE_STATE_GOING;
|
|
||||||
synchronize_sched();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long module_refcount(struct module *mod)
|
unsigned long module_refcount(struct module *mod)
|
||||||
|
@ -810,21 +801,6 @@ EXPORT_SYMBOL(module_refcount);
|
||||||
/* This exists whether we can unload or not */
|
/* This exists whether we can unload or not */
|
||||||
static void free_module(struct module *mod);
|
static void free_module(struct module *mod);
|
||||||
|
|
||||||
static void wait_for_zero_refcount(struct module *mod)
|
|
||||||
{
|
|
||||||
/* Since we might sleep for some time, release the mutex first */
|
|
||||||
mutex_unlock(&module_mutex);
|
|
||||||
for (;;) {
|
|
||||||
pr_debug("Looking at refcount...\n");
|
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
|
||||||
if (module_refcount(mod) == 0)
|
|
||||||
break;
|
|
||||||
schedule();
|
|
||||||
}
|
|
||||||
current->state = TASK_RUNNING;
|
|
||||||
mutex_lock(&module_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
|
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
|
||||||
unsigned int, flags)
|
unsigned int, flags)
|
||||||
{
|
{
|
||||||
|
@ -839,6 +815,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
name[MODULE_NAME_LEN-1] = '\0';
|
name[MODULE_NAME_LEN-1] = '\0';
|
||||||
|
|
||||||
|
if (!(flags & O_NONBLOCK)) {
|
||||||
|
printk(KERN_WARNING
|
||||||
|
"waiting module removal not supported: please upgrade");
|
||||||
|
}
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&module_mutex) != 0)
|
if (mutex_lock_interruptible(&module_mutex) != 0)
|
||||||
return -EINTR;
|
return -EINTR;
|
||||||
|
|
||||||
|
@ -856,8 +837,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
|
||||||
|
|
||||||
/* Doing init or already dying? */
|
/* Doing init or already dying? */
|
||||||
if (mod->state != MODULE_STATE_LIVE) {
|
if (mod->state != MODULE_STATE_LIVE) {
|
||||||
/* FIXME: if (force), slam module count and wake up
|
/* FIXME: if (force), slam module count damn the torpedoes */
|
||||||
waiter --RR */
|
|
||||||
pr_debug("%s already dying\n", mod->name);
|
pr_debug("%s already dying\n", mod->name);
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -873,18 +853,11 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set this up before setting mod->state */
|
|
||||||
mod->waiter = current;
|
|
||||||
|
|
||||||
/* Stop the machine so refcounts can't move and disable module. */
|
/* Stop the machine so refcounts can't move and disable module. */
|
||||||
ret = try_stop_module(mod, flags, &forced);
|
ret = try_stop_module(mod, flags, &forced);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Never wait if forced. */
|
|
||||||
if (!forced && module_refcount(mod) != 0)
|
|
||||||
wait_for_zero_refcount(mod);
|
|
||||||
|
|
||||||
mutex_unlock(&module_mutex);
|
mutex_unlock(&module_mutex);
|
||||||
/* Final destruction now no one is using it. */
|
/* Final destruction now no one is using it. */
|
||||||
if (mod->exit != NULL)
|
if (mod->exit != NULL)
|
||||||
|
@ -1002,9 +975,6 @@ void module_put(struct module *module)
|
||||||
__this_cpu_inc(module->refptr->decs);
|
__this_cpu_inc(module->refptr->decs);
|
||||||
|
|
||||||
trace_module_put(module, _RET_IP_);
|
trace_module_put(module, _RET_IP_);
|
||||||
/* Maybe they're waiting for us to drop reference? */
|
|
||||||
if (unlikely(!module_is_live(module)))
|
|
||||||
wake_up_process(module->waiter);
|
|
||||||
preempt_enable();
|
preempt_enable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2728,7 +2698,7 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_module_sections(struct module *mod, struct load_info *info)
|
static int find_module_sections(struct module *mod, struct load_info *info)
|
||||||
{
|
{
|
||||||
mod->kp = section_objs(info, "__param",
|
mod->kp = section_objs(info, "__param",
|
||||||
sizeof(*mod->kp), &mod->num_kp);
|
sizeof(*mod->kp), &mod->num_kp);
|
||||||
|
@ -2758,6 +2728,18 @@ static void find_module_sections(struct module *mod, struct load_info *info)
|
||||||
#ifdef CONFIG_CONSTRUCTORS
|
#ifdef CONFIG_CONSTRUCTORS
|
||||||
mod->ctors = section_objs(info, ".ctors",
|
mod->ctors = section_objs(info, ".ctors",
|
||||||
sizeof(*mod->ctors), &mod->num_ctors);
|
sizeof(*mod->ctors), &mod->num_ctors);
|
||||||
|
if (!mod->ctors)
|
||||||
|
mod->ctors = section_objs(info, ".init_array",
|
||||||
|
sizeof(*mod->ctors), &mod->num_ctors);
|
||||||
|
else if (find_sec(info, ".init_array")) {
|
||||||
|
/*
|
||||||
|
* This shouldn't happen with same compiler and binutils
|
||||||
|
* building all parts of the module.
|
||||||
|
*/
|
||||||
|
printk(KERN_WARNING "%s: has both .ctors and .init_array.\n",
|
||||||
|
mod->name);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_TRACEPOINTS
|
#ifdef CONFIG_TRACEPOINTS
|
||||||
|
@ -2795,6 +2777,8 @@ static void find_module_sections(struct module *mod, struct load_info *info)
|
||||||
|
|
||||||
info->debug = section_objs(info, "__verbose",
|
info->debug = section_objs(info, "__verbose",
|
||||||
sizeof(*info->debug), &info->num_debug);
|
sizeof(*info->debug), &info->num_debug);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int move_module(struct module *mod, struct load_info *info)
|
static int move_module(struct module *mod, struct load_info *info)
|
||||||
|
@ -3248,7 +3232,9 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
||||||
|
|
||||||
/* Now we've got everything in the final locations, we can
|
/* Now we've got everything in the final locations, we can
|
||||||
* find optional sections. */
|
* find optional sections. */
|
||||||
find_module_sections(mod, info);
|
err = find_module_sections(mod, info);
|
||||||
|
if (err)
|
||||||
|
goto free_unload;
|
||||||
|
|
||||||
err = check_module_license_and_versions(mod);
|
err = check_module_license_and_versions(mod);
|
||||||
if (err)
|
if (err)
|
||||||
|
|
|
@ -79,9 +79,11 @@ modpost = scripts/mod/modpost \
|
||||||
$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
|
$(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S) \
|
||||||
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
|
$(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
|
||||||
|
|
||||||
|
MODPOST_OPT=$(subst -i,-n,$(filter -i,$(MAKEFLAGS)))
|
||||||
|
|
||||||
# We can go over command line length here, so be careful.
|
# We can go over command line length here, so be careful.
|
||||||
quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
|
quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
|
||||||
cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) -s -T -
|
cmd_modpost = $(MODLISTCMD) | sed 's/\.ko$$/.o/' | $(modpost) $(MODPOST_OPT) -s -T -
|
||||||
|
|
||||||
PHONY += __modpost
|
PHONY += __modpost
|
||||||
__modpost: $(modules:.ko=.o) FORCE
|
__modpost: $(modules:.ko=.o) FORCE
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "modpost.h"
|
#include "modpost.h"
|
||||||
#include "../../include/generated/autoconf.h"
|
#include "../../include/generated/autoconf.h"
|
||||||
#include "../../include/linux/license.h"
|
#include "../../include/linux/license.h"
|
||||||
|
@ -37,6 +38,8 @@ static int warn_unresolved = 0;
|
||||||
/* How a symbol is exported */
|
/* How a symbol is exported */
|
||||||
static int sec_mismatch_count = 0;
|
static int sec_mismatch_count = 0;
|
||||||
static int sec_mismatch_verbose = 1;
|
static int sec_mismatch_verbose = 1;
|
||||||
|
/* ignore missing files */
|
||||||
|
static int ignore_missing_files;
|
||||||
|
|
||||||
enum export {
|
enum export {
|
||||||
export_plain, export_unused, export_gpl,
|
export_plain, export_unused, export_gpl,
|
||||||
|
@ -161,7 +164,7 @@ struct symbol {
|
||||||
unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
|
unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
|
||||||
unsigned int kernel:1; /* 1 if symbol is from kernel
|
unsigned int kernel:1; /* 1 if symbol is from kernel
|
||||||
* (only for external modules) **/
|
* (only for external modules) **/
|
||||||
unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
|
unsigned int preloaded:1; /* 1 if symbol from Module.symvers, or crc */
|
||||||
enum export export; /* Type of export */
|
enum export export; /* Type of export */
|
||||||
char name[0];
|
char name[0];
|
||||||
};
|
};
|
||||||
|
@ -329,8 +332,11 @@ static void sym_update_crc(const char *name, struct module *mod,
|
||||||
{
|
{
|
||||||
struct symbol *s = find_symbol(name);
|
struct symbol *s = find_symbol(name);
|
||||||
|
|
||||||
if (!s)
|
if (!s) {
|
||||||
s = new_symbol(name, mod, export);
|
s = new_symbol(name, mod, export);
|
||||||
|
/* Don't complain when we find it later. */
|
||||||
|
s->preloaded = 1;
|
||||||
|
}
|
||||||
s->crc = crc;
|
s->crc = crc;
|
||||||
s->crc_valid = 1;
|
s->crc_valid = 1;
|
||||||
}
|
}
|
||||||
|
@ -407,6 +413,11 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||||
|
|
||||||
hdr = grab_file(filename, &info->size);
|
hdr = grab_file(filename, &info->size);
|
||||||
if (!hdr) {
|
if (!hdr) {
|
||||||
|
if (ignore_missing_files) {
|
||||||
|
fprintf(stderr, "%s: %s (ignored)\n", filename,
|
||||||
|
strerror(errno));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
perror(filename);
|
perror(filename);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -1852,7 +1863,7 @@ static void add_header(struct buffer *b, struct module *mod)
|
||||||
buf_printf(b, "\n");
|
buf_printf(b, "\n");
|
||||||
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
|
buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
|
||||||
buf_printf(b, "\n");
|
buf_printf(b, "\n");
|
||||||
buf_printf(b, "struct module __this_module\n");
|
buf_printf(b, "__visible struct module __this_module\n");
|
||||||
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
|
buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
|
||||||
buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
|
buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
|
||||||
if (mod->has_init)
|
if (mod->has_init)
|
||||||
|
@ -2118,7 +2129,7 @@ int main(int argc, char **argv)
|
||||||
struct ext_sym_list *extsym_iter;
|
struct ext_sym_list *extsym_iter;
|
||||||
struct ext_sym_list *extsym_start = NULL;
|
struct ext_sym_list *extsym_start = NULL;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) {
|
while ((opt = getopt(argc, argv, "i:I:e:mnsST:o:awM:K:")) != -1) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'i':
|
case 'i':
|
||||||
kernel_read = optarg;
|
kernel_read = optarg;
|
||||||
|
@ -2138,6 +2149,9 @@ int main(int argc, char **argv)
|
||||||
case 'm':
|
case 'm':
|
||||||
modversions = 1;
|
modversions = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'n':
|
||||||
|
ignore_missing_files = 1;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
dump_write = optarg;
|
dump_write = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Reference in a new issue