~ubuntu-branches/ubuntu/vivid/virtualbox-ose/vivid

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Felix Geyer
  • Date: 2009-09-14 18:25:07 UTC
  • mfrom: (0.4.1 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090914182507-c98g07mq16hjmn6d
Tags: 3.0.6-dfsg-1ubuntu1
* Merge from debian unstable (LP: #429697), remaining changes:
  - Enable DKMS support on virtualbox host and guest modules (LP: #267097)
    - Drop virtualbox-ose{-guest,}-modules-* package templates
    - Recommend *-source instead of *-modules packages
    - Replace error messages related to missing/mismatched
      kernel module accordingly
  - Autoload kernel module
    - LOAD_VBOXDRV_MODULE=1 in virtualbox-ose.default
  - Disable update action
    - patches/u01-disable-update-action.dpatch
  - Virtualbox should go in Accessories, not in System tools (LP: #288590)
    - virtualbox-ose-qt.files/virtualbox-ose.desktop
  - Add apport hook
    - virtualbox-ose.files/source_virtualbox-ose.py
    - virtualbox-ose.install
  - Add launchpad integration
    - control
    - lpi-bug.xpm
    - patches/u02-lp-integration.dpatch
  - virtualbox, virtualbox-* (names of the upstream proprietary packages)
    conflict with virtualbox-ose (LP: #379878)
* Make debug package depend on normal or guest utils package
* Drop patches/22-pulseaudio-stubs.dpatch (applied upstream)
* Rename Ubuntu specific patches to uXX-*.dpatch
* Fix lintian warnings in maintainer scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
82
82
static bool vmxR0IsValidReadField(uint32_t idxField);
83
83
static bool vmxR0IsValidWriteField(uint32_t idxField);
84
84
#endif
 
85
static void vmxR0SetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool fWrite);
85
86
 
86
87
static void VMXR0CheckError(PVM pVM, PVMCPU pVCpu, int rc)
87
88
{
197
198
        pVM->hwaccm.s.vmx.pAPICPhys   = 0;
198
199
    }
199
200
 
200
 
    /* Allocate the MSR bitmap if this feature is supported. */
201
 
    if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
202
 
    {
203
 
        rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjMSRBitmap, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
204
 
        AssertRC(rc);
205
 
        if (RT_FAILURE(rc))
206
 
            return rc;
207
 
 
208
 
        pVM->hwaccm.s.vmx.pMSRBitmap     = (uint8_t *)RTR0MemObjAddress(pVM->hwaccm.s.vmx.pMemObjMSRBitmap);
209
 
        pVM->hwaccm.s.vmx.pMSRBitmapPhys = RTR0MemObjGetPagePhysAddr(pVM->hwaccm.s.vmx.pMemObjMSRBitmap, 0);
210
 
        memset(pVM->hwaccm.s.vmx.pMSRBitmap, 0xff, PAGE_SIZE);
211
 
    }
212
 
 
213
201
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
214
202
    {
215
203
        rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjScratch, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
256
244
        pVCpu->hwaccm.s.vmx.pVAPICPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjVAPIC, 0);
257
245
        ASMMemZero32(pVCpu->hwaccm.s.vmx.pVAPIC, PAGE_SIZE);
258
246
 
 
247
        /* Allocate the MSR bitmap if this feature is supported. */
 
248
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
 
249
        {
 
250
            rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
 
251
            AssertRC(rc);
 
252
            if (RT_FAILURE(rc))
 
253
                return rc;
 
254
 
 
255
            pVCpu->hwaccm.s.vmx.pMSRBitmap     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap);
 
256
            pVCpu->hwaccm.s.vmx.pMSRBitmapPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, 0);
 
257
            memset(pVCpu->hwaccm.s.vmx.pMSRBitmap, 0xff, PAGE_SIZE);
 
258
        }
 
259
 
 
260
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
261
        /* Allocate one page for the guest MSR load area (for preloading guest MSRs during the world switch). */
 
262
        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
 
263
        AssertRC(rc);
 
264
        if (RT_FAILURE(rc))
 
265
            return rc;
 
266
 
 
267
        pVCpu->hwaccm.s.vmx.pGuestMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR);
 
268
        pVCpu->hwaccm.s.vmx.pGuestMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, 0);
 
269
        memset(pVCpu->hwaccm.s.vmx.pGuestMSR, 0, PAGE_SIZE);
 
270
 
 
271
        /* Allocate one page for the host MSR load area (for restoring host MSRs after the world switch back). */
 
272
        rc = RTR0MemObjAllocCont(&pVCpu->hwaccm.s.vmx.pMemObjHostMSR, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
 
273
        AssertRC(rc);
 
274
        if (RT_FAILURE(rc))
 
275
            return rc;
 
276
 
 
277
        pVCpu->hwaccm.s.vmx.pHostMSR     = (uint8_t *)RTR0MemObjAddress(pVCpu->hwaccm.s.vmx.pMemObjHostMSR);
 
278
        pVCpu->hwaccm.s.vmx.pHostMSRPhys = RTR0MemObjGetPagePhysAddr(pVCpu->hwaccm.s.vmx.pMemObjHostMSR, 0);
 
279
        memset(pVCpu->hwaccm.s.vmx.pHostMSR, 0, PAGE_SIZE);
 
280
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
 
281
 
259
282
        /* Current guest paging mode. */
260
283
        pVCpu->hwaccm.s.vmx.enmLastSeenGuestMode = PGMMODE_REAL;
261
284
 
293
316
            pVCpu->hwaccm.s.vmx.pVAPIC       = 0;
294
317
            pVCpu->hwaccm.s.vmx.pVAPICPhys   = 0;
295
318
        }
 
