Commit e5d5d233 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
parents 730c1451 a7ed7b9d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ struct mod_arch_specific {

	/* for CONFIG_DYNAMIC_FTRACE */
	struct plt_entry	*ftrace_trampolines;
	struct plt_entry	*init_ftrace_trampolines;
};

u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs,
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ SECTIONS {
	.plt 0 : { BYTE(0) }
	.init.plt 0 : { BYTE(0) }
	.text.ftrace_trampoline 0 : { BYTE(0) }
	.init.text.ftrace_trampoline 0 : { BYTE(0) }

#ifdef CONFIG_KASAN_SW_TAGS
	/*
+5 −0
Original line number Diff line number Diff line
@@ -17,7 +17,12 @@
#ifndef __ASM_BITSPERLONG_H
#define __ASM_BITSPERLONG_H

#if defined(__KERNEL__) && !defined(__aarch64__)
/* Used by the compat vDSO */
#define __BITS_PER_LONG 32
#else
#define __BITS_PER_LONG 64
#endif

#include <asm-generic/bitsperlong.h>

+10 −3
Original line number Diff line number Diff line
@@ -258,10 +258,17 @@ int ftrace_update_ftrace_func(ftrace_func_t func)
	return ftrace_modify_code(pc, 0, new, false);
}

static struct plt_entry *get_ftrace_plt(struct module *mod)
static struct plt_entry *get_ftrace_plt(struct module *mod, unsigned long addr)
{
#ifdef CONFIG_MODULES
	struct plt_entry *plt = mod->arch.ftrace_trampolines;
	struct plt_entry *plt = NULL;

	if (within_module_mem_type(addr, mod, MOD_INIT_TEXT))
		plt = mod->arch.init_ftrace_trampolines;
	else if (within_module_mem_type(addr, mod, MOD_TEXT))
		plt = mod->arch.ftrace_trampolines;
	else
		return NULL;

	return &plt[FTRACE_PLT_IDX];
#else
@@ -332,7 +339,7 @@ static bool ftrace_find_callable_addr(struct dyn_ftrace *rec,
	if (WARN_ON(!mod))
		return false;

	plt = get_ftrace_plt(mod);
	plt = get_ftrace_plt(mod, pc);
	if (!plt) {
		pr_err("ftrace: no module PLT for %ps\n", (void *)*addr);
		return false;
+11 −1
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
	unsigned long core_plts = 0;
	unsigned long init_plts = 0;
	Elf64_Sym *syms = NULL;
	Elf_Shdr *pltsec, *tramp = NULL;
	Elf_Shdr *pltsec, *tramp = NULL, *init_tramp = NULL;
	int i;

	/*
@@ -298,6 +298,9 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
		else if (!strcmp(secstrings + sechdrs[i].sh_name,
				 ".text.ftrace_trampoline"))
			tramp = sechdrs + i;
		else if (!strcmp(secstrings + sechdrs[i].sh_name,
				 ".init.text.ftrace_trampoline"))
			init_tramp = sechdrs + i;
		else if (sechdrs[i].sh_type == SHT_SYMTAB)
			syms = (Elf64_Sym *)sechdrs[i].sh_addr;
	}
@@ -363,5 +366,12 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
		tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry);
	}

	if (init_tramp) {
		init_tramp->sh_type = SHT_NOBITS;
		init_tramp->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
		init_tramp->sh_addralign = __alignof__(struct plt_entry);
		init_tramp->sh_size = NR_FTRACE_PLTS * sizeof(struct plt_entry);
	}

	return 0;
}
Loading