diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-18 19:03:31 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-11-18 19:03:31 -0500 |
| commit | e27fc7e476077c724f313a3ddec44ad26c49f678 (patch) | |
| tree | 5d66d9694e4aa3985464e5034f1d4908ec426766 /arch/sparc/kernel/module.c | |
| parent | b6844523839779030430ff28f036f83e2a3f43e6 (diff) | |
| parent | 0b64120cceb86e93cb1bda0dc055f13016646907 (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc:
sparc64: Patch sun4v code sequences properly on module load.
sparc: Kill custom io_remap_pfn_range().
sparc: Stash orig_i0 into %g6 instead of %g2
sparc: Fix handling of orig_i0 wrt. debugging when restarting syscalls.
sparc: sigutil: Include <linux/errno.h>
Diffstat (limited to 'arch/sparc/kernel/module.c')
| -rw-r--r-- | arch/sparc/kernel/module.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/sparc/kernel/module.c b/arch/sparc/kernel/module.c index da0c6c70ccb2..e5519870c3d9 100644 --- a/arch/sparc/kernel/module.c +++ b/arch/sparc/kernel/module.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
| 18 | #include <asm/spitfire.h> | 18 | #include <asm/spitfire.h> |
| 19 | 19 | ||
| 20 | #include "entry.h" | ||
| 21 | |||
| 20 | #ifdef CONFIG_SPARC64 | 22 | #ifdef CONFIG_SPARC64 |
| 21 | 23 | ||
| 22 | #include <linux/jump_label.h> | 24 | #include <linux/jump_label.h> |
| @@ -203,6 +205,29 @@ int apply_relocate_add(Elf_Shdr *sechdrs, | |||
| 203 | } | 205 | } |
| 204 | 206 | ||
| 205 | #ifdef CONFIG_SPARC64 | 207 | #ifdef CONFIG_SPARC64 |
| 208 | static void do_patch_sections(const Elf_Ehdr *hdr, | ||
| 209 | const Elf_Shdr *sechdrs) | ||
| 210 | { | ||
| 211 | const Elf_Shdr *s, *sun4v_1insn = NULL, *sun4v_2insn = NULL; | ||
| 212 | char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; | ||
| 213 | |||
| 214 | for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { | ||
| 215 | if (!strcmp(".sun4v_1insn_patch", secstrings + s->sh_name)) | ||
| 216 | sun4v_1insn = s; | ||
| 217 | if (!strcmp(".sun4v_2insn_patch", secstrings + s->sh_name)) | ||
| 218 | sun4v_2insn = s; | ||
| 219 | } | ||
| 220 | |||
| 221 | if (sun4v_1insn && tlb_type == hypervisor) { | ||
| 222 | void *p = (void *) sun4v_1insn->sh_addr; | ||
| 223 | sun4v_patch_1insn_range(p, p + sun4v_1insn->sh_size); | ||
| 224 | } | ||
| 225 | if (sun4v_2insn && tlb_type == hypervisor) { | ||
| 226 | void *p = (void *) sun4v_2insn->sh_addr; | ||
| 227 | sun4v_patch_2insn_range(p, p + sun4v_2insn->sh_size); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 206 | int module_finalize(const Elf_Ehdr *hdr, | 231 | int module_finalize(const Elf_Ehdr *hdr, |
| 207 | const Elf_Shdr *sechdrs, | 232 | const Elf_Shdr *sechdrs, |
| 208 | struct module *me) | 233 | struct module *me) |
| @@ -210,6 +235,8 @@ int module_finalize(const Elf_Ehdr *hdr, | |||
| 210 | /* make jump label nops */ | 235 | /* make jump label nops */ |
| 211 | jump_label_apply_nops(me); | 236 | jump_label_apply_nops(me); |
| 212 | 237 | ||
| 238 | do_patch_sections(hdr, sechdrs); | ||
| 239 | |||
| 213 | /* Cheetah's I-cache is fully coherent. */ | 240 | /* Cheetah's I-cache is fully coherent. */ |
| 214 | if (tlb_type == spitfire) { | 241 | if (tlb_type == spitfire) { |
| 215 | unsigned long va; | 242 | unsigned long va; |
