diff options
Diffstat (limited to 'kernel/module.c')
| -rw-r--r-- | kernel/module.c | 244 |
1 files changed, 61 insertions, 183 deletions
diff --git a/kernel/module.c b/kernel/module.c index fe748a86d452..c968d3606dca 100644 --- a/kernel/module.c +++ b/kernel/module.c | |||
| @@ -370,8 +370,6 @@ EXPORT_SYMBOL_GPL(find_module); | |||
| 370 | 370 | ||
| 371 | #ifdef CONFIG_SMP | 371 | #ifdef CONFIG_SMP |
| 372 | 372 | ||
| 373 | #ifndef CONFIG_HAVE_LEGACY_PER_CPU_AREA | ||
| 374 | |||
| 375 | static void *percpu_modalloc(unsigned long size, unsigned long align, | 373 | static void *percpu_modalloc(unsigned long size, unsigned long align, |
| 376 | const char *name) | 374 | const char *name) |
| 377 | { | 375 | { |
| @@ -395,154 +393,6 @@ static void percpu_modfree(void *freeme) | |||
| 395 | free_percpu(freeme); | 393 | free_percpu(freeme); |
| 396 | } | 394 | } |
| 397 | 395 | ||
| 398 | #else /* ... CONFIG_HAVE_LEGACY_PER_CPU_AREA */ | ||
| 399 | |||
| 400 | /* Number of blocks used and allocated. */ | ||
| 401 | static unsigned int pcpu_num_used, pcpu_num_allocated; | ||
| 402 | /* Size of each block. -ve means used. */ | ||
| 403 | static int *pcpu_size; | ||
| 404 | |||
| 405 | static int split_block(unsigned int i, unsigned short size) | ||
| 406 | { | ||
| 407 | /* Reallocation required? */ | ||
| 408 | if (pcpu_num_used + 1 > pcpu_num_allocated) { | ||
| 409 | int *new; | ||
| 410 | |||
| 411 | new = krealloc(pcpu_size, sizeof(new[0])*pcpu_num_allocated*2, | ||
| 412 | GFP_KERNEL); | ||
| 413 | if (!new) | ||
| 414 | return 0; | ||
| 415 | |||
| 416 | pcpu_num_allocated *= 2; | ||
| 417 | pcpu_size = new; | ||
| 418 | } | ||
| 419 | |||
| 420 | /* Insert a new subblock */ | ||
| 421 | memmove(&pcpu_size[i+1], &pcpu_size[i], | ||
| 422 | sizeof(pcpu_size[0]) * (pcpu_num_used - i)); | ||
| 423 | pcpu_num_used++; | ||
| 424 | |||
| 425 | pcpu_size[i+1] -= size; | ||
| 426 | pcpu_size[i] = size; | ||
| 427 | return 1; | ||
| 428 | } | ||
| 429 | |||
| 430 | static inline unsigned int block_size(int val) | ||
| 431 | { | ||
| 432 | if (val < 0) | ||
| 433 | return -val; | ||
| 434 | return val; | ||
| 435 | } | ||
| 436 | |||
| 437 | static void *percpu_modalloc(unsigned long size, unsigned long align, | ||
| 438 | const char *name) | ||
| 439 | { | ||
| 440 | unsigned long extra; | ||
| 441 | unsigned int i; | ||
| 442 | void *ptr; | ||
| 443 | int cpu; | ||
| 444 | |||
| 445 | if (align > PAGE_SIZE) { | ||
| 446 | printk(KERN_WARNING "%s: per-cpu alignment %li > %li\n", | ||
| 447 | name, align, PAGE_SIZE); | ||
| 448 | align = PAGE_SIZE; | ||
| 449 | } | ||
| 450 | |||
| 451 | ptr = __per_cpu_start; | ||
| 452 | for (i = 0; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { | ||
| 453 | /* Extra for alignment requirement. */ | ||
| 454 | extra = ALIGN((unsigned long)ptr, align) - (unsigned long)ptr; | ||
| 455 | BUG_ON(i == 0 && extra != 0); | ||
| 456 | |||
| 457 | if (pcpu_size[i] < 0 || pcpu_size[i] < extra + size) | ||
| 458 | continue; | ||
| 459 | |||
| 460 | /* Transfer extra to previous block. */ | ||
| 461 | if (pcpu_size[i-1] < 0) | ||
| 462 | pcpu_size[i-1] -= extra; | ||
| 463 | else | ||
| 464 | pcpu_size[i-1] += extra; | ||
| 465 | pcpu_size[i] -= extra; | ||
| 466 | ptr += extra; | ||
| 467 | |||
| 468 | /* Split block if warranted */ | ||
| 469 | if (pcpu_size[i] - size > sizeof(unsigned long)) | ||
| 470 | if (!split_block(i, size)) | ||
| 471 | return NULL; | ||
| 472 | |||
| 473 | /* add the per-cpu scanning areas */ | ||
| 474 | for_each_possible_cpu(cpu) | ||
| 475 | kmemleak_alloc(ptr + per_cpu_offset(cpu), size, 0, | ||
| 476 | GFP_KERNEL); | ||
| 477 | |||
| 478 | /* Mark allocated */ | ||
| 479 | pcpu_size[i] = -pcpu_size[i]; | ||
| 480 | return ptr; | ||
| 481 | } | ||
| 482 | |||
| 483 | printk(KERN_WARNING "Could not allocate %lu bytes percpu data\n", | ||
| 484 | size); | ||
| 485 | return NULL; | ||
| 486 | } | ||
| 487 | |||
| 488 | static void percpu_modfree(void *freeme) | ||
| 489 | { | ||
| 490 | unsigned int i; | ||
| 491 | void *ptr = __per_cpu_start + block_size(pcpu_size[0]); | ||
| 492 | int cpu; | ||
| 493 | |||
| 494 | /* First entry is core kernel percpu data. */ | ||
| 495 | for (i = 1; i < pcpu_num_used; ptr += block_size(pcpu_size[i]), i++) { | ||
| 496 | if (ptr == freeme) { | ||
| 497 | pcpu_size[i] = -pcpu_size[i]; | ||
| 498 | goto free; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | BUG(); | ||
| 502 | |||
| 503 | free: | ||
| 504 | /* remove the per-cpu scanning areas */ | ||
| 505 | for_each_possible_cpu(cpu) | ||
| 506 | kmemleak_free(freeme + per_cpu_offset(cpu)); | ||
| 507 | |||
| 508 | /* Merge with previous? */ | ||
| 509 | if (pcpu_size[i-1] >= 0) { | ||
| 510 | pcpu_size[i-1] += pcpu_size[i]; | ||
| 511 | pcpu_num_used--; | ||
| 512 | memmove(&pcpu_size[i], &pcpu_size[i+1], | ||
| 513 | (pcpu_num_used - i) * sizeof(pcpu_size[0])); | ||
| 514 | i--; | ||
| 515 | } | ||
| 516 | /* Merge with next? */ | ||
| 517 | if (i+1 < pcpu_num_used && pcpu_size[i+1] >= 0) { | ||
| 518 | pcpu_size[i] += pcpu_size[i+1]; | ||
| 519 | pcpu_num_used--; | ||
| 520 | memmove(&pcpu_size[i+1], &pcpu_size[i+2], | ||
| 521 | (pcpu_num_used - (i+1)) * sizeof(pcpu_size[0])); | ||
| 522 | } | ||
| 523 | } | ||
| 524 | |||
| 525 | static int percpu_modinit(void) | ||
| 526 | { | ||
| 527 | pcpu_num_used = 2; | ||
| 528 | pcpu_num_allocated = 2; | ||
| 529 | pcpu_size = kmalloc(sizeof(pcpu_size[0]) * pcpu_num_allocated, | ||
| 530 | GFP_KERNEL); | ||
| 531 | /* Static in-kernel percpu data (used). */ | ||
| 532 | pcpu_size[0] = -(__per_cpu_end-__per_cpu_start); | ||
| 533 | /* Free room. */ | ||
| 534 | pcpu_size[1] = PERCPU_ENOUGH_ROOM + pcpu_size[0]; | ||
| 535 | if (pcpu_size[1] < 0) { | ||
| 536 | printk(KERN_ERR "No per-cpu room for modules.\n"); | ||
| 537 | pcpu_num_used = 1; | ||
| 538 | } | ||
| 539 | |||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | __initcall(percpu_modinit); | ||
| 543 | |||
| 544 | #endif /* CONFIG_HAVE_LEGACY_PER_CPU_AREA */ | ||
| 545 | |||
| 546 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, | 396 | static unsigned int find_pcpusec(Elf_Ehdr *hdr, |
| 547 | Elf_Shdr *sechdrs, | 397 | Elf_Shdr *sechdrs, |
| 548 | const char *secstrings) | 398 | const char *secstrings) |
| @@ -624,9 +474,10 @@ static void module_unload_init(struct module *mod) | |||
| 624 | 474 | ||
| 625 | INIT_LIST_HEAD(&mod->modules_which_use_me); | 475 | INIT_LIST_HEAD(&mod->modules_which_use_me); |
| 626 | for_each_possible_cpu(cpu) | 476 | for_each_possible_cpu(cpu) |
| 627 | local_set(__module_ref_addr(mod, cpu), 0); | 477 | per_cpu_ptr(mod->refptr, cpu)->count = 0; |
| 478 | |||
| 628 | /* Hold reference count during initialization. */ | 479 | /* Hold reference count during initialization. */ |
| 629 | local_set(__module_ref_addr(mod, raw_smp_processor_id()), 1); | 480 | __this_cpu_write(mod->refptr->count, 1); |
| 630 | /* Backwards compatibility macros put refcount during init. */ | 481 | /* Backwards compatibility macros put refcount during init. */ |
| 631 | mod->waiter = current; | 482 | mod->waiter = current; |
| 632 | } | 483 | } |
| @@ -769,7 +620,7 @@ unsigned int module_refcount(struct module *mod) | |||
| 769 | int cpu; | 620 | int cpu; |
| 770 | 621 | ||
| 771 | for_each_possible_cpu(cpu) | 622 | for_each_possible_cpu(cpu) |
| 772 | total += local_read(__module_ref_addr(mod, cpu)); | 623 | total += per_cpu_ptr(mod->refptr, cpu)->count; |
| 773 | return total; | 624 | return total; |
| 774 | } | 625 | } |
| 775 | EXPORT_SYMBOL(module_refcount); | 626 | EXPORT_SYMBOL(module_refcount); |
| @@ -946,14 +797,15 @@ static struct module_attribute refcnt = { | |||
| 946 | void module_put(struct module *module) | 797 | void module_put(struct module *module) |
| 947 | { | 798 | { |
| 948 | if (module) { | 799 | if (module) { |
| 949 | unsigned int cpu = get_cpu(); | 800 | preempt_disable(); |
| 950 | local_dec(__module_ref_addr(module, cpu)); | 801 | __this_cpu_dec(module->refptr->count); |
| 802 | |||
| 951 | trace_module_put(module, _RET_IP_, | 803 | trace_module_put(module, _RET_IP_, |
| 952 | local_read(__module_ref_addr(module, cpu))); | 804 | __this_cpu_read(module->refptr->count)); |
| 953 | /* Maybe they're waiting for us to drop reference? */ | 805 | /* Maybe they're waiting for us to drop reference? */ |
| 954 | if (unlikely(!module_is_live(module))) | 806 | if (unlikely(!module_is_live(module))) |
| 955 | wake_up_process(module->waiter); | 807 | wake_up_process(module->waiter); |
| 956 | put_cpu(); | 808 | preempt_enable(); |
| 957 | } | 809 | } |
| 958 | } | 810 | } |
| 959 | EXPORT_SYMBOL(module_put); | 811 | EXPORT_SYMBOL(module_put); |
| @@ -1030,11 +882,23 @@ static int try_to_force_load(struct module *mod, const char *reason) | |||
| 1030 | } | 882 | } |
| 1031 | 883 | ||
| 1032 | #ifdef CONFIG_MODVERSIONS | 884 | #ifdef CONFIG_MODVERSIONS |
| 885 | /* If the arch applies (non-zero) relocations to kernel kcrctab, unapply it. */ | ||
| 886 | static unsigned long maybe_relocated(unsigned long crc, | ||
| 887 | const struct module *crc_owner) | ||
| 888 | { | ||
| 889 | #ifdef ARCH_RELOCATES_KCRCTAB | ||
| 890 | if (crc_owner == NULL) | ||
| 891 | return crc - (unsigned long)reloc_start; | ||
| 892 | #endif | ||
| 893 | return crc; | ||
| 894 | } | ||
| 895 | |||
| 1033 | static int check_version(Elf_Shdr *sechdrs, | 896 | static int check_version(Elf_Shdr *sechdrs, |
| 1034 | unsigned int versindex, | 897 | unsigned int versindex, |
| 1035 | const char *symname, | 898 | const char *symname, |
| 1036 | struct module *mod, | 899 | struct module *mod, |
| 1037 | const unsigned long *crc) | 900 | const unsigned long *crc, |
| 901 | const struct module *crc_owner) | ||
| 1038 | { | 902 | { |
| 1039 | unsigned int i, num_versions; | 903 | unsigned int i, num_versions; |
| 1040 | struct modversion_info *versions; | 904 | struct modversion_info *versions; |
| @@ -1055,10 +919,10 @@ static int check_version(Elf_Shdr *sechdrs, | |||
| 1055 | if (strcmp(versions[i].name, symname) != 0) | 919 | if (strcmp(versions[i].name, symname) != 0) |
| 1056 | continue; | 920 | continue; |
| 1057 | 921 | ||
| 1058 | if (versions[i].crc == *crc) | 922 | if (versions[i].crc == maybe_relocated(*crc, crc_owner)) |
| 1059 | return 1; | 923 | return 1; |
| 1060 | DEBUGP("Found checksum %lX vs module %lX\n", | 924 | DEBUGP("Found checksum %lX vs module %lX\n", |
| 1061 | *crc, versions[i].crc); | 925 | maybe_relocated(*crc, crc_owner), versions[i].crc); |
| 1062 | goto bad_version; | 926 | goto bad_version; |
| 1063 | } | 927 | } |
| 1064 | 928 | ||
| @@ -1081,7 +945,8 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs, | |||
| 1081 | if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, | 945 | if (!find_symbol(MODULE_SYMBOL_PREFIX "module_layout", NULL, |
| 1082 | &crc, true, false)) | 946 | &crc, true, false)) |
| 1083 | BUG(); | 947 | BUG(); |
| 1084 | return check_version(sechdrs, versindex, "module_layout", mod, crc); | 948 | return check_version(sechdrs, versindex, "module_layout", mod, crc, |
| 949 | NULL); | ||
| 1085 | } | 950 | } |
| 1086 | 951 | ||
| 1087 | /* First part is kernel version, which we ignore if module has crcs. */ | 952 | /* First part is kernel version, which we ignore if module has crcs. */ |
| @@ -1099,7 +964,8 @@ static inline int check_version(Elf_Shdr *sechdrs, | |||
| 1099 | unsigned int versindex, | 964 | unsigned int versindex, |
| 1100 | const char *symname, | 965 | const char *symname, |
| 1101 | struct module *mod, | 966 | struct module *mod, |
| 1102 | const unsigned long *crc) | 967 | const unsigned long *crc, |
| 968 | const struct module *crc_owner) | ||
| 1103 | { | 969 | { |
| 1104 | return 1; | 970 | return 1; |
| 1105 | } | 971 | } |
| @@ -1134,8 +1000,8 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, | |||
| 1134 | /* use_module can fail due to OOM, | 1000 | /* use_module can fail due to OOM, |
| 1135 | or module initialization or unloading */ | 1001 | or module initialization or unloading */ |
| 1136 | if (sym) { | 1002 | if (sym) { |
| 1137 | if (!check_version(sechdrs, versindex, name, mod, crc) || | 1003 | if (!check_version(sechdrs, versindex, name, mod, crc, owner) |
| 1138 | !use_module(mod, owner)) | 1004 | || !use_module(mod, owner)) |
| 1139 | sym = NULL; | 1005 | sym = NULL; |
| 1140 | } | 1006 | } |
| 1141 | return sym; | 1007 | return sym; |
| @@ -1146,6 +1012,12 @@ static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs, | |||
| 1146 | * J. Corbet <corbet@lwn.net> | 1012 | * J. Corbet <corbet@lwn.net> |
| 1147 | */ | 1013 | */ |
| 1148 | #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) | 1014 | #if defined(CONFIG_KALLSYMS) && defined(CONFIG_SYSFS) |
| 1015 | |||
| 1016 | static inline bool sect_empty(const Elf_Shdr *sect) | ||
| 1017 | { | ||
| 1018 | return !(sect->sh_flags & SHF_ALLOC) || sect->sh_size == 0; | ||
| 1019 | } | ||
| 1020 | |||
| 1149 | struct module_sect_attr | 1021 | struct module_sect_attr |
| 1150 | { | 1022 | { |
| 1151 | struct module_attribute mattr; | 1023 | struct module_attribute mattr; |
| @@ -1187,7 +1059,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
| 1187 | 1059 | ||
| 1188 | /* Count loaded sections and allocate structures */ | 1060 | /* Count loaded sections and allocate structures */ |
| 1189 | for (i = 0; i < nsect; i++) | 1061 | for (i = 0; i < nsect; i++) |
| 1190 | if (sechdrs[i].sh_flags & SHF_ALLOC) | 1062 | if (!sect_empty(&sechdrs[i])) |
| 1191 | nloaded++; | 1063 | nloaded++; |
| 1192 | size[0] = ALIGN(sizeof(*sect_attrs) | 1064 | size[0] = ALIGN(sizeof(*sect_attrs) |
| 1193 | + nloaded * sizeof(sect_attrs->attrs[0]), | 1065 | + nloaded * sizeof(sect_attrs->attrs[0]), |
| @@ -1205,7 +1077,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
| 1205 | sattr = §_attrs->attrs[0]; | 1077 | sattr = §_attrs->attrs[0]; |
| 1206 | gattr = §_attrs->grp.attrs[0]; | 1078 | gattr = §_attrs->grp.attrs[0]; |
| 1207 | for (i = 0; i < nsect; i++) { | 1079 | for (i = 0; i < nsect; i++) { |
| 1208 | if (! (sechdrs[i].sh_flags & SHF_ALLOC)) | 1080 | if (sect_empty(&sechdrs[i])) |
| 1209 | continue; | 1081 | continue; |
| 1210 | sattr->address = sechdrs[i].sh_addr; | 1082 | sattr->address = sechdrs[i].sh_addr; |
| 1211 | sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, | 1083 | sattr->name = kstrdup(secstrings + sechdrs[i].sh_name, |
| @@ -1213,6 +1085,7 @@ static void add_sect_attrs(struct module *mod, unsigned int nsect, | |||
| 1213 | if (sattr->name == NULL) | 1085 | if (sattr->name == NULL) |
| 1214 | goto out; | 1086 | goto out; |
| 1215 | sect_attrs->nsections++; | 1087 | sect_attrs->nsections++; |
| 1088 | sysfs_attr_init(&sattr->mattr.attr); | ||
| 1216 | sattr->mattr.show = module_sect_show; | 1089 | sattr->mattr.show = module_sect_show; |
| 1217 | sattr->mattr.store = NULL; | 1090 | sattr->mattr.store = NULL; |
| 1218 | sattr->mattr.attr.name = sattr->name; | 1091 | sattr->mattr.attr.name = sattr->name; |
| @@ -1289,7 +1162,7 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, | |||
| 1289 | /* Count notes sections and allocate structures. */ | 1162 | /* Count notes sections and allocate structures. */ |
| 1290 | notes = 0; | 1163 | notes = 0; |
| 1291 | for (i = 0; i < nsect; i++) | 1164 | for (i = 0; i < nsect; i++) |
| 1292 | if ((sechdrs[i].sh_flags & SHF_ALLOC) && | 1165 | if (!sect_empty(&sechdrs[i]) && |
| 1293 | (sechdrs[i].sh_type == SHT_NOTE)) | 1166 | (sechdrs[i].sh_type == SHT_NOTE)) |
| 1294 | ++notes; | 1167 | ++notes; |
| 1295 | 1168 | ||
| @@ -1305,9 +1178,10 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect, | |||
| 1305 | notes_attrs->notes = notes; | 1178 | notes_attrs->notes = notes; |
| 1306 | nattr = ¬es_attrs->attrs[0]; | 1179 | nattr = ¬es_attrs->attrs[0]; |
| 1307 | for (loaded = i = 0; i < nsect; ++i) { | 1180 | for (loaded = i = 0; i < nsect; ++i) { |
| 1308 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | 1181 | if (sect_empty(&sechdrs[i])) |
| 1309 | continue; | 1182 | continue; |
| 1310 | if (sechdrs[i].sh_type == SHT_NOTE) { | 1183 | if (sechdrs[i].sh_type == SHT_NOTE) { |
| 1184 | sysfs_bin_attr_init(nattr); | ||
| 1311 | nattr->attr.name = mod->sect_attrs->attrs[loaded].name; | 1185 | nattr->attr.name = mod->sect_attrs->attrs[loaded].name; |
| 1312 | nattr->attr.mode = S_IRUGO; | 1186 | nattr->attr.mode = S_IRUGO; |
| 1313 | nattr->size = sechdrs[i].sh_size; | 1187 | nattr->size = sechdrs[i].sh_size; |
| @@ -1380,6 +1254,7 @@ int module_add_modinfo_attrs(struct module *mod) | |||
| 1380 | if (!attr->test || | 1254 | if (!attr->test || |
| 1381 | (attr->test && attr->test(mod))) { | 1255 | (attr->test && attr->test(mod))) { |
| 1382 | memcpy(temp_attr, attr, sizeof(*temp_attr)); | 1256 | memcpy(temp_attr, attr, sizeof(*temp_attr)); |
| 1257 | sysfs_attr_init(&temp_attr->attr); | ||
| 1383 | error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr); | 1258 | error = sysfs_create_file(&mod->mkobj.kobj,&temp_attr->attr); |
| 1384 | ++temp_attr; | 1259 | ++temp_attr; |
| 1385 | } | 1260 | } |
| @@ -1527,9 +1402,9 @@ static void free_module(struct module *mod) | |||
| 1527 | kfree(mod->args); | 1402 | kfree(mod->args); |
| 1528 | if (mod->percpu) | 1403 | if (mod->percpu) |
| 1529 | percpu_modfree(mod->percpu); | 1404 | percpu_modfree(mod->percpu); |
| 1530 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | 1405 | #if defined(CONFIG_MODULE_UNLOAD) |
| 1531 | if (mod->refptr) | 1406 | if (mod->refptr) |
| 1532 | percpu_modfree(mod->refptr); | 1407 | free_percpu(mod->refptr); |
| 1533 | #endif | 1408 | #endif |
| 1534 | /* Free lock-classes: */ | 1409 | /* Free lock-classes: */ |
| 1535 | lockdep_free_key_range(mod->module_core, mod->core_size); | 1410 | lockdep_free_key_range(mod->module_core, mod->core_size); |
| @@ -1992,12 +1867,14 @@ static inline unsigned long layout_symtab(struct module *mod, | |||
| 1992 | Elf_Shdr *sechdrs, | 1867 | Elf_Shdr *sechdrs, |
| 1993 | unsigned int symindex, | 1868 | unsigned int symindex, |
| 1994 | unsigned int strindex, | 1869 | unsigned int strindex, |
| 1995 | const Elf_Hdr *hdr, | 1870 | const Elf_Ehdr *hdr, |
| 1996 | const char *secstrings, | 1871 | const char *secstrings, |
| 1997 | unsigned long *pstroffs, | 1872 | unsigned long *pstroffs, |
| 1998 | unsigned long *strmap) | 1873 | unsigned long *strmap) |
| 1999 | { | 1874 | { |
| 1875 | return 0; | ||
| 2000 | } | 1876 | } |
| 1877 | |||
| 2001 | static inline void add_kallsyms(struct module *mod, | 1878 | static inline void add_kallsyms(struct module *mod, |
| 2002 | Elf_Shdr *sechdrs, | 1879 | Elf_Shdr *sechdrs, |
| 2003 | unsigned int shnum, | 1880 | unsigned int shnum, |
| @@ -2041,9 +1918,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, | |||
| 2041 | unsigned int i; | 1918 | unsigned int i; |
| 2042 | 1919 | ||
| 2043 | /* only scan the sections containing data */ | 1920 | /* only scan the sections containing data */ |
| 2044 | kmemleak_scan_area(mod->module_core, (unsigned long)mod - | 1921 | kmemleak_scan_area(mod, sizeof(struct module), GFP_KERNEL); |
| 2045 | (unsigned long)mod->module_core, | ||
| 2046 | sizeof(struct module), GFP_KERNEL); | ||
| 2047 | 1922 | ||
| 2048 | for (i = 1; i < hdr->e_shnum; i++) { | 1923 | for (i = 1; i < hdr->e_shnum; i++) { |
| 2049 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | 1924 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) |
| @@ -2052,8 +1927,7 @@ static void kmemleak_load_module(struct module *mod, Elf_Ehdr *hdr, | |||
| 2052 | && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) | 1927 | && strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) != 0) |
| 2053 | continue; | 1928 | continue; |
| 2054 | 1929 | ||
| 2055 | kmemleak_scan_area(mod->module_core, sechdrs[i].sh_addr - | 1930 | kmemleak_scan_area((void *)sechdrs[i].sh_addr, |
| 2056 | (unsigned long)mod->module_core, | ||
| 2057 | sechdrs[i].sh_size, GFP_KERNEL); | 1931 | sechdrs[i].sh_size, GFP_KERNEL); |
| 2058 | } | 1932 | } |
| 2059 | } | 1933 | } |
| @@ -2081,9 +1955,8 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2081 | struct module *mod; | 1955 | struct module *mod; |
| 2082 | long err = 0; | 1956 | long err = 0; |
| 2083 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ | 1957 | void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */ |
| 2084 | #ifdef CONFIG_KALLSYMS | ||
| 2085 | unsigned long symoffs, stroffs, *strmap; | 1958 | unsigned long symoffs, stroffs, *strmap; |
| 2086 | #endif | 1959 | |
| 2087 | mm_segment_t old_fs; | 1960 | mm_segment_t old_fs; |
| 2088 | 1961 | ||
| 2089 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", | 1962 | DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n", |
| @@ -2294,9 +2167,8 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2294 | mod = (void *)sechdrs[modindex].sh_addr; | 2167 | mod = (void *)sechdrs[modindex].sh_addr; |
| 2295 | kmemleak_load_module(mod, hdr, sechdrs, secstrings); | 2168 | kmemleak_load_module(mod, hdr, sechdrs, secstrings); |
| 2296 | 2169 | ||
| 2297 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | 2170 | #if defined(CONFIG_MODULE_UNLOAD) |
| 2298 | mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), | 2171 | mod->refptr = alloc_percpu(struct module_ref); |
| 2299 | mod->name); | ||
| 2300 | if (!mod->refptr) { | 2172 | if (!mod->refptr) { |
| 2301 | err = -ENOMEM; | 2173 | err = -ENOMEM; |
| 2302 | goto free_init; | 2174 | goto free_init; |
| @@ -2382,6 +2254,12 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2382 | "_ftrace_events", | 2254 | "_ftrace_events", |
| 2383 | sizeof(*mod->trace_events), | 2255 | sizeof(*mod->trace_events), |
| 2384 | &mod->num_trace_events); | 2256 | &mod->num_trace_events); |
| 2257 | /* | ||
| 2258 | * This section contains pointers to allocated objects in the trace | ||
| 2259 | * code and not scanning it leads to false positives. | ||
| 2260 | */ | ||
| 2261 | kmemleak_scan_area(mod->trace_events, sizeof(*mod->trace_events) * | ||
| 2262 | mod->num_trace_events, GFP_KERNEL); | ||
| 2385 | #endif | 2263 | #endif |
| 2386 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD | 2264 | #ifdef CONFIG_FTRACE_MCOUNT_RECORD |
| 2387 | /* sechdrs[0].sh_size is always zero */ | 2265 | /* sechdrs[0].sh_size is always zero */ |
| @@ -2522,8 +2400,8 @@ static noinline struct module *load_module(void __user *umod, | |||
| 2522 | kobject_put(&mod->mkobj.kobj); | 2400 | kobject_put(&mod->mkobj.kobj); |
| 2523 | free_unload: | 2401 | free_unload: |
| 2524 | module_unload_free(mod); | 2402 | module_unload_free(mod); |
| 2525 | #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) | 2403 | #if defined(CONFIG_MODULE_UNLOAD) |
| 2526 | percpu_modfree(mod->refptr); | 2404 | free_percpu(mod->refptr); |
| 2527 | free_init: | 2405 | free_init: |
| 2528 | #endif | 2406 | #endif |
| 2529 | module_free(mod, mod->module_init); | 2407 | module_free(mod, mod->module_init); |
