diff options
| author | Jeff Garzik <jeff@garzik.org> | 2006-03-29 19:58:22 -0500 | 
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-03-29 19:58:22 -0500 | 
| commit | 79072f38909e3d9883317238887460c39ddcc4cb (patch) | |
| tree | 28369f5a844535ff836565eefd62695b0e890fa3 /kernel/module.c | |
| parent | 200d5a7684cc49ef4be40e832daf3f217e70dfbb (diff) | |
| parent | 55d8ca4f8094246da6e71889a4e04bfafaa78b10 (diff) | |
Merge branch 'upstream'
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 263 | 
1 files changed, 40 insertions, 223 deletions
| diff --git a/kernel/module.c b/kernel/module.c index 77764f22f021..bd088a7c1499 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -39,6 +39,7 @@ | |||
| 39 | #include <linux/device.h> | 39 | #include <linux/device.h> | 
| 40 | #include <linux/string.h> | 40 | #include <linux/string.h> | 
| 41 | #include <linux/sched.h> | 41 | #include <linux/sched.h> | 
| 42 | #include <linux/mutex.h> | ||
| 42 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> | 
| 43 | #include <asm/semaphore.h> | 44 | #include <asm/semaphore.h> | 
| 44 | #include <asm/cacheflush.h> | 45 | #include <asm/cacheflush.h> | 
| @@ -60,29 +61,20 @@ | |||
| 60 | static DEFINE_SPINLOCK(modlist_lock); | 61 | static DEFINE_SPINLOCK(modlist_lock); | 
| 61 | 62 | ||
| 62 | /* List of modules, protected by module_mutex AND modlist_lock */ | 63 | /* List of modules, protected by module_mutex AND modlist_lock */ | 
| 63 | static DECLARE_MUTEX(module_mutex); | 64 | static DEFINE_MUTEX(module_mutex); | 
| 64 | static LIST_HEAD(modules); | 65 | static LIST_HEAD(modules); | 
| 65 | 66 | ||
| 66 | static DECLARE_MUTEX(notify_mutex); | 67 | static BLOCKING_NOTIFIER_HEAD(module_notify_list); | 
| 67 | static struct notifier_block * module_notify_list; | ||
| 68 | 68 | ||
| 69 | int register_module_notifier(struct notifier_block * nb) | 69 | int register_module_notifier(struct notifier_block * nb) | 
| 70 | { | 70 | { | 
| 71 | int err; | 71 | return blocking_notifier_chain_register(&module_notify_list, nb); | 
| 72 | down(¬ify_mutex); | ||
| 73 | err = notifier_chain_register(&module_notify_list, nb); | ||
| 74 | up(¬ify_mutex); | ||
| 75 | return err; | ||
| 76 | } | 72 | } | 
| 77 | EXPORT_SYMBOL(register_module_notifier); | 73 | EXPORT_SYMBOL(register_module_notifier); | 
| 78 | 74 | ||
| 79 | int unregister_module_notifier(struct notifier_block * nb) | 75 | int unregister_module_notifier(struct notifier_block * nb) | 
| 80 | { | 76 | { | 
| 81 | int err; | 77 | return blocking_notifier_chain_unregister(&module_notify_list, nb); | 
| 82 | down(¬ify_mutex); | ||
| 83 | err = notifier_chain_unregister(&module_notify_list, nb); | ||
| 84 | up(¬ify_mutex); | ||
| 85 | return err; | ||
| 86 | } | 78 | } | 
| 87 | EXPORT_SYMBOL(unregister_module_notifier); | 79 | EXPORT_SYMBOL(unregister_module_notifier); | 
| 88 | 80 | ||
| @@ -135,7 +127,7 @@ extern const unsigned long __start___kcrctab_gpl_future[]; | |||
| 135 | #ifndef CONFIG_MODVERSIONS | 127 | #ifndef CONFIG_MODVERSIONS | 
| 136 | #define symversion(base, idx) NULL | 128 | #define symversion(base, idx) NULL | 
| 137 | #else | 129 | #else | 
| 138 | #define symversion(base, idx) ((base) ? ((base) + (idx)) : NULL) | 130 | #define symversion(base, idx) ((base != NULL) ? ((base) + (idx)) : NULL) | 
| 139 | #endif | 131 | #endif | 
| 140 | 132 | ||
| 141 | /* lookup symbol in given range of kernel_symbols */ | 133 | /* lookup symbol in given range of kernel_symbols */ | 
| @@ -232,24 +224,6 @@ static unsigned long __find_symbol(const char *name, | |||
| 232 | return 0; | 224 | return 0; | 
| 233 | } | 225 | } | 
| 234 | 226 | ||
| 235 | /* Find a symbol in this elf symbol table */ | ||
| 236 | static unsigned long find_local_symbol(Elf_Shdr *sechdrs, | ||
| 237 | unsigned int symindex, | ||
| 238 | const char *strtab, | ||
| 239 | const char *name) | ||
| 240 | { | ||
| 241 | unsigned int i; | ||
| 242 | Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; | ||
| 243 | |||
| 244 | /* Search (defined) internal symbols first. */ | ||
| 245 | for (i = 1; i < sechdrs[symindex].sh_size/sizeof(*sym); i++) { | ||
| 246 | if (sym[i].st_shndx != SHN_UNDEF | ||
| 247 | && strcmp(name, strtab + sym[i].st_name) == 0) | ||
| 248 | return sym[i].st_value; | ||
| 249 | } | ||
| 250 | return 0; | ||
| 251 | } | ||
| 252 | |||
| 253 | /* Search for module by name: must hold module_mutex. */ | 227 | /* Search for module by name: must hold module_mutex. */ | 
| 254 | static struct module *find_module(const char *name) | 228 | static struct module *find_module(const char *name) | 
| 255 | { | 229 | { | 
| @@ -601,7 +575,7 @@ static void free_module(struct module *mod); | |||
| 601 | static void wait_for_zero_refcount(struct module *mod) | 575 | static void wait_for_zero_refcount(struct module *mod) | 
| 602 | { | 576 | { | 
| 603 | /* Since we might sleep for some time, drop the semaphore first */ | 577 | /* Since we might sleep for some time, drop the semaphore first */ | 
| 604 | up(&module_mutex); | 578 | mutex_unlock(&module_mutex); | 
| 605 | for (;;) { | 579 | for (;;) { | 
| 606 | DEBUGP("Looking at refcount...\n"); | 580 | DEBUGP("Looking at refcount...\n"); | 
| 607 | set_current_state(TASK_UNINTERRUPTIBLE); | 581 | set_current_state(TASK_UNINTERRUPTIBLE); | 
| @@ -610,7 +584,7 @@ static void wait_for_zero_refcount(struct module *mod) | |||
| 610 | schedule(); | 584 | schedule(); | 
| 611 | } | 585 | } | 
| 612 | current->state = TASK_RUNNING; | 586 | current->state = TASK_RUNNING; | 
| 613 | down(&module_mutex); | 587 | mutex_lock(&module_mutex); | 
| 614 | } | 588 | } | 
| 615 | 589 | ||
| 616 | asmlinkage long | 590 | asmlinkage long | 
| @@ -627,7 +601,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
| 627 | return -EFAULT; | 601 | return -EFAULT; | 
| 628 | name[MODULE_NAME_LEN-1] = '\0'; | 602 | name[MODULE_NAME_LEN-1] = '\0'; | 
| 629 | 603 | ||
| 630 | if (down_interruptible(&module_mutex) != 0) | 604 | if (mutex_lock_interruptible(&module_mutex) != 0) | 
| 631 | return -EINTR; | 605 | return -EINTR; | 
| 632 | 606 | ||
| 633 | mod = find_module(name); | 607 | mod = find_module(name); | 
| @@ -676,14 +650,14 @@ sys_delete_module(const char __user *name_user, unsigned int flags) | |||
| 676 | 650 | ||
| 677 | /* Final destruction now noone is using it. */ | 651 | /* Final destruction now noone is using it. */ | 
| 678 | if (mod->exit != NULL) { | 652 | if (mod->exit != NULL) { | 
| 679 | up(&module_mutex); | 653 | mutex_unlock(&module_mutex); | 
| 680 | mod->exit(); | 654 | mod->exit(); | 
| 681 | down(&module_mutex); | 655 | mutex_lock(&module_mutex); | 
| 682 | } | 656 | } | 
| 683 | free_module(mod); | 657 | free_module(mod); | 
| 684 | 658 | ||
| 685 | out: | 659 | out: | 
| 686 | up(&module_mutex); | 660 | mutex_unlock(&module_mutex); | 
| 687 | return ret; | 661 | return ret; | 
| 688 | } | 662 | } | 
| 689 | 663 | ||
| @@ -784,139 +758,6 @@ static struct module_attribute *modinfo_attrs[] = { | |||
| 784 | NULL, | 758 | NULL, | 
| 785 | }; | 759 | }; | 
| 786 | 760 | ||
| 787 | #ifdef CONFIG_OBSOLETE_MODPARM | ||
| 788 | /* Bounds checking done below */ | ||
| 789 | static int obsparm_copy_string(const char *val, struct kernel_param *kp) | ||
| 790 | { | ||
| 791 | strcpy(kp->arg, val); | ||
| 792 | return 0; | ||
| 793 | } | ||
| 794 | |||
| 795 | static int set_obsolete(const char *val, struct kernel_param *kp) | ||
| 796 | { | ||
| 797 | unsigned int min, max; | ||
| 798 | unsigned int size, maxsize; | ||
| 799 | int dummy; | ||
| 800 | char *endp; | ||
| 801 | const char *p; | ||
| 802 | struct obsolete_modparm *obsparm = kp->arg; | ||
| 803 | |||
| 804 | if (!val) { | ||
| 805 | printk(KERN_ERR "Parameter %s needs an argument\n", kp->name); | ||
| 806 | return -EINVAL; | ||
| 807 | } | ||
| 808 | |||
| 809 | /* type is: [min[-max]]{b,h,i,l,s} */ | ||
| 810 | p = obsparm->type; | ||
| 811 | min = simple_strtol(p, &endp, 10); | ||
| 812 | if (endp == obsparm->type) | ||
| 813 | min = max = 1; | ||
| 814 | else if (*endp == '-') { | ||
| 815 | p = endp+1; | ||
| 816 | max = simple_strtol(p, &endp, 10); | ||
| 817 | } else | ||
| 818 | max = min; | ||
| 819 | switch (*endp) { | ||
| 820 | case 'b': | ||
| 821 | return param_array(kp->name, val, min, max, obsparm->addr, | ||
| 822 | 1, param_set_byte, &dummy); | ||
| 823 | case 'h': | ||
| 824 | return param_array(kp->name, val, min, max, obsparm->addr, | ||
| 825 | sizeof(short), param_set_short, &dummy); | ||
| 826 | case 'i': | ||
| 827 | return param_array(kp->name, val, min, max, obsparm->addr, | ||
| 828 | sizeof(int), param_set_int, &dummy); | ||
| 829 | case 'l': | ||
| 830 | return param_array(kp->name, val, min, max, obsparm->addr, | ||
| 831 | sizeof(long), param_set_long, &dummy); | ||
| 832 | case 's': | ||
| 833 | return param_array(kp->name, val, min, max, obsparm->addr, | ||
| 834 | sizeof(char *), param_set_charp, &dummy); | ||
| 835 | |||
| 836 | case 'c': | ||
| 837 | /* Undocumented: 1-5c50 means 1-5 strings of up to 49 chars, | ||
| 838 | and the decl is "char xxx[5][50];" */ | ||
| 839 | p = endp+1; | ||
| 840 | maxsize = simple_strtol(p, &endp, 10); | ||
| 841 | /* We check lengths here (yes, this is a hack). */ | ||
| 842 | p = val; | ||
| 843 | while (p[size = strcspn(p, ",")]) { | ||
| 844 | if (size >= maxsize) | ||
| 845 | goto oversize; | ||
| 846 | p += size+1; | ||
| 847 | } | ||
| 848 | if (size >= maxsize) | ||
| 849 | goto oversize; | ||
| 850 | return param_array(kp->name, val, min, max, obsparm->addr, | ||
| 851 | maxsize, obsparm_copy_string, &dummy); | ||
| 852 | } | ||
| 853 | printk(KERN_ERR "Unknown obsolete parameter type %s\n", obsparm->type); | ||
| 854 | return -EINVAL; | ||
| 855 | oversize: | ||
| 856 | printk(KERN_ERR | ||
| 857 | "Parameter %s doesn't fit in %u chars.\n", kp->name, maxsize); | ||
| 858 | return -EINVAL; | ||
| 859 | } | ||
| 860 | |||
| 861 | static int obsolete_params(const char *name, | ||
| 862 | char *args, | ||
| 863 | struct obsolete_modparm obsparm[], | ||
| 864 | unsigned int num, | ||
| 865 | Elf_Shdr *sechdrs, | ||
| 866 | unsigned int symindex, | ||
| 867 | const char *strtab) | ||
| 868 | { | ||
| 869 | struct kernel_param *kp; | ||
| 870 | unsigned int i; | ||
| 871 | int ret; | ||
| 872 | |||
| 873 | kp = kmalloc(sizeof(kp[0]) * num, GFP_KERNEL); | ||
| 874 | if (!kp) | ||
| 875 | return -ENOMEM; | ||
| 876 | |||
| 877 | for (i = 0; i < num; i++) { | ||
| 878 | char sym_name[128 + sizeof(MODULE_SYMBOL_PREFIX)]; | ||
| 879 | |||
| 880 | snprintf(sym_name, sizeof(sym_name), "%s%s", | ||
| 881 | MODULE_SYMBOL_PREFIX, obsparm[i].name); | ||
| 882 | |||
| 883 | kp[i].name = obsparm[i].name; | ||
| 884 | kp[i].perm = 000; | ||
| 885 | kp[i].set = set_obsolete; | ||
| 886 | kp[i].get = NULL; | ||
| 887 | obsparm[i].addr | ||
| 888 | = (void *)find_local_symbol(sechdrs, symindex, strtab, | ||
| 889 | sym_name); | ||
| 890 | if (!obsparm[i].addr) { | ||
| 891 | printk("%s: falsely claims to have parameter %s\n", | ||
| 892 | name, obsparm[i].name); | ||
| 893 | ret = -EINVAL; | ||
| 894 | goto out; | ||
| 895 | } | ||
| 896 | kp[i].arg = &obsparm[i]; | ||
| 897 | } | ||
| 898 | |||
| 899 | ret = parse_args(name, args, kp, num, NULL); | ||
| 900 | out: | ||
| 901 | kfree(kp); | ||
| 902 | return ret; | ||
| 903 | } | ||
| 904 | #else | ||
| 905 | static int obsolete_params(const char *name, | ||
| 906 | char *args, | ||
| 907 | struct obsolete_modparm obsparm[], | ||
| 908 | unsigned int num, | ||
| 909 | Elf_Shdr *sechdrs, | ||
| 910 | unsigned int symindex, | ||
| 911 | const char *strtab) | ||
| 912 | { | ||
| 913 | if (num != 0) | ||
| 914 | printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", | ||
| 915 | name); | ||
| 916 | return 0; | ||
| 917 | } | ||
| 918 | #endif /* CONFIG_OBSOLETE_MODPARM */ | ||
| 919 | |||
| 920 | static const char vermagic[] = VERMAGIC_STRING; | 761 | static const char vermagic[] = VERMAGIC_STRING; | 
| 921 | 762 | ||
| 922 | #ifdef CONFIG_MODVERSIONS | 763 | #ifdef CONFIG_MODVERSIONS | 
| @@ -1571,7 +1412,6 @@ static struct module *load_module(void __user *umod, | |||
| 1571 | exportindex, modindex, obsparmindex, infoindex, gplindex, | 1412 | exportindex, modindex, obsparmindex, infoindex, gplindex, | 
| 1572 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, | 1413 | crcindex, gplcrcindex, versindex, pcpuindex, gplfutureindex, | 
| 1573 | gplfuturecrcindex; | 1414 | gplfuturecrcindex; | 
| 1574 | long arglen; | ||
| 1575 | struct module *mod; | 1415 | struct module *mod; | 
| 1576 | long err = 0; | 1416 | long err = 0; | 
| 1577 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1417 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 
| @@ -1690,23 +1530,11 @@ static struct module *load_module(void __user *umod, | |||
| 1690 | } | 1530 | } | 
| 1691 | 1531 | ||
| 1692 | /* Now copy in args */ | 1532 | /* Now copy in args */ | 
| 1693 | arglen = strlen_user(uargs); | 1533 | args = strndup_user(uargs, ~0UL >> 1); | 
| 1694 | if (!arglen) { | 1534 | if (IS_ERR(args)) { | 
| 1695 | err = -EFAULT; | 1535 | err = PTR_ERR(args); | 
| 1696 | goto free_hdr; | 1536 | goto free_hdr; | 
| 1697 | } | 1537 | } | 
| 1698 | args = kmalloc(arglen, GFP_KERNEL); | ||
| 1699 | if (!args) { | ||
| 1700 | err = -ENOMEM; | ||
| 1701 | goto free_hdr; | ||
| 1702 | } | ||
| 1703 | if (copy_from_user(args, uargs, arglen) != 0) { | ||
| 1704 | err = -EFAULT; | ||
| 1705 | goto free_mod; | ||
| 1706 | } | ||
| 1707 | |||
| 1708 | /* Userspace could have altered the string after the strlen_user() */ | ||
| 1709 | args[arglen - 1] = '\0'; | ||
| 1710 | 1538 | ||
| 1711 | if (find_module(mod->name)) { | 1539 | if (find_module(mod->name)) { | 
| 1712 | err = -EEXIST; | 1540 | err = -EEXIST; | 
| @@ -1886,27 +1714,17 @@ static struct module *load_module(void __user *umod, | |||
| 1886 | set_fs(old_fs); | 1714 | set_fs(old_fs); | 
| 1887 | 1715 | ||
| 1888 | mod->args = args; | 1716 | mod->args = args; | 
| 1889 | if (obsparmindex) { | 1717 | if (obsparmindex) | 
| 1890 | err = obsolete_params(mod->name, mod->args, | 1718 | printk(KERN_WARNING "%s: Ignoring obsolete parameters\n", | 
| 1891 | (struct obsolete_modparm *) | 1719 | mod->name); | 
| 1892 | sechdrs[obsparmindex].sh_addr, | 1720 | |
| 1893 | sechdrs[obsparmindex].sh_size | 1721 | /* Size of section 0 is 0, so this works well if no params */ | 
| 1894 | / sizeof(struct obsolete_modparm), | 1722 | err = parse_args(mod->name, mod->args, | 
| 1895 | sechdrs, symindex, | 1723 | (struct kernel_param *) | 
| 1896 | (char *)sechdrs[strindex].sh_addr); | 1724 | sechdrs[setupindex].sh_addr, | 
| 1897 | if (setupindex) | 1725 | sechdrs[setupindex].sh_size | 
| 1898 | printk(KERN_WARNING "%s: Ignoring new-style " | 1726 | / sizeof(struct kernel_param), | 
| 1899 | "parameters in presence of obsolete ones\n", | 1727 | NULL); | 
| 1900 | mod->name); | ||
| 1901 | } else { | ||
| 1902 | /* Size of section 0 is 0, so this works well if no params */ | ||
| 1903 | err = parse_args(mod->name, mod->args, | ||
| 1904 | (struct kernel_param *) | ||
| 1905 | sechdrs[setupindex].sh_addr, | ||
| 1906 | sechdrs[setupindex].sh_size | ||
| 1907 | / sizeof(struct kernel_param), | ||
| 1908 | NULL); | ||
| 1909 | } | ||
| 1910 | if (err < 0) | 1728 | if (err < 0) | 
| 1911 | goto arch_cleanup; | 1729 | goto arch_cleanup; | 
| 1912 | 1730 | ||
| @@ -1972,13 +1790,13 @@ sys_init_module(void __user *umod, | |||
| 1972 | return -EPERM; | 1790 | return -EPERM; | 
| 1973 | 1791 | ||
| 1974 | /* Only one module load at a time, please */ | 1792 | /* Only one module load at a time, please */ | 
| 1975 | if (down_interruptible(&module_mutex) != 0) | 1793 | if (mutex_lock_interruptible(&module_mutex) != 0) | 
| 1976 | return -EINTR; | 1794 | return -EINTR; | 
| 1977 | 1795 | ||
| 1978 | /* Do all the hard work */ | 1796 | /* Do all the hard work */ | 
| 1979 | mod = load_module(umod, len, uargs); | 1797 | mod = load_module(umod, len, uargs); | 
| 1980 | if (IS_ERR(mod)) { | 1798 | if (IS_ERR(mod)) { | 
| 1981 | up(&module_mutex); | 1799 | mutex_unlock(&module_mutex); | 
| 1982 | return PTR_ERR(mod); | 1800 | return PTR_ERR(mod); | 
| 1983 | } | 1801 | } | 
| 1984 | 1802 | ||
| @@ -1987,11 +1805,10 @@ sys_init_module(void __user *umod, | |||
| 1987 | stop_machine_run(__link_module, mod, NR_CPUS); | 1805 | stop_machine_run(__link_module, mod, NR_CPUS); | 
| 1988 | 1806 | ||
| 1989 | /* Drop lock so they can recurse */ | 1807 | /* Drop lock so they can recurse */ | 
| 1990 | up(&module_mutex); | 1808 | mutex_unlock(&module_mutex); | 
| 1991 | 1809 | ||
| 1992 | down(¬ify_mutex); | 1810 | blocking_notifier_call_chain(&module_notify_list, | 
| 1993 | notifier_call_chain(&module_notify_list, MODULE_STATE_COMING, mod); | 1811 | MODULE_STATE_COMING, mod); | 
| 1994 | up(¬ify_mutex); | ||
| 1995 | 1812 | ||
| 1996 | /* Start the module */ | 1813 | /* Start the module */ | 
| 1997 | if (mod->init != NULL) | 1814 | if (mod->init != NULL) | 
| @@ -2006,15 +1823,15 @@ sys_init_module(void __user *umod, | |||
| 2006 | mod->name); | 1823 | mod->name); | 
| 2007 | else { | 1824 | else { | 
| 2008 | module_put(mod); | 1825 | module_put(mod); | 
| 2009 | down(&module_mutex); | 1826 | mutex_lock(&module_mutex); | 
| 2010 | free_module(mod); | 1827 | free_module(mod); | 
| 2011 | up(&module_mutex); | 1828 | mutex_unlock(&module_mutex); | 
| 2012 | } | 1829 | } | 
| 2013 | return ret; | 1830 | return ret; | 
| 2014 | } | 1831 | } | 
| 2015 | 1832 | ||
| 2016 | /* Now it's a first class citizen! */ | 1833 | /* Now it's a first class citizen! */ | 
| 2017 | down(&module_mutex); | 1834 | mutex_lock(&module_mutex); | 
| 2018 | mod->state = MODULE_STATE_LIVE; | 1835 | mod->state = MODULE_STATE_LIVE; | 
| 2019 | /* Drop initial reference. */ | 1836 | /* Drop initial reference. */ | 
| 2020 | module_put(mod); | 1837 | module_put(mod); | 
| @@ -2022,7 +1839,7 @@ sys_init_module(void __user *umod, | |||
| 2022 | mod->module_init = NULL; | 1839 | mod->module_init = NULL; | 
| 2023 | mod->init_size = 0; | 1840 | mod->init_size = 0; | 
| 2024 | mod->init_text_size = 0; | 1841 | mod->init_text_size = 0; | 
| 2025 | up(&module_mutex); | 1842 | mutex_unlock(&module_mutex); | 
| 2026 | 1843 | ||
| 2027 | return 0; | 1844 | return 0; | 
| 2028 | } | 1845 | } | 
| @@ -2112,7 +1929,7 @@ struct module *module_get_kallsym(unsigned int symnum, | |||
| 2112 | { | 1929 | { | 
| 2113 | struct module *mod; | 1930 | struct module *mod; | 
| 2114 | 1931 | ||
| 2115 | down(&module_mutex); | 1932 | mutex_lock(&module_mutex); | 
| 2116 | list_for_each_entry(mod, &modules, list) { | 1933 | list_for_each_entry(mod, &modules, list) { | 
| 2117 | if (symnum < mod->num_symtab) { | 1934 | if (symnum < mod->num_symtab) { | 
| 2118 | *value = mod->symtab[symnum].st_value; | 1935 | *value = mod->symtab[symnum].st_value; | 
| @@ -2120,12 +1937,12 @@ struct module *module_get_kallsym(unsigned int symnum, | |||
| 2120 | strncpy(namebuf, | 1937 | strncpy(namebuf, | 
| 2121 | mod->strtab + mod->symtab[symnum].st_name, | 1938 | mod->strtab + mod->symtab[symnum].st_name, | 
| 2122 | 127); | 1939 | 127); | 
| 2123 | up(&module_mutex); | 1940 | mutex_unlock(&module_mutex); | 
| 2124 | return mod; | 1941 | return mod; | 
| 2125 | } | 1942 | } | 
| 2126 | symnum -= mod->num_symtab; | 1943 | symnum -= mod->num_symtab; | 
| 2127 | } | 1944 | } | 
| 2128 | up(&module_mutex); | 1945 | mutex_unlock(&module_mutex); | 
| 2129 | return NULL; | 1946 | return NULL; | 
| 2130 | } | 1947 | } | 
| 2131 | 1948 | ||
| @@ -2168,7 +1985,7 @@ static void *m_start(struct seq_file *m, loff_t *pos) | |||
| 2168 | struct list_head *i; | 1985 | struct list_head *i; | 
| 2169 | loff_t n = 0; | 1986 | loff_t n = 0; | 
| 2170 | 1987 | ||
| 2171 | down(&module_mutex); | 1988 | mutex_lock(&module_mutex); | 
| 2172 | list_for_each(i, &modules) { | 1989 | list_for_each(i, &modules) { | 
| 2173 | if (n++ == *pos) | 1990 | if (n++ == *pos) | 
| 2174 | break; | 1991 | break; | 
| @@ -2189,7 +2006,7 @@ static void *m_next(struct seq_file *m, void *p, loff_t *pos) | |||
| 2189 | 2006 | ||
| 2190 | static void m_stop(struct seq_file *m, void *p) | 2007 | static void m_stop(struct seq_file *m, void *p) | 
| 2191 | { | 2008 | { | 
| 2192 | up(&module_mutex); | 2009 | mutex_unlock(&module_mutex); | 
| 2193 | } | 2010 | } | 
| 2194 | 2011 | ||
| 2195 | static int m_show(struct seq_file *m, void *p) | 2012 | static int m_show(struct seq_file *m, void *p) | 
