Changeset 20317 in vbox
- Timestamp:
- Jun 5, 2009 12:20:10 PM (16 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r20291 r20317 44 44 #include <iprt/cpuset.h> 45 45 #include <iprt/mp.h> 46 #include <iprt/time.h> 46 47 #ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION 47 48 # include <iprt/thread.h> … … 858 859 RTCCUINTREG uOldEFlags = ~(RTCCUINTREG)0; 859 860 #ifdef VBOX_STRICT 860 RTCPUID idCpuCheck; 861 RTCPUID idCpuCheck; 862 #endif 863 #ifdef VBOX_HIGH_RES_TIMERS_HACK_IN_RING0 864 uint64_t u64LastTime = RTTimeMilliTS(); 861 865 #endif 862 866 … … 900 904 pVMCB->ctrl.u64IntShadow = 0; 901 905 } 906 907 #ifdef VBOX_HIGH_RES_TIMERS_HACK_IN_RING0 908 if (RT_UNLIKELY(cResume & 0xf) == 0) 909 { 910 uint64_t u64CurTime = RTTimeMilliTS(); 911 912 if (RT_UNLIKELY(u64CurTime > u64LastTime)) 913 { 914 u64LastTime = u64CurTime; 915 TMTimerPollVoid(pVM, pVCpu); 916 } 917 } 918 #endif 902 919 903 920 /* Check for pending actions that force us to go back to ring 3. */ … … 1514 1531 AssertRC(rc); 1515 1532 1516 pVM->hwaccm.s.svm.fTPRPatching = true;1517 1533 Log(("Acceptable write candidate!\n")); 1518 1534 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x); … … 1534 1550 AssertRC(rc); 1535 1551 1536 pVM->hwaccm.s.svm.fTPRPatching = true;1537 1552 Log(("Acceptable read candidate!\n")); 1538 1553 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x); … … 1684 1699 Assert(pVM->hwaccm.s.fNestedPaging); 1685 1700 LogFlow(("Nested page fault at %RGv cr2=%RGp error code %x\n", (RTGCPTR)pCtx->rip, uFaultAddress, errCode)); 1701 1702 #if 0 1703 /* Shortcut for APIC TPR reads and writes; 32 bits guests only */ 1704 if ( (uFaultAddress & 0xfff) == 0x080 1705 && pVM->hwaccm.s.fHasIoApic 1706 && !(errCode & X86_TRAP_PF_P) /* not present */ 1707 && !CPUMIsGuestInLongModeEx(pCtx)) 1708 { 1709 RTGCPHYS GCPhysApicBase; 1710 PDMApicGetBase(pVM, &GCPhysApicBase); /* @todo cache this */ 1711 GCPhysApicBase &= PAGE_BASE_GC_MASK; 1712 1713 if (uFaultAddress == GCPhysApicBase + 0x80) 1714 { 1715 Log(("Replace TPR access at %RGv\n", pCtx->rip)); 1716 DISCPUSTATE Cpu; 1717 unsigned cbOp; 1718 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 1719 AssertRC(rc); 1720 if ( rc == VINF_SUCCESS 1721 && Cpu.pCurInstr->opcode == OP_MOV) 1722 { 1723 uint8_t szInstr[15]; 1724 if ( cbOp == 10 1725 && (errCode & X86_TRAP_PF_RW) 1726 && Cpu.param2.flags == USE_IMMEDIATE32) 1727 { 1728 /* Found: 1729 * mov [fffe0080], immediate_dword (10 bytes) 1730 * 1731 * Replace with: 1732 * mov free_register, immediate_dword >> 4 (5 bytes) 1733 * mov cr8, free_register (4 bytes) 1734 * nop (1 byte) 1735 * 1736 */ 1737 RTGCPTR oldEip = pCtx->eip; 1738 uint32_t u32tpr = (uint32_t)Cpu.param2.parval; 1739 1740 u32tpr = (u32tpr >> 4) & 0xf; 1741 1742 pCtx->eip += cbOp; 1743 /* Check if the next instruction overwrites a general purpose register. If 1744 * it does, then we can safely use it ourselves. 1745 */ 1746 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 1747 pCtx->eip = oldEip; 1748 if ( rc == VINF_SUCCESS 1749 && Cpu.pCurInstr->opcode == OP_MOV 1750 && Cpu.param1.flags == USE_REG_GEN32) 1751 { 1752 /* 0xB8, dword immediate = mov eax, dword immediate */ 1753 szInstr[0] = 0xB8 + Cpu.param1.base.reg_gen; 1754 szInstr[1] = (uint8_t)u32tpr; 1755 szInstr[2] = 0; 1756 szInstr[3] = 0; 1757 szInstr[4] = 0; 1758 1759 /* 0xF0, 0x0F, 0x22, 0xC0 = mov cr8, eax */ 1760 szInstr[5] = 0xF0; 1761 szInstr[6] = 0x0F; 1762 szInstr[7] = 0x22; 1763 szInstr[8] = 0xC0 | Cpu.param1.base.reg_gen; 1764 szInstr[9] = 0x90; /* nop */ 1765 1766 rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, szInstr, 10); 1767 AssertRC(rc); 1768 1769 Log(("Acceptable write candidate!\n")); 1770 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x); 1771 goto ResumeExecution; 1772 } 1773 } 1774 else 1775 { 1776 if ( Cpu.param2.flags == USE_REG_GEN32 1777 && cbOp == 6) 1778 { 1779 RTGCPTR oldEip = pCtx->eip; 1780 RTGCPTR GCPtrTpr = Cpu.param1.parval; 1781 uint32_t uMmioReg = Cpu.param2.base.reg_gen; 1782 1783 /* Found: 1784 * mov dword [fffe0080], eax (6 bytes) 1785 * Check if next instruction is a TPR read: 1786 * mov ecx, dword [fffe0080] (5 bytes) 1787 */ 1788 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 1789 pCtx->eip = oldEip; 1790 if ( rc == VINF_SUCCESS 1791 && Cpu.pCurInstr->opcode == OP_MOV 1792 && Cpu.param1.flags == USE_REG_GEN32 1793 && Cpu.param2.flags == USE_IMMEDIATE32 1794 && Cpu.param2.parval == GCPtrTpr 1795 && cbOp == 5) 1796 { 1797 /* mov new_reg, uMmioReg */ 1798 szInstr[0] = 0x89; 1799 szInstr[1] = MAKE_MODRM(3, uMmioReg, Cpu.param2.base.reg_gen); 1800 szInstr[2] = 4; 1801 1802 /* Let's hope the guest won't mind us trashing the source register... 1803 * shr uMmioReg, 4 1804 */ 1805 szInstr[3] = 0xC1; 1806 szInstr[4] = 0xE0 | uMmioReg; 1807 szInstr[5] = 4; 1808 1809 /* 0xF0, 0x0F, 0x22, 0xC0 = mov cr8, eax */ 1810 szInstr[6] = 0xF0; 1811 szInstr[7] = 0x0F; 1812 szInstr[8] = 0x22; 1813 szInstr[9] = 0xC0 | uMmioReg; 1814 1815 /* Two nop instructions */ 1816 szInstr[10] = 0x90; 1817 szInstr[11] = 0x90; 1818 1819 rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, szInstr, 6+cbOp); 1820 AssertRC(rc); 1821 1822 Log(("Acceptable write candidate!\n")); 1823 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x); 1824 goto ResumeExecution; 1825 } 1826 } 1827 else 1828 if ( Cpu.param1.flags == USE_REG_GEN32 1829 && cbOp == 5) 1830 { 1831 RTGCPTR oldEip = pCtx->eip; 1832 uint32_t uMmioReg = Cpu.param1.base.reg_gen; 1833 1834 /* Found: 1835 * mov eax, dword [fffe0080] (5 bytes) 1836 * Check if next instruction is: 1837 * shr eax, 4 1838 */ 1839 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp); 1840 pCtx->eip = oldEip; 1841 if ( rc == VINF_SUCCESS 1842 && Cpu.pCurInstr->opcode == OP_SHR 1843 && Cpu.param1.flags == USE_REG_GEN32 1844 && Cpu.param1.base.reg_gen == uMmioReg 1845 && Cpu.param2.flags == USE_IMMEDIATE8 1846 && Cpu.param2.parval == 4) 1847 { 1848 /* 0xF0, 0x0F, 0x20, 0xC0 = mov eax, cr8 */ 1849 szInstr[0] = 0xF0; 1850 szInstr[1] = 0x0F; 1851 szInstr[2] = 0x20; 1852 szInstr[3] = 0xC0 | Cpu.param1.base.reg_gen; 1853 for (unsigned i = 4; i < 5+cbOp; i++) 1854 szInstr[i] = 0x90; /* nop */ 1855 1856 rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, szInstr, 5+cbOp); 1857 AssertRC(rc); 1858 1859 Log(("Acceptable read candidate!\n")); 1860 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x); 1861 goto ResumeExecution; 1862 } 1863 } 1864 } 1865 } 1866 rc = IOMMMIOPhysHandler(pVM, errCode, CPUMCTX2CORE(pCtx), uFaultAddress); 1867 if (rc == VINF_SUCCESS) 1868 goto ResumeExecution; /* rip already updated */ 1869 } 1870 } 1871 #endif 1872 1686 1873 /* Exit qualification contains the linear address of the page fault. */ 1687 1874 TRPMAssertTrap(pVCpu, X86_XCPT_PF, TRPM_TRAP); 1688 1875 TRPMSetErrorCode(pVCpu, errCode); 1689 1876 TRPMSetFaultAddress(pVCpu, uFaultAddress); 1690 1691 #if 01692 /* Shortcut for APIC TPR reads and writes; 32 bits guests only */1693 if ( (uFaultAddress & 0xfff) == 0x0801694 && pVM->hwaccm.s.fHasIoApic1695 && !(errCode & X86_TRAP_PF_P) /* not present */1696 && !CPUMIsGuestInLongModeEx(pCtx))1697 {1698 RTGCPHYS GCPhysApicBase;1699 PDMApicGetBase(pVM, &GCPhysApicBase); /* @todo cache this */1700 GCPhysApicBase &= PAGE_BASE_GC_MASK;1701 1702 if (uFaultAddress == GCPhysApicBase + 0x80)1703 {1704 Log(("Replace TPR access at %RGv\n", pCtx->rip));1705 #if 01706 DISCPUSTATE Cpu;1707 unsigned cbOp;1708 rc = EMInterpretDisasOne(pVM, pVCpu, CPUMCTX2CORE(pCtx), &Cpu, &cbOp);1709 AssertRC(rc);1710 if ( rc == VINF_SUCCESS1711 && Cpu.pCurInstr->opcode == OP_MOV1712 && (cbOp == 5 || cbOp == 6))1713 {1714 uint8_t szInstr[15];1715 if ( (errCode & X86_TRAP_PF_RW)1716 && Cpu.param1.disp32 == (uint32_t)uFaultAddress1717 && Cpu.param2.flags == USE_REG_GEN32)1718 {1719 /* 0xF0, 0x0F, 0x22, 0xC0 = mov cr8, eax */1720 szInstr[0] = 0xF0;1721 szInstr[1] = 0x0F;1722 szInstr[2] = 0x22;1723 szInstr[3] = 0xC0 | Cpu.param2.base.reg_gen;1724 for (unsigned i = 4; i < cbOp; i++)1725 szInstr[i] = 0x90; /* nop */1726 1727 rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, szInstr, cbOp);1728 AssertRC(rc);1729 1730 pVM->hwaccm.s.svm.fTPRPatching = true;1731 Log(("Acceptable write candidate!\n"));1732 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x);1733 goto ResumeExecution;1734 }1735 else1736 if ( Cpu.param2.disp32 == (uint32_t)uFaultAddress1737 && Cpu.param1.flags == USE_REG_GEN32)1738 {1739 /* 0xF0, 0x0F, 0x20, 0xC0 = mov eax, cr8 */1740 szInstr[0] = 0xF0;1741 szInstr[1] = 0x0F;1742 szInstr[2] = 0x20;1743 szInstr[3] = 0xC0 | Cpu.param1.base.reg_gen;1744 for (unsigned i = 4; i < cbOp; i++)1745 szInstr[i] = 0x90; /* nop */1746 1747 rc = PGMPhysSimpleWriteGCPtr(pVCpu, pCtx->rip, szInstr, cbOp);1748 AssertRC(rc);1749 1750 pVM->hwaccm.s.svm.fTPRPatching = true;1751 Log(("Acceptable read candidate!\n"));1752 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, x);1753 goto ResumeExecution;1754 }1755 }1756 #endif1757 }1758 }1759 #endif1760 1877 1761 1878 /* Handle the pagefault trap for the nested shadow table. */ -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r20222 r20317 40 40 #include <iprt/param.h> 41 41 #include <iprt/string.h> 42 #include <iprt/time.h> 42 43 #ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION 43 44 # include <iprt/thread.h> … … 2009 2010 unsigned cResume = 0; 2010 2011 #ifdef VBOX_STRICT 2011 RTCPUID idCpuCheck; 2012 RTCPUID idCpuCheck; 2013 #endif 2014 #ifdef VBOX_HIGH_RES_TIMERS_HACK_IN_RING0 2015 uint64_t u64LastTime = RTTimeMilliTS(); 2012 2016 #endif 2013 2017 #ifdef VBOX_WITH_STATISTICS … … 2139 2143 } 2140 2144 2145 #ifdef VBOX_HIGH_RES_TIMERS_HACK_IN_RING0 2146 if (RT_UNLIKELY(cResume & 0xf) == 0) 2147 { 2148 uint64_t u64CurTime = RTTimeMilliTS(); 2149 2150 if (RT_UNLIKELY(u64CurTime > u64LastTime)) 2151 { 2152 u64LastTime = u64CurTime; 2153 TMTimerPollVoid(pVM, pVCpu); 2154 } 2155 } 2156 #endif 2157 2141 2158 /* Check for pending actions that force us to go back to ring 3. */ 2142 if ( VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK) 2143 || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK)) 2144 { 2145 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3); 2146 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3); 2147 rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3; 2148 goto end; 2149 } 2159 #ifdef DEBUG 2160 /* Intercept X86_XCPT_DB if stepping is enabled */ 2161 if (!DBGFIsStepping(pVCpu)) 2162 #endif 2163 { 2164 if ( VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK) 2165 || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_HWACCM_TO_R3_MASK)) 2166 { 2167 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3); 2168 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3); 2169 rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3; 2170 goto end; 2171 } 2172 } 2173 2150 2174 /* Pending request packets might contain actions that need immediate attention, such as pending hardware interrupts. */ 2151 2175 if ( VM_FF_ISPENDING(pVM, VM_FF_REQUEST)
Note:
See TracChangeset
for help on using the changeset viewer.