VirtualBox

Changeset 80803 in vbox for trunk/src


Ignore:
Timestamp:
Sep 16, 2019 5:33:35 AM (5 years ago)
Author:
vboxsync
Message:

VMM/CPUM: Nested VMX: bugref:9180 Fix I/O bitmap accesses. We need to check 1, 2 or 4 bits depending on the size of the I/O access.

File:
1 edited

Legend:

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

    r80763 r80803  
    24232423 *
    24242424 * @returns @c true if the I/O port access must cause a VM-exit, @c false otherwise.
    2425  * @param   pvIoBitmapA     Pointer to I/O bitmap A.
    2426  * @param   pvIoBitmapB     Pointer to I/O bitmap B.
     2425 * @param   pvIoBitmap      Pointer to I/O bitmap.
    24272426 * @param   uPort           The I/O port being accessed.
    24282427 * @param   cbAccess        The size of the I/O access in bytes (1, 2 or 4 bytes).
    24292428 */
    2430 VMM_INT_DECL(bool) CPUMGetVmxIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,
    2431                                                 uint8_t cbAccess)
     2429static bool cpumGetVmxIoBitmapPermission(void const *pvIoBitmap, uint16_t uPort, uint8_t cbAccess)
    24322430{
    24332431    Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4);
    24342432
    24352433    /*
    2436      * If the I/O port access wraps around the 16-bit port I/O space,
    2437      * we must cause a VM-exit.
     2434     * If the I/O port access wraps around the 16-bit port I/O space, we must cause a
     2435     * VM-exit.
    24382436     *
    24392437     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
     
    24462444        return true;
    24472445
    2448     /* Read the appropriate bit from the corresponding IO bitmap. */
    2449     void const *pvIoBitmap = uPort < 0x8000 ? pvIoBitmapA : pvIoBitmapB;
    2450     return ASMBitTest(pvIoBitmap, uPort);
     2446    /*
     2447     * If any bit corresponding to the I/O access is set, we must cause a VM-exit.
     2448     */
     2449    uint8_t const *pbIoBitmap   = (uint8_t const *)pvIoBitmap;
     2450    signed int     cBitsToCheck = cbAccess;                     /* Number of permission bits to check for this access. */
     2451    while (cBitsToCheck > 0)
     2452    {
     2453        uint16_t const offPerm    = uPort >> 3;                 /* Byte offset of the port. */
     2454        uint16_t const idxPermBit = uPort - (offPerm << 3);     /* Bit offset within byte. */
     2455        Assert(idxPermBit < 8);
     2456        uint8_t const  fMask = RT_BIT(idxPermBit);              /* Mask of the permission bit to check within the byte. */
     2457        uint8_t const  bPerm = *(pbIoBitmap + offPerm);         /* The bitmap content at the byte offset of the port. */
     2458
     2459        /* If any bit for the access is 1, we must cause a VM-exit. */
     2460        if (bPerm & fMask)
     2461            return true;
     2462
     2463        /* Move to the next permission bit. */
     2464        --cBitsToCheck;
     2465        ++uPort;
     2466    }
     2467
     2468    return false;
    24512469}
    24522470
     
    27342752    if (CPUMIsGuestVmxProcCtlsSet(pVCpu, pCtx, VMX_PROC_CTLS_USE_IO_BITMAPS))
    27352753    {
    2736         uint8_t const *pbIoBitmapA = (uint8_t const *)pCtx->hwvirt.vmx.CTX_SUFF(pvIoBitmap);
    2737         uint8_t const *pbIoBitmapB = (uint8_t const *)pCtx->hwvirt.vmx.CTX_SUFF(pvIoBitmap) + VMX_V_IO_BITMAP_A_SIZE;
    2738         Assert(pbIoBitmapA);
    2739         Assert(pbIoBitmapB);
    2740         return CPUMGetVmxIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port, cbAccess);
     2754        uint8_t const *pbIoBitmap = (uint8_t const *)pCtx->hwvirt.vmx.CTX_SUFF(pvIoBitmap);
     2755        Assert(pbIoBitmap);
     2756        return cpumGetVmxIoBitmapPermission(pbIoBitmap, u16Port, cbAccess);
    27412757    }
    27422758
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