VirtualBox

Changeset 46925 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Jul 3, 2013 11:16:39 AM (12 years ago)
Author:
vboxsync
Message:

VMM: Optimized world-switch with lazy restoration LDTR and TR on Intel.

Location:
trunk/src/VBox/VMM/VMMR0
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMR0A.asm

    r46905 r46925  
    318318.test_es:
    319319    test        edi, VMX_RESTORE_HOST_SEL_ES
    320     jz          near .test_fs
     320    jz          near .test_ldtr
    321321    mov         ax, word [rsi + VMXRESTOREHOST.uHostSelES]
    322322    mov         es, ax
     323
     324.test_ldtr:
     325    test        edi, VMX_RESTORE_HOST_SEL_LDTR
     326    jz          near .test_tr
     327    mov         ax, word [rsi + VMXRESTOREHOST.uHostSelLDTR]
     328    lldt        ax
     329
     330.test_tr:
     331    test        edi, VMX_RESTORE_HOST_SEL_TR
     332    jz          near .test_fs
     333    mov         dx, word [rsi + VMXRESTOREHOST.uHostSelTR]
     334    xor         xAX, xAX
     335    mov         ax, dx
     336    and         al, X86_SEL_MASK                                  ; Mask away TI and RPL bits leaving only the descriptor offset.
     337    add         xAX, qword [rsi + VMXRESTOREHOST.HostGdtr + 2]    ; xAX <- descriptor offset + GDTR.pGdt.
     338    and         dword [ss:xAX + 4], ~RT_BIT(9)                    ; Clear the busy flag in TSS (bits 0-7=base, bit 9=busy bit).
     339    ltr         dx
    323340
    324341.test_fs:
  • trunk/src/VBox/VMM/VMMR0/HMR0Mixed.mac

    r46914 r46925  
    2121 %ifdef RT_ARCH_AMD64
    2222  %define VMX_SKIP_GDTR_IDTR
     23  %define VMX_SKIP_LDTR_TR
    2324 %endif
    2425%endif
     
    111112    push    xSI
    112113
     114%ifndef VMX_SKIP_LDTR_TR
    113115    ; Save LDTR.
    114116    xor     eax, eax
     
    119121    str     eax
    120122    push    xAX
    121 
     123%endif
     124
     125%ifndef VMX_SKIP_GDTR_IDTR
    122126    ; VT-x only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
    123 %ifndef VMX_SKIP_GDTR_IDTR
    124127    sub     xSP, xCB * 2
    125128    sgdt    [xSP]
     
    182185
    183186    push    xDI
    184     mov     xDI, [xSP + xCB * 3]         ; pCtx (*3 to skip the saved LDTR + TR).
     187%ifndef VMX_SKIP_LDTR_TR
     188    mov     xDI, [xSP + xCB * 3]         ; pCtx (*3 to skip the saved xDI, LDTR + TR).
     189%else
     190    mov     xDI, [xSP + xCB]             ; pCtx
     191%endif
    185192
    186193    mov     [ss:xDI + CPUMCTX.eax], eax
     
    202209%endif
    203210
     211%ifndef VMX_SKIP_LDTR_TR
    204212    ; Restore TSS selector; must mark it as not busy before using ltr (!)
    205213    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
     
    217225    pop     xAX         ; Saved LDTR
    218226    lldt    ax
     227%endif
    219228
    220229    add     xSP, xCB     ; pCtx
     
    267276%endif
    268277
     278%ifndef VMX_SKIP_LDTR_TR
    269279    ; Restore TSS selector; must mark it as not busy before using ltr (!)
    270280    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
     
    282292    pop     xAX         ; Saved LDTR
    283293    lldt    ax
     294%endif
    284295
    285296%ifdef VMX_USE_CACHED_VMCS_ACCESSES
     
    306317%endif
    307318
     319%ifndef VMX_SKIP_LDTR_TR
    308320    ; Restore TSS selector; must mark it as not busy before using ltr (!)
    309321    ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
     
    321333    pop     xAX         ; Saved LDTR
    322334    lldt    ax
     335%endif
    323336
    324337%ifdef VMX_USE_CACHED_VMCS_ACCESSES
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r46900 r46925  
    21382138{
    21392139    int rc = VERR_INTERNAL_ERROR_5;
    2140     RTSEL uSelDS = 0;
    2141     RTSEL uSelES = 0;
    2142     RTSEL uSelFS = 0;
    2143     RTSEL uSelGS = 0;
    2144     RTSEL uSelTR = 0;
     2140    RTSEL uSelDS   = 0;
     2141    RTSEL uSelES   = 0;
     2142    RTSEL uSelFS   = 0;
     2143    RTSEL uSelGS   = 0;
     2144    RTSEL uSelTR   = 0;
     2145    RTSEL uSelLDTR = 0;
    21452146
    21462147    /*
     
    21492150#if HC_ARCH_BITS == 64
    21502151    pVCpu->hm.s.vmx.fRestoreHostFlags = 0;
    2151     uSelDS = ASMGetDS();
    2152     uSelES = ASMGetES();
    2153     uSelFS = ASMGetFS();
    2154     uSelGS = ASMGetGS();
     2152    uSelDS   = ASMGetDS();
     2153    uSelES   = ASMGetES();
     2154    uSelFS   = ASMGetFS();
     2155    uSelGS   = ASMGetGS();
     2156    uSelLDTR = ASMGetLDTR();
    21552157#endif
    21562158
     
    22102212        pVCpu->hm.s.vmx.RestoreHost.uHostSelGS = uSelGS;
    22112213        uSelGS = 0;
     2214    }
     2215
     2216    /*
     2217     * VT-x unconditionally writes LDTR to 0 on all VM-exits. If the host has something different, we shall restore it.
     2218     * See Intel spec. 27.5.2 "Loading Host Segment and Descriptor-Table Registers".
     2219     */
     2220    if (uSelLDTR)
     2221    {
     2222        pVCpu->hm.s.vmx.fRestoreHostFlags |= VMX_RESTORE_HOST_SEL_LDTR;
     2223        pVCpu->hm.s.vmx.RestoreHost.uHostSelLDTR = uSelLDTR;
    22122224    }
    22132225#endif
     
    23172329#if HC_ARCH_BITS == 64
    23182330        uTRBase = X86DESC64_BASE(pDesc);
     2331
     2332        /*
     2333         * VT-x unconditionally restores the TR limit to 0x67 and type to 11 (32-bit busy TSS) on all VM-exits.
     2334         * The type is the same for 64-bit busy TSS[1]. The limit needs manual restoration if the host has something else.
     2335         * Task switching is not supported in 64-bit mode[2], but the limit still matters as IOPM is supported in 64-bit mode.
     2336         * Restoring the limit lazily while returning to ring-3 is safe because IOPM is not applicable in ring-0.
     2337         *
     2338         * [1] See Intel spec. 3.5 "System Descriptor Types".
     2339         * [2] See Intel spec. 7.2.3 "TSS Descriptor in 64-bit mode".
     2340         */
     2341        Assert(pDesc->System.u4Type == 11);
     2342        if (   pDesc->System.u16LimitLow != 0x67
     2343            || pDesc->System.u4LimitHigh)
     2344        {
     2345            pVCpu->hm.s.vmx.fRestoreHostFlags |= VMX_RESTORE_HOST_SEL_TR;
     2346            pVCpu->hm.s.vmx.RestoreHost.uHostSelTR = uSelTR;
     2347
     2348            /* Store the GDTR here as we need it while restoring TR. */
     2349            memcpy(&pVCpu->hm.s.vmx.RestoreHost.HostGdtr, &Gdtr, sizeof(X86XDTR64));
     2350        }
    23192351#else
    23202352        uTRBase = X86DESC_BASE(pDesc);
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