319
        if (pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
 
320
        {
 
321
            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap, false);
 
322
            pVCpu->hwaccm.s.vmx.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
 
323
            pVCpu->hwaccm.s.vmx.pMSRBitmap       = 0;
 
324
            pVCpu->hwaccm.s.vmx.pMSRBitmapPhys   = 0;
 
325
        }
 
326
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
327
        if (pVCpu->hwaccm.s.vmx.pMemObjHostMSR != NIL_RTR0MEMOBJ)
 
328
        {
 
329
            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjHostMSR, false);
 
330
            pVCpu->hwaccm.s.vmx.pMemObjHostMSR = NIL_RTR0MEMOBJ;
 
331
            pVCpu->hwaccm.s.vmx.pHostMSR       = 0;
 
332
            pVCpu->hwaccm.s.vmx.pHostMSRPhys   = 0;
 
333
        }
 
334
        if (pVCpu->hwaccm.s.vmx.pMemObjGuestMSR != NIL_RTR0MEMOBJ)
 
335
        {
 
336
            RTR0MemObjFree(pVCpu->hwaccm.s.vmx.pMemObjGuestMSR, false);
 
337
            pVCpu->hwaccm.s.vmx.pMemObjGuestMSR = NIL_RTR0MEMOBJ;
 
338
            pVCpu->hwaccm.s.vmx.pGuestMSR       = 0;
 
339
            pVCpu->hwaccm.s.vmx.pGuestMSRPhys   = 0;
 
340
        }
 
341
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
296
342
    }
297
343
    if (pVM->hwaccm.s.vmx.pMemObjAPIC != NIL_RTR0MEMOBJ)
298
344
    {
301
347
        pVM->hwaccm.s.vmx.pAPIC       = 0;
302
348
        pVM->hwaccm.s.vmx.pAPICPhys   = 0;
303
349
    }
304
 
    if (pVM->hwaccm.s.vmx.pMemObjMSRBitmap != NIL_RTR0MEMOBJ)
305
 
    {
306
 
        RTR0MemObjFree(pVM->hwaccm.s.vmx.pMemObjMSRBitmap, false);
307
 
        pVM->hwaccm.s.vmx.pMemObjMSRBitmap = NIL_RTR0MEMOBJ;
308
 
        pVM->hwaccm.s.vmx.pMSRBitmap       = 0;
309
 
        pVM->hwaccm.s.vmx.pMSRBitmapPhys   = 0;
310
 
    }
311
350
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
312
351
    if (pVM->hwaccm.s.vmx.pMemObjScratch != NIL_RTR0MEMOBJ)
313
352
    {
394
433
            /* Exit on CR8 reads & writes in case the TPR shadow feature isn't present. */
395
434
            val |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT | VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT;
396
435
 
397
 
#ifdef VBOX_WITH_VTX_MSR_BITMAPS
398
436
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
399
437
        {
400
 
            Assert(pVM->hwaccm.s.vmx.pMSRBitmapPhys);
 
438
            Assert(pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
401
439
            val |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS;
402
440
        }
403
 
#endif
404
441
 
405
442
        /* We will use the secondary control if it's present. */
406
443
        val |= VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL;
479
516
        /* Set the MSR bitmap address. */
480
517
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS)
481
518
        {
482
 
            /* Optional */
483
 
            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_MSR_BITMAP_FULL, pVM->hwaccm.s.vmx.pMSRBitmapPhys);
 
519
            Assert(pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
 
520
 
 
521
            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_MSR_BITMAP_FULL, pVCpu->hwaccm.s.vmx.pMSRBitmapPhys);
484
522
            AssertRC(rc);
 
523
 
 
524
            /* Allow the guest to directly modify these MSRs; they are restored and saved automatically. */
 
525
            vmxR0SetMSRPermission(pVCpu, MSR_IA32_SYSENTER_CS, true, true);
 
526
            vmxR0SetMSRPermission(pVCpu, MSR_IA32_SYSENTER_ESP, true, true);
 
527
            vmxR0SetMSRPermission(pVCpu, MSR_IA32_SYSENTER_EIP, true, true);
 
528
            vmxR0SetMSRPermission(pVCpu, MSR_K8_LSTAR, true, true);
 
529
            vmxR0SetMSRPermission(pVCpu, MSR_K6_STAR, true, true);
 
530
            vmxR0SetMSRPermission(pVCpu, MSR_K8_SF_MASK, true, true);
 
531
            vmxR0SetMSRPermission(pVCpu, MSR_K8_KERNEL_GS_BASE, true, true);
 
532
            vmxR0SetMSRPermission(pVCpu, MSR_K8_GS_BASE, true, true);
 
533
            vmxR0SetMSRPermission(pVCpu, MSR_K8_FS_BASE, true, true);
485
534
        }
486
535
 
487
 
        /* Clear MSR controls. */
488
 
        rc  = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL, 0);
489
 
        rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL, 0);
490
 
        rc |= VMXWriteVMCS64(VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL, 0);
491
 
        rc |= VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT, 0);
492
 
        rc |= VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT, 0);
 
536
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
537
        /* Set the guest & host MSR load/store physical addresses. */
 
