]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/sparc64/kernel/ptrace.c
[ARM] 3386/1: AT91RM9200 Clock update
[linux-2.6-omap-h63xx.git] / arch / sparc64 / kernel / ptrace.c
index 5efbff90d66862054ce827bb3c327bd636d280bc..eb93e9c528462c6a2d92a8cb76251b65f91f0db7 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/visasm.h>
 #include <asm/spitfire.h>
 #include <asm/page.h>
+#include <asm/cpudata.h>
 
 /* Returning from ptrace is a bit tricky because the syscall return
  * low level code assumes any value returned which is negative and
@@ -123,6 +124,9 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
 {
        BUG_ON(len > PAGE_SIZE);
 
+       if (tlb_type == hypervisor)
+               return;
+
 #ifdef DCACHE_ALIASING_POSSIBLE
        /* If bit 13 of the kernel address we used to access the
         * user page is the same as the virtual address that page
@@ -132,12 +136,16 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
        if ((uaddr ^ (unsigned long) kaddr) & (1UL << 13)) {
                unsigned long start = __pa(kaddr);
                unsigned long end = start + len;
+               unsigned long dcache_line_size;
+
+               dcache_line_size = local_cpu_data().dcache_line_size;
 
                if (tlb_type == spitfire) {
-                       for (; start < end; start += 32)
+                       for (; start < end; start += dcache_line_size)
                                spitfire_put_dcache_tag(start & 0x3fe0, 0x0);
                } else {
-                       for (; start < end; start += 32)
+                       start &= ~(dcache_line_size - 1);
+                       for (; start < end; start += dcache_line_size)
                                __asm__ __volatile__(
                                        "stxa %%g0, [%0] %1\n\t"
                                        "membar #Sync"
@@ -150,8 +158,11 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
        if (write && tlb_type == spitfire) {
                unsigned long start = (unsigned long) kaddr;
                unsigned long end = start + len;
+               unsigned long icache_line_size;
 
-               for (; start < end; start += 32)
+               icache_line_size = local_cpu_data().icache_line_size;
+
+               for (; start < end; start += icache_line_size)
                        flushi(start);
        }
 }
@@ -190,39 +201,15 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
        }
 #endif
        if (request == PTRACE_TRACEME) {
-               int ret;
-
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED) {
-                       pt_error_return(regs, EPERM);
-                       goto out;
-               }
-               ret = security_ptrace(current->parent, current);
-               if (ret) {
-                       pt_error_return(regs, -ret);
-                       goto out;
-               }
-
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
+               ret = ptrace_traceme();
                pt_succ_return(regs, 0);
                goto out;
        }
-#ifndef ALLOW_INIT_TRACING
-       if (pid == 1) {
-               /* Can't dork with init. */
-               pt_error_return(regs, EPERM);
-               goto out;
-       }
-#endif
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
 
