2.5.39 s390 (18/26): fpu registers.

2.5.39 s390 (18/26): fpu registers.

Post by Martin Schwidefsk » Tue, 01 Oct 2002 16:30:12



Cleanup load/store of fpu register on s390.

diff -urN linux-2.5.39/arch/s390/kernel/Makefile linux-2.5.39-s390/arch/s390/kernel/Makefile
--- linux-2.5.39/arch/s390/kernel/Makefile      Mon Sep 30 13:25:21 2002
+++ linux-2.5.39-s390/arch/s390/kernel/Makefile Mon Sep 30 13:33:09 2002
@@ -8,7 +8,7 @@
 export-objs    := debug.o ebcdic.o s390_ext.o smp.o s390_ksyms.o
 obj-y  := entry.o bitmap.o traps.o time.o process.o \
             setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
-            semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
+            semaphore.o reipl.o s390_ext.o debug.o

 obj-$(CONFIG_MODULES)          += s390_ksyms.o
 obj-$(CONFIG_SMP)              += smp.o
diff -urN linux-2.5.39/arch/s390/kernel/process.c linux-2.5.39-s390/arch/s390/kernel/process.c
--- linux-2.5.39/arch/s390/kernel/process.c     Mon Sep 30 13:33:09 2002
+++ linux-2.5.39-s390/arch/s390/kernel/process.c        Mon Sep 30 13:33:09 2002
@@ -199,8 +199,13 @@

         /* fake return stack for resume(), don't go back to schedule */
         frame->gprs[9]  = (unsigned long) frame;
-        /* save fprs, if used in last task */
-       save_fp_regs(&p->thread.fp_regs);
+        /*
+        * save fprs to current->thread.fp_regs to merge them with
+        * the emulated registers and then copy the result to the child.
+        */
+       save_fp_regs(&current->thread.fp_regs);
+       memcpy(&p->thread.fp_regs, &current->thread.fp_regs,
+              sizeof(s390_fp_regs));
         p->thread.user_seg = __pa((unsigned long) p->mm->pgd) | _SEGMENT_TABLE;
        /* start process with ar4 pointing to the correct address space */
        p->thread.ar4 = get_fs().ar4;
@@ -262,20 +267,13 @@
         error = PTR_ERR(filename);
         if (IS_ERR(filename))
                 goto out;
-        error = do_execve(filename, (char **) regs.gprs[3], (char **) regs.gprs[4], &regs);
-       if (error == 0)
-       {
+        error = do_execve(filename, (char **) regs.gprs[3],
+                         (char **) regs.gprs[4], &regs);
+       if (error == 0) {
                current->ptrace &= ~PT_DTRACE;
-               current->thread.fp_regs.fpc=0;
-               if(MACHINE_HAS_IEEE)
-               {
-                       __asm__ __volatile__
-                       ("sr  0,0\n\t"
-                        "sfpc 0,0\n\t"
-                               :
-                               :
-                                :"0");
-               }
+               current->thread.fp_regs.fpc = 0;
+               if (MACHINE_HAS_IEEE)
+                       asm volatile("sfpc %0,%0" : : "d" (0));
        }
         putname(filename);
 out:
@@ -288,7 +286,12 @@
  */
 int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs)
 {
-       save_fp_regs(fpregs);
+        /*
+        * save fprs to current->thread.fp_regs to merge them with
+        * the emulated registers and then copy the result to the dump.
+        */
+       save_fp_regs(&current->thread.fp_regs);
+       memcpy(fpregs, &current->thread.fp_regs, sizeof(s390_fp_regs));
        return 1;
 }

