aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/ia32/ia32_signal.c8
-rw-r--r--arch/x86/include/asm/fpu/signal.h2
-rw-r--r--arch/x86/include/asm/ia32.h4
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/include/asm/sigcontext.h75
-rw-r--r--arch/x86/include/asm/sigframe.h8
-rw-r--r--arch/x86/include/asm/signal.h2
-rw-r--r--arch/x86/include/uapi/asm/sigcontext.h475
-rw-r--r--arch/x86/include/uapi/asm/sigcontext32.h73
-rw-r--r--arch/x86/kernel/asm-offsets.c18
-rw-r--r--arch/x86/kernel/fpu/signal.c4
-rw-r--r--arch/x86/kernel/signal.c4
-rw-r--r--arch/x86/math-emu/fpu_emu.h2
13 files changed, 338 insertions, 339 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index e6a5c275cd3f..0552884da18d 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -26,7 +26,7 @@
26#include <asm/ptrace.h> 26#include <asm/ptrace.h>
27#include <asm/ia32_unistd.h> 27#include <asm/ia32_unistd.h>
28#include <asm/user32.h> 28#include <asm/user32.h>
29#include <asm/sigcontext32.h> 29#include <uapi/asm/sigcontext.h>
30#include <asm/proto.h> 30#include <asm/proto.h>
31#include <asm/vdso.h> 31#include <asm/vdso.h>
32#include <asm/sigframe.h> 32#include <asm/sigframe.h>
@@ -68,7 +68,7 @@
68} 68}
69 69
70static int ia32_restore_sigcontext(struct pt_regs *regs, 70static int ia32_restore_sigcontext(struct pt_regs *regs,
71 struct sigcontext_ia32 __user *sc) 71 struct sigcontext_32 __user *sc)
72{ 72{
73 unsigned int tmpflags, err = 0; 73 unsigned int tmpflags, err = 0;
74 void __user *buf; 74 void __user *buf;
@@ -170,7 +170,7 @@ badframe:
170 * Set up a signal frame. 170 * Set up a signal frame.
171 */ 171 */
172 172
173static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, 173static int ia32_setup_sigcontext(struct sigcontext_32 __user *sc,
174 void __user *fpstate, 174 void __user *fpstate,
175 struct pt_regs *regs, unsigned int mask) 175 struct pt_regs *regs, unsigned int mask)
176{ 176{
@@ -234,7 +234,7 @@ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
234 unsigned long fx_aligned, math_size; 234 unsigned long fx_aligned, math_size;
235 235
236 sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size); 236 sp = fpu__alloc_mathframe(sp, 1, &fx_aligned, &math_size);
237 *fpstate = (struct _fpstate_ia32 __user *) sp; 237 *fpstate = (struct _fpstate_32 __user *) sp;
238 if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned, 238 if (copy_fpstate_to_sigframe(*fpstate, (void __user *)fx_aligned,
239 math_size) < 0) 239 math_size) < 0)
240 return (void __user *) -1L; 240 return (void __user *) -1L;
diff --git a/arch/x86/include/asm/fpu/signal.h b/arch/x86/include/asm/fpu/signal.h
index 7358e9d61f1e..0e970d00dfcd 100644
--- a/arch/x86/include/asm/fpu/signal.h
+++ b/arch/x86/include/asm/fpu/signal.h
@@ -5,7 +5,7 @@
5#define _ASM_X86_FPU_SIGNAL_H 5#define _ASM_X86_FPU_SIGNAL_H
6 6
7#ifdef CONFIG_X86_64 7#ifdef CONFIG_X86_64
8# include <asm/sigcontext32.h> 8# include <uapi/asm/sigcontext.h>
9# include <asm/user32.h> 9# include <asm/user32.h>
10struct ksignal; 10struct ksignal;
11int ia32_setup_rt_frame(int sig, struct ksignal *ksig, 11int ia32_setup_rt_frame(int sig, struct ksignal *ksig,
diff --git a/arch/x86/include/asm/ia32.h b/arch/x86/include/asm/ia32.h
index 28019765442e..a9bdf5569ab3 100644
--- a/arch/x86/include/asm/ia32.h
+++ b/arch/x86/include/asm/ia32.h
@@ -10,7 +10,7 @@
10 * 32 bit structures for IA32 support. 10 * 32 bit structures for IA32 support.
11 */ 11 */
12 12
13#include <asm/sigcontext32.h> 13#include <uapi/asm/sigcontext.h>
14 14
15/* signal.h */ 15/* signal.h */
16 16
@@ -18,7 +18,7 @@ struct ucontext_ia32 {
18 unsigned int uc_flags; 18 unsigned int uc_flags;
19 unsigned int uc_link; 19 unsigned int uc_link;
20 compat_stack_t uc_stack; 20 compat_stack_t uc_stack;
21 struct sigcontext_ia32 uc_mcontext; 21 struct sigcontext_32 uc_mcontext;
22 compat_sigset_t uc_sigmask; /* mask last for extensibility */ 22 compat_sigset_t uc_sigmask; /* mask last for extensibility */
23}; 23};
24 24
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index b55f30960554..67522256c7ff 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -11,7 +11,7 @@ struct vm86;
11#include <asm/math_emu.h> 11#include <asm/math_emu.h>
12#include <asm/segment.h> 12#include <asm/segment.h>
13#include <asm/types.h> 13#include <asm/types.h>
14#include <asm/sigcontext.h> 14#include <uapi/asm/sigcontext.h>
15#include <asm/current.h> 15#include <asm/current.h>
16#include <asm/cpufeature.h> 16#include <asm/cpufeature.h>
17#include <asm/page.h> 17#include <asm/page.h>
diff --git a/arch/x86/include/asm/sigcontext.h b/arch/x86/include/asm/sigcontext.h
index 9dfce4e0417d..e6cd2c489dbb 100644
--- a/arch/x86/include/asm/sigcontext.h
+++ b/arch/x86/include/asm/sigcontext.h
@@ -1,79 +1,8 @@
1#ifndef _ASM_X86_SIGCONTEXT_H 1#ifndef _ASM_X86_SIGCONTEXT_H
2#define _ASM_X86_SIGCONTEXT_H 2#define _ASM_X86_SIGCONTEXT_H
3 3
4#include <uapi/asm/sigcontext.h> 4/* This is a legacy header - all kernel code includes <uapi/asm/sigcontext.h> directly. */
5
6#ifdef __i386__
7struct sigcontext {
8 unsigned short gs, __gsh;
9 unsigned short fs, __fsh;
10 unsigned short es, __esh;
11 unsigned short ds, __dsh;
12 unsigned long di;
13 unsigned long si;
14 unsigned long bp;
15 unsigned long sp;
16 unsigned long bx;
17 unsigned long dx;
18 unsigned long cx;
19 unsigned long ax;
20 unsigned long trapno;
21 unsigned long err;
22 unsigned long ip;
23 unsigned short cs, __csh;
24 unsigned long flags;
25 unsigned long sp_at_signal;
26 unsigned short ss, __ssh;
27 5
28 /* 6#include <uapi/asm/sigcontext.h>
29 * fpstate is really (struct _fpstate *) or (struct _xstate *)
30 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
31 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
32 * of extended memory layout. See comments at the definition of
33 * (struct _fpx_sw_bytes)
34 */
35 void __user *fpstate; /* zero when no FPU/extended context */
36 unsigned long oldmask;
37 unsigned long cr2;
38};
39#else /* __i386__ */
40struct sigcontext {
41 unsigned long r8;
42 unsigned long r9;
43 unsigned long r10;
44 unsigned long r11;
45 unsigned long r12;
46 unsigned long r13;
47 unsigned long r14;
48 unsigned long r15;
49 unsigned long di;
50 unsigned long si;
51 unsigned long bp;
52 unsigned long bx;
53 unsigned long dx;
54 unsigned long ax;
55 unsigned long cx;
56 unsigned long sp;
57 unsigned long ip;
58 unsigned long flags;
59 unsigned short cs;
60 unsigned short gs;
61 unsigned short fs;
62 unsigned short __pad0;
63 unsigned long err;
64 unsigned long trapno;
65 unsigned long oldmask;
66 unsigned long cr2;
67 7
68 /*
69 * fpstate is really (struct _fpstate *) or (struct _xstate *)
70 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
71 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
72 * of extended memory layout. See comments at the definition of
73 * (struct _fpx_sw_bytes)
74 */
75 void __user *fpstate; /* zero when no FPU/extended context */
76 unsigned long reserved1[8];
77};
78#endif /* !__i386__ */
79#endif /* _ASM_X86_SIGCONTEXT_H */ 8#endif /* _ASM_X86_SIGCONTEXT_H */
diff --git a/arch/x86/include/asm/sigframe.h b/arch/x86/include/asm/sigframe.h
index 1f3175bb994e..34edd1650bae 100644
--- a/arch/x86/include/asm/sigframe.h
+++ b/arch/x86/include/asm/sigframe.h
@@ -1,7 +1,7 @@
1#ifndef _ASM_X86_SIGFRAME_H 1#ifndef _ASM_X86_SIGFRAME_H
2#define _ASM_X86_SIGFRAME_H 2#define _ASM_X86_SIGFRAME_H
3 3
4#include <asm/sigcontext.h> 4#include <uapi/asm/sigcontext.h>
5#include <asm/siginfo.h> 5#include <asm/siginfo.h>
6#include <asm/ucontext.h> 6#include <asm/ucontext.h>
7#include <linux/compat.h> 7#include <linux/compat.h>
@@ -9,8 +9,6 @@
9#ifdef CONFIG_X86_32 9#ifdef CONFIG_X86_32
10#define sigframe_ia32 sigframe 10#define sigframe_ia32 sigframe
11#define rt_sigframe_ia32 rt_sigframe 11#define rt_sigframe_ia32 rt_sigframe
12#define sigcontext_ia32 sigcontext
13#define _fpstate_ia32 _fpstate
14#define ucontext_ia32 ucontext 12#define ucontext_ia32 ucontext
15#else /* !CONFIG_X86_32 */ 13#else /* !CONFIG_X86_32 */
16 14
@@ -24,7 +22,7 @@
24struct sigframe_ia32 { 22struct sigframe_ia32 {
25 u32 pretcode; 23 u32 pretcode;
26 int sig; 24 int sig;
27 struct sigcontext_ia32 sc; 25 struct sigcontext_32 sc;
28 /* 26 /*
29 * fpstate is unused. fpstate is moved/allocated after 27 * fpstate is unused. fpstate is moved/allocated after
30 * retcode[] below. This movement allows to have the FP state and the 28 * retcode[] below. This movement allows to have the FP state and the
@@ -33,7 +31,7 @@ struct sigframe_ia32 {
33 * the offset of extramask[] in the sigframe and thus prevent any 31 * the offset of extramask[] in the sigframe and thus prevent any
34 * legacy application accessing/modifying it. 32 * legacy application accessing/modifying it.
35 */ 33 */
36 struct _fpstate_ia32 fpstate_unused; 34 struct _fpstate_32 fpstate_unused;
37#ifdef CONFIG_IA32_EMULATION 35#ifdef CONFIG_IA32_EMULATION
38 unsigned int extramask[_COMPAT_NSIG_WORDS-1]; 36 unsigned int extramask[_COMPAT_NSIG_WORDS-1];
39#else /* !CONFIG_IA32_EMULATION */ 37#else /* !CONFIG_IA32_EMULATION */
diff --git a/arch/x86/include/asm/signal.h b/arch/x86/include/asm/signal.h
index c481be78fcf1..2138c9ae19ee 100644
--- a/arch/x86/include/asm/signal.h
+++ b/arch/x86/include/asm/signal.h
@@ -34,7 +34,7 @@ extern void do_signal(struct pt_regs *regs);
34 34
35#define __ARCH_HAS_SA_RESTORER 35#define __ARCH_HAS_SA_RESTORER
36 36
37#include <asm/sigcontext.h> 37#include <uapi/asm/sigcontext.h>
38 38
39#ifdef __i386__ 39#ifdef __i386__
40 40
diff --git a/arch/x86/include/uapi/asm/sigcontext.h b/arch/x86/include/uapi/asm/sigcontext.h
index 40836a9a7250..d485232f1e9f 100644
--- a/arch/x86/include/uapi/asm/sigcontext.h
+++ b/arch/x86/include/uapi/asm/sigcontext.h
@@ -1,221 +1,360 @@
1#ifndef _UAPI_ASM_X86_SIGCONTEXT_H 1#ifndef _UAPI_ASM_X86_SIGCONTEXT_H
2#define _UAPI_ASM_X86_SIGCONTEXT_H 2#define _UAPI_ASM_X86_SIGCONTEXT_H
3 3
4/*
5 * Linux signal context definitions. The sigcontext includes a complex
6 * hierarchy of CPU and FPU state, available to user-space (on the stack) when
7 * a signal handler is executed.
8 *
9 * As over the years this ABI grew from its very simple roots towards
10 * supporting more and more CPU state organically, some of the details (which
11 * were rather clever hacks back in the days) became a bit quirky by today.
12 *
13 * The current ABI includes flexible provisions for future extensions, so we
14 * won't have to grow new quirks for quite some time. Promise!
15 */
16
4#include <linux/compiler.h> 17#include <linux/compiler.h>
5#include <linux/types.h> 18#include <linux/types.h>
6 19
7#define FP_XSTATE_MAGIC1 0x46505853U 20#define FP_XSTATE_MAGIC1 0x46505853U
8#define FP_XSTATE_MAGIC2 0x46505845U 21#define FP_XSTATE_MAGIC2 0x46505845U
9#define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2) 22#define FP_XSTATE_MAGIC2_SIZE sizeof(FP_XSTATE_MAGIC2)
10 23
11/* 24/*
12 * bytes 464..511 in the current 512byte layout of fxsave/fxrstor frame 25 * Bytes 464..511 in the current 512-byte layout of the FXSAVE/FXRSTOR frame
13 * are reserved for SW usage. On cpu's supporting xsave/xrstor, these bytes 26 * are reserved for SW usage. On CPUs supporting XSAVE/XRSTOR, these bytes are
14 * are used to extended the fpstate pointer in the sigcontext, which now 27 * used to extend the fpstate pointer in the sigcontext, which now includes the
15 * includes the extended state information along with fpstate information. 28 * extended state information along with fpstate information.
29 *
30 * If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then there's a
31 * sw_reserved.extended_size bytes large extended context area present. (The
32 * last 32-bit word of this extended area (at the
33 * fpstate+extended_size-FP_XSTATE_MAGIC2_SIZE address) is set to
34 * FP_XSTATE_MAGIC2 so that you can sanity check your size calculations.)
16 * 35 *
17 * Presence of FP_XSTATE_MAGIC1 at the beginning of this SW reserved 36 * This extended area typically grows with newer CPUs that have larger and
18 * area and FP_XSTATE_MAGIC2 at the end of memory layout 37 * larger XSAVE areas.
19 * (extended_size - FP_XSTATE_MAGIC2_SIZE) indicates the presence of the
20 * extended state information in the memory layout pointed by the fpstate
21 * pointer in sigcontext.
22 */ 38 */
23struct _fpx_sw_bytes { 39struct _fpx_sw_bytes {
24 __u32 magic1; /* FP_XSTATE_MAGIC1 */ 40 /*
25 __u32 extended_size; /* total size of the layout referred by 41 * If set to FP_XSTATE_MAGIC1 then this is an xstate context.
26 * fpstate pointer in the sigcontext. 42 * 0 if a legacy frame.
27 */ 43 */
28 __u64 xfeatures; 44 __u32 magic1;
29 /* feature bit mask (including fp/sse/extended 45
30 * state) that is present in the memory 46 /*
31 * layout. 47 * Total size of the fpstate area:
32 */ 48 *
33 __u32 xstate_size; /* actual xsave state size, based on the 49 * - if magic1 == 0 then it's sizeof(struct _fpstate)
34 * features saved in the layout. 50 * - if magic1 == FP_XSTATE_MAGIC1 then it's sizeof(struct _xstate)
35 * 'extended_size' will be greater than 51 * plus extensions (if any)
36 * 'xstate_size'. 52 */
37 */ 53 __u32 extended_size;
38 __u32 padding[7]; /* for future use. */ 54
55 /*
56 * Feature bit mask (including FP/SSE/extended state) that is present
57 * in the memory layout:
58 */
59 __u64 xfeatures;
60
61 /*
62 * Actual XSAVE state size, based on the xfeatures saved in the layout.
63 * 'extended_size' is greater than 'xstate_size':
64 */
65 __u32 xstate_size;
66
67 /* For future use: */
68 __u32 padding[7];
39}; 69};
40 70
41#ifdef __i386__
42/* 71/*
43 * As documented in the iBCS2 standard.. 72 * As documented in the iBCS2 standard:
44 *
45 * The first part of "struct _fpstate" is just the normal i387
46 * hardware setup, the extra "status" word is used to save the
47 * coprocessor status word before entering the handler.
48 * 73 *
49 * Pentium III FXSR, SSE support 74 * The first part of "struct _fpstate" is just the normal i387 hardware setup,
50 * Gareth Hughes <gareth@valinux.com>, May 2000 75 * the extra "status" word is used to save the coprocessor status word before
76 * entering the handler.
51 * 77 *
52 * The FPU state data structure has had to grow to accommodate the 78 * The FPU state data structure has had to grow to accommodate the extended FPU
53 * extended FPU state required by the Streaming SIMD Extensions. 79 * state required by the Streaming SIMD Extensions. There is no documented
54 * There is no documented standard to accomplish this at the moment. 80 * standard to accomplish this at the moment.
55 */ 81 */
82
83/* 10-byte legacy floating point register: */
56struct _fpreg { 84struct _fpreg {
57 unsigned short significand[4]; 85 __u16 significand[4];
58 unsigned short exponent; 86 __u16 exponent;
59}; 87};
60 88
89/* 16-byte floating point register: */
61struct _fpxreg { 90struct _fpxreg {
62 unsigned short significand[4]; 91 __u16 significand[4];
63 unsigned short exponent; 92 __u16 exponent;
64 unsigned short padding[3]; 93 __u16 padding[3];
65}; 94};
66 95
96/* 16-byte XMM register: */
67struct _xmmreg { 97struct _xmmreg {
68 unsigned long element[4]; 98 __u32 element[4];
69}; 99};
70 100
71struct _fpstate { 101#define X86_FXSR_MAGIC 0x0000
72 /* Regular FPU environment */ 102
73 unsigned long cw; 103/*
74 unsigned long sw; 104 * The 32-bit FPU frame:
75 unsigned long tag; 105 */
76 unsigned long ipoff; 106struct _fpstate_32 {
77 unsigned long cssel; 107 /* Legacy FPU environment: */
78 unsigned long dataoff; 108 __u32 cw;
79 unsigned long datasel; 109 __u32 sw;
80 struct _fpreg _st[8]; 110 __u32 tag;
81 unsigned short status; 111 __u32 ipoff;
82 unsigned short magic; /* 0xffff = regular FPU data only */ 112 __u32 cssel;
113 __u32 dataoff;
114 __u32 datasel;
115 struct _fpreg _st[8];
116 __u16 status;
117 __u16 magic; /* 0xffff: regular FPU data only */
118 /* 0x0000: FXSR FPU data */
83 119
84 /* FXSR FPU environment */ 120 /* FXSR FPU environment */
85 unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ 121 __u32 _fxsr_env[6]; /* FXSR FPU env is ignored */
86 unsigned long mxcsr; 122 __u32 mxcsr;
87 unsigned long reserved; 123 __u32 reserved;
88 struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ 124 struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */
89 struct _xmmreg _xmm[8]; 125 struct _xmmreg _xmm[8]; /* First 8 XMM registers */
90 unsigned long padding1[44]; 126 union {
127 __u32 padding1[44]; /* Second 8 XMM registers plus padding */
128 __u32 padding[44]; /* Alias name for old user-space */
129 };
91 130
92 union { 131 union {
93 unsigned long padding2[12]; 132 __u32 padding2[12];
94 struct _fpx_sw_bytes sw_reserved; /* represents the extended 133 struct _fpx_sw_bytes sw_reserved; /* Potential extended state is encoded here */
95 * state info */
96 }; 134 };
97}; 135};
98 136
99#define X86_FXSR_MAGIC 0x0000
100
101#ifndef __KERNEL__
102/* 137/*
103 * User-space might still rely on the old definition: 138 * The 64-bit FPU frame. (FXSAVE format and later)
139 *
140 * Note1: If sw_reserved.magic1 == FP_XSTATE_MAGIC1 then the structure is
141 * larger: 'struct _xstate'. Note that 'struct _xstate' embedds
142 * 'struct _fpstate' so that you can always assume the _fpstate portion
143 * exists so that you can check the magic value.
144 *
145 * Note2: Reserved fields may someday contain valuable data. Always
146 * save/restore them when you change signal frames.
104 */ 147 */
105struct sigcontext { 148struct _fpstate_64 {
106 unsigned short gs, __gsh; 149 __u16 cwd;
107 unsigned short fs, __fsh; 150 __u16 swd;
108 unsigned short es, __esh; 151 /* Note this is not the same as the 32-bit/x87/FSAVE twd: */
109 unsigned short ds, __dsh; 152 __u16 twd;
110 unsigned long edi; 153 __u16 fop;
111 unsigned long esi; 154 __u64 rip;
112 unsigned long ebp; 155 __u64 rdp;
113 unsigned long esp; 156 __u32 mxcsr;
114 unsigned long ebx; 157 __u32 mxcsr_mask;
115 unsigned long edx; 158 __u32 st_space[32]; /* 8x FP registers, 16 bytes each */
116 unsigned long ecx; 159 __u32 xmm_space[64]; /* 16x XMM registers, 16 bytes each */
117 unsigned long eax; 160 __u32 reserved2[12];
118 unsigned long trapno;
119 unsigned long err;
120 unsigned long eip;
121 unsigned short cs, __csh;
122 unsigned long eflags;
123 unsigned long esp_at_signal;
124 unsigned short ss, __ssh;
125 struct _fpstate __user *fpstate;
126 unsigned long oldmask;
127 unsigned long cr2;
128};
129#endif /* !__KERNEL__ */
130
131#else /* __i386__ */
132
133/* FXSAVE frame */
134/* Note: reserved1/2 may someday contain valuable data. Always save/restore
135 them when you change signal frames. */
136struct _fpstate {
137 __u16 cwd;
138 __u16 swd;
139 __u16 twd; /* Note this is not the same as the
140 32bit/x87/FSAVE twd */
141 __u16 fop;
142 __u64 rip;
143 __u64 rdp;
144 __u32 mxcsr;
145 __u32 mxcsr_mask;
146 __u32 st_space[32]; /* 8*16 bytes for each FP-reg */
147 __u32 xmm_space[64]; /* 16*16 bytes for each XMM-reg */
148 __u32 reserved2[12];
149 union { 161 union {
150 __u32 reserved3[12]; 162 __u32 reserved3[12];
151 struct _fpx_sw_bytes sw_reserved; /* represents the extended 163 struct _fpx_sw_bytes sw_reserved; /* Potential extended state is encoded here */
152 * state information */
153 }; 164 };
154}; 165};
155 166
156#ifndef __KERNEL__ 167#ifdef __i386__
157/* 168# define _fpstate _fpstate_32
158 * User-space might still rely on the old definition: 169#else
159 */ 170# define _fpstate _fpstate_64
160struct sigcontext {
161 __u64 r8;
162 __u64 r9;
163 __u64 r10;
164 __u64 r11;
165 __u64 r12;
166 __u64 r13;
167 __u64 r14;
168 __u64 r15;
169 __u64 rdi;
170 __u64 rsi;
171 __u64 rbp;
172 __u64 rbx;
173 __u64 rdx;
174 __u64 rax;
175 __u64 rcx;
176 __u64 rsp;
177 __u64 rip;
178 __u64 eflags; /* RFLAGS */
179 __u16 cs;
180 __u16 gs;
181 __u16 fs;
182 __u16 __pad0;
183 __u64 err;
184 __u64 trapno;
185 __u64 oldmask;
186 __u64 cr2;
187 struct _fpstate __user *fpstate; /* zero when no FPU context */
188#ifdef __ILP32__
189 __u32 __fpstate_pad;
190#endif 171#endif
191 __u64 reserved1[8];
192};
193#endif /* !__KERNEL__ */
194
195#endif /* !__i386__ */
196 172
197struct _header { 173struct _header {
198 __u64 xfeatures; 174 __u64 xfeatures;
199 __u64 reserved1[2]; 175 __u64 reserved1[2];
200 __u64 reserved2[5]; 176 __u64 reserved2[5];
201}; 177};
202 178
203struct _ymmh_state { 179struct _ymmh_state {
204 /* 16 * 16 bytes for each YMMH-reg */ 180 /* 16x YMM registers, 16 bytes each: */
205 __u32 ymmh_space[64]; 181 __u32 ymmh_space[64];
206}; 182};
207 183
208/* 184/*
209 * Extended state pointed by the fpstate pointer in the sigcontext. 185 * Extended state pointed to by sigcontext::fpstate.
210 * In addition to the fpstate, information encoded in the xstate_hdr 186 *
211 * indicates the presence of other extended state information 187 * In addition to the fpstate, information encoded in _xstate::xstate_hdr
212 * supported by the processor and OS. 188 * indicates the presence of other extended state information supported
189 * by the CPU and kernel:
213 */ 190 */
214struct _xstate { 191struct _xstate {
215 struct _fpstate fpstate; 192 struct _fpstate fpstate;
216 struct _header xstate_hdr; 193 struct _header xstate_hdr;
217 struct _ymmh_state ymmh; 194 struct _ymmh_state ymmh;
218 /* new processor state extensions go here */ 195 /* New processor state extensions go here: */
196};
197
198/*
199 * The 32-bit signal frame:
200 */
201struct sigcontext_32 {
202 __u16 gs, __gsh;
203 __u16 fs, __fsh;
204 __u16 es, __esh;
205 __u16 ds, __dsh;
206 __u32 di;
207 __u32 si;
208 __u32 bp;
209 __u32 sp;
210 __u32 bx;
211 __u32 dx;
212 __u32 cx;
213 __u32 ax;
214 __u32 trapno;
215 __u32 err;
216 __u32 ip;
217 __u16 cs, __csh;
218 __u32 flags;
219 __u32 sp_at_signal;
220 __u16 ss, __ssh;
221
222 /*
223 * fpstate is really (struct _fpstate *) or (struct _xstate *)
224 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
225 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
226 * of extended memory layout. See comments at the definition of
227 * (struct _fpx_sw_bytes)
228 */
229 __u32 fpstate; /* Zero when no FPU/extended context */
230 __u32 oldmask;
231 __u32 cr2;
232};
233
234/*
235 * The 64-bit signal frame:
236 */
237struct sigcontext_64 {
238 __u64 r8;
239 __u64 r9;
240 __u64 r10;
241 __u64 r11;
242 __u64 r12;
243 __u64 r13;
244 __u64 r14;
245 __u64 r15;
246 __u64 di;
247 __u64 si;
248 __u64 bp;
249 __u64 bx;
250 __u64 dx;
251 __u64 ax;
252 __u64 cx;
253 __u64 sp;
254 __u64 ip;
255 __u64 flags;
256 __u16 cs;
257 __u16 gs;
258 __u16 fs;
259 __u16 __pad0;
260 __u64 err;
261 __u64 trapno;
262 __u64 oldmask;
263 __u64 cr2;
264
265 /*
266 * fpstate is really (struct _fpstate *) or (struct _xstate *)
267 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
268 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
269 * of extended memory layout. See comments at the definition of
270 * (struct _fpx_sw_bytes)
271 */
272 __u64 fpstate; /* Zero when no FPU/extended context */
273 __u64 reserved1[8];
274};
275
276/*
277 * Create the real 'struct sigcontext' type:
278 */
279#ifdef __KERNEL__
280# ifdef __i386__
281# define sigcontext sigcontext_32
282# else
283# define sigcontext sigcontext_64
284# endif
285#endif
286
287/*
288 * The old user-space sigcontext definition, just in case user-space still
289 * relies on it. The kernel definition (in asm/sigcontext.h) has unified
290 * field names but otherwise the same layout.
291 */
292#ifndef __KERNEL__
293
294#define _fpstate_ia32 _fpstate_32
295#define sigcontext_ia32 sigcontext_32
296
297
298# ifdef __i386__
299struct sigcontext {
300 __u16 gs, __gsh;
301 __u16 fs, __fsh;
302 __u16 es, __esh;
303 __u16 ds, __dsh;
304 __u32 edi;
305 __u32 esi;
306 __u32 ebp;
307 __u32 esp;
308 __u32 ebx;
309 __u32 edx;
310 __u32 ecx;
311 __u32 eax;
312 __u32 trapno;
313 __u32 err;
314 __u32 eip;
315 __u16 cs, __csh;
316 __u32 eflags;
317 __u32 esp_at_signal;
318 __u16 ss, __ssh;
319 struct _fpstate __user *fpstate;
320 __u32 oldmask;
321 __u32 cr2;
219}; 322};
323# else /* __x86_64__: */
324struct sigcontext {
325 __u64 r8;
326 __u64 r9;
327 __u64 r10;
328 __u64 r11;
329 __u64 r12;
330 __u64 r13;
331 __u64 r14;
332 __u64 r15;
333 __u64 rdi;
334 __u64 rsi;
335 __u64 rbp;
336 __u64 rbx;
337 __u64 rdx;
338 __u64 rax;
339 __u64 rcx;
340 __u64 rsp;
341 __u64 rip;
342 __u64 eflags; /* RFLAGS */
343 __u16 cs;
344 __u16 gs;
345 __u16 fs;
346 __u16 __pad0;
347 __u64 err;
348 __u64 trapno;
349 __u64 oldmask;
350 __u64 cr2;
351 struct _fpstate __user *fpstate; /* Zero when no FPU context */
352# ifdef __ILP32__
353 __u32 __fpstate_pad;
354# endif
355 __u64 reserved1[8];
356};
357# endif /* __x86_64__ */
358#endif /* !__KERNEL__ */
220 359
221#endif /* _UAPI_ASM_X86_SIGCONTEXT_H */ 360#endif /* _UAPI_ASM_X86_SIGCONTEXT_H */
diff --git a/arch/x86/include/uapi/asm/sigcontext32.h b/arch/x86/include/uapi/asm/sigcontext32.h
index ad1478c4ae12..a92b0f0dc09e 100644
--- a/arch/x86/include/uapi/asm/sigcontext32.h
+++ b/arch/x86/include/uapi/asm/sigcontext32.h
@@ -1,77 +1,8 @@
1#ifndef _ASM_X86_SIGCONTEXT32_H 1#ifndef _ASM_X86_SIGCONTEXT32_H
2#define _ASM_X86_SIGCONTEXT32_H 2#define _ASM_X86_SIGCONTEXT32_H
3 3
4#include <linux/types.h> 4/* This is a legacy file - all the type definitions are in sigcontext.h: */
5 5
6/* signal context for 32bit programs. */ 6#include <asm/sigcontext.h>
7
8#define X86_FXSR_MAGIC 0x0000
9
10struct _fpreg {
11 unsigned short significand[4];
12 unsigned short exponent;
13};
14
15struct _fpxreg {
16 unsigned short significand[4];
17 unsigned short exponent;
18 unsigned short padding[3];
19};
20
21struct _xmmreg {
22 __u32 element[4];
23};
24
25/* FSAVE frame with extensions */
26struct _fpstate_ia32 {
27 /* Regular FPU environment */
28 __u32 cw;
29 __u32 sw;
30 __u32 tag; /* not compatible to 64bit twd */
31 __u32 ipoff;
32 __u32 cssel;
33 __u32 dataoff;
34 __u32 datasel;
35 struct _fpreg _st[8];
36 unsigned short status;
37 unsigned short magic; /* 0xffff = regular FPU data only */
38
39 /* FXSR FPU environment */
40 __u32 _fxsr_env[6];
41 __u32 mxcsr;
42 __u32 reserved;
43 struct _fpxreg _fxsr_st[8];
44 struct _xmmreg _xmm[8]; /* It's actually 16 */
45 __u32 padding[44];
46 union {
47 __u32 padding2[12];
48 struct _fpx_sw_bytes sw_reserved;
49 };
50};
51
52struct sigcontext_ia32 {
53 unsigned short gs, __gsh;
54 unsigned short fs, __fsh;
55 unsigned short es, __esh;
56 unsigned short ds, __dsh;
57 unsigned int di;
58 unsigned int si;
59 unsigned int bp;
60 unsigned int sp;
61 unsigned int bx;
62 unsigned int dx;
63 unsigned int cx;
64 unsigned int ax;
65 unsigned int trapno;
66 unsigned int err;
67 unsigned int ip;
68 unsigned short cs, __csh;
69 unsigned int flags;
70 unsigned int sp_at_signal;
71 unsigned short ss, __ssh;
72 unsigned int fpstate; /* really (struct _fpstate_ia32 *) */
73 unsigned int oldmask;
74 unsigned int cr2;
75};
76 7
77#endif /* _ASM_X86_SIGCONTEXT32_H */ 8#endif /* _ASM_X86_SIGCONTEXT32_H */
diff --git a/arch/x86/kernel/asm-offsets.c b/arch/x86/kernel/asm-offsets.c
index 95a18e25d5bf..439df975bc7a 100644
--- a/arch/x86/kernel/asm-offsets.c
+++ b/arch/x86/kernel/asm-offsets.c
@@ -43,15 +43,15 @@ void common(void) {
43 43
44#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION) 44#if defined(CONFIG_X86_32) || defined(CONFIG_IA32_EMULATION)
45 BLANK(); 45 BLANK();
46 OFFSET(IA32_SIGCONTEXT_ax, sigcontext_ia32, ax); 46 OFFSET(IA32_SIGCONTEXT_ax, sigcontext_32, ax);
47 OFFSET(IA32_SIGCONTEXT_bx, sigcontext_ia32, bx); 47 OFFSET(IA32_SIGCONTEXT_bx, sigcontext_32, bx);
48 OFFSET(IA32_SIGCONTEXT_cx, sigcontext_ia32, cx); 48 OFFSET(IA32_SIGCONTEXT_cx, sigcontext_32, cx);
49 OFFSET(IA32_SIGCONTEXT_dx, sigcontext_ia32, dx); 49 OFFSET(IA32_SIGCONTEXT_dx, sigcontext_32, dx);
50 OFFSET(IA32_SIGCONTEXT_si, sigcontext_ia32, si); 50 OFFSET(IA32_SIGCONTEXT_si, sigcontext_32, si);
51 OFFSET(IA32_SIGCONTEXT_di, sigcontext_ia32, di); 51 OFFSET(IA32_SIGCONTEXT_di, sigcontext_32, di);
52 OFFSET(IA32_SIGCONTEXT_bp, sigcontext_ia32, bp); 52 OFFSET(IA32_SIGCONTEXT_bp, sigcontext_32, bp);
53 OFFSET(IA32_SIGCONTEXT_sp, sigcontext_ia32, sp); 53 OFFSET(IA32_SIGCONTEXT_sp, sigcontext_32, sp);
54 OFFSET(IA32_SIGCONTEXT_ip, sigcontext_ia32, ip); 54 OFFSET(IA32_SIGCONTEXT_ip, sigcontext_32, ip);
55 55
56 BLANK(); 56 BLANK();
57 OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext); 57 OFFSET(IA32_RT_SIGFRAME_sigcontext, rt_sigframe_ia32, uc.uc_mcontext);
diff --git a/arch/x86/kernel/fpu/signal.c b/arch/x86/kernel/fpu/signal.c
index eb032677f939..ef29b742cea7 100644
--- a/arch/x86/kernel/fpu/signal.c
+++ b/arch/x86/kernel/fpu/signal.c
@@ -56,7 +56,7 @@ static inline int save_fsave_header(struct task_struct *tsk, void __user *buf)
56 if (use_fxsr()) { 56 if (use_fxsr()) {
57 struct xregs_state *xsave = &tsk->thread.fpu.state.xsave; 57 struct xregs_state *xsave = &tsk->thread.fpu.state.xsave;
58 struct user_i387_ia32_struct env; 58 struct user_i387_ia32_struct env;
59 struct _fpstate_ia32 __user *fp = buf; 59 struct _fpstate_32 __user *fp = buf;
60 60
61 convert_from_fxsr(&env, tsk); 61 convert_from_fxsr(&env, tsk);
62 62
@@ -165,7 +165,7 @@ int copy_fpstate_to_sigframe(void __user *buf, void __user *buf_fx, int size)
165 if (!static_cpu_has(X86_FEATURE_FPU)) 165 if (!static_cpu_has(X86_FEATURE_FPU))
166 return fpregs_soft_get(current, NULL, 0, 166 return fpregs_soft_get(current, NULL, 0,
167 sizeof(struct user_i387_ia32_struct), NULL, 167 sizeof(struct user_i387_ia32_struct), NULL,
168 (struct _fpstate_ia32 __user *) buf) ? -1 : 1; 168 (struct _fpstate_32 __user *) buf) ? -1 : 1;
169 169
170 if (fpregs_active()) { 170 if (fpregs_active()) {
171 /* Save the live register state to the user directly. */ 171 /* Save the live register state to the user directly. */
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 32165d649979..b7ffb7c00075 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -63,6 +63,7 @@
63 63
64int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) 64int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
65{ 65{
66 unsigned long buf_val;
66 void __user *buf; 67 void __user *buf;
67 unsigned int tmpflags; 68 unsigned int tmpflags;
68 unsigned int err = 0; 69 unsigned int err = 0;
@@ -107,7 +108,8 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
107 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); 108 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
108 regs->orig_ax = -1; /* disable syscall checks */ 109 regs->orig_ax = -1; /* disable syscall checks */
109 110
110 get_user_ex(buf, &sc->fpstate); 111 get_user_ex(buf_val, &sc->fpstate);
112 buf = (void __user *)buf_val;
111 } get_user_catch(err); 113 } get_user_catch(err);
112 114
113 err |= fpu__restore_sig(buf, config_enabled(CONFIG_X86_32)); 115 err |= fpu__restore_sig(buf, config_enabled(CONFIG_X86_32));
diff --git a/arch/x86/math-emu/fpu_emu.h b/arch/x86/math-emu/fpu_emu.h
index 4dae511c85ad..afbc4d805d66 100644
--- a/arch/x86/math-emu/fpu_emu.h
+++ b/arch/x86/math-emu/fpu_emu.h
@@ -71,7 +71,7 @@
71 71
72#include "fpu_system.h" 72#include "fpu_system.h"
73 73
74#include <asm/sigcontext.h> /* for struct _fpstate */ 74#include <uapi/asm/sigcontext.h> /* for struct _fpstate */
75#include <asm/math_emu.h> 75#include <asm/math_emu.h>
76#include <linux/linkage.h> 76#include <linux/linkage.h>
77 77