]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] s390: 31 bit compat.
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 26 Sep 2003 01:01:19 +0000 (18:01 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 26 Sep 2003 01:01:19 +0000 (18:01 -0700)
 - Fix emulation of sys_sysinfo and sys_clone.
 - Add code for -ERESTART_RESTARTBLOCK in signal emulation.
 - Fix ptrace peek/poke for 31 bit programs under a 64 bit kernel.
 - Fix typos in cp_stat64.

arch/s390/kernel/compat_ioctl.c
arch/s390/kernel/compat_linux.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/ptrace.c

index 2f58414cc96047cfeb42963cb079fa1ee655bcc1..5f74503818d4a20e593beee5e29e78cd6430099c 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 
+#include <linux/blkdev.h>
 #include <linux/blkpg.h>
 #include <linux/cdrom.h>
 #include <linux/dm-ioctl.h>
index 62d0d764dab8f86826ac3323575207d45a4c0890..1b03d2709b8d8040db21affc051f205cbe5e68b9 100644 (file)
@@ -1554,7 +1554,11 @@ struct sysinfo32 {
         u32 totalswap;
         u32 freeswap;
         unsigned short procs;
-        char _f[22];
+       unsigned short pads;
+       u32 totalhigh;
+       u32 freehigh;
+       unsigned int mem_unit;
+        char _f[8];
 };
 
 extern asmlinkage int sys_sysinfo(struct sysinfo *info);
@@ -1579,6 +1583,9 @@ asmlinkage int sys32_sysinfo(struct sysinfo32 *info)
        err |= __put_user (s.totalswap, &info->totalswap);
        err |= __put_user (s.freeswap, &info->freeswap);
        err |= __put_user (s.procs, &info->procs);
+       err |= __put_user (s.totalhigh, &info->totalhigh);
+       err |= __put_user (s.freehigh, &info->freehigh);
+       err |= __put_user (s.mem_unit, &info->mem_unit);
        if (err)
                return -EFAULT;
        return ret;
@@ -2581,10 +2588,10 @@ static int cp_stat64(struct stat64_emu31 *ubuf, struct kstat *stat)
        tmp.__st_ino = (u32)stat->ino;
        tmp.st_mode = stat->mode;
        tmp.st_nlink = (unsigned int)stat->nlink;
-       tmp.uid = stat->uid;
-       tmp.gid = stat->gid;
+       tmp.st_uid = stat->uid;
+       tmp.st_gid = stat->gid;
        tmp.st_rdev = huge_encode_dev(stat->rdev);
-       tmp.st_size = stat->st_size;
+       tmp.st_size = stat->size;
        tmp.st_blksize = (u32)stat->blksize;
        tmp.st_blocks = (u32)stat->blocks;
        tmp.st_atime = (u32)stat->atime.tv_sec;
@@ -2773,7 +2780,6 @@ asmlinkage int sys32_clone(struct pt_regs regs)
 {
         unsigned long clone_flags;
         unsigned long newsp;
-       struct task_struct *p;
        int *parent_tidptr, *child_tidptr;
 
         clone_flags = regs.gprs[3] & 0xffffffffUL;
@@ -2782,7 +2788,8 @@ asmlinkage int sys32_clone(struct pt_regs regs)
        child_tidptr = (int *) (regs.gprs[5] & 0x7fffffffUL);
         if (!newsp)
                 newsp = regs.gprs[15];
-        p = do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
-                   parent_tidptr, child_tidptr);
-       return IS_ERR(p) ? PTR_ERR(p) : p->pid;
+        return do_fork(clone_flags & ~CLONE_IDLETASK, newsp, &regs, 0,
+                      parent_tidptr, child_tidptr);
 }
+
+
index 836319402664eb42b612123afdb90cc7df8bbcac..a128403e4d98a1ae170566136c3a64280cfa9d26 100644 (file)
@@ -563,6 +563,10 @@ handle_signal32(unsigned long sig, siginfo_t *info, sigset_t *oldset,
        if (regs->trap == __LC_SVC_OLD_PSW) {
                /* If so, check system call restarting.. */
                switch (regs->gprs[2]) {
+                       case -ERESTART_RESTARTBLOCK:
+                               current_thread_info()->restart_block.fn =
+                                       do_no_restart_syscall;
+                               clear_thread_flag(TIF_RESTART_SVC);
                        case -ERESTARTNOHAND:
                                regs->gprs[2] = -EINTR;
                                break;
index c81e2e13fc6f208a5caa5859390a9a5c7b56d64e..73cb7e8136e306b9b8a5382be0ca23d1186268b3 100644 (file)
@@ -321,9 +321,18 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
                        /* Fake a 31 bit psw address. */
                        tmp = (__u32) __KSTK_PTREGS(child)->psw.addr |
                                PSW32_ADDR_AMODE31;
-               } else
+               } else if (addr < (addr_t) &dummy32->regs.acrs[0]) {
+                       /* gpr 0-15 */
                        tmp = *(__u32 *)((addr_t) __KSTK_PTREGS(child) + 
                                         addr*2 + 4);
+               } else if (addr < (addr_t) &dummy32->regs.orig_gpr2) {
+                       offset = PT_ACR0 + addr - (addr_t) &dummy32->regs.acrs;
+                       tmp = *(__u32*)((addr_t) __KSTK_PTREGS(child) + offset);
+               } else {
+                       /* orig gpr 2 */
+                       offset = PT_ORIGGPR2 + 4;
+                       tmp = *(__u32*)((addr_t) __KSTK_PTREGS(child) + offset);
+               }
        } else if (addr >= (addr_t) &dummy32->regs.fp_regs &&
                   addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
                /*
@@ -387,9 +396,17 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
                        /* Build a 64 bit psw address from 31 bit address. */
                        __KSTK_PTREGS(child)->psw.addr = 
                                (__u64) tmp & PSW32_ADDR_INSN;
-               } else
+               } else if (addr < (addr_t) &dummy32->regs.acrs[0]) {
+                       /* gpr 0-15 */
                        *(__u32*)((addr_t) __KSTK_PTREGS(child) + addr*2 + 4) =
                                tmp;
+               } else if (addr < (addr_t) &dummy32->regs.orig_gpr2) {
+                       offset = PT_ACR0 + addr - (addr_t) &dummy32->regs.acrs;
+                       *(__u32*)((addr_t) __KSTK_PTREGS(child) + offset) = tmp;
+               } else {
+                       offset = PT_ORIGGPR2 + 4;
+                       *(__u32*)((addr_t) __KSTK_PTREGS(child) + offset) = tmp;
+               }
        } else if (addr >= (addr_t) &dummy32->regs.fp_regs &&
                   addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
                /*