diff -urN linux-2.5.39/arch/s390/kernel/s390fpu.c linux-2.5.39-s390/arch/s390/kernel/s390fpu.c
--- linux-2.5.39/arch/s390/kernel/s390fpu.c     Fri Sep 27 23:49:05 2002
+++ linux-2.5.39-s390/arch/s390/kernel/s390fpu.c        Thu Jan  1 01:00:00 1970
@@ -1,138 +0,0 @@
-/*
- *  arch/s390/kernel/s390fpu.c
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbar...@de.ibm.com,barrow...@yahoo.com)
- *
- *  s390fpu.h functions for saving & restoring the fpu state.
- *
- *  I couldn't inline these as linux/sched.h included half the world
- *  & was required to at the task structure.
- *  & the functions were too complex to make macros from.
- *  ( & as usual I didn't feel like debugging inline code ).
- */
-
-#include <linux/config.h>
-#include <linux/sched.h>
-
-int save_fp_regs1(s390_fp_regs *fpregs)
-{
-       int has_ieee=MACHINE_HAS_IEEE;
-/*
-  I don't think we can use STE here as this would load
-  fp registers 0 & 2 into memory locations 0 & 1 etc.
- */    
-       asm volatile ("STD   0,8(%0)\n\t"
-                     "STD   2,24(%0)\n\t"
-                     "STD   4,40(%0)\n\t"
-                     "STD   6,56(%0)"
-                      :
-                     : "a" (fpregs)
-                     : "memory"
-               );
-       if(has_ieee)
-       {
-               asm volatile ("STFPC 0(%0)\n\t"
-                             "STD   1,16(%0)\n\t"
-                             "STD   3,32(%0)\n\t"
-                             "STD   5,48(%0)\n\t"
-                             "STD   7,64(%0)\n\t"
-                             "STD   8,72(%0)\n\t"
-                             "STD   9,80(%0)\n\t"
-                             "STD   10,88(%0)\n\t"
-                             "STD   11,96(%0)\n\t"
-                             "STD   12,104(%0)\n\t"
-                             "STD   13,112(%0)\n\t"
-                             "STD   14,120(%0)\n\t"
-                             "STD   15,128(%0)\n\t"
-                             :
-                             : "a" (fpregs)
-                             : "memory"
-                       );
-       }
-       return(has_ieee);
-}
-
-
-void save_fp_regs(s390_fp_regs *fpregs)
-{
-#if CONFIG_MATHEMU
-       s390_fp_regs *currentfprs;
-
-       if(!save_fp_regs1(fpregs))
-       {
-               currentfprs=&current->thread.fp_regs;
-               fpregs->fpc=currentfprs->fpc;
-               fpregs->fprs[1].d=currentfprs->fprs[1].d;
-               fpregs->fprs[3].d=currentfprs->fprs[3].d;
-               fpregs->fprs[5].d=currentfprs->fprs[5].d;
-               fpregs->fprs[7].d=currentfprs->fprs[7].d;
-               memcpy(&fpregs->fprs[8].d,&currentfprs->fprs[8].d,sizeof(freg_t)*8);
-       }
-#else
-       save_fp_regs1(fpregs);
-#endif
-}
-
-
-int restore_fp_regs1(s390_fp_regs *fpregs)
-{
-       int has_ieee=MACHINE_HAS_IEEE;
-
-       /* If we don't mask with the FPC_VALID_MASK here
-        * we've got a very quick shutdown -h now command
-         * via a kernel specification exception.
-        */
-       fpregs->fpc&=FPC_VALID_MASK;
-       asm volatile ("LD   0,8(%0)\n\t"
-                     "LD   2,24(%0)\n\t"
-                     "LD   4,40(%0)\n\t"
-                     "LD   6,56(%0)"
-                      :
-                     : "a" (fpregs)
-                     : "memory"
-               );
-       if(has_ieee)
-       {
-               asm volatile ("LFPC 0(%0)\n\t"
-                             "LD   1,16(%0)\n\t"
-                             "LD   3,32(%0)\n\t"
-                             "LD   5,48(%0)\n\t"
-                             "LD   7,64(%0)\n\t"
-                             "LD   8,72(%0)\n\t"
-                             "LD   9,80(%0)\n\t"
-                             "LD   10,88(%0)\n\t"
-                             "LD   11,96(%0)\n\t"
-                             "LD   12,104(%0)\n\t"
-                             "LD   13,112(%0)\n\t"
-                             "LD   14,120(%0)\n\t"
-                             "LD   15,128(%0)\n\t"
-                             :
-                             : "a" (fpregs)
-                             : "memory"
-                       );
-       }
-       return(has_ieee);
-}
-
-void restore_fp_regs(s390_fp_regs *fpregs)
-{
-#if CONFIG_MATHEMU
-       s390_fp_regs *currentfprs;
-
-       if(!restore_fp_regs1(fpregs))
-       {
-               currentfprs=&current->thread.fp_regs;
-               currentfprs->fpc=fpregs->fpc;
-               currentfprs->fprs[1].d=fpregs->fprs[1].d;
-               currentfprs->fprs[3].d=fpregs->fprs[3].d;
-               currentfprs->fprs[5].d=fpregs->fprs[5].d;
-               currentfprs->fprs[7].d=fpregs->fprs[7].d;
-               memcpy(&currentfprs->fprs[8].d,&fpregs->fprs[8].d,sizeof(freg_t)*8);
-       }
-#else
-       restore_fp_regs1(fpregs);
-#endif
-}
-
diff -urN linux-2.5.39/arch/s390/kernel/signal.c linux-2.5.39-s390/arch/s390/kernel/signal.c
--- linux-2.5.39/arch/s390/kernel/signal.c      Fri Sep 27 23:49:16 2002
+++ linux-2.5.39-s390/arch/s390/kernel/signal.c Mon Sep 30 13:33:09 2002
@@ -49,13 +49,14 @@
        struct ucontext uc;
 } rt_sigframe;

-asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset));
+int do_signal(struct pt_regs *regs, sigset_t *oldset);

 /*
  * Atomically swap in the new signal mask, and wait for a signal.
  */
 asmlinkage int
-sys_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask)
+sys_sigsuspend(struct pt_regs * regs, int history0, int history1,
+              old_sigset_t mask)
 {
        sigset_t saveset;

@@ -147,37 +148,39 @@
 static int save_sigregs(struct pt_regs *regs,_sigregs *sregs)
 {
        int err;
-       s390_fp_regs fpregs;

-       err = __copy_to_user(&sregs->regs,regs,sizeof(_s390_regs_common));
-       if(!err)
-       {
-               save_fp_regs(&fpregs);
-               err=__copy_to_user(&sregs->fpregs,&fpregs,sizeof(fpregs));
-       }
-       return(err);
-      
+       err = __copy_to_user(&sregs->regs, regs, sizeof(_s390_regs_common));
+       if (err != 0)
+               return err;
+       /*
+        * We have to store the fp registers to current->thread.fp_regs
+        * to merge them with the emulated registers.
+        */
+       save_fp_regs(&current->thread.fp_regs);
+       return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
+                             sizeof(s390_fp_regs));
 }

 /* Returns positive number on error */
 static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
 {
        int err;
-       s390_fp_regs fpregs;
-       psw_t saved_psw=regs->psw;
-       err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
-       if(!err)
-       {
-               regs->trap = -1;             /* disable syscall checks */
-               regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
-               (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
-               regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
-               (regs->psw.addr&PSW_ADDR_DEBUGCHANGE);
-               err=__copy_from_user(&fpregs,&sregs->fpregs,sizeof(fpregs));
-               if(!err)
-                       restore_fp_regs(&fpregs);
-       }
-       return(err);
+
+       err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common));
+       regs->psw.mask = _USER_PSW_MASK | (regs->psw.mask & PSW_MASK_DEBUGCHANGE);
+       regs->psw.addr |= _ADDR_31;
+       if (err)
+               return err;
+
+       err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
+                              sizeof(s390_fp_regs));
+       current->thread.fp_regs.fpc &= FPC_VALID_MASK;
+       if (err)
+               return err;
+
+       restore_fp_regs(&current->thread.fp_regs);
+       regs->trap = -1;     /* disable syscall checks */
+       return 0;
 }

 asmlinkage long sys_sigreturn(struct pt_regs *regs)
diff -urN linux-2.5.39/arch/s390x/kernel/Makefile linux-2.5.39-s390/arch/s390x/kernel/Makefile
--- linux-2.5.39/arch/s390x/kernel/Makefile     Mon Sep 30 13:25:21 2002
+++ linux-2.5.39-s390/arch/s390x/kernel/Makefile        Mon Sep 30 13:33:09 2002
@@ -10,7 +10,7 @@

 obj-y          := entry.o bitmap.o traps.o time.o process.o \
                   setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
