224
224
#ifndef CPUM_CAN_HANDLE_NM_TRAPS_IN_KERNEL_MODE
225
225
# if defined(VBOX_WITH_HYBRID_32BIT_KERNEL) || defined(VBOX_WITH_KERNEL_USING_XMM) /** @todo remove the #else here and move cpumHandleLazyFPUAsm back to VMMGC after branching out 3.0!!. */
226
Assert(!(pVCpu->cpum.s.fUseFlags & CPUM_MANUAL_XMM_RESTORE));
226
227
/** @todo Move the FFXR handling down into
227
228
* cpumR0SaveHostRestoreguestFPUState to optimize the
228
229
* VBOX_WITH_KERNEL_USING_XMM handling. */
443
444
* Restore the host's debug state. DR0-3, DR6 and only then DR7!
444
445
* DR7 contains 0x400 right now.
446
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
447
AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
448
cpumR0LoadDRx(&pVCpu->cpum.s.Host.dr0);
450
ASMSetDR0(pVCpu->cpum.s.Host.dr0);
451
ASMSetDR1(pVCpu->cpum.s.Host.dr1);
452
ASMSetDR2(pVCpu->cpum.s.Host.dr2);
453
ASMSetDR3(pVCpu->cpum.s.Host.dr3);
455
ASMSetDR6(pVCpu->cpum.s.Host.dr6);
456
ASMSetDR7(pVCpu->cpum.s.Host.dr7);
458
pVCpu->cpum.s.fUseFlags &= ~CPUM_USE_DEBUG_REGS;
447
CPUMR0LoadHostDebugState(pVM, pVCpu);
448
Assert(!(pVCpu->cpum.s.fUseFlags & CPUM_USE_DEBUG_REGS));
459
449
return VINF_SUCCESS;
472
462
VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6)
474
464
/* Save the host state. */
465
CPUMR0SaveHostDebugState(pVM, pVCpu);
466
Assert(ASMGetDR7() == X86_DR7_INIT_VAL);
468
/* Activate the guest state DR0-3; DR7 is left to the caller. */
469
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
470
if (CPUMIsGuestInLongModeEx(pCtx))
472
/* Restore the state on entry as we need to be in 64 bits mode to access the full state. */
473
pVCpu->cpum.s.fUseFlags |= CPUM_SYNC_DEBUG_STATE;
478
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
479
cpumR0LoadDRx(&pCtx->dr[0]);
481
ASMSetDR0(pCtx->dr[0]);
482
ASMSetDR1(pCtx->dr[1]);
483
ASMSetDR2(pCtx->dr[2]);
484
ASMSetDR3(pCtx->dr[3]);
487
ASMSetDR6(pCtx->dr[6]);
490
pVCpu->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS;
495
* Save the host debug state
497
* @returns VBox status code.
498
* @param pVM VM handle.
499
* @param pVCpu VMCPU handle.
501
VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu)
503
/* Save the host state. */
475
504
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
476
505
AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
477
506
cpumR0SaveDRx(&pVCpu->cpum.s.Host.dr0);
487
516
/* Make sure DR7 is harmless or else we could trigger breakpoints when restoring dr0-3 (!) */
488
517
ASMSetDR7(X86_DR7_INIT_VAL);
523
* Load the host debug state
525
* @returns VBox status code.
526
* @param pVM VM handle.
527
* @param pVCpu VMCPU handle.
529
VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu)
531
Assert(pVCpu->cpum.s.fUseFlags & (CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HYPER));
534
* Restore the host's debug state. DR0-3, DR6 and only then DR7!
535
* DR7 contains 0x400 right now.
537
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
538
AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
539
cpumR0LoadDRx(&pVCpu->cpum.s.Host.dr0);
541
ASMSetDR0(pVCpu->cpum.s.Host.dr0);
542
ASMSetDR1(pVCpu->cpum.s.Host.dr1);
543
ASMSetDR2(pVCpu->cpum.s.Host.dr2);
544
ASMSetDR3(pVCpu->cpum.s.Host.dr3);
546
ASMSetDR6(pVCpu->cpum.s.Host.dr6);
547
ASMSetDR7(pVCpu->cpum.s.Host.dr7);
549
pVCpu->cpum.s.fUseFlags &= ~(CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HYPER);
555
* Lazily sync in the hypervisor debug state
557
* @returns VBox status code.
558
* @param pVM VM handle.
559
* @param pVCpu VMCPU handle.
560
* @param pCtx CPU context
561
* @param fDR6 Include DR6 or not
563
VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6)
565
/* Save the host state. */
566
CPUMR0SaveHostDebugState(pVM, pVCpu);
567
Assert(ASMGetDR7() == X86_DR7_INIT_VAL);
490
569
/* Activate the guest state DR0-3; DR7 is left to the caller. */
491
570
#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
492
571
if (CPUMIsGuestInLongModeEx(pCtx))
494
/* Restore the state on entry as we need to be in 64 bits mode to access the full state. */
495
pVCpu->cpum.s.fUseFlags |= CPUM_SYNC_DEBUG_STATE;
574
return VERR_NOT_IMPLEMENTED;
500
579
#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
501
cpumR0LoadDRx(&pCtx->dr[0]);
581
return VERR_NOT_IMPLEMENTED;
503
ASMSetDR0(pCtx->dr[0]);
504
ASMSetDR1(pCtx->dr[1]);
505
ASMSetDR2(pCtx->dr[2]);
506
ASMSetDR3(pCtx->dr[3]);
583
ASMSetDR0(CPUMGetHyperDR0(pVCpu));
584
ASMSetDR1(CPUMGetHyperDR1(pVCpu));
585
ASMSetDR2(CPUMGetHyperDR2(pVCpu));
586
ASMSetDR3(CPUMGetHyperDR3(pVCpu));
509
ASMSetDR6(pCtx->dr[6]);
589
ASMSetDR6(CPUMGetHyperDR6(pVCpu));
512
pVCpu->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS;
592
pVCpu->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS_HYPER;
513
593
return VINF_SUCCESS;