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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * License.  See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2001 - 2007  Tensilica Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Chris Zankel <chris@zankel.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Scott Foehner<sfoehner@yahoo.com>,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Kevin Chea
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/hw_breakpoint.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/regset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/seccomp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define CREATE_TRACE_POINTS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <trace/events/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <asm/coprocessor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <asm/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static int gpr_get(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		   const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct pt_regs *regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct user_pt_regs newregs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		.pc = regs->pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		.ps = regs->ps & ~(1 << PS_EXCM_BIT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		.lbeg = regs->lbeg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		.lend = regs->lend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		.lcount = regs->lcount,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		.sar = regs->sar,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		.threadptr = regs->threadptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		.windowbase = regs->windowbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		.windowstart = regs->windowstart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		.syscall = regs->syscall,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	memcpy(newregs.a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	       regs->areg + XCHAL_NUM_AREGS - regs->windowbase * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	       regs->windowbase * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	memcpy(newregs.a + regs->windowbase * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	       regs->areg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	       (WSBITS - regs->windowbase) * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	return membuf_write(&to, &newregs, sizeof(newregs));
^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) static int gpr_set(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		   const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		   unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		   const void *kbuf, const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct user_pt_regs newregs = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct pt_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	const u32 ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newregs, 0, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	if (newregs.windowbase >= XCHAL_NUM_AREGS / 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	regs->pc = newregs.pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	regs->ps = (regs->ps & ~ps_mask) | (newregs.ps & ps_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	regs->lbeg = newregs.lbeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	regs->lend = newregs.lend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	regs->lcount = newregs.lcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	regs->sar = newregs.sar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	regs->threadptr = newregs.threadptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	if (newregs.syscall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		regs->syscall = newregs.syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (newregs.windowbase != regs->windowbase ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	    newregs.windowstart != regs->windowstart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		u32 rotws, wmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		rotws = (((newregs.windowstart |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 			   (newregs.windowstart << WSBITS)) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 			  newregs.windowbase) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 			 ((1 << WSBITS) - 1)) & ~1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		wmask = ((rotws ? WSBITS + 1 - ffs(rotws) : 0) << 4) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 			(rotws & 0xF) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		regs->windowbase = newregs.windowbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		regs->windowstart = newregs.windowstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		regs->wmask = wmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	memcpy(regs->areg + XCHAL_NUM_AREGS - newregs.windowbase * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	       newregs.a, newregs.windowbase * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	memcpy(regs->areg, newregs.a + newregs.windowbase * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	       (WSBITS - newregs.windowbase) * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return 0;
^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) static int tie_get(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		   const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		   struct membuf to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	struct pt_regs *regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	struct thread_info *ti = task_thread_info(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	elf_xtregs_t *newregs = kzalloc(sizeof(elf_xtregs_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (!newregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	newregs->opt = regs->xtregs_opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	newregs->user = ti->xtregs_user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #if XTENSA_HAVE_COPROCESSORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	/* Flush all coprocessor registers to memory. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	coprocessor_flush_all(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	newregs->cp0 = ti->xtregs_cp.cp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	newregs->cp1 = ti->xtregs_cp.cp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	newregs->cp2 = ti->xtregs_cp.cp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	newregs->cp3 = ti->xtregs_cp.cp3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	newregs->cp4 = ti->xtregs_cp.cp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	newregs->cp5 = ti->xtregs_cp.cp5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	newregs->cp6 = ti->xtregs_cp.cp6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	newregs->cp7 = ti->xtregs_cp.cp7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	ret = membuf_write(&to, newregs, sizeof(*newregs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	kfree(newregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static int tie_set(struct task_struct *target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		   const struct user_regset *regset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		   unsigned int pos, unsigned int count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		   const void *kbuf, const void __user *ubuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	struct pt_regs *regs = task_pt_regs(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	struct thread_info *ti = task_thread_info(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	elf_xtregs_t *newregs = kzalloc(sizeof(elf_xtregs_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	if (!newregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				 newregs, 0, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	regs->xtregs_opt = newregs->opt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	ti->xtregs_user = newregs->user;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #if XTENSA_HAVE_COPROCESSORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	/* Flush all coprocessors before we overwrite them. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	coprocessor_flush_all(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	coprocessor_release_all(ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	ti->xtregs_cp.cp0 = newregs->cp0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	ti->xtregs_cp.cp1 = newregs->cp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ti->xtregs_cp.cp2 = newregs->cp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	ti->xtregs_cp.cp3 = newregs->cp3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	ti->xtregs_cp.cp4 = newregs->cp4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	ti->xtregs_cp.cp5 = newregs->cp5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	ti->xtregs_cp.cp6 = newregs->cp6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	ti->xtregs_cp.cp7 = newregs->cp7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	kfree(newregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) enum xtensa_regset {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	REGSET_GPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	REGSET_TIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) static const struct user_regset xtensa_regsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	[REGSET_GPR] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 		.core_note_type = NT_PRSTATUS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		.n = sizeof(struct user_pt_regs) / sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		.size = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		.align = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		.regset_get = gpr_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		.set = gpr_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	[REGSET_TIE] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		.core_note_type = NT_PRFPREG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		.n = sizeof(elf_xtregs_t) / sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		.size = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		.align = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		.regset_get = tie_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		.set = tie_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static const struct user_regset_view user_xtensa_view = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	.name = "xtensa",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	.e_machine = EM_XTENSA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	.regsets = xtensa_regsets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	.n = ARRAY_SIZE(xtensa_regsets)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) const struct user_regset_view *task_user_regset_view(struct task_struct *task)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return &user_xtensa_view;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) void user_enable_single_step(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	child->ptrace |= PT_SINGLESTEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) void user_disable_single_step(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	child->ptrace &= ~PT_SINGLESTEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * Called by kernel/ptrace.c when detaching to disable single stepping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) void ptrace_disable(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	/* Nothing to do.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int ptrace_getregs(struct task_struct *child, void __user *uregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	return copy_regset_to_user(child, &user_xtensa_view, REGSET_GPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 				   0, sizeof(xtensa_gregset_t), uregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int ptrace_setregs(struct task_struct *child, void __user *uregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	return copy_regset_from_user(child, &user_xtensa_view, REGSET_GPR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 				     0, sizeof(xtensa_gregset_t), uregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int ptrace_getxregs(struct task_struct *child, void __user *uregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return copy_regset_to_user(child, &user_xtensa_view, REGSET_TIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				   0, sizeof(elf_xtregs_t), uregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int ptrace_setxregs(struct task_struct *child, void __user *uregs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	return copy_regset_from_user(child, &user_xtensa_view, REGSET_TIE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 				     0, sizeof(elf_xtregs_t), uregs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int ptrace_peekusr(struct task_struct *child, long regno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			  long __user *ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	struct pt_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	unsigned long tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	regs = task_pt_regs(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	tmp = 0;  /* Default return value. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	switch(regno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		tmp = regs->areg[regno - REG_AR_BASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	case REG_A_BASE ... REG_A_BASE + 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		tmp = regs->areg[regno - REG_A_BASE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	case REG_PC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		tmp = regs->pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	case REG_PS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		/* Note: PS.EXCM is not set while user task is running;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		 * its being set in regs is for exception handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		 * convenience.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		tmp = (regs->ps & ~(1 << PS_EXCM_BIT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	case REG_WB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		break;		/* tmp = 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	case REG_WS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 			unsigned long wb = regs->windowbase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			unsigned long ws = regs->windowstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 			tmp = ((ws >> wb) | (ws << (WSBITS - wb))) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 				((1 << WSBITS) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	case REG_LBEG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 		tmp = regs->lbeg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	case REG_LEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		tmp = regs->lend;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	case REG_LCOUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		tmp = regs->lcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	case REG_SAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		tmp = regs->sar;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	case SYSCALL_NR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		tmp = regs->syscall;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	return put_user(tmp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static int ptrace_pokeusr(struct task_struct *child, long regno, long val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	struct pt_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	regs = task_pt_regs(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	switch (regno) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	case REG_AR_BASE ... REG_AR_BASE + XCHAL_NUM_AREGS - 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		regs->areg[regno - REG_AR_BASE] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	case REG_A_BASE ... REG_A_BASE + 15:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		regs->areg[regno - REG_A_BASE] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	case REG_PC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		regs->pc = val;
^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) 	case SYSCALL_NR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 		regs->syscall = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #ifdef CONFIG_HAVE_HW_BREAKPOINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static void ptrace_hbptriggered(struct perf_event *bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 				struct perf_sample_data *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 				struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	struct arch_hw_breakpoint *bkpt = counter_arch_bp(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	if (bp->attr.bp_type & HW_BREAKPOINT_X) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		for (i = 0; i < XCHAL_NUM_IBREAK; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			if (current->thread.ptrace_bp[i] == bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		i <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		for (i = 0; i < XCHAL_NUM_DBREAK; ++i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			if (current->thread.ptrace_wp[i] == bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 		i = (i << 1) | 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	force_sig_ptrace_errno_trap(i, (void __user *)bkpt->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	ptrace_breakpoint_init(&attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	/* Initialise fields to sane defaults. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	attr.bp_addr	= 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	attr.bp_len	= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	attr.bp_type	= type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	attr.disabled	= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 					   tsk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  * Address bit 0 choose instruction (0) or data (1) break register, bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  * 31..1 are the register number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  * Both PTRACE_GETHBPREGS and PTRACE_SETHBPREGS transfer two 32-bit words:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  * address (0) and control (1).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  * Instruction breakpoint contorl word is 0 to clear breakpoint, 1 to set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  * Data breakpoint control word bit 31 is 'trigger on store', bit 30 is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)  * 'trigger on load, bits 29..0 are length. Length 0 is used to clear a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  * breakpoint. To set a breakpoint length must be a power of 2 in the range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * 1..64 and the address must be length-aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) static long ptrace_gethbpregs(struct task_struct *child, long addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 			      long __user *datap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	struct perf_event *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	u32 user_data[2] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	bool dbreak = addr & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	unsigned idx = addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	if ((!dbreak && idx >= XCHAL_NUM_IBREAK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	    (dbreak && idx >= XCHAL_NUM_DBREAK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (dbreak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		bp = child->thread.ptrace_wp[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		bp = child->thread.ptrace_bp[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		user_data[0] = bp->attr.bp_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		user_data[1] = bp->attr.disabled ? 0 : bp->attr.bp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		if (dbreak) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 			if (bp->attr.bp_type & HW_BREAKPOINT_R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 				user_data[1] |= DBREAKC_LOAD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 			if (bp->attr.bp_type & HW_BREAKPOINT_W)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 				user_data[1] |= DBREAKC_STOR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	if (copy_to_user(datap, user_data, sizeof(user_data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static long ptrace_sethbpregs(struct task_struct *child, long addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 			      long __user *datap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	struct perf_event *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	struct perf_event_attr attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	u32 user_data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	bool dbreak = addr & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	unsigned idx = addr >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	int bp_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	if ((!dbreak && idx >= XCHAL_NUM_IBREAK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	    (dbreak && idx >= XCHAL_NUM_DBREAK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if (copy_from_user(user_data, datap, sizeof(user_data)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	if (dbreak) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 		bp = child->thread.ptrace_wp[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 		if (user_data[1] & DBREAKC_LOAD_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 			bp_type |= HW_BREAKPOINT_R;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		if (user_data[1] & DBREAKC_STOR_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 			bp_type |= HW_BREAKPOINT_W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		bp = child->thread.ptrace_bp[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		bp_type = HW_BREAKPOINT_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (!bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		bp = ptrace_hbp_create(child,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 				       bp_type ? bp_type : HW_BREAKPOINT_RW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 		if (IS_ERR(bp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 			return PTR_ERR(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 		if (dbreak)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 			child->thread.ptrace_wp[idx] = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 			child->thread.ptrace_bp[idx] = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	attr = bp->attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	attr.bp_addr = user_data[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	attr.bp_len = user_data[1] & ~(DBREAKC_LOAD_MASK | DBREAKC_STOR_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	attr.bp_type = bp_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	attr.disabled = !attr.bp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	return modify_user_hw_breakpoint(bp, &attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) long arch_ptrace(struct task_struct *child, long request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 		 unsigned long addr, unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	int ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	void __user *datap = (void __user *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	case PTRACE_PEEKUSR:	/* read register specified by addr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		ret = ptrace_peekusr(child, addr, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	case PTRACE_POKEUSR:	/* write register specified by addr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		ret = ptrace_pokeusr(child, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	case PTRACE_GETREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 		ret = ptrace_getregs(child, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	case PTRACE_SETREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		ret = ptrace_setregs(child, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	case PTRACE_GETXTREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		ret = ptrace_getxregs(child, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	case PTRACE_SETXTREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 		ret = ptrace_setxregs(child, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) #ifdef CONFIG_HAVE_HW_BREAKPOINT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	case PTRACE_GETHBPREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		ret = ptrace_gethbpregs(child, addr, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 	case PTRACE_SETHBPREGS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		ret = ptrace_sethbpregs(child, addr, datap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		ret = ptrace_request(child, request, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) void do_syscall_trace_leave(struct pt_regs *regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) int do_syscall_trace_enter(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 	if (regs->syscall == NO_SYSCALL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		regs->areg[2] = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	if (test_thread_flag(TIF_SYSCALL_TRACE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	    tracehook_report_syscall_entry(regs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		regs->areg[2] = -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 		regs->syscall = NO_SYSCALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	if (regs->syscall == NO_SYSCALL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 	    secure_computing() == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		do_syscall_trace_leave(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		trace_sys_enter(regs, syscall_get_nr(current, regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	audit_syscall_entry(regs->syscall, regs->areg[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 			    regs->areg[3], regs->areg[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 			    regs->areg[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) void do_syscall_trace_leave(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	int step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	audit_syscall_exit(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		trace_sys_exit(regs, regs_return_value(regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	step = test_thread_flag(TIF_SINGLESTEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		tracehook_report_syscall_exit(regs, step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }