x86/fpu: Factor out the exception error code handling code
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / fpu / core.c
1 /*
2  *  Copyright (C) 1994 Linus Torvalds
3  *
4  *  Pentium III FXSR, SSE support
5  *  General FPU state handling cleanups
6  *      Gareth Hughes <gareth@valinux.com>, May 2000
7  */
8 #include <asm/fpu/internal.h>
9 #include <asm/fpu/regset.h>
10 #include <asm/fpu/signal.h>
11 #include <asm/traps.h>
12
13 #include <linux/hardirq.h>
14
15 /*
16  * Track whether the kernel is using the FPU state
17  * currently.
18  *
19  * This flag is used:
20  *
21  *   - by IRQ context code to potentially use the FPU
22  *     if it's unused.
23  *
24  *   - to debug kernel_fpu_begin()/end() correctness
25  */
26 static DEFINE_PER_CPU(bool, in_kernel_fpu);
27
28 /*
29  * Track which context is using the FPU on the CPU:
30  */
31 DEFINE_PER_CPU(struct fpu *, fpu_fpregs_owner_ctx);
32
33 static void kernel_fpu_disable(void)
34 {
35         WARN_ON(this_cpu_read(in_kernel_fpu));
36         this_cpu_write(in_kernel_fpu, true);
37 }
38
39 static void kernel_fpu_enable(void)
40 {
41         WARN_ON_ONCE(!this_cpu_read(in_kernel_fpu));
42         this_cpu_write(in_kernel_fpu, false);
43 }
44
45 static bool kernel_fpu_disabled(void)
46 {
47         return this_cpu_read(in_kernel_fpu);
48 }
49
50 /*
51  * Were we in an interrupt that interrupted kernel mode?
52  *
53  * On others, we can do a kernel_fpu_begin/end() pair *ONLY* if that
54  * pair does nothing at all: the thread must not have fpu (so
55  * that we don't try to save the FPU state), and TS must
56  * be set (so that the clts/stts pair does nothing that is
57  * visible in the interrupted kernel thread).
58  *
59  * Except for the eagerfpu case when we return true; in the likely case
60  * the thread has FPU but we are not going to set/clear TS.
61  */
62 static bool interrupted_kernel_fpu_idle(void)
63 {
64         if (kernel_fpu_disabled())
65                 return false;
66
67         if (use_eager_fpu())
68                 return true;
69
70         return !current->thread.fpu.fpregs_active && (read_cr0() & X86_CR0_TS);
71 }
72
73 /*
74  * Were we in user mode (or vm86 mode) when we were
75  * interrupted?
76  *
77  * Doing kernel_fpu_begin/end() is ok if we are running
78  * in an interrupt context from user mode - we'll just
79  * save the FPU state as required.
80  */
81 static bool interrupted_user_mode(void)
82 {
83         struct pt_regs *regs = get_irq_regs();
84         return regs && user_mode(regs);
85 }
86
87 /*
88  * Can we use the FPU in kernel mode with the
89  * whole "kernel_fpu_begin/end()" sequence?
90  *
91  * It's always ok in process context (ie "not interrupt")
92  * but it is sometimes ok even from an irq.
93  */
94 bool irq_fpu_usable(void)
95 {
96         return !in_interrupt() ||
97                 interrupted_user_mode() ||
98                 interrupted_kernel_fpu_idle();
99 }
100 EXPORT_SYMBOL(irq_fpu_usable);
101
102 void __kernel_fpu_begin(void)
103 {
104         struct fpu *fpu = &current->thread.fpu;
105
106         kernel_fpu_disable();
107
108         if (fpu->fpregs_active) {
109                 copy_fpregs_to_fpstate(fpu);
110         } else {
111                 this_cpu_write(fpu_fpregs_owner_ctx, NULL);
112                 __fpregs_activate_hw();
113         }
114 }
115 EXPORT_SYMBOL(__kernel_fpu_begin);
116
117 void __kernel_fpu_end(void)
118 {
119         struct fpu *fpu = &current->thread.fpu;
120
121         if (fpu->fpregs_active) {
122                 if (WARN_ON(copy_fpstate_to_fpregs(fpu)))
123                         fpu__clear(fpu);
124         } else {
125                 __fpregs_deactivate_hw();
126         }
127
128         kernel_fpu_enable();
129 }
130 EXPORT_SYMBOL(__kernel_fpu_end);
131
132 void kernel_fpu_begin(void)
133 {
134         preempt_disable();
135         WARN_ON_ONCE(!irq_fpu_usable());
136         __kernel_fpu_begin();
137 }
138 EXPORT_SYMBOL_GPL(kernel_fpu_begin);
139
140 void kernel_fpu_end(void)
141 {
142         __kernel_fpu_end();
143         preempt_enable();
144 }
145 EXPORT_SYMBOL_GPL(kernel_fpu_end);
146
147 /*
148  * CR0::TS save/restore functions:
149  */
150 int irq_ts_save(void)
151 {
152         /*
153          * If in process context and not atomic, we can take a spurious DNA fault.
154          * Otherwise, doing clts() in process context requires disabling preemption
155          * or some heavy lifting like kernel_fpu_begin()
156          */
157         if (!in_atomic())
158                 return 0;
159
160         if (read_cr0() & X86_CR0_TS) {
161                 clts();
162                 return 1;
163         }
164
165         return 0;
166 }
167 EXPORT_SYMBOL_GPL(irq_ts_save);
168
169 void irq_ts_restore(int TS_state)
170 {
171         if (TS_state)
172                 stts();
173 }
174 EXPORT_SYMBOL_GPL(irq_ts_restore);
175
176 /*
177  * Save the FPU state (mark it for reload if necessary):
178  *
179  * This only ever gets called for the current task.
180  */
181 void fpu__save(struct fpu *fpu)
182 {
183         WARN_ON(fpu != &current->thread.fpu);
184
185         preempt_disable();
186         if (fpu->fpregs_active) {
187                 if (!copy_fpregs_to_fpstate(fpu))
188                         fpregs_deactivate(fpu);
189         }
190         preempt_enable();
191 }
192 EXPORT_SYMBOL_GPL(fpu__save);
193
194 void fpstate_init(struct fpu *fpu)
195 {
196         if (!cpu_has_fpu) {
197                 finit_soft_fpu(&fpu->state.soft);
198                 return;
199         }
200
201         memset(&fpu->state, 0, xstate_size);
202
203         if (cpu_has_fxsr) {
204                 fx_finit(&fpu->state.fxsave);
205         } else {
206                 struct i387_fsave_struct *fp = &fpu->state.fsave;
207                 fp->cwd = 0xffff037fu;
208                 fp->swd = 0xffff0000u;
209                 fp->twd = 0xffffffffu;
210                 fp->fos = 0xffff0000u;
211         }
212 }
213 EXPORT_SYMBOL_GPL(fpstate_init);
214
215 /*
216  * Copy the current task's FPU state to a new task's FPU context.
217  *
218  * In the 'eager' case we just save to the destination context.
219  *
220  * In the 'lazy' case we save to the source context, mark the FPU lazy
221  * via stts() and copy the source context into the destination context.
222  */
223 static void fpu_copy(struct fpu *dst_fpu, struct fpu *src_fpu)
224 {
225         WARN_ON(src_fpu != &current->thread.fpu);
226
227         /*
228          * Don't let 'init optimized' areas of the XSAVE area
229          * leak into the child task:
230          */
231         if (use_eager_fpu())
232                 memset(&dst_fpu->state.xsave, 0, xstate_size);
233
234         /*
235          * Save current FPU registers directly into the child
236          * FPU context, without any memory-to-memory copying.
237          *
238          * If the FPU context got destroyed in the process (FNSAVE
239          * done on old CPUs) then copy it back into the source
240          * context and mark the current task for lazy restore.
241          *
242          * We have to do all this with preemption disabled,
243          * mostly because of the FNSAVE case, because in that
244          * case we must not allow preemption in the window
245          * between the FNSAVE and us marking the context lazy.
246          *
247          * It shouldn't be an issue as even FNSAVE is plenty
248          * fast in terms of critical section length.
249          */
250         preempt_disable();
251         if (!copy_fpregs_to_fpstate(dst_fpu)) {
252                 memcpy(&src_fpu->state, &dst_fpu->state, xstate_size);
253                 fpregs_deactivate(src_fpu);
254         }
255         preempt_enable();
256 }
257
258 int fpu__copy(struct fpu *dst_fpu, struct fpu *src_fpu)
259 {
260         dst_fpu->counter = 0;
261         dst_fpu->fpregs_active = 0;
262         dst_fpu->last_cpu = -1;
263
264         if (src_fpu->fpstate_active)
265                 fpu_copy(dst_fpu, src_fpu);
266
267         return 0;
268 }
269
270 /*
271  * Activate the current task's in-memory FPU context,
272  * if it has not been used before:
273  */
274 void fpu__activate_curr(struct fpu *fpu)
275 {
276         WARN_ON_ONCE(fpu != &current->thread.fpu);
277
278         if (!fpu->fpstate_active) {
279                 fpstate_init(fpu);
280
281                 /* Safe to do for the current task: */
282                 fpu->fpstate_active = 1;
283         }
284 }
285 EXPORT_SYMBOL_GPL(fpu__activate_curr);
286
287 /*
288  * This function must be called before we modify a stopped child's
289  * fpstate.
290  *
291  * If the child has not used the FPU before then initialize its
292  * fpstate.
293  *
294  * If the child has used the FPU before then unlazy it.
295  *
296  * [ After this function call, after registers in the fpstate are
297  *   modified and the child task has woken up, the child task will
298  *   restore the modified FPU state from the modified context. If we
299  *   didn't clear its lazy status here then the lazy in-registers
300  *   state pending on its former CPU could be restored, corrupting
301  *   the modifications. ]
302  *
303  * This function is also called before we read a stopped child's
304  * FPU state - to make sure it's initialized if the child has
305  * no active FPU state.
306  *
307  * TODO: A future optimization would be to skip the unlazying in
308  *       the read-only case, it's not strictly necessary for
309  *       read-only access to the context.
310  */
311 static void fpu__activate_stopped(struct fpu *child_fpu)
312 {
313         WARN_ON_ONCE(child_fpu == &current->thread.fpu);
314
315         if (child_fpu->fpstate_active) {
316                 child_fpu->last_cpu = -1;
317         } else {
318                 fpstate_init(child_fpu);
319
320                 /* Safe to do for stopped child tasks: */
321                 child_fpu->fpstate_active = 1;
322         }
323 }
324
325 /*
326  * 'fpu__restore()' is called to copy FPU registers from
327  * the FPU fpstate to the live hw registers and to activate
328  * access to the hardware registers, so that FPU instructions
329  * can be used afterwards.
330  *
331  * Must be called with kernel preemption disabled (for example
332  * with local interrupts disabled, as it is in the case of
333  * do_device_not_available()).
334  */
335 void fpu__restore(void)
336 {
337         struct task_struct *tsk = current;
338         struct fpu *fpu = &tsk->thread.fpu;
339
340         fpu__activate_curr(fpu);
341
342         /* Avoid __kernel_fpu_begin() right after fpregs_activate() */
343         kernel_fpu_disable();
344         fpregs_activate(fpu);
345         if (unlikely(copy_fpstate_to_fpregs(fpu))) {
346                 fpu__clear(fpu);
347                 force_sig_info(SIGSEGV, SEND_SIG_PRIV, tsk);
348         } else {
349                 tsk->thread.fpu.counter++;
350         }
351         kernel_fpu_enable();
352 }
353 EXPORT_SYMBOL_GPL(fpu__restore);
354
355 /*
356  * Drops current FPU state: deactivates the fpregs and
357  * the fpstate. NOTE: it still leaves previous contents
358  * in the fpregs in the eager-FPU case.
359  *
360  * This function can be used in cases where we know that
361  * a state-restore is coming: either an explicit one,
362  * or a reschedule.
363  */
364 void fpu__drop(struct fpu *fpu)
365 {
366         preempt_disable();
367         fpu->counter = 0;
368
369         if (fpu->fpregs_active) {
370                 /* Ignore delayed exceptions from user space */
371                 asm volatile("1: fwait\n"
372                              "2:\n"
373                              _ASM_EXTABLE(1b, 2b));
374                 fpregs_deactivate(fpu);
375         }
376
377         fpu->fpstate_active = 0;
378
379         preempt_enable();
380 }
381
382 /*
383  * Clear the FPU state back to init state.
384  *
385  * Called by sys_execve(), by the signal handler code and by various
386  * error paths.
387  */
388 void fpu__clear(struct fpu *fpu)
389 {
390         WARN_ON_ONCE(fpu != &current->thread.fpu); /* Almost certainly an anomaly */
391
392         if (!use_eager_fpu()) {
393                 /* FPU state will be reallocated lazily at the first use. */
394                 fpu__drop(fpu);
395         } else {
396                 if (!fpu->fpstate_active) {
397                         fpu__activate_curr(fpu);
398                         user_fpu_begin();
399                 }
400                 restore_init_xstate();
401         }
402 }
403
404 /*
405  * The xstateregs_active() routine is the same as the regset_fpregs_active() routine,
406  * as the "regset->n" for the xstate regset will be updated based on the feature
407  * capabilites supported by the xsave.
408  */
409 int regset_fpregs_active(struct task_struct *target, const struct user_regset *regset)
410 {
411         struct fpu *target_fpu = &target->thread.fpu;
412
413         return target_fpu->fpstate_active ? regset->n : 0;
414 }
415
416 int regset_xregset_fpregs_active(struct task_struct *target, const struct user_regset *regset)
417 {
418         struct fpu *target_fpu = &target->thread.fpu;
419
420         return (cpu_has_fxsr && target_fpu->fpstate_active) ? regset->n : 0;
421 }
422
423 int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
424                 unsigned int pos, unsigned int count,
425                 void *kbuf, void __user *ubuf)
426 {
427         struct fpu *fpu = &target->thread.fpu;
428
429         if (!cpu_has_fxsr)
430                 return -ENODEV;
431
432         fpu__activate_stopped(fpu);
433         fpstate_sanitize_xstate(fpu);
434
435         return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
436                                    &fpu->state.fxsave, 0, -1);
437 }
438
439 int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
440                 unsigned int pos, unsigned int count,
441                 const void *kbuf, const void __user *ubuf)
442 {
443         struct fpu *fpu = &target->thread.fpu;
444         int ret;
445
446         if (!cpu_has_fxsr)
447                 return -ENODEV;
448
449         fpu__activate_stopped(fpu);
450         fpstate_sanitize_xstate(fpu);
451
452         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
453                                  &fpu->state.fxsave, 0, -1);
454
455         /*
456          * mxcsr reserved bits must be masked to zero for security reasons.
457          */
458         fpu->state.fxsave.mxcsr &= mxcsr_feature_mask;
459
460         /*
461          * update the header bits in the xsave header, indicating the
462          * presence of FP and SSE state.
463          */
464         if (cpu_has_xsave)
465                 fpu->state.xsave.header.xfeatures |= XSTATE_FPSSE;
466
467         return ret;
468 }
469
470 int xstateregs_get(struct task_struct *target, const struct user_regset *regset,
471                 unsigned int pos, unsigned int count,
472                 void *kbuf, void __user *ubuf)
473 {
474         struct fpu *fpu = &target->thread.fpu;
475         struct xsave_struct *xsave;
476         int ret;
477
478         if (!cpu_has_xsave)
479                 return -ENODEV;
480
481         fpu__activate_stopped(fpu);
482
483         xsave = &fpu->state.xsave;
484
485         /*
486          * Copy the 48bytes defined by the software first into the xstate
487          * memory layout in the thread struct, so that we can copy the entire
488          * xstateregs to the user using one user_regset_copyout().
489          */
490         memcpy(&xsave->i387.sw_reserved,
491                 xstate_fx_sw_bytes, sizeof(xstate_fx_sw_bytes));
492         /*
493          * Copy the xstate memory layout.
494          */
495         ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, xsave, 0, -1);
496         return ret;
497 }
498
499 int xstateregs_set(struct task_struct *target, const struct user_regset *regset,
500                   unsigned int pos, unsigned int count,
501                   const void *kbuf, const void __user *ubuf)
502 {
503         struct fpu *fpu = &target->thread.fpu;
504         struct xsave_struct *xsave;
505         int ret;
506
507         if (!cpu_has_xsave)
508                 return -ENODEV;
509
510         fpu__activate_stopped(fpu);
511
512         xsave = &fpu->state.xsave;
513
514         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1);
515         /*
516          * mxcsr reserved bits must be masked to zero for security reasons.
517          */
518         xsave->i387.mxcsr &= mxcsr_feature_mask;
519         xsave->header.xfeatures &= xfeatures_mask;
520         /*
521          * These bits must be zero.
522          */
523         memset(&xsave->header.reserved, 0, 48);
524
525         return ret;
526 }
527
528 #if defined CONFIG_X86_32 || defined CONFIG_IA32_EMULATION
529
530 /*
531  * FPU tag word conversions.
532  */
533
534 static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
535 {
536         unsigned int tmp; /* to avoid 16 bit prefixes in the code */
537
538         /* Transform each pair of bits into 01 (valid) or 00 (empty) */
539         tmp = ~twd;
540         tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
541         /* and move the valid bits to the lower byte. */
542         tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
543         tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
544         tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
545
546         return tmp;
547 }
548
549 #define FPREG_ADDR(f, n)        ((void *)&(f)->st_space + (n) * 16)
550 #define FP_EXP_TAG_VALID        0
551 #define FP_EXP_TAG_ZERO         1
552 #define FP_EXP_TAG_SPECIAL      2
553 #define FP_EXP_TAG_EMPTY        3
554
555 static inline u32 twd_fxsr_to_i387(struct i387_fxsave_struct *fxsave)
556 {
557         struct _fpxreg *st;
558         u32 tos = (fxsave->swd >> 11) & 7;
559         u32 twd = (unsigned long) fxsave->twd;
560         u32 tag;
561         u32 ret = 0xffff0000u;
562         int i;
563
564         for (i = 0; i < 8; i++, twd >>= 1) {
565                 if (twd & 0x1) {
566                         st = FPREG_ADDR(fxsave, (i - tos) & 7);
567
568                         switch (st->exponent & 0x7fff) {
569                         case 0x7fff:
570                                 tag = FP_EXP_TAG_SPECIAL;
571                                 break;
572                         case 0x0000:
573                                 if (!st->significand[0] &&
574                                     !st->significand[1] &&
575                                     !st->significand[2] &&
576                                     !st->significand[3])
577                                         tag = FP_EXP_TAG_ZERO;
578                                 else
579                                         tag = FP_EXP_TAG_SPECIAL;
580                                 break;
581                         default:
582                                 if (st->significand[3] & 0x8000)
583                                         tag = FP_EXP_TAG_VALID;
584                                 else
585                                         tag = FP_EXP_TAG_SPECIAL;
586                                 break;
587                         }
588                 } else {
589                         tag = FP_EXP_TAG_EMPTY;
590                 }
591                 ret |= tag << (2 * i);
592         }
593         return ret;
594 }
595
596 /*
597  * FXSR floating point environment conversions.
598  */
599
600 void
601 convert_from_fxsr(struct user_i387_ia32_struct *env, struct task_struct *tsk)
602 {
603         struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state.fxsave;
604         struct _fpreg *to = (struct _fpreg *) &env->st_space[0];
605         struct _fpxreg *from = (struct _fpxreg *) &fxsave->st_space[0];
606         int i;
607
608         env->cwd = fxsave->cwd | 0xffff0000u;
609         env->swd = fxsave->swd | 0xffff0000u;
610         env->twd = twd_fxsr_to_i387(fxsave);
611
612 #ifdef CONFIG_X86_64
613         env->fip = fxsave->rip;
614         env->foo = fxsave->rdp;
615         /*
616          * should be actually ds/cs at fpu exception time, but
617          * that information is not available in 64bit mode.
618          */
619         env->fcs = task_pt_regs(tsk)->cs;
620         if (tsk == current) {
621                 savesegment(ds, env->fos);
622         } else {
623                 env->fos = tsk->thread.ds;
624         }
625         env->fos |= 0xffff0000;
626 #else
627         env->fip = fxsave->fip;
628         env->fcs = (u16) fxsave->fcs | ((u32) fxsave->fop << 16);
629         env->foo = fxsave->foo;
630         env->fos = fxsave->fos;
631 #endif
632
633         for (i = 0; i < 8; ++i)
634                 memcpy(&to[i], &from[i], sizeof(to[0]));
635 }
636
637 void convert_to_fxsr(struct task_struct *tsk,
638                      const struct user_i387_ia32_struct *env)
639
640 {
641         struct i387_fxsave_struct *fxsave = &tsk->thread.fpu.state.fxsave;
642         struct _fpreg *from = (struct _fpreg *) &env->st_space[0];
643         struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0];
644         int i;
645
646         fxsave->cwd = env->cwd;
647         fxsave->swd = env->swd;
648         fxsave->twd = twd_i387_to_fxsr(env->twd);
649         fxsave->fop = (u16) ((u32) env->fcs >> 16);
650 #ifdef CONFIG_X86_64
651         fxsave->rip = env->fip;
652         fxsave->rdp = env->foo;
653         /* cs and ds ignored */
654 #else
655         fxsave->fip = env->fip;
656         fxsave->fcs = (env->fcs & 0xffff);
657         fxsave->foo = env->foo;
658         fxsave->fos = env->fos;
659 #endif
660
661         for (i = 0; i < 8; ++i)
662                 memcpy(&to[i], &from[i], sizeof(from[0]));
663 }
664
665 int fpregs_get(struct task_struct *target, const struct user_regset *regset,
666                unsigned int pos, unsigned int count,
667                void *kbuf, void __user *ubuf)
668 {
669         struct fpu *fpu = &target->thread.fpu;
670         struct user_i387_ia32_struct env;
671
672         fpu__activate_stopped(fpu);
673
674         if (!static_cpu_has(X86_FEATURE_FPU))
675                 return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf);
676
677         if (!cpu_has_fxsr)
678                 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
679                                            &fpu->state.fsave, 0,
680                                            -1);
681
682         fpstate_sanitize_xstate(fpu);
683
684         if (kbuf && pos == 0 && count == sizeof(env)) {
685                 convert_from_fxsr(kbuf, target);
686                 return 0;
687         }
688
689         convert_from_fxsr(&env, target);
690
691         return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &env, 0, -1);
692 }
693
694 int fpregs_set(struct task_struct *target, const struct user_regset *regset,
695                unsigned int pos, unsigned int count,
696                const void *kbuf, const void __user *ubuf)
697 {
698         struct fpu *fpu = &target->thread.fpu;
699         struct user_i387_ia32_struct env;
700         int ret;
701
702         fpu__activate_stopped(fpu);
703         fpstate_sanitize_xstate(fpu);
704
705         if (!static_cpu_has(X86_FEATURE_FPU))
706                 return fpregs_soft_set(target, regset, pos, count, kbuf, ubuf);
707
708         if (!cpu_has_fxsr)
709                 return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
710                                           &fpu->state.fsave, 0,
711                                           -1);
712
713         if (pos > 0 || count < sizeof(env))
714                 convert_from_fxsr(&env, target);
715
716         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &env, 0, -1);
717         if (!ret)
718                 convert_to_fxsr(target, &env);
719
720         /*
721          * update the header bit in the xsave header, indicating the
722          * presence of FP.
723          */
724         if (cpu_has_xsave)
725                 fpu->state.xsave.header.xfeatures |= XSTATE_FP;
726         return ret;
727 }
728
729 /*
730  * FPU state for core dumps.
731  * This is only used for a.out dumps now.
732  * It is declared generically using elf_fpregset_t (which is
733  * struct user_i387_struct) but is in fact only used for 32-bit
734  * dumps, so on 64-bit it is really struct user_i387_ia32_struct.
735  */
736 int dump_fpu(struct pt_regs *regs, struct user_i387_struct *ufpu)
737 {
738         struct task_struct *tsk = current;
739         struct fpu *fpu = &tsk->thread.fpu;
740         int fpvalid;
741
742         fpvalid = fpu->fpstate_active;
743         if (fpvalid)
744                 fpvalid = !fpregs_get(tsk, NULL,
745                                       0, sizeof(struct user_i387_ia32_struct),
746                                       ufpu, NULL);
747
748         return fpvalid;
749 }
750 EXPORT_SYMBOL(dump_fpu);
751
752 #endif  /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */
753
754 /*
755  * x87 math exception handling:
756  */
757
758 static inline unsigned short get_fpu_cwd(struct fpu *fpu)
759 {
760         if (cpu_has_fxsr) {
761                 return fpu->state.fxsave.cwd;
762         } else {
763                 return (unsigned short)fpu->state.fsave.cwd;
764         }
765 }
766
767 static inline unsigned short get_fpu_swd(struct fpu *fpu)
768 {
769         if (cpu_has_fxsr) {
770                 return fpu->state.fxsave.swd;
771         } else {
772                 return (unsigned short)fpu->state.fsave.swd;
773         }
774 }
775
776 static inline unsigned short get_fpu_mxcsr(struct fpu *fpu)
777 {
778         if (cpu_has_xmm) {
779                 return fpu->state.fxsave.mxcsr;
780         } else {
781                 return MXCSR_DEFAULT;
782         }
783 }
784
785 int fpu__exception_code(struct fpu *fpu, int trap_nr)
786 {
787         int err;
788
789         if (trap_nr == X86_TRAP_MF) {
790                 unsigned short cwd, swd;
791                 /*
792                  * (~cwd & swd) will mask out exceptions that are not set to unmasked
793                  * status.  0x3f is the exception bits in these regs, 0x200 is the
794                  * C1 reg you need in case of a stack fault, 0x040 is the stack
795                  * fault bit.  We should only be taking one exception at a time,
796                  * so if this combination doesn't produce any single exception,
797                  * then we have a bad program that isn't synchronizing its FPU usage
798                  * and it will suffer the consequences since we won't be able to
799                  * fully reproduce the context of the exception
800                  */
801                 cwd = get_fpu_cwd(fpu);
802                 swd = get_fpu_swd(fpu);
803
804                 err = swd & ~cwd;
805         } else {
806                 /*
807                  * The SIMD FPU exceptions are handled a little differently, as there
808                  * is only a single status/control register.  Thus, to determine which
809                  * unmasked exception was caught we must mask the exception mask bits
810                  * at 0x1f80, and then use these to mask the exception bits at 0x3f.
811                  */
812                 unsigned short mxcsr = get_fpu_mxcsr(fpu);
813                 err = ~(mxcsr >> 7) & mxcsr;
814         }
815
816         if (err & 0x001) {      /* Invalid op */
817                 /*
818                  * swd & 0x240 == 0x040: Stack Underflow
819                  * swd & 0x240 == 0x240: Stack Overflow
820                  * User must clear the SF bit (0x40) if set
821                  */
822                 return FPE_FLTINV;
823         } else if (err & 0x004) { /* Divide by Zero */
824                 return FPE_FLTDIV;
825         } else if (err & 0x008) { /* Overflow */
826                 return FPE_FLTOVF;
827         } else if (err & 0x012) { /* Denormal, Underflow */
828                 return FPE_FLTUND;
829         } else if (err & 0x020) { /* Precision */
830                 return FPE_FLTRES;
831         }
832
833         /*
834          * If we're using IRQ 13, or supposedly even some trap
835          * X86_TRAP_MF implementations, it's possible
836          * we get a spurious trap, which is not an error.
837          */
838         return 0;
839 }