-                  semaphore.o s390fpu.o reipl.o s390_ext.o debug.o
+                  semaphore.o reipl.o s390_ext.o debug.o

 obj-$(CONFIG_MODULES)          += s390_ksyms.o
 obj-$(CONFIG_SMP)              += smp.o
diff -urN linux-2.5.39/arch/s390x/kernel/process.c linux-2.5.39-s390/arch/s390x/kernel/process.c
--- linux-2.5.39/arch/s390x/kernel/process.c    Mon Sep 30 13:33:09 2002
+++ linux-2.5.39-s390/arch/s390x/kernel/process.c       Mon Sep 30 13:33:09 2002
@@ -257,15 +257,12 @@
         error = PTR_ERR(filename);
         if (IS_ERR(filename))
                 goto out;
-        error = do_execve(filename, (char **) regs.gprs[3], (char **) regs.gprs[4], &regs);
-       if (error == 0)
-       {
+        error = do_execve(filename, (char **) regs.gprs[3],
+                         (char **) regs.gprs[4], &regs);
+       if (error == 0) {
                current->ptrace &= ~PT_DTRACE;
-               current->thread.fp_regs.fpc=0;
-               __asm__ __volatile__
-                       ("sr  0,0\n\t"
-                        "sfpc 0,0\n\t"
-                        : : :"0");
+               current->thread.fp_regs.fpc = 0;
+               asm volatile("sfpc %0,%0" : : "d" (0));
        }
         putname(filename);
 out:
diff -urN linux-2.5.39/arch/s390x/kernel/s390fpu.c linux-2.5.39-s390/arch/s390x/kernel/s390fpu.c
--- linux-2.5.39/arch/s390x/kernel/s390fpu.c    Fri Sep 27 23:50:56 2002
+++ linux-2.5.39-s390/arch/s390x/kernel/s390fpu.c       Thu Jan  1 01:00:00 1970
@@ -1,87 +0,0 @@
-/*
- *  arch/s390/kernel/s390fpu.c
- *
- *  S390 version
- *    Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Denis Joseph Barrow (djbar...@de.ibm.com,barrow...@yahoo.com)
- *
- *  s390fpu.h functions for saving & restoring the fpu state.
- *
- *  I couldn't inline these as linux/sched.h included half the world
- *  & was required to at the task structure.
- *  & the functions were too complex to make macros from.
- *  ( & as usual I didn't feel like debugging inline code ).
- */
-
-#include <linux/sched.h>
-
-void save_fp_regs(s390_fp_regs *fpregs)
-{
-/*
- * I don't think we can use STE here as this would load
- * fp registers 0 & 2 into memory locations 0 & 1 etc.
- */    
-       asm volatile ("STFPC 0(%0)\n\t"
-                     "STD   0,8(%0)\n\t"
-                     "STD   1,16(%0)\n\t"
-                     "STD   2,24(%0)\n\t"
-                     "STD   3,32(%0)\n\t"
-                     "STD   4,40(%0)\n\t"
-                     "STD   5,48(%0)\n\t"
-                     "STD   6,56(%0)\n\t"
-                     "STD   7,64(%0)\n\t"
-                     "STD   8,72(%0)\n\t"
-                     "STD   9,80(%0)\n\t"
-                     "STD   10,88(%0)\n\t"
-                     "STD   11,96(%0)\n\t"
-                     "STD   12,104(%0)\n\t"
-                     "STD   13,112(%0)\n\t"
-                     "STD   14,120(%0)\n\t"
-                     "STD   15,128(%0)\n\t"
-                      :
-                     : "a" (fpregs)
-                     : "memory"
-               );
-}
-
-void restore_fp_regs(s390_fp_regs *fpregs)
-{
-       /* If we don't mask with the FPC_VALID_MASK here
-        * we've got a very quick shutdown -h now command
-         * via a kernel specification exception.
-        */
-       fpregs->fpc&=FPC_VALID_MASK;
-       asm volatile ("LFPC 0(%0)\n\t"
-                     "LD   0,8(%0)\n\t"
-                     "LD   1,16(%0)\n\t"
-                     "LD   2,24(%0)\n\t"
-                     "LD   3,32(%0)\n\t"
-                     "LD   4,40(%0)\n\t"
-                     "LD   5,48(%0)\n\t"
-                     "LD   6,56(%0)\n\t"
-                     "LD   7,64(%0)\n\t"
-                     "LD   8,72(%0)\n\t"
-                     "LD   9,80(%0)\n\t"
-                     "LD   10,88(%0)\n\t"
-                     "LD   11,96(%0)\n\t"
-                     "LD   12,104(%0)\n\t"
-                     "LD   13,112(%0)\n\t"
-                     "LD   14,120(%0)\n\t"
-                     "LD   15,128(%0)\n\t"
-                      :
-                     : "a" (fpregs)
-                     : "memory"
-               );
-}
-
-
-
-
-
-
-
-
-
-
-
-
diff -urN linux-2.5.39/arch/s390x/kernel/signal.c linux-2.5.39-s390/arch/s390x/kernel/signal.c
--- linux-2.5.39/arch/s390x/kernel/signal.c     Fri Sep 27 23:50:21 2002
+++ linux-2.5.39-s390/arch/s390x/kernel/signal.c        Mon Sep 30 13:33:09 2002
@@ -144,40 +144,37 @@

 /* Returns non-zero on fault */
-static int save_sigregs(struct pt_regs *regs,_sigregs *sregs)
+static int save_sigregs(struct pt_regs *regs, _sigregs *sregs)
 {
        int err;
-       s390_fp_regs fpregs;

-       err = __copy_to_user(&sregs->regs,regs,sizeof(_s390_regs_common));
-       if(!err)
-       {
-               save_fp_regs(&fpregs);
-               err=__copy_to_user(&sregs->fpregs,&fpregs,sizeof(fpregs));
-       }
-       return(err);
-      
+       err = __copy_to_user(&sregs->regs, regs, sizeof(_s390_regs_common));
+       if (err != 0)
+               return err;
+       save_fp_regs(&current->thread.fp_regs);
+       return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
+                             sizeof(s390_fp_regs));
 }

 /* Returns positive number on error */
-static int restore_sigregs(struct pt_regs *regs,_sigregs *sregs)
+static int restore_sigregs(struct pt_regs *regs, _sigregs *sregs)
 {
        int err;
-       s390_fp_regs fpregs;
-       psw_t saved_psw=regs->psw;
-       err=__copy_from_user(regs,&sregs->regs,sizeof(_s390_regs_common));
-       if(!err)
-       {
-               regs->trap = -1;             /* disable syscall checks */
-               regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
-               (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
-               regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
-               (regs->psw.addr&PSW_ADDR_DEBUGCHANGE);
-               err=__copy_from_user(&fpregs,&sregs->fpregs,sizeof(fpregs));
-               if(!err)
-                       restore_fp_regs(&fpregs);
-       }
-       return(err);
+
+       err = __copy_from_user(regs, &sregs->regs, sizeof(_s390_regs_common));
+       regs->psw.mask = _USER_PSW_MASK | (regs->psw.mask & PSW_MASK_DEBUGCHANGE);
+       if (err)
+               return err;
+
+       err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
+                              sizeof(s390_fp_regs));
+       current->thread.fp_regs.fpc &= FPC_VALID_MASK;
+       if (err)
+               return err;
+
+       restore_fp_regs(&current->thread.fp_regs);
+       regs->trap = -1;     /* disable syscall checks */
+       return 0;
 }

 asmlinkage long sys_sigreturn(struct pt_regs *regs)
diff -urN linux-2.5.39/arch/s390x/kernel/signal32.c linux-2.5.39-s390/arch/s390x/kernel/signal32.c
--- linux-2.5.39/arch/s390x/kernel/signal32.c   Fri Sep 27 23:49:53 2002
+++ linux-2.5.39-s390/arch/s390x/kernel/signal32.c      Mon Sep 30 13:33:09 2002
@@ -32,7 +32,11 @@

 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))

