Loading arch/loongarch/include/asm/asm-prototypes.h +8 −0 Original line number Diff line number Diff line Loading @@ -12,3 +12,11 @@ __int128_t __ashlti3(__int128_t a, int b); __int128_t __ashrti3(__int128_t a, int b); __int128_t __lshrti3(__int128_t a, int b); #endif asmlinkage void noinstr __no_stack_protector ret_from_fork(struct task_struct *prev, struct pt_regs *regs); asmlinkage void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev, struct pt_regs *regs, int (*fn)(void *), void *fn_arg); arch/loongarch/kernel/entry.S +10 −12 Original line number Diff line number Diff line Loading @@ -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) arch/loongarch/kernel/process.c +27 −6 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <linux/cpu.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/entry-common.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/sched/debug.h> Loading @@ -34,6 +35,7 @@ #include <linux/nmi.h> #include <asm/asm.h> #include <asm/asm-prototypes.h> #include <asm/bootinfo.h> #include <asm/cpu.h> #include <asm/elf.h> Loading @@ -47,6 +49,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> Loading @@ -63,8 +66,9 @@ 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); asmlinkage void ret_from_kernel_thread_asm(void); void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { Loading Loading @@ -138,6 +142,23 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) return 0; } asmlinkage 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); } asmlinkage 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); } /* * Copy architecture-specific thread state */ Loading Loading @@ -165,8 +186,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; Loading @@ -182,8 +203,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 Loading arch/riscv/include/asm/asm-prototypes.h +2 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ DECLARE_DO_ERROR_INFO(do_trap_ecall_s); DECLARE_DO_ERROR_INFO(do_trap_ecall_m); DECLARE_DO_ERROR_INFO(do_trap_break); asmlinkage void ret_from_fork_kernel(void *fn_arg, int (*fn)(void *), struct pt_regs *regs); asmlinkage void ret_from_fork_user(struct pt_regs *regs); asmlinkage void handle_bad_stack(struct pt_regs *regs); asmlinkage void do_page_fault(struct pt_regs *regs); asmlinkage void do_irq(struct pt_regs *regs); Loading arch/riscv/kernel/entry.S +12 −8 Original line number Diff line number Diff line Loading @@ -319,17 +319,21 @@ SYM_CODE_END(handle_kernel_stack_overflow) ASM_NOKPROBE(handle_kernel_stack_overflow) #endif SYM_CODE_START(ret_from_fork) SYM_CODE_START(ret_from_fork_kernel_asm) call schedule_tail move a0, s1 /* fn_arg */ move a1, s0 /* fn */ move a2, sp /* pt_regs */ call ret_from_fork_kernel j ret_from_exception SYM_CODE_END(ret_from_fork_kernel_asm) SYM_CODE_START(ret_from_fork_user_asm) call schedule_tail beqz s0, 1f /* not from kernel thread */ /* Call fn(arg) */ move a0, s1 jalr s0 1: move a0, sp /* pt_regs */ call syscall_exit_to_user_mode call ret_from_fork_user j ret_from_exception SYM_CODE_END(ret_from_fork) SYM_CODE_END(ret_from_fork_user_asm) #ifdef CONFIG_IRQ_STACKS /* Loading Loading
arch/loongarch/include/asm/asm-prototypes.h +8 −0 Original line number Diff line number Diff line Loading @@ -12,3 +12,11 @@ __int128_t __ashlti3(__int128_t a, int b); __int128_t __ashrti3(__int128_t a, int b); __int128_t __lshrti3(__int128_t a, int b); #endif asmlinkage void noinstr __no_stack_protector ret_from_fork(struct task_struct *prev, struct pt_regs *regs); asmlinkage void noinstr __no_stack_protector ret_from_kernel_thread(struct task_struct *prev, struct pt_regs *regs, int (*fn)(void *), void *fn_arg);
arch/loongarch/kernel/entry.S +10 −12 Original line number Diff line number Diff line Loading @@ -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)
arch/loongarch/kernel/process.c +27 −6 Original line number Diff line number Diff line Loading @@ -13,6 +13,7 @@ #include <linux/cpu.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/entry-common.h> #include <linux/errno.h> #include <linux/sched.h> #include <linux/sched/debug.h> Loading @@ -34,6 +35,7 @@ #include <linux/nmi.h> #include <asm/asm.h> #include <asm/asm-prototypes.h> #include <asm/bootinfo.h> #include <asm/cpu.h> #include <asm/elf.h> Loading @@ -47,6 +49,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> Loading @@ -63,8 +66,9 @@ 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); asmlinkage void ret_from_kernel_thread_asm(void); void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp) { Loading Loading @@ -138,6 +142,23 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src) return 0; } asmlinkage 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); } asmlinkage 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); } /* * Copy architecture-specific thread state */ Loading Loading @@ -165,8 +186,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; Loading @@ -182,8 +203,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 Loading
arch/riscv/include/asm/asm-prototypes.h +2 −0 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ DECLARE_DO_ERROR_INFO(do_trap_ecall_s); DECLARE_DO_ERROR_INFO(do_trap_ecall_m); DECLARE_DO_ERROR_INFO(do_trap_break); asmlinkage void ret_from_fork_kernel(void *fn_arg, int (*fn)(void *), struct pt_regs *regs); asmlinkage void ret_from_fork_user(struct pt_regs *regs); asmlinkage void handle_bad_stack(struct pt_regs *regs); asmlinkage void do_page_fault(struct pt_regs *regs); asmlinkage void do_irq(struct pt_regs *regs); Loading
arch/riscv/kernel/entry.S +12 −8 Original line number Diff line number Diff line Loading @@ -319,17 +319,21 @@ SYM_CODE_END(handle_kernel_stack_overflow) ASM_NOKPROBE(handle_kernel_stack_overflow) #endif SYM_CODE_START(ret_from_fork) SYM_CODE_START(ret_from_fork_kernel_asm) call schedule_tail move a0, s1 /* fn_arg */ move a1, s0 /* fn */ move a2, sp /* pt_regs */ call ret_from_fork_kernel j ret_from_exception SYM_CODE_END(ret_from_fork_kernel_asm) SYM_CODE_START(ret_from_fork_user_asm) call schedule_tail beqz s0, 1f /* not from kernel thread */ /* Call fn(arg) */ move a0, s1 jalr s0 1: move a0, sp /* pt_regs */ call syscall_exit_to_user_mode call ret_from_fork_user j ret_from_exception SYM_CODE_END(ret_from_fork) SYM_CODE_END(ret_from_fork_user_asm) #ifdef CONFIG_IRQ_STACKS /* Loading