]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/s390/kernel/ptrace.c
[S390] dcssblk: add >2G DCSSs support and stacked contiguous DCSSs support.
[linux-2.6-omap-h63xx.git] / arch / s390 / kernel / ptrace.c
index 2815bfe348a6f92e67b64e04e0b70cbecde6bc58..1f31be1ecc4bd57bd3af99ef004f00df4f24987b 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/signal.h>
 #include <linux/elf.h>
 #include <linux/regset.h>
+#include <linux/tracehook.h>
 
 #include <asm/segment.h>
 #include <asm/page.h>
@@ -170,6 +171,13 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
                 */
                tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
 
+       } else if (addr < (addr_t) &dummy->regs.fp_regs) {
+               /*
+                * prevent reads of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               tmp = 0;
+
        } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
                /* 
                 * floating point regs. are stored in the thread structure
@@ -270,6 +278,13 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                 */
                task_pt_regs(child)->orig_gpr2 = data;
 
+       } else if (addr < (addr_t) &dummy->regs.fp_regs) {
+               /*
+                * prevent writes of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               return 0;
+
        } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
                /*
                 * floating point regs. are stored in the thread structure
@@ -428,6 +443,13 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
                 */
                tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
 
+       } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
+               /*
+                * prevent reads of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               tmp = 0;
+
        } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
                /*
                 * floating point regs. are stored in the thread structure 
@@ -514,6 +536,13 @@ static int __poke_user_compat(struct task_struct *child,
                 */
                *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
 
+       } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
+               /*
+                * prevent writess of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               return 0;
+
        } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
                /*
                 * floating point regs. are stored in the thread structure 
@@ -611,40 +640,44 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 }
 #endif
 
-asmlinkage void
-syscall_trace(struct pt_regs *regs, int entryexit)
+asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
-       if (unlikely(current->audit_context) && entryexit)
-               audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]);
-
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               goto out;
-       if (!(current->ptrace & PT_PTRACED))
-               goto out;
-       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
-                                ? 0x80 : 0));
+       long ret;
 
        /*
-        * If the debuffer has set an invalid system call number,
-        * we prepare to skip the system call restart handling.
+        * The sysc_tracesys code in entry.S stored the system
+        * call number to gprs[2].
         */
-       if (!entryexit && regs->gprs[2] >= NR_syscalls)
+       ret = regs->gprs[2];
+       if (test_thread_flag(TIF_SYSCALL_TRACE) &&
+           (tracehook_report_syscall_entry(regs) ||
+            regs->gprs[2] >= NR_syscalls)) {
+               /*
+                * Tracing decided this syscall should not happen or the
+                * debugger stored an invalid system call number. Skip
+                * the system call and the system call restart handling.
+                */
                regs->trap = -1;
-
-       /*
-        * this isn't the same as continuing with a signal, but it will do
-        * for normal use.  strace only continues with a signal if the
-        * stopping signal is not SIGTRAP.  -brl
-        */
-       if (current->exit_code) {
-               send_sig(current->exit_code, current, 1);
-               current->exit_code = 0;
+               ret = -1;
        }
- out:
-       if (unlikely(current->audit_context) && !entryexit)
-               audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X,
-                                   regs->gprs[2], regs->orig_gpr2, regs->gprs[3],
-                                   regs->gprs[4], regs->gprs[5]);
+
+       if (unlikely(current->audit_context))
+               audit_syscall_entry(test_thread_flag(TIF_31BIT) ?
+                                       AUDIT_ARCH_S390 : AUDIT_ARCH_S390X,
+                                   regs->gprs[2], regs->orig_gpr2,
+                                   regs->gprs[3], regs->gprs[4],
+                                   regs->gprs[5]);
+       return ret;
+}
+
+asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
+{
+       if (unlikely(current->audit_context))
+               audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
+                                  regs->gprs[2]);
+
+       if (test_thread_flag(TIF_SYSCALL_TRACE))
+               tracehook_report_syscall_exit(regs, 0);
 }
 
 /*