Loongarch is the only architecture that calls
syscall_exit_to_user_mode() from asm. Move the call into C so that this
function can be inlined across all architectures.
Signed-off-by: Charlie Jenkins <charlie@rivosinc.com>
---
arch/loongarch/include/asm/switch_to.h | 8 ++++++++
arch/loongarch/kernel/entry.S | 22 ++++++++++-----------
arch/loongarch/kernel/process.c | 36 ++++++++++++++++++++++++++++------
3 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/arch/loongarch/include/asm/switch_to.h b/arch/loongarch/include/asm/switch_to.h
index 5b225aff3ba21aa06d0713bc8e73e1b941389630..a1c5576f1fd145670e13038bec6dd390486099ab 100644
--- a/arch/loongarch/include/asm/switch_to.h
+++ b/arch/loongarch/include/asm/switch_to.h
@@ -26,6 +26,14 @@ extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
struct task_struct *next, struct thread_info *next_ti,
void *sched_ra, void *sched_cfa);
+void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev,
+ struct pt_regs *regs,
+ int (*fn)(void *),
+ void *fn_arg);
+
+void noinstr __no_stack_protector ret_from_fork(struct task_struct *prev,
+ struct pt_regs *regs);
+
/*
* For newly created kernel threads switch_to() will return to
* ret_from_kernel_thread, newly created user threads to ret_from_fork.
diff --git a/arch/loongarch/kernel/entry.S b/arch/loongarch/kernel/entry.S
index 48e7e34e355e83eae8165957ba2eac05a8bf17df..2abc29e573810e000f2fef4646ddca0dbb80eabe 100644
--- a/arch/loongarch/kernel/entry.S
+++ b/arch/loongarch/kernel/entry.S
@@ -77,24 +77,22 @@ SYM_CODE_START(handle_syscall)
SYM_CODE_END(handle_syscall)
_ASM_NOKPROBE(handle_syscall)
-SYM_CODE_START(ret_from_fork)
+SYM_CODE_START(ret_from_fork_asm)
UNWIND_HINT_REGS
- bl schedule_tail # a0 = struct task_struct *prev
- move a0, sp
- bl syscall_exit_to_user_mode
+ move a1, sp
+ bl ret_from_fork
RESTORE_STATIC
RESTORE_SOME
RESTORE_SP_AND_RET
-SYM_CODE_END(ret_from_fork)
+SYM_CODE_END(ret_from_fork_asm)
-SYM_CODE_START(ret_from_kernel_thread)
+SYM_CODE_START(ret_from_kernel_thread_asm)
UNWIND_HINT_REGS
- bl schedule_tail # a0 = struct task_struct *prev
- move a0, s1
- jirl ra, s0, 0
- move a0, sp
- bl syscall_exit_to_user_mode
+ move a1, sp
+ move a2, s0
+ move a3, s1
+ bl ret_from_kernel_thread
RESTORE_STATIC
RESTORE_SOME
RESTORE_SP_AND_RET
-SYM_CODE_END(ret_from_kernel_thread)
+SYM_CODE_END(ret_from_kernel_thread_asm)
diff --git a/arch/loongarch/kernel/process.c b/arch/loongarch/kernel/process.c
index 6e58f65455c7ca3eae2e88ed852c8655a6701e5c..9bb069ef363fefed1f2115e6572b31c2b76bb414 100644
--- a/arch/loongarch/kernel/process.c
+++ b/arch/loongarch/kernel/process.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/entry-common.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task.h>
@@ -47,6 +48,7 @@
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/reg.h>
+#include <asm/switch_to.h>
#include <asm/unwind.h>
#include <asm/vdso.h>
@@ -63,8 +65,12 @@ EXPORT_SYMBOL(__stack_chk_guard);
unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
EXPORT_SYMBOL(boot_option_idle_override);
-asmlinkage void ret_from_fork(void);
-asmlinkage void ret_from_kernel_thread(void);
+asmlinkage void restore_and_ret(void);
+asmlinkage void ret_from_fork_asm(void);
+void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev,
+ struct pt_regs *regs,
+ int (*fn)(void *),
+ void *fn_arg)
void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
{
@@ -138,6 +144,24 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
return 0;
}
+void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev,
+ struct pt_regs *regs,
+ int (*fn)(void *),
+ void *fn_arg)
+{
+ schedule_tail(prev);
+
+ fn(fn_arg);
+
+ syscall_exit_to_user_mode(regs);
+}
+
+void noinstr __no_stack_protector ret_from_fork(struct task_struct *prev, struct pt_regs *regs)
+{
+ schedule_tail(prev);
+ syscall_exit_to_user_mode(regs);
+}
+
/*
* Copy architecture-specific thread state
*/
@@ -165,8 +189,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.reg03 = childksp;
p->thread.reg23 = (unsigned long)args->fn;
p->thread.reg24 = (unsigned long)args->fn_arg;
- p->thread.reg01 = (unsigned long)ret_from_kernel_thread;
- p->thread.sched_ra = (unsigned long)ret_from_kernel_thread;
+ p->thread.reg01 = (unsigned long)ret_from_kernel_thread_asm;
+ p->thread.sched_ra = (unsigned long)ret_from_kernel_thread_asm;
memset(childregs, 0, sizeof(struct pt_regs));
childregs->csr_euen = p->thread.csr_euen;
childregs->csr_crmd = p->thread.csr_crmd;
@@ -182,8 +206,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
childregs->regs[3] = usp;
p->thread.reg03 = (unsigned long) childregs;
- p->thread.reg01 = (unsigned long) ret_from_fork;
- p->thread.sched_ra = (unsigned long) ret_from_fork;
+ p->thread.reg01 = (unsigned long) ret_from_fork_asm;
+ p->thread.sched_ra = (unsigned long) ret_from_fork_asm;
/*
* New tasks lose permission to use the fpu. This accelerates context
--
2.43.0
Hi Charlie,
kernel test robot noticed the following build errors:
[auto build test ERROR on ffd294d346d185b70e28b1a28abe367bbfe53c04]
url: https://github.com/intel-lab-lkp/linux/commits/Charlie-Jenkins/riscv-entry-Convert-ret_from_fork-to-C/20250123-065957
base: ffd294d346d185b70e28b1a28abe367bbfe53c04
patch link: https://lore.kernel.org/r/20250122-riscv_optimize_entry-v1-3-4ee95559cfd0%40rivosinc.com
patch subject: [PATCH 3/4] loongarch: entry: Migrate ret_from_fork() to C
config: loongarch-allnoconfig (https://download.01.org/0day-ci/archive/20250124/202501240042.hEXt9u9r-lkp@intel.com/config)
compiler: loongarch64-linux-gcc (GCC) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250124/202501240042.hEXt9u9r-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202501240042.hEXt9u9r-lkp@intel.com/
All errors (new ones prefixed by >>):
arch/loongarch/kernel/process.c: In function 'ret_from_kernel_thread':
>> arch/loongarch/kernel/process.c:76:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
76 | {
| ^
arch/loongarch/kernel/process.c:105:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
105 | {
| ^
arch/loongarch/kernel/process.c:110:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
110 | {
| ^
arch/loongarch/kernel/process.c:114:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
114 | {
| ^
arch/loongarch/kernel/process.c:151:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
151 | {
| ^
arch/loongarch/kernel/process.c:160:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
160 | {
| ^
arch/loongarch/kernel/process.c:169:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
169 | {
| ^
arch/loongarch/kernel/process.c:234:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
234 | {
| ^
arch/loongarch/kernel/process.c:257:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
257 | {
| ^
arch/loongarch/kernel/process.c:279:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
279 | {
| ^
arch/loongarch/kernel/process.c:296:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
296 | {
| ^
arch/loongarch/kernel/process.c:317:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
317 | {
| ^
arch/loongarch/kernel/process.c:338:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
338 | {
| ^
In file included from include/asm-generic/percpu.h:7,
from arch/loongarch/include/asm/percpu.h:184,
from include/linux/irqflags.h:19,
from include/linux/spinlock.h:59,
from include/linux/sched.h:2171,
from include/linux/ratelimit.h:6,
from include/linux/dev_printk.h:16,
from include/linux/device.h:15,
from include/linux/node.h:18,
from include/linux/cpu.h:17,
from arch/loongarch/kernel/process.c:13:
>> arch/loongarch/kernel/process.c:345:43: error: storage class specified for parameter 'backtrace_csd'
345 | static DEFINE_PER_CPU(call_single_data_t, backtrace_csd);
| ^~~~~~~~~~~~~
include/linux/percpu-defs.h:104:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
104 | __PCPU_ATTRS(sec) __typeof__(type) name
| ^~~~
arch/loongarch/kernel/process.c:345:8: note: in expansion of macro 'DEFINE_PER_CPU'
345 | static DEFINE_PER_CPU(call_single_data_t, backtrace_csd);
| ^~~~~~~~~~~~~~
>> arch/loongarch/kernel/process.c:345:43: error: section attribute not allowed for 'backtrace_csd'
345 | static DEFINE_PER_CPU(call_single_data_t, backtrace_csd);
| ^~~~~~~~~~~~~
include/linux/percpu-defs.h:104:44: note: in definition of macro 'DEFINE_PER_CPU_SECTION'
104 | __PCPU_ATTRS(sec) __typeof__(type) name
| ^~~~
arch/loongarch/kernel/process.c:345:8: note: in expansion of macro 'DEFINE_PER_CPU'
345 | static DEFINE_PER_CPU(call_single_data_t, backtrace_csd);
| ^~~~~~~~~~~~~~
>> arch/loongarch/kernel/process.c:346:23: error: storage class specified for parameter 'backtrace_csd_busy'
346 | static struct cpumask backtrace_csd_busy;
| ^~~~~~~~~~~~~~~~~~
arch/loongarch/kernel/process.c:349:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
349 | {
| ^
arch/loongarch/kernel/process.c:355:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
355 | {
| ^
arch/loongarch/kernel/process.c:379:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
379 | {
| ^
arch/loongarch/kernel/process.c:385:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
385 | {
| ^
>> arch/loongarch/kernel/process.c:70:35: error: old-style parameter declarations in prototyped function definition
70 | void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev,
| ^~~~~~~~~~~~~~~~~~~~~~
>> arch/loongarch/kernel/process.c:402: error: expected '{' at end of input
vim +76 arch/loongarch/kernel/process.c
803b0fc5c3f2baa Huacai Chen 2022-05-31 @13 #include <linux/cpu.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 14 #include <linux/init.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 15 #include <linux/kernel.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 16 #include <linux/errno.h>
5c881018646d666 Charlie Jenkins 2025-01-22 17 #include <linux/entry-common.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 18 #include <linux/sched.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 19 #include <linux/sched/debug.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 20 #include <linux/sched/task.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 21 #include <linux/sched/task_stack.h>
edffa33c7bb5a73 Qing Zhang 2023-02-25 22 #include <linux/hw_breakpoint.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 23 #include <linux/mm.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 24 #include <linux/stddef.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 25 #include <linux/unistd.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 26 #include <linux/export.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 27 #include <linux/ptrace.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 28 #include <linux/mman.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 29 #include <linux/personality.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 30 #include <linux/sys.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 31 #include <linux/completion.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 32 #include <linux/kallsyms.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 33 #include <linux/random.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 34 #include <linux/prctl.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 35 #include <linux/nmi.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 36
803b0fc5c3f2baa Huacai Chen 2022-05-31 37 #include <asm/asm.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 38 #include <asm/bootinfo.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 39 #include <asm/cpu.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 40 #include <asm/elf.h>
c718a0bad75ccef Bibo Mao 2023-09-20 41 #include <asm/exec.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 42 #include <asm/fpu.h>
bd3c5798484aa9a Qi Hu 2023-09-06 43 #include <asm/lbt.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 44 #include <asm/io.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 45 #include <asm/irq.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 46 #include <asm/irq_regs.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 47 #include <asm/loongarch.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 48 #include <asm/pgtable.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 49 #include <asm/processor.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 50 #include <asm/reg.h>
5c881018646d666 Charlie Jenkins 2025-01-22 51 #include <asm/switch_to.h>
49232773d8233ed Qing Zhang 2022-08-06 52 #include <asm/unwind.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 53 #include <asm/vdso.h>
803b0fc5c3f2baa Huacai Chen 2022-05-31 54
09f33601bf940f9 Huacai Chen 2022-12-10 55 #ifdef CONFIG_STACKPROTECTOR
09f33601bf940f9 Huacai Chen 2022-12-10 56 #include <linux/stackprotector.h>
09f33601bf940f9 Huacai Chen 2022-12-10 57 unsigned long __stack_chk_guard __read_mostly;
09f33601bf940f9 Huacai Chen 2022-12-10 58 EXPORT_SYMBOL(__stack_chk_guard);
09f33601bf940f9 Huacai Chen 2022-12-10 59 #endif
09f33601bf940f9 Huacai Chen 2022-12-10 60
803b0fc5c3f2baa Huacai Chen 2022-05-31 61 /*
803b0fc5c3f2baa Huacai Chen 2022-05-31 62 * Idle related variables and functions
803b0fc5c3f2baa Huacai Chen 2022-05-31 63 */
803b0fc5c3f2baa Huacai Chen 2022-05-31 64
803b0fc5c3f2baa Huacai Chen 2022-05-31 65 unsigned long boot_option_idle_override = IDLE_NO_OVERRIDE;
803b0fc5c3f2baa Huacai Chen 2022-05-31 66 EXPORT_SYMBOL(boot_option_idle_override);
803b0fc5c3f2baa Huacai Chen 2022-05-31 67
5c881018646d666 Charlie Jenkins 2025-01-22 68 asmlinkage void restore_and_ret(void);
5c881018646d666 Charlie Jenkins 2025-01-22 69 asmlinkage void ret_from_fork_asm(void);
5c881018646d666 Charlie Jenkins 2025-01-22 @70 void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev,
5c881018646d666 Charlie Jenkins 2025-01-22 71 struct pt_regs *regs,
5c881018646d666 Charlie Jenkins 2025-01-22 72 int (*fn)(void *),
5c881018646d666 Charlie Jenkins 2025-01-22 73 void *fn_arg)
803b0fc5c3f2baa Huacai Chen 2022-05-31 74
803b0fc5c3f2baa Huacai Chen 2022-05-31 75 void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
803b0fc5c3f2baa Huacai Chen 2022-05-31 @76 {
803b0fc5c3f2baa Huacai Chen 2022-05-31 77 unsigned long crmd;
803b0fc5c3f2baa Huacai Chen 2022-05-31 78 unsigned long prmd;
803b0fc5c3f2baa Huacai Chen 2022-05-31 79 unsigned long euen;
803b0fc5c3f2baa Huacai Chen 2022-05-31 80
803b0fc5c3f2baa Huacai Chen 2022-05-31 81 /* New thread loses kernel privileges. */
803b0fc5c3f2baa Huacai Chen 2022-05-31 82 crmd = regs->csr_crmd & ~(PLV_MASK);
803b0fc5c3f2baa Huacai Chen 2022-05-31 83 crmd |= PLV_USER;
803b0fc5c3f2baa Huacai Chen 2022-05-31 84 regs->csr_crmd = crmd;
803b0fc5c3f2baa Huacai Chen 2022-05-31 85
803b0fc5c3f2baa Huacai Chen 2022-05-31 86 prmd = regs->csr_prmd & ~(PLV_MASK);
803b0fc5c3f2baa Huacai Chen 2022-05-31 87 prmd |= PLV_USER;
803b0fc5c3f2baa Huacai Chen 2022-05-31 88 regs->csr_prmd = prmd;
803b0fc5c3f2baa Huacai Chen 2022-05-31 89
803b0fc5c3f2baa Huacai Chen 2022-05-31 90 euen = regs->csr_euen & ~(CSR_EUEN_FPEN);
803b0fc5c3f2baa Huacai Chen 2022-05-31 91 regs->csr_euen = euen;
803b0fc5c3f2baa Huacai Chen 2022-05-31 92 lose_fpu(0);
bd3c5798484aa9a Qi Hu 2023-09-06 93 lose_lbt(0);
c2396651309eba2 Xi Ruoyao 2024-01-17 94 current->thread.fpu.fcsr = boot_cpu_data.fpu_csr0;
803b0fc5c3f2baa Huacai Chen 2022-05-31 95
803b0fc5c3f2baa Huacai Chen 2022-05-31 96 clear_thread_flag(TIF_LSX_CTX_LIVE);
803b0fc5c3f2baa Huacai Chen 2022-05-31 97 clear_thread_flag(TIF_LASX_CTX_LIVE);
bd3c5798484aa9a Qi Hu 2023-09-06 98 clear_thread_flag(TIF_LBT_CTX_LIVE);
803b0fc5c3f2baa Huacai Chen 2022-05-31 99 clear_used_math();
803b0fc5c3f2baa Huacai Chen 2022-05-31 100 regs->csr_era = pc;
803b0fc5c3f2baa Huacai Chen 2022-05-31 101 regs->regs[3] = sp;
803b0fc5c3f2baa Huacai Chen 2022-05-31 102 }
803b0fc5c3f2baa Huacai Chen 2022-05-31 103
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.