538
        Assert(pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
 
539
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL, pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
 
540
        AssertRC(rc);
 
541
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL, pVCpu->hwaccm.s.vmx.pGuestMSRPhys);
 
542
        AssertRC(rc);
 
543
 
 
544
        Assert(pVCpu->hwaccm.s.vmx.pHostMSRPhys);
 
545
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL,  pVCpu->hwaccm.s.vmx.pHostMSRPhys);
 
546
        AssertRC(rc);
 
547
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
 
548
 
 
549
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT, 0);
 
550
        AssertRC(rc);
 
551
 
 
552
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT, 0);
493
553
        AssertRC(rc);
494
554
 
495
555
        if (pVM->hwaccm.s.vmx.msr.vmx_proc_ctls.n.allowed1 & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
611
671
    return rc;
612
672
}
613
673
 
 
674
/**
 
675
 * Sets the permission bits for the specified MSR
 
676
 *
 
677
 * @param   pVCpu       The VMCPU to operate on.
 
678
 * @param   ulMSR       MSR value
 
679
 * @param   fRead       Reading allowed/disallowed
 
680
 * @param   fWrite      Writing allowed/disallowed
 
681
 */
 
682
static void vmxR0SetMSRPermission(PVMCPU pVCpu, unsigned ulMSR, bool fRead, bool fWrite)
 
683
{
 
684
    unsigned ulBit;
 
685
    uint8_t *pMSRBitmap = (uint8_t *)pVCpu->hwaccm.s.vmx.pMSRBitmap;
 
686
 
 
687
    /* Layout:
 
688
     * 0x000 - 0x3ff - Low MSR read bits
 
689
     * 0x400 - 0x7ff - High MSR read bits
 
690
     * 0x800 - 0xbff - Low MSR write bits
 
691
     * 0xc00 - 0xfff - High MSR write bits
 
692
     */
 
693
    if (ulMSR <= 0x00001FFF)
 
694
    {
 
695
        /* Pentium-compatible MSRs */
 
696
        ulBit    = ulMSR;
 
697
    }
 
698
    else
 
699
    if (    ulMSR >= 0xC0000000
 
700
        &&  ulMSR <= 0xC0001FFF)
 
701
    {
 
702
        /* AMD Sixth Generation x86 Processor MSRs */
 
703
        ulBit = (ulMSR - 0xC0000000);
 
704
        pMSRBitmap += 0x400;
 
705
    }
 
706
    else
 
707
    {
 
708
        AssertFailed();
 
709
        return;
 
710
    }
 
711
 
 
712
    Assert(ulBit <= 0x1fff);
 
713
    if (fRead)
 
714
        ASMBitClear(pMSRBitmap, ulBit);
 
715
    else
 
716
        ASMBitSet(pMSRBitmap, ulBit);
 
717
 
 
718
    if (fWrite)
 
719
        ASMBitClear(pMSRBitmap + 0x800, ulBit);
 
720
    else
 
721
        ASMBitSet(pMSRBitmap + 0x800, ulBit);
 
722
}
 
723
 
614
724
 
615
725
/**
616
726
 * Injects an event (trap or external interrupt)
897
1007
        RTIDTR      idtr;
898
1008
        RTGDTR      gdtr;
899
1009
        RTSEL       SelTR;
900
 
        PX86DESCHC  pDesc;
 
1010
        PCX86DESCHC pDesc;
901
1011
        uintptr_t   trBase;
902
1012
        RTSEL       cs;
903
1013
        RTSEL       ss;
991
1101
            Log2(("VMX_VMCS_HOST_IDTR_BASE %RHv\n", idtr.pIdt));
992
1102
        }
993
1103
 
994
 
 
995
1104
        /* Save the base address of the TR selector. */
996
1105
        if (SelTR > gdtr.cbGdt)
997
1106
        {
999
1108
            return VERR_VMX_INVALID_HOST_STATE;
1000
1109
        }
1001
1110
 
 
1111
        pDesc = (PCX86DESCHC)(gdtr.pGdt + (SelTR & X86_SEL_MASK));
1002
1112
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1003
1113
        if (VMX_IS_64BIT_HOST_MODE())
