u32 pretcode;
        int sig;
        struct sigcontext_ia32 sc;
-       struct _fpstate_ia32 fpstate;
+       struct _fpstate_ia32 fpstate_unused; /* look at kernel/sigframe.h */
        unsigned int extramask[_COMPAT_NSIG_WORDS-1];
        char retcode[8];
+       /* fp state follows here */
 };
 
 struct rt_sigframe
        u32 puc;
        compat_siginfo_t info;
        struct ucontext_ia32 uc;
-       struct _fpstate_ia32 fpstate;
        char retcode[8];
+       /* fp state follows here */
 };
 
 #define COPY(x)                {               \
  * Determine which stack to use..
  */
 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
-                                size_t frame_size)
+                                size_t frame_size,
+                                struct _fpstate_ia32 **fpstate)
 {
        unsigned long sp;
 
                 ka->sa.sa_restorer)
                sp = (unsigned long) ka->sa.sa_restorer;
 
+       if (used_math()) {
+               sp = sp - sig_xstate_ia32_size;
+               *fpstate = (struct _fpstate_ia32 *) sp;
+       }
+
        sp -= frame_size;
        /* Align the stack pointer according to the i386 ABI,
         * i.e. so that on function entry ((sp + 4) & 15) == 0. */
        struct sigframe __user *frame;
        void __user *restorer;
        int err = 0;
+       struct _fpstate_ia32 __user *fpstate = NULL;
 
        /* copy_to_user optimizes that into a single 8 byte store */
        static const struct {
                0,
        };
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
        if (err)
                goto give_sigsegv;
 
-       err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs,
-                                       set->sig[0]);
+       err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
        if (err)
                goto give_sigsegv;
 
        struct rt_sigframe __user *frame;
        void __user *restorer;
        int err = 0;
+       struct _fpstate_ia32 __user *fpstate = NULL;
 
        /* __copy_to_user optimizes that into a single 8 byte store */
        static const struct {
                0,
        };
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
        err |= __put_user(sas_ss_flags(regs->sp),
                          &frame->uc.uc_stack.ss_flags);
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
+       err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
                                     regs, set->sig[0]);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
 
 # define save_i387_ia32                save_i387
 # define restore_i387_ia32     restore_i387
 # define _fpstate_ia32         _fpstate
+# define sig_xstate_ia32_size   sig_xstate_size
 # define user_i387_ia32_struct user_i387_struct
 # define user32_fxsr_struct    user_fxsr_struct
 #endif
 
 static unsigned int            mxcsr_feature_mask __read_mostly = 0xffffffffu;
 unsigned int xstate_size;
+unsigned int sig_xstate_ia32_size = sizeof(struct _fpstate_ia32);
 static struct i387_fxsave_struct fx_scratch __cpuinitdata;
 
 void __cpuinit mxcsr_feature_mask_init(void)
 
        char __user *pretcode;
        int sig;
        struct sigcontext sc;
-       struct _fpstate fpstate;
+       /*
+        * fpstate is unused. fpstate is moved/allocated after
+        * retcode[] below. This movement allows to have the FP state and the
+        * future state extensions (xsave) stay together.
+        * And at the same time retaining the unused fpstate, prevents changing
+        * the offset of extramask[] in the sigframe and thus prevent any
+        * legacy application accessing/modifying it.
+        */
+       struct _fpstate fpstate_unused;
        unsigned long extramask[_NSIG_WORDS-1];
        char retcode[8];
+       /* fp state follows here */
 };
 
 struct rt_sigframe {
        void __user *puc;
        struct siginfo info;
        struct ucontext uc;
-       struct _fpstate fpstate;
        char retcode[8];
+       /* fp state follows here */
 };
 #else
 struct rt_sigframe {
        char __user *pretcode;
        struct ucontext uc;
        struct siginfo info;
+       /* fp state follows here */
 };
 #endif
 
  * Determine which stack to use..
  */
 static inline void __user *
-get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
+get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size,
+            struct _fpstate **fpstate)
 {
        unsigned long sp;
 
                        sp = (unsigned long) ka->sa.sa_restorer;
        }
 
+       if (used_math()) {
+               sp = sp - sig_xstate_size;
+               *fpstate = (struct _fpstate *) sp;
+       }
+
        sp -= frame_size;
        /*
         * Align the stack pointer according to the i386 ABI,
        void __user *restorer;
        int err = 0;
        int usig;
+       struct _fpstate __user *fpstate = NULL;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
        if (err)
                goto give_sigsegv;
 
-       err = setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
+       err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
        if (err)
                goto give_sigsegv;
 
        void __user *restorer;
        int err = 0;
        int usig;
+       struct _fpstate __user *fpstate = NULL;
 
-       frame = get_sigframe(ka, regs, sizeof(*frame));
+       frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
 
        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
                goto give_sigsegv;
        err |= __put_user(sas_ss_flags(regs->sp),
                          &frame->uc.uc_stack.ss_flags);
        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
-       err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
+       err |= setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
                                regs, set->sig[0]);
        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
        if (err)
 
        struct task_struct *me = current;
 
        if (used_math()) {
-               fp = get_stack(ka, regs, sizeof(struct _fpstate)); 
+               fp = get_stack(ka, regs, sig_xstate_size);
                frame = (void __user *)round_down(
                        (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
 
 
  */
 struct xsave_struct *init_xstate_buf;
 
+#ifdef CONFIG_X86_64
+unsigned int sig_xstate_size = sizeof(struct _fpstate);
+#endif
+
 /*
  * Enable the extended processor state save/restore feature
  */
 
 #include <asm/uaccess.h>
 #include <asm/xsave.h>
 
+extern unsigned int sig_xstate_size;
 extern void fpu_init(void);
 extern void mxcsr_feature_mask_init(void);
 extern int init_fpu(struct task_struct *child);
 extern user_regset_set_fn fpregs_set, xfpregs_set, fpregs_soft_set;
 
 #ifdef CONFIG_IA32_EMULATION
+extern unsigned int sig_xstate_ia32_size;
 struct _fpstate_ia32;
 extern int save_i387_ia32(struct _fpstate_ia32 __user *buf);
 extern int restore_i387_ia32(struct _fpstate_ia32 __user *buf);