1 #ifndef _ASM_X86_SIGCONTEXT_H
2 #define _ASM_X86_SIGCONTEXT_H
3 
4 #include <linux/compiler.h>
5 #include <linux/types.h>
6 
7 #define FP_XSTATE_MAGIC1	0x46505853U
8 #define FP_XSTATE_MAGIC2	0x46505845U
9 #define FP_XSTATE_MAGIC2_SIZE	sizeof(FP_XSTATE_MAGIC2)
10 
11 /*
12  * bytes 464..511 in the current 512byte layout of fxsave/fxrstor frame
13  * are reserved for SW usage. On cpu's supporting xsave/xrstor, these bytes
14  * are used to extended the fpstate pointer in the sigcontext, which now
15  * includes the extended state information along with fpstate information.
16  *
17  * Presence of FP_XSTATE_MAGIC1 at the beginning of this SW reserved
18  * area and FP_XSTATE_MAGIC2 at the end of memory layout
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  */
23 struct _fpx_sw_bytes {
24 	__u32 magic1;		/* FP_XSTATE_MAGIC1 */
25 	__u32 extended_size;	/* total size of the layout referred by
26 				 * fpstate pointer in the sigcontext.
27 				 */
28 	__u64 xstate_bv;
29 				/* feature bit mask (including fp/sse/extended
30 				 * state) that is present in the memory
31 				 * layout.
32 				 */
33 	__u32 xstate_size;	/* actual xsave state size, based on the
34 				 * features saved in the layout.
35 				 * 'extended_size' will be greater than
36 				 * 'xstate_size'.
37 				 */
38 	__u32 padding[7];	/*  for future use. */
39 };
40 
41 #ifdef __i386__
42 /*
43  * 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  *
49  * Pentium III FXSR, SSE support
50  *	Gareth Hughes <gareth@valinux.com>, May 2000
51  *
52  * The FPU state data structure has had to grow to accommodate the
53  * extended FPU state required by the Streaming SIMD Extensions.
54  * There is no documented standard to accomplish this at the moment.
55  */
56 struct _fpreg {
57 	unsigned short significand[4];
58 	unsigned short exponent;
59 };
60 
61 struct _fpxreg {
62 	unsigned short significand[4];
63 	unsigned short exponent;
64 	unsigned short padding[3];
65 };
66 
67 struct _xmmreg {
68 	unsigned long element[4];
69 };
70 
71 struct _fpstate {
72 	/* Regular FPU environment */
73 	unsigned long	cw;
74 	unsigned long	sw;
75 	unsigned long	tag;
76 	unsigned long	ipoff;
77 	unsigned long	cssel;
78 	unsigned long	dataoff;
79 	unsigned long	datasel;
80 	struct _fpreg	_st[8];
81 	unsigned short	status;
82 	unsigned short	magic;		/* 0xffff = regular FPU data only */
83 
84 	/* FXSR FPU environment */
85 	unsigned long	_fxsr_env[6];	/* FXSR FPU env is ignored */
86 	unsigned long	mxcsr;
87 	unsigned long	reserved;
88 	struct _fpxreg	_fxsr_st[8];	/* FXSR FPU reg data is ignored */
89 	struct _xmmreg	_xmm[8];
90 	unsigned long	padding1[44];
91 
92 	union {
93 		unsigned long	padding2[12];
94 		struct _fpx_sw_bytes sw_reserved; /* represents the extended
95 						   * state info */
96 	};
97 };
98 
99 #define X86_FXSR_MAGIC		0x0000
100 
101 #ifdef __KERNEL__
102 struct sigcontext {
103 	unsigned short gs, __gsh;
104 	unsigned short fs, __fsh;
105 	unsigned short es, __esh;
106 	unsigned short ds, __dsh;
107 	unsigned long di;
108 	unsigned long si;
109 	unsigned long bp;
110 	unsigned long sp;
111 	unsigned long bx;
112 	unsigned long dx;
113 	unsigned long cx;
114 	unsigned long ax;
115 	unsigned long trapno;
116 	unsigned long err;
117 	unsigned long ip;
118 	unsigned short cs, __csh;
119 	unsigned long flags;
120 	unsigned long sp_at_signal;
121 	unsigned short ss, __ssh;
122 
123 	/*
124 	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
125 	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
126 	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
127 	 * of extended memory layout. See comments at the definition of
128 	 * (struct _fpx_sw_bytes)
129 	 */
130 	void __user *fpstate;		/* zero when no FPU/extended context */
131 	unsigned long oldmask;
132 	unsigned long cr2;
133 };
134 #else /* __KERNEL__ */
135 /*
136  * User-space might still rely on the old definition:
137  */
138 struct sigcontext {
139 	unsigned short gs, __gsh;
140 	unsigned short fs, __fsh;
141 	unsigned short es, __esh;
142 	unsigned short ds, __dsh;
143 	unsigned long edi;
144 	unsigned long esi;
145 	unsigned long ebp;
146 	unsigned long esp;
147 	unsigned long ebx;
148 	unsigned long edx;
149 	unsigned long ecx;
150 	unsigned long eax;
151 	unsigned long trapno;
152 	unsigned long err;
153 	unsigned long eip;
154 	unsigned short cs, __csh;
155 	unsigned long eflags;
156 	unsigned long esp_at_signal;
157 	unsigned short ss, __ssh;
158 	struct _fpstate __user *fpstate;
159 	unsigned long oldmask;
160 	unsigned long cr2;
161 };
162 #endif /* !__KERNEL__ */
163 
164 #else /* __i386__ */
165 
166 /* FXSAVE frame */
167 /* Note: reserved1/2 may someday contain valuable data. Always save/restore
168    them when you change signal frames. */
169 struct _fpstate {
170 	__u16	cwd;
171 	__u16	swd;
172 	__u16	twd;		/* Note this is not the same as the
173 				   32bit/x87/FSAVE twd */
174 	__u16	fop;
175 	__u64	rip;
176 	__u64	rdp;
177 	__u32	mxcsr;
178 	__u32	mxcsr_mask;
179 	__u32	st_space[32];	/* 8*16 bytes for each FP-reg */
180 	__u32	xmm_space[64];	/* 16*16 bytes for each XMM-reg  */
181 	__u32	reserved2[12];
182 	union {
183 		__u32	reserved3[12];
184 		struct _fpx_sw_bytes sw_reserved; /* represents the extended
185 						   * state information */
186 	};
187 };
188 
189 #ifdef __KERNEL__
190 struct sigcontext {
191 	unsigned long r8;
192 	unsigned long r9;
193 	unsigned long r10;
194 	unsigned long r11;
195 	unsigned long r12;
196 	unsigned long r13;
197 	unsigned long r14;
198 	unsigned long r15;
199 	unsigned long di;
200 	unsigned long si;
201 	unsigned long bp;
202 	unsigned long bx;
203 	unsigned long dx;
204 	unsigned long ax;
205 	unsigned long cx;
206 	unsigned long sp;
207 	unsigned long ip;
208 	unsigned long flags;
209 	unsigned short cs;
210 	unsigned short gs;
211 	unsigned short fs;
212 	unsigned short __pad0;
213 	unsigned long err;
214 	unsigned long trapno;
215 	unsigned long oldmask;
216 	unsigned long cr2;
217 
218 	/*
219 	 * fpstate is really (struct _fpstate *) or (struct _xstate *)
220 	 * depending on the FP_XSTATE_MAGIC1 encoded in the SW reserved
221 	 * bytes of (struct _fpstate) and FP_XSTATE_MAGIC2 present at the end
222 	 * of extended memory layout. See comments at the definition of
223 	 * (struct _fpx_sw_bytes)
224 	 */
225 	void __user *fpstate;		/* zero when no FPU/extended context */
226 	unsigned long reserved1[8];
227 };
228 #else /* __KERNEL__ */
229 /*
230  * User-space might still rely on the old definition:
231  */
232 struct sigcontext {
233 	__u64 r8;
234 	__u64 r9;
235 	__u64 r10;
236 	__u64 r11;
237 	__u64 r12;
238 	__u64 r13;
239 	__u64 r14;
240 	__u64 r15;
241 	__u64 rdi;
242 	__u64 rsi;
243 	__u64 rbp;
244 	__u64 rbx;
245 	__u64 rdx;
246 	__u64 rax;
247 	__u64 rcx;
248 	__u64 rsp;
249 	__u64 rip;
250 	__u64 eflags;		/* RFLAGS */
251 	__u16 cs;
252 	__u16 gs;
253 	__u16 fs;
254 	__u16 __pad0;
255 	__u64 err;
256 	__u64 trapno;
257 	__u64 oldmask;
258 	__u64 cr2;
259 	struct _fpstate __user *fpstate;	/* zero when no FPU context */
260 #ifdef __ILP32__
261 	__u32 __fpstate_pad;
262 #endif
263 	__u64 reserved1[8];
264 };
265 #endif /* !__KERNEL__ */
266 
267 #endif /* !__i386__ */
268 
269 struct _xsave_hdr {
270 	__u64 xstate_bv;
271 	__u64 reserved1[2];
272 	__u64 reserved2[5];
273 };
274 
275 struct _ymmh_state {
276 	/* 16 * 16 bytes for each YMMH-reg */
277 	__u32 ymmh_space[64];
278 };
279 
280 /*
281  * Extended state pointed by the fpstate pointer in the sigcontext.
282  * In addition to the fpstate, information encoded in the xstate_hdr
283  * indicates the presence of other extended state information
284  * supported by the processor and OS.
285  */
286 struct _xstate {
287 	struct _fpstate fpstate;
288 	struct _xsave_hdr xstate_hdr;
289 	struct _ymmh_state ymmh;
290 	/* new processor state extensions go here */
291 };
292 
293 #endif /* _ASM_X86_SIGCONTEXT_H */
294