+++ /dev/null
-From foo@baz Thu Sep 23 12:33:34 PM CEST 2021
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Wed, 22 Sep 2021 10:02:07 -0700
-Subject: ARM: 9077/1: PLT: Move struct plt_entries definition to header
-To: linux-kernel@vger.kernel.org
-Cc: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, Alex Sverdlin <alexander.sverdlin@nokia.com>, Russell King <rmk+kernel@armlinux.org.uk>, Florian Fainelli <f.fainelli@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, Ingo Molnar <mingo@redhat.com>, Russell King <linux@armlinux.org.uk>, linux-arm-kernel@lists.infradead.org (moderated list:ARM PORT)
-Message-ID: <20210922170210.190410-2-f.fainelli@gmail.com>
-
-From: Alex Sverdlin <alexander.sverdlin@nokia.com>
-
-commit 4e271701c17dee70c6e1351c4d7d42e70405c6a9 upstream
-
-No functional change, later it will be re-used in several files.
-
-Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/arm/include/asm/module.h | 9 +++++++++
- arch/arm/kernel/module-plts.c | 9 ---------
- 2 files changed, 9 insertions(+), 9 deletions(-)
-
---- a/arch/arm/include/asm/module.h
-+++ b/arch/arm/include/asm/module.h
-@@ -19,6 +19,15 @@ enum {
- };
- #endif
-
-+#define PLT_ENT_STRIDE L1_CACHE_BYTES
-+#define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32))
-+#define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT)
-+
-+struct plt_entries {
-+ u32 ldr[PLT_ENT_COUNT];
-+ u32 lit[PLT_ENT_COUNT];
-+};
-+
- struct mod_plt_sec {
- struct elf32_shdr *plt;
- int plt_count;
---- a/arch/arm/kernel/module-plts.c
-+++ b/arch/arm/kernel/module-plts.c
-@@ -14,10 +14,6 @@
- #include <asm/cache.h>
- #include <asm/opcodes.h>
-
--#define PLT_ENT_STRIDE L1_CACHE_BYTES
--#define PLT_ENT_COUNT (PLT_ENT_STRIDE / sizeof(u32))
--#define PLT_ENT_SIZE (sizeof(struct plt_entries) / PLT_ENT_COUNT)
--
- #ifdef CONFIG_THUMB2_KERNEL
- #define PLT_ENT_LDR __opcode_to_mem_thumb32(0xf8dff000 | \
- (PLT_ENT_STRIDE - 4))
-@@ -26,11 +22,6 @@
- (PLT_ENT_STRIDE - 8))
- #endif
-
--struct plt_entries {
-- u32 ldr[PLT_ENT_COUNT];
-- u32 lit[PLT_ENT_COUNT];
--};
--
- static bool in_init(const struct module *mod, unsigned long loc)
- {
- return loc - (u32)mod->init_layout.base < mod->init_layout.size;
+++ /dev/null
-From foo@baz Thu Sep 23 12:33:34 PM CEST 2021
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Wed, 22 Sep 2021 10:02:08 -0700
-Subject: ARM: 9078/1: Add warn suppress parameter to arm_gen_branch_link()
-To: linux-kernel@vger.kernel.org
-Cc: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, Alex Sverdlin <alexander.sverdlin@nokia.com>, Russell King <rmk+kernel@armlinux.org.uk>, Florian Fainelli <f.fainelli@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, Ingo Molnar <mingo@redhat.com>, Russell King <linux@armlinux.org.uk>, linux-arm-kernel@lists.infradead.org (moderated list:ARM PORT)
-Message-ID: <20210922170210.190410-3-f.fainelli@gmail.com>
-
-From: Alex Sverdlin <alexander.sverdlin@nokia.com>
-
-commit 890cb057a46d323fd8c77ebecb6485476614cd21 upstream
-
-Will be used in the following patch. No functional change.
-
-Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/arm/include/asm/insn.h | 8 ++++----
- arch/arm/kernel/ftrace.c | 2 +-
- arch/arm/kernel/insn.c | 19 ++++++++++---------
- 3 files changed, 15 insertions(+), 14 deletions(-)
-
---- a/arch/arm/include/asm/insn.h
-+++ b/arch/arm/include/asm/insn.h
-@@ -13,18 +13,18 @@ arm_gen_nop(void)
- }
-
- unsigned long
--__arm_gen_branch(unsigned long pc, unsigned long addr, bool link);
-+__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn);
-
- static inline unsigned long
- arm_gen_branch(unsigned long pc, unsigned long addr)
- {
-- return __arm_gen_branch(pc, addr, false);
-+ return __arm_gen_branch(pc, addr, false, true);
- }
-
- static inline unsigned long
--arm_gen_branch_link(unsigned long pc, unsigned long addr)
-+arm_gen_branch_link(unsigned long pc, unsigned long addr, bool warn)
- {
-- return __arm_gen_branch(pc, addr, true);
-+ return __arm_gen_branch(pc, addr, true, warn);
- }
-
- #endif
---- a/arch/arm/kernel/ftrace.c
-+++ b/arch/arm/kernel/ftrace.c
-@@ -98,7 +98,7 @@ int ftrace_arch_code_modify_post_process
-
- static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
- {
-- return arm_gen_branch_link(pc, addr);
-+ return arm_gen_branch_link(pc, addr, true);
- }
-
- static int ftrace_modify_code(unsigned long pc, unsigned long old,
---- a/arch/arm/kernel/insn.c
-+++ b/arch/arm/kernel/insn.c
-@@ -3,8 +3,9 @@
- #include <linux/kernel.h>
- #include <asm/opcodes.h>
-
--static unsigned long
--__arm_gen_branch_thumb2(unsigned long pc, unsigned long addr, bool link)
-+static unsigned long __arm_gen_branch_thumb2(unsigned long pc,
-+ unsigned long addr, bool link,
-+ bool warn)
- {
- unsigned long s, j1, j2, i1, i2, imm10, imm11;
- unsigned long first, second;
-@@ -12,7 +13,7 @@ __arm_gen_branch_thumb2(unsigned long pc
-
- offset = (long)addr - (long)(pc + 4);
- if (offset < -16777216 || offset > 16777214) {
-- WARN_ON_ONCE(1);
-+ WARN_ON_ONCE(warn);
- return 0;
- }
-
-@@ -33,8 +34,8 @@ __arm_gen_branch_thumb2(unsigned long pc
- return __opcode_thumb32_compose(first, second);
- }
-
--static unsigned long
--__arm_gen_branch_arm(unsigned long pc, unsigned long addr, bool link)
-+static unsigned long __arm_gen_branch_arm(unsigned long pc, unsigned long addr,
-+ bool link, bool warn)
- {
- unsigned long opcode = 0xea000000;
- long offset;
-@@ -44,7 +45,7 @@ __arm_gen_branch_arm(unsigned long pc, u
-
- offset = (long)addr - (long)(pc + 8);
- if (unlikely(offset < -33554432 || offset > 33554428)) {
-- WARN_ON_ONCE(1);
-+ WARN_ON_ONCE(warn);
- return 0;
- }
-
-@@ -54,10 +55,10 @@ __arm_gen_branch_arm(unsigned long pc, u
- }
-
- unsigned long
--__arm_gen_branch(unsigned long pc, unsigned long addr, bool link)
-+__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn)
- {
- if (IS_ENABLED(CONFIG_THUMB2_KERNEL))
-- return __arm_gen_branch_thumb2(pc, addr, link);
-+ return __arm_gen_branch_thumb2(pc, addr, link, warn);
- else
-- return __arm_gen_branch_arm(pc, addr, link);
-+ return __arm_gen_branch_arm(pc, addr, link, warn);
- }
+++ /dev/null
-From foo@baz Thu Sep 23 12:33:34 PM CEST 2021
-From: Florian Fainelli <f.fainelli@gmail.com>
-Date: Wed, 22 Sep 2021 10:02:09 -0700
-Subject: ARM: 9079/1: ftrace: Add MODULE_PLTS support
-To: linux-kernel@vger.kernel.org
-Cc: stable@vger.kernel.org, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>, Alex Sverdlin <alexander.sverdlin@nokia.com>, Russell King <rmk+kernel@armlinux.org.uk>, Florian Fainelli <f.fainelli@gmail.com>, Steven Rostedt <rostedt@goodmis.org>, Ingo Molnar <mingo@redhat.com>, Russell King <linux@armlinux.org.uk>, linux-arm-kernel@lists.infradead.org (moderated list:ARM PORT)
-Message-ID: <20210922170210.190410-4-f.fainelli@gmail.com>
-
-From: Alex Sverdlin <alexander.sverdlin@nokia.com>
-
-commit 79f32b221b18c15a98507b101ef4beb52444cc6f upstream
-
-Teach ftrace_make_call() and ftrace_make_nop() about PLTs.
-Teach PLT code about FTRACE and all its callbacks.
-Otherwise the following might happen:
-
-------------[ cut here ]------------
-WARNING: CPU: 14 PID: 2265 at .../arch/arm/kernel/insn.c:14 __arm_gen_branch+0x83/0x8c()
-...
-Hardware name: LSI Axxia AXM55XX
-[<c0314a49>] (unwind_backtrace) from [<c03115e9>] (show_stack+0x11/0x14)
-[<c03115e9>] (show_stack) from [<c0519f51>] (dump_stack+0x81/0xa8)
-[<c0519f51>] (dump_stack) from [<c032185d>] (warn_slowpath_common+0x69/0x90)
-[<c032185d>] (warn_slowpath_common) from [<c03218f3>] (warn_slowpath_null+0x17/0x1c)
-[<c03218f3>] (warn_slowpath_null) from [<c03143cf>] (__arm_gen_branch+0x83/0x8c)
-[<c03143cf>] (__arm_gen_branch) from [<c0314337>] (ftrace_make_nop+0xf/0x24)
-[<c0314337>] (ftrace_make_nop) from [<c038ebcb>] (ftrace_process_locs+0x27b/0x3e8)
-[<c038ebcb>] (ftrace_process_locs) from [<c0378d79>] (load_module+0x11e9/0x1a44)
-[<c0378d79>] (load_module) from [<c037974d>] (SyS_finit_module+0x59/0x84)
-[<c037974d>] (SyS_finit_module) from [<c030e981>] (ret_fast_syscall+0x1/0x18)
----[ end trace e1b64ced7a89adcc ]---
-------------[ cut here ]------------
-WARNING: CPU: 14 PID: 2265 at .../kernel/trace/ftrace.c:1979 ftrace_bug+0x1b1/0x234()
-...
-Hardware name: LSI Axxia AXM55XX
-[<c0314a49>] (unwind_backtrace) from [<c03115e9>] (show_stack+0x11/0x14)
-[<c03115e9>] (show_stack) from [<c0519f51>] (dump_stack+0x81/0xa8)
-[<c0519f51>] (dump_stack) from [<c032185d>] (warn_slowpath_common+0x69/0x90)
-[<c032185d>] (warn_slowpath_common) from [<c03218f3>] (warn_slowpath_null+0x17/0x1c)
-[<c03218f3>] (warn_slowpath_null) from [<c038e87d>] (ftrace_bug+0x1b1/0x234)
-[<c038e87d>] (ftrace_bug) from [<c038ebd5>] (ftrace_process_locs+0x285/0x3e8)
-[<c038ebd5>] (ftrace_process_locs) from [<c0378d79>] (load_module+0x11e9/0x1a44)
-[<c0378d79>] (load_module) from [<c037974d>] (SyS_finit_module+0x59/0x84)
-[<c037974d>] (SyS_finit_module) from [<c030e981>] (ret_fast_syscall+0x1/0x18)
----[ end trace e1b64ced7a89adcd ]---
-ftrace failed to modify [<e9ef7006>] 0xe9ef7006
-actual: 02:f0:3b:fa
-ftrace record flags: 0
-(0) expected tramp: c0314265
-
-Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nokia.com>
-Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
-[florian: resolved merge conflict with struct
-dyn_arch_ftrace::old_mcount]
-Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- arch/arm/include/asm/ftrace.h | 3 ++
- arch/arm/include/asm/module.h | 1
- arch/arm/kernel/ftrace.c | 46 ++++++++++++++++++++++++++++++++++--------
- arch/arm/kernel/module-plts.c | 44 ++++++++++++++++++++++++++++++++++++----
- 4 files changed, 82 insertions(+), 12 deletions(-)
-
---- a/arch/arm/include/asm/ftrace.h
-+++ b/arch/arm/include/asm/ftrace.h
-@@ -19,6 +19,9 @@ struct dyn_arch_ftrace {
- #ifdef CONFIG_OLD_MCOUNT
- bool old_mcount;
- #endif
-+#ifdef CONFIG_ARM_MODULE_PLTS
-+ struct module *mod;
-+#endif
- };
-
- static inline unsigned long ftrace_call_adjust(unsigned long addr)
---- a/arch/arm/include/asm/module.h
-+++ b/arch/arm/include/asm/module.h
-@@ -30,6 +30,7 @@ struct plt_entries {
-
- struct mod_plt_sec {
- struct elf32_shdr *plt;
-+ struct plt_entries *plt_ent;
- int plt_count;
- };
-
---- a/arch/arm/kernel/ftrace.c
-+++ b/arch/arm/kernel/ftrace.c
-@@ -96,9 +96,10 @@ int ftrace_arch_code_modify_post_process
- return 0;
- }
-
--static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr)
-+static unsigned long ftrace_call_replace(unsigned long pc, unsigned long addr,
-+ bool warn)
- {
-- return arm_gen_branch_link(pc, addr, true);
-+ return arm_gen_branch_link(pc, addr, warn);
- }
-
- static int ftrace_modify_code(unsigned long pc, unsigned long old,
-@@ -137,14 +138,14 @@ int ftrace_update_ftrace_func(ftrace_fun
- int ret;
-
- pc = (unsigned long)&ftrace_call;
-- new = ftrace_call_replace(pc, (unsigned long)func);
-+ new = ftrace_call_replace(pc, (unsigned long)func, true);
-
- ret = ftrace_modify_code(pc, 0, new, false);
-
- #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS
- if (!ret) {
- pc = (unsigned long)&ftrace_regs_call;
-- new = ftrace_call_replace(pc, (unsigned long)func);
-+ new = ftrace_call_replace(pc, (unsigned long)func, true);
-
- ret = ftrace_modify_code(pc, 0, new, false);
- }
-@@ -166,10 +167,22 @@ int ftrace_make_call(struct dyn_ftrace *
- {
- unsigned long new, old;
- unsigned long ip = rec->ip;
-+ unsigned long aaddr = adjust_address(rec, addr);
-+ struct module *mod = NULL;
-+
-+#ifdef CONFIG_ARM_MODULE_PLTS
-+ mod = rec->arch.mod;
-+#endif
-
- old = ftrace_nop_replace(rec);
-
-- new = ftrace_call_replace(ip, adjust_address(rec, addr));
-+ new = ftrace_call_replace(ip, aaddr, !mod);
-+#ifdef CONFIG_ARM_MODULE_PLTS
-+ if (!new && mod) {
-+ aaddr = get_module_plt(mod, ip, aaddr);
-+ new = ftrace_call_replace(ip, aaddr, true);
-+ }
-+#endif
-
- return ftrace_modify_code(rec->ip, old, new, true);
- }
-@@ -182,9 +195,9 @@ int ftrace_modify_call(struct dyn_ftrace
- unsigned long new, old;
- unsigned long ip = rec->ip;
-
-- old = ftrace_call_replace(ip, adjust_address(rec, old_addr));
-+ old = ftrace_call_replace(ip, adjust_address(rec, old_addr), true);
-
-- new = ftrace_call_replace(ip, adjust_address(rec, addr));
-+ new = ftrace_call_replace(ip, adjust_address(rec, addr), true);
-
- return ftrace_modify_code(rec->ip, old, new, true);
- }
-@@ -194,12 +207,29 @@ int ftrace_modify_call(struct dyn_ftrace
- int ftrace_make_nop(struct module *mod,
- struct dyn_ftrace *rec, unsigned long addr)
- {
-+ unsigned long aaddr = adjust_address(rec, addr);
- unsigned long ip = rec->ip;
- unsigned long old;
- unsigned long new;
- int ret;
-
-- old = ftrace_call_replace(ip, adjust_address(rec, addr));
-+#ifdef CONFIG_ARM_MODULE_PLTS
-+ /* mod is only supplied during module loading */
-+ if (!mod)
-+ mod = rec->arch.mod;
-+ else
-+ rec->arch.mod = mod;
-+#endif
-+
-+ old = ftrace_call_replace(ip, aaddr,
-+ !IS_ENABLED(CONFIG_ARM_MODULE_PLTS) || !mod);
-+#ifdef CONFIG_ARM_MODULE_PLTS
-+ if (!old && mod) {
-+ aaddr = get_module_plt(mod, ip, aaddr);
-+ old = ftrace_call_replace(ip, aaddr, true);
-+ }
-+#endif
-+
- new = ftrace_nop_replace(rec);
- ret = ftrace_modify_code(ip, old, new, true);
-
---- a/arch/arm/kernel/module-plts.c
-+++ b/arch/arm/kernel/module-plts.c
-@@ -7,6 +7,7 @@
- */
-
- #include <linux/elf.h>
-+#include <linux/ftrace.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/sort.h>
-@@ -22,19 +23,52 @@
- (PLT_ENT_STRIDE - 8))
- #endif
-
-+static const u32 fixed_plts[] = {
-+#ifdef CONFIG_FUNCTION_TRACER
-+ FTRACE_ADDR,
-+ MCOUNT_ADDR,
-+#endif
-+};
-+
- static bool in_init(const struct module *mod, unsigned long loc)
- {
- return loc - (u32)mod->init_layout.base < mod->init_layout.size;
- }
-
-+static void prealloc_fixed(struct mod_plt_sec *pltsec, struct plt_entries *plt)
-+{
-+ int i;
-+
-+ if (!ARRAY_SIZE(fixed_plts) || pltsec->plt_count)
-+ return;
-+ pltsec->plt_count = ARRAY_SIZE(fixed_plts);
-+
-+ for (i = 0; i < ARRAY_SIZE(plt->ldr); ++i)
-+ plt->ldr[i] = PLT_ENT_LDR;
-+
-+ BUILD_BUG_ON(sizeof(fixed_plts) > sizeof(plt->lit));
-+ memcpy(plt->lit, fixed_plts, sizeof(fixed_plts));
-+}
-+
- u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
- {
- struct mod_plt_sec *pltsec = !in_init(mod, loc) ? &mod->arch.core :
- &mod->arch.init;
-+ struct plt_entries *plt;
-+ int idx;
-+
-+ /* cache the address, ELF header is available only during module load */
-+ if (!pltsec->plt_ent)
-+ pltsec->plt_ent = (struct plt_entries *)pltsec->plt->sh_addr;
-+ plt = pltsec->plt_ent;
-
-- struct plt_entries *plt = (struct plt_entries *)pltsec->plt->sh_addr;
-- int idx = 0;
-+ prealloc_fixed(pltsec, plt);
-+
-+ for (idx = 0; idx < ARRAY_SIZE(fixed_plts); ++idx)
-+ if (plt->lit[idx] == val)
-+ return (u32)&plt->ldr[idx];
-
-+ idx = 0;
- /*
- * Look for an existing entry pointing to 'val'. Given that the
- * relocations are sorted, this will be the last entry we allocated.
-@@ -182,8 +216,8 @@ static unsigned int count_plts(const Elf
- int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
- char *secstrings, struct module *mod)
- {
-- unsigned long core_plts = 0;
-- unsigned long init_plts = 0;
-+ unsigned long core_plts = ARRAY_SIZE(fixed_plts);
-+ unsigned long init_plts = ARRAY_SIZE(fixed_plts);
- Elf32_Shdr *s, *sechdrs_end = sechdrs + ehdr->e_shnum;
- Elf32_Sym *syms = NULL;
-
-@@ -238,6 +272,7 @@ int module_frob_arch_sections(Elf_Ehdr *
- mod->arch.core.plt->sh_size = round_up(core_plts * PLT_ENT_SIZE,
- sizeof(struct plt_entries));
- mod->arch.core.plt_count = 0;
-+ mod->arch.core.plt_ent = NULL;
-
- mod->arch.init.plt->sh_type = SHT_NOBITS;
- mod->arch.init.plt->sh_flags = SHF_EXECINSTR | SHF_ALLOC;
-@@ -245,6 +280,7 @@ int module_frob_arch_sections(Elf_Ehdr *
- mod->arch.init.plt->sh_size = round_up(init_plts * PLT_ENT_SIZE,
- sizeof(struct plt_entries));
- mod->arch.init.plt_count = 0;
-+ mod->arch.init.plt_ent = NULL;
-
- pr_debug("%s: plt=%x, init.plt=%x\n", __func__,
- mod->arch.core.plt->sh_size, mod->arch.init.plt->sh_size);