VirtualBox

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


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

VMM: Nested Hw.virt: SVM R0 bits.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
2 edited

Legend:

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

    r67924 r68226  
    26242624}
    26252625
     2626
     2627/**
     2628 * Restores the host-state from the host-state save area as part of a \#VMEXIT.
     2629 *
     2630 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
     2631 * @param   pCtx        The guest-CPU context.
     2632 */
     2633VMM_INT_DECL(void) CPUMSvmVmExitRestoreHostState(PCPUMCTX pCtx)
     2634{
     2635   /*
     2636     * Reload the guest's "host state".
     2637     */
     2638    PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
     2639    pCtx->es         = pHostState->es;
     2640    pCtx->cs         = pHostState->cs;
     2641    pCtx->ss         = pHostState->ss;
     2642    pCtx->ds         = pHostState->ds;
     2643    pCtx->gdtr       = pHostState->gdtr;
     2644    pCtx->idtr       = pHostState->idtr;
     2645    pCtx->msrEFER    = pHostState->uEferMsr;
     2646    pCtx->cr0        = pHostState->uCr0 | X86_CR0_PE;
     2647    pCtx->cr3        = pHostState->uCr3;
     2648    pCtx->cr4        = pHostState->uCr4;
     2649    pCtx->rflags     = pHostState->rflags;
     2650    pCtx->rflags.Bits.u1VM = 0;
     2651    pCtx->rip        = pHostState->uRip;
     2652    pCtx->rsp        = pHostState->uRsp;
     2653    pCtx->rax        = pHostState->uRax;
     2654    pCtx->dr[7]     &= ~(X86_DR7_ENABLED_MASK | X86_DR7_RAZ_MASK | X86_DR7_MBZ_MASK);
     2655    pCtx->dr[7]     |= X86_DR7_RA1_MASK;
     2656
     2657    /** @todo if RIP is not canonical or outside the CS segment limit, we need to
     2658     *        raise \#GP(0) in the guest. */
     2659
     2660    /** @todo check the loaded host-state for consistency. Figure out what
     2661     *        exactly this involves? */
     2662}
     2663
     2664
     2665/**
     2666 * Saves the host-state to the host-state save area as part of a VMRUN.
     2667 *
     2668 * @param   pVCpu       The cross context virtual CPU structure of the calling EMT.
     2669 * @param   pCtx        The guest-CPU context.
     2670 * @param   cbInstr     The length of the VMRUN instruction in bytes.
     2671 */
     2672VMM_INT_DECL(void) CPUMSvmVmRunSaveHostState(PCPUMCTX pCtx, uint8_t cbInstr)
     2673{
     2674    PSVMHOSTSTATE pHostState = &pCtx->hwvirt.svm.HostState;
     2675    pHostState->es       = pCtx->es;
     2676    pHostState->cs       = pCtx->cs;
     2677    pHostState->ss       = pCtx->ss;
     2678    pHostState->ds       = pCtx->ds;
     2679    pHostState->gdtr     = pCtx->gdtr;
     2680    pHostState->idtr     = pCtx->idtr;
     2681    pHostState->uEferMsr = pCtx->msrEFER;
     2682    pHostState->uCr0     = pCtx->cr0;
     2683    pHostState->uCr3     = pCtx->cr3;
     2684    pHostState->uCr4     = pCtx->cr4;
     2685    pHostState->rflags   = pCtx->rflags;
     2686    pHostState->uRip     = pCtx->rip + cbInstr;
     2687    pHostState->uRsp     = pCtx->rsp;
     2688    pHostState->uRax     = pCtx->rax;
     2689}
     2690
  • trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp

    r67529 r68226  
    258258}
    259259
     260
     261/**
     262 * Determines whether an IOIO intercept is active for the nested-guest or not.
     263 *
     264 * @param   pvIoBitmap      Pointer to the nested-guest IO bitmap.
     265 * @param   u16Port         The IO port being accessed.
     266 * @param   enmIoType       The type of IO access.
     267 * @param   cbReg           The IO operand size in bytes.
     268 * @param   cAddrSizeBits   The address size bits (for 16, 32 or 64).
     269 * @param   iEffSeg         The effective segment number.
     270 * @param   fRep            Whether this is a repeating IO instruction (REP prefix).
     271 * @param   fStrIo          Whether this is a string IO instruction.
     272 * @param   pIoExitInfo     Pointer to the SVMIOIOEXITINFO struct to be filled.
     273 *                          Optional, can be NULL.
     274 */
     275VMM_INT_DECL(bool) HMSvmIsIOInterceptActive(void *pvIoBitmap, uint16_t u16Port, SVMIOIOTYPE enmIoType, uint8_t cbReg,
     276                                            uint8_t cAddrSizeBits, uint8_t iEffSeg, bool fRep, bool fStrIo,
     277                                            PSVMIOIOEXITINFO pIoExitInfo)
     278{
     279    Assert(cAddrSizeBits == 0 || cAddrSizeBits == 16 || cAddrSizeBits == 32 || cAddrSizeBits == 64);
     280    Assert(cbReg == 1 || cbReg == 2 || cbReg == 4 || cbReg == 8);
     281
     282    /*
     283     * The IOPM layout:
     284     * Each bit represents one 8-bit port. That makes a total of 0..65535 bits or
     285     * two 4K pages.
     286     *
     287     * For IO instructions that access more than a single byte, the permission bits
     288     * for all bytes are checked; if any bit is set to 1, the IO access is intercepted.
     289     *
     290     * Since it's possible to do a 32-bit IO access at port 65534 (accessing 4 bytes),
     291     * we need 3 extra bits beyond the second 4K page.
     292     */
     293    static const uint16_t s_auSizeMasks[] = { 0, 1, 3, 0, 0xf, 0, 0, 0 };
     294
     295    uint16_t const offIopm   = u16Port >> 3;
     296    uint16_t const fSizeMask = s_auSizeMasks[(cAddrSizeBits >> SVM_IOIO_OP_SIZE_SHIFT) & 7];
     297    uint8_t  const cShift    = u16Port - (offIopm << 3);
     298    uint16_t const fIopmMask = (1 << cShift) | (fSizeMask << cShift);
     299
     300    uint8_t const *pbIopm = (uint8_t *)pvIoBitmap;
     301    Assert(pbIopm);
     302    pbIopm += offIopm;
     303    uint16_t const u16Iopm = *(uint16_t *)pbIopm;
     304    if (u16Iopm & fIopmMask)
     305    {
     306        if (pIoExitInfo)
     307        {
     308            static const uint32_t s_auIoOpSize[] =
     309            { SVM_IOIO_32_BIT_OP, SVM_IOIO_8_BIT_OP, SVM_IOIO_16_BIT_OP, 0, SVM_IOIO_32_BIT_OP, 0, 0, 0 };
     310
     311            static const uint32_t s_auIoAddrSize[] =
     312            { 0, SVM_IOIO_16_BIT_ADDR, SVM_IOIO_32_BIT_ADDR, 0, SVM_IOIO_64_BIT_ADDR, 0, 0, 0 };
     313
     314            pIoExitInfo->u         = s_auIoOpSize[cbReg & 7];
     315            pIoExitInfo->u        |= s_auIoAddrSize[(cAddrSizeBits >> 4) & 7];
     316            pIoExitInfo->n.u1STR   = fStrIo;
     317            pIoExitInfo->n.u1REP   = fRep;
     318            pIoExitInfo->n.u3SEG   = iEffSeg & 7;
     319            pIoExitInfo->n.u1Type  = enmIoType;
     320            pIoExitInfo->n.u16Port = u16Port;
     321        }
     322        return true;
     323    }
     324
     325    /** @todo remove later (for debugging as VirtualBox always traps all IO
     326     *        intercepts). */
     327    AssertMsgFailed(("iemSvmHandleIOIntercept: We expect an IO intercept here!\n"));
     328    return false;
     329}
     330
     331
     332/**
     333 * Notification callback for when a \#VMEXIT happens outside SVM R0 code (e.g.
     334 * in IEM).
     335 *
     336 * @param   pVCpu           The cross context virtual CPU structure.
     337 * @param   pVmcbNstGst     Pointer to the nested-guest VM control block.
     338 *
     339 * @sa      hmR0SvmVmRunCacheVmcb.
     340 */
     341VMM_INT_DECL(void) HMSvmNstGstVmExitNotify(PVMCPU pVCpu, PSVMVMCB pVmcbNstGst)
     342{
     343    PSVMVMCBCTRL        pVmcbCtrl        = &pVmcbNstGst->ctrl;
     344    PSVMNESTEDVMCBCACHE pNstGstVmcbCache = &pVCpu->hm.s.svm.NstGstVmcbCache;
     345
     346    /*
     347     * Restore the nested-guest VMCB fields which have been modified for executing
     348     * the nested-guest under SVM R0.
     349     */
     350    if (pNstGstVmcbCache->fValid)
     351    {
     352        pVmcbCtrl->u16InterceptRdCRx        = pNstGstVmcbCache->u16InterceptRdCRx;
     353        pVmcbCtrl->u16InterceptWrCRx        = pNstGstVmcbCache->u16InterceptWrCRx;
     354        pVmcbCtrl->u16InterceptRdCRx        = pNstGstVmcbCache->u16InterceptRdCRx;
     355        pVmcbCtrl->u16InterceptWrDRx        = pNstGstVmcbCache->u16InterceptWrDRx;
     356        pVmcbCtrl->u32InterceptXcpt         = pNstGstVmcbCache->u32InterceptXcpt;
     357        pVmcbCtrl->u64InterceptCtrl         = pNstGstVmcbCache->u64InterceptCtrl;
     358        pVmcbCtrl->u64VmcbCleanBits         = pNstGstVmcbCache->u64VmcbCleanBits;
     359        pVmcbCtrl->u64IOPMPhysAddr          = pNstGstVmcbCache->u64IOPMPhysAddr;
     360        pVmcbCtrl->u64MSRPMPhysAddr         = pNstGstVmcbCache->u64MSRPMPhysAddr;
     361        pVmcbCtrl->IntCtrl.n.u1VIntrMasking = pNstGstVmcbCache->fVIntrMasking;
     362        pNstGstVmcbCache->fValid = false;
     363    }
     364    pNstGstVmcbCache->fVmrunEmulatedInR0 = false;
     365}
     366
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