-       if (!child) {
-               pt_error_return(regs, ESRCH);
+       child = ptrace_get_task_struct(pid);
+       if (IS_ERR(child)) {
+               ret = PTR_ERR(child);
+               pt_error_return(regs, -ret);
                goto out;
        }
 
@@ -312,7 +299,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
        case PTRACE_GETREGS: {
                struct pt_regs32 __user *pregs =
                        (struct pt_regs32 __user *) addr;
-               struct pt_regs *cregs = child->thread_info->kregs;
+               struct pt_regs *cregs = task_pt_regs(child);
                int rval;
 
                if (__put_user(tstate_to_psr(cregs->tstate), (&pregs->psr)) ||
@@ -336,11 +323,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
 
        case PTRACE_GETREGS64: {
                struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-               struct pt_regs *cregs = child->thread_info->kregs;
+               struct pt_regs *cregs = task_pt_regs(child);
                unsigned long tpc = cregs->tpc;
                int rval;
 
-               if ((child->thread_info->flags & _TIF_32BIT) != 0)
+               if ((task_thread_info(child)->flags & _TIF_32BIT) != 0)
                        tpc &= 0xffffffff;
                if (__put_user(cregs->tstate, (&pregs->tstate)) ||
                    __put_user(tpc, (&pregs->tpc)) ||
@@ -364,7 +351,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
        case PTRACE_SETREGS: {
                struct pt_regs32 __user *pregs =
                        (struct pt_regs32 __user *) addr;
-               struct pt_regs *cregs = child->thread_info->kregs;
+               struct pt_regs *cregs = task_pt_regs(child);
                unsigned int psr, pc, npc, y;
                int i;
 
@@ -397,7 +384,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
 
        case PTRACE_SETREGS64: {
                struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
-               struct pt_regs *cregs = child->thread_info->kregs;
+               struct pt_regs *cregs = task_pt_regs(child);
                unsigned long tstate, tpc, tnpc, y;
                int i;
 
@@ -411,7 +398,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        pt_error_return(regs, EFAULT);
                        goto out_tsk;
                }
-               if ((child->thread_info->flags & _TIF_32BIT) != 0) {
+               if ((task_thread_info(child)->flags & _TIF_32BIT) != 0) {
                        tpc &= 0xffffffff;
                        tnpc &= 0xffffffff;
                }
@@ -446,11 +433,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        } fpq[16];
                };
                struct fps __user *fps = (struct fps __user *) addr;
-               unsigned long *fpregs = child->thread_info->fpregs;
+               unsigned long *fpregs = task_thread_info(child)->fpregs;
 
                if (copy_to_user(&fps->regs[0], fpregs,
                                 (32 * sizeof(unsigned int))) ||
-                   __put_user(child->thread_info->xfsr[0], (&fps->fsr)) ||
+                   __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr)) ||
                    __put_user(0, (&fps->fpqd)) ||
                    __put_user(0, (&fps->flags)) ||
                    __put_user(0, (&fps->extra)) ||
@@ -468,11 +455,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        unsigned long fsr;
                };
                struct fps __user *fps = (struct fps __user *) addr;
-               unsigned long *fpregs = child->thread_info->fpregs;
+               unsigned long *fpregs = task_thread_info(child)->fpregs;
 
                if (copy_to_user(&fps->regs[0], fpregs,
                                 (64 * sizeof(unsigned int))) ||
-                   __put_user(child->thread_info->xfsr[0], (&fps->fsr))) {
+                   __put_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
                        pt_error_return(regs, EFAULT);
                        goto out_tsk;
                }
@@ -493,7 +480,7 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        } fpq[16];
                };
                struct fps __user *fps = (struct fps __user *) addr;
-               unsigned long *fpregs = child->thread_info->fpregs;
+               unsigned long *fpregs = task_thread_info(child)->fpregs;
                unsigned fsr;
 
                if (copy_from_user(fpregs, &fps->regs[0],
@@ -502,11 +489,11 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        pt_error_return(regs, EFAULT);
                        goto out_tsk;
                }
-               child->thread_info->xfsr[0] &= 0xffffffff00000000UL;
-               child->thread_info->xfsr[0] |= fsr;
-               if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
-                       child->thread_info->gsr[0] = 0;
-               child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
+               task_thread_info(child)->xfsr[0] &= 0xffffffff00000000UL;
+               task_thread_info(child)->xfsr[0] |= fsr;
+               if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
+                       task_thread_info(child)->gsr[0] = 0;
+               task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL);
                pt_succ_return(regs, 0);
                goto out_tsk;
        }
@@ -517,17 +504,17 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
                        unsigned long fsr;
                };
                struct fps __user *fps = (struct fps __user *) addr;
-               unsigned long *fpregs = child->thread_info->fpregs;
+               unsigned long *fpregs = task_thread_info(child)->fpregs;
 
                if (copy_from_user(fpregs, &fps->regs[0],
                                   (64 * sizeof(unsigned int))) ||
-                   __get_user(child->thread_info->xfsr[0], (&fps->fsr))) {
+                   __get_user(task_thread_info(child)->xfsr[0], (&fps->fsr))) {
                        pt_error_return(regs, EFAULT);
                        goto out_tsk;
                }
-               if (!(child->thread_info->fpsaved[0] & FPRS_FEF))
-                       child->thread_info->gsr[0] = 0;
-               child->thread_info->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
+               if (!(task_thread_info(child)->fpsaved[0] & FPRS_FEF))
+                       task_thread_info(child)->gsr[0] = 0;
+               task_thread_info(child)->fpsaved[0] |= (FPRS_FEF | FPRS_DL | FPRS_DU);
                pt_succ_return(regs, 0);
                goto out_tsk;
        }
@@ -578,8 +565,8 @@ asmlinkage void do_ptrace(struct pt_regs *regs)
 #ifdef DEBUG_PTRACE
                printk("CONT: %s [%d]: set exit_code = %x %lx %lx\n", child->comm,
                        child->pid, child->exit_code,
-                       child->thread_info->kregs->tpc,
-                       child->thread_info->kregs->tnpc);
+                       task_pt_regs(child)->tpc,
+                       task_pt_regs(child)->tnpc);
                       
 #endif
                wake_up_process(child);