| 750 | } |
| 751 | |
| 752 | static void |
| 753 | restore_fpu_curthread(struct thread *td) |
| 754 | { |
| 755 | struct pcb *pcb; |
| 756 | |
| 757 | /* |
| 758 | * Record new context early in case frstor causes a trap. |
| 759 | */ |
| 760 | PCPU_SET(fpcurthread, td); |
| 761 | |
| 762 | stop_emulating(); |
| 763 | fpu_clean_state(); |
| 764 | pcb = td->td_pcb; |
| 765 | |
| 766 | if ((pcb->pcb_flags & PCB_FPUINITDONE) == 0) { |
| 767 | /* |
| 768 | * This is the first time this thread has used the FPU or |
| 769 | * the PCB doesn't contain a clean FPU state. Explicitly |
| 770 | * load an initial state. |
| 771 | * |
| 772 | * We prefer to restore the state from the actual save |
| 773 | * area in PCB instead of directly loading from |
| 774 | * fpu_initialstate, to ignite the XSAVEOPT |
| 775 | * tracking engine. |
| 776 | */ |
| 777 | bcopy(fpu_initialstate, pcb->pcb_save, |
| 778 | cpu_max_ext_state_size); |
| 779 | fpurestore(pcb->pcb_save); |
| 780 | if (pcb->pcb_initial_fpucw != __INITIAL_FPUCW__) |
| 781 | fldcw(pcb->pcb_initial_fpucw); |
| 782 | if (PCB_USER_FPU(pcb)) |
| 783 | set_pcb_flags(pcb, PCB_FPUINITDONE | |
| 784 | PCB_USERFPUINITDONE); |
| 785 | else |
| 786 | set_pcb_flags(pcb, PCB_FPUINITDONE); |
| 787 | } else |
| 788 | fpurestore(pcb->pcb_save); |
| 789 | } |
| 790 | |
| 791 | /* |
| 792 | * Device Not Available (DNA, #NM) exception handler. |
no test coverage detected