VirtualBox

Changeset 97562 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Nov 16, 2022 2:34:26 AM (2 years ago)
Author:
vboxsync
Message:

VMM/HMVMX,CPUM: Added a HM/AlwaysInterceptVmxMovDRx config for controlling how we deal with DR6.RTM & DR7.RTM and similar. Current default (-1) is the old behaviour of ignoring the issue, will change that to hide these new bits in a few hours.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h

    r97335 r97562  
    71447144                        | (pVmxTransient->uExitQual & (  X86_DR6_B0 | X86_DR6_B1 | X86_DR6_B2 | X86_DR6_B3
    71457145                                                       | X86_DR6_BD | X86_DR6_BS));
     7146    Log6Func(("uDR6=%#RX64 uExitQual=%#RX64\n", uDR6, pVmxTransient->uExitQual));
    71467147
    71477148    int rc;
     
    71707171         * The exception was for the guest.  Update DR6, DR7.GD and
    71717172         * IA32_DEBUGCTL.LBR before forwarding it.
    7172          * See Intel spec. 27.1 "Architectural State before a VM-Exit".
     7173         * See Intel spec. 27.1 "Architectural State before a VM-Exit"
     7174         * and @sdmv3{077,622,17.2.3,Debug Status Register (DR6)}.
    71737175         */
    71747176#ifndef IN_NEM_DARWIN
     
    91709172    {
    91719173        /* We should -not- get this VM-exit if the guest's debug registers were active. */
    9172         if (pVmxTransient->fWasGuestDebugStateActive)
     9174        if (   pVmxTransient->fWasGuestDebugStateActive
     9175#ifdef VMX_WITH_MAYBE_ALWAYS_INTERCEPT_MOV_DRX
     9176            && !pVCpu->CTX_SUFF(pVM)->hmr0.s.vmx.fAlwaysInterceptMovDRx
     9177#endif
     9178           )
    91739179        {
    91749180            AssertMsgFailed(("Unexpected MOV DRx exit\n"));
     
    91829188            Assert(pVmcsInfo->u32XcptBitmap & RT_BIT(X86_XCPT_DB));
    91839189
    9184             /* Don't intercept MOV DRx any more. */
    9185             pVmcsInfo->u32ProcCtls &= ~VMX_PROC_CTLS_MOV_DR_EXIT;
    9186             int rc = VMX_VMCS_WRITE_32(pVCpu, VMX_VMCS32_CTRL_PROC_EXEC, pVmcsInfo->u32ProcCtls);
    9187             AssertRC(rc);
     9190            /* Whether we disable intercepting MOV DRx instructions and resume
     9191               the current one, or emulate it and keep intercepting them is
     9192               configurable.  Though it usually comes down to whether there are
     9193               any new DR6 & DR7 bits (RTM) we want to hide from the guest. */
     9194#ifdef VMX_WITH_MAYBE_ALWAYS_INTERCEPT_MOV_DRX
     9195            bool const fResumeInstruction = !pVCpu->CTX_SUFF(pVM)->hmr0.s.vmx.fAlwaysInterceptMovDRx;
     9196#else
     9197            bool const fResumeInstruction = true;
     9198#endif
     9199            if (fResumeInstruction)
     9200            {
     9201                pVmcsInfo->u32ProcCtls &= ~VMX_PROC_CTLS_MOV_DR_EXIT;
     9202                int rc = VMX_VMCS_WRITE_32(pVCpu, VMX_VMCS32_CTRL_PROC_EXEC, pVmcsInfo->u32ProcCtls);
     9203                AssertRC(rc);
     9204            }
    91889205
    91899206#ifndef IN_NEM_DARWIN
     
    92049221#endif
    92059222
     9223            STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatDRxContextSwitch);
     9224            if (fResumeInstruction)
     9225            {
    92069226#ifdef VBOX_WITH_STATISTICS
    9207             vmxHCReadToTransient<HMVMX_READ_EXIT_QUALIFICATION>(pVCpu, pVmxTransient);
    9208             if (VMX_EXIT_QUAL_DRX_DIRECTION(pVmxTransient->uExitQual) == VMX_EXIT_QUAL_DRX_DIRECTION_WRITE)
    9209                 STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatExitDRxWrite);
    9210             else
    9211                 STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatExitDRxRead);
    9212 #endif
    9213             STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatDRxContextSwitch);
    9214             return VINF_SUCCESS;
     9227                vmxHCReadToTransient<HMVMX_READ_EXIT_QUALIFICATION>(pVCpu, pVmxTransient);
     9228                if (VMX_EXIT_QUAL_DRX_DIRECTION(pVmxTransient->uExitQual) == VMX_EXIT_QUAL_DRX_DIRECTION_WRITE)
     9229                    STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatExitDRxWrite);
     9230                else
     9231                    STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatExitDRxRead);
     9232#endif
     9233                return VINF_SUCCESS;
     9234            }
    92159235        }
    92169236    }
     
    92269246                                   | CPUMCTX_EXTRN_DR7>(pVCpu, pVmcsInfo, __FUNCTION__);
    92279247    AssertRCReturn(rc, rc);
    9228     Log4Func(("cs:rip=%#04x:%08RX64\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip));
    92299248
    92309249    uint8_t const iGReg  = VMX_EXIT_QUAL_DRX_GENREG(pVmxTransient->uExitQual);
    92319250    uint8_t const iDrReg = VMX_EXIT_QUAL_DRX_REGISTER(pVmxTransient->uExitQual);
     9251    Log4Func(("cs:rip=%#04x:%08RX64 r%d %s dr%d\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, iGReg,
     9252              VMX_EXIT_QUAL_DRX_DIRECTION(pVmxTransient->uExitQual) == VMX_EXIT_QUAL_DRX_DIRECTION_WRITE ? "->" : "<-", iDrReg));
    92329253
    92339254    VBOXSTRICTRC  rcStrict;
     
    92429263
    92439264        if (rcStrict == VINF_SUCCESS)
     9265       {
    92449266            /** @todo r=bird: Not sure why we always flag DR7 as modified here, but I've
    92459267             * kept it for now to avoid breaking something non-obvious. */
    92469268            ASMAtomicUoOrU64(&VCPU_2_VMXSTATE(pVCpu).fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS
    92479269                                                                | HM_CHANGED_GUEST_DR7);
     9270            /* Update the DR6 register if guest debug state is active, otherwise we'll
     9271               trash it when calling CPUMR0DebugStateMaybeSaveGuestAndRestoreHost. */
     9272            if (iDrReg == 6 && CPUMIsGuestDebugStateActive(pVCpu))
     9273                ASMSetDR6(pVCpu->cpum.GstCtx.dr[6]);
     9274            Log4Func(("r%d=%#RX64 => dr%d=%#RX64\n", iGReg, pVCpu->cpum.GstCtx.aGRegs[iGReg].u,
     9275                      iDrReg, pVCpu->cpum.GstCtx.dr[iDrReg]));
     9276        }
    92489277        else if (rcStrict == VINF_IEM_RAISED_XCPT)
    92499278        {
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