VirtualBox

Changeset 21252 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 6, 2009 2:11:25 PM (16 years ago)
Author:
vboxsync
Message:

First attempt to enable hypervisor breakpoints with vt-x/amd-v guests

Location:
trunk/src/VBox/VMM
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/CPUMInternal.h

    r20374 r21252  
    7676/** Sync the debug state on entry (32->64 switcher only). */
    7777#define CPUM_SYNC_DEBUG_STATE           RT_BIT(8)
     78/** Enabled use of hypervisor debug registers in guest context. */
     79#define CPUM_USE_DEBUG_REGS_HYPER       RT_BIT(9)
    7880/** @} */
    7981
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r19076 r21252  
    19301930}
    19311931
    1932 
    1933 /**
    1934  * Mark the guest's debug state as inactive
     1932/**
     1933 * Checks if the hyper debug state is active
    19351934 *
    19361935 * @returns boolean
    19371936 * @param   pVM         VM handle.
    19381937 */
     1938VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu)
     1939{
     1940    return (pVCpu->cpum.s.fUseFlags & CPUM_USE_DEBUG_REGS_HYPER) != 0;
     1941}
     1942
     1943
     1944/**
     1945 * Mark the guest's debug state as inactive
     1946 *
     1947 * @returns boolean
     1948 * @param   pVM         VM handle.
     1949 */
    19391950VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu)
    19401951{
     
    19421953}
    19431954
     1955
     1956/**
     1957 * Mark the hypervisor's debug state as inactive
     1958 *
     1959 * @returns boolean
     1960 * @param   pVM         VM handle.
     1961 */
     1962VMMDECL(void) CPUMDeactivateHyperDebugState(PVMCPU pVCpu)
     1963{
     1964    pVCpu->cpum.s.fUseFlags &= ~CPUM_USE_DEBUG_REGS_HYPER;
     1965}
    19441966
    19451967/**
  • trunk/src/VBox/VMM/VMMR0/CPUMR0.cpp

    r20997 r21252  
    404404     * DR7 contains 0x400 right now.
    405405     */
    406 #ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
    407     AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
    408     cpumR0LoadDRx(&pVCpu->cpum.s.Host.dr0);
    409 #else
    410     ASMSetDR0(pVCpu->cpum.s.Host.dr0);
    411     ASMSetDR1(pVCpu->cpum.s.Host.dr1);
    412     ASMSetDR2(pVCpu->cpum.s.Host.dr2);
    413     ASMSetDR3(pVCpu->cpum.s.Host.dr3);
    414 #endif
    415     ASMSetDR6(pVCpu->cpum.s.Host.dr6);
    416     ASMSetDR7(pVCpu->cpum.s.Host.dr7);
    417 
    418     pVCpu->cpum.s.fUseFlags &= ~CPUM_USE_DEBUG_REGS;
     406    CPUMR0LoadHostDebugState(pVM, pVCpu);
     407    Assert(!(pVCpu->cpum.s.fUseFlags & CPUM_USE_DEBUG_REGS));
    419408    return VINF_SUCCESS;
    420409}
     
    431420 */
    432421VMMR0DECL(int) CPUMR0LoadGuestDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6)
     422{
     423    /* Save the host state. */
     424    CPUMR0SaveHostDebugState(pVM, pVCpu);
     425    Assert(ASMGetDR7() == X86_DR7_INIT_VAL);
     426
     427    /* Activate the guest state DR0-3; DR7 is left to the caller. */
     428#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
     429    if (CPUMIsGuestInLongModeEx(pCtx))
     430    {
     431        /* Restore the state on entry as we need to be in 64 bits mode to access the full state. */
     432        pVCpu->cpum.s.fUseFlags |= CPUM_SYNC_DEBUG_STATE;
     433    }
     434    else
     435#endif
     436    {
     437#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
     438        cpumR0LoadDRx(&pCtx->dr[0]);
     439#else
     440        ASMSetDR0(pCtx->dr[0]);
     441        ASMSetDR1(pCtx->dr[1]);
     442        ASMSetDR2(pCtx->dr[2]);
     443        ASMSetDR3(pCtx->dr[3]);
     444#endif
     445        if (fDR6)
     446            ASMSetDR6(pCtx->dr[6]);
     447    }
     448
     449    pVCpu->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS;
     450    return VINF_SUCCESS;
     451}
     452
     453/**
     454 * Save the host debug state
     455 *
     456 * @returns VBox status code.
     457 * @param   pVM         VM handle.
     458 * @param   pVCpu       VMCPU handle.
     459 */
     460VMMR0DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu)
    433461{
    434462    /* Save the host state. */
     
    448476    ASMSetDR7(X86_DR7_INIT_VAL);
    449477
     478    return VINF_SUCCESS;
     479}
     480
     481/**
     482 * Load the host debug state
     483 *
     484 * @returns VBox status code.
     485 * @param   pVM         VM handle.
     486 * @param   pVCpu       VMCPU handle.
     487 */
     488VMMR0DECL(int) CPUMR0LoadHostDebugState(PVM pVM, PVMCPU pVCpu)
     489{
     490    Assert(pVCpu->cpum.s.fUseFlags & (CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HYPER));
     491
     492    /*
     493     * Restore the host's debug state. DR0-3, DR6 and only then DR7!
     494     * DR7 contains 0x400 right now.
     495     */
     496#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
     497    AssertCompile((uintptr_t)&pVCpu->cpum.s.Host.dr3 - (uintptr_t)&pVCpu->cpum.s.Host.dr0 == sizeof(uint64_t) * 3);
     498    cpumR0LoadDRx(&pVCpu->cpum.s.Host.dr0);
     499#else
     500    ASMSetDR0(pVCpu->cpum.s.Host.dr0);
     501    ASMSetDR1(pVCpu->cpum.s.Host.dr1);
     502    ASMSetDR2(pVCpu->cpum.s.Host.dr2);
     503    ASMSetDR3(pVCpu->cpum.s.Host.dr3);
     504#endif
     505    ASMSetDR6(pVCpu->cpum.s.Host.dr6);
     506    ASMSetDR7(pVCpu->cpum.s.Host.dr7);
     507
     508    pVCpu->cpum.s.fUseFlags &= ~(CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HYPER);
     509    return VINF_SUCCESS;
     510}
     511
     512
     513/**
     514 * Lazily sync in the hypervisor debug state
     515 *
     516 * @returns VBox status code.
     517 * @param   pVM         VM handle.
     518 * @param   pVCpu       VMCPU handle.
     519 * @param   pCtx        CPU context
     520 * @param   fDR6        Include DR6 or not
     521 */
     522VMMR0DECL(int) CPUMR0LoadHyperDebugState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, bool fDR6)
     523{
     524    /* Save the host state. */
     525    CPUMR0SaveHostDebugState(pVM, pVCpu);
     526    Assert(ASMGetDR7() == X86_DR7_INIT_VAL);
     527
    450528    /* Activate the guest state DR0-3; DR7 is left to the caller. */
    451529#if HC_ARCH_BITS == 32 && defined(VBOX_WITH_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
    452530    if (CPUMIsGuestInLongModeEx(pCtx))
    453531    {
    454         /* Restore the state on entry as we need to be in 64 bits mode to access the full state. */
    455         pVCpu->cpum.s.fUseFlags |= CPUM_SYNC_DEBUG_STATE;
     532        AssertFailed();
     533        return VERR_NOT_IMPLEMENTED;
    456534    }
    457535    else
     
    459537    {
    460538#ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
    461         cpumR0LoadDRx(&pCtx->dr[0]);
     539        AssertFailed();
     540        return VERR_NOT_IMPLEMENTED;
    462541#else
    463         ASMSetDR0(pCtx->dr[0]);
    464         ASMSetDR1(pCtx->dr[1]);
    465         ASMSetDR2(pCtx->dr[2]);
    466         ASMSetDR3(pCtx->dr[3]);
     542        ASMSetDR0(CPUMGetHyperDR0(pVCpu));
     543        ASMSetDR1(CPUMGetHyperDR1(pVCpu));
     544        ASMSetDR2(CPUMGetHyperDR2(pVCpu));
     545        ASMSetDR3(CPUMGetHyperDR3(pVCpu));
    467546#endif
    468547        if (fDR6)
    469             ASMSetDR6(pCtx->dr[6]);
    470     }
    471 
    472     pVCpu->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS;
    473     return VINF_SUCCESS;
    474 }
    475 
    476 
     548            ASMSetDR6(CPUMGetHyperDR6(pVCpu));
     549    }
     550
     551    pVCpu->cpum.s.fUseFlags |= CPUM_USE_DEBUG_REGS_HYPER;
     552    return VINF_SUCCESS;
     553}
     554
     555
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r21210 r21252  
    753753        pVMCB->guest.u64DR6 = pCtx->dr[6];
    754754
     755#ifdef DEBUG
     756        /* Sync the hypervisor debug state now if any breakpoint is armed. */
     757        if (    CPUMGetHyperDR7(pVCpu) & (X86_DR7_ENABLED_MASK|X86_DR7_GD)
     758            &&  !CPUMIsHyperDebugStateActive(pVCpu)
     759            &&  !DBGFIsStepping(pVCpu))
     760        {
     761            /* Save the host and load the hypervisor debug state. */
     762            int rc = CPUMR0LoadHyperDebugState(pVM, pVCpu, pCtx, false /* exclude DR6 */);
     763            AssertRC(rc);
     764
     765            /* DRx intercepts remain enabled. */
     766
     767            /* Override dr6 & dr7 with the hypervisor values. */
     768            pVMCB->guest.u64DR7 = CPUMGetHyperDR7(pVCpu);
     769            pVMCB->guest.u64DR6 = CPUMGetHyperDR6(pVCpu);
     770        }
     771        else
     772#endif
    755773        /* Sync the debug state now if any breakpoint is armed. */
    756774        if (    (pCtx->dr[7] & (X86_DR7_ENABLED_MASK|X86_DR7_GD))
     
    26202638    Assert(pVM->hwaccm.s.svm.fSupported);
    26212639
     2640#ifdef DEBUG
     2641    if (CPUMIsHyperDebugStateActive(pVCpu))
     2642    {
     2643        CPUMR0LoadHostDebugState(pVM, pVCpu);
     2644    }
     2645    else
     2646#endif
    26222647    /* Save the guest debug state if necessary. */
    26232648    if (CPUMIsGuestDebugStateActive(pVCpu))
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r21210 r21252  
    15881588        AssertRC(rc);
    15891589
     1590#ifdef DEBUG
     1591        /* Sync the hypervisor debug state now if any breakpoint is armed. */
     1592        if (    CPUMGetHyperDR7(pVCpu) & (X86_DR7_ENABLED_MASK|X86_DR7_GD)
     1593            &&  !CPUMIsHyperDebugStateActive(pVCpu)
     1594            &&  !DBGFIsStepping(pVCpu))
     1595        {
     1596            /* Save the host and load the hypervisor debug state. */
     1597            rc = CPUMR0LoadHyperDebugState(pVM, pVCpu, pCtx, true /* include DR6 */);
     1598            AssertRC(rc);
     1599
     1600            /* DRx intercepts remain enabled. */
     1601
     1602            /* Override dr7 with the hypervisor value. */
     1603            rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_DR7, CPUMGetHyperDR7(pVCpu));
     1604            AssertRC(rc);
     1605        }
     1606        else
     1607#endif
    15901608        /* Sync the debug state now if any breakpoint is armed. */
    15911609        if (    (pCtx->dr[7] & (X86_DR7_ENABLED_MASK|X86_DR7_GD))
     
    38003818    Assert(pVM->hwaccm.s.vmx.fSupported);
    38013819
     3820#ifdef DEBUG
     3821    if (CPUMIsHyperDebugStateActive(pVCpu))
     3822    {
     3823        CPUMR0LoadHostDebugState(pVM, pVCpu);
     3824    }
     3825    else
     3826#endif
    38023827    /* Save the guest debug state if necessary. */
    38033828    if (CPUMIsGuestDebugStateActive(pVCpu))
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette