VirtualBox

Ignore:
Timestamp:
May 15, 2012 12:28:47 PM (13 years ago)
Author:
vboxsync
Message:

SVM: Rearranged intercept setup code for clarity.

File:
1 edited

Legend:

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

    r41302 r41309  
    293293        AssertMsgReturn(pVMCB, ("Invalid pVMCB\n"), VERR_HMSVM_INVALID_PVMCB);
    294294
    295         /* Program the control fields. Most of them never have to be changed again. */
    296         /* CR0/3/4 reads must be intercepted, our shadow values are not necessarily the same as the guest's. */
    297         /* Note: CR0 & CR4 can be safely read when guest and shadow copies are identical. */
    298         if (!pVM->hwaccm.s.fNestedPaging)
    299             pVMCB->ctrl.u16InterceptRdCRx = RT_BIT(0) | RT_BIT(3) | RT_BIT(4);
    300         else
    301             pVMCB->ctrl.u16InterceptRdCRx = RT_BIT(0) | RT_BIT(4);
    302 
    303         /*
    304         * CR0/3/4 writes must be intercepted for obvious reasons.
    305         */
    306         if (!pVM->hwaccm.s.fNestedPaging)
    307             pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(3) | RT_BIT(4);
    308         else
    309             pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(4);
     295        /* Program the control fields. Most of them never have to be changed again.
     296         * CR0/4 reads must be intercepted, our shadow values are not necessarily the same as the guest's.
     297         * Note: CR0 & CR4 can be safely read when guest and shadow copies are identical.
     298         */
     299        pVMCB->ctrl.u16InterceptRdCRx = RT_BIT(0) | RT_BIT(4);
     300
     301        /* CR0/4 writes must be intercepted for obvious reasons. */
     302        pVMCB->ctrl.u16InterceptWrCRx = RT_BIT(0) | RT_BIT(4);
    310303
    311304        /* Intercept all DRx reads and writes by default. Changed later on. */
     
    313306        pVMCB->ctrl.u16InterceptWrDRx = 0xFFFF;
    314307
    315         /* Currently we don't care about DRx reads or writes. DRx registers are trashed.
    316         * All breakpoints are automatically cleared when the VM exits.
    317         */
    318 
    319         pVMCB->ctrl.u32InterceptException = HWACCM_SVM_TRAP_MASK;
    320 #ifndef DEBUG
    321         if (pVM->hwaccm.s.fNestedPaging)
    322             pVMCB->ctrl.u32InterceptException &= ~RT_BIT(X86_XCPT_PF);   /* no longer need to intercept #PF. */
    323 #endif
    324 
     308        /* Intercept traps; only #NM is always intercepted. */
     309        pVMCB->ctrl.u32InterceptException  =   RT_BIT(X86_XCPT_NM);
     310#ifdef VBOX_ALWAYS_TRAP_PF
     311        pVMCB->ctrl.u32InterceptException |=   RT_BIT(X86_XCPT_PF);
     312#endif
     313#ifdef VBOX_STRICT
     314        pVMCB->ctrl.u32InterceptException |=   RT_BIT(X86_XCPT_BP)
     315                                             | RT_BIT(X86_XCPT_DB)
     316                                             | RT_BIT(X86_XCPT_DE)
     317                                             | RT_BIT(X86_XCPT_UD)
     318                                             | RT_BIT(X86_XCPT_NP)
     319                                             | RT_BIT(X86_XCPT_SS)
     320                                             | RT_BIT(X86_XCPT_GP)
     321                                             | RT_BIT(X86_XCPT_MF)
     322                                             ;
     323#endif
     324
     325        /* Set up instruction and miscellaneous intercepts. */
    325326        pVMCB->ctrl.u32InterceptCtrl1 =   SVM_CTRL1_INTERCEPT_INTR
    326327                                        | SVM_CTRL1_INTERCEPT_VINTR
     
    334335                                        | SVM_CTRL1_INTERCEPT_INOUT_BITMAP
    335336                                        | SVM_CTRL1_INTERCEPT_MSR_SHADOW
    336                                         | SVM_CTRL1_INTERCEPT_INVLPG
    337337                                        | SVM_CTRL1_INTERCEPT_INVLPGA       /* AMD only */
    338                                         | SVM_CTRL1_INTERCEPT_TASK_SWITCH
    339338                                        | SVM_CTRL1_INTERCEPT_SHUTDOWN      /* fatal */
    340339                                        | SVM_CTRL1_INTERCEPT_FERR_FREEZE;  /* Legacy FPU FERR handling. */
    341340                                        ;
    342         /* With nested paging we don't care about invlpg or task switches anymore. */
    343         if (pVM->hwaccm.s.fNestedPaging)
    344             pVMCB->ctrl.u32InterceptCtrl1 &= ~(SVM_CTRL1_INTERCEPT_INVLPG | SVM_CTRL1_INTERCEPT_TASK_SWITCH);
    345 
    346341        pVMCB->ctrl.u32InterceptCtrl2 =   SVM_CTRL2_INTERCEPT_VMRUN         /* required */
    347342                                        | SVM_CTRL2_INTERCEPT_VMMCALL
     
    371366        pVMCB->ctrl.u64LBRVirt      = 0;
    372367
    373         /** The ASID must start at 1; the host uses 0. */
     368        /* The ASID must start at 1; the host uses 0. */
    374369        pVMCB->ctrl.TLBCtrl.n.u32ASID = 1;
    375370
    376         /** Setup the PAT msr (nested paging only) */
     371        /* Setup the PAT msr (nested paging only) */
    377372        /* The default value should be 0x0007040600070406ULL, but we want to treat all guest memory as WB, so choose type 6 for all PAT slots. */
    378373        pVMCB->guest.u64GPAT = 0x0006060606060606ULL;
     374
     375        /* If nested paging is not in use, additional intercepts have to be set up. */
     376        if (!pVM->hwaccm.s.fNestedPaging)
     377        {
     378            /* CR3 reads/writes must be intercepted; our shadow values are different from guest's. */
     379            pVMCB->ctrl.u16InterceptRdCRx |= RT_BIT(3);
     380            pVMCB->ctrl.u16InterceptWrCRx |= RT_BIT(3);
     381
     382            /* We must also intercept:
     383             * - INVLPG (must go through shadow paging)
     384             * - task switches (may change CR3/EFLAGS/LDT)
     385             */
     386            pVMCB->ctrl.u32InterceptCtrl1 |=   SVM_CTRL1_INTERCEPT_INVLPG
     387                                             | SVM_CTRL1_INTERCEPT_TASK_SWITCH
     388                                             ;
     389
     390            /* Page faults must be intercepted to implement shadow paging. */
     391            pVMCB->ctrl.u32InterceptException |= RT_BIT(X86_XCPT_PF);
     392        }
    379393
    380394        /* The following MSRs are saved automatically by vmload/vmsave, so we allow the guest
     
    17601774            RTGCUINTPTR uFaultAddress  = pVMCB->ctrl.u64ExitInfo2;     /* EXITINFO2 = fault address */
    17611775
    1762 #ifdef DEBUG
     1776#ifdef VBOX_ALWAYS_TRAP_PF
    17631777            if (pVM->hwaccm.s.fNestedPaging)
    17641778            {   /* A genuine pagefault.
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