1004
1114
        {
1005
 
            pDesc  = &((PX86DESCHC)gdtr.pGdt)[SelTR >> X86_SEL_SHIFT_HC]; /// ????
1006
1115
            uint64_t trBase64 = X86DESC64_BASE(*(PX86DESC64)pDesc);
1007
1116
            rc = VMXWriteVMCS64(VMX_VMCS_HOST_TR_BASE, trBase64);
1008
1117
            Log2(("VMX_VMCS_HOST_TR_BASE %RX64\n", trBase64));
1011
1120
        else
1012
1121
#endif
1013
1122
        {
1014
 
            pDesc  = &((PX86DESCHC)gdtr.pGdt)[SelTR >> X86_SEL_SHIFT_HC];
1015
1123
#if HC_ARCH_BITS == 64
1016
1124
            trBase = X86DESC64_BASE(*pDesc);
1017
1125
#else
1066
1174
#endif
1067
1175
        AssertRC(rc);
1068
1176
 
1069
 
#if 0 /* @todo deal with 32/64 */
1070
 
        /* Restore the host EFER - on CPUs that support it. */
1071
 
        if (pVM->hwaccm.s.vmx.msr.vmx_exit.n.allowed1 & VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR)
1072
 
        {
1073
 
            uint64_t msrEFER = ASMRdMsr(MSR_IA32_EFER);
1074
 
            rc = VMXWriteVMCS64(VMX_VMCS_HOST_FIELD_EFER_FULL, msrEFER);
1075
 
            AssertRC(rc);
1076
 
        }
1077
 
#endif
 
1177
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
1178
        /* Store all host MSRs in the VM-Exit load area, so they will be reloaded after the world switch back to the host. */
 
1179
        PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pHostMSR;
 
1180
        unsigned idxMsr = 0;
 
1181
 
 
1182
        /* EFER MSR present? */
 
1183
        if (ASMCpuId_EDX(0x80000001) & (X86_CPUID_AMD_FEATURE_EDX_NX|X86_CPUID_AMD_FEATURE_EDX_LONG_MODE))
 
1184
        {
 
1185
            if (ASMCpuId_EDX(0x80000001) & X86_CPUID_AMD_FEATURE_EDX_SEP)
 
1186
            {
 
1187
                pMsr->u32IndexMSR = MSR_K6_STAR;
 
1188
                pMsr->u32Reserved = 0;
 
1189
                pMsr->u64Value    = ASMRdMsr(MSR_K6_STAR);                   /* legacy syscall eip, cs & ss */
 
1190
                pMsr++; idxMsr++;
 
1191
            }
 
1192
 
 
1193
            pMsr->u32IndexMSR = MSR_K6_EFER;
 
1194
            pMsr->u32Reserved = 0;
 
1195
# if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
 
1196
            if (CPUMIsGuestInLongMode(pVCpu))
 
1197
            {
 
1198
                /* Must match the efer value in our 64 bits switcher. */
 
1199
                pMsr->u64Value    = ASMRdMsr(MSR_K6_EFER) | MSR_K6_EFER_LME | MSR_K6_EFER_SCE | MSR_K6_EFER_NXE;
 
1200
            }
 
1201
            else
 
1202
# endif
 
1203
                pMsr->u64Value    = ASMRdMsr(MSR_K6_EFER);
 
1204
            pMsr++; idxMsr++;
 
1205
        }
 
1206
 
 
1207
# if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
 
1208
        if (VMX_IS_64BIT_HOST_MODE())
 
1209
        {
 
1210
            pMsr->u32IndexMSR = MSR_K8_LSTAR;
 
1211
            pMsr->u32Reserved = 0;
 
1212
            pMsr->u64Value    = ASMRdMsr(MSR_K8_LSTAR);             /* 64 bits mode syscall rip */
 
1213
            pMsr++; idxMsr++;
 
1214
            pMsr->u32IndexMSR = MSR_K8_SF_MASK;
 
1215
            pMsr->u32Reserved = 0;
 
1216
            pMsr->u64Value    = ASMRdMsr(MSR_K8_SF_MASK);           /* syscall flag mask */
 
1217
            pMsr++; idxMsr++;
 
1218
            pMsr->u32IndexMSR = MSR_K8_KERNEL_GS_BASE;
 
1219
            pMsr->u32Reserved = 0;
 
1220
            pMsr->u64Value    = ASMRdMsr(MSR_K8_KERNEL_GS_BASE);    /* swapgs exchange value */
 
1221
            pMsr++; idxMsr++;
 
1222
        }
 
1223
# endif
 
1224
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT, idxMsr);
 
1225
        AssertRC(rc);
 
1226
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
 
1227
 
1078
1228
        pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_HOST_CONTEXT;
1079
1229
    }
1080
1230
    return rc;
1131
1281
 
1132
1282
#ifdef DEBUG /* till after branching, enable it by default then. */
1133
1283
    /* Intercept X86_XCPT_DB if stepping is enabled */
1134
 
    if (DBGFIsStepping(pVCpu))
 
1284
    if (    DBGFIsStepping(pVCpu)
 
1285
        ||  CPUMIsHyperDebugStateActive(pVCpu))
1135
1286
        u32TrapMask |= RT_BIT(X86_XCPT_DB);
1136
1287
    /** @todo Don't trap it unless the debugger has armed breakpoints.  */
1137
1288
    u32TrapMask |= RT_BIT(X86_XCPT_BP);
1173
1324
    val  = pVM->hwaccm.s.vmx.msr.vmx_entry.n.disallowed0;
1174
1325
    /* 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) */
1175
1326
    val |= VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG;
1176
 
#if 0 /* @todo deal with 32/64 */
1177
 
    /* Required for the EFER write below, not supported on all CPUs. */
1178
 
    val |= VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR;
1179
 
#endif
1180
1327
    /* 64 bits guest mode? */
1181
1328
    if (CPUMIsGuestInLongModeEx(pCtx))
1182
1329
        val |= VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE;
1193
1340
    val  = pVM->hwaccm.s.vmx.msr.vmx_exit.n.disallowed0;
1194
1341
 
1195
1342
    /* Save debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
1196
 
#if 0 /* @todo deal with 32/64 */
1197
 
    val |= VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG | VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR;
1198
 
#else
1199
1343
    val |= VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG;
1200
 
#endif
1201
1344
 
1202
1345
#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1203
1346
    if (VMX_IS_64BIT_HOST_MODE())
1243
1386
                    pCtx->gsHid.Attr.n.u2Dpl  = 0;
1244
1387
                    pCtx->ssHid.Attr.n.u2Dpl  = 0;
1245
1388
 
1246
 
                    /* The limit must correspond to the granularity bit. */
1247
 
                    if (!pCtx->csHid.Attr.n.u1Granularity)
 
1389
                    /* The limit must correspond to the 32 bits setting. */
 
