aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/module.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-11-18 01:44:58 -0500
committerDavid S. Miller <davem@davemloft.net>2011-11-18 01:44:58 -0500
commit0b64120cceb86e93cb1bda0dc055f13016646907 (patch)
tree5dcd3444fc219e5b9774734d846b655e0776575b /arch/sparc/kernel/module.c
parent3e37fd3153ac95088a74f5e7c569f7567e9f993a (diff)
sparc64: Patch sun4v code sequences properly on module load.
Some of the sun4v code patching occurs in inline functions visible to, and usable by, modules. Therefore we have to patch them up during module load. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/module.c')
-rw-r--r--arch/sparc/kernel/module.c27
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
208static 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
206int module_finalize(const Elf_Ehdr *hdr, 231int 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;