aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-06-20 12:31:01 -0400
committerPaul Mackerras <paulus@samba.org>2008-06-30 21:28:05 -0400
commitf0c426bc3557a93e9d2f2863fda1e2042f942a60 (patch)
treead52a0ac08a47b46c3b2b7ccdab364042a73b67b
parent87e9ab13c36b838f7d557a6111dfdd29fcde85ad (diff)
powerpc: Move common module code into its own file
Refactor common code between ppc32 and ppc64 module handling into a shared filed. Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/module.c110
-rw-r--r--arch/powerpc/kernel/module_32.c72
-rw-r--r--arch/powerpc/kernel/module_64.c78
4 files changed, 111 insertions, 151 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 0e8f928fef70..9ebeb2406b5b 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -44,7 +44,7 @@ obj-$(CONFIG_TAU) += tau_6xx.o
44obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \ 44obj-$(CONFIG_HIBERNATION) += swsusp.o suspend.o \
45 swsusp_$(CONFIG_WORD_SIZE).o 45 swsusp_$(CONFIG_WORD_SIZE).o
46obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o 46obj64-$(CONFIG_HIBERNATION) += swsusp_asm64.o
47obj-$(CONFIG_MODULES) += module_$(CONFIG_WORD_SIZE).o 47obj-$(CONFIG_MODULES) += module.o module_$(CONFIG_WORD_SIZE).o
48obj-$(CONFIG_44x) += cpu_setup_44x.o 48obj-$(CONFIG_44x) += cpu_setup_44x.o
49 49
50ifeq ($(CONFIG_PPC_MERGE),y) 50ifeq ($(CONFIG_PPC_MERGE),y)
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
new file mode 100644
index 000000000000..40dd52d81c18
--- /dev/null
+++ b/arch/powerpc/kernel/module.c
@@ -0,0 +1,110 @@
1/* Kernel module help for powerpc.
2 Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
3 Copyright (C) 2008 Freescale Semiconductor, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19#include <linux/module.h>
20#include <linux/elf.h>
21#include <linux/moduleloader.h>
22#include <linux/err.h>
23#include <linux/vmalloc.h>
24#include <linux/bug.h>
25#include <asm/module.h>
26#include <asm/uaccess.h>
27#include <asm/firmware.h>
28#include <linux/sort.h>
29
30#include "setup.h"
31
32LIST_HEAD(module_bug_list);
33
34void *module_alloc(unsigned long size)
35{
36 if (size == 0)
37 return NULL;
38
39 return vmalloc_exec(size);
40}
41
42/* Free memory returned from module_alloc */
43void module_free(struct module *mod, void *module_region)
44{
45 vfree(module_region);
46 /* FIXME: If module_region == mod->init_region, trim exception
47 table entries. */
48}
49
50static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
51 const Elf_Shdr *sechdrs,
52 const char *name)
53{
54 char *secstrings;
55 unsigned int i;
56
57 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
58 for (i = 1; i < hdr->e_shnum; i++)
59 if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
60 return &sechdrs[i];
61 return NULL;
62}
63
64int module_finalize(const Elf_Ehdr *hdr,
65 const Elf_Shdr *sechdrs, struct module *me)
66{
67 const Elf_Shdr *sect;
68 int err;
69
70 err = module_bug_finalize(hdr, sechdrs, me);
71 if (err)
72 return err;
73
74 /* Apply feature fixups */
75 sect = find_section(hdr, sechdrs, "__ftr_fixup");
76 if (sect != NULL)
77 do_feature_fixups(cur_cpu_spec->cpu_features,
78 (void *)sect->sh_addr,
79 (void *)sect->sh_addr + sect->sh_size);
80
81#ifdef CONFIG_PPC64
82 sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
83 if (sect != NULL)
84 do_feature_fixups(powerpc_firmware_features,
85 (void *)sect->sh_addr,
86 (void *)sect->sh_addr + sect->sh_size);
87#endif
88
89 return 0;
90}
91
92void module_arch_cleanup(struct module *mod)
93{
94 module_bug_cleanup(mod);
95}
96
97struct bug_entry *module_find_bug(unsigned long bugaddr)
98{
99 struct mod_arch_specific *mod;
100 unsigned int i;
101 struct bug_entry *bug;
102
103 list_for_each_entry(mod, &module_bug_list, bug_list) {
104 bug = mod->bug_table;
105 for (i = 0; i < mod->num_bugs; ++i, ++bug)
106 if (bugaddr == bug->bug_addr)
107 return bug;
108 }
109 return NULL;
110}
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index eab313858315..2df91a03462a 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -34,23 +34,6 @@
34#define DEBUGP(fmt , ...) 34#define DEBUGP(fmt , ...)
35#endif 35#endif
36 36
37LIST_HEAD(module_bug_list);
38
39void *module_alloc(unsigned long size)
40{
41 if (size == 0)
42 return NULL;
43 return vmalloc(size);
44}
45
46/* Free memory returned from module_alloc */
47void module_free(struct module *mod, void *module_region)
48{
49 vfree(module_region);
50 /* FIXME: If module_region == mod->init_region, trim exception
51 table entries. */
52}
53
54/* Count how many different relocations (different symbol, different 37/* Count how many different relocations (different symbol, different
55 addend) */ 38 addend) */
56static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) 39static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
@@ -325,58 +308,3 @@ int apply_relocate_add(Elf32_Shdr *sechdrs,
325 } 308 }
326 return 0; 309 return 0;
327} 310}
328
329static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
330 const Elf_Shdr *sechdrs,
331 const char *name)
332{
333 char *secstrings;
334 unsigned int i;
335
336 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
337 for (i = 1; i < hdr->e_shnum; i++)
338 if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
339 return &sechdrs[i];
340 return NULL;
341}
342
343int module_finalize(const Elf_Ehdr *hdr,
344 const Elf_Shdr *sechdrs,
345 struct module *me)
346{
347 const Elf_Shdr *sect;
348 int err;
349
350 err = module_bug_finalize(hdr, sechdrs, me);
351 if (err) /* never true, currently */
352 return err;
353
354 /* Apply feature fixups */
355 sect = find_section(hdr, sechdrs, "__ftr_fixup");
356 if (sect != NULL)
357 do_feature_fixups(cur_cpu_spec->cpu_features,
358 (void *)sect->sh_addr,
359 (void *)sect->sh_addr + sect->sh_size);
360
361 return 0;
362}
363
364void module_arch_cleanup(struct module *mod)
365{
366 module_bug_cleanup(mod);
367}
368
369struct bug_entry *module_find_bug(unsigned long bugaddr)
370{
371 struct mod_arch_specific *mod;
372 unsigned int i;
373 struct bug_entry *bug;
374
375 list_for_each_entry(mod, &module_bug_list, bug_list) {
376 bug = mod->bug_table;
377 for (i = 0; i < mod->num_bugs; ++i, ++bug)
378 if (bugaddr == bug->bug_addr)
379 return bug;
380 }
381 return NULL;
382}
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 3a82b02b784b..4803f2de98dd 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -101,22 +101,6 @@ static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
101 return _count_relocs; 101 return _count_relocs;
102} 102}
103 103
104void *module_alloc(unsigned long size)
105{
106 if (size == 0)
107 return NULL;
108
109 return vmalloc_exec(size);
110}
111
112/* Free memory returned from module_alloc */
113void module_free(struct module *mod, void *module_region)
114{
115 vfree(module_region);
116 /* FIXME: If module_region == mod->init_region, trim exception
117 table entries. */
118}
119
120static int relacmp(const void *_x, const void *_y) 104static int relacmp(const void *_x, const void *_y)
121{ 105{
122 const Elf64_Rela *x, *y; 106 const Elf64_Rela *x, *y;
@@ -466,65 +450,3 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
466 450
467 return 0; 451 return 0;
468} 452}
469
470LIST_HEAD(module_bug_list);
471
472static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
473 const Elf_Shdr *sechdrs,
474 const char *name)
475{
476 char *secstrings;
477 unsigned int i;
478
479 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
480 for (i = 1; i < hdr->e_shnum; i++)
481 if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
482 return &sechdrs[i];
483 return NULL;
484}
485
486int module_finalize(const Elf_Ehdr *hdr,
487 const Elf_Shdr *sechdrs, struct module *me)
488{
489 const Elf_Shdr *sect;
490 int err;
491
492 err = module_bug_finalize(hdr, sechdrs, me);
493 if (err)
494 return err;
495
496 /* Apply feature fixups */
497 sect = find_section(hdr, sechdrs, "__ftr_fixup");
498 if (sect != NULL)
499 do_feature_fixups(cur_cpu_spec->cpu_features,
500 (void *)sect->sh_addr,
501 (void *)sect->sh_addr + sect->sh_size);
502
503 sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
504 if (sect != NULL)
505 do_feature_fixups(powerpc_firmware_features,
506 (void *)sect->sh_addr,
507 (void *)sect->sh_addr + sect->sh_size);
508
509 return 0;
510}
511
512void module_arch_cleanup(struct module *mod)
513{
514 module_bug_cleanup(mod);
515}
516
517struct bug_entry *module_find_bug(unsigned long bugaddr)
518{
519 struct mod_arch_specific *mod;
520 unsigned int i;
521 struct bug_entry *bug;
522
523 list_for_each_entry(mod, &module_bug_list, bug_list) {
524 bug = mod->bug_table;
525 for (i = 0; i < mod->num_bugs; ++i, ++bug)
526 if (bugaddr == bug->bug_addr)
527 return bug;
528 }
529 return NULL;
530}