1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd. 3 4 #include <linux/audit.h> 5 #include <linux/elf.h> 6 #include <linux/errno.h> 7 #include <linux/kernel.h> 8 #include <linux/mm.h> 9 #include <linux/ptrace.h> 10 #include <linux/regset.h> 11 #include <linux/sched.h> 12 #include <linux/sched/task_stack.h> 13 #include <linux/signal.h> 14 #include <linux/smp.h> 15 #include <linux/tracehook.h> 16 #include <linux/uaccess.h> 17 #include <linux/user.h> 18 19 #include <asm/thread_info.h> 20 #include <asm/page.h> 21 #include <asm/pgtable.h> 22 #include <asm/processor.h> 23 #include <asm/asm-offsets.h> 24 25 #include <abi/regdef.h> 26 27 #define CREATE_TRACE_POINTS 28 #include <trace/events/syscalls.h> 29 30 /* sets the trace bits. */ 31 #define TRACE_MODE_SI (1 << 14) 32 #define TRACE_MODE_RUN 0 33 #define TRACE_MODE_MASK ~(0x3 << 14) 34 35 /* 36 * Make sure the single step bit is not set. 37 */ 38 static void singlestep_disable(struct task_struct *tsk) 39 { 40 struct pt_regs *regs; 41 42 regs = task_pt_regs(tsk); 43 regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_RUN; 44 45 /* Enable irq */ 46 regs->sr |= BIT(6); 47 } 48 49 static void singlestep_enable(struct task_struct *tsk) 50 { 51 struct pt_regs *regs; 52 53 regs = task_pt_regs(tsk); 54 regs->sr = (regs->sr & TRACE_MODE_MASK) | TRACE_MODE_SI; 55 56 /* Disable irq */ 57 regs->sr &= ~BIT(6); 58 } 59 60 /* 61 * Make sure the single step bit is set. 62 */ 63 void user_enable_single_step(struct task_struct *child) 64 { 65 singlestep_enable(child); 66 } 67 68 void user_disable_single_step(struct task_struct *child) 69 { 70 singlestep_disable(child); 71 } 72 73 enum csky_regset { 74 REGSET_GPR, 75 REGSET_FPR, 76 }; 77 78 static int gpr_get(struct task_struct *target, 79 const struct user_regset *regset, 80 unsigned int pos, unsigned int count, 81 void *kbuf, void __user *ubuf) 82 { 83 struct pt_regs *regs; 84 85 regs = task_pt_regs(target); 86 87 /* Abiv1 regs->tls is fake and we need sync here. */ 88 regs->tls = task_thread_info(target)->tp_value; 89 90 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs, 0, -1); 91 } 92 93 static int gpr_set(struct task_struct *target, 94 const struct user_regset *regset, 95 unsigned int pos, unsigned int count, 96 const void *kbuf, const void __user *ubuf) 97 { 98 int ret; 99 struct pt_regs regs; 100 101 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s, 0, -1); 102 if (ret) 103 return ret; 104 105 regs.sr = task_pt_regs(target)->sr; 106 #ifdef CONFIG_CPU_HAS_HILO 107 regs.dcsr = task_pt_regs(target)->dcsr; 108 #endif 109 task_thread_info(target)->tp_value = regs.tls; 110 111 *task_pt_regs(target) = regs; 112 113 return 0; 114 } 115 116 static int fpr_get(struct task_struct *target, 117 const struct user_regset *regset, 118 unsigned int pos, unsigned int count, 119 void *kbuf, void __user *ubuf) 120 { 121 struct user_fp *regs = (struct user_fp *)&target->thread.user_fp; 122 123 #if defined(CONFIG_CPU_HAS_FPUV2) && !defined(CONFIG_CPU_HAS_VDSP) 124 int i; 125 struct user_fp tmp = *regs; 126 127 for (i = 0; i < 16; i++) { 128 tmp.vr[i*4] = regs->vr[i*2]; 129 tmp.vr[i*4 + 1] = regs->vr[i*2 + 1]; 130 } 131 132 for (i = 0; i < 32; i++) 133 tmp.vr[64 + i] = regs->vr[32 + i]; 134 135 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &tmp, 0, -1); 136 #else 137 return user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs, 0, -1); 138 #endif 139 } 140 141 static int fpr_set(struct task_struct *target, 142 const struct user_regset *regset, 143 unsigned int pos, unsigned int count, 144 const void *kbuf, const void __user *ubuf) 145 { 146 int ret; 147 struct user_fp *regs = (struct user_fp *)&target->thread.user_fp; 148 149 #if defined(CONFIG_CPU_HAS_FPUV2) && !defined(CONFIG_CPU_HAS_VDSP) 150 int i; 151 struct user_fp tmp; 152 153 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tmp, 0, -1); 154 155 *regs = tmp; 156 157 for (i = 0; i < 16; i++) { 158 regs->vr[i*2] = tmp.vr[i*4]; 159 regs->vr[i*2 + 1] = tmp.vr[i*4 + 1]; 160 } 161 162 for (i = 0; i < 32; i++) 163 regs->vr[32 + i] = tmp.vr[64 + i]; 164 #else 165 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs, 0, -1); 166 #endif 167 168 return ret; 169 } 170 171 static const struct user_regset csky_regsets[] = { 172 [REGSET_GPR] = { 173 .core_note_type = NT_PRSTATUS, 174 .n = sizeof(struct pt_regs) / sizeof(u32), 175 .size = sizeof(u32), 176 .align = sizeof(u32), 177 .get = &gpr_get, 178 .set = &gpr_set, 179 }, 180 [REGSET_FPR] = { 181 .core_note_type = NT_PRFPREG, 182 .n = sizeof(struct user_fp) / sizeof(u32), 183 .size = sizeof(u32), 184 .align = sizeof(u32), 185 .get = &fpr_get, 186 .set = &fpr_set, 187 }, 188 }; 189 190 static const struct user_regset_view user_csky_view = { 191 .name = "csky", 192 .e_machine = ELF_ARCH, 193 .regsets = csky_regsets, 194 .n = ARRAY_SIZE(csky_regsets), 195 }; 196 197 const struct user_regset_view *task_user_regset_view(struct task_struct *task) 198 { 199 return &user_csky_view; 200 } 201 202 struct pt_regs_offset { 203 const char *name; 204 int offset; 205 }; 206 207 #define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} 208 #define REG_OFFSET_END {.name = NULL, .offset = 0} 209 210 static const struct pt_regs_offset regoffset_table[] = { 211 REG_OFFSET_NAME(tls), 212 REG_OFFSET_NAME(lr), 213 REG_OFFSET_NAME(pc), 214 REG_OFFSET_NAME(sr), 215 REG_OFFSET_NAME(usp), 216 REG_OFFSET_NAME(orig_a0), 217 REG_OFFSET_NAME(a0), 218 REG_OFFSET_NAME(a1), 219 REG_OFFSET_NAME(a2), 220 REG_OFFSET_NAME(a3), 221 REG_OFFSET_NAME(regs[0]), 222 REG_OFFSET_NAME(regs[1]), 223 REG_OFFSET_NAME(regs[2]), 224 REG_OFFSET_NAME(regs[3]), 225 REG_OFFSET_NAME(regs[4]), 226 REG_OFFSET_NAME(regs[5]), 227 REG_OFFSET_NAME(regs[6]), 228 REG_OFFSET_NAME(regs[7]), 229 REG_OFFSET_NAME(regs[8]), 230 REG_OFFSET_NAME(regs[9]), 231 #if defined(__CSKYABIV2__) 232 REG_OFFSET_NAME(exregs[0]), 233 REG_OFFSET_NAME(exregs[1]), 234 REG_OFFSET_NAME(exregs[2]), 235 REG_OFFSET_NAME(exregs[3]), 236 REG_OFFSET_NAME(exregs[4]), 237 REG_OFFSET_NAME(exregs[5]), 238 REG_OFFSET_NAME(exregs[6]), 239 REG_OFFSET_NAME(exregs[7]), 240 REG_OFFSET_NAME(exregs[8]), 241 REG_OFFSET_NAME(exregs[9]), 242 REG_OFFSET_NAME(exregs[10]), 243 REG_OFFSET_NAME(exregs[11]), 244 REG_OFFSET_NAME(exregs[12]), 245 REG_OFFSET_NAME(exregs[13]), 246 REG_OFFSET_NAME(exregs[14]), 247 REG_OFFSET_NAME(rhi), 248 REG_OFFSET_NAME(rlo), 249 REG_OFFSET_NAME(dcsr), 250 #endif 251 REG_OFFSET_END, 252 }; 253 254 /** 255 * regs_query_register_offset() - query register offset from its name 256 * @name: the name of a register 257 * 258 * regs_query_register_offset() returns the offset of a register in struct 259 * pt_regs from its name. If the name is invalid, this returns -EINVAL; 260 */ 261 int regs_query_register_offset(const char *name) 262 { 263 const struct pt_regs_offset *roff; 264 265 for (roff = regoffset_table; roff->name != NULL; roff++) 266 if (!strcmp(roff->name, name)) 267 return roff->offset; 268 return -EINVAL; 269 } 270 271 /** 272 * regs_within_kernel_stack() - check the address in the stack 273 * @regs: pt_regs which contains kernel stack pointer. 274 * @addr: address which is checked. 275 * 276 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). 277 * If @addr is within the kernel stack, it returns true. If not, returns false. 278 */ 279 static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) 280 { 281 return (addr & ~(THREAD_SIZE - 1)) == 282 (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)); 283 } 284 285 /** 286 * regs_get_kernel_stack_nth() - get Nth entry of the stack 287 * @regs: pt_regs which contains kernel stack pointer. 288 * @n: stack entry number. 289 * 290 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which 291 * is specified by @regs. If the @n th entry is NOT in the kernel stack, 292 * this returns 0. 293 */ 294 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) 295 { 296 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); 297 298 addr += n; 299 if (regs_within_kernel_stack(regs, (unsigned long)addr)) 300 return *addr; 301 else 302 return 0; 303 } 304 305 void ptrace_disable(struct task_struct *child) 306 { 307 singlestep_disable(child); 308 } 309 310 long arch_ptrace(struct task_struct *child, long request, 311 unsigned long addr, unsigned long data) 312 { 313 long ret = -EIO; 314 315 switch (request) { 316 default: 317 ret = ptrace_request(child, request, addr, data); 318 break; 319 } 320 321 return ret; 322 } 323 324 asmlinkage void syscall_trace_enter(struct pt_regs *regs) 325 { 326 if (test_thread_flag(TIF_SYSCALL_TRACE)) 327 if (tracehook_report_syscall_entry(regs)) 328 syscall_set_nr(current, regs, -1); 329 330 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 331 trace_sys_enter(regs, syscall_get_nr(current, regs)); 332 333 audit_syscall_entry(regs_syscallid(regs), regs->a0, regs->a1, regs->a2, regs->a3); 334 } 335 336 asmlinkage void syscall_trace_exit(struct pt_regs *regs) 337 { 338 audit_syscall_exit(regs); 339 340 if (test_thread_flag(TIF_SYSCALL_TRACE)) 341 tracehook_report_syscall_exit(regs, 0); 342 343 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 344 trace_sys_exit(regs, syscall_get_return_value(current, regs)); 345 } 346 347 extern void show_stack(struct task_struct *task, unsigned long *stack); 348 void show_regs(struct pt_regs *fp) 349 { 350 unsigned long *sp; 351 unsigned char *tp; 352 int i; 353 354 pr_info("\nCURRENT PROCESS:\n\n"); 355 pr_info("COMM=%s PID=%d\n", current->comm, current->pid); 356 357 if (current->mm) { 358 pr_info("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n", 359 (int) current->mm->start_code, 360 (int) current->mm->end_code, 361 (int) current->mm->start_data, 362 (int) current->mm->end_data, 363 (int) current->mm->end_data, 364 (int) current->mm->brk); 365 pr_info("USER-STACK=%08x KERNEL-STACK=%08x\n\n", 366 (int) current->mm->start_stack, 367 (int) (((unsigned long) current) + 2 * PAGE_SIZE)); 368 } 369 370 pr_info("PC: 0x%08lx (%pS)\n", (long)fp->pc, (void *)fp->pc); 371 pr_info("LR: 0x%08lx (%pS)\n", (long)fp->lr, (void *)fp->lr); 372 pr_info("SP: 0x%08lx\n", (long)fp); 373 pr_info("orig_a0: 0x%08lx\n", fp->orig_a0); 374 pr_info("PSR: 0x%08lx\n", (long)fp->sr); 375 376 pr_info(" a0: 0x%08lx a1: 0x%08lx a2: 0x%08lx a3: 0x%08lx\n", 377 fp->a0, fp->a1, fp->a2, fp->a3); 378 #if defined(__CSKYABIV2__) 379 pr_info(" r4: 0x%08lx r5: 0x%08lx r6: 0x%08lx r7: 0x%08lx\n", 380 fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]); 381 pr_info(" r8: 0x%08lx r9: 0x%08lx r10: 0x%08lx r11: 0x%08lx\n", 382 fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]); 383 pr_info("r12: 0x%08lx r13: 0x%08lx r15: 0x%08lx\n", 384 fp->regs[8], fp->regs[9], fp->lr); 385 pr_info("r16: 0x%08lx r17: 0x%08lx r18: 0x%08lx r19: 0x%08lx\n", 386 fp->exregs[0], fp->exregs[1], fp->exregs[2], fp->exregs[3]); 387 pr_info("r20: 0x%08lx r21: 0x%08lx r22: 0x%08lx r23: 0x%08lx\n", 388 fp->exregs[4], fp->exregs[5], fp->exregs[6], fp->exregs[7]); 389 pr_info("r24: 0x%08lx r25: 0x%08lx r26: 0x%08lx r27: 0x%08lx\n", 390 fp->exregs[8], fp->exregs[9], fp->exregs[10], fp->exregs[11]); 391 pr_info("r28: 0x%08lx r29: 0x%08lx r30: 0x%08lx tls: 0x%08lx\n", 392 fp->exregs[12], fp->exregs[13], fp->exregs[14], fp->tls); 393 pr_info(" hi: 0x%08lx lo: 0x%08lx\n", 394 fp->rhi, fp->rlo); 395 #else 396 pr_info(" r6: 0x%08lx r7: 0x%08lx r8: 0x%08lx r9: 0x%08lx\n", 397 fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]); 398 pr_info("r10: 0x%08lx r11: 0x%08lx r12: 0x%08lx r13: 0x%08lx\n", 399 fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]); 400 pr_info("r14: 0x%08lx r1: 0x%08lx r15: 0x%08lx\n", 401 fp->regs[8], fp->regs[9], fp->lr); 402 #endif 403 404 pr_info("\nCODE:"); 405 tp = ((unsigned char *) fp->pc) - 0x20; 406 tp += ((int)tp % 4) ? 2 : 0; 407 for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { 408 if ((i % 0x10) == 0) 409 pr_cont("\n%08x: ", (int) (tp + i)); 410 pr_cont("%08x ", (int) *sp++); 411 } 412 pr_cont("\n"); 413 414 pr_info("\nKERNEL STACK:"); 415 tp = ((unsigned char *) fp) - 0x40; 416 for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { 417 if ((i % 0x10) == 0) 418 pr_cont("\n%08x: ", (int) (tp + i)); 419 pr_cont("%08x ", (int) *sp++); 420 } 421 pr_cont("\n"); 422 423 show_stack(NULL, (unsigned long *)fp->regs[4]); 424 return; 425 } 426