1390
                    if (!pCtx->csHid.Attr.n.u1DefBig)
1248
1391
                        pCtx->csHid.u32Limit &= 0xffff;
1249
 
                    if (!pCtx->dsHid.Attr.n.u1Granularity)
 
1392
                    if (!pCtx->dsHid.Attr.n.u1DefBig)
1250
1393
                        pCtx->dsHid.u32Limit &= 0xffff;
1251
 
                    if (!pCtx->esHid.Attr.n.u1Granularity)
 
1394
                    if (!pCtx->esHid.Attr.n.u1DefBig)
1252
1395
                        pCtx->esHid.u32Limit &= 0xffff;
1253
 
                    if (!pCtx->fsHid.Attr.n.u1Granularity)
 
1396
                    if (!pCtx->fsHid.Attr.n.u1DefBig)
1254
1397
                        pCtx->fsHid.u32Limit &= 0xffff;
1255
 
                    if (!pCtx->gsHid.Attr.n.u1Granularity)
 
1398
                    if (!pCtx->gsHid.Attr.n.u1DefBig)
1256
1399
                        pCtx->gsHid.u32Limit &= 0xffff;
1257
 
                    if (!pCtx->ssHid.Attr.n.u1Granularity)
 
1400
                    if (!pCtx->ssHid.Attr.n.u1DefBig)
1258
1401
                        pCtx->ssHid.u32Limit &= 0xffff;
1259
1402
                }
1260
1403
                else
1301
1444
        VMX_WRITE_SELREG(DS, ds);
1302
1445
        AssertRC(rc);
1303
1446
 
1304
 
        /* The base values in the hidden fs & gs registers are not in sync with the msrs; they are cut to 32 bits. */
1305
1447
        VMX_WRITE_SELREG(FS, fs);
1306
1448
        AssertRC(rc);
1307
1449
 
1592
1734
        rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_DR7, pCtx->dr[7]);
1593
1735
        AssertRC(rc);
1594
1736
 
 
1737
#ifdef DEBUG
 
1738
        /* Sync the hypervisor debug state now if any breakpoint is armed. */
 
1739
        if (    CPUMGetHyperDR7(pVCpu) & (X86_DR7_ENABLED_MASK|X86_DR7_GD)
 
1740
            &&  !CPUMIsHyperDebugStateActive(pVCpu)
 
1741
            &&  !DBGFIsStepping(pVCpu))
 
1742
        {
 
1743
            /* Save the host and load the hypervisor debug state. */
 
1744
            rc = CPUMR0LoadHyperDebugState(pVM, pVCpu, pCtx, true /* include DR6 */);
 
1745
            AssertRC(rc);
 
1746
 
 
1747
            /* DRx intercepts remain enabled. */
 
1748
 
 
1749
            /* Override dr7 with the hypervisor value. */
 
1750
            rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_DR7, CPUMGetHyperDR7(pVCpu));
 
1751
            AssertRC(rc);
 
1752
        }
 
1753
        else
 
1754
#endif
1595
1755
        /* Sync the debug state now if any breakpoint is armed. */
1596
1756
        if (    (pCtx->dr[7] & (X86_DR7_ENABLED_MASK|X86_DR7_GD))
1597
1757
            &&  !CPUMIsGuestDebugStateActive(pVCpu)
1641
1801
    rc   = VMXWriteVMCS(VMX_VMCS_GUEST_RFLAGS,           eflags.u32);
1642
1802
    AssertRC(rc);
1643
1803
 
1644
 
    /* TSC offset. */
1645
 
    uint64_t u64TSCOffset;
1646
 
 
1647
 
    if (TMCpuTickCanUseRealTSC(pVCpu, &u64TSCOffset))
 
1804
    if (TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hwaccm.s.vmx.u64TSCOffset))
1648
1805
    {
1649
 
        /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
1650
 
        rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, u64TSCOffset);
1651
 
        AssertRC(rc);
 
1806
        uint64_t u64CurTSC = ASMReadTSC();
 
1807
        if (u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))
 
1808
        {
 
1809
            /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */
 
1810
            rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, pVCpu->hwaccm.s.vmx.u64TSCOffset);
 
1811
            AssertRC(rc);
1652
1812
 
1653
 
        pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
1654
 
        rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
1655
 
        AssertRC(rc);
1656
 
        STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
 
1813
            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
 
1814
            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
 
1815
            AssertRC(rc);
 
1816
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);
 
1817
        }
 
1818
        else
 
1819
        {
 
1820
            /* Fall back to rdtsc emulation as we would otherwise pass decreasing tsc values to the guest. */
 
1821
            Log(("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)));
 
1822
            pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;
 
1823
            rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);
 
1824
            AssertRC(rc);
 
1825
            STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow);
 
1826
        }
1657
1827
    }
1658
1828
    else
1659
1829
    {
1688
1858
        pVCpu->hwaccm.s.vmx.pfnStartVM  = VMXR0StartVM32;
1689
1859
    }
1690
1860
 
1691
 
#if 0 /* @todo deal with 32/64 */
1692
 
    /* Unconditionally update the guest EFER - on CPUs that supports it. */
1693
 
    if (pVM->hwaccm.s.vmx.msr.vmx_entry.n.allowed1 & VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR)
1694
 
    {
1695
 
        rc = VMXWriteVMCS64(VMX_VMCS_GUEST_EFER_FULL, pCtx->msrEFER);
1696
 
        AssertRC(rc);
1697
 
    }
