VirtualBox

Changeset 49020 in vbox


Ignore:
Timestamp:
Oct 10, 2013 8:52:52 AM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
89769
Message:

VMM: FPU cleanup, CPUMAllA.asm is RC only, move it to CPUMRCA.asm and delete CPUMAllA.asm.

Location:
trunk/src/VBox/VMM
Files:
1 deleted
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r49019 r49020  
    438438        VMMRZ/VMMRZ.cpp \
    439439        VMMAll/CPUMAllRegs.cpp \
    440         VMMAll/CPUMAllA.asm \
    441440        VMMAll/DBGFAll.cpp \
    442441        VMMAll/IEMAll.cpp \
  • trunk/src/VBox/VMM/VMMR0/CPUMR0A.asm

    r49019 r49020  
    7272; This macro ASSUMES CR0.TS is not set!
    7373; @remarks Trashes xAX!!
    74 ; Changes here should also be reflected in CPUMAllA.asm's copy!
     74; Changes here should also be reflected in CPUMRCA.asm's copy!
    7575%macro CLEANFPU 0
    7676    test    dword [xDX + CPUMCPU.fUseFlags], CPUM_USE_FFXSR_LEAKY
  • trunk/src/VBox/VMM/VMMRC/CPUMRCA.asm

    r42771 r49020  
    4444BEGINCODE
    4545
     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;
     86align 16
     87BEGINPROC   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    ;
     134align 16
     135hlfpua_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
     144align 16
     145;; jump table using fpu related cr0 flags as index.
     146hlfpuajmp1:
     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.
     156hlfpu_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    ;
     169align 16
     170hlfpua_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
     202hlfpua_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.
     215hlfpua_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
     225hlfpua_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    ;
     234hlfpua_action_4:
     235hlfpua_to_host:
     236    mov     eax, VINF_EM_RAW_GUEST_TRAP
     237    ret
     238ENDPROC     cpumHandleLazyFPUAsm
     239
    46240
    47241;;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette