VirtualBox

Changeset 74695 in vbox for trunk


Ignore:
Timestamp:
Oct 9, 2018 5:56:37 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 Fix the I/O port wrap-around detection case.

Location:
trunk
Files:
3 edited

Legend:

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

    r74660 r74695  
    152152VMM_INT_DECL(int)               HMVmxGetMsrPermission(void const *pvMsrBitmap, uint32_t idMsr, PVMXMSREXITREAD penmRead,
    153153                                                      PVMXMSREXITWRITE penmWrite);
    154 VMM_INT_DECL(bool)              HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort);
     154VMM_INT_DECL(bool)              HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort,
     155                                                           uint8_t cbAccess);
    155156/** @} */
    156157
  • trunk/src/VBox/VMM/VMMAll/HMVMXAll.cpp

    r74660 r74695  
    963963 * @param   pvIoBitmapB     Pointer to I/O bitmap B.
    964964 * @param   uPort           The I/O port being accessed.
    965  */
    966 VMM_INT_DECL(bool) HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort)
    967 {
    968     /* If the port is 0 or ffff ("wrap around"), we cause a VM-exit. */
    969     if (   uPort == 0x0000
    970         || uPort == 0xffff)
     965 * @param   cbAccess        The size of the I/O access in bytes (1, 2 or 4 bytes).
     966 */
     967VMM_INT_DECL(bool) HMVmxGetIoBitmapPermission(void const *pvIoBitmapA, void const *pvIoBitmapB, uint16_t uPort, uint8_t cbAccess)
     968{
     969    Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4);
     970
     971    /*
     972     * If the I/O port accecss wraps around the 16-bit port I/O space,
     973     * we must cause a VM-exit.
     974     *
     975     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
     976     */
     977    /** @todo r=ramshankar: Reading 1, 2, 4 bytes at ports 0xffff, 0xfffe and 0xfffc
     978     *        respectively are valid and do not constitute a wrap around from what I
     979     *        understand. Verify this later. */
     980    uint32_t const uPortLast = uPort + cbAccess;
     981    if (uPortLast > 0x10000)
    971982        return true;
    972983
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74694 r74695  
    28632863 *
    28642864 * @returns @c true if the instruction is intercepted, @c false otherwise.
    2865  * @param   pVCpu           The cross context virtual CPU structure.
    2866  * @param   u16Port         The I/O port being accessed by the instruction.
    2867  */
    2868 IEM_STATIC bool iemVmxIsIoInterceptSet(PVMCPU pVCpu, uint16_t u16Port)
     2865 * @param   pVCpu       The cross context virtual CPU structure.
     2866 * @param   u16Port     The I/O port being accessed by the instruction.
     2867 * @param   cbAccess    The size of the I/O access in bytes (1, 2 or 4 bytes).
     2868 */
     2869IEM_STATIC bool iemVmxIsIoInterceptSet(PVMCPU pVCpu, uint16_t u16Port, uint8_t cbAccess)
    28692870{
    28702871    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     
    28842885        Assert(pbIoBitmapA);
    28852886        Assert(pbIoBitmapB);
    2886         return HMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port);
     2887        return HMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port, cbAccess);
    28872888    }
    28882889
     
    33493350    Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4);
    33503351
    3351     bool const fIntercept = iemVmxIsIoInterceptSet(pVCpu, u16Port);
     3352    bool const fIntercept = iemVmxIsIoInterceptSet(pVCpu, u16Port, cbAccess);
    33523353    if (fIntercept)
    33533354    {
     
    33913392    Assert(uInstrId != VMXINSTRID_IO_INS || ExitInstrInfo.StrIo.iSegReg == X86_SREG_ES);
    33923393
    3393     bool const fIntercept = iemVmxIsIoInterceptSet(pVCpu, u16Port);
     3394    bool const fIntercept = iemVmxIsIoInterceptSet(pVCpu, u16Port, cbAccess);
    33943395    if (fIntercept)
    33953396    {
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