VirtualBox

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


Ignore:
Timestamp:
Aug 2, 2017 9:03:02 AM (7 years ago)
Author:
vboxsync
Message:

VMM/IEM: Updates for SVM R0 nested bits.

File:
1 edited

Legend:

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

    r68150 r68227  
    120120         * Save the nested-guest state into the VMCB state-save area.
    121121         */
    122         SVMVMCBSTATESAVE VmcbNstGst;
    123         HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, ES, es);
    124         HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, CS, cs);
    125         HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, SS, ss);
    126         HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, &VmcbNstGst, DS, ds);
    127         VmcbNstGst.GDTR.u32Limit = pCtx->gdtr.cbGdt;
    128         VmcbNstGst.GDTR.u64Base  = pCtx->gdtr.pGdt;
    129         VmcbNstGst.IDTR.u32Limit = pCtx->idtr.cbIdt;
    130         VmcbNstGst.IDTR.u64Base  = pCtx->idtr.pIdt;
    131         VmcbNstGst.u64EFER       = pCtx->msrEFER;
    132         VmcbNstGst.u64CR4        = pCtx->cr4;
    133         VmcbNstGst.u64CR3        = pCtx->cr3;
    134         VmcbNstGst.u64CR2        = pCtx->cr2;
    135         VmcbNstGst.u64CR0        = pCtx->cr0;
     122        PSVMVMCB           pVmcbNstGst      = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
     123        PSVMVMCBCTRL       pVmcbNstGstCtrl  = &pVmcbNstGst->ctrl;
     124        PSVMVMCBSTATESAVE  pVmcbNstGstState = &pVmcbNstGst->guest;
     125
     126        HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, ES, es);
     127        HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, CS, cs);
     128        HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, SS, ss);
     129        HMSVM_SEG_REG_COPY_TO_VMCB(pCtx, pVmcbNstGstState, DS, ds);
     130        pVmcbNstGstState->GDTR.u32Limit = pCtx->gdtr.cbGdt;
     131        pVmcbNstGstState->GDTR.u64Base  = pCtx->gdtr.pGdt;
     132        pVmcbNstGstState->IDTR.u32Limit = pCtx->idtr.cbIdt;
     133        pVmcbNstGstState->IDTR.u64Base  = pCtx->idtr.pIdt;
     134        pVmcbNstGstState->u64EFER       = pCtx->msrEFER;
     135        pVmcbNstGstState->u64CR4        = pCtx->cr4;
     136        pVmcbNstGstState->u64CR3        = pCtx->cr3;
     137        pVmcbNstGstState->u64CR2        = pCtx->cr2;
     138        pVmcbNstGstState->u64CR0        = pCtx->cr0;
    136139        /** @todo Nested paging. */
    137         VmcbNstGst.u64RFlags     = pCtx->rflags.u64;
    138         VmcbNstGst.u64RIP        = pCtx->rip;
    139         VmcbNstGst.u64RSP        = pCtx->rsp;
    140         VmcbNstGst.u64RAX        = pCtx->rax;
    141         VmcbNstGst.u64DR7        = pCtx->dr[6];
    142         VmcbNstGst.u64DR6        = pCtx->dr[7];
    143         VmcbNstGst.u8CPL         = pCtx->ss.Attr.n.u2Dpl;   /* See comment in CPUMGetGuestCPL(). */
     140        pVmcbNstGstState->u64RFlags     = pCtx->rflags.u64;
     141        pVmcbNstGstState->u64RIP        = pCtx->rip;
     142        pVmcbNstGstState->u64RSP        = pCtx->rsp;
     143        pVmcbNstGstState->u64RAX        = pCtx->rax;
     144        pVmcbNstGstState->u64DR7        = pCtx->dr[6];
     145        pVmcbNstGstState->u64DR6        = pCtx->dr[7];
     146        pVmcbNstGstState->u8CPL         = pCtx->ss.Attr.n.u2Dpl;   /* See comment in CPUMGetGuestCPL(). */
    144147        Assert(CPUMGetGuestCPL(pVCpu) == pCtx->ss.Attr.n.u2Dpl);
    145148
     
    201204
    202205        /*
    203          * Write back the VMCB controls to the guest VMCB in guest physical memory.
    204          */
    205         VBOXSTRICTRC rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), pCtx->hwvirt.svm.GCPhysVmcb, pVmcbCtrl,
    206                                                          sizeof(*pVmcbCtrl));
     206         * Notify HM in case the VMRUN was executed using SVM R0, HM would have modified some VMCB
     207         * state that we need to restore on #VMEXIT before writing it back to guest memory.
     208         */
     209        HMSvmNstGstVmExitNotify(pVCpu, pVmcbNstGst);
     210
     211        /*
     212         * Write back the nested-guest's VMCB to its guest physical memory location.
     213         */
     214        VBOXSTRICTRC rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), pCtx->hwvirt.svm.GCPhysVmcb, pVmcbNstGst,
     215                                                         sizeof(*pVmcbNstGst));
    207216        /*
    208217         * Prepare for guest's "host mode" by clearing internal processor state bits.
    209218         *
    210          * Some of these like TSC offset can then be used unconditionally in our TM code
    211          * but the offset in the guest's VMCB will remain as it should as we've written
    212          * back the VMCB controls above.
    213          */
    214         memset(pVmcbCtrl, 0, sizeof(*pVmcbCtrl));
     219         * We don't need to zero out the state-save area, just the controls should be
     220         * sufficient because it has the critical bit of indicating whether we're inside
     221         * the nested-guest or not.
     222         */
     223        memset(pVmcbNstGstCtrl, 0, sizeof(*pVmcbNstGstCtrl));
    215224        Assert(!CPUMIsGuestInSvmNestedHwVirtMode(pCtx));
    216225
    217226        if (RT_SUCCESS(rcStrict))
    218227        {
    219             rcStrict = PGMPhysSimpleWriteGCPhys(pVCpu->CTX_SUFF(pVM), pCtx->hwvirt.svm.GCPhysVmcb + RT_OFFSETOF(SVMVMCB, guest),
    220                                                 &VmcbNstGst, sizeof(VmcbNstGst));
     228            /** @todo Nested paging. */
     229            /** @todo ASID. */
     230
     231            /*
     232             * Reload the guest's "host state".
     233             */
     234            CPUMSvmVmExitRestoreHostState(pCtx);
     235
     236            /*
     237             * Update PGM, IEM and others of a world-switch.
     238             */
     239            rcStrict = iemSvmWorldSwitch(pVCpu, pCtx);
     240            if (rcStrict == VINF_SUCCESS)
     241                return VINF_SVM_VMEXIT;
     242
    221243            if (RT_SUCCESS(rcStrict))
    222244            {
    223                 /** @todo Nested paging. */
    224                 /** @todo ASID. */
    225 
    226                 /*
    227                  * Reload the guest's "host state".
    228                  */
    229                 PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
    230                 pCtx->es         = pHostState->es;
    231                 pCtx->cs         = pHostState->cs;
    232                 pCtx->ss         = pHostState->ss;
    233                 pCtx->ds         = pHostState->ds;
    234                 pCtx->gdtr       = pHostState->gdtr;
    235                 pCtx->idtr       = pHostState->idtr;
    236                 pCtx->msrEFER    = pHostState->uEferMsr;
    237                 pCtx->cr0        = pHostState->uCr0 | X86_CR0_PE;
    238                 pCtx->cr3        = pHostState->uCr3;
    239                 pCtx->cr4        = pHostState->uCr4;
    240                 pCtx->rflags     = pHostState->rflags;
    241                 pCtx->rflags.Bits.u1VM = 0;
    242                 pCtx->rip        = pHostState->uRip;
    243                 pCtx->rsp        = pHostState->uRsp;
    244                 pCtx->rax        = pHostState->uRax;
    245                 pCtx->dr[7]     &= ~(X86_DR7_ENABLED_MASK | X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK);
    246                 pCtx->dr[7]     |= X86_DR7_RA1_MASK;
    247 
    248                 /** @todo if RIP is not canonical or outside the CS segment limit, we need to
    249                  *        raise \#GP(0) in the guest. */
    250 
    251                 /** @todo check the loaded host-state for consistency. Figure out what
    252                  *        exactly this involves? */
    253 
    254                 /* Restore guest's force-flags. */
    255                 if (pCtx->hwvirt.fLocalForcedActions)
    256                 {
    257                     VMCPU_FF_SET(pVCpu, pCtx->hwvirt.fLocalForcedActions);
    258                     pCtx->hwvirt.fLocalForcedActions = 0;
    259                 }
    260 
    261                 /*
    262                  * Update PGM, IEM and others of a world-switch.
    263                  */
    264                 rcStrict = iemSvmWorldSwitch(pVCpu, pCtx);
    265                 if (rcStrict == VINF_SUCCESS)
    266                     return VINF_SVM_VMEXIT;
    267 
    268                 if (RT_SUCCESS(rcStrict))
    269                 {
    270                     LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", rcStrict));
    271                     iemSetPassUpStatus(pVCpu, rcStrict);
    272                     return VINF_SVM_VMEXIT;
    273                 }
    274 
    275                 LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     245                LogFlow(("iemSvmVmexit: Setting passup status from iemSvmWorldSwitch %Rrc\n", rcStrict));
     246                iemSetPassUpStatus(pVCpu, rcStrict);
     247                return VINF_SVM_VMEXIT;
    276248            }
    277             else
    278                 LogFlow(("iemSvmVmexit: Writing VMCB guest-state at %#RGp failed. rc=%Rrc\n", pCtx->hwvirt.svm.GCPhysVmcb,
    279                          VBOXSTRICTRC_VAL(rcStrict)));
     249
     250            LogFlow(("iemSvmVmexit: iemSvmWorldSwitch unexpected failure. rc=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    280251        }
    281252        else
    282             LogFlow(("iemSvmVmexit: Writing VMCB guest-controls at %#RGp failed. rc=%Rrc\n", pCtx->hwvirt.svm.GCPhysVmcb,
     253            LogFlow(("iemSvmVmexit: Writing VMCB at %#RGp failed. rc=%Rrc\n", pCtx->hwvirt.svm.GCPhysVmcb,
    283254                     VBOXSTRICTRC_VAL(rcStrict)));
    284255
     
    326297     * Save the host state.
    327298     */
    328     PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
    329     pHostState->es       = pCtx->es;
    330     pHostState->cs       = pCtx->cs;
    331     pHostState->ss       = pCtx->ss;
    332     pHostState->ds       = pCtx->ds;
    333     pHostState->gdtr     = pCtx->gdtr;
    334     pHostState->idtr     = pCtx->idtr;
    335     pHostState->uEferMsr = pCtx->msrEFER;
    336     pHostState->uCr0     = pCtx->cr0;
    337     pHostState->uCr3     = pCtx->cr3;
    338     pHostState->uCr4     = pCtx->cr4;
    339     pHostState->rflags   = pCtx->rflags;
    340     pHostState->uRip     = pCtx->rip + cbInstr;
    341     pHostState->uRsp     = pCtx->rsp;
    342     pHostState->uRax     = pCtx->rax;
     299    CPUMSvmVmRunSaveHostState(pCtx, cbInstr);
    343300
    344301    /*
     
    977934    Log3(("iemSvmHandleIOIntercept: u16Port=%#x (%u)\n", u16Port, u16Port));
    978935
     936#if 1
     937    SVMIOIOEXITINFO IoExitInfo;
     938    PCPUMCTX pCtx = IEM_GET_CTX(pVCpu);
     939    void *pvIoBitmap = pCtx->hwvirt.svm.CTX_SUFF(pvIoBitmap);
     940    bool const fIntercept = HMSvmIsIOInterceptActive(pvIoBitmap, u16Port, enmIoType, cbReg, cAddrSizeBits, iEffSeg, fRep, fStrIo,
     941                                                     &IoExitInfo);
     942    if (fIntercept)
     943    {
     944        Log3(("iemSvmHandleIOIntercept: u16Port=%#x (%u) -> #VMEXIT\n", u16Port, u16Port));
     945        return iemSvmVmexit(pVCpu, pCtx, SVM_EXIT_IOIO, IoExitInfo.u, pCtx->rip + cbInstr);
     946    }
     947#else
    979948    /*
    980949     * The IOPM layout:
     
    1011980        IoExitInfo.u         = s_auIoOpSize[cbReg & 7];
    1012981        IoExitInfo.u        |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7];
    1013         IoExitInfo.n.u1STR   = fStrIo;
     982        IoExitInfo.n.u1STR   = iemSvmVmexitfStrIo;
    1014983        IoExitInfo.n.u1REP   = fRep;
    1015984        IoExitInfo.n.u3SEG   = iEffSeg & 7;
     
    1021990        return iemSvmVmexit(pVCpu, pCtx, SVM_EXIT_IOIO, IoExitInfo.u, pCtx->rip + cbInstr);
    1022991    }
     992#endif
    1023993
    1024994    /** @todo remove later (for debugging as VirtualBox always traps all IO
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