1698
 
#endif
1699
 
 
1700
1861
    vmxR0UpdateExceptionBitmap(pVM, pVCpu, pCtx);
1701
1862
 
 
1863
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
1864
    /* Store all guest MSRs in the VM-Entry load area, so they will be loaded during the world switch. */
 
1865
    PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pGuestMSR;
 
1866
    unsigned idxMsr = 0;
 
1867
 
 
1868
    uint32_t ulEdx;
 
1869
    uint32_t ulTemp;
 
1870
    CPUMGetGuestCpuId(pVCpu, 0x80000001, &ulTemp, &ulTemp, &ulTemp, &ulEdx);
 
1871
    /* EFER MSR present? */
 
1872
    if (ulEdx & (X86_CPUID_AMD_FEATURE_EDX_NX|X86_CPUID_AMD_FEATURE_EDX_LONG_MODE))
 
1873
    {
 
1874
        pMsr->u32IndexMSR = MSR_K6_EFER;
 
1875
        pMsr->u32Reserved = 0;
 
1876
        pMsr->u64Value    = pCtx->msrEFER;
 
1877
        /* VT-x will complain if only MSR_K6_EFER_LME is set. */
 
1878
        if (!CPUMIsGuestInLongModeEx(pCtx))
 
1879
            pMsr->u64Value &= ~(MSR_K6_EFER_LMA|MSR_K6_EFER_LME);
 
1880
        pMsr++; idxMsr++;
 
1881
 
 
1882
        if (ulEdx & X86_CPUID_AMD_FEATURE_EDX_LONG_MODE)
 
1883
        {
 
1884
            pMsr->u32IndexMSR = MSR_K8_LSTAR;
 
1885
            pMsr->u32Reserved = 0;
 
1886
            pMsr->u64Value    = pCtx->msrLSTAR;           /* 64 bits mode syscall rip */
 
1887
            pMsr++; idxMsr++;
 
1888
            pMsr->u32IndexMSR = MSR_K6_STAR;
 
1889
            pMsr->u32Reserved = 0;
 
1890
            pMsr->u64Value    = pCtx->msrSTAR;            /* legacy syscall eip, cs & ss */
 
1891
            pMsr++; idxMsr++;
 
1892
            pMsr->u32IndexMSR = MSR_K8_SF_MASK;
 
1893
            pMsr->u32Reserved = 0;
 
1894
            pMsr->u64Value    = pCtx->msrSFMASK;          /* syscall flag mask */
 
1895
            pMsr++; idxMsr++;
 
1896
            pMsr->u32IndexMSR = MSR_K8_KERNEL_GS_BASE;
 
1897
            pMsr->u32Reserved = 0;
 
1898
            pMsr->u64Value    = pCtx->msrKERNELGSBASE;    /* swapgs exchange value */
 
1899
            pMsr++; idxMsr++;
 
1900
        }
 
1901
    }
 
1902
    pVCpu->hwaccm.s.vmx.cCachedMSRs = idxMsr;
 
1903
 
 
1904
    rc = VMXWriteVMCS(VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT, idxMsr);
 
1905
    AssertRC(rc);
 
1906
 
 
1907
    rc = VMXWriteVMCS(VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT, idxMsr);
 
1908
    AssertRC(rc);
 
1909
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
 
1910
 
1702
1911
    /* Done. */
1703
1912
    pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_ALL_GUEST;
1704
1913
 
1828
2037
        /* In real mode we have a fake TSS, so only sync it back when it's supposed to be valid. */
1829
2038
        VMX_READ_SELREG(TR, tr);
1830
2039
    }
 
2040
 
 
2041
#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
 
2042
    /* Save the possibly changed MSRs that we automatically restore and save during a world switch. */
 
2043
    for (unsigned i = 0; i < pVCpu->hwaccm.s.vmx.cCachedMSRs; i++)
 
2044
    {
 
2045
        PVMXMSR pMsr = (PVMXMSR)pVCpu->hwaccm.s.vmx.pGuestMSR;
 
2046
        pMsr += i;
 
2047
 
 
2048
        switch (pMsr->u32IndexMSR)
 
2049
        {
 
2050
        case MSR_K8_LSTAR:
 
2051
            pCtx->msrLSTAR = pMsr->u64Value;
 
2052
            break;
 
2053
        case MSR_K6_STAR:
 
2054
            pCtx->msrSTAR = pMsr->u64Value;
 
2055
            break;
 
2056
        case MSR_K8_SF_MASK:
 
2057
            pCtx->msrSFMASK = pMsr->u64Value;
 
2058
            break;
 
2059
        case MSR_K8_KERNEL_GS_BASE:
 
2060
            pCtx->msrKERNELGSBASE = pMsr->u64Value;
 
2061
            break;
 
2062
        case MSR_K6_EFER:
 
2063
            /* EFER can't be changed without causing a VM-exit. */
 
2064
//            Assert(pCtx->msrEFER == pMsr->u64Value);
 
2065
            break;
 
2066
        default:
 
2067
            AssertFailed();
 
2068
            return VERR_INTERNAL_ERROR;
 
2069
        }
 
2070
    }
 
2071
#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
1831
2072
    return VINF_SUCCESS;
1832
2073
}
1833
2074
 
2021
2262
    unsigned    cResume = 0;
2022
2263
#ifdef VBOX_STRICT
2023
2264
    RTCPUID     idCpuCheck;
 
2265
    bool        fWasInLongMode = false;
2024
2266
#endif
2025
2267
#ifdef VBOX_HIGH_RES_TIMERS_HACK_IN_RING0
2026
2268
    uint64_t    u64LastTime = RTTimeMilliTS();
2103
2345
        if ((val & ~pVM->hwaccm.s.vmx.msr.vmx_exit.n.allowed1) != 0)
2104
2346
            Log(("Invalid VMX_VMCS_CTRL_EXIT_CONTROLS: one\n"));
2105
2347
    }
 
2348
    fWasInLongMode = CPUMIsGuestInLongMode(pVCpu);
2106
2349
#endif
2107
2350
 
2108
2351
#ifdef VBOX_WITH_CRASHDUMP_MAGIC
2120
2363
              ("Expected %d, I'm %d; cResume=%d exitReason=%RGv exitQualification=%RGv\n",
2121
2364
               (int)pVCpu->hwaccm.s.idEnteredCpu, (int)RTMpCpuId(), cResume, exitReason, exitQualification));
2122
2365
    Assert(!HWACCMR0SuspendPending());
 
2366
    /* Not allowed to switch modes without reloading the host state (32->64 switcher)!! */
 
2367
    Assert(fWasInLongMode == CPUMIsGuestInLongMode(pVCpu));
2123
2368
 
2124
2369
    /* Safety precaution; looping for too long here can have a very bad effect on the host */
2125
2370
    if (RT_UNLIKELY(++cResume > pVM->hwaccm.s.cMaxResumeLoops))
2221
2466
 
2222
2467
    /* TPR caching using CR8 is only available in 64 bits mode */
2223
2468
    /* Note the 32 bits exception for AMD (X86_CPUID_AMD_FEATURE_ECX_CR8L), but that appears missing in Intel CPUs */
2224
 
    /* Note: we can't do this in LoadGuestState as PDMApicGetTPR can jump back to ring 3 (lock)!!!!! */
 
2469
    /* Note: we can't do this in LoadGuestState as PDMApicGetTPR can jump back to ring 3 (lock)!!!!! (no longer true) */
2225
2470
    /**
2226
2471
     * @todo query and update the TPR only when it could have been changed (mmio access & wrmsr (x2apic))
2227
2472
     */
2343
2588
#else
2344
2589
    rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
2345
2590
#endif
 
2591
    /* Possibly the last TSC value seen by the guest (too high) (only when we're in tsc offset mode). */
 
2592
    if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT))
 
2593
        TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + pVCpu->hwaccm.s.vmx.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */);
 
2594
 
2346
2595
    TMNotifyEndOfExecution(pVCpu);
2347
2596
    VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED);
2348
2597
    Assert(!(ASMGetFlags() & X86_EFL_IF));
2642
2891
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestDB);
2643
2892
 
2644
2893
                /* Note that we don't support guest and host-initiated debugging at the same time. */
2645
 
                Assert(DBGFIsStepping(pVCpu) || CPUMIsGuestInRealModeEx(pCtx));
 
2894
                Assert(DBGFIsStepping(pVCpu) || CPUMIsGuestInRealModeEx(pCtx) || CPUMIsHyperDebugStateActive(pVCpu));
2646
2895
 
2647
2896
                uDR6  = X86_DR6_INIT_VAL;
2648
2897
                uDR6 |= (exitQualification & (X86_DR6_B0|X86_DR6_B1|X86_DR6_B2|X86_DR6_B3|X86_DR6_BD|X86_DR6_BS));
2674
2923
                    goto ResumeExecution;
2675
2924
                }
2676
2925
                /* Return to ring 3 to deal with the debug exit code. */
 
2926
                Log(("Debugger hardware BP at %04x:%RGv (rc=%Rrc)\n", pCtx->cs, pCtx->rip, rc));
2677
2927
                break;
2678
2928
            }
2679
2929
 
3281
3531
 
3282
3532
    case VMX_EXIT_DRX_MOVE:             /* 29 Debug-register accesses. */
3283
3533
    {
3284
 
        if (!DBGFIsStepping(pVCpu))
 
3534
        if (    !DBGFIsStepping(pVCpu)
 
3535
            &&  !CPUMIsHyperDebugStateActive(pVCpu))
3285
3536
        {
3286
3537
            /* Disable drx move intercepts. */
3287
3538
            pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
3399
3650
            {
3400
3651
                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitIOWrite);
3401
3652
                rc = IOMIOPortWrite(pVM, uPort, pCtx->eax & uAndVal, cbSize);
 
3653
                if (rc == VINF_IOM_HC_IOPORT_WRITE)
 
3654
                    HWACCMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
3402
3655
            }
3403
3656
            else
3404
3657
            {
3411
3664
                    /* Write back to the EAX register. */
3412
3665
                    pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);
3413
3666
                }
 
3667
                else
 
3668
                if (rc == VINF_IOM_HC_IOPORT_READ)
 
3669
                    HWACCMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pCtx->rip + cbInstr, uPort, uAndVal, cbSize);
3414
3670
            }
3415
3671
        }
3416
3672
        /*
3610
3866
 
3611
3867
    case VMX_EXIT_RSM:                  /* 17 Guest software attempted to execute RSM in SMM. */
3612
3868
        AssertFailed(); /* can't happen. */
3613
 
        rc = VINF_EM_RAW_EXCEPTION_PRIVILEGED;
 
3869
        rc = VERR_EM_INTERPRETER;
3614
3870
        break;
3615
3871
 
3616
3872
    case VMX_EXIT_VMCALL:               /* 18 Guest software executed VMCALL. */
3624
3880
    case VMX_EXIT_VMXOFF:               /* 26 Guest software executed VMXOFF. */
3625
3881
    case VMX_EXIT_VMXON:                /* 27 Guest software executed VMXON. */
3626
3882
        /** @todo inject #UD immediately */
3627
 
        rc = VINF_EM_RAW_EXCEPTION_PRIVILEGED;
 
3883
        rc = VERR_EM_INTERPRETER;
3628
3884
        break;
3629
3885
 
3630
3886
    case VMX_EXIT_CPUID:                /* 10 Guest software attempted to execute CPUID. */
3652
3908
    case VMX_EXIT_APIC_ACCESS:          /* 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
3653
3909
    case VMX_EXIT_RDMSR:                /* 31 RDMSR. Guest software attempted to execute RDMSR. */
3654
3910
    case VMX_EXIT_WRMSR:                /* 32 WRMSR. Guest software attempted to execute WRMSR. */
3655
 
        /* Note: If we decide to emulate them here, then we must sync the MSRs that could have been changed (sysenter, fs/gs base)!!! */
3656
 
        rc = VERR_EM_INTERPRETER;
3657
 
        break;
3658
 
 
3659
3911
    case VMX_EXIT_MONITOR:              /* 39 Guest software attempted to execute MONITOR. */
3660
3912
    case VMX_EXIT_PAUSE:                /* 40 Guest software attempted to execute PAUSE. */
3661
 
        rc = VINF_EM_RAW_EXCEPTION_PRIVILEGED;
 
3913
        /* Note: If we decide to emulate them here, then we must sync the MSRs that could have been changed (sysenter, fs/gs base)!!! */
 
3914
        rc = VERR_EM_INTERPRETER;
3662
3915
        break;
3663
3916
 
3664
3917
    case VMX_EXIT_IRQ_WINDOW:           /* 7 Interrupt window. */
3806
4059
{
3807
4060
    Assert(pVM->hwaccm.s.vmx.fSupported);
3808
4061
 
 
4062
#ifdef DEBUG
 
4063
    if (CPUMIsHyperDebugStateActive(pVCpu))
 
4064
    {
 
4065
        CPUMR0LoadHostDebugState(pVM, pVCpu);
 
4066
    }
 
4067
    else
 
4068
#endif
3809
4069
    /* Save the guest debug state if necessary. */
3810
4070
    if (CPUMIsGuestDebugStateActive(pVCpu))
3811
4071
    {
3971
4231
 
3972
4232
#ifdef VBOX_STRICT
3973
4233
            RTGDTR      gdtr;
3974
 
            PX86DESCHC  pDesc;
 
4234
            PCX86DESCHC pDesc;
3975
4235
            RTCCUINTREG val;
3976
4236
 
3977
4237
            ASMGetGDTR(&gdtr);
4004
4264
 
4005
4265
            if (val < gdtr.cbGdt)
4006
4266
            {
4007
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4267
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4008
4268
                HWACCMR0DumpDescriptor(pDesc, val, "CS: ");
4009
4269
            }
4010
4270
 
4012
4272
            Log(("VMX_VMCS_HOST_FIELD_DS %08x\n", val));
4013
4273
            if (val < gdtr.cbGdt)
4014
4274
            {
4015
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4275
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4016
4276
                HWACCMR0DumpDescriptor(pDesc, val, "DS: ");
4017
4277
            }
4018
4278
 
4020
4280
            Log(("VMX_VMCS_HOST_FIELD_ES %08x\n", val));
4021
4281
            if (val < gdtr.cbGdt)
4022
4282
            {
4023
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4283
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4024
4284
                HWACCMR0DumpDescriptor(pDesc, val, "ES: ");
4025
4285
            }
4026
4286
 
4028
4288
            Log(("VMX_VMCS16_HOST_FIELD_FS %08x\n", val));
4029
4289
            if (val < gdtr.cbGdt)
4030
4290
            {
4031
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4291
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4032
4292
                HWACCMR0DumpDescriptor(pDesc, val, "FS: ");
4033
4293
            }
4034
4294
 
4036
4296
            Log(("VMX_VMCS16_HOST_FIELD_GS %08x\n", val));
4037
4297
            if (val < gdtr.cbGdt)
4038
4298
            {
4039
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4299
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4040
4300
                HWACCMR0DumpDescriptor(pDesc, val, "GS: ");
4041
4301
            }
4042
4302
 
4044
4304
            Log(("VMX_VMCS16_HOST_FIELD_SS %08x\n", val));
4045
4305
            if (val < gdtr.cbGdt)
4046
4306
            {
4047
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4307
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4048
4308
                HWACCMR0DumpDescriptor(pDesc, val, "SS: ");
4049
4309
            }
4050
4310
 
4052
4312
            Log(("VMX_VMCS16_HOST_FIELD_TR %08x\n", val));
4053
4313
            if (val < gdtr.cbGdt)
4054
4314
            {
4055
 
                pDesc  = &((PX86DESCHC)gdtr.pGdt)[val >> X86_SEL_SHIFT_HC];
 
4315
                pDesc  = (PCX86DESCHC)(gdtr.pGdt + (val & X86_SEL_MASK));
4056
4316
                HWACCMR0DumpDescriptor(pDesc, val, "TR: ");
4057
4317
            }
4058
4318