VirtualBox

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


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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{
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