+#define _ADDR_31 0x80000000
+#define _USER_PSW_MASK_EMU32 0x070DC000
 #define _USER_PSW_MASK32 0x0705C00080000000
+#define PSW_MASK_DEBUGCHANGE32 0x00003000UL
+#define PSW_ADDR_DEBUGCHANGE32 0x7FFFFFFFUL

 typedef struct
 {
@@ -290,55 +294,48 @@

 static int save_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
 {
-       int err = 0;
-       s390_fp_regs fpregs;
-       int i;
-
-       for(i=0; i<NUM_GPRS; i++)
-               err |= __put_user(regs->gprs[i], &sregs->regs.gprs[i]);  
-       for(i=0; i<NUM_ACRS; i++)
-               err |= __put_user(regs->acrs[i], &sregs->regs.acrs[i]);  
-       err |= __copy_to_user(&sregs->regs.psw.mask, &regs->psw.mask, 4);
-       err |= __copy_to_user(&sregs->regs.psw.addr, ((char*)&regs->psw.addr)+4, 4);
-       if(!err)
-       {
-               save_fp_regs(&fpregs);
-               __put_user(fpregs.fpc, &sregs->fpregs.fpc);
-               for(i=0; i<NUM_FPRS; i++)
-                       err |= __put_user(fpregs.fprs[i].d, &sregs->fpregs.fprs[i].d);  
-       }
-       return(err);
-      
+       _s390_regs_common32 regs32;
+       int err, i;
+
+       regs32.psw.mask = _USER_PSW_MASK_EMU32 |
+               (__u32)((regs->psw.mask & PSW_MASK_DEBUGCHANGE) >> 32);
+       regs32.psw.addr = _ADDR_31 | (__u32) regs->psw.addr;
+       for (i = 0; i < NUM_GPRS; i++)
+               regs32.gprs[i] = (__u32) regs->gprs[i];
+       memcpy(regs32.acrs, regs->acrs, sizeof(regs32.acrs));
+       err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
+       if (err)
+               return err;
+       save_fp_regs(&current->thread.fp_regs);
+       /* s390_fp_regs and _s390_fp_regs32 are the same ! */
+       return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
+                             sizeof(_s390_fp_regs32));
 }

 static int restore_sigregs32(struct pt_regs *regs,_sigregs32 *sregs)
 {
-       int err = 0;
-       s390_fp_regs fpregs;
-       psw_t saved_psw=regs->psw;
-       int i;
-
-       for(i=0; i<NUM_GPRS; i++)
-               err |= __get_user(regs->gprs[i], &sregs->regs.gprs[i]);  
-       for(i=0; i<NUM_ACRS; i++)
-               err |= __get_user(regs->acrs[i], &sregs->regs.acrs[i]);  
-       err |= __copy_from_user(&regs->psw.mask, &sregs->regs.psw.mask, 4);
-       err |= __copy_from_user(((char*)&regs->psw.addr)+4, &sregs->regs.psw.addr, 4);
-
-       if(!err)
-       {
-               regs->trap = -1;             /* disable syscall checks */
-               regs->psw.mask=(saved_psw.mask&~PSW_MASK_DEBUGCHANGE)|
-               (regs->psw.mask&PSW_MASK_DEBUGCHANGE);
-               regs->psw.addr=(saved_psw.addr&~PSW_ADDR_DEBUGCHANGE)|
-               (regs->psw.addr&PSW_ADDR_DEBUGCHANGE);
-               __get_user(fpregs.fpc, &sregs->fpregs.fpc);
-                for(i=0; i<NUM_FPRS; i++)
-                        err |= __get_user(fpregs.fprs[i].d, &sregs->fpregs.fprs[i].d);              
-               if(!err)
-                       restore_fp_regs(&fpregs);
-       }
-       return(err);
+       _s390_regs_common32 regs32;
+       int err, i;
+
+       err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
+       if (err)
+               return err;
+       regs->psw.mask = _USER_PSW_MASK32 |
+               (__u64)(regs32.psw.mask & PSW_MASK_DEBUGCHANGE32) << 32;
+       regs->psw.addr = (__u64)(regs32.psw.addr & PSW_ADDR_DEBUGCHANGE32);
+       for (i = 0; i < NUM_GPRS; i++)
+               regs->gprs[i] = (__u64) regs32.gprs[i];
+       memcpy(regs->acrs, regs32.acrs, sizeof(regs32.acrs));
+
+       err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
+                              sizeof(_s390_fp_regs32));
+       current->thread.fp_regs.fpc &= FPC_VALID_MASK;
+       if (err)
+               return err;
+
+       restore_fp_regs(&current->thread.fp_regs);
+       regs->trap = -1;     /* disable syscall checks */
+       return 0;
 }

 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
