aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIsaku Yamahata <yamahata@valinux.co.jp>2009-03-04 07:06:53 -0500
committerTony Luck <tony.luck@intel.com>2009-03-26 14:02:51 -0400
commitee158fcd095c8233c9b578fbbe8a5897979a52a9 (patch)
tree5b10977ac6305d181406c7b68a4ce2b8cb194f26
parent03f511dd02f1431ef652fb97a7f2fe7aef47e025 (diff)
ia64/pv_ops/bp/module: support binary patching for kernel module.
support binary patching for kernel module. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/include/asm/module.h6
-rw-r--r--arch/ia64/kernel/module.c32
2 files changed, 38 insertions, 0 deletions
diff --git a/arch/ia64/include/asm/module.h b/arch/ia64/include/asm/module.h
index d2da61e4c49b..908eaef42a08 100644
--- a/arch/ia64/include/asm/module.h
+++ b/arch/ia64/include/asm/module.h
@@ -16,6 +16,12 @@ struct mod_arch_specific {
16 struct elf64_shdr *got; /* global offset table */ 16 struct elf64_shdr *got; /* global offset table */
17 struct elf64_shdr *opd; /* official procedure descriptors */ 17 struct elf64_shdr *opd; /* official procedure descriptors */
18 struct elf64_shdr *unwind; /* unwind-table section */ 18 struct elf64_shdr *unwind; /* unwind-table section */
19#ifdef CONFIG_PARAVIRT
20 struct elf64_shdr *paravirt_bundles;
21 /* paravirt_alt_bundle_patch table */
22 struct elf64_shdr *paravirt_insts;
23 /* paravirt_alt_inst_patch table */
24#endif
19 unsigned long gp; /* global-pointer for module */ 25 unsigned long gp; /* global-pointer for module */
20 26
21 void *core_unw_table; /* core unwind-table cookie returned by unwinder */ 27 void *core_unw_table; /* core unwind-table cookie returned by unwinder */
diff --git a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
index aaa7d901521f..34fe4259a144 100644
--- a/arch/ia64/kernel/module.c
+++ b/arch/ia64/kernel/module.c
@@ -446,6 +446,14 @@ module_frob_arch_sections (Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, char *secstrings,
446 mod->arch.opd = s; 446 mod->arch.opd = s;
447 else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0) 447 else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0)
448 mod->arch.unwind = s; 448 mod->arch.unwind = s;
449#ifdef CONFIG_PARAVIRT
450 else if (strcmp(".paravirt_bundles",
451 secstrings + s->sh_name) == 0)
452 mod->arch.paravirt_bundles = s;
453 else if (strcmp(".paravirt_insts",
454 secstrings + s->sh_name) == 0)
455 mod->arch.paravirt_insts = s;
456#endif
449 457
450 if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) { 458 if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) {
451 printk(KERN_ERR "%s: sections missing\n", mod->name); 459 printk(KERN_ERR "%s: sections missing\n", mod->name);
@@ -921,6 +929,30 @@ module_finalize (const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *mo
921 DEBUGP("%s: init: entry=%p\n", __func__, mod->init); 929 DEBUGP("%s: init: entry=%p\n", __func__, mod->init);
922 if (mod->arch.unwind) 930 if (mod->arch.unwind)
923 register_unwind_table(mod); 931 register_unwind_table(mod);
932#ifdef CONFIG_PARAVIRT
933 if (mod->arch.paravirt_bundles) {
934 struct paravirt_patch_site_bundle *start =
935 (struct paravirt_patch_site_bundle *)
936 mod->arch.paravirt_bundles->sh_addr;
937 struct paravirt_patch_site_bundle *end =
938 (struct paravirt_patch_site_bundle *)
939 (mod->arch.paravirt_bundles->sh_addr +
940 mod->arch.paravirt_bundles->sh_size);
941
942 paravirt_patch_apply_bundle(start, end);
943 }
944 if (mod->arch.paravirt_insts) {
945 struct paravirt_patch_site_inst *start =
946 (struct paravirt_patch_site_inst *)
947 mod->arch.paravirt_insts->sh_addr;
948 struct paravirt_patch_site_inst *end =
949 (struct paravirt_patch_site_inst *)
950 (mod->arch.paravirt_insts->sh_addr +
951 mod->arch.paravirt_insts->sh_size);
952
953 paravirt_patch_apply_inst(start, end);
954 }
955#endif
924 return 0; 956 return 0;
925} 957}
926 958