Skip to contentSkip to conversation

riscv: Add GENERIC_ENTRY, irq stack support

PATCH Superseded [email protected] 6 participants 38 messages Sep 8, 2022 – Sep 22, 2022

Subsystems (3)

v4 of 17 Superseded Latest is v17 →

lore
Share & tools
lore
#0 lore raw

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
#1 lore raw

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;
      |                       ^~~~~~~~~~~~
Fixes 838b3e28488f ("RISC-V: Load purgatory in kexec_file")
---
 arch/riscv/kernel/elf_kexec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/riscv/kernel/elf_kexec.c +1 -1
index 0cb94992c15b..4b9264340b78 100644
@@ -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
#2 lore raw

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)

Fixes 59c10c52f573 ("riscv: compat: syscall: Add compat_sys_call_table implementation")
---
 arch/riscv/kernel/Makefile | 1 +
 1 file changed, 1 insertion(+)
arch/riscv/kernel/Makefile +1 -0
index 33bb60a354cd..01da14e21019 100644
@@ -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
#3 lore raw

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
index 2ae8280ae475..44f4b1ca315d 100644
@@ -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
#4 lore raw

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
index 635e6ec26938..3ed3dbec250d 100644
@@ -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
index f2fbd1400b7c..c7829289e806 100644
@@ -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
#5 lore raw

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)

---
 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
index 635e6ec26938..3ed3dbec250d 100644

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

author
#6 lore raw

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)

---
 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
index 635e6ec26938..3ed3dbec250d 100644
@@ -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.

Oops, thx for correcting. Here is my solution.

arch/riscv/kernel/traps.c +0 -0
index 635e6ec26938..eba744caa711 100644
@@ -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
author
#7 lore raw

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)

---
 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
index 635e6ec26938..3ed3dbec250d 100644
@@ -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.

Oops, thx for correcting. Here is my solution.

arch/riscv/kernel/traps.c +0 -0
index 635e6ec26938..eba744caa711 100644

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
#8 lore raw

Re: [PATCH V4 4/8] riscv: traps: Add noinstr to prevent instrumentation inserted

In reply to Guo Ren
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_section and noinstr both adding a section attribute.

Oops, thx for correcting. Here is my solution.

arch/riscv/kernel/traps.c +0 -0
index 635e6ec26938..eba744caa711 100644
@@ -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

author
#9 lore raw

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_section and noinstr both adding a section attribute.

Oops, thx for correcting. Here is my solution.

arch/riscv/kernel/traps.c +0 -0
index 635e6ec26938..eba744caa711 100644
@@ -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

https://lore.kernel.org/all/[email protected]/

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
#10 lore raw

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
index ed66c31e4655..a07bb3b73b5b 100644
@@ -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
index 0e571f6483d9..7c2b8cdb7b77 100644
@@ -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
new file mode 100644
index 000000000000..1636ac2af28e
@@ -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
index 6ecd461129d2..4e46a611f255 100644
@@ -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
index 3450c1912afd..f7e8ef2418b9 100644
@@ -16,4 +16,9 @@ extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *re
 extern 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
index 384a63b86420..6c573f18030b 100644
@@ -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
index 67322f878e0d..7de4fb96f0b5 100644
@@ -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
index 7207fa08d78f..24c2e1bd756a 100644
@@ -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
index 44f4b1ca315d..4caed6c683e4 100644
@@ -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
index 5a2de6b6f882..5871eccbbd94 100644
@@ -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
index 571556bb9261..41cc1c4bccb3 100644
@@ -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
index 3ed3dbec250d..d24c6a9c2735 100644
@@ -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
index c7829289e806..cc8e642a91ea 100644
@@ -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
Tested-by on v4 5/8
#11 lore raw

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.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
index ed66c31e4655..a07bb3b73b5b 100644
@@ -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
index 0e571f6483d9..7c2b8cdb7b77 100644
@@ -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
new file mode 100644
index 000000000000..1636ac2af28e
@@ -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
index 6ecd461129d2..4e46a611f255 100644
@@ -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
index 3450c1912afd..f7e8ef2418b9 100644
@@ -16,4 +16,9 @@ extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *re
  extern 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
