| .. | .. |
|---|
| 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 |
|---|