Changeset 49020 in vbox
- Timestamp:
- Oct 10, 2013 8:52:52 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 89769
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 1 deleted
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r49019 r49020 438 438 VMMRZ/VMMRZ.cpp \ 439 439 VMMAll/CPUMAllRegs.cpp \ 440 VMMAll/CPUMAllA.asm \441 440 VMMAll/DBGFAll.cpp \ 442 441 VMMAll/IEMAll.cpp \ -
trunk/src/VBox/VMM/VMMR0/CPUMR0A.asm
r49019 r49020 72 72 ; This macro ASSUMES CR0.TS is not set! 73 73 ; @remarks Trashes xAX!! 74 ; Changes here should also be reflected in CPUM AllA.asm's copy!74 ; Changes here should also be reflected in CPUMRCA.asm's copy! 75 75 %macro CLEANFPU 0 76 76 test dword [xDX + CPUMCPU.fUseFlags], CPUM_USE_FFXSR_LEAKY -
trunk/src/VBox/VMM/VMMRC/CPUMRCA.asm
r42771 r49020 44 44 BEGINCODE 45 45 46 ;; Macro for FXSAVE/FXRSTOR leaky behaviour on AMD CPUs, see cpumR3CheckLeakyFpu(). 47 ; Cleans the FPU state, if necessary, before restoring the FPU. 48 ; 49 ; This macro ASSUMES CR0.TS is not set! 50 ; @remarks Trashes xAX!! 51 ; Changes here should also be reflected in CPUMR0A.asm's copy! 52 %macro CLEANFPU 0 53 test dword [xDX + CPUMCPU.fUseFlags], CPUM_USE_FFXSR_LEAKY 54 jz .nothing_to_clean 55 56 xor eax, eax 57 fnstsw ax ; Get FSW 58 test eax, RT_BIT(7) ; If FSW.ES (bit 7) is set, clear it to not cause FPU exceptions 59 ; while clearing & loading the FPU bits in 'clean_fpu' 60 jz clean_fpu 61 fnclex 62 63 .clean_fpu: 64 ffree st7 ; Clear FPU stack register(7)'s tag entry to prevent overflow if a wraparound occurs 65 ; for the upcoming push (load) 66 fild dword [xDX + CPUMCPU.Guest.fpu] ; Explicit FPU load to overwrite FIP, FOP, FDP registers in the FPU. 67 68 .nothing_to_clean: 69 %endmacro 70 71 72 ;; 73 ; Handles lazy FPU saving and restoring. 74 ; 75 ; This handler will implement lazy fpu (sse/mmx/stuff) saving. 76 ; Two actions may be taken in this handler since the Guest OS may 77 ; be doing lazy fpu switching. So, we'll have to generate those 78 ; traps which the Guest CPU CTX shall have according to the 79 ; its CR0 flags. If no traps for the Guest OS, we'll save the host 80 ; context and restore the guest context. 81 ; 82 ; @returns 0 if caller should continue execution. 83 ; @returns VINF_EM_RAW_GUEST_TRAP if a guest trap should be generated. 84 ; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer 85 ; 86 align 16 87 BEGINPROC cpumHandleLazyFPUAsm 88 ; 89 ; Figure out what to do. 90 ; 91 ; There are two basic actions: 92 ; 1. Save host fpu and restore guest fpu. 93 ; 2. Generate guest trap. 94 ; 95 ; When entering the hypervisor we'll always enable MP (for proper wait 96 ; trapping) and TS (for intercepting all fpu/mmx/sse stuff). The EM flag 97 ; is taken from the guest OS in order to get proper SSE handling. 98 ; 99 ; 100 ; Actions taken depending on the guest CR0 flags: 101 ; 102 ; 3 2 1 103 ; TS | EM | MP | FPUInstr | WAIT :: VMM Action 104 ; ------------------------------------------------------------------------ 105 ; 0 | 0 | 0 | Exec | Exec :: Clear TS & MP, Save HC, Load GC. 106 ; 0 | 0 | 1 | Exec | Exec :: Clear TS, Save HC, Load GC. 107 ; 0 | 1 | 0 | #NM | Exec :: Clear TS & MP, Save HC, Load GC; 108 ; 0 | 1 | 1 | #NM | Exec :: Clear TS, Save HC, Load GC. 109 ; 1 | 0 | 0 | #NM | Exec :: Clear MP, Save HC, Load GC. (EM is already cleared.) 110 ; 1 | 0 | 1 | #NM | #NM :: Go to host taking trap there. 111 ; 1 | 1 | 0 | #NM | Exec :: Clear MP, Save HC, Load GC. (EM is already set.) 112 ; 1 | 1 | 1 | #NM | #NM :: Go to host taking trap there. 113 114 ; 115 ; Before taking any of these actions we're checking if we have already 116 ; loaded the GC FPU. Because if we have, this is an trap for the guest - raw ring-3. 117 ; 118 %ifdef RT_ARCH_AMD64 119 %ifdef RT_OS_WINDOWS 120 mov xDX, rcx 121 %else 122 mov xDX, rdi 123 %endif 124 %else 125 mov xDX, dword [esp + 4] 126 %endif 127 test dword [xDX + CPUMCPU.fUseFlags], CPUM_USED_FPU 128 jz hlfpua_not_loaded 129 jmp hlfpua_to_host 130 131 ; 132 ; Take action. 133 ; 134 align 16 135 hlfpua_not_loaded: 136 mov eax, [xDX + CPUMCPU.Guest.cr0] 137 and eax, X86_CR0_MP | X86_CR0_EM | X86_CR0_TS 138 %ifdef RT_ARCH_AMD64 139 lea r8, [hlfpuajmp1 wrt rip] 140 jmp qword [rax*4 + r8] 141 %else 142 jmp dword [eax*2 + hlfpuajmp1] 143 %endif 144 align 16 145 ;; jump table using fpu related cr0 flags as index. 146 hlfpuajmp1: 147 RTCCPTR_DEF hlfpua_switch_fpu_ctx 148 RTCCPTR_DEF hlfpua_switch_fpu_ctx 149 RTCCPTR_DEF hlfpua_switch_fpu_ctx 150 RTCCPTR_DEF hlfpua_switch_fpu_ctx 151 RTCCPTR_DEF hlfpua_switch_fpu_ctx 152 RTCCPTR_DEF hlfpua_to_host 153 RTCCPTR_DEF hlfpua_switch_fpu_ctx 154 RTCCPTR_DEF hlfpua_to_host 155 ;; and mask for cr0. 156 hlfpu_afFlags: 157 RTCCPTR_DEF ~(X86_CR0_TS | X86_CR0_MP) 158 RTCCPTR_DEF ~(X86_CR0_TS) 159 RTCCPTR_DEF ~(X86_CR0_TS | X86_CR0_MP) 160 RTCCPTR_DEF ~(X86_CR0_TS) 161 RTCCPTR_DEF ~(X86_CR0_MP) 162 RTCCPTR_DEF 0 163 RTCCPTR_DEF ~(X86_CR0_MP) 164 RTCCPTR_DEF 0 165 166 ; 167 ; Action - switch FPU context and change cr0 flags. 168 ; 169 align 16 170 hlfpua_switch_fpu_ctx: 171 %ifndef IN_RING3 ; IN_RC or IN_RING0 172 mov xCX, cr0 173 %ifdef RT_ARCH_AMD64 174 lea r8, [hlfpu_afFlags wrt rip] 175 and rcx, [rax*4 + r8] ; calc the new cr0 flags. 176 %else 177 and ecx, [eax*2 + hlfpu_afFlags] ; calc the new cr0 flags. 178 %endif 179 mov xAX, cr0 180 and xAX, ~(X86_CR0_TS | X86_CR0_EM) 181 mov cr0, xAX ; clear flags so we don't trap here. 182 %endif 183 %ifndef RT_ARCH_AMD64 184 mov eax, edx ; Calculate the PCPUM pointer 185 sub eax, [edx + CPUMCPU.offCPUM] 186 test dword [eax + CPUM.CPUFeatures.edx], X86_CPUID_FEATURE_EDX_FXSR 187 jz short hlfpua_no_fxsave 188 %endif 189 190 %ifdef RT_ARCH_AMD64 191 ; Use explicit REX prefix. See @bugref{6398}. 192 o64 fxsave [xDX + CPUMCPU.Host.fpu] 193 %else 194 fxsave [xDX + CPUMCPU.Host.fpu] 195 %endif 196 or dword [xDX + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM) 197 %ifdef RT_ARCH_AMD64 198 o64 fxrstor [xDX + CPUMCPU.Guest.fpu] 199 %else 200 fxrstor [xDX + CPUMCPU.Guest.fpu] 201 %endif 202 hlfpua_finished_switch: 203 204 ; Load new CR0 value. 205 ;; @todo Optimize the many unconditional CR0 writes. 206 %ifndef IN_RING3 207 mov cr0, xCX ; load the new cr0 flags. 208 %endif 209 ; return continue execution. 210 xor eax, eax 211 ret 212 213 %ifndef RT_ARCH_AMD64 214 ; legacy support. 215 hlfpua_no_fxsave: 216 fnsave [xDX + CPUMCPU.Host.fpu] 217 or dword [xDX + CPUMCPU.fUseFlags], dword (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM) ; yasm / nasm 218 mov eax, [xDX + CPUMCPU.Guest.fpu] ; control word 219 not eax ; 1 means exception ignored (6 LS bits) 220 and eax, byte 03Fh ; 6 LS bits only 221 test eax, [xDX + CPUMCPU.Guest.fpu + 4] ; status word 222 jz short hlfpua_no_exceptions_pending 223 ; technically incorrect, but we certainly don't want any exceptions now!! 224 and dword [xDX + CPUMCPU.Guest.fpu + 4], ~03Fh 225 hlfpua_no_exceptions_pending: 226 frstor [xDX + CPUMCPU.Guest.fpu] 227 jmp near hlfpua_finished_switch 228 %endif ; !RT_ARCH_AMD64 229 230 231 ; 232 ; Action - Generate Guest trap. 233 ; 234 hlfpua_action_4: 235 hlfpua_to_host: 236 mov eax, VINF_EM_RAW_GUEST_TRAP 237 ret 238 ENDPROC cpumHandleLazyFPUAsm 239 46 240 47 241 ;;
Note:
See TracChangeset
for help on using the changeset viewer.