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

Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 fixes from Catalin Marinas:

- Incorrect __BITS_PER_LONG as 64 when compiling the compat vDSO

- Unreachable PLT for ftrace_caller() in a module's .init.text
following past reworking of the module VA range selection

- Memory leak in the ACPI iort_rmr_alloc_sids() after a failed
krealloc_array()

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: ftrace: fix unreachable PLT for ftrace_caller in init_module with CONFIG_DYNAMIC_FTRACE
ACPI/IORT: Fix memory leak in iort_rmr_alloc_sids()
arm64: uapi: Provide correct __BITS_PER_LONG for the compat vDSO

+42 -5
+1
arch/arm64/include/asm/module.h
··· 19 19 20 20 /* for CONFIG_DYNAMIC_FTRACE */ 21 21 struct plt_entry *ftrace_trampolines; 22 + struct plt_entry *init_ftrace_trampolines; 22 23 }; 23 24 24 25 u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
+1
arch/arm64/include/asm/module.lds.h
··· 2 2 .plt 0 : { BYTE(0) } 3 3 .init.plt 0 : { BYTE(0) } 4 4 .text.ftrace_trampoline 0 : { BYTE(0) } 5 + .init.text.ftrace_trampoline 0 : { BYTE(0) } 5 6 6 7 #ifdef CONFIG_KASAN_SW_TAGS 7 8 /*
+5
arch/arm64/include/uapi/asm/bitsperlong.h
··· 17 17 #ifndef __ASM_BITSPERLONG_H 18 18 #define __ASM_BITSPERLONG_H 19 19 20 + #if defined(__KERNEL__) && !defined(__aarch64__) 21 + /* Used by the compat vDSO */ 22 + #define __BITS_PER_LONG 32 23 + #else 20 24 #define __BITS_PER_LONG 64 25 + #endif 21 26 22 27 #include <asm-generic/bitsperlong.h> 23 28
+10 -3
arch/arm64/kernel/ftrace.c
··· 258 258 return ftrace_modify_code(pc, 0, new, false); 259 259 } 260 260 261 - static struct plt_entry *get_ftrace_plt(struct module *mod) 261 + static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr) 262 262 { 263 263 #ifdef CONFIG_MODULES 264 - struct plt_entry *plt = mod->arch.ftrace_trampolines; 264 + struct plt_entry *plt = NULL; 265 + 266 + if (within_module_mem_type(addr, mod, MOD_INIT_TEXT)) 267 + plt = mod->arch.init_ftrace_trampolines; 268 + else if (within_module_mem_type(addr, mod, MOD_TEXT)) 269 + plt = mod->arch.ftrace_trampolines; 270 + else 271 + return NULL; 265 272 266 273 return &plt[FTRACE_PLT_IDX]; 267 274 #else ··· 339 332 if (WARN_ON(!mod)) 340 333 return false; 341 334 342 - plt = get_ftrace_plt(mod); 335 + plt = get_ftrace_plt(mod, pc); 343 336 if (!plt) { 344 337 pr_err("ftrace: no module PLT for %ps\n", (void *)*addr); 345 338 return false;
+11 -1
arch/arm64/kernel/module-plts.c
··· 283 283 unsigned long core_plts = 0; 284 284 unsigned long init_plts = 0; 285 285 Elf64_Sym *syms = NULL; 286 - Elf_Shdr *pltsec, *tramp = NULL; 286 + Elf_Shdr *pltsec, *tramp = NULL, *init_tramp = NULL; 287 287 int i; 288 288 289 289 /* ··· 298 298 else if (!strcmp(secstrings + sechdrs[i].sh_name, 299 299 ".text.ftrace_trampoline")) 300 300 tramp = sechdrs + i; 301 + else if (!strcmp(secstrings + sechdrs[i].sh_name, 302 + ".init.text.ftrace_trampoline")) 303 + init_tramp = sechdrs + i; 301 304 else if (sechdrs[i].sh_type == SHT_SYMTAB) 302 305 syms = (Elf64_Sym *)sechdrs[i].sh_addr; 303 306 } ··· 364 361 tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC; 365 362 tramp->sh_addralign = __alignof__(struct plt_entry); 366 363 tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry); 364 + } 365 + 366 + if (init_tramp) { 367 + init_tramp->sh_type = SHT_NOBITS; 368 + init_tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC; 369 + init_tramp->sh_addralign = __alignof__(struct plt_entry); 370 + init_tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry); 367 371 } 368 372 369 373 return 0;
+11
arch/arm64/kernel/module.c
··· 466 466 __init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR); 467 467 468 468 mod->arch.ftrace_trampolines = plts; 469 + 470 + s = find_section(hdr, sechdrs, ".init.text.ftrace_trampoline"); 471 + if (!s) 472 + return -ENOEXEC; 473 + 474 + plts = (void *)s->sh_addr; 475 + 476 + __init_plt(&plts[FTRACE_PLT_IDX], FTRACE_ADDR); 477 + 478 + mod->arch.init_ftrace_trampolines = plts; 479 + 469 480 #endif 470 481 return 0; 471 482 }
+3 -1
drivers/acpi/arm64/iort.c
··· 937 937 938 938 new_sids = krealloc_array(sids, count + new_count, 939 939 sizeof(*new_sids), GFP_KERNEL); 940 - if (!new_sids) 940 + if (!new_sids) { 941 + kfree(sids); 941 942 return NULL; 943 + } 942 944 943 945 for (i = count; i < total_count; i++) 944 946 new_sids[i] = id_start++;