VirtualBox

Changeset 30338 in vbox


Ignore:
Timestamp:
Jun 21, 2010 2:48:17 PM (14 years ago)
Author:
vboxsync
Message:

EM,IOM: Don't try write directly to the fault address as the backing page might be read-only (shared page, write monitored page or zero page) and require special handle. Took the simple way out, which is to take the same path as in ring-0/3. Converted the remaining EMGCA.asm bits to EMAllA.asm code.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/em.h

    r30050 r30338  
    187187VMMDECL(uint32_t)   EMEmulateCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
    188188VMMDECL(uint32_t)   EMEmulateLockCmpXchg8b(void *pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX);
     189VMMDECL(uint32_t)   EMEmulateXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
     190VMMDECL(uint32_t)   EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
    189191/** @} */
    190192
     
    246248 */
    247249VMMRCDECL(int)      EMGCTrap(PVM pVM, unsigned uTrap, PCPUMCTXCORE pRegFrame);
    248 VMMRCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTRCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    249 VMMRCDECL(uint32_t) EMGCEmulateCmpXchg(RTRCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    250 VMMRCDECL(uint32_t) EMGCEmulateLockCmpXchg8b(RTRCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags);
    251 VMMRCDECL(uint32_t) EMGCEmulateCmpXchg8b(RTRCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags);
    252 VMMRCDECL(uint32_t) EMGCEmulateLockXAdd(RTRCPTR pu32Param1, uint32_t *pu32Param2, size_t cbSize, uint32_t *pEflags);
    253 VMMRCDECL(uint32_t) EMGCEmulateXAdd(RTRCPTR pu32Param1, uint32_t *pu32Param2, size_t cbSize, uint32_t *pEflags);
    254250/** @} */
    255251#endif /* IN_RC */
  • trunk/include/VBox/mm.h

    r30050 r30338  
    349349VMMRCDECL(void)     MMGCRamDeregisterTrapHandler(PVM pVM);
    350350VMMRCDECL(int)      MMGCRamReadNoTrapHandler(void *pDst, void *pSrc, size_t cb);
     351/**
     352 * @deprecated Don't use this as it doesn't check the page state.
     353 */
    351354VMMRCDECL(int)      MMGCRamWriteNoTrapHandler(void *pDst, void *pSrc, size_t cb);
    352355VMMRCDECL(int)      MMGCRamRead(PVM pVM, void *pDst, void *pSrc, size_t cb);
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r29287 r30338  
    424424DECLINLINE(int) emRamWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc, uint32_t cb)
    425425{
    426 #ifdef IN_RC
    427     int rc = MMGCRamWrite(pVM, (void *)(uintptr_t)GCPtrDst, (void *)pvSrc, cb);
    428     if (RT_LIKELY(rc != VERR_ACCESS_DENIED))
    429         return rc;
    430     /*
    431      * The page pool cache may end up here in some cases because it
    432      * flushed one of the shadow mappings used by the trapping
    433      * instruction and it either flushed the TLB or the CPU reused it.
    434      * We want to play safe here, verifying that we've got write
    435      * access doesn't cost us much (see PGMPhysGCPtr2GCPhys()).
    436      */
    437 #endif
     426    /* Don't use MMGCRamWrite here as it does not respect zero pages, shared
     427       pages or write monitored pages. */
    438428    return PGMPhysInterpretedWriteNoHandlers(pVCpu, pCtxCore, GCPtrDst, pvSrc, cb, /*fMayTrap*/ false);
    439429}
     
    933923    RTGCPTR GCPtrPar1 = param1.val.val64;
    934924    GCPtrPar1 = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, GCPtrPar1);
    935 #ifdef IN_RC
    936     pvParam1  = (void *)(uintptr_t)GCPtrPar1;
    937 #else
    938925    PGMPAGEMAPLOCK Lock;
    939926    rc = PGMPhysGCPtr2CCPtr(pVCpu, GCPtrPar1, &pvParam1, &Lock);
    940927    AssertRCReturn(rc, VERR_EM_INTERPRETER);
    941 #endif
    942928
    943929    /* Try emulate it with a one-shot #PF handler in place. (RC) */
     
    945931
    946932    RTGCUINTREG32 eflags = 0;
    947 #ifdef IN_RC
    948     MMGCRamRegisterTrapHandler(pVM);
    949 #endif
    950933    rc = pfnEmulate(pvParam1, ValPar2, pDis->param2.size, &eflags);
    951 #ifdef IN_RC
    952     MMGCRamDeregisterTrapHandler(pVM);
    953 #else
    954934    PGMPhysReleasePageMappingLock(pVM, &Lock);
    955 #endif
    956935    if (RT_FAILURE(rc))
    957936    {
     
    11891168#endif
    11901169
    1191 #ifdef IN_RC
    1192     pvParam1  = (void *)(uintptr_t)GCPtrPar1;
    1193 #else
    11941170    PGMPAGEMAPLOCK Lock;
    11951171    rc = PGMPhysGCPtr2CCPtr(pVCpu, GCPtrPar1, &pvParam1, &Lock);
    11961172    AssertRCReturn(rc, VERR_EM_INTERPRETER);
    1197 #endif
    11981173
    11991174    Log2(("emInterpretLockBitTest %s: pvFault=%RGv GCPtrPar1=%RGv imm=%RX64\n", emGetMnemonic(pDis), pvFault, GCPtrPar1, ValPar2));
     
    12011176    /* Try emulate it with a one-shot #PF handler in place. (RC) */
    12021177    RTGCUINTREG32 eflags = 0;
    1203 #ifdef IN_RC
    1204     MMGCRamRegisterTrapHandler(pVM);
    1205 #endif
    12061178    rc = pfnEmulate(pvParam1, ValPar2, &eflags);
    1207 #ifdef IN_RC
    1208     MMGCRamDeregisterTrapHandler(pVM);
    1209 #else
    12101179    PGMPhysReleasePageMappingLock(pVM, &Lock);
    1211 #endif
    12121180    if (RT_FAILURE(rc))
    12131181    {
     
    15141482#endif /* !IN_RC */
    15151483
    1516 #ifndef IN_RC
    15171484
    15181485/**
     
    16371604}
    16381605
    1639 #else /* IN_RC */
    1640 
    1641 /**
    1642  * [LOCK] CMPXCHG emulation.
    1643  */
    1644 static int emInterpretCmpXchg(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
     1606
     1607#ifdef IN_RC /** @todo test+enable for HWACCM as well. */
     1608/**
     1609 * [LOCK] XADD emulation.
     1610 */
     1611static int emInterpretXAdd(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
    16451612{
    16461613    Assert(pDis->mode != CPUMODE_64BIT);    /** @todo check */
    1647     OP_PARAMVAL param1, param2;
     1614    OP_PARAMVAL param1;
     1615    void *pvParamReg2;
     1616    size_t cbParamReg2;
    16481617
    16491618    /* Source to make DISQueryParamVal read the register value - ugly hack */
     
    16521621        return VERR_EM_INTERPRETER;
    16531622
    1654     rc = DISQueryParamVal(pRegFrame, pDis, &pDis->param2, &param2, PARAM_SOURCE);
     1623    rc = DISQueryParamRegPtr(pRegFrame, pDis, &pDis->param2, &pvParamReg2, &cbParamReg2);
     1624    Assert(cbParamReg2 <= 4);
    16551625    if(RT_FAILURE(rc))
    16561626        return VERR_EM_INTERPRETER;
    16571627
     1628#ifdef IN_RC
    16581629    if (TRPMHasTrap(pVCpu))
    16591630    {
    16601631        if (TRPMGetErrorCode(pVCpu) & X86_TRAP_PF_RW)
    16611632        {
    1662             RTRCPTR pParam1;
    1663             uint32_t valpar, eflags;
     1633#endif
     1634            RTGCPTR         GCPtrPar1;
     1635            void           *pvParam1;
     1636            uint32_t        eflags;
     1637            PGMPAGEMAPLOCK  Lock;
    16641638
    16651639            AssertReturn(pDis->param1.size == pDis->param2.size, VERR_EM_INTERPRETER);
     
    16671641            {
    16681642            case PARMTYPE_ADDRESS:
    1669                 pParam1 = (RTRCPTR)(uintptr_t)emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, (RTRCUINTPTR)param1.val.val64);
    1670                 EM_ASSERT_FAULT_RETURN(pParam1 == (RTRCPTR)pvFault, VERR_EM_INTERPRETER);
     1643                GCPtrPar1 = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, (RTRCUINTPTR)param1.val.val64);
     1644#ifdef IN_RC
     1645                EM_ASSERT_FAULT_RETURN(GCPtrPar1 == pvFault, VERR_EM_INTERPRETER);
     1646#endif
     1647
     1648                rc = PGMPhysGCPtr2CCPtr(pVCpu, GCPtrPar1, &pvParam1, &Lock);
     1649                AssertRCReturn(rc, VERR_EM_INTERPRETER);
    16711650                break;
    16721651
     
    16751654            }
    16761655
    1677             switch(param2.type)
    1678             {
    1679             case PARMTYPE_IMMEDIATE: /* register actually */
    1680                 valpar = param2.val.val32;
    1681                 break;
    1682 
    1683             default:
    1684                 return VERR_EM_INTERPRETER;
    1685             }
    1686 
    1687             LogFlow(("%s %RRv eax=%08x %08x\n", emGetMnemonic(pDis), pParam1, pRegFrame->eax, valpar));
    1688 
    1689             MMGCRamRegisterTrapHandler(pVM);
     1656            LogFlow(("XAdd %RGv=%p reg=%ll08x\n", GCPtrPar1, pvParam1, *(uint64_t *)pvParamReg2));
     1657
    16901658            if (pDis->prefix & PREFIX_LOCK)
    1691                 rc = EMGCEmulateLockCmpXchg(pParam1, &pRegFrame->eax, valpar, pDis->param2.size, &eflags);
     1659                eflags = EMEmulateLockXAdd(pvParam1, pvParamReg2, cbParamReg2);
    16921660            else
    1693                 rc = EMGCEmulateCmpXchg(pParam1, &pRegFrame->eax, valpar, pDis->param2.size, &eflags);
    1694             MMGCRamDeregisterTrapHandler(pVM);
    1695 
    1696             if (RT_FAILURE(rc))
    1697             {
    1698                 Log(("%s %RGv eax=%08x %08x -> emulation failed due to page fault!\n", emGetMnemonic(pDis), pParam1, pRegFrame->eax, valpar));
    1699                 return VERR_EM_INTERPRETER;
    1700             }
    1701 
    1702             LogFlow(("%s %RRv eax=%08x %08x ZF=%d\n", emGetMnemonic(pDis), pParam1, pRegFrame->eax, valpar, !!(eflags & X86_EFL_ZF)));
     1661                eflags = EMEmulateXAdd(pvParam1, pvParamReg2, cbParamReg2);
     1662
     1663            LogFlow(("XAdd %RGv=%p reg=%ll08x ZF=%d\n", GCPtrPar1, pvParam1, *(uint64_t *)pvParamReg2, !!(eflags & X86_EFL_ZF) ));
    17031664
    17041665            /* Update guest's eflags and finish. */
     
    17061667                                  | (eflags                &  (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF));
    17071668
    1708             *pcbSize = param2.size;
     1669            *pcbSize = cbParamReg2;
     1670            PGMPhysReleasePageMappingLock(pVM, &Lock);
    17091671            return VINF_SUCCESS;
     1672#ifdef IN_RC
    17101673        }
    17111674    }
     1675
    17121676    return VERR_EM_INTERPRETER;
    1713 }
    1714 
    1715 
    1716 /**
    1717  * [LOCK] CMPXCHG8B emulation.
    1718  */
    1719 static int emInterpretCmpXchg8b(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
    1720 {
    1721     Assert(pDis->mode != CPUMODE_64BIT);    /** @todo check */
    1722     OP_PARAMVAL param1;
    1723 
    1724     /* Source to make DISQueryParamVal read the register value - ugly hack */
    1725     int rc = DISQueryParamVal(pRegFrame, pDis, &pDis->param1, &param1, PARAM_SOURCE);
    1726     if(RT_FAILURE(rc))
    1727         return VERR_EM_INTERPRETER;
    1728 
    1729     if (TRPMHasTrap(pVCpu))
    1730     {
    1731         if (TRPMGetErrorCode(pVCpu) & X86_TRAP_PF_RW)
    1732         {
    1733             RTRCPTR pParam1;
    1734             uint32_t eflags;
    1735 
    1736             AssertReturn(pDis->param1.size == 8, VERR_EM_INTERPRETER);
    1737             switch(param1.type)
    1738             {
    1739             case PARMTYPE_ADDRESS:
    1740                 pParam1 = (RTRCPTR)(uintptr_t)emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, (RTRCUINTPTR)param1.val.val64);
    1741                 EM_ASSERT_FAULT_RETURN(pParam1 == (RTRCPTR)pvFault, VERR_EM_INTERPRETER);
    1742                 break;
    1743 
    1744             default:
    1745                 return VERR_EM_INTERPRETER;
    1746             }
    1747 
    1748             LogFlow(("%s %RRv=%08x eax=%08x\n", emGetMnemonic(pDis), pParam1, pRegFrame->eax));
    1749 
    1750             MMGCRamRegisterTrapHandler(pVM);
    1751             if (pDis->prefix & PREFIX_LOCK)
    1752                 rc = EMGCEmulateLockCmpXchg8b(pParam1, &pRegFrame->eax, &pRegFrame->edx, pRegFrame->ebx, pRegFrame->ecx, &eflags);
    1753             else
    1754                 rc = EMGCEmulateCmpXchg8b(pParam1, &pRegFrame->eax, &pRegFrame->edx, pRegFrame->ebx, pRegFrame->ecx, &eflags);
    1755             MMGCRamDeregisterTrapHandler(pVM);
    1756 
    1757             if (RT_FAILURE(rc))
    1758             {
    1759                 Log(("%s %RGv=%08x eax=%08x -> emulation failed due to page fault!\n", emGetMnemonic(pDis), pParam1, pRegFrame->eax));
    1760                 return VERR_EM_INTERPRETER;
    1761             }
    1762 
    1763             LogFlow(("%s %RGv=%08x eax=%08x ZF=%d\n", emGetMnemonic(pDis), pParam1, pRegFrame->eax, !!(eflags & X86_EFL_ZF)));
    1764 
    1765             /* Update guest's eflags and finish; note that *only* ZF is affected. */
    1766             pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_ZF))
    1767                                   | (eflags                &  (X86_EFL_ZF));
    1768 
    1769             *pcbSize = 8;
    1770             return VINF_SUCCESS;
    1771         }
    1772     }
    1773     return VERR_EM_INTERPRETER;
    1774 }
    1775 
    1776 #endif /* IN_RC */
    1777 
    1778 #ifdef IN_RC
    1779 /**
    1780  * [LOCK] XADD emulation.
    1781  */
    1782 static int emInterpretXAdd(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
    1783 {
    1784     Assert(pDis->mode != CPUMODE_64BIT);    /** @todo check */
    1785     OP_PARAMVAL param1;
    1786     uint32_t *pParamReg2;
    1787     size_t cbSizeParamReg2;
    1788 
    1789     /* Source to make DISQueryParamVal read the register value - ugly hack */
    1790     int rc = DISQueryParamVal(pRegFrame, pDis, &pDis->param1, &param1, PARAM_SOURCE);
    1791     if(RT_FAILURE(rc))
    1792         return VERR_EM_INTERPRETER;
    1793 
    1794     rc = DISQueryParamRegPtr(pRegFrame, pDis, &pDis->param2, (void **)&pParamReg2, &cbSizeParamReg2);
    1795     Assert(cbSizeParamReg2 <= 4);
    1796     if(RT_FAILURE(rc))
    1797         return VERR_EM_INTERPRETER;
    1798 
    1799     if (TRPMHasTrap(pVCpu))
    1800     {
    1801         if (TRPMGetErrorCode(pVCpu) & X86_TRAP_PF_RW)
    1802         {
    1803             RTRCPTR pParam1;
    1804             uint32_t eflags;
    1805 
    1806             AssertReturn(pDis->param1.size == pDis->param2.size, VERR_EM_INTERPRETER);
    1807             switch(param1.type)
    1808             {
    1809             case PARMTYPE_ADDRESS:
    1810                 pParam1 = (RTRCPTR)(uintptr_t)emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, (RTRCUINTPTR)param1.val.val64);
    1811                 EM_ASSERT_FAULT_RETURN(pParam1 == (RTRCPTR)pvFault, VERR_EM_INTERPRETER);
    1812                 break;
    1813 
    1814             default:
    1815                 return VERR_EM_INTERPRETER;
    1816             }
    1817 
    1818             LogFlow(("XAdd %RRv=%08x reg=%08x\n", pParam1, *pParamReg2));
    1819 
    1820             MMGCRamRegisterTrapHandler(pVM);
    1821             if (pDis->prefix & PREFIX_LOCK)
    1822                 rc = EMGCEmulateLockXAdd(pParam1, pParamReg2, cbSizeParamReg2, &eflags);
    1823             else
    1824                 rc = EMGCEmulateXAdd(pParam1, pParamReg2, cbSizeParamReg2, &eflags);
    1825             MMGCRamDeregisterTrapHandler(pVM);
    1826 
    1827             if (RT_FAILURE(rc))
    1828             {
    1829                 Log(("XAdd %RGv reg=%08x -> emulation failed due to page fault!\n", pParam1, *pParamReg2));
    1830                 return VERR_EM_INTERPRETER;
    1831             }
    1832 
    1833             LogFlow(("XAdd %RGv reg=%08x ZF=%d\n", pParam1, *pParamReg2, !!(eflags & X86_EFL_ZF)));
    1834 
    1835             /* Update guest's eflags and finish. */
    1836             pRegFrame->eflags.u32 = (pRegFrame->eflags.u32 & ~(X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF))
    1837                                   | (eflags                &  (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF));
    1838 
    1839             *pcbSize = cbSizeParamReg2;
    1840             return VINF_SUCCESS;
    1841         }
    1842     }
    1843     return VERR_EM_INTERPRETER;
     1677#endif
    18441678}
    18451679#endif /* IN_RC */
     
    31933027 * @copydoc EMInterpretInstructionCPU
    31943028 */
    3195 DECLINLINE(int) emInterpretInstructionCPU(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize, EMCODETYPE enmCodeType)
     3029DECLINLINE(int) emInterpretInstructionCPU(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
     3030                                          uint32_t *pcbSize, EMCODETYPE enmCodeType)
    31963031{
    31973032    Assert(enmCodeType == EMCODETYPE_SUPERVISOR || enmCodeType == EMCODETYPE_ALL);
  • trunk/src/VBox/VMM/VMMAll/EMAllA.asm

    r28800 r30338  
    2424
    2525;; @def MY_PTR_REG
    26 ; The register we use for value pointers (And,Or,Dec,Inc).
     26; The register we use for value pointers (And,Or,Dec,Inc,XAdd).
    2727%ifdef RT_ARCH_AMD64
    2828 %define MY_PTR_REG     rcx
     
    293293BITS 32
    294294%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
    295 
    296 
    297 %ifdef IN_RC
    298 ; #PF resume point.
    299 GLOBALNAME EMEmulateLockAnd_Error
    300     mov     eax, VERR_ACCESS_DENIED
    301     ret
    302 %endif
    303 
    304295ENDPROC     EMEmulateLockAnd
    305296
     
    471462BITS 32
    472463%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
    473 
    474 
    475 %ifdef IN_RC
    476 ; #PF resume point.
    477 GLOBALNAME EMEmulateLockOr_Error
    478     mov     eax, VERR_ACCESS_DENIED
    479     ret
    480 %endif
    481 
    482464ENDPROC     EMEmulateLockOr
    483465
     
    649631BITS 32
    650632%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
    651 
    652 
    653 %ifdef IN_RC
    654 ; #PF resume point.
    655 GLOBALNAME EMEmulateLockXor_Error
    656     mov     eax, VERR_ACCESS_DENIED
    657     ret
    658 %endif
    659 
    660633ENDPROC     EMEmulateLockXor
    661634
     
    10971070    mov     eax, VINF_SUCCESS
    10981071    retn
    1099 
    1100 %ifdef IN_RC
    1101 ; #PF resume point.
    1102 GLOBALNAME EMEmulateLockBtr_Error
    1103     mov     eax, VERR_ACCESS_DENIED
    1104     ret
    1105 %endif
    1106 
    11071072ENDPROC     EMEmulateLockBtr
    11081073
     
    15291494ENDPROC     EMEmulateCmpXchg8b
    15301495
     1496
     1497;;
     1498; Emulate LOCK XADD instruction.
     1499; VMMDECL(uint32_t)   EMEmulateLockXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
     1500;
     1501; @returns (eax=)eflags
     1502; @param    [esp + 04h]  gcc:rdi  msc:rcx  Param 1 - First parameter - pointer to data item.
     1503; @param    [esp + 08h]  gcc:rsi  msc:rdx  Param 2 - Second parameter - pointer to second parameter (general register)
     1504; @param    [esp + 0ch]  gcc:rdx  msc:r8   Param 3 - Size of parameters - {1,2,4,8}.
     1505;
     1506align 16
     1507BEGINPROC   EMEmulateLockXAdd
     1508%ifdef RT_ARCH_AMD64
     1509 %ifdef RT_OS_WINDOWS
     1510    mov     rax, r8                     ; eax = size of parameters
     1511 %else  ; !RT_OS_WINDOWS
     1512    mov     rax, rdx                    ; rax = size of parameters
     1513    mov     rcx, rdi                    ; rcx = first parameter
     1514    mov     rdx, rsi                    ; rdx = second parameter
     1515 %endif ; !RT_OS_WINDOWS
     1516%else   ; !RT_ARCH_AMD64
     1517    mov     eax, [esp + 0ch]            ; eax = size of parameters
     1518    mov     ecx, [esp + 04h]            ; ecx = first parameter
     1519    mov     edx, [esp + 08h]            ; edx = second parameter
     1520%endif
     1521
     1522    ; switch on size
     1523%ifdef CAN_DO_8_BYTE_OP
     1524    cmp     al, 8
     1525    je short .do_qword                  ; 8 bytes variant
     1526%endif
     1527    cmp     al, 4
     1528    je short .do_dword                  ; 4 bytes variant
     1529    cmp     al, 2
     1530    je short .do_word                   ; 2 byte variant
     1531    cmp     al, 1
     1532    je short .do_byte                   ; 1 bytes variant
     1533    int3
     1534
     1535    ; workers
     1536%ifdef RT_ARCH_AMD64
     1537.do_qword:
     1538    mov     rax, qword [xDX]            ; load 2nd parameter's value
     1539    lock xadd qword [MY_PTR_REG], rax   ; do 8 bytes XADD
     1540    mov     qword [xDX], rax
     1541    jmp     short .done
     1542%endif
     1543
     1544.do_dword:
     1545    mov     eax, dword [xDX]            ; load 2nd parameter's value
     1546    lock xadd dword [MY_PTR_REG], eax   ; do 4 bytes XADD
     1547    mov     dword [xDX], eax
     1548    jmp     short .done
     1549
     1550.do_word:
     1551    mov     eax, dword [xDX]            ; load 2nd parameter's value
     1552    lock xadd word [MY_PTR_REG], ax     ; do 2 bytes XADD
     1553    mov     word [xDX], ax
     1554    jmp     short .done
     1555
     1556.do_byte:
     1557    mov     eax, dword [xDX]            ; load 2nd parameter's value
     1558    lock xadd byte [MY_PTR_REG], al     ; do 1 bytes XADD
     1559    mov     byte [xDX], al
     1560
     1561.done:
     1562    ; collect flags and return.
     1563    pushf
     1564    pop     MY_RET_REG
     1565
     1566    retn
     1567
     1568%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     1569.do_qword:
     1570    db      0xea                        ; jmp far .sixtyfourbit_mode
     1571    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
     1572BITS 64
     1573.sixtyfourbit_mode:
     1574    and     esp, 0ffffffffh
     1575    and     edx, 0ffffffffh
     1576    and     MY_PTR_REG, 0ffffffffh
     1577    mov     rax, qword [rdx]            ; load 2nd parameter's value
     1578    and     [MY_PTR_REG64], rax         ; do 8 bytes XADD
     1579    jmp far [.fpret wrt rip]
     1580.fpret:                                 ; 16:32 Pointer to .done.
     1581    dd      .done, NAME(SUPR0AbsKernelCS)
     1582BITS 32
     1583%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     1584ENDPROC     EMEmulateLockXAdd
     1585
     1586
     1587;;
     1588; Emulate XADD instruction.
     1589; VMMDECL(uint32_t)   EMEmulateXAdd(void *pvParam1, void *pvParam2, size_t cbOp);
     1590;
     1591; @returns eax=eflags
     1592; @param    [esp + 04h]  gcc:rdi  msc:rcx  Param 1 - First parameter - pointer to data item.
     1593; @param    [esp + 08h]  gcc:rsi  msc:rdx  Param 2 - Second parameter - pointer to second parameter (general register)
     1594; @param    [esp + 0ch]  gcc:rdx  msc:r8   Param 3 - Size of parameters - {1,2,4,8}.
     1595align 16
     1596BEGINPROC   EMEmulateXAdd
     1597%ifdef RT_ARCH_AMD64
     1598%ifdef RT_OS_WINDOWS
     1599    mov     rax, r8                     ; eax = size of parameters
     1600%else   ; !RT_OS_WINDOWS
     1601    mov     rax, rdx                    ; rax = size of parameters
     1602    mov     rcx, rdi                    ; rcx = first parameter
     1603    mov     rdx, rsi                    ; rdx = second parameter
     1604%endif  ; !RT_OS_WINDOWS
     1605%else   ; !RT_ARCH_AMD64
     1606    mov     eax, [esp + 0ch]            ; eax = size of parameters
     1607    mov     ecx, [esp + 04h]            ; ecx = first parameter
     1608    mov     edx, [esp + 08h]            ; edx = second parameter
     1609%endif
     1610
     1611    ; switch on size
     1612%ifdef CAN_DO_8_BYTE_OP
     1613    cmp     al, 8
     1614    je short .do_qword                  ; 8 bytes variant
     1615%endif
     1616    cmp     al, 4
     1617    je short .do_dword                  ; 4 bytes variant
     1618    cmp     al, 2
     1619    je short .do_word                   ; 2 byte variant
     1620    cmp     al, 1
     1621    je short .do_byte                   ; 1 bytes variant
     1622    int3
     1623
     1624    ; workers
     1625%ifdef RT_ARCH_AMD64
     1626.do_qword:
     1627    mov     rax, qword [xDX]            ; load 2nd parameter's value
     1628    xadd    qword [MY_PTR_REG], rax   ; do 8 bytes XADD
     1629    mov     qword [xDX], rax
     1630    jmp     short .done
     1631%endif
     1632
     1633.do_dword:
     1634    mov     eax, dword [xDX]            ; load 2nd parameter's value
     1635    xadd    dword [MY_PTR_REG], eax     ; do 4 bytes XADD
     1636    mov     dword [xDX], eax
     1637    jmp     short .done
     1638
     1639.do_word:
     1640    mov     eax, dword [xDX]            ; load 2nd parameter's value
     1641    xadd    word [MY_PTR_REG], ax       ; do 2 bytes XADD
     1642    mov     word [xDX], ax
     1643    jmp     short .done
     1644
     1645.do_byte:
     1646    mov     eax, dword [xDX]            ; load 2nd parameter's value
     1647    xadd    byte [MY_PTR_REG], al       ; do 1 bytes XADD
     1648    mov     byte [xDX], al
     1649
     1650.done:
     1651    ; collect flags and return.
     1652    pushf
     1653    pop     MY_RET_REG
     1654
     1655    retn
     1656
     1657%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     1658.do_qword:
     1659    db      0xea                        ; jmp far .sixtyfourbit_mode
     1660    dd      .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
     1661BITS 64
     1662.sixtyfourbit_mode:
     1663    and     esp, 0ffffffffh
     1664    and     edx, 0ffffffffh
     1665    and     MY_PTR_REG, 0ffffffffh
     1666    mov     rax, qword [rdx]            ; load 2nd parameter's value
     1667    and     [MY_PTR_REG64], rax         ; do 8 bytes XADD
     1668    jmp far [.fpret wrt rip]
     1669.fpret:                                 ; 16:32 Pointer to .done.
     1670    dd      .done, NAME(SUPR0AbsKernelCS)
     1671BITS 32
     1672%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
     1673ENDPROC     EMEmulateXAdd
     1674
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r29436 r30338  
    287287     *        raw mode code. Some thought needs to be spent on theoretical concurrency issues as
    288288     *        as well since we're not behind the pgm lock and handler may change between calls.
    289      *        MMGCRamWriteNoTrapHandler may also trap if the page isn't shadowed, or was kicked
    290      *        out from both the shadow pt (SMP or our changes) and TLB.
    291289     *
    292      *        Currently MMGCRamWriteNoTrapHandler may also fail when it hits a write access handler.
    293      *        PGMPhysInterpretedWriteNoHandlers/PGMPhysWriteGCPtr OTOH may mess up the state
    294      *        of some shadowed structure in R0. */
    295 #ifdef IN_RC
    296     NOREF(pCtxCore);
    297     return MMGCRamWriteNoTrapHandler((void *)(uintptr_t)GCPtrDst, pvSrc, cb);
    298 #elif IN_RING0
     290     *        PGMPhysInterpretedWriteNoHandlers/PGMPhysWriteGCPtr may mess up
     291     *        the state of some shadowed structures. */
     292#if defined(IN_RING0) || defined(IN_RC)
    299293    return PGMPhysInterpretedWriteNoHandlers(pVCpu, pCtxCore, GCPtrDst, pvSrc, cb, false /*fRaiseTrap*/);
    300294#else
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r30078 r30338  
    34513451     * 4. Set access bits if required.
    34523452     */
     3453    /** @todo Since this method is frequently used by EMInterpret or IOM
     3454     *        upon a write fault to an write access monitored page, we can
     3455     *        reuse the guest page table walking from the \#PF code. */
    34533456    int rc;
    34543457    unsigned cb1 = PAGE_SIZE - (GCPtrDst & PAGE_OFFSET_MASK);
  • trunk/src/VBox/VMM/VMMGC/EMGCA.asm

    r28800 r30338  
    2525BEGINCODE
    2626
    27 ;;
    28 ; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
    29 ; VMMRCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    30 ;
    31 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    32 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    33 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (eax)
    34 ; @param    [esp + 0ch]    Param 3 - Third parameter - third parameter
    35 ; @param    [esp + 10h]    Param 4 - Size of parameters, only 1/2/4 is valid.
    36 ; @param    [esp + 14h]    Param 4 - Pointer to eflags (out)
    37 ; @uses     eax, ecx, edx
    38 ;
    39 align 16
    40 BEGINPROC   EMGCEmulateLockCmpXchg
    41     push    ebx
    42     mov     ecx, [esp + 04h + 4]        ; ecx = first parameter
    43     mov     ebx, [esp + 08h + 4]        ; ebx = 2nd parameter (eax)
    44     mov     edx, [esp + 0ch + 4]        ; edx = third parameter
    45     mov     eax, [esp + 10h + 4]        ; eax = size of parameters
    46 
    47     cmp     al, 4
    48     je short .do_dword                  ; 4 bytes variant
    49     cmp     al, 2
    50     je short .do_word                   ; 2 byte variant
    51     cmp     al, 1
    52     je short .do_byte                   ; 1 bytes variant
    53     int3
    54 
    55 .do_dword:
    56     ; load 2nd parameter's value
    57     mov     eax, dword [ebx]
    58 
    59     lock cmpxchg dword [ecx], edx            ; do 4 bytes CMPXCHG
    60     mov     dword [ebx], eax
    61     jmp     short .done
    62 
    63 .do_word:
    64     ; load 2nd parameter's value
    65     mov     eax, dword [ebx]
    66 
    67     lock cmpxchg word [ecx], dx              ; do 2 bytes CMPXCHG
    68     mov     word [ebx], ax
    69     jmp     short .done
    70 
    71 .do_byte:
    72     ; load 2nd parameter's value
    73     mov     eax, dword [ebx]
    74 
    75     lock cmpxchg byte [ecx], dl              ; do 1 bytes CMPXCHG
    76     mov     byte [ebx], al
    77 
    78 .done:
    79     ; collect flags and return.
    80     pushf
    81     pop     eax
    82 
    83     mov     edx, [esp + 14h + 4]            ; eflags pointer
    84     mov     dword [edx], eax
    85 
    86     pop     ebx
    87     mov     eax, VINF_SUCCESS
    88     retn
    89 
    90 ; Read error - we will be here after our page fault handler.
    91 GLOBALNAME EMGCEmulateLockCmpXchg_Error
    92     pop     ebx
    93     mov     eax, VERR_ACCESS_DENIED
    94     ret
    95 
    96 ENDPROC     EMGCEmulateLockCmpXchg
    97 
    98 ;;
    99 ; Emulate CMPXCHG instruction, CDECL calling conv.
    100 ; VMMRCDECL(uint32_t) EMGCEmulateCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    101 ;
    102 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    103 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    104 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (eax)
    105 ; @param    [esp + 0ch]    Param 3 - Third parameter - third parameter
    106 ; @param    [esp + 10h]    Param 4 - Size of parameters, only 1/2/4 is valid.
    107 ; @param    [esp + 14h]    Param 4 - Pointer to eflags (out)
    108 ; @uses     eax, ecx, edx
    109 ;
    110 align 16
    111 BEGINPROC   EMGCEmulateCmpXchg
    112     push    ebx
    113     mov     ecx, [esp + 04h + 4]        ; ecx = first parameter
    114     mov     ebx, [esp + 08h + 4]        ; ebx = 2nd parameter (eax)
    115     mov     edx, [esp + 0ch + 4]        ; edx = third parameter
    116     mov     eax, [esp + 10h + 4]        ; eax = size of parameters
    117 
    118     cmp     al, 4
    119     je short .do_dword                  ; 4 bytes variant
    120     cmp     al, 2
    121     je short .do_word                   ; 2 byte variant
    122     cmp     al, 1
    123     je short .do_byte                   ; 1 bytes variant
    124     int3
    125 
    126 .do_dword:
    127     ; load 2nd parameter's value
    128     mov     eax, dword [ebx]
    129 
    130     cmpxchg dword [ecx], edx            ; do 4 bytes CMPXCHG
    131     mov     dword [ebx], eax
    132     jmp     short .done
    133 
    134 .do_word:
    135     ; load 2nd parameter's value
    136     mov     eax, dword [ebx]
    137 
    138     cmpxchg word [ecx], dx              ; do 2 bytes CMPXCHG
    139     mov     word [ebx], ax
    140     jmp     short .done
    141 
    142 .do_byte:
    143     ; load 2nd parameter's value
    144     mov     eax, dword [ebx]
    145 
    146     cmpxchg byte [ecx], dl              ; do 1 bytes CMPXCHG
    147     mov     byte [ebx], al
    148 
    149 .done:
    150     ; collect flags and return.
    151     pushf
    152     pop     eax
    153 
    154     mov     edx, [esp + 14h + 4]        ; eflags pointer
    155     mov     dword [edx], eax
    156 
    157     pop     ebx
    158     mov     eax, VINF_SUCCESS
    159     retn
    160 
    161 ; Read error - we will be here after our page fault handler.
    162 GLOBALNAME EMGCEmulateCmpXchg_Error
    163     pop     ebx
    164     mov     eax, VERR_ACCESS_DENIED
    165     ret
    166 ENDPROC     EMGCEmulateCmpXchg
    167 
    168 ;;
    169 ; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv.
    170 ; VMMRCDECL(uint32_t) EMGCEmulateLockCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags);
    171 ;
    172 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    173 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    174 ; @param    [esp + 08h]    Param 2 - Address of the eax register
    175 ; @param    [esp + 0ch]    Param 3 - Address of the edx register
    176 ; @param    [esp + 10h]    Param 4 - EBX
    177 ; @param    [esp + 14h]    Param 5 - ECX
    178 ; @param    [esp + 18h]    Param 6 - Pointer to eflags (out)
    179 ; @uses     eax, ecx, edx
    180 ;
    181 align 16
    182 BEGINPROC   EMGCEmulateLockCmpXchg8b
    183     push    ebp
    184     push    ebx
    185     mov     ebp, [esp + 04h + 8]        ; ebp = first parameter
    186     mov     eax, [esp + 08h + 8]        ; &EAX
    187     mov     eax, dword [eax]
    188     mov     edx, [esp + 0ch + 8]        ; &EDX
    189     mov     edx, dword [edx]
    190     mov     ebx, [esp + 10h + 8]        ; EBX
    191     mov     ecx, [esp + 14h + 8]        ; ECX
    192 
    193 %ifdef RT_OS_OS2
    194     lock cmpxchg8b [ebp]                ; do CMPXCHG8B
    195 %else
    196     lock cmpxchg8b qword [ebp]          ; do CMPXCHG8B
    197 %endif
    198     mov     ebx, dword [esp + 08h + 8]
    199     mov     dword [ebx], eax
    200     mov     ebx, dword [esp + 0ch + 8]
    201     mov     dword [ebx], edx
    202 
    203     ; collect flags and return.
    204     pushf
    205     pop     eax
    206 
    207     mov     edx, [esp + 18h + 8]            ; eflags pointer
    208     mov     dword [edx], eax
    209 
    210     pop     ebx
    211     pop     ebp
    212     mov     eax, VINF_SUCCESS
    213     retn
    214 
    215 ; Read error - we will be here after our page fault handler.
    216 GLOBALNAME EMGCEmulateLockCmpXchg8b_Error
    217     pop     ebx
    218     pop     ebp
    219     mov     eax, VERR_ACCESS_DENIED
    220     ret
    221 
    222 ENDPROC     EMGCEmulateLockCmpXchg8b
    223 
    224 ;;
    225 ; Emulate CMPXCHG8B instruction, CDECL calling conv.
    226 ; VMMRCDECL(uint32_t) EMGCEmulateCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags);
    227 ;
    228 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    229 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    230 ; @param    [esp + 08h]    Param 2 - Address of the eax register
    231 ; @param    [esp + 0ch]    Param 3 - Address of the edx register
    232 ; @param    [esp + 10h]    Param 4 - EBX
    233 ; @param    [esp + 14h]    Param 5 - ECX
    234 ; @param    [esp + 18h]    Param 6 - Pointer to eflags (out)
    235 ; @uses     eax, ecx, edx
    236 ;
    237 align 16
    238 BEGINPROC   EMGCEmulateCmpXchg8b
    239     push    ebp
    240     push    ebx
    241     mov     ebp, [esp + 04h + 8]        ; ebp = first parameter
    242     mov     eax, [esp + 08h + 8]        ; &EAX
    243     mov     eax, dword [eax]
    244     mov     edx, [esp + 0ch + 8]        ; &EDX
    245     mov     edx, dword [edx]
    246     mov     ebx, [esp + 10h + 8]        ; EBX
    247     mov     ecx, [esp + 14h + 8]        ; ECX
    248 
    249 %ifdef RT_OS_OS2
    250     cmpxchg8b [ebp]                     ; do CMPXCHG8B
    251 %else
    252     cmpxchg8b qword [ebp]               ; do CMPXCHG8B
    253 %endif
    254     mov     ebx, dword [esp + 08h + 8]
    255     mov     dword [ebx], eax
    256     mov     ebx, dword [esp + 0ch + 8]
    257     mov     dword [ebx], edx
    258 
    259     ; collect flags and return.
    260     pushf
    261     pop     eax
    262 
    263     mov     edx, [esp + 18h + 8]            ; eflags pointer
    264     mov     dword [edx], eax
    265 
    266     pop     ebx
    267     pop     ebp
    268     mov     eax, VINF_SUCCESS
    269     retn
    270 
    271 ; Read error - we will be here after our page fault handler.
    272 GLOBALNAME EMGCEmulateCmpXchg8b_Error
    273     pop     ebx
    274     pop     ebp
    275     mov     eax, VERR_ACCESS_DENIED
    276     ret
    277 ENDPROC     EMGCEmulateCmpXchg8b
    278 
    279 ;;
    280 ; Emulate LOCK XADD instruction, CDECL calling conv.
    281 ; VMMRCDECL(uint32_t) EMGCEmulateLockXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    282 ;
    283 ; @returns eax=0 if data exchanged, other code - invalid access, #PF was generated.
    284 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    285 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (general register)
    286 ; @param    [esp + 0ch]    Param 3 - Size of parameters, only 1/2/4 is valid.
    287 ; @param    [esp + 10h]    Param 4 - Pointer to eflags (out)
    288 ; @uses     eax, ecx, edx
    289 ;
    290 align 16
    291 BEGINPROC   EMGCEmulateLockXAdd
    292     mov     ecx, [esp + 04h + 0]        ; ecx = first parameter
    293     mov     edx, [esp + 08h + 0]        ; edx = 2nd parameter
    294     mov     eax, [esp + 0ch + 0]        ; eax = size of parameters
    295 
    296     cmp     al, 4
    297     je short .do_dword                  ; 4 bytes variant
    298     cmp     al, 2
    299     je short .do_word                   ; 2 byte variant
    300     cmp     al, 1
    301     je short .do_byte                   ; 1 bytes variant
    302     int3
    303 
    304 .do_dword:
    305     ; load 2nd parameter's value
    306     mov     eax, dword [edx]
    307     lock xadd dword [ecx], eax              ; do 4 bytes XADD
    308     mov     dword [edx], eax
    309     jmp     short .done
    310 
    311 .do_word:
    312     ; load 2nd parameter's value
    313     mov     eax, dword [edx]
    314     lock xadd word [ecx], ax                ; do 2 bytes XADD
    315     mov     word [edx], ax
    316     jmp     short .done
    317 
    318 .do_byte:
    319     ; load 2nd parameter's value
    320     mov     eax, dword [edx]
    321     lock xadd byte [ecx], al                ; do 1 bytes XADD
    322     mov     byte [edx], al
    323 
    324 .done:
    325     ; collect flags and return.
    326     mov     edx, [esp + 10h + 0]            ; eflags pointer
    327     pushf
    328     pop     dword [edx]
    329 
    330     mov     eax, VINF_SUCCESS
    331     retn
    332 
    333 ; Read error - we will be here after our page fault handler.
    334 GLOBALNAME EMGCEmulateLockXAdd_Error
    335     mov     eax, VERR_ACCESS_DENIED
    336     ret
    337 
    338 ENDPROC     EMGCEmulateLockXAdd
    339 
    340 ;;
    341 ; Emulate XADD instruction, CDECL calling conv.
    342 ; VMMRCDECL(uint32_t) EMGCEmulateXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    343 ;
    344 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    345 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    346 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (general register)
    347 ; @param    [esp + 0ch]    Param 3 - Size of parameters, only 1/2/4 is valid.
    348 ; @param    [esp + 10h]    Param 4 - Pointer to eflags (out)
    349 ; @uses     eax, ecx, edx
    350 ;
    351 align 16
    352 BEGINPROC   EMGCEmulateXAdd
    353     mov     ecx, [esp + 04h + 0]        ; ecx = first parameter
    354     mov     edx, [esp + 08h + 0]        ; edx = 2nd parameter (eax)
    355     mov     eax, [esp + 0ch + 0]        ; eax = size of parameters
    356 
    357     cmp     al, 4
    358     je short .do_dword                  ; 4 bytes variant
    359     cmp     al, 2
    360     je short .do_word                   ; 2 byte variant
    361     cmp     al, 1
    362     je short .do_byte                   ; 1 bytes variant
    363     int3
    364 
    365 .do_dword:
    366     ; load 2nd parameter's value
    367     mov     eax, dword [edx]
    368     xadd    dword [ecx], eax            ; do 4 bytes XADD
    369     mov     dword [edx], eax
    370     jmp     short .done
    371 
    372 .do_word:
    373     ; load 2nd parameter's value
    374     mov     eax, dword [edx]
    375     xadd    word [ecx], ax              ; do 2 bytes XADD
    376     mov     word [edx], ax
    377     jmp     short .done
    378 
    379 .do_byte:
    380     ; load 2nd parameter's value
    381     mov     eax, dword [edx]
    382     xadd    byte [ecx], al              ; do 1 bytes XADD
    383     mov     byte [edx], al
    384 
    385 .done:
    386     ; collect flags and return.
    387     mov     edx, [esp + 10h + 0]        ; eflags pointer
    388     pushf
    389     pop     dword [edx]
    390 
    391     mov     eax, VINF_SUCCESS
    392     retn
    393 
    394 ; Read error - we will be here after our page fault handler.
    395 GLOBALNAME EMGCEmulateXAdd_Error
    396     mov     eax, VERR_ACCESS_DENIED
    397     ret
    398 ENDPROC     EMGCEmulateXAdd
  • trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp

    r28800 r30338  
    4242DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void);
    4343DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void);
    44 DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void);
    45 DECLASM(void) EMGCEmulateLockCmpXchg_Error(void);
    46 DECLASM(void) EMGCEmulateCmpXchg_EndProc(void);
    47 DECLASM(void) EMGCEmulateCmpXchg_Error(void);
    48 DECLASM(void) EMGCEmulateLockCmpXchg8b_EndProc(void);
    49 DECLASM(void) EMGCEmulateLockCmpXchg8b_Error(void);
    50 DECLASM(void) EMGCEmulateCmpXchg8b_EndProc(void);
    51 DECLASM(void) EMGCEmulateCmpXchg8b_Error(void);
    52 DECLASM(void) EMGCEmulateLockXAdd_EndProc(void);
    53 DECLASM(void) EMGCEmulateLockXAdd_Error(void);
    54 DECLASM(void) EMGCEmulateXAdd_EndProc(void);
    55 DECLASM(void) EMGCEmulateXAdd_Error(void);
    56 DECLASM(void) EMEmulateLockOr_EndProc(void);
    57 DECLASM(void) EMEmulateLockOr_Error(void);
    58 DECLASM(void) EMEmulateLockBtr_EndProc(void);
    59 DECLASM(void) EMEmulateLockBtr_Error(void);
    6044DECLASM(void) MMGCRamRead_Error(void);
    6145DECLASM(void) MMGCRamWrite_Error(void);
     
    122106 * @param   pSrc        Pointer to the data to write.
    123107 * @param   cb          Size of data to write, only 1/2/4 is valid.
     108 *
     109 * @deprecated Don't use this as it doesn't check the page state.
    124110 */
    125111VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
     
    175161
    176162    /*
    177      * Page fault inside EMGCEmulateLockCmpXchg()? Resume at _Error.
    178      */
    179     if (    (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip
    180         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc)
    181     {
    182         pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error;
    183         return VINF_SUCCESS;
    184     }
    185 
    186     /*
    187      * Page fault inside EMGCEmulateCmpXchg()? Resume at _Error.
    188      */
    189     if (    (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip
    190         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc)
    191     {
    192         pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error;
    193         return VINF_SUCCESS;
    194     }
    195 
    196     /*
    197      * Page fault inside EMGCEmulateLockCmpXchg8b()? Resume at _Error.
    198      */
    199     if (    (uintptr_t)&EMGCEmulateLockCmpXchg8b < (uintptr_t)pRegFrame->eip
    200         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg8b_EndProc)
    201     {
    202         pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg8b_Error;
    203         return VINF_SUCCESS;
    204     }
    205 
    206     /*
    207      * Page fault inside EMGCEmulateCmpXchg8b()? Resume at _Error.
    208      */
    209     if (    (uintptr_t)&EMGCEmulateCmpXchg8b < (uintptr_t)pRegFrame->eip
    210         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg8b_EndProc)
    211     {
    212         pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg8b_Error;
    213         return VINF_SUCCESS;
    214     }
    215 
    216     /*
    217      * Page fault inside EMGCEmulateLockXAdd()? Resume at _Error.
    218      */
    219     if (    (uintptr_t)&EMGCEmulateLockXAdd < (uintptr_t)pRegFrame->eip
    220         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockXAdd_EndProc)
    221     {
    222         pRegFrame->eip = (uintptr_t)&EMGCEmulateLockXAdd_Error;
    223         return VINF_SUCCESS;
    224     }
    225 
    226     /*
    227      * Page fault inside EMGCEmulateXAdd()? Resume at _Error.
    228      */
    229     if (    (uintptr_t)&EMGCEmulateXAdd < (uintptr_t)pRegFrame->eip
    230         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateXAdd_EndProc)
    231     {
    232         pRegFrame->eip = (uintptr_t)&EMGCEmulateXAdd_Error;
    233         return VINF_SUCCESS;
    234     }
    235 
    236     /*
    237      * Page fault inside EMEmulateLockOr()? Resume at *_Error.
    238      */
    239     if (    (uintptr_t)&EMEmulateLockOr < (uintptr_t)pRegFrame->eip
    240         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockOr_EndProc)
    241     {
    242         pRegFrame->eip = (uintptr_t)&EMEmulateLockOr_Error;
    243         return VINF_SUCCESS;
    244     }
    245 
    246     /*
    247      * Page fault inside EMEmulateLockBtr()? Resume at *_Error.
    248      */
    249     if (    (uintptr_t)&EMEmulateLockBtr < (uintptr_t)pRegFrame->eip
    250         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockBtr_EndProc)
    251     {
    252         pRegFrame->eip = (uintptr_t)&EMEmulateLockBtr_Error;
    253         return VINF_SUCCESS;
    254     }
    255 
    256     /*
    257163     * #PF is not handled - cause guru meditation.
    258164     */
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