VirtualBox

Changeset 14802 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Nov 29, 2008 1:37:55 AM (16 years ago)
Author:
vboxsync
Message:

#3202: More darwin mess.

Location:
trunk/src/VBox/VMM/VMMR0
Files:
1 edited
1 copied

Legend:

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

    r14799 r14802  
    4545%endif
    4646
     47;*******************************************************************************
     48;*  Defined Constants And Macros                                               *
     49;*******************************************************************************
     50%ifdef RT_ARCH_AMD64
     51 %define MAYBE_64_BIT
     52%endif
     53%ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
     54 %define MAYBE_64_BIT
     55%endif
     56
     57
    4758;; This is too risky wrt. stability, performance and correctness.
    4859;%define VBOX_WITH_DR6_EXPERIMENT 1
     
    6475; @param 2  16-bit regsiter name for \a 1.
    6576
    66 %ifdef RT_ARCH_AMD64
     77%ifdef MAYBE_64_BIT
    6778  ; Save a host and load the corresponding guest MSR (trashes rdx & rcx)
    6879  %macro LOADGUESTMSR 2
     
    95106    wrmsr
    96107  %endmacro
    97 
    98  %ifdef ASM_CALL64_GCC
    99   %macro MYPUSHAD 0
    100     push    r15
    101     push    r14
    102     push    r13
    103     push    r12
    104     push    rbx
    105   %endmacro
    106   %macro MYPOPAD 0
    107     pop     rbx
    108     pop     r12
    109     pop     r13
    110     pop     r14
    111     pop     r15
    112   %endmacro
    113 
    114  %else ; ASM_CALL64_MSC
    115   %macro MYPUSHAD 0
    116     push    r15
    117     push    r14
    118     push    r13
    119     push    r12
    120     push    rbx
    121     push    rsi
    122     push    rdi
    123   %endmacro
    124   %macro MYPOPAD 0
    125     pop     rdi
    126     pop     rsi
    127     pop     rbx
    128     pop     r12
    129     pop     r13
    130     pop     r14
    131     pop     r15
    132   %endmacro
    133  %endif
     108%endif
     109
     110%ifdef ASM_CALL64_GCC
     111 %macro MYPUSHAD64 0
     112   push    r15
     113   push    r14
     114   push    r13
     115   push    r12
     116   push    rbx
     117 %endmacro
     118 %macro MYPOPAD64 0
     119   pop     rbx
     120   pop     r12
     121   pop     r13
     122   pop     r14
     123   pop     r15
     124 %endmacro
     125
     126%else ; ASM_CALL64_MSC
     127 %macro MYPUSHAD64 0
     128   push    r15
     129   push    r14
     130   push    r13
     131   push    r12
     132   push    rbx
     133   push    rsi
     134   push    rdi
     135 %endmacro
     136 %macro MYPOPAD64 0
     137   pop     rdi
     138   pop     rsi
     139   pop     rbx
     140   pop     r12
     141   pop     r13
     142   pop     r14
     143   pop     r15
     144 %endmacro
     145%endif
    134146
    135147; trashes, rax, rdx & rcx
    136  %macro MYPUSHSEGS 2
    137     mov     %2, es
    138     push    %1
    139     mov     %2, ds
    140     push    %1
    141 
    142     ; Special case for FS; Windows and Linux either don't use it or restore it when leaving kernel mode, Solaris OTOH doesn't and we must save it.
    143     mov     ecx, MSR_K8_FS_BASE
    144     rdmsr
    145     push    rdx
    146     push    rax
    147     push    fs
    148 
    149     ; Special case for GS; OSes typically use swapgs to reset the hidden base register for GS on entry into the kernel. The same happens on exit
    150     mov     ecx, MSR_K8_GS_BASE
    151     rdmsr
    152     push    rdx
    153     push    rax
    154     push    gs
    155  %endmacro
     148%macro MYPUSHSEGS64 2
     149   mov     %2, es
     150   push    %1
     151   mov     %2, ds
     152   push    %1
     153
     154   ; Special case for FS; Windows and Linux either don't use it or restore it when leaving kernel mode, Solaris OTOH doesn't and we must save it.
     155   mov     ecx, MSR_K8_FS_BASE
     156   rdmsr
     157   push    rdx
     158   push    rax
     159   push    fs
     160
     161   ; Special case for GS; OSes typically use swapgs to reset the hidden base register for GS on entry into the kernel. The same happens on exit
     162   mov     ecx, MSR_K8_GS_BASE
     163   rdmsr
     164   push    rdx
     165   push    rax
     166   push    gs
     167%endmacro
    156168
    157169; trashes, rax, rdx & rcx
    158  %macro MYPOPSEGS 2
    159     ; Note: do not step through this code with a debugger!
    160     pop     gs
    161     pop     rax
    162     pop     rdx
    163     mov     ecx, MSR_K8_GS_BASE
    164     wrmsr
    165 
    166     pop     fs
    167     pop     rax
    168     pop     rdx
    169     mov     ecx, MSR_K8_FS_BASE
    170     wrmsr
    171     ; Now it's safe to step again
    172 
    173     pop     %1
    174     mov     ds, %2
    175     pop     %1
    176     mov     es, %2
    177  %endmacro
    178 
    179 %else ; RT_ARCH_X86
    180   %macro MYPUSHAD 0
    181     pushad
    182   %endmacro
    183   %macro MYPOPAD 0
    184     popad
    185   %endmacro
    186 
    187   %macro MYPUSHSEGS 2
    188     push    ds
    189     push    es
    190     push    fs
    191     push    gs
    192   %endmacro
    193   %macro MYPOPSEGS 2
    194     pop     gs
    195     pop     fs
    196     pop     es
    197     pop     ds
    198   %endmacro
    199 %endif
     170%macro MYPOPSEGS64 2
     171   ; Note: do not step through this code with a debugger!
     172   pop     gs
     173   pop     rax
     174   pop     rdx
     175   mov     ecx, MSR_K8_GS_BASE
     176   wrmsr
     177
     178   pop     fs
     179   pop     rax
     180   pop     rdx
     181   mov     ecx, MSR_K8_FS_BASE
     182   wrmsr
     183   ; Now it's safe to step again
     184
     185   pop     %1
     186   mov     ds, %2
     187   pop     %1
     188   mov     es, %2
     189%endmacro
     190
     191%macro MYPUSHAD32 0
     192  pushad
     193%endmacro
     194%macro MYPOPAD32 0
     195  popad
     196%endmacro
     197
     198%macro MYPUSHSEGS32 2
     199  push    ds
     200  push    es
     201  push    fs
     202  push    gs
     203%endmacro
     204%macro MYPOPSEGS32 2
     205  pop     gs
     206  pop     fs
     207  pop     es
     208  pop     ds
     209%endmacro
    200210
    201211
     
    220230; needing to clobber a register. (This trick doesn't quite work for PE btw.
    221231; but that's not relevant atm.)
    222 g_fIs64bit:
     232GLOBALNAME g_fVMXIs64bitHost
    223233    dd  NAME(SUPR0AbsIs64bit)
    224234%endif
     
    226236
    227237BEGINCODE
    228 
    229 ;/**
    230 ; * Prepares for and executes VMLAUNCH/VMRESUME (32 bits guest mode)
    231 ; *
    232 ; * @returns VBox status code
    233 ; * @param   fResume    vmlauch/vmresume
    234 ; * @param   pCtx       Guest context
    235 ; */
    236 BEGINPROC VMXR0StartVM32
    237     push    xBP
    238     mov     xBP, xSP
    239 
    240     pushf
    241     cli
    242 
    243     ;/* First we have to save some final CPU context registers. */
    244 %ifdef RT_ARCH_AMD64
    245     mov     rax, qword .vmlaunch_done
    246     push    rax
    247 %else
    248     push    .vmlaunch_done
    249 %endif
    250     mov     eax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
    251     vmwrite xAX, [xSP]
    252     ;/* Note: assumes success... */
    253     add     xSP, xS
    254 
    255     ;/* Manual save and restore:
    256     ; * - General purpose registers except RIP, RSP
    257     ; *
    258     ; * Trashed:
    259     ; * - CR2 (we don't care)
    260     ; * - LDTR (reset to 0)
    261     ; * - DRx (presumably not changed at all)
    262     ; * - DR7 (reset to 0x400)
    263     ; * - EFLAGS (reset to RT_BIT(1); not relevant)
    264     ; *
    265     ; */
    266 
    267     ;/* Save all general purpose host registers. */
    268     MYPUSHAD
    269 
    270     ;/* Save the Guest CPU context pointer. */
    271 %ifdef RT_ARCH_AMD64
    272  %ifdef ASM_CALL64_GCC
    273     ; fResume already in rdi
    274     ; pCtx    already in rsi
    275  %else
    276     mov     rdi, rcx        ; fResume
    277     mov     rsi, rdx        ; pCtx
    278  %endif
    279 %else
    280     mov     edi, [ebp + 8]  ; fResume
    281     mov     esi, [ebp + 12] ; pCtx
    282 %endif
    283 
    284     ;/* Save segment registers */
    285     ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case)
    286     MYPUSHSEGS xAX, ax
    287 
    288     ; Save the pCtx pointer
    289     push    xSI
    290 
    291     ; Save LDTR
    292     xor     eax, eax
    293     sldt    ax
    294     push    xAX
    295 
    296     ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
    297     sub     xSP, xS*2
    298     sgdt    [xSP]
    299 
    300     sub     xSP, xS*2
    301     sidt    [xSP]
    302 
    303 %ifdef VBOX_WITH_DR6_EXPERIMENT
    304     ; Restore DR6 - experiment, not safe!
    305     mov     xBX, [xSI + CPUMCTX.dr6]
    306     mov     dr6, xBX
    307 %endif
    308 
    309     ; Restore CR2
    310     mov     ebx, [xSI + CPUMCTX.cr2]
    311     mov     cr2, xBX
    312 
    313     mov     eax, VMX_VMCS_HOST_RSP
    314     vmwrite xAX, xSP
    315     ;/* Note: assumes success... */
    316     ;/* Don't mess with ESP anymore!! */
    317 
    318     ;/* Restore Guest's general purpose registers. */
    319     mov     eax, [xSI + CPUMCTX.eax]
    320     mov     ebx, [xSI + CPUMCTX.ebx]
    321     mov     ecx, [xSI + CPUMCTX.ecx]
    322     mov     edx, [xSI + CPUMCTX.edx]
    323     mov     ebp, [xSI + CPUMCTX.ebp]
    324 
    325     ; resume or start?
    326     cmp     xDI, 0                  ; fResume
    327     je      .vmlauch_lauch
    328 
    329     ;/* Restore edi & esi. */
    330     mov     edi, [xSI + CPUMCTX.edi]
    331     mov     esi, [xSI + CPUMCTX.esi]
    332 
    333     vmresume
    334     jmp     .vmlaunch_done;      ;/* here if vmresume detected a failure. */
    335 
    336 .vmlauch_lauch:
    337     ;/* Restore edi & esi. */
    338     mov     edi, [xSI + CPUMCTX.edi]
    339     mov     esi, [xSI + CPUMCTX.esi]
    340 
    341     vmlaunch
    342     jmp     .vmlaunch_done;      ;/* here if vmlaunch detected a failure. */
    343 
    344 ALIGNCODE(16)
    345 .vmlaunch_done:
    346     jc      near .vmxstart_invalid_vmxon_ptr
    347     jz      near .vmxstart_start_failed
    348 
    349     ; Restore base and limit of the IDTR & GDTR
    350     lidt    [xSP]
    351     add     xSP, xS*2
    352     lgdt    [xSP]
    353     add     xSP, xS*2
    354 
    355     push    xDI
    356     mov     xDI, [xSP + xS * 2]         ; pCtx
    357 
    358     mov     [ss:xDI + CPUMCTX.eax], eax
    359     mov     [ss:xDI + CPUMCTX.ebx], ebx
    360     mov     [ss:xDI + CPUMCTX.ecx], ecx
    361     mov     [ss:xDI + CPUMCTX.edx], edx
    362     mov     [ss:xDI + CPUMCTX.esi], esi
    363     mov     [ss:xDI + CPUMCTX.ebp], ebp
    364 %ifdef RT_ARCH_AMD64
    365     pop     xAX                                 ; the guest edi we pushed above
    366     mov     dword [ss:xDI + CPUMCTX.edi], eax
    367 %else
    368     pop     dword [ss:xDI + CPUMCTX.edi]        ; the guest edi we pushed above
    369 %endif
    370 
    371 %ifdef VBOX_WITH_DR6_EXPERIMENT
    372     ; Save DR6 - experiment, not safe!
    373     mov     xAX, dr6
    374     mov     [ss:xDI + CPUMCTX.dr6], xAX
    375 %endif
    376 
    377     pop     xAX         ; saved LDTR
    378     lldt    ax
    379 
    380     add     xSP, xS      ; pCtx
    381 
    382     ; Restore segment registers
    383     MYPOPSEGS xAX, ax
    384 
    385     ; Restore general purpose registers
    386     MYPOPAD
    387 
    388     mov     eax, VINF_SUCCESS
    389 
    390 .vmstart_end:
    391     popf
    392     pop     xBP
    393     ret
    394 
    395 
    396 .vmxstart_invalid_vmxon_ptr:
    397     ; Restore base and limit of the IDTR & GDTR
    398     lidt    [xSP]
    399     add     xSP, xS*2
    400     lgdt    [xSP]
    401     add     xSP, xS*2
    402 
    403     pop     xAX         ; saved LDTR
    404     lldt    ax
    405 
    406     add     xSP, xS     ; pCtx
    407 
    408     ; Restore segment registers
    409     MYPOPSEGS xAX, ax
    410 
    411     ; Restore all general purpose host registers.
    412     MYPOPAD
    413     mov     eax, VERR_VMX_INVALID_VMXON_PTR
    414     jmp     .vmstart_end
    415 
    416 .vmxstart_start_failed:
    417     ; Restore base and limit of the IDTR & GDTR
    418     lidt    [xSP]
    419     add     xSP, xS*2
    420     lgdt    [xSP]
    421     add     xSP, xS*2
    422 
    423     pop     xAX         ; saved LDTR
    424     lldt    ax
    425 
    426     add     xSP, xS     ; pCtx
    427 
    428     ; Restore segment registers
    429     MYPOPSEGS xAX, ax
    430 
    431     ; Restore all general purpose host registers.
    432     MYPOPAD
    433     mov     eax, VERR_VMX_UNABLE_TO_START_VM
    434     jmp     .vmstart_end
    435 
    436 ENDPROC VMXR0StartVM32
    437 
    438 %ifdef RT_ARCH_AMD64
    439 ;/**
    440 ; * Prepares for and executes VMLAUNCH/VMRESUME (64 bits guest mode)
    441 ; *
    442 ; * @returns VBox status code
    443 ; * @param   fResume    vmlauch/vmresume
    444 ; * @param   pCtx       Guest context
    445 ; */
    446 BEGINPROC VMXR0StartVM64
    447     push    xBP
    448     mov     xBP, xSP
    449 
    450     pushf
    451     cli
    452 
    453     ;/* First we have to save some final CPU context registers. */
    454     mov     rax, qword .vmlaunch64_done
    455     push    rax
    456     mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
    457     vmwrite rax, [xSP]
    458     ;/* Note: assumes success... */
    459     add     xSP, xS
    460 
    461     ;/* Manual save and restore:
    462     ; * - General purpose registers except RIP, RSP
    463     ; *
    464     ; * Trashed:
    465     ; * - CR2 (we don't care)
    466     ; * - LDTR (reset to 0)
    467     ; * - DRx (presumably not changed at all)
    468     ; * - DR7 (reset to 0x400)
    469     ; * - EFLAGS (reset to RT_BIT(1); not relevant)
    470     ; *
    471     ; */
    472 
    473     ;/* Save all general purpose host registers. */
    474     MYPUSHAD
    475 
    476     ;/* Save the Guest CPU context pointer. */
    477 %ifdef ASM_CALL64_GCC
    478     ; fResume already in rdi
    479     ; pCtx    already in rsi
    480 %else
    481     mov     rdi, rcx        ; fResume
    482     mov     rsi, rdx        ; pCtx
    483 %endif
    484 
    485     ;/* Save segment registers */
    486     ; Note: MYPUSHSEGS trashes rdx & rcx, so we moved it here (msvc amd64 case)
    487     MYPUSHSEGS xAX, ax
    488 
    489     ; Save the host LSTAR, CSTAR, SFMASK & KERNEL_GSBASE MSRs and restore the guest MSRs
    490     ;; @todo use the automatic load feature for MSRs
    491     LOADGUESTMSR MSR_K8_LSTAR, CPUMCTX.msrLSTAR
    492 %if 0  ; not supported on Intel CPUs
    493     LOADGUESTMSR MSR_K8_CSTAR, CPUMCTX.msrCSTAR
    494 %endif
    495     LOADGUESTMSR MSR_K6_STAR, CPUMCTX.msrSTAR
    496     LOADGUESTMSR MSR_K8_SF_MASK, CPUMCTX.msrSFMASK
    497     LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
    498 
    499     ; Save the pCtx pointer
    500     push    xSI
    501 
    502     ; Save LDTR
    503     xor     eax, eax
    504     sldt    ax
    505     push    xAX
    506 
    507     ; VMX only saves the base of the GDTR & IDTR and resets the limit to 0xffff; we must restore the limit correctly!
    508     sub     xSP, xS*2
    509     sgdt    [xSP]
    510 
    511     sub     xSP, xS*2
    512     sidt    [xSP]
    513 
    514 %ifdef VBOX_WITH_DR6_EXPERIMENT
    515     ; Restore DR6 - experiment, not safe!
    516     mov     xBX, [xSI + CPUMCTX.dr6]
    517     mov     dr6, xBX
    518 %endif
    519 
    520     ; Restore CR2
    521     mov     rbx, qword [xSI + CPUMCTX.cr2]
    522     mov     cr2, rbx
    523 
    524     mov     eax, VMX_VMCS_HOST_RSP
    525     vmwrite xAX, xSP
    526     ;/* Note: assumes success... */
    527     ;/* Don't mess with ESP anymore!! */
    528 
    529     ;/* Restore Guest's general purpose registers. */
    530     mov     rax, qword [xSI + CPUMCTX.eax]
    531     mov     rbx, qword [xSI + CPUMCTX.ebx]
    532     mov     rcx, qword [xSI + CPUMCTX.ecx]
    533     mov     rdx, qword [xSI + CPUMCTX.edx]
    534     mov     rbp, qword [xSI + CPUMCTX.ebp]
    535     mov     r8,  qword [xSI + CPUMCTX.r8]
    536     mov     r9,  qword [xSI + CPUMCTX.r9]
    537     mov     r10, qword [xSI + CPUMCTX.r10]
    538     mov     r11, qword [xSI + CPUMCTX.r11]
    539     mov     r12, qword [xSI + CPUMCTX.r12]
    540     mov     r13, qword [xSI + CPUMCTX.r13]
    541     mov     r14, qword [xSI + CPUMCTX.r14]
    542     mov     r15, qword [xSI + CPUMCTX.r15]
    543 
    544     ; resume or start?
    545     cmp     xDI, 0                  ; fResume
    546     je      .vmlauch64_lauch
    547 
    548     ;/* Restore edi & esi. */
    549     mov     rdi, qword [xSI + CPUMCTX.edi]
    550     mov     rsi, qword [xSI + CPUMCTX.esi]
    551 
    552     vmresume
    553     jmp     .vmlaunch64_done;      ;/* here if vmresume detected a failure. */
    554 
    555 .vmlauch64_lauch:
    556     ;/* Restore rdi & rsi. */
    557     mov     rdi, qword [xSI + CPUMCTX.edi]
    558     mov     rsi, qword [xSI + CPUMCTX.esi]
    559 
    560     vmlaunch
    561     jmp     .vmlaunch64_done;      ;/* here if vmlaunch detected a failure. */
    562 
    563 ALIGNCODE(16)
    564 .vmlaunch64_done:
    565     jc      near .vmxstart64_invalid_vmxon_ptr
    566     jz      near .vmxstart64_start_failed
    567 
    568     ; Restore base and limit of the IDTR & GDTR
    569     lidt    [xSP]
    570     add     xSP, xS*2
    571     lgdt    [xSP]
    572     add     xSP, xS*2
    573 
    574     push    xDI
    575     mov     xDI, [xSP + xS * 2]         ; pCtx
    576 
    577     mov     qword [xDI + CPUMCTX.eax], rax
    578     mov     qword [xDI + CPUMCTX.ebx], rbx
    579     mov     qword [xDI + CPUMCTX.ecx], rcx
    580     mov     qword [xDI + CPUMCTX.edx], rdx
    581     mov     qword [xDI + CPUMCTX.esi], rsi
    582     mov     qword [xDI + CPUMCTX.ebp], rbp
    583     mov     qword [xDI + CPUMCTX.r8],  r8
    584     mov     qword [xDI + CPUMCTX.r9],  r9
    585     mov     qword [xDI + CPUMCTX.r10], r10
    586     mov     qword [xDI + CPUMCTX.r11], r11
    587     mov     qword [xDI + CPUMCTX.r12], r12
    588     mov     qword [xDI + CPUMCTX.r13], r13
    589     mov     qword [xDI + CPUMCTX.r14], r14
    590     mov     qword [xDI + CPUMCTX.r15], r15
    591 
    592     pop     xAX                                 ; the guest edi we pushed above
    593     mov     qword [xDI + CPUMCTX.edi], rax
    594 
    595 %ifdef VBOX_WITH_DR6_EXPERIMENT
    596     ; Save DR6 - experiment, not safe!
    597     mov     xAX, dr6
    598     mov     [xDI + CPUMCTX.dr6], xAX
    599 %endif
    600 
    601     pop     xAX         ; saved LDTR
    602     lldt    ax
    603 
    604     pop     xSI         ; pCtx (needed in rsi by the macros below)
    605 
    606     ; Restore the host LSTAR, CSTAR, SFMASK & KERNEL_GSBASE MSRs
    607     ;; @todo use the automatic load feature for MSRs
    608     LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
    609     LOADHOSTMSR MSR_K8_SF_MASK
    610     LOADHOSTMSR MSR_K6_STAR
    611 %if 0  ; not supported on Intel CPUs
    612     LOADHOSTMSR MSR_K8_CSTAR
    613 %endif
    614     LOADHOSTMSR MSR_K8_LSTAR
    615 
    616     ; Restore segment registers
    617     MYPOPSEGS xAX, ax
    618 
    619     ; Restore general purpose registers
    620     MYPOPAD
    621 
    622     mov     eax, VINF_SUCCESS
    623 
    624 .vmstart64_end:
    625     popf
    626     pop     xBP
    627     ret
    628 
    629 
    630 .vmxstart64_invalid_vmxon_ptr:
    631     ; Restore base and limit of the IDTR & GDTR
    632     lidt    [xSP]
    633     add     xSP, xS*2
    634     lgdt    [xSP]
    635     add     xSP, xS*2
    636 
    637     pop     xAX         ; saved LDTR
    638     lldt    ax
    639 
    640     pop     xSI         ; pCtx (needed in rsi by the macros below)
    641 
    642     ; Restore the host LSTAR, CSTAR, SFMASK & KERNEL_GSBASE MSRs
    643     ;; @todo use the automatic load feature for MSRs
    644     LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
    645     LOADHOSTMSR MSR_K8_SF_MASK
    646     LOADHOSTMSR MSR_K6_STAR
    647 %if 0  ; not supported on Intel CPUs
    648     LOADHOSTMSR MSR_K8_CSTAR
    649 %endif
    650     LOADHOSTMSR MSR_K8_LSTAR
    651 
    652     ; Restore segment registers
    653     MYPOPSEGS xAX, ax
    654 
    655     ; Restore all general purpose host registers.
    656     MYPOPAD
    657     mov     eax, VERR_VMX_INVALID_VMXON_PTR
    658     jmp     .vmstart64_end
    659 
    660 .vmxstart64_start_failed:
    661     ; Restore base and limit of the IDTR & GDTR
    662     lidt    [xSP]
    663     add     xSP, xS*2
    664     lgdt    [xSP]
    665     add     xSP, xS*2
    666 
    667     pop     xAX         ; saved LDTR
    668     lldt    ax
    669 
    670     pop     xSI         ; pCtx (needed in rsi by the macros below)
    671 
    672     ; Restore the host LSTAR, CSTAR, SFMASK & KERNEL_GSBASE MSRs
    673     ;; @todo use the automatic load feature for MSRs
    674     LOADHOSTMSREX MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
    675     LOADHOSTMSR MSR_K8_SF_MASK
    676     LOADHOSTMSR MSR_K6_STAR
    677 %if 0  ; not supported on Intel CPUs
    678     LOADHOSTMSR MSR_K8_CSTAR
    679 %endif
    680     LOADHOSTMSR MSR_K8_LSTAR
    681 
    682     ; Restore segment registers
    683     MYPOPSEGS xAX, ax
    684 
    685     ; Restore all general purpose host registers.
    686     MYPOPAD
    687     mov     eax, VERR_VMX_UNABLE_TO_START_VM
    688     jmp     .vmstart64_end
    689 ENDPROC VMXR0StartVM64
    690 %endif ; RT_ARCH_AMD64
    691238
    692239
     
    713260    lea         edx, [esp + 8]          ; &u64Data
    714261 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    715     cmp         byte [g_fIs64bit], 0
     262    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
    716263    jne         .longmode
    717264 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    783330    mov         edx, [esp + 8]          ; pData
    784331 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    785     cmp         byte [g_fIs64bit], 0
     332    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
    786333    jne         .longmode
    787334 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    855402    mov     edx, [esp + 8]              ; pu32Data
    856403 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    857     cmp     byte [g_fIs64bit], 0
     404    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    858405    jne     .longmode
    859406 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    923470    mov     edx, [esp + 8]              ; u32Data
    924471 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    925     cmp     byte [g_fIs64bit], 0
     472    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    926473    jne     .longmode
    927474 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    983530%else  ; RT_ARCH_X86
    984531 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    985     cmp     byte [g_fIs64bit], 0
     532    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    986533    jne     .longmode
    987534 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1036583BEGINPROC VMXDisable
    1037584%ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1038     cmp     byte [g_fIs64bit], 0
     585    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    1039586    jne     .longmode
    1040587%endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1080627%else  ; RT_ARCH_X86
    1081628 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1082     cmp     byte [g_fIs64bit], 0
     629    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    1083630    jne     .longmode
    1084631 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1137684%else
    1138685 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1139     cmp     byte [g_fIs64bit], 0
     686    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    1140687    jne     .longmode
    1141688 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1196743 %else
    1197744  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1198     cmp     byte [g_fIs64bit], 0
     745    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
    1199746    jne     .longmode
    1200747  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1248795%else
    1249796 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1250     cmp         byte [g_fIs64bit], 0
     797    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
    1251798    jne         .longmode
    1252799 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1316863%else
    1317864 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1318     cmp         byte [g_fIs64bit], 0
     865    cmp         byte [NAME(g_fVMXIs64bitHost)], 0
    1319866    jne         .longmode
    1320867 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
     
    1361908%endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1362909ENDPROC VMXR0InvVPID
    1363 
    1364 
    1365 ;/**
    1366 ; * Prepares for and executes VMRUN (32 bits guests)
    1367 ; *
    1368 ; * @returns VBox status code
    1369 ; * @param   HCPhysVMCB     Physical address of host VMCB
    1370 ; * @param   HCPhysVMCB     Physical address of guest VMCB
    1371 ; * @param   pCtx           Guest context
    1372 ; */
    1373 BEGINPROC SVMR0VMRun
    1374 %ifdef RT_ARCH_AMD64 ; fake a cdecl stack frame
    1375  %ifdef ASM_CALL64_GCC
    1376     push    rdx
    1377     push    rsi
    1378     push    rdi
    1379  %else
    1380     push    r8
    1381     push    rdx
    1382     push    rcx
    1383  %endif
    1384     push    0
    1385 %endif
    1386     push    xBP
    1387     mov     xBP, xSP
    1388     pushf
    1389 
    1390     ;/* Manual save and restore:
    1391     ; * - General purpose registers except RIP, RSP, RAX
    1392     ; *
    1393     ; * Trashed:
    1394     ; * - CR2 (we don't care)
    1395     ; * - LDTR (reset to 0)
    1396     ; * - DRx (presumably not changed at all)
    1397     ; * - DR7 (reset to 0x400)
    1398     ; */
    1399 
    1400     ;/* Save all general purpose host registers. */
    1401     MYPUSHAD
    1402 
    1403     ;/* Save the Guest CPU context pointer. */
    1404     mov     xSI, [xBP + xS*2 + RTHCPHYS_CB*2]   ; pCtx
    1405     push    xSI                     ; push for saving the state at the end
    1406 
    1407     ; Restore CR2
    1408     mov     ebx, [xSI + CPUMCTX.cr2]
    1409     mov     cr2, xBX
    1410 
    1411     ; save host fs, gs, sysenter msr etc
    1412     mov     xAX, [xBP + xS*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
    1413     push    xAX                     ; save for the vmload after vmrun
    1414     vmsave
    1415 
    1416     ; setup eax for VMLOAD
    1417     mov     xAX, [xBP + xS*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
    1418 
    1419     ;/* Restore Guest's general purpose registers. */
    1420     ;/* EAX is loaded from the VMCB by VMRUN */
    1421     mov     ebx, [xSI + CPUMCTX.ebx]
    1422     mov     ecx, [xSI + CPUMCTX.ecx]
    1423     mov     edx, [xSI + CPUMCTX.edx]
    1424     mov     edi, [xSI + CPUMCTX.edi]
    1425     mov     ebp, [xSI + CPUMCTX.ebp]
    1426     mov     esi, [xSI + CPUMCTX.esi]
    1427 
    1428     ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
    1429     clgi
    1430     sti
    1431 
    1432     ; load guest fs, gs, sysenter msr etc
    1433     vmload
    1434     ; run the VM
    1435     vmrun
    1436 
    1437     ;/* EAX is in the VMCB already; we can use it here. */
    1438 
    1439     ; save guest fs, gs, sysenter msr etc
    1440     vmsave
    1441 
    1442     ; load host fs, gs, sysenter msr etc
    1443     pop     xAX                     ; pushed above
    1444     vmload
    1445 
    1446     ; Set the global interrupt flag again, but execute cli to make sure IF=0.
    1447     cli
    1448     stgi
    1449 
    1450     pop     xAX                     ; pCtx
    1451 
    1452     mov     [ss:xAX + CPUMCTX.ebx], ebx
    1453     mov     [ss:xAX + CPUMCTX.ecx], ecx
    1454     mov     [ss:xAX + CPUMCTX.edx], edx
    1455     mov     [ss:xAX + CPUMCTX.esi], esi
    1456     mov     [ss:xAX + CPUMCTX.edi], edi
    1457     mov     [ss:xAX + CPUMCTX.ebp], ebp
    1458 
    1459     ; Restore general purpose registers
    1460     MYPOPAD
    1461 
    1462     mov     eax, VINF_SUCCESS
    1463 
    1464     popf
    1465     pop     xBP
    1466 %ifdef RT_ARCH_AMD64
    1467     add     xSP, 4*xS
    1468 %endif
    1469     ret
    1470 ENDPROC SVMR0VMRun
    1471 
    1472 %ifdef RT_ARCH_AMD64
    1473 ;/**
    1474 ; * Prepares for and executes VMRUN (64 bits guests)
    1475 ; *
    1476 ; * @returns VBox status code
    1477 ; * @param   HCPhysVMCB     Physical address of host VMCB
    1478 ; * @param   HCPhysVMCB     Physical address of guest VMCB
    1479 ; * @param   pCtx           Guest context
    1480 ; */
    1481 BEGINPROC SVMR0VMRun64
    1482     ; fake a cdecl stack frame
    1483  %ifdef ASM_CALL64_GCC
    1484     push    rdx
    1485     push    rsi
    1486     push    rdi
    1487  %else
    1488     push    r8
    1489     push    rdx
    1490     push    rcx
    1491  %endif
    1492     push    0
    1493     push    rbp
    1494     mov     rbp, rsp
    1495     pushf
    1496 
    1497     ;/* Manual save and restore:
    1498     ; * - General purpose registers except RIP, RSP, RAX
    1499     ; *
    1500     ; * Trashed:
    1501     ; * - CR2 (we don't care)
    1502     ; * - LDTR (reset to 0)
    1503     ; * - DRx (presumably not changed at all)
    1504     ; * - DR7 (reset to 0x400)
    1505     ; */
    1506 
    1507     ;/* Save all general purpose host registers. */
    1508     MYPUSHAD
    1509 
    1510     ;/* Save the Guest CPU context pointer. */
    1511     mov     rsi, [rbp + xS*2 + RTHCPHYS_CB*2]   ; pCtx
    1512     push    rsi                     ; push for saving the state at the end
    1513 
    1514     ; Restore CR2
    1515     mov     rbx, [rsi + CPUMCTX.cr2]
    1516     mov     cr2, rbx
    1517 
    1518     ; save host fs, gs, sysenter msr etc
    1519     mov     rax, [rbp + xS*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
    1520     push    rax                     ; save for the vmload after vmrun
    1521     vmsave
    1522 
    1523     ; setup eax for VMLOAD
    1524     mov     rax, [rbp + xS*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
    1525 
    1526     ;/* Restore Guest's general purpose registers. */
    1527     ;/* RAX is loaded from the VMCB by VMRUN */
    1528     mov     rbx, qword [xSI + CPUMCTX.ebx]
    1529     mov     rcx, qword [xSI + CPUMCTX.ecx]
    1530     mov     rdx, qword [xSI + CPUMCTX.edx]
    1531     mov     rdi, qword [xSI + CPUMCTX.edi]
    1532     mov     rbp, qword [xSI + CPUMCTX.ebp]
    1533     mov     r8,  qword [xSI + CPUMCTX.r8]
    1534     mov     r9,  qword [xSI + CPUMCTX.r9]
    1535     mov     r10, qword [xSI + CPUMCTX.r10]
    1536     mov     r11, qword [xSI + CPUMCTX.r11]
    1537     mov     r12, qword [xSI + CPUMCTX.r12]
    1538     mov     r13, qword [xSI + CPUMCTX.r13]
    1539     mov     r14, qword [xSI + CPUMCTX.r14]
    1540     mov     r15, qword [xSI + CPUMCTX.r15]
    1541     mov     rsi, qword [xSI + CPUMCTX.esi]
    1542 
    1543     ; Clear the global interrupt flag & execute sti to make sure external interrupts cause a world switch
    1544     clgi
    1545     sti
    1546 
    1547     ; load guest fs, gs, sysenter msr etc
    1548     vmload
    1549     ; run the VM
    1550     vmrun
    1551 
    1552     ;/* RAX is in the VMCB already; we can use it here. */
    1553 
    1554     ; save guest fs, gs, sysenter msr etc
    1555     vmsave
    1556 
    1557     ; load host fs, gs, sysenter msr etc
    1558     pop     rax                     ; pushed above
    1559     vmload
    1560 
    1561     ; Set the global interrupt flag again, but execute cli to make sure IF=0.
    1562     cli
    1563     stgi
    1564 
    1565     pop     rax                     ; pCtx
    1566 
    1567     mov     qword [rax + CPUMCTX.ebx], rbx
    1568     mov     qword [rax + CPUMCTX.ecx], rcx
    1569     mov     qword [rax + CPUMCTX.edx], rdx
    1570     mov     qword [rax + CPUMCTX.esi], rsi
    1571     mov     qword [rax + CPUMCTX.edi], rdi
    1572     mov     qword [rax + CPUMCTX.ebp], rbp
    1573     mov     qword [rax + CPUMCTX.r8],  r8
    1574     mov     qword [rax + CPUMCTX.r9],  r9
    1575     mov     qword [rax + CPUMCTX.r10], r10
    1576     mov     qword [rax + CPUMCTX.r11], r11
    1577     mov     qword [rax + CPUMCTX.r12], r12
    1578     mov     qword [rax + CPUMCTX.r13], r13
    1579     mov     qword [rax + CPUMCTX.r14], r14
    1580     mov     qword [rax + CPUMCTX.r15], r15
    1581 
    1582     ; Restore general purpose registers
    1583     MYPOPAD
    1584 
    1585     mov     eax, VINF_SUCCESS
    1586 
    1587     popf
    1588     pop     rbp
    1589     add     rsp, 4*xS
    1590     ret
    1591 ENDPROC SVMR0VMRun64
    1592 %endif ; RT_ARCH_AMD64
    1593910
    1594911
     
    1622939ENDPROC SVMR0InvlpgA
    1623940
    1624 %else
     941%else ; GC_ARCH_BITS != 64
    1625942;;
    1626943; Executes INVLPGA
     
    1653970%endif ; GC_ARCH_BITS != 64
    1654971
     972
     973
     974;
     975; The default setup of the StartVM routines.
     976;
     977%ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
     978 %define MY_NAME(name)   name %+ _32
     979%else
     980 %define MY_NAME(name)   name
     981%endif
     982%ifdef RT_ARCH_AMD64
     983 %define MYPUSHAD       MYPUSHAD64
     984 %define MYPOPAD        MYPOPAD64
     985 %define MYPUSHSEGS     MYPUSHSEGS64
     986 %define MYPOPSEGS      MYPOPSEGS64
     987%else
     988 %define MYPUSHAD       MYPUSHAD32
     989 %define MYPOPAD        MYPOPAD32
     990 %define MYPUSHSEGS     MYPUSHSEGS32
     991 %define MYPOPSEGS      MYPOPSEGS32
     992%endif
     993
     994%include "HWACCMR0Mixed.mac"
     995
     996
     997%ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
     998 ;
     999 ; Write the wrapper procedures.
     1000 ;
     1001
     1002; DECLASM(int) VMXR0StartVM32(RTHCUINT fResume, PCPUMCTX pCtx);
     1003BEGINPROC VMXR0StartVM32
     1004    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
     1005    je near NAME(VMXR0StartVM32_32)
     1006
     1007    ; stack frame.
     1008    push    ebp
     1009    mov     ebp, esp
     1010    push    esi
     1011    push    edi
     1012    and     esp, 0fffffff0h
     1013
     1014    ; retf frame (64 -> 32).
     1015    push    0
     1016    push    cs
     1017    push    0
     1018    push    .thunk32
     1019
     1020    ; jmp far .thunk64
     1021    db      0xea
     1022    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
     1023BITS 64
     1024.thunk64:
     1025    and     esp, 0ffffffffh
     1026    and     ebp, 0ffffffffh
     1027    mov     edi, [rbp + 8]              ; fResume
     1028    mov     esi, [rbp + 12]             ; pCtx
     1029    sub     rsp, 20h
     1030    call    NAME(VMXR0StartVM32_64)
     1031    add     rsp, 20h
     1032    retf
     1033BITS 32
     1034.thunk32:
     1035    mov     esi, [ebp - 4]
     1036    mov     edi, [ebp - 8]
     1037    leave
     1038    ret
     1039ENDPROC   VMXR0StartVM32
     1040
     1041; DECLASM(int) VMXR0StartVM64(RTHCUINT fResume, PCPUMCTX pCtx)
     1042BEGINPROC VMXR0StartVM64
     1043    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
     1044    jne     .longmode
     1045    mov     eax, VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE
     1046    ret
     1047
     1048.longmode:
     1049    ; stack frame.
     1050    push    ebp
     1051    mov     ebp, esp
     1052    push    esi
     1053    push    edi
     1054    and     esp, 0fffffff0h
     1055
     1056    ; retf frame (64 -> 32).
     1057    push    0
     1058    push    cs
     1059    push    0
     1060    push    .thunk32
     1061
     1062    ; jmp far .thunk64
     1063    db      0xea
     1064    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
     1065BITS 64
     1066.thunk64:
     1067    and     esp, 0ffffffffh
     1068    and     ebp, 0ffffffffh
     1069    mov     edi, [rbp + 8]              ; fResume
     1070    mov     esi, [rbp + 12]             ; pCtx
     1071    sub     rsp, 20h
     1072    call    NAME(VMXR0StartVM64_64)
     1073    add     rsp, 20h
     1074    retf
     1075BITS 32
     1076.thunk32:
     1077    mov     esi, [ebp - 4]
     1078    mov     edi, [ebp - 8]
     1079    leave
     1080    ret
     1081ENDPROC   VMXR0StartVM64
     1082
     1083;DECLASM(int) SVMR0VMRun(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx);
     1084BEGINPROC SVMR0VMRun
     1085    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
     1086    je near NAME(SVMR0VMRun_32)
     1087
     1088    ; stack frame.
     1089    push    ebp
     1090    mov     ebp, esp
     1091    push    esi
     1092    push    edi
     1093    and     esp, 0fffffff0h
     1094
     1095    ; retf frame (64 -> 32).
     1096    push    0
     1097    push    cs
     1098    push    0
     1099    push    .thunk32
     1100
     1101    ; jmp far .thunk64
     1102    db      0xea
     1103    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
     1104BITS 64
     1105.thunk64:
     1106    and     esp, 0ffffffffh
     1107    and     ebp, 0ffffffffh
     1108    mov     rdi, [rbp + 8]              ; pVMCBHostPhys
     1109    mov     rsi, [rbp + 16]             ; pVMCBPhys
     1110    mov     edx, [rbp + 24]             ; pCtx
     1111    sub     rsp, 20h
     1112    call    NAME(SVMR0VMRun_64)
     1113    add     rsp, 20h
     1114    retf
     1115BITS 32
     1116.thunk32:
     1117    mov     esi, [ebp - 4]
     1118    mov     edi, [ebp - 8]
     1119    leave
     1120    ret
     1121ENDPROC   SVMR0VMRun
     1122
     1123; DECLASM(int) SVMR0VMRun64(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx);
     1124BEGINPROC SVMR0VMRun64
     1125    cmp     byte [NAME(g_fVMXIs64bitHost)], 0
     1126    jne     .longmode
     1127    mov     eax, VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE
     1128    ret
     1129
     1130.longmode:
     1131    ; stack frame.
     1132    push    ebp
     1133    mov     ebp, esp
     1134    push    esi
     1135    push    edi
     1136    and     esp, 0fffffff0h
     1137
     1138    ; retf frame (64 -> 32).
     1139    push    0
     1140    push    cs
     1141    push    0
     1142    push    .thunk32
     1143
     1144    ; jmp far .thunk64
     1145    db      0xea
     1146    dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
     1147BITS 64
     1148.thunk64:
     1149    and     esp, 0ffffffffh
     1150    and     ebp, 0ffffffffh
     1151    mov     rdi, [rbp + 8]              ; pVMCBHostPhys
     1152    mov     rsi, [rbp + 16]             ; pVMCBPhys
     1153    mov     edx, [rbp + 24]             ; pCtx
     1154    sub     rsp, 20h
     1155    call    NAME(SVMR0VMRun64_64)
     1156    add     rsp, 20h
     1157    retf
     1158BITS 32
     1159.thunk32:
     1160    mov     esi, [ebp - 4]
     1161    mov     edi, [ebp - 8]
     1162    leave
     1163    ret
     1164ENDPROC   SVMR0VMRun64
     1165
     1166 ;
     1167 ; Do it a second time pretending we're a 64-bit host.
     1168 ;
     1169 ; This *HAS* to be done at the very end of the file to avoid restoring
     1170 ; macros. So, add new code *BEFORE* this mess.
     1171 ;
     1172 BITS 64
     1173 %undef RT_ARCH_X86
     1174 %define RT_ARCH_AMD64
     1175 %define xS             8
     1176 %define xSP            rsp
     1177 %define xBP            rbp
     1178 %define xAX            rax
     1179 %define xBX            rbx
     1180 %define xCX            rcx
     1181 %define xDX            rdx
     1182 %define xDI            rdi
     1183 %define xSI            rsi
     1184 %define MY_NAME(name)   name %+ _64
     1185 %define MYPUSHAD       MYPUSHAD64
     1186 %define MYPOPAD        MYPOPAD64
     1187 %define MYPUSHSEGS     MYPUSHSEGS64
     1188 %define MYPOPSEGS      MYPOPSEGS64
     1189
     1190 %include "HWACCMR0Mixed.mac"
     1191%endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0Mixed.mac

    r14799 r14802  
    11; $Id$
    22;; @file
    3 ; VMXM - R0 vmx helpers
     3; HWACCMR0Mixed.mac - Stuff that darwin needs to build two versions of.
     4;
     5; Included by HWACCMR0A.asm with RT_ARCH_AMD64 defined or or undefined.
    46;
    57
     
    2022;
    2123
    22 ;*******************************************************************************
    23 ;* Header Files                                                                *
    24 ;*******************************************************************************
    25 %include "VBox/asmdefs.mac"
    26 %include "VBox/err.mac"
    27 %include "VBox/hwacc_vmx.mac"
    28 %include "VBox/cpum.mac"
    29 %include "VBox/x86.mac"
    30 
    31 %ifdef RT_OS_OS2 ;; @todo fix OMF support in yasm and kick nasm out completely.
    32  %macro vmwrite 2,
    33     int3
    34  %endmacro
    35  %define vmlaunch int3
    36  %define vmresume int3
    37  %define vmsave int3
    38  %define vmload int3
    39  %define vmrun int3
    40  %define clgi int3
    41  %define stgi int3
    42  %macro invlpga 2,
    43     int3
    44  %endmacro
    45 %endif
    46 
    47 ;; This is too risky wrt. stability, performance and correctness.
    48 ;%define VBOX_WITH_DR6_EXPERIMENT 1
    49 
    50 ;; @def MYPUSHAD
    51 ; Macro generating an equivalent to pushad
    52 
    53 ;; @def MYPOPAD
    54 ; Macro generating an equivalent to popad
    55 
    56 ;; @def MYPUSHSEGS
    57 ; Macro saving all segment registers on the stack.
    58 ; @param 1  full width register name
    59 ; @param 2  16-bit regsiter name for \a 1.
    60 
    61 ;; @def MYPOPSEGS
    62 ; Macro restoring all segment registers on the stack
    63 ; @param 1  full width register name
    64 ; @param 2  16-bit regsiter name for \a 1.
    65 
    66 %ifdef RT_ARCH_AMD64
    67   ; Save a host and load the corresponding guest MSR (trashes rdx & rcx)
    68   %macro LOADGUESTMSR 2
    69     mov     rcx, %1
    70     rdmsr
    71     push    rdx
    72     push    rax
    73     mov     edx, dword [xSI + %2 + 4]
    74     mov     eax, dword [xSI + %2]
    75     wrmsr
    76   %endmacro
    77 
    78   ; Save a guest and load the corresponding host MSR (trashes rdx & rcx)
    79   ; Only really useful for gs kernel base as that one can be changed behind our back (swapgs)
    80   %macro LOADHOSTMSREX 2
    81     mov     rcx, %1
    82     rdmsr
    83     mov     dword [xSI + %2], eax
    84     mov     dword [xSI + %2 + 4], edx
    85     pop     rax
    86     pop     rdx
    87     wrmsr
    88   %endmacro
    89 
    90   ; Load the corresponding host MSR (trashes rdx & rcx)
    91   %macro LOADHOSTMSR 1
    92     mov     rcx, %1
    93     pop     rax
    94     pop     rdx
    95     wrmsr
    96   %endmacro
    97 
    98  %ifdef ASM_CALL64_GCC
    99   %macro MYPUSHAD 0
    100     push    r15
    101     push    r14
    102     push    r13
    103     push    r12
    104     push    rbx
    105   %endmacro
    106   %macro MYPOPAD 0
    107     pop     rbx
    108     pop     r12
    109     pop     r13
    110     pop     r14
    111     pop     r15
    112   %endmacro
    113 
    114  %else ; ASM_CALL64_MSC
    115   %macro MYPUSHAD 0
    116     push    r15
    117     push    r14
    118     push    r13
    119     push    r12
    120     push    rbx
    121     push    rsi
    122     push    rdi
    123   %endmacro
    124   %macro MYPOPAD 0
    125     pop     rdi
    126     pop     rsi
    127     pop     rbx
    128     pop     r12
    129     pop     r13
    130     pop     r14
    131     pop     r15
    132   %endmacro
    133  %endif
    134 
    135 ; trashes, rax, rdx & rcx
    136  %macro MYPUSHSEGS 2
    137     mov     %2, es
    138     push    %1
    139     mov     %2, ds
    140     push    %1
    141 
    142     ; Special case for FS; Windows and Linux either don't use it or restore it when leaving kernel mode, Solaris OTOH doesn't and we must save it.
    143     mov     ecx, MSR_K8_FS_BASE
    144     rdmsr
    145     push    rdx
    146     push    rax
    147     push    fs
    148 
    149     ; Special case for GS; OSes typically use swapgs to reset the hidden base register for GS on entry into the kernel. The same happens on exit
    150     mov     ecx, MSR_K8_GS_BASE
    151     rdmsr
    152     push    rdx
    153     push    rax
    154     push    gs
    155  %endmacro
    156 
    157 ; trashes, rax, rdx & rcx
    158  %macro MYPOPSEGS 2
    159     ; Note: do not step through this code with a debugger!
    160     pop     gs
    161     pop     rax
    162     pop     rdx
    163     mov     ecx, MSR_K8_GS_BASE
    164     wrmsr
    165 
    166     pop     fs
    167     pop     rax
    168     pop     rdx
    169     mov     ecx, MSR_K8_FS_BASE
    170     wrmsr
    171     ; Now it's safe to step again
    172 
    173     pop     %1
    174     mov     ds, %2
    175     pop     %1
    176     mov     es, %2
    177  %endmacro
    178 
    179 %else ; RT_ARCH_X86
    180   %macro MYPUSHAD 0
    181     pushad
    182   %endmacro
    183   %macro MYPOPAD 0
    184     popad
    185   %endmacro
    186 
    187   %macro MYPUSHSEGS 2
    188     push    ds
    189     push    es
    190     push    fs
    191     push    gs
    192   %endmacro
    193   %macro MYPOPSEGS 2
    194     pop     gs
    195     pop     fs
    196     pop     es
    197     pop     ds
    198   %endmacro
    199 %endif
    200 
    201 
    202 ;*******************************************************************************
    203 ;* External Symbols                                                            *
    204 ;*******************************************************************************
    205 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    206 extern NAME(SUPR0AbsIs64bit)
    207 extern NAME(SUPR0Abs64bitKernelCS)
    208 extern NAME(SUPR0Abs64bitKernelSS)
    209 extern NAME(SUPR0Abs64bitKernelDS)
    210 %endif
    211 
    212 
    213 ;*******************************************************************************
    214 ;*  Global Variables                                                           *
    215 ;*******************************************************************************
    216 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    217 BEGINDATA
    218 ;;
    219 ; Store the SUPR0AbsIs64bit absolute value here so we can cmp/test without
    220 ; needing to clobber a register. (This trick doesn't quite work for PE btw.
    221 ; but that's not relevant atm.)
    222 g_fIs64bit:
    223     dd  NAME(SUPR0AbsIs64bit)
    224 %endif
    225 
    226 
    227 BEGINCODE
    22824
    22925;/**
     
    23430; * @param   pCtx       Guest context
    23531; */
    236 BEGINPROC VMXR0StartVM32
     32BEGINPROC MY_NAME(VMXR0StartVM32)
    23733    push    xBP
    23834    mov     xBP, xSP
     
    24339    ;/* First we have to save some final CPU context registers. */
    24440%ifdef RT_ARCH_AMD64
    245     mov     rax, qword .vmlaunch_done
     41    lea     rax, [.vmlaunch_done wrt rip]
    24642    push    rax
    24743%else
     
    434230    jmp     .vmstart_end
    435231
    436 ENDPROC VMXR0StartVM32
     232ENDPROC MY_NAME(VMXR0StartVM32)
    437233
    438234%ifdef RT_ARCH_AMD64
     
    444240; * @param   pCtx       Guest context
    445241; */
    446 BEGINPROC VMXR0StartVM64
     242BEGINPROC MY_NAME(VMXR0StartVM64)
    447243    push    xBP
    448244    mov     xBP, xSP
     
    452248
    453249    ;/* First we have to save some final CPU context registers. */
    454     mov     rax, qword .vmlaunch64_done
     250    lea     rax, [.vmlaunch64_done wrt rip]
    455251    push    rax
    456252    mov     rax, VMX_VMCS_HOST_RIP  ;/* return address (too difficult to continue after VMLAUNCH?) */
     
    687483    mov     eax, VERR_VMX_UNABLE_TO_START_VM
    688484    jmp     .vmstart64_end
    689 ENDPROC VMXR0StartVM64
     485ENDPROC MY_NAME(VMXR0StartVM64)
    690486%endif ; RT_ARCH_AMD64
    691 
    692 
    693 ;/**
    694 ; * Executes VMWRITE, 64-bit value.
    695 ; *
    696 ; * @returns VBox status code
    697 ; * @param   idxField   x86: [ebp + 08h]  msc: rcx  gcc: rdi   VMCS index
    698 ; * @param   u64Data    x86: [ebp + 0ch]  msc: rdx  gcc: rsi   VM field value
    699 ; */
    700 BEGINPROC VMXWriteVMCS64
    701 %ifdef RT_ARCH_AMD64
    702  %ifdef ASM_CALL64_GCC
    703     and         edi, 0ffffffffh
    704     xor         rax, rax
    705     vmwrite     rdi, rsi
    706  %else
    707     and         ecx, 0ffffffffh
    708     xor         rax, rax
    709     vmwrite     rcx, rdx
    710  %endif
    711 %else  ; RT_ARCH_X86
    712     mov         ecx, [esp + 4]          ; idxField
    713     lea         edx, [esp + 8]          ; &u64Data
    714  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    715     cmp         byte [g_fIs64bit], 0
    716     jne         .longmode
    717  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    718     vmwrite     ecx, [edx]              ; low dword
    719     jz          .done
    720     jc          .done
    721     inc         ecx
    722     xor         eax, eax
    723     vmwrite     ecx, [edx + 4]          ; high dword
    724 .done:
    725 %endif ; RT_ARCH_X86
    726     jnc         .valid_vmcs
    727     mov         eax, VERR_VMX_INVALID_VMCS_PTR
    728     ret
    729 .valid_vmcs:
    730     jnz         .the_end
    731     mov         eax, VERR_VMX_INVALID_VMCS_FIELD
    732 .the_end:
    733     ret
    734 
    735 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    736 .longmode:
    737     ; Convert return frame into a retf frame 64-bit -> 32-bit
    738     xor     eax, eax
    739     xchg    eax, [esp]
    740     push    cs
    741     push    0
    742     push    eax                         ; original return address.
    743     ; jmp far .thunk64
    744     db      0xea
    745     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    746 BITS 64
    747 .thunk64:
    748     and     edx, 0ffffffffh
    749     and     ecx, 0ffffffffh
    750     xor     eax, eax
    751     vmwrite rcx, [rdx]
    752     mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
    753     cmovz   eax, r8d
    754     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    755     cmovc   eax, r9d
    756     retf                                ; return to caller
    757 BITS 32
    758 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    759 ENDPROC VMXWriteVMCS64
    760 
    761 
    762 ;/**
    763 ; * Executes VMREAD, 64-bit value
    764 ; *
    765 ; * @returns VBox status code
    766 ; * @param   idxField        VMCS index
    767 ; * @param   pData           Ptr to store VM field value
    768 ; */
    769 ;DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData);
    770 BEGINPROC VMXReadVMCS64
    771 %ifdef RT_ARCH_AMD64
    772  %ifdef ASM_CALL64_GCC
    773     and         edi, 0ffffffffh
    774     xor         rax, rax
    775     vmread      [rsi], rdi
    776  %else
    777     and         ecx, 0ffffffffh
    778     xor         rax, rax
    779     vmread      [rdx], rcx
    780  %endif
    781 %else  ; RT_ARCH_X86
    782     mov         ecx, [esp + 4]          ; idxField
    783     mov         edx, [esp + 8]          ; pData
    784  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    785     cmp         byte [g_fIs64bit], 0
    786     jne         .longmode
    787  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    788     vmread      [edx], ecx              ; low dword
    789     jz          .done
    790     jc          .done
    791     inc         ecx
    792     xor         eax, eax
    793     vmread      [edx + 4], ecx          ; high dword
    794 .done:
    795 %endif ; RT_ARCH_X86
    796     jnc         .valid_vmcs
    797     mov         eax, VERR_VMX_INVALID_VMCS_PTR
    798     ret
    799 .valid_vmcs:
    800     jnz         .the_end
    801     mov         eax, VERR_VMX_INVALID_VMCS_FIELD
    802 .the_end:
    803     ret
    804 
    805 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    806 .longmode:
    807     ; Convert return frame into a retf frame 64-bit -> 32-bit
    808     xor     eax, eax
    809     xchg    eax, [esp]
    810     push    cs
    811     push    0
    812     push    eax                         ; original return address.
    813     ; jmp far .thunk64
    814     db      0xea
    815     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    816 BITS 64
    817 .thunk64:
    818     and     edx, 0ffffffffh
    819     and     ecx, 0ffffffffh
    820     xor     eax, eax
    821     vmread  [rdx], rcx
    822     mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
    823     cmovz   eax, r8d
    824     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    825     cmovc   eax, r9d
    826     retf                                ; return to caller
    827 BITS 32
    828 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    829 ENDPROC VMXReadVMCS64
    830 
    831 
    832 ;/**
    833 ; * Executes VMREAD, 32-bit value.
    834 ; *
    835 ; * @returns VBox status code
    836 ; * @param   idxField        VMCS index
    837 ; * @param   pu32Data        Ptr to store VM field value
    838 ; */
    839 ;DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pu32Data);
    840 BEGINPROC VMXReadVMCS32
    841 %ifdef RT_ARCH_AMD64
    842  %ifdef ASM_CALL64_GCC
    843     and     edi, 0ffffffffh
    844     xor     rax, rax
    845     vmread  r10, rdi
    846     mov     [rsi], r10d
    847  %else
    848     and     ecx, 0ffffffffh
    849     xor     rax, rax
    850     vmread  r10, rcx
    851     mov     [rdx], r10d
    852  %endif
    853 %else  ; RT_ARCH_X86
    854     mov     ecx, [esp + 4]              ; idxField
    855     mov     edx, [esp + 8]              ; pu32Data
    856  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    857     cmp     byte [g_fIs64bit], 0
    858     jne     .longmode
    859  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    860     xor     eax, eax
    861     vmread  [edx], ecx
    862 %endif ; RT_ARCH_X86
    863     jnc     .valid_vmcs
    864     mov     eax, VERR_VMX_INVALID_VMCS_PTR
    865     ret
    866 .valid_vmcs:
    867     jnz     .the_end
    868     mov     eax, VERR_VMX_INVALID_VMCS_FIELD
    869 .the_end:
    870     ret
    871 
    872 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    873 .longmode:
    874     ; Convert return frame into a retf frame 64-bit -> 32-bit
    875     xor     eax, eax
    876     xchg    eax, [esp]
    877     push    cs
    878     push    0
    879     push    eax                         ; original return address.
    880     ; jmp far .thunk64
    881     db      0xea
    882     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    883 BITS 64
    884 .thunk64:
    885     and     edx, 0ffffffffh
    886     and     ecx, 0ffffffffh
    887     xor     eax, eax
    888     vmread  r10, rcx
    889     mov     [rdx], r10d
    890     mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
    891     cmovz   eax, r8d
    892     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    893     cmovc   eax, r9d
    894     retf                                ; return to caller
    895 BITS 32
    896 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    897 ENDPROC VMXReadVMCS32
    898 
    899 
    900 ;/**
    901 ; * Executes VMWRITE, 32-bit value.
    902 ; *
    903 ; * @returns VBox status code
    904 ; * @param   idxField        VMCS index
    905 ; * @param   u32Data         Ptr to store VM field value
    906 ; */
    907 ;DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Data);
    908 BEGINPROC VMXWriteVMCS32
    909 %ifdef RT_ARCH_AMD64
    910  %ifdef ASM_CALL64_GCC
    911     and     edi, 0ffffffffh
    912     and     esi, 0ffffffffh
    913     xor     rax, rax
    914     vmwrite rdi, rsi
    915  %else
    916     and     ecx, 0ffffffffh
    917     and     edx, 0ffffffffh
    918     xor     rax, rax
    919     vmwrite rcx, rdx
    920  %endif
    921 %else  ; RT_ARCH_X86
    922     mov     ecx, [esp + 4]              ; idxField
    923     mov     edx, [esp + 8]              ; u32Data
    924  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    925     cmp     byte [g_fIs64bit], 0
    926     jne     .longmode
    927  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    928     xor     eax, eax
    929     vmwrite ecx, edx
    930 %endif ; RT_ARCH_X86
    931     jnc     .valid_vmcs
    932     mov     eax, VERR_VMX_INVALID_VMCS_PTR
    933     ret
    934 .valid_vmcs:
    935     jnz     .the_end
    936     mov     eax, VERR_VMX_INVALID_VMCS_FIELD
    937 .the_end:
    938     ret
    939 
    940 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    941 .longmode:
    942     ; Convert return frame into a retf frame 64-bit -> 32-bit
    943     xor     eax, eax
    944     xchg    eax, [esp]
    945     push    cs
    946     push    0
    947     push    eax                         ; original return address.
    948     ; jmp far .thunk64
    949     db      0xea
    950     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    951 BITS 64
    952 .thunk64:
    953     and     edx, 0ffffffffh
    954     and     ecx, 0ffffffffh
    955     xor     eax, eax
    956     vmwrite rcx, rdx
    957     mov     r8d, VERR_VMX_INVALID_VMCS_FIELD
    958     cmovz   eax, r8d
    959     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    960     cmovc   eax, r9d
    961     retf                                ; return to caller
    962 BITS 32
    963 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    964 ENDPROC VMXWriteVMCS32
    965 
    966 
    967 ;/**
    968 ; * Executes VMXON
    969 ; *
    970 ; * @returns VBox status code
    971 ; * @param   HCPhysVMXOn      Physical address of VMXON structure
    972 ; */
    973 ;DECLASM(int) VMXEnable(RTHCPHYS HCPhysVMXOn);
    974 BEGINPROC VMXEnable
    975 %ifdef RT_ARCH_AMD64
    976     xor     rax, rax
    977  %ifdef ASM_CALL64_GCC
    978     push    rdi
    979  %else
    980     push    rcx
    981  %endif
    982     vmxon   [rsp]
    983 %else  ; RT_ARCH_X86
    984  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    985     cmp     byte [g_fIs64bit], 0
    986     jne     .longmode
    987  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    988     xor     eax, eax
    989     vmxon   [esp + 4]
    990 %endif ; RT_ARCH_X86
    991     jnc     .good
    992     mov     eax, VERR_VMX_INVALID_VMXON_PTR
    993     jmp     .the_end
    994 
    995 .good:
    996     jnz     .the_end
    997     mov     eax, VERR_VMX_GENERIC
    998 
    999 .the_end:
    1000 %ifdef RT_ARCH_AMD64
    1001     add     rsp, 8
    1002 %endif
    1003     ret
    1004 
    1005 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1006 .longmode:
    1007     lea     edx, [esp + 4]              ; &HCPhysVMXOn.
    1008     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1009     xor     eax, eax
    1010     xchg    eax, [esp]
    1011     push    cs
    1012     push    0
    1013     push    eax                         ; original return address.
    1014     ; jmp far .thunk64
    1015     db      0xea
    1016     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1017 BITS 64
    1018 .thunk64:
    1019     and     edx, 0ffffffffh
    1020     xor     eax, eax
    1021     vmxon   [rdx]
    1022     mov     r8d, VERR_INVALID_PARAMETER
    1023     cmovz   eax, r8d
    1024     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    1025     cmovc   eax, r9d
    1026     retf                                ; return to caller
    1027 BITS 32
    1028 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1029 ENDPROC VMXEnable
    1030 
    1031 
    1032 ;/**
    1033 ; * Executes VMXOFF
    1034 ; */
    1035 ;DECLASM(void) VMXDisable(void);
    1036 BEGINPROC VMXDisable
    1037 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1038     cmp     byte [g_fIs64bit], 0
    1039     jne     .longmode
    1040 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1041     vmxoff
    1042     ret
    1043 
    1044 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1045 .longmode:
    1046     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1047     xor     eax, eax
    1048     xchg    eax, [esp]
    1049     push    cs
    1050     push    0
    1051     push    eax                         ; original return address.
    1052     ; jmp far .thunk64
    1053     db      0xea
    1054     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1055 BITS 64
    1056 .thunk64:
    1057     vmxoff
    1058     retf                                ; return to caller
    1059 BITS 32
    1060 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1061 ENDPROC VMXDisable
    1062 
    1063 
    1064 ;/**
    1065 ; * Executes VMCLEAR
    1066 ; *
    1067 ; * @returns VBox status code
    1068 ; * @param   HCPhysVMCS     Physical address of VM control structure
    1069 ; */
    1070 ;DECLASM(int) VMXClearVMCS(RTHCPHYS HCPhysVMCS);
    1071 BEGINPROC VMXClearVMCS
    1072 %ifdef RT_ARCH_AMD64
    1073     xor     rax, rax
    1074  %ifdef ASM_CALL64_GCC
    1075     push    rdi
    1076  %else
    1077     push    rcx
    1078  %endif
    1079     vmclear [rsp]
    1080 %else  ; RT_ARCH_X86
    1081  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1082     cmp     byte [g_fIs64bit], 0
    1083     jne     .longmode
    1084  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1085     xor     eax, eax
    1086     vmclear [esp + 4]
    1087 %endif ; RT_ARCH_X86
    1088     jnc     .the_end
    1089     mov     eax, VERR_VMX_INVALID_VMCS_PTR
    1090 .the_end:
    1091 %ifdef RT_ARCH_AMD64
    1092     add     rsp, 8
    1093 %endif
    1094     ret
    1095 
    1096 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1097 .longmode:
    1098     lea     edx, [esp + 4]              ; &HCPhysVMCS
    1099     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1100     xor     eax, eax
    1101     xchg    eax, [esp]
    1102     push    cs
    1103     push    0
    1104     push    eax                         ; original return address.
    1105     ; jmp far .thunk64
    1106     db      0xea
    1107     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1108 BITS 64
    1109 .thunk64:
    1110     and     edx, 0ffffffffh
    1111     xor     eax, eax
    1112     vmclear [rdx]
    1113     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    1114     cmovc   eax, r9d
    1115     retf                                ; return to caller
    1116 BITS 32
    1117 %endif
    1118 ENDPROC VMXClearVMCS
    1119 
    1120 
    1121 ;/**
    1122 ; * Executes VMPTRLD
    1123 ; *
    1124 ; * @returns VBox status code
    1125 ; * @param   HCPhysVMCS     Physical address of VMCS structure
    1126 ; */
    1127 ;DECLASM(int) VMXActivateVMCS(RTHCPHYS HCPhysVMCS);
    1128 BEGINPROC VMXActivateVMCS
    1129 %ifdef RT_ARCH_AMD64
    1130     xor     rax, rax
    1131  %ifdef ASM_CALL64_GCC
    1132     push    rdi
    1133  %else
    1134     push    rcx
    1135  %endif
    1136     vmptrld [rsp]
    1137 %else
    1138  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1139     cmp     byte [g_fIs64bit], 0
    1140     jne     .longmode
    1141  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1142     xor     eax, eax
    1143     vmptrld [esp + 4]
    1144 %endif
    1145     jnc     .the_end
    1146     mov     eax, VERR_VMX_INVALID_VMCS_PTR
    1147 .the_end:
    1148 %ifdef RT_ARCH_AMD64
    1149     add     rsp, 8
    1150 %endif
    1151     ret
    1152 
    1153 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1154 .longmode:
    1155     lea     edx, [esp + 4]              ; &HCPhysVMCS
    1156     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1157     xor     eax, eax
    1158     xchg    eax, [esp]
    1159     push    cs
    1160     push    0
    1161     push    eax                         ; original return address.
    1162     ; jmp far .thunk64
    1163     db      0xea
    1164     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1165 BITS 64
    1166 .thunk64:
    1167     and     edx, 0ffffffffh
    1168     xor     eax, eax
    1169     vmptrld [rdx]
    1170     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    1171     cmovc   eax, r9d
    1172     retf                                ; return to caller
    1173 BITS 32
    1174 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1175 ENDPROC VMXActivateVMCS
    1176 
    1177 
    1178 ;/**
    1179 ; * Executes VMPTRST
    1180 ; *
    1181 ; * @returns VBox status code
    1182 ; * @param    [esp + 04h]  gcc:rdi  msc:rcx   Param 1 - First parameter - Address that will receive the current pointer
    1183 ; */
    1184 ;DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
    1185 BEGINPROC VMXGetActivateVMCS
    1186 %ifdef RT_OS_OS2
    1187     mov     eax, VERR_NOT_SUPPORTED
    1188     ret
    1189 %else
    1190  %ifdef RT_ARCH_AMD64
    1191   %ifdef ASM_CALL64_GCC
    1192     vmptrst qword [rdi]
    1193   %else
    1194     vmptrst qword [rcx]
    1195   %endif
    1196  %else
    1197   %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1198     cmp     byte [g_fIs64bit], 0
    1199     jne     .longmode
    1200   %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1201     vmptrst qword [esp+04h]
    1202  %endif
    1203     xor     eax, eax
    1204     ret
    1205 
    1206  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1207 .longmode:
    1208     lea     edx, [esp + 4]              ; &HCPhysVMCS
    1209     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1210     xor     eax, eax
    1211     xchg    eax, [esp]
    1212     push    cs
    1213     push    0
    1214     push    eax                         ; original return address.
    1215     ; jmp far .thunk64
    1216     db      0xea
    1217     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1218 BITS 64
    1219 .thunk64:
    1220     and     edx, 0ffffffffh
    1221     vmptrst qword [rdx]
    1222     xor     eax, eax
    1223     retf                                ; return to caller
    1224 BITS 32
    1225  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1226 %endif
    1227 ENDPROC VMXGetActivateVMCS
    1228 
    1229 ;/**
    1230 ; * Invalidate a page using invept
    1231 ; @param   enmFlush     msc:ecx  gcc:edi  x86:[esp+04]  Type of flush
    1232 ; @param   pDescriptor  msc:edx  gcc:esi  x86:[esp+08]  Descriptor pointer
    1233 ; */
    1234 ;DECLASM(int) VMXR0InvEPT(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
    1235 BEGINPROC VMXR0InvEPT
    1236 %ifdef RT_ARCH_AMD64
    1237  %ifdef ASM_CALL64_GCC
    1238     and         edi, 0ffffffffh
    1239     xor         rax, rax
    1240 ;    invept      rdi, qword [rsi]
    1241     DB          0x66, 0x0F, 0x38, 0x80, 0x3E
    1242  %else
    1243     and         ecx, 0ffffffffh
    1244     xor         rax, rax
    1245 ;    invept      rcx, qword [rdx]
    1246     DB          0x66, 0x0F, 0x38, 0x80, 0xA
    1247  %endif
    1248 %else
    1249  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1250     cmp         byte [g_fIs64bit], 0
    1251     jne         .longmode
    1252  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1253     mov         eax, [esp + 4]
    1254     mov         ecx, [esp + 8]
    1255 ;    invept      eax, qword [ecx]
    1256     DB          0x66, 0x0F, 0x38, 0x80, 0x1
    1257 %endif
    1258     jnc         .valid_vmcs
    1259     mov         eax, VERR_VMX_INVALID_VMCS_PTR
    1260     ret
    1261 .valid_vmcs:
    1262     jnz         .the_end
    1263     mov         eax, VERR_INVALID_PARAMETER
    1264 .the_end:
    1265     ret
    1266 
    1267 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1268 .longmode:
    1269     mov     ecx, [esp + 4]              ; enmFlush
    1270     mov     edx, [esp + 8]              ; pDescriptor
    1271     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1272     xor     eax, eax
    1273     xchg    eax, [esp]
    1274     push    cs
    1275     push    0
    1276     push    eax                         ; original return address.
    1277     ; jmp far .thunk64
    1278     db      0xea
    1279     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1280 BITS 64
    1281 .thunk64:
    1282     and     ecx, 0ffffffffh
    1283     and     edx, 0ffffffffh
    1284     xor     eax, eax
    1285 ;    invept  rcx, qword [rdx]
    1286     DB      0x66, 0x0F, 0x38, 0x80, 0xA
    1287     mov     r8d, VERR_INVALID_PARAMETER
    1288     cmovz   eax, r8d
    1289     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    1290     cmovc   eax, r9d
    1291     retf                                ; return to caller
    1292 BITS 32
    1293 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1294 ENDPROC VMXR0InvEPT
    1295 
    1296 
    1297 ;/**
    1298 ; * Invalidate a page using invvpid
    1299 ; @param   enmFlush     msc:ecx  gcc:edi  x86:[esp+04]  Type of flush
    1300 ; @param   pDescriptor  msc:edx  gcc:esi  x86:[esp+08]  Descriptor pointer
    1301 ; */
    1302 ;DECLASM(int) VMXR0InvVPID(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
    1303 BEGINPROC VMXR0InvVPID
    1304 %ifdef RT_ARCH_AMD64
    1305  %ifdef ASM_CALL64_GCC
    1306     and         edi, 0ffffffffh
    1307     xor         rax, rax
    1308     ;invvpid     rdi, qword [rsi]
    1309     DB          0x66, 0x0F, 0x38, 0x81, 0x3E
    1310  %else
    1311     and         ecx, 0ffffffffh
    1312     xor         rax, rax
    1313 ;    invvpid     rcx, qword [rdx]
    1314     DB          0x66, 0x0F, 0x38, 0x81, 0xA
    1315  %endif
    1316 %else
    1317  %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1318     cmp         byte [g_fIs64bit], 0
    1319     jne         .longmode
    1320  %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1321     mov         eax, [esp + 4]
    1322     mov         ecx, [esp + 8]
    1323 ;    invept      eax, qword [ecx]
    1324     DB          0x66, 0x0F, 0x38, 0x81, 0x1
    1325 %endif
    1326     jnc         .valid_vmcs
    1327     mov         eax, VERR_VMX_INVALID_VMCS_PTR
    1328     ret
    1329 .valid_vmcs:
    1330     jnz         .the_end
    1331     mov         eax, VERR_INVALID_PARAMETER
    1332 .the_end:
    1333     ret
    1334 
    1335 %ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
    1336 .longmode:
    1337     mov     ecx, [esp + 4]              ; enmFlush
    1338     mov     edx, [esp + 8]              ; pDescriptor
    1339     ; Convert return frame into a retf frame 64-bit -> 32-bit
    1340     xor     eax, eax
    1341     xchg    eax, [esp]
    1342     push    cs
    1343     push    0
    1344     push    eax                         ; original return address.
    1345     ; jmp far .thunk64
    1346     db      0xea
    1347     dd      .thunk64, NAME(SUPR0Abs64bitKernelCS)
    1348 BITS 64
    1349 .thunk64:
    1350     and     ecx, 0ffffffffh
    1351     and     edx, 0ffffffffh
    1352     xor     eax, eax
    1353 ;    invvpid rcx, qword [rdx]
    1354     DB      0x66, 0x0F, 0x38, 0x81, 0xA
    1355     mov     r8d, VERR_INVALID_PARAMETER
    1356     cmovz   eax, r8d
    1357     mov     r9d, VERR_VMX_INVALID_VMCS_PTR
    1358     cmovc   eax, r9d
    1359     retf                                ; return to caller
    1360 BITS 32
    1361 %endif ; VBOX_WITH_HYBIRD_32BIT_KERNEL
    1362 ENDPROC VMXR0InvVPID
    1363487
    1364488
     
    1371495; * @param   pCtx           Guest context
    1372496; */
    1373 BEGINPROC SVMR0VMRun
     497BEGINPROC MY_NAME(SVMR0VMRun)
    1374498%ifdef RT_ARCH_AMD64 ; fake a cdecl stack frame
    1375499 %ifdef ASM_CALL64_GCC
     
    1468592%endif
    1469593    ret
    1470 ENDPROC SVMR0VMRun
     594ENDPROC MY_NAME(SVMR0VMRun)
    1471595
    1472596%ifdef RT_ARCH_AMD64
     
    1479603; * @param   pCtx           Guest context
    1480604; */
    1481 BEGINPROC SVMR0VMRun64
     605BEGINPROC MY_NAME(SVMR0VMRun64)
    1482606    ; fake a cdecl stack frame
    1483607 %ifdef ASM_CALL64_GCC
     
    1589713    add     rsp, 4*xS
    1590714    ret
    1591 ENDPROC SVMR0VMRun64
     715ENDPROC MY_NAME(SVMR0VMRun64)
    1592716%endif ; RT_ARCH_AMD64
    1593717
    1594 
    1595 %if GC_ARCH_BITS == 64
    1596 ;;
    1597 ; Executes INVLPGA
    1598 ;
    1599 ; @param   pPageGC  msc:rcx  gcc:rdi  x86:[esp+04]  Virtual page to invalidate
    1600 ; @param   uASID    msc:rdx  gcc:rsi  x86:[esp+0C]  Tagged TLB id
    1601 ;
    1602 ;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
    1603 BEGINPROC SVMR0InvlpgA
    1604 %ifdef RT_ARCH_AMD64
    1605  %ifdef ASM_CALL64_GCC
    1606     mov     rax, rdi
    1607     mov     rcx, rsi
    1608  %else
    1609     ; from http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf:
    1610     ; ``Perhaps unexpectedly, instructions that move or generate 32-bit register
    1611     ;   values also set the upper 32 bits of the register to zero. Consequently
    1612     ;   there is no need for an instruction movzlq.''
    1613     mov     eax, ecx
    1614     mov     rcx, rdx
    1615  %endif
    1616 %else
    1617     mov     eax, [esp + 4]
    1618     mov     ecx, [esp + 0Ch]
    1619 %endif
    1620     invlpga [xAX], ecx
    1621     ret
    1622 ENDPROC SVMR0InvlpgA
    1623 
    1624 %else
    1625 ;;
    1626 ; Executes INVLPGA
    1627 ;
    1628 ; @param   pPageGC  msc:ecx  gcc:edi  x86:[esp+04]  Virtual page to invalidate
    1629 ; @param   uASID    msc:edx  gcc:esi  x86:[esp+08]  Tagged TLB id
    1630 ;
    1631 ;DECLASM(void) SVMR0InvlpgA(RTGCPTR pPageGC, uint32_t uASID);
    1632 BEGINPROC SVMR0InvlpgA
    1633 %ifdef RT_ARCH_AMD64
    1634  %ifdef ASM_CALL64_GCC
    1635     movzx   rax, edi
    1636     mov     ecx, esi
    1637  %else
    1638     ; from http://www.cs.cmu.edu/~fp/courses/15213-s06/misc/asm64-handout.pdf:
    1639     ; ``Perhaps unexpectedly, instructions that move or generate 32-bit register
    1640     ;   values also set the upper 32 bits of the register to zero. Consequently
    1641     ;   there is no need for an instruction movzlq.''
    1642     mov     eax, ecx
    1643     mov     ecx, edx
    1644  %endif
    1645 %else
    1646     mov     eax, [esp + 4]
    1647     mov     ecx, [esp + 8]
    1648 %endif
    1649     invlpga [xAX], ecx
    1650     ret
    1651 ENDPROC SVMR0InvlpgA
    1652 
    1653 %endif ; GC_ARCH_BITS != 64
    1654 
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