Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v5.3 53 lines 1.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * livepatch.c - x86-specific Kernel Live Patching Core 4 */ 5 6#include <linux/module.h> 7#include <linux/kallsyms.h> 8#include <linux/livepatch.h> 9#include <asm/text-patching.h> 10 11/* Apply per-object alternatives. Based on x86 module_finalize() */ 12void arch_klp_init_object_loaded(struct klp_patch *patch, 13 struct klp_object *obj) 14{ 15 int cnt; 16 struct klp_modinfo *info; 17 Elf_Shdr *s, *alt = NULL, *para = NULL; 18 void *aseg, *pseg; 19 const char *objname; 20 char sec_objname[MODULE_NAME_LEN]; 21 char secname[KSYM_NAME_LEN]; 22 23 info = patch->mod->klp_info; 24 objname = obj->name ? obj->name : "vmlinux"; 25 26 /* See livepatch core code for BUILD_BUG_ON() explanation */ 27 BUILD_BUG_ON(MODULE_NAME_LEN < 56 || KSYM_NAME_LEN != 128); 28 29 for (s = info->sechdrs; s < info->sechdrs + info->hdr.e_shnum; s++) { 30 /* Apply per-object .klp.arch sections */ 31 cnt = sscanf(info->secstrings + s->sh_name, 32 ".klp.arch.%55[^.].%127s", 33 sec_objname, secname); 34 if (cnt != 2) 35 continue; 36 if (strcmp(sec_objname, objname)) 37 continue; 38 if (!strcmp(".altinstructions", secname)) 39 alt = s; 40 if (!strcmp(".parainstructions", secname)) 41 para = s; 42 } 43 44 if (alt) { 45 aseg = (void *) alt->sh_addr; 46 apply_alternatives(aseg, aseg + alt->sh_size); 47 } 48 49 if (para) { 50 pseg = (void *) para->sh_addr; 51 apply_paravirt(pseg, pseg + para->sh_size); 52 } 53}