.. | .. |
---|
15 | 15 | #include <linux/sched.h> |
---|
16 | 16 | #include <linux/slab.h> |
---|
17 | 17 | #include <linux/mm.h> |
---|
| 18 | +#include <linux/dovetail.h> |
---|
18 | 19 | |
---|
19 | 20 | #include <asm/user.h> |
---|
20 | 21 | #include <asm/fpu/api.h> |
---|
.. | .. |
---|
509 | 510 | clear_thread_flag(TIF_NEED_FPU_LOAD); |
---|
510 | 511 | } |
---|
511 | 512 | |
---|
| 513 | +#ifdef CONFIG_DOVETAIL |
---|
| 514 | + |
---|
| 515 | +static inline void oob_fpu_set_preempt(struct fpu *fpu) |
---|
| 516 | +{ |
---|
| 517 | + fpu->preempted = 1; |
---|
| 518 | +} |
---|
| 519 | + |
---|
| 520 | +static inline void oob_fpu_clear_preempt(struct fpu *fpu) |
---|
| 521 | +{ |
---|
| 522 | + fpu->preempted = 0; |
---|
| 523 | +} |
---|
| 524 | + |
---|
| 525 | +static inline bool oob_fpu_preempted(struct fpu *old_fpu) |
---|
| 526 | +{ |
---|
| 527 | + return old_fpu->preempted; |
---|
| 528 | +} |
---|
| 529 | + |
---|
| 530 | +#else |
---|
| 531 | + |
---|
| 532 | +static inline bool oob_fpu_preempted(struct fpu *old_fpu) |
---|
| 533 | +{ |
---|
| 534 | + return false; |
---|
| 535 | +} |
---|
| 536 | + |
---|
| 537 | +#endif /* !CONFIG_DOVETAIL */ |
---|
| 538 | + |
---|
512 | 539 | /* |
---|
513 | 540 | * FPU state switching for scheduling. |
---|
514 | 541 | * |
---|
.. | .. |
---|
535 | 562 | { |
---|
536 | 563 | struct fpu *old_fpu = &prev->thread.fpu; |
---|
537 | 564 | |
---|
538 | | - if (static_cpu_has(X86_FEATURE_FPU) && !(prev->flags & PF_KTHREAD)) { |
---|
| 565 | + if (static_cpu_has(X86_FEATURE_FPU) && |
---|
| 566 | + !(prev->flags & PF_KTHREAD) && |
---|
| 567 | + !oob_fpu_preempted(old_fpu)) { |
---|
539 | 568 | if (!copy_fpregs_to_fpstate(old_fpu)) |
---|
540 | 569 | old_fpu->last_cpu = -1; |
---|
541 | 570 | else |
---|