# From: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
# 
# s390 doesn't have PTRACE_GETREGS and friends, but has
# PTRACE_[PEEK|POKE]USR_AREA to let user of ptrace() read or write
# struct user as he wants.
# So we need to support this operation conditionally.
# 
# Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>

Index: linux-2.6.17/arch/um/kernel/ptrace.c
===================================================================
--- linux-2.6.17.orig/arch/um/kernel/ptrace.c	2007-10-24 10:04:50.000000000 -0400
+++ linux-2.6.17/arch/um/kernel/ptrace.c	2007-11-19 11:20:07.000000000 -0500
@@ -163,6 +163,45 @@ long arch_ptrace(struct task_struct *chi
 					     (struct user_desc __user *) data);
 		break;
 
+#ifdef PTRACE_PEEKUSR_AREA
+	/*
+	 * Shamelessly stolen from arch/s390/kernel/ptrace.c
+	 * and modified a little only.
+	 */
+	case PTRACE_PEEKUSR_AREA:
+	case PTRACE_POKEUSR_AREA: {
+
+		ptrace_area parea;
+
+		ret = 0;
+		if (copy_from_user(&parea, (void __user *) addr,
+							sizeof(parea))) {
+			ret = -EFAULT;
+			break;
+		}
+		addr = parea.kernel_addr;
+		data = parea.process_addr;
+		i = 0;
+		while (i < parea.len) {
+			if (request == PTRACE_PEEKUSR_AREA)
+				ret = peek_user(child, addr, data);
+			else {
+				addr_t tmp;
+				if (get_user (tmp, (addr_t __user *) data)) {
+					ret = -EFAULT;
+					break;
+				}
+				ret = poke_user(child, addr, tmp);
+			}
+			if (ret)
+				break;
+			addr += sizeof(unsigned long);
+			data += sizeof(unsigned long);
+			i += sizeof(unsigned long);
+		}
+		break;
+	}
+#endif
 	case PTRACE_FAULTINFO: {
 		/*
 		 * Take the info from thread->arch->faultinfo,
@@ -171,6 +210,8 @@ long arch_ptrace(struct task_struct *chi
 		 */
 		ret = copy_to_user(p, &child->thread.arch.faultinfo,
 				   sizeof(struct ptrace_faultinfo));
+		if (ret)
+			ret = -EIO;
 		break;
 	}