Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags   |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Process creation support for Hexagon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/sched/task.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/tick.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * Program thread launch.  Often defined as a macro in processor.h,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * but we're shooting for a small footprint and it's not an inner-loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * performance-critical operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * The Hexagon ABI specifies that R28 is zero'ed before program launch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * so that gets automatically done here.  If we ever stop doing that here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * we'll probably want to define the ELF_PLAT_INIT macro.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	/* We want to zero all data-containing registers. Is this overkill? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	memset(regs, 0, sizeof(*regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	/* We might want to also zero all Processor registers here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	pt_set_usermode(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	pt_set_elr(regs, pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	pt_set_rte_sp(regs, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  *  Spin, or better still, do a hardware or VM wait instruction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  *  If hardware or VM offer wait termination even though interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *  are disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) void arch_cpu_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	__vmwait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	/*  interrupts wake us up, but irqs are still disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	raw_local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * Copy architecture-specific thread state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		struct task_struct *p, unsigned long tls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	struct thread_info *ti = task_thread_info(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	struct hexagon_switch_stack *ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	struct pt_regs *childregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	asmlinkage void ret_from_fork(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	childregs = (struct pt_regs *) (((unsigned long) ti + THREAD_SIZE) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 					sizeof(*childregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	ti->regs = childregs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	 * Establish kernel stack pointer and initial PC for new thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	 * Note that unlike the usual situation, we do not copy the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * parent's callee-saved here; those are in pt_regs and whatever
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 * we leave here will be overridden on return to userland.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	ss = (struct hexagon_switch_stack *) ((unsigned long) childregs -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 						    sizeof(*ss));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	ss->lr = (unsigned long)ret_from_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	p->thread.switch_sp = ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (unlikely(p->flags & PF_KTHREAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		memset(childregs, 0, sizeof(struct pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		/* r24 <- fn, r25 <- arg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		ss->r24 = usp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		ss->r25 = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		pt_set_kmode(childregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	memcpy(childregs, current_pt_regs(), sizeof(*childregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	ss->r2524 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (usp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		pt_set_rte_sp(childregs, usp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	/* Child sees zero return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	childregs->r00 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	 * The clone syscall has the C signature:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	 * int [r0] clone(int flags [r0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	 *           void *child_frame [r1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	 *           void *parent_tid [r2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	 *           void *child_tid [r3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	 *           void *thread_control_block [r4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	 * ugp is used to provide TLS support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	if (clone_flags & CLONE_SETTLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		childregs->ugp = tls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	 * Parent sees new pid -- not necessary, not even possible at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	 * this point in the fork process
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	 * Might also want to set things like ti->addr_limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * Release any architecture-specific resources locked by thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) void release_thread(struct task_struct *dead_task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * Some archs flush debug and FPU info here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) void flush_thread(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  * The "wait channel" terminology is archaic, but what we want
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * is an identification of the point at which the scheduler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * was invoked by a blocked thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) unsigned long get_wchan(struct task_struct *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	unsigned long fp, pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	unsigned long stack_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	if (!p || p == current || p->state == TASK_RUNNING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	stack_page = (unsigned long)task_stack_page(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 		if (fp < (stack_page + sizeof(struct thread_info)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			fp >= (THREAD_SIZE - 8 + stack_page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		pc = ((unsigned long *)fp)[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		if (!in_sched_functions(pc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			return pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		fp = *(unsigned long *) fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	} while (count++ < 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  * Called on the exit path of event entry; see vm_entry.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * Interrupts will already be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)  * Returns 0 if there's no need to re-check for more work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	if (!(thread_info_flags & _TIF_WORK_MASK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}  /* shortcut -- no work to be done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (thread_info_flags & _TIF_NEED_RESCHED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (thread_info_flags & _TIF_SIGPENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		do_signal(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		tracehook_notify_resume(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	/* Should not even reach here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	panic("%s: bad thread_info flags 0x%08x\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		thread_info_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }