~ubuntu-branches/ubuntu/trusty/virtualbox/trusty-proposed

« back to all changes in this revision

Viewing changes to src/VBox/VMM/VMMR0/HWVMXR0.cpp

  • Committer: Package Import Robot
  • Author(s): Felix Geyer
  • Date: 2013-03-07 16:38:36 UTC
  • mfrom: (1.1.13) (3.1.20 experimental)
  • Revision ID: package-import@ubuntu.com-20130307163836-p93jpbgx39tp3gb4
Tags: 4.2.8-dfsg-0ubuntu1
* New upstream release. (Closes: #691148)
  - Fixes compatibility with kernel 3.8. (Closes: #700823; LP: #1101867)
* Switch to my @debian.org email address.
* Move package to contrib as virtualbox 4.2 needs a non-free compiler to
  build the BIOS.
* Build-depend on libdevmapper-dev.
* Refresh patches.
  - Drop 36-fix-ftbfs-xserver-112.patch, cve-2012-3221.patch,
    CVE-2013-0420.patch 37-kcompat-3.6.patch and 38-kcompat-3.7.patch.
* Drop all virtualbox-ose transitional packages.
* Drop the virtualbox-fuse package as vdfuse fails to build with
  virtualbox 4.2.
* Update install files and VBox.sh.
* Bump required kbuild version to 0.1.9998svn2577.
* Fix path to VBoxCreateUSBNode.sh in virtualbox.postinst. (Closes: #700479)
* Add an init script to virtuabox-guest-x11 which loads the vboxvideo
  kernel module. The X Server 1.13 doesn't load it anymore. (Closes: #686994)
* Update man pages. (Closes: #680053)
* Add 36-python-multiarch.patch from Rico Tzschichholz to fix detection of
  python in multiarch paths using pkg-config.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* $Id: HWVMXR0.cpp $ */
2
2
/** @file
3
 
 * HWACCM VMX - Host Context Ring 0.
 
3
 * HM VMX (VT-x) - Host Context Ring-0.
4
4
 */
5
5
 
6
6
/*
7
 
 * Copyright (C) 2006-2007 Oracle Corporation
 
7
 * Copyright (C) 2006-2013 Oracle Corporation
8
8
 *
9
9
 * This file is part of VirtualBox Open Source Edition (OSE), as
10
10
 * available from http://www.virtualbox.org. This file is free software;
24
24
#include <VBox/vmm/hwaccm.h>
25
25
#include <VBox/vmm/pgm.h>
26
26
#include <VBox/vmm/dbgf.h>
 
27
#include <VBox/vmm/dbgftrace.h>
27
28
#include <VBox/vmm/selm.h>
28
29
#include <VBox/vmm/iom.h>
29
 
#include <VBox/vmm/rem.h>
 
30
#ifdef VBOX_WITH_REM
 
31
# include <VBox/vmm/rem.h>
 
32
#endif
30
33
#include <VBox/vmm/tm.h>
31
34
#include "HWACCMInternal.h"
32
35
#include <VBox/vmm/vm.h>
43
46
#include <iprt/x86.h>
44
47
#include "HWVMXR0.h"
45
48
 
 
49
#include "dtrace/VBoxVMM.h"
 
50
 
 
51
 
46
52
/*******************************************************************************
47
53
*   Defined Constants And Macros                                               *
48
54
*******************************************************************************/
54
60
# define VMX_IS_64BIT_HOST_MODE()   (false)
55
61
#endif
56
62
 
 
63
 
57
64
/*******************************************************************************
58
65
*   Global Variables                                                           *
59
66
*******************************************************************************/
66
73
extern "C" uint32_t g_fVMXIs64bitHost;
67
74
#endif
68
75
 
 
76
 
69
77
/*******************************************************************************
70
78
*   Local Functions                                                            *
71
79
*******************************************************************************/
72
 
static void VMXR0ReportWorldSwitchError(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc, PCPUMCTX pCtx);
73
 
static DECLCALLBACK(void) vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu);
74
 
static DECLCALLBACK(void) vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu);
75
 
static DECLCALLBACK(void) vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu);
76
 
static void vmxR0FlushEPT(PVM pVM, PVMCPU pVCpu, VMX_FLUSH enmFlush, RTGCPHYS GCPhys);
77
 
static void vmxR0FlushVPID(PVM pVM, PVMCPU pVCpu, VMX_FLUSH enmFlush, RTGCPTR GCPtr);
78
 
static void vmxR0UpdateExceptionBitmap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
79
 
#ifdef VBOX_STRICT
80
 
static bool vmxR0IsValidReadField(uint32_t idxField);
81
 
static bool vmxR0IsValidWriteField(uint32_t idxField);
82
 
#endif
83
 
static void vmxR0SetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool fWrite);
84
 
 
85
 
static void VMXR0CheckError(PVM pVM, PVMCPU pVCpu, int rc)
 
80
static DECLCALLBACK(void) hmR0VmxSetupTLBEPT(PVM pVM, PVMCPU pVCpu);
 
81
static DECLCALLBACK(void) hmR0VmxSetupTLBVPID(PVM pVM, PVMCPU pVCpu);
 
82
static DECLCALLBACK(void) hmR0VmxSetupTLBBoth(PVM pVM, PVMCPU pVCpu);
 
83
static DECLCALLBACK(void) hmR0VmxSetupTLBDummy(PVM pVM, PVMCPU pVCpu);
 
84
static void hmR0VmxFlushEPT(PVM pVM, PVMCPU pVCpu, VMX_FLUSH_EPT enmFlush);
 
85
static void hmR0VmxFlushVPID(PVM pVM, PVMCPU pVCpu, VMX_FLUSH_VPID enmFlush, RTGCPTR GCPtr);
 
86
static void hmR0VmxUpdateExceptionBitmap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
 
87
static void hmR0VmxSetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool fWrite);
 
88
static void hmR0VmxReportWorldSwitchError(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc, PCPUMCTX pCtx);
 
89
 
 
90
 
 
91
/**
 
92
 * Updates error from VMCS to HWACCMCPU's lasterror record.
 
93
 *
 
94
 * @param    pVM            Pointer to the VM.
 
95
 * @param    pVCpu          Pointer to the VMCPU.
 
96
 * @param    rc             The error code.
 
97
 */
 
98
static void hmR0VmxCheckError(PVM pVM, PVMCPU pVCpu, int rc)
86
99
{
87
100
    if (rc == VERR_VMX_GENERIC)
88
101
    {
94
107
    pVM->hwaccm.s.lLastError = rc;
95
108
}
96
109
 
 
110
 
97
111
/**
98
 
 * Sets up and activates VT-x on the current CPU
 
112
 * Sets up and activates VT-x on the current CPU.
99
113
 *
100
114
 * @returns VBox status code.
101
 
 * @param   pCpu            CPU info struct
102
 
 * @param   pVM             The VM to operate on. (can be NULL after a resume!!)
103
 
 * @param   pvCpuPage       Pointer to the global cpu page.
104
 
 * @param   HCPhysCpuPage   Physical address of the global cpu page.
 
115
 * @param   pCpu            Pointer to the CPU info struct.
 
116
 * @param   pVM             Pointer to the VM. (can be NULL after a resume!!)
 
117
 * @param   pvCpuPage       Pointer to the global CPU page.
 
118
 * @param   HCPhysCpuPage   Physical address of the global CPU page.
 
119
 * @param   fEnabledByHost  Set if SUPR0EnableVTx or similar was used to enable
 
120
 *                          VT-x/AMD-V on the host.
105
121
 */
106
 
VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
 
122
VMMR0DECL(int) VMXR0EnableCpu(PHMGLOBLCPUINFO pCpu, PVM pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, bool fEnabledByHost)
107
123
{
108
 
    AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
109
 
    AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
110
 
 
111
 
    if (pVM)
112
 
    {
113
 
        /* Set revision dword at the beginning of the VMXON structure. */
114
 
        *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
115
 
    }
116
 
 
117
 
    /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
118
 
     * (which can have very bad consequences!!!)
119
 
     */
120
 
 
121
 
    if (ASMGetCR4() & X86_CR4_VMXE)
122
 
        return VERR_VMX_IN_VMX_ROOT_MODE;
123
 
 
124
 
    /* Make sure the VMX instructions don't cause #UD faults. */
125
 
    ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);
126
 
 
127
 
    /* Enter VMX Root Mode. */
128
 
    int rc = VMXEnable(HCPhysCpuPage);
129
 
    if (RT_FAILURE(rc))
130
 
    {
131
 
        ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
132
 
        return VERR_VMX_VMXON_FAILED;
133
 
    }
 
124
    if (!fEnabledByHost)
 
125
    {
 
126
        AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
 
127
        AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
 
128
 
 
129
        if (pVM)
 
130
        {
 
131
            /* Set revision dword at the beginning of the VMXON structure. */
 
132
            *(uint32_t *)pvCpuPage = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
 
133
        }
 
134
 
 
135
        /** @todo we should unmap the two pages from the virtual address space in order to prevent accidental corruption.
 
136
         * (which can have very bad consequences!!!)
 
137
         */
 
138
 
 
139
        if (ASMGetCR4() & X86_CR4_VMXE)
 
140
            return VERR_VMX_IN_VMX_ROOT_MODE;
 
141
 
 
142
        ASMSetCR4(ASMGetCR4() | X86_CR4_VMXE);    /* Make sure the VMX instructions don't cause #UD faults. */
 
143
 
 
144
        /*
 
145
         * Enter VM root mode.
 
146
         */
 
147
        int rc = VMXEnable(HCPhysCpuPage);
 
148
        if (RT_FAILURE(rc))
 
149
        {
 
150
            ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
 
151
            return VERR_VMX_VMXON_FAILED;
 
152
        }
 
153
    }
 
154
 
 
155
    /*
 
156
     * Flush all VPIDs (in case we or any other hypervisor have been using VPIDs) so that
 
157
     * we can avoid an explicit flush while using new VPIDs. We would still need to flush
 
158
     * each time while reusing a VPID after hitting the MaxASID limit once.
 
159
     */
 
160
    if (   pVM
 
161
        && pVM->hwaccm.s.vmx.fVPID
 
162
        && (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS))
 
163
    {
 
164
        hmR0VmxFlushVPID(pVM, NULL /* pvCpu */, VMX_FLUSH_VPID_ALL_CONTEXTS, 0 /* GCPtr */);
 
165
        pCpu->fFlushASIDBeforeUse = false;
 
166
    }
 
167
    else
 
168
        pCpu->fFlushASIDBeforeUse = true;
 
169
 
 
170
    /*
 
171
     * Ensure each VCPU scheduled on this CPU gets a new VPID on resume. See @bugref{6255}.
 
172
     */
 
173
    ++pCpu->cTLBFlushes;
 
174
 
134
175
    return VINF_SUCCESS;
135
176
}
136
177
 
 
178
 
137
179
/**
138
 
 * Deactivates VT-x on the current CPU
 
180
 * Deactivates VT-x on the current CPU.
139
181
 *
140
182
 * @returns VBox status code.
141
 
 * @param   pCpu            CPU info struct
142
 
 * @param   pvCpuPage       Pointer to the global cpu page.
143
 
 * @param   HCPhysCpuPage   Physical address of the global cpu page.
 
183
 * @param   pCpu            Pointer to the CPU info struct.
 
184
 * @param   pvCpuPage       Pointer to the global CPU page.
 
185
 * @param   HCPhysCpuPage   Physical address of the global CPU page.
144
186
 */
145
187
VMMR0DECL(int) VMXR0DisableCpu(PHMGLOBLCPUINFO pCpu, void *pvCpuPage, RTHCPHYS HCPhysCpuPage)
146
188
{
147
189
    AssertReturn(HCPhysCpuPage != 0 && HCPhysCpuPage != NIL_RTHCPHYS, VERR_INVALID_PARAMETER);
148
190
    AssertReturn(pvCpuPage, VERR_INVALID_PARAMETER);
 
191
    NOREF(pCpu);
149
192
 
150
193
    /* If we're somehow not in VMX root mode, then we shouldn't dare leaving it. */
151
194
    if (!(ASMGetCR4() & X86_CR4_VMXE))
159
202
    return VINF_SUCCESS;
160
203
}
161
204
 
 
205
 
162
206
/**
163
 
 * Does Ring-0 per VM VT-x init.
 
207
 * Does Ring-0 per VM VT-x initialization.
164
208
 *
165
209
 * @returns VBox status code.
166
 
 * @param   pVM         The VM to operate on.
 
210
 * @param   pVM         Pointer to the VM.
167
211
 */
168
212
VMMR0DECL(int) VMXR0InitVM(PVM pVM)
169
213
{
170
214
    int rc;
171
215
 
172
216
#ifdef LOG_ENABLED
173
 
    SUPR0Printf("VMXR0InitVM %x\n", pVM);
 
217
    SUPR0Printf("VMXR0InitVM %p\n", pVM);
174
218
#endif
175
219
 
176
220
    pVM->hwaccm.s.vmx.pMemObjAPIC = NIL_RTR0MEMOBJ;
210
254
    }
211
255
#endif
212
256
 
213
 
    /* Allocate VMCBs for all guest CPUs. */
 
257
    /* Allocate VMCSs for all guest CPUs. */
214
258
    for (VMCPUID i = 0; i < pVM->cCpus; i++)
215
259
    {
216
260
        PVMCPU pVCpu = &pVM->aCpus[i];
262
306
 
263
307
        pVCpu->hwaccm.s.vmx.pGuestMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR);
264
308
        pVCpu->hwaccm.s.vmx.pGuestMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, 0);
 
309
        Assert(!(pVCpu->hwaccm.s.vmx.pGuestMSRPhys & 0xf));
265
310
        memset(pVCpu->hwaccm.s.vmx.pGuestMSR, 0, PAGE_SIZE);
266
311
 
267
312
        /* Allocate one page for the host MSR load area (for restoring host MSRs after the world switch back). */
272
317
 
273
318
        pVCpu->hwaccm.s.vmx.pHostMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjHostMSR);
274
319
        pVCpu->hwaccm.s.vmx.pHostMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjHostMSR, 0);
 
320
        Assert(!(pVCpu->hwaccm.s.vmx.pHostMSRPhys & 0xf));
275
321
        memset(pVCpu->hwaccm.s.vmx.pHostMSR, 0, PAGE_SIZE);
276
322
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
277
323
 
286
332
    return VINF_SUCCESS;
287
333
}
288
334
 
 
335
 
289
336
/**
290
337
 * Does Ring-0 per VM VT-x termination.
291
338
 *
292
339
 * @returns VBox status code.
293
 
 * @param   pVM         The VM to operate on.
 
340
 * @param   pVM         Pointer to the VM.
294
341
 */
295
342
VMMR0DECL(int) VMXR0TermVM(PVM pVM)
296
343
{
356
403
    return VINF_SUCCESS;
357
404
}
358
405
 
 
406
 
359
407
/**
360
 
 * Sets up VT-x for the specified VM
 
408
 * Sets up VT-x for the specified VM.
361
409
 *
362
410
 * @returns VBox status code.
363
 
 * @param   pVM         The VM to operate on.
 
411
 * @param   pVM         Pointer to the VM.
364
412
 */
365
413
VMMR0DECL(int) VMXR0SetupVM(PVM pVM)
366
414
{
369
417
 
370
418
    AssertReturn(pVM, VERR_INVALID_PARAMETER);
371
419
 
 
420
    /* Initialize these always, see hwaccmR3InitFinalizeR0().*/
 
421
    pVM->hwaccm.s.vmx.enmFlushEPT  = VMX_FLUSH_EPT_NONE;
 
422
    pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NONE;
 
423
 
 
424
    /* Determine optimal flush type for EPT. */
 
425
    if (pVM->hwaccm.s.fNestedPaging)
 
426
    {
 
427
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT)
 
428
        {
 
429
            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_SINGLE_CONTEXT)
 
430
                pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_SINGLE_CONTEXT;
 
431
            else if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL_CONTEXTS)
 
432
                pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_ALL_CONTEXTS;
 
433
            else
 
434
            {
 
435
                /*
 
436
                 * Should never really happen. EPT is supported but no suitable flush types supported.
 
437
                 * We cannot ignore EPT at this point as we've already setup Unrestricted Guest execution.
 
438
                 */
 
439
                pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_NOT_SUPPORTED;
 
440
                return VERR_VMX_GENERIC;
 
441
            }
 
442
        }
 
443
        else
 
444
        {
 
445
            /*
 
446
             * Should never really happen. EPT is supported but INVEPT instruction is not supported.
 
447
             */
 
448
            pVM->hwaccm.s.vmx.enmFlushEPT = VMX_FLUSH_EPT_NOT_SUPPORTED;
 
449
            return VERR_VMX_GENERIC;
 
450
        }
 
451
    }
 
452
 
 
453
    /* Determine optimal flush type for VPID. */
 
454
    if (pVM->hwaccm.s.vmx.fVPID)
 
455
    {
 
456
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID)
 
457
        {
 
458
            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
 
459
                pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_SINGLE_CONTEXT;
 
460
            else if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL_CONTEXTS)
 
461
                pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_ALL_CONTEXTS;
 
462
            else
 
463
            {
 
464
                /*
 
465
                 * Neither SINGLE nor ALL context flush types for VPID supported by the CPU.
 
466
                 * We do not handle other flush type combinations, ignore VPID capabilities.
 
467
                 */
 
468
                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
 
469
                    Log(("VMXR0SetupVM: Only VMX_FLUSH_VPID_INDIV_ADDR supported. Ignoring VPID.\n"));
 
470
                if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT_RETAIN_GLOBALS)
 
471
                    Log(("VMXR0SetupVM: Only VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS supported. Ignoring VPID.\n"));
 
472
                pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NOT_SUPPORTED;
 
473
                pVM->hwaccm.s.vmx.fVPID = false;
 
474
            }
 
475
        }
 
476
        else
 
477
        {
 
478
            /*
 
479
             * Should not really happen. EPT is supported but INVEPT is not supported.
 
480
             * Ignore VPID capabilities as our code relies on using INVEPT for selective flushing.
 
481
             */
 
482
            Log(("VMXR0SetupVM: VPID supported without INVEPT support. Ignoring VPID.\n"));
 
483
            pVM->hwaccm.s.vmx.enmFlushVPID = VMX_FLUSH_VPID_NOT_SUPPORTED;
 
484
            pVM->hwaccm.s.vmx.fVPID = false;
 
485
        }
 
486
    }
 
487
 
372
488
    for (VMCPUID i = 0; i < pVM->cCpus; i++)
373
489
    {
374
490
        PVMCPU pVCpu = &pVM->aCpus[i];
378
494
        /* Set revision dword at the beginning of the VMCS structure. */
379
495
        *(uint32_t *)pVCpu->hwaccm.s.vmx.pvVMCS = MSR_IA32_VMX_BASIC_INFO_VMCS_ID(pVM->hwaccm.s.vmx.msr.vmx_basic_info);
380
496
 
381
 
        /* Clear VM Control Structure. */
 
497
        /*
 
498
         * Clear and activate the VMCS.
 
499
         */
382
500
        Log(("HCPhysVMCS  = %RHp\n", pVCpu->hwaccm.s.vmx.HCPhysVMCS));
383
501
        rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
384
502
        if (RT_FAILURE(rc))
385
503
            goto vmx_end;
386
504
 
387
 
        /* Activate the VM Control Structure. */
388
505
        rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
389
506
        if (RT_FAILURE(rc))
390
507
            goto vmx_end;
391
508
 
392
 
        /* VMX_VMCS_CTRL_PIN_EXEC_CONTROLS
 
509
        /*
 
510
         * VMX_VMCS_CTRL_PIN_EXEC_CONTROLS
393
511
         * Set required bits to one and zero according to the MSR capabilities.
394
512
         */
395
 
        val  = pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0;
396
 
        /* External and non-maskable interrupts cause VM-exits. */
397
 
        val |= VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT | VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT;
398
 
        /* enable the preemption timer. */
 
513
        val = pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0;
 
514
        val |=    VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT      /* External interrupts */
 
515
                | VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT;         /* Non-maskable interrupts */
 
516
 
 
517
        /*
 
518
         * Enable the VMX preemption timer.
 
519
         */
399
520
        if (pVM->hwaccm.s.vmx.fUsePreemptTimer)
400
521
            val |= VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER;
401
522
        val &= pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.allowed1;
403
524
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, val);
404
525
        AssertRC(rc);
405
526
 
406
 
        /* VMX_VMCS_CTRL_PROC_EXEC_CONTROLS
 
527
        /*
 
528
         * VMX_VMCS_CTRL_PROC_EXEC_CONTROLS
407
529
         * Set required bits to one and zero according to the MSR capabilities.
408
530
         */
409
531
        val = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0;
410
532
        /* Program which event cause VM-exits and which features we want to use. */
411
 
        val = val | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT
412
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET
413
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT
414
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT
415
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT
416
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT
417
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT;    /* don't execute mwait or else we'll idle inside the guest (host thinks the cpu load is high) */
 
533
        val |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT
 
534
               | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET
 
535
               | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT
 
536
               | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT
 
537
               | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT
 
538
               | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT
 
539
               | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT;     /* don't execute mwait or else we'll idle inside
 
540
                                                                      the guest (host thinks the cpu load is high) */
418
541
 
419
542
        /* Without nested paging we should intercept invlpg and cr3 mov instructions. */
420
543
        if (!pVM->hwaccm.s.fNestedPaging)
421
 
            val |=  VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT
422
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
423
 
                  | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT;
 
544
        {
 
545
            val |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT
 
546
                   | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
 
547
                   | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT;
 
548
        }
424
549
 
425
 
        /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT might cause a vmlaunch failure with an invalid control fields error. (combined with some other exit reasons) */
 
550
        /*
 
551
         * VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT might cause a vmlaunch
 
552
         * failure with an invalid control fields error. (combined with some other exit reasons)
 
553
         */
426
554
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
427
555
        {
428
556
            /* CR8 reads from the APIC shadow page; writes cause an exit is they lower the TPR below the threshold */
452
580
 
453
581
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL)
454
582
        {
455
 
            /* VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2
 
583
            /*
 
584
             * VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2
456
585
             * Set required bits to one and zero according to the MSR capabilities.
457
586
             */
458
587
            val  = pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.disallowed0;
459
588
            val |= VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT;
460
589
 
461
 
#ifdef HWACCM_VTX_WITH_EPT
462
590
            if (pVM->hwaccm.s.fNestedPaging)
463
591
                val |= VMX_VMCS_CTRL_PROC_EXEC2_EPT;
464
 
#endif /* HWACCM_VTX_WITH_EPT */
465
 
#ifdef HWACCM_VTX_WITH_VPID
466
 
            else
 
592
 
467
593
            if (pVM->hwaccm.s.vmx.fVPID)
468
594
                val |= VMX_VMCS_CTRL_PROC_EXEC2_VPID;
469
 
#endif /* HWACCM_VTX_WITH_VPID */
470
595
 
471
596
            if (pVM->hwaccm.s.fHasIoApic)
472
597
                val |= VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC;
474
599
            if (pVM->hwaccm.s.vmx.fUnrestrictedGuest)
475
600
                val |= VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE;
476
601
 
 
602
            if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
 
603
                val |= VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP;
 
604
 
477
605
            /* Mask away the bits that the CPU doesn't support */
478
606
            /** @todo make sure they don't conflict with the above requirements. */
479
607
            val &= pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1;
482
610
            AssertRC(rc);
483
611
        }
484
612
 
485
 
        /* VMX_VMCS_CTRL_CR3_TARGET_COUNT
 
613
        /*
 
614
         * VMX_VMCS_CTRL_CR3_TARGET_COUNT
486
615
         * Set required bits to one and zero according to the MSR capabilities.
487
616
         */
488
617
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_CR3_TARGET_COUNT, 0);
489
618
        AssertRC(rc);
490
619
 
491
 
        /* Forward all exception except #NM & #PF to the guest.
 
620
        /*
 
621
         * Forward all exception except #NM & #PF to the guest.
492
622
         * We always need to check pagefaults since our shadow page table can be out of sync.
493
 
         * And we always lazily sync the FPU & XMM state.
 
623
         * And we always lazily sync the FPU & XMM state.                                                           .
494
624
         */
495
625
 
496
626
        /** @todo Possible optimization:
501
631
         * Note: only possible if the current state is actually ours (X86_CR0_TS flag)
502
632
         */
503
633
 
504
 
        /* Don't filter page faults; all of them should cause a switch. */
 
634
        /*
 
635
         * Don't filter page faults, all of them should cause a world switch.
 
636
         */
505
637
        rc  = VMXWriteVMCS(VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK, 0);
506
 
        rc |= VMXWriteVMCS(VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH, 0);
 
638
        AssertRC(rc);
 
639
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH, 0);
507
640
        AssertRC(rc);
508
641
 
509
 
        /* Init TSC offset to zero. */
510
642
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, 0);
511
643
        AssertRC(rc);
512
 
 
513
644
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_IO_BITMAP_A_FULL, 0);
514
645
        AssertRC(rc);
515
 
 
516
646
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_IO_BITMAP_B_FULL, 0);
517
647
        AssertRC(rc);
518
648
 
519
 
        /* Set the MSR bitmap address. */
 
649
        /*
 
650
         * Set the MSR bitmap address.
 
651
         */
520
652
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
521
653
        {
522
654
            Assert(pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
524
656
            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_MSR_BITMAP_FULL, pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
525
657
            AssertRC(rc);
526
658
 
527
 
            /* Allow the guest to directly modify these MSRs; they are restored and saved automatically. */
528
 
            vmxR0SetMSRPermission(pVCpu, MSR_IA32_SYSENTER_CS, true, true);
529
 
            vmxR0SetMSRPermission(pVCpu, MSR_IA32_SYSENTER_ESP, true, true);
530
 
            vmxR0SetMSRPermission(pVCpu, MSR_IA32_SYSENTER_EIP, true, true);
531
 
            vmxR0SetMSRPermission(pVCpu, MSR_K8_LSTAR, true, true);
532
 
            vmxR0SetMSRPermission(pVCpu, MSR_K6_STAR, true, true);
533
 
            vmxR0SetMSRPermission(pVCpu, MSR_K8_SF_MASK, true, true);
534
 
            vmxR0SetMSRPermission(pVCpu, MSR_K8_KERNEL_GS_BASE, true, true);
535
 
            vmxR0SetMSRPermission(pVCpu, MSR_K8_GS_BASE, true, true);
536
 
            vmxR0SetMSRPermission(pVCpu, MSR_K8_FS_BASE, true, true);
 
659
            /*
 
660
             * Allow the guest to directly modify these MSRs; they are loaded/stored automatically
 
661
             * using MSR-load/store areas in the VMCS.
 
662
             */
 
663
            hmR0VmxSetMSRPermission(pVCpu, MSR_IA32_SYSENTER_CS, true, true);
 
664
            hmR0VmxSetMSRPermission(pVCpu, MSR_IA32_SYSENTER_ESP, true, true);
 
665
            hmR0VmxSetMSRPermission(pVCpu, MSR_IA32_SYSENTER_EIP, true, true);
 
666
            hmR0VmxSetMSRPermission(pVCpu, MSR_K8_LSTAR, true, true);
 
667
            hmR0VmxSetMSRPermission(pVCpu, MSR_K6_STAR, true, true);
 
668
            hmR0VmxSetMSRPermission(pVCpu, MSR_K8_SF_MASK, true, true);
 
669
            hmR0VmxSetMSRPermission(pVCpu, MSR_K8_KERNEL_GS_BASE, true, true);
 
670
            hmR0VmxSetMSRPermission(pVCpu, MSR_K8_GS_BASE, true, true);
 
671
            hmR0VmxSetMSRPermission(pVCpu, MSR_K8_FS_BASE, true, true);
 
672
            if (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
 
673
                hmR0VmxSetMSRPermission(pVCpu, MSR_K8_TSC_AUX, true, true);
537
674
        }
538
675
 
539
676
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
540
 
        /* Set the guest & host MSR load/store physical addresses. */
 
677
        /*
 
678
         * Set the guest & host MSR load/store physical addresses.
 
679
         */
541
680
        Assert(pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
542
681
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL, pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
543
682
        AssertRC(rc);
544
683
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL, pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
545
684
        AssertRC(rc);
546
 
 
547
685
        Assert(pVCpu->hwaccm.s.vmx.pHostMSRPhys);
548
686
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL,  pVCpu->hwaccm.s.vmx.pHostMSRPhys);
549
687
        AssertRC(rc);
551
689
 
552
690
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT, 0);
553
691
        AssertRC(rc);
554
 
 
555
692
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT, 0);
556
693
        AssertRC(rc);
 
694
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT, 0);
 
695
        AssertRC(rc);
557
696
 
558
697
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
559
698
        {
572
711
        rc = VMXWriteVMCS64(VMX_VMCS_GUEST_LINK_PTR_FULL, 0xFFFFFFFFFFFFFFFFULL);
573
712
        AssertRC(rc);
574
713
 
575
 
        /* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */
 
714
        /*
 
715
         * Clear VMCS, marking it inactive. Clear implementation specific data and writing back
 
716
         * VMCS data back to memory.
 
717
         */
576
718
        rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
577
719
        AssertRC(rc);
578
720
 
579
 
        /* Configure the VMCS read cache. */
 
721
        /*
 
722
         * Configure the VMCS read cache.
 
723
         */
580
724
        PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
581
725
 
582
726
        VMXSetupCachedReadVMCS(pCache, VMX_VMCS64_GUEST_RIP);
596
740
        VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_GUEST_IDTR_LIMIT);
597
741
        VMXSetupCachedReadVMCS(pCache, VMX_VMCS64_GUEST_IDTR_BASE);
598
742
 
599
 
        VMX_SETUP_SELREG(ES, pCache);
600
 
        VMX_SETUP_SELREG(SS, pCache);
601
 
        VMX_SETUP_SELREG(CS, pCache);
602
 
        VMX_SETUP_SELREG(DS, pCache);
603
 
        VMX_SETUP_SELREG(FS, pCache);
604
 
        VMX_SETUP_SELREG(GS, pCache);
 
743
        VMX_SETUP_SELREG(ES,   pCache);
 
744
        VMX_SETUP_SELREG(SS,   pCache);
 
745
        VMX_SETUP_SELREG(CS,   pCache);
 
746
        VMX_SETUP_SELREG(DS,   pCache);
 
747
        VMX_SETUP_SELREG(FS,   pCache);
 
748
        VMX_SETUP_SELREG(GS,   pCache);
605
749
        VMX_SETUP_SELREG(LDTR, pCache);
606
 
        VMX_SETUP_SELREG(TR, pCache);
 
750
        VMX_SETUP_SELREG(TR,   pCache);
607
751
 
608
 
        /* Status code VMCS reads. */
 
752
        /*
 
753
         * Status code VMCS reads.
 
754
         */
609
755
        VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_RO_EXIT_REASON);
610
756
        VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_RO_VM_INSTR_ERROR);
611
757
        VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_RO_EXIT_INSTR_LENGTH);
626
772
            pCache->Read.cValidEntries = VMX_VMCS_MAX_CACHE_IDX;
627
773
    } /* for each VMCPU */
628
774
 
629
 
    /* Choose the right TLB setup function. */
630
 
    if (pVM->hwaccm.s.fNestedPaging)
631
 
    {
632
 
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = vmxR0SetupTLBEPT;
633
 
 
634
 
        /* Default values for flushing. */
635
 
        pVM->hwaccm.s.vmx.enmFlushPage    = VMX_FLUSH_ALL_CONTEXTS;
636
 
        pVM->hwaccm.s.vmx.enmFlushContext = VMX_FLUSH_ALL_CONTEXTS;
637
 
 
638
 
        /* If the capabilities specify we can do more, then make use of it. */
639
 
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_INDIV)
640
 
            pVM->hwaccm.s.vmx.enmFlushPage = VMX_FLUSH_PAGE;
641
 
        else
642
 
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_CONTEXT)
643
 
            pVM->hwaccm.s.vmx.enmFlushPage = VMX_FLUSH_SINGLE_CONTEXT;
644
 
 
645
 
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_CONTEXT)
646
 
            pVM->hwaccm.s.vmx.enmFlushContext = VMX_FLUSH_SINGLE_CONTEXT;
647
 
    }
648
 
#ifdef HWACCM_VTX_WITH_VPID
649
 
    else
650
 
    if (pVM->hwaccm.s.vmx.fVPID)
651
 
    {
652
 
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = vmxR0SetupTLBVPID;
653
 
 
654
 
        /* Default values for flushing. */
655
 
        pVM->hwaccm.s.vmx.enmFlushPage    = VMX_FLUSH_ALL_CONTEXTS;
656
 
        pVM->hwaccm.s.vmx.enmFlushContext = VMX_FLUSH_ALL_CONTEXTS;
657
 
 
658
 
        /* If the capabilities specify we can do more, then make use of it. */
659
 
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV)
660
 
            pVM->hwaccm.s.vmx.enmFlushPage = VMX_FLUSH_PAGE;
661
 
        else
662
 
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_CONTEXT)
663
 
            pVM->hwaccm.s.vmx.enmFlushPage = VMX_FLUSH_SINGLE_CONTEXT;
664
 
 
665
 
        if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_CONTEXT)
666
 
            pVM->hwaccm.s.vmx.enmFlushContext = VMX_FLUSH_SINGLE_CONTEXT;
667
 
    }
668
 
#endif /* HWACCM_VTX_WITH_VPID */
669
 
    else
670
 
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = vmxR0SetupTLBDummy;
 
775
    /*
 
776
     * Setup the right TLB function based on CPU capabilities.
 
777
     */
 
778
    if (pVM->hwaccm.s.fNestedPaging && pVM->hwaccm.s.vmx.fVPID)
 
779
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBBoth;
 
780
    else if (pVM->hwaccm.s.fNestedPaging)
 
781
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBEPT;
 
782
    else if (pVM->hwaccm.s.vmx.fVPID)
 
783
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBVPID;
 
784
    else
 
785
        pVM->hwaccm.s.vmx.pfnSetupTaggedTLB = hmR0VmxSetupTLBDummy;
671
786
 
672
787
vmx_end:
673
 
    VMXR0CheckError(pVM, &pVM->aCpus[0], rc);
 
788
    hmR0VmxCheckError(pVM, &pVM->aCpus[0], rc);
674
789
    return rc;
675
790
}
676
791
 
 
792
 
677
793
/**
678
 
 * Sets the permission bits for the specified MSR
 
794
 * Sets the permission bits for the specified MSR.
679
795
 *
680
 
 * @param   pVCpu       The VMCPU to operate on.
681
 
 * @param   ulMSR       MSR value
682
 
 * @param   fRead       Reading allowed/disallowed
683
 
 * @param   fWrite      Writing allowed/disallowed
 
796
 * @param   pVCpu       Pointer to the VMCPU.
 
797
 * @param   ulMSR       The MSR value.
 
798
 * @param   fRead       Whether reading is allowed.
 
799
 * @param   fWrite      Whether writing is allowed.
684
800
 */
685
 
static void vmxR0SetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool fWrite)
 
801
static void hmR0VmxSetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool fWrite)
686
802
{
687
803
    unsigned ulBit;
688
804
    uint8_t *pMSRBitmap = (uint8_t *)pVCpu->hwaccm.s.vmx.pMSRBitmap;
689
805
 
690
 
    /* Layout:
 
806
    /*
 
807
     * Layout:
691
808
     * 0x000 - 0x3ff - Low MSR read bits
692
809
     * 0x400 - 0x7ff - High MSR read bits
693
810
     * 0x800 - 0xbff - Low MSR write bits
698
815
        /* Pentium-compatible MSRs */
699
816
        ulBit    = ulMSR;
700
817
    }
701
 
    else
702
 
    if (    ulMSR >= 0xC0000000
703
 
        &&  ulMSR <= 0xC0001FFF)
 
818
    else if (   ulMSR >= 0xC0000000
 
819
             && ulMSR <= 0xC0001FFF)
704
820
    {
705
821
        /* AMD Sixth Generation x86 Processor MSRs */
706
822
        ulBit = (ulMSR - 0xC0000000);
726
842
 
727
843
 
728
844
/**
729
 
 * Injects an event (trap or external interrupt)
 
845
 * Injects an event (trap or external interrupt).
730
846
 *
731
847
 * @returns VBox status code.  Note that it may return VINF_EM_RESET to
732
848
 *          indicate a triple fault when injecting X86_XCPT_DF.
733
849
 *
734
 
 * @param   pVM         The VM to operate on.
735
 
 * @param   pVCpu       The VMCPU to operate on.
736
 
 * @param   pCtx        CPU Context
737
 
 * @param   intInfo     VMX interrupt info
738
 
 * @param   cbInstr     Opcode length of faulting instruction
739
 
 * @param   errCode     Error code (optional)
 
850
 * @param   pVM         Pointer to the VM.
 
851
 * @param   pVCpu       Pointer to the VMCPU.
 
852
 * @param   pCtx        Pointer to the guest CPU Context.
 
853
 * @param   intInfo     VMX interrupt info.
 
854
 * @param   cbInstr     Opcode length of faulting instruction.
 
855
 * @param   errCode     Error code (optional).
740
856
 */
741
 
static int VMXR0InjectEvent(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t intInfo, uint32_t cbInstr, uint32_t errCode)
 
857
static int hmR0VmxInjectEvent(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t intInfo, uint32_t cbInstr, uint32_t errCode)
742
858
{
743
859
    int         rc;
744
860
    uint32_t    iGate = VMX_EXIT_INTERRUPTION_INFO_VECTOR(intInfo);
749
865
 
750
866
#ifdef VBOX_STRICT
751
867
    if (iGate == 0xE)
752
 
        LogFlow(("VMXR0InjectEvent: Injecting interrupt %d at %RGv error code=%08x CR2=%RGv intInfo=%08x\n", iGate, (RTGCPTR)pCtx->rip, errCode, pCtx->cr2, intInfo));
753
 
    else
754
 
    if (iGate < 0x20)
755
 
        LogFlow(("VMXR0InjectEvent: Injecting interrupt %d at %RGv error code=%08x\n", iGate, (RTGCPTR)pCtx->rip, errCode));
 
868
    {
 
869
        LogFlow(("hmR0VmxInjectEvent: Injecting interrupt %d at %RGv error code=%08x CR2=%RGv intInfo=%08x\n", iGate,
 
870
                 (RTGCPTR)pCtx->rip, errCode, pCtx->cr2, intInfo));
 
871
    }
 
872
    else if (iGate < 0x20)
 
873
    {
 
874
        LogFlow(("hmR0VmxInjectEvent: Injecting interrupt %d at %RGv error code=%08x\n", iGate, (RTGCPTR)pCtx->rip,
 
875
                 errCode));
 
876
    }
756
877
    else
757
878
    {
758
879
        LogFlow(("INJ-EI: %x at %RGv\n", iGate, (RTGCPTR)pCtx->rip));
759
 
        Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || !VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
760
 
        Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || pCtx->eflags.u32 & X86_EFL_IF);
 
880
        Assert(   VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW
 
881
               || !VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
 
882
        Assert(   VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW
 
883
               || pCtx->eflags.u32 & X86_EFL_IF);
761
884
    }
762
885
#endif
763
886
 
768
891
        uint16_t offset, ip;
769
892
        RTSEL    sel;
770
893
 
771
 
        /* Injecting events doesn't work right with real mode emulation.
 
894
        /*
 
895
         * Injecting events doesn't work right with real mode emulation.
772
896
         * (#GP if we try to inject external hardware interrupts)
773
897
         * Inject the interrupt or trap directly instead.
774
898
         *
776
900
         */
777
901
        Log(("Manual interrupt/trap '%x' inject (real mode)\n", iGate));
778
902
 
779
 
        /* Check if the interrupt handler is present. */
 
903
        /*
 
904
         * Check if the interrupt handler is present.
 
905
         */
780
906
        if (iGate * 4 + 3 > pCtx->idtr.cbIdt)
781
907
        {
782
908
            Log(("IDT cbIdt violation\n"));
784
910
            {
785
911
                uint32_t intInfo2;
786
912
 
787
 
                intInfo2  = (iGate == X86_XCPT_GP) ? (uint32_t)X86_XCPT_DF : iGate;
 
913
                intInfo2  = (iGate == X86_XCPT_GP) ? (uint32_t)X86_XCPT_DF : (uint32_t)X86_XCPT_GP;
788
914
                intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
789
915
                intInfo2 |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID;
790
916
                intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
791
917
 
792
 
                return VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo2, 0, 0 /* no error code according to the Intel docs */);
 
918
                return hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo2, 0, 0 /* no error code according to the Intel docs */);
793
919
            }
794
920
            Log(("Triple fault -> reset the VM!\n"));
795
921
            return VINF_EM_RESET;
803
929
        else
804
930
            ip = pCtx->ip;
805
931
 
806
 
        /* Read the selector:offset pair of the interrupt handler. */
 
932
        /*
 
933
         * Read the selector:offset pair of the interrupt handler.
 
934
         */
807
935
        GCPhysHandler = (RTGCPHYS)pCtx->idtr.pIdt + iGate * 4;
808
936
        rc = PGMPhysSimpleReadGCPhys(pVM, &offset, GCPhysHandler,     sizeof(offset)); AssertRC(rc);
809
937
        rc = PGMPhysSimpleReadGCPhys(pVM, &sel,    GCPhysHandler + 2, sizeof(sel));    AssertRC(rc);
810
938
 
811
939
        LogFlow(("IDT handler %04X:%04X\n", sel, offset));
812
940
 
813
 
        /* Construct the stack frame. */
814
 
        /** @todo should check stack limit. */
815
 
        pCtx->sp -= 2;
816
 
        LogFlow(("ss:sp %04X:%04X eflags=%x\n", pCtx->ss, pCtx->sp, pCtx->eflags.u));
817
 
        rc = PGMPhysSimpleWriteGCPhys(pVM, pCtx->ssHid.u64Base + pCtx->sp, &pCtx->eflags, sizeof(uint16_t)); AssertRC(rc);
818
 
        pCtx->sp -= 2;
819
 
        LogFlow(("ss:sp %04X:%04X cs=%x\n", pCtx->ss, pCtx->sp, pCtx->cs));
820
 
        rc = PGMPhysSimpleWriteGCPhys(pVM, pCtx->ssHid.u64Base + pCtx->sp, &pCtx->cs, sizeof(uint16_t)); AssertRC(rc);
821
 
        pCtx->sp -= 2;
822
 
        LogFlow(("ss:sp %04X:%04X ip=%x\n", pCtx->ss, pCtx->sp, ip));
823
 
        rc = PGMPhysSimpleWriteGCPhys(pVM, pCtx->ssHid.u64Base + pCtx->sp, &ip, sizeof(ip)); AssertRC(rc);
 
941
        /*
 
942
         * Construct the stack frame.
 
943
         */
 
944
        /** @todo Check stack limit. */
 
945
        pCtx->sp -= 2;
 
946
        LogFlow(("ss:sp %04X:%04X eflags=%x\n", pCtx->ss.Sel, pCtx->sp, pCtx->eflags.u));
 
947
        rc = PGMPhysSimpleWriteGCPhys(pVM, pCtx->ss.u64Base + pCtx->sp, &pCtx->eflags, sizeof(uint16_t)); AssertRC(rc);
 
948
        pCtx->sp -= 2;
 
949
        LogFlow(("ss:sp %04X:%04X cs=%x\n", pCtx->ss.Sel, pCtx->sp, pCtx->cs.Sel));
 
950
        rc = PGMPhysSimpleWriteGCPhys(pVM, pCtx->ss.u64Base + pCtx->sp, &pCtx->cs, sizeof(uint16_t)); AssertRC(rc);
 
951
        pCtx->sp -= 2;
 
952
        LogFlow(("ss:sp %04X:%04X ip=%x\n", pCtx->ss.Sel, pCtx->sp, ip));
 
953
        rc = PGMPhysSimpleWriteGCPhys(pVM, pCtx->ss.u64Base + pCtx->sp, &ip, sizeof(ip)); AssertRC(rc);
824
954
 
825
 
        /* Update the CPU state for executing the handler. */
 
955
        /*
 
956
         * Update the CPU state for executing the handler.
 
957
         */
826
958
        pCtx->rip           = offset;
827
 
        pCtx->cs            = sel;
828
 
        pCtx->csHid.u64Base = sel << 4;
829
 
        pCtx->eflags.u     &= ~(X86_EFL_IF|X86_EFL_TF|X86_EFL_RF|X86_EFL_AC);
 
959
        pCtx->cs.Sel        = sel;
 
960
        pCtx->cs.u64Base    = sel << 4;
 
961
        pCtx->eflags.u     &= ~(X86_EFL_IF | X86_EFL_TF | X86_EFL_RF | X86_EFL_AC);
830
962
 
831
963
        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_SEGMENT_REGS;
832
964
        return VINF_SUCCESS;
833
965
    }
834
966
 
835
 
    /* Set event injection state. */
 
967
    /*
 
968
     * Set event injection state.
 
969
     */
836
970
    rc  = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_IRQ_INFO, intInfo | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT));
837
 
 
838
971
    rc |= VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH, cbInstr);
839
972
    rc |= VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE, errCode);
840
973
 
844
977
 
845
978
 
846
979
/**
847
 
 * Checks for pending guest interrupts and injects them
 
980
 * Checks for pending guest interrupts and injects them.
848
981
 *
849
982
 * @returns VBox status code.
850
 
 * @param   pVM         The VM to operate on.
851
 
 * @param   pVCpu       The VMCPU to operate on.
852
 
 * @param   pCtx        CPU Context
 
983
 * @param   pVM         Pointer to the VM.
 
984
 * @param   pVCpu       Pointer to the VMCPU.
 
985
 * @param   pCtx        Pointer to the guest CPU context.
853
986
 */
854
 
static int VMXR0CheckPendingInterrupt(PVM pVM, PVMCPU pVCpu, CPUMCTX *pCtx)
 
987
static int hmR0VmxCheckPendingInterrupt(PVM pVM, PVMCPU pVCpu, CPUMCTX *pCtx)
855
988
{
856
989
    int rc;
857
990
 
858
 
    /* Dispatch any pending interrupts. (injected before, but a VM exit occurred prematurely) */
 
991
    /*
 
992
     * Dispatch any pending interrupts (injected before, but a VM exit occurred prematurely).
 
993
     */
859
994
    if (pVCpu->hwaccm.s.Event.fPending)
860
995
    {
861
 
        Log(("CPU%d: Reinjecting event %RX64 %08x at %RGv cr2=%RX64\n", pVCpu->idCpu, pVCpu->hwaccm.s.Event.intInfo, pVCpu->hwaccm.s.Event.errCode, (RTGCPTR)pCtx->rip, pCtx->cr2));
 
996
        Log(("CPU%d: Reinjecting event %RX64 %08x at %RGv cr2=%RX64\n", pVCpu->idCpu, pVCpu->hwaccm.s.Event.intInfo,
 
997
             pVCpu->hwaccm.s.Event.errCode, (RTGCPTR)pCtx->rip, pCtx->cr2));
862
998
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatIntReinject);
863
 
        rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, pVCpu->hwaccm.s.Event.intInfo, 0, pVCpu->hwaccm.s.Event.errCode);
 
999
        rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, pVCpu->hwaccm.s.Event.intInfo, 0, pVCpu->hwaccm.s.Event.errCode);
864
1000
        AssertRC(rc);
865
1001
 
866
1002
        pVCpu->hwaccm.s.Event.fPending = false;
867
1003
        return VINF_SUCCESS;
868
1004
    }
869
1005
 
870
 
    /* If an active trap is already pending, then we must forward it first! */
 
1006
    /*
 
1007
     * If an active trap is already pending, we must forward it first!
 
1008
     */
871
1009
    if (!TRPMHasTrap(pVCpu))
872
1010
    {
873
1011
        if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI))
880
1018
            intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
881
1019
            intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
882
1020
 
883
 
            rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, 0, 0);
 
1021
            rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo, 0, 0);
884
1022
            AssertRC(rc);
885
1023
 
886
1024
            return VINF_SUCCESS;
887
1025
        }
888
1026
 
889
 
        /* @todo SMI interrupts. */
 
1027
        /** @todo SMI interrupts. */
890
1028
 
891
 
        /* When external interrupts are pending, we should exit the VM when IF is set. */
 
1029
        /*
 
1030
         * When external interrupts are pending, we should exit the VM when IF is set.
 
1031
         */
892
1032
        if (VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)))
893
1033
        {
894
1034
            if (!(pCtx->eflags.u32 & X86_EFL_IF))
902
1042
                }
903
1043
                /* else nothing to do but wait */
904
1044
            }
905
 
            else
906
 
            if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
 
1045
            else if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
907
1046
            {
908
1047
                uint8_t u8Interrupt;
909
1048
 
910
1049
                rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
911
 
                Log(("CPU%d: Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc cs:rip=%04X:%RGv\n", pVCpu->idCpu, u8Interrupt, u8Interrupt, rc, pCtx->cs, (RTGCPTR)pCtx->rip));
 
1050
                Log(("CPU%d: Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc cs:rip=%04X:%RGv\n", pVCpu->idCpu,
 
1051
                     u8Interrupt, u8Interrupt, rc, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
912
1052
                if (RT_SUCCESS(rc))
913
1053
                {
914
1054
                    rc = TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT);
930
1070
#ifdef VBOX_STRICT
931
1071
    if (TRPMHasTrap(pVCpu))
932
1072
    {
933
 
        uint8_t     u8Vector;
 
1073
        uint8_t u8Vector;
934
1074
        rc = TRPMQueryTrapAll(pVCpu, &u8Vector, 0, 0, 0);
935
1075
        AssertRC(rc);
936
1076
    }
937
1077
#endif
938
1078
 
939
 
    if (    (pCtx->eflags.u32 & X86_EFL_IF)
 
1079
    if (   (pCtx->eflags.u32 & X86_EFL_IF)
940
1080
        && (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
941
1081
        && TRPMHasTrap(pVCpu)
942
1082
       )
946
1086
        RTGCUINTPTR intInfo;
947
1087
        RTGCUINT    errCode;
948
1088
 
949
 
        /* If a new event is pending, then dispatch it now. */
 
1089
        /*
 
1090
         * If a new event is pending, dispatch it now.
 
1091
         */
950
1092
        rc = TRPMQueryTrapAll(pVCpu, &u8Vector, &enmType, &errCode, 0);
951
1093
        AssertRC(rc);
952
1094
        Assert(pCtx->eflags.Bits.u1IF == 1 || enmType == TRPM_TRAP);
953
1095
        Assert(enmType != TRPM_SOFTWARE_INT);
954
1096
 
955
 
        /* Clear the pending trap. */
 
1097
        /*
 
1098
         * Clear the pending trap.
 
1099
         */
956
1100
        rc = TRPMResetTrap(pVCpu);
957
1101
        AssertRC(rc);
958
1102
 
961
1105
 
962
1106
        if (enmType == TRPM_TRAP)
963
1107
        {
964
 
            switch (u8Vector) {
965
 
            case 8:
966
 
            case 10:
967
 
            case 11:
968
 
            case 12:
969
 
            case 13:
970
 
            case 14:
971
 
            case 17:
972
 
                /* Valid error codes. */
973
 
                intInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID;
974
 
                break;
975
 
            default:
976
 
                break;
 
1108
            switch (u8Vector)
 
1109
            {
 
1110
                case X86_XCPT_DF:
 
1111
                case X86_XCPT_TS:
 
1112
                case X86_XCPT_NP:
 
1113
                case X86_XCPT_SS:
 
1114
                case X86_XCPT_GP:
 
1115
                case X86_XCPT_PF:
 
1116
                case X86_XCPT_AC:
 
1117
                {
 
1118
                    /* Valid error codes. */
 
1119
                    intInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID;
 
1120
                    break;
 
1121
                }
 
1122
 
 
1123
                default:
 
1124
                    break;
977
1125
            }
978
 
            if (u8Vector == X86_XCPT_BP || u8Vector == X86_XCPT_OF)
 
1126
 
 
1127
            if (   u8Vector == X86_XCPT_BP
 
1128
                || u8Vector == X86_XCPT_OF)
 
1129
            {
979
1130
                intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
 
1131
            }
980
1132
            else
981
1133
                intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
982
1134
        }
984
1136
            intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
985
1137
 
986
1138
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatIntInject);
987
 
        rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, 0, errCode);
 
1139
        rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo, 0, errCode);
988
1140
        AssertRC(rc);
989
1141
    } /* if (interrupts can be dispatched) */
990
1142
 
991
1143
    return VINF_SUCCESS;
992
1144
}
993
1145
 
 
1146
 
994
1147
/**
995
 
 * Save the host state
 
1148
 * Save the host state into the VMCS.
996
1149
 *
997
1150
 * @returns VBox status code.
998
 
 * @param   pVM         The VM to operate on.
999
 
 * @param   pVCpu       The VMCPU to operate on.
 
1151
 * @param   pVM         Pointer to the VM.
 
1152
 * @param   pVCpu       Pointer to the VMCPU.
1000
1153
 */
1001
1154
VMMR0DECL(int) VMXR0SaveHostState(PVM pVM, PVMCPU pVCpu)
1002
1155
{
1003
1156
    int rc = VINF_SUCCESS;
 
1157
    NOREF(pVM);
1004
1158
 
1005
1159
    /*
1006
 
     * Host CPU Context
 
1160
     * Host CPU Context.
1007
1161
     */
1008
1162
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_HOST_CONTEXT)
1009
1163
    {
1016
1170
        RTSEL       ss;
1017
1171
        uint64_t    cr3;
1018
1172
 
1019
 
        /* Control registers */
1020
 
        rc  = VMXWriteVMCS(VMX_VMCS_HOST_CR0,               ASMGetCR0());
 
1173
        /*
 
1174
         * Control registers.
 
1175
         */
 
1176
        rc  = VMXWriteVMCS(VMX_VMCS_HOST_CR0,           ASMGetCR0());
 
1177
        Log2(("VMX_VMCS_HOST_CR0 %08x\n",               ASMGetCR0()));
1021
1178
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1022
1179
        if (VMX_IS_64BIT_HOST_MODE())
1023
1180
        {
1024
1181
            cr3 = hwaccmR0Get64bitCR3();
1025
 
            rc |= VMXWriteVMCS64(VMX_VMCS_HOST_CR3,         cr3);
 
1182
            rc |= VMXWriteVMCS64(VMX_VMCS_HOST_CR3,     cr3);
1026
1183
        }
1027
1184
        else
1028
1185
#endif
1029
1186
        {
1030
1187
            cr3 = ASMGetCR3();
1031
 
            rc |= VMXWriteVMCS(VMX_VMCS_HOST_CR3,           cr3);
 
1188
            rc |= VMXWriteVMCS(VMX_VMCS_HOST_CR3,       cr3);
1032
1189
        }
1033
 
        rc |= VMXWriteVMCS(VMX_VMCS_HOST_CR4,               ASMGetCR4());
 
1190
        Log2(("VMX_VMCS_HOST_CR3 %08RX64\n",            cr3));
 
1191
        rc |= VMXWriteVMCS(VMX_VMCS_HOST_CR4,           ASMGetCR4());
 
1192
        Log2(("VMX_VMCS_HOST_CR4 %08x\n",               ASMGetCR4()));
1034
1193
        AssertRC(rc);
1035
 
        Log2(("VMX_VMCS_HOST_CR0 %08x\n", ASMGetCR0()));
1036
 
        Log2(("VMX_VMCS_HOST_CR3 %08RX64\n", cr3));
1037
 
        Log2(("VMX_VMCS_HOST_CR4 %08x\n", ASMGetCR4()));
1038
1194
 
1039
 
        /* Selector registers. */
 
1195
        /*
 
1196
         * Selector registers.
 
1197
         */
1040
1198
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1041
1199
        if (VMX_IS_64BIT_HOST_MODE())
1042
1200
        {
1078
1236
        Log2(("VMX_VMCS_HOST_FIELD_SS %08x (%08x)\n", ss, ASMGetSS()));
1079
1237
        Log2(("VMX_VMCS_HOST_FIELD_TR %08x\n", ASMGetTR()));
1080
1238
 
1081
 
        /* GDTR & IDTR */
 
1239
        /*
 
1240
         * GDTR & IDTR.
 
1241
         */
1082
1242
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1083
1243
        if (VMX_IS_64BIT_HOST_MODE())
1084
1244
        {
1104
1264
            Log2(("VMX_VMCS_HOST_IDTR_BASE %RHv\n", idtr.pIdt));
1105
1265
        }
1106
1266
 
1107
 
        /* Save the base address of the TR selector. */
 
1267
        /*
 
1268
         * Save the base address of the TR selector.
 
1269
         */
1108
1270
        if (SelTR > gdtr.cbGdt)
1109
1271
        {
1110
1272
            AssertMsgFailed(("Invalid TR selector %x. GDTR.cbGdt=%x\n", SelTR, gdtr.cbGdt));
1115
1277
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1116
1278
        if (VMX_IS_64BIT_HOST_MODE())
1117
1279
        {
1118
 
            uint64_t trBase64 = X86DESC64_BASE(*(PX86DESC64)pDesc);
 
1280
            uint64_t trBase64 = X86DESC64_BASE((PX86DESC64)pDesc);
1119
1281
            rc = VMXWriteVMCS64(VMX_VMCS_HOST_TR_BASE, trBase64);
1120
1282
            Log2(("VMX_VMCS_HOST_TR_BASE %RX64\n", trBase64));
1121
1283
            AssertRC(rc);
1124
1286
#endif
1125
1287
        {
1126
1288
#if HC_ARCH_BITS == 64
1127
 
            trBase = X86DESC64_BASE(*pDesc);
 
1289
            trBase = X86DESC64_BASE(pDesc);
1128
1290
#else
1129
 
            trBase = X86DESC_BASE(*pDesc);
 
1291
            trBase = X86DESC_BASE(pDesc);
1130
1292
#endif
1131
1293
            rc = VMXWriteVMCS(VMX_VMCS_HOST_TR_BASE, trBase);
1132
1294
            AssertRC(rc);
1133
1295
            Log2(("VMX_VMCS_HOST_TR_BASE %RHv\n", trBase));
1134
1296
        }
1135
1297
 
1136
 
        /* FS and GS base. */
 
1298
        /*
 
1299
         * FS base and GS base.
 
1300
         */
1137
1301
#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1138
1302
        if (VMX_IS_64BIT_HOST_MODE())
1139
1303
        {
1140
1304
            Log2(("MSR_K8_FS_BASE = %RX64\n", ASMRdMsr(MSR_K8_FS_BASE)));
1141
1305
            Log2(("MSR_K8_GS_BASE = %RX64\n", ASMRdMsr(MSR_K8_GS_BASE)));
1142
 
            rc  = VMXWriteVMCS64(VMX_VMCS_HOST_FS_BASE,     ASMRdMsr(MSR_K8_FS_BASE));
1143
 
            rc |= VMXWriteVMCS64(VMX_VMCS_HOST_GS_BASE,     ASMRdMsr(MSR_K8_GS_BASE));
 
1306
            rc  = VMXWriteVMCS64(VMX_VMCS_HOST_FS_BASE,         ASMRdMsr(MSR_K8_FS_BASE));
 
1307
            rc |= VMXWriteVMCS64(VMX_VMCS_HOST_GS_BASE,         ASMRdMsr(MSR_K8_GS_BASE));
1144
1308
        }
1145
1309
#endif
1146
1310
        AssertRC(rc);
1147
1311
 
1148
 
        /* Sysenter MSRs. */
 
1312
        /*
 
1313
         * Sysenter MSRs.
 
1314
         */
1149
1315
        /** @todo expensive!! */
1150
 
        rc  = VMXWriteVMCS(VMX_VMCS32_HOST_SYSENTER_CS,       ASMRdMsr_Low(MSR_IA32_SYSENTER_CS));
1151
 
        Log2(("VMX_VMCS_HOST_SYSENTER_CS  %08x\n", ASMRdMsr_Low(MSR_IA32_SYSENTER_CS)));
 
1316
        rc  = VMXWriteVMCS(VMX_VMCS32_HOST_SYSENTER_CS,         ASMRdMsr_Low(MSR_IA32_SYSENTER_CS));
 
1317
        Log2(("VMX_VMCS_HOST_SYSENTER_CS  %08x\n",              ASMRdMsr_Low(MSR_IA32_SYSENTER_CS)));
1152
1318
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1153
1319
        if (VMX_IS_64BIT_HOST_MODE())
1154
1320
        {
1159
1325
        }
1160
1326
        else
1161
1327
        {
1162
 
            rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_ESP,  ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP));
1163
 
            rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_EIP,  ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP));
1164
 
            Log2(("VMX_VMCS_HOST_SYSENTER_EIP %RX32\n",     ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP)));
1165
 
            Log2(("VMX_VMCS_HOST_SYSENTER_ESP %RX32\n",     ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP)));
 
1328
            rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_ESP,      ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP));
 
1329
            rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_EIP,      ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP));
 
1330
            Log2(("VMX_VMCS_HOST_SYSENTER_EIP %RX32\n",         ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP)));
 
1331
            Log2(("VMX_VMCS_HOST_SYSENTER_ESP %RX32\n",         ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP)));
1166
1332
        }
1167
1333
#elif HC_ARCH_BITS == 32
1168
 
        rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_ESP,      ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP));
1169
 
        rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_EIP,      ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP));
1170
 
        Log2(("VMX_VMCS_HOST_SYSENTER_EIP %RX32\n", ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP)));
1171
 
        Log2(("VMX_VMCS_HOST_SYSENTER_ESP %RX32\n", ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP)));
 
1334
        rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_ESP,          ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP));
 
1335
        rc |= VMXWriteVMCS(VMX_VMCS_HOST_SYSENTER_EIP,          ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP));
 
1336
        Log2(("VMX_VMCS_HOST_SYSENTER_EIP %RX32\n",             ASMRdMsr_Low(MSR_IA32_SYSENTER_EIP)));
 
1337
        Log2(("VMX_VMCS_HOST_SYSENTER_ESP %RX32\n",             ASMRdMsr_Low(MSR_IA32_SYSENTER_ESP)));
1172
1338
#else
1173
 
        Log2(("VMX_VMCS_HOST_SYSENTER_EIP %RX64\n", ASMRdMsr(MSR_IA32_SYSENTER_EIP)));
1174
 
        Log2(("VMX_VMCS_HOST_SYSENTER_ESP %RX64\n", ASMRdMsr(MSR_IA32_SYSENTER_ESP)));
1175
 
        rc |= VMXWriteVMCS64(VMX_VMCS_HOST_SYSENTER_ESP,      ASMRdMsr(MSR_IA32_SYSENTER_ESP));
1176
 
        rc |= VMXWriteVMCS64(VMX_VMCS_HOST_SYSENTER_EIP,      ASMRdMsr(MSR_IA32_SYSENTER_EIP));
 
1339
        Log2(("VMX_VMCS_HOST_SYSENTER_EIP %RX64\n",             ASMRdMsr(MSR_IA32_SYSENTER_EIP)));
 
1340
        Log2(("VMX_VMCS_HOST_SYSENTER_ESP %RX64\n",             ASMRdMsr(MSR_IA32_SYSENTER_ESP)));
 
1341
            rc |= VMXWriteVMCS64(VMX_VMCS_HOST_SYSENTER_ESP,    ASMRdMsr(MSR_IA32_SYSENTER_ESP));
 
1342
        rc |= VMXWriteVMCS64(VMX_VMCS_HOST_SYSENTER_EIP,        ASMRdMsr(MSR_IA32_SYSENTER_EIP));
1177
1343
#endif
1178
1344
        AssertRC(rc);
1179
1345
 
 
1346
 
1180
1347
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
1181
 
        /* Store all host MSRs in the VM-Exit load area, so they will be reloaded after the world switch back to the host. */
 
1348
        /*
 
1349
         * Store all host MSRs in the VM-Exit load area, so they will be reloaded after
 
1350
         * the world switch back to the host.
 
1351
         */
1182
1352
        PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pHostMSR;
1183
1353
        unsigned idxMsr = 0;
1184
1354
 
1185
 
        /* EFER MSR present? */
1186
 
        if (ASMCpuId_EDX(0x80000001) & (X86_CPUID_AMD_FEATURE_EDX_NX|X86_CPUID_AMD_FEATURE_EDX_LONG_MODE))
 
1355
        uint32_t u32HostExtFeatures = ASMCpuId_EDX(0x80000001);
 
1356
        if (u32HostExtFeatures & (X86_CPUID_EXT_FEATURE_EDX_NX | X86_CPUID_EXT_FEATURE_EDX_LONG_MODE))
1187
1357
        {
1188
 
            if (ASMCpuId_EDX(0x80000001) & X86_CPUID_AMD_FEATURE_EDX_SEP)
1189
 
            {
1190
 
                pMsr->u32IndexMSR = MSR_K6_STAR;
1191
 
                pMsr->u32Reserved = 0;
1192
 
                pMsr->u64Value    = ASMRdMsr(MSR_K6_STAR);                   /* legacy syscall eip, cs & ss */
1193
 
                pMsr++; idxMsr++;
1194
 
            }
1195
 
 
1196
1358
            pMsr->u32IndexMSR = MSR_K6_EFER;
1197
1359
            pMsr->u32Reserved = 0;
1198
1360
# if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1199
1361
            if (CPUMIsGuestInLongMode(pVCpu))
1200
1362
            {
1201
 
                /* Must match the efer value in our 64 bits switcher. */
 
1363
                /* Must match the EFER value in our 64 bits switcher. */
1202
1364
                pMsr->u64Value    = ASMRdMsr(MSR_K6_EFER) | MSR_K6_EFER_LME | MSR_K6_EFER_SCE | MSR_K6_EFER_NXE;
1203
1365
            }
1204
1366
            else
1210
1372
# if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1211
1373
        if (VMX_IS_64BIT_HOST_MODE())
1212
1374
        {
 
1375
            pMsr->u32IndexMSR = MSR_K6_STAR;
 
1376
            pMsr->u32Reserved = 0;
 
1377
            pMsr->u64Value    = ASMRdMsr(MSR_K6_STAR);              /* legacy syscall eip, cs & ss */
 
1378
            pMsr++; idxMsr++;
1213
1379
            pMsr->u32IndexMSR = MSR_K8_LSTAR;
1214
1380
            pMsr->u32Reserved = 0;
1215
1381
            pMsr->u64Value    = ASMRdMsr(MSR_K8_LSTAR);             /* 64 bits mode syscall rip */
1218
1384
            pMsr->u32Reserved = 0;
1219
1385
            pMsr->u64Value    = ASMRdMsr(MSR_K8_SF_MASK);           /* syscall flag mask */
1220
1386
            pMsr++; idxMsr++;
 
1387
 
 
1388
            /* The KERNEL_GS_BASE MSR doesn't work reliably with auto load/store. See @bugref{6208}  */
 
1389
#if 0
1221
1390
            pMsr->u32IndexMSR = MSR_K8_KERNEL_GS_BASE;
1222
1391
            pMsr->u32Reserved = 0;
1223
1392
            pMsr->u64Value    = ASMRdMsr(MSR_K8_KERNEL_GS_BASE);    /* swapgs exchange value */
1224
1393
            pMsr++; idxMsr++;
 
1394
#endif
1225
1395
        }
1226
1396
# endif
 
1397
 
 
1398
        if (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
 
1399
        {
 
1400
            pMsr->u32IndexMSR = MSR_K8_TSC_AUX;
 
1401
            pMsr->u32Reserved = 0;
 
1402
            pMsr->u64Value    = ASMRdMsr(MSR_K8_TSC_AUX);
 
1403
            pMsr++; idxMsr++;
 
1404
        }
 
1405
 
 
1406
        /** @todo r=ramshankar: check IA32_VMX_MISC bits 27:25 for valid idxMsr
 
1407
         *        range. */
1227
1408
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT, idxMsr);
1228
1409
        AssertRC(rc);
1229
1410
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
1233
1414
    return rc;
1234
1415
}
1235
1416
 
 
1417
 
1236
1418
/**
1237
1419
 * Loads the 4 PDPEs into the guest state when nested paging is used and the
1238
1420
 * guest operates in PAE mode.
1239
1421
 *
1240
 
 * @returns VINF_SUCCESS or fatal error.
1241
 
 * @param   pVCpu       The VMCPU to operate on.
1242
 
 * @param   pCtx        Guest context
 
1422
 * @returns VBox status code.
 
1423
 * @param   pVCpu       Pointer to the VMCPU.
 
1424
 * @param   pCtx        Pointer to the guest CPU context.
1243
1425
 */
1244
1426
static int hmR0VmxLoadPaePdpes(PVMCPU pVCpu, PCPUMCTX pCtx)
1245
1427
{
1257
1439
    return VINF_SUCCESS;
1258
1440
}
1259
1441
 
 
1442
 
1260
1443
/**
1261
1444
 * Saves the 4 PDPEs into the guest state when nested paging is used and the
1262
1445
 * guest operates in PAE mode.
1263
1446
 *
1264
 
 * @returns VINF_SUCCESS or fatal error.
1265
 
 * @param   pVCpu       The VMCPU to operate on.
1266
 
 * @param   pCtx        Guest context
 
1447
 * @returns VBox status code.
 
1448
 * @param   pVCpu       Pointer to the VM CPU.
 
1449
 * @param   pCtx        Pointer to the guest CPU context.
1267
1450
 *
1268
1451
 * @remarks Tell PGM about CR3 changes before calling this helper.
1269
1452
 */
1286
1469
 
1287
1470
 
1288
1471
/**
1289
 
 * Update the exception bitmap according to the current CPU state
 
1472
 * Update the exception bitmap according to the current CPU state.
1290
1473
 *
1291
 
 * @param   pVM         The VM to operate on.
1292
 
 * @param   pVCpu       The VMCPU to operate on.
1293
 
 * @param   pCtx        Guest context
 
1474
 * @param   pVM         Pointer to the VM.
 
1475
 * @param   pVCpu       Pointer to the VMCPU.
 
1476
 * @param   pCtx        Pointer to the guest CPU context.
1294
1477
 */
1295
 
static void vmxR0UpdateExceptionBitmap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 
1478
static void hmR0VmxUpdateExceptionBitmap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
1296
1479
{
1297
1480
    uint32_t u32TrapMask;
1298
1481
    Assert(pCtx);
1299
1482
 
1300
 
    u32TrapMask = HWACCM_VMX_TRAP_MASK;
1301
 
#ifndef DEBUG
1302
 
    if (pVM->hwaccm.s.fNestedPaging)
1303
 
        u32TrapMask &= ~RT_BIT(X86_XCPT_PF);   /* no longer need to intercept #PF. */
1304
 
#endif
1305
 
 
1306
 
    /* Also catch floating point exceptions if we need to report them to the guest in a different way. */
 
1483
    /*
 
1484
     * Set up a mask for intercepting traps.
 
1485
     */
 
1486
    /** @todo Do we really need to always intercept #DB? */
 
1487
    u32TrapMask  =   RT_BIT(X86_XCPT_DB)
 
1488
                   | RT_BIT(X86_XCPT_NM)
 
1489
#ifdef VBOX_ALWAYS_TRAP_PF
 
1490
                   | RT_BIT(X86_XCPT_PF)
 
1491
#endif
 
1492
#ifdef VBOX_STRICT
 
1493
                   | RT_BIT(X86_XCPT_BP)
 
1494
                   | RT_BIT(X86_XCPT_DB)
 
1495
                   | RT_BIT(X86_XCPT_DE)
 
1496
                   | RT_BIT(X86_XCPT_NM)
 
1497
                   | RT_BIT(X86_XCPT_UD)
 
1498
                   | RT_BIT(X86_XCPT_NP)
 
1499
                   | RT_BIT(X86_XCPT_SS)
 
1500
                   | RT_BIT(X86_XCPT_GP)
 
1501
                   | RT_BIT(X86_XCPT_MF)
 
1502
#endif
 
1503
                   ;
 
1504
 
 
1505
    /*
 
1506
     * Without nested paging, #PF must be intercepted to implement shadow paging.
 
1507
     */
 
1508
    /** @todo NP state won't change so maybe we should build the initial trap mask up front? */
 
1509
    if (!pVM->hwaccm.s.fNestedPaging)
 
1510
        u32TrapMask |= RT_BIT(X86_XCPT_PF);
 
1511
 
 
1512
    /* Catch floating point exceptions if we need to report them to the guest in a different way. */
1307
1513
    if (!(pCtx->cr0 & X86_CR0_NE))
1308
 
    {
1309
1514
        u32TrapMask |= RT_BIT(X86_XCPT_MF);
1310
 
    }
1311
1515
 
1312
1516
#ifdef VBOX_STRICT
1313
1517
    Assert(u32TrapMask & RT_BIT(X86_XCPT_GP));
1314
1518
#endif
1315
1519
 
1316
 
    /* Intercept all exceptions in real mode as none of them can be injected directly (#GP otherwise). */
 
1520
    /*
 
1521
     * Intercept all exceptions in real mode as none of them can be injected directly (#GP otherwise).
 
1522
     */
 
1523
    /** @todo Despite the claim to intercept everything, with NP we do not intercept #PF. Should we? */
1317
1524
    if (    CPUMIsGuestInRealModeEx(pCtx)
1318
1525
        &&  pVM->hwaccm.s.vmx.pRealModeTSS)
1319
 
        u32TrapMask |= HWACCM_VMX_TRAP_MASK_REALMODE;
 
1526
    {
 
1527
        u32TrapMask |=   RT_BIT(X86_XCPT_DE)
 
1528
                       | RT_BIT(X86_XCPT_DB)
 
1529
                       | RT_BIT(X86_XCPT_NMI)
 
1530
                       | RT_BIT(X86_XCPT_BP)
 
1531
                       | RT_BIT(X86_XCPT_OF)
 
1532
                       | RT_BIT(X86_XCPT_BR)
 
1533
                       | RT_BIT(X86_XCPT_UD)
 
1534
                       | RT_BIT(X86_XCPT_DF)
 
1535
                       | RT_BIT(X86_XCPT_CO_SEG_OVERRUN)
 
1536
                       | RT_BIT(X86_XCPT_TS)
 
1537
                       | RT_BIT(X86_XCPT_NP)
 
1538
                       | RT_BIT(X86_XCPT_SS)
 
1539
                       | RT_BIT(X86_XCPT_GP)
 
1540
                       | RT_BIT(X86_XCPT_MF)
 
1541
                       | RT_BIT(X86_XCPT_AC)
 
1542
                       | RT_BIT(X86_XCPT_MC)
 
1543
                       | RT_BIT(X86_XCPT_XF)
 
1544
                       ;
 
1545
    }
1320
1546
 
1321
1547
    int rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXCEPTION_BITMAP, u32TrapMask);
1322
1548
    AssertRC(rc);
1323
1549
}
1324
1550
 
 
1551
 
1325
1552
/**
1326
 
 * Loads a minimal guest state
 
1553
 * Loads a minimal guest state.
1327
1554
 *
1328
1555
 * NOTE: Don't do anything here that can cause a jump back to ring 3!!!!!
1329
1556
 *
1330
 
 * @param   pVM         The VM to operate on.
1331
 
 * @param   pVCpu       The VMCPU to operate on.
1332
 
 * @param   pCtx        Guest context
 
1557
 * @param   pVM         Pointer to the VM.
 
1558
 * @param   pVCpu       Pointer to the VMCPU.
 
1559
 * @param   pCtx        Pointer to the guest CPU context.
1333
1560
 */
1334
1561
VMMR0DECL(void) VMXR0LoadMinimalGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
1335
1562
{
1338
1565
 
1339
1566
    Assert(!(pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_ALL_GUEST));
1340
1567
 
1341
 
    /* EIP, ESP and EFLAGS */
 
1568
    /*
 
1569
     * Load EIP, ESP and EFLAGS.
 
1570
     */
1342
1571
    rc  = VMXWriteVMCS64(VMX_VMCS64_GUEST_RIP, pCtx->rip);
1343
1572
    rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_RSP, pCtx->rsp);
1344
1573
    AssertRC(rc);
1345
1574
 
1346
 
    /* Bits 22-31, 15, 5 & 3 must be zero. Bit 1 must be 1. */
 
1575
    /*
 
1576
     * Bits 22-31, 15, 5 & 3 must be zero. Bit 1 must be 1.
 
1577
     */
1347
1578
    eflags      = pCtx->eflags;
1348
1579
    eflags.u32 &= VMX_EFLAGS_RESERVED_0;
1349
1580
    eflags.u32 |= VMX_EFLAGS_RESERVED_1;
1350
1581
 
1351
 
    /* Real mode emulation using v86 mode. */
 
1582
    /*
 
1583
     * Check if real mode emulation using v86 mode.
 
1584
     */
1352
1585
    if (    CPUMIsGuestInRealModeEx(pCtx)
1353
1586
        &&  pVM->hwaccm.s.vmx.pRealModeTSS)
1354
1587
    {
1361
1594
    AssertRC(rc);
1362
1595
}
1363
1596
 
 
1597
 
1364
1598
/**
1365
 
 * Loads the guest state
 
1599
 * Loads the guest state.
1366
1600
 *
1367
1601
 * NOTE: Don't do anything here that can cause a jump back to ring 3!!!!!
1368
1602
 *
1369
1603
 * @returns VBox status code.
1370
 
 * @param   pVM         The VM to operate on.
1371
 
 * @param   pVCpu       The VMCPU to operate on.
1372
 
 * @param   pCtx        Guest context
 
1604
 * @param   pVM         Pointer to the VM.
 
1605
 * @param   pVCpu       Pointer to the VMCPU.
 
1606
 * @param   pCtx        Pointer to the guest CPU context.
1373
1607
 */
1374
1608
VMMR0DECL(int) VMXR0LoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
1375
1609
{
1376
1610
    int         rc = VINF_SUCCESS;
1377
1611
    RTGCUINTPTR val;
1378
1612
 
1379
 
    /* VMX_VMCS_CTRL_ENTRY_CONTROLS
 
1613
    /*
 
1614
     * VMX_VMCS_CTRL_ENTRY_CONTROLS
1380
1615
     * Set required bits to one and zero according to the MSR capabilities.
1381
1616
     */
1382
1617
    val  = pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0;
1383
 
    /* Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
 
1618
 
 
1619
    /*
 
1620
     * Load guest debug controls (DR7 & IA32_DEBUGCTL_MSR).
 
1621
     * Forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs
 
1622
     */
1384
1623
    val |= VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG;
1385
 
    /* 64 bits guest mode? */
 
1624
 
1386
1625
    if (CPUMIsGuestInLongModeEx(pCtx))
1387
1626
        val |= VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE;
1388
1627
    /* else Must be zero when AMD64 is not available. */
1389
1628
 
1390
 
    /* Mask away the bits that the CPU doesn't support */
 
1629
    /*
 
1630
     * Mask away the bits that the CPU doesn't support.
 
1631
     */
1391
1632
    val &= pVM->hwaccm.s.vmx.msr.vmx_entry.n.allowed1;
1392
1633
    rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_CONTROLS, val);
1393
1634
    AssertRC(rc);
1394
1635
 
1395
 
    /* VMX_VMCS_CTRL_EXIT_CONTROLS
 
1636
    /*
 
1637
     * VMX_VMCS_CTRL_EXIT_CONTROLS
1396
1638
     * Set required bits to one and zero according to the MSR capabilities.
1397
1639
     */
1398
1640
    val  = pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0;
1399
1641
 
1400
 
    /* Save debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
 
1642
    /*
 
1643
     * Save debug controls (DR7 & IA32_DEBUGCTL_MSR)
 
1644
     * Forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs
 
1645
     */
1401
1646
    val |= VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG;
1402
1647
 
1403
1648
#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1404
1649
    if (VMX_IS_64BIT_HOST_MODE())
1405
1650
        val |= VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64;
1406
 
    /* else: Must be zero when AMD64 is not available. */
 
1651
    /* else Must be zero when AMD64 is not available. */
1407
1652
#elif HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS)
1408
1653
    if (CPUMIsGuestInLongModeEx(pCtx))
1409
1654
        val |= VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64;      /* our switcher goes to long mode */
1411
1656
        Assert(!(val & VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64));
1412
1657
#endif
1413
1658
    val &= pVM->hwaccm.s.vmx.msr.vmx_exit.n.allowed1;
1414
 
    /* Don't acknowledge external interrupts on VM-exit. */
 
1659
 
 
1660
    /*
 
1661
     * Don't acknowledge external interrupts on VM-exit.
 
1662
     */
1415
1663
    rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_CONTROLS, val);
1416
1664
    AssertRC(rc);
1417
1665
 
1418
 
    /* Guest CPU context: ES, CS, SS, DS, FS, GS. */
 
1666
    /*
 
1667
     * Guest CPU context: ES, CS, SS, DS, FS, GS.
 
1668
     */
1419
1669
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_SEGMENT_REGS)
1420
1670
    {
1421
1671
        if (pVM->hwaccm.s.vmx.pRealModeTSS)
1423
1673
            PGMMODE enmGuestMode = PGMGetGuestMode(pVCpu);
1424
1674
            if (pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode != enmGuestMode)
1425
1675
            {
1426
 
                /* Correct weird requirements for switching to protected mode. */
 
1676
                /*
 
1677
                 * Correct weird requirements for switching to protected mode.
 
1678
                 */
1427
1679
                if (    pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode == PGMMODE_REAL
1428
1680
                    &&  enmGuestMode >= PGMMODE_PROTECTED)
1429
1681
                {
1430
 
                    /* Flush the recompiler code cache as it's not unlikely
1431
 
                     * the guest will rewrite code it will later execute in real
1432
 
                     * mode (OpenBSD 4.0 is one such example)
 
1682
#ifdef VBOX_WITH_REM
 
1683
                    /*
 
1684
                     * Flush the recompiler code cache as it's not unlikely the guest will rewrite code
 
1685
                     * it will later execute in real mode (OpenBSD 4.0 is one such example)
1433
1686
                     */
1434
1687
                    REMFlushTBs(pVM);
1435
 
 
1436
 
                    /* DPL of all hidden selector registers must match the current CPL (0). */
1437
 
                    pCtx->csHid.Attr.n.u2Dpl  = 0;
1438
 
                    pCtx->csHid.Attr.n.u4Type = X86_SEL_TYPE_CODE | X86_SEL_TYPE_RW_ACC;
1439
 
 
1440
 
                    pCtx->dsHid.Attr.n.u2Dpl  = 0;
1441
 
                    pCtx->esHid.Attr.n.u2Dpl  = 0;
1442
 
                    pCtx->fsHid.Attr.n.u2Dpl  = 0;
1443
 
                    pCtx->gsHid.Attr.n.u2Dpl  = 0;
1444
 
                    pCtx->ssHid.Attr.n.u2Dpl  = 0;
 
1688
#endif
 
1689
 
 
1690
                    /*
 
1691
                     * DPL of all hidden selector registers must match the current CPL (0).
 
1692
                     */
 
1693
                    pCtx->cs.Attr.n.u2Dpl  = 0;
 
1694
                    pCtx->cs.Attr.n.u4Type = X86_SEL_TYPE_CODE | X86_SEL_TYPE_RW_ACC;
 
1695
 
 
1696
                    pCtx->ds.Attr.n.u2Dpl  = 0;
 
1697
                    pCtx->es.Attr.n.u2Dpl  = 0;
 
1698
                    pCtx->fs.Attr.n.u2Dpl  = 0;
 
1699
                    pCtx->gs.Attr.n.u2Dpl  = 0;
 
1700
                    pCtx->ss.Attr.n.u2Dpl  = 0;
1445
1701
                }
1446
1702
                pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = enmGuestMode;
1447
1703
            }
1448
 
            else
1449
 
            /* VT-x will fail with a guest invalid state otherwise... (CPU state after a reset) */
1450
 
            if (   CPUMIsGuestInRealModeEx(pCtx)
1451
 
                && pCtx->csHid.u64Base == 0xffff0000)
 
1704
            else if (   CPUMIsGuestInRealModeEx(pCtx)
 
1705
                     && pCtx->cs.u64Base == 0xffff0000)
1452
1706
            {
1453
 
                pCtx->csHid.u64Base = 0xf0000;
1454
 
                pCtx->cs = 0xf000;
 
1707
                /* VT-x will fail with a guest invalid state otherwise... (CPU state after a reset) */
 
1708
                pCtx->cs.u64Base = 0xf0000;
 
1709
                pCtx->cs.Sel     =  0xf000;
1455
1710
            }
1456
1711
        }
1457
1712
 
1474
1729
        AssertRC(rc);
1475
1730
    }
1476
1731
 
1477
 
    /* Guest CPU context: LDTR. */
 
1732
    /*
 
1733
     * Guest CPU context: LDTR.
 
1734
     */
1478
1735
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_LDTR)
1479
1736
    {
1480
 
        if (pCtx->ldtr == 0)
 
1737
        if (pCtx->ldtr.Sel == 0)
1481
1738
        {
1482
1739
            rc =  VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_LDTR,         0);
1483
1740
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_LDTR_LIMIT,         0);
1487
1744
        }
1488
1745
        else
1489
1746
        {
1490
 
            rc =  VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_LDTR,         pCtx->ldtr);
1491
 
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_LDTR_LIMIT,         pCtx->ldtrHid.u32Limit);
1492
 
            rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_LDTR_BASE,        pCtx->ldtrHid.u64Base);
1493
 
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS, pCtx->ldtrHid.Attr.u);
 
1747
            rc =  VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_LDTR,         pCtx->ldtr.Sel);
 
1748
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_LDTR_LIMIT,         pCtx->ldtr.u32Limit);
 
1749
            rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_LDTR_BASE,        pCtx->ldtr.u64Base);
 
1750
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS, pCtx->ldtr.Attr.u);
1494
1751
        }
1495
1752
        AssertRC(rc);
1496
1753
    }
1497
 
    /* Guest CPU context: TR. */
 
1754
 
 
1755
    /*
 
1756
     * Guest CPU context: TR.
 
1757
     */
1498
1758
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_TR)
1499
1759
    {
1500
 
        /* Real mode emulation using v86 mode with CR4.VME (interrupt redirection using the int bitmap in the TSS) */
 
1760
        /*
 
1761
         * Real mode emulation using v86 mode with CR4.VME (interrupt redirection
 
1762
         * using the int bitmap in the TSS).
 
1763
         */
1501
1764
        if (    CPUMIsGuestInRealModeEx(pCtx)
1502
1765
            &&  pVM->hwaccm.s.vmx.pRealModeTSS)
1503
1766
        {
1504
1767
            RTGCPHYS GCPhys;
1505
1768
 
1506
 
            /* We convert it here every time as pci regions could be reconfigured. */
 
1769
            /* We convert it here every time as PCI regions could be reconfigured. */
1507
1770
            rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hwaccm.s.vmx.pRealModeTSS, &GCPhys);
1508
1771
            AssertRC(rc);
1509
1772
 
1520
1783
        }
1521
1784
        else
1522
1785
        {
1523
 
            rc =  VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_TR,         pCtx->tr);
1524
 
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_TR_LIMIT,         pCtx->trHid.u32Limit);
1525
 
            rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_TR_BASE,        pCtx->trHid.u64Base);
 
1786
            rc =  VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_TR,         pCtx->tr.Sel);
 
1787
            rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_TR_LIMIT,         pCtx->tr.u32Limit);
 
1788
            rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_TR_BASE,        pCtx->tr.u64Base);
1526
1789
 
1527
 
            val = pCtx->trHid.Attr.u;
 
1790
            val = pCtx->tr.Attr.u;
1528
1791
 
1529
1792
            /* The TSS selector must be busy (REM bugs? see defect #XXXX). */
1530
1793
            if (!(val & X86_SEL_TYPE_SYS_TSS_BUSY_MASK))
1535
1798
                    /* Default if no TR selector has been set (otherwise vmlaunch will fail!) */
1536
1799
                    val = (val & ~0xF) | X86_SEL_TYPE_SYS_386_TSS_BUSY;
1537
1800
            }
1538
 
            AssertMsg((val & 0xf) == X86_SEL_TYPE_SYS_386_TSS_BUSY || (val & 0xf) == X86_SEL_TYPE_SYS_286_TSS_BUSY, ("%#x\n", val));
 
1801
            AssertMsg((val & 0xf) == X86_SEL_TYPE_SYS_386_TSS_BUSY || (val & 0xf) == X86_SEL_TYPE_SYS_286_TSS_BUSY,
 
1802
                      ("%#x\n", val));
1539
1803
        }
1540
1804
        rc |= VMXWriteVMCS(VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS, val);
1541
1805
        AssertRC(rc);
1542
1806
    }
1543
 
    /* Guest CPU context: GDTR. */
 
1807
 
 
1808
    /*
 
1809
     * Guest CPU context: GDTR.
 
1810
     */
1544
1811
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_GDTR)
1545
1812
    {
1546
1813
        rc  = VMXWriteVMCS(VMX_VMCS32_GUEST_GDTR_LIMIT,       pCtx->gdtr.cbGdt);
1547
1814
        rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_GDTR_BASE,      pCtx->gdtr.pGdt);
1548
1815
        AssertRC(rc);
1549
1816
    }
1550
 
    /* Guest CPU context: IDTR. */
 
1817
 
 
1818
    /*
 
1819
     * Guest CPU context: IDTR.
 
1820
     */
1551
1821
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_IDTR)
1552
1822
    {
1553
1823
        rc  = VMXWriteVMCS(VMX_VMCS32_GUEST_IDTR_LIMIT,       pCtx->idtr.cbIdt);
1556
1826
    }
1557
1827
 
1558
1828
    /*
1559
 
     * Sysenter MSRs
 
1829
     * Sysenter MSRs.
1560
1830
     */
1561
1831
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_MSR)
1562
1832
    {
1566
1836
        AssertRC(rc);
1567
1837
    }
1568
1838
 
1569
 
    /* Control registers */
 
1839
    /*
 
1840
     * Guest CPU context: Control registers.
 
1841
     */
1570
1842
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR0)
1571
1843
    {
1572
1844
        val = pCtx->cr0;
1585
1857
 
1586
1858
            val |= X86_CR0_NE;  /* always turn on the native mechanism to report FPU errors (old style uses interrupts) */
1587
1859
        }
1588
 
        /* Note: protected mode & paging are always enabled; we use them for emulating real and protected mode without paging too. */
 
1860
        /* Protected mode & paging are always enabled; we use them for emulating real and protected mode without paging too. */
1589
1861
        if (!pVM->hwaccm.s.vmx.fUnrestrictedGuest)
1590
1862
            val |= X86_CR0_PE | X86_CR0_PG;
1591
1863
 
1593
1865
        {
1594
1866
            if (CPUMIsGuestInPagedProtectedModeEx(pCtx))
1595
1867
            {
1596
 
                /* Disable cr3 read/write monitoring as we don't need it for EPT. */
 
1868
                /* Disable CR3 read/write monitoring as we don't need it for EPT. */
1597
1869
                pVCpu->hwaccm.s.vmx.proc_ctls &=  ~(  VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
1598
1870
                                                    | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT);
1599
1871
            }
1600
1872
            else
1601
1873
            {
1602
 
                /* Reenable cr3 read/write monitoring as our identity mapped page table is active. */
 
1874
                /* Reenable CR3 read/write monitoring as our identity mapped page table is active. */
1603
1875
                pVCpu->hwaccm.s.vmx.proc_ctls |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
1604
1876
                                                 | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT;
1605
1877
            }
1617
1889
 
1618
1890
        rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_CR0,            val);
1619
1891
        Log2(("Guest CR0 %08x\n", val));
1620
 
        /* CR0 flags owned by the host; if the guests attempts to change them, then
1621
 
         * the VM will exit.
 
1892
 
 
1893
        /*
 
1894
         * CR0 flags owned by the host; if the guests attempts to change them, then the VM will exit.
1622
1895
         */
1623
1896
        val =   X86_CR0_PE  /* Must monitor this bit (assumptions are made for real mode emulation) */
1624
1897
              | X86_CR0_WP  /* Must monitor this bit (it must always be enabled). */
1625
1898
              | X86_CR0_PG  /* Must monitor this bit (assumptions are made for real mode & protected mode without paging emulation) */
1626
1899
              | X86_CR0_CD  /* Bit not restored during VM-exit! */
1627
 
              | X86_CR0_NW /* Bit not restored during VM-exit! */
 
1900
              | X86_CR0_NW  /* Bit not restored during VM-exit! */
1628
1901
              | X86_CR0_NE;
1629
1902
 
1630
 
        /* When the guest's FPU state is active, then we no longer care about
1631
 
         * the FPU related bits.
 
1903
        /*
 
1904
         * When the guest's FPU state is active, then we no longer care about the FPU related bits.
1632
1905
         */
1633
1906
        if (CPUMIsGuestFPUStateActive(pVCpu) == false)
1634
1907
            val |= X86_CR0_TS | X86_CR0_ET | X86_CR0_MP;
1639
1912
        Log2(("Guest CR0-mask %08x\n", val));
1640
1913
        AssertRC(rc);
1641
1914
    }
 
1915
 
1642
1916
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR4)
1643
1917
    {
1644
 
        /* CR4 */
1645
1918
        rc  = VMXWriteVMCS(VMX_VMCS_CTRL_CR4_READ_SHADOW,   pCtx->cr4);
1646
1919
        Log2(("Guest CR4-shadow %08x\n", pCtx->cr4));
1647
1920
        /* Set the required bits in cr4 too (currently X86_CR4_VMXE). */
1649
1922
 
1650
1923
        if (!pVM->hwaccm.s.fNestedPaging)
1651
1924
        {
1652
 
            switch(pVCpu->hwaccm.s.enmShadowMode)
 
1925
            switch (pVCpu->hwaccm.s.enmShadowMode)
1653
1926
            {
1654
 
            case PGMMODE_REAL:          /* Real mode                 -> emulated using v86 mode */
1655
 
            case PGMMODE_PROTECTED:     /* Protected mode, no paging -> emulated using identity mapping. */
1656
 
            case PGMMODE_32_BIT:        /* 32-bit paging. */
1657
 
                val &= ~X86_CR4_PAE;
1658
 
                break;
1659
 
 
1660
 
            case PGMMODE_PAE:           /* PAE paging. */
1661
 
            case PGMMODE_PAE_NX:        /* PAE paging with NX enabled. */
1662
 
                /** Must use PAE paging as we could use physical memory > 4 GB */
1663
 
                val |= X86_CR4_PAE;
1664
 
                break;
1665
 
 
1666
 
            case PGMMODE_AMD64:         /* 64-bit AMD paging (long mode). */
1667
 
            case PGMMODE_AMD64_NX:      /* 64-bit AMD paging (long mode) with NX enabled. */
 
1927
                case PGMMODE_REAL:          /* Real mode                 -> emulated using v86 mode */
 
1928
                case PGMMODE_PROTECTED:     /* Protected mode, no paging -> emulated using identity mapping. */
 
1929
                case PGMMODE_32_BIT:        /* 32-bit paging. */
 
1930
                    val &= ~X86_CR4_PAE;
 
1931
                    break;
 
1932
 
 
1933
                case PGMMODE_PAE:           /* PAE paging. */
 
1934
                case PGMMODE_PAE_NX:        /* PAE paging with NX enabled. */
 
1935
                    /** Must use PAE paging as we could use physical memory > 4 GB */
 
1936
                    val |= X86_CR4_PAE;
 
1937
                    break;
 
1938
 
 
1939
                case PGMMODE_AMD64:         /* 64-bit AMD paging (long mode). */
 
1940
                case PGMMODE_AMD64_NX:      /* 64-bit AMD paging (long mode) with NX enabled. */
1668
1941
#ifdef VBOX_ENABLE_64_BITS_GUESTS
1669
 
                break;
 
1942
                    break;
1670
1943
#else
1671
 
                AssertFailed();
1672
 
                return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
 
1944
                    AssertFailed();
 
1945
                    return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
1673
1946
#endif
1674
 
            default:                   /* shut up gcc */
1675
 
                AssertFailed();
1676
 
                return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
 
1947
                default:                   /* shut up gcc */
 
1948
                    AssertFailed();
 
1949
                    return VERR_PGM_UNSUPPORTED_SHADOW_PAGING_MODE;
1677
1950
            }
1678
1951
        }
1679
 
        else
1680
 
        if (    !CPUMIsGuestInPagedProtectedModeEx(pCtx)
1681
 
            &&  !pVM->hwaccm.s.vmx.fUnrestrictedGuest)
 
1952
        else if (   !CPUMIsGuestInPagedProtectedModeEx(pCtx)
 
1953
                 && !pVM->hwaccm.s.vmx.fUnrestrictedGuest)
1682
1954
        {
1683
1955
            /* We use 4 MB pages in our identity mapping page table for real and protected mode without paging. */
1684
1956
            val |= X86_CR4_PSE;
1686
1958
            val &= ~X86_CR4_PAE;
1687
1959
        }
1688
1960
 
1689
 
        /* Turn off VME if we're in emulated real mode. */
 
1961
        /*
 
1962
         * Turn off VME if we're in emulated real mode.
 
1963
         */
1690
1964
        if (    CPUMIsGuestInRealModeEx(pCtx)
1691
1965
            &&  pVM->hwaccm.s.vmx.pRealModeTSS)
 
1966
        {
1692
1967
            val &= ~X86_CR4_VME;
 
1968
        }
1693
1969
 
1694
1970
        rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_CR4,            val);
1695
1971
        Log2(("Guest CR4 %08x\n", val));
1696
 
        /* CR4 flags owned by the host; if the guests attempts to change them, then
1697
 
         * the VM will exit.
 
1972
 
 
1973
        /*
 
1974
         * CR4 flags owned by the host; if the guests attempts to change them, then the VM will exit.
1698
1975
         */
1699
1976
        val =   0
1700
1977
              | X86_CR4_VME
1709
1986
        AssertRC(rc);
1710
1987
    }
1711
1988
 
 
1989
#if 0
 
1990
    /* Enable single stepping if requested and CPU supports it. */
 
1991
    if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG)
 
1992
        if (DBGFIsStepping(pVCpu))
 
1993
        {
 
1994
            pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG;
 
1995
            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
 
1996
            AssertRC(rc);
 
1997
        }
 
1998
#endif
 
1999
 
1712
2000
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_CR3)
1713
2001
    {
1714
2002
        if (pVM->hwaccm.s.fNestedPaging)
1729
2017
            {
1730
2018
                RTGCPHYS GCPhys;
1731
2019
 
1732
 
                /* We convert it here every time as pci regions could be reconfigured. */
 
2020
                /* We convert it here every time as PCI regions could be reconfigured. */
1733
2021
                rc = PDMVMMDevHeapR3ToGCPhys(pVM, pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable, &GCPhys);
1734
2022
                AssertMsgRC(rc, ("pNonPagingModeEPTPageTable = %RGv\n", pVM->hwaccm.s.vmx.pNonPagingModeEPTPageTable));
1735
2023
 
1736
 
                /* We use our identity mapping page table here as we need to map guest virtual to guest physical addresses; EPT will
1737
 
                 * take care of the translation to host physical addresses.
 
2024
                /*
 
2025
                 * We use our identity mapping page table here as we need to map guest virtual to
 
2026
                 * guest physical addresses; EPT will take care of the translation to host physical addresses.
1738
2027
                 */
1739
2028
                val = GCPhys;
1740
2029
            }
1757
2046
        AssertRC(rc);
1758
2047
    }
1759
2048
 
1760
 
    /* Debug registers. */
 
2049
    /*
 
2050
     * Guest CPU context: Debug registers.
 
2051
     */
1761
2052
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_DEBUG)
1762
2053
    {
1763
2054
        pCtx->dr[6] |= X86_DR6_INIT_VAL;                                          /* set all reserved bits to 1. */
1796
2087
        {
1797
2088
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxArmed);
1798
2089
 
1799
 
            /* Disable drx move intercepts. */
 
2090
            /* Disable DRx move intercepts. */
1800
2091
            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
1801
2092
            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
1802
2093
            AssertRC(rc);
1811
2102
        AssertRC(rc);
1812
2103
 
1813
2104
        /** @todo do we really ever need this? */
1814
 
        rc |= VMXWriteVMCS(VMX_VMCS_GUEST_DEBUG_EXCEPTIONS,         0);
 
2105
        rc |= VMXWriteVMCS(VMX_VMCS_GUEST_DEBUG_EXCEPTIONS,  0);
1815
2106
        AssertRC(rc);
1816
2107
    }
1817
2108
 
1818
 
    /* 64 bits guest mode? */
 
2109
    /*
 
2110
     * 64-bit guest mode.
 
2111
     */
1819
2112
    if (CPUMIsGuestInLongModeEx(pCtx))
1820
2113
    {
1821
2114
#if !defined(VBOX_ENABLE_64_BITS_GUESTS)
1832
2125
        if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_GUEST_MSR)
1833
2126
        {
1834
2127
            /* Update these as wrmsr might have changed them. */
1835
 
            rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_FS_BASE, pCtx->fsHid.u64Base);
 
2128
            rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_FS_BASE, pCtx->fs.u64Base);
1836
2129
            AssertRC(rc);
1837
 
            rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_GS_BASE, pCtx->gsHid.u64Base);
 
2130
            rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_GS_BASE, pCtx->gs.u64Base);
1838
2131
            AssertRC(rc);
1839
2132
        }
1840
2133
    }
1843
2136
        pVCpu->hwaccm.s.vmx.pfnStartVM  = VMXR0StartVM32;
1844
2137
    }
1845
2138
 
1846
 
    vmxR0UpdateExceptionBitmap(pVM, pVCpu, pCtx);
 
2139
    hmR0VmxUpdateExceptionBitmap(pVM, pVCpu, pCtx);
1847
2140
 
1848
2141
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
1849
 
    /* Store all guest MSRs in the VM-Entry load area, so they will be loaded during the world switch. */
 
2142
    /*
 
2143
     * Store all guest MSRs in the VM-entry load area, so they will be loaded
 
2144
     * during VM-entry and restored into the VM-exit store area during VM-exit.
 
2145
     */
1850
2146
    PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pGuestMSR;
1851
2147
    unsigned idxMsr = 0;
1852
2148
 
1853
 
    uint32_t ulEdx;
1854
 
    uint32_t ulTemp;
1855
 
    CPUMGetGuestCpuId(pVCpu, 0x80000001, &ulTemp, &ulTemp, &ulTemp, &ulEdx);
1856
 
    /* EFER MSR present? */
1857
 
    if (ulEdx & (X86_CPUID_AMD_FEATURE_EDX_NX|X86_CPUID_AMD_FEATURE_EDX_LONG_MODE))
 
2149
    uint32_t u32GstExtFeatures;
 
2150
    uint32_t u32Temp;
 
2151
    CPUMGetGuestCpuId(pVCpu, 0x80000001, &u32Temp, &u32Temp, &u32Temp, &u32GstExtFeatures);
 
2152
 
 
2153
    if (u32GstExtFeatures & (X86_CPUID_EXT_FEATURE_EDX_NX | X86_CPUID_EXT_FEATURE_EDX_LONG_MODE))
1858
2154
    {
1859
2155
        pMsr->u32IndexMSR = MSR_K6_EFER;
1860
2156
        pMsr->u32Reserved = 0;
1861
2157
        pMsr->u64Value    = pCtx->msrEFER;
1862
2158
        /* VT-x will complain if only MSR_K6_EFER_LME is set. */
1863
2159
        if (!CPUMIsGuestInLongModeEx(pCtx))
1864
 
            pMsr->u64Value &= ~(MSR_K6_EFER_LMA|MSR_K6_EFER_LME);
 
2160
            pMsr->u64Value &= ~(MSR_K6_EFER_LMA | MSR_K6_EFER_LME);
1865
2161
        pMsr++; idxMsr++;
1866
2162
 
1867
 
        if (ulEdx & X86_CPUID_AMD_FEATURE_EDX_LONG_MODE)
 
2163
        if (u32GstExtFeatures & X86_CPUID_EXT_FEATURE_EDX_LONG_MODE)
1868
2164
        {
1869
2165
            pMsr->u32IndexMSR = MSR_K8_LSTAR;
1870
2166
            pMsr->u32Reserved = 0;
1878
2174
            pMsr->u32Reserved = 0;
1879
2175
            pMsr->u64Value    = pCtx->msrSFMASK;          /* syscall flag mask */
1880
2176
            pMsr++; idxMsr++;
 
2177
 
 
2178
            /* The KERNEL_GS_BASE MSR doesn't work reliably with auto load/store. See @bugref{6208}  */
 
2179
#if 0
1881
2180
            pMsr->u32IndexMSR = MSR_K8_KERNEL_GS_BASE;
1882
2181
            pMsr->u32Reserved = 0;
1883
2182
            pMsr->u64Value    = pCtx->msrKERNELGSBASE;    /* swapgs exchange value */
1884
2183
            pMsr++; idxMsr++;
 
2184
#endif
1885
2185
        }
1886
2186
    }
 
2187
 
 
2188
    if (   pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP
 
2189
        && (u32GstExtFeatures & X86_CPUID_EXT_FEATURE_EDX_RDTSCP))
 
2190
    {
 
2191
        pMsr->u32IndexMSR = MSR_K8_TSC_AUX;
 
2192
        pMsr->u32Reserved = 0;
 
2193
        rc = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX, &pMsr->u64Value);
 
2194
        AssertRC(rc);
 
2195
        pMsr++; idxMsr++;
 
2196
    }
 
2197
 
1887
2198
    pVCpu->hwaccm.s.vmx.cCachedMSRs = idxMsr;
1888
2199
 
1889
2200
    rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT, idxMsr);
1911
2222
    }
1912
2223
    else
1913
2224
        fOffsettedTsc = TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hwaccm.s.vmx.u64TSCOffset);
 
2225
 
1914
2226
    if (fOffsettedTsc)
1915
2227
    {
1916
2228
        uint64_t u64CurTSC = ASMReadTSC();
1917
2229
        if (u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))
1918
2230
        {
1919
 
            /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
 
2231
            /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET, applies to RDTSCP too. */
1920
2232
            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, pVCpu->hwaccm.s.vmx.u64TSCOffset);
1921
2233
            AssertRC(rc);
1922
2234
 
1927
2239
        }
1928
2240
        else
1929
2241
        {
1930
 
            /* Fall back to rdtsc emulation as we would otherwise pass decreasing tsc values to the guest. */
1931
 
            LogFlow(("TSC %RX64 offset %RX64 time=%RX64 last=%RX64 (diff=%RX64, virt_tsc=%RX64)\n", u64CurTSC, pVCpu->hwaccm.s.vmx.u64TSCOffset, u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset, TMCpuTickGetLastSeen(pVCpu), TMCpuTickGetLastSeen(pVCpu) - u64CurTSC - pVCpu->hwaccm.s.vmx.u64TSCOffset, TMCpuTickGet(pVCpu)));
 
2242
            /* Fall back to rdtsc, rdtscp emulation as we would otherwise pass decreasing tsc values to the guest. */
 
2243
            LogFlow(("TSC %RX64 offset %RX64 time=%RX64 last=%RX64 (diff=%RX64, virt_tsc=%RX64)\n", u64CurTSC,
 
2244
                     pVCpu->hwaccm.s.vmx.u64TSCOffset, u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset,
 
2245
                     TMCpuTickGetLastSeen(pVCpu), TMCpuTickGetLastSeen(pVCpu) - u64CurTSC - pVCpu->hwaccm.s.vmx.u64TSCOffset,
 
2246
                     TMCpuTickGet(pVCpu)));
1932
2247
            pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
1933
2248
            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
1934
2249
            AssertRC(rc);
1946
2261
    /* Done with the major changes */
1947
2262
    pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_ALL_GUEST;
1948
2263
 
1949
 
    /* Minimal guest state update (esp, eip, eflags mostly) */
 
2264
    /* Minimal guest state update (ESP, EIP, EFLAGS mostly) */
1950
2265
    VMXR0LoadMinimalGuestState(pVM, pVCpu, pCtx);
1951
2266
    return rc;
1952
2267
}
1953
2268
 
 
2269
 
1954
2270
/**
1955
 
 * Syncs back the guest state
 
2271
 * Syncs back the guest state from VMCS.
1956
2272
 *
1957
2273
 * @returns VBox status code.
1958
 
 * @param   pVM         The VM to operate on.
1959
 
 * @param   pVCpu       The VMCPU to operate on.
1960
 
 * @param   pCtx        Guest context
 
2274
 * @param   pVM         Pointer to the VM.
 
2275
 * @param   pVCpu       Pointer to the VMCPU.
 
2276
 * @param   pCtx        Pointer to the guest CPU context.
1961
2277
 */
1962
2278
DECLINLINE(int) VMXR0SaveGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
1963
2279
{
1965
2281
    RTGCUINTPTR uInterruptState;
1966
2282
    int         rc;
1967
2283
 
1968
 
    /* Let's first sync back eip, esp, and eflags. */
1969
 
    rc = VMXReadCachedVMCS(VMX_VMCS64_GUEST_RIP,              &val);
 
2284
    /* First sync back EIP, ESP, and EFLAGS. */
 
2285
    rc = VMXReadCachedVMCS(VMX_VMCS64_GUEST_RIP,            &val);
1970
2286
    AssertRC(rc);
1971
2287
    pCtx->rip               = val;
1972
 
    rc = VMXReadCachedVMCS(VMX_VMCS64_GUEST_RSP,              &val);
 
2288
    rc = VMXReadCachedVMCS(VMX_VMCS64_GUEST_RSP,            &val);
1973
2289
    AssertRC(rc);
1974
2290
    pCtx->rsp               = val;
1975
2291
    rc = VMXReadCachedVMCS(VMX_VMCS_GUEST_RFLAGS,           &val);
1999
2315
    val = (valShadow & pVCpu->hwaccm.s.vmx.cr4_mask) | (val & ~pVCpu->hwaccm.s.vmx.cr4_mask);
2000
2316
    CPUMSetGuestCR4(pVCpu, val);
2001
2317
 
2002
 
    /* Note: no reason to sync back the CRx registers. They can't be changed by the guest. */
2003
 
    /* Note: only in the nested paging case can CR3 & CR4 be changed by the guest. */
2004
 
    if (    pVM->hwaccm.s.fNestedPaging
2005
 
        &&  CPUMIsGuestInPagedProtectedModeEx(pCtx))
 
2318
    /*
 
2319
     * No reason to sync back the CRx registers. They can't be changed by the guest unless in
 
2320
     * the nested paging case where CR3 & CR4 can be changed by the guest.
 
2321
     */
 
2322
    if (   pVM->hwaccm.s.fNestedPaging
 
2323
        && CPUMIsGuestInPagedProtectedModeEx(pCtx)) /** @todo check if we will always catch mode switches and such... */
2006
2324
    {
2007
2325
        PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
2008
2326
 
2020
2338
        AssertRCReturn(rc, rc);
2021
2339
    }
2022
2340
 
2023
 
    /* Sync back DR7 here. */
 
2341
    /* Sync back DR7. */
2024
2342
    VMXReadCachedVMCS(VMX_VMCS64_GUEST_DR7, &val);
2025
2343
    pCtx->dr[7] = val;
2026
2344
 
2032
2350
    VMX_READ_SELREG(FS, fs);
2033
2351
    VMX_READ_SELREG(GS, gs);
2034
2352
 
2035
 
    /*
2036
 
     * System MSRs
2037
 
     */
2038
 
    VMXReadCachedVMCS(VMX_VMCS32_GUEST_SYSENTER_CS,    &val);
 
2353
    /* System MSRs */
 
2354
    VMXReadCachedVMCS(VMX_VMCS32_GUEST_SYSENTER_CS,      &val);
2039
2355
    pCtx->SysEnter.cs       = val;
2040
2356
    VMXReadCachedVMCS(VMX_VMCS64_GUEST_SYSENTER_EIP,     &val);
2041
2357
    pCtx->SysEnter.eip      = val;
2045
2361
    /* Misc. registers; must sync everything otherwise we can get out of sync when jumping to ring 3. */
2046
2362
    VMX_READ_SELREG(LDTR, ldtr);
2047
2363
 
2048
 
    VMXReadCachedVMCS(VMX_VMCS32_GUEST_GDTR_LIMIT,     &val);
 
2364
    VMXReadCachedVMCS(VMX_VMCS32_GUEST_GDTR_LIMIT,       &val);
2049
2365
    pCtx->gdtr.cbGdt        = val;
2050
2366
    VMXReadCachedVMCS(VMX_VMCS64_GUEST_GDTR_BASE,        &val);
2051
2367
    pCtx->gdtr.pGdt         = val;
2052
2368
 
2053
 
    VMXReadCachedVMCS(VMX_VMCS32_GUEST_IDTR_LIMIT,     &val);
 
2369
    VMXReadCachedVMCS(VMX_VMCS32_GUEST_IDTR_LIMIT,       &val);
2054
2370
    pCtx->idtr.cbIdt        = val;
2055
2371
    VMXReadCachedVMCS(VMX_VMCS64_GUEST_IDTR_BASE,        &val);
2056
2372
    pCtx->idtr.pIdt         = val;
2075
2391
    }
2076
2392
 
2077
2393
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
2078
 
    /* Save the possibly changed MSRs that we automatically restore and save during a world switch. */
 
2394
    /*
 
2395
     * Save the possibly changed MSRs that we automatically restore and save during a world switch.
 
2396
     */
2079
2397
    for (unsigned i = 0; i < pVCpu->hwaccm.s.vmx.cCachedMSRs; i++)
2080
2398
    {
2081
2399
        PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pGuestMSR;
2083
2401
 
2084
2402
        switch (pMsr->u32IndexMSR)
2085
2403
        {
2086
 
        case MSR_K8_LSTAR:
2087
 
            pCtx->msrLSTAR = pMsr->u64Value;
2088
 
            break;
2089
 
        case MSR_K6_STAR:
2090
 
            pCtx->msrSTAR = pMsr->u64Value;
2091
 
            break;
2092
 
        case MSR_K8_SF_MASK:
2093
 
            pCtx->msrSFMASK = pMsr->u64Value;
2094
 
            break;
2095
 
        case MSR_K8_KERNEL_GS_BASE:
2096
 
            pCtx->msrKERNELGSBASE = pMsr->u64Value;
2097
 
            break;
2098
 
        case MSR_K6_EFER:
2099
 
            /* EFER can't be changed without causing a VM-exit. */
2100
 
//            Assert(pCtx->msrEFER == pMsr->u64Value);
2101
 
            break;
2102
 
        default:
2103
 
            AssertFailed();
2104
 
            return VERR_HM_UNEXPECTED_LD_ST_MSR;
 
2404
            case MSR_K8_LSTAR:
 
2405
                pCtx->msrLSTAR = pMsr->u64Value;
 
2406
                break;
 
2407
            case MSR_K6_STAR:
 
2408
                pCtx->msrSTAR = pMsr->u64Value;
 
2409
                break;
 
2410
            case MSR_K8_SF_MASK:
 
2411
                pCtx->msrSFMASK = pMsr->u64Value;
 
2412
                break;
 
2413
            /* The KERNEL_GS_BASE MSR doesn't work reliably with auto load/store. See @bugref{6208}  */
 
2414
#if 0
 
2415
            case MSR_K8_KERNEL_GS_BASE:
 
2416
                pCtx->msrKERNELGSBASE = pMsr->u64Value;
 
2417
                break;
 
2418
#endif
 
2419
            case MSR_K8_TSC_AUX:
 
2420
                CPUMSetGuestMsr(pVCpu, MSR_K8_TSC_AUX, pMsr->u64Value);
 
2421
                break;
 
2422
 
 
2423
            case MSR_K6_EFER:
 
2424
                /* EFER can't be changed without causing a VM-exit. */
 
2425
                /* Assert(pCtx->msrEFER == pMsr->u64Value); */
 
2426
                break;
 
2427
 
 
2428
            default:
 
2429
                AssertFailed();
 
2430
                return VERR_HM_UNEXPECTED_LD_ST_MSR;
2105
2431
        }
2106
2432
    }
2107
2433
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
2108
2434
    return VINF_SUCCESS;
2109
2435
}
2110
2436
 
 
2437
 
2111
2438
/**
2112
 
 * Dummy placeholder
 
2439
 * Dummy placeholder for TLB flush handling before VM-entry. Used in the case
 
2440
 * where neither EPT nor VPID is supported by the CPU.
2113
2441
 *
2114
 
 * @param   pVM         The VM to operate on.
2115
 
 * @param   pVCpu       The VMCPU to operate on.
 
2442
 * @param   pVM         Pointer to the VM.
 
2443
 * @param   pVCpu       Pointer to the VMCPU.
2116
2444
 */
2117
 
static DECLCALLBACK(void) vmxR0SetupTLBDummy(PVM pVM, PVMCPU pVCpu)
 
2445
static DECLCALLBACK(void) hmR0VmxSetupTLBDummy(PVM pVM, PVMCPU pVCpu)
2118
2446
{
2119
2447
    NOREF(pVM);
2120
2448
    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_FLUSH);
2123
2451
    return;
2124
2452
}
2125
2453
 
2126
 
/**
2127
 
 * Setup the tagged TLB for EPT
 
2454
 
 
2455
/**
 
2456
 * Setup the tagged TLB for EPT+VPID.
 
2457
 *
 
2458
 * @param    pVM        Pointer to the VM.
 
2459
 * @param    pVCpu      Pointer to the VMCPU.
 
2460
 */
 
2461
static DECLCALLBACK(void) hmR0VmxSetupTLBBoth(PVM pVM, PVMCPU pVCpu)
 
2462
{
 
2463
    PHMGLOBLCPUINFO pCpu;
 
2464
 
 
2465
    Assert(pVM->hwaccm.s.fNestedPaging && pVM->hwaccm.s.vmx.fVPID);
 
2466
 
 
2467
    pCpu = HWACCMR0GetCurrentCpu();
 
2468
 
 
2469
    /*
 
2470
     * Force a TLB flush for the first world switch if the current CPU differs from the one we ran on last
 
2471
     * This can happen both for start & resume due to long jumps back to ring-3.
 
2472
     * If the TLB flush count changed, another VM (VCPU rather) has hit the ASID limit while flushing the TLB
 
2473
     * or the host Cpu is online after a suspend/resume, so we cannot reuse the current ASID anymore.
 
2474
     */
 
2475
    bool fNewASID = false;
 
2476
    if (   pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
 
2477
        || pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
 
2478
    {
 
2479
        pVCpu->hwaccm.s.fForceTLBFlush = true;
 
2480
        fNewASID = true;
 
2481
    }
 
2482
 
 
2483
    /*
 
2484
     * Check for explicit TLB shootdowns.
 
2485
     */
 
2486
    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
 
2487
        pVCpu->hwaccm.s.fForceTLBFlush = true;
 
2488
 
 
2489
    pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
 
2490
 
 
2491
    if (pVCpu->hwaccm.s.fForceTLBFlush)
 
2492
    {
 
2493
        if (fNewASID)
 
2494
        {
 
2495
            ++pCpu->uCurrentASID;
 
2496
            if (pCpu->uCurrentASID >= pVM->hwaccm.s.uMaxASID)
 
2497
            {
 
2498
                pCpu->uCurrentASID = 1;       /* start at 1; host uses 0 */
 
2499
                pCpu->cTLBFlushes++;
 
2500
                pCpu->fFlushASIDBeforeUse = true;
 
2501
            }
 
2502
 
 
2503
            pVCpu->hwaccm.s.uCurrentASID = pCpu->uCurrentASID;
 
2504
            if (pCpu->fFlushASIDBeforeUse)
 
2505
            {
 
2506
                hmR0VmxFlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
 
2507
#ifdef VBOX_WITH_STATISTICS
 
2508
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
 
2509
#endif
 
2510
            }
 
2511
        }
 
2512
        else
 
2513
        {
 
2514
            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_SINGLE_CONTEXT)
 
2515
                hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_SINGLE_CONTEXT, 0 /* GCPtr */);
 
2516
            else
 
2517
                hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
 
2518
 
 
2519
#ifdef VBOX_WITH_STATISTICS
 
2520
            /*
 
2521
             * This is not terribly accurate (i.e. we don't have any StatFlushEPT counter). We currently count these
 
2522
             * as ASID flushes too, better than including them under StatFlushTLBWorldSwitch.
 
2523
             */
 
2524
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
 
2525
#endif
 
2526
        }
 
2527
 
 
2528
        pVCpu->hwaccm.s.cTLBFlushes    = pCpu->cTLBFlushes;
 
2529
        pVCpu->hwaccm.s.fForceTLBFlush = false;
 
2530
    }
 
2531
    else
 
2532
    {
 
2533
        AssertMsg(pVCpu->hwaccm.s.uCurrentASID && pCpu->uCurrentASID,
 
2534
                  ("hwaccm->uCurrentASID=%lu hwaccm->cTLBFlushes=%lu cpu->uCurrentASID=%lu cpu->cTLBFlushes=%lu\n",
 
2535
                   pVCpu->hwaccm.s.uCurrentASID, pVCpu->hwaccm.s.cTLBFlushes,
 
2536
                   pCpu->uCurrentASID, pCpu->cTLBFlushes));
 
2537
 
 
2538
        /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
 
2539
         *        not be executed. See hwaccmQueueInvlPage() where it is commented
 
2540
         *        out. Support individual entry flushing someday. */
 
2541
        if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
 
2542
        {
 
2543
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
 
2544
 
 
2545
            /*
 
2546
             * Flush individual guest entries using VPID from the TLB or as little as possible with EPT
 
2547
             * as supported by the CPU.
 
2548
             */
 
2549
            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
 
2550
            {
 
2551
                for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
 
2552
                    hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
 
2553
            }
 
2554
            else
 
2555
                hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
 
2556
        }
 
2557
        else
 
2558
        {
 
2559
#ifdef VBOX_WITH_STATISTICS
 
2560
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
 
2561
#endif
 
2562
        }
 
2563
    }
 
2564
    pVCpu->hwaccm.s.TlbShootdown.cPages = 0;
 
2565
    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
 
2566
 
 
2567
    AssertMsg(pVCpu->hwaccm.s.cTLBFlushes == pCpu->cTLBFlushes,
 
2568
              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
 
2569
    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.uMaxASID,
 
2570
              ("cpu%d uCurrentASID = %x\n", pCpu->idCpu, pCpu->uCurrentASID));
 
2571
    AssertMsg(pVCpu->hwaccm.s.uCurrentASID >= 1 && pVCpu->hwaccm.s.uCurrentASID < pVM->hwaccm.s.uMaxASID,
 
2572
              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hwaccm.s.uCurrentASID));
 
2573
 
 
2574
    /* Update VMCS with the VPID. */
 
2575
    int rc  = VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_VPID, pVCpu->hwaccm.s.uCurrentASID);
 
2576
    AssertRC(rc);
 
2577
}
 
2578
 
 
2579
 
 
2580
/**
 
2581
 * Setup the tagged TLB for EPT only.
2128
2582
 *
2129
2583
 * @returns VBox status code.
2130
 
 * @param   pVM         The VM to operate on.
2131
 
 * @param   pVCpu       The VMCPU to operate on.
 
2584
 * @param   pVM         Pointer to the VM.
 
2585
 * @param   pVCpu       Pointer to the VMCPU.
2132
2586
 */
2133
 
static DECLCALLBACK(void) vmxR0SetupTLBEPT(PVM pVM, PVMCPU pVCpu)
 
2587
static DECLCALLBACK(void) hmR0VmxSetupTLBEPT(PVM pVM, PVMCPU pVCpu)
2134
2588
{
2135
2589
    PHMGLOBLCPUINFO pCpu;
2136
2590
 
2137
2591
    Assert(pVM->hwaccm.s.fNestedPaging);
2138
2592
    Assert(!pVM->hwaccm.s.vmx.fVPID);
2139
2593
 
2140
 
    /* Deal with tagged TLBs if VPID or EPT is supported. */
2141
2594
    pCpu = HWACCMR0GetCurrentCpu();
2142
 
    /* Force a TLB flush for the first world switch if the current cpu differs from the one we ran on last. */
2143
 
    /* Note that this can happen both for start and resume due to long jumps back to ring 3. */
2144
 
    if (    pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
2145
 
            /* if the tlb flush count has changed, another VM has flushed the TLB of this cpu, so we can't use our current ASID anymore. */
2146
 
        ||  pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
 
2595
 
 
2596
    /*
 
2597
     * Force a TLB flush for the first world switch if the current CPU differs from the one we ran on last
 
2598
     * This can happen both for start & resume due to long jumps back to ring-3.
 
2599
     * A change in the TLB flush count implies the host Cpu is online after a suspend/resume.
 
2600
     */
 
2601
    if (   pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
 
2602
        || pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
2147
2603
    {
2148
 
        /* Force a TLB flush on VM entry. */
2149
2604
        pVCpu->hwaccm.s.fForceTLBFlush = true;
2150
2605
    }
2151
 
    /* Disabled because this has triggered every time I have suspended my
2152
 
     * laptop with a VM running for the past three months or more.  */
2153
 
    // else
2154
 
    //     Assert(!pCpu->fFlushTLB);
2155
2606
 
2156
 
    /* Check for tlb shootdown flushes. */
 
2607
    /*
 
2608
     * Check for explicit TLB shootdown flushes.
 
2609
     */
2157
2610
    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
2158
2611
        pVCpu->hwaccm.s.fForceTLBFlush = true;
2159
2612
 
2160
 
    pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
2161
 
    pCpu->fFlushTLB           = false;
 
2613
    pVCpu->hwaccm.s.idLastCpu   = pCpu->idCpu;
 
2614
    pVCpu->hwaccm.s.cTLBFlushes = pCpu->cTLBFlushes;
2162
2615
 
2163
2616
    if (pVCpu->hwaccm.s.fForceTLBFlush)
2164
 
    {
2165
 
        vmxR0FlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushContext, 0);
2166
 
    }
 
2617
        hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
2167
2618
    else
2168
 
    if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
2169
2619
    {
2170
 
        /* Deal with pending TLB shootdown actions which were queued when we were not executing code. */
2171
 
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
2172
 
 
2173
 
        for (unsigned i=0;i<pVCpu->hwaccm.s.TlbShootdown.cPages;i++)
 
2620
        /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
 
2621
         *        not be executed. See hwaccmQueueInvlPage() where it is commented
 
2622
         *        out. Support individual entry flushing someday. */
 
2623
        if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
2174
2624
        {
2175
 
            /* aTlbShootdownPages contains physical addresses in this case. */
2176
 
            vmxR0FlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushPage, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
 
2625
            /*
 
2626
             * We cannot flush individual entries without VPID support. Flush using EPT.
 
2627
             */
 
2628
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
 
2629
            hmR0VmxFlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushEPT);
2177
2630
        }
2178
2631
    }
2179
2632
    pVCpu->hwaccm.s.TlbShootdown.cPages= 0;
2187
2640
#endif
2188
2641
}
2189
2642
 
2190
 
#ifdef HWACCM_VTX_WITH_VPID
 
2643
 
2191
2644
/**
2192
 
 * Setup the tagged TLB for VPID
 
2645
 * Setup the tagged TLB for VPID.
2193
2646
 *
2194
2647
 * @returns VBox status code.
2195
 
 * @param   pVM         The VM to operate on.
2196
 
 * @param   pVCpu       The VMCPU to operate on.
 
2648
 * @param   pVM         Pointer to the VM.
 
2649
 * @param   pVCpu       Pointer to the VMCPU.
2197
2650
 */
2198
 
static DECLCALLBACK(void) vmxR0SetupTLBVPID(PVM pVM, PVMCPU pVCpu)
 
2651
static DECLCALLBACK(void) hmR0VmxSetupTLBVPID(PVM pVM, PVMCPU pVCpu)
2199
2652
{
2200
2653
    PHMGLOBLCPUINFO pCpu;
2201
2654
 
2202
2655
    Assert(pVM->hwaccm.s.vmx.fVPID);
2203
2656
    Assert(!pVM->hwaccm.s.fNestedPaging);
2204
2657
 
2205
 
    /* Deal with tagged TLBs if VPID or EPT is supported. */
2206
2658
    pCpu = HWACCMR0GetCurrentCpu();
2207
 
    /* Force a TLB flush for the first world switch if the current cpu differs from the one we ran on last. */
2208
 
    /* Note that this can happen both for start and resume due to long jumps back to ring 3. */
2209
 
    if (    pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
2210
 
            /* if the tlb flush count has changed, another VM has flushed the TLB of this cpu, so we can't use our current ASID anymore. */
2211
 
        ||  pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
 
2659
 
 
2660
    /*
 
2661
     * Force a TLB flush for the first world switch if the current CPU differs from the one we ran on last
 
2662
     * This can happen both for start & resume due to long jumps back to ring-3.
 
2663
     * If the TLB flush count changed, another VM (VCPU rather) has hit the ASID limit while flushing the TLB
 
2664
     * or the host Cpu is online after a suspend/resume, so we cannot reuse the current ASID anymore.
 
2665
     */
 
2666
    if (   pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu
 
2667
        || pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
2212
2668
    {
2213
2669
        /* Force a TLB flush on VM entry. */
2214
2670
        pVCpu->hwaccm.s.fForceTLBFlush = true;
2215
2671
    }
2216
 
    else
2217
 
        Assert(!pCpu->fFlushTLB);
 
2672
 
 
2673
    /*
 
2674
     * Check for explicit TLB shootdown flushes.
 
2675
     */
 
2676
    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
 
2677
        pVCpu->hwaccm.s.fForceTLBFlush = true;
2218
2678
 
2219
2679
    pVCpu->hwaccm.s.idLastCpu = pCpu->idCpu;
2220
2680
 
2221
 
    /* Check for tlb shootdown flushes. */
2222
 
    if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_TLB_FLUSH))
2223
 
        pVCpu->hwaccm.s.fForceTLBFlush = true;
2224
 
 
2225
 
    /* Make sure we flush the TLB when required. Switch ASID to achieve the same thing, but without actually flushing the whole TLB (which is expensive). */
2226
2681
    if (pVCpu->hwaccm.s.fForceTLBFlush)
2227
2682
    {
2228
 
        if (    ++pCpu->uCurrentASID >= pVM->hwaccm.s.uMaxASID
2229
 
            ||  pCpu->fFlushTLB)
 
2683
        ++pCpu->uCurrentASID;
 
2684
        if (pCpu->uCurrentASID >= pVM->hwaccm.s.uMaxASID)
2230
2685
        {
2231
 
            pCpu->fFlushTLB                  = false;
2232
2686
            pCpu->uCurrentASID               = 1;       /* start at 1; host uses 0 */
2233
2687
            pCpu->cTLBFlushes++;
2234
 
            vmxR0FlushVPID(pVM, pVCpu, VMX_FLUSH_ALL_CONTEXTS, 0);
 
2688
            pCpu->fFlushASIDBeforeUse        = true;
2235
2689
        }
2236
2690
        else
2237
2691
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushASID);
2239
2693
        pVCpu->hwaccm.s.fForceTLBFlush = false;
2240
2694
        pVCpu->hwaccm.s.cTLBFlushes    = pCpu->cTLBFlushes;
2241
2695
        pVCpu->hwaccm.s.uCurrentASID   = pCpu->uCurrentASID;
 
2696
        if (pCpu->fFlushASIDBeforeUse)
 
2697
            hmR0VmxFlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
2242
2698
    }
2243
2699
    else
2244
2700
    {
2245
 
        Assert(!pCpu->fFlushTLB);
2246
 
        Assert(pVCpu->hwaccm.s.uCurrentASID && pCpu->uCurrentASID);
 
2701
        AssertMsg(pVCpu->hwaccm.s.uCurrentASID && pCpu->uCurrentASID,
 
2702
                  ("hwaccm->uCurrentASID=%lu hwaccm->cTLBFlushes=%lu cpu->uCurrentASID=%lu cpu->cTLBFlushes=%lu\n",
 
2703
                   pVCpu->hwaccm.s.uCurrentASID, pVCpu->hwaccm.s.cTLBFlushes,
 
2704
                   pCpu->uCurrentASID, pCpu->cTLBFlushes));
2247
2705
 
 
2706
        /** @todo We never set VMCPU_FF_TLB_SHOOTDOWN anywhere so this path should
 
2707
         *        not be executed. See hwaccmQueueInvlPage() where it is commented
 
2708
         *        out. Support individual entry flushing someday. */
2248
2709
        if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_TLB_SHOOTDOWN))
2249
2710
        {
2250
 
            /* Deal with pending TLB shootdown actions which were queued when we were not executing code. */
2251
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTlbShootdown);
2252
 
            for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
2253
 
                vmxR0FlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushPage, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
 
2711
            /*
 
2712
             * Flush individual guest entries using VPID from the TLB or as little as possible with EPT
 
2713
             * as supported by the CPU.
 
2714
             */
 
2715
            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
 
2716
            {
 
2717
                for (unsigned i = 0; i < pVCpu->hwaccm.s.TlbShootdown.cPages; i++)
 
2718
                    hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, pVCpu->hwaccm.s.TlbShootdown.aPages[i]);
 
2719
            }
 
2720
            else
 
2721
                hmR0VmxFlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushVPID, 0 /* GCPtr */);
2254
2722
        }
2255
2723
    }
2256
2724
    pVCpu->hwaccm.s.TlbShootdown.cPages = 0;
2257
2725
    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TLB_SHOOTDOWN);
2258
2726
 
2259
 
    AssertMsg(pVCpu->hwaccm.s.cTLBFlushes == pCpu->cTLBFlushes, ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
2260
 
    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.uMaxASID, ("cpu%d uCurrentASID = %x\n", pCpu->idCpu, pCpu->uCurrentASID));
2261
 
    AssertMsg(pVCpu->hwaccm.s.uCurrentASID >= 1 && pVCpu->hwaccm.s.uCurrentASID < pVM->hwaccm.s.uMaxASID, ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hwaccm.s.uCurrentASID));
 
2727
    AssertMsg(pVCpu->hwaccm.s.cTLBFlushes == pCpu->cTLBFlushes,
 
2728
              ("Flush count mismatch for cpu %d (%x vs %x)\n", pCpu->idCpu, pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
 
2729
    AssertMsg(pCpu->uCurrentASID >= 1 && pCpu->uCurrentASID < pVM->hwaccm.s.uMaxASID,
 
2730
              ("cpu%d uCurrentASID = %x\n", pCpu->idCpu, pCpu->uCurrentASID));
 
2731
    AssertMsg(pVCpu->hwaccm.s.uCurrentASID >= 1 && pVCpu->hwaccm.s.uCurrentASID < pVM->hwaccm.s.uMaxASID,
 
2732
              ("cpu%d VM uCurrentASID = %x\n", pCpu->idCpu, pVCpu->hwaccm.s.uCurrentASID));
2262
2733
 
2263
2734
    int rc  = VMXWriteVMCS(VMX_VMCS16_GUEST_FIELD_VPID, pVCpu->hwaccm.s.uCurrentASID);
2264
2735
    AssertRC(rc);
2265
2736
 
2266
 
    if (pVCpu->hwaccm.s.fForceTLBFlush)
2267
 
        vmxR0FlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushContext, 0);
2268
 
 
2269
2737
# ifdef VBOX_WITH_STATISTICS
2270
2738
    if (pVCpu->hwaccm.s.fForceTLBFlush)
2271
2739
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatFlushTLBWorldSwitch);
2273
2741
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatNoFlushTLBWorldSwitch);
2274
2742
# endif
2275
2743
}
2276
 
#endif /* HWACCM_VTX_WITH_VPID */
 
2744
 
2277
2745
 
2278
2746
/**
2279
2747
 * Runs guest code in a VT-x VM.
2280
2748
 *
2281
2749
 * @returns VBox status code.
2282
 
 * @param   pVM         The VM to operate on.
2283
 
 * @param   pVCpu       The VMCPU to operate on.
2284
 
 * @param   pCtx        Guest context
 
2750
 * @param   pVM         Pointer to the VM.
 
2751
 * @param   pVCpu       Pointer to the VMCPU.
 
2752
 * @param   pCtx        Pointer to the guest CPU context.
2285
2753
 */
2286
2754
VMMR0DECL(int) VMXR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
2287
2755
{
2310
2778
    uint64_t    u64LastTime = RTTimeMilliTS();
2311
2779
#endif
2312
2780
 
2313
 
    Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) || (pVCpu->hwaccm.s.vmx.pbVAPIC && pVM->hwaccm.s.vmx.pAPIC));
 
2781
    Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
 
2782
           || (pVCpu->hwaccm.s.vmx.pbVAPIC && pVM->hwaccm.s.vmx.pAPIC));
2314
2783
 
2315
 
    /* Check if we need to use TPR shadowing. */
 
2784
    /*
 
2785
     * Check if we need to use TPR shadowing.
 
2786
     */
2316
2787
    if (    CPUMIsGuestInLongModeEx(pCtx)
2317
 
        || (   ((pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) || pVM->hwaccm.s.fTRPPatchingAllowed)
 
2788
        || (   ((   pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC)
 
2789
                 || pVM->hwaccm.s.fTRPPatchingAllowed)
2318
2790
            &&  pVM->hwaccm.s.fHasIoApic)
2319
2791
       )
2320
2792
    {
2323
2795
 
2324
2796
    Log2(("\nE"));
2325
2797
 
 
2798
    /* This is not ideal, but if we don't clear the event injection in the VMCS right here,
 
2799
     * we may end up injecting some stale event into a VM, including injecting an event that 
 
2800
     * originated before a VM reset *after* the VM has been reset. See @bugref{6220}.
 
2801
     */
 
2802
    VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_IRQ_INFO, 0);
 
2803
 
2326
2804
#ifdef VBOX_STRICT
2327
2805
    {
2328
2806
        RTCCUINTREG val2;
2329
2807
 
2330
2808
        rc2 = VMXReadVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, &val2);
2331
2809
        AssertRC(rc2);
2332
 
        Log2(("VMX_VMCS_CTRL_PIN_EXEC_CONTROLS = %08x\n", val2));
 
2810
        Log2(("VMX_VMCS_CTRL_PIN_EXEC_CONTROLS = %08x\n",  val2));
2333
2811
 
2334
2812
        /* allowed zero */
2335
2813
        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_pin_ctls.n.disallowed0)
2341
2819
 
2342
2820
        rc2 = VMXReadVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, &val2);
2343
2821
        AssertRC(rc2);
2344
 
        Log2(("VMX_VMCS_CTRL_PROC_EXEC_CONTROLS = %08x\n", val2));
 
2822
        Log2(("VMX_VMCS_CTRL_PROC_EXEC_CONTROLS = %08x\n",  val2));
2345
2823
 
2346
 
        /* Must be set according to the MSR, but can be cleared in case of EPT. */
 
2824
        /*
 
2825
         * Must be set according to the MSR, but can be cleared if nested paging is used.
 
2826
         */
2347
2827
        if (pVM->hwaccm.s.fNestedPaging)
 
2828
        {
2348
2829
            val2 |=   VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT
2349
2830
                    | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT
2350
2831
                    | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT;
 
2832
        }
2351
2833
 
2352
2834
        /* allowed zero */
2353
2835
        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.disallowed0)
2359
2841
 
2360
2842
        rc2 = VMXReadVMCS(VMX_VMCS_CTRL_ENTRY_CONTROLS, &val2);
2361
2843
        AssertRC(rc2);
2362
 
        Log2(("VMX_VMCS_CTRL_ENTRY_CONTROLS = %08x\n", val2));
 
2844
        Log2(("VMX_VMCS_CTRL_ENTRY_CONTROLS = %08x\n",  val2));
2363
2845
 
2364
2846
        /* allowed zero */
2365
2847
        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0)
2371
2853
 
2372
2854
        rc2 = VMXReadVMCS(VMX_VMCS_CTRL_EXIT_CONTROLS, &val2);
2373
2855
        AssertRC(rc2);
2374
 
        Log2(("VMX_VMCS_CTRL_EXIT_CONTROLS = %08x\n", val2));
 
2856
        Log2(("VMX_VMCS_CTRL_EXIT_CONTROLS = %08x\n",  val2));
2375
2857
 
2376
2858
        /* allowed zero */
2377
2859
        if ((val2 & pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0) != pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0)
2388
2870
    pVCpu->hwaccm.s.vmx.VMCSCache.u64TimeEntry = RTTimeNanoTS();
2389
2871
#endif
2390
2872
 
2391
 
    /* We can jump to this point to resume execution after determining that a VM-exit is innocent.
 
2873
    /*
 
2874
     * We can jump to this point to resume execution after determining that a VM-exit is innocent.
2392
2875
     */
2393
2876
ResumeExecution:
2394
2877
    if (!STAM_REL_PROFILE_ADV_IS_RUNNING(&pVCpu->hwaccm.s.StatEntry))
2400
2883
    /* Not allowed to switch modes without reloading the host state (32->64 switcher)!! */
2401
2884
    Assert(fWasInLongMode == CPUMIsGuestInLongModeEx(pCtx));
2402
2885
 
2403
 
    /* Safety precaution; looping for too long here can have a very bad effect on the host */
 
2886
    /*
 
2887
     * Safety precaution; looping for too long here can have a very bad effect on the host.
 
2888
     */
2404
2889
    if (RT_UNLIKELY(++cResume > pVM->hwaccm.s.cMaxResumeLoops))
2405
2890
    {
2406
2891
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMaxResume);
2408
2893
        goto end;
2409
2894
    }
2410
2895
 
2411
 
    /* Check for irq inhibition due to instruction fusing (sti, mov ss). */
 
2896
    /*
 
2897
     * Check for IRQ inhibition due to instruction fusing (sti, mov ss).
 
2898
     */
2412
2899
    if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))
2413
2900
    {
2414
2901
        Log(("VM_FF_INHIBIT_INTERRUPTS at %RGv successor %RGv\n", (RTGCPTR)pCtx->rip, EMGetInhibitInterruptsPC(pVCpu)));
2415
2902
        if (pCtx->rip != EMGetInhibitInterruptsPC(pVCpu))
2416
2903
        {
2417
 
            /* Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here.
 
2904
            /*
 
2905
             * Note: we intentionally don't clear VM_FF_INHIBIT_INTERRUPTS here.
2418
2906
             * Before we are able to execute this instruction in raw mode (iret to guest code) an external interrupt might
2419
2907
             * force a world switch again. Possibly allowing a guest interrupt to be dispatched in the process. This could
2420
2908
             * break the guest. Sounds very unlikely, but such timing sensitive problems are not as rare as you might think.
2445
2933
    }
2446
2934
#endif
2447
2935
 
2448
 
    /* Check for pending actions that force us to go back to ring 3. */
 
2936
    /*
 
2937
     * Check for pending actions that force us to go back to ring-3.
 
2938
     */
2449
2939
    if (    VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
2450
2940
        ||  VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL | VMCPU_FF_REQUEST))
2451
2941
    {
2504
2994
     *
2505
2995
     * Interrupts are disabled before the call to make sure we don't miss any interrupt
2506
2996
     * that would flag preemption (IPI, timer tick, ++). (Would've been nice to do this
2507
 
     * further down, but VMXR0CheckPendingInterrupt makes that impossible.)
 
2997
     * further down, but hmR0VmxCheckPendingInterrupt makes that impossible.)
2508
2998
     *
2509
2999
     * Note! Interrupts must be disabled done *before* we check for TLB flushes; TLB
2510
3000
     *       shootdowns rely on this.
2519
3009
    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC);
2520
3010
#endif
2521
3011
 
2522
 
    /* When external interrupts are pending, we should exit the VM when IF is set. */
2523
 
    /* Note! *After* VM_FF_INHIBIT_INTERRUPTS check!!! */
2524
 
    rc = VMXR0CheckPendingInterrupt(pVM, pVCpu, pCtx);
 
3012
    /*
 
3013
     * When external interrupts are pending, we should exit the VM when IF is et.
 
3014
     * Note: *After* VM_FF_INHIBIT_INTERRUPTS check!
 
3015
     */
 
3016
    rc = hmR0VmxCheckPendingInterrupt(pVM, pVCpu, pCtx);
2525
3017
    if (RT_FAILURE(rc))
2526
3018
        goto end;
2527
3019
 
2528
3020
    /** @todo check timers?? */
2529
3021
 
2530
 
    /* TPR caching using CR8 is only available in 64 bits mode */
2531
 
    /* Note the 32 bits exception for AMD (X86_CPUID_AMD_FEATURE_ECX_CR8L), but that appears missing in Intel CPUs */
2532
 
    /* Note: we can't do this in LoadGuestState as PDMApicGetTPR can jump back to ring 3 (lock)!!!!! (no longer true) */
2533
 
    /**
2534
 
     * @todo query and update the TPR only when it could have been changed (mmio access & wrmsr (x2apic))
 
3022
    /*
 
3023
     * TPR caching using CR8 is only available in 64-bit mode.
 
3024
     * Note: The 32-bit exception for AMD (X86_CPUID_AMD_FEATURE_ECX_CR8L), but this appears missing in Intel CPUs.
 
3025
     * Note: We can't do this in LoadGuestState() as PDMApicGetTPR can jump back to ring-3 (lock)!! (no longer true)                                                                                                           .
2535
3026
     */
 
3027
    /** @todo query and update the TPR only when it could have been changed (mmio
 
3028
     *        access & wrsmr (x2apic) */
2536
3029
    if (fSetupTPRCaching)
2537
3030
    {
2538
3031
        /* TPR caching in CR8 */
2543
3036
        /* The TPR can be found at offset 0x80 in the APIC mmio page. */
2544
3037
        pVCpu->hwaccm.s.vmx.pbVAPIC[0x80] = u8LastTPR;
2545
3038
 
2546
 
        /* Two options here:
 
3039
        /*
 
3040
         * Two options here:
2547
3041
         * - external interrupt pending, but masked by the TPR value.
2548
3042
         *   -> a CR8 update that lower the current TPR value should cause an exit
2549
3043
         * - no pending interrupts
2550
3044
         *   -> We don't need to be explicitely notified. There are enough world switches for detecting pending interrupts.
2551
3045
         */
2552
 
        rc  = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, (fPending) ? (u8LastTPR >> 4) : 0);     /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
 
3046
 
 
3047
        /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
 
3048
        rc  = VMXWriteVMCS(VMX_VMCS_CTRL_TPR_THRESHOLD, (fPending) ? (u8LastTPR >> 4) : 0);
2553
3049
        AssertRC(VBOXSTRICTRC_VAL(rc));
2554
3050
 
2555
3051
        if (pVM->hwaccm.s.fTPRPatchingActive)
2558
3054
            /* Our patch code uses LSTAR for TPR caching. */
2559
3055
            pCtx->msrLSTAR = u8LastTPR;
2560
3056
 
 
3057
            /** @todo r=ramshankar: we should check for MSR-bitmap support here. */
2561
3058
            if (fPending)
2562
3059
            {
2563
3060
                /* A TPR change could activate a pending interrupt, so catch lstar writes. */
2564
 
                vmxR0SetMSRPermission(pVCpu, MSR_K8_LSTAR, true, false);
 
3061
                hmR0VmxSetMSRPermission(pVCpu, MSR_K8_LSTAR, true, false);
2565
3062
            }
2566
3063
            else
2567
3064
            {
2568
 
                /* No interrupts are pending, so we don't need to be explicitely notified.
 
3065
                /*
 
3066
                 * No interrupts are pending, so we don't need to be explicitely notified.
2569
3067
                 * There are enough world switches for detecting pending interrupts.
2570
3068
                 */
2571
 
                vmxR0SetMSRPermission(pVCpu, MSR_K8_LSTAR, true, true);
 
3069
                hmR0VmxSetMSRPermission(pVCpu, MSR_K8_LSTAR, true, true);
2572
3070
            }
2573
3071
        }
2574
3072
    }
2575
3073
 
2576
 
#if defined(HWACCM_VTX_WITH_EPT) && defined(LOG_ENABLED)
 
3074
#ifdef LOG_ENABLED
2577
3075
    if (    pVM->hwaccm.s.fNestedPaging
2578
 
# ifdef HWACCM_VTX_WITH_VPID
2579
 
        ||  pVM->hwaccm.s.vmx.fVPID
2580
 
# endif /* HWACCM_VTX_WITH_VPID */
2581
 
        )
 
3076
        ||  pVM->hwaccm.s.vmx.fVPID)
2582
3077
    {
2583
 
        PHMGLOBLCPUINFO pCpu;
2584
 
 
2585
 
        pCpu = HWACCMR0GetCurrentCpu();
2586
 
        if (    pVCpu->hwaccm.s.idLastCpu   != pCpu->idCpu
2587
 
            ||  pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
2588
 
        {
2589
 
            if (pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu)
2590
 
                LogFlow(("Force TLB flush due to rescheduling to a different cpu (%d vs %d)\n", pVCpu->hwaccm.s.idLastCpu, pCpu->idCpu));
2591
 
            else
2592
 
                LogFlow(("Force TLB flush due to changed TLB flush count (%x vs %x)\n", pVCpu->hwaccm.s.cTLBFlushes, pCpu->cTLBFlushes));
2593
 
        }
2594
 
        if (pCpu->fFlushTLB)
2595
 
            LogFlow(("Force TLB flush: first time cpu %d is used -> flush\n", pCpu->idCpu));
2596
 
        else
2597
 
        if (pVCpu->hwaccm.s.fForceTLBFlush)
 
3078
        PHMGLOBLCPUINFO pCpu = HWACCMR0GetCurrentCpu();
 
3079
        if (pVCpu->hwaccm.s.idLastCpu != pCpu->idCpu)
 
3080
        {
 
3081
            LogFlow(("Force TLB flush due to rescheduling to a different cpu (%d vs %d)\n", pVCpu->hwaccm.s.idLastCpu,
 
3082
                     pCpu->idCpu));
 
3083
        }
 
3084
        else if (pVCpu->hwaccm.s.cTLBFlushes != pCpu->cTLBFlushes)
 
3085
        {
 
3086
            LogFlow(("Force TLB flush due to changed TLB flush count (%x vs %x)\n", pVCpu->hwaccm.s.cTLBFlushes,
 
3087
                     pCpu->cTLBFlushes));
 
3088
        }
 
3089
        else if (VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH))
2598
3090
            LogFlow(("Manual TLB flush\n"));
2599
3091
    }
2600
3092
#endif
2603
3095
#endif
2604
3096
 
2605
3097
    /*
2606
 
     * NOTE: DO NOT DO ANYTHING AFTER THIS POINT THAT MIGHT JUMP BACK TO RING 3!
 
3098
     * NOTE: DO NOT DO ANYTHING AFTER THIS POINT THAT MIGHT JUMP BACK TO RING-3!
2607
3099
     *       (until the actual world switch)
2608
3100
     */
2609
3101
#ifdef VBOX_STRICT
2612
3104
#ifdef LOG_ENABLED
2613
3105
    VMMR0LogFlushDisable(pVCpu);
2614
3106
#endif
2615
 
    /* Save the host state first. */
 
3107
 
 
3108
    /*
 
3109
     * Save the host state first.
 
3110
     */
2616
3111
    if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_HOST_CONTEXT)
2617
3112
    {
2618
3113
        rc  = VMXR0SaveHostState(pVM, pVCpu);
2623
3118
        }
2624
3119
    }
2625
3120
 
2626
 
    /* Load the guest state */
 
3121
    /*
 
3122
     * Load the guest state.
 
3123
     */
2627
3124
    if (!pVCpu->hwaccm.s.fContextUseFlags)
2628
3125
    {
2629
3126
        VMXR0LoadMinimalGuestState(pVM, pVCpu, pCtx);
2641
3138
    }
2642
3139
 
2643
3140
#ifndef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
2644
 
    /* Disable interrupts to make sure a poke will interrupt execution.
 
3141
    /*
 
3142
     * Disable interrupts to make sure a poke will interrupt execution.
2645
3143
     * This must be done *before* we check for TLB flushes; TLB shootdowns rely on this.
2646
3144
     */
2647
3145
    uOldEFlags = ASMIntDisableFlags();
2658
3156
    /* Deal with tagged TLB setup and invalidation. */
2659
3157
    pVM->hwaccm.s.vmx.pfnSetupTaggedTLB(pVM, pVCpu);
2660
3158
 
2661
 
    /* Manual save and restore:
 
3159
    /*
 
3160
     * Manual save and restore:
2662
3161
     * - General purpose registers except RIP, RSP
2663
3162
     *
2664
3163
     * Trashed:
2667
3166
     * - DRx (presumably not changed at all)
2668
3167
     * - DR7 (reset to 0x400)
2669
3168
     * - EFLAGS (reset to RT_BIT(1); not relevant)
2670
 
     *
2671
3169
     */
2672
3170
 
2673
3171
    /* All done! Let's start VM execution. */
2679
3177
    pVCpu->hwaccm.s.vmx.VMCSCache.u64TimeSwitch = RTTimeNanoTS();
2680
3178
#endif
2681
3179
 
2682
 
    /* Save the current TPR value in the LSTAR msr so our patches can access it. */
 
3180
    /*
 
3181
     * Save the current TPR value in the LSTAR MSR so our patches can access it.
 
3182
     */
2683
3183
    if (pVM->hwaccm.s.fTPRPatchingActive)
2684
3184
    {
2685
3185
        Assert(pVM->hwaccm.s.fTPRPatchingActive);
2688
3188
    }
2689
3189
 
2690
3190
    TMNotifyStartOfExecution(pVCpu);
 
3191
 
 
3192
#ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
3193
    /*
 
3194
     * Save the current Host TSC_AUX and write the guest TSC_AUX to the host, so that
 
3195
     * RDTSCPs (that don't cause exits) reads the guest MSR. See @bugref{3324}.
 
3196
     */
 
3197
    if (    (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
 
3198
        && !(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
 
3199
    {
 
3200
        pVCpu->hwaccm.s.u64HostTSCAux = ASMRdMsr(MSR_K8_TSC_AUX);
 
3201
        uint64_t u64GuestTSCAux = 0;
 
3202
        rc2 = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX, &u64GuestTSCAux);
 
3203
        AssertRC(rc2);
 
3204
        ASMWrMsr(MSR_K8_TSC_AUX, u64GuestTSCAux);
 
3205
    }
 
3206
#endif
 
3207
 
2691
3208
#ifdef VBOX_WITH_KERNEL_USING_XMM
2692
3209
    rc = hwaccmR0VMXStartVMWrapXMM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu, pVCpu->hwaccm.s.vmx.pfnStartVM);
2693
3210
#else
2695
3212
#endif
2696
3213
    ASMAtomicWriteBool(&pVCpu->hwaccm.s.fCheckedTLBFlush, false);
2697
3214
    ASMAtomicIncU32(&pVCpu->hwaccm.s.cWorldSwitchExits);
2698
 
    /* Possibly the last TSC value seen by the guest (too high) (only when we're in tsc offset mode). */
 
3215
 
 
3216
    /* Possibly the last TSC value seen by the guest (too high) (only when we're in TSC offset mode). */
2699
3217
    if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
2700
 
        TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hwaccm.s.vmx.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
 
3218
    {
 
3219
#ifndef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
3220
        /* Restore host's TSC_AUX. */
 
3221
        if (pVCpu->hwaccm.s.vmx.proc_ctls2 & VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP)
 
3222
            ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hwaccm.s.u64HostTSCAux);
 
3223
#endif
 
3224
 
 
3225
        TMCpuTickSetLastSeen(pVCpu,
 
3226
                             ASMReadTSC() + pVCpu->hwaccm.s.vmx.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
 
3227
    }
2701
3228
 
2702
3229
    TMNotifyEndOfExecution(pVCpu);
2703
3230
    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
2704
3231
    Assert(!(ASMGetFlags() & X86_EFL_IF));
2705
3232
 
2706
 
    /* Restore the host LSTAR msr if the guest could have changed it. */
 
3233
    /*
 
3234
     * Restore the host LSTAR MSR if the guest could have changed it.
 
3235
     */
2707
3236
    if (pVM->hwaccm.s.fTPRPatchingActive)
2708
3237
    {
2709
3238
        Assert(pVM->hwaccm.s.fTPRPatchingActive);
2717
3246
    uOldEFlags = ~(RTCCUINTREG)0;
2718
3247
#endif
2719
3248
 
2720
 
    AssertMsg(!pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries=%d\n", pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries));
 
3249
    AssertMsg(!pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries, ("pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries=%d\n",
 
3250
                                                                   pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries));
2721
3251
 
2722
3252
    /* In case we execute a goto ResumeExecution later on. */
2723
3253
    pVCpu->hwaccm.s.fResumeVM  = true;
2731
3261
 
2732
3262
    if (RT_UNLIKELY(rc != VINF_SUCCESS))
2733
3263
    {
2734
 
        VMXR0ReportWorldSwitchError(pVM, pVCpu, rc, pCtx);
 
3264
        hmR0VmxReportWorldSwitchError(pVM, pVCpu, rc, pCtx);
2735
3265
        VMMR0LogFlushEnable(pVCpu);
2736
3266
        goto end;
2737
3267
    }
2752
3282
    rc2 |= VMXReadCachedVMCS(VMX_VMCS_RO_EXIT_QUALIFICATION, &exitQualification);
2753
3283
    AssertRC(rc2);
2754
3284
 
2755
 
    /* Sync back the guest state */
 
3285
    /*
 
3286
     * Sync back the guest state.
 
3287
     */
2756
3288
    rc2 = VMXR0SaveGuestState(pVM, pVCpu, pCtx);
2757
3289
    AssertRC(rc2);
2758
3290
 
2759
3291
    /* Note! NOW IT'S SAFE FOR LOGGING! */
2760
3292
    VMMR0LogFlushEnable(pVCpu);
2761
3293
    Log2(("Raw exit reason %08x\n", exitReason));
 
3294
#if ARCH_BITS == 64 /* for the time being */
 
3295
    VBOXVMM_R0_HMVMX_VMEXIT(pVCpu, pCtx, exitReason);
 
3296
#endif
2762
3297
 
2763
 
    /* Check if an injected event was interrupted prematurely. */
 
3298
    /*
 
3299
     * Check if an injected event was interrupted prematurely.
 
3300
     */
2764
3301
    rc2 = VMXReadCachedVMCS(VMX_VMCS32_RO_IDT_INFO,            &val);
2765
3302
    AssertRC(rc2);
2766
3303
    pVCpu->hwaccm.s.Event.intInfo = VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(val);
2778
3315
            rc2 = VMXReadCachedVMCS(VMX_VMCS32_RO_IDT_ERRCODE, &val);
2779
3316
            AssertRC(rc2);
2780
3317
            pVCpu->hwaccm.s.Event.errCode  = val;
2781
 
            Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv pending error=%RX64\n", pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification, val));
 
3318
            Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv pending error=%RX64\n",
 
3319
                 pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification, val));
2782
3320
        }
2783
3321
        else
2784
3322
        {
2785
 
            Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n", pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
 
3323
            Log(("Pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n", pVCpu->hwaccm.s.Event.intInfo,
 
3324
                 (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
2786
3325
            pVCpu->hwaccm.s.Event.errCode  = 0;
2787
3326
        }
2788
3327
    }
2789
3328
#ifdef VBOX_STRICT
2790
 
    else
2791
 
    if (    VMX_EXIT_INTERRUPTION_INFO_VALID(pVCpu->hwaccm.s.Event.intInfo)
2792
 
        /* Ignore software exceptions (such as int3) as they're reoccur when we restart the instruction anyway. */
2793
 
        &&  VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hwaccm.s.Event.intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT)
 
3329
    else if (   VMX_EXIT_INTERRUPTION_INFO_VALID(pVCpu->hwaccm.s.Event.intInfo)
 
3330
                /* Ignore software exceptions (such as int3) as they're reoccur when we restart the instruction anyway. */
 
3331
             && VMX_EXIT_INTERRUPTION_INFO_TYPE(pVCpu->hwaccm.s.Event.intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT)
2794
3332
    {
2795
 
        Log(("Ignore pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n", pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
 
3333
        Log(("Ignore pending inject %RX64 at %RGv exit=%08x intInfo=%08x exitQualification=%RGv\n",
 
3334
             pVCpu->hwaccm.s.Event.intInfo, (RTGCPTR)pCtx->rip, exitReason, intInfo, exitQualification));
2796
3335
    }
2797
3336
 
2798
3337
    if (exitReason == VMX_EXIT_ERR_INVALID_GUEST_STATE)
2799
3338
        HWACCMDumpRegs(pVM, pVCpu, pCtx);
2800
3339
#endif
2801
3340
 
2802
 
    Log2(("E%d: New EIP=%x:%RGv\n", (uint32_t)exitReason, pCtx->cs, (RTGCPTR)pCtx->rip));
 
3341
    Log2(("E%d: New EIP=%x:%RGv\n", (uint32_t)exitReason, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
2803
3342
    Log2(("Exit reason %d, exitQualification %RGv\n", (uint32_t)exitReason, exitQualification));
2804
3343
    Log2(("instrInfo=%d instrError=%d instr length=%d\n", (uint32_t)instrInfo, (uint32_t)instrError, (uint32_t)cbInstr));
2805
3344
    Log2(("Interruption error code %d\n", (uint32_t)errCode));
2806
3345
    Log2(("IntInfo = %08x\n", (uint32_t)intInfo));
2807
3346
 
2808
 
    /* Sync back the TPR if it was changed. */
 
3347
    /*
 
3348
     * Sync back the TPR if it was changed.
 
3349
     */
2809
3350
    if (    fSetupTPRCaching
2810
3351
        &&  u8LastTPR != pVCpu->hwaccm.s.vmx.pbVAPIC[0x80])
2811
3352
    {
2813
3354
        AssertRC(rc2);
2814
3355
    }
2815
3356
 
 
3357
#ifdef DBGFTRACE_ENABLED /** @todo DTrace later. */
 
3358
    RTTraceBufAddMsgF(pVM->CTX_SUFF(hTraceBuf), "vmexit %08x %016RX64 at %04:%08RX64 %RX64",
 
3359
                      exitReason, (uint64_t)exitQualification, pCtx->cs.Sel, pCtx->rip, (uint64_t)intInfo);
 
3360
#endif
2816
3361
    STAM_PROFILE_ADV_STOP_START(&pVCpu->hwaccm.s.StatExit1, &pVCpu->hwaccm.s.StatExit2, x);
2817
3362
 
2818
3363
    /* Some cases don't need a complete resync of the guest CPU state; handle them here. */
2878
3423
 
2879
3424
                Log(("Forward #NM fault to the guest\n"));
2880
3425
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNM);
2881
 
                rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, 0);
 
3426
                rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3427
                                         cbInstr, 0);
2882
3428
                AssertRC(rc2);
2883
3429
                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
2884
3430
                goto ResumeExecution;
2886
3432
 
2887
3433
            case X86_XCPT_PF: /* Page fault */
2888
3434
            {
2889
 
#ifdef DEBUG
 
3435
#ifdef VBOX_ALWAYS_TRAP_PF
2890
3436
                if (pVM->hwaccm.s.fNestedPaging)
2891
 
                {   /* A genuine pagefault.
2892
 
                     * Forward the trap to the guest by injecting the exception and resuming execution.
 
3437
                {
 
3438
                    /*
 
3439
                     * A genuine pagefault. Forward the trap to the guest by injecting the exception and resuming execution.
2893
3440
                     */
2894
 
                    Log(("Guest page fault at %RGv cr2=%RGv error code %RGv rsp=%RGv\n", (RTGCPTR)pCtx->rip, exitQualification, errCode, (RTGCPTR)pCtx->rsp));
 
3441
                    Log(("Guest page fault at %RGv cr2=%RGv error code %RGv rsp=%RGv\n", (RTGCPTR)pCtx->rip, exitQualification,
 
3442
                         errCode, (RTGCPTR)pCtx->rsp));
2895
3443
 
2896
3444
                    Assert(CPUMIsGuestInPagedProtectedModeEx(pCtx));
2897
3445
 
2899
3447
 
2900
3448
                    /* Now we must update CR2. */
2901
3449
                    pCtx->cr2 = exitQualification;
2902
 
                    rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3450
                    rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3451
                                             cbInstr, errCode);
2903
3452
                    AssertRC(rc2);
2904
3453
 
2905
3454
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
2906
3455
                    goto ResumeExecution;
2907
3456
                }
2908
 
#endif
 
3457
#else
2909
3458
                Assert(!pVM->hwaccm.s.fNestedPaging);
 
3459
#endif
2910
3460
 
2911
3461
#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
2912
3462
                /* Shortcut for APIC TPR reads and writes; 32 bits guests only */
2914
3464
                    &&  pVM->hwaccm.s.pGuestPatchMem
2915
3465
                    &&  (exitQualification & 0xfff) == 0x080
2916
3466
                    &&  !(errCode & X86_TRAP_PF_P)  /* not present */
2917
 
                    &&  CPUMGetGuestCPL(pVCpu, CPUMCTX2CORE(pCtx)) == 0
 
3467
                    &&  CPUMGetGuestCPL(pVCpu) == 0
2918
3468
                    &&  !CPUMIsGuestInLongModeEx(pCtx)
2919
3469
                    &&  pVM->hwaccm.s.cPatches < RT_ELEMENTS(pVM->hwaccm.s.aPatches))
2920
3470
                {
2921
3471
                    RTGCPHYS GCPhysApicBase, GCPhys;
2922
 
                    PDMApicGetBase(pVM, &GCPhysApicBase);   /* @todo cache this */
 
3472
                    PDMApicGetBase(pVM, &GCPhysApicBase);   /** @todo cache this */
2923
3473
                    GCPhysApicBase &= PAGE_BASE_GC_MASK;
2924
3474
 
2925
3475
                    rc = PGMGstGetPage(pVCpu, (RTGCPTR)exitQualification, NULL, &GCPhys);
2976
3526
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
2977
3527
                    goto ResumeExecution;
2978
3528
                }
2979
 
                else
2980
 
                if (rc == VINF_EM_RAW_GUEST_TRAP)
2981
 
                {   /* A genuine pagefault.
2982
 
                     * Forward the trap to the guest by injecting the exception and resuming execution.
 
3529
                else if (rc == VINF_EM_RAW_GUEST_TRAP)
 
3530
                {
 
3531
                    /*
 
3532
                     * A genuine pagefault. Forward the trap to the guest by injecting the exception and resuming execution.
2983
3533
                     */
2984
3534
                    Log2(("Forward page fault to the guest\n"));
2985
3535
 
2991
3541
 
2992
3542
                    /* Now we must update CR2. */
2993
3543
                    pCtx->cr2 = exitQualification;
2994
 
                    rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3544
                    rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3545
                                             cbInstr, errCode);
2995
3546
                    AssertRC(rc2);
2996
3547
 
2997
3548
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3002
3553
                    Log2(("PGMTrap0eHandler failed with %d\n", VBOXSTRICTRC_VAL(rc)));
3003
3554
#endif
3004
3555
                /* Need to go back to the recompiler to emulate the instruction. */
 
3556
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitShadowPFEM);
3005
3557
                TRPMResetTrap(pVCpu);
3006
3558
                break;
3007
3559
            }
3016
3568
                    rc = VINF_EM_RAW_EMULATE_INSTR;
3017
3569
                    break;
3018
3570
                }
3019
 
                Log(("Trap %x at %04X:%RGv\n", vector, pCtx->cs, (RTGCPTR)pCtx->rip));
3020
 
                rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3571
                Log(("Trap %x at %04X:%RGv\n", vector, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
 
3572
                rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3573
                                         cbInstr, errCode);
3021
3574
                AssertRC(rc2);
3022
3575
 
3023
3576
                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3028
3581
            {
3029
3582
                uint64_t uDR6;
3030
3583
 
3031
 
                /* DR6, DR7.GD and IA32_DEBUGCTL.LBR are not updated yet.
 
3584
                /*
 
3585
                 * DR6, DR7.GD and IA32_DEBUGCTL.LBR are not updated yet.
3032
3586
                 *
3033
3587
                 * Exit qualification bits:
3034
3588
                 *  3:0     B0-B3 which breakpoint condition was met
3053
3607
                    if (CPUMIsGuestDebugStateActive(pVCpu))
3054
3608
                        ASMSetDR6(pCtx->dr[6]);
3055
3609
 
3056
 
                    /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */
 
3610
                    /* X86_DR7_GD will be cleared if DRx accesses should be trapped inside the guest. */
3057
3611
                    pCtx->dr[7] &= ~X86_DR7_GD;
3058
3612
 
3059
3613
                    /* Paranoia. */
3065
3619
                    rc2 = VMXWriteVMCS64(VMX_VMCS64_GUEST_DR7, pCtx->dr[7]);
3066
3620
                    AssertRC(rc2);
3067
3621
 
3068
 
                    Log(("Trap %x (debug) at %RGv exit qualification %RX64 dr6=%x dr7=%x\n", vector, (RTGCPTR)pCtx->rip, exitQualification, (uint32_t)pCtx->dr[6], (uint32_t)pCtx->dr[7]));
3069
 
                    rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3622
                    Log(("Trap %x (debug) at %RGv exit qualification %RX64 dr6=%x dr7=%x\n", vector, (RTGCPTR)pCtx->rip,
 
3623
                         exitQualification, (uint32_t)pCtx->dr[6], (uint32_t)pCtx->dr[7]));
 
3624
                    rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3625
                                             cbInstr, errCode);
3070
3626
                    AssertRC(rc2);
3071
3627
 
3072
3628
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3073
3629
                    goto ResumeExecution;
3074
3630
                }
3075
3631
                /* Return to ring 3 to deal with the debug exit code. */
3076
 
                Log(("Debugger hardware BP at %04x:%RGv (rc=%Rrc)\n", pCtx->cs, pCtx->rip, VBOXSTRICTRC_VAL(rc)));
 
3632
                Log(("Debugger hardware BP at %04x:%RGv (rc=%Rrc)\n", pCtx->cs.Sel, pCtx->rip, VBOXSTRICTRC_VAL(rc)));
3077
3633
                break;
3078
3634
            }
3079
3635
 
3080
3636
            case X86_XCPT_BP:   /* Breakpoint. */
3081
3637
            {
 
3638
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestBP);
3082
3639
                rc = DBGFRZTrap03Handler(pVM, pVCpu, CPUMCTX2CORE(pCtx));
3083
3640
                if (rc == VINF_EM_RAW_GUEST_TRAP)
3084
3641
                {
3085
 
                    Log(("Guest #BP at %04x:%RGv\n", pCtx->cs, pCtx->rip));
3086
 
                    rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3642
                    Log(("Guest #BP at %04x:%RGv\n", pCtx->cs.Sel, pCtx->rip));
 
3643
                    rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3644
                                             cbInstr, errCode);
3087
3645
                    AssertRC(rc2);
3088
3646
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3089
3647
                    goto ResumeExecution;
3093
3651
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3094
3652
                    goto ResumeExecution;
3095
3653
                }
3096
 
                Log(("Debugger BP at %04x:%RGv (rc=%Rrc)\n", pCtx->cs, pCtx->rip, VBOXSTRICTRC_VAL(rc)));
 
3654
                Log(("Debugger BP at %04x:%RGv (rc=%Rrc)\n", pCtx->cs.Sel, pCtx->rip, VBOXSTRICTRC_VAL(rc)));
3097
3655
                break;
3098
3656
            }
3099
3657
 
3100
 
            case X86_XCPT_GP:   /* General protection failure exception.*/
 
3658
            case X86_XCPT_GP:   /* General protection failure exception. */
3101
3659
            {
3102
3660
                uint32_t     cbOp;
3103
 
                uint32_t     cbSize;
3104
3661
                PDISCPUSTATE pDis = &pVCpu->hwaccm.s.DisState;
3105
3662
 
3106
3663
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestGP);
3108
3665
                if (    !CPUMIsGuestInRealModeEx(pCtx)
3109
3666
                    ||  !pVM->hwaccm.s.vmx.pRealModeTSS)
3110
3667
                {
3111
 
                    Log(("Trap %x at %04X:%RGv errorCode=%RGv\n", vector, pCtx->cs, (RTGCPTR)pCtx->rip, errCode));
3112
 
                    rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3668
                    Log(("Trap %x at %04X:%RGv errorCode=%RGv\n", vector, pCtx->cs.Sel, (RTGCPTR)pCtx->rip, errCode));
 
3669
                    rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3670
                                             cbInstr, errCode);
3113
3671
                    AssertRC(rc2);
3114
3672
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3115
3673
                    goto ResumeExecution;
3117
3675
#endif
3118
3676
                Assert(CPUMIsGuestInRealModeEx(pCtx));
3119
3677
 
3120
 
                LogFlow(("Real mode X86_XCPT_GP instruction emulation at %x:%RGv\n", pCtx->cs, (RTGCPTR)pCtx->rip));
 
3678
                LogFlow(("Real mode X86_XCPT_GP instruction emulation at %x:%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
3121
3679
 
3122
 
                rc2 = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, &cbOp);
 
3680
                rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, &cbOp);
3123
3681
                if (RT_SUCCESS(rc2))
3124
3682
                {
3125
3683
                    bool fUpdateRIP = true;
3126
3684
 
3127
3685
                    rc = VINF_SUCCESS;
3128
 
                    Assert(cbOp == pDis->opsize);
3129
 
                    switch (pDis->pCurInstr->opcode)
3130
 
                    {
3131
 
                    case OP_CLI:
3132
 
                        pCtx->eflags.Bits.u1IF = 0;
3133
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCli);
3134
 
                        break;
3135
 
 
3136
 
                    case OP_STI:
3137
 
                        pCtx->eflags.Bits.u1IF = 1;
3138
 
                        EMSetInhibitInterruptsPC(pVCpu, pCtx->rip + pDis->opsize);
3139
 
                        Assert(VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
3140
 
                        rc2 = VMXWriteVMCS(VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE, VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI);
3141
 
                        AssertRC(rc2);
3142
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitSti);
3143
 
                        break;
3144
 
 
3145
 
                    case OP_HLT:
3146
 
                        fUpdateRIP = false;
3147
 
                        rc = VINF_EM_HALT;
3148
 
                        pCtx->rip += pDis->opsize;
3149
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt);
3150
 
                        break;
3151
 
 
3152
 
                    case OP_POPF:
3153
 
                    {
3154
 
                        RTGCPTR   GCPtrStack;
3155
 
                        uint32_t  cbParm;
3156
 
                        uint32_t  uMask;
3157
 
                        X86EFLAGS eflags;
3158
 
 
3159
 
                        if (pDis->prefix & PREFIX_OPSIZE)
3160
 
                        {
3161
 
                            cbParm = 4;
3162
 
                            uMask  = 0xffffffff;
3163
 
                        }
3164
 
                        else
3165
 
                        {
3166
 
                            cbParm = 2;
3167
 
                            uMask  = 0xffff;
3168
 
                        }
3169
 
 
3170
 
                        rc2 = SELMToFlatEx(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), pCtx->esp & uMask, 0, &GCPtrStack);
3171
 
                        if (RT_FAILURE(rc2))
3172
 
                        {
3173
 
                            rc = VERR_EM_INTERPRETER;
3174
 
                            break;
3175
 
                        }
3176
 
                        eflags.u = 0;
3177
 
                        rc2 = PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
3178
 
                        if (RT_FAILURE(rc2))
3179
 
                        {
3180
 
                            rc = VERR_EM_INTERPRETER;
3181
 
                            break;
3182
 
                        }
3183
 
                        LogFlow(("POPF %x -> %RGv mask=%x\n", eflags.u, pCtx->rsp, uMask));
3184
 
                        pCtx->eflags.u = (pCtx->eflags.u & ~(X86_EFL_POPF_BITS & uMask)) | (eflags.u & X86_EFL_POPF_BITS & uMask);
3185
 
                        /* RF cleared when popped in real mode; see pushf description in AMD manual. */
3186
 
                        pCtx->eflags.Bits.u1RF = 0;
3187
 
                        pCtx->esp += cbParm;
3188
 
                        pCtx->esp &= uMask;
3189
 
 
3190
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPopf);
3191
 
                        break;
3192
 
                    }
3193
 
 
3194
 
                    case OP_PUSHF:
3195
 
                    {
3196
 
                        RTGCPTR   GCPtrStack;
3197
 
                        uint32_t  cbParm;
3198
 
                        uint32_t  uMask;
3199
 
                        X86EFLAGS eflags;
3200
 
 
3201
 
                        if (pDis->prefix & PREFIX_OPSIZE)
3202
 
                        {
3203
 
                            cbParm = 4;
3204
 
                            uMask  = 0xffffffff;
3205
 
                        }
3206
 
                        else
3207
 
                        {
3208
 
                            cbParm = 2;
3209
 
                            uMask  = 0xffff;
3210
 
                        }
3211
 
 
3212
 
                        rc2 = SELMToFlatEx(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), (pCtx->esp - cbParm) & uMask, 0, &GCPtrStack);
3213
 
                        if (RT_FAILURE(rc2))
3214
 
                        {
3215
 
                            rc = VERR_EM_INTERPRETER;
3216
 
                            break;
3217
 
                        }
3218
 
                        eflags = pCtx->eflags;
3219
 
                        /* RF & VM cleared when pushed in real mode; see pushf description in AMD manual. */
3220
 
                        eflags.Bits.u1RF = 0;
3221
 
                        eflags.Bits.u1VM = 0;
3222
 
 
3223
 
                        rc2 = PGMPhysWrite(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
3224
 
                        if (RT_FAILURE(rc2))
3225
 
                        {
3226
 
                            rc = VERR_EM_INTERPRETER;
3227
 
                            break;
3228
 
                        }
3229
 
                        LogFlow(("PUSHF %x -> %RGv\n", eflags.u, GCPtrStack));
3230
 
                        pCtx->esp -= cbParm;
3231
 
                        pCtx->esp &= uMask;
3232
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPushf);
3233
 
                        break;
3234
 
                    }
3235
 
 
3236
 
                    case OP_IRET:
3237
 
                    {
3238
 
                        RTGCPTR   GCPtrStack;
3239
 
                        uint32_t  uMask = 0xffff;
3240
 
                        uint16_t  aIretFrame[3];
3241
 
 
3242
 
                        if (pDis->prefix & (PREFIX_OPSIZE | PREFIX_ADDRSIZE))
3243
 
                        {
3244
 
                            rc = VERR_EM_INTERPRETER;
3245
 
                            break;
3246
 
                        }
3247
 
 
3248
 
                        rc2 = SELMToFlatEx(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), pCtx->esp & uMask, 0, &GCPtrStack);
3249
 
                        if (RT_FAILURE(rc2))
3250
 
                        {
3251
 
                            rc = VERR_EM_INTERPRETER;
3252
 
                            break;
3253
 
                        }
3254
 
                        rc2 = PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &aIretFrame[0], sizeof(aIretFrame));
3255
 
                        if (RT_FAILURE(rc2))
3256
 
                        {
3257
 
                            rc = VERR_EM_INTERPRETER;
3258
 
                            break;
3259
 
                        }
3260
 
                        pCtx->ip            = aIretFrame[0];
3261
 
                        pCtx->cs            = aIretFrame[1];
3262
 
                        pCtx->csHid.u64Base = pCtx->cs << 4;
3263
 
                        pCtx->eflags.u      = (pCtx->eflags.u & ~(X86_EFL_POPF_BITS & uMask)) | (aIretFrame[2] & X86_EFL_POPF_BITS & uMask);
3264
 
                        pCtx->sp           += sizeof(aIretFrame);
3265
 
 
3266
 
                        LogFlow(("iret to %04x:%x\n", pCtx->cs, pCtx->ip));
3267
 
                        fUpdateRIP = false;
3268
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIret);
3269
 
                        break;
3270
 
                    }
3271
 
 
3272
 
                    case OP_INT:
3273
 
                    {
3274
 
                        uint32_t intInfo2;
3275
 
 
3276
 
                        LogFlow(("Realmode: INT %x\n", pDis->param1.parval & 0xff));
3277
 
                        intInfo2  = pDis->param1.parval & 0xff;
3278
 
                        intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
3279
 
                        intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
3280
 
 
3281
 
                        rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo2, cbOp, 0);
3282
 
                        AssertRC(VBOXSTRICTRC_VAL(rc));
3283
 
                        fUpdateRIP = false;
3284
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
3285
 
                        break;
3286
 
                    }
3287
 
 
3288
 
                    case OP_INTO:
3289
 
                    {
3290
 
                        if (pCtx->eflags.Bits.u1OF)
3291
 
                        {
3292
 
                            uint32_t intInfo2;
3293
 
 
3294
 
                            LogFlow(("Realmode: INTO\n"));
3295
 
                            intInfo2  = X86_XCPT_OF;
3296
 
                            intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
3297
 
                            intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
3298
 
 
3299
 
                            rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo2, cbOp, 0);
3300
 
                            AssertRC(VBOXSTRICTRC_VAL(rc));
3301
 
                            fUpdateRIP = false;
3302
 
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
3303
 
                        }
3304
 
                        break;
3305
 
                    }
3306
 
 
3307
 
                    case OP_INT3:
3308
 
                    {
3309
 
                        uint32_t intInfo2;
3310
 
 
3311
 
                        LogFlow(("Realmode: INT 3\n"));
3312
 
                        intInfo2  = 3;
3313
 
                        intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
3314
 
                        intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
3315
 
 
3316
 
                        rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo2, cbOp, 0);
3317
 
                        AssertRC(VBOXSTRICTRC_VAL(rc));
3318
 
                        fUpdateRIP = false;
3319
 
                        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
3320
 
                        break;
3321
 
                    }
3322
 
 
3323
 
                    default:
3324
 
                        rc = EMInterpretInstructionCPU(pVM, pVCpu, pDis, CPUMCTX2CORE(pCtx), 0, EMCODETYPE_SUPERVISOR, &cbSize);
3325
 
                        break;
 
3686
                    Assert(cbOp == pDis->cbInstr);
 
3687
                    switch (pDis->pCurInstr->uOpcode)
 
3688
                    {
 
3689
                        case OP_CLI:
 
3690
                            pCtx->eflags.Bits.u1IF = 0;
 
3691
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCli);
 
3692
                            break;
 
3693
 
 
3694
                        case OP_STI:
 
3695
                            pCtx->eflags.Bits.u1IF = 1;
 
3696
                            EMSetInhibitInterruptsPC(pVCpu, pCtx->rip + pDis->cbInstr);
 
3697
                            Assert(VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS));
 
3698
                            rc2 = VMXWriteVMCS(VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE,
 
3699
                                               VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI);
 
3700
                            AssertRC(rc2);
 
3701
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitSti);
 
3702
                            break;
 
3703
 
 
3704
                        case OP_HLT:
 
3705
                            fUpdateRIP = false;
 
3706
                            rc = VINF_EM_HALT;
 
3707
                            pCtx->rip += pDis->cbInstr;
 
3708
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt);
 
3709
                            break;
 
3710
 
 
3711
                        case OP_POPF:
 
3712
                        {
 
3713
                            RTGCPTR   GCPtrStack;
 
3714
                            uint32_t  cbParm;
 
3715
                            uint32_t  uMask;
 
3716
                            X86EFLAGS eflags;
 
3717
 
 
3718
                            if (pDis->fPrefix & DISPREFIX_OPSIZE)
 
3719
                            {
 
3720
                                cbParm = 4;
 
3721
                                uMask  = 0xffffffff;
 
3722
                            }
 
3723
                            else
 
3724
                            {
 
3725
                                cbParm = 2;
 
3726
                                uMask  = 0xffff;
 
3727
                            }
 
3728
 
 
3729
                            rc2 = SELMToFlatEx(pVCpu, DISSELREG_SS, CPUMCTX2CORE(pCtx), pCtx->esp & uMask, 0, &GCPtrStack);
 
3730
                            if (RT_FAILURE(rc2))
 
3731
                            {
 
3732
                                rc = VERR_EM_INTERPRETER;
 
3733
                                break;
 
3734
                            }
 
3735
                            eflags.u = 0;
 
3736
                            rc2 = PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
 
3737
                            if (RT_FAILURE(rc2))
 
3738
                            {
 
3739
                                rc = VERR_EM_INTERPRETER;
 
3740
                                break;
 
3741
                            }
 
3742
                            LogFlow(("POPF %x -> %RGv mask=%x\n", eflags.u, pCtx->rsp, uMask));
 
3743
                            pCtx->eflags.u = (pCtx->eflags.u & ~(X86_EFL_POPF_BITS & uMask))
 
3744
                                            | (eflags.u & X86_EFL_POPF_BITS & uMask);
 
3745
                            /* RF cleared when popped in real mode; see pushf description in AMD manual. */
 
3746
                            pCtx->eflags.Bits.u1RF = 0;
 
3747
                            pCtx->esp += cbParm;
 
3748
                            pCtx->esp &= uMask;
 
3749
 
 
3750
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPopf);
 
3751
                            break;
 
3752
                        }
 
3753
 
 
3754
                        case OP_PUSHF:
 
3755
                        {
 
3756
                            RTGCPTR   GCPtrStack;
 
3757
                            uint32_t  cbParm;
 
3758
                            uint32_t  uMask;
 
3759
                            X86EFLAGS eflags;
 
3760
 
 
3761
                            if (pDis->fPrefix & DISPREFIX_OPSIZE)
 
3762
                            {
 
3763
                                cbParm = 4;
 
3764
                                uMask  = 0xffffffff;
 
3765
                            }
 
3766
                            else
 
3767
                            {
 
3768
                                cbParm = 2;
 
3769
                                uMask  = 0xffff;
 
3770
                            }
 
3771
 
 
3772
                            rc2 = SELMToFlatEx(pVCpu, DISSELREG_SS, CPUMCTX2CORE(pCtx), (pCtx->esp - cbParm) & uMask, 0,
 
3773
                                               &GCPtrStack);
 
3774
                            if (RT_FAILURE(rc2))
 
3775
                            {
 
3776
                                rc = VERR_EM_INTERPRETER;
 
3777
                                break;
 
3778
                            }
 
3779
                            eflags = pCtx->eflags;
 
3780
                            /* RF & VM cleared when pushed in real mode; see pushf description in AMD manual. */
 
3781
                            eflags.Bits.u1RF = 0;
 
3782
                            eflags.Bits.u1VM = 0;
 
3783
 
 
3784
                            rc2 = PGMPhysWrite(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
 
3785
                            if (RT_FAILURE(rc2))
 
3786
                            {
 
3787
                                rc = VERR_EM_INTERPRETER;
 
3788
                                break;
 
3789
                            }
 
3790
                            LogFlow(("PUSHF %x -> %RGv\n", eflags.u, GCPtrStack));
 
3791
                            pCtx->esp -= cbParm;
 
3792
                            pCtx->esp &= uMask;
 
3793
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitPushf);
 
3794
                            break;
 
3795
                        }
 
3796
 
 
3797
                        case OP_IRET:
 
3798
                        {
 
3799
                            RTGCPTR   GCPtrStack;
 
3800
                            uint32_t  uMask = 0xffff;
 
3801
                            uint16_t  aIretFrame[3];
 
3802
 
 
3803
                            if (pDis->fPrefix & (DISPREFIX_OPSIZE | DISPREFIX_ADDRSIZE))
 
3804
                            {
 
3805
                                rc = VERR_EM_INTERPRETER;
 
3806
                                break;
 
3807
                            }
 
3808
 
 
3809
                            rc2 = SELMToFlatEx(pVCpu, DISSELREG_SS, CPUMCTX2CORE(pCtx), pCtx->esp & uMask, 0, &GCPtrStack);
 
3810
                            if (RT_FAILURE(rc2))
 
3811
                            {
 
3812
                                rc = VERR_EM_INTERPRETER;
 
3813
                                break;
 
3814
                            }
 
3815
                            rc2 = PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &aIretFrame[0], sizeof(aIretFrame));
 
3816
                            if (RT_FAILURE(rc2))
 
3817
                            {
 
3818
                                rc = VERR_EM_INTERPRETER;
 
3819
                                break;
 
3820
                            }
 
3821
                            pCtx->ip            = aIretFrame[0];
 
3822
                            pCtx->cs.Sel        = aIretFrame[1];
 
3823
                            pCtx->cs.ValidSel   = aIretFrame[1];
 
3824
                            pCtx->cs.u64Base    = (uint32_t)pCtx->cs.Sel << 4;
 
3825
                            pCtx->eflags.u      =   (pCtx->eflags.u & ~(X86_EFL_POPF_BITS & uMask))
 
3826
                                                  | (aIretFrame[2] & X86_EFL_POPF_BITS & uMask);
 
3827
                            pCtx->sp           += sizeof(aIretFrame);
 
3828
 
 
3829
                            LogFlow(("iret to %04x:%x\n", pCtx->cs.Sel, pCtx->ip));
 
3830
                            fUpdateRIP = false;
 
3831
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIret);
 
3832
                            break;
 
3833
                        }
 
3834
 
 
3835
                        case OP_INT:
 
3836
                        {
 
3837
                            uint32_t intInfo2;
 
3838
 
 
3839
                            LogFlow(("Realmode: INT %x\n", pDis->Param1.uValue & 0xff));
 
3840
                            intInfo2  = pDis->Param1.uValue & 0xff;
 
3841
                            intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
 
3842
                            intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
 
3843
 
 
3844
                            rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo2, cbOp, 0);
 
3845
                            AssertRC(VBOXSTRICTRC_VAL(rc));
 
3846
                            fUpdateRIP = false;
 
3847
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
 
3848
                            break;
 
3849
                        }
 
3850
 
 
3851
                        case OP_INTO:
 
3852
                        {
 
3853
                            if (pCtx->eflags.Bits.u1OF)
 
3854
                            {
 
3855
                                uint32_t intInfo2;
 
3856
 
 
3857
                                LogFlow(("Realmode: INTO\n"));
 
3858
                                intInfo2  = X86_XCPT_OF;
 
3859
                                intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
 
3860
                                intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
 
3861
 
 
3862
                                rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo2, cbOp, 0);
 
3863
                                AssertRC(VBOXSTRICTRC_VAL(rc));
 
3864
                                fUpdateRIP = false;
 
3865
                                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
 
3866
                            }
 
3867
                            break;
 
3868
                        }
 
3869
 
 
3870
                        case OP_INT3:
 
3871
                        {
 
3872
                            uint32_t intInfo2;
 
3873
 
 
3874
                            LogFlow(("Realmode: INT 3\n"));
 
3875
                            intInfo2  = 3;
 
3876
                            intInfo2 |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
 
3877
                            intInfo2 |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
 
3878
 
 
3879
                            rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, intInfo2, cbOp, 0);
 
3880
                            AssertRC(VBOXSTRICTRC_VAL(rc));
 
3881
                            fUpdateRIP = false;
 
3882
                            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInt);
 
3883
                            break;
 
3884
                        }
 
3885
 
 
3886
                        default:
 
3887
                            rc = EMInterpretInstructionDisasState(pVCpu, pDis, CPUMCTX2CORE(pCtx), 0, EMCODETYPE_SUPERVISOR);
 
3888
                            fUpdateRIP = false;
 
3889
                            break;
3326
3890
                    }
3327
3891
 
3328
3892
                    if (rc == VINF_SUCCESS)
3330
3894
                        if (fUpdateRIP)
3331
3895
                            pCtx->rip += cbOp; /* Move on to the next instruction. */
3332
3896
 
3333
 
                        /* lidt, lgdt can end up here. In the future crx changes as well. Just reload the whole context to be done with it. */
 
3897
                        /*
 
3898
                         * LIDT, LGDT can end up here. In the future CRx changes as well. Just reload the
 
3899
                         * whole context to be done with it.
 
3900
                         */
3334
3901
                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
3335
3902
 
3336
3903
                        /* Only resume if successful. */
3341
3908
                else
3342
3909
                    rc = VERR_EM_INTERPRETER;
3343
3910
 
3344
 
                AssertMsg(rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT, ("Unexpected rc=%Rrc\n", VBOXSTRICTRC_VAL(rc)));
 
3911
                AssertMsg(rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT,
 
3912
                          ("Unexpected rc=%Rrc\n", VBOXSTRICTRC_VAL(rc)));
3345
3913
                break;
3346
3914
            }
3347
3915
 
3352
3920
            case X86_XCPT_SS:   /* Stack segment exception. */
3353
3921
            case X86_XCPT_NP:   /* Segment not present exception. */
3354
3922
            {
3355
 
                switch(vector)
 
3923
                switch (vector)
3356
3924
                {
3357
 
                case X86_XCPT_DE:
3358
 
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDE);
3359
 
                    break;
3360
 
                case X86_XCPT_UD:
3361
 
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestUD);
3362
 
                    break;
3363
 
                case X86_XCPT_SS:
3364
 
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestSS);
3365
 
                    break;
3366
 
                case X86_XCPT_NP:
3367
 
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNP);
3368
 
                    break;
 
3925
                    case X86_XCPT_DE: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDE); break;
 
3926
                    case X86_XCPT_UD: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestUD); break;
 
3927
                    case X86_XCPT_SS: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestSS); break;
 
3928
                    case X86_XCPT_NP: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestNP); break;
 
3929
                    case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestXF); break;
3369
3930
                }
3370
3931
 
3371
 
                Log(("Trap %x at %04X:%RGv\n", vector, pCtx->cs, (RTGCPTR)pCtx->rip));
3372
 
                rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3932
                Log(("Trap %x at %04X:%RGv\n", vector, pCtx->cs.Sel, (RTGCPTR)pCtx->rip));
 
3933
                rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3934
                                         cbInstr, errCode);
3373
3935
                AssertRC(rc2);
3374
3936
 
3375
3937
                STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3377
3939
            }
3378
3940
#endif
3379
3941
            default:
 
3942
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestXcpUnk);
3380
3943
                if (    CPUMIsGuestInRealModeEx(pCtx)
3381
3944
                    &&  pVM->hwaccm.s.vmx.pRealModeTSS)
3382
3945
                {
3383
 
                    Log(("Real Mode Trap %x at %04x:%04X error code %x\n", vector, pCtx->cs, pCtx->eip, errCode));
3384
 
                    rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), cbInstr, errCode);
 
3946
                    Log(("Real Mode Trap %x at %04x:%04X error code %x\n", vector, pCtx->cs.Sel, pCtx->eip, errCode));
 
3947
                    rc = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
3948
                                            cbInstr, errCode);
3385
3949
                    AssertRC(VBOXSTRICTRC_VAL(rc)); /* Strict RC check below. */
3386
3950
 
3387
 
                    /* Go back to ring 3 in case of a triple fault. */
3388
 
                    if (    vector == X86_XCPT_DF
3389
 
                        &&  rc == VINF_EM_RESET)
 
3951
                    /* Go back to ring-3 in case of a triple fault. */
 
3952
                    if (   vector == X86_XCPT_DF
 
3953
                        && rc == VINF_EM_RESET)
 
3954
                    {
3390
3955
                        break;
 
3956
                    }
3391
3957
 
3392
3958
                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
3393
3959
                    goto ResumeExecution;
3409
3975
        break;
3410
3976
    }
3411
3977
 
3412
 
    case VMX_EXIT_EPT_VIOLATION:        /* 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */
 
3978
    /*
 
3979
     * 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed
 
3980
     * by the configuration of the EPT paging structures.
 
3981
     */
 
3982
    case VMX_EXIT_EPT_VIOLATION:
3413
3983
    {
3414
3984
        RTGCPHYS GCPhys;
3415
3985
 
3429
3999
 
3430
4000
        /* If the page is present, then it's a page level protection fault. */
3431
4001
        if (exitQualification & VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT)
3432
 
        {
3433
4002
            errCode |= X86_TRAP_PF_P;
3434
 
        }
3435
4003
        else
3436
4004
        {
3437
4005
            /* Shortcut for APIC TPR reads and writes. */
3438
4006
            if (    (GCPhys & 0xfff) == 0x080
3439
 
                &&  GCPhys > 0x1000000   /* to skip VGA frame buffer accesses */
 
4007
                &&  GCPhys > 0x1000000          /* to skip VGA frame buffer accesses */
3440
4008
                &&  fSetupTPRCaching
3441
4009
                &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
3442
4010
            {
3460
4028
 
3461
4029
        /* Handle the pagefault trap for the nested shadow table. */
3462
4030
        rc = PGMR0Trap0eHandlerNestedPaging(pVM, pVCpu, PGMMODE_EPT, errCode, CPUMCTX2CORE(pCtx), GCPhys);
3463
 
        if (rc == VINF_SUCCESS)
3464
 
        {   /* We've successfully synced our shadow pages, so let's just continue execution. */
 
4031
 
 
4032
        /*
 
4033
         * Same case as PGMR0Trap0eHandlerNPMisconfig(). See comment below, @bugref{6043}.
 
4034
         */
 
4035
        if (   rc == VINF_SUCCESS
 
4036
            || rc == VERR_PAGE_TABLE_NOT_PRESENT
 
4037
            || rc == VERR_PAGE_NOT_PRESENT)
 
4038
        {
 
4039
            /* We've successfully synced our shadow pages, so let's just continue execution. */
3465
4040
            Log2(("Shadow page fault at %RGv cr2=%RGp error code %x\n", (RTGCPTR)pCtx->rip, exitQualification , errCode));
3466
4041
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitReasonNPF);
3467
4042
 
3468
4043
            TRPMResetTrap(pVCpu);
3469
4044
            goto ResumeExecution;
3470
4045
        }
3471
 
        /** @todo We probably should handle failure to get the instruction page
3472
 
         *        (VERR_PAGE_NOT_PRESENT, VERR_PAGE_TABLE_NOT_PRESENT). See
3473
 
         *        @bugref{6043}. */
3474
4046
 
3475
4047
#ifdef VBOX_STRICT
3476
4048
        if (rc != VINF_EM_RAW_EMULATE_INSTR)
3493
4065
 
3494
4066
        /* Shortcut for APIC TPR reads and writes. */
3495
4067
        if (    (GCPhys & 0xfff) == 0x080
3496
 
            &&  GCPhys > 0x1000000   /* to skip VGA frame buffer accesses */
 
4068
            &&  GCPhys > 0x1000000              /* to skip VGA frame buffer accesses */
3497
4069
            &&  fSetupTPRCaching
3498
4070
            &&  (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls2.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC))
3499
4071
        {
3509
4081
        }
3510
4082
 
3511
4083
        rc = PGMR0Trap0eHandlerNPMisconfig(pVM, pVCpu, PGMMODE_EPT, CPUMCTX2CORE(pCtx), GCPhys, UINT32_MAX);
3512
 
        if (rc == VINF_SUCCESS)
 
4084
 
 
4085
        /*
 
4086
         * If we succeed, resume execution.
 
4087
         * Or, if fail in interpreting the instruction because we couldn't get the guest physical address
 
4088
         * of the page containing the instruction via the guest's page tables (we would invalidate the guest page
 
4089
         * in the host TLB), resume execution which would cause a guest page fault to let the guest handle this
 
4090
         * weird case. See @bugref{6043}.
 
4091
         */
 
4092
        if (   rc == VINF_SUCCESS
 
4093
            || rc == VERR_PAGE_TABLE_NOT_PRESENT
 
4094
            || rc == VERR_PAGE_NOT_PRESENT)
3513
4095
        {
3514
4096
            Log2(("PGMR0Trap0eHandlerNPMisconfig(,,,%RGp) at %RGv -> resume\n", GCPhys, (RTGCPTR)pCtx->rip));
3515
4097
            goto ResumeExecution;
3516
4098
        }
3517
 
        /** @todo We probably should handle failure to get the instruction page
3518
 
         *        (VERR_PAGE_NOT_PRESENT, VERR_PAGE_TABLE_NOT_PRESENT). See
3519
 
         *        @bugref{6043}. */
3520
4099
 
3521
4100
        Log2(("PGMR0Trap0eHandlerNPMisconfig(,,,%RGp) at %RGv -> %Rrc\n", GCPhys, (RTGCPTR)pCtx->rip, VBOXSTRICTRC_VAL(rc)));
3522
4101
        break;
3524
4103
 
3525
4104
    case VMX_EXIT_IRQ_WINDOW:           /* 7 Interrupt window. */
3526
4105
        /* Clear VM-exit on IF=1 change. */
3527
 
        LogFlow(("VMX_EXIT_IRQ_WINDOW %RGv pending=%d IF=%d\n", (RTGCPTR)pCtx->rip, VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)), pCtx->eflags.Bits.u1IF));
 
4106
        LogFlow(("VMX_EXIT_IRQ_WINDOW %RGv pending=%d IF=%d\n", (RTGCPTR)pCtx->rip,
 
4107
                 VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC)), pCtx->eflags.Bits.u1IF));
3528
4108
        pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT;
3529
4109
        rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
3530
4110
        AssertRC(rc2);
3588
4168
        break;
3589
4169
    }
3590
4170
 
3591
 
    case VMX_EXIT_INVPG:                /* 14 Guest software attempted to execute INVPG. */
 
4171
    case VMX_EXIT_RDTSCP:                /* 51 Guest software attempted to execute RDTSCP. */
 
4172
    {
 
4173
        Log2(("VMX: Rdtscp\n"));
 
4174
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitRdtscp);
 
4175
        rc = EMInterpretRdtscp(pVM, pVCpu, pCtx);
 
4176
        if (rc == VINF_SUCCESS)
 
4177
        {
 
4178
            /* Update EIP and continue execution. */
 
4179
            Assert(cbInstr == 3);
 
4180
            pCtx->rip += cbInstr;
 
4181
            goto ResumeExecution;
 
4182
        }
 
4183
        rc = VINF_EM_RAW_EMULATE_INSTR;
 
4184
        break;
 
4185
    }
 
4186
 
 
4187
    case VMX_EXIT_INVLPG:               /* 14 Guest software attempted to execute INVLPG. */
3592
4188
    {
3593
4189
        Log2(("VMX: invlpg\n"));
3594
4190
        Assert(!pVM->hwaccm.s.fNestedPaging);
3595
4191
 
3596
 
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInvpg);
 
4192
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitInvlpg);
3597
4193
        rc = EMInterpretInvlpg(pVM, pVCpu, CPUMCTX2CORE(pCtx), exitQualification);
3598
4194
        if (rc == VINF_SUCCESS)
3599
4195
        {
3646
4242
        /* no break */
3647
4243
    case VMX_EXIT_RDMSR:                /* 31 RDMSR. Guest software attempted to execute RDMSR. */
3648
4244
    {
3649
 
        uint32_t cbSize;
3650
 
 
3651
4245
        STAM_COUNTER_INC((exitReason == VMX_EXIT_RDMSR) ? &pVCpu->hwaccm.s.StatExitRdmsr : &pVCpu->hwaccm.s.StatExitWrmsr);
3652
4246
 
3653
 
        /* Note: the intel manual claims there's a REX version of RDMSR that's slightly different, so we play safe by completely disassembling the instruction. */
 
4247
        /*
 
4248
         * Note: The Intel spec. claims there's an REX version of RDMSR that's slightly different,
 
4249
         * so we play safe by completely disassembling the instruction.
 
4250
         */
3654
4251
        Log2(("VMX: %s\n", (exitReason == VMX_EXIT_RDMSR) ? "rdmsr" : "wrmsr"));
3655
 
        rc = EMInterpretInstruction(pVM, pVCpu, CPUMCTX2CORE(pCtx), 0, &cbSize);
 
4252
        rc = EMInterpretInstruction(pVCpu, CPUMCTX2CORE(pCtx), 0);
3656
4253
        if (rc == VINF_SUCCESS)
3657
4254
        {
3658
4255
            /* EIP has been updated already. */
3659
 
 
3660
4256
            /* Only resume if successful. */
3661
4257
            goto ResumeExecution;
3662
4258
        }
3663
 
        AssertMsg(rc == VERR_EM_INTERPRETER, ("EMU: %s failed with %Rrc\n", (exitReason == VMX_EXIT_RDMSR) ? "rdmsr" : "wrmsr", VBOXSTRICTRC_VAL(rc)));
 
4259
        AssertMsg(rc == VERR_EM_INTERPRETER, ("EMU: %s failed with %Rrc\n",
 
4260
                                              (exitReason == VMX_EXIT_RDMSR) ? "rdmsr" : "wrmsr", VBOXSTRICTRC_VAL(rc)));
3664
4261
        break;
3665
4262
    }
3666
4263
 
3670
4267
 
3671
4268
        switch (VMX_EXIT_QUALIFICATION_CRX_ACCESS(exitQualification))
3672
4269
        {
3673
 
        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE:
3674
 
            Log2(("VMX: %RGv mov cr%d, x\n", (RTGCPTR)pCtx->rip, VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)));
3675
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxWrite[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
3676
 
            rc = EMInterpretCRxWrite(pVM, pVCpu, CPUMCTX2CORE(pCtx),
3677
 
                                     VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification),
3678
 
                                     VMX_EXIT_QUALIFICATION_CRX_GENREG(exitQualification));
3679
 
 
3680
 
            switch (VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification))
3681
 
            {
3682
 
            case 0:
3683
 
                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0 | HWACCM_CHANGED_GUEST_CR3;
3684
 
                break;
3685
 
            case 2:
3686
 
                break;
3687
 
            case 3:
3688
 
                Assert(!pVM->hwaccm.s.fNestedPaging || !CPUMIsGuestInPagedProtectedModeEx(pCtx));
3689
 
                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR3;
3690
 
                break;
3691
 
            case 4:
3692
 
                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR4;
3693
 
                break;
3694
 
            case 8:
3695
 
                /* CR8 contains the APIC TPR */
3696
 
                Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
3697
 
                break;
3698
 
 
3699
 
            default:
3700
 
                AssertFailed();
3701
 
                break;
3702
 
            }
3703
 
            break;
3704
 
 
3705
 
        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ:
3706
 
            Log2(("VMX: mov x, crx\n"));
3707
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxRead[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
3708
 
 
3709
 
            Assert(!pVM->hwaccm.s.fNestedPaging || !CPUMIsGuestInPagedProtectedModeEx(pCtx) || VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification) != USE_REG_CR3);
3710
 
 
3711
 
            /* CR8 reads only cause an exit when the TPR shadow feature isn't present. */
3712
 
            Assert(VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification) != 8 || !(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
3713
 
 
3714
 
            rc = EMInterpretCRxRead(pVM, pVCpu, CPUMCTX2CORE(pCtx),
3715
 
                                    VMX_EXIT_QUALIFICATION_CRX_GENREG(exitQualification),
3716
 
                                    VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification));
3717
 
            break;
3718
 
 
3719
 
        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS:
3720
 
            Log2(("VMX: clts\n"));
3721
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCLTS);
3722
 
            rc = EMInterpretCLTS(pVM, pVCpu);
3723
 
            pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
3724
 
            break;
3725
 
 
3726
 
        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW:
3727
 
            Log2(("VMX: lmsw %x\n", VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(exitQualification)));
3728
 
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitLMSW);
3729
 
            rc = EMInterpretLMSW(pVM, pVCpu, CPUMCTX2CORE(pCtx), VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(exitQualification));
3730
 
            pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
3731
 
            break;
 
4270
            case VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE:
 
4271
            {
 
4272
                Log2(("VMX: %RGv mov cr%d, x\n", (RTGCPTR)pCtx->rip, VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)));
 
4273
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxWrite[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
 
4274
                rc = EMInterpretCRxWrite(pVM, pVCpu, CPUMCTX2CORE(pCtx),
 
4275
                                         VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification),
 
4276
                                         VMX_EXIT_QUALIFICATION_CRX_GENREG(exitQualification));
 
4277
                switch (VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification))
 
4278
                {
 
4279
                    case 0:
 
4280
                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0 | HWACCM_CHANGED_GUEST_CR3;
 
4281
                        break;
 
4282
                    case 2:
 
4283
                        break;
 
4284
                    case 3:
 
4285
                        Assert(!pVM->hwaccm.s.fNestedPaging || !CPUMIsGuestInPagedProtectedModeEx(pCtx));
 
4286
                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR3;
 
4287
                        break;
 
4288
                    case 4:
 
4289
                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR4;
 
4290
                        break;
 
4291
                    case 8:
 
4292
                        /* CR8 contains the APIC TPR */
 
4293
                        Assert(!(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1
 
4294
                                 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
 
4295
                        break;
 
4296
 
 
4297
                    default:
 
4298
                        AssertFailed();
 
4299
                        break;
 
4300
                }
 
4301
                break;
 
4302
            }
 
4303
 
 
4304
            case VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ:
 
4305
            {
 
4306
                Log2(("VMX: mov x, crx\n"));
 
4307
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCRxRead[VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification)]);
 
4308
 
 
4309
                Assert(   !pVM->hwaccm.s.fNestedPaging
 
4310
                       || !CPUMIsGuestInPagedProtectedModeEx(pCtx)
 
4311
                       || VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification) != DISCREG_CR3);
 
4312
 
 
4313
                /* CR8 reads only cause an exit when the TPR shadow feature isn't present. */
 
4314
                Assert(   VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification) != 8
 
4315
                       || !(pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW));
 
4316
 
 
4317
                rc = EMInterpretCRxRead(pVM, pVCpu, CPUMCTX2CORE(pCtx),
 
4318
                                        VMX_EXIT_QUALIFICATION_CRX_GENREG(exitQualification),
 
4319
                                        VMX_EXIT_QUALIFICATION_CRX_REGISTER(exitQualification));
 
4320
                break;
 
4321
            }
 
4322
 
 
4323
            case VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS:
 
4324
            {
 
4325
                Log2(("VMX: clts\n"));
 
4326
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitCLTS);
 
4327
                rc = EMInterpretCLTS(pVM, pVCpu);
 
4328
                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
 
4329
                break;
 
4330
            }
 
4331
 
 
4332
            case VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW:
 
4333
            {
 
4334
                Log2(("VMX: lmsw %x\n", VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(exitQualification)));
 
4335
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitLMSW);
 
4336
                rc = EMInterpretLMSW(pVM, pVCpu, CPUMCTX2CORE(pCtx), VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(exitQualification));
 
4337
                pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_GUEST_CR0;
 
4338
                break;
 
4339
            }
3732
4340
        }
3733
4341
 
3734
4342
        /* Update EIP if no error occurred. */
3751
4359
        if (    !DBGFIsStepping(pVCpu)
3752
4360
            &&  !CPUMIsHyperDebugStateActive(pVCpu))
3753
4361
        {
3754
 
            /* Disable drx move intercepts. */
 
4362
            /* Disable DRx move intercepts. */
3755
4363
            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
3756
4364
            rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
3757
4365
            AssertRC(rc2);
3762
4370
 
3763
4371
#ifdef LOG_ENABLED
3764
4372
            if (VMX_EXIT_QUALIFICATION_DRX_DIRECTION(exitQualification) == VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE)
3765
 
                Log(("VMX_EXIT_DRX_MOVE: write DR%d genreg %d\n", VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification), VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification)));
 
4373
            {
 
4374
                Log(("VMX_EXIT_DRX_MOVE: write DR%d genreg %d\n", VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification),
 
4375
                     VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification)));
 
4376
            }
3766
4377
            else
3767
4378
                Log(("VMX_EXIT_DRX_MOVE: read DR%d\n", VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification)));
3768
4379
#endif
3778
4389
            goto ResumeExecution;
3779
4390
        }
3780
4391
 
3781
 
        /** @todo clear VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT after the first time and restore drx registers afterwards */
 
4392
        /** @todo clear VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT after the first
 
4393
         *        time and restore DRx registers afterwards */
3782
4394
        if (VMX_EXIT_QUALIFICATION_DRX_DIRECTION(exitQualification) == VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE)
3783
4395
        {
3784
 
            Log2(("VMX: mov drx%d, genreg%d\n", VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification), VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification)));
 
4396
            Log2(("VMX: mov DRx%d, genreg%d\n", VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification),
 
4397
                  VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification)));
3785
4398
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxWrite);
3786
4399
            rc = EMInterpretDRxWrite(pVM, pVCpu, CPUMCTX2CORE(pCtx),
3787
4400
                                     VMX_EXIT_QUALIFICATION_DRX_REGISTER(exitQualification),
3791
4404
        }
3792
4405
        else
3793
4406
        {
3794
 
            Log2(("VMX: mov x, drx\n"));
 
4407
            Log2(("VMX: mov x, DRx\n"));
3795
4408
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitDRxRead);
3796
4409
            rc = EMInterpretDRxRead(pVM, pVCpu, CPUMCTX2CORE(pCtx),
3797
4410
                                    VMX_EXIT_QUALIFICATION_DRX_GENREG(exitQualification),
3814
4427
    case VMX_EXIT_PORT_IO:              /* 30 I/O instruction. */
3815
4428
    {
3816
4429
        STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
 
4430
        uint32_t uPort;
3817
4431
        uint32_t uIOWidth = VMX_EXIT_QUALIFICATION_IO_WIDTH(exitQualification);
3818
 
        uint32_t uPort;
3819
4432
        bool     fIOWrite = (VMX_EXIT_QUALIFICATION_IO_DIRECTION(exitQualification) == VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT);
3820
4433
 
3821
4434
        /** @todo necessary to make the distinction? */
3822
4435
        if (VMX_EXIT_QUALIFICATION_IO_ENCODING(exitQualification) == VMX_EXIT_QUALIFICATION_IO_ENCODING_DX)
3823
 
        {
3824
4436
            uPort = pCtx->edx & 0xffff;
3825
 
        }
3826
4437
        else
3827
4438
            uPort = VMX_EXIT_QUALIFICATION_IO_PORT(exitQualification);  /* Immediate encoding. */
3828
4439
 
3829
 
        /* paranoia */
3830
 
        if (RT_UNLIKELY(uIOWidth == 2 || uIOWidth >= 4))
 
4440
        if (RT_UNLIKELY(uIOWidth == 2 || uIOWidth >= 4))         /* paranoia */
3831
4441
        {
3832
 
            rc = fIOWrite ? VINF_IOM_HC_IOPORT_WRITE : VINF_IOM_HC_IOPORT_READ;
 
4442
            rc = fIOWrite ? VINF_IOM_R3_IOPORT_WRITE : VINF_IOM_R3_IOPORT_READ;
3833
4443
            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
3834
4444
            break;
3835
4445
        }
3836
4446
 
3837
4447
        uint32_t cbSize = g_aIOSize[uIOWidth];
3838
 
 
3839
4448
        if (VMX_EXIT_QUALIFICATION_IO_STRING(exitQualification))
3840
4449
        {
3841
4450
            /* ins/outs */
3844
4453
            /* Disassemble manually to deal with segment prefixes. */
3845
4454
            /** @todo VMX_VMCS_EXIT_GUEST_LINEAR_ADDR contains the flat pointer operand of the instruction. */
3846
4455
            /** @todo VMX_VMCS32_RO_EXIT_INSTR_INFO also contains segment prefix info. */
3847
 
            rc2 = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), pDis, NULL);
 
4456
            rc2 = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
3848
4457
            if (RT_SUCCESS(rc))
3849
4458
            {
3850
4459
                if (fIOWrite)
3851
4460
                {
3852
4461
                    Log2(("IOMInterpretOUTSEx %RGv %x size=%d\n", (RTGCPTR)pCtx->rip, uPort, cbSize));
3853
4462
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOStringWrite);
3854
 
                    rc = IOMInterpretOUTSEx(pVM, CPUMCTX2CORE(pCtx), uPort, pDis->prefix, pDis->addrmode, cbSize);
 
4463
                    rc = IOMInterpretOUTSEx(pVM, CPUMCTX2CORE(pCtx), uPort, pDis->fPrefix, (DISCPUMODE)pDis->uAddrMode, cbSize);
3855
4464
                }
3856
4465
                else
3857
4466
                {
3858
4467
                    Log2(("IOMInterpretINSEx  %RGv %x size=%d\n", (RTGCPTR)pCtx->rip, uPort, cbSize));
3859
4468
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOStringRead);
3860
 
                    rc = IOMInterpretINSEx(pVM, CPUMCTX2CORE(pCtx), uPort, pDis->prefix, pDis->addrmode, cbSize);
 
4469
                    rc = IOMInterpretINSEx(pVM, CPUMCTX2CORE(pCtx), uPort, pDis->fPrefix, (DISCPUMODE)pDis->uAddrMode, cbSize);
3861
4470
                }
3862
4471
            }
3863
4472
            else
3865
4474
        }
3866
4475
        else
3867
4476
        {
3868
 
            /* normal in/out */
 
4477
            /* Normal in/out */
3869
4478
            uint32_t uAndVal = g_aIOOpAnd[uIOWidth];
3870
4479
 
3871
4480
            Assert(!VMX_EXIT_QUALIFICATION_IO_REP(exitQualification));
3874
4483
            {
3875
4484
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOWrite);
3876
4485
                rc = IOMIOPortWrite(pVM, uPort, pCtx->eax & uAndVal, cbSize);
3877
 
                if (rc == VINF_IOM_HC_IOPORT_WRITE)
 
4486
                if (rc == VINF_IOM_R3_IOPORT_WRITE)
3878
4487
                    HWACCMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
3879
4488
            }
3880
4489
            else
3889
4498
                    pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);
3890
4499
                }
3891
4500
                else
3892
 
                if (rc == VINF_IOM_HC_IOPORT_READ)
 
4501
                if (rc == VINF_IOM_R3_IOPORT_READ)
3893
4502
                    HWACCMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
3894
4503
            }
3895
4504
        }
 
4505
 
3896
4506
        /*
3897
4507
         * Handled the I/O return codes.
3898
4508
         * (The unhandled cases end up with rc == VINF_EM_RAW_EMULATE_INSTR.)
3907
4517
                if (pCtx->dr[7] & X86_DR7_ENABLED_MASK)
3908
4518
                {
3909
4519
                    STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatDRxIOCheck);
3910
 
                    for (unsigned i=0;i<4;i++)
 
4520
                    for (unsigned i = 0; i < 4; i++)
3911
4521
                    {
3912
4522
                        unsigned uBPLen = g_aIOSize[X86_DR7_GET_LEN(pCtx->dr[7], i)];
3913
4523
 
3925
4535
                            uDR6 &= ~(X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3);
3926
4536
                            uDR6 |= (uint64_t)RT_BIT(i);
3927
4537
 
3928
 
                            /* Note: AMD64 Architecture Programmer's Manual 13.1:
3929
 
                             * Bits 15:13 of the DR6 register is never cleared by the processor and must be cleared by software after
3930
 
                             * the contents have been read.
 
4538
                            /*
 
4539
                             * Note: AMD64 Architecture Programmer's Manual 13.1:
 
4540
                             * Bits 15:13 of the DR6 register is never cleared by the processor and must
 
4541
                             * be cleared by software after the contents have been read.
3931
4542
                             */
3932
4543
                            ASMSetDR6(uDR6);
3933
4544
 
3934
 
                            /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */
 
4545
                            /* X86_DR7_GD will be cleared if DRx accesses should be trapped inside the guest. */
3935
4546
                            pCtx->dr[7] &= ~X86_DR7_GD;
3936
4547
 
3937
4548
                            /* Paranoia. */
3949
4560
                            intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
3950
4561
 
3951
4562
                            Log(("Inject IO debug trap at %RGv\n", (RTGCPTR)pCtx->rip));
3952
 
                            rc2 = VMXR0InjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo), 0, 0);
 
4563
                            rc2 = hmR0VmxInjectEvent(pVM, pVCpu, pCtx, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(intInfo),
 
4564
                                                     0 /* cbInstr */, 0 /* errCode */);
3953
4565
                            AssertRC(rc2);
3954
4566
 
3955
4567
                            STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
3965
4577
        }
3966
4578
 
3967
4579
#ifdef VBOX_STRICT
3968
 
        if (rc == VINF_IOM_HC_IOPORT_READ)
 
4580
        if (rc == VINF_IOM_R3_IOPORT_READ)
3969
4581
            Assert(!fIOWrite);
3970
 
        else if (rc == VINF_IOM_HC_IOPORT_WRITE)
 
4582
        else if (rc == VINF_IOM_R3_IOPORT_WRITE)
3971
4583
            Assert(fIOWrite);
3972
4584
        else
3973
 
            AssertMsg(RT_FAILURE(rc) || rc == VINF_EM_RAW_EMULATE_INSTR || rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_TRPM_XCPT_DISPATCHED, ("%Rrc\n", VBOXSTRICTRC_VAL(rc)));
 
4585
        {
 
4586
            AssertMsg(   RT_FAILURE(rc)
 
4587
                      || rc == VINF_EM_RAW_EMULATE_INSTR
 
4588
                      || rc == VINF_EM_RAW_GUEST_TRAP
 
4589
                      || rc == VINF_TRPM_XCPT_DISPATCHED, ("%Rrc\n", VBOXSTRICTRC_VAL(rc)));
 
4590
        }
3974
4591
#endif
3975
4592
        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1);
3976
4593
        break;
3981
4598
        /* RIP is already set to the next instruction and the TPR has been synced back. Just resume. */
3982
4599
        goto ResumeExecution;
3983
4600
 
3984
 
    case VMX_EXIT_APIC_ACCESS:          /* 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
 
4601
    case VMX_EXIT_APIC_ACCESS:          /* 44 APIC access. Guest software attempted to access memory at a physical address
 
4602
                                                            on the APIC-access page. */
3985
4603
    {
3986
4604
        LogFlow(("VMX_EXIT_APIC_ACCESS\n"));
3987
4605
        unsigned uAccessType = VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(exitQualification);
3988
4606
 
3989
 
        switch(uAccessType)
3990
 
        {
3991
 
        case VMX_APIC_ACCESS_TYPE_LINEAR_READ:
3992
 
        case VMX_APIC_ACCESS_TYPE_LINEAR_WRITE:
3993
 
        {
3994
 
            RTGCPHYS GCPhys;
3995
 
            PDMApicGetBase(pVM, &GCPhys);
3996
 
            GCPhys &= PAGE_BASE_GC_MASK;
3997
 
            GCPhys += VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(exitQualification);
3998
 
 
3999
 
            LogFlow(("Apic access at %RGp\n", GCPhys));
4000
 
            rc = IOMMMIOPhysHandler(pVM, (uAccessType == VMX_APIC_ACCESS_TYPE_LINEAR_READ) ? 0 : X86_TRAP_PF_RW, CPUMCTX2CORE(pCtx), GCPhys);
4001
 
            if (rc == VINF_SUCCESS)
4002
 
                goto ResumeExecution;   /* rip already updated */
4003
 
            break;
4004
 
        }
4005
 
 
4006
 
        default:
4007
 
            rc = VINF_EM_RAW_EMULATE_INSTR;
4008
 
            break;
 
4607
        switch (uAccessType)
 
4608
        {
 
4609
            case VMX_APIC_ACCESS_TYPE_LINEAR_READ:
 
4610
            case VMX_APIC_ACCESS_TYPE_LINEAR_WRITE:
 
4611
            {
 
4612
                RTGCPHYS GCPhys;
 
4613
                PDMApicGetBase(pVM, &GCPhys);
 
4614
                GCPhys &= PAGE_BASE_GC_MASK;
 
4615
                GCPhys += VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(exitQualification);
 
4616
 
 
4617
                LogFlow(("Apic access at %RGp\n", GCPhys));
 
4618
                rc = IOMMMIOPhysHandler(pVM, (uAccessType == VMX_APIC_ACCESS_TYPE_LINEAR_READ) ? 0 : X86_TRAP_PF_RW,
 
4619
                                        CPUMCTX2CORE(pCtx), GCPhys);
 
4620
                if (rc == VINF_SUCCESS)
 
4621
                    goto ResumeExecution;   /* rip already updated */
 
4622
                break;
 
4623
            }
 
4624
 
 
4625
            default:
 
4626
                rc = VINF_EM_RAW_EMULATE_INSTR;
 
4627
                break;
4009
4628
        }
4010
4629
        break;
4011
4630
    }
4021
4640
        break;
4022
4641
    }
4023
4642
 
4024
 
    /* Note: the guest state isn't entirely synced back at this stage. */
 
4643
 
 
4644
    /*
 
4645
     * Note: The guest state is not entirely synced back at this stage!
 
4646
     */
4025
4647
 
4026
4648
    /* Investigate why there was a VM-exit. (part 2) */
4027
4649
    switch (exitReason)
4068
4690
        break;
4069
4691
 
4070
4692
    case VMX_EXIT_HLT:                  /* 12 Guest software attempted to execute HLT. */
4071
 
        /** Check if external interrupts are pending; if so, don't switch back. */
 
4693
        /* Check if external interrupts are pending; if so, don't switch back. */
4072
4694
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitHlt);
4073
4695
        pCtx->rip++;    /* skip hlt */
4074
4696
        if (EMShouldContinueAfterHalt(pVCpu, pCtx))
4087
4709
            /* Update EIP and continue execution. */
4088
4710
            pCtx->rip += cbInstr;
4089
4711
 
4090
 
            /** Check if external interrupts are pending; if so, don't switch back. */
 
4712
            /* Check if external interrupts are pending; if so, don't switch back. */
4091
4713
            if (    rc == VINF_SUCCESS
4092
4714
                ||  (   rc == VINF_EM_HALT
4093
4715
                     && EMShouldContinueAfterHalt(pVCpu, pCtx))
4102
4724
        rc = VERR_EM_INTERPRETER;
4103
4725
        break;
4104
4726
 
 
4727
    case VMX_EXIT_MTF:                  /* 37 Exit due to Monitor Trap Flag. */
 
4728
        LogFlow(("VMX_EXIT_MTF at %RGv\n", (RTGCPTR)pCtx->rip));
 
4729
        pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG;
 
4730
        rc2 = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
 
4731
        AssertRC(rc2);
 
4732
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitMTF);
 
4733
#if 0
 
4734
        DBGFDoneStepping(pVCpu);
 
4735
#endif
 
4736
        rc = VINF_EM_DBG_STOP;
 
4737
        break;
 
4738
 
4105
4739
    case VMX_EXIT_VMCALL:               /* 18 Guest software executed VMCALL. */
4106
4740
    case VMX_EXIT_VMCLEAR:              /* 19 Guest software executed VMCLEAR. */
4107
4741
    case VMX_EXIT_VMLAUNCH:             /* 20 Guest software executed VMLAUNCH. */
4118
4752
 
4119
4753
    case VMX_EXIT_CPUID:                /* 10 Guest software attempted to execute CPUID. */
4120
4754
    case VMX_EXIT_RDTSC:                /* 16 Guest software attempted to execute RDTSC. */
4121
 
    case VMX_EXIT_INVPG:                /* 14 Guest software attempted to execute INVPG. */
 
4755
    case VMX_EXIT_INVLPG:               /* 14 Guest software attempted to execute INVLPG. */
4122
4756
    case VMX_EXIT_CRX_MOVE:             /* 28 Control-register accesses. */
4123
4757
    case VMX_EXIT_DRX_MOVE:             /* 29 Debug-register accesses. */
4124
4758
    case VMX_EXIT_PORT_IO:              /* 30 I/O instruction. */
4125
4759
    case VMX_EXIT_RDPMC:                /* 15 Guest software attempted to execute RDPMC. */
 
4760
    case VMX_EXIT_RDTSCP:               /* 51 Guest software attempted to execute RDTSCP. */
4126
4761
        /* already handled above */
4127
4762
        AssertMsg(   rc == VINF_PGM_CHANGE_MODE
4128
4763
                  || rc == VINF_EM_RAW_INTERRUPT
4129
4764
                  || rc == VERR_EM_INTERPRETER
4130
4765
                  || rc == VINF_EM_RAW_EMULATE_INSTR
4131
4766
                  || rc == VINF_PGM_SYNC_CR3
4132
 
                  || rc == VINF_IOM_HC_IOPORT_READ
4133
 
                  || rc == VINF_IOM_HC_IOPORT_WRITE
 
4767
                  || rc == VINF_IOM_R3_IOPORT_READ
 
4768
                  || rc == VINF_IOM_R3_IOPORT_WRITE
4134
4769
                  || rc == VINF_EM_RAW_GUEST_TRAP
4135
4770
                  || rc == VINF_TRPM_XCPT_DISPATCHED
4136
4771
                  || rc == VINF_EM_RESCHEDULE_REM,
4138
4773
        break;
4139
4774
 
4140
4775
    case VMX_EXIT_TPR:                  /* 43 TPR below threshold. Guest software executed MOV to CR8. */
4141
 
    case VMX_EXIT_APIC_ACCESS:          /* 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
4142
4776
    case VMX_EXIT_RDMSR:                /* 31 RDMSR. Guest software attempted to execute RDMSR. */
4143
4777
    case VMX_EXIT_WRMSR:                /* 32 WRMSR. Guest software attempted to execute WRMSR. */
4144
4778
    case VMX_EXIT_PAUSE:                /* 40 Guest software attempted to execute PAUSE. */
4145
4779
    case VMX_EXIT_MONITOR:              /* 39 Guest software attempted to execute MONITOR. */
4146
 
        /* Note: If we decide to emulate them here, then we must sync the MSRs that could have been changed (sysenter, fs/gs base)!!! */
 
4780
    case VMX_EXIT_APIC_ACCESS:          /* 44 APIC access. Guest software attempted to access memory at a physical address
 
4781
                                                        on the APIC-access page. */
 
4782
    {
 
4783
        /*
 
4784
         * If we decided to emulate them here, then we must sync the MSRs that could have been changed (sysenter, FS/GS base)
 
4785
         */
4147
4786
        rc = VERR_EM_INTERPRETER;
4148
4787
        break;
 
4788
    }
4149
4789
 
4150
4790
    case VMX_EXIT_IRQ_WINDOW:           /* 7 Interrupt window. */
4151
4791
        Assert(rc == VINF_EM_RAW_INTERRUPT);
4173
4813
        VMXReadVMCS(VMX_VMCS_GUEST_RFLAGS, &val2);
4174
4814
        Log(("VMX_VMCS_GUEST_RFLAGS     %08x\n", val2));
4175
4815
 
4176
 
        VMX_LOG_SELREG(CS, "CS", val2);
4177
 
        VMX_LOG_SELREG(DS, "DS", val2);
4178
 
        VMX_LOG_SELREG(ES, "ES", val2);
4179
 
        VMX_LOG_SELREG(FS, "FS", val2);
4180
 
        VMX_LOG_SELREG(GS, "GS", val2);
4181
 
        VMX_LOG_SELREG(SS, "SS", val2);
4182
 
        VMX_LOG_SELREG(TR, "TR", val2);
 
4816
        VMX_LOG_SELREG(CS,   "CS",   val2);
 
4817
        VMX_LOG_SELREG(DS,   "DS",   val2);
 
4818
        VMX_LOG_SELREG(ES,   "ES",   val2);
 
4819
        VMX_LOG_SELREG(FS,   "FS",   val2);
 
4820
        VMX_LOG_SELREG(GS,   "GS",   val2);
 
4821
        VMX_LOG_SELREG(SS,   "SS",   val2);
 
4822
        VMX_LOG_SELREG(TR,   "TR",   val2);
4183
4823
        VMX_LOG_SELREG(LDTR, "LDTR", val2);
4184
4824
 
4185
4825
        VMXReadVMCS(VMX_VMCS64_GUEST_GDTR_BASE, &val2);
4199
4839
        break;
4200
4840
 
4201
4841
    }
 
4842
 
4202
4843
end:
4203
 
 
4204
4844
    /* We now going back to ring-3, so clear the action flag. */
4205
4845
    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
4206
4846
 
4207
 
    /* Signal changes for the recompiler. */
4208
 
    CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_SYSENTER_MSR | CPUM_CHANGED_LDTR | CPUM_CHANGED_GDTR | CPUM_CHANGED_IDTR | CPUM_CHANGED_TR | CPUM_CHANGED_HIDDEN_SEL_REGS);
 
4847
    /*
 
4848
     * Signal changes for the recompiler.
 
4849
     */
 
4850
    CPUMSetChangedFlags(pVCpu,
 
4851
                          CPUM_CHANGED_SYSENTER_MSR
 
4852
                        | CPUM_CHANGED_LDTR
 
4853
                        | CPUM_CHANGED_GDTR
 
4854
                        | CPUM_CHANGED_IDTR
 
4855
                        | CPUM_CHANGED_TR
 
4856
                        | CPUM_CHANGED_HIDDEN_SEL_REGS);
4209
4857
 
4210
 
    /* If we executed vmlaunch/vmresume and an external irq was pending, then we don't have to do a full sync the next time. */
 
4858
    /*
 
4859
     * If we executed vmlaunch/vmresume and an external IRQ was pending, then we don't have to do a full sync the next time.
 
4860
     */
4211
4861
    if (    exitReason == VMX_EXIT_EXTERNAL_IRQ
4212
4862
        &&  !VMX_EXIT_INTERRUPTION_INFO_VALID(intInfo))
4213
4863
    {
4223
4873
        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
4224
4874
    }
4225
4875
 
4226
 
    /* translate into a less severe return code */
 
4876
    /* Translate into a less severe return code */
4227
4877
    if (rc == VERR_EM_INTERPRETER)
4228
4878
        rc = VINF_EM_RAW_EMULATE_INSTR;
4229
 
    else
4230
 
    /* Try to extract more information about what might have gone wrong here. */
4231
 
    if (rc == VERR_VMX_INVALID_VMCS_PTR)
 
4879
    else if (rc == VERR_VMX_INVALID_VMCS_PTR)
4232
4880
    {
 
4881
        /* Try to extract more information about what might have gone wrong here. */
4233
4882
        VMXGetActivateVMCS(&pVCpu->hwaccm.s.vmx.lasterror.u64VMCSPhys);
4234
4883
        pVCpu->hwaccm.s.vmx.lasterror.ulVMCSRevision = *(uint32_t *)pVCpu->hwaccm.s.vmx.pvVMCS;
4235
4884
        pVCpu->hwaccm.s.vmx.lasterror.idEnteredCpu   = pVCpu->hwaccm.s.idEnteredCpu;
4240
4889
    VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC);
4241
4890
 
4242
4891
#ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION
4243
 
    /* Restore interrupts if we exitted after disabling them. */
 
4892
    /* Restore interrupts if we exited after disabling them. */
4244
4893
    if (uOldEFlags != ~(RTCCUINTREG)0)
4245
4894
        ASMSetFlags(uOldEFlags);
4246
4895
#endif
4254
4903
 
4255
4904
 
4256
4905
/**
4257
 
 * Enters the VT-x session
 
4906
 * Enters the VT-x session.
4258
4907
 *
4259
4908
 * @returns VBox status code.
4260
 
 * @param   pVM         The VM to operate on.
4261
 
 * @param   pVCpu       The VMCPU to operate on.
4262
 
 * @param   pCpu        CPU info struct
 
4909
 * @param   pVM         Pointer to the VM.
 
4910
 * @param   pVCpu       Pointer to the VMCPU.
 
4911
 * @param   pCpu        Pointer to the CPU info struct.
4263
4912
 */
4264
4913
VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHMGLOBLCPUINFO pCpu)
4265
4914
{
4266
4915
    Assert(pVM->hwaccm.s.vmx.fSupported);
 
4916
    NOREF(pCpu);
4267
4917
 
4268
4918
    unsigned cr4 = ASMGetCR4();
4269
4919
    if (!(cr4 & X86_CR4_VMXE))
4272
4922
        return VERR_VMX_X86_CR4_VMXE_CLEARED;
4273
4923
    }
4274
4924
 
4275
 
    /* Activate the VM Control Structure. */
 
4925
    /* Activate the VMCS. */
4276
4926
    int rc = VMXActivateVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
4277
4927
    if (RT_FAILURE(rc))
4278
4928
        return rc;
4283
4933
 
4284
4934
 
4285
4935
/**
4286
 
 * Leaves the VT-x session
 
4936
 * Leaves the VT-x session.
4287
4937
 *
4288
4938
 * @returns VBox status code.
4289
 
 * @param   pVM         The VM to operate on.
4290
 
 * @param   pVCpu       The VMCPU to operate on.
4291
 
 * @param   pCtx        CPU context
 
4939
 * @param   pVM         Pointer to the VM.
 
4940
 * @param   pVCpu       Pointer to the VMCPU.
 
4941
 * @param   pCtx        Pointer to the guests CPU context.
4292
4942
 */
4293
4943
VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
4294
4944
{
4302
4952
    }
4303
4953
    else
4304
4954
#endif
4305
 
    /* Save the guest debug state if necessary. */
 
4955
 
 
4956
    /*
 
4957
     * Save the guest debug state if necessary.
 
4958
     */
4306
4959
    if (CPUMIsGuestDebugStateActive(pVCpu))
4307
4960
    {
4308
4961
        CPUMR0SaveGuestDebugState(pVM, pVCpu, pCtx, true /* save DR6 */);
4309
4962
 
4310
 
        /* Enable drx move intercepts again. */
 
4963
        /* Enable DRx move intercepts again. */
4311
4964
        pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
4312
4965
        int rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
4313
4966
        AssertRC(rc);
4318
4971
    else
4319
4972
        Assert(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT);
4320
4973
 
4321
 
    /* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */
 
4974
    /*
 
4975
     * Clear VMCS, marking it inactive, clearing implementation-specific data and writing
 
4976
     * VMCS data back to memory.
 
4977
     */
4322
4978
    int rc = VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
4323
4979
    AssertRC(rc);
4324
4980
 
4325
4981
    return VINF_SUCCESS;
4326
4982
}
4327
4983
 
 
4984
 
4328
4985
/**
4329
 
 * Flush the TLB (EPT)
 
4986
 * Flush the TLB using EPT.
4330
4987
 *
4331
4988
 * @returns VBox status code.
4332
 
 * @param   pVM         The VM to operate on.
4333
 
 * @param   pVCpu       The VM CPU to operate on.
4334
 
 * @param   enmFlush    Type of flush
4335
 
 * @param   GCPhys      Physical address of the page to flush
 
4989
 * @param   pVM         Pointer to the VM.
 
4990
 * @param   pVCpu       Pointer to the VMCPU.
 
4991
 * @param   enmFlush    Type of flush.
4336
4992
 */
4337
 
static void vmxR0FlushEPT(PVM pVM, PVMCPU pVCpu, VMX_FLUSH enmFlush, RTGCPHYS GCPhys)
 
4993
static void hmR0VmxFlushEPT(PVM pVM, PVMCPU pVCpu, VMX_FLUSH_EPT enmFlush)
4338
4994
{
4339
4995
    uint64_t descriptor[2];
4340
4996
 
4341
 
    LogFlow(("vmxR0FlushEPT %d %RGv\n", enmFlush, GCPhys));
 
4997
    LogFlow(("hmR0VmxFlushEPT %d\n", enmFlush));
4342
4998
    Assert(pVM->hwaccm.s.fNestedPaging);
4343
4999
    descriptor[0] = pVCpu->hwaccm.s.vmx.GCPhysEPTP;
4344
 
    descriptor[1] = GCPhys;
 
5000
    descriptor[1] = 0; /* MBZ. Intel spec. 33.3 VMX Instructions */
4345
5001
    int rc = VMXR0InvEPT(enmFlush, &descriptor[0]);
4346
 
    AssertRC(rc);
 
5002
    AssertMsg(rc == VINF_SUCCESS, ("VMXR0InvEPT %x %RGv failed with %d\n", enmFlush, pVCpu->hwaccm.s.vmx.GCPhysEPTP, rc));
4347
5003
}
4348
5004
 
4349
 
#ifdef HWACCM_VTX_WITH_VPID
 
5005
 
4350
5006
/**
4351
 
 * Flush the TLB (EPT)
 
5007
 * Flush the TLB using VPID.
4352
5008
 *
4353
5009
 * @returns VBox status code.
4354
 
 * @param   pVM         The VM to operate on.
4355
 
 * @param   pVCpu       The VM CPU to operate on.
4356
 
 * @param   enmFlush    Type of flush
4357
 
 * @param   GCPtr       Virtual address of the page to flush
 
5010
 * @param   pVM         Pointer to the VM.
 
5011
 * @param   pVCpu       Pointer to the VMCPU (can be NULL depending on @a
 
5012
 *                      enmFlush).
 
5013
 * @param   enmFlush    Type of flush.
 
5014
 * @param   GCPtr       Virtual address of the page to flush (can be 0 depending
 
5015
 *                      on @a enmFlush).
4358
5016
 */
4359
 
static void vmxR0FlushVPID(PVM pVM, PVMCPU pVCpu, VMX_FLUSH enmFlush, RTGCPTR GCPtr)
 
5017
static void hmR0VmxFlushVPID(PVM pVM, PVMCPU pVCpu, VMX_FLUSH_VPID enmFlush, RTGCPTR GCPtr)
4360
5018
{
4361
 
#if HC_ARCH_BITS == 32
4362
 
    /* If we get a flush in 64 bits guest mode, then force a full TLB flush. Invvpid probably takes only 32 bits addresses. (@todo) */
4363
 
    if (   CPUMIsGuestInLongMode(pVCpu)
4364
 
        && !VMX_IS_64BIT_HOST_MODE())
 
5019
    uint64_t descriptor[2];
 
5020
 
 
5021
    Assert(pVM->hwaccm.s.vmx.fVPID);
 
5022
    if (enmFlush == VMX_FLUSH_VPID_ALL_CONTEXTS)
4365
5023
    {
4366
 
        VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
 
5024
        descriptor[0] = 0;
 
5025
        descriptor[1] = 0;
4367
5026
    }
4368
5027
    else
4369
 
#endif
4370
5028
    {
4371
 
        uint64_t descriptor[2];
4372
 
 
4373
 
        Assert(pVM->hwaccm.s.vmx.fVPID);
 
5029
        AssertPtr(pVCpu);
 
5030
        AssertMsg(pVCpu->hwaccm.s.uCurrentASID != 0, ("VMXR0InvVPID invalid ASID %lu\n", pVCpu->hwaccm.s.uCurrentASID));
 
5031
        AssertMsg(pVCpu->hwaccm.s.uCurrentASID <= UINT16_MAX, ("VMXR0InvVPID invalid ASID %lu\n", pVCpu->hwaccm.s.uCurrentASID));
4374
5032
        descriptor[0] = pVCpu->hwaccm.s.uCurrentASID;
4375
5033
        descriptor[1] = GCPtr;
4376
 
        int rc = VMXR0InvVPID(enmFlush, &descriptor[0]);
4377
 
        AssertMsg(rc == VINF_SUCCESS, ("VMXR0InvVPID %x %x %RGv failed with %d\n", enmFlush, pVCpu->hwaccm.s.uCurrentASID, GCPtr, rc));
4378
5034
    }
 
5035
    int rc = VMXR0InvVPID(enmFlush, &descriptor[0]); NOREF(rc);
 
5036
    AssertMsg(rc == VINF_SUCCESS,
 
5037
              ("VMXR0InvVPID %x %x %RGv failed with %d\n", enmFlush, pVCpu ? pVCpu->hwaccm.s.uCurrentASID : 0, GCPtr, rc));
4379
5038
}
4380
 
#endif /* HWACCM_VTX_WITH_VPID */
 
5039
 
4381
5040
 
4382
5041
/**
4383
 
 * Invalidates a guest page
 
5042
 * Invalidates a guest page by guest virtual address. Only relevant for
 
5043
 * EPT/VPID, otherwise there is nothing really to invalidate.
4384
5044
 *
4385
5045
 * @returns VBox status code.
4386
 
 * @param   pVM         The VM to operate on.
4387
 
 * @param   pVCpu       The VM CPU to operate on.
4388
 
 * @param   GCVirt      Page to invalidate
 
5046
 * @param   pVM         Pointer to the VM.
 
5047
 * @param   pVCpu       Pointer to the VMCPU.
 
5048
 * @param   GCVirt      Guest virtual address of the page to invalidate.
4389
5049
 */
4390
5050
VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt)
4391
5051
{
4393
5053
 
4394
5054
    Log2(("VMXR0InvalidatePage %RGv\n", GCVirt));
4395
5055
 
4396
 
    /* Only relevant if we want to use VPID as otherwise every VMX transition
4397
 
     * will flush the TLBs and paging-structure caches.
4398
 
     * In the nested paging case we still see such calls, but
4399
 
     * can safely ignore them. (e.g. after cr3 updates)
4400
 
     */
4401
 
#ifdef HWACCM_VTX_WITH_VPID
4402
 
    /* Skip it if a TLB flush is already pending. */
4403
 
    if (   !fFlushPending
4404
 
        && pVM->hwaccm.s.vmx.fVPID)
4405
 
        vmxR0FlushVPID(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushPage, GCVirt);
4406
 
#endif /* HWACCM_VTX_WITH_VPID */
 
5056
    if (!fFlushPending)
 
5057
    {
 
5058
        /*
 
5059
         * We must invalidate the guest TLB entry in either case, we cannot ignore it even for the EPT case
 
5060
         * See @bugref{6043} and @bugref{6177}
 
5061
         *
 
5062
         * Set the VMCPU_FF_TLB_FLUSH force flag and flush before VMENTRY in hmR0VmxSetupTLB*() as this
 
5063
         * function maybe called in a loop with individual addresses.
 
5064
         */
 
5065
        if (pVM->hwaccm.s.vmx.fVPID)
 
5066
        {
 
5067
            /* If we can flush just this page do it, otherwise flush as little as possible. */
 
5068
            if (pVM->hwaccm.s.vmx.msr.vmx_eptcaps & MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV_ADDR)
 
5069
                hmR0VmxFlushVPID(pVM, pVCpu, VMX_FLUSH_VPID_INDIV_ADDR, GCVirt);
 
5070
            else
 
5071
                VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
 
5072
        }
 
5073
        else if (pVM->hwaccm.s.fNestedPaging)
 
5074
            VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
 
5075
    }
4407
5076
 
4408
5077
    return VINF_SUCCESS;
4409
5078
}
4410
5079
 
 
5080
 
4411
5081
/**
4412
 
 * Invalidates a guest page by physical address
 
5082
 * Invalidates a guest page by physical address. Only relevant for EPT/VPID,
 
5083
 * otherwise there is nothing really to invalidate.
4413
5084
 *
4414
5085
 * NOTE: Assumes the current instruction references this physical page though a virtual address!!
4415
5086
 *
4416
5087
 * @returns VBox status code.
4417
 
 * @param   pVM         The VM to operate on.
4418
 
 * @param   pVCpu       The VM CPU to operate on.
4419
 
 * @param   GCPhys      Page to invalidate
 
5088
 * @param   pVM         Pointer to the VM.
 
5089
 * @param   pVCpu       Pointer to the VMCPU.
 
5090
 * @param   GCPhys      Guest physical address of the page to invalidate.
4420
5091
 */
4421
5092
VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
4422
5093
{
4423
 
    bool fFlushPending = VMCPU_FF_ISSET(pVCpu, VMCPU_FF_TLB_FLUSH);
4424
 
 
4425
 
    Assert(pVM->hwaccm.s.fNestedPaging);
4426
 
 
4427
5094
    LogFlow(("VMXR0InvalidatePhysPage %RGp\n", GCPhys));
4428
5095
 
4429
 
    /* Skip it if a TLB flush is already pending. */
4430
 
    if (!fFlushPending)
4431
 
        vmxR0FlushEPT(pVM, pVCpu, pVM->hwaccm.s.vmx.enmFlushPage, GCPhys);
4432
 
 
 
5096
    /*
 
5097
     * We cannot flush a page by guest-physical address. invvpid takes only a linear address
 
5098
     * while invept only flushes by EPT not individual addresses. We update the force flag here
 
5099
     * and flush before VMENTRY in hmR0VmxSetupTLB*(). This function might be called in a loop.
 
5100
     */
 
5101
    VMCPU_FF_SET(pVCpu, VMCPU_FF_TLB_FLUSH);
4433
5102
    return VINF_SUCCESS;
4434
5103
}
4435
5104
 
 
5105
 
4436
5106
/**
4437
 
 * Report world switch error and dump some useful debug info
 
5107
 * Report world switch error and dump some useful debug info.
4438
5108
 *
4439
 
 * @param   pVM         The VM to operate on.
4440
 
 * @param   pVCpu       The VMCPU to operate on.
4441
 
 * @param   rc          Return code
4442
 
 * @param   pCtx        Current CPU context (not updated)
 
5109
 * @param   pVM         Pointer to the VM.
 
5110
 * @param   pVCpu       Pointer to the VMCPU.
 
5111
 * @param   rc          Return code.
 
5112
 * @param   pCtx        Pointer to the current guest CPU context (not updated).
4443
5113
 */
4444
 
static void VMXR0ReportWorldSwitchError(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc, PCPUMCTX pCtx)
 
5114
static void hmR0VmxReportWorldSwitchError(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc, PCPUMCTX pCtx)
4445
5115
{
 
5116
    NOREF(pVM);
 
5117
 
4446
5118
    switch (VBOXSTRICTRC_VAL(rc))
4447
5119
    {
4448
 
    case VERR_VMX_INVALID_VMXON_PTR:
4449
 
        AssertFailed();
4450
 
        break;
4451
 
 
4452
 
    case VERR_VMX_UNABLE_TO_START_VM:
4453
 
    case VERR_VMX_UNABLE_TO_RESUME_VM:
4454
 
    {
4455
 
        int         rc2;
4456
 
        RTCCUINTREG exitReason, instrError;
4457
 
 
4458
 
        rc2  = VMXReadVMCS(VMX_VMCS32_RO_EXIT_REASON, &exitReason);
4459
 
        rc2 |= VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &instrError);
4460
 
        AssertRC(rc2);
4461
 
        if (rc2 == VINF_SUCCESS)
 
5120
        case VERR_VMX_INVALID_VMXON_PTR:
 
5121
            AssertFailed();
 
5122
            break;
 
5123
 
 
5124
        case VERR_VMX_UNABLE_TO_START_VM:
 
5125
        case VERR_VMX_UNABLE_TO_RESUME_VM:
4462
5126
        {
4463
 
            Log(("Unable to start/resume VM for reason: %x. Instruction error %x\n", (uint32_t)exitReason, (uint32_t)instrError));
4464
 
            Log(("Current stack %08x\n", &rc2));
4465
 
 
4466
 
            pVCpu->hwaccm.s.vmx.lasterror.ulInstrError = instrError;
4467
 
            pVCpu->hwaccm.s.vmx.lasterror.ulExitReason = exitReason;
 
5127
            int         rc2;
 
5128
            RTCCUINTREG exitReason, instrError;
 
5129
 
 
5130
            rc2  = VMXReadVMCS(VMX_VMCS32_RO_EXIT_REASON, &exitReason);
 
5131
            rc2 |= VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &instrError);
 
5132
            AssertRC(rc2);
 
5133
            if (rc2 == VINF_SUCCESS)
 
5134
            {
 
5135
                Log(("Unable to start/resume VM for reason: %x. Instruction error %x\n", (uint32_t)exitReason,
 
5136
                     (uint32_t)instrError));
 
5137
                Log(("Current stack %08x\n", &rc2));
 
5138
 
 
5139
                pVCpu->hwaccm.s.vmx.lasterror.ulInstrError = instrError;
 
5140
                pVCpu->hwaccm.s.vmx.lasterror.ulExitReason = exitReason;
4468
5141
 
4469
5142
#ifdef VBOX_STRICT
4470
 
            RTGDTR      gdtr;
4471
 
            PCX86DESCHC pDesc;
4472
 
            RTCCUINTREG val;
4473
 
 
4474
 
            ASMGetGDTR(&gdtr);
4475
 
 
4476
 
            VMXReadVMCS(VMX_VMCS64_GUEST_RIP, &val);
4477
 
            Log(("Old eip %RGv new %RGv\n", (RTGCPTR)pCtx->rip, (RTGCPTR)val));
4478
 
            VMXReadVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS, &val);
4479
 
            Log(("VMX_VMCS_CTRL_PIN_EXEC_CONTROLS   %08x\n", val));
4480
 
            VMXReadVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, &val);
4481
 
            Log(("VMX_VMCS_CTRL_PROC_EXEC_CONTROLS  %08x\n", val));
4482
 
            VMXReadVMCS(VMX_VMCS_CTRL_ENTRY_CONTROLS, &val);
4483
 
            Log(("VMX_VMCS_CTRL_ENTRY_CONTROLS      %08x\n", val));
4484
 
            VMXReadVMCS(VMX_VMCS_CTRL_EXIT_CONTROLS, &val);
4485
 
            Log(("VMX_VMCS_CTRL_EXIT_CONTROLS       %08x\n", val));
4486
 
 
4487
 
            VMXReadVMCS(VMX_VMCS_HOST_CR0, &val);
4488
 
            Log(("VMX_VMCS_HOST_CR0 %08x\n", val));
4489
 
 
4490
 
            VMXReadVMCS(VMX_VMCS_HOST_CR3, &val);
4491
 
            Log(("VMX_VMCS_HOST_CR3 %08x\n", val));
4492
 
 
4493
 
            VMXReadVMCS(VMX_VMCS_HOST_CR4, &val);
4494
 
            Log(("VMX_VMCS_HOST_CR4 %08x\n", val));
4495
 
 
4496
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_CS, &val);
4497
 
            Log(("VMX_VMCS_HOST_FIELD_CS %08x\n", val));
4498
 
 
4499
 
            VMXReadVMCS(VMX_VMCS_GUEST_RFLAGS, &val);
4500
 
            Log(("VMX_VMCS_GUEST_RFLAGS %08x\n", val));
4501
 
 
4502
 
            if (val < gdtr.cbGdt)
4503
 
            {
4504
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4505
 
                HWACCMR0DumpDescriptor(pDesc, val, "CS: ");
4506
 
            }
4507
 
 
4508
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_DS, &val);
4509
 
            Log(("VMX_VMCS_HOST_FIELD_DS %08x\n", val));
4510
 
            if (val < gdtr.cbGdt)
4511
 
            {
4512
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4513
 
                HWACCMR0DumpDescriptor(pDesc, val, "DS: ");
4514
 
            }
4515
 
 
4516
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_ES, &val);
4517
 
            Log(("VMX_VMCS_HOST_FIELD_ES %08x\n", val));
4518
 
            if (val < gdtr.cbGdt)
4519
 
            {
4520
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4521
 
                HWACCMR0DumpDescriptor(pDesc, val, "ES: ");
4522
 
            }
4523
 
 
4524
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_FS, &val);
4525
 
            Log(("VMX_VMCS16_HOST_FIELD_FS %08x\n", val));
4526
 
            if (val < gdtr.cbGdt)
4527
 
            {
4528
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4529
 
                HWACCMR0DumpDescriptor(pDesc, val, "FS: ");
4530
 
            }
4531
 
 
4532
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_GS, &val);
4533
 
            Log(("VMX_VMCS16_HOST_FIELD_GS %08x\n", val));
4534
 
            if (val < gdtr.cbGdt)
4535
 
            {
4536
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4537
 
                HWACCMR0DumpDescriptor(pDesc, val, "GS: ");
4538
 
            }
4539
 
 
4540
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_SS, &val);
4541
 
            Log(("VMX_VMCS16_HOST_FIELD_SS %08x\n", val));
4542
 
            if (val < gdtr.cbGdt)
4543
 
            {
4544
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4545
 
                HWACCMR0DumpDescriptor(pDesc, val, "SS: ");
4546
 
            }
4547
 
 
4548
 
            VMXReadVMCS(VMX_VMCS16_HOST_FIELD_TR, &val);
4549
 
            Log(("VMX_VMCS16_HOST_FIELD_TR %08x\n", val));
4550
 
            if (val < gdtr.cbGdt)
4551
 
            {
4552
 
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4553
 
                HWACCMR0DumpDescriptor(pDesc, val, "TR: ");
4554
 
            }
4555
 
 
4556
 
            VMXReadVMCS(VMX_VMCS_HOST_TR_BASE, &val);
4557
 
            Log(("VMX_VMCS_HOST_TR_BASE %RHv\n", val));
4558
 
 
4559
 
            VMXReadVMCS(VMX_VMCS_HOST_GDTR_BASE, &val);
4560
 
            Log(("VMX_VMCS_HOST_GDTR_BASE %RHv\n", val));
4561
 
            VMXReadVMCS(VMX_VMCS_HOST_IDTR_BASE, &val);
4562
 
            Log(("VMX_VMCS_HOST_IDTR_BASE %RHv\n", val));
4563
 
 
4564
 
            VMXReadVMCS(VMX_VMCS32_HOST_SYSENTER_CS, &val);
4565
 
            Log(("VMX_VMCS_HOST_SYSENTER_CS  %08x\n", val));
4566
 
 
4567
 
            VMXReadVMCS(VMX_VMCS_HOST_SYSENTER_EIP, &val);
4568
 
            Log(("VMX_VMCS_HOST_SYSENTER_EIP %RHv\n", val));
4569
 
 
4570
 
            VMXReadVMCS(VMX_VMCS_HOST_SYSENTER_ESP, &val);
4571
 
            Log(("VMX_VMCS_HOST_SYSENTER_ESP %RHv\n", val));
4572
 
 
4573
 
            VMXReadVMCS(VMX_VMCS_HOST_RSP, &val);
4574
 
            Log(("VMX_VMCS_HOST_RSP %RHv\n", val));
4575
 
            VMXReadVMCS(VMX_VMCS_HOST_RIP, &val);
4576
 
            Log(("VMX_VMCS_HOST_RIP %RHv\n", val));
4577
 
 
 
5143
                RTGDTR      gdtr;
 
5144
                PCX86DESCHC pDesc;
 
5145
                RTCCUINTREG val;
 
5146
 
 
5147
                ASMGetGDTR(&gdtr);
 
5148
 
 
5149
                VMXReadVMCS(VMX_VMCS64_GUEST_RIP, &val);
 
5150
                Log(("Old eip %RGv new %RGv\n", (RTGCPTR)pCtx->rip, (RTGCPTR)val));
 
5151
                VMXReadVMCS(VMX_VMCS_CTRL_PIN_EXEC_CONTROLS,    &val);
 
5152
                Log(("VMX_VMCS_CTRL_PIN_EXEC_CONTROLS   %08x\n", val));
 
5153
                VMXReadVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS,   &val);
 
5154
                Log(("VMX_VMCS_CTRL_PROC_EXEC_CONTROLS  %08x\n", val));
 
5155
                VMXReadVMCS(VMX_VMCS_CTRL_ENTRY_CONTROLS,       &val);
 
5156
                Log(("VMX_VMCS_CTRL_ENTRY_CONTROLS      %08x\n", val));
 
5157
                VMXReadVMCS(VMX_VMCS_CTRL_EXIT_CONTROLS,        &val);
 
5158
                Log(("VMX_VMCS_CTRL_EXIT_CONTROLS       %08x\n", val));
 
5159
 
 
5160
                VMXReadVMCS(VMX_VMCS_HOST_CR0,  &val);
 
5161
                Log(("VMX_VMCS_HOST_CR0 %08x\n", val));
 
5162
                VMXReadVMCS(VMX_VMCS_HOST_CR3,  &val);
 
5163
                Log(("VMX_VMCS_HOST_CR3 %08x\n", val));
 
5164
                VMXReadVMCS(VMX_VMCS_HOST_CR4,  &val);
 
5165
                Log(("VMX_VMCS_HOST_CR4 %08x\n", val));
 
5166
 
 
5167
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_CS, &val);
 
5168
                Log(("VMX_VMCS_HOST_FIELD_CS %08x\n",  val));
 
5169
                VMXReadVMCS(VMX_VMCS_GUEST_RFLAGS,  &val);
 
5170
                Log(("VMX_VMCS_GUEST_RFLAGS %08x\n", val));
 
5171
 
 
5172
                if (val < gdtr.cbGdt)
 
5173
                {
 
5174
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5175
                    HWACCMR0DumpDescriptor(pDesc, val, "CS: ");
 
5176
                }
 
5177
 
 
5178
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_DS, &val);
 
5179
                Log(("VMX_VMCS_HOST_FIELD_DS %08x\n",  val));
 
5180
                if (val < gdtr.cbGdt)
 
5181
                {
 
5182
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5183
                    HWACCMR0DumpDescriptor(pDesc, val, "DS: ");
 
5184
                }
 
5185
 
 
5186
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_ES, &val);
 
5187
                Log(("VMX_VMCS_HOST_FIELD_ES %08x\n",  val));
 
5188
                if (val < gdtr.cbGdt)
 
5189
                {
 
5190
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5191
                    HWACCMR0DumpDescriptor(pDesc, val, "ES: ");
 
5192
                }
 
5193
 
 
5194
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_FS, &val);
 
5195
                Log(("VMX_VMCS16_HOST_FIELD_FS %08x\n", val));
 
5196
                if (val < gdtr.cbGdt)
 
5197
                {
 
5198
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5199
                    HWACCMR0DumpDescriptor(pDesc, val, "FS: ");
 
5200
                }
 
5201
 
 
5202
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_GS,  &val);
 
5203
                Log(("VMX_VMCS16_HOST_FIELD_GS %08x\n", val));
 
5204
                if (val < gdtr.cbGdt)
 
5205
                {
 
5206
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5207
                    HWACCMR0DumpDescriptor(pDesc, val, "GS: ");
 
5208
                }
 
5209
 
 
5210
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_SS,  &val);
 
5211
                Log(("VMX_VMCS16_HOST_FIELD_SS %08x\n", val));
 
5212
                if (val < gdtr.cbGdt)
 
5213
                {
 
5214
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5215
                    HWACCMR0DumpDescriptor(pDesc, val, "SS: ");
 
5216
                }
 
5217
 
 
5218
                VMXReadVMCS(VMX_VMCS16_HOST_FIELD_TR,  &val);
 
5219
                Log(("VMX_VMCS16_HOST_FIELD_TR %08x\n", val));
 
5220
                if (val < gdtr.cbGdt)
 
5221
                {
 
5222
                    pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
 
5223
                    HWACCMR0DumpDescriptor(pDesc, val, "TR: ");
 
5224
                }
 
5225
 
 
5226
                VMXReadVMCS(VMX_VMCS_HOST_TR_BASE,         &val);
 
5227
                Log(("VMX_VMCS_HOST_TR_BASE %RHv\n",        val));
 
5228
                VMXReadVMCS(VMX_VMCS_HOST_GDTR_BASE,       &val);
 
5229
                Log(("VMX_VMCS_HOST_GDTR_BASE %RHv\n",      val));
 
5230
                VMXReadVMCS(VMX_VMCS_HOST_IDTR_BASE,       &val);
 
5231
                Log(("VMX_VMCS_HOST_IDTR_BASE %RHv\n",      val));
 
5232
                VMXReadVMCS(VMX_VMCS32_HOST_SYSENTER_CS,   &val);
 
5233
                Log(("VMX_VMCS_HOST_SYSENTER_CS  %08x\n",   val));
 
5234
                VMXReadVMCS(VMX_VMCS_HOST_SYSENTER_EIP,    &val);
 
5235
                Log(("VMX_VMCS_HOST_SYSENTER_EIP %RHv\n",   val));
 
5236
                VMXReadVMCS(VMX_VMCS_HOST_SYSENTER_ESP,    &val);
 
5237
                Log(("VMX_VMCS_HOST_SYSENTER_ESP %RHv\n",   val));
 
5238
                VMXReadVMCS(VMX_VMCS_HOST_RSP,             &val);
 
5239
                Log(("VMX_VMCS_HOST_RSP %RHv\n",            val));
 
5240
                VMXReadVMCS(VMX_VMCS_HOST_RIP,             &val);
 
5241
                Log(("VMX_VMCS_HOST_RIP %RHv\n",            val));
4578
5242
# if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
4579
 
            if (VMX_IS_64BIT_HOST_MODE())
4580
 
            {
4581
 
                Log(("MSR_K6_EFER       = %RX64\n", ASMRdMsr(MSR_K6_EFER)));
4582
 
                Log(("MSR_K6_STAR       = %RX64\n", ASMRdMsr(MSR_K6_STAR)));
4583
 
                Log(("MSR_K8_LSTAR      = %RX64\n", ASMRdMsr(MSR_K8_LSTAR)));
4584
 
                Log(("MSR_K8_CSTAR      = %RX64\n", ASMRdMsr(MSR_K8_CSTAR)));
4585
 
                Log(("MSR_K8_SF_MASK    = %RX64\n", ASMRdMsr(MSR_K8_SF_MASK)));
4586
 
            }
 
5243
                if (VMX_IS_64BIT_HOST_MODE())
 
5244
                {
 
5245
                    Log(("MSR_K6_EFER            = %RX64\n", ASMRdMsr(MSR_K6_EFER)));
 
5246
                    Log(("MSR_K6_STAR            = %RX64\n", ASMRdMsr(MSR_K6_STAR)));
 
5247
                    Log(("MSR_K8_LSTAR           = %RX64\n", ASMRdMsr(MSR_K8_LSTAR)));
 
5248
                    Log(("MSR_K8_CSTAR           = %RX64\n", ASMRdMsr(MSR_K8_CSTAR)));
 
5249
                    Log(("MSR_K8_SF_MASK         = %RX64\n", ASMRdMsr(MSR_K8_SF_MASK)));
 
5250
                    Log(("MSR_K8_KERNEL_GS_BASE  = %RX64\n", ASMRdMsr(MSR_K8_KERNEL_GS_BASE)));
 
5251
                }
4587
5252
# endif
4588
5253
#endif /* VBOX_STRICT */
 
5254
            }
 
5255
            break;
4589
5256
        }
4590
 
        break;
4591
 
    }
4592
5257
 
4593
 
    default:
4594
 
        /* impossible */
4595
 
        AssertMsgFailed(("%Rrc (%#x)\n", VBOXSTRICTRC_VAL(rc), VBOXSTRICTRC_VAL(rc)));
4596
 
        break;
 
5258
        default:
 
5259
            /* impossible */
 
5260
            AssertMsgFailed(("%Rrc (%#x)\n", VBOXSTRICTRC_VAL(rc), VBOXSTRICTRC_VAL(rc)));
 
5261
            break;
4597
5262
    }
4598
5263
}
4599
5264
 
 
5265
 
4600
5266
#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
4601
5267
/**
4602
 
 * Prepares for and executes VMLAUNCH (64 bits guest mode)
 
5268
 * Prepares for and executes VMLAUNCH (64 bits guest mode).
4603
5269
 *
4604
 
 * @returns VBox status code
4605
 
 * @param   fResume     vmlauch/vmresume
4606
 
 * @param   pCtx        Guest context
4607
 
 * @param   pCache      VMCS cache
4608
 
 * @param   pVM         The VM to operate on.
4609
 
 * @param   pVCpu       The VMCPU to operate on.
 
5270
 * @returns VBox status code.
 
5271
 * @param   fResume     Whether to vmlauch/vmresume.
 
5272
 * @param   pCtx        Pointer to the guest CPU context.
 
5273
 * @param   pCache      Pointer to the VMCS cache.
 
5274
 * @param   pVM         Pointer to the VM.
 
5275
 * @param   pVCpu       Pointer to the VMCPU.
4610
5276
 */
4611
5277
DECLASM(int) VMXR0SwitcherStartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu)
4612
5278
{
4655
5321
 
4656
5322
#ifdef DEBUG
4657
5323
    AssertMsg(pCache->TestIn.HCPhysCpuPage== HCPhysCpuPage, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysCpuPage, HCPhysCpuPage));
4658
 
    AssertMsg(pCache->TestIn.HCPhysVMCS   == pVCpu->hwaccm.s.vmx.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS, pVCpu->hwaccm.s.vmx.HCPhysVMCS));
4659
 
    AssertMsg(pCache->TestIn.HCPhysVMCS   == pCache->TestOut.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS, pCache->TestOut.HCPhysVMCS));
4660
 
    AssertMsg(pCache->TestIn.pCache       == pCache->TestOut.pCache, ("%RGv vs %RGv\n", pCache->TestIn.pCache, pCache->TestOut.pCache));
4661
 
    AssertMsg(pCache->TestIn.pCache       == VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache), ("%RGv vs %RGv\n", pCache->TestIn.pCache, VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache)));
4662
 
    AssertMsg(pCache->TestIn.pCtx         == pCache->TestOut.pCtx, ("%RGv vs %RGv\n", pCache->TestIn.pCtx, pCache->TestOut.pCtx));
 
5324
    AssertMsg(pCache->TestIn.HCPhysVMCS   == pVCpu->hwaccm.s.vmx.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS,
 
5325
                                                                              pVCpu->hwaccm.s.vmx.HCPhysVMCS));
 
5326
    AssertMsg(pCache->TestIn.HCPhysVMCS   == pCache->TestOut.HCPhysVMCS, ("%RHp vs %RHp\n", pCache->TestIn.HCPhysVMCS,
 
5327
                                                                          pCache->TestOut.HCPhysVMCS));
 
5328
    AssertMsg(pCache->TestIn.pCache       == pCache->TestOut.pCache, ("%RGv vs %RGv\n", pCache->TestIn.pCache,
 
5329
                                                                      pCache->TestOut.pCache));
 
5330
    AssertMsg(pCache->TestIn.pCache       == VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache),
 
5331
              ("%RGv vs %RGv\n", pCache->TestIn.pCache, VM_RC_ADDR(pVM, &pVM->aCpus[pVCpu->idCpu].hwaccm.s.vmx.VMCSCache)));
 
5332
    AssertMsg(pCache->TestIn.pCtx         == pCache->TestOut.pCtx, ("%RGv vs %RGv\n", pCache->TestIn.pCtx,
 
5333
                                                                    pCache->TestOut.pCtx));
4663
5334
    Assert(!(pCache->TestOut.eflags & X86_EFL_IF));
4664
5335
#endif
4665
5336
    return rc;
4666
5337
}
4667
5338
 
 
5339
 
 
5340
# ifdef VBOX_STRICT
 
5341
static bool hmR0VmxIsValidReadField(uint32_t idxField)
 
5342
{
 
5343
    switch (idxField)
 
5344
    {
 
5345
        case VMX_VMCS64_GUEST_RIP:
 
5346
        case VMX_VMCS64_GUEST_RSP:
 
5347
        case VMX_VMCS_GUEST_RFLAGS:
 
5348
        case VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE:
 
5349
        case VMX_VMCS_CTRL_CR0_READ_SHADOW:
 
5350
        case VMX_VMCS64_GUEST_CR0:
 
5351
        case VMX_VMCS_CTRL_CR4_READ_SHADOW:
 
5352
        case VMX_VMCS64_GUEST_CR4:
 
5353
        case VMX_VMCS64_GUEST_DR7:
 
5354
        case VMX_VMCS32_GUEST_SYSENTER_CS:
 
5355
        case VMX_VMCS64_GUEST_SYSENTER_EIP:
 
5356
        case VMX_VMCS64_GUEST_SYSENTER_ESP:
 
5357
        case VMX_VMCS32_GUEST_GDTR_LIMIT:
 
5358
        case VMX_VMCS64_GUEST_GDTR_BASE:
 
5359
        case VMX_VMCS32_GUEST_IDTR_LIMIT:
 
5360
        case VMX_VMCS64_GUEST_IDTR_BASE:
 
5361
        case VMX_VMCS16_GUEST_FIELD_CS:
 
5362
        case VMX_VMCS32_GUEST_CS_LIMIT:
 
5363
        case VMX_VMCS64_GUEST_CS_BASE:
 
5364
        case VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS:
 
5365
        case VMX_VMCS16_GUEST_FIELD_DS:
 
5366
        case VMX_VMCS32_GUEST_DS_LIMIT:
 
5367
        case VMX_VMCS64_GUEST_DS_BASE:
 
5368
        case VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS:
 
5369
        case VMX_VMCS16_GUEST_FIELD_ES:
 
5370
        case VMX_VMCS32_GUEST_ES_LIMIT:
 
5371
        case VMX_VMCS64_GUEST_ES_BASE:
 
5372
        case VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS:
 
5373
        case VMX_VMCS16_GUEST_FIELD_FS:
 
5374
        case VMX_VMCS32_GUEST_FS_LIMIT:
 
5375
        case VMX_VMCS64_GUEST_FS_BASE:
 
5376
        case VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS:
 
5377
        case VMX_VMCS16_GUEST_FIELD_GS:
 
5378
        case VMX_VMCS32_GUEST_GS_LIMIT:
 
5379
        case VMX_VMCS64_GUEST_GS_BASE:
 
5380
        case VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS:
 
5381
        case VMX_VMCS16_GUEST_FIELD_SS:
 
5382
        case VMX_VMCS32_GUEST_SS_LIMIT:
 
5383
        case VMX_VMCS64_GUEST_SS_BASE:
 
5384
        case VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS:
 
5385
        case VMX_VMCS16_GUEST_FIELD_LDTR:
 
5386
        case VMX_VMCS32_GUEST_LDTR_LIMIT:
 
5387
        case VMX_VMCS64_GUEST_LDTR_BASE:
 
5388
        case VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS:
 
5389
        case VMX_VMCS16_GUEST_FIELD_TR:
 
5390
        case VMX_VMCS32_GUEST_TR_LIMIT:
 
5391
        case VMX_VMCS64_GUEST_TR_BASE:
 
5392
        case VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS:
 
5393
        case VMX_VMCS32_RO_EXIT_REASON:
 
5394
        case VMX_VMCS32_RO_VM_INSTR_ERROR:
 
5395
        case VMX_VMCS32_RO_EXIT_INSTR_LENGTH:
 
5396
        case VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE:
 
5397
        case VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO:
 
5398
        case VMX_VMCS32_RO_EXIT_INSTR_INFO:
 
5399
        case VMX_VMCS_RO_EXIT_QUALIFICATION:
 
5400
        case VMX_VMCS32_RO_IDT_INFO:
 
5401
        case VMX_VMCS32_RO_IDT_ERRCODE:
 
5402
        case VMX_VMCS64_GUEST_CR3:
 
5403
        case VMX_VMCS_EXIT_PHYS_ADDR_FULL:
 
5404
            return true;
 
5405
    }
 
5406
    return false;
 
5407
}
 
5408
 
 
5409
 
 
5410
static bool hmR0VmxIsValidWriteField(uint32_t idxField)
 
5411
{
 
5412
    switch (idxField)
 
5413
    {
 
5414
        case VMX_VMCS64_GUEST_LDTR_BASE:
 
5415
        case VMX_VMCS64_GUEST_TR_BASE:
 
5416
        case VMX_VMCS64_GUEST_GDTR_BASE:
 
5417
        case VMX_VMCS64_GUEST_IDTR_BASE:
 
5418
        case VMX_VMCS64_GUEST_SYSENTER_EIP:
 
5419
        case VMX_VMCS64_GUEST_SYSENTER_ESP:
 
5420
        case VMX_VMCS64_GUEST_CR0:
 
5421
        case VMX_VMCS64_GUEST_CR4:
 
5422
        case VMX_VMCS64_GUEST_CR3:
 
5423
        case VMX_VMCS64_GUEST_DR7:
 
5424
        case VMX_VMCS64_GUEST_RIP:
 
5425
        case VMX_VMCS64_GUEST_RSP:
 
5426
        case VMX_VMCS64_GUEST_CS_BASE:
 
5427
        case VMX_VMCS64_GUEST_DS_BASE:
 
5428
        case VMX_VMCS64_GUEST_ES_BASE:
 
5429
        case VMX_VMCS64_GUEST_FS_BASE:
 
5430
        case VMX_VMCS64_GUEST_GS_BASE:
 
5431
        case VMX_VMCS64_GUEST_SS_BASE:
 
5432
            return true;
 
5433
    }
 
5434
    return false;
 
5435
}
 
5436
# endif /* VBOX_STRICT */
 
5437
 
 
5438
 
4668
5439
/**
4669
 
 * Executes the specified handler in 64 mode
 
5440
 * Executes the specified handler in 64-bit mode.
4670
5441
 *
4671
5442
 * @returns VBox status code.
4672
 
 * @param   pVM         The VM to operate on.
4673
 
 * @param   pVCpu       The VMCPU to operate on.
4674
 
 * @param   pCtx        Guest context
4675
 
 * @param   pfnHandler  RC handler
4676
 
 * @param   cbParam     Number of parameters
4677
 
 * @param   paParam     Array of 32 bits parameters
 
5443
 * @param   pVM         Pointer to the VM.
 
5444
 * @param   pVCpu       Pointer to the VMCPU.
 
5445
 * @param   pCtx        Pointer to the guest CPU context.
 
5446
 * @param   pfnHandler  Pointer to the RC handler function.
 
5447
 * @param   cbParam     Number of parameters.
 
5448
 * @param   paParam     Array of 32-bit parameters.
4678
5449
 */
4679
 
VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTRCPTR pfnHandler, uint32_t cbParam, uint32_t *paParam)
 
5450
VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTRCPTR pfnHandler, uint32_t cbParam,
 
5451
                                         uint32_t *paParam)
4680
5452
{
4681
5453
    int             rc, rc2;
4682
5454
    PHMGLOBLCPUINFO pCpu;
4690
5462
 
4691
5463
#ifdef VBOX_STRICT
4692
5464
    for (unsigned i=0;i<pVCpu->hwaccm.s.vmx.VMCSCache.Write.cValidEntries;i++)
4693
 
        Assert(vmxR0IsValidWriteField(pVCpu->hwaccm.s.vmx.VMCSCache.Write.aField[i]));
 
5465
        Assert(hmR0VmxIsValidWriteField(pVCpu->hwaccm.s.vmx.VMCSCache.Write.aField[i]));
4694
5466
 
4695
5467
    for (unsigned i=0;i<pVCpu->hwaccm.s.vmx.VMCSCache.Read.cValidEntries;i++)
4696
 
        Assert(vmxR0IsValidReadField(pVCpu->hwaccm.s.vmx.VMCSCache.Read.aField[i]));
 
5468
        Assert(hmR0VmxIsValidReadField(pVCpu->hwaccm.s.vmx.VMCSCache.Read.aField[i]));
4697
5469
#endif
4698
5470
 
4699
5471
    /* Disable interrupts. */
4707
5479
    pCpu = HWACCMR0GetCurrentCpu();
4708
5480
    HCPhysCpuPage = RTR0MemObjGetPagePhysAddr(pCpu->hMemObj, 0);
4709
5481
 
4710
 
    /* Clear VM Control Structure. Marking it inactive, clearing implementation specific data and writing back VMCS data to memory. */
 
5482
    /* Clear VMCS. Marking it inactive, clearing implementation-specific data and writing VMCS data back to memory. */
4711
5483
    VMXClearVMCS(pVCpu->hwaccm.s.vmx.HCPhysVMCS);
4712
5484
 
4713
5485
    /* Leave VMX Root Mode. */
4721
5493
        CPUMPushHyper(pVCpu, paParam[i]);
4722
5494
 
4723
5495
    STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
 
5496
 
4724
5497
    /* Call switcher. */
4725
5498
    rc = pVM->hwaccm.s.pfnHost32ToGuest64R0(pVM, RT_OFFSETOF(VM, aCpus[pVCpu->idCpu].cpum) - RT_OFFSETOF(VM, cpum));
4726
5499
    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatWorldSwitch3264, z);
4743
5516
    ASMSetFlags(uOldEFlags);
4744
5517
    return rc;
4745
5518
}
4746
 
 
4747
5519
#endif /* HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL) */
4748
5520
 
4749
5521
 
4750
5522
#if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
4751
5523
/**
4752
 
 * Executes VMWRITE
 
5524
 * Executes VMWRITE.
4753
5525
 *
4754
5526
 * @returns VBox status code
4755
 
 * @param   pVCpu           The VMCPU to operate on.
4756
 
 * @param   idxField        VMCS index
4757
 
 * @param   u64Val          16, 32 or 64 bits value
 
5527
 * @param   pVCpu           Pointer to the VMCPU.
 
5528
 * @param   idxField        VMCS field index.
 
5529
 * @param   u64Val          16, 32 or 64 bits value.
4758
5530
 */
4759
5531
VMMR0DECL(int) VMXWriteVMCS64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val)
4760
5532
{
4761
5533
    int rc;
4762
 
 
4763
5534
    switch (idxField)
4764
5535
    {
4765
 
    case VMX_VMCS_CTRL_TSC_OFFSET_FULL:
4766
 
    case VMX_VMCS_CTRL_IO_BITMAP_A_FULL:
4767
 
    case VMX_VMCS_CTRL_IO_BITMAP_B_FULL:
4768
 
    case VMX_VMCS_CTRL_MSR_BITMAP_FULL:
4769
 
    case VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL:
4770
 
    case VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL:
4771
 
    case VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL:
4772
 
    case VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL:
4773
 
    case VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL:
4774
 
    case VMX_VMCS_GUEST_LINK_PTR_FULL:
4775
 
    case VMX_VMCS_GUEST_PDPTR0_FULL:
4776
 
    case VMX_VMCS_GUEST_PDPTR1_FULL:
4777
 
    case VMX_VMCS_GUEST_PDPTR2_FULL:
4778
 
    case VMX_VMCS_GUEST_PDPTR3_FULL:
4779
 
    case VMX_VMCS_GUEST_DEBUGCTL_FULL:
4780
 
    case VMX_VMCS_GUEST_EFER_FULL:
4781
 
    case VMX_VMCS_CTRL_EPTP_FULL:
4782
 
        /* These fields consist of two parts, which are both writable in 32 bits mode. */
4783
 
        rc  = VMXWriteVMCS32(idxField, u64Val);
4784
 
        rc |= VMXWriteVMCS32(idxField + 1, (uint32_t)(u64Val >> 32ULL));
4785
 
        AssertRC(rc);
4786
 
        return rc;
4787
 
 
4788
 
    case VMX_VMCS64_GUEST_LDTR_BASE:
4789
 
    case VMX_VMCS64_GUEST_TR_BASE:
4790
 
    case VMX_VMCS64_GUEST_GDTR_BASE:
4791
 
    case VMX_VMCS64_GUEST_IDTR_BASE:
4792
 
    case VMX_VMCS64_GUEST_SYSENTER_EIP:
4793
 
    case VMX_VMCS64_GUEST_SYSENTER_ESP:
4794
 
    case VMX_VMCS64_GUEST_CR0:
4795
 
    case VMX_VMCS64_GUEST_CR4:
4796
 
    case VMX_VMCS64_GUEST_CR3:
4797
 
    case VMX_VMCS64_GUEST_DR7:
4798
 
    case VMX_VMCS64_GUEST_RIP:
4799
 
    case VMX_VMCS64_GUEST_RSP:
4800
 
    case VMX_VMCS64_GUEST_CS_BASE:
4801
 
    case VMX_VMCS64_GUEST_DS_BASE:
4802
 
    case VMX_VMCS64_GUEST_ES_BASE:
4803
 
    case VMX_VMCS64_GUEST_FS_BASE:
4804
 
    case VMX_VMCS64_GUEST_GS_BASE:
4805
 
    case VMX_VMCS64_GUEST_SS_BASE:
4806
 
        /* Queue a 64 bits value as we can't set it in 32 bits host mode. */
4807
 
        if (u64Val >> 32ULL)
4808
 
            rc = VMXWriteCachedVMCSEx(pVCpu, idxField, u64Val);
4809
 
        else
4810
 
            rc = VMXWriteVMCS32(idxField, (uint32_t)u64Val);
4811
 
 
4812
 
        return rc;
4813
 
 
4814
 
    default:
4815
 
        AssertMsgFailed(("Unexpected field %x\n", idxField));
4816
 
        return VERR_INVALID_PARAMETER;
 
5536
        case VMX_VMCS_CTRL_TSC_OFFSET_FULL:
 
5537
        case VMX_VMCS_CTRL_IO_BITMAP_A_FULL:
 
5538
        case VMX_VMCS_CTRL_IO_BITMAP_B_FULL:
 
5539
        case VMX_VMCS_CTRL_MSR_BITMAP_FULL:
 
5540
        case VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL:
 
5541
        case VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL:
 
5542
        case VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL:
 
5543
        case VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL:
 
5544
        case VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL:
 
5545
        case VMX_VMCS_GUEST_LINK_PTR_FULL:
 
5546
        case VMX_VMCS_GUEST_PDPTR0_FULL:
 
5547
        case VMX_VMCS_GUEST_PDPTR1_FULL:
 
5548
        case VMX_VMCS_GUEST_PDPTR2_FULL:
 
5549
        case VMX_VMCS_GUEST_PDPTR3_FULL:
 
5550
        case VMX_VMCS_GUEST_DEBUGCTL_FULL:
 
5551
        case VMX_VMCS_GUEST_EFER_FULL:
 
5552
        case VMX_VMCS_CTRL_EPTP_FULL:
 
5553
            /* These fields consist of two parts, which are both writable in 32 bits mode. */
 
5554
            rc  = VMXWriteVMCS32(idxField, u64Val);
 
5555
            rc |= VMXWriteVMCS32(idxField + 1, (uint32_t)(u64Val >> 32ULL));
 
5556
            AssertRC(rc);
 
5557
            return rc;
 
5558
 
 
5559
        case VMX_VMCS64_GUEST_LDTR_BASE:
 
5560
        case VMX_VMCS64_GUEST_TR_BASE:
 
5561
        case VMX_VMCS64_GUEST_GDTR_BASE:
 
5562
        case VMX_VMCS64_GUEST_IDTR_BASE:
 
5563
        case VMX_VMCS64_GUEST_SYSENTER_EIP:
 
5564
        case VMX_VMCS64_GUEST_SYSENTER_ESP:
 
5565
        case VMX_VMCS64_GUEST_CR0:
 
5566
        case VMX_VMCS64_GUEST_CR4:
 
5567
        case VMX_VMCS64_GUEST_CR3:
 
5568
        case VMX_VMCS64_GUEST_DR7:
 
5569
        case VMX_VMCS64_GUEST_RIP:
 
5570
        case VMX_VMCS64_GUEST_RSP:
 
5571
        case VMX_VMCS64_GUEST_CS_BASE:
 
5572
        case VMX_VMCS64_GUEST_DS_BASE:
 
5573
        case VMX_VMCS64_GUEST_ES_BASE:
 
5574
        case VMX_VMCS64_GUEST_FS_BASE:
 
5575
        case VMX_VMCS64_GUEST_GS_BASE:
 
5576
        case VMX_VMCS64_GUEST_SS_BASE:
 
5577
            /* Queue a 64 bits value as we can't set it in 32 bits host mode. */
 
5578
            if (u64Val >> 32ULL)
 
5579
                rc = VMXWriteCachedVMCSEx(pVCpu, idxField, u64Val);
 
5580
            else
 
5581
                rc = VMXWriteVMCS32(idxField, (uint32_t)u64Val);
 
5582
 
 
5583
            return rc;
 
5584
 
 
5585
        default:
 
5586
            AssertMsgFailed(("Unexpected field %x\n", idxField));
 
5587
            return VERR_INVALID_PARAMETER;
4817
5588
    }
4818
5589
}
4819
5590
 
 
5591
 
4820
5592
/**
4821
5593
 * Cache VMCS writes for performance reasons (Darwin) and for running 64 bits guests on 32 bits hosts.
4822
5594
 *
4823
 
 * @param   pVCpu       The VMCPU to operate on.
4824
 
 * @param   idxField    VMCS field
4825
 
 * @param   u64Val      Value
 
5595
 * @param   pVCpu       Pointer to the VMCPU.
 
5596
 * @param   idxField    VMCS field index.
 
5597
 * @param   u64Val      16, 32 or 64 bits value.
4826
5598
 */
4827
5599
VMMR0DECL(int) VMXWriteCachedVMCSEx(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val)
4828
5600
{
4829
5601
    PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
4830
5602
 
4831
 
    AssertMsgReturn(pCache->Write.cValidEntries < VMCSCACHE_MAX_ENTRY - 1, ("entries=%x\n", pCache->Write.cValidEntries), VERR_ACCESS_DENIED);
 
5603
    AssertMsgReturn(pCache->Write.cValidEntries < VMCSCACHE_MAX_ENTRY - 1,
 
5604
                    ("entries=%x\n", pCache->Write.cValidEntries), VERR_ACCESS_DENIED);
4832
5605
 
4833
5606
    /* Make sure there are no duplicates. */
4834
 
    for (unsigned i=0;i<pCache->Write.cValidEntries;i++)
 
5607
    for (unsigned i = 0; i < pCache->Write.cValidEntries; i++)
4835
5608
    {
4836
5609
        if (pCache->Write.aField[i] == idxField)
4837
5610
        {
4848
5621
 
4849
5622
#endif /* HC_ARCH_BITS == 32 && !VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 */
4850
5623
 
4851
 
#ifdef VBOX_STRICT
4852
 
static bool vmxR0IsValidReadField(uint32_t idxField)
4853
 
{
4854
 
    switch(idxField)
4855
 
    {
4856
 
    case VMX_VMCS64_GUEST_RIP:
4857
 
    case VMX_VMCS64_GUEST_RSP:
4858
 
    case VMX_VMCS_GUEST_RFLAGS:
4859
 
    case VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE:
4860
 
    case VMX_VMCS_CTRL_CR0_READ_SHADOW:
4861
 
    case VMX_VMCS64_GUEST_CR0:
4862
 
    case VMX_VMCS_CTRL_CR4_READ_SHADOW:
4863
 
    case VMX_VMCS64_GUEST_CR4:
4864
 
    case VMX_VMCS64_GUEST_DR7:
4865
 
    case VMX_VMCS32_GUEST_SYSENTER_CS:
4866
 
    case VMX_VMCS64_GUEST_SYSENTER_EIP:
4867
 
    case VMX_VMCS64_GUEST_SYSENTER_ESP:
4868
 
    case VMX_VMCS32_GUEST_GDTR_LIMIT:
4869
 
    case VMX_VMCS64_GUEST_GDTR_BASE:
4870
 
    case VMX_VMCS32_GUEST_IDTR_LIMIT:
4871
 
    case VMX_VMCS64_GUEST_IDTR_BASE:
4872
 
    case VMX_VMCS16_GUEST_FIELD_CS:
4873
 
    case VMX_VMCS32_GUEST_CS_LIMIT:
4874
 
    case VMX_VMCS64_GUEST_CS_BASE:
4875
 
    case VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS:
4876
 
    case VMX_VMCS16_GUEST_FIELD_DS:
4877
 
    case VMX_VMCS32_GUEST_DS_LIMIT:
4878
 
    case VMX_VMCS64_GUEST_DS_BASE:
4879
 
    case VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS:
4880
 
    case VMX_VMCS16_GUEST_FIELD_ES:
4881
 
    case VMX_VMCS32_GUEST_ES_LIMIT:
4882
 
    case VMX_VMCS64_GUEST_ES_BASE:
4883
 
    case VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS:
4884
 
    case VMX_VMCS16_GUEST_FIELD_FS:
4885
 
    case VMX_VMCS32_GUEST_FS_LIMIT:
4886
 
    case VMX_VMCS64_GUEST_FS_BASE:
4887
 
    case VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS:
4888
 
    case VMX_VMCS16_GUEST_FIELD_GS:
4889
 
    case VMX_VMCS32_GUEST_GS_LIMIT:
4890
 
    case VMX_VMCS64_GUEST_GS_BASE:
4891
 
    case VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS:
4892
 
    case VMX_VMCS16_GUEST_FIELD_SS:
4893
 
    case VMX_VMCS32_GUEST_SS_LIMIT:
4894
 
    case VMX_VMCS64_GUEST_SS_BASE:
4895
 
    case VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS:
4896
 
    case VMX_VMCS16_GUEST_FIELD_LDTR:
4897
 
    case VMX_VMCS32_GUEST_LDTR_LIMIT:
4898
 
    case VMX_VMCS64_GUEST_LDTR_BASE:
4899
 
    case VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS:
4900
 
    case VMX_VMCS16_GUEST_FIELD_TR:
4901
 
    case VMX_VMCS32_GUEST_TR_LIMIT:
4902
 
    case VMX_VMCS64_GUEST_TR_BASE:
4903
 
    case VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS:
4904
 
    case VMX_VMCS32_RO_EXIT_REASON:
4905
 
    case VMX_VMCS32_RO_VM_INSTR_ERROR:
4906
 
    case VMX_VMCS32_RO_EXIT_INSTR_LENGTH:
4907
 
    case VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE:
4908
 
    case VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO:
4909
 
    case VMX_VMCS32_RO_EXIT_INSTR_INFO:
4910
 
    case VMX_VMCS_RO_EXIT_QUALIFICATION:
4911
 
    case VMX_VMCS32_RO_IDT_INFO:
4912
 
    case VMX_VMCS32_RO_IDT_ERRCODE:
4913
 
    case VMX_VMCS64_GUEST_CR3:
4914
 
    case VMX_VMCS_EXIT_PHYS_ADDR_FULL:
4915
 
        return true;
4916
 
    }
4917
 
    return false;
4918
 
}
4919
 
 
4920
 
static bool vmxR0IsValidWriteField(uint32_t idxField)
4921
 
{
4922
 
    switch(idxField)
4923
 
    {
4924
 
    case VMX_VMCS64_GUEST_LDTR_BASE:
4925
 
    case VMX_VMCS64_GUEST_TR_BASE:
4926
 
    case VMX_VMCS64_GUEST_GDTR_BASE:
4927
 
    case VMX_VMCS64_GUEST_IDTR_BASE:
4928
 
    case VMX_VMCS64_GUEST_SYSENTER_EIP:
4929
 
    case VMX_VMCS64_GUEST_SYSENTER_ESP:
4930
 
    case VMX_VMCS64_GUEST_CR0:
4931
 
    case VMX_VMCS64_GUEST_CR4:
4932
 
    case VMX_VMCS64_GUEST_CR3:
4933
 
    case VMX_VMCS64_GUEST_DR7:
4934
 
    case VMX_VMCS64_GUEST_RIP:
4935
 
    case VMX_VMCS64_GUEST_RSP:
4936
 
    case VMX_VMCS64_GUEST_CS_BASE:
4937
 
    case VMX_VMCS64_GUEST_DS_BASE:
4938
 
    case VMX_VMCS64_GUEST_ES_BASE:
4939
 
    case VMX_VMCS64_GUEST_FS_BASE:
4940
 
    case VMX_VMCS64_GUEST_GS_BASE:
4941
 
    case VMX_VMCS64_GUEST_SS_BASE:
4942
 
        return true;
4943
 
    }
4944
 
    return false;
4945
 
}
4946
 
 
4947
 
#endif