VirtualBox

Changeset 66371 in vbox


Ignore:
Timestamp:
Mar 30, 2017 5:49:00 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
114316
Message:

VMM: Nested Hw.virt: MSR and IO intercept helpers for SVM.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/hm.h

    r66356 r66371  
    159159VMM_INT_DECL(int)               HMSvmNstGstGetInterrupt(PCCPUMCTX pCtx, uint8_t *pu8Interrupt);
    160160VMM_INT_DECL(bool)              HMSvmNstGstIsInterruptPending(PCCPUMCTX pCtx);
    161 VMM_INT_DECL(VBOXSTRICTRC)      HMSvmNstGstHandleCtrlIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t uExitCode,
    162                                                                uint64_t uExitInfo1,uint64_t uExitInfo2);
     161VMM_INT_DECL(VBOXSTRICTRC)      HMSvmNstGstHandleCtrlIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t uExitCode, uint64_t uExitInfo1,
     162                                                               uint64_t uExitInfo2);
    163163VMM_INT_DECL(VBOXSTRICTRC)      HMSvmNstGstHandleMsrIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t idMsr, bool fWrite);
     164VMM_INT_DECL(VBOXSTRICTRC)      HMSvmNstGstHandleIOIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, PCSVMIOIOEXITINFO pIoExitInfo,
     165                                                             uint64_t uNextRip);
    164166/** @} */
    165167
  • trunk/include/VBox/vmm/hm_svm.h

    r66356 r66371  
    9393 */
    9494#ifndef IN_REM_R3
    95 /** @name SVM Basic Exit Reasons.
     95/** @name SVM_EXIT_XXX - SVM Basic Exit Reasons.
    9696 * @{
    9797 */
     
    588588
    589589/**
    590  * SVM IOIO exit structure (EXITINFO1 for IOIO intercepts).
     590 * SVM IOIO exit info. structure (EXITINFO1 for IOIO intercepts).
    591591 */
    592592typedef union
     
    594594    struct
    595595    {
    596         uint32_t    u1Type              : 1;        /**< Bit 0: 0 = out, 1 = in */
    597         uint32_t    u1Reserved          : 1;        /**< Bit 1: Reserved */
    598         uint32_t    u1STR               : 1;        /**< Bit 2: String I/O (1) or not (0). */
    599         uint32_t    u1REP               : 1;        /**< Bit 3: Repeat prefixed string I/O. */
    600         uint32_t    u1OP8               : 1;        /**< Bit 4: 8-bit operand. */
    601         uint32_t    u1OP16              : 1;        /**< Bit 5: 16-bit operand. */
    602         uint32_t    u1OP32              : 1;        /**< Bit 6: 32-bit operand. */
    603         uint32_t    u1ADDR16            : 1;        /**< Bit 7: 16-bit operand. */
    604         uint32_t    u1ADDR32            : 1;        /**< Bit 8: 32-bit operand. */
    605         uint32_t    u1ADDR64            : 1;        /**< Bit 9: 64-bit operand. */
    606         uint32_t    u3SEG               : 3;        /**< BITS 12:10: Effective segment number. Added with decode assist in APM v3.17. */
     596        uint32_t    u1Type              : 1;   /**< Bit 0: 0 = out, 1 = in */
     597        uint32_t    u1Reserved          : 1;   /**< Bit 1: Reserved */
     598        uint32_t    u1STR               : 1;   /**< Bit 2: String I/O (1) or not (0). */
     599        uint32_t    u1REP               : 1;   /**< Bit 3: Repeat prefixed string I/O. */
     600        uint32_t    u1OP8               : 1;   /**< Bit 4: 8-bit operand. */
     601        uint32_t    u1OP16              : 1;   /**< Bit 5: 16-bit operand. */
     602        uint32_t    u1OP32              : 1;   /**< Bit 6: 32-bit operand. */
     603        uint32_t    u1ADDR16            : 1;   /**< Bit 7: 16-bit operand. */
     604        uint32_t    u1ADDR32            : 1;   /**< Bit 8: 32-bit operand. */
     605        uint32_t    u1ADDR64            : 1;   /**< Bit 9: 64-bit operand. */
     606        uint32_t    u3SEG               : 3;   /**< BITS 12:10: Effective segment number. Added w/ decode assist in APM v3.17. */
    607607        uint32_t    u3Reserved          : 3;
    608         uint32_t    u16Port             : 16;       /**< Bits 31:16: Port number. */
     608        uint32_t    u16Port             : 16;  /**< Bits 31:16: Port number. */
    609609    } n;
    610610    uint32_t    u;
    611 } SVMIOIOEXIT;
     611} SVMIOIOEXITINFO;
     612/** Pointer to an SVM IOIO exit info. structure. */
     613typedef SVMIOIOEXITINFO *PSVMIOIOEXITINFO;
     614/** Pointer to a const SVM IOIO exit info. structure. */
     615typedef const SVMIOIOEXITINFO *PCSVMIOIOEXITINFO;
    612616
    613617/** @name SVMIOIOEXIT.u1Type
  • trunk/src/VBox/VMM/VMMAll/HMSVMAll.cpp

    r66356 r66371  
    741741
    742742/**
    743  * Handles nested-guest SVM intercepts and performs the \#VMEXIT if the
     743 * Handles nested-guest SVM control intercepts and performs the \#VMEXIT if the
    744744 * intercept is active.
    745745 *
     
    751751 * @retval  VERR_SVM_VMEXIT_FAILED if the intercept is active and the \#VMEXIT
    752752 *          failed and a shutdown needs to be initiated for the geust.
     753 *
     754 * @param   pVCpu       The cross context virtual CPU structure.
     755 * @param   pCtx        The guest-CPU context.
     756 * @param   uExitCode   The SVM exit code (see SVM_EXIT_XXX).
     757 * @param   uExitInfo1  The exit info. 1 field.
     758 * @param   uExitInfo2  The exit info. 2 field.
    753759 */
    754760VMM_INT_DECL(VBOXSTRICTRC) HMSvmNstGstHandleCtrlIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t uExitCode, uint64_t uExitInfo1,
     
    895901
    896902
     903/**
     904 * Handles nested-guest SVM IO intercepts and performs the \#VMEXIT
     905 * if the intercept is active.
     906 *
     907 * @returns Strict VBox status code.
     908 * @retval  VINF_SVM_INTERCEPT_NOT_ACTIVE if the intercept is not active or
     909 *          we're not executing a nested-guest.
     910 * @retval  VINF_SVM_VMEXIT if the intercept is active and the \#VMEXIT occurred
     911 *          successfully.
     912 * @retval  VERR_SVM_VMEXIT_FAILED if the intercept is active and the \#VMEXIT
     913 *          failed and a shutdown needs to be initiated for the geust.
     914 *
     915 * @param   pVCpu           The cross context virtual CPU structure.
     916 * @param   pCtx            The guest-CPU context.
     917 * @param   pIoExitInfo     The SVM IOIO exit info. structure.
     918 * @param   uNextRip        The RIP of the instruction following the IO
     919 *                          instruction.
     920 */
     921VMM_INT_DECL(VBOXSTRICTRC) HMSvmNstGstHandleIOIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, PCSVMIOIOEXITINFO pIoExitInfo,
     922                                                        uint64_t uNextRip)
     923{
     924    /*
     925     * Check if any IO accesses are being intercepted.
     926     */
     927    if (CPUMIsGuestSvmCtrlInterceptSet(pCtx, SVM_CTRL_INTERCEPT_IOIO_PROT))
     928    {
     929        Assert(CPUMIsGuestInNestedHwVirtMode(pCtx));
     930
     931        /*
     932         * The IOPM layout:
     933         * Each bit represents one 8-bit port. That makes a total of 0..65535 bits or
     934         * two 4K pages. However, since it's possible to do a 32-bit port IO at port
     935         * 65534 (thus accessing 4 bytes), we need 3 extra bits beyond the two 4K page.
     936         *
     937         * For IO instructions that access more than a single byte, the permission bits
     938         * for all bytes are checked; if any bit is set to 1, the IO access is intercepted.
     939         */
     940        uint8_t *pbIopm = (uint8_t *)pCtx->hwvirt.svm.CTX_SUFF(pvIoBitmap);
     941
     942        uint16_t const u16Port     = pIoExitInfo->n.u16Port;
     943        uint16_t const offIoBitmap = u16Port >> 3;
     944        uint16_t const fSizeMask   = pIoExitInfo->n.u1OP32 ? 0xf : pIoExitInfo->n.u1OP16 ? 3 : 1;
     945        uint8_t  const cShift      = u16Port - (offIoBitmap << 3);
     946        uint16_t const fIopmMask   = (1 << cShift) | (fSizeMask << cShift);
     947
     948        pbIopm += offIoBitmap;
     949        uint16_t const fIopmBits = *(uint16_t *)pbIopm;
     950        if (fIopmBits & fIopmMask)
     951            return HMSvmNstGstVmExit(pVCpu, pCtx, SVM_EXIT_IOIO, pIoExitInfo->u, uNextRip);
     952    }
     953    return VINF_HM_INTERCEPT_NOT_ACTIVE;
     954}
     955
     956
     957/**
     958 * Handles nested-guest SVM MSR read/write intercepts and performs the \#VMEXIT
     959 * if the intercept is active.
     960 *
     961 * @returns Strict VBox status code.
     962 * @retval  VINF_SVM_INTERCEPT_NOT_ACTIVE if the intercept is not active or
     963 *          we're not executing a nested-guest.
     964 * @retval  VINF_SVM_VMEXIT if the intercept is active and the \#VMEXIT occurred
     965 *          successfully.
     966 * @retval  VERR_SVM_VMEXIT_FAILED if the intercept is active and the \#VMEXIT
     967 *          failed and a shutdown needs to be initiated for the geust.
     968 *
     969 * @param   pVCpu       The cross context virtual CPU structure.
     970 * @param   pCtx        The guest-CPU context.
     971 * @param   idMsr       The MSR being accessed in the nested-guest.
     972 * @param   fWrite      Whether this is an MSR write access, @c false implies an
     973 *                      MSR read.
     974 */
    897975VMM_INT_DECL(VBOXSTRICTRC) HMSvmNstGstHandleMsrIntercept(PVMCPU pVCpu, PCPUMCTX pCtx, uint32_t idMsr, bool fWrite)
    898976{
     
    9381016}
    9391017
     1018
     1019/**
     1020 * Gets the MSR permission bitmap byte and bit offset for the specified MSR.
     1021 *
     1022 * @returns VBox status code.
     1023 * @param   idMsr       The MSR being requested.
     1024 * @param   pbOffMsrpm  Where to store the byte offset in the MSR permission
     1025 *                      bitmap for @a idMsr.
     1026 * @param   puMsrpmBit  Where to store the bit offset starting at the byte
     1027 *                      returned in @a pbOffMsrpm.
     1028 */
    9401029VMM_INT_DECL(int) hmSvmGetMsrpmOffsetAndBit(uint32_t idMsr, uint16_t *pbOffMsrpm, uint32_t *puMsrpmBit)
    9411030{
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r66356 r66371  
    47624762
    47634763    /* Refer AMD spec. 15.10.2 "IN and OUT Behaviour" and Figure 15-2. "EXITINFO1 for IOIO Intercept" for the format. */
    4764     SVMIOIOEXIT IoExitInfo;
     4764    SVMIOIOEXITINFO IoExitInfo;
    47654765    IoExitInfo.u       = (uint32_t)pVmcb->ctrl.u64ExitInfo1;
    47664766    uint32_t uIOWidth  = (IoExitInfo.u >> 4) & 0x7;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette