diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2007-05-31 03:40:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-31 10:58:13 -0400 |
commit | fbe9c9612930e0604dc99ef2da7e063fa3278817 (patch) | |
tree | b11a5a03edd4a61fc5c71b2b38402cdfe914de22 /arch/m68k | |
parent | 1fc799e1b4efdbc405d87d9f154d64d9bc299e5c (diff) |
m68k: runtime patching infrastructure
Add the basic infrastructure to allow runtime patching of kernel and modules
to optimize a few functions with parameters, which are only calculated once
during bootup and are otherwise constant. Use this for the conversion between
virtual and physical addresses.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/Makefile | 1 | ||||
-rw-r--r-- | arch/m68k/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/m68k/kernel/module.c | 28 | ||||
-rw-r--r-- | arch/m68k/kernel/module.lds | 7 | ||||
-rw-r--r-- | arch/m68k/kernel/vmlinux-std.lds | 5 | ||||
-rw-r--r-- | arch/m68k/kernel/vmlinux-sun3.lds | 5 | ||||
-rw-r--r-- | arch/m68k/mm/motorola.c | 3 |
7 files changed, 49 insertions, 3 deletions
diff --git a/arch/m68k/Makefile b/arch/m68k/Makefile index c20831a7e1a9..aa383a5ea7ac 100644 --- a/arch/m68k/Makefile +++ b/arch/m68k/Makefile | |||
@@ -19,6 +19,7 @@ COMPILE_ARCH = $(shell uname -m) | |||
19 | # override top level makefile | 19 | # override top level makefile |
20 | AS += -m68020 | 20 | AS += -m68020 |
21 | LDFLAGS := -m m68kelf | 21 | LDFLAGS := -m m68kelf |
22 | LDFLAGS_MODULE += -T $(srctree)/arch/m68k/kernel/module.lds | ||
22 | ifneq ($(COMPILE_ARCH),$(ARCH)) | 23 | ifneq ($(COMPILE_ARCH),$(ARCH)) |
23 | # prefix for cross-compiling binaries | 24 | # prefix for cross-compiling binaries |
24 | CROSS_COMPILE = m68k-linux-gnu- | 25 | CROSS_COMPILE = m68k-linux-gnu- |
diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index 0b68ab8d63d1..a806208c7fb5 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile | |||
@@ -9,13 +9,12 @@ else | |||
9 | endif | 9 | endif |
10 | extra-y += vmlinux.lds | 10 | extra-y += vmlinux.lds |
11 | 11 | ||
12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o \ | 12 | obj-y := entry.o process.o traps.o ints.o signal.o ptrace.o module.o \ |
13 | sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o | 13 | sys_m68k.o time.o semaphore.o setup.o m68k_ksyms.o devres.o |
14 | 14 | ||
15 | devres-y = ../../../kernel/irq/devres.o | 15 | devres-y = ../../../kernel/irq/devres.o |
16 | 16 | ||
17 | obj-$(CONFIG_PCI) += bios32.o | 17 | obj-$(CONFIG_PCI) += bios32.o |
18 | obj-$(CONFIG_MODULES) += module.o | ||
19 | obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo | 18 | obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo |
20 | 19 | ||
21 | EXTRA_AFLAGS := -traditional | 20 | EXTRA_AFLAGS := -traditional |
diff --git a/arch/m68k/kernel/module.c b/arch/m68k/kernel/module.c index 3b1a2ff61ddc..32969d0cecc4 100644 --- a/arch/m68k/kernel/module.c +++ b/arch/m68k/kernel/module.c | |||
@@ -1,3 +1,9 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file COPYING in the main directory of this archive | ||
4 | * for more details. | ||
5 | */ | ||
6 | |||
1 | #include <linux/moduleloader.h> | 7 | #include <linux/moduleloader.h> |
2 | #include <linux/elf.h> | 8 | #include <linux/elf.h> |
3 | #include <linux/vmalloc.h> | 9 | #include <linux/vmalloc.h> |
@@ -11,6 +17,8 @@ | |||
11 | #define DEBUGP(fmt...) | 17 | #define DEBUGP(fmt...) |
12 | #endif | 18 | #endif |
13 | 19 | ||
20 | #ifdef CONFIG_MODULES | ||
21 | |||
14 | void *module_alloc(unsigned long size) | 22 | void *module_alloc(unsigned long size) |
15 | { | 23 | { |
16 | if (size == 0) | 24 | if (size == 0) |
@@ -118,11 +126,29 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, | |||
118 | 126 | ||
119 | int module_finalize(const Elf_Ehdr *hdr, | 127 | int module_finalize(const Elf_Ehdr *hdr, |
120 | const Elf_Shdr *sechdrs, | 128 | const Elf_Shdr *sechdrs, |
121 | struct module *me) | 129 | struct module *mod) |
122 | { | 130 | { |
131 | module_fixup(mod, mod->arch.fixup_start, mod->arch.fixup_end); | ||
132 | |||
123 | return 0; | 133 | return 0; |
124 | } | 134 | } |
125 | 135 | ||
126 | void module_arch_cleanup(struct module *mod) | 136 | void module_arch_cleanup(struct module *mod) |
127 | { | 137 | { |
128 | } | 138 | } |
139 | |||
140 | #endif /* CONFIG_MODULES */ | ||
141 | |||
142 | void module_fixup(struct module *mod, struct m68k_fixup_info *start, | ||
143 | struct m68k_fixup_info *end) | ||
144 | { | ||
145 | struct m68k_fixup_info *fixup; | ||
146 | |||
147 | for (fixup = start; fixup < end; fixup++) { | ||
148 | switch (fixup->type) { | ||
149 | case m68k_fixup_memoffset: | ||
150 | *(u32 *)fixup->addr = m68k_memoffset; | ||
151 | break; | ||
152 | } | ||
153 | } | ||
154 | } | ||
diff --git a/arch/m68k/kernel/module.lds b/arch/m68k/kernel/module.lds new file mode 100644 index 000000000000..fda94fa38243 --- /dev/null +++ b/arch/m68k/kernel/module.lds | |||
@@ -0,0 +1,7 @@ | |||
1 | SECTIONS { | ||
2 | .m68k_fixup : { | ||
3 | __start_fixup = .; | ||
4 | *(.m68k_fixup) | ||
5 | __stop_fixup = .; | ||
6 | } | ||
7 | } | ||
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 78f139226a1b..40f02b128f22 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds | |||
@@ -60,6 +60,11 @@ SECTIONS | |||
60 | __con_initcall_start = .; | 60 | __con_initcall_start = .; |
61 | .con_initcall.init : { *(.con_initcall.init) } | 61 | .con_initcall.init : { *(.con_initcall.init) } |
62 | __con_initcall_end = .; | 62 | __con_initcall_end = .; |
63 | .m68k_fixup : { | ||
64 | __start_fixup = .; | ||
65 | *(.m68k_fixup) | ||
66 | __stop_fixup = .; | ||
67 | } | ||
63 | SECURITY_INIT | 68 | SECURITY_INIT |
64 | #ifdef CONFIG_BLK_DEV_INITRD | 69 | #ifdef CONFIG_BLK_DEV_INITRD |
65 | . = ALIGN(8192); | 70 | . = ALIGN(8192); |
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index c8999b2db23b..f06425b6d206 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds | |||
@@ -54,6 +54,11 @@ __init_begin = .; | |||
54 | __con_initcall_start = .; | 54 | __con_initcall_start = .; |
55 | .con_initcall.init : { *(.con_initcall.init) } | 55 | .con_initcall.init : { *(.con_initcall.init) } |
56 | __con_initcall_end = .; | 56 | __con_initcall_end = .; |
57 | .m68k_fixup : { | ||
58 | __start_fixup = .; | ||
59 | *(.m68k_fixup) | ||
60 | __stop_fixup = .; | ||
61 | } | ||
57 | SECURITY_INIT | 62 | SECURITY_INIT |
58 | #ifdef CONFIG_BLK_DEV_INITRD | 63 | #ifdef CONFIG_BLK_DEV_INITRD |
59 | . = ALIGN(8192); | 64 | . = ALIGN(8192); |
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c index afcccdc6ad45..98ef00547b37 100644 --- a/arch/m68k/mm/motorola.c +++ b/arch/m68k/mm/motorola.c | |||
@@ -222,6 +222,9 @@ void __init paging_init(void) | |||
222 | pgprot_val(protection_map[i]) |= _PAGE_CACHE040; | 222 | pgprot_val(protection_map[i]) |= _PAGE_CACHE040; |
223 | } | 223 | } |
224 | 224 | ||
225 | module_fixup(NULL, __start_fixup, __stop_fixup); | ||
226 | flush_icache(); | ||
227 | |||
225 | /* | 228 | /* |
226 | * Map the physical memory available into the kernel virtual | 229 | * Map the physical memory available into the kernel virtual |
227 | * address space. It may allocate some memory for page | 230 | * address space. It may allocate some memory for page |