VirtualBox

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


Ignore:
Timestamp:
Jun 21, 2010 2:48:17 PM (15 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/src/VBox/VMM/VMMAll
Files:
4 edited

Legend:

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