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/processor.h> 22 #include <asm/asm-offsets.h> 23 24 #include <abi/regdef.h> 25 #include <abi/ckmmu.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 struct membuf to) 81 { 82 struct pt_regs *regs = task_pt_regs(target); 83 84 /* Abiv1 regs->tls is fake and we need sync here. */ 85 regs->tls = task_thread_info(target)->tp_value; 86 87 return membuf_write(&to, regs, sizeof(*regs)); 88 } 89 90 static int gpr_set(struct task_struct *target, 91 const struct user_regset *regset, 92 unsigned int pos, unsigned int count, 93 const void *kbuf, const void __user *ubuf) 94 { 95 int ret; 96 struct pt_regs regs; 97 98 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s, 0, -1); 99 if (ret) 100 return ret; 101 102 /* BIT(0) of regs.sr is Condition Code/Carry bit */ 103 regs.sr = (regs.sr & BIT(0)) | (task_pt_regs(target)->sr & ~BIT(0)); 104 #ifdef CONFIG_CPU_HAS_HILO 105 regs.dcsr = task_pt_regs(target)->dcsr; 106 #endif 107 task_thread_info(target)->tp_value = regs.tls; 108 109 *task_pt_regs(target) = regs; 110 111 return 0; 112 } 113 114 static int fpr_get(struct task_struct *target, 115 const struct user_regset *regset, 116 struct membuf to) 117 { 118 struct user_fp *regs = (struct user_fp *)&target->thread.user_fp; 119 120 #if defined(CONFIG_CPU_HAS_FPUV2) && !defined(CONFIG_CPU_HAS_VDSP) 121 int i; 122 struct user_fp tmp = *regs; 123 124 for (i = 0; i < 16; i++) { 125 tmp.vr[i*4] = regs->vr[i*2]; 126 tmp.vr[i*4 + 1] = regs->vr[i*2 + 1]; 127 } 128 129 for (i = 0; i < 32; i++) 130 tmp.vr[64 + i] = regs->vr[32 + i]; 131 132 return membuf_write(&to, &tmp, sizeof(tmp)); 133 #else 134 return membuf_write(&to, regs, sizeof(*regs)); 135 #endif 136 } 137 138 static int fpr_set(struct task_struct *target, 139 const struct user_regset *regset, 140 unsigned int pos, unsigned int count, 141 const void *kbuf, const void __user *ubuf) 142 { 143 int ret; 144 struct user_fp *regs = (struct user_fp *)&target->thread.user_fp; 145 146 #if defined(CONFIG_CPU_HAS_FPUV2) && !defined(CONFIG_CPU_HAS_VDSP) 147 int i; 148 struct user_fp tmp; 149 150 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tmp, 0, -1); 151 152 *regs = tmp; 153 154 for (i = 0; i < 16; i++) { 155 regs->vr[i*2] = tmp.vr[i*4]; 156 regs->vr[i*2 + 1] = tmp.vr[i*4 + 1]; 157 } 158 159 for (i = 0; i < 32; i++) 160 regs->vr[32 + i] = tmp.vr[64 + i]; 161 #else 162 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs, 0, -1); 163 #endif 164 165 return ret; 166 } 167 168 static const struct user_regset csky_regsets[] = { 169 [REGSET_GPR] = { 170 .core_note_type = NT_PRSTATUS, 171 .n = sizeof(struct pt_regs) / sizeof(u32), 172 .size = sizeof(u32), 173 .align = sizeof(u32), 174 .regset_get = gpr_get, 175 .set = gpr_set, 176 }, 177 [REGSET_FPR] = { 178 .core_note_type = NT_PRFPREG, 179 .n = sizeof(struct user_fp) / sizeof(u32), 180 .size = sizeof(u32), 181 .align = sizeof(u32), 182 .regset_get = fpr_get, 183 .set = fpr_set, 184 }, 185 }; 186 187 static const struct user_regset_view user_csky_view = { 188 .name = "csky", 189 .e_machine = ELF_ARCH, 190 .regsets = csky_regsets, 191 .n = ARRAY_SIZE(csky_regsets), 192 }; 193 194 const struct user_regset_view *task_user_regset_view(struct task_struct *task) 195 { 196 return &user_csky_view; 197 } 198 199 struct pt_regs_offset { 200 const char *name; 201 int offset; 202 }; 203 204 #define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)} 205 #define REG_OFFSET_END {.name = NULL, .offset = 0} 206 207 static const struct pt_regs_offset regoffset_table[] = { 208 REG_OFFSET_NAME(tls), 209 REG_OFFSET_NAME(lr), 210 REG_OFFSET_NAME(pc), 211 REG_OFFSET_NAME(sr), 212 REG_OFFSET_NAME(usp), 213 REG_OFFSET_NAME(orig_a0), 214 REG_OFFSET_NAME(a0), 215 REG_OFFSET_NAME(a1), 216 REG_OFFSET_NAME(a2), 217 REG_OFFSET_NAME(a3), 218 REG_OFFSET_NAME(regs[0]), 219 REG_OFFSET_NAME(regs[1]), 220 REG_OFFSET_NAME(regs[2]), 221 REG_OFFSET_NAME(regs[3]), 222 REG_OFFSET_NAME(regs[4]), 223 REG_OFFSET_NAME(regs[5]), 224 REG_OFFSET_NAME(regs[6]), 225 REG_OFFSET_NAME(regs[7]), 226 REG_OFFSET_NAME(regs[8]), 227 REG_OFFSET_NAME(regs[9]), 228 #if defined(__CSKYABIV2__) 229 REG_OFFSET_NAME(exregs[0]), 230 REG_OFFSET_NAME(exregs[1]), 231 REG_OFFSET_NAME(exregs[2]), 232 REG_OFFSET_NAME(exregs[3]), 233 REG_OFFSET_NAME(exregs[4]), 234 REG_OFFSET_NAME(exregs[5]), 235 REG_OFFSET_NAME(exregs[6]), 236 REG_OFFSET_NAME(exregs[7]), 237 REG_OFFSET_NAME(exregs[8]), 238 REG_OFFSET_NAME(exregs[9]), 239 REG_OFFSET_NAME(exregs[10]), 240 REG_OFFSET_NAME(exregs[11]), 241 REG_OFFSET_NAME(exregs[12]), 242 REG_OFFSET_NAME(exregs[13]), 243 REG_OFFSET_NAME(exregs[14]), 244 REG_OFFSET_NAME(rhi), 245 REG_OFFSET_NAME(rlo), 246 REG_OFFSET_NAME(dcsr), 247 #endif 248 REG_OFFSET_END, 249 }; 250 251 /** 252 * regs_query_register_offset() - query register offset from its name 253 * @name: the name of a register 254 * 255 * regs_query_register_offset() returns the offset of a register in struct 256 * pt_regs from its name. If the name is invalid, this returns -EINVAL; 257 */ 258 int regs_query_register_offset(const char *name) 259 { 260 const struct pt_regs_offset *roff; 261 262 for (roff = regoffset_table; roff->name != NULL; roff++) 263 if (!strcmp(roff->name, name)) 264 return roff->offset; 265 return -EINVAL; 266 } 267 268 /** 269 * regs_within_kernel_stack() - check the address in the stack 270 * @regs: pt_regs which contains kernel stack pointer. 271 * @addr: address which is checked. 272 * 273 * regs_within_kernel_stack() checks @addr is within the kernel stack page(s). 274 * If @addr is within the kernel stack, it returns true. If not, returns false. 275 */ 276 static bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) 277 { 278 return (addr & ~(THREAD_SIZE - 1)) == 279 (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)); 280 } 281 282 /** 283 * regs_get_kernel_stack_nth() - get Nth entry of the stack 284 * @regs: pt_regs which contains kernel stack pointer. 285 * @n: stack entry number. 286 * 287 * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which 288 * is specified by @regs. If the @n th entry is NOT in the kernel stack, 289 * this returns 0. 290 */ 291 unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) 292 { 293 unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs); 294 295 addr += n; 296 if (regs_within_kernel_stack(regs, (unsigned long)addr)) 297 return *addr; 298 else 299 return 0; 300 } 301 302 void ptrace_disable(struct task_struct *child) 303 { 304 singlestep_disable(child); 305 } 306 307 long arch_ptrace(struct task_struct *child, long request, 308 unsigned long addr, unsigned long data) 309 { 310 long ret = -EIO; 311 312 switch (request) { 313 default: 314 ret = ptrace_request(child, request, addr, data); 315 break; 316 } 317 318 return ret; 319 } 320 321 asmlinkage int syscall_trace_enter(struct pt_regs *regs) 322 { 323 if (test_thread_flag(TIF_SYSCALL_TRACE)) 324 if (tracehook_report_syscall_entry(regs)) 325 return -1; 326 327 if (secure_computing() == -1) 328 return -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 return 0; 335 } 336 337 asmlinkage void syscall_trace_exit(struct pt_regs *regs) 338 { 339 audit_syscall_exit(regs); 340 341 if (test_thread_flag(TIF_SYSCALL_TRACE)) 342 tracehook_report_syscall_exit(regs, 0); 343 344 if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) 345 trace_sys_exit(regs, syscall_get_return_value(current, regs)); 346 } 347 348 #ifdef CONFIG_CPU_CK860 349 static void show_iutlb(void) 350 { 351 int entry, i; 352 unsigned long flags; 353 unsigned long oldpid; 354 unsigned long entryhi[16], entrylo0[16], entrylo1[16]; 355 356 oldpid = read_mmu_entryhi(); 357 358 entry = 0x8000; 359 360 local_irq_save(flags); 361 362 for (i = 0; i < 16; i++) { 363 write_mmu_index(entry); 364 tlb_read(); 365 entryhi[i] = read_mmu_entryhi(); 366 entrylo0[i] = read_mmu_entrylo0(); 367 entrylo1[i] = read_mmu_entrylo1(); 368 369 entry++; 370 } 371 372 local_irq_restore(flags); 373 374 write_mmu_entryhi(oldpid); 375 376 printk("\n\n\n"); 377 for (i = 0; i < 16; i++) 378 printk("iutlb[%d]: entryhi - 0x%lx; entrylo0 - 0x%lx;" 379 " entrylo1 - 0x%lx\n", 380 i, entryhi[i], entrylo0[i], entrylo1[i]); 381 printk("\n\n\n"); 382 } 383 384 static void show_dutlb(void) 385 { 386 int entry, i; 387 unsigned long flags; 388 unsigned long oldpid; 389 unsigned long entryhi[16], entrylo0[16], entrylo1[16]; 390 391 oldpid = read_mmu_entryhi(); 392 393 entry = 0x4000; 394 395 local_irq_save(flags); 396 397 for (i = 0; i < 16; i++) { 398 write_mmu_index(entry); 399 tlb_read(); 400 entryhi[i] = read_mmu_entryhi(); 401 entrylo0[i] = read_mmu_entrylo0(); 402 entrylo1[i] = read_mmu_entrylo1(); 403 404 entry++; 405 } 406 407 local_irq_restore(flags); 408 409 write_mmu_entryhi(oldpid); 410 411 printk("\n\n\n"); 412 for (i = 0; i < 16; i++) 413 printk("dutlb[%d]: entryhi - 0x%lx; entrylo0 - 0x%lx;" 414 " entrylo1 - 0x%lx\n", 415 i, entryhi[i], entrylo0[i], entrylo1[i]); 416 printk("\n\n\n"); 417 } 418 419 static unsigned long entryhi[1024], entrylo0[1024], entrylo1[1024]; 420 static void show_jtlb(void) 421 { 422 int entry; 423 unsigned long flags; 424 unsigned long oldpid; 425 426 oldpid = read_mmu_entryhi(); 427 428 entry = 0; 429 430 local_irq_save(flags); 431 while (entry < 1024) { 432 write_mmu_index(entry); 433 tlb_read(); 434 entryhi[entry] = read_mmu_entryhi(); 435 entrylo0[entry] = read_mmu_entrylo0(); 436 entrylo1[entry] = read_mmu_entrylo1(); 437 438 entry++; 439 } 440 local_irq_restore(flags); 441 442 write_mmu_entryhi(oldpid); 443 444 printk("\n\n\n"); 445 446 for (entry = 0; entry < 1024; entry++) 447 printk("jtlb[%x]: entryhi - 0x%lx; entrylo0 - 0x%lx;" 448 " entrylo1 - 0x%lx\n", 449 entry, entryhi[entry], entrylo0[entry], entrylo1[entry]); 450 printk("\n\n\n"); 451 } 452 453 static void show_tlb(void) 454 { 455 show_iutlb(); 456 show_dutlb(); 457 show_jtlb(); 458 } 459 #else 460 static void show_tlb(void) 461 { 462 return; 463 } 464 #endif 465 466 void show_regs(struct pt_regs *fp) 467 { 468 pr_info("\nCURRENT PROCESS:\n\n"); 469 pr_info("COMM=%s PID=%d\n", current->comm, current->pid); 470 471 if (current->mm) { 472 pr_info("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n", 473 (int) current->mm->start_code, 474 (int) current->mm->end_code, 475 (int) current->mm->start_data, 476 (int) current->mm->end_data, 477 (int) current->mm->end_data, 478 (int) current->mm->brk); 479 pr_info("USER-STACK=%08x KERNEL-STACK=%08x\n\n", 480 (int) current->mm->start_stack, 481 (int) (((unsigned long) current) + 2 * PAGE_SIZE)); 482 } 483 484 pr_info("PC: 0x%08lx (%pS)\n", (long)fp->pc, (void *)fp->pc); 485 pr_info("LR: 0x%08lx (%pS)\n", (long)fp->lr, (void *)fp->lr); 486 pr_info("SP: 0x%08lx\n", (long)fp->usp); 487 pr_info("PSR: 0x%08lx\n", (long)fp->sr); 488 pr_info("orig_a0: 0x%08lx\n", fp->orig_a0); 489 pr_info("PT_REGS: 0x%08lx\n", (long)fp); 490 491 pr_info(" a0: 0x%08lx a1: 0x%08lx a2: 0x%08lx a3: 0x%08lx\n", 492 fp->a0, fp->a1, fp->a2, fp->a3); 493 #if defined(__CSKYABIV2__) 494 pr_info(" r4: 0x%08lx r5: 0x%08lx r6: 0x%08lx r7: 0x%08lx\n", 495 fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]); 496 pr_info(" r8: 0x%08lx r9: 0x%08lx r10: 0x%08lx r11: 0x%08lx\n", 497 fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]); 498 pr_info("r12: 0x%08lx r13: 0x%08lx r15: 0x%08lx\n", 499 fp->regs[8], fp->regs[9], fp->lr); 500 pr_info("r16: 0x%08lx r17: 0x%08lx r18: 0x%08lx r19: 0x%08lx\n", 501 fp->exregs[0], fp->exregs[1], fp->exregs[2], fp->exregs[3]); 502 pr_info("r20: 0x%08lx r21: 0x%08lx r22: 0x%08lx r23: 0x%08lx\n", 503 fp->exregs[4], fp->exregs[5], fp->exregs[6], fp->exregs[7]); 504 pr_info("r24: 0x%08lx r25: 0x%08lx r26: 0x%08lx r27: 0x%08lx\n", 505 fp->exregs[8], fp->exregs[9], fp->exregs[10], fp->exregs[11]); 506 pr_info("r28: 0x%08lx r29: 0x%08lx r30: 0x%08lx tls: 0x%08lx\n", 507 fp->exregs[12], fp->exregs[13], fp->exregs[14], fp->tls); 508 pr_info(" hi: 0x%08lx lo: 0x%08lx\n", 509 fp->rhi, fp->rlo); 510 #else 511 pr_info(" r6: 0x%08lx r7: 0x%08lx r8: 0x%08lx r9: 0x%08lx\n", 512 fp->regs[0], fp->regs[1], fp->regs[2], fp->regs[3]); 513 pr_info("r10: 0x%08lx r11: 0x%08lx r12: 0x%08lx r13: 0x%08lx\n", 514 fp->regs[4], fp->regs[5], fp->regs[6], fp->regs[7]); 515 pr_info("r14: 0x%08lx r1: 0x%08lx\n", 516 fp->regs[8], fp->regs[9]); 517 #endif 518 519 show_tlb(); 520 521 return; 522 } 523