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
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * SuperH process tracing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 1999, 2000  Kaz Kojima & Niibe Yutaka
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2002 - 2009  Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/seccomp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/regset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/hw_breakpoint.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <asm/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <asm/fpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define CREATE_TRACE_POINTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <trace/events/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * This routine will get a word off of the process kernel stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static inline int get_stack_long(struct task_struct *task, int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	unsigned char *stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	stack = (unsigned char *)task_pt_regs(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	stack += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	return (*((int *)stack));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49)  * This routine will put a word on the process kernel stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static inline int put_stack_long(struct task_struct *task, int offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 				 unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	unsigned char *stack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	stack = (unsigned char *)task_pt_regs(task);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	stack += offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	*(unsigned long *) stack = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) void ptrace_triggered(struct perf_event *bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		      struct perf_sample_data *data, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	 * Disable the breakpoint request here since ptrace has defined a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	 * one-shot behaviour for breakpoint exceptions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	attr = bp->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	attr.disabled = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	modify_user_hw_breakpoint(bp, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) static int set_single_step(struct task_struct *tsk, unsigned long addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	struct thread_struct *thread = &tsk->thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	struct perf_event *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	bp = thread->ptrace_bps[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (!bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		ptrace_breakpoint_init(&attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		attr.bp_addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		attr.bp_len = HW_BREAKPOINT_LEN_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		attr.bp_type = HW_BREAKPOINT_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		bp = register_user_hw_breakpoint(&attr, ptrace_triggered,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 						 NULL, tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		if (IS_ERR(bp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			return PTR_ERR(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		thread->ptrace_bps[0] = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		attr = bp->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		attr.bp_addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		/* reenable breakpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		attr.disabled = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		err = modify_user_hw_breakpoint(bp, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	return 0;
^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) void user_enable_single_step(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	unsigned long pc = get_stack_long(child, offsetof(struct pt_regs, pc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	set_tsk_thread_flag(child, TIF_SINGLESTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	set_single_step(child, pc);
^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) void user_disable_single_step(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	clear_tsk_thread_flag(child, TIF_SINGLESTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  * Called by kernel/ptrace.c when detaching..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)  * Make sure single step bits etc are not set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) void ptrace_disable(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	user_disable_single_step(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) static int genregs_get(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		       const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		       struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	const struct pt_regs *regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return membuf_write(&to, regs, sizeof(struct pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static int genregs_set(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		       const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		       unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		       const void *kbuf, const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct pt_regs *regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 				 regs->regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 				 0, 16 * sizeof(unsigned long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (!ret && count > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 					 &regs->pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 					 offsetof(struct pt_regs, pc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 					 sizeof(struct pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 						sizeof(struct pt_regs), -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static int fpregs_get(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	       const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	       struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	ret = init_fpu(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	return membuf_write(&to, target->thread.xstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 			    sizeof(struct user_fpu_struct));
^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) static int fpregs_set(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		       const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		       unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		       const void *kbuf, const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	ret = init_fpu(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	set_stopped_child_used_math(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	if ((boot_cpu_data.flags & CPU_HAS_FPU))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 					  &target->thread.xstate->hardfpu, 0, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 				  &target->thread.xstate->softfpu, 0, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int fpregs_active(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 			 const struct user_regset *regset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	return tsk_used_math(target) ? regset->n : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #ifdef CONFIG_SH_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int dspregs_get(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		       const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		       struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	const struct pt_dspregs *regs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		(struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	return membuf_write(&to, regs, sizeof(struct pt_dspregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static int dspregs_set(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		       const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		       unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		       const void *kbuf, const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	struct pt_dspregs *regs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		(struct pt_dspregs *)&target->thread.dsp_status.dsp_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 				 0, sizeof(struct pt_dspregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 						sizeof(struct pt_dspregs), -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static int dspregs_active(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 			  const struct user_regset *regset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	struct pt_regs *regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	return regs->sr & SR_DSP ? regset->n : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) const struct pt_regs_offset regoffset_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	REGS_OFFSET_NAME(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	REGS_OFFSET_NAME(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	REGS_OFFSET_NAME(2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	REGS_OFFSET_NAME(3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	REGS_OFFSET_NAME(4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	REGS_OFFSET_NAME(5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	REGS_OFFSET_NAME(6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	REGS_OFFSET_NAME(7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	REGS_OFFSET_NAME(8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	REGS_OFFSET_NAME(9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	REGS_OFFSET_NAME(10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	REGS_OFFSET_NAME(11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	REGS_OFFSET_NAME(12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 	REGS_OFFSET_NAME(13),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	REGS_OFFSET_NAME(14),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	REGS_OFFSET_NAME(15),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	REG_OFFSET_NAME(pc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	REG_OFFSET_NAME(pr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	REG_OFFSET_NAME(sr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	REG_OFFSET_NAME(gbr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	REG_OFFSET_NAME(mach),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	REG_OFFSET_NAME(macl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	REG_OFFSET_NAME(tra),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	REG_OFFSET_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * These are our native regset flavours.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) enum sh_regset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	REGSET_GENERAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	REGSET_FPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) #ifdef CONFIG_SH_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	REGSET_DSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static const struct user_regset sh_regsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	 * Format is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	 *	R0 --> R15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	 *	PC, PR, SR, GBR, MACH, MACL, TRA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	[REGSET_GENERAL] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		.core_note_type	= NT_PRSTATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		.n		= ELF_NGREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		.size		= sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		.align		= sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		.regset_get		= genregs_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		.set		= genregs_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	[REGSET_FPU] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		.core_note_type	= NT_PRFPREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		.n		= sizeof(struct user_fpu_struct) / sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		.size		= sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		.align		= sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 		.regset_get		= fpregs_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		.set		= fpregs_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		.active		= fpregs_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) #ifdef CONFIG_SH_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	[REGSET_DSP] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		.n		= sizeof(struct pt_dspregs) / sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		.size		= sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		.align		= sizeof(long),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		.regset_get		= dspregs_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		.set		= dspregs_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		.active		= dspregs_active,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) static const struct user_regset_view user_sh_native_view = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	.name		= "sh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	.e_machine	= EM_SH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	.regsets	= sh_regsets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	.n		= ARRAY_SIZE(sh_regsets),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) const struct user_regset_view *task_user_regset_view(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	return &user_sh_native_view;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) long arch_ptrace(struct task_struct *child, long request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		 unsigned long addr, unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	unsigned long __user *datap = (unsigned long __user *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	/* read the word at location addr in the USER area. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	case PTRACE_PEEKUSR: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		if ((addr & 3) || addr < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		    addr > sizeof(struct user) - 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 		if (addr < sizeof(struct pt_regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			tmp = get_stack_long(child, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		else if (addr >= offsetof(struct user, fpu) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			 addr < offsetof(struct user, u_fpvalid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 			if (!tsk_used_math(child)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 				if (addr == offsetof(struct user, fpu.fpscr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 					tmp = FPSCR_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 					tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 				unsigned long index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				ret = init_fpu(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 				if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 				index = addr - offsetof(struct user, fpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 				tmp = ((unsigned long *)child->thread.xstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 					[index >> 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		} else if (addr == offsetof(struct user, u_fpvalid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 			tmp = !!tsk_used_math(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		else if (addr == PT_TEXT_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 			tmp = child->mm->start_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		else if (addr == PT_DATA_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			tmp = child->mm->start_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		else if (addr == PT_TEXT_END_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			tmp = child->mm->end_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		else if (addr == PT_TEXT_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 			tmp = child->mm->end_code - child->mm->start_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 			tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		ret = put_user(tmp, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		if ((addr & 3) || addr < 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		    addr > sizeof(struct user) - 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		if (addr < sizeof(struct pt_regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 			ret = put_stack_long(child, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		else if (addr >= offsetof(struct user, fpu) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			 addr < offsetof(struct user, u_fpvalid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			unsigned long index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			ret = init_fpu(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			index = addr - offsetof(struct user, fpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 			set_stopped_child_used_math(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			((unsigned long *)child->thread.xstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 				[index >> 2] = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		} else if (addr == offsetof(struct user, u_fpvalid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			conditional_stopped_child_used_math(data, child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	case PTRACE_GETREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		return copy_regset_to_user(child, &user_sh_native_view,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 					   REGSET_GENERAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 					   0, sizeof(struct pt_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 					   datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	case PTRACE_SETREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		return copy_regset_from_user(child, &user_sh_native_view,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 					     REGSET_GENERAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 					     0, sizeof(struct pt_regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 					     datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) #ifdef CONFIG_SH_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	case PTRACE_GETFPREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return copy_regset_to_user(child, &user_sh_native_view,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 					   REGSET_FPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 					   0, sizeof(struct user_fpu_struct),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 					   datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	case PTRACE_SETFPREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		return copy_regset_from_user(child, &user_sh_native_view,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 					     REGSET_FPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 					     0, sizeof(struct user_fpu_struct),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 					     datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) #ifdef CONFIG_SH_DSP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	case PTRACE_GETDSPREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		return copy_regset_to_user(child, &user_sh_native_view,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 					   REGSET_DSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 					   0, sizeof(struct pt_dspregs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 					   datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	case PTRACE_SETDSPREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		return copy_regset_from_user(child, &user_sh_native_view,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 					     REGSET_DSP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 					     0, sizeof(struct pt_dspregs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 					     datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		ret = ptrace_request(child, request, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	    tracehook_report_syscall_entry(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		regs->regs[0] = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (secure_computing() == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		trace_sys_enter(regs, regs->regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 			    regs->regs[6], regs->regs[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	int step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	audit_syscall_exit(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		trace_sys_exit(regs, regs->regs[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	step = test_thread_flag(TIF_SINGLESTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		tracehook_report_syscall_exit(regs, step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) }