|
Lines 13-18
Link Here
|
| 13 |
|
13 |
|
| 14 |
#include <linux/sched.h> |
14 |
#include <linux/sched.h> |
| 15 |
#include <linux/init.h> |
15 |
#include <linux/init.h> |
|
|
16 |
#include <linux/kernel_stat.h> |
| 16 |
#include <asm/processor.h> |
17 |
#include <asm/processor.h> |
| 17 |
#include <asm/sigcontext.h> |
18 |
#include <asm/sigcontext.h> |
| 18 |
#include <asm/user.h> |
19 |
#include <asm/user.h> |
|
Lines 38-54
extern void init_fpu(struct task_struct
Link Here
|
| 38 |
extern void kernel_fpu_begin(void); |
39 |
extern void kernel_fpu_begin(void); |
| 39 |
#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) |
40 |
#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) |
| 40 |
|
41 |
|
|
|
42 |
/* We need a safe address that is cheap to find and that is already |
| 43 |
in L1 during context switch. The best choices are unfortunately |
| 44 |
different for UP and SMP */ |
| 45 |
#ifdef CONFIG_SMP |
| 46 |
#define safe_address (__per_cpu_offset[0]) |
| 47 |
#else |
| 48 |
#define safe_address (kstat_cpu(0).cpustat.user) |
| 49 |
#endif |
| 50 |
|
| 41 |
/* |
51 |
/* |
| 42 |
* These must be called with preempt disabled |
52 |
* These must be called with preempt disabled |
| 43 |
*/ |
53 |
*/ |
| 44 |
static inline void __save_init_fpu( struct task_struct *tsk ) |
54 |
static inline void __save_init_fpu( struct task_struct *tsk ) |
| 45 |
{ |
55 |
{ |
|
|
56 |
/* Use more nops than strictly needed in case the compiler |
| 57 |
varies code */ |
| 46 |
alternative_input( |
58 |
alternative_input( |
| 47 |
"fnsave %1 ; fwait ;" GENERIC_NOP2, |
59 |
"fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, |
| 48 |
"fxsave %1 ; fnclex", |
60 |
"fxsave %[fx]\n" |
|
|
61 |
"bt $7,%[fsw] ; jc 1f ; fnclex\n1:", |
| 49 |
X86_FEATURE_FXSR, |
62 |
X86_FEATURE_FXSR, |
| 50 |
"m" (tsk->thread.i387.fxsave) |
63 |
[fx] "m" (tsk->thread.i387.fxsave), |
| 51 |
:"memory"); |
64 |
[fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); |
|
|
65 |
/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception |
| 66 |
is pending. Clear the x87 state here by setting it to fixed |
| 67 |
values. __per_cpu_offset[0] is a random variable that should be in L1 |
| 68 |
alternative_input( |
| 69 |
GENERIC_NOP8 GENERIC_NOP2, |
| 70 |
"emms\n\t" /* clear stack tags */ |
| 71 |
"fildl %[addr]", /* set F?P to defined value */ |
| 72 |
X86_FEATURE_FXSAVE_LEAK, |
| 73 |
[addr] "m" (safe_address)); |
| 52 |
task_thread_info(tsk)->status &= ~TS_USEDFPU; |
74 |
task_thread_info(tsk)->status &= ~TS_USEDFPU; |
| 53 |
} |
75 |
} |
| 54 |
|
76 |
|