riscv: Add GENERIC_ENTRY, irq stack support
Subsystems (3)
v4 cover riscv: Add GENERIC_ENTRY, irq stack support
From: Guo Ren <[email protected]>
The patches convert riscv to use the generic entry infrastructure from kernel/entry/*. Add independent irq stacks (IRQ_STACKS) for percpu to prevent kernel stack overflows. Add the HAVE_SOFTIRQ_ON_OWN_STACK feature for the IRQ_STACKS config. You can try it directly with [1].
[1] https://github.com/guoren83/linux/tree/generic_entry_v4
V4:
- Fixup entry.S with "la" bug (by Conor.Dooley)
- Fixup missing noinstr bug (by Peter Ziji)
V3: https://lore.kernel.org/linux-riscv/[email protected]/
- Fixup CONFIG_COMPAT=n compile error
- Add THREAD_SIZE_ORDER config
- Optimize elf_kexec.c warning fixup
- Add static to irq_stack_ptr definition
V2: https://lore.kernel.org/linux-riscv/[email protected]/
- Fixup compile error by include "riscv: ptrace: Remove duplicate operation"
- Fixup compile warning
- Add test repo link in cover letter
V1: https://lore.kernel.org/linux-riscv/[email protected]/
Guo Ren (8):
riscv: elf_kexec: Fixup compile warning
riscv: compat_syscall_table: Fixup compile warning
riscv: ptrace: Remove duplicate operation
riscv: traps: Add noinstr to prevent instrumentation inserted
riscv: convert to generic entry
riscv: Support HAVE_IRQ_EXIT_ON_IRQ_STACK
riscv: Support HAVE_SOFTIRQ_ON_OWN_STACK
riscv: Add config of thread stack size
arch/riscv/Kconfig | 19 ++ arch/riscv/include/asm/csr.h | 1 - arch/riscv/include/asm/entry-common.h | 8 + arch/riscv/include/asm/irq.h | 3 + arch/riscv/include/asm/ptrace.h | 10 +- arch/riscv/include/asm/stacktrace.h | 5 + arch/riscv/include/asm/syscall.h | 6 + arch/riscv/include/asm/thread_info.h | 19 +- arch/riscv/include/asm/vmap_stack.h | 28 +++ arch/riscv/kernel/Makefile | 1 + arch/riscv/kernel/elf_kexec.c | 2 +- arch/riscv/kernel/entry.S | 255 +++++--------------------- arch/riscv/kernel/irq.c | 75 ++++++++ arch/riscv/kernel/ptrace.c | 41 ----- arch/riscv/kernel/signal.c | 21 +-- arch/riscv/kernel/sys_riscv.c | 27 +++ arch/riscv/kernel/traps.c | 19 +- arch/riscv/mm/fault.c | 12 +- 18 files changed, 263 insertions(+), 289 deletions(-) create mode 100644 arch/riscv/include/asm/entry-common.h create mode 100644 arch/riscv/include/asm/vmap_stack.h
Signature · 1 line
2.36.1
PATCH v4 1/8 riscv: elf_kexec: Fixup compile warning
From: Guo Ren <[email protected]>
If CRYTPO or CRYPTO_SHA256 or KEXE_FILE is not enabled, then:
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=riscv SHELL=/bin/bash arch/riscv/
../arch/riscv/kernel/elf_kexec.c: In function 'elf_kexec_load':../arch/riscv/kernel/elf_kexec.c:185:23: warning: variable 'kernel_start' set but not used [-Wunused-but-set-variable]
185 | unsigned long kernel_start;
| ^~~~~~~~~~~~--- arch/riscv/kernel/elf_kexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/elf_kexec.c +1 -1
@@ -198,7 +198,7 @@ static void *elf_kexec_load(struct kimage *image, char *kernel_buf,if (ret) goto out; kernel_start = image->start; -pr_notice ("The entry point of kernel at 0x%lx\n" , image->start); +pr_notice ("The entry point of kernel at 0x%lx\n" , kernel_start);/* Add the kernel binary to the image */ ret = riscv_kexec_elf_load(image, &ehdr, &elf_info,
Signature · 1 line
2.36.1
PATCH v4 2/8 riscv: compat_syscall_table: Fixup compile warning
In reply to [email protected]From: Guo Ren <[email protected]>
../arch/riscv/kernel/compat_syscall_table.c:12:41: warning: initialized field overwritten [-Woverride-init]
12 | #define __SYSCALL(nr, call) [nr] = (call),
| ^../include/uapi/asm-generic/unistd.h:567:1: note: in expansion of macro '__SYSCALL'
567 | __SYSCALL(__NR_semget, sys_semget)
--- arch/riscv/kernel/Makefile | 1 + 1 file changed, 1 insertion(+)
arch/riscv/kernel/Makefile +1 -0
@@ -9,6 +9,7 @@ CFLAGS_REMOVE_patch.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_sbi.o = $(CC_FLAGS_FTRACE) endif CFLAGS_syscall_table.o += $(call cc-option,-Wno-override-init,) +CFLAGS_compat_syscall_table.o += $(call cc-option,-Wno-override-init,) ifdef CONFIG_KEXEC AFLAGS_kexec_relocate.o := -mcmodel=medany $(call cc-option,-mno-relax)
Signature · 1 line
2.36.1
PATCH v4 3/8 riscv: ptrace: Remove duplicate operation
In reply to [email protected]From: Guo Ren <[email protected]>
The TIF_SYSCALL_TRACE is controlled by a common code, see kernel/ptrace.c and include/linux/thread.h.
clear_task_syscall_work(child, SYSCALL_TRACE);
--- arch/riscv/kernel/ptrace.c | 1 - 1 file changed, 1 deletion(-)
arch/riscv/kernel/ptrace.c +0 -1
@@ -212,7 +212,6 @@ unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)void ptrace_disable (struct task_struct *child) { -clear_tsk_thread_flag (child,TIF_SYSCALL_TRACE ); } long arch_ptrace(struct task_struct *child, long request,
Signature · 7 lines
2.36.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
PATCH v4 4/8 riscv: traps: Add noinstr to prevent instrumentation inserted
In reply to [email protected]From: Guo Ren <[email protected]>
Without noinstr the compiler is free to insert instrumentation (think all the k*SAN, KCov, GCov, ftrace etc..) which can call code we're not yet ready to run this early in the entry path, for instance it could rely on RCU which isn't on yet, or expect lockdep state. (by peterz)
--- arch/riscv/kernel/traps.c | 8 ++++---- arch/riscv/mm/fault.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
arch/riscv/kernel/traps.c +4 -4
@@ -97,7 +97,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,#define __trap_section#endif #define DO_ERROR_INFO (name, signo, code, str) \ -asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ +asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \ { \ do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \ }
@@ -121,7 +121,7 @@ DO_ERROR_INFO(do_trap_store_misaligned,int handle_misaligned_load (struct pt_regs *regs);int handle_misaligned_store (struct pt_regs *regs); -asmlinkage void __trap_section do_trap_load_misaligned(struct pt_regs *regs) +asmlinkage __trap_section void noinstr do_trap_load_misaligned(struct pt_regs *regs) {if (!handle_misaligned_load (regs))return ;
@@ -129,7 +129,7 @@ asmlinkage void __trap_section do_trap_load_misaligned(struct pt_regs *regs) "Oops - load address misaligned"); } -asmlinkage void __trap_section do_trap_store_misaligned(struct pt_regs *regs) +asmlinkage __trap_section void noinstr do_trap_store_misaligned(struct pt_regs *regs) {if (!handle_misaligned_store (regs))return ;
@@ -156,7 +156,7 @@ static inline unsigned long get_break_insn_length(unsigned long pc)return GET_INSN_LENGTH (insn); } -asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs) +asmlinkage __visible __trap_section void noinstr do_trap_break(struct pt_regs *regs) {#ifdef CONFIG_KPROBES if (kprobe_single_step_handler (regs))
arch/riscv/mm/fault.c +1 -1
@@ -203,7 +203,7 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)* This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. */ -asmlinkage void do_page_fault(struct pt_regs *regs) +asmlinkage void noinstr do_page_fault(struct pt_regs *regs) {struct task_struct *tsk;struct vm_area_struct *vma;
Signature · 7 lines
2.36.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 4/8] riscv: traps: Add noinstr to prevent instrumentation inserted
Quoted 21 lines · On Wed, Sep 07, 2022 at 10:25:02PM -0400, [email protected] wrote:
From: Guo Ren <[email protected]>
Without noinstr the compiler is free to insert instrumentation (think all the k*SAN, KCov, GCov, ftrace etc..) which can call code we're not yet ready to run this early in the entry path, for instance it could rely on RCU which isn't on yet, or expect lockdep state. (by peterz)
Suggested-by Peter Zijlstra <[email protected]>Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>--- arch/riscv/kernel/traps.c | 8 ++++---- arch/riscv/mm/fault.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)arch/riscv/kernel/traps.c +0
-0
arch/riscv/kernel/traps.c static void do_trap_error(struct pt_regs *regs, int signo, int code, · line 100
Quoted 5 lines
arch/riscv/kernel/traps.c +1
-1@@ -97,7 +97,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,#define __trap_section#endif #define DO_ERROR_INFO (name, signo, code, str) \ -asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ +asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \
But now you have __trap_section and noinstr both adding a section attribute.
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 4/8] riscv: traps: Add noinstr to prevent instrumentation inserted
Quoted 18 lines · Peter Zijlstra
Quoted 16 lines · On Wed, Sep 07, 2022 at 10:25:02PM -0400, [email protected] wrote:
From: Guo Ren <[email protected]>
Without noinstr the compiler is free to insert instrumentation (think all the k*SAN, KCov, GCov, ftrace etc..) which can call code we're not yet ready to run this early in the entry path, for instance it could rely on RCU which isn't on yet, or expect lockdep state. (by peterz)
Suggested-by Peter Zijlstra <[email protected]>Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>--- arch/riscv/kernel/traps.c | 8 ++++---- arch/riscv/mm/fault.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)
Quoted 13 lines
arch/riscv/kernel/traps.c static void do_trap_error(struct pt_regs *regs, int signo, int code, · line 100
Quoted 10 lines
arch/riscv/kernel/traps.c +1
-1@@ -97,7 +97,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,#define __trap_section#endif #define DO_ERROR_INFO (name, signo, code, str) \ -asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ +asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \But now you have
__trap_sectionand noinstr both adding a section attribute.
Oops, thx for correcting. Here is my solution.
arch/riscv/kernel/traps.c +0 -0
@@ -92,9 +92,11 @@ static void do_trap_error(struct pt_regs *regs, int
signo, int code,
}
#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_RISCV_ALTERNATIVE)
-#define __trap_section __section(".xip.traps")
+#define __trap_section \
+ noinline notrace __attribute((__section__(".xip.traps"))) \
+ __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage
#else
-#define __trap_section
+#define __trap_section noinstr
#endif
Signature · 7 lines
Best Regards Guo Ren _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 4/8] riscv: traps: Add noinstr to prevent instrumentation inserted
Quoted 41 lines · Guo Ren
Quoted 18 lines · Peter Zijlstra
Quoted 16 lines · On Wed, Sep 07, 2022 at 10:25:02PM -0400, [email protected] wrote:
From: Guo Ren <[email protected]>
Without noinstr the compiler is free to insert instrumentation (think all the k*SAN, KCov, GCov, ftrace etc..) which can call code we're not yet ready to run this early in the entry path, for instance it could rely on RCU which isn't on yet, or expect lockdep state. (by peterz)
Suggested-by Peter Zijlstra <[email protected]>Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>--- arch/riscv/kernel/traps.c | 8 ++++---- arch/riscv/mm/fault.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-)Quoted 13 lines
arch/riscv/kernel/traps.c static void do_trap_error(struct pt_regs *regs, int signo, int code, · line 100
Quoted 10 lines
arch/riscv/kernel/traps.c +1
-1@@ -97,7 +97,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,#define __trap_section#endif #define DO_ERROR_INFO (name, signo, code, str) \ -asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ +asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \But now you have
__trap_sectionand noinstr both adding a section attribute.Oops, thx for correcting. Here is my solution.
arch/riscv/kernel/traps.c +0
-0
arch/riscv/kernel/traps.c static void do_trap_error(struct pt_regs *regs, int · line 98
Quoted 8 lines
arch/riscv/kernel/traps.c +3
-1@@ -92,9 +92,11 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code, }#if defined(CONFIG_XIP_KERNEL ) && defined(CONFIG_RISCV_ALTERNATIVE ) -#define __trap_section __section(".xip.traps") +#define __trap_section \ + noinline notrace __attribute((__section__(".xip.traps"))) \ + __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage
How about let __section(".xip.traps") replace the __section__(".noinstr.text")? +#define __trap_section noinstr __attribute(__section(".xip.traps"))
Quoted 9 lines
arch/riscv/kernel/traps.c +1
-2#else -#define __trap_section +#define __trap_section noinstr#endif --Best Regards
Guo Ren
Signature · 2 lines
Best Regards Guo Ren
Re: [PATCH V4 4/8] riscv: traps: Add noinstr to prevent instrumentation inserted
In reply to Guo RenQuoted 15 lines · Guo Ren
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +1
-1-asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ +asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \But now you have
__trap_sectionand noinstr both adding a section attribute.Oops, thx for correcting. Here is my solution.
arch/riscv/kernel/traps.c +0
-0@@ -92,9 +92,11 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code, }
arch/riscv/kernel/traps.c static void do_trap_error(struct pt_regs *regs, int · line 101
Quoted 10 lines
arch/riscv/kernel/traps.c +4
-2#if defined(CONFIG_XIP_KERNEL ) && defined(CONFIG_RISCV_ALTERNATIVE ) -#define __trap_section __section(".xip.traps") +#define __trap_section \ + noinline notrace __attribute((__section__(".xip.traps"))) \ + __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage#else -#define __trap_section +#define __trap_section noinstr#endif
This is almost guaranteed to get out of sync when the compiler guys add yet another sanitizier. Please consider picking up this patch:
https://lore.kernel.org/all/[email protected]/
and using __noinstr_section(".xip.traps")
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 4/8] riscv: traps: Add noinstr to prevent instrumentation inserted
Quoted 32 lines · Peter Zijlstra
Quoted 15 lines · Guo Ren
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +1
-1-asmlinkage __visible __trap_section void name(struct pt_regs *regs) \ +asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \But now you have
__trap_sectionand noinstr both adding a section attribute.Oops, thx for correcting. Here is my solution.
arch/riscv/kernel/traps.c +0
-0@@ -92,9 +92,11 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code, }arch/riscv/kernel/traps.c static void do_trap_error(struct pt_regs *regs, int · line 101
Quoted 10 lines
arch/riscv/kernel/traps.c +4
-2#if defined(CONFIG_XIP_KERNEL ) && defined(CONFIG_RISCV_ALTERNATIVE ) -#define __trap_section __section(".xip.traps") +#define __trap_section \ + noinline notrace __attribute((__section__(".xip.traps"))) \ + __no_kcsan __no_sanitize_address __no_profile __no_sanitize_coverage#else -#define __trap_section +#define __trap_section noinstr#endif This is almost guaranteed to get out of sync when the compiler guys add yet another sanitizier. Please consider picking up this patch:
Quoted 1 line
Thx, that is what I want.
Quoted 2 lines
and using
__noinstr_section(".xip.traps")
Signature · 7 lines
Best Regards Guo Ren _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
PATCH v4 5/8 riscv: convert to generic entry
In reply to [email protected]From: Guo Ren <[email protected]>
This patch converts riscv to use the generic entry infrastructure from kernel/entry/*. The generic entry makes maintainers' work easier and codes more elegant. Here are the changes than before:
- More clear entry.S with handle_exception and ret_from_exception
- Get rid of complex custom signal implementation
- More readable syscall procedure
- Little modification on ret_from_fork & ret_from_kernel_thread
- Wrap with irqentry_enter/exit and syscall_enter/exit_from_user_mode
- Use the standard preemption code instead of custom
--- arch/riscv/Kconfig | 1 + arch/riscv/include/asm/csr.h | 1 - arch/riscv/include/asm/entry-common.h | 8 + arch/riscv/include/asm/ptrace.h | 10 +- arch/riscv/include/asm/stacktrace.h | 5 + arch/riscv/include/asm/syscall.h | 6 + arch/riscv/include/asm/thread_info.h | 13 +- arch/riscv/kernel/entry.S | 228 +++----------------------- arch/riscv/kernel/irq.c | 15 ++ arch/riscv/kernel/ptrace.c | 40 ----- arch/riscv/kernel/signal.c | 21 +-- arch/riscv/kernel/sys_riscv.c | 27 +++ arch/riscv/kernel/traps.c | 11 ++ arch/riscv/mm/fault.c | 12 +- 14 files changed, 117 insertions(+), 281 deletions(-) create mode 100644 arch/riscv/include/asm/entry-common.h
arch/riscv/Kconfig +1 -0
@@ -56,6 +56,7 @@ config RISCV select GENERIC_ATOMIC64 if !64BIT select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_EARLY_IOREMAP + select GENERIC_ENTRY select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO select GENERIC_IDLE_POLL_SETUP select GENERIC_IOREMAP if MMU
arch/riscv/include/asm/csr.h +0 -1
@@ -40,7 +40,6 @@#define SR_UXL _AC(0x300000000, UL)/* XLEN mask for U-mode */ #define SR_UXL_32 _AC(0x100000000, UL)/* XLEN = 32 for U-mode */ #define SR_UXL_64 _AC(0x200000000, UL)/* XLEN = 64 for U-mode */ -#define SR_UXL_SHIFT 32#endif /* SATP flags */
arch/riscv/include/asm/entry-common.h new file +8 -0
@@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_RISCV_ENTRY_COMMON_H +#define _ASM_RISCV_ENTRY_COMMON_H + +#include <asm/stacktrace.h> + +#endif /* _ASM_RISCV_ENTRY_COMMON_H */
arch/riscv/include/asm/ptrace.h +8 -2
@@ -53,6 +53,9 @@ struct pt_regs {unsigned long orig_a0; }; +#define PTRACE_SYSEMU 0x1f +#define PTRACE_SYSEMU_SINGLESTEP 0x20 +#ifdef CONFIG_64BIT #define REG_FMT "%016lx"#else
@@ -121,8 +124,6 @@ extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,void prepare_ftrace_return (unsigned long *parent,unsigned long self_addr,unsigned long frame_pointer); -int do_syscall_trace_enter (struct pt_regs *regs); -void do_syscall_trace_exit (struct pt_regs *regs);/** * regs_get_register() - get register value from its offset
@@ -172,6 +173,11 @@ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,return 0 ; } +static inline int regs_irqs_disabled (struct pt_regs *regs) +{ +return !(regs->status &SR_IE ); +} +#endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_PTRACE_H */
arch/riscv/include/asm/stacktrace.h +5 -0
@@ -16,4 +16,9 @@ extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *reextern void dump_backtrace (struct pt_regs *regs,struct task_struct *task,const char *loglvl); +static inline bool on_thread_stack (void ) +{ +return !(((unsigned long )(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE -1 )); +} +#endif /* _ASM_RISCV_STACKTRACE_H */
arch/riscv/include/asm/syscall.h +6 -0
@@ -74,5 +74,11 @@ static inline int syscall_get_arch(struct task_struct *task)#endif } +static inline bool arch_syscall_is_vdso_sigreturn (struct pt_regs *regs) +{ +return false; +} +asmlinkage long sys_riscv_flush_icache (uintptr_t ,uintptr_t ,uintptr_t ); +asmlinkage void do_sys_ecall_u(struct pt_regs *regs);#endif /* _ASM_RISCV_SYSCALL_H */
arch/riscv/include/asm/thread_info.h +1 -12
@@ -66,6 +66,7 @@ struct thread_info {long kernel_sp;/* Kernel stack pointer */ long user_sp;/* User stack pointer */ int cpu; +unsigned long syscall_work;/* SYSCALL_WORK_ flags */ };/*
@@ -88,26 +89,18 @@ struct thread_info {* - pending work-to-be-done flags are in lowest half-word * - other flags in upper half-word(s) */ -#define TIF_SYSCALL_TRACE 0/* syscall trace active */ #define TIF_NOTIFY_RESUME 1/* callback before returning to user */ #define TIF_SIGPENDING 2/* signal pending */ #define TIF_NEED_RESCHED 3/* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 4/* restore signal mask in do_signal() */ #define TIF_MEMDIE 5/* is terminating due to OOM killer */ -#define TIF_SYSCALL_TRACEPOINT 6/* syscall tracepoint instrumentation */ -#define TIF_SYSCALL_AUDIT 7/* syscall auditing */ -#define TIF_SECCOMP 8/* syscall secure computing */ #define TIF_NOTIFY_SIGNAL 9/* signal notifications exist */ #define TIF_UPROBE 10/* uprobe breakpoint or singlestep */ #define TIF_32BIT 11/* compat-mode 32bit process */ -#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) -#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -#define _TIF_SECCOMP (1 << TIF_SECCOMP)#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)#define _TIF_UPROBE (1 << TIF_UPROBE)
@@ -115,8 +108,4 @@ struct thread_info { (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_SIGNAL | _TIF_UPROBE) -#define _TIF_SYSCALL_WORK \ - (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT | \ - _TIF_SECCOMP) -#endif /* _ASM_RISCV_THREAD_INFO_H */
arch/riscv/kernel/entry.S +22 -206
312 lines not on this page · raw message
arch/riscv/kernel/irq.c +15 -0
@@ -5,6 +5,7 @@* Copyright (C) 2018 Christoph Hellwig */ +#include <linux/entry-common.h> #include <linux/interrupt.h> #include <linux/irqchip.h> #include <linux/seq_file.h>
@@ -22,3 +23,17 @@ void __init init_IRQ(void)if (!handle_arch_irq)panic ("No interrupt controller found." ); } + +asmlinkage void noinstr do_riscv_irq(struct pt_regs *regs) +{ +struct pt_regs *old_regs; +irqentry_state_t state =irqentry_enter (regs); + +irq_enter_rcu (); + old_regs =set_irq_regs (regs); +handle_arch_irq (regs); +set_irq_regs (old_regs); +irq_exit_rcu (); + +irqentry_exit (regs, state); +}
arch/riscv/kernel/ptrace.c +0 -40
@@ -228,46 +228,6 @@ long arch_ptrace(struct task_struct *child, long request,return ret; } -/* -* Allows PTRACE_SYSCALL to work. These are called from entry.S in -* {handle,ret_from}_syscall. -*/ -__visible int do_syscall_trace_enter(struct pt_regs *regs) -{ -if (test_thread_flag (TIF_SYSCALL_TRACE )) -if (ptrace_report_syscall_entry (regs)) -return -1 ; - -/* -* Do the secure computing after ptrace; failures should be fast. -* If this fails we might have return value in a0 from seccomp -* (via SECCOMP_RET_ERRNO/TRACE). -*/ -if (secure_computing () ==-1 ) -return -1 ; - -#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS -if (test_thread_flag (TIF_SYSCALL_TRACEPOINT )) -trace_sys_enter (regs,syscall_get_nr (current, regs)); -#endif - -audit_syscall_entry (regs->a7, regs->a0, regs->a1, regs->a2, regs->a3); -return 0 ; -} - -__visible void do_syscall_trace_exit(struct pt_regs *regs) -{ -audit_syscall_exit (regs); - -if (test_thread_flag (TIF_SYSCALL_TRACE )) -ptrace_report_syscall_exit (regs,0 ); - -#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS -if (test_thread_flag (TIF_SYSCALL_TRACEPOINT )) -trace_sys_exit (regs,regs_return_value (regs)); -#endif -} -#ifdef CONFIG_COMPAT static int compat_riscv_gpr_get(struct task_struct *target, const struct user_regset *regset,
arch/riscv/kernel/signal.c +2 -19
@@ -12,6 +12,7 @@#include <linux/syscalls.h> #include <linux/resume_user_mode.h> #include <linux/linkage.h> +#include <linux/entry-common.h> #include <asm/ucontext.h> #include <asm/vdso.h>
@@ -272,7 +273,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)signal_setup_done (ret, ksig,0 ); } -static void do_signal (struct pt_regs *regs) +void arch_do_signal_or_restart (struct pt_regs *regs) {struct ksignal ksig;
@@ -309,21 +310,3 @@ static void do_signal(struct pt_regs *regs)*/ restore_saved_sigmask (); } - -/* -* notification of userspace execution resumption -* - triggered by the _TIF_WORK_MASK flags -*/ -asmlinkage __visible void do_notify_resume(struct pt_regs *regs, -unsigned long thread_info_flags) -{ -if (thread_info_flags & _TIF_UPROBE) -uprobe_notify_resume (regs); - -/* Handle pending signal delivery */ -if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) -do_signal (regs); - -if (thread_info_flags & _TIF_NOTIFY_RESUME) -resume_user_mode_work (regs); -}
arch/riscv/kernel/sys_riscv.c +27 -0
@@ -5,8 +5,10 @@* Copyright (C) 2017 SiFive */ +#include <linux/entry-common.h> #include <linux/syscalls.h> #include <asm/unistd.h> +#include <asm/syscall.h> #include <asm/cacheflush.h> #include <asm-generic/mman-common.h>
@@ -72,3 +74,28 @@ SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,return 0 ; } + +typedef long (*syscall_t )(ulong ,ulong ,ulong ,ulong ,ulong ,ulong ,ulong ); + +asmlinkage void do_sys_ecall_u(struct pt_regs *regs) +{ +syscall_t syscall; +ulong nr = regs->a7; + + regs->epc +=4 ; + regs->orig_a0 = regs->a0; + regs->a0 = -ENOSYS ; + + nr =syscall_enter_from_user_mode (regs, nr); +#ifdef CONFIG_COMPAT +if ((regs->status &SR_UXL ) ==SR_UXL_32 ) + syscall = compat_sys_call_table[nr]; + else +#endif + syscall = sys_call_table[nr]; + +if (nr < NR_syscalls) + regs->a0 =syscall (regs->orig_a0, regs->a1, regs->a2, + regs->a3, regs->a4, regs->a5, regs->a6); +syscall_exit_to_user_mode (regs); +}
arch/riscv/kernel/traps.c +11 -0
@@ -17,6 +17,7 @@#include <linux/module.h> #include <linux/irq.h> #include <linux/kexec.h> +#include <linux/entry-common.h> #include <asm/asm-prototypes.h> #include <asm/bug.h>
@@ -99,7 +100,9 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,#define DO_ERROR_INFO (name, signo, code, str) \ asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \ { \ + irqentry_state_t state = irqentry_enter(regs); \ do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \ + irqentry_exit(regs, state); \ } DO_ERROR_INFO(do_trap_unknown,
@@ -123,18 +126,22 @@ int handle_misaligned_store(struct pt_regs *regs); asmlinkage __trap_section void noinstr do_trap_load_misaligned(struct pt_regs *regs) { +irqentry_state_t state =irqentry_enter (regs);if (!handle_misaligned_load (regs))return ;do_trap_error (regs,SIGBUS ,BUS_ADRALN , regs->epc,"Oops - load address misaligned" ); +irqentry_exit (regs, state); } asmlinkage __trap_section void noinstr do_trap_store_misaligned(struct pt_regs *regs) { +irqentry_state_t state =irqentry_enter (regs);if (!handle_misaligned_store (regs))return ;do_trap_error (regs,SIGBUS ,BUS_ADRALN , regs->epc,"Oops - store (or AMO) address misaligned" ); +irqentry_exit (regs, state); }#endif DO_ERROR_INFO(do_trap_store_fault,
@@ -158,6 +165,8 @@ static inline unsigned long get_break_insn_length(unsigned long pc) asmlinkage __visible __trap_section void noinstr do_trap_break(struct pt_regs *regs) { +irqentry_state_t state =irqentry_enter (regs); +#ifdef CONFIG_KPROBES if (kprobe_single_step_handler (regs))return ;
@@ -185,6 +194,8 @@ asmlinkage __visible __trap_section void noinstr do_trap_break(struct pt_regs *r regs->epc +=get_break_insn_length (regs->epc); else die(regs, "Kernel BUG"); + +irqentry_exit (regs, state); }NOKPROBE_SYMBOL (do_trap_break);
arch/riscv/mm/fault.c +11 -1
@@ -15,6 +15,7 @@#include <linux/uaccess.h> #include <linux/kprobes.h> #include <linux/kfence.h> +#include <linux/entry-common.h> #include <asm/ptrace.h> #include <asm/tlbflush.h>
@@ -203,7 +204,7 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)* This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. */ -asmlinkage void noinstr do_page_fault(struct pt_regs *regs) +static void __do_page_fault (struct pt_regs *regs) {struct task_struct *tsk;struct vm_area_struct *vma;
@@ -350,4 +351,13 @@ asmlinkage void noinstr do_page_fault(struct pt_regs *regs) }return ; } + +asmlinkage void noinstr do_page_fault(struct pt_regs *regs) +{ +irqentry_state_t state =irqentry_enter (regs); + +__do_page_fault (regs); + +irqentry_exit (regs, state); +}NOKPROBE_SYMBOL (do_page_fault);
Signature · 7 lines
2.36.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 5/8] riscv: convert to generic entry
I test this patch, its work without any error.
Quoted 776 lines · 在 2022/9/8 10:25, [email protected] 写道:
From: Guo Ren <[email protected]>
This patch converts riscv to use the generic entry infrastructure from
kernel/entry/*. The generic entry makes maintainers' work easier and codes more elegant. Here are the changes than before:- More clear
entry.Swithhandle_exceptionandret_from_exception
- Get rid of complex custom signal implementation
- More readable syscall procedure
- Little modification onret_from_fork&ret_from_kernel_thread
- Wrap with irqentry_enter/exit and syscall_enter/exit_from_user_mode
- Use the standard preemption code instead of customSigned-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>Suggested-by Huacai Chen <[email protected]>--- arch/riscv/Kconfig | 1 + arch/riscv/include/asm/csr.h | 1 - arch/riscv/include/asm/entry-common.h | 8 + arch/riscv/include/asm/ptrace.h | 10 +- arch/riscv/include/asm/stacktrace.h | 5 + arch/riscv/include/asm/syscall.h | 6 + arch/riscv/include/asm/thread_info.h | 13 +- arch/riscv/kernel/entry.S | 228 +++----------------------- arch/riscv/kernel/irq.c | 15 ++ arch/riscv/kernel/ptrace.c | 40 ----- arch/riscv/kernel/signal.c | 21 +-- arch/riscv/kernel/sys_riscv.c | 27 +++ arch/riscv/kernel/traps.c | 11 ++ arch/riscv/mm/fault.c | 12 +- 14 files changed, 117 insertions(+), 281 deletions(-)create mode 100644
arch/riscv/include/asm/entry-common.harch/riscv/Kconfig +1
-0@@ -56,6 +56,7 @@ config RISCV select GENERIC_ATOMIC64 if !64BIT select GENERIC_CLOCKEVENTS_BROADCAST if SMP select GENERIC_EARLY_IOREMAP + select GENERIC_ENTRY select GENERIC_GETTIMEOFDAY if HAVE_GENERIC_VDSO select GENERIC_IDLE_POLL_SETUP select GENERIC_IOREMAP if MMUarch/riscv/include/asm/csr.h +0
-1@@ -40,7 +40,6 @@#define SR_UXL _AC(0x300000000, UL)/* XLEN mask for U-mode */ #define SR_UXL_32 _AC(0x100000000, UL)/* XLEN = 32 for U-mode */ #define SR_UXL_64 _AC(0x200000000, UL)/* XLEN = 64 for U-mode */ -#define SR_UXL_SHIFT 32#endif /* SATP flags */ arch/riscv/include/asm/entry-common.h new file +8
-0@@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _ASM_RISCV_ENTRY_COMMON_H +#define _ASM_RISCV_ENTRY_COMMON_H + +#include <asm/stacktrace.h> + +#endif /* _ASM_RISCV_ENTRY_COMMON_H */ arch/riscv/include/asm/ptrace.h +8
-2@@ -53,6 +53,9 @@ struct pt_regs {unsigned long orig_a0; }; +#define PTRACE_SYSEMU 0x1f +#define PTRACE_SYSEMU_SINGLESTEP 0x20 +#ifdef CONFIG_64BIT #define REG_FMT "%016lx"#else @@ -121,8 +124,6 @@ extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,void prepare_ftrace_return (unsigned long *parent,unsigned long self_addr,unsigned long frame_pointer); -int do_syscall_trace_enter (struct pt_regs *regs); -void do_syscall_trace_exit (struct pt_regs *regs);/** * regs_get_register() - get register value from its offset @@ -172,6 +173,11 @@ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,return 0 ; } +static inline int regs_irqs_disabled (struct pt_regs *regs) +{ +return !(regs->status &SR_IE ); +} +#endif /* __ASSEMBLY__ */ #endif /* _ASM_RISCV_PTRACE_H */ arch/riscv/include/asm/stacktrace.h +5
-0@@ -16,4 +16,9 @@ extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *reextern void dump_backtrace (struct pt_regs *regs,struct task_struct *task,const char *loglvl); +static inline bool on_thread_stack (void ) +{ +return !(((unsigned long )(current->stack) ^ current_stack_pointer) & ~(THREAD_SIZE -1 )); +} +#endif /* _ASM_RISCV_STACKTRACE_H */ arch/riscv/include/asm/syscall.h +6
-0@@ -74,5 +74,11 @@ static inline int syscall_get_arch(struct task_struct *task)#endif } +static inline bool arch_syscall_is_vdso_sigreturn (struct pt_regs *regs) +{ +return false; +} +asmlinkage long sys_riscv_flush_icache (uintptr_t ,uintptr_t ,uintptr_t ); +asmlinkage void do_sys_ecall_u(struct pt_regs *regs);#endif /* _ASM_RISCV_SYSCALL_H */ arch/riscv/include/asm/thread_info.h +1
-12@@ -66,6 +66,7 @@ struct thread_info {long kernel_sp;/* Kernel stack pointer */ long user_sp;/* User stack pointer */ int cpu; +unsigned long syscall_work;/* SYSCALL_WORK_ flags */ };/* @@ -88,26 +89,18 @@ struct thread_info {* - pending work-to-be-done flags are in lowest half-word * - other flags in upper half-word(s) */ -#define TIF_SYSCALL_TRACE 0/* syscall trace active */ #define TIF_NOTIFY_RESUME 1/* callback before returning to user */ #define TIF_SIGPENDING 2/* signal pending */ #define TIF_NEED_RESCHED 3/* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 4/* restore signal mask in do_signal() */ #define TIF_MEMDIE 5/* is terminating due to OOM killer */ -#define TIF_SYSCALL_TRACEPOINT 6/* syscall tracepoint instrumentation */ -#define TIF_SYSCALL_AUDIT 7/* syscall auditing */ -#define TIF_SECCOMP 8/* syscall secure computing */ #define TIF_NOTIFY_SIGNAL 9/* signal notifications exist */ #define TIF_UPROBE 10/* uprobe breakpoint or singlestep */ #define TIF_32BIT 11/* compat-mode 32bit process */ -#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_SYSCALL_TRACEPOINT (1 << TIF_SYSCALL_TRACEPOINT) -#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -#define _TIF_SECCOMP (1 << TIF_SECCOMP)#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)#define _TIF_UPROBE (1 << TIF_UPROBE)@@ -115,8 +108,4 @@ struct thread_info { (_TIF_NOTIFY_RESUME | _TIF_SIGPENDING | _TIF_NEED_RESCHED | \ _TIF_NOTIFY_SIGNAL | _TIF_UPROBE) -#define _TIF_SYSCALL_WORK \ - (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_TRACEPOINT | _TIF_SYSCALL_AUDIT | \ - _TIF_SECCOMP) -#endif /* _ASM_RISCV_THREAD_INFO_H */ arch/riscv/kernel/entry.S +22
-206@@ -14,10 +14,6 @@ #include <asm/asm-offsets.h> #include <asm/errata_list.h> -#if !IS_ENABLED(CONFIG_PREEMPTION) -.set resume_kernel, restore_all -#endif - ENTRY(handle_exception) /* * If coming from userspace, preserve the user thread pointer and load@@ -106,19 +102,8 @@ _save_context: .option norelax la gp, __global_pointer$ .option pop - -#ifdef CONFIG_TRACE_IRQFLAGS - call __trace_hardirqs_off -#endif - -#ifdef CONFIG_CONTEXT_TRACKING_USER - /* If previous state is in user mode, call user_exit_callable(). */ - li a0, SR_PP - and a0, s1, a0 - bnez a0, skip_context_tracking - call user_exit_callable -skip_context_tracking: -#endif + move a0, sp /* pt_regs */ + la ra, ret_from_exception /* * MSB of cause differentiates between@@ -126,134 +111,26 @@ skip_context_tracking: */ bge s4, zero, 1f - la ra, ret_from_exception - /* Handle interrupts */ - move a0, sp /* pt_regs */ - la a1, generic_handle_arch_irq - jr a1 + tail do_riscv_irq 1: - /* - * 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 - /* kprobes, entered via ebreak, must have interrupts disabled. */ - li t0, EXC_BREAKPOINT - beq s4, t0, 1f -#ifdef CONFIG_TRACE_IRQFLAGS - call __trace_hardirqs_on -#endif - csrs CSR_STATUS, SR_IE - -1: - la ra, ret_from_exception - /* Handle syscalls */ - li t0, EXC_SYSCALL - beq s4, t0, handle_syscall - /* Handle other exceptions */ slli t0, s4, RISCV_LGPTR la t1, excp_vect_table la t2, excp_vect_table_end - move a0, sp /* pt_regs */ add t0, t1, t0 /* Check if exception code lies within bounds */ - bgeu t0, t2, 1f + bgeu t0, t2, 2f REG_L t0, 0(t0) jr t0 -1: +2: tail do_trap_unknown +END(handle_exception) -handle_syscall: -#ifdef CONFIG_RISCV_M_MODE - /* - * When running is M-Mode (no MMU config), MPIE does not get set. - * As a result, we need to force enable interrupts here because - * handle_exception did not do set SR_IE as it always sees SR_PIE - * being cleared. - */ - csrs CSR_STATUS, SR_IE -#endif -#if defined(CONFIG_TRACE_IRQFLAGS) || defined(CONFIG_CONTEXT_TRACKING_USER) - /* Recover a0 - a7 for system calls */ - REG_L a0, PT_A0(sp) - REG_L a1, PT_A1(sp) - REG_L a2, PT_A2(sp) - REG_L a3, PT_A3(sp) - REG_L a4, PT_A4(sp) - REG_L a5, PT_A5(sp) - REG_L a6, PT_A6(sp) - REG_L a7, PT_A7(sp) -#endif - /* save the initial A0 value (needed in signal handlers) */ - REG_S a0, PT_ORIG_A0(sp) - /* - * Advance SEPC to avoid executing the original - * scall instruction on sret - */ - addi s2, s2, 0x4 - 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 - bnez t0, handle_syscall_trace_enter -check_syscall_nr: - /* Check to make sure we don't jump to a bogus syscall number. */ - li t0, __NR_syscalls - la s0, sys_ni_syscall - /* - * Syscall number held in a7. - * If syscall number is above allowed value, redirect to ni_syscall. - */ - bgeu a7, t0, 3f -#ifdef CONFIG_COMPAT +ENTRY(ret_from_exception) REG_L s0, PT_STATUS(sp) - srli s0, s0, SR_UXL_SHIFT - andi s0, s0, (SR_UXL >> SR_UXL_SHIFT) - li t0, (SR_UXL_32 >> SR_UXL_SHIFT) - sub t0, s0, t0 - bnez t0, 1f - - /* Call compat_syscall */ - la s0, compat_sys_call_table - j 2f -1: -#endif - /* Call syscall */ - la s0, sys_call_table -2: - slli t0, a7, RISCV_LGPTR - add s0, s0, t0 - REG_L s0, 0(s0) -3: - jalr s0 -ret_from_syscall: - /* Set user a0 to kernel a0 */ - REG_S a0, PT_A0(sp) - /* - * We didn't execute the actual syscall. - * Seccomp already set return value for the current task pt_regs. - * (If it was configured with SECCOMP_RET_ERRNO/TRACE) - */ -ret_from_syscall_rejected: -#ifdef CONFIG_DEBUG_RSEQ - move a0, sp - call rseq_syscall -#endif - /* Trace syscalls, but only if requested by the user. */ - REG_L t0, TASK_TI_FLAGS(tp) - andi t0, t0, _TIF_SYSCALL_WORK - bnez t0, handle_syscall_trace_exit - -ret_from_exception: - REG_L s0, PT_STATUS(sp) csrc CSR_STATUS, SR_IE -#ifdef CONFIG_TRACE_IRQFLAGS - call __trace_hardirqs_off -#endif #ifdef CONFIG_RISCV_M_MODE /* the MPP value is too large to be used as an immediate arg for addi */ li t0, SR_MPP@@ -261,17 +138,7 @@ ret_from_exception: #else andi s0, s0, SR_SPP #endif - bnez s0, resume_kernel - -resume_userspace: - /* Interrupts must be disabled here so flags are checked atomically */ - REG_L s0, TASK_TI_FLAGS(tp) /* current_thread_info->flags */ - andi s1, s0, _TIF_WORK_MASK - bnez s1, work_pending - -#ifdef CONFIG_CONTEXT_TRACKING_USER - call user_enter_callable -#endif + bnez s0, 1f /* Save unwound kernel stack pointer in thread_info */ addi s0, sp, PT_SIZE_ON_STACK@@ -282,19 +149,7 @@ resume_userspace: * structures again. */ csrw CSR_SCRATCH, tp - -restore_all: -#ifdef CONFIG_TRACE_IRQFLAGS - REG_L s1, PT_STATUS(sp) - andi t0, s1, SR_PIE - beqz t0, 1f - call __trace_hardirqs_on - j 2f 1: - call __trace_hardirqs_off -2: -#endif - 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@@ -315,9 +170,11 @@ restore_all: REG_L a2, PT_EPC(sp) REG_SC x0, a2, PT_EPC(sp) - csrw CSR_STATUS, a0 csrw CSR_EPC, a2 + REG_L a0, PT_STATUS(sp) + csrw CSR_STATUS, a0 + REG_L x1, PT_RA(sp) REG_L x3, PT_GP(sp) REG_L x4, PT_TP(sp)@@ -356,54 +213,10 @@ restore_all: #else sret #endif - -#if IS_ENABLED(CONFIG_PREEMPTION) -resume_kernel: - REG_L s0, TASK_TI_PREEMPT_COUNT(tp) - bnez s0, restore_all - REG_L s0, TASK_TI_FLAGS(tp) - andi s0, s0, _TIF_NEED_RESCHED - beqz s0, restore_all - call preempt_schedule_irq - j restore_all -#endif - -work_pending: - /* Enter slow path for supplementary processing */ - la ra, ret_from_exception - andi s1, s0, _TIF_NEED_RESCHED - bnez s1, work_resched -work_notifysig: - /* Handle pending signals and notify-resume requests */ - 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 -work_resched: - tail schedule - -/* Slow paths for ptrace. */ -handle_syscall_trace_enter: - move a0, sp - call do_syscall_trace_enter - move t0, a0 - REG_L a0, PT_A0(sp) - REG_L a1, PT_A1(sp) - REG_L a2, PT_A2(sp) - REG_L a3, PT_A3(sp) - REG_L a4, PT_A4(sp) - REG_L a5, PT_A5(sp) - REG_L a6, PT_A6(sp) - REG_L a7, PT_A7(sp) - bnez t0, ret_from_syscall_rejected - j check_syscall_nr -handle_syscall_trace_exit: - move a0, sp - call do_syscall_trace_exit - j ret_from_exception +END(ret_from_exception) #ifdef CONFIG_VMAP_STACK -handle_kernel_stack_overflow: +ENTRY(handle_kernel_stack_overflow) la sp, shadow_stack addi sp, sp, SHADOW_OVERFLOW_STACK_SIZE@@ -499,21 +312,24 @@ restore_caller_reg: REG_S s5, PT_TP(sp) move a0, sp tail handle_bad_stack +END(handle_kernel_stack_overflow) #endif -END(handle_exception) - ENTRY(ret_from_fork) + call schedule_tail + move a0, sp /* pt_regs */ la ra, ret_from_exception - tail schedule_tail + tail syscall_exit_to_user_mode ENDPROC(ret_from_fork) ENTRY(ret_from_kernel_thread) call schedule_tail /* Call fn(arg) */ - la ra, ret_from_exception move a0, s1 - jr s0 + jalr s0 + move a0, sp /* pt_regs */ + la ra, ret_from_exception + tail syscall_exit_to_user_mode ENDPROC(ret_from_kernel_thread)@@ -582,7 +398,7 @@ ENTRY(excp_vect_table) RISCV_PTR do_trap_load_fault RISCV_PTR do_trap_store_misaligned RISCV_PTR do_trap_store_fault - RISCV_PTR do_trap_ecall_u /* system call, gets intercepted */ + RISCV_PTR do_sys_ecall_u /* system call */ RISCV_PTR do_trap_ecall_s RISCV_PTR do_trap_unknown RISCV_PTR do_trap_ecall_march/riscv/kernel/irq.c +15
-0@@ -5,6 +5,7 @@* Copyright (C) 2018 Christoph Hellwig */ +#include <linux/entry-common.h> #include <linux/interrupt.h> #include <linux/irqchip.h> #include <linux/seq_file.h> @@ -22,3 +23,17 @@ void __init init_IRQ(void)if (!handle_arch_irq)panic ("No interrupt controller found." ); } + +asmlinkage void noinstr do_riscv_irq(struct pt_regs *regs) +{ +struct pt_regs *old_regs; +irqentry_state_t state =irqentry_enter (regs); + +irq_enter_rcu (); + old_regs =set_irq_regs (regs); +handle_arch_irq (regs); +set_irq_regs (old_regs); +irq_exit_rcu (); + +irqentry_exit (regs, state); +}arch/riscv/kernel/ptrace.c +0
-40@@ -228,46 +228,6 @@ long arch_ptrace(struct task_struct *child, long request,return ret; } -/* -* Allows PTRACE_SYSCALL to work. These are called from entry.S in -* {handle,ret_from}_syscall. -*/ -__visible int do_syscall_trace_enter(struct pt_regs *regs) -{ -if (test_thread_flag (TIF_SYSCALL_TRACE )) -if (ptrace_report_syscall_entry (regs)) -return -1 ; - -/* -* Do the secure computing after ptrace; failures should be fast. -* If this fails we might have return value in a0 from seccomp -* (via SECCOMP_RET_ERRNO/TRACE). -*/ -if (secure_computing () ==-1 ) -return -1 ; - -#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS -if (test_thread_flag (TIF_SYSCALL_TRACEPOINT )) -trace_sys_enter (regs,syscall_get_nr (current, regs)); -#endif - -audit_syscall_entry (regs->a7, regs->a0, regs->a1, regs->a2, regs->a3); -return 0 ; -} - -__visible void do_syscall_trace_exit(struct pt_regs *regs) -{ -audit_syscall_exit (regs); - -if (test_thread_flag (TIF_SYSCALL_TRACE )) -ptrace_report_syscall_exit (regs,0 ); - -#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS -if (test_thread_flag (TIF_SYSCALL_TRACEPOINT )) -trace_sys_exit (regs,regs_return_value (regs)); -#endif -} -#ifdef CONFIG_COMPAT static int compat_riscv_gpr_get(struct task_struct *target, const struct user_regset *regset,arch/riscv/kernel/signal.c +2
-19@@ -12,6 +12,7 @@#include <linux/syscalls.h> #include <linux/resume_user_mode.h> #include <linux/linkage.h> +#include <linux/entry-common.h> #include <asm/ucontext.h> #include <asm/vdso.h> @@ -272,7 +273,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)signal_setup_done (ret, ksig,0 ); } -static void do_signal (struct pt_regs *regs) +void arch_do_signal_or_restart (struct pt_regs *regs) {struct ksignal ksig;@@ -309,21 +310,3 @@ static void do_signal(struct pt_regs *regs)*/ restore_saved_sigmask (); } - -/* -* notification of userspace execution resumption -* - triggered by the _TIF_WORK_MASK flags -*/ -asmlinkage __visible void do_notify_resume(struct pt_regs *regs, -unsigned long thread_info_flags) -{ -if (thread_info_flags & _TIF_UPROBE) -uprobe_notify_resume (regs); - -/* Handle pending signal delivery */ -if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) -do_signal (regs); - -if (thread_info_flags & _TIF_NOTIFY_RESUME) -resume_user_mode_work (regs); -}arch/riscv/kernel/sys_riscv.c +27
-0@@ -5,8 +5,10 @@* Copyright (C) 2017 SiFive */ +#include <linux/entry-common.h> #include <linux/syscalls.h> #include <asm/unistd.h> +#include <asm/syscall.h> #include <asm/cacheflush.h> #include <asm-generic/mman-common.h> @@ -72,3 +74,28 @@ SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,return 0 ; } + +typedef long (*syscall_t )(ulong ,ulong ,ulong ,ulong ,ulong ,ulong ,ulong ); + +asmlinkage void do_sys_ecall_u(struct pt_regs *regs) +{ +syscall_t syscall; +ulong nr = regs->a7; + + regs->epc +=4 ; + regs->orig_a0 = regs->a0; + regs->a0 = -ENOSYS ; + + nr =syscall_enter_from_user_mode (regs, nr); +#ifdef CONFIG_COMPAT +if ((regs->status &SR_UXL ) ==SR_UXL_32 ) + syscall = compat_sys_call_table[nr]; + else +#endif + syscall = sys_call_table[nr]; + +if (nr < NR_syscalls) + regs->a0 =syscall (regs->orig_a0, regs->a1, regs->a2, + regs->a3, regs->a4, regs->a5, regs->a6); +syscall_exit_to_user_mode (regs); +}arch/riscv/kernel/traps.c +11
-0@@ -17,6 +17,7 @@#include <linux/module.h> #include <linux/irq.h> #include <linux/kexec.h> +#include <linux/entry-common.h> #include <asm/asm-prototypes.h> #include <asm/bug.h> @@ -99,7 +100,9 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,#define DO_ERROR_INFO (name, signo, code, str) \ asmlinkage __visible __trap_section void noinstr name(struct pt_regs *regs) \ { \ + irqentry_state_t state = irqentry_enter(regs); \ do_trap_error(regs, signo, code, regs->epc, "Oops - " str); \ + irqentry_exit(regs, state); \ } DO_ERROR_INFO(do_trap_unknown,@@ -123,18 +126,22 @@ int handle_misaligned_store(struct pt_regs *regs); asmlinkage __trap_section void noinstr do_trap_load_misaligned(struct pt_regs *regs) { +irqentry_state_t state =irqentry_enter (regs);if (!handle_misaligned_load (regs))return ;do_trap_error (regs,SIGBUS ,BUS_ADRALN , regs->epc,"Oops - load address misaligned" ); +irqentry_exit (regs, state); } asmlinkage __trap_section void noinstr do_trap_store_misaligned(struct pt_regs *regs) { +irqentry_state_t state =irqentry_enter (regs);if (!handle_misaligned_store (regs))return ;do_trap_error (regs,SIGBUS ,BUS_ADRALN , regs->epc,"Oops - store (or AMO) address misaligned" ); +irqentry_exit (regs, state); }#endif DO_ERROR_INFO(do_trap_store_fault,@@ -158,6 +165,8 @@ static inline unsigned long get_break_insn_length(unsigned long pc) asmlinkage __visible __trap_section void noinstr do_trap_break(struct pt_regs *regs) { +irqentry_state_t state =irqentry_enter (regs); +#ifdef CONFIG_KPROBES if (kprobe_single_step_handler (regs))return ;@@ -185,6 +194,8 @@ asmlinkage __visible __trap_section void noinstr do_trap_break(struct pt_regs *r regs->epc +=get_break_insn_length (regs->epc); else die(regs, "Kernel BUG"); + +irqentry_exit (regs, state); }NOKPROBE_SYMBOL (do_trap_break);arch/riscv/mm/fault.c +11
-1@@ -15,6 +15,7 @@#include <linux/uaccess.h> #include <linux/kprobes.h> #include <linux/kfence.h> +#include <linux/entry-common.h> #include <asm/ptrace.h> #include <asm/tlbflush.h> @@ -203,7 +204,7 @@ static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)* This routine handles page faults. It determines the address and the * problem, and then passes it off to one of the appropriate routines. */ -asmlinkage void noinstr do_page_fault(struct pt_regs *regs) +static void __do_page_fault (struct pt_regs *regs) {struct task_struct *tsk;struct vm_area_struct *vma;@@ -350,4 +351,13 @@ asmlinkage void noinstr do_page_fault(struct pt_regs *regs) }return ; } + +asmlinkage void noinstr do_page_fault(struct pt_regs *regs) +{ +irqentry_state_t state =irqentry_enter (regs); + +__do_page_fault (regs); + +irqentry_exit (regs, state); +}NOKPROBE_SYMBOL (do_page_fault);
Signature · 2 lines
Regards, Yipeng Zou
PATCH v4 6/8 riscv: Support HAVE_IRQ_EXIT_ON_IRQ_STACK
In reply to [email protected]From: Guo Ren <[email protected]>
Add independent irq stacks for percpu to prevent kernel stack overflows. It is also compatible with VMAP_STACK by implementing arch_alloc_vmap_stack. Many architectures have supported HAVE_IRQ_EXIT_ON_IRQ_STACK, riscv should follow up.
--- arch/riscv/Kconfig | 8 +++++ arch/riscv/include/asm/irq.h | 3 ++ arch/riscv/include/asm/thread_info.h | 2 ++ arch/riscv/include/asm/vmap_stack.h | 28 ++++++++++++++++ arch/riscv/kernel/entry.S | 27 ++++++++++++++++ arch/riscv/kernel/irq.c | 48 ++++++++++++++++++++++++++-- 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 arch/riscv/include/asm/vmap_stack.h
arch/riscv/Kconfig +8 -0
@@ -433,6 +433,14 @@ config FPU If you don't know what to do here, say Y. +config IRQ_STACKS + bool "Independent irq stacks" + default y + select HAVE_IRQ_EXIT_ON_IRQ_STACK + help + Add independent irq stacks for percpu to prevent kernel stack overflows. + We may save some memory footprint by disabling IRQ_STACKS. + endmenu # "Platform type" menu "Kernel features"
arch/riscv/include/asm/irq.h +3 -0
@@ -13,5 +13,8 @@#include <asm-generic/irq.h> extern void __init init_IRQ (void ); +asmlinkage void call_on_stack(struct pt_regs *regs, ulong *sp, +void (*fn)(struct pt_regs *),ulong tmp); +asmlinkage void noinstr do_riscv_irq(struct pt_regs *regs);#endif /* _ASM_RISCV_IRQ_H */
arch/riscv/include/asm/thread_info.h +2 -0
@@ -40,6 +40,8 @@#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024) +#define IRQ_STACK_SIZE THREAD_SIZE +#ifndef __ASSEMBLY__extern long shadow_stack[SHADOW_OVERFLOW_STACK_SIZE /sizeof (long )];
arch/riscv/include/asm/vmap_stack.h new file +28 -0
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copied from arch/arm64/include/asm/vmap_stack.h. +#ifndef _ASM_RISCV_VMAP_STACK_H +#define _ASM_RISCV_VMAP_STACK_H + +#include <linux/bug.h> +#include <linux/gfp.h> +#include <linux/kconfig.h> +#include <linux/vmalloc.h> +#include <linux/pgtable.h> +#include <asm/thread_info.h> + +/* +* To ensure that VMAP'd stack overflow detection works correctly, all VMAP'd +* stacks need to have the same alignment. +*/ +static inline unsigned long *arch_alloc_vmap_stack (size_t stack_size,int node) +{ +void *p; + +BUILD_BUG_ON (!IS_ENABLED (CONFIG_VMAP_STACK )); + + p =__vmalloc_node (stack_size,THREAD_ALIGN ,THREADINFO_GFP , node, +__builtin_return_address (0 )); +return kasan_reset_tag (p); +} + +#endif /* _ASM_RISCV_VMAP_STACK_H */
arch/riscv/kernel/entry.S +27 -0
@@ -332,6 +332,33 @@ ENTRY(ret_from_kernel_thread) tail syscall_exit_to_user_mode ENDPROC(ret_from_kernel_thread) +#ifdef CONFIG_IRQ_STACKS +ENTRY(call_on_stack) + /* Create a frame record to save our ra and fp */ + addi sp, sp, -RISCV_SZPTR + REG_S ra, (sp) + addi sp, sp, -RISCV_SZPTR + REG_S fp, (sp) + + /* Save sp in fp */ + move fp, sp + + /* Move to the new stack and call the function there */ + li a3, IRQ_STACK_SIZE + add sp, a1, a3 + jalr a2 + + /* + * Restore sp from prev fp, and fp, ra from the frame + */ + move sp, fp + REG_L fp, (sp) + addi sp, sp, RISCV_SZPTR + REG_L ra, (sp) + addi sp, sp, RISCV_SZPTR + ret +ENDPROC(call_on_stack) +#endif /* * Integer register context switch
arch/riscv/kernel/irq.c +46 -2
73 lines not on this page · raw message
Signature · 7 lines
2.36.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 6/8] riscv: Support HAVE_IRQ_EXIT_ON_IRQ_STACK
Quoted 5 lines · On 2022-09-07 22:25:04 [-0400], [email protected] wrote:
arch/riscv/Kconfig +0
-0
arch/riscv/Kconfig config FPU · line 442
Quoted 10 lines
arch/riscv/Kconfig +7
-0@@ -433,6 +433,14 @@ config FPU If you don't know what to do here, say Y. +config IRQ_STACKS + bool "Independent irq stacks" + default y + select HAVE_IRQ_EXIT_ON_IRQ_STACK + help + Add independent irq stacks for percpu to prevent kernel stack overflows. + We may save some memory footprint by disabling IRQ_STACKS.
Do you really think that it is needed to save memory here? Avoiding stack overflows in deep call chains is probably more important than saving ~8KiB per CPU.
Sebastian
RE: [PATCH V4 6/8] riscv: Support HAVE_IRQ_EXIT_ON_IRQ_STACK
From: Sebastian Andrzej Siewior
Quoted 11 lines
Sent: 08 September 2022 17:08
Quoted 8 lines · On 2022-09-07 22:25:04 [-0400], [email protected] wrote:
arch/riscv/Kconfig +0
-0@@ -433,6 +433,14 @@ config FPU If you don't know what to do here, say Y.
Quoted 11 lines
arch/riscv/Kconfig config FPU · line 442
Quoted 7 lines
arch/riscv/Kconfig +7
-0+config IRQ_STACKS + bool "Independent irq stacks" + default y + select HAVE_IRQ_EXIT_ON_IRQ_STACK + help + Add independent irq stacks for percpu to prevent kernel stack overflows. + We may save some memory footprint by disabling IRQ_STACKS.Do you really think that it is needed to save memory here? Avoiding stack overflows in deep call chains is probably more important than saving ~8KiB per CPU.
Particularly if a 64bit build is using small stacks.
Without static analysis of actual call chain depth it is really difficult to trim the stack size.
I'd bet (a few beers) that the deepest stack use in inside the console print code form a printk() (eg warn_on_once) in an obscure error path somewhere.
This won't be hit during any normal testing.
I think that the analysis objtool does is getting close to be able to generate the raw data that can be used for static stack depth analysis.
You need the 'CFI' constants for indirect calls and some assumptions about depth of recursive calls. But apart from that the code to process the raw output isn't that complex.
A nice task for someone with some spare time.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Re: [PATCH V4 6/8] riscv: Support HAVE_IRQ_EXIT_ON_IRQ_STACK
Quoted 24 lines · David Laight
From: Sebastian Andrzej Siewior
Quoted 22 lines
Sent: 08 September 2022 17:08
Quoted 5 lines · On 2022-09-07 22:25:04 [-0400], [email protected] wrote:
arch/riscv/Kconfig +0
-0arch/riscv/Kconfig config FPU · line 442
Quoted 10 lines
arch/riscv/Kconfig +7
-0@@ -433,6 +433,14 @@ config FPU If you don't know what to do here, say Y. +config IRQ_STACKS + bool "Independent irq stacks" + default y + select HAVE_IRQ_EXIT_ON_IRQ_STACK + help + Add independent irq stacks for percpu to prevent kernel stack overflows. + We may save some memory footprint by disabling IRQ_STACKS.Do you really think that it is needed to save memory here? Avoiding stack overflows in deep call chains is probably more important than saving ~8KiB per CPU.
Original riscv is !IRQ_STACKS, I just give a config to make it back. So I would add a CONFIG_EXPERT in the next version.
Actually, I have a similar opinion to you, IRQ_STACKS should be force enabled. But as a new feature, we should give users a choice - use or not.
Quoted 10 lines
Particularly if a 64bit build is using small stacks.
Without static analysis of actual call chain depth it is really difficult to trim the stack size.
I'd bet (a few beers) that the deepest stack use in inside the console print code form a
printk()(egwarn_on_once) in an obscure error path somewhere.
This won't be hit during any normal testing.
That means stack overflow would be hidden a lot. But we could enable VMAP_STACK & STACK_LEAK [1].
[1]: https://lore.kernel.org/lkml/[email protected]/
Quoted 16 lines
I think that the analysis objtool does is getting close to be able to generate the raw data that can be used for static stack depth analysis.
You need the 'CFI' constants for indirect calls and some assumptions about depth of recursive calls. But apart from that the code to process the raw output isn't that complex.A nice task for someone with some spare time.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Signature · 2 lines
Best Regards Guo Ren
PATCH v4 7/8 riscv: Support HAVE_SOFTIRQ_ON_OWN_STACK
In reply to [email protected]From: Guo Ren <[email protected]>
Add the HAVE_SOFTIRQ_ON_OWN_STACK feature for the IRQ_STACKS config. The irq and softirq use the same independent irq_stack of percpu by time division multiplexing.
--- arch/riscv/Kconfig | 7 ++++--- arch/riscv/kernel/irq.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-)
arch/riscv/Kconfig +4 -3
@@ -434,12 +434,13 @@ config FPU If you don't know what to do here, say Y. config IRQ_STACKS - bool "Independent irq stacks" + bool "Independent irq & softirq stacks" default y select HAVE_IRQ_EXIT_ON_IRQ_STACK + select HAVE_SOFTIRQ_ON_OWN_STACK help - Add independent irq stacks for percpu to prevent kernel stack overflows. - We may save some memory footprint by disabling IRQ_STACKS. + Add independent irq & softirq stacks for percpu to prevent kernel stack + overflows. We may save some memory footprint by disabling IRQ_STACKS. endmenu # "Platform type"
arch/riscv/kernel/irq.c +16 -0
@@ -11,6 +11,7 @@#include <linux/seq_file.h> #include <asm/smp.h> #include <asm/vmap_stack.h> +#include <asm/softirq_stack.h> #ifdef CONFIG_IRQ_STACKS static DEFINE_PER_CPU(ulong *, irq_stack_ptr);
@@ -38,6 +39,21 @@ static void init_irq_stacks(void)per_cpu (irq_stack_ptr, cpu) =per_cpu (irq_stack, cpu); }#endif /* CONFIG_VMAP_STACK */ + +#ifndef CONFIG_PREEMPT_RT +static void do_riscv_softirq (struct pt_regs *regs) +{ +__do_softirq (); +} + +void do_softirq_own_stack (void ) +{ +ulong *sp =per_cpu (irq_stack_ptr,smp_processor_id ()); + +call_on_stack (NULL , sp, do_riscv_softirq,0 ); +} +#endif /* CONFIG_PREEMPT_RT */ +#else static void init_irq_stacks (void ) {}#endif /* CONFIG_IRQ_STACKS */
Signature · 7 lines
2.36.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 7/8] riscv: Support HAVE_SOFTIRQ_ON_OWN_STACK
Quoted 11 lines · On 2022-09-07 22:25:05 [-0400], [email protected] wrote:
arch/riscv/kernel/irq.c +1
-0@@ -11,6 +11,7 @@#include <linux/seq_file.h> #include <asm/smp.h> #include <asm/vmap_stack.h> +#include <asm/softirq_stack.h> #ifdef CONFIG_IRQ_STACKS static DEFINE_PER_CPU(ulong *, irq_stack_ptr);
arch/riscv/kernel/irq.c static void init_irq_stacks(void) · line 43
Quoted 5 lines
arch/riscv/kernel/irq.c +2
-0@@ -38,6 +39,21 @@ static void init_irq_stacks(void) per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu); }#endif /* CONFIG_VMAP_STACK */ + +#ifndef CONFIG_PREEMPT_RT
Could you please replace it with
#ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
instead? See
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git/commit/?id=8cbb2b50ee2dcb082675237eaaa48fe8479f8aa5
Quoted 6 lines
arch/riscv/kernel/irq.c +6
-0+static void do_riscv_softirq (struct pt_regs *regs) +{ +__do_softirq (); +} + +void do_softirq_own_stack (void )
arch/riscv/kernel/irq.c static void init_irq_stacks(void) · line 59
Quoted 10 lines
arch/riscv/kernel/irq.c +7
-0+{ +ulong *sp =per_cpu (irq_stack_ptr,smp_processor_id ()); + +call_on_stack (NULL , sp, do_riscv_softirq,0 ); +} +#endif /* CONFIG_PREEMPT_RT */ +#else static void init_irq_stacks (void ) {}#endif /* CONFIG_IRQ_STACKS */
Sebastian
Re: [PATCH V4 7/8] riscv: Support HAVE_SOFTIRQ_ON_OWN_STACK
Quoted 20 lines · Sebastian Andrzej Siewior
Quoted 11 lines · On 2022-09-07 22:25:05 [-0400], [email protected] wrote:
arch/riscv/kernel/irq.c +1
-0@@ -11,6 +11,7 @@#include <linux/seq_file.h> #include <asm/smp.h> #include <asm/vmap_stack.h> +#include <asm/softirq_stack.h> #ifdef CONFIG_IRQ_STACKS static DEFINE_PER_CPU(ulong *, irq_stack_ptr);arch/riscv/kernel/irq.c static void init_irq_stacks(void) · line 43
Quoted 5 lines
arch/riscv/kernel/irq.c +2
-0@@ -38,6 +39,21 @@ static void init_irq_stacks(void) per_cpu(irq_stack_ptr, cpu) = per_cpu(irq_stack, cpu); }#endif /* CONFIG_VMAP_STACK */ + +#ifndef CONFIG_PREEMPT_RT Could you please replace it with
Quoted 1 line
#ifdef CONFIG_SOFTIRQ_ON_OWN_STACK
Thx, I would.
Quoted 22 lines
instead? See
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic.git/commit/?id=8cbb2b50ee2dcb082675237eaaa48fe8479f8aa5Quoted 6 lines
arch/riscv/kernel/irq.c +6
-0+static void do_riscv_softirq (struct pt_regs *regs) +{ +__do_softirq (); +} + +void do_softirq_own_stack (void )arch/riscv/kernel/irq.c static void init_irq_stacks(void) · line 59
Quoted 10 lines
arch/riscv/kernel/irq.c +7
-0+{ +ulong *sp =per_cpu (irq_stack_ptr,smp_processor_id ()); + +call_on_stack (NULL , sp, do_riscv_softirq,0 ); +} +#endif /* CONFIG_PREEMPT_RT */ +#else static void init_irq_stacks (void ) {}#endif /* CONFIG_IRQ_STACKS */ Sebastian
Signature · 2 lines
Best Regards Guo Ren
PATCH v4 8/8 riscv: Add config of thread stack size
In reply to [email protected]From: Guo Ren <[email protected]>
0cac21b02ba5 ("risc v: use 16KB kernel stack on 64-bit") increase the thread size mandatory, but some scenarios, such as D1 with a small memory footprint, would suffer from that. After independent irq stack support, let's give users a choice to determine their custom stack size.
--- arch/riscv/Kconfig | 9 +++++++++ arch/riscv/include/asm/thread_info.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +9 -0
@@ -442,6 +442,15 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent kernel stack overflows. We may save some memory footprint by disabling IRQ_STACKS. +config THREAD_SIZE_ORDER + int "Pages of thread stack size (as a power of 2)" + range 1 4 + default "1" if 32BIT + default "2" if 64BIT + help + Specify the Pages of thread stack size (from 8KB to 64KB), which also + affects irq stack size, which is equal to thread stack size. + endmenu # "Platform type" menu "Kernel features"
arch/riscv/include/asm/thread_info.h +2 -2
@@ -19,9 +19,9 @@/* thread information allocation */ #ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER)#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER)#endif #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
Signature · 7 lines
2.36.1 _______________________________________________ linux-riscv mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-riscv
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 21 lines · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
0cac21b02ba5("risc v: use 16KB kernel stack on 64-bit") increase the thread size mandatory, but some scenarios, such as D1 with a small memory footprint, would suffer from that. After independent irq stack support, let's give users a choice to determine their custom stack size.Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>Cc Andreas Schwab <[email protected]>--- arch/riscv/Kconfig | 9 +++++++++ arch/riscv/include/asm/thread_info.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-)arch/riscv/Kconfig +0
-0@@ -442,6 +442,15 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent kernel stack
arch/riscv/Kconfig config IRQ_STACKS · line 452
Quoted 10 lines
arch/riscv/Kconfig +8
-0overflows. We may save some memory footprint by disabling IRQ_STACKS. +config THREAD_SIZE_ORDER + int "Pages of thread stack size (as a power of 2)" + range 1 4 + default "1" if 32BIT + default "2" if 64BIT + help + Specify the Pages of thread stack size (from 8KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.
I would suggest hiding this under 'depends on EXPERT', no need to bother normal users with that question because the defaults are probably what everyone should use unless they are extremely limited.
arch/riscv/Kconfig config IRQ_STACKS
Quoted 7 lines
arch/riscv/Kconfig +2
-2#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER) #else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER) #endif
The two sides of the #ifdef are now the same, so you no longer need both. You could also consider expressing the KASAN_STACK_ORDER bit in Kconfig logic for consistency, and put those into the defaults as well. Unless you actually use CONFIG_KASAN_STACK, the stack requirements of KASAN are not too bad, so that way one could decide to still use a smaller stack even with KASAN.
If you want to make the setting really useful, you can add two more ideas:
- When VMAP_STACK is set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB without VMAP_STACK anyway since that just makes it really hard to debug, so hiding the option when VMAP_STACK is disabled may also be a good idea.
- For testing purposes, you can even allow byte-exact stack sizes that allow finding out what the actual minimum is by adding a fixed offset during kernel entry. See add_random_kstack_offset() for how to adjust the stack.
With all those ideas added in, the Kconfig logic would be something like (assuming you can use
config THREAD_SIZE
int "Kernel stack size (in bytes)" if VMAP_STACK && EXPERT
range 4096 65536
default 8192 if 32BIT && !KASAN
default 32768 if 64BIT && KASAN
default 16384config THREAD_SIZE_ORDER
int
default 0 if THREAD_SIZE = 4096
default 1 if THREAD_SIZE <= 8192
default 2 if THREAD_SIZE <= 16384
default 3 if THREAD_SIZE <= 32768
default 4
Arnd
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 57 lines · Arnd Bergmann
Quoted 21 lines · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
0cac21b02ba5("risc v: use 16KB kernel stack on 64-bit") increase the thread size mandatory, but some scenarios, such as D1 with a small memory footprint, would suffer from that. After independent irq stack support, let's give users a choice to determine their custom stack size.Signed-off-by Guo Ren <[email protected]>Signed-off-by Guo Ren <[email protected]>Cc Andreas Schwab <[email protected]>--- arch/riscv/Kconfig | 9 +++++++++ arch/riscv/include/asm/thread_info.h | 4 ++-- 2 files changed, 11 insertions(+), 2 deletions(-)arch/riscv/Kconfig +0
-0@@ -442,6 +442,15 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent kernel stackarch/riscv/Kconfig config IRQ_STACKS · line 452
Quoted 10 lines
arch/riscv/Kconfig +8
-0overflows. We may save some memory footprint by disabling IRQ_STACKS. +config THREAD_SIZE_ORDER + int "Pages of thread stack size (as a power of 2)" + range 1 4 + default "1" if 32BIT + default "2" if 64BIT + help + Specify the Pages of thread stack size (from 8KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.I would suggest hiding this under 'depends on EXPERT', no need to bother normal users with that question because the defaults are probably what everyone should use unless they are extremely limited.
arch/riscv/Kconfig config IRQ_STACKS
Quoted 7 lines
arch/riscv/Kconfig +2
-2#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER) #else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) +#define THREAD_SIZE_ORDER (CONFIG_THREAD_SIZE_ORDER + KASAN_STACK_ORDER) #endifThe two sides of the #ifdef are now the same, so you no longer need both. You could also consider expressing the
KASAN_STACK_ORDERbit inKconfiglogic for consistency, and put those into the defaults as well. Unless you actually useCONFIG_KASAN_STACK, the stack requirements of KASAN are not too bad, so that way one could decide to still use a smaller stack even with KASAN.If you want to make the setting really useful, you can add two more ideas:
Quoted 7 lines
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.
I don't want this config to depend on VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.
Here is the new patch:
arch/riscv/Kconfig +0 -0
@@ -442,6 +442,24 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent
kernel stack
overflows. We may save some memory footprint by disabling IRQ_STACKS.
+config THREAD_SIZE
+ int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help
+ Specify the Pages of thread stack size (from 4KB to 64KB), which also
+ affects irq stack size, which is equal to thread stack size.
+
+config THREAD_SIZE_ORDER
+ int + default 0 if THREAD_SIZE = 4096 + default 1 if THREAD_SIZE <= 8192 + default 2 if THREAD_SIZE <= 16384 + default 3 if THREAD_SIZE <= 32768 + default 4
+
endmenu # "Platform type"
menu "Kernel features"
(quoted diff) +0 -0
b/arch/riscv/include/asm/thread_info.h
index 043da8ccc7e6..c970d41dc4c6 100644
arch/riscv/include/asm/thread_info.h +1 -11
@@ -11,18 +11,8 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
Quoted 24 lines
- For testing purposes, you can even allow byte-exact stack sizes that allow finding out what the actual minimum is by adding a fixed offset during kernel entry. See
add_random_kstack_offset()for how to adjust the stack.With all those ideas added in, the
Kconfiglogic would be something like (assuming you can useconfig
THREAD_SIZEint "Kernel stack size (in bytes)" if VMAP_STACK && EXPERT range 4096 65536 default 8192 if 32BIT && !KASAN default 32768 if 64BIT && KASAN default 16384config
THREAD_SIZE_ORDER
int
default 0 ifTHREAD_SIZE= 4096
default 1 ifTHREAD_SIZE<= 8192
default 2 ifTHREAD_SIZE<= 16384
default 3 ifTHREAD_SIZE<= 32768
default 4
Quoted 1 line
Arnd
--
Best Regards
Guo Ren
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 10 lines · Guo Ren
Quoted 9 lines · Arnd Bergmann
Quoted 1 line · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.
Quoted 2 lines
I don't want this config to depend on
VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.
That sounds like a really bad idea, why would you want to risk using such a small stack without CONFIG_VMAP_STACK?
Are you worried about increased memory usage or something else?
arch/riscv/include/asm/thread_info.h line 16
Quoted 8 lines
/* thread information allocation */
arch/riscv/include/asm/thread_info.h +1
-5-#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
This doesn't actually allow additional THREAD_SIZE values, as you still round up to the nearest power of two.
I think all the non-arch code can deal with non-power-of-2 sizes, so you'd just need
#define THREAD_SIZE round_up(CONFIG_THREAD_SIZE, PAGE_SIZE)
and fix up the risc-v specific code to do the right thing as well. I now see that THREAD_SIZE_ORDER is not actually used anywhere with CONFIG_VMAP_STACK, so I suppose that definition can be skipped, but you still need a THREAD_ALIGN definition that is a power of two and at least a page larger than THREAD_SIZE.
Arnd
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 12 lines · Arnd Bergmann
Quoted 10 lines · Guo Ren
Quoted 9 lines · Arnd Bergmann
Quoted 1 line · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.
Quoted 7 lines
Quoted 2 lines
I don't want this config to depend on
VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
The requirement is from [1], and I think disabling CONFIG_VMAP_STACK would be the last step after serious testing.
[1] https://www.cnx-software.com/2021/10/25/allwinner-d1s-f133-risc-v-processor-64mb-ddr2/
Quoted 26 lines
arch/riscv/include/asm/thread_info.h line 16
Quoted 9 lines
/* thread information allocation */
arch/riscv/include/asm/thread_info.h +1
-5-#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)This doesn't actually allow additional
THREAD_SIZEvalues, as you still round up to the nearest power of two.I think all the non-arch code can deal with non-power-of-2 sizes, so you'd just need
#define
THREAD_SIZEround_up(CONFIG_THREAD_SIZE, PAGE_SIZE)and fix up the risc-v specific code to do the right thing as well. I now see that
THREAD_SIZE_ORDERis not actually used anywhere withCONFIG_VMAP_STACK, so I suppose that definition can be skipped, but you still need aTHREAD_ALIGNdefinition that is a power of two and at least a page larger thanTHREAD_SIZE.Arnd
Signature · 2 lines
Best Regards Guo Ren
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 16 lines · Guo Ren
Quoted 15 lines · Arnd Bergmann
Quoted 12 lines · Guo Ren
Quoted 9 lines · Arnd Bergmann
Quoted 1 line · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.I don't want this config to depend on
VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.
Quoted 6 lines
Quoted 4 lines
That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
The requirement is from [1], and I think disabling
CONFIG_VMAP_STACKwould be the last step after serious testing.
I still don't see why you need to turn off VMAP_STACK at all if it works. The only downside I can see with using VMAP_STACK on a 64-bit system is that it may expose bugs with device drivers that do DMA to stack data. Once you have tested the system successfully, you can also assume that you have no such drivers.
Arnd
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 27 lines · Arnd Bergmann
Quoted 16 lines · Guo Ren
Quoted 15 lines · Arnd Bergmann
Quoted 12 lines · Guo Ren
Quoted 9 lines · Arnd Bergmann
Quoted 1 line · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.I don't want this config to depend on
VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.Quoted 6 lines
Quoted 4 lines
That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
The requirement is from [1], and I think disabling
CONFIG_VMAP_STACKwould be the last step after serious testing.
Quoted 6 lines
I still don't see why you need to turn off
VMAP_STACKat all if it works. The only downside I can see with usingVMAP_STACKon a 64-bit system is that it may expose bugs with device drivers that do DMA to stack data. Once you have tested the system successfully, you can also assume that you have no such drivers.
1st, VMAP_STACK could be enabled&disabled in arch/Kconfig. If we don't force users to enable VMAP_STACK, why couldn't user adjust THREAD_SIZE?
2nd, VMAP_STACK is not free, we still need 1KB shadow_stack. The EXPERT is enough for your concern.
Quoted 2 lines
Arnd
--
Best Regards
Guo Ren
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 17 lines · Guo Ren
Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · Guo Ren
Quoted 5 lines · Arnd Bergmann
That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
The requirement is from [1], and I think disabling
CONFIG_VMAP_STACKwould be the last step after serious testing.Quoted 6 lines
I still don't see why you need to turn off
VMAP_STACKat all if it works. The only downside I can see with usingVMAP_STACKon a 64-bit system is that it may expose bugs with device drivers that do DMA to stack data. Once you have tested the system successfully, you can also assume that you have no such drivers.
Quoted 3 lines
1st,
VMAP_STACKcould be enabled&disabled inarch/Kconfig. If we don't force users to enableVMAP_STACK, why couldn't user adjustTHREAD_SIZE?
Turning off VMAP_STACK is harmless and may help debug issues with VMAP_STACK itself. It's also required on architectures that don't have KASAN_VMALLOC or something else that conflicts with it.
Changing THREAD_SIZE is also fine, as long as VMAP_STACK catches the inevitable overflows. I would not object to having an option that allows setting the stack size larger than the default without VMAP_STACK, as long as setting it lower requires using VMAP_STACK. That would however add a lot more complexity and probably doesn't do what you want either.
Quoted 2 lines
2nd,
VMAP_STACKis not free, we still need 1KBshadow_stack. The EXPERT is enough for your concern.
It's actually more than the 1KB: you need both 1KB of shadow stack and 4KB per CPU for the actual overflow_stack. If you are micro-optimizing at this level, then a possible option may be to change the handle_kernel_stack_overflow() function to not preserve the task stack and just panic() without showing the backtrace. That way you don't see which code caused the issue, but at least you avoid corrupting random data.
Arnd
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 28 lines · Arnd Bergmann
Quoted 17 lines · Guo Ren
Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · Guo Ren
Quoted 5 lines · Arnd Bergmann
That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
The requirement is from [1], and I think disabling
CONFIG_VMAP_STACKwould be the last step after serious testing.Quoted 6 lines
I still don't see why you need to turn off
VMAP_STACKat all if it works. The only downside I can see with usingVMAP_STACKon a 64-bit system is that it may expose bugs with device drivers that do DMA to stack data. Once you have tested the system successfully, you can also assume that you have no such drivers.Quoted 3 lines
1st,
VMAP_STACKcould be enabled&disabled inarch/Kconfig. If we don't force users to enableVMAP_STACK, why couldn't user adjustTHREAD_SIZE?Turning off
VMAP_STACKis harmless and may help debug issues withVMAP_STACKitself. It's also required on architectures that don't haveKASAN_VMALLOCor something else that conflicts with it.
Quoted 6 lines
Changing
THREAD_SIZEis also fine, as long asVMAP_STACKcatches the inevitable overflows. I would not object to having an option that allows setting the stack size larger than the default withoutVMAP_STACK, as long as setting it lower requires usingVMAP_STACK. That would however add a lot more complexity and probably doesn't do what you want either.
Thx for the detailed clarification, I agree with the point. I've put an EXPERT on config.
Quoted 4 lines
Quoted 3 lines
2nd,
VMAP_STACKis not free, we still need 1KBshadow_stack. The EXPERT is enough for your concern.
Quoted 8 lines
It's actually more than the 1KB: you need both 1KB of shadow stack and 4KB per CPU for the actual
overflow_stack. If you are micro-optimizing at this level, then a possible option may be to change thehandle_kernel_stack_overflow()function to not preserve the task stack and justpanic()without showing the backtrace. That way you don't see which code caused the issue, but at least you avoid corrupting random data.
Thx for the detailed explanation, the handle_kernel_stack_overflow() is a novel idea, which I will consider later.
Quoted 2 lines
Arnd
--
Best Regards
Guo Ren
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
In reply to Arnd BergmannQuoted 35 lines · Arnd Bergmann
Quoted 10 lines · Guo Ren
Quoted 9 lines · Arnd Bergmann
Quoted 1 line · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.Quoted 2 lines
I don't want this config to depend on
VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
arch/riscv/include/asm/thread_info.h line 16
Quoted 8 lines
/* thread information allocation */
arch/riscv/include/asm/thread_info.h +1
-5-#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)This doesn't actually allow additional
THREAD_SIZEvalues, as you still round up to the nearest power of two.I think all the non-arch code can deal with non-power-of-2 sizes, so you'd just need
Quoted 8 lines
#define
THREAD_SIZEround_up(CONFIG_THREAD_SIZE, PAGE_SIZE)and fix up the risc-v specific code to do the right thing as well. I now see that
THREAD_SIZE_ORDERis not actually used anywhere withCONFIG_VMAP_STACK, so I suppose that definition can be skipped, but you still need aTHREAD_ALIGNdefinition that is a power of two and at least a page larger thanTHREAD_SIZE.
Sorry, I missed this part. I would RESEND v5
Quoted 2 lines
Arnd
Signature · 2 lines
Best Regards Guo Ren
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 39 lines · Guo Ren
Quoted 37 lines · Arnd Bergmann
Quoted 10 lines · Guo Ren
Quoted 9 lines · Arnd Bergmann
Quoted 1 line · On Thu, Sep 8, 2022, at 4:25 AM, [email protected] wrote:
From: Guo Ren <[email protected]>
- When
VMAP_STACKis set, make it possible to select non-power-of-two stack sizes. Most importantly, 12KB should be a really interesting choice as 8KB is probably still not enough for many 64-bit workloads, but 16KB is often more than what you need. You probably don't want to allow 64BIT/8KB withoutVMAP_STACKanyway since that just makes it really hard to debug, so hiding the option whenVMAP_STACKis disabled may also be a good idea.Quoted 2 lines
I don't want this config to depend on
VMAP_STACK. Some D1 chips would run with an 8K stack size and !VMAP_STACK.That sounds like a really bad idea, why would you want to risk using such a small stack without
CONFIG_VMAP_STACK?Are you worried about increased memory usage or something else?
Review
Quoted 8 lines
/* thread information allocation */
(quoted diff) +1
-5-#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER #define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)This doesn't actually allow additional
THREAD_SIZEvalues, as you still round up to the nearest power of two.I think all the non-arch code can deal with non-power-of-2 sizes, so you'd just need
#define
THREAD_SIZEround_up(CONFIG_THREAD_SIZE, PAGE_SIZE)
Quoted 7 lines
Quoted 6 lines
and fix up the risc-v specific code to do the right thing as well. I now see that
THREAD_SIZE_ORDERis not actually used anywhere withCONFIG_VMAP_STACK, so I suppose that definition can be skipped, but you still need aTHREAD_ALIGNdefinition that is a power of two and at least a page larger thanTHREAD_SIZE.Sorry, I missed this part. I would RESEND v5
Hi Arnd,
How about this one: (only THREAD_SIZE, no THREAD_ORDER&SHIFT.)
commit 447cddede7898c35a9a3b8ab3d7bdb7b0de0714d (HEAD)
Author: Guo Ren <[email protected]> Date: Mon Sep 5 22:53:06 2022 -0400
riscv: Add config of thread stack size
0cac21b02ba5 ("riscv: use 16KB kernel stack on 64-bit") increase the thread size mandatory, but some scenarios, such as D1 with a small memory footprint, would suffer from that. After independent irq stack support, let's give users a choice to determine their custom stack size.
arch/riscv/Kconfig +0 -0
@@ -442,6 +442,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent
kernel stack
overflows. We may save some memory footprint by disabling IRQ_STACKS.
+config THREAD_SIZE
+ int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help
+ Specify the Pages of thread stack size (from 4KB to 64KB), which also
+ affects irq stack size, which is equal to thread stack size.
+
endmenu # "Platform type"
menu "Kernel features"
(quoted diff) +0 -0
b/arch/riscv/include/asm/thread_info.h
index 043da8ccc7e6..181fdfbd5e99 100644
arch/riscv/include/asm/thread_info.h +2 -15
@@ -11,24 +11,12 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE CONFIG_THREAD_SIZE/* * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by -* checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry -* assembly. +* checking sp & THREAD_SIZE, which we can do cheaply in the entry assembly. */ #ifdef CONFIG_VMAP_STACK #define THREAD_ALIGN (2 * THREAD_SIZE)
@@ -36,7 +24,6 @@#define THREAD_ALIGN THREAD_SIZE#endif -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024)
arch/riscv/kernel/entry.S +2 -2
@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_SIZE >> PAGE_SHIFT) bnez sp, handle_kernel_stack_overflow REG_L sp, TASK_TI_KERNEL_SP(tp) #endif
Quoted 9 lines
Quoted 3 lines
Arnd
--
Best Regards
Guo Ren
Signature · 2 lines
Best Regards Guo Ren
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
arch/riscv/include/asm/thread_info.h line 15
Quoted 12 lines · Guo Ren
How about this one: (only
THREAD_SIZE, no THREAD_ORDER&SHIFT.)arch/riscv/include/asm/thread_info.h +1
-7-/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE CONFIG_THREAD_SIZE
So far looks fine.
arch/riscv/include/asm/thread_info.h line 25
Quoted 12 lines
/*
* By aligning VMAP'd stacks to 2 *THREAD_SIZE, we can detect overflow by
- * checking sp & (1 <<THREAD_SHIFT), which we can do cheaply in the entry
- * assembly.
+ * checking sp &THREAD_SIZE, which we can do cheaply in the entry assembly. */
#ifdefCONFIG_VMAP_STACK
#defineTHREAD_ALIGN(2 *THREAD_SIZE)arch/riscv/include/asm/thread_info.h +0
-0@@ -36,7 +24,6 @@#define THREAD_ALIGN THREAD_SIZE#endif
The THREAD_ALIGN does not, this only works for power-of-two numbers of THREAD_SIZE,
arch/riscv/kernel/entry.S _restore_kernel_tpsp: · line 33
Quoted 12 lines
arch/riscv/kernel/entry.S +2
-2@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_SIZE >> PAGE_SHIFT)
I think this needs to use THREAD_ALIGN, not THREAD_SIZE.
Arnd
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 20 lines · Arnd Bergmann
arch/riscv/include/asm/thread_info.h line 15
Quoted 12 lines · Guo Ren
How about this one: (only
THREAD_SIZE, no THREAD_ORDER&SHIFT.)arch/riscv/include/asm/thread_info.h +1
-7-/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE CONFIG_THREAD_SIZESo far looks fine.
Quoted 1 line
Quoted 14 lines
arch/riscv/include/asm/thread_info.h line 25
Quoted 11 lines
/*
* By aligning VMAP'd stacks to 2 *THREAD_SIZE, we can detect overflow by
- * checking sp & (1 <<THREAD_SHIFT), which we can do cheaply in the entry
- * assembly.
+ * checking sp &THREAD_SIZE, which we can do cheaply in the entry assembly. */
#ifdefCONFIG_VMAP_STACK
#defineTHREAD_ALIGN(2 *THREAD_SIZE)arch/riscv/include/asm/thread_info.h +0
-0@@ -36,7 +24,6 @@#define THREAD_ALIGN THREAD_SIZE#endif The
THREAD_ALIGNdoes not, this only works for power-of-two numbers ofTHREAD_SIZE,
We double THREAD_SIZE to simplify the detection. See the commit log:
The overflow detect is performed before any attempt is made to access the stack and the principle of stack overflow detection: kernel stacks are aligned to double their size, enabling overflow to be detected with a single bit test. For example, a 16K stack is aligned to 32K, ensuring that bit 14 of the SP must be zero. On an overflow (or underflow), this bit is flipped. Thus, overflow (of less than the size of the stack) can be detected by testing whether this bit is set.
I would try to optimize the size of VMAP_STACK in another patch.
Quoted 7 lines
Quoted 7 lines
arch/riscv/kernel/entry.S +0
-0@@ -29,8 +29,8 @@ _restore_kernel_tpsp:
Quoted 8 lines
arch/riscv/kernel/entry.S _restore_kernel_tpsp: · line 33
Quoted 6 lines
arch/riscv/kernel/entry.S +2
-2#ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_SIZE >> PAGE_SHIFT)I think this needs to use
THREAD_ALIGN, notTHREAD_SIZE.
No, it's BIT[14], when THREAD_SIZE = 16K.
Quoted 2 lines
Arnd
Signature · 2 lines
Best Regards Guo Ren
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
In reply to Guo RenQuoted 9 lines · Guo Ren
arch/riscv/Kconfig +0
-0@@ -442,6 +442,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.
arch/riscv/Kconfig
Quoted 9 lines
arch/riscv/Kconfig +9
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.
I still think this should be guarded in a way that prevents setting the stack to smaller than default values unless VMAP_STACK is set as well.
Arnd
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 12 lines · Arnd Bergmann
Quoted 9 lines · Guo Ren
arch/riscv/Kconfig +0
-0@@ -442,6 +442,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.
Quoted 13 lines
arch/riscv/Kconfig
Quoted 9 lines
arch/riscv/Kconfig +9
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.I still think this should be guarded in a way that prevents setting the stack to smaller than default values unless
VMAP_STACKis set as well.
Current VMAP_STACK would double THREAD_SIZE. Let me see how to reduce the VMAP_STACK.
Quoted 2 lines
Arnd
Signature · 2 lines
Best Regards Guo Ren
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 27 lines · Guo Ren
Quoted 12 lines · Arnd Bergmann
Quoted 9 lines · Guo Ren
arch/riscv/Kconfig +0
-0@@ -442,6 +442,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.Quoted 13 lines
arch/riscv/Kconfig
Quoted 9 lines
arch/riscv/Kconfig +9
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.I still think this should be guarded in a way that prevents setting the stack to smaller than default values unless
VMAP_STACKis set as well.
Quoted 2 lines
Current
VMAP_STACKwould doubleTHREAD_SIZE. Let me see how to reduce theVMAP_STACK.
Sorry, for my miss understanding. I have no idea to reduce the VMAP_STACK's THREAD_ALIGN, THREAD_SIZE*2 is fine. Here is my new patch:
arch/riscv/Kconfig +0 -0
@@ -443,6 +443,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent
kernel stack
overflows. We may save some memory footprint by disabling IRQ_STACKS.
+config THREAD_SIZE
+ int "Kernel stack size (in bytes)" if VMAP_STACK && EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help
+ Specify the Pages of thread stack size (from 4KB to 64KB), which also
+ affects irq stack size, which is equal to thread stack size.
+
endmenu # "Platform type"
menu "Kernel features"
(quoted diff) +0 -0
b/arch/riscv/include/asm/thread_info.h
index 043da8ccc7e6..e7ae3f13b879 100644
arch/riscv/include/asm/thread_info.h +2 -17
@@ -11,32 +11,17 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE CONFIG_THREAD_SIZE/* * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by -* checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry -* assembly. +* checking sp & THREAD_SIZE, which we can do cheaply in the entry assembly. */ #ifdef CONFIG_VMAP_STACK #define THREAD_ALIGN (2 * THREAD_SIZE) -#else -#define THREAD_ALIGN THREAD_SIZE#endif -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024)
arch/riscv/kernel/entry.S +2 -2
@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_ALIGN >> PAGE_SHIFT >> 1) bnez sp, handle_kernel_stack_overflow REG_L sp, TASK_TI_KERNEL_SP(tp) #endif
Quoted 9 lines
Quoted 3 lines
Arnd
--
Best Regards
Guo Ren
Signature · 2 lines
Best Regards Guo Ren
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 102 lines · Guo Ren
Quoted 27 lines · Guo Ren
Quoted 12 lines · Arnd Bergmann
Quoted 9 lines · Guo Ren
arch/riscv/Kconfig +0
-0@@ -442,6 +442,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.Quoted 13 lines
arch/riscv/Kconfig
Quoted 9 lines
arch/riscv/Kconfig +9
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.I still think this should be guarded in a way that prevents setting the stack to smaller than default values unless
VMAP_STACKis set as well.Quoted 2 lines
Current
VMAP_STACKwould doubleTHREAD_SIZE. Let me see how to reduce theVMAP_STACK.Sorry, for my miss understanding. I have no idea to reduce the VMAP_STACK's
THREAD_ALIGN, THREAD_SIZE*2 is fine. Here is my new patch:arch/riscv/Kconfig +0
-0@@ -443,6 +443,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.arch/riscv/Kconfig +10
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if VMAP_STACK && EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size. + endmenu # "Platform type" menu "Kernel features"arch/riscv/include/asm/thread_info.h +2
-17@@ -11,32 +11,17 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE CONFIG_THREAD_SIZE/* * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by -* checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry -* assembly. +* checking sp & THREAD_SIZE, which we can do cheaply in the entry assembly. */ #ifdef CONFIG_VMAP_STACK #define THREAD_ALIGN (2 * THREAD_SIZE) -#else -#define THREAD_ALIGN THREAD_SIZE#endif -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024)arch/riscv/kernel/entry.S +0
-0
arch/riscv/kernel/entry.S _restore_kernel_tpsp: · line 36
Quoted 10 lines
arch/riscv/kernel/entry.S +2
-2@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_ALIGN >> PAGE_SHIFT >> 1) bnez sp, handle_kernel_stack_overflow REG_L sp, TASK_TI_KERNEL_SP(tp) #endif
Sorry for the update again, fixup !VMAP_STACK compile error.
arch/riscv/Kconfig +0 -0
@@ -443,6 +443,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent
kernel stack
overflows. We may save some memory footprint by disabling IRQ_STACKS.
+config THREAD_SIZE_ORDER
+ int "Kernel stack size (in power-of-two numbers of page size)"
if VMAP_STACK && EXPERT
+ range 0 4 + default 1 if 32BIT && !KASAN + default 3 if 64BIT && KASAN + default 2 + help
+ Specify the Pages of thread stack size (from 4KB to 64KB), which also
+ affects irq stack size, which is equal to thread stack size.
+
endmenu # "Platform type"
menu "Kernel features"
(quoted diff) +0 -0
b/arch/riscv/include/asm/thread_info.h
index 043da8ccc7e6..3f382490d8ed 100644
arch/riscv/include/asm/thread_info.h +3 -15
@@ -11,24 +11,13 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER +#define THREAD_SIZE (1 << PAGE_SHIFT << THREAD_SIZE_ORDER)/* * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by -* checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry -* assembly. +* checking sp & THREAD_SIZE, which we can do cheaply in the entry assembly. */ #ifdef CONFIG_VMAP_STACK #define THREAD_ALIGN (2 * THREAD_SIZE)
@@ -36,7 +25,6 @@#define THREAD_ALIGN THREAD_SIZE#endif -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024)
arch/riscv/kernel/entry.S +2 -2
@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_ALIGN >> PAGE_SHIFT >> 1) bnez sp, handle_kernel_stack_overflow REG_L sp, TASK_TI_KERNEL_SP(tp) #endif
Quoted 17 lines
Quoted 11 lines
Quoted 5 lines
Arnd
--
Best Regards
Guo Ren--
Best Regards
Guo Ren
Signature · 2 lines
Best Regards Guo Ren
Re: [PATCH V4 8/8] riscv: Add config of thread stack size
Hi Arnd,
No more coding conventions for the patch, THREAD_ALIGN & THREAD_SIZE_ORDER are used by vmlinux.lds.S and common code. So here is my considerable version:
arch/riscv/Kconfig +0 -0
@@ -443,6 +443,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to prevent
kernel stack
overflows. We may save some memory footprint by disabling IRQ_STACKS.
+config THREAD_SIZE_ORDER
+ int "Kernel stack size (in power-of-two numbers of page size)"
if VMAP_STACK && EXPERT
+ range 0 4 + default 1 if 32BIT && !KASAN + default 3 if 64BIT && KASAN + default 2 + help
+ Specify the Pages of thread stack size (from 4KB to 64KB), which also
+ affects irq stack size, which is equal to thread stack size.
+
endmenu # "Platform type"
menu "Kernel features"
(quoted diff) +0 -0
b/arch/riscv/include/asm/thread_info.h
index 043da8ccc7e6..c970d41dc4c6 100644
arch/riscv/include/asm/thread_info.h +1 -11
@@ -11,18 +11,8 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
It's a little bit back to the original, but KASAN_STACK_ORDER has been deleted. VMAP_STACK && EXPERT added.
Quoted 219 lines · Guo Ren
Quoted 102 lines · Guo Ren
Quoted 27 lines · Guo Ren
Quoted 12 lines · Arnd Bergmann
Quoted 9 lines · Guo Ren
arch/riscv/Kconfig +0
-0@@ -442,6 +442,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.Quoted 13 lines
arch/riscv/Kconfig
Quoted 9 lines
arch/riscv/Kconfig +9
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size.I still think this should be guarded in a way that prevents setting the stack to smaller than default values unless
VMAP_STACKis set as well.Quoted 2 lines
Current
VMAP_STACKwould doubleTHREAD_SIZE. Let me see how to reduce theVMAP_STACK.Sorry, for my miss understanding. I have no idea to reduce the VMAP_STACK's
THREAD_ALIGN, THREAD_SIZE*2 is fine. Here is my new patch:arch/riscv/Kconfig +0
-0@@ -443,6 +443,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.arch/riscv/Kconfig +10
-0+config THREAD_SIZE + int "Kernel stack size (in bytes)" if VMAP_STACK && EXPERT + range 4096 65536 + default 8192 if 32BIT && !KASAN + default 32768 if 64BIT && KASAN + default 16384 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size. + endmenu # "Platform type" menu "Kernel features"arch/riscv/include/asm/thread_info.h +2
-17@@ -11,32 +11,17 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE CONFIG_THREAD_SIZE/* * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by -* checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry -* assembly. +* checking sp & THREAD_SIZE, which we can do cheaply in the entry assembly. */ #ifdef CONFIG_VMAP_STACK #define THREAD_ALIGN (2 * THREAD_SIZE) -#else -#define THREAD_ALIGN THREAD_SIZE#endif -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024)arch/riscv/kernel/entry.S +0
-0arch/riscv/kernel/entry.S _restore_kernel_tpsp: · line 36
Quoted 10 lines
arch/riscv/kernel/entry.S +2
-2@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_ALIGN >> PAGE_SHIFT >> 1) bnez sp, handle_kernel_stack_overflow REG_L sp, TASK_TI_KERNEL_SP(tp) #endifSorry for the update again, fixup !VMAP_STACK compile error.
arch/riscv/Kconfig +0
-0@@ -443,6 +443,16 @@ config IRQ_STACKS Add independent irq & softirq stacks for percpu to preventkernel stack
overflows. We may save some memory footprint by disablingIRQ_STACKS.arch/riscv/Kconfig +2
-0+config THREAD_SIZE_ORDER + int "Kernel stack size (in power-of-two numbers of page size)"if
VMAP_STACK&& EXPERTarch/riscv/Kconfig +8
-0+ range 0 4 + default 1 if 32BIT && !KASAN + default 3 if 64BIT && KASAN + default 2 + help + Specify the Pages of thread stack size (from 4KB to 64KB), which also + affects irq stack size, which is equal to thread stack size. + endmenu # "Platform type" menu "Kernel features"arch/riscv/include/asm/thread_info.h +3
-15@@ -11,24 +11,13 @@#include <asm/page.h> #include <linux/const.h> -#ifdef CONFIG_KASAN -#define KASAN_STACK_ORDER 1 -#else -#define KASAN_STACK_ORDER 0 -#endif -/* thread information allocation */ -#ifdef CONFIG_64BIT -#define THREAD_SIZE_ORDER (2 + KASAN_STACK_ORDER) -#else -#define THREAD_SIZE_ORDER (1 + KASAN_STACK_ORDER) -#endif -#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER) +#define THREAD_SIZE_ORDER CONFIG_THREAD_SIZE_ORDER +#define THREAD_SIZE (1 << PAGE_SHIFT << THREAD_SIZE_ORDER)/* * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by -* checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry -* assembly. +* checking sp & THREAD_SIZE, which we can do cheaply in the entry assembly. */ #ifdef CONFIG_VMAP_STACK #define THREAD_ALIGN (2 * THREAD_SIZE)@@ -36,7 +25,6 @@#define THREAD_ALIGN THREAD_SIZE#endif -#define THREAD_SHIFT (PAGE_SHIFT + THREAD_SIZE_ORDER)#define OVERFLOW_STACK_SIZE SZ_4K#define SHADOW_OVERFLOW_STACK_SIZE (1024)arch/riscv/kernel/entry.S +2
-2@@ -29,8 +29,8 @@ _restore_kernel_tpsp: #ifdef CONFIG_VMAP_STACK addi sp, sp, -(PT_SIZE_ON_STACK) - srli sp, sp, THREAD_SHIFT - andi sp, sp, 0x1 + srli sp, sp, PAGE_SHIFT + andi sp, sp, (THREAD_ALIGN >> PAGE_SHIFT >> 1) bnez sp, handle_kernel_stack_overflow REG_L sp, TASK_TI_KERNEL_SP(tp) #endifQuoted 15 lines
Quoted 5 lines
Quoted 5 lines
Quoted 7 lines
Quoted 1 line
Arnd
--
Best Regards
Guo RenQuoted 3 lines
--
Best Regards
Guo Ren--
Best Regards
Guo Ren
Signature · 2 lines
Best Regards Guo Ren
Arnd Bergmann
maintainerRe: [PATCH V4 8/8] riscv: Add config of thread stack size
Quoted 6 lines · Guo Ren
Hi Arnd,
No more coding conventions for the patch,
THREAD_ALIGN&THREAD_SIZE_ORDERare used byvmlinux.lds.Sand common code. So here is my considerable version:
That's fine with me, it should get the job done.
I still think a way to use 12KB stacks with VMAP_STACK would be a good addition, but that can come later, and we may want to do this in an architecture-independent way when we get there.
Arnd