No one cares about this arch on those old trees.
+++ /dev/null
-From 9385d1c7aeff25710c0423b0e63cd659cd755daf Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Jan 2023 04:05:59 -0500
-Subject: riscv: ftrace: Reduce the detour code size to half
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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:
-<func_prolog>:
- 0: REG_S ra, -SZREG(sp)
- 4: auipc ra, ?
- 8: jalr ?(ra)
-12: REG_L ra, -SZREG(sp)
- (func_boddy)
-
-After the patch:
-<func_prolog>:
- 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
-<func_prolog+12> 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 <suagrfillet@gmail.com>
-Signed-off-by: Song Shuai <suagrfillet@gmail.com>
-Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
-Signed-off-by: Guo Ren <guoren@kernel.org>
-Cc: Evgenii Shatokhin <e.shatokhin@yadro.com>
-Reviewed-by: Evgenii Shatokhin <e.shatokhin@yadro.com>
-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 <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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)
- *
-+ *<ftrace enable>:
-+ * 0: auipc t0/ra, 0x?
-+ * 4: jalr t0/ra, ?(t0/ra)
-+ *
-+ *<ftrace disable>:
-+ * 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
-
+++ /dev/null
-From 2bb876ceceeb443eb49400f1e7222c467e6f858f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Jan 2023 04:05:58 -0500
-Subject: riscv: ftrace: Remove wasted nops for !RISCV_ISA_C
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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
-<ftrace_caller>
- 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 <guoren@linux.alibaba.com>
-Signed-off-by: Guo Ren <guoren@kernel.org>
-Link: https://lore.kernel.org/r/20230112090603.1295340-3-guoren@kernel.org
-Cc: stable@vger.kernel.org
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From abf571023a017240202a094778d26e61ee6d0ce2 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 17 Dec 2020 16:01:41 +0000
-Subject: riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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:
-<funca>:
- 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:
-<funca>:
- 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 <guoren@linux.alibaba.com>
-Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Stable-dep-of: 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
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
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- 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
+#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 @@
+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 @@
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;
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 @@
#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.
+ return ret;
}
NOKPROBE_SYMBOL(patch_text);
---
-2.39.2
-
+++ /dev/null
-From 584f80a2b4caa34c1809e9356be1b8300aa2923e Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Jan 2023 04:05:59 -0500
-Subject: riscv: ftrace: Reduce the detour code size to half
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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:
-<func_prolog>:
- 0: REG_S ra, -SZREG(sp)
- 4: auipc ra, ?
- 8: jalr ?(ra)
-12: REG_L ra, -SZREG(sp)
- (func_boddy)
-
-After the patch:
-<func_prolog>:
- 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
-<func_prolog+12> 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 <suagrfillet@gmail.com>
-Signed-off-by: Song Shuai <suagrfillet@gmail.com>
-Signed-off-by: Guo Ren <guoren@linux.alibaba.com>
-Signed-off-by: Guo Ren <guoren@kernel.org>
-Cc: Evgenii Shatokhin <e.shatokhin@yadro.com>
-Reviewed-by: Evgenii Shatokhin <e.shatokhin@yadro.com>
-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 <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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)
- *
-+ *<ftrace enable>:
-+ * 0: auipc t0/ra, 0x?
-+ * 4: jalr t0/ra, ?(t0/ra)
-+ *
-+ *<ftrace disable>:
-+ * 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
-
+++ /dev/null
-From 008af635bed0d4f0d83564b2b3986ed14472119b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Jan 2023 04:05:58 -0500
-Subject: riscv: ftrace: Remove wasted nops for !RISCV_ISA_C
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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
-<ftrace_caller>
- 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 <guoren@linux.alibaba.com>
-Signed-off-by: Guo Ren <guoren@kernel.org>
-Link: https://lore.kernel.org/r/20230112090603.1295340-3-guoren@kernel.org
-Cc: stable@vger.kernel.org
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From adebc8817b5c975d598ac379bbdf67a7a5186ade Mon Sep 17 00:00:00 2001
-From: Nathan Chancellor <nathan@kernel.org>
-Date: Thu, 25 Mar 2021 15:38:07 -0700
-Subject: riscv: Select HAVE_DYNAMIC_FTRACE when -fpatchable-function-entry is available
-
-From: Nathan Chancellor <nathan@kernel.org>
-
-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 <lkp@intel.com>
-Signed-off-by: Nathan Chancellor <nathan@kernel.org>
-Reviewed-by: Fangrui Song <maskray@google.com>
-Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- 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
+++ /dev/null
-From abb0542c5e210048f5905f02935615dc315a5240 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 17 Dec 2020 16:01:41 +0000
-Subject: riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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:
-<funca>:
- 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:
-<funca>:
- 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 <guoren@linux.alibaba.com>
-Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Stable-dep-of: 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
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
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
+++ /dev/null
-From bf37e6388dc21d42ea1cdca38b9ac990b4042fed Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Tue, 20 Sep 2022 13:00:37 -0700
-Subject: RISC-V: Avoid dereferening NULL regs in die()
-
-From: Palmer Dabbelt <palmer@rivosinc.com>
-
-[ 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 <lkp@intel.com>
-Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
-Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
-Link: https://lore.kernel.org/r/20220920200037.6727-1-palmer@rivosinc.com
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Stable-dep-of: 130aee3fd998 ("riscv: Avoid enabling interrupts in die()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From 3ef295cec87891ddcce650d9aea368d2179be8c9 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 28 Oct 2019 13:10:32 +0100
-Subject: riscv: abstract out CSR names for supervisor vs machine mode
-
-From: Christoph Hellwig <hch@lst.de>
-
-[ 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 <Damien.LeMoal@wdc.com>
-and Paul Walmsley <paul.walmsley@sifive.com>.
-
-Signed-off-by: Christoph Hellwig <hch@lst.de>
-Acked-by: Thomas Gleixner <tglx@linutronix.de> # for drivers/clocksource, drivers/irqchip
-[paul.walmsley@sifive.com: updated to apply]
-Signed-off-by: Paul Walmsley <paul.walmsley@sifive.com>
-Stable-dep-of: 130aee3fd998 ("riscv: Avoid enabling interrupts in die()")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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 <linux/seq_file.h>
- #include <asm/smp.h>
-
--/*
-- * 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
-
+++ /dev/null
-From d52b7f5ca92c5ccfd25076035a3bc1d329e7d83b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-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 <mnissler@rivosinc.com>
-
-[ 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 <mnissler@rivosinc.com>
-Reviewed-by: Björn Töpel <bjorn@kernel.org>
-Link: https://lore.kernel.org/r/20230215144828.3370316-1-mnissler@rivosinc.com
-Cc: stable@vger.kernel.org
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From 90d2039dfb03cdc912ca5b796940853ee5c978ab Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 12 Jan 2023 04:05:58 -0500
-Subject: riscv: ftrace: Remove wasted nops for !RISCV_ISA_C
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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
-<ftrace_caller>
- 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 <guoren@linux.alibaba.com>
-Signed-off-by: Guo Ren <guoren@kernel.org>
-Link: https://lore.kernel.org/r/20230112090603.1295340-3-guoren@kernel.org
-Cc: stable@vger.kernel.org
-Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
+++ /dev/null
-From 90df613c317f4d768516001b773fde681377bc27 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Thu, 17 Dec 2020 16:01:41 +0000
-Subject: riscv: Using PATCHABLE_FUNCTION_ENTRY instead of MCOUNT
-
-From: Guo Ren <guoren@linux.alibaba.com>
-
-[ 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:
-<funca>:
- 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:
-<funca>:
- 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 <guoren@linux.alibaba.com>
-Signed-off-by: Palmer Dabbelt <palmerdabbelt@google.com>
-Stable-dep-of: 409c8fb20c66 ("riscv: ftrace: Remove wasted nops for !RISCV_ISA_C")
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- 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
-
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
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