Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Isaku Yamahata and committed by
Tony Luck
ee158fcd 03f511dd

+38
+6
arch/ia64/include/asm/module.h
··· 16 16 struct elf64_shdr *got; /* global offset table */ 17 17 struct elf64_shdr *opd; /* official procedure descriptors */ 18 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 25 unsigned long gp; /* global-pointer for module */ 20 26 21 27 void *core_unw_table; /* core unwind-table cookie returned by unwinder */
+32
arch/ia64/kernel/module.c
··· 446 446 mod->arch.opd = s; 447 447 else if (strcmp(".IA_64.unwind", secstrings + s->sh_name) == 0) 448 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 458 if (!mod->arch.core_plt || !mod->arch.init_plt || !mod->arch.got || !mod->arch.opd) { 451 459 printk(KERN_ERR "%s: sections missing\n", mod->name); ··· 929 921 DEBUGP("%s: init: entry=%p\n", __func__, mod->init); 930 922 if (mod->arch.unwind) 931 923 register_unwind_table(mod); 924 + #ifdef CONFIG_PARAVIRT 925 + if (mod->arch.paravirt_bundles) { 926 + struct paravirt_patch_site_bundle *start = 927 + (struct paravirt_patch_site_bundle *) 928 + mod->arch.paravirt_bundles->sh_addr; 929 + struct paravirt_patch_site_bundle *end = 930 + (struct paravirt_patch_site_bundle *) 931 + (mod->arch.paravirt_bundles->sh_addr + 932 + mod->arch.paravirt_bundles->sh_size); 933 + 934 + paravirt_patch_apply_bundle(start, end); 935 + } 936 + if (mod->arch.paravirt_insts) { 937 + struct paravirt_patch_site_inst *start = 938 + (struct paravirt_patch_site_inst *) 939 + mod->arch.paravirt_insts->sh_addr; 940 + struct paravirt_patch_site_inst *end = 941 + (struct paravirt_patch_site_inst *) 942 + (mod->arch.paravirt_insts->sh_addr + 943 + mod->arch.paravirt_insts->sh_size); 944 + 945 + paravirt_patch_apply_inst(start, end); 946 + } 947 + #endif 932 948 return 0; 933 949 } 934 950