Changeset 30338 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 21, 2010 2:48:17 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r29287 r30338 424 424 DECLINLINE(int) emRamWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, RTGCPTR GCPtrDst, const void *pvSrc, uint32_t cb) 425 425 { 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. */ 438 428 return PGMPhysInterpretedWriteNoHandlers(pVCpu, pCtxCore, GCPtrDst, pvSrc, cb, /*fMayTrap*/ false); 439 429 } … … 933 923 RTGCPTR GCPtrPar1 = param1.val.val64; 934 924 GCPtrPar1 = emConvertToFlatAddr(pVM, pRegFrame, pDis, &pDis->param1, GCPtrPar1); 935 #ifdef IN_RC936 pvParam1 = (void *)(uintptr_t)GCPtrPar1;937 #else938 925 PGMPAGEMAPLOCK Lock; 939 926 rc = PGMPhysGCPtr2CCPtr(pVCpu, GCPtrPar1, &pvParam1, &Lock); 940 927 AssertRCReturn(rc, VERR_EM_INTERPRETER); 941 #endif942 928 943 929 /* Try emulate it with a one-shot #PF handler in place. (RC) */ … … 945 931 946 932 RTGCUINTREG32 eflags = 0; 947 #ifdef IN_RC948 MMGCRamRegisterTrapHandler(pVM);949 #endif950 933 rc = pfnEmulate(pvParam1, ValPar2, pDis->param2.size, &eflags); 951 #ifdef IN_RC952 MMGCRamDeregisterTrapHandler(pVM);953 #else954 934 PGMPhysReleasePageMappingLock(pVM, &Lock); 955 #endif956 935 if (RT_FAILURE(rc)) 957 936 { … … 1189 1168 #endif 1190 1169 1191 #ifdef IN_RC1192 pvParam1 = (void *)(uintptr_t)GCPtrPar1;1193 #else1194 1170 PGMPAGEMAPLOCK Lock; 1195 1171 rc = PGMPhysGCPtr2CCPtr(pVCpu, GCPtrPar1, &pvParam1, &Lock); 1196 1172 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1197 #endif1198 1173 1199 1174 Log2(("emInterpretLockBitTest %s: pvFault=%RGv GCPtrPar1=%RGv imm=%RX64\n", emGetMnemonic(pDis), pvFault, GCPtrPar1, ValPar2)); … … 1201 1176 /* Try emulate it with a one-shot #PF handler in place. (RC) */ 1202 1177 RTGCUINTREG32 eflags = 0; 1203 #ifdef IN_RC1204 MMGCRamRegisterTrapHandler(pVM);1205 #endif1206 1178 rc = pfnEmulate(pvParam1, ValPar2, &eflags); 1207 #ifdef IN_RC1208 MMGCRamDeregisterTrapHandler(pVM);1209 #else1210 1179 PGMPhysReleasePageMappingLock(pVM, &Lock); 1211 #endif1212 1180 if (RT_FAILURE(rc)) 1213 1181 { … … 1514 1482 #endif /* !IN_RC */ 1515 1483 1516 #ifndef IN_RC1517 1484 1518 1485 /** … … 1637 1604 } 1638 1605 1639 #else /* IN_RC */ 1640 1641 /** 1642 * [LOCK] CMPXCHGemulation.1643 */ 1644 static int emInterpret CmpXchg(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 */ 1611 static int emInterpretXAdd(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 1645 1612 { 1646 1613 Assert(pDis->mode != CPUMODE_64BIT); /** @todo check */ 1647 OP_PARAMVAL param1, param2; 1614 OP_PARAMVAL param1; 1615 void *pvParamReg2; 1616 size_t cbParamReg2; 1648 1617 1649 1618 /* Source to make DISQueryParamVal read the register value - ugly hack */ … … 1652 1621 return VERR_EM_INTERPRETER; 1653 1622 1654 rc = DISQueryParamVal(pRegFrame, pDis, &pDis->param2, ¶m2, PARAM_SOURCE); 1623 rc = DISQueryParamRegPtr(pRegFrame, pDis, &pDis->param2, &pvParamReg2, &cbParamReg2); 1624 Assert(cbParamReg2 <= 4); 1655 1625 if(RT_FAILURE(rc)) 1656 1626 return VERR_EM_INTERPRETER; 1657 1627 1628 #ifdef IN_RC 1658 1629 if (TRPMHasTrap(pVCpu)) 1659 1630 { 1660 1631 if (TRPMGetErrorCode(pVCpu) & X86_TRAP_PF_RW) 1661 1632 { 1662 RTRCPTR pParam1; 1663 uint32_t valpar, eflags; 1633 #endif 1634 RTGCPTR GCPtrPar1; 1635 void *pvParam1; 1636 uint32_t eflags; 1637 PGMPAGEMAPLOCK Lock; 1664 1638 1665 1639 AssertReturn(pDis->param1.size == pDis->param2.size, VERR_EM_INTERPRETER); … … 1667 1641 { 1668 1642 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); 1671 1650 break; 1672 1651 … … 1675 1654 } 1676 1655 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 1690 1658 if (pDis->prefix & PREFIX_LOCK) 1691 rc = EMGCEmulateLockCmpXchg(pParam1, &pRegFrame->eax, valpar, pDis->param2.size, &eflags);1659 eflags = EMEmulateLockXAdd(pvParam1, pvParamReg2, cbParamReg2); 1692 1660 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) )); 1703 1664 1704 1665 /* Update guest's eflags and finish. */ … … 1706 1667 | (eflags & (X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF)); 1707 1668 1708 *pcbSize = param2.size; 1669 *pcbSize = cbParamReg2; 1670 PGMPhysReleasePageMappingLock(pVM, &Lock); 1709 1671 return VINF_SUCCESS; 1672 #ifdef IN_RC 1710 1673 } 1711 1674 } 1675 1712 1676 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, ¶m1, 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, ¶m1, 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 1844 1678 } 1845 1679 #endif /* IN_RC */ … … 3193 3027 * @copydoc EMInterpretInstructionCPU 3194 3028 */ 3195 DECLINLINE(int) emInterpretInstructionCPU(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize, EMCODETYPE enmCodeType) 3029 DECLINLINE(int) emInterpretInstructionCPU(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, 3030 uint32_t *pcbSize, EMCODETYPE enmCodeType) 3196 3031 { 3197 3032 Assert(enmCodeType == EMCODETYPE_SUPERVISOR || enmCodeType == EMCODETYPE_ALL); -
trunk/src/VBox/VMM/VMMAll/EMAllA.asm
r28800 r30338 24 24 25 25 ;; @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). 27 27 %ifdef RT_ARCH_AMD64 28 28 %define MY_PTR_REG rcx … … 293 293 BITS 32 294 294 %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0 295 296 297 %ifdef IN_RC298 ; #PF resume point.299 GLOBALNAME EMEmulateLockAnd_Error300 mov eax, VERR_ACCESS_DENIED301 ret302 %endif303 304 295 ENDPROC EMEmulateLockAnd 305 296 … … 471 462 BITS 32 472 463 %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0 473 474 475 %ifdef IN_RC476 ; #PF resume point.477 GLOBALNAME EMEmulateLockOr_Error478 mov eax, VERR_ACCESS_DENIED479 ret480 %endif481 482 464 ENDPROC EMEmulateLockOr 483 465 … … 649 631 BITS 32 650 632 %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0 651 652 653 %ifdef IN_RC654 ; #PF resume point.655 GLOBALNAME EMEmulateLockXor_Error656 mov eax, VERR_ACCESS_DENIED657 ret658 %endif659 660 633 ENDPROC EMEmulateLockXor 661 634 … … 1097 1070 mov eax, VINF_SUCCESS 1098 1071 retn 1099 1100 %ifdef IN_RC1101 ; #PF resume point.1102 GLOBALNAME EMEmulateLockBtr_Error1103 mov eax, VERR_ACCESS_DENIED1104 ret1105 %endif1106 1107 1072 ENDPROC EMEmulateLockBtr 1108 1073 … … 1529 1494 ENDPROC EMEmulateCmpXchg8b 1530 1495 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 ; 1506 align 16 1507 BEGINPROC 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) 1572 BITS 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) 1582 BITS 32 1583 %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0 1584 ENDPROC 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}. 1595 align 16 1596 BEGINPROC 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) 1661 BITS 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) 1671 BITS 32 1672 %endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0 1673 ENDPROC EMEmulateXAdd 1674 -
trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
r29436 r30338 287 287 * raw mode code. Some thought needs to be spent on theoretical concurrency issues as 288 288 * 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 kicked290 * out from both the shadow pt (SMP or our changes) and TLB.291 289 * 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) 299 293 return PGMPhysInterpretedWriteNoHandlers(pVCpu, pCtxCore, GCPtrDst, pvSrc, cb, false /*fRaiseTrap*/); 300 294 #else -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r30078 r30338 3451 3451 * 4. Set access bits if required. 3452 3452 */ 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. */ 3453 3456 int rc; 3454 3457 unsigned cb1 = PAGE_SIZE - (GCPtrDst & PAGE_OFFSET_MASK);
Note:
See TracChangeset
for help on using the changeset viewer.