diff -urN linux-2.5.39/include/asm-s390/system.h linux-2.5.39-s390/include/asm-s390/system.h
--- linux-2.5.39/include/asm-s390/system.h      Mon Sep 30 13:33:09 2002
+++ linux-2.5.39-s390/include/asm-s390/system.h Mon Sep 30 13:33:09 2002
@@ -12,22 +12,79 @@
 #define __ASM_SYSTEM_H

 #include <linux/config.h>
+#include <linux/kernel.h>
 #include <asm/types.h>
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+
 #ifdef __KERNEL__
-#include <asm/lowcore.h>
-#endif
-#include <linux/kernel.h>
+
+struct task_struct;
+
+extern struct task_struct *resume(void *, void *);
+
+static inline void save_fp_regs(s390_fp_regs *fpregs)
+{
+       asm volatile (
+               "   std   0,8(%0)\n"
+               "   std   2,24(%0)\n"
+               "   std   4,40(%0)\n"
+               "   std   6,56(%0)"
+               : : "a" (fpregs) : "memory" );
+       if (!MACHINE_HAS_IEEE)
+               return;
+       asm volatile(
+               "   stfpc 0(%0)\n"
+               "   std   1,16(%0)\n"
+               "   std   3,32(%0)\n"
+               "   std   5,48(%0)\n"
+               "   std   7,64(%0)\n"
+               "   std   8,72(%0)\n"
+               "   std   9,80(%0)\n"
+               "   std   10,88(%0)\n"
+               "   std   11,96(%0)\n"
+               "   std   12,104(%0)\n"
+               "   std   13,112(%0)\n"
+               "   std   14,120(%0)\n"
+               "   std   15,128(%0)\n"
+               : : "a" (fpregs) : "memory" );
+}
+
+static inline void restore_fp_regs(s390_fp_regs *fpregs)
+{
+       asm volatile (
+               "   ld    0,8(%0)\n"
+               "   ld    2,24(%0)\n"
+               "   ld    4,40(%0)\n"
+               "   ld    6,56(%0)"
+               : : "a" (fpregs));
+       if (!MACHINE_HAS_IEEE)
+               return;
+       asm volatile(
+               "   lfpc  0(%0)\n"
+               "   ld    1,16(%0)\n"
+               "   ld    3,32(%0)\n"
+               "   ld    5,48(%0)\n"
+               "   ld    7,64(%0)\n"
+               "   ld    8,72(%0)\n"
+               "   ld    9,80(%0)\n"
+               "   ld    10,88(%0)\n"
+               "   ld    11,96(%0)\n"
+               "   ld    12,104(%0)\n"
+               "   ld    13,112(%0)\n"
+               "   ld    14,120(%0)\n"
+               "   ld    15,128(%0)\n"
+               : : "a" (fpregs));
+}

 #define switch_to(prev,next,last) do {                                      \
        if (prev == next)                                                    \
                break;                                                       \
-       save_fp_regs1(&prev->thread.fp_regs);                                 \
-       restore_fp_regs1(&next->thread.fp_regs);                      \
+       save_fp_regs(&prev->thread.fp_regs);                                  \
+       restore_fp_regs(&next->thread.fp_regs);                               \
        resume(prev,next);                                                   \
 } while (0)

-struct task_struct;
-
 #define nop() __asm__ __volatile__ ("nop")

 #define xchg(ptr,x) \
@@ -281,23 +338,13 @@
 #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
 #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)