index 384a63b86420..6c573f18030b 100644
@@ -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
index 67322f878e0d..7de4fb96f0b5 100644
@@ -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
index b9eda3fcbd6d..5f49517cd3a2 100644
@@ -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_m
arch/riscv/kernel/irq.c +15 -0
index 7207fa08d78f..24c2e1bd756a 100644
@@ -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
index 44f4b1ca315d..4caed6c683e4 100644
@@ -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
index 5a2de6b6f882..5871eccbbd94 100644
@@ -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
index 571556bb9261..41cc1c4bccb3 100644
@@ -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
index 3ed3dbec250d..d24c6a9c2735 100644
@@ -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
index c7829289e806..cc8e642a91ea 100644
@@ -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
#12 lore raw

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
index a07bb3b73b5b..a8a12b4ba1a9 100644
@@ -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
index e4c435509983..205e1c693dfd 100644
@@ -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
index 7de4fb96f0b5..043da8ccc7e6 100644
@@ -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
new file mode 100644
index 000000000000..3fbf481abf4f
@@ -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
index 5f49517cd3a2..426529b84db0 100644
@@ -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
#13 lore raw

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
index a07bb3b73b5b..a8a12b4ba1a9 100644

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

#14 lore raw

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
index a07bb3b73b5b..a8a12b4ba1a9 100644
@@ -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)

