summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.8/0006-i387-don-t-ever-touch-TS_USEDFPU-directly-use-helper.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.8/0006-i387-don-t-ever-touch-TS_USEDFPU-directly-use-helper.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.8/0006-i387-don-t-ever-touch-TS_USEDFPU-directly-use-helper.patch228
1 files changed, 228 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.8/0006-i387-don-t-ever-touch-TS_USEDFPU-directly-use-helper.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.8/0006-i387-don-t-ever-touch-TS_USEDFPU-directly-use-helper.patch
new file mode 100644
index 00000000..7daaa620
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.8/0006-i387-don-t-ever-touch-TS_USEDFPU-directly-use-helper.patch
@@ -0,0 +1,228 @@
1From 29515b215b9bbbad0368a5039ba6e53ed3fa7f25 Mon Sep 17 00:00:00 2001
2From: Linus Torvalds <torvalds@linux-foundation.org>
3Date: Thu, 16 Feb 2012 13:33:12 -0800
4Subject: [PATCH 06/11] i387: don't ever touch TS_USEDFPU directly, use helper
5 functions
6
7commit 6d59d7a9f5b723a7ac1925c136e93ec83c0c3043 upstream.
8
9This creates three helper functions that do the TS_USEDFPU accesses, and
10makes everybody that used to do it by hand use those helpers instead.
11
12In addition, there's a couple of helper functions for the "change both
13CR0.TS and TS_USEDFPU at the same time" case, and the places that do
14that together have been changed to use those. That means that we have
15fewer random places that open-code this situation.
16
17The intent is partly to clarify the code without actually changing any
18semantics yet (since we clearly still have some hard to reproduce bug in
19this area), but also to make it much easier to use another approach
20entirely to caching the CR0.TS bit for software accesses.
21
22Right now we use a bit in the thread-info 'status' variable (this patch
23does not change that), but we might want to make it a full field of its
24own or even make it a per-cpu variable.
25
26Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
27Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28---
29 arch/x86/include/asm/i387.h | 75 +++++++++++++++++++++++++++++++-----------
30 arch/x86/kernel/traps.c | 2 +-
31 arch/x86/kernel/xsave.c | 2 +-
32 arch/x86/kvm/vmx.c | 2 +-
33 4 files changed, 58 insertions(+), 23 deletions(-)
34
35diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
36index 55fb3aa..730d7be 100644
37--- a/arch/x86/include/asm/i387.h
38+++ b/arch/x86/include/asm/i387.h
39@@ -280,6 +280,47 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
40 }
41
42 /*
43+ * Software FPU state helpers. Careful: these need to
44+ * be preemption protection *and* they need to be
45+ * properly paired with the CR0.TS changes!
46+ */
47+static inline int __thread_has_fpu(struct thread_info *ti)
48+{
49+ return ti->status & TS_USEDFPU;
50+}
51+
52+/* Must be paired with an 'stts' after! */
53+static inline void __thread_clear_has_fpu(struct thread_info *ti)
54+{
55+ ti->status &= ~TS_USEDFPU;
56+}
57+
58+/* Must be paired with a 'clts' before! */
59+static inline void __thread_set_has_fpu(struct thread_info *ti)
60+{
61+ ti->status |= TS_USEDFPU;
62+}
63+
64+/*
65+ * Encapsulate the CR0.TS handling together with the
66+ * software flag.
67+ *
68+ * These generally need preemption protection to work,
69+ * do try to avoid using these on their own.
70+ */
71+static inline void __thread_fpu_end(struct thread_info *ti)
72+{
73+ __thread_clear_has_fpu(ti);
74+ stts();
75+}
76+
77+static inline void __thread_fpu_begin(struct thread_info *ti)
78+{
79+ clts();
80+ __thread_set_has_fpu(ti);
81+}
82+
83+/*
84 * Signal frame handlers...
85 */
86 extern int save_i387_xstate(void __user *buf);
87@@ -287,23 +328,21 @@ extern int restore_i387_xstate(void __user *buf);
88
89 static inline void __unlazy_fpu(struct task_struct *tsk)
90 {
91- if (task_thread_info(tsk)->status & TS_USEDFPU) {
92+ if (__thread_has_fpu(task_thread_info(tsk))) {
93 __save_init_fpu(tsk);
94- task_thread_info(tsk)->status &= ~TS_USEDFPU;
95- stts();
96+ __thread_fpu_end(task_thread_info(tsk));
97 } else
98 tsk->fpu_counter = 0;
99 }
100
101 static inline void __clear_fpu(struct task_struct *tsk)
102 {
103- if (task_thread_info(tsk)->status & TS_USEDFPU) {
104+ if (__thread_has_fpu(task_thread_info(tsk))) {
105 /* Ignore delayed exceptions from user space */
106 asm volatile("1: fwait\n"
107 "2:\n"
108 _ASM_EXTABLE(1b, 2b));
109- task_thread_info(tsk)->status &= ~TS_USEDFPU;
110- stts();
111+ __thread_fpu_end(task_thread_info(tsk));
112 }
113 }
114
115@@ -311,14 +350,14 @@ static inline void __clear_fpu(struct task_struct *tsk)
116 * Were we in an interrupt that interrupted kernel mode?
117 *
118 * We can do a kernel_fpu_begin/end() pair *ONLY* if that
119- * pair does nothing at all: TS_USEDFPU must be clear (so
120+ * pair does nothing at all: the thread must not have fpu (so
121 * that we don't try to save the FPU state), and TS must
122 * be set (so that the clts/stts pair does nothing that is
123 * visible in the interrupted kernel thread).
124 */
125 static inline bool interrupted_kernel_fpu_idle(void)
126 {
127- return !(current_thread_info()->status & TS_USEDFPU) &&
128+ return !__thread_has_fpu(current_thread_info()) &&
129 (read_cr0() & X86_CR0_TS);
130 }
131
132@@ -356,9 +395,9 @@ static inline void kernel_fpu_begin(void)
133
134 WARN_ON_ONCE(!irq_fpu_usable());
135 preempt_disable();
136- if (me->status & TS_USEDFPU) {
137+ if (__thread_has_fpu(me)) {
138 __save_init_fpu(me->task);
139- me->status &= ~TS_USEDFPU;
140+ __thread_clear_has_fpu(me);
141 /* We do 'stts()' in kernel_fpu_end() */
142 } else
143 clts();
144@@ -422,24 +461,21 @@ static inline void irq_ts_restore(int TS_state)
145 */
146 static inline int user_has_fpu(void)
147 {
148- return current_thread_info()->status & TS_USEDFPU;
149+ return __thread_has_fpu(current_thread_info());
150 }
151
152 static inline void user_fpu_end(void)
153 {
154 preempt_disable();
155- current_thread_info()->status &= ~TS_USEDFPU;
156- stts();
157+ __thread_fpu_end(current_thread_info());
158 preempt_enable();
159 }
160
161 static inline void user_fpu_begin(void)
162 {
163 preempt_disable();
164- if (!user_has_fpu()) {
165- clts();
166- current_thread_info()->status |= TS_USEDFPU;
167- }
168+ if (!user_has_fpu())
169+ __thread_fpu_begin(current_thread_info());
170 preempt_enable();
171 }
172
173@@ -448,11 +484,10 @@ static inline void user_fpu_begin(void)
174 */
175 static inline void save_init_fpu(struct task_struct *tsk)
176 {
177- WARN_ON_ONCE(!(task_thread_info(tsk)->status & TS_USEDFPU));
178+ WARN_ON_ONCE(!__thread_has_fpu(task_thread_info(tsk)));
179 preempt_disable();
180 __save_init_fpu(tsk);
181- task_thread_info(tsk)->status &= ~TS_USEDFPU;
182- stts();
183+ __thread_fpu_end(task_thread_info(tsk));
184 preempt_enable();
185 }
186
187diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
188index 727e6c1..bb5445c 100644
189--- a/arch/x86/kernel/traps.c
190+++ b/arch/x86/kernel/traps.c
191@@ -579,7 +579,7 @@ void __math_state_restore(void)
192 return;
193 }
194
195- thread->status |= TS_USEDFPU; /* So we fnsave on switch_to() */
196+ __thread_set_has_fpu(thread); /* clts in caller! */
197 tsk->fpu_counter++;
198 }
199
200diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c
201index 86f1f09..a0bcd0d 100644
202--- a/arch/x86/kernel/xsave.c
203+++ b/arch/x86/kernel/xsave.c
204@@ -47,7 +47,7 @@ void __sanitize_i387_state(struct task_struct *tsk)
205 if (!fx)
206 return;
207
208- BUG_ON(task_thread_info(tsk)->status & TS_USEDFPU);
209+ BUG_ON(__thread_has_fpu(task_thread_info(tsk)));
210
211 xstate_bv = tsk->thread.fpu.state->xsave.xsave_hdr.xstate_bv;
212
213diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
214index 579a0b5..b2c612d 100644
215--- a/arch/x86/kvm/vmx.c
216+++ b/arch/x86/kvm/vmx.c
217@@ -1456,7 +1456,7 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx)
218 #ifdef CONFIG_X86_64
219 wrmsrl(MSR_KERNEL_GS_BASE, vmx->msr_host_kernel_gs_base);
220 #endif
221- if (current_thread_info()->status & TS_USEDFPU)
222+ if (__thread_has_fpu(current_thread_info()))
223 clts();
224 load_gdt(&__get_cpu_var(host_gdt));
225 }
226--
2271.7.7.4
228