diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2009-03-04 07:06:53 -0500 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2009-03-26 14:02:51 -0400 |
commit | ee158fcd095c8233c9b578fbbe8a5897979a52a9 (patch) | |
tree | 5b10977ac6305d181406c7b68a4ce2b8cb194f26 | |
parent | 03f511dd02f1431ef652fb97a7f2fe7aef47e025 (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.h | 6 | ||||
-rw-r--r-- | arch/ia64/kernel/module.c | 32 |
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 | ||