author
#15 lore raw

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 -0
index a07bb3b73b5b..a8a12b4ba1a9 100644

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.

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() (eg warn_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
#16 lore raw

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
index a8a12b4ba1a9..da548ed7d107 100644
@@ -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
index 5ad4952203c5..c09cd4d28308 100644
@@ -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
#17 lore raw

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

author
#18 lore raw

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=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

Signature · 2 lines
Best Regards
 Guo Ren
#19 lore raw

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
index da548ed7d107..e436b5793ab6 100644
@@ -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
index 043da8ccc7e6..c64d995df6e1 100644
@@ -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
maintainer
#20 lore raw

Re: [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.

---
 arch/riscv/Kconfig                   | 9 +++++++++
 arch/riscv/include/asm/thread_info.h | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +0 -0
index da548ed7d107..e436b5793ab6 100644
@@ -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 -0
 	  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.

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 16384

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

Arnd

author
#21 lore raw

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.

---
 arch/riscv/Kconfig                   | 9 +++++++++
 arch/riscv/include/asm/thread_info.h | 4 ++--
 2 files changed, 11 insertions(+), 2 deletions(-)
arch/riscv/Kconfig +0 -0
index da548ed7d107..e436b5793ab6 100644
@@ -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 -0
        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.

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:

Quoted 7 lines

- 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.

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
index da548ed7d107..e7fcc3fbf48e 100644
@@ -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 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 16384

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

Quoted 1 line

Arnd

--
Best Regards

Guo Ren

maintainer
#22 lore raw

Re: [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_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.

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

author
#23 lore raw

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_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.

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_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

Signature · 2 lines
Best Regards
 Guo Ren
maintainer
#24 lore raw

Re: [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_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.

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_STACK would 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

author
#25 lore raw

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_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.

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_STACK would be the last step after serious testing.

Quoted 6 lines

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.

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

maintainer
#26 lore raw

Re: [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_STACK would be the last step after serious testing.

Quoted 6 lines

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.

Quoted 3 lines

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?

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_STACK is not free, we still need 1KB shadow_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

author
#27 lore raw

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_STACK would be the last step after serious testing.

Quoted 6 lines

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.

Quoted 3 lines

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?

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.

Quoted 6 lines

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.

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_STACK is not free, we still need 1KB shadow_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 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.

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

author
#28 lore raw

Re: [PATCH V4 8/8] riscv: Add config of thread stack size

In reply to Arnd Bergmann
Quoted 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_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.

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

Quoted 8 lines

#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.

Sorry, I missed this part. I would RESEND v5

Quoted 2 lines

Arnd

Signature · 2 lines
Best Regards
 Guo Ren
author
#29 lore raw

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_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.

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_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)

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_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.

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
index dfe600f3526c..8def456f328c 100644
@@ -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
index 426529b84db0..1e35fb3bdae5 100644
@@ -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
maintainer
#30 lore raw

Re: [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. */
#ifdef CONFIG_VMAP_STACK
#define THREAD_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
index 426529b84db0..1e35fb3bdae5 100644
@@ -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

author
#31 lore raw

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_SIZE

So 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. */
#ifdef CONFIG_VMAP_STACK
#define THREAD_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,

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
index 426529b84db0..1e35fb3bdae5 100644
@@ -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, not THREAD_SIZE.

No, it's BIT[14], when THREAD_SIZE = 16K.

Quoted 2 lines

Arnd

Signature · 2 lines
Best Regards
 Guo Ren
maintainer
#32 lore raw

Re: [PATCH V4 8/8] riscv: Add config of thread stack size

In reply to Guo Ren
Quoted 9 lines · Guo Ren
arch/riscv/Kconfig +0 -0
index dfe600f3526c..8def456f328c 100644
@@ -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.

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

author
#33 lore raw

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
index dfe600f3526c..8def456f328c 100644
@@ -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.

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_STACK is 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
author
#34 lore raw

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
index dfe600f3526c..8def456f328c 100644
@@ -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.

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_STACK is set as well.

Quoted 2 lines

Current VMAP_STACK would double THREAD_SIZE. Let me see how to reduce the VMAP_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
index 76bde12d9f8c..669ae57356a2 100644
@@ -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
index 2207cf44a3bc..71ea850ff0db 100644
@@ -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
author
#35 lore raw

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
index dfe600f3526c..8def456f328c 100644
@@ -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.

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_STACK is set as well.

Quoted 2 lines

Current VMAP_STACK would double THREAD_SIZE. Let me see how to reduce the VMAP_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
index 76bde12d9f8c..669ae57356a2 100644
@@ -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.

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
index 043da8ccc7e6..e7ae3f13b879 100644
@@ -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
index 2207cf44a3bc..71ea850ff0db 100644

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
index 76bde12d9f8c..602e577c429c 100644
@@ -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
index 5cbd6684ef52..62e8f3a3c942 100644
@@ -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
author
#36 lore raw

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
index 76bde12d9f8c..602e577c429c 100644
@@ -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
index dfe600f3526c..8def456f328c 100644
@@ -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.

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_STACK is set as well.

Quoted 2 lines

Current VMAP_STACK would double THREAD_SIZE. Let me see how to reduce the VMAP_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
index 76bde12d9f8c..669ae57356a2 100644
@@ -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.

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
index 043da8ccc7e6..e7ae3f13b879 100644
@@ -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
index 2207cf44a3bc..71ea850ff0db 100644

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
index 76bde12d9f8c..602e577c429c 100644
@@ -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.

arch/riscv/Kconfig +2 -0
+config THREAD_SIZE_ORDER
+       int "Kernel stack size (in power-of-two numbers of page size)"

if VMAP_STACK && EXPERT

arch/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
index 043da8ccc7e6..3f382490d8ed 100644
@@ -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
index 5cbd6684ef52..62e8f3a3c942 100644
@@ -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 15 lines
Quoted 5 lines
Quoted 5 lines
Quoted 7 lines
Quoted 1 line

Arnd

--
Best Regards
Guo Ren

Quoted 3 lines

--
Best Regards
Guo Ren

--
Best Regards
Guo Ren

Signature · 2 lines
Best Regards
 Guo Ren
maintainer
#37 lore raw

Re: [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_ORDER are used by vmlinux.lds.S and 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