-#endif
-
-#ifdef __KERNEL__
-extern struct task_struct *resume(void *, void *);
-
-extern int save_fp_regs1(s390_fp_regs *fpregs);
-extern void save_fp_regs(s390_fp_regs *fpregs);
-extern int restore_fp_regs1(s390_fp_regs *fpregs);
-extern void restore_fp_regs(s390_fp_regs *fpregs);
+#endif /* CONFIG_SMP */

 extern void (*_machine_restart)(char *command);
 extern void (*_machine_halt)(void);
 extern void (*_machine_power_off)(void);

-#endif
+#endif /* __KERNEL__ */

 #endif

-
-
diff -urN linux-2.5.39/include/asm-s390x/system.h linux-2.5.39-s390/include/asm-s390x/system.h
--- linux-2.5.39/include/asm-s390x/system.h     Mon Sep 30 13:33:09 2002
+++ linux-2.5.39-s390/include/asm-s390x/system.h        Mon Sep 30 13:33:09 2002
@@ -12,11 +12,62 @@
 #define __ASM_SYSTEM_H

 #include <linux/config.h>
+#include <linux/kernel.h>
 #include <asm/types.h>
+#include <asm/ptrace.h>
+#include <asm/setup.h>
+
 #ifdef __KERNEL__
-#include <asm/lowcore.h>
-#endif
-#include <linux/kernel.h>
+
+struct task_struct;
+
+extern struct task_struct *resume(void *, void *);
+
+static inline void save_fp_regs(s390_fp_regs *fpregs)
+{
+       asm volatile (
+               "   stfpc 0(%0)\n"
+               "   std   0,8(%0)\n"
+               "   std   1,16(%0)\n"
+               "   std   2,24(%0)\n"
+               "   std   3,32(%0)\n"
+               "   std   4,40(%0)\n"
+               "   std   5,48(%0)\n"
+               "   std   6,56(%0)\n"
+               "   std   7,64(%0)\n"
+               "   std   8,72(%0)\n"
+               "   std   9,80(%0)\n"
+               "   std   10,88(%0)\n"
+               "   std   11,96(%0)\n"
+               "   std   12,104(%0)\n"
+               "   std   13,112(%0)\n"
+               "   std   14,120(%0)\n"
+               "   std   15,128(%0)\n"
+               : : "a" (fpregs) : "memory" );
+}
+
+static inline void restore_fp_regs(s390_fp_regs *fpregs)
+{
+       asm volatile (
+               "   lfpc  0(%0)\n"
+               "   ld    0,8(%0)\n"
+               "   ld    1,16(%0)\n"
+               "   ld    2,24(%0)\n"
+               "   ld    3,32(%0)\n"
+               "   ld    4,40(%0)\n"
+               "   ld    5,48(%0)\n"
+               "   ld    6,56(%0)\n"
+               "   ld    7,64(%0)\n"
+               "   ld    8,72(%0)\n"
+               "   ld    9,80(%0)\n"
+               "   ld    10,88(%0)\n"
+               "   ld    11,96(%0)\n"
+               "   ld    12,104(%0)\n"
+               "   ld    13,112(%0)\n"
+               "   ld    14,120(%0)\n"
+               "   ld    15,128(%0)\n"
+               : : "a" (fpregs));
+}

 #define switch_to(prev,next,last) do {                                      \
        if (prev == next)                                                    \
@@ -26,8 +77,6 @@
        resume(prev,next);                                                   \
 } while (0)

-struct task_struct;
-
 #define nop() __asm__ __volatile__ ("nop")

 #define xchg(ptr,x) \
@@ -297,23 +346,13 @@
 #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit)
 #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit)

-#endif
-
-#ifdef __KERNEL__
-extern struct task_struct *resume(void *, void *);
-
-extern int save_fp_regs1(s390_fp_regs *fpregs);
-extern void save_fp_regs(s390_fp_regs *fpregs);
-extern int restore_fp_regs1(s390_fp_regs *fpregs);
-extern void restore_fp_regs(s390_fp_regs *fpregs);
+#endif /* CONFIG_SMP */

 extern void (*_machine_restart)(char *command);
 extern void (*_machine_halt)(void);
 extern void (*_machine_power_off)(void);

-#endif
+#endif /* __KERNEL __ */

 #endif

-
-

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/