+#endif
+ if (write && tlb_type == spitfire) {
+ unsigned long start = (unsigned long) kaddr;
+ unsigned long end = start + len;
+ unsigned long icache_line_size;
+
+ icache_line_size = local_cpu_data().icache_line_size;
+
+ for (; start < end; start += icache_line_size)
+ flushi(start);
+ }
+}
+
+#ifdef CONFIG_PTRACE
+static const struct ptrace_layout_segment sparc64_getregs_layout[] = {
+ { 0, offsetof(struct pt_regs, u_regs[15]), 0, sizeof(long) },
+ { offsetof(struct pt_regs, u_regs[15]),
+ offsetof(struct pt_regs, tstate),
+ -1, 0 },
+ { offsetof(struct pt_regs, tstate), offsetof(struct pt_regs, y),
+ 0, 32 * sizeof(long) },
+ {0, 0, -1, 0}
+};
+
+int arch_ptrace(long *request, struct task_struct *child,
+ struct utrace_attached_engine *engine,
+ unsigned long addr, unsigned long data,
+ long *retval)
+{
+ void __user *uaddr = (void __user *) addr;
+ struct pt_regs *uregs = uaddr;
+ int err = -ENOSYS;
+
+ switch (*request) {
+ case PTRACE_GETREGS64:
+ err = ptrace_layout_access(child, engine,
+ &utrace_sparc64_native_view,
+ sparc64_getregs_layout,
+ 0, offsetof(struct pt_regs, y),
+ uaddr, NULL, 0);
+ if (!err &&
+ (put_user(task_pt_regs(child)->y, &uregs->y) ||
+ put_user(task_pt_regs(child)->fprs, &uregs->fprs)))
+ err = -EFAULT;
+ break;
+
+ case PTRACE_SETREGS64:
+ err = ptrace_layout_access(child, engine,
+ &utrace_sparc64_native_view,
+ sparc64_getregs_layout,
+ 0, offsetof(struct pt_regs, y),
+ uaddr, NULL, 1);
+ if (!err &&
+ (get_user(task_pt_regs(child)->y, &uregs->y) ||
+ get_user(task_pt_regs(child)->fprs, &uregs->fprs)))
+ err = -EFAULT;
+ break;
+
+ case PTRACE_GETFPREGS64:
+ case PTRACE_SETFPREGS64:
+ err = ptrace_regset_access(child, engine,
+ utrace_native_view(current),
+ 2, 0, 34 * sizeof(long), uaddr,
+ (*request == PTRACE_SETFPREGS64));
+ break;
+
+ case PTRACE_SUNDETACH:
+ *request = PTRACE_DETACH;
+ break;
+
+ default:
+ break;
+ };
+ return err;