[PATCH] x86_64: Fix 32bit thread coredumps
[linux-2.6] / include / asm-i386 / i387.h
1 /*
2  * include/asm-i386/i387.h
3  *
4  * Copyright (C) 1994 Linus Torvalds
5  *
6  * Pentium III FXSR, SSE support
7  * General FPU state handling cleanups
8  *      Gareth Hughes <gareth@valinux.com>, May 2000
9  */
10
11 #ifndef __ASM_I386_I387_H
12 #define __ASM_I386_I387_H
13
14 #include <linux/sched.h>
15 #include <linux/init.h>
16 #include <asm/processor.h>
17 #include <asm/sigcontext.h>
18 #include <asm/user.h>
19
20 extern void mxcsr_feature_mask_init(void);
21 extern void init_fpu(struct task_struct *);
22
23 /*
24  * FPU lazy state save handling...
25  */
26
27 /*
28  * The "nop" is needed to make the instructions the same
29  * length.
30  */
31 #define restore_fpu(tsk)                        \
32         alternative_input(                      \
33                 "nop ; frstor %1",              \
34                 "fxrstor %1",                   \
35                 X86_FEATURE_FXSR,               \
36                 "m" ((tsk)->thread.i387.fxsave))
37
38 extern void kernel_fpu_begin(void);
39 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
40
41 /*
42  * These must be called with preempt disabled
43  */
44 static inline void __save_init_fpu( struct task_struct *tsk )
45 {
46         alternative_input(
47                 "fnsave %1 ; fwait ;" GENERIC_NOP2,
48                 "fxsave %1 ; fnclex",
49                 X86_FEATURE_FXSR,
50                 "m" (tsk->thread.i387.fxsave)
51                 :"memory");
52         tsk->thread_info->status &= ~TS_USEDFPU;
53 }
54
55 #define __unlazy_fpu( tsk ) do { \
56         if ((tsk)->thread_info->status & TS_USEDFPU) \
57                 save_init_fpu( tsk ); \
58 } while (0)
59
60 #define __clear_fpu( tsk )                                      \
61 do {                                                            \
62         if ((tsk)->thread_info->status & TS_USEDFPU) {          \
63                 asm volatile("fnclex ; fwait");                         \
64                 (tsk)->thread_info->status &= ~TS_USEDFPU;      \
65                 stts();                                         \
66         }                                                       \
67 } while (0)
68
69
70 /*
71  * These disable preemption on their own and are safe
72  */
73 static inline void save_init_fpu( struct task_struct *tsk )
74 {
75         preempt_disable();
76         __save_init_fpu(tsk);
77         stts();
78         preempt_enable();
79 }
80
81 #define unlazy_fpu( tsk ) do {  \
82         preempt_disable();      \
83         __unlazy_fpu(tsk);      \
84         preempt_enable();       \
85 } while (0)
86
87 #define clear_fpu( tsk ) do {   \
88         preempt_disable();      \
89         __clear_fpu( tsk );     \
90         preempt_enable();       \
91 } while (0)
92                                         \
93 /*
94  * FPU state interaction...
95  */
96 extern unsigned short get_fpu_cwd( struct task_struct *tsk );
97 extern unsigned short get_fpu_swd( struct task_struct *tsk );
98 extern unsigned short get_fpu_mxcsr( struct task_struct *tsk );
99
100 /*
101  * Signal frame handlers...
102  */
103 extern int save_i387( struct _fpstate __user *buf );
104 extern int restore_i387( struct _fpstate __user *buf );
105
106 /*
107  * ptrace request handers...
108  */
109 extern int get_fpregs( struct user_i387_struct __user *buf,
110                        struct task_struct *tsk );
111 extern int set_fpregs( struct task_struct *tsk,
112                        struct user_i387_struct __user *buf );
113
114 extern int get_fpxregs( struct user_fxsr_struct __user *buf,
115                         struct task_struct *tsk );
116 extern int set_fpxregs( struct task_struct *tsk,
117                         struct user_fxsr_struct __user *buf );
118
119 /*
120  * FPU state for core dumps...
121  */
122 extern int dump_fpu( struct pt_regs *regs,
123                      struct user_i387_struct *fpu );
124
125 #endif /* __ASM_I386_I387_H */