VirtualBox

Changeset 45617 in vbox for trunk


Ignore:
Timestamp:
Apr 18, 2013 5:56:25 PM (12 years ago)
Author:
vboxsync
Message:

VMMR0/HMVMXR0: Fix MOV DRx intercepts. Haiku now works.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r45609 r45617  
    28062806                    | X86_CR0_CD    /* Bit ignored on VM-entry and VM-exit. Don't let the guest modify the host CR0.CD */
    28072807                    | X86_CR0_NW;   /* Bit ignored on VM-entry and VM-exit. Don't let the guest modify the host CR0.NW */
    2808 
    2809         /* We don't need to intercept changes to CR0.PE with unrestricted guests. */
    28102808        if (pVM->hm.s.vmx.fUnrestrictedGuest)
    28112809            u64CR0Mask &= ~X86_CR0_PE;
     2810        /* Enable this later. */
     2811        /* if (pVM->hm.s.fNestedPaging)
     2812            u64CR0Mask &= ~X86_CR0_WP; */
    28122813
    28132814        /* If the guest FPU state is active, don't need to VM-exit on writes to FPU related bits in CR0. */
     
    28352836    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR3)
    28362837    {
    2837         uint64_t u64GuestCR3 = 0;
     2838        RTGCPHYS GCPhysGuestCR3 = NIL_RTGCPHYS;
    28382839        if (pVM->hm.s.fNestedPaging)
    28392840        {
     
    28742875                /* The guest's view of its CR3 is unblemished with Nested Paging when the guest is using paging or we
    28752876                   have Unrestricted Execution to handle the guest when it's not using paging. */
    2876                 u64GuestCR3 = pCtx->cr3;
     2877                GCPhysGuestCR3 = pCtx->cr3;
    28772878            }
    28782879            else
     
    28912892                AssertRCReturn(rc, rc);
    28922893
    2893                 u64GuestCR3 = GCPhys;
     2894                GCPhysGuestCR3 = GCPhys;
    28942895            }
    28952896        }
     
    28972898        {
    28982899            /* Non-nested paging case, just use the hypervisor's CR3. */
    2899             u64GuestCR3 = PGMGetHyperCR3(pVCpu);
    2900         }
    2901 
    2902         Log(("Load: VMX_VMCS_GUEST_CR3=%#RX64\n", u64GuestCR3));
    2903         rc = VMXWriteVmcsGstN(VMX_VMCS_GUEST_CR3, u64GuestCR3);
     2900            GCPhysGuestCR3 = PGMGetHyperCR3(pVCpu);
     2901        }
     2902
     2903        Log(("Load: VMX_VMCS_GUEST_CR3=%#RGv\n", GCPhysGuestCR3));
     2904        rc = VMXWriteVmcsGstN(VMX_VMCS_GUEST_CR3, GCPhysGuestCR3);
    29042905        AssertRCReturn(rc, rc);
    29052906
     
    29122913    if (pVCpu->hm.s.fContextUseFlags & HM_CHANGED_GUEST_CR4)
    29132914    {
    2914         uint64_t u64GuestCR4 = pCtx->cr4;
     2915        uint32_t u64GuestCR4 = pCtx->cr4;
     2916        Assert(!(pCtx->cr4 >> 32));
    29152917
    29162918        /* The guest's view of its CR4 is unblemished. */
     
    30573059        Assert(fInterceptDB == false);      /* If we are not single stepping in DBGF, there is no need to intercept #DB. */
    30583060
     3061
    30593062    /*
    30603063     * If the guest is using its DRx registers and the host DRx does not yet contain the guest DRx values,
     
    30623065     * The same for the hypervisor DRx registers, priority is for the guest here.
    30633066     */
    3064     if (    (pCtx->dr[7] & (X86_DR7_ENABLED_MASK | X86_DR7_GD))
    3065         && !CPUMIsGuestDebugStateActive(pVCpu))
    3066     {
    3067         /* Save the host and load the guest debug registers. This will make the guest debug state active. */
    3068         rc = CPUMR0LoadGuestDebugState(pVM, pVCpu, pCtx, true /* include DR6 */);
    3069         AssertRC(rc);
     3067    if (pCtx->dr[7] & (X86_DR7_ENABLED_MASK | X86_DR7_GD))
     3068    {
     3069        if (!CPUMIsGuestDebugStateActive(pVCpu))
     3070        {
     3071            rc = CPUMR0LoadGuestDebugState(pVM, pVCpu, pCtx, true /* include DR6 */);
     3072            AssertRC(rc);
     3073            STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxArmed);
     3074        }
    30703075        Assert(CPUMIsGuestDebugStateActive(pVCpu));
    30713076        Assert(fInterceptMovDRx == false);
    3072         STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxArmed);
    3073     }
    3074     else if (    CPUMGetHyperDR7(pVCpu) & (X86_DR7_ENABLED_MASK | X86_DR7_GD)
    3075              && !CPUMIsHyperDebugStateActive(pVCpu))
    3076     {
    3077         /* Save the host and load the hypervisor debug registers. This will make the hyper debug state active. */
    3078         rc = CPUMR0LoadHyperDebugState(pVM, pVCpu, pCtx, true /* include DR6 */);
    3079         AssertRC(rc);
     3077    }
     3078    else if (CPUMGetHyperDR7(pVCpu) & (X86_DR7_ENABLED_MASK | X86_DR7_GD))
     3079    {
     3080        if (!CPUMIsHyperDebugStateActive(pVCpu))
     3081        {
     3082            rc = CPUMR0LoadHyperDebugState(pVM, pVCpu, pCtx, true /* include DR6 */);
     3083            AssertRC(rc);
     3084        }
    30803085        Assert(CPUMIsHyperDebugStateActive(pVCpu));
    30813086        fInterceptMovDRx = true;
    30823087    }
    3083     else
    3084         Assert(fInterceptMovDRx == false);  /* No need to intercept MOV DRx if DBGF is not active nor the guest is debugging. */
     3088    else if (!CPUMIsGuestDebugStateActive(pVCpu))
     3089    {
     3090        /* For the first time we would need to intercept MOV DRx accesses even when the guest debug state isn't active. */
     3091        fInterceptMovDRx = true;
     3092    }
    30853093
    30863094    /* Update the exception bitmap regarding intercepting #DB generated by the guest. */
     
    72287236{
    72297237    VMX_VALIDATE_EXIT_HANDLER_PARAMS();
     7238    PVM pVM = pVCpu->CTX_SUFF(pVM);
     7239    Assert(!pVM->hm.s.fNestedPaging);
     7240
    72307241    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
    72317242    rc    |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
    72327243    AssertRCReturn(rc, rc);
    72337244
    7234     PVM pVM = pVCpu->CTX_SUFF(pVM);
    72357245    VBOXSTRICTRC rc2 = EMInterpretInvlpg(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx), pVmxTransient->uExitQualification);
    72367246    rc = VBOXSTRICTRC_VAL(rc2);
     
    72417251        AssertMsg(rc == VERR_EM_INTERPRETER, ("hmR0VmxExitInvlpg: EMInterpretInvlpg %#RGv failed with %Rrc\n",
    72427252                                              pVmxTransient->uExitQualification, rc));
    7243         rc = VERR_EM_INTERPRETER;
    72447253    }
    72457254    STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInvlpg);
     
    82198228        && !CPUMIsHyperDebugStateActive(pVCpu))
    82208229    {
    8221         Assert(!CPUMIsGuestDebugStateActive(pVCpu));
    8222 
    82238230        /* Don't intercept MOV DRx. */
    82248231        pVCpu->hm.s.vmx.u32ProcCtls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT;
     
    82448251    }
    82458252
    8246     /** @todo clear VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT after the first
    8247      *        time and restore DRx registers afterwards */
    82488253    /*
    82498254     * EMInterpretDRx[Write|Read]() calls CPUMIsGuestIn64BitCode() which requires EFER, CS. EFER is always up-to-date, see
     
    88798884    AssertRCReturn(rc, rc);
    88808885
    8881     Log(("#PF: cr2=%#RGv cs:rip=%#04x:%#RGv uErrCode %#RX32\n", pVmxTransient->uExitQualification, pMixedCtx->cs.Sel,
    8882          pMixedCtx->rip, pVmxTransient->uExitIntrErrorCode));
     8886    Log(("#PF: cr2=%#RGv cs:rip=%#04x:%#RGv uErrCode %#RX32 cr3=%#RGv\n", pVmxTransient->uExitQualification, pMixedCtx->cs.Sel,
     8887         pMixedCtx->rip, pVmxTransient->uExitIntrErrorCode, pMixedCtx->cr3));
    88838888
    88848889    TRPMAssertXcptPF(pVCpu, pVmxTransient->uExitQualification, (RTGCUINT)pVmxTransient->uExitIntrErrorCode);
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