From: Greg Kroah-Hartman Date: Wed, 15 Mar 2023 11:07:29 +0000 (+0100) Subject: drop a bunch of riscv patches on older kernels. X-Git-Tag: v4.14.310~27 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fda622dbd3255b233283266bb29ae3d1f54c11fc;p=thirdparty%2Fkernel%2Fstable-queue.git drop a bunch of riscv patches on older kernels. No one cares about this arch on those old trees. --- diff --git a/queue-4.19/riscv-ftrace-reduce-the-detour-code-size-to-half.patch b/queue-4.19/riscv-ftrace-reduce-the-detour-code-size-to-half.patch deleted file mode 100644 index 9f21c4809aa..00000000000 --- a/queue-4.19/riscv-ftrace-reduce-the-detour-code-size-to-half.patch +++ /dev/null @@ -1,448 +0,0 @@ -From 9385d1c7aeff25710c0423b0e63cd659cd755daf Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 12 Jan 2023 04:05:59 -0500 -Subject: riscv: ftrace: Reduce the detour code size to half - -From: Guo Ren - -[ Upstream commit 6724a76cff85ee271bbbff42ac527e4643b2ec52 ] - -Use a temporary register to reduce the size of detour code from 16 bytes to -8 bytes. The previous implementation is from 'commit afc76b8b8011 ("riscv: -Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT")'. - -Before the patch: -: - 0: REG_S ra, -SZREG(sp) - 4: auipc ra, ? - 8: jalr ?(ra) -12: REG_L ra, -SZREG(sp) - (func_boddy) - -After the patch: -: - 0: auipc t0, ? - 4: jalr t0, ?(t0) - (func_boddy) - -This patch not just reduces the size of detour code, but also fixes an -important issue: - -An Ftrace callback registered with FTRACE_OPS_FL_IPMODIFY flag can -actually change the instruction pointer, e.g. to "replace" the given -kernel function with a new one, which is needed for livepatching, etc. - -In this case, the trampoline (ftrace_regs_caller) would not return to - but would rather jump to the new function. So, "REG_L -ra, -SZREG(sp)" would not run and the original return address would not -be restored. The kernel is likely to hang or crash as a result. - -This can be easily demonstrated if one tries to "replace", say, -cmdline_proc_show() with a new function with the same signature using -instruction_pointer_set(&fregs->regs, new_func_addr) in the Ftrace -callback. - -Link: https://lore.kernel.org/linux-riscv/20221122075440.1165172-1-suagrfillet@gmail.com/ -Link: https://lore.kernel.org/linux-riscv/d7d5730b-ebef-68e5-5046-e763e1ee6164@yadro.com/ -Co-developed-by: Song Shuai -Signed-off-by: Song Shuai -Signed-off-by: Guo Ren -Signed-off-by: Guo Ren -Cc: Evgenii Shatokhin -Reviewed-by: Evgenii Shatokhin -Link: https://lore.kernel.org/r/20230112090603.1295340-4-guoren@kernel.org -Cc: stable@vger.kernel.org -Fixes: 10626c32e382 ("riscv/ftrace: Add basic support") -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 4 +- - arch/riscv/include/asm/ftrace.h | 50 +++++++++++++++++++------ - arch/riscv/kernel/ftrace.c | 65 ++++++++++----------------------- - arch/riscv/kernel/mcount-dyn.S | 42 ++++++++------------- - 4 files changed, 75 insertions(+), 86 deletions(-) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index fbc3c9adca70a..f241cbdd45bd4 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -14,9 +14,9 @@ ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax - KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY - ifeq ($(CONFIG_RISCV_ISA_C),y) -- CC_FLAGS_FTRACE := -fpatchable-function-entry=8 --else - CC_FLAGS_FTRACE := -fpatchable-function-entry=4 -+else -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=2 - endif - endif - KBUILD_AFLAGS_MODULE += -fPIC -diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h -index 693c3839a7dfe..21c1aaf9fd3d7 100644 ---- a/arch/riscv/include/asm/ftrace.h -+++ b/arch/riscv/include/asm/ftrace.h -@@ -39,6 +39,14 @@ struct dyn_arch_ftrace { - * 2) jalr: setting low-12 offset to ra, jump to ra, and set ra to - * return address (original pc + 4) - * -+ *: -+ * 0: auipc t0/ra, 0x? -+ * 4: jalr t0/ra, ?(t0/ra) -+ * -+ *: -+ * 0: nop -+ * 4: nop -+ * - * Dynamic ftrace generates probes to call sites, so we must deal with - * both auipc and jalr at the same time. - */ -@@ -49,25 +57,43 @@ struct dyn_arch_ftrace { - #define AUIPC_OFFSET_MASK (0xfffff000) - #define AUIPC_PAD (0x00001000) - #define JALR_SHIFT 20 --#define JALR_BASIC (0x000080e7) --#define AUIPC_BASIC (0x00000097) -+#define JALR_RA (0x000080e7) -+#define AUIPC_RA (0x00000097) -+#define JALR_T0 (0x000282e7) -+#define AUIPC_T0 (0x00000297) - #define NOP4 (0x00000013) - --#define make_call(caller, callee, call) \ -+#define to_jalr_t0(offset) \ -+ (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_T0) -+ -+#define to_auipc_t0(offset) \ -+ ((offset & JALR_SIGN_MASK) ? \ -+ (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_T0) : \ -+ ((offset & AUIPC_OFFSET_MASK) | AUIPC_T0)) -+ -+#define make_call_t0(caller, callee, call) \ - do { \ -- call[0] = to_auipc_insn((unsigned int)((unsigned long)callee - \ -- (unsigned long)caller)); \ -- call[1] = to_jalr_insn((unsigned int)((unsigned long)callee - \ -- (unsigned long)caller)); \ -+ unsigned int offset = \ -+ (unsigned long) callee - (unsigned long) caller; \ -+ call[0] = to_auipc_t0(offset); \ -+ call[1] = to_jalr_t0(offset); \ - } while (0) - --#define to_jalr_insn(offset) \ -- (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_BASIC) -+#define to_jalr_ra(offset) \ -+ (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_RA) - --#define to_auipc_insn(offset) \ -+#define to_auipc_ra(offset) \ - ((offset & JALR_SIGN_MASK) ? \ -- (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_BASIC) : \ -- ((offset & AUIPC_OFFSET_MASK) | AUIPC_BASIC)) -+ (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_RA) : \ -+ ((offset & AUIPC_OFFSET_MASK) | AUIPC_RA)) -+ -+#define make_call_ra(caller, callee, call) \ -+do { \ -+ unsigned int offset = \ -+ (unsigned long) callee - (unsigned long) caller; \ -+ call[0] = to_auipc_ra(offset); \ -+ call[1] = to_jalr_ra(offset); \ -+} while (0) - - /* - * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here. -diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c -index c9b97f8f165c6..3c91330ec2fb6 100644 ---- a/arch/riscv/kernel/ftrace.c -+++ b/arch/riscv/kernel/ftrace.c -@@ -42,13 +42,16 @@ static int ftrace_check_current_call(unsigned long hook_pos, - } - - static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, -- bool enable) -+ bool enable, bool ra) - { - unsigned int call[2]; - unsigned int nops[2] = {NOP4, NOP4}; - int ret = 0; - -- make_call(hook_pos, target, call); -+ if (ra) -+ make_call_ra(hook_pos, target, call); -+ else -+ make_call_t0(hook_pos, target, call); - - /* replace the auipc-jalr pair at once */ - ret = probe_kernel_write((void *)hook_pos, enable ? call : nops, -@@ -63,42 +66,13 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, - return 0; - } - --/* -- * Put 5 instructions with 16 bytes at the front of function within -- * patchable function entry nops' area. -- * -- * 0: REG_S ra, -SZREG(sp) -- * 1: auipc ra, 0x? -- * 2: jalr -?(ra) -- * 3: REG_L ra, -SZREG(sp) -- * -- * So the opcodes is: -- * 0: 0xfe113c23 (sd)/0xfe112e23 (sw) -- * 1: 0x???????? -> auipc -- * 2: 0x???????? -> jalr -- * 3: 0xff813083 (ld)/0xffc12083 (lw) -- */ --#if __riscv_xlen == 64 --#define INSN0 0xfe113c23 --#define INSN3 0xff813083 --#elif __riscv_xlen == 32 --#define INSN0 0xfe112e23 --#define INSN3 0xffc12083 --#endif -- --#define FUNC_ENTRY_SIZE 16 --#define FUNC_ENTRY_JMP 4 -- - int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - { -- unsigned int call[4] = {INSN0, 0, 0, INSN3}; -- unsigned long target = addr; -- unsigned long caller = rec->ip + FUNC_ENTRY_JMP; -+ unsigned int call[2]; - -- call[1] = to_auipc_insn((unsigned int)(target - caller)); -- call[2] = to_jalr_insn((unsigned int)(target - caller)); -+ make_call_t0(rec->ip, addr, call); - -- if (patch_text_nosync((void *)rec->ip, call, FUNC_ENTRY_SIZE)) -+ if (patch_text_nosync((void *)rec->ip, call, MCOUNT_INSN_SIZE)) - return -EPERM; - - return 0; -@@ -107,15 +81,14 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, - unsigned long addr) - { -- unsigned int nops[4] = {NOP4, NOP4, NOP4, NOP4}; -+ unsigned int nops[2] = {NOP4, NOP4}; - -- if (patch_text_nosync((void *)rec->ip, nops, FUNC_ENTRY_SIZE)) -+ if (patch_text_nosync((void *)rec->ip, nops, MCOUNT_INSN_SIZE)) - return -EPERM; - - return 0; - } - -- - /* - * This is called early on, and isn't wrapped by - * ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold -@@ -137,10 +110,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) - int ftrace_update_ftrace_func(ftrace_func_t func) - { - int ret = __ftrace_modify_call((unsigned long)&ftrace_call, -- (unsigned long)func, true); -+ (unsigned long)func, true, true); - if (!ret) { - ret = __ftrace_modify_call((unsigned long)&ftrace_regs_call, -- (unsigned long)func, true); -+ (unsigned long)func, true, true); - } - - return ret; -@@ -157,16 +130,16 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, - unsigned long addr) - { - unsigned int call[2]; -- unsigned long caller = rec->ip + FUNC_ENTRY_JMP; -+ unsigned long caller = rec->ip; - int ret; - -- make_call(caller, old_addr, call); -+ make_call_t0(caller, old_addr, call); - ret = ftrace_check_current_call(caller, call); - - if (ret) - return ret; - -- return __ftrace_modify_call(caller, addr, true); -+ return __ftrace_modify_call(caller, addr, true, false); - } - #endif - -@@ -201,12 +174,12 @@ int ftrace_enable_ftrace_graph_caller(void) - int ret; - - ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -- (unsigned long)&prepare_ftrace_return, true); -+ (unsigned long)&prepare_ftrace_return, true, true); - if (ret) - return ret; - - return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, -- (unsigned long)&prepare_ftrace_return, true); -+ (unsigned long)&prepare_ftrace_return, true, true); - } - - int ftrace_disable_ftrace_graph_caller(void) -@@ -214,12 +187,12 @@ int ftrace_disable_ftrace_graph_caller(void) - int ret; - - ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -- (unsigned long)&prepare_ftrace_return, false); -+ (unsigned long)&prepare_ftrace_return, false, true); - if (ret) - return ret; - - return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, -- (unsigned long)&prepare_ftrace_return, false); -+ (unsigned long)&prepare_ftrace_return, false, true); - } - #endif /* CONFIG_DYNAMIC_FTRACE */ - #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S -index d171eca623b6f..125de818d1bab 100644 ---- a/arch/riscv/kernel/mcount-dyn.S -+++ b/arch/riscv/kernel/mcount-dyn.S -@@ -13,8 +13,8 @@ - - .text - --#define FENTRY_RA_OFFSET 12 --#define ABI_SIZE_ON_STACK 72 -+#define FENTRY_RA_OFFSET 8 -+#define ABI_SIZE_ON_STACK 80 - #define ABI_A0 0 - #define ABI_A1 8 - #define ABI_A2 16 -@@ -23,10 +23,10 @@ - #define ABI_A5 40 - #define ABI_A6 48 - #define ABI_A7 56 --#define ABI_RA 64 -+#define ABI_T0 64 -+#define ABI_RA 72 - - .macro SAVE_ABI -- addi sp, sp, -SZREG - addi sp, sp, -ABI_SIZE_ON_STACK - - REG_S a0, ABI_A0(sp) -@@ -37,6 +37,7 @@ - REG_S a5, ABI_A5(sp) - REG_S a6, ABI_A6(sp) - REG_S a7, ABI_A7(sp) -+ REG_S t0, ABI_T0(sp) - REG_S ra, ABI_RA(sp) - .endm - -@@ -49,24 +50,18 @@ - REG_L a5, ABI_A5(sp) - REG_L a6, ABI_A6(sp) - REG_L a7, ABI_A7(sp) -+ REG_L t0, ABI_T0(sp) - REG_L ra, ABI_RA(sp) - - addi sp, sp, ABI_SIZE_ON_STACK -- addi sp, sp, SZREG - .endm - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS - .macro SAVE_ALL -- addi sp, sp, -SZREG - addi sp, sp, -PT_SIZE_ON_STACK - -- REG_S x1, PT_EPC(sp) -- addi sp, sp, PT_SIZE_ON_STACK -- REG_L x1, (sp) -- addi sp, sp, -PT_SIZE_ON_STACK -+ REG_S t0, PT_EPC(sp) - REG_S x1, PT_RA(sp) -- REG_L x1, PT_EPC(sp) -- - REG_S x2, PT_SP(sp) - REG_S x3, PT_GP(sp) - REG_S x4, PT_TP(sp) -@@ -100,15 +95,11 @@ - .endm - - .macro RESTORE_ALL -+ REG_L t0, PT_EPC(sp) - REG_L x1, PT_RA(sp) -- addi sp, sp, PT_SIZE_ON_STACK -- REG_S x1, (sp) -- addi sp, sp, -PT_SIZE_ON_STACK -- REG_L x1, PT_EPC(sp) - REG_L x2, PT_SP(sp) - REG_L x3, PT_GP(sp) - REG_L x4, PT_TP(sp) -- REG_L x5, PT_T0(sp) - REG_L x6, PT_T1(sp) - REG_L x7, PT_T2(sp) - REG_L x8, PT_S0(sp) -@@ -137,17 +128,16 @@ - REG_L x31, PT_T6(sp) - - addi sp, sp, PT_SIZE_ON_STACK -- addi sp, sp, SZREG - .endm - #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ - - ENTRY(ftrace_caller) - SAVE_ABI - -- addi a0, ra, -FENTRY_RA_OFFSET -+ addi a0, t0, -FENTRY_RA_OFFSET - la a1, function_trace_op - REG_L a2, 0(a1) -- REG_L a1, ABI_SIZE_ON_STACK(sp) -+ mv a1, ra - mv a3, sp - - ftrace_call: -@@ -155,8 +145,8 @@ ftrace_call: - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi a0, sp, ABI_SIZE_ON_STACK -- REG_L a1, ABI_RA(sp) -+ addi a0, sp, ABI_RA -+ REG_L a1, ABI_T0(sp) - addi a1, a1, -FENTRY_RA_OFFSET - #ifdef HAVE_FUNCTION_GRAPH_FP_TEST - mv a2, s0 -@@ -166,17 +156,17 @@ ftrace_graph_call: - call ftrace_stub - #endif - RESTORE_ABI -- ret -+ jr t0 - ENDPROC(ftrace_caller) - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS - ENTRY(ftrace_regs_caller) - SAVE_ALL - -- addi a0, ra, -FENTRY_RA_OFFSET -+ addi a0, t0, -FENTRY_RA_OFFSET - la a1, function_trace_op - REG_L a2, 0(a1) -- REG_L a1, PT_SIZE_ON_STACK(sp) -+ mv a1, ra - mv a3, sp - - ftrace_regs_call: -@@ -196,6 +186,6 @@ ftrace_graph_regs_call: - #endif - - RESTORE_ALL -- ret -+ jr t0 - ENDPROC(ftrace_regs_caller) - #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ --- -2.39.2 - diff --git a/queue-4.19/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch b/queue-4.19/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch deleted file mode 100644 index ea230e9ccc2..00000000000 --- a/queue-4.19/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 2bb876ceceeb443eb49400f1e7222c467e6f858f Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 12 Jan 2023 04:05:58 -0500 -Subject: riscv: ftrace: Remove wasted nops for !RISCV_ISA_C - -From: Guo Ren - -[ Upstream commit 409c8fb20c66df7150e592747412438c04aeb11f ] - -When CONFIG_RISCV_ISA_C=n, -fpatchable-function-entry=8 would generate -more nops than we expect. Because it treat nop opcode as 0x00000013 -instead of 0x0001. - -Dump of assembler code for function dw_pcie_free_msi: - 0xffffffff806fce94 <+0>: sd ra,-8(sp) - 0xffffffff806fce98 <+4>: auipc ra,0xff90f - 0xffffffff806fce9c <+8>: jalr -684(ra) # 0xffffffff8000bbec - - 0xffffffff806fcea0 <+12>: ld ra,-8(sp) - 0xffffffff806fcea4 <+16>: nop /* wasted */ - 0xffffffff806fcea8 <+20>: nop /* wasted */ - 0xffffffff806fceac <+24>: nop /* wasted */ - 0xffffffff806fceb0 <+28>: nop /* wasted */ - 0xffffffff806fceb4 <+0>: addi sp,sp,-48 - 0xffffffff806fceb8 <+4>: sd s0,32(sp) - 0xffffffff806fcebc <+8>: sd s1,24(sp) - 0xffffffff806fcec0 <+12>: sd s2,16(sp) - 0xffffffff806fcec4 <+16>: sd s3,8(sp) - 0xffffffff806fcec8 <+20>: sd ra,40(sp) - 0xffffffff806fcecc <+24>: addi s0,sp,48 - -Signed-off-by: Guo Ren -Signed-off-by: Guo Ren -Link: https://lore.kernel.org/r/20230112090603.1295340-3-guoren@kernel.org -Cc: stable@vger.kernel.org -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 7de9ce876f404..fbc3c9adca70a 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -13,7 +13,11 @@ LDFLAGS_vmlinux := - ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax - KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY -+ifeq ($(CONFIG_RISCV_ISA_C),y) - CC_FLAGS_FTRACE := -fpatchable-function-entry=8 -+else -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=4 -+endif - endif - KBUILD_AFLAGS_MODULE += -fPIC - KBUILD_CFLAGS_MODULE += -fPIC --- -2.39.2 - diff --git a/queue-4.19/riscv-using-patchable_function_entry-instead-of-mcou.patch b/queue-4.19/riscv-using-patchable_function_entry-instead-of-mcou.patch deleted file mode 100644 index 2bc6c9d193f..00000000000 --- a/queue-4.19/riscv-using-patchable_function_entry-instead-of-mcou.patch +++ /dev/null @@ -1,600 +0,0 @@ -From abf571023a017240202a094778d26e61ee6d0ce2 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 17 Dec 2020 16:01:41 +0000 -Subject: riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT - -From: Guo Ren - -[ Upstream commit afc76b8b80112189b6f11e67e19cf58301944814 ] - -This patch changes the current detour mechanism of dynamic ftrace -which has been discussed during LPC 2020 RISCV-MC [1]. - -Before the patch, we used mcount for detour: -: - addi sp,sp,-16 - sd ra,8(sp) - sd s0,0(sp) - addi s0,sp,16 - mv a5,ra - mv a0,a5 - auipc ra,0x0 -> nop - jalr -296(ra) <_mcount@plt> ->nop - ... - -After the patch, we use nop call site area for detour: -: - nop -> REG_S ra, -SZREG(sp) - nop -> auipc ra, 0x? - nop -> jalr ?(ra) - nop -> REG_L ra, -SZREG(sp) - ... - -The mcount mechanism is mixed with gcc function prologue which is -not very clear. The patchable function entry just put 16 bytes nop -before the front of the function prologue which could be filled -with a separated detour mechanism. - -[1] https://www.linuxplumbersconf.org/event/7/contributions/807/ - -Signed-off-by: Guo Ren -Signed-off-by: Palmer Dabbelt -Stable-dep-of: 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C") -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 2 + - arch/riscv/kernel/ftrace.c | 95 ++++----- - arch/riscv/kernel/mcount-dyn.S | 342 +++++++++++++++------------------ - 3 files changed, 204 insertions(+), 235 deletions(-) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index a374e255336b3..7de9ce876f404 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -12,6 +12,8 @@ OBJCOPYFLAGS := -O binary - LDFLAGS_vmlinux := - ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax -+ KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=8 - endif - KBUILD_AFLAGS_MODULE += -fPIC - KBUILD_CFLAGS_MODULE += -fPIC -diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c -index fa8530f05ed4f..c9b97f8f165c6 100644 ---- a/arch/riscv/kernel/ftrace.c -+++ b/arch/riscv/kernel/ftrace.c -@@ -63,29 +63,56 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, - return 0; - } - -+/* -+ * Put 5 instructions with 16 bytes at the front of function within -+ * patchable function entry nops' area. -+ * -+ * 0: REG_S ra, -SZREG(sp) -+ * 1: auipc ra, 0x? -+ * 2: jalr -?(ra) -+ * 3: REG_L ra, -SZREG(sp) -+ * -+ * So the opcodes is: -+ * 0: 0xfe113c23 (sd)/0xfe112e23 (sw) -+ * 1: 0x???????? -> auipc -+ * 2: 0x???????? -> jalr -+ * 3: 0xff813083 (ld)/0xffc12083 (lw) -+ */ -+#if __riscv_xlen == 64 -+#define INSN0 0xfe113c23 -+#define INSN3 0xff813083 -+#elif __riscv_xlen == 32 -+#define INSN0 0xfe112e23 -+#define INSN3 0xffc12083 -+#endif -+ -+#define FUNC_ENTRY_SIZE 16 -+#define FUNC_ENTRY_JMP 4 -+ - int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - { -- int ret = ftrace_check_current_call(rec->ip, NULL); -+ unsigned int call[4] = {INSN0, 0, 0, INSN3}; -+ unsigned long target = addr; -+ unsigned long caller = rec->ip + FUNC_ENTRY_JMP; - -- if (ret) -- return ret; -+ call[1] = to_auipc_insn((unsigned int)(target - caller)); -+ call[2] = to_jalr_insn((unsigned int)(target - caller)); - -- return __ftrace_modify_call(rec->ip, addr, true); -+ if (patch_text_nosync((void *)rec->ip, call, FUNC_ENTRY_SIZE)) -+ return -EPERM; -+ -+ return 0; - } - - int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, - unsigned long addr) - { -- unsigned int call[2]; -- int ret; -+ unsigned int nops[4] = {NOP4, NOP4, NOP4, NOP4}; - -- make_call(rec->ip, addr, call); -- ret = ftrace_check_current_call(rec->ip, call); -- -- if (ret) -- return ret; -+ if (patch_text_nosync((void *)rec->ip, nops, FUNC_ENTRY_SIZE)) -+ return -EPERM; - -- return __ftrace_modify_call(rec->ip, addr, false); -+ return 0; - } - - -@@ -130,15 +157,16 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, - unsigned long addr) - { - unsigned int call[2]; -+ unsigned long caller = rec->ip + FUNC_ENTRY_JMP; - int ret; - -- make_call(rec->ip, old_addr, call); -- ret = ftrace_check_current_call(rec->ip, call); -+ make_call(caller, old_addr, call); -+ ret = ftrace_check_current_call(caller, call); - - if (ret) - return ret; - -- return __ftrace_modify_call(rec->ip, addr, true); -+ return __ftrace_modify_call(caller, addr, true); - } - #endif - -@@ -167,53 +195,30 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, - - #ifdef CONFIG_DYNAMIC_FTRACE - extern void ftrace_graph_call(void); -+extern void ftrace_graph_regs_call(void); - int ftrace_enable_ftrace_graph_caller(void) - { -- unsigned int call[2]; -- static int init_graph = 1; - int ret; - -- make_call(&ftrace_graph_call, &ftrace_stub, call); -- -- /* -- * When enabling graph tracer for the first time, ftrace_graph_call -- * should contains a call to ftrace_stub. Once it has been disabled, -- * the 8-bytes at the position becomes NOPs. -- */ -- if (init_graph) { -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- call); -- init_graph = 0; -- } else { -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- NULL); -- } -- -+ ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ (unsigned long)&prepare_ftrace_return, true); - if (ret) - return ret; - -- return __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, - (unsigned long)&prepare_ftrace_return, true); - } - - int ftrace_disable_ftrace_graph_caller(void) - { -- unsigned int call[2]; - int ret; - -- make_call(&ftrace_graph_call, &prepare_ftrace_return, call); -- -- /* -- * This is to make sure that ftrace_enable_ftrace_graph_caller -- * did the right thing. -- */ -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- call); -- -+ ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ (unsigned long)&prepare_ftrace_return, false); - if (ret) - return ret; - -- return __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, - (unsigned long)&prepare_ftrace_return, false); - } - #endif /* CONFIG_DYNAMIC_FTRACE */ -diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S -index 35a6ed76cb8b7..d171eca623b6f 100644 ---- a/arch/riscv/kernel/mcount-dyn.S -+++ b/arch/riscv/kernel/mcount-dyn.S -@@ -13,224 +13,186 @@ - - .text - -- .macro SAVE_ABI_STATE --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi sp, sp, -48 -- sd s0, 32(sp) -- sd ra, 40(sp) -- addi s0, sp, 48 -- sd t0, 24(sp) -- sd t1, 16(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- sd t2, 8(sp) --#endif --#else -- addi sp, sp, -16 -- sd s0, 0(sp) -- sd ra, 8(sp) -- addi s0, sp, 16 --#endif -+#define FENTRY_RA_OFFSET 12 -+#define ABI_SIZE_ON_STACK 72 -+#define ABI_A0 0 -+#define ABI_A1 8 -+#define ABI_A2 16 -+#define ABI_A3 24 -+#define ABI_A4 32 -+#define ABI_A5 40 -+#define ABI_A6 48 -+#define ABI_A7 56 -+#define ABI_RA 64 -+ -+ .macro SAVE_ABI -+ addi sp, sp, -SZREG -+ addi sp, sp, -ABI_SIZE_ON_STACK -+ -+ REG_S a0, ABI_A0(sp) -+ REG_S a1, ABI_A1(sp) -+ REG_S a2, ABI_A2(sp) -+ REG_S a3, ABI_A3(sp) -+ REG_S a4, ABI_A4(sp) -+ REG_S a5, ABI_A5(sp) -+ REG_S a6, ABI_A6(sp) -+ REG_S a7, ABI_A7(sp) -+ REG_S ra, ABI_RA(sp) - .endm - -- .macro RESTORE_ABI_STATE --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- ld s0, 32(sp) -- ld ra, 40(sp) -- addi sp, sp, 48 --#else -- ld ra, 8(sp) -- ld s0, 0(sp) -- addi sp, sp, 16 --#endif -+ .macro RESTORE_ABI -+ REG_L a0, ABI_A0(sp) -+ REG_L a1, ABI_A1(sp) -+ REG_L a2, ABI_A2(sp) -+ REG_L a3, ABI_A3(sp) -+ REG_L a4, ABI_A4(sp) -+ REG_L a5, ABI_A5(sp) -+ REG_L a6, ABI_A6(sp) -+ REG_L a7, ABI_A7(sp) -+ REG_L ra, ABI_RA(sp) -+ -+ addi sp, sp, ABI_SIZE_ON_STACK -+ addi sp, sp, SZREG - .endm - -- .macro RESTORE_GRAPH_ARGS -- ld a0, 24(sp) -- ld a1, 16(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld a2, 8(sp) --#endif -+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS -+ .macro SAVE_ALL -+ addi sp, sp, -SZREG -+ addi sp, sp, -PT_SIZE_ON_STACK -+ -+ REG_S x1, PT_EPC(sp) -+ addi sp, sp, PT_SIZE_ON_STACK -+ REG_L x1, (sp) -+ addi sp, sp, -PT_SIZE_ON_STACK -+ REG_S x1, PT_RA(sp) -+ REG_L x1, PT_EPC(sp) -+ -+ REG_S x2, PT_SP(sp) -+ REG_S x3, PT_GP(sp) -+ REG_S x4, PT_TP(sp) -+ REG_S x5, PT_T0(sp) -+ REG_S x6, PT_T1(sp) -+ REG_S x7, PT_T2(sp) -+ REG_S x8, PT_S0(sp) -+ REG_S x9, PT_S1(sp) -+ REG_S x10, PT_A0(sp) -+ REG_S x11, PT_A1(sp) -+ REG_S x12, PT_A2(sp) -+ REG_S x13, PT_A3(sp) -+ REG_S x14, PT_A4(sp) -+ REG_S x15, PT_A5(sp) -+ REG_S x16, PT_A6(sp) -+ REG_S x17, PT_A7(sp) -+ REG_S x18, PT_S2(sp) -+ REG_S x19, PT_S3(sp) -+ REG_S x20, PT_S4(sp) -+ REG_S x21, PT_S5(sp) -+ REG_S x22, PT_S6(sp) -+ REG_S x23, PT_S7(sp) -+ REG_S x24, PT_S8(sp) -+ REG_S x25, PT_S9(sp) -+ REG_S x26, PT_S10(sp) -+ REG_S x27, PT_S11(sp) -+ REG_S x28, PT_T3(sp) -+ REG_S x29, PT_T4(sp) -+ REG_S x30, PT_T5(sp) -+ REG_S x31, PT_T6(sp) - .endm - --ENTRY(ftrace_graph_caller) -- addi sp, sp, -16 -- sd s0, 0(sp) -- sd ra, 8(sp) -- addi s0, sp, 16 --ftrace_graph_call: -- .global ftrace_graph_call -- /* -- * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the -- * call below. Check ftrace_modify_all_code for details. -- */ -- call ftrace_stub -- ld ra, 8(sp) -- ld s0, 0(sp) -- addi sp, sp, 16 -- ret --ENDPROC(ftrace_graph_caller) -+ .macro RESTORE_ALL -+ REG_L x1, PT_RA(sp) -+ addi sp, sp, PT_SIZE_ON_STACK -+ REG_S x1, (sp) -+ addi sp, sp, -PT_SIZE_ON_STACK -+ REG_L x1, PT_EPC(sp) -+ REG_L x2, PT_SP(sp) -+ REG_L x3, PT_GP(sp) -+ REG_L x4, PT_TP(sp) -+ REG_L x5, PT_T0(sp) -+ REG_L x6, PT_T1(sp) -+ REG_L x7, PT_T2(sp) -+ REG_L x8, PT_S0(sp) -+ REG_L x9, PT_S1(sp) -+ REG_L x10, PT_A0(sp) -+ REG_L x11, PT_A1(sp) -+ REG_L x12, PT_A2(sp) -+ REG_L x13, PT_A3(sp) -+ REG_L x14, PT_A4(sp) -+ REG_L x15, PT_A5(sp) -+ REG_L x16, PT_A6(sp) -+ REG_L x17, PT_A7(sp) -+ REG_L x18, PT_S2(sp) -+ REG_L x19, PT_S3(sp) -+ REG_L x20, PT_S4(sp) -+ REG_L x21, PT_S5(sp) -+ REG_L x22, PT_S6(sp) -+ REG_L x23, PT_S7(sp) -+ REG_L x24, PT_S8(sp) -+ REG_L x25, PT_S9(sp) -+ REG_L x26, PT_S10(sp) -+ REG_L x27, PT_S11(sp) -+ REG_L x28, PT_T3(sp) -+ REG_L x29, PT_T4(sp) -+ REG_L x30, PT_T5(sp) -+ REG_L x31, PT_T6(sp) -+ -+ addi sp, sp, PT_SIZE_ON_STACK -+ addi sp, sp, SZREG -+ .endm -+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ - - ENTRY(ftrace_caller) -- /* -- * a0: the address in the caller when calling ftrace_caller -- * a1: the caller's return address -- * a2: the address of global variable function_trace_op -- */ -- ld a1, -8(s0) -- addi a0, ra, -MCOUNT_INSN_SIZE -- la t5, function_trace_op -- ld a2, 0(t5) -+ SAVE_ABI - --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- /* -- * the graph tracer (specifically, prepare_ftrace_return) needs these -- * arguments but for now the function tracer occupies the regs, so we -- * save them in temporary regs to recover later. -- */ -- addi t0, s0, -8 -- mv t1, a0 --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld t2, -16(s0) --#endif --#endif -+ addi a0, ra, -FENTRY_RA_OFFSET -+ la a1, function_trace_op -+ REG_L a2, 0(a1) -+ REG_L a1, ABI_SIZE_ON_STACK(sp) -+ mv a3, sp - -- SAVE_ABI_STATE - ftrace_call: - .global ftrace_call -- /* -- * For the dynamic ftrace to work, here we should reserve at least -- * 8 bytes for a functional auipc-jalr pair. The following call -- * serves this purpose. -- * -- * Calling ftrace_update_ftrace_func would overwrite the nops below. -- * Check ftrace_modify_all_code for details. -- */ - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- RESTORE_GRAPH_ARGS -- call ftrace_graph_caller -+ addi a0, sp, ABI_SIZE_ON_STACK -+ REG_L a1, ABI_RA(sp) -+ addi a1, a1, -FENTRY_RA_OFFSET -+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -+ mv a2, s0 - #endif -- -- RESTORE_ABI_STATE -+ftrace_graph_call: -+ .global ftrace_graph_call -+ call ftrace_stub -+#endif -+ RESTORE_ABI - ret - ENDPROC(ftrace_caller) - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS -- .macro SAVE_ALL -- addi sp, sp, -(PT_SIZE_ON_STACK+16) -- sd s0, (PT_SIZE_ON_STACK)(sp) -- sd ra, (PT_SIZE_ON_STACK+8)(sp) -- addi s0, sp, (PT_SIZE_ON_STACK+16) -- -- sd x1, PT_RA(sp) -- sd x2, PT_SP(sp) -- sd x3, PT_GP(sp) -- sd x4, PT_TP(sp) -- sd x5, PT_T0(sp) -- sd x6, PT_T1(sp) -- sd x7, PT_T2(sp) -- sd x8, PT_S0(sp) -- sd x9, PT_S1(sp) -- sd x10, PT_A0(sp) -- sd x11, PT_A1(sp) -- sd x12, PT_A2(sp) -- sd x13, PT_A3(sp) -- sd x14, PT_A4(sp) -- sd x15, PT_A5(sp) -- sd x16, PT_A6(sp) -- sd x17, PT_A7(sp) -- sd x18, PT_S2(sp) -- sd x19, PT_S3(sp) -- sd x20, PT_S4(sp) -- sd x21, PT_S5(sp) -- sd x22, PT_S6(sp) -- sd x23, PT_S7(sp) -- sd x24, PT_S8(sp) -- sd x25, PT_S9(sp) -- sd x26, PT_S10(sp) -- sd x27, PT_S11(sp) -- sd x28, PT_T3(sp) -- sd x29, PT_T4(sp) -- sd x30, PT_T5(sp) -- sd x31, PT_T6(sp) -- .endm -- -- .macro RESTORE_ALL -- ld x1, PT_RA(sp) -- ld x2, PT_SP(sp) -- ld x3, PT_GP(sp) -- ld x4, PT_TP(sp) -- ld x5, PT_T0(sp) -- ld x6, PT_T1(sp) -- ld x7, PT_T2(sp) -- ld x8, PT_S0(sp) -- ld x9, PT_S1(sp) -- ld x10, PT_A0(sp) -- ld x11, PT_A1(sp) -- ld x12, PT_A2(sp) -- ld x13, PT_A3(sp) -- ld x14, PT_A4(sp) -- ld x15, PT_A5(sp) -- ld x16, PT_A6(sp) -- ld x17, PT_A7(sp) -- ld x18, PT_S2(sp) -- ld x19, PT_S3(sp) -- ld x20, PT_S4(sp) -- ld x21, PT_S5(sp) -- ld x22, PT_S6(sp) -- ld x23, PT_S7(sp) -- ld x24, PT_S8(sp) -- ld x25, PT_S9(sp) -- ld x26, PT_S10(sp) -- ld x27, PT_S11(sp) -- ld x28, PT_T3(sp) -- ld x29, PT_T4(sp) -- ld x30, PT_T5(sp) -- ld x31, PT_T6(sp) -- -- ld s0, (PT_SIZE_ON_STACK)(sp) -- ld ra, (PT_SIZE_ON_STACK+8)(sp) -- addi sp, sp, (PT_SIZE_ON_STACK+16) -- .endm -- -- .macro RESTORE_GRAPH_REG_ARGS -- ld a0, PT_T0(sp) -- ld a1, PT_T1(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld a2, PT_T2(sp) --#endif -- .endm -- --/* -- * Most of the contents are the same as ftrace_caller. -- */ - ENTRY(ftrace_regs_caller) -- /* -- * a3: the address of all registers in the stack -- */ -- ld a1, -8(s0) -- addi a0, ra, -MCOUNT_INSN_SIZE -- la t5, function_trace_op -- ld a2, 0(t5) -- addi a3, sp, -(PT_SIZE_ON_STACK+16) -- --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi t0, s0, -8 -- mv t1, a0 --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld t2, -16(s0) --#endif --#endif - SAVE_ALL - -+ addi a0, ra, -FENTRY_RA_OFFSET -+ la a1, function_trace_op -+ REG_L a2, 0(a1) -+ REG_L a1, PT_SIZE_ON_STACK(sp) -+ mv a3, sp -+ - ftrace_regs_call: - .global ftrace_regs_call - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- RESTORE_GRAPH_REG_ARGS -- call ftrace_graph_caller -+ addi a0, sp, PT_RA -+ REG_L a1, PT_EPC(sp) -+ addi a1, a1, -FENTRY_RA_OFFSET -+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -+ mv a2, s0 -+#endif -+ftrace_graph_regs_call: -+ .global ftrace_graph_regs_call -+ call ftrace_stub - #endif - - RESTORE_ALL --- -2.39.2 - diff --git a/queue-4.19/series b/queue-4.19/series index 98fea79eed5..30b42cfac2e 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -11,11 +11,8 @@ udf-reduce-leakage-of-blocks-related-to-named-stream.patch udf-remove-pointless-union-in-udf_inode_info.patch udf-preserve-link-count-of-system-files.patch udf-detect-system-inodes-linked-into-directory-hiera.patch -riscv-using-patchable_function_entry-instead-of-mcou.patch arm-dts-exynos-fix-language-typo-and-indentation.patch -riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch arm-dts-exynos-override-thermal-by-label-in-exynos42.patch -riscv-ftrace-reduce-the-detour-code-size-to-half.patch arm-dts-exynos-correct-tmu-phandle-in-exynos4210.patch arm-dts-exynos-add-all-cpus-in-cooling-maps.patch arm-dts-exynos-move-pmu-and-timer-nodes-out-of-soc.patch diff --git a/queue-5.10/risc-v-don-t-check-text_mutex-during-stop_machine.patch b/queue-5.10/risc-v-don-t-check-text_mutex-during-stop_machine.patch index 2ce5412171f..668f0866ee2 100644 --- a/queue-5.10/risc-v-don-t-check-text_mutex-during-stop_machine.patch +++ b/queue-5.10/risc-v-don-t-check-text_mutex-during-stop_machine.patch @@ -25,17 +25,15 @@ Link: https://lore.kernel.org/r/20230303143754.4005217-1-conor.dooley@microchip. Signed-off-by: Palmer Dabbelt Signed-off-by: Sasha Levin --- - arch/riscv/include/asm/ftrace.h | 2 +- - arch/riscv/include/asm/patch.h | 2 ++ - arch/riscv/kernel/ftrace.c | 14 ++++++++++++-- - arch/riscv/kernel/patch.c | 28 +++++++++++++++++++++++++--- + arch/riscv/include/asm/ftrace.h | 2 +- + arch/riscv/include/asm/patch.h | 2 ++ + arch/riscv/kernel/ftrace.c | 14 ++++++++++++-- + arch/riscv/kernel/patch.c | 28 +++++++++++++++++++++++++--- 4 files changed, 40 insertions(+), 6 deletions(-) -diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h -index 9e73922e1e2e5..d47d87c2d7e3d 100644 --- a/arch/riscv/include/asm/ftrace.h +++ b/arch/riscv/include/asm/ftrace.h -@@ -109,6 +109,6 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); +@@ -83,6 +83,6 @@ int ftrace_init_nop(struct module *mod, #define ftrace_init_nop ftrace_init_nop #endif @@ -43,8 +41,6 @@ index 9e73922e1e2e5..d47d87c2d7e3d 100644 +#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* _ASM_RISCV_FTRACE_H */ -diff --git a/arch/riscv/include/asm/patch.h b/arch/riscv/include/asm/patch.h -index 9a7d7346001ee..98d9de07cba17 100644 --- a/arch/riscv/include/asm/patch.h +++ b/arch/riscv/include/asm/patch.h @@ -9,4 +9,6 @@ @@ -54,8 +50,6 @@ index 9a7d7346001ee..98d9de07cba17 100644 +extern int riscv_patch_in_stop_machine; + #endif /* _ASM_RISCV_PATCH_H */ -diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c -index 47b43d8ee9a6c..1bf92cfa6764e 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -15,11 +15,21 @@ @@ -80,7 +74,7 @@ index 47b43d8ee9a6c..1bf92cfa6764e 100644 mutex_unlock(&text_mutex); return 0; } -@@ -109,9 +119,9 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) +@@ -109,9 +119,9 @@ int ftrace_init_nop(struct module *mod, { int out; @@ -92,8 +86,6 @@ index 47b43d8ee9a6c..1bf92cfa6764e 100644 return out; } -diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c -index 1612e11f7bf6d..c3fced410e742 100644 --- a/arch/riscv/kernel/patch.c +++ b/arch/riscv/kernel/patch.c @@ -11,6 +11,7 @@ @@ -113,7 +105,7 @@ index 1612e11f7bf6d..c3fced410e742 100644 #ifdef CONFIG_MMU static void *patch_map(void *addr, int fixmap) { -@@ -55,8 +58,15 @@ static int patch_insn_write(void *addr, const void *insn, size_t len) +@@ -55,8 +58,15 @@ static int patch_insn_write(void *addr, * Before reaching here, it was expected to lock the text_mutex * already, so we don't need to give another lock here and could * ensure that it was safe between each cores. @@ -158,6 +150,3 @@ index 1612e11f7bf6d..c3fced410e742 100644 + return ret; } NOKPROBE_SYMBOL(patch_text); --- -2.39.2 - diff --git a/queue-5.10/riscv-ftrace-reduce-the-detour-code-size-to-half.patch b/queue-5.10/riscv-ftrace-reduce-the-detour-code-size-to-half.patch deleted file mode 100644 index a334c946b16..00000000000 --- a/queue-5.10/riscv-ftrace-reduce-the-detour-code-size-to-half.patch +++ /dev/null @@ -1,447 +0,0 @@ -From 584f80a2b4caa34c1809e9356be1b8300aa2923e Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 12 Jan 2023 04:05:59 -0500 -Subject: riscv: ftrace: Reduce the detour code size to half - -From: Guo Ren - -[ Upstream commit 6724a76cff85ee271bbbff42ac527e4643b2ec52 ] - -Use a temporary register to reduce the size of detour code from 16 bytes to -8 bytes. The previous implementation is from 'commit afc76b8b8011 ("riscv: -Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT")'. - -Before the patch: -: - 0: REG_S ra, -SZREG(sp) - 4: auipc ra, ? - 8: jalr ?(ra) -12: REG_L ra, -SZREG(sp) - (func_boddy) - -After the patch: -: - 0: auipc t0, ? - 4: jalr t0, ?(t0) - (func_boddy) - -This patch not just reduces the size of detour code, but also fixes an -important issue: - -An Ftrace callback registered with FTRACE_OPS_FL_IPMODIFY flag can -actually change the instruction pointer, e.g. to "replace" the given -kernel function with a new one, which is needed for livepatching, etc. - -In this case, the trampoline (ftrace_regs_caller) would not return to - but would rather jump to the new function. So, "REG_L -ra, -SZREG(sp)" would not run and the original return address would not -be restored. The kernel is likely to hang or crash as a result. - -This can be easily demonstrated if one tries to "replace", say, -cmdline_proc_show() with a new function with the same signature using -instruction_pointer_set(&fregs->regs, new_func_addr) in the Ftrace -callback. - -Link: https://lore.kernel.org/linux-riscv/20221122075440.1165172-1-suagrfillet@gmail.com/ -Link: https://lore.kernel.org/linux-riscv/d7d5730b-ebef-68e5-5046-e763e1ee6164@yadro.com/ -Co-developed-by: Song Shuai -Signed-off-by: Song Shuai -Signed-off-by: Guo Ren -Signed-off-by: Guo Ren -Cc: Evgenii Shatokhin -Reviewed-by: Evgenii Shatokhin -Link: https://lore.kernel.org/r/20230112090603.1295340-4-guoren@kernel.org -Cc: stable@vger.kernel.org -Fixes: 10626c32e382 ("riscv/ftrace: Add basic support") -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 4 +- - arch/riscv/include/asm/ftrace.h | 50 +++++++++++++++++++------ - arch/riscv/kernel/ftrace.c | 65 ++++++++++----------------------- - arch/riscv/kernel/mcount-dyn.S | 42 ++++++++------------- - 4 files changed, 75 insertions(+), 86 deletions(-) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 3e3467dbbf73f..8ceb667e4f38c 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -14,9 +14,9 @@ ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax - KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY - ifeq ($(CONFIG_RISCV_ISA_C),y) -- CC_FLAGS_FTRACE := -fpatchable-function-entry=8 --else - CC_FLAGS_FTRACE := -fpatchable-function-entry=4 -+else -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=2 - endif - endif - -diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h -index 04dad33800418..9e73922e1e2e5 100644 ---- a/arch/riscv/include/asm/ftrace.h -+++ b/arch/riscv/include/asm/ftrace.h -@@ -42,6 +42,14 @@ struct dyn_arch_ftrace { - * 2) jalr: setting low-12 offset to ra, jump to ra, and set ra to - * return address (original pc + 4) - * -+ *: -+ * 0: auipc t0/ra, 0x? -+ * 4: jalr t0/ra, ?(t0/ra) -+ * -+ *: -+ * 0: nop -+ * 4: nop -+ * - * Dynamic ftrace generates probes to call sites, so we must deal with - * both auipc and jalr at the same time. - */ -@@ -52,25 +60,43 @@ struct dyn_arch_ftrace { - #define AUIPC_OFFSET_MASK (0xfffff000) - #define AUIPC_PAD (0x00001000) - #define JALR_SHIFT 20 --#define JALR_BASIC (0x000080e7) --#define AUIPC_BASIC (0x00000097) -+#define JALR_RA (0x000080e7) -+#define AUIPC_RA (0x00000097) -+#define JALR_T0 (0x000282e7) -+#define AUIPC_T0 (0x00000297) - #define NOP4 (0x00000013) - --#define make_call(caller, callee, call) \ -+#define to_jalr_t0(offset) \ -+ (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_T0) -+ -+#define to_auipc_t0(offset) \ -+ ((offset & JALR_SIGN_MASK) ? \ -+ (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_T0) : \ -+ ((offset & AUIPC_OFFSET_MASK) | AUIPC_T0)) -+ -+#define make_call_t0(caller, callee, call) \ - do { \ -- call[0] = to_auipc_insn((unsigned int)((unsigned long)callee - \ -- (unsigned long)caller)); \ -- call[1] = to_jalr_insn((unsigned int)((unsigned long)callee - \ -- (unsigned long)caller)); \ -+ unsigned int offset = \ -+ (unsigned long) callee - (unsigned long) caller; \ -+ call[0] = to_auipc_t0(offset); \ -+ call[1] = to_jalr_t0(offset); \ - } while (0) - --#define to_jalr_insn(offset) \ -- (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_BASIC) -+#define to_jalr_ra(offset) \ -+ (((offset & JALR_OFFSET_MASK) << JALR_SHIFT) | JALR_RA) - --#define to_auipc_insn(offset) \ -+#define to_auipc_ra(offset) \ - ((offset & JALR_SIGN_MASK) ? \ -- (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_BASIC) : \ -- ((offset & AUIPC_OFFSET_MASK) | AUIPC_BASIC)) -+ (((offset & AUIPC_OFFSET_MASK) + AUIPC_PAD) | AUIPC_RA) : \ -+ ((offset & AUIPC_OFFSET_MASK) | AUIPC_RA)) -+ -+#define make_call_ra(caller, callee, call) \ -+do { \ -+ unsigned int offset = \ -+ (unsigned long) callee - (unsigned long) caller; \ -+ call[0] = to_auipc_ra(offset); \ -+ call[1] = to_jalr_ra(offset); \ -+} while (0) - - /* - * Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here. -diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c -index 7f1e5203de886..47b43d8ee9a6c 100644 ---- a/arch/riscv/kernel/ftrace.c -+++ b/arch/riscv/kernel/ftrace.c -@@ -57,12 +57,15 @@ static int ftrace_check_current_call(unsigned long hook_pos, - } - - static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, -- bool enable) -+ bool enable, bool ra) - { - unsigned int call[2]; - unsigned int nops[2] = {NOP4, NOP4}; - -- make_call(hook_pos, target, call); -+ if (ra) -+ make_call_ra(hook_pos, target, call); -+ else -+ make_call_t0(hook_pos, target, call); - - /* Replace the auipc-jalr pair at once. Return -EPERM on write error. */ - if (patch_text_nosync -@@ -72,42 +75,13 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, - return 0; - } - --/* -- * Put 5 instructions with 16 bytes at the front of function within -- * patchable function entry nops' area. -- * -- * 0: REG_S ra, -SZREG(sp) -- * 1: auipc ra, 0x? -- * 2: jalr -?(ra) -- * 3: REG_L ra, -SZREG(sp) -- * -- * So the opcodes is: -- * 0: 0xfe113c23 (sd)/0xfe112e23 (sw) -- * 1: 0x???????? -> auipc -- * 2: 0x???????? -> jalr -- * 3: 0xff813083 (ld)/0xffc12083 (lw) -- */ --#if __riscv_xlen == 64 --#define INSN0 0xfe113c23 --#define INSN3 0xff813083 --#elif __riscv_xlen == 32 --#define INSN0 0xfe112e23 --#define INSN3 0xffc12083 --#endif -- --#define FUNC_ENTRY_SIZE 16 --#define FUNC_ENTRY_JMP 4 -- - int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - { -- unsigned int call[4] = {INSN0, 0, 0, INSN3}; -- unsigned long target = addr; -- unsigned long caller = rec->ip + FUNC_ENTRY_JMP; -+ unsigned int call[2]; - -- call[1] = to_auipc_insn((unsigned int)(target - caller)); -- call[2] = to_jalr_insn((unsigned int)(target - caller)); -+ make_call_t0(rec->ip, addr, call); - -- if (patch_text_nosync((void *)rec->ip, call, FUNC_ENTRY_SIZE)) -+ if (patch_text_nosync((void *)rec->ip, call, MCOUNT_INSN_SIZE)) - return -EPERM; - - return 0; -@@ -116,15 +90,14 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, - unsigned long addr) - { -- unsigned int nops[4] = {NOP4, NOP4, NOP4, NOP4}; -+ unsigned int nops[2] = {NOP4, NOP4}; - -- if (patch_text_nosync((void *)rec->ip, nops, FUNC_ENTRY_SIZE)) -+ if (patch_text_nosync((void *)rec->ip, nops, MCOUNT_INSN_SIZE)) - return -EPERM; - - return 0; - } - -- - /* - * This is called early on, and isn't wrapped by - * ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold -@@ -146,10 +119,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec) - int ftrace_update_ftrace_func(ftrace_func_t func) - { - int ret = __ftrace_modify_call((unsigned long)&ftrace_call, -- (unsigned long)func, true); -+ (unsigned long)func, true, true); - if (!ret) { - ret = __ftrace_modify_call((unsigned long)&ftrace_regs_call, -- (unsigned long)func, true); -+ (unsigned long)func, true, true); - } - - return ret; -@@ -166,16 +139,16 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, - unsigned long addr) - { - unsigned int call[2]; -- unsigned long caller = rec->ip + FUNC_ENTRY_JMP; -+ unsigned long caller = rec->ip; - int ret; - -- make_call(caller, old_addr, call); -+ make_call_t0(caller, old_addr, call); - ret = ftrace_check_current_call(caller, call); - - if (ret) - return ret; - -- return __ftrace_modify_call(caller, addr, true); -+ return __ftrace_modify_call(caller, addr, true, false); - } - #endif - -@@ -210,12 +183,12 @@ int ftrace_enable_ftrace_graph_caller(void) - int ret; - - ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -- (unsigned long)&prepare_ftrace_return, true); -+ (unsigned long)&prepare_ftrace_return, true, true); - if (ret) - return ret; - - return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, -- (unsigned long)&prepare_ftrace_return, true); -+ (unsigned long)&prepare_ftrace_return, true, true); - } - - int ftrace_disable_ftrace_graph_caller(void) -@@ -223,12 +196,12 @@ int ftrace_disable_ftrace_graph_caller(void) - int ret; - - ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -- (unsigned long)&prepare_ftrace_return, false); -+ (unsigned long)&prepare_ftrace_return, false, true); - if (ret) - return ret; - - return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, -- (unsigned long)&prepare_ftrace_return, false); -+ (unsigned long)&prepare_ftrace_return, false, true); - } - #endif /* CONFIG_DYNAMIC_FTRACE */ - #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S -index d171eca623b6f..125de818d1bab 100644 ---- a/arch/riscv/kernel/mcount-dyn.S -+++ b/arch/riscv/kernel/mcount-dyn.S -@@ -13,8 +13,8 @@ - - .text - --#define FENTRY_RA_OFFSET 12 --#define ABI_SIZE_ON_STACK 72 -+#define FENTRY_RA_OFFSET 8 -+#define ABI_SIZE_ON_STACK 80 - #define ABI_A0 0 - #define ABI_A1 8 - #define ABI_A2 16 -@@ -23,10 +23,10 @@ - #define ABI_A5 40 - #define ABI_A6 48 - #define ABI_A7 56 --#define ABI_RA 64 -+#define ABI_T0 64 -+#define ABI_RA 72 - - .macro SAVE_ABI -- addi sp, sp, -SZREG - addi sp, sp, -ABI_SIZE_ON_STACK - - REG_S a0, ABI_A0(sp) -@@ -37,6 +37,7 @@ - REG_S a5, ABI_A5(sp) - REG_S a6, ABI_A6(sp) - REG_S a7, ABI_A7(sp) -+ REG_S t0, ABI_T0(sp) - REG_S ra, ABI_RA(sp) - .endm - -@@ -49,24 +50,18 @@ - REG_L a5, ABI_A5(sp) - REG_L a6, ABI_A6(sp) - REG_L a7, ABI_A7(sp) -+ REG_L t0, ABI_T0(sp) - REG_L ra, ABI_RA(sp) - - addi sp, sp, ABI_SIZE_ON_STACK -- addi sp, sp, SZREG - .endm - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS - .macro SAVE_ALL -- addi sp, sp, -SZREG - addi sp, sp, -PT_SIZE_ON_STACK - -- REG_S x1, PT_EPC(sp) -- addi sp, sp, PT_SIZE_ON_STACK -- REG_L x1, (sp) -- addi sp, sp, -PT_SIZE_ON_STACK -+ REG_S t0, PT_EPC(sp) - REG_S x1, PT_RA(sp) -- REG_L x1, PT_EPC(sp) -- - REG_S x2, PT_SP(sp) - REG_S x3, PT_GP(sp) - REG_S x4, PT_TP(sp) -@@ -100,15 +95,11 @@ - .endm - - .macro RESTORE_ALL -+ REG_L t0, PT_EPC(sp) - REG_L x1, PT_RA(sp) -- addi sp, sp, PT_SIZE_ON_STACK -- REG_S x1, (sp) -- addi sp, sp, -PT_SIZE_ON_STACK -- REG_L x1, PT_EPC(sp) - REG_L x2, PT_SP(sp) - REG_L x3, PT_GP(sp) - REG_L x4, PT_TP(sp) -- REG_L x5, PT_T0(sp) - REG_L x6, PT_T1(sp) - REG_L x7, PT_T2(sp) - REG_L x8, PT_S0(sp) -@@ -137,17 +128,16 @@ - REG_L x31, PT_T6(sp) - - addi sp, sp, PT_SIZE_ON_STACK -- addi sp, sp, SZREG - .endm - #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ - - ENTRY(ftrace_caller) - SAVE_ABI - -- addi a0, ra, -FENTRY_RA_OFFSET -+ addi a0, t0, -FENTRY_RA_OFFSET - la a1, function_trace_op - REG_L a2, 0(a1) -- REG_L a1, ABI_SIZE_ON_STACK(sp) -+ mv a1, ra - mv a3, sp - - ftrace_call: -@@ -155,8 +145,8 @@ ftrace_call: - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi a0, sp, ABI_SIZE_ON_STACK -- REG_L a1, ABI_RA(sp) -+ addi a0, sp, ABI_RA -+ REG_L a1, ABI_T0(sp) - addi a1, a1, -FENTRY_RA_OFFSET - #ifdef HAVE_FUNCTION_GRAPH_FP_TEST - mv a2, s0 -@@ -166,17 +156,17 @@ ftrace_graph_call: - call ftrace_stub - #endif - RESTORE_ABI -- ret -+ jr t0 - ENDPROC(ftrace_caller) - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS - ENTRY(ftrace_regs_caller) - SAVE_ALL - -- addi a0, ra, -FENTRY_RA_OFFSET -+ addi a0, t0, -FENTRY_RA_OFFSET - la a1, function_trace_op - REG_L a2, 0(a1) -- REG_L a1, PT_SIZE_ON_STACK(sp) -+ mv a1, ra - mv a3, sp - - ftrace_regs_call: -@@ -196,6 +186,6 @@ ftrace_graph_regs_call: - #endif - - RESTORE_ALL -- ret -+ jr t0 - ENDPROC(ftrace_regs_caller) - #endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ --- -2.39.2 - diff --git a/queue-5.10/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch b/queue-5.10/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch deleted file mode 100644 index 44201fe0cf6..00000000000 --- a/queue-5.10/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 008af635bed0d4f0d83564b2b3986ed14472119b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 12 Jan 2023 04:05:58 -0500 -Subject: riscv: ftrace: Remove wasted nops for !RISCV_ISA_C - -From: Guo Ren - -[ Upstream commit 409c8fb20c66df7150e592747412438c04aeb11f ] - -When CONFIG_RISCV_ISA_C=n, -fpatchable-function-entry=8 would generate -more nops than we expect. Because it treat nop opcode as 0x00000013 -instead of 0x0001. - -Dump of assembler code for function dw_pcie_free_msi: - 0xffffffff806fce94 <+0>: sd ra,-8(sp) - 0xffffffff806fce98 <+4>: auipc ra,0xff90f - 0xffffffff806fce9c <+8>: jalr -684(ra) # 0xffffffff8000bbec - - 0xffffffff806fcea0 <+12>: ld ra,-8(sp) - 0xffffffff806fcea4 <+16>: nop /* wasted */ - 0xffffffff806fcea8 <+20>: nop /* wasted */ - 0xffffffff806fceac <+24>: nop /* wasted */ - 0xffffffff806fceb0 <+28>: nop /* wasted */ - 0xffffffff806fceb4 <+0>: addi sp,sp,-48 - 0xffffffff806fceb8 <+4>: sd s0,32(sp) - 0xffffffff806fcebc <+8>: sd s1,24(sp) - 0xffffffff806fcec0 <+12>: sd s2,16(sp) - 0xffffffff806fcec4 <+16>: sd s3,8(sp) - 0xffffffff806fcec8 <+20>: sd ra,40(sp) - 0xffffffff806fcecc <+24>: addi s0,sp,48 - -Signed-off-by: Guo Ren -Signed-off-by: Guo Ren -Link: https://lore.kernel.org/r/20230112090603.1295340-3-guoren@kernel.org -Cc: stable@vger.kernel.org -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 6c1ef42d5a0df..3e3467dbbf73f 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -13,7 +13,11 @@ LDFLAGS_vmlinux := - ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax - KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY -+ifeq ($(CONFIG_RISCV_ISA_C),y) - CC_FLAGS_FTRACE := -fpatchable-function-entry=8 -+else -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=4 -+endif - endif - - ifeq ($(CONFIG_CMODEL_MEDLOW),y) --- -2.39.2 - diff --git a/queue-5.10/riscv-select-have_dynamic_ftrace-when-fpatchable-function-entry-is-available.patch b/queue-5.10/riscv-select-have_dynamic_ftrace-when-fpatchable-function-entry-is-available.patch deleted file mode 100644 index fcbfd4a698a..00000000000 --- a/queue-5.10/riscv-select-have_dynamic_ftrace-when-fpatchable-function-entry-is-available.patch +++ /dev/null @@ -1,39 +0,0 @@ -From adebc8817b5c975d598ac379bbdf67a7a5186ade Mon Sep 17 00:00:00 2001 -From: Nathan Chancellor -Date: Thu, 25 Mar 2021 15:38:07 -0700 -Subject: riscv: Select HAVE_DYNAMIC_FTRACE when -fpatchable-function-entry is available - -From: Nathan Chancellor - -commit adebc8817b5c975d598ac379bbdf67a7a5186ade upstream. - -clang prior to 13.0.0 does not support -fpatchable-function-entry for -RISC-V. - -clang: error: unsupported option '-fpatchable-function-entry=8' for target 'riscv64-unknown-linux-gnu' - -To avoid this error, only select HAVE_DYNAMIC_FTRACE when this option is -not available. - -Fixes: afc76b8b8011 ("riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT") -Link: https://github.com/ClangBuiltLinux/linux/issues/1268 -Reported-by: kernel test robot -Signed-off-by: Nathan Chancellor -Reviewed-by: Fangrui Song -Signed-off-by: Palmer Dabbelt -Signed-off-by: Greg Kroah-Hartman ---- - arch/riscv/Kconfig | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -224,7 +224,7 @@ config ARCH_RV64I - bool "RV64I" - select 64BIT - select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && GCC_VERSION >= 50000 -- select HAVE_DYNAMIC_FTRACE if MMU -+ select HAVE_DYNAMIC_FTRACE if MMU && $(cc-option,-fpatchable-function-entry=8) - select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE - select HAVE_FTRACE_MCOUNT_RECORD - select HAVE_FUNCTION_GRAPH_TRACER diff --git a/queue-5.10/riscv-using-patchable_function_entry-instead-of-mcou.patch b/queue-5.10/riscv-using-patchable_function_entry-instead-of-mcou.patch deleted file mode 100644 index ee0f5fe2b11..00000000000 --- a/queue-5.10/riscv-using-patchable_function_entry-instead-of-mcou.patch +++ /dev/null @@ -1,600 +0,0 @@ -From abb0542c5e210048f5905f02935615dc315a5240 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 17 Dec 2020 16:01:41 +0000 -Subject: riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT - -From: Guo Ren - -[ Upstream commit afc76b8b80112189b6f11e67e19cf58301944814 ] - -This patch changes the current detour mechanism of dynamic ftrace -which has been discussed during LPC 2020 RISCV-MC [1]. - -Before the patch, we used mcount for detour: -: - addi sp,sp,-16 - sd ra,8(sp) - sd s0,0(sp) - addi s0,sp,16 - mv a5,ra - mv a0,a5 - auipc ra,0x0 -> nop - jalr -296(ra) <_mcount@plt> ->nop - ... - -After the patch, we use nop call site area for detour: -: - nop -> REG_S ra, -SZREG(sp) - nop -> auipc ra, 0x? - nop -> jalr ?(ra) - nop -> REG_L ra, -SZREG(sp) - ... - -The mcount mechanism is mixed with gcc function prologue which is -not very clear. The patchable function entry just put 16 bytes nop -before the front of the function prologue which could be filled -with a separated detour mechanism. - -[1] https://www.linuxplumbersconf.org/event/7/contributions/807/ - -Signed-off-by: Guo Ren -Signed-off-by: Palmer Dabbelt -Stable-dep-of: 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C") -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 2 + - arch/riscv/kernel/ftrace.c | 95 ++++----- - arch/riscv/kernel/mcount-dyn.S | 342 +++++++++++++++------------------ - 3 files changed, 204 insertions(+), 235 deletions(-) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 9446282b52bab..6c1ef42d5a0df 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -12,6 +12,8 @@ OBJCOPYFLAGS := -O binary - LDFLAGS_vmlinux := - ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax -+ KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=8 - endif - - ifeq ($(CONFIG_CMODEL_MEDLOW),y) -diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c -index 765b62434f303..7f1e5203de886 100644 ---- a/arch/riscv/kernel/ftrace.c -+++ b/arch/riscv/kernel/ftrace.c -@@ -72,29 +72,56 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, - return 0; - } - -+/* -+ * Put 5 instructions with 16 bytes at the front of function within -+ * patchable function entry nops' area. -+ * -+ * 0: REG_S ra, -SZREG(sp) -+ * 1: auipc ra, 0x? -+ * 2: jalr -?(ra) -+ * 3: REG_L ra, -SZREG(sp) -+ * -+ * So the opcodes is: -+ * 0: 0xfe113c23 (sd)/0xfe112e23 (sw) -+ * 1: 0x???????? -> auipc -+ * 2: 0x???????? -> jalr -+ * 3: 0xff813083 (ld)/0xffc12083 (lw) -+ */ -+#if __riscv_xlen == 64 -+#define INSN0 0xfe113c23 -+#define INSN3 0xff813083 -+#elif __riscv_xlen == 32 -+#define INSN0 0xfe112e23 -+#define INSN3 0xffc12083 -+#endif -+ -+#define FUNC_ENTRY_SIZE 16 -+#define FUNC_ENTRY_JMP 4 -+ - int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - { -- int ret = ftrace_check_current_call(rec->ip, NULL); -+ unsigned int call[4] = {INSN0, 0, 0, INSN3}; -+ unsigned long target = addr; -+ unsigned long caller = rec->ip + FUNC_ENTRY_JMP; - -- if (ret) -- return ret; -+ call[1] = to_auipc_insn((unsigned int)(target - caller)); -+ call[2] = to_jalr_insn((unsigned int)(target - caller)); - -- return __ftrace_modify_call(rec->ip, addr, true); -+ if (patch_text_nosync((void *)rec->ip, call, FUNC_ENTRY_SIZE)) -+ return -EPERM; -+ -+ return 0; - } - - int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, - unsigned long addr) - { -- unsigned int call[2]; -- int ret; -+ unsigned int nops[4] = {NOP4, NOP4, NOP4, NOP4}; - -- make_call(rec->ip, addr, call); -- ret = ftrace_check_current_call(rec->ip, call); -- -- if (ret) -- return ret; -+ if (patch_text_nosync((void *)rec->ip, nops, FUNC_ENTRY_SIZE)) -+ return -EPERM; - -- return __ftrace_modify_call(rec->ip, addr, false); -+ return 0; - } - - -@@ -139,15 +166,16 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, - unsigned long addr) - { - unsigned int call[2]; -+ unsigned long caller = rec->ip + FUNC_ENTRY_JMP; - int ret; - -- make_call(rec->ip, old_addr, call); -- ret = ftrace_check_current_call(rec->ip, call); -+ make_call(caller, old_addr, call); -+ ret = ftrace_check_current_call(caller, call); - - if (ret) - return ret; - -- return __ftrace_modify_call(rec->ip, addr, true); -+ return __ftrace_modify_call(caller, addr, true); - } - #endif - -@@ -176,53 +204,30 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, - - #ifdef CONFIG_DYNAMIC_FTRACE - extern void ftrace_graph_call(void); -+extern void ftrace_graph_regs_call(void); - int ftrace_enable_ftrace_graph_caller(void) - { -- unsigned int call[2]; -- static int init_graph = 1; - int ret; - -- make_call(&ftrace_graph_call, &ftrace_stub, call); -- -- /* -- * When enabling graph tracer for the first time, ftrace_graph_call -- * should contains a call to ftrace_stub. Once it has been disabled, -- * the 8-bytes at the position becomes NOPs. -- */ -- if (init_graph) { -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- call); -- init_graph = 0; -- } else { -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- NULL); -- } -- -+ ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ (unsigned long)&prepare_ftrace_return, true); - if (ret) - return ret; - -- return __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, - (unsigned long)&prepare_ftrace_return, true); - } - - int ftrace_disable_ftrace_graph_caller(void) - { -- unsigned int call[2]; - int ret; - -- make_call(&ftrace_graph_call, &prepare_ftrace_return, call); -- -- /* -- * This is to make sure that ftrace_enable_ftrace_graph_caller -- * did the right thing. -- */ -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- call); -- -+ ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ (unsigned long)&prepare_ftrace_return, false); - if (ret) - return ret; - -- return __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, - (unsigned long)&prepare_ftrace_return, false); - } - #endif /* CONFIG_DYNAMIC_FTRACE */ -diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S -index 35a6ed76cb8b7..d171eca623b6f 100644 ---- a/arch/riscv/kernel/mcount-dyn.S -+++ b/arch/riscv/kernel/mcount-dyn.S -@@ -13,224 +13,186 @@ - - .text - -- .macro SAVE_ABI_STATE --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi sp, sp, -48 -- sd s0, 32(sp) -- sd ra, 40(sp) -- addi s0, sp, 48 -- sd t0, 24(sp) -- sd t1, 16(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- sd t2, 8(sp) --#endif --#else -- addi sp, sp, -16 -- sd s0, 0(sp) -- sd ra, 8(sp) -- addi s0, sp, 16 --#endif -+#define FENTRY_RA_OFFSET 12 -+#define ABI_SIZE_ON_STACK 72 -+#define ABI_A0 0 -+#define ABI_A1 8 -+#define ABI_A2 16 -+#define ABI_A3 24 -+#define ABI_A4 32 -+#define ABI_A5 40 -+#define ABI_A6 48 -+#define ABI_A7 56 -+#define ABI_RA 64 -+ -+ .macro SAVE_ABI -+ addi sp, sp, -SZREG -+ addi sp, sp, -ABI_SIZE_ON_STACK -+ -+ REG_S a0, ABI_A0(sp) -+ REG_S a1, ABI_A1(sp) -+ REG_S a2, ABI_A2(sp) -+ REG_S a3, ABI_A3(sp) -+ REG_S a4, ABI_A4(sp) -+ REG_S a5, ABI_A5(sp) -+ REG_S a6, ABI_A6(sp) -+ REG_S a7, ABI_A7(sp) -+ REG_S ra, ABI_RA(sp) - .endm - -- .macro RESTORE_ABI_STATE --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- ld s0, 32(sp) -- ld ra, 40(sp) -- addi sp, sp, 48 --#else -- ld ra, 8(sp) -- ld s0, 0(sp) -- addi sp, sp, 16 --#endif -+ .macro RESTORE_ABI -+ REG_L a0, ABI_A0(sp) -+ REG_L a1, ABI_A1(sp) -+ REG_L a2, ABI_A2(sp) -+ REG_L a3, ABI_A3(sp) -+ REG_L a4, ABI_A4(sp) -+ REG_L a5, ABI_A5(sp) -+ REG_L a6, ABI_A6(sp) -+ REG_L a7, ABI_A7(sp) -+ REG_L ra, ABI_RA(sp) -+ -+ addi sp, sp, ABI_SIZE_ON_STACK -+ addi sp, sp, SZREG - .endm - -- .macro RESTORE_GRAPH_ARGS -- ld a0, 24(sp) -- ld a1, 16(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld a2, 8(sp) --#endif -+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS -+ .macro SAVE_ALL -+ addi sp, sp, -SZREG -+ addi sp, sp, -PT_SIZE_ON_STACK -+ -+ REG_S x1, PT_EPC(sp) -+ addi sp, sp, PT_SIZE_ON_STACK -+ REG_L x1, (sp) -+ addi sp, sp, -PT_SIZE_ON_STACK -+ REG_S x1, PT_RA(sp) -+ REG_L x1, PT_EPC(sp) -+ -+ REG_S x2, PT_SP(sp) -+ REG_S x3, PT_GP(sp) -+ REG_S x4, PT_TP(sp) -+ REG_S x5, PT_T0(sp) -+ REG_S x6, PT_T1(sp) -+ REG_S x7, PT_T2(sp) -+ REG_S x8, PT_S0(sp) -+ REG_S x9, PT_S1(sp) -+ REG_S x10, PT_A0(sp) -+ REG_S x11, PT_A1(sp) -+ REG_S x12, PT_A2(sp) -+ REG_S x13, PT_A3(sp) -+ REG_S x14, PT_A4(sp) -+ REG_S x15, PT_A5(sp) -+ REG_S x16, PT_A6(sp) -+ REG_S x17, PT_A7(sp) -+ REG_S x18, PT_S2(sp) -+ REG_S x19, PT_S3(sp) -+ REG_S x20, PT_S4(sp) -+ REG_S x21, PT_S5(sp) -+ REG_S x22, PT_S6(sp) -+ REG_S x23, PT_S7(sp) -+ REG_S x24, PT_S8(sp) -+ REG_S x25, PT_S9(sp) -+ REG_S x26, PT_S10(sp) -+ REG_S x27, PT_S11(sp) -+ REG_S x28, PT_T3(sp) -+ REG_S x29, PT_T4(sp) -+ REG_S x30, PT_T5(sp) -+ REG_S x31, PT_T6(sp) - .endm - --ENTRY(ftrace_graph_caller) -- addi sp, sp, -16 -- sd s0, 0(sp) -- sd ra, 8(sp) -- addi s0, sp, 16 --ftrace_graph_call: -- .global ftrace_graph_call -- /* -- * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the -- * call below. Check ftrace_modify_all_code for details. -- */ -- call ftrace_stub -- ld ra, 8(sp) -- ld s0, 0(sp) -- addi sp, sp, 16 -- ret --ENDPROC(ftrace_graph_caller) -+ .macro RESTORE_ALL -+ REG_L x1, PT_RA(sp) -+ addi sp, sp, PT_SIZE_ON_STACK -+ REG_S x1, (sp) -+ addi sp, sp, -PT_SIZE_ON_STACK -+ REG_L x1, PT_EPC(sp) -+ REG_L x2, PT_SP(sp) -+ REG_L x3, PT_GP(sp) -+ REG_L x4, PT_TP(sp) -+ REG_L x5, PT_T0(sp) -+ REG_L x6, PT_T1(sp) -+ REG_L x7, PT_T2(sp) -+ REG_L x8, PT_S0(sp) -+ REG_L x9, PT_S1(sp) -+ REG_L x10, PT_A0(sp) -+ REG_L x11, PT_A1(sp) -+ REG_L x12, PT_A2(sp) -+ REG_L x13, PT_A3(sp) -+ REG_L x14, PT_A4(sp) -+ REG_L x15, PT_A5(sp) -+ REG_L x16, PT_A6(sp) -+ REG_L x17, PT_A7(sp) -+ REG_L x18, PT_S2(sp) -+ REG_L x19, PT_S3(sp) -+ REG_L x20, PT_S4(sp) -+ REG_L x21, PT_S5(sp) -+ REG_L x22, PT_S6(sp) -+ REG_L x23, PT_S7(sp) -+ REG_L x24, PT_S8(sp) -+ REG_L x25, PT_S9(sp) -+ REG_L x26, PT_S10(sp) -+ REG_L x27, PT_S11(sp) -+ REG_L x28, PT_T3(sp) -+ REG_L x29, PT_T4(sp) -+ REG_L x30, PT_T5(sp) -+ REG_L x31, PT_T6(sp) -+ -+ addi sp, sp, PT_SIZE_ON_STACK -+ addi sp, sp, SZREG -+ .endm -+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ - - ENTRY(ftrace_caller) -- /* -- * a0: the address in the caller when calling ftrace_caller -- * a1: the caller's return address -- * a2: the address of global variable function_trace_op -- */ -- ld a1, -8(s0) -- addi a0, ra, -MCOUNT_INSN_SIZE -- la t5, function_trace_op -- ld a2, 0(t5) -+ SAVE_ABI - --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- /* -- * the graph tracer (specifically, prepare_ftrace_return) needs these -- * arguments but for now the function tracer occupies the regs, so we -- * save them in temporary regs to recover later. -- */ -- addi t0, s0, -8 -- mv t1, a0 --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld t2, -16(s0) --#endif --#endif -+ addi a0, ra, -FENTRY_RA_OFFSET -+ la a1, function_trace_op -+ REG_L a2, 0(a1) -+ REG_L a1, ABI_SIZE_ON_STACK(sp) -+ mv a3, sp - -- SAVE_ABI_STATE - ftrace_call: - .global ftrace_call -- /* -- * For the dynamic ftrace to work, here we should reserve at least -- * 8 bytes for a functional auipc-jalr pair. The following call -- * serves this purpose. -- * -- * Calling ftrace_update_ftrace_func would overwrite the nops below. -- * Check ftrace_modify_all_code for details. -- */ - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- RESTORE_GRAPH_ARGS -- call ftrace_graph_caller -+ addi a0, sp, ABI_SIZE_ON_STACK -+ REG_L a1, ABI_RA(sp) -+ addi a1, a1, -FENTRY_RA_OFFSET -+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -+ mv a2, s0 - #endif -- -- RESTORE_ABI_STATE -+ftrace_graph_call: -+ .global ftrace_graph_call -+ call ftrace_stub -+#endif -+ RESTORE_ABI - ret - ENDPROC(ftrace_caller) - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS -- .macro SAVE_ALL -- addi sp, sp, -(PT_SIZE_ON_STACK+16) -- sd s0, (PT_SIZE_ON_STACK)(sp) -- sd ra, (PT_SIZE_ON_STACK+8)(sp) -- addi s0, sp, (PT_SIZE_ON_STACK+16) -- -- sd x1, PT_RA(sp) -- sd x2, PT_SP(sp) -- sd x3, PT_GP(sp) -- sd x4, PT_TP(sp) -- sd x5, PT_T0(sp) -- sd x6, PT_T1(sp) -- sd x7, PT_T2(sp) -- sd x8, PT_S0(sp) -- sd x9, PT_S1(sp) -- sd x10, PT_A0(sp) -- sd x11, PT_A1(sp) -- sd x12, PT_A2(sp) -- sd x13, PT_A3(sp) -- sd x14, PT_A4(sp) -- sd x15, PT_A5(sp) -- sd x16, PT_A6(sp) -- sd x17, PT_A7(sp) -- sd x18, PT_S2(sp) -- sd x19, PT_S3(sp) -- sd x20, PT_S4(sp) -- sd x21, PT_S5(sp) -- sd x22, PT_S6(sp) -- sd x23, PT_S7(sp) -- sd x24, PT_S8(sp) -- sd x25, PT_S9(sp) -- sd x26, PT_S10(sp) -- sd x27, PT_S11(sp) -- sd x28, PT_T3(sp) -- sd x29, PT_T4(sp) -- sd x30, PT_T5(sp) -- sd x31, PT_T6(sp) -- .endm -- -- .macro RESTORE_ALL -- ld x1, PT_RA(sp) -- ld x2, PT_SP(sp) -- ld x3, PT_GP(sp) -- ld x4, PT_TP(sp) -- ld x5, PT_T0(sp) -- ld x6, PT_T1(sp) -- ld x7, PT_T2(sp) -- ld x8, PT_S0(sp) -- ld x9, PT_S1(sp) -- ld x10, PT_A0(sp) -- ld x11, PT_A1(sp) -- ld x12, PT_A2(sp) -- ld x13, PT_A3(sp) -- ld x14, PT_A4(sp) -- ld x15, PT_A5(sp) -- ld x16, PT_A6(sp) -- ld x17, PT_A7(sp) -- ld x18, PT_S2(sp) -- ld x19, PT_S3(sp) -- ld x20, PT_S4(sp) -- ld x21, PT_S5(sp) -- ld x22, PT_S6(sp) -- ld x23, PT_S7(sp) -- ld x24, PT_S8(sp) -- ld x25, PT_S9(sp) -- ld x26, PT_S10(sp) -- ld x27, PT_S11(sp) -- ld x28, PT_T3(sp) -- ld x29, PT_T4(sp) -- ld x30, PT_T5(sp) -- ld x31, PT_T6(sp) -- -- ld s0, (PT_SIZE_ON_STACK)(sp) -- ld ra, (PT_SIZE_ON_STACK+8)(sp) -- addi sp, sp, (PT_SIZE_ON_STACK+16) -- .endm -- -- .macro RESTORE_GRAPH_REG_ARGS -- ld a0, PT_T0(sp) -- ld a1, PT_T1(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld a2, PT_T2(sp) --#endif -- .endm -- --/* -- * Most of the contents are the same as ftrace_caller. -- */ - ENTRY(ftrace_regs_caller) -- /* -- * a3: the address of all registers in the stack -- */ -- ld a1, -8(s0) -- addi a0, ra, -MCOUNT_INSN_SIZE -- la t5, function_trace_op -- ld a2, 0(t5) -- addi a3, sp, -(PT_SIZE_ON_STACK+16) -- --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi t0, s0, -8 -- mv t1, a0 --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld t2, -16(s0) --#endif --#endif - SAVE_ALL - -+ addi a0, ra, -FENTRY_RA_OFFSET -+ la a1, function_trace_op -+ REG_L a2, 0(a1) -+ REG_L a1, PT_SIZE_ON_STACK(sp) -+ mv a3, sp -+ - ftrace_regs_call: - .global ftrace_regs_call - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- RESTORE_GRAPH_REG_ARGS -- call ftrace_graph_caller -+ addi a0, sp, PT_RA -+ REG_L a1, PT_EPC(sp) -+ addi a1, a1, -FENTRY_RA_OFFSET -+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -+ mv a2, s0 -+#endif -+ftrace_graph_regs_call: -+ .global ftrace_graph_regs_call -+ call ftrace_stub - #endif - - RESTORE_ALL --- -2.39.2 - diff --git a/queue-5.10/series b/queue-5.10/series index be9b14391e2..fcd326a2d0f 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -17,9 +17,6 @@ irqdomain-refactor-__irq_domain_alloc_irqs.patch irqdomain-fix-mapping-creation-race.patch irqdomain-change-the-type-of-size-in-__irq_domain_ad.patch irqdomain-fix-domain-registration-race.patch -riscv-using-patchable_function_entry-instead-of-mcou.patch -riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch -riscv-ftrace-reduce-the-detour-code-size-to-half.patch iommu-vt-d-fix-lockdep-splat-in-intel_pasid_get_entr.patch iommu-vt-d-fix-pasid-directory-pointer-coherency.patch arm64-efi-make-efi_rt_lock-a-raw_spinlock.patch @@ -101,4 +98,3 @@ powerpc-vmlinux.lds-don-t-discard-.rela-for-relocatable-builds.patch s390-define-runtime_discard_exit-to-fix-link-error-with-gnu-ld-2.36.patch sh-define-runtime_discard_exit.patch uml-define-runtime_discard_exit.patch -riscv-select-have_dynamic_ftrace-when-fpatchable-function-entry-is-available.patch diff --git a/queue-5.4/risc-v-avoid-dereferening-null-regs-in-die.patch b/queue-5.4/risc-v-avoid-dereferening-null-regs-in-die.patch deleted file mode 100644 index 88b17f4d55a..00000000000 --- a/queue-5.4/risc-v-avoid-dereferening-null-regs-in-die.patch +++ /dev/null @@ -1,57 +0,0 @@ -From bf37e6388dc21d42ea1cdca38b9ac990b4042fed Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 20 Sep 2022 13:00:37 -0700 -Subject: RISC-V: Avoid dereferening NULL regs in die() - -From: Palmer Dabbelt - -[ Upstream commit f2913d006fcdb61719635e093d1b5dd0dafecac7 ] - -I don't think we can actually die() without a regs pointer, but the -compiler was warning about a NULL check after a dereference. It seems -prudent to just avoid the possibly-NULL dereference, given that when -die()ing the system is already toast so who knows how we got there. - -Reported-by: kernel test robot -Reported-by: Dan Carpenter -Reviewed-by: Conor Dooley -Link: https://lore.kernel.org/r/20220920200037.6727-1-palmer@rivosinc.com -Signed-off-by: Palmer Dabbelt -Stable-dep-of: 130aee3fd998 ("riscv: Avoid enabling interrupts in die()") -Signed-off-by: Sasha Levin ---- - arch/riscv/kernel/traps.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c -index 030094ac71902..5ca5a04258d0d 100644 ---- a/arch/riscv/kernel/traps.c -+++ b/arch/riscv/kernel/traps.c -@@ -31,6 +31,7 @@ void die(struct pt_regs *regs, const char *str) - { - static int die_counter; - int ret; -+ long cause; - - oops_enter(); - -@@ -40,11 +41,13 @@ void die(struct pt_regs *regs, const char *str) - - pr_emerg("%s [#%d]\n", str, ++die_counter); - print_modules(); -- show_regs(regs); -+ if (regs) -+ show_regs(regs); - -- ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV); -+ cause = regs ? regs->cause : -1; -+ ret = notify_die(DIE_OOPS, str, regs, 0, cause, SIGSEGV); - -- if (regs && kexec_should_crash(current)) -+ if (kexec_should_crash(current)) - crash_kexec(regs); - - bust_spinlocks(0); --- -2.39.2 - diff --git a/queue-5.4/riscv-abstract-out-csr-names-for-supervisor-vs-machi.patch b/queue-5.4/riscv-abstract-out-csr-names-for-supervisor-vs-machi.patch deleted file mode 100644 index 91a51270e07..00000000000 --- a/queue-5.4/riscv-abstract-out-csr-names-for-supervisor-vs-machi.patch +++ /dev/null @@ -1,1043 +0,0 @@ -From 3ef295cec87891ddcce650d9aea368d2179be8c9 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 28 Oct 2019 13:10:32 +0100 -Subject: riscv: abstract out CSR names for supervisor vs machine mode - -From: Christoph Hellwig - -[ Upstream commit a4c3733d32a72f11dee86d0731d7565aa6ebe22d ] - -Many of the privileged CSRs exist in a supervisor and machine version -that are used very similarly. Provide versions of the CSR names and -fields that map to either the S-mode or M-mode variant depending on -a new CONFIG_RISCV_M_MODE kconfig symbol. - -Contains contributions from Damien Le Moal -and Paul Walmsley . - -Signed-off-by: Christoph Hellwig -Acked-by: Thomas Gleixner # for drivers/clocksource, drivers/irqchip -[paul.walmsley@sifive.com: updated to apply] -Signed-off-by: Paul Walmsley -Stable-dep-of: 130aee3fd998 ("riscv: Avoid enabling interrupts in die()") -Signed-off-by: Sasha Levin ---- - arch/riscv/Kconfig | 4 ++ - arch/riscv/include/asm/csr.h | 72 +++++++++++++++++++++++++---- - arch/riscv/include/asm/irqflags.h | 12 ++--- - arch/riscv/include/asm/processor.h | 2 +- - arch/riscv/include/asm/ptrace.h | 16 +++---- - arch/riscv/include/asm/switch_to.h | 10 ++-- - arch/riscv/kernel/asm-offsets.c | 8 ++-- - arch/riscv/kernel/entry.S | 74 +++++++++++++++++------------- - arch/riscv/kernel/fpu.S | 8 ++-- - arch/riscv/kernel/head.S | 12 ++--- - arch/riscv/kernel/irq.c | 17 ++----- - arch/riscv/kernel/perf_callchain.c | 2 +- - arch/riscv/kernel/process.c | 17 +++---- - arch/riscv/kernel/signal.c | 21 ++++----- - arch/riscv/kernel/smp.c | 2 +- - arch/riscv/kernel/traps.c | 16 +++---- - arch/riscv/lib/uaccess.S | 12 ++--- - arch/riscv/mm/extable.c | 4 +- - arch/riscv/mm/fault.c | 6 +-- - drivers/clocksource/timer-riscv.c | 8 ++-- - drivers/irqchip/irq-sifive-plic.c | 11 +++-- - 21 files changed, 199 insertions(+), 135 deletions(-) - -diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index e0a77af5c130c..c21ebdb969570 100644 ---- a/arch/riscv/Kconfig -+++ b/arch/riscv/Kconfig -@@ -72,6 +72,10 @@ config ARCH_MMAP_RND_BITS_MAX - default 24 if 64BIT # SV39 based - default 17 - -+# set if we run in machine mode, cleared if we run in supervisor mode -+config RISCV_M_MODE -+ bool -+ - config MMU - def_bool y - -diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h -index a18923fa23c80..0ab6428110280 100644 ---- a/arch/riscv/include/asm/csr.h -+++ b/arch/riscv/include/asm/csr.h -@@ -11,8 +11,11 @@ - - /* Status register flags */ - #define SR_SIE _AC(0x00000002, UL) /* Supervisor Interrupt Enable */ -+#define SR_MIE _AC(0x00000008, UL) /* Machine Interrupt Enable */ - #define SR_SPIE _AC(0x00000020, UL) /* Previous Supervisor IE */ -+#define SR_MPIE _AC(0x00000080, UL) /* Previous Machine IE */ - #define SR_SPP _AC(0x00000100, UL) /* Previously Supervisor */ -+#define SR_MPP _AC(0x00001800, UL) /* Previously Machine */ - #define SR_SUM _AC(0x00040000, UL) /* Supervisor User Memory Access */ - - #define SR_FS _AC(0x00006000, UL) /* Floating-point Status */ -@@ -44,9 +47,10 @@ - #define SATP_MODE SATP_MODE_39 - #endif - --/* SCAUSE */ --#define SCAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) -+/* Exception cause high bit - is an interrupt if set */ -+#define CAUSE_IRQ_FLAG (_AC(1, UL) << (__riscv_xlen - 1)) - -+/* Interrupt causes (minus the high bit) */ - #define IRQ_U_SOFT 0 - #define IRQ_S_SOFT 1 - #define IRQ_M_SOFT 3 -@@ -57,6 +61,7 @@ - #define IRQ_S_EXT 9 - #define IRQ_M_EXT 11 - -+/* Exception causes */ - #define EXC_INST_MISALIGNED 0 - #define EXC_INST_ACCESS 1 - #define EXC_BREAKPOINT 3 -@@ -67,14 +72,14 @@ - #define EXC_LOAD_PAGE_FAULT 13 - #define EXC_STORE_PAGE_FAULT 15 - --/* SIE (Interrupt Enable) and SIP (Interrupt Pending) flags */ --#define SIE_SSIE (_AC(0x1, UL) << IRQ_S_SOFT) --#define SIE_STIE (_AC(0x1, UL) << IRQ_S_TIMER) --#define SIE_SEIE (_AC(0x1, UL) << IRQ_S_EXT) -- -+/* symbolic CSR names: */ - #define CSR_CYCLE 0xc00 - #define CSR_TIME 0xc01 - #define CSR_INSTRET 0xc02 -+#define CSR_CYCLEH 0xc80 -+#define CSR_TIMEH 0xc81 -+#define CSR_INSTRETH 0xc82 -+ - #define CSR_SSTATUS 0x100 - #define CSR_SIE 0x104 - #define CSR_STVEC 0x105 -@@ -85,9 +90,56 @@ - #define CSR_STVAL 0x143 - #define CSR_SIP 0x144 - #define CSR_SATP 0x180 --#define CSR_CYCLEH 0xc80 --#define CSR_TIMEH 0xc81 --#define CSR_INSTRETH 0xc82 -+ -+#define CSR_MSTATUS 0x300 -+#define CSR_MIE 0x304 -+#define CSR_MTVEC 0x305 -+#define CSR_MSCRATCH 0x340 -+#define CSR_MEPC 0x341 -+#define CSR_MCAUSE 0x342 -+#define CSR_MTVAL 0x343 -+#define CSR_MIP 0x344 -+ -+#ifdef CONFIG_RISCV_M_MODE -+# define CSR_STATUS CSR_MSTATUS -+# define CSR_IE CSR_MIE -+# define CSR_TVEC CSR_MTVEC -+# define CSR_SCRATCH CSR_MSCRATCH -+# define CSR_EPC CSR_MEPC -+# define CSR_CAUSE CSR_MCAUSE -+# define CSR_TVAL CSR_MTVAL -+# define CSR_IP CSR_MIP -+ -+# define SR_IE SR_MIE -+# define SR_PIE SR_MPIE -+# define SR_PP SR_MPP -+ -+# define IRQ_SOFT IRQ_M_SOFT -+# define IRQ_TIMER IRQ_M_TIMER -+# define IRQ_EXT IRQ_M_EXT -+#else /* CONFIG_RISCV_M_MODE */ -+# define CSR_STATUS CSR_SSTATUS -+# define CSR_IE CSR_SIE -+# define CSR_TVEC CSR_STVEC -+# define CSR_SCRATCH CSR_SSCRATCH -+# define CSR_EPC CSR_SEPC -+# define CSR_CAUSE CSR_SCAUSE -+# define CSR_TVAL CSR_STVAL -+# define CSR_IP CSR_SIP -+ -+# define SR_IE SR_SIE -+# define SR_PIE SR_SPIE -+# define SR_PP SR_SPP -+ -+# define IRQ_SOFT IRQ_S_SOFT -+# define IRQ_TIMER IRQ_S_TIMER -+# define IRQ_EXT IRQ_S_EXT -+#endif /* CONFIG_RISCV_M_MODE */ -+ -+/* IE/IP (Supervisor/Machine Interrupt Enable/Pending) flags */ -+#define IE_SIE (_AC(0x1, UL) << IRQ_SOFT) -+#define IE_TIE (_AC(0x1, UL) << IRQ_TIMER) -+#define IE_EIE (_AC(0x1, UL) << IRQ_EXT) - - #ifndef __ASSEMBLY__ - -diff --git a/arch/riscv/include/asm/irqflags.h b/arch/riscv/include/asm/irqflags.h -index e70f647ce3b76..08d4d6a5b7e95 100644 ---- a/arch/riscv/include/asm/irqflags.h -+++ b/arch/riscv/include/asm/irqflags.h -@@ -13,31 +13,31 @@ - /* read interrupt enabled status */ - static inline unsigned long arch_local_save_flags(void) - { -- return csr_read(CSR_SSTATUS); -+ return csr_read(CSR_STATUS); - } - - /* unconditionally enable interrupts */ - static inline void arch_local_irq_enable(void) - { -- csr_set(CSR_SSTATUS, SR_SIE); -+ csr_set(CSR_STATUS, SR_IE); - } - - /* unconditionally disable interrupts */ - static inline void arch_local_irq_disable(void) - { -- csr_clear(CSR_SSTATUS, SR_SIE); -+ csr_clear(CSR_STATUS, SR_IE); - } - - /* get status and disable interrupts */ - static inline unsigned long arch_local_irq_save(void) - { -- return csr_read_clear(CSR_SSTATUS, SR_SIE); -+ return csr_read_clear(CSR_STATUS, SR_IE); - } - - /* test flags */ - static inline int arch_irqs_disabled_flags(unsigned long flags) - { -- return !(flags & SR_SIE); -+ return !(flags & SR_IE); - } - - /* test hardware interrupt enable bit */ -@@ -49,7 +49,7 @@ static inline int arch_irqs_disabled(void) - /* set interrupt enabled status */ - static inline void arch_local_irq_restore(unsigned long flags) - { -- csr_set(CSR_SSTATUS, flags & SR_SIE); -+ csr_set(CSR_STATUS, flags & SR_IE); - } - - #endif /* _ASM_RISCV_IRQFLAGS_H */ -diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h -index 8c5b11a640dd3..60fd02698b770 100644 ---- a/arch/riscv/include/asm/processor.h -+++ b/arch/riscv/include/asm/processor.h -@@ -44,7 +44,7 @@ struct thread_struct { - ((struct pt_regs *)(task_stack_page(tsk) + THREAD_SIZE \ - - ALIGN(sizeof(struct pt_regs), STACK_ALIGN))) - --#define KSTK_EIP(tsk) (task_pt_regs(tsk)->sepc) -+#define KSTK_EIP(tsk) (task_pt_regs(tsk)->epc) - #define KSTK_ESP(tsk) (task_pt_regs(tsk)->sp) - - -diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h -index d48d1e13973ce..ee49f80c95337 100644 ---- a/arch/riscv/include/asm/ptrace.h -+++ b/arch/riscv/include/asm/ptrace.h -@@ -12,7 +12,7 @@ - #ifndef __ASSEMBLY__ - - struct pt_regs { -- unsigned long sepc; -+ unsigned long epc; - unsigned long ra; - unsigned long sp; - unsigned long gp; -@@ -44,10 +44,10 @@ struct pt_regs { - unsigned long t4; - unsigned long t5; - unsigned long t6; -- /* Supervisor CSRs */ -- unsigned long sstatus; -- unsigned long sbadaddr; -- unsigned long scause; -+ /* Supervisor/Machine CSRs */ -+ unsigned long status; -+ unsigned long badaddr; -+ unsigned long cause; - /* a0 value before the syscall */ - unsigned long orig_a0; - }; -@@ -58,18 +58,18 @@ struct pt_regs { - #define REG_FMT "%08lx" - #endif - --#define user_mode(regs) (((regs)->sstatus & SR_SPP) == 0) -+#define user_mode(regs) (((regs)->status & SR_PP) == 0) - - - /* Helpers for working with the instruction pointer */ - static inline unsigned long instruction_pointer(struct pt_regs *regs) - { -- return regs->sepc; -+ return regs->epc; - } - static inline void instruction_pointer_set(struct pt_regs *regs, - unsigned long val) - { -- regs->sepc = val; -+ regs->epc = val; - } - - #define profile_pc(regs) instruction_pointer(regs) -diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h -index ee4f0ac62c9d7..407bcc96a7109 100644 ---- a/arch/riscv/include/asm/switch_to.h -+++ b/arch/riscv/include/asm/switch_to.h -@@ -17,19 +17,19 @@ extern void __fstate_restore(struct task_struct *restore_from); - - static inline void __fstate_clean(struct pt_regs *regs) - { -- regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_CLEAN; -+ regs->status = (regs->status & ~SR_FS) | SR_FS_CLEAN; - } - - static inline void fstate_off(struct task_struct *task, - struct pt_regs *regs) - { -- regs->sstatus = (regs->sstatus & ~SR_FS) | SR_FS_OFF; -+ regs->status = (regs->status & ~SR_FS) | SR_FS_OFF; - } - - static inline void fstate_save(struct task_struct *task, - struct pt_regs *regs) - { -- if ((regs->sstatus & SR_FS) == SR_FS_DIRTY) { -+ if ((regs->status & SR_FS) == SR_FS_DIRTY) { - __fstate_save(task); - __fstate_clean(regs); - } -@@ -38,7 +38,7 @@ static inline void fstate_save(struct task_struct *task, - static inline void fstate_restore(struct task_struct *task, - struct pt_regs *regs) - { -- if ((regs->sstatus & SR_FS) != SR_FS_OFF) { -+ if ((regs->status & SR_FS) != SR_FS_OFF) { - __fstate_restore(task); - __fstate_clean(regs); - } -@@ -50,7 +50,7 @@ static inline void __switch_to_aux(struct task_struct *prev, - struct pt_regs *regs; - - regs = task_pt_regs(prev); -- if (unlikely(regs->sstatus & SR_SD)) -+ if (unlikely(regs->status & SR_SD)) - fstate_save(prev, regs); - fstate_restore(next, task_pt_regs(next)); - } -diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c -index 9f5628c38ac9f..07cb9c10de4ec 100644 ---- a/arch/riscv/kernel/asm-offsets.c -+++ b/arch/riscv/kernel/asm-offsets.c -@@ -71,7 +71,7 @@ void asm_offsets(void) - OFFSET(TASK_THREAD_FCSR, task_struct, thread.fstate.fcsr); - - DEFINE(PT_SIZE, sizeof(struct pt_regs)); -- OFFSET(PT_SEPC, pt_regs, sepc); -+ OFFSET(PT_EPC, pt_regs, epc); - OFFSET(PT_RA, pt_regs, ra); - OFFSET(PT_FP, pt_regs, s0); - OFFSET(PT_S0, pt_regs, s0); -@@ -105,9 +105,9 @@ void asm_offsets(void) - OFFSET(PT_T6, pt_regs, t6); - OFFSET(PT_GP, pt_regs, gp); - OFFSET(PT_ORIG_A0, pt_regs, orig_a0); -- OFFSET(PT_SSTATUS, pt_regs, sstatus); -- OFFSET(PT_SBADADDR, pt_regs, sbadaddr); -- OFFSET(PT_SCAUSE, pt_regs, scause); -+ OFFSET(PT_STATUS, pt_regs, status); -+ OFFSET(PT_BADADDR, pt_regs, badaddr); -+ OFFSET(PT_CAUSE, pt_regs, cause); - - /* - * THREAD_{F,X}* might be larger than a S-type offset can handle, but -diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S -index 9c87ae77ad5d3..57b27b8278b1e 100644 ---- a/arch/riscv/kernel/entry.S -+++ b/arch/riscv/kernel/entry.S -@@ -26,14 +26,14 @@ - - /* - * If coming from userspace, preserve the user thread pointer and load -- * the kernel thread pointer. If we came from the kernel, sscratch -- * will contain 0, and we should continue on the current TP. -+ * the kernel thread pointer. If we came from the kernel, the scratch -+ * register will contain 0, and we should continue on the current TP. - */ -- csrrw tp, CSR_SSCRATCH, tp -+ csrrw tp, CSR_SCRATCH, tp - bnez tp, _save_context - - _restore_kernel_tpsp: -- csrr tp, CSR_SSCRATCH -+ csrr tp, CSR_SCRATCH - REG_S sp, TASK_TI_KERNEL_SP(tp) - _save_context: - REG_S sp, TASK_TI_USER_SP(tp) -@@ -79,16 +79,16 @@ _save_context: - li t0, SR_SUM | SR_FS - - REG_L s0, TASK_TI_USER_SP(tp) -- csrrc s1, CSR_SSTATUS, t0 -- csrr s2, CSR_SEPC -- csrr s3, CSR_STVAL -- csrr s4, CSR_SCAUSE -- csrr s5, CSR_SSCRATCH -+ csrrc s1, CSR_STATUS, t0 -+ csrr s2, CSR_EPC -+ csrr s3, CSR_TVAL -+ csrr s4, CSR_CAUSE -+ csrr s5, CSR_SCRATCH - REG_S s0, PT_SP(sp) -- REG_S s1, PT_SSTATUS(sp) -- REG_S s2, PT_SEPC(sp) -- REG_S s3, PT_SBADADDR(sp) -- REG_S s4, PT_SCAUSE(sp) -+ REG_S s1, PT_STATUS(sp) -+ REG_S s2, PT_EPC(sp) -+ REG_S s3, PT_BADADDR(sp) -+ REG_S s4, PT_CAUSE(sp) - REG_S s5, PT_TP(sp) - .endm - -@@ -97,7 +97,7 @@ _save_context: - * registers from the stack. - */ - .macro RESTORE_ALL -- REG_L a0, PT_SSTATUS(sp) -+ REG_L a0, PT_STATUS(sp) - /* - * The current load reservation is effectively part of the processor's - * state, in the sense that load reservations cannot be shared between -@@ -115,11 +115,11 @@ _save_context: - * completes, implementations are allowed to expand reservations to be - * arbitrarily large. - */ -- REG_L a2, PT_SEPC(sp) -- REG_SC x0, a2, PT_SEPC(sp) -+ REG_L a2, PT_EPC(sp) -+ REG_SC x0, a2, PT_EPC(sp) - -- csrw CSR_SSTATUS, a0 -- csrw CSR_SEPC, a2 -+ csrw CSR_STATUS, a0 -+ csrw CSR_EPC, a2 - - REG_L x1, PT_RA(sp) - REG_L x3, PT_GP(sp) -@@ -163,10 +163,10 @@ ENTRY(handle_exception) - SAVE_ALL - - /* -- * Set sscratch register to 0, so that if a recursive exception -+ * Set the scratch register to 0, so that if a recursive exception - * occurs, the exception vector knows it came from the kernel - */ -- csrw CSR_SSCRATCH, x0 -+ csrw CSR_SCRATCH, x0 - - /* Load the global pointer */ - .option push -@@ -185,11 +185,13 @@ ENTRY(handle_exception) - move a0, sp /* pt_regs */ - tail do_IRQ - 1: -- /* Exceptions run with interrupts enabled or disabled -- depending on the state of sstatus.SR_SPIE */ -- andi t0, s1, SR_SPIE -+ /* -+ * Exceptions run with interrupts enabled or disabled depending on the -+ * state of SR_PIE in m/sstatus. -+ */ -+ andi t0, s1, SR_PIE - beqz t0, 1f -- csrs CSR_SSTATUS, SR_SIE -+ csrs CSR_STATUS, SR_IE - - 1: - /* Handle syscalls */ -@@ -217,7 +219,7 @@ handle_syscall: - * scall instruction on sret - */ - addi s2, s2, 0x4 -- REG_S s2, PT_SEPC(sp) -+ REG_S s2, PT_EPC(sp) - /* Trace syscalls, but only if requested by the user. */ - REG_L t0, TASK_TI_FLAGS(tp) - andi t0, t0, _TIF_SYSCALL_WORK -@@ -244,9 +246,15 @@ ret_from_syscall: - bnez t0, handle_syscall_trace_exit - - ret_from_exception: -- REG_L s0, PT_SSTATUS(sp) -- csrc CSR_SSTATUS, SR_SIE -+ REG_L s0, PT_STATUS(sp) -+ csrc CSR_STATUS, SR_IE -+#ifdef CONFIG_RISCV_M_MODE -+ /* the MPP value is too large to be used as an immediate arg for addi */ -+ li t0, SR_MPP -+ and s0, s0, t0 -+#else - andi s0, s0, SR_SPP -+#endif - bnez s0, resume_kernel - - resume_userspace: -@@ -260,14 +268,18 @@ resume_userspace: - REG_S s0, TASK_TI_KERNEL_SP(tp) - - /* -- * Save TP into sscratch, so we can find the kernel data structures -- * again. -+ * Save TP into the scratch register , so we can find the kernel data -+ * structures again. - */ -- csrw CSR_SSCRATCH, tp -+ csrw CSR_SCRATCH, tp - - restore_all: - RESTORE_ALL -+#ifdef CONFIG_RISCV_M_MODE -+ mret -+#else - sret -+#endif - - #if IS_ENABLED(CONFIG_PREEMPT) - resume_kernel: -@@ -287,7 +299,7 @@ work_pending: - bnez s1, work_resched - work_notifysig: - /* Handle pending signals and notify-resume requests */ -- csrs CSR_SSTATUS, SR_SIE /* Enable interrupts for do_notify_resume() */ -+ csrs CSR_STATUS, SR_IE /* Enable interrupts for do_notify_resume() */ - move a0, sp /* pt_regs */ - move a1, s0 /* current_thread_info->flags */ - tail do_notify_resume -diff --git a/arch/riscv/kernel/fpu.S b/arch/riscv/kernel/fpu.S -index 631d31540660e..dd2205473de78 100644 ---- a/arch/riscv/kernel/fpu.S -+++ b/arch/riscv/kernel/fpu.S -@@ -23,7 +23,7 @@ ENTRY(__fstate_save) - li a2, TASK_THREAD_F0 - add a0, a0, a2 - li t1, SR_FS -- csrs CSR_SSTATUS, t1 -+ csrs CSR_STATUS, t1 - frcsr t0 - fsd f0, TASK_THREAD_F0_F0(a0) - fsd f1, TASK_THREAD_F1_F0(a0) -@@ -58,7 +58,7 @@ ENTRY(__fstate_save) - fsd f30, TASK_THREAD_F30_F0(a0) - fsd f31, TASK_THREAD_F31_F0(a0) - sw t0, TASK_THREAD_FCSR_F0(a0) -- csrc CSR_SSTATUS, t1 -+ csrc CSR_STATUS, t1 - ret - ENDPROC(__fstate_save) - -@@ -67,7 +67,7 @@ ENTRY(__fstate_restore) - add a0, a0, a2 - li t1, SR_FS - lw t0, TASK_THREAD_FCSR_F0(a0) -- csrs CSR_SSTATUS, t1 -+ csrs CSR_STATUS, t1 - fld f0, TASK_THREAD_F0_F0(a0) - fld f1, TASK_THREAD_F1_F0(a0) - fld f2, TASK_THREAD_F2_F0(a0) -@@ -101,6 +101,6 @@ ENTRY(__fstate_restore) - fld f30, TASK_THREAD_F30_F0(a0) - fld f31, TASK_THREAD_F31_F0(a0) - fscsr t0 -- csrc CSR_SSTATUS, t1 -+ csrc CSR_STATUS, t1 - ret - ENDPROC(__fstate_restore) -diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S -index 344793159b97d..57817c1987743 100644 ---- a/arch/riscv/kernel/head.S -+++ b/arch/riscv/kernel/head.S -@@ -52,8 +52,8 @@ ENTRY(_start) - .global _start_kernel - _start_kernel: - /* Mask all interrupts */ -- csrw CSR_SIE, zero -- csrw CSR_SIP, zero -+ csrw CSR_IE, zero -+ csrw CSR_IP, zero - - /* Load the global pointer */ - .option push -@@ -66,7 +66,7 @@ _start_kernel: - * floating point in kernel space - */ - li t0, SR_FS -- csrc CSR_SSTATUS, t0 -+ csrc CSR_STATUS, t0 - - #ifdef CONFIG_SMP - li t0, CONFIG_NR_CPUS -@@ -121,7 +121,7 @@ relocate: - /* Point stvec to virtual address of intruction after satp write */ - la a2, 1f - add a2, a2, a1 -- csrw CSR_STVEC, a2 -+ csrw CSR_TVEC, a2 - - /* Compute satp for kernel page tables, but don't load it yet */ - srl a2, a0, PAGE_SHIFT -@@ -143,7 +143,7 @@ relocate: - 1: - /* Set trap vector to spin forever to help debug */ - la a0, .Lsecondary_park -- csrw CSR_STVEC, a0 -+ csrw CSR_TVEC, a0 - - /* Reload the global pointer */ - .option push -@@ -166,7 +166,7 @@ relocate: - #ifdef CONFIG_SMP - /* Set trap vector to spin forever to help debug */ - la a3, .Lsecondary_park -- csrw CSR_STVEC, a3 -+ csrw CSR_TVEC, a3 - - slli a3, a0, LGREG - la a1, __cpu_up_stack_pointer -diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c -index fffac6ddb0e00..3f07a91d5afb4 100644 ---- a/arch/riscv/kernel/irq.c -+++ b/arch/riscv/kernel/irq.c -@@ -11,13 +11,6 @@ - #include - #include - --/* -- * Possible interrupt causes: -- */ --#define INTERRUPT_CAUSE_SOFTWARE IRQ_S_SOFT --#define INTERRUPT_CAUSE_TIMER IRQ_S_TIMER --#define INTERRUPT_CAUSE_EXTERNAL IRQ_S_EXT -- - int arch_show_interrupts(struct seq_file *p, int prec) - { - show_ipi_stats(p, prec); -@@ -29,12 +22,12 @@ asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs) - struct pt_regs *old_regs = set_irq_regs(regs); - - irq_enter(); -- switch (regs->scause & ~SCAUSE_IRQ_FLAG) { -- case INTERRUPT_CAUSE_TIMER: -+ switch (regs->cause & ~CAUSE_IRQ_FLAG) { -+ case IRQ_TIMER: - riscv_timer_interrupt(); - break; - #ifdef CONFIG_SMP -- case INTERRUPT_CAUSE_SOFTWARE: -+ case IRQ_SOFT: - /* - * We only use software interrupts to pass IPIs, so if a non-SMP - * system gets one, then we don't know what to do. -@@ -42,11 +35,11 @@ asmlinkage __visible void __irq_entry do_IRQ(struct pt_regs *regs) - riscv_software_interrupt(); - break; - #endif -- case INTERRUPT_CAUSE_EXTERNAL: -+ case IRQ_EXT: - handle_arch_irq(regs); - break; - default: -- pr_alert("unexpected interrupt cause 0x%lx", regs->scause); -+ pr_alert("unexpected interrupt cause 0x%lx", regs->cause); - BUG(); - } - irq_exit(); -diff --git a/arch/riscv/kernel/perf_callchain.c b/arch/riscv/kernel/perf_callchain.c -index 1de5991916eb9..20af8ecbb7e41 100644 ---- a/arch/riscv/kernel/perf_callchain.c -+++ b/arch/riscv/kernel/perf_callchain.c -@@ -68,7 +68,7 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry, - return; - - fp = regs->s0; -- perf_callchain_store(entry, regs->sepc); -+ perf_callchain_store(entry, regs->epc); - - fp = user_backtrace(entry, fp, regs->ra); - while (fp && !(fp & 0x3) && entry->nr < entry->max_stack) -diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c -index 9d4b4098874bb..f17e7f4ad3e7a 100644 ---- a/arch/riscv/kernel/process.c -+++ b/arch/riscv/kernel/process.c -@@ -35,8 +35,8 @@ void show_regs(struct pt_regs *regs) - { - show_regs_print_info(KERN_DEFAULT); - -- pr_cont("sepc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n", -- regs->sepc, regs->ra, regs->sp); -+ pr_cont("epc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n", -+ regs->epc, regs->ra, regs->sp); - pr_cont(" gp : " REG_FMT " tp : " REG_FMT " t0 : " REG_FMT "\n", - regs->gp, regs->tp, regs->t0); - pr_cont(" t1 : " REG_FMT " t2 : " REG_FMT " s0 : " REG_FMT "\n", -@@ -58,23 +58,23 @@ void show_regs(struct pt_regs *regs) - pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n", - regs->t5, regs->t6); - -- pr_cont("sstatus: " REG_FMT " sbadaddr: " REG_FMT " scause: " REG_FMT "\n", -- regs->sstatus, regs->sbadaddr, regs->scause); -+ pr_cont("status: " REG_FMT " badaddr: " REG_FMT " cause: " REG_FMT "\n", -+ regs->status, regs->badaddr, regs->cause); - } - - void start_thread(struct pt_regs *regs, unsigned long pc, - unsigned long sp) - { -- regs->sstatus = SR_SPIE; -+ regs->status = SR_PIE; - if (has_fpu) { -- regs->sstatus |= SR_FS_INITIAL; -+ regs->status |= SR_FS_INITIAL; - /* - * Restore the initial value to the FP register - * before starting the user program. - */ - fstate_restore(current, regs); - } -- regs->sepc = pc; -+ regs->epc = pc; - regs->sp = sp; - set_fs(USER_DS); - } -@@ -112,7 +112,8 @@ int copy_thread_tls(unsigned long clone_flags, unsigned long usp, - const register unsigned long gp __asm__ ("gp"); - memset(childregs, 0, sizeof(struct pt_regs)); - childregs->gp = gp; -- childregs->sstatus = SR_SPP | SR_SPIE; /* Supervisor, irqs on */ -+ /* Supervisor/Machine, irqs on: */ -+ childregs->status = SR_PP | SR_PIE; - - p->thread.ra = (unsigned long)ret_from_kernel_thread; - p->thread.s[0] = usp; /* fn */ -diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c -index d0f6f212f5dfd..b7f9a5565c4bf 100644 ---- a/arch/riscv/kernel/signal.c -+++ b/arch/riscv/kernel/signal.c -@@ -124,7 +124,7 @@ SYSCALL_DEFINE0(rt_sigreturn) - pr_info_ratelimited( - "%s[%d]: bad frame in %s: frame=%p pc=%p sp=%p\n", - task->comm, task_pid_nr(task), __func__, -- frame, (void *)regs->sepc, (void *)regs->sp); -+ frame, (void *)regs->epc, (void *)regs->sp); - } - force_sig(SIGSEGV); - return 0; -@@ -199,7 +199,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, - * We always pass siginfo and mcontext, regardless of SA_SIGINFO, - * since some things rely on this (e.g. glibc's debug/segfault.c). - */ -- regs->sepc = (unsigned long)ksig->ka.sa.sa_handler; -+ regs->epc = (unsigned long)ksig->ka.sa.sa_handler; - regs->sp = (unsigned long)frame; - regs->a0 = ksig->sig; /* a0: signal number */ - regs->a1 = (unsigned long)(&frame->info); /* a1: siginfo pointer */ -@@ -208,7 +208,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, - #if DEBUG_SIG - pr_info("SIG deliver (%s:%d): sig=%d pc=%p ra=%p sp=%p\n", - current->comm, task_pid_nr(current), ksig->sig, -- (void *)regs->sepc, (void *)regs->ra, frame); -+ (void *)regs->epc, (void *)regs->ra, frame); - #endif - - return 0; -@@ -220,10 +220,9 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) - int ret; - - /* Are we from a system call? */ -- if (regs->scause == EXC_SYSCALL) { -+ if (regs->cause == EXC_SYSCALL) { - /* Avoid additional syscall restarting via ret_from_exception */ -- regs->scause = -1UL; -- -+ regs->cause = -1UL; - /* If so, check system call restarting.. */ - switch (regs->a0) { - case -ERESTART_RESTARTBLOCK: -@@ -239,7 +238,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) - /* fallthrough */ - case -ERESTARTNOINTR: - regs->a0 = regs->orig_a0; -- regs->sepc -= 0x4; -+ regs->epc -= 0x4; - break; - } - } -@@ -261,9 +260,9 @@ static void do_signal(struct pt_regs *regs) - } - - /* Did we come from a system call? */ -- if (regs->scause == EXC_SYSCALL) { -+ if (regs->cause == EXC_SYSCALL) { - /* Avoid additional syscall restarting via ret_from_exception */ -- regs->scause = -1UL; -+ regs->cause = -1UL; - - /* Restart the system call - no handlers present */ - switch (regs->a0) { -@@ -271,12 +270,12 @@ static void do_signal(struct pt_regs *regs) - case -ERESTARTSYS: - case -ERESTARTNOINTR: - regs->a0 = regs->orig_a0; -- regs->sepc -= 0x4; -+ regs->epc -= 0x4; - break; - case -ERESTART_RESTARTBLOCK: - regs->a0 = regs->orig_a0; - regs->a7 = __NR_restart_syscall; -- regs->sepc -= 0x4; -+ regs->epc -= 0x4; - break; - } - } -diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c -index 098c04adbaaf6..d724a7e6f4eb8 100644 ---- a/arch/riscv/kernel/smp.c -+++ b/arch/riscv/kernel/smp.c -@@ -108,7 +108,7 @@ static void send_ipi_single(int cpu, enum ipi_message_type op) - - static inline void clear_ipi(void) - { -- csr_clear(CSR_SIP, SIE_SSIE); -+ csr_clear(CSR_IP, IE_SIE); - } - - void riscv_software_interrupt(void) -diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c -index c28d4debf5926..030094ac71902 100644 ---- a/arch/riscv/kernel/traps.c -+++ b/arch/riscv/kernel/traps.c -@@ -42,7 +42,7 @@ void die(struct pt_regs *regs, const char *str) - print_modules(); - show_regs(regs); - -- ret = notify_die(DIE_OOPS, str, regs, 0, regs->scause, SIGSEGV); -+ ret = notify_die(DIE_OOPS, str, regs, 0, regs->cause, SIGSEGV); - - if (regs && kexec_should_crash(current)) - crash_kexec(regs); -@@ -90,7 +90,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code, - #define DO_ERROR_INFO(name, signo, code, str) \ - asmlinkage __visible void name(struct pt_regs *regs) \ - { \ -- do_trap_error(regs, signo, code, regs->sepc, "Oops - " str); \ -+ do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \ - } - - DO_ERROR_INFO(do_trap_unknown, -@@ -128,9 +128,9 @@ static inline unsigned long get_break_insn_length(unsigned long pc) - asmlinkage __visible void do_trap_break(struct pt_regs *regs) - { - if (user_mode(regs)) -- force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->sepc); -- else if (report_bug(regs->sepc, regs) == BUG_TRAP_TYPE_WARN) -- regs->sepc += get_break_insn_length(regs->sepc); -+ force_sig_fault(SIGTRAP, TRAP_BRKPT, (void __user *)regs->epc); -+ else if (report_bug(regs->epc, regs) == BUG_TRAP_TYPE_WARN) -+ regs->epc += get_break_insn_length(regs->epc); - else - die(regs, "Kernel BUG"); - } -@@ -157,9 +157,9 @@ void __init trap_init(void) - * Set sup0 scratch register to 0, indicating to exception vector - * that we are presently executing in the kernel - */ -- csr_write(CSR_SSCRATCH, 0); -+ csr_write(CSR_SCRATCH, 0); - /* Set the exception vector address */ -- csr_write(CSR_STVEC, &handle_exception); -+ csr_write(CSR_TVEC, &handle_exception); - /* Enable all interrupts */ -- csr_write(CSR_SIE, -1); -+ csr_write(CSR_IE, -1); - } -diff --git a/arch/riscv/lib/uaccess.S b/arch/riscv/lib/uaccess.S -index ed2696c0143d5..fecd65657a6fc 100644 ---- a/arch/riscv/lib/uaccess.S -+++ b/arch/riscv/lib/uaccess.S -@@ -18,7 +18,7 @@ ENTRY(__asm_copy_from_user) - - /* Enable access to user memory */ - li t6, SR_SUM -- csrs CSR_SSTATUS, t6 -+ csrs CSR_STATUS, t6 - - add a3, a1, a2 - /* Use word-oriented copy only if low-order bits match */ -@@ -47,7 +47,7 @@ ENTRY(__asm_copy_from_user) - - 3: - /* Disable access to user memory */ -- csrc CSR_SSTATUS, t6 -+ csrc CSR_STATUS, t6 - li a0, 0 - ret - 4: /* Edge case: unalignment */ -@@ -72,7 +72,7 @@ ENTRY(__clear_user) - - /* Enable access to user memory */ - li t6, SR_SUM -- csrs CSR_SSTATUS, t6 -+ csrs CSR_STATUS, t6 - - add a3, a0, a1 - addi t0, a0, SZREG-1 -@@ -94,7 +94,7 @@ ENTRY(__clear_user) - - 3: - /* Disable access to user memory */ -- csrc CSR_SSTATUS, t6 -+ csrc CSR_STATUS, t6 - li a0, 0 - ret - 4: /* Edge case: unalignment */ -@@ -114,11 +114,11 @@ ENDPROC(__clear_user) - /* Fixup code for __copy_user(10) and __clear_user(11) */ - 10: - /* Disable access to user memory */ -- csrs CSR_SSTATUS, t6 -+ csrs CSR_STATUS, t6 - mv a0, a2 - ret - 11: -- csrs CSR_SSTATUS, t6 -+ csrs CSR_STATUS, t6 - mv a0, a1 - ret - .previous -diff --git a/arch/riscv/mm/extable.c b/arch/riscv/mm/extable.c -index 7aed9178d365d..2fc7294221515 100644 ---- a/arch/riscv/mm/extable.c -+++ b/arch/riscv/mm/extable.c -@@ -15,9 +15,9 @@ int fixup_exception(struct pt_regs *regs) - { - const struct exception_table_entry *fixup; - -- fixup = search_exception_tables(regs->sepc); -+ fixup = search_exception_tables(regs->epc); - if (fixup) { -- regs->sepc = fixup->fixup; -+ regs->epc = fixup->fixup; - return 1; - } - return 0; -diff --git a/arch/riscv/mm/fault.c b/arch/riscv/mm/fault.c -index 1cfce62caa119..55ac8b7bb432d 100644 ---- a/arch/riscv/mm/fault.c -+++ b/arch/riscv/mm/fault.c -@@ -34,8 +34,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs) - int code = SEGV_MAPERR; - vm_fault_t fault; - -- cause = regs->scause; -- addr = regs->sbadaddr; -+ cause = regs->cause; -+ addr = regs->badaddr; - - tsk = current; - mm = tsk->mm; -@@ -53,7 +53,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs) - goto vmalloc_fault; - - /* Enable interrupts if they were enabled in the parent context. */ -- if (likely(regs->sstatus & SR_SPIE)) -+ if (likely(regs->status & SR_PIE)) - local_irq_enable(); - - /* -diff --git a/drivers/clocksource/timer-riscv.c b/drivers/clocksource/timer-riscv.c -index 4b04ffbe5e7e9..cd83951718494 100644 ---- a/drivers/clocksource/timer-riscv.c -+++ b/drivers/clocksource/timer-riscv.c -@@ -19,7 +19,7 @@ - static int riscv_clock_next_event(unsigned long delta, - struct clock_event_device *ce) - { -- csr_set(sie, SIE_STIE); -+ csr_set(CSR_IE, IE_TIE); - sbi_set_timer(get_cycles64() + delta); - return 0; - } -@@ -61,13 +61,13 @@ static int riscv_timer_starting_cpu(unsigned int cpu) - ce->cpumask = cpumask_of(cpu); - clockevents_config_and_register(ce, riscv_timebase, 100, 0x7fffffff); - -- csr_set(sie, SIE_STIE); -+ csr_set(CSR_IE, IE_TIE); - return 0; - } - - static int riscv_timer_dying_cpu(unsigned int cpu) - { -- csr_clear(sie, SIE_STIE); -+ csr_clear(CSR_IE, IE_TIE); - return 0; - } - -@@ -76,7 +76,7 @@ void riscv_timer_interrupt(void) - { - struct clock_event_device *evdev = this_cpu_ptr(&riscv_clock_event); - -- csr_clear(sie, SIE_STIE); -+ csr_clear(CSR_IE, IE_TIE); - evdev->event_handler(evdev); - } - -diff --git a/drivers/irqchip/irq-sifive-plic.c b/drivers/irqchip/irq-sifive-plic.c -index 9dad45d928bfe..2dca689a5cbc6 100644 ---- a/drivers/irqchip/irq-sifive-plic.c -+++ b/drivers/irqchip/irq-sifive-plic.c -@@ -187,7 +187,7 @@ static void plic_handle_irq(struct pt_regs *regs) - - WARN_ON_ONCE(!handler->present); - -- csr_clear(sie, SIE_SEIE); -+ csr_clear(CSR_IE, IE_EIE); - while ((hwirq = readl(claim))) { - int irq = irq_find_mapping(plic_irqdomain, hwirq); - -@@ -197,7 +197,7 @@ static void plic_handle_irq(struct pt_regs *regs) - else - generic_handle_irq(irq); - } -- csr_set(sie, SIE_SEIE); -+ csr_set(CSR_IE, IE_EIE); - } - - /* -@@ -258,8 +258,11 @@ static int __init plic_init(struct device_node *node, - continue; - } - -- /* skip contexts other than supervisor external interrupt */ -- if (parent.args[0] != IRQ_S_EXT) -+ /* -+ * Skip contexts other than external interrupts for our -+ * privilege level. -+ */ -+ if (parent.args[0] != IRQ_EXT) - continue; - - hartid = plic_find_hart_id(parent.np); --- -2.39.2 - diff --git a/queue-5.4/riscv-avoid-enabling-interrupts-in-die.patch b/queue-5.4/riscv-avoid-enabling-interrupts-in-die.patch deleted file mode 100644 index 1dc6f843f5a..00000000000 --- a/queue-5.4/riscv-avoid-enabling-interrupts-in-die.patch +++ /dev/null @@ -1,60 +0,0 @@ -From d52b7f5ca92c5ccfd25076035a3bc1d329e7d83b Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Wed, 15 Feb 2023 14:48:28 +0000 -Subject: riscv: Avoid enabling interrupts in die() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Mattias Nissler - -[ Upstream commit 130aee3fd9981297ff9354e5d5609cd59aafbbea ] - -While working on something else, I noticed that the kernel would start -accepting interrupts again after crashing in an interrupt handler. Since -the kernel is already in inconsistent state, enabling interrupts is -dangerous and opens up risk of kernel state deteriorating further. -Interrupts do get enabled via what looks like an unintended side effect of -spin_unlock_irq, so switch to the more cautious -spin_lock_irqsave/spin_unlock_irqrestore instead. - -Fixes: 76d2a0493a17 ("RISC-V: Init and Halt Code") -Signed-off-by: Mattias Nissler -Reviewed-by: Björn Töpel -Link: https://lore.kernel.org/r/20230215144828.3370316-1-mnissler@rivosinc.com -Cc: stable@vger.kernel.org -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/kernel/traps.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c -index 5ca5a04258d0d..312da504b0162 100644 ---- a/arch/riscv/kernel/traps.c -+++ b/arch/riscv/kernel/traps.c -@@ -32,10 +32,11 @@ void die(struct pt_regs *regs, const char *str) - static int die_counter; - int ret; - long cause; -+ unsigned long flags; - - oops_enter(); - -- spin_lock_irq(&die_lock); -+ spin_lock_irqsave(&die_lock, flags); - console_verbose(); - bust_spinlocks(1); - -@@ -52,7 +53,7 @@ void die(struct pt_regs *regs, const char *str) - - bust_spinlocks(0); - add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); -- spin_unlock_irq(&die_lock); -+ spin_unlock_irqrestore(&die_lock, flags); - oops_exit(); - - if (in_interrupt()) --- -2.39.2 - diff --git a/queue-5.4/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch b/queue-5.4/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch deleted file mode 100644 index 122defca3b5..00000000000 --- a/queue-5.4/riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 90d2039dfb03cdc912ca5b796940853ee5c978ab Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 12 Jan 2023 04:05:58 -0500 -Subject: riscv: ftrace: Remove wasted nops for !RISCV_ISA_C - -From: Guo Ren - -[ Upstream commit 409c8fb20c66df7150e592747412438c04aeb11f ] - -When CONFIG_RISCV_ISA_C=n, -fpatchable-function-entry=8 would generate -more nops than we expect. Because it treat nop opcode as 0x00000013 -instead of 0x0001. - -Dump of assembler code for function dw_pcie_free_msi: - 0xffffffff806fce94 <+0>: sd ra,-8(sp) - 0xffffffff806fce98 <+4>: auipc ra,0xff90f - 0xffffffff806fce9c <+8>: jalr -684(ra) # 0xffffffff8000bbec - - 0xffffffff806fcea0 <+12>: ld ra,-8(sp) - 0xffffffff806fcea4 <+16>: nop /* wasted */ - 0xffffffff806fcea8 <+20>: nop /* wasted */ - 0xffffffff806fceac <+24>: nop /* wasted */ - 0xffffffff806fceb0 <+28>: nop /* wasted */ - 0xffffffff806fceb4 <+0>: addi sp,sp,-48 - 0xffffffff806fceb8 <+4>: sd s0,32(sp) - 0xffffffff806fcebc <+8>: sd s1,24(sp) - 0xffffffff806fcec0 <+12>: sd s2,16(sp) - 0xffffffff806fcec4 <+16>: sd s3,8(sp) - 0xffffffff806fcec8 <+20>: sd ra,40(sp) - 0xffffffff806fcecc <+24>: addi s0,sp,48 - -Signed-off-by: Guo Ren -Signed-off-by: Guo Ren -Link: https://lore.kernel.org/r/20230112090603.1295340-3-guoren@kernel.org -Cc: stable@vger.kernel.org -Signed-off-by: Palmer Dabbelt -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 16dc4a7e9b379..26ffd9e6a2818 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -13,7 +13,11 @@ LDFLAGS_vmlinux := - ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax - KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY -+ifeq ($(CONFIG_RISCV_ISA_C),y) - CC_FLAGS_FTRACE := -fpatchable-function-entry=8 -+else -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=4 -+endif - endif - KBUILD_AFLAGS_MODULE += -fPIC - KBUILD_CFLAGS_MODULE += -fPIC --- -2.39.2 - diff --git a/queue-5.4/riscv-using-patchable_function_entry-instead-of-mcou.patch b/queue-5.4/riscv-using-patchable_function_entry-instead-of-mcou.patch deleted file mode 100644 index 77528335361..00000000000 --- a/queue-5.4/riscv-using-patchable_function_entry-instead-of-mcou.patch +++ /dev/null @@ -1,600 +0,0 @@ -From 90df613c317f4d768516001b773fde681377bc27 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Thu, 17 Dec 2020 16:01:41 +0000 -Subject: riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT - -From: Guo Ren - -[ Upstream commit afc76b8b80112189b6f11e67e19cf58301944814 ] - -This patch changes the current detour mechanism of dynamic ftrace -which has been discussed during LPC 2020 RISCV-MC [1]. - -Before the patch, we used mcount for detour: -: - addi sp,sp,-16 - sd ra,8(sp) - sd s0,0(sp) - addi s0,sp,16 - mv a5,ra - mv a0,a5 - auipc ra,0x0 -> nop - jalr -296(ra) <_mcount@plt> ->nop - ... - -After the patch, we use nop call site area for detour: -: - nop -> REG_S ra, -SZREG(sp) - nop -> auipc ra, 0x? - nop -> jalr ?(ra) - nop -> REG_L ra, -SZREG(sp) - ... - -The mcount mechanism is mixed with gcc function prologue which is -not very clear. The patchable function entry just put 16 bytes nop -before the front of the function prologue which could be filled -with a separated detour mechanism. - -[1] https://www.linuxplumbersconf.org/event/7/contributions/807/ - -Signed-off-by: Guo Ren -Signed-off-by: Palmer Dabbelt -Stable-dep-of: 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C") -Signed-off-by: Sasha Levin ---- - arch/riscv/Makefile | 2 + - arch/riscv/kernel/ftrace.c | 95 ++++----- - arch/riscv/kernel/mcount-dyn.S | 342 +++++++++++++++------------------ - 3 files changed, 204 insertions(+), 235 deletions(-) - -diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile -index 1641d82014127..16dc4a7e9b379 100644 ---- a/arch/riscv/Makefile -+++ b/arch/riscv/Makefile -@@ -12,6 +12,8 @@ OBJCOPYFLAGS := -O binary - LDFLAGS_vmlinux := - ifeq ($(CONFIG_DYNAMIC_FTRACE),y) - LDFLAGS_vmlinux := --no-relax -+ KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY -+ CC_FLAGS_FTRACE := -fpatchable-function-entry=8 - endif - KBUILD_AFLAGS_MODULE += -fPIC - KBUILD_CFLAGS_MODULE += -fPIC -diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c -index 291c579e12457..d42df2d561ddd 100644 ---- a/arch/riscv/kernel/ftrace.c -+++ b/arch/riscv/kernel/ftrace.c -@@ -63,29 +63,56 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, - return 0; - } - -+/* -+ * Put 5 instructions with 16 bytes at the front of function within -+ * patchable function entry nops' area. -+ * -+ * 0: REG_S ra, -SZREG(sp) -+ * 1: auipc ra, 0x? -+ * 2: jalr -?(ra) -+ * 3: REG_L ra, -SZREG(sp) -+ * -+ * So the opcodes is: -+ * 0: 0xfe113c23 (sd)/0xfe112e23 (sw) -+ * 1: 0x???????? -> auipc -+ * 2: 0x???????? -> jalr -+ * 3: 0xff813083 (ld)/0xffc12083 (lw) -+ */ -+#if __riscv_xlen == 64 -+#define INSN0 0xfe113c23 -+#define INSN3 0xff813083 -+#elif __riscv_xlen == 32 -+#define INSN0 0xfe112e23 -+#define INSN3 0xffc12083 -+#endif -+ -+#define FUNC_ENTRY_SIZE 16 -+#define FUNC_ENTRY_JMP 4 -+ - int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) - { -- int ret = ftrace_check_current_call(rec->ip, NULL); -+ unsigned int call[4] = {INSN0, 0, 0, INSN3}; -+ unsigned long target = addr; -+ unsigned long caller = rec->ip + FUNC_ENTRY_JMP; - -- if (ret) -- return ret; -+ call[1] = to_auipc_insn((unsigned int)(target - caller)); -+ call[2] = to_jalr_insn((unsigned int)(target - caller)); - -- return __ftrace_modify_call(rec->ip, addr, true); -+ if (patch_text_nosync((void *)rec->ip, call, FUNC_ENTRY_SIZE)) -+ return -EPERM; -+ -+ return 0; - } - - int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, - unsigned long addr) - { -- unsigned int call[2]; -- int ret; -+ unsigned int nops[4] = {NOP4, NOP4, NOP4, NOP4}; - -- make_call(rec->ip, addr, call); -- ret = ftrace_check_current_call(rec->ip, call); -- -- if (ret) -- return ret; -+ if (patch_text_nosync((void *)rec->ip, nops, FUNC_ENTRY_SIZE)) -+ return -EPERM; - -- return __ftrace_modify_call(rec->ip, addr, false); -+ return 0; - } - - -@@ -130,15 +157,16 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, - unsigned long addr) - { - unsigned int call[2]; -+ unsigned long caller = rec->ip + FUNC_ENTRY_JMP; - int ret; - -- make_call(rec->ip, old_addr, call); -- ret = ftrace_check_current_call(rec->ip, call); -+ make_call(caller, old_addr, call); -+ ret = ftrace_check_current_call(caller, call); - - if (ret) - return ret; - -- return __ftrace_modify_call(rec->ip, addr, true); -+ return __ftrace_modify_call(caller, addr, true); - } - #endif - -@@ -167,53 +195,30 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, - - #ifdef CONFIG_DYNAMIC_FTRACE - extern void ftrace_graph_call(void); -+extern void ftrace_graph_regs_call(void); - int ftrace_enable_ftrace_graph_caller(void) - { -- unsigned int call[2]; -- static int init_graph = 1; - int ret; - -- make_call(&ftrace_graph_call, &ftrace_stub, call); -- -- /* -- * When enabling graph tracer for the first time, ftrace_graph_call -- * should contains a call to ftrace_stub. Once it has been disabled, -- * the 8-bytes at the position becomes NOPs. -- */ -- if (init_graph) { -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- call); -- init_graph = 0; -- } else { -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- NULL); -- } -- -+ ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ (unsigned long)&prepare_ftrace_return, true); - if (ret) - return ret; - -- return __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, - (unsigned long)&prepare_ftrace_return, true); - } - - int ftrace_disable_ftrace_graph_caller(void) - { -- unsigned int call[2]; - int ret; - -- make_call(&ftrace_graph_call, &prepare_ftrace_return, call); -- -- /* -- * This is to make sure that ftrace_enable_ftrace_graph_caller -- * did the right thing. -- */ -- ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, -- call); -- -+ ret = __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ (unsigned long)&prepare_ftrace_return, false); - if (ret) - return ret; - -- return __ftrace_modify_call((unsigned long)&ftrace_graph_call, -+ return __ftrace_modify_call((unsigned long)&ftrace_graph_regs_call, - (unsigned long)&prepare_ftrace_return, false); - } - #endif /* CONFIG_DYNAMIC_FTRACE */ -diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S -index 35a6ed76cb8b7..d171eca623b6f 100644 ---- a/arch/riscv/kernel/mcount-dyn.S -+++ b/arch/riscv/kernel/mcount-dyn.S -@@ -13,224 +13,186 @@ - - .text - -- .macro SAVE_ABI_STATE --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi sp, sp, -48 -- sd s0, 32(sp) -- sd ra, 40(sp) -- addi s0, sp, 48 -- sd t0, 24(sp) -- sd t1, 16(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- sd t2, 8(sp) --#endif --#else -- addi sp, sp, -16 -- sd s0, 0(sp) -- sd ra, 8(sp) -- addi s0, sp, 16 --#endif -+#define FENTRY_RA_OFFSET 12 -+#define ABI_SIZE_ON_STACK 72 -+#define ABI_A0 0 -+#define ABI_A1 8 -+#define ABI_A2 16 -+#define ABI_A3 24 -+#define ABI_A4 32 -+#define ABI_A5 40 -+#define ABI_A6 48 -+#define ABI_A7 56 -+#define ABI_RA 64 -+ -+ .macro SAVE_ABI -+ addi sp, sp, -SZREG -+ addi sp, sp, -ABI_SIZE_ON_STACK -+ -+ REG_S a0, ABI_A0(sp) -+ REG_S a1, ABI_A1(sp) -+ REG_S a2, ABI_A2(sp) -+ REG_S a3, ABI_A3(sp) -+ REG_S a4, ABI_A4(sp) -+ REG_S a5, ABI_A5(sp) -+ REG_S a6, ABI_A6(sp) -+ REG_S a7, ABI_A7(sp) -+ REG_S ra, ABI_RA(sp) - .endm - -- .macro RESTORE_ABI_STATE --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- ld s0, 32(sp) -- ld ra, 40(sp) -- addi sp, sp, 48 --#else -- ld ra, 8(sp) -- ld s0, 0(sp) -- addi sp, sp, 16 --#endif -+ .macro RESTORE_ABI -+ REG_L a0, ABI_A0(sp) -+ REG_L a1, ABI_A1(sp) -+ REG_L a2, ABI_A2(sp) -+ REG_L a3, ABI_A3(sp) -+ REG_L a4, ABI_A4(sp) -+ REG_L a5, ABI_A5(sp) -+ REG_L a6, ABI_A6(sp) -+ REG_L a7, ABI_A7(sp) -+ REG_L ra, ABI_RA(sp) -+ -+ addi sp, sp, ABI_SIZE_ON_STACK -+ addi sp, sp, SZREG - .endm - -- .macro RESTORE_GRAPH_ARGS -- ld a0, 24(sp) -- ld a1, 16(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld a2, 8(sp) --#endif -+#ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS -+ .macro SAVE_ALL -+ addi sp, sp, -SZREG -+ addi sp, sp, -PT_SIZE_ON_STACK -+ -+ REG_S x1, PT_EPC(sp) -+ addi sp, sp, PT_SIZE_ON_STACK -+ REG_L x1, (sp) -+ addi sp, sp, -PT_SIZE_ON_STACK -+ REG_S x1, PT_RA(sp) -+ REG_L x1, PT_EPC(sp) -+ -+ REG_S x2, PT_SP(sp) -+ REG_S x3, PT_GP(sp) -+ REG_S x4, PT_TP(sp) -+ REG_S x5, PT_T0(sp) -+ REG_S x6, PT_T1(sp) -+ REG_S x7, PT_T2(sp) -+ REG_S x8, PT_S0(sp) -+ REG_S x9, PT_S1(sp) -+ REG_S x10, PT_A0(sp) -+ REG_S x11, PT_A1(sp) -+ REG_S x12, PT_A2(sp) -+ REG_S x13, PT_A3(sp) -+ REG_S x14, PT_A4(sp) -+ REG_S x15, PT_A5(sp) -+ REG_S x16, PT_A6(sp) -+ REG_S x17, PT_A7(sp) -+ REG_S x18, PT_S2(sp) -+ REG_S x19, PT_S3(sp) -+ REG_S x20, PT_S4(sp) -+ REG_S x21, PT_S5(sp) -+ REG_S x22, PT_S6(sp) -+ REG_S x23, PT_S7(sp) -+ REG_S x24, PT_S8(sp) -+ REG_S x25, PT_S9(sp) -+ REG_S x26, PT_S10(sp) -+ REG_S x27, PT_S11(sp) -+ REG_S x28, PT_T3(sp) -+ REG_S x29, PT_T4(sp) -+ REG_S x30, PT_T5(sp) -+ REG_S x31, PT_T6(sp) - .endm - --ENTRY(ftrace_graph_caller) -- addi sp, sp, -16 -- sd s0, 0(sp) -- sd ra, 8(sp) -- addi s0, sp, 16 --ftrace_graph_call: -- .global ftrace_graph_call -- /* -- * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the -- * call below. Check ftrace_modify_all_code for details. -- */ -- call ftrace_stub -- ld ra, 8(sp) -- ld s0, 0(sp) -- addi sp, sp, 16 -- ret --ENDPROC(ftrace_graph_caller) -+ .macro RESTORE_ALL -+ REG_L x1, PT_RA(sp) -+ addi sp, sp, PT_SIZE_ON_STACK -+ REG_S x1, (sp) -+ addi sp, sp, -PT_SIZE_ON_STACK -+ REG_L x1, PT_EPC(sp) -+ REG_L x2, PT_SP(sp) -+ REG_L x3, PT_GP(sp) -+ REG_L x4, PT_TP(sp) -+ REG_L x5, PT_T0(sp) -+ REG_L x6, PT_T1(sp) -+ REG_L x7, PT_T2(sp) -+ REG_L x8, PT_S0(sp) -+ REG_L x9, PT_S1(sp) -+ REG_L x10, PT_A0(sp) -+ REG_L x11, PT_A1(sp) -+ REG_L x12, PT_A2(sp) -+ REG_L x13, PT_A3(sp) -+ REG_L x14, PT_A4(sp) -+ REG_L x15, PT_A5(sp) -+ REG_L x16, PT_A6(sp) -+ REG_L x17, PT_A7(sp) -+ REG_L x18, PT_S2(sp) -+ REG_L x19, PT_S3(sp) -+ REG_L x20, PT_S4(sp) -+ REG_L x21, PT_S5(sp) -+ REG_L x22, PT_S6(sp) -+ REG_L x23, PT_S7(sp) -+ REG_L x24, PT_S8(sp) -+ REG_L x25, PT_S9(sp) -+ REG_L x26, PT_S10(sp) -+ REG_L x27, PT_S11(sp) -+ REG_L x28, PT_T3(sp) -+ REG_L x29, PT_T4(sp) -+ REG_L x30, PT_T5(sp) -+ REG_L x31, PT_T6(sp) -+ -+ addi sp, sp, PT_SIZE_ON_STACK -+ addi sp, sp, SZREG -+ .endm -+#endif /* CONFIG_DYNAMIC_FTRACE_WITH_REGS */ - - ENTRY(ftrace_caller) -- /* -- * a0: the address in the caller when calling ftrace_caller -- * a1: the caller's return address -- * a2: the address of global variable function_trace_op -- */ -- ld a1, -8(s0) -- addi a0, ra, -MCOUNT_INSN_SIZE -- la t5, function_trace_op -- ld a2, 0(t5) -+ SAVE_ABI - --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- /* -- * the graph tracer (specifically, prepare_ftrace_return) needs these -- * arguments but for now the function tracer occupies the regs, so we -- * save them in temporary regs to recover later. -- */ -- addi t0, s0, -8 -- mv t1, a0 --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld t2, -16(s0) --#endif --#endif -+ addi a0, ra, -FENTRY_RA_OFFSET -+ la a1, function_trace_op -+ REG_L a2, 0(a1) -+ REG_L a1, ABI_SIZE_ON_STACK(sp) -+ mv a3, sp - -- SAVE_ABI_STATE - ftrace_call: - .global ftrace_call -- /* -- * For the dynamic ftrace to work, here we should reserve at least -- * 8 bytes for a functional auipc-jalr pair. The following call -- * serves this purpose. -- * -- * Calling ftrace_update_ftrace_func would overwrite the nops below. -- * Check ftrace_modify_all_code for details. -- */ - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- RESTORE_GRAPH_ARGS -- call ftrace_graph_caller -+ addi a0, sp, ABI_SIZE_ON_STACK -+ REG_L a1, ABI_RA(sp) -+ addi a1, a1, -FENTRY_RA_OFFSET -+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -+ mv a2, s0 - #endif -- -- RESTORE_ABI_STATE -+ftrace_graph_call: -+ .global ftrace_graph_call -+ call ftrace_stub -+#endif -+ RESTORE_ABI - ret - ENDPROC(ftrace_caller) - - #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS -- .macro SAVE_ALL -- addi sp, sp, -(PT_SIZE_ON_STACK+16) -- sd s0, (PT_SIZE_ON_STACK)(sp) -- sd ra, (PT_SIZE_ON_STACK+8)(sp) -- addi s0, sp, (PT_SIZE_ON_STACK+16) -- -- sd x1, PT_RA(sp) -- sd x2, PT_SP(sp) -- sd x3, PT_GP(sp) -- sd x4, PT_TP(sp) -- sd x5, PT_T0(sp) -- sd x6, PT_T1(sp) -- sd x7, PT_T2(sp) -- sd x8, PT_S0(sp) -- sd x9, PT_S1(sp) -- sd x10, PT_A0(sp) -- sd x11, PT_A1(sp) -- sd x12, PT_A2(sp) -- sd x13, PT_A3(sp) -- sd x14, PT_A4(sp) -- sd x15, PT_A5(sp) -- sd x16, PT_A6(sp) -- sd x17, PT_A7(sp) -- sd x18, PT_S2(sp) -- sd x19, PT_S3(sp) -- sd x20, PT_S4(sp) -- sd x21, PT_S5(sp) -- sd x22, PT_S6(sp) -- sd x23, PT_S7(sp) -- sd x24, PT_S8(sp) -- sd x25, PT_S9(sp) -- sd x26, PT_S10(sp) -- sd x27, PT_S11(sp) -- sd x28, PT_T3(sp) -- sd x29, PT_T4(sp) -- sd x30, PT_T5(sp) -- sd x31, PT_T6(sp) -- .endm -- -- .macro RESTORE_ALL -- ld x1, PT_RA(sp) -- ld x2, PT_SP(sp) -- ld x3, PT_GP(sp) -- ld x4, PT_TP(sp) -- ld x5, PT_T0(sp) -- ld x6, PT_T1(sp) -- ld x7, PT_T2(sp) -- ld x8, PT_S0(sp) -- ld x9, PT_S1(sp) -- ld x10, PT_A0(sp) -- ld x11, PT_A1(sp) -- ld x12, PT_A2(sp) -- ld x13, PT_A3(sp) -- ld x14, PT_A4(sp) -- ld x15, PT_A5(sp) -- ld x16, PT_A6(sp) -- ld x17, PT_A7(sp) -- ld x18, PT_S2(sp) -- ld x19, PT_S3(sp) -- ld x20, PT_S4(sp) -- ld x21, PT_S5(sp) -- ld x22, PT_S6(sp) -- ld x23, PT_S7(sp) -- ld x24, PT_S8(sp) -- ld x25, PT_S9(sp) -- ld x26, PT_S10(sp) -- ld x27, PT_S11(sp) -- ld x28, PT_T3(sp) -- ld x29, PT_T4(sp) -- ld x30, PT_T5(sp) -- ld x31, PT_T6(sp) -- -- ld s0, (PT_SIZE_ON_STACK)(sp) -- ld ra, (PT_SIZE_ON_STACK+8)(sp) -- addi sp, sp, (PT_SIZE_ON_STACK+16) -- .endm -- -- .macro RESTORE_GRAPH_REG_ARGS -- ld a0, PT_T0(sp) -- ld a1, PT_T1(sp) --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld a2, PT_T2(sp) --#endif -- .endm -- --/* -- * Most of the contents are the same as ftrace_caller. -- */ - ENTRY(ftrace_regs_caller) -- /* -- * a3: the address of all registers in the stack -- */ -- ld a1, -8(s0) -- addi a0, ra, -MCOUNT_INSN_SIZE -- la t5, function_trace_op -- ld a2, 0(t5) -- addi a3, sp, -(PT_SIZE_ON_STACK+16) -- --#ifdef CONFIG_FUNCTION_GRAPH_TRACER -- addi t0, s0, -8 -- mv t1, a0 --#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -- ld t2, -16(s0) --#endif --#endif - SAVE_ALL - -+ addi a0, ra, -FENTRY_RA_OFFSET -+ la a1, function_trace_op -+ REG_L a2, 0(a1) -+ REG_L a1, PT_SIZE_ON_STACK(sp) -+ mv a3, sp -+ - ftrace_regs_call: - .global ftrace_regs_call - call ftrace_stub - - #ifdef CONFIG_FUNCTION_GRAPH_TRACER -- RESTORE_GRAPH_REG_ARGS -- call ftrace_graph_caller -+ addi a0, sp, PT_RA -+ REG_L a1, PT_EPC(sp) -+ addi a1, a1, -FENTRY_RA_OFFSET -+#ifdef HAVE_FUNCTION_GRAPH_FP_TEST -+ mv a2, s0 -+#endif -+ftrace_graph_regs_call: -+ .global ftrace_graph_regs_call -+ call ftrace_stub - #endif - - RESTORE_ALL --- -2.39.2 - diff --git a/queue-5.4/series b/queue-5.4/series index 344e01fea96..b1e2a6df78d 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -21,8 +21,6 @@ ipmi-ssif-increase-the-message-retry-time.patch ipmi-ssif-add-a-timer-between-request-retries.patch irqdomain-change-the-type-of-size-in-__irq_domain_ad.patch irqdomain-fix-domain-registration-race.patch -riscv-using-patchable_function_entry-instead-of-mcou.patch -riscv-ftrace-remove-wasted-nops-for-riscv_isa_c.patch iommu-vt-d-fix-pasid-directory-pointer-coherency.patch arm-dts-exynos-override-thermal-by-label-in-exynos42.patch arm-dts-exynos-correct-tmu-phandle-in-exynos4210.patch @@ -33,9 +31,6 @@ arm-dts-exynos-correct-tmu-phandle-in-odroid-hc1.patch arm-dts-exynos-correct-tmu-phandle-in-odroid-xu3-fam.patch smb3-backup-intent-flag-missing-from-some-more-ops.patch cifs-fix-uninitialized-memory-read-in-smb3_qfs_tcon.patch -riscv-abstract-out-csr-names-for-supervisor-vs-machi.patch -risc-v-avoid-dereferening-null-regs-in-die.patch -riscv-avoid-enabling-interrupts-in-die.patch scsi-core-remove-the-proc-scsi-proc_name-directory-e.patch ext4-fix-possible-corruption-when-moving-a-directory.patch drm-msm-a5xx-fix-setting-of-the-cp_preempt_enable_lo.patch