aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/module.c
diff options
context:
space:
mode:
authorJeff Garzik <jeff@garzik.org>2006-03-29 17:18:49 -0500
committerJeff Garzik <jeff@garzik.org>2006-03-29 17:18:49 -0500
commite02a4cabfcb9a999b74a2e2e6f13ffcb7ff2d606 (patch)
tree2f3db60be4c57eca2a4c3ab3f3122dcf1ec0c624 /kernel/module.c
parent600511e86babe3727264a0883a3a264f6fb6caf5 (diff)
parentf3cab8a0b1a772dc8b055b7affa567a366627c9e (diff)
Merge branch 'master'
Diffstat (limited to 'kernel/module.c')
-rw-r--r--kernel/module.c205
1 files changed, 17 insertions, 188 deletions
diff --git a/kernel/module.c b/kernel/module.c
index 54623c714bba..bd088a7c1499 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -64,26 +64,17 @@ static DEFINE_SPINLOCK(modlist_lock);
64static DEFINE_MUTEX(module_mutex); 64static DEFINE_MUTEX(module_mutex);
65static LIST_HEAD(modules); 65static LIST_HEAD(modules);
66 66
67static DEFINE_MUTEX(notify_mutex); 67static BLOCKING_NOTIFIER_HEAD(module_notify_list);
68static struct notifier_block * module_notify_list;
69 68
70int register_module_notifier(struct notifier_block * nb) 69int register_module_notifier(struct notifier_block * nb)
71{ 70{
72 int err; 71 return blocking_notifier_chain_register(&module_notify_list, nb);
73 mutex_lock(&notify_mutex);
74 err = notifier_chain_register(&module_notify_list, nb);
75 mutex_unlock(&notify_mutex);
76 return err;
77} 72}
78EXPORT_SYMBOL(register_module_notifier); 73EXPORT_SYMBOL(register_module_notifier);
79 74
80int unregister_module_notifier(struct notifier_block * nb) 75int unregister_module_notifier(struct notifier_block * nb)
81{ 76{
82 int err; 77 return blocking_notifier_chain_unregister(&module_notify_list, nb);
83 mutex_lock(&notify_mutex);
84 err = notifier_chain_unregister(&module_notify_list, nb);
85 mutex_unlock(&notify_mutex);
86 return err;
87} 78}
88EXPORT_SYMBOL(unregister_module_notifier); 79EXPORT_SYMBOL(unregister_module_notifier);
89 80
@@ -136,7 +127,7 @@ extern const unsigned long __start___kcrctab_gpl_future[];
136#ifndef CONFIG_MODVERSIONS 127#ifndef CONFIG_MODVERSIONS
137#define symversion(base, idx) NULL 128#define symversion(base, idx) NULL
138#else 129#else
139#define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL) 130#define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL)
140#endif 131#endif
141 132
142/* lookup symbol in given range of kernel_symbols */ 133/* lookup symbol in given range of kernel_symbols */
@@ -233,24 +224,6 @@ static unsigned long __find_symbol(const char *name,
233 return 0; 224 return 0;
234} 225}
235 226
236/* Find a symbol in this elf symbol table */
237static unsigned long find_local_symbol(Elf_Shdr *sechdrs,
238 unsigned int symindex,
239 const char *strtab,
240 const char *name)
241{
242 unsigned int i;
243 Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
244
245 /* Search (defined) internal symbols first. */
246 for (i = 1; i < sechdrs[symindex].sh_size/sizeof(*sym); i++) {
247 if (sym[i].st_shndx != SHN_UNDEF
248 && strcmp(name, strtab + sym[i].st_name) == 0)
249 return sym[i].st_value;
250 }
251 return 0;
252}
253
254/* Search for module by name: must hold module_mutex. */ 227/* Search for module by name: must hold module_mutex. */
255static struct module *find_module(const char *name) 228static struct module *find_module(const char *name)
256{ 229{
@@ -785,139 +758,6 @@ static struct module_attribute *modinfo_attrs[] = {
785 NULL, 758 NULL,
786}; 759};
787 760
788#ifdef CONFIG_OBSOLETE_MODPARM
789/* Bounds checking done below */
790static int obsparm_copy_string(const char *val, struct kernel_param *kp)
791{
792 strcpy(kp->arg, val);
793 return 0;
794}
795
796static int set_obsolete(const char *val, struct kernel_param *kp)
797{
798 unsigned int min, max;
799 unsigned int size, maxsize;
800 int dummy;
801 char *endp;
802 const char *p;
803 struct obsolete_modparm *obsparm = kp->arg;
804
805 if (!val) {
806 printk(KERN_ERR "Parameter %s needs an argument\n", kp->name);
807 return -EINVAL;
808 }
809
810 /* type is: [min[-max]]{b,h,i,l,s} */
811 p = obsparm->type;
812 min = simple_strtol(p, &endp, 10);
813 if (endp == obsparm->type)
814 min = max = 1;
815 else if (*endp == '-') {
816 p = endp+1;
817 max = simple_strtol(p, &endp, 10);
818 } else
819 max = min;
820 switch (*endp) {
821 case 'b':
822 return param_array(kp->name, val, min, max, obsparm->addr,
823 1, param_set_byte, &dummy);
824 case 'h':
825 return param_array(kp->name, val, min, max, obsparm->addr,
826 sizeof(short), param_set_short, &dummy);
827 case 'i':
828 return param_array(kp->name, val, min, max, obsparm->addr,
829 sizeof(int), param_set_int, &dummy);
830 case 'l':
831 return param_array(kp->name, val, min, max, obsparm->addr,
832 sizeof(long), param_set_long, &dummy);
833 case 's':
834 return param_array(kp->name, val, min, max, obsparm->addr,
835 sizeof(char *), param_set_charp, &dummy);
836
837 case 'c':
838 /* Undocumented: 1-5c50 means 1-5 strings of up to 49 chars,
839 and the decl is "char xxx[5][50];" */
840 p = endp+1;
841 maxsize = simple_strtol(p, &endp, 10);
842 /* We check lengths here (yes, this is a hack). */
843 p = val;
844 while (p[size = strcspn(p, ",")]) {
845 if (size >= maxsize)
846 goto oversize;
847 p += size+1;
848 }
849 if (size >= maxsize)
850 goto oversize;
851 return param_array(kp->name, val, min, max, obsparm->addr,
852 maxsize, obsparm_copy_string, &dummy);
853 }
854 printk(KERN_ERR "Unknown obsolete parameter type %s\n", obsparm->type);
855 return -EINVAL;
856 oversize:
857 printk(KERN_ERR
858 "Parameter %s doesn't fit in %u chars.\n", kp->name, maxsize);
859 return -EINVAL;
860}
861
862static int obsolete_params(const char *name,
863 char *args,
864 struct obsolete_modparm obsparm[],
865 unsigned int num,
866 Elf_Shdr *sechdrs,
867 unsigned int symindex,
868 const char *strtab)
869{
870 struct kernel_param *kp;
871 unsigned int i;
872 int ret;
873
874 kp = kmalloc(sizeof(kp[0]) * num, GFP_KERNEL);
875 if (!kp)
876 return -ENOMEM;
877
878 for (i = 0; i < num; i++) {
879 char sym_name[128 + sizeof(MODULE_SYMBOL_PREFIX)];
880
881 snprintf(sym_name, sizeof(sym_name), "%s%s",
882 MODULE_SYMBOL_PREFIX, obsparm[i].name);
883
884 kp[i].name = obsparm[i].name;
885 kp[i].perm = 000;
886 kp[i].set = set_obsolete;
887 kp[i].get = NULL;
888 obsparm[i].addr
889 = (void *)find_local_symbol(sechdrs, symindex, strtab,
890 sym_name);
891 if (!obsparm[i].addr) {
892 printk("%s: falsely claims to have parameter %s\n",
893 name, obsparm[i].name);
894 ret = -EINVAL;
895 goto out;
896 }
897 kp[i].arg = &obsparm[i];
898 }
899
900 ret = parse_args(name, args, kp, num, NULL);
901 out:
902 kfree(kp);
903 return ret;
904}
905#else
906static int obsolete_params(const char *name,
907 char *args,
908 struct obsolete_modparm obsparm[],
909 unsigned int num,
910 Elf_Shdr *sechdrs,
911 unsigned int symindex,
912 const char *strtab)
913{
914 if (num != 0)
915 printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
916 name);
917 return 0;
918}
919#endif /* CONFIG_OBSOLETE_MODPARM */
920
921static const char vermagic[] = VERMAGIC_STRING; 761static const char vermagic[] = VERMAGIC_STRING;
922 762
923#ifdef CONFIG_MODVERSIONS 763#ifdef CONFIG_MODVERSIONS
@@ -1874,27 +1714,17 @@ static struct module *load_module(void __user *umod,
1874 set_fs(old_fs); 1714 set_fs(old_fs);
1875 1715
1876 mod->args = args; 1716 mod->args = args;
1877 if (obsparmindex) { 1717 if (obsparmindex)
1878 err = obsolete_params(mod->name, mod->args, 1718 printk(KERN_WARNING "%s: Ignoring obsolete parameters\n",
1879 (struct obsolete_modparm *) 1719 mod->name);
1880 sechdrs[obsparmindex].sh_addr, 1720
1881 sechdrs[obsparmindex].sh_size 1721 /* Size of section 0 is 0, so this works well if no params */
1882 / sizeof(struct obsolete_modparm), 1722 err = parse_args(mod->name, mod->args,
1883 sechdrs, symindex, 1723 (struct kernel_param *)
1884 (char *)sechdrs[strindex].sh_addr); 1724 sechdrs[setupindex].sh_addr,
1885 if (setupindex) 1725 sechdrs[setupindex].sh_size
1886 printk(KERN_WARNING "%s: Ignoring new-style " 1726 / sizeof(struct kernel_param),
1887 "parameters in presence of obsolete ones\n", 1727 NULL);
1888 mod->name);
1889 } else {
1890 /* Size of section 0 is 0, so this works well if no params */
1891 err = parse_args(mod->name, mod->args,
1892 (struct kernel_param *)
1893 sechdrs[setupindex].sh_addr,
1894 sechdrs[setupindex].sh_size
1895 / sizeof(struct kernel_param),
1896 NULL);
1897 }
1898 if (err < 0) 1728 if (err < 0)
1899 goto arch_cleanup; 1729 goto arch_cleanup;
1900 1730
@@ -1977,9 +1807,8 @@ sys_init_module(void __user *umod,
1977 /* Drop lock so they can recurse */ 1807 /* Drop lock so they can recurse */
1978 mutex_unlock(&module_mutex); 1808 mutex_unlock(&module_mutex);
1979 1809
1980 mutex_lock(&notify_mutex); 1810 blocking_notifier_call_chain(&module_notify_list,
1981 notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); 1811 MODULE_STATE_COMING, mod);
1982 mutex_unlock(&notify_mutex);
1983 1812
1984 /* Start the module */ 1813 /* Start the module */
1985 if (mod->init != NULL) 1814 if (mod->init != NULL)