/[linux-patches]/genpatches-2.6/trunk/2.6.16/1008_linux-2.6.16.9.patch
Gentoo

Contents of /genpatches-2.6/trunk/2.6.16/1008_linux-2.6.16.9.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 415 - (show annotations) (download) (as text)
Wed Apr 19 09:29:21 2006 UTC (14 years, 7 months ago) by johnm
File MIME type: text/x-diff
File size: 6489 byte(s)
apply 2.6.16.9
1 diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
2 index 0810f81..d2d50cb 100644
3 --- a/arch/i386/kernel/cpu/amd.c
4 +++ b/arch/i386/kernel/cpu/amd.c
5 @@ -207,6 +207,8 @@ #define CBAR_KEY (0X000000CB)
6 set_bit(X86_FEATURE_K7, c->x86_capability);
7 break;
8 }
9 + if (c->x86 >= 6)
10 + set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability);
11
12 display_cacheinfo(c);
13
14 diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
15 index 22a05de..818ab9e 100644
16 --- a/arch/x86_64/kernel/process.c
17 +++ b/arch/x86_64/kernel/process.c
18 @@ -527,8 +527,6 @@ __switch_to(struct task_struct *prev_p,
19 int cpu = smp_processor_id();
20 struct tss_struct *tss = &per_cpu(init_tss, cpu);
21
22 - unlazy_fpu(prev_p);
23 -
24 /*
25 * Reload esp0, LDT and the page table pointer:
26 */
27 @@ -591,6 +589,12 @@ __switch_to(struct task_struct *prev_p,
28 prev->userrsp = read_pda(oldrsp);
29 write_pda(oldrsp, next->userrsp);
30 write_pda(pcurrent, next_p);
31 +
32 + /* This must be here to ensure both math_state_restore() and
33 + kernel_fpu_begin() work consistently.
34 + And the AMD workaround requires it to be after DS reload. */
35 + unlazy_fpu(prev_p);
36 +
37 write_pda(kernelstack,
38 task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
39
40 diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
41 index aa55e3c..a4a0bb5 100644
42 --- a/arch/x86_64/kernel/setup.c
43 +++ b/arch/x86_64/kernel/setup.c
44 @@ -909,6 +909,10 @@ #endif
45 if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
46 set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
47
48 + /* Enable workaround for FXSAVE leak */
49 + if (c->x86 >= 6)
50 + set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
51 +
52 r = get_model_name(c);
53 if (!r) {
54 switch (c->x86) {
55 diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h
56 index c4ec2a4..9d15eec 100644
57 --- a/include/asm-i386/cpufeature.h
58 +++ b/include/asm-i386/cpufeature.h
59 @@ -70,6 +70,7 @@ #define X86_FEATURE_K7 (3*32+ 5) /* Ath
60 #define X86_FEATURE_P3 (3*32+ 6) /* P3 */
61 #define X86_FEATURE_P4 (3*32+ 7) /* P4 */
62 #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
63 +#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */
64
65 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
66 #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
67 diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
68 index 152d0ba..7b1f011 100644
69 --- a/include/asm-i386/i387.h
70 +++ b/include/asm-i386/i387.h
71 @@ -13,6 +13,7 @@ #define __ASM_I386_I387_H
72
73 #include <linux/sched.h>
74 #include <linux/init.h>
75 +#include <linux/kernel_stat.h>
76 #include <asm/processor.h>
77 #include <asm/sigcontext.h>
78 #include <asm/user.h>
79 @@ -38,17 +39,38 @@ #define restore_fpu(tsk) \
80 extern void kernel_fpu_begin(void);
81 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
82
83 +/* We need a safe address that is cheap to find and that is already
84 + in L1 during context switch. The best choices are unfortunately
85 + different for UP and SMP */
86 +#ifdef CONFIG_SMP
87 +#define safe_address (__per_cpu_offset[0])
88 +#else
89 +#define safe_address (kstat_cpu(0).cpustat.user)
90 +#endif
91 +
92 /*
93 * These must be called with preempt disabled
94 */
95 static inline void __save_init_fpu( struct task_struct *tsk )
96 {
97 + /* Use more nops than strictly needed in case the compiler
98 + varies code */
99 alternative_input(
100 - "fnsave %1 ; fwait ;" GENERIC_NOP2,
101 - "fxsave %1 ; fnclex",
102 + "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
103 + "fxsave %[fx]\n"
104 + "bt $7,%[fsw] ; jc 1f ; fnclex\n1:",
105 X86_FEATURE_FXSR,
106 - "m" (tsk->thread.i387.fxsave)
107 - :"memory");
108 + [fx] "m" (tsk->thread.i387.fxsave),
109 + [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
110 + /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
111 + is pending. Clear the x87 state here by setting it to fixed
112 + values. __per_cpu_offset[0] is a random variable that should be in L1 */
113 + alternative_input(
114 + GENERIC_NOP8 GENERIC_NOP2,
115 + "emms\n\t" /* clear stack tags */
116 + "fildl %[addr]", /* set F?P to defined value */
117 + X86_FEATURE_FXSAVE_LEAK,
118 + [addr] "m" (safe_address));
119 task_thread_info(tsk)->status &= ~TS_USEDFPU;
120 }
121
122 diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h
123 index 76bb619..662964b 100644
124 --- a/include/asm-x86_64/cpufeature.h
125 +++ b/include/asm-x86_64/cpufeature.h
126 @@ -64,6 +64,7 @@ #define X86_FEATURE_CENTAUR_MCR (3*32+ 3
127 #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */
128 #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
129 #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */
130 +#define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */
131
132 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
133 #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */
134 diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h
135 index 876eb9a..cba8a3b 100644
136 --- a/include/asm-x86_64/i387.h
137 +++ b/include/asm-x86_64/i387.h
138 @@ -72,6 +72,23 @@ #define set_fpu_cwd(t,val) ((t)->thread.
139 #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
140 #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
141
142 +#define X87_FSW_ES (1 << 7) /* Exception Summary */
143 +
144 +/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
145 + is pending. Clear the x87 state here by setting it to fixed
146 + values. The kernel data segment can be sometimes 0 and sometimes
147 + new user value. Both should be ok.
148 + Use the PDA as safe address because it should be already in L1. */
149 +static inline void clear_fpu_state(struct i387_fxsave_struct *fx)
150 +{
151 + if (unlikely(fx->swd & X87_FSW_ES))
152 + asm volatile("fnclex");
153 + alternative_input(ASM_NOP8 ASM_NOP2,
154 + " emms\n" /* clear stack tags */
155 + " fildl %%gs:0", /* load to clear state */
156 + X86_FEATURE_FXSAVE_LEAK);
157 +}
158 +
159 static inline int restore_fpu_checking(struct i387_fxsave_struct *fx)
160 {
161 int err;
162 @@ -119,6 +136,7 @@ #else
163 #endif
164 if (unlikely(err))
165 __clear_user(fx, sizeof(struct i387_fxsave_struct));
166 + /* No need to clear here because the caller clears USED_MATH */
167 return err;
168 }
169
170 @@ -149,7 +167,7 @@ #else
171 "i" (offsetof(__typeof__(*tsk),
172 thread.i387.fxsave)));
173 #endif
174 - __asm__ __volatile__("fnclex");
175 + clear_fpu_state(&tsk->thread.i387.fxsave);
176 }
177
178 static inline void kernel_fpu_begin(void)

  ViewVC Help
Powered by ViewVC 1.1.20