VirtualBox

Changeset 9475 in vbox


Ignore:
Timestamp:
Jun 6, 2008 1:10:55 PM (16 years ago)
Author:
vboxsync
Message:

Added VMXR0StartVM64.
Sync the FS_BASE & GS_BASE MSRs.

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

Legend:

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

    r9457 r9475  
    395395; */
    396396BEGINPROC VMXR0StartVM64
    397     ret
     397    push    xBP
     398    mov     xBP, xSP
     399
     400    pushf
     401    cli
     402
     403    ;/* First we have to save some final CPU context registers. */
     404    mov     rax, qword .vmlaunch64_done
     405    push    rax
     406    mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
     407    vmwrite rax, [xSP]
     408    ;/* Note: assumes success... */
     409    add     xSP, xS
     410
     411    ;/* Manual save and restore:
     412    ; * - General purpose registers except RIP, RSP
     413    ; *
     414    ; * Trashed:
     415    ; * - CR2 (we don't care)
     416    ; * - LDTR (reset to 0)
     417    ; * - DRx (presumably not changed at all)
     418    ; * - DR7 (reset to 0x400)
     419    ; * - EFLAGS (reset to RT_BIT(1); not relevant)
     420    ; *
     421    ; */
     422
     423    ;/* Save all general purpose host registers. */
     424    MYPUSHAD
     425
     426    ;/* Save the Guest CPU context pointer. */
     427%ifdef ASM_CALL64_GCC
     428    ; fResume already in rdi
     429    ; pCtx    already in rsi
     430%else
     431    mov     rdi, rcx        ; fResume
     432    mov     rsi, rdx        ; pCtx
     433%endif
     434
     435    ;/* Save segment registers */
     436    ; Note: MYPUSHSEGS trashes rdx (among others), so we moved it here (msvc amd64 case)
     437    MYPUSHSEGS xAX, ax
     438
     439    ; Save the pCtx pointer
     440    push    xSI
     441
     442    ; Save LDTR
     443    xor     eax, eax
     444    sldt    ax
     445    push    xAX
     446
     447    ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
     448    sub     xSP, xS*2
     449    sgdt    [xSP]
     450
     451    sub     xSP, xS*2
     452    sidt    [xSP]
     453
     454%ifdef VBOX_WITH_DR6_EXPERIMENT
     455    ; Restore DR6 - experiment, not safe!
     456    mov     xBX, [xSI + CPUMCTX.dr6]
     457    mov     dr6, xBX
     458%endif
     459
     460    ; Restore CR2
     461    mov     rbx, qword [xSI + CPUMCTX.cr2]
     462    mov     cr2, rbx
     463
     464    mov     eax, VMX_VMCS_HOST_RSP
     465    vmwrite xAX, xSP
     466    ;/* Note: assumes success... */
     467    ;/* Don't mess with ESP anymore!! */
     468
     469    ;/* Restore Guest's general purpose registers. */
     470    mov     rax, qword [xSI + CPUMCTX.eax]
     471    mov     rbx, qword [xSI + CPUMCTX.ebx]
     472    mov     rcx, qword [xSI + CPUMCTX.ecx]
     473    mov     rdx, qword [xSI + CPUMCTX.edx]
     474    mov     rbp, qword [xSI + CPUMCTX.ebp]
     475    mov     r8,  qword [xSI + CPUMCTX.r8]
     476    mov     r9,  qword [xSI + CPUMCTX.r9]
     477    mov     r10, qword [xSI + CPUMCTX.r10]
     478    mov     r11, qword [xSI + CPUMCTX.r11]
     479    mov     r12, qword [xSI + CPUMCTX.r12]
     480    mov     r13, qword [xSI + CPUMCTX.r13]
     481    mov     r14, qword [xSI + CPUMCTX.r14]
     482    mov     r15, qword [xSI + CPUMCTX.r15]
     483
     484    ; resume or start?
     485    cmp     xDI, 0                  ; fResume
     486    je      .vmlauch64_lauch
     487
     488    ;/* Restore edi & esi. */
     489    mov     rdi, qword [xSI + CPUMCTX.edi]
     490    mov     rsi, qword [xSI + CPUMCTX.esi]
     491
     492    vmresume
     493    jmp     .vmlaunch64_done;      ;/* here if vmresume detected a failure. */
     494   
     495.vmlauch64_lauch:   
     496    ;/* Restore rdi & rsi. */
     497    mov     rdi, qword [xSI + CPUMCTX.edi]
     498    mov     rsi, qword [xSI + CPUMCTX.esi]
     499
     500    vmlaunch
     501    jmp     .vmlaunch64_done;      ;/* here if vmlaunch detected a failure. */
     502
     503ALIGNCODE(16)
     504.vmlaunch64_done:
     505    jc      near .vmxstart64_invalid_vmxon_ptr
     506    jz      near .vmxstart64_start_failed
     507
     508    ; Restore base and limit of the IDTR & GDTR
     509    lidt    [xSP]
     510    add     xSP, xS*2
     511    lgdt    [xSP]
     512    add     xSP, xS*2
     513
     514    push    xDI
     515    mov     xDI, [xSP + xS * 2]         ; pCtx
     516
     517    mov     qword [xDI + CPUMCTX.eax], rax
     518    mov     qword [xDI + CPUMCTX.ebx], rbx
     519    mov     qword [xDI + CPUMCTX.ecx], rcx
     520    mov     qword [xDI + CPUMCTX.edx], rdx
     521    mov     qword [xDI + CPUMCTX.esi], rsi
     522    mov     qword [xDI + CPUMCTX.ebp], rbp
     523    mov     qword [xDI + CPUMCTX.r8],  r8
     524    mov     qword [xDI + CPUMCTX.r9],  r9
     525    mov     qword [xDI + CPUMCTX.r10], r10
     526    mov     qword [xDI + CPUMCTX.r11], r11
     527    mov     qword [xDI + CPUMCTX.r12], r12
     528    mov     qword [xDI + CPUMCTX.r13], r13
     529    mov     qword [xDI + CPUMCTX.r14], r14
     530    mov     qword [xDI + CPUMCTX.r15], r15
     531
     532    pop     xAX                                 ; the guest edi we pushed above
     533    mov     qword [xDI + CPUMCTX.edi], rax
     534
     535%ifdef VBOX_WITH_DR6_EXPERIMENT
     536    ; Save DR6 - experiment, not safe!
     537    mov     xAX, dr6
     538    mov     [xDI + CPUMCTX.dr6], xAX
     539%endif
     540
     541    pop     xAX         ; saved LDTR
     542    lldt    ax
     543
     544    add     xSP, xS      ; pCtx
     545
     546    ; Restore segment registers
     547    MYPOPSEGS xAX, ax
     548
     549    ; Restore general purpose registers
     550    MYPOPAD
     551
     552    mov     eax, VINF_SUCCESS
     553
     554.vmstart64_end:
     555    popf
     556    pop     xBP
     557    ret
     558
     559
     560.vmxstart64_invalid_vmxon_ptr:
     561    ; Restore base and limit of the IDTR & GDTR
     562    lidt    [xSP]
     563    add     xSP, xS*2
     564    lgdt    [xSP]
     565    add     xSP, xS*2
     566
     567    pop     xAX         ; saved LDTR
     568    lldt    ax
     569
     570    add     xSP, xS     ; pCtx
     571
     572    ; Restore segment registers
     573    MYPOPSEGS xAX, ax
     574
     575    ; Restore all general purpose host registers.
     576    MYPOPAD
     577    mov     eax, VERR_VMX_INVALID_VMXON_PTR
     578    jmp     .vmstart64_end
     579
     580.vmxstart64_start_failed:
     581    ; Restore base and limit of the IDTR & GDTR
     582    lidt    [xSP]
     583    add     xSP, xS*2
     584    lgdt    [xSP]
     585    add     xSP, xS*2
     586
     587    pop     xAX         ; saved LDTR
     588    lldt    ax
     589
     590    add     xSP, xS     ; pCtx
     591
     592    ; Restore segment registers
     593    MYPOPSEGS xAX, ax
     594
     595    ; Restore all general purpose host registers.
     596    MYPOPAD
     597    mov     eax, VERR_VMX_UNABLE_TO_START_VM
     598    jmp     .vmstart64_end
    398599ENDPROC VMXR0StartVM64
    399600
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r9457 r9475  
    681681        AssertRC(rc);
    682682
     683        /* @todo are the hidden base registers in sync with the MSRs? */
    683684        VMX_WRITE_SELREG(FS, fs);
    684685        AssertRC(rc);
     
    967968        pVM->hwaccm.s.vmx.pfnStartVM  = VMXR0StartVM64;
    968969#endif
     970        rc = VMXWriteVMCS(VMX_VMCS_GUEST_FS_BASE, pCtx->msrFSBASE);
     971        AssertRC(rc);
     972        rc = VMXWriteVMCS(VMX_VMCS_GUEST_GS_BASE, pCtx->msrGSBASE);
     973        AssertRC(rc);
    969974    }
    970975    else
     
    19821987        break;
    19831988
    1984     case VMX_EXIT_RDPMC:                /* 15 Guest software attempted to execute RDPMC. */
    19851989    case VMX_EXIT_RDMSR:                /* 31 RDMSR. Guest software attempted to execute RDMSR. */
    19861990    case VMX_EXIT_WRMSR:                /* 32 WRMSR. Guest software attempted to execute WRMSR. */
     1991        /* Note: If we decide to emulate them here, then we must sync the MSRs that could have been changed (sysenter, fs/gs base)!!! */
     1992    case VMX_EXIT_RDPMC:                /* 15 Guest software attempted to execute RDPMC. */
    19871993    case VMX_EXIT_MWAIT:                /* 36 Guest software executed MWAIT. */
    19881994    case VMX_EXIT_MONITOR:              /* 39 Guest software attempted to execute MONITOR. */
     
    20312037        VMXReadVMCS(VMX_VMCS_GUEST_SYSENTER_ESP,     &val);
    20322038        pCtx->SysEnter.esp      = val;
     2039
     2040        /* 64 bits guest mode? */
     2041        if (pCtx->msrEFER & MSR_K6_EFER_LMA)
     2042        {
     2043            /* Note: we assume that either you can't rely on fs/gs base staying intact when switching in and out of 64 bits mode or that in
     2044             *       reality it really doesn't matter (as the guest OS restores them manually).
     2045             */
     2046            VMXReadVMCS(VMX_VMCS_GUEST_FS_BASE, &val);
     2047            pCtx->msrFSBASE = val;
     2048            VMXReadVMCS(VMX_VMCS_GUEST_GS_BASE, &val);
     2049            pCtx->msrGSBASE = val;
     2050        }
    20332051    }
    20342052
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