powerpc/64s/syscall: Fix ptrace syscall info with scv syscalls
[sfrench/cifs-2.6.git] / arch / powerpc / include / asm / syscall.h
index fd1b518eed17c2865010f7ed6ebb7a980261c271..ba0f88f3a30daea20e9c5e9efb322a627678a00c 100644 (file)
@@ -41,11 +41,17 @@ static inline void syscall_rollback(struct task_struct *task,
 static inline long syscall_get_error(struct task_struct *task,
                                     struct pt_regs *regs)
 {
-       /*
-        * If the system call failed,
-        * regs->gpr[3] contains a positive ERRORCODE.
-        */
-       return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0;
+       if (trap_is_scv(regs)) {
+               unsigned long error = regs->gpr[3];
+
+               return IS_ERR_VALUE(error) ? error : 0;
+       } else {
+               /*
+                * If the system call failed,
+                * regs->gpr[3] contains a positive ERRORCODE.
+                */
+               return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0;
+       }
 }
 
 static inline long syscall_get_return_value(struct task_struct *task,
@@ -58,18 +64,22 @@ static inline void syscall_set_return_value(struct task_struct *task,
                                            struct pt_regs *regs,
                                            int error, long val)
 {
-       /*
-        * In the general case it's not obvious that we must deal with CCR
-        * here, as the syscall exit path will also do that for us. However
-        * there are some places, eg. the signal code, which check ccr to
-        * decide if the value in r3 is actually an error.
-        */
-       if (error) {
-               regs->ccr |= 0x10000000L;
-               regs->gpr[3] = error;
+       if (trap_is_scv(regs)) {
+               regs->gpr[3] = (long) error ?: val;
        } else {
-               regs->ccr &= ~0x10000000L;
-               regs->gpr[3] = val;
+               /*
+                * In the general case it's not obvious that we must deal with
+                * CCR here, as the syscall exit path will also do that for us.
+                * However there are some places, eg. the signal code, which
+                * check ccr to decide if the value in r3 is actually an error.
+                */
+               if (error) {
+                       regs->ccr |= 0x10000000L;
+                       regs->gpr[3] = error;
+               } else {
+                       regs->ccr &= ~0x10000000L;
+                       regs->gpr[3] = val;
+               }
        }
 }