- Timestamp:
- Aug 5, 2010 12:01:43 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r31197 r31394 1292 1292 1293 1293 /** 1294 * Loads a minimal guest state 1295 * 1296 * NOTE: Don't do anything here that can cause a jump back to ring 3!!!!! 1297 * 1298 * @param pVM The VM to operate on. 1299 * @param pVCpu The VMCPU to operate on. 1300 * @param pCtx Guest context 1301 */ 1302 VMMR0DECL(void) VMXR0LoadMinimalGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx) 1303 { 1304 int rc; 1305 X86EFLAGS eflags; 1306 1307 Assert(!(pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_ALL_GUEST)); 1308 1309 /* EIP, ESP and EFLAGS */ 1310 rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_RIP, pCtx->rip); 1311 rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_RSP, pCtx->rsp); 1312 AssertRC(rc); 1313 1314 /* Bits 22-31, 15, 5 & 3 must be zero. Bit 1 must be 1. */ 1315 eflags = pCtx->eflags; 1316 eflags.u32 &= VMX_EFLAGS_RESERVED_0; 1317 eflags.u32 |= VMX_EFLAGS_RESERVED_1; 1318 1319 /* Real mode emulation using v86 mode. */ 1320 if ( CPUMIsGuestInRealModeEx(pCtx) 1321 && pVM->hwaccm.s.vmx.pRealModeTSS) 1322 { 1323 pVCpu->hwaccm.s.vmx.RealMode.eflags = eflags; 1324 1325 eflags.Bits.u1VM = 1; 1326 eflags.Bits.u2IOPL = 0; /* must always be 0 or else certain instructions won't cause faults. */ 1327 } 1328 rc = VMXWriteVMCS(VMX_VMCS_GUEST_RFLAGS, eflags.u32); 1329 AssertRC(rc); 1330 } 1331 1332 /** 1294 1333 * Loads the guest state 1295 1334 * … … 1305 1344 int rc = VINF_SUCCESS; 1306 1345 RTGCUINTPTR val; 1307 X86EFLAGS eflags;1308 1346 1309 1347 /* VMX_VMCS_CTRL_ENTRY_CONTROLS … … 1773 1811 } 1774 1812 1775 /* EIP, ESP and EFLAGS */1776 rc = VMXWriteVMCS64(VMX_VMCS64_GUEST_RIP, pCtx->rip);1777 rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_RSP, pCtx->rsp);1778 AssertRC(rc);1779 1780 /* Bits 22-31, 15, 5 & 3 must be zero. Bit 1 must be 1. */1781 eflags = pCtx->eflags;1782 eflags.u32 &= VMX_EFLAGS_RESERVED_0;1783 eflags.u32 |= VMX_EFLAGS_RESERVED_1;1784 1785 /* Real mode emulation using v86 mode. */1786 if ( CPUMIsGuestInRealModeEx(pCtx)1787 && pVM->hwaccm.s.vmx.pRealModeTSS)1788 {1789 pVCpu->hwaccm.s.vmx.RealMode.eflags = eflags;1790 1791 eflags.Bits.u1VM = 1;1792 eflags.Bits.u2IOPL = 0; /* must always be 0 or else certain instructions won't cause faults. */1793 }1794 rc = VMXWriteVMCS(VMX_VMCS_GUEST_RFLAGS, eflags.u32);1795 AssertRC(rc);1796 1797 if (TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hwaccm.s.vmx.u64TSCOffset))1798 {1799 uint64_t u64CurTSC = ASMReadTSC();1800 if (u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu))1801 {1802 /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */1803 rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, pVCpu->hwaccm.s.vmx.u64TSCOffset);1804 AssertRC(rc);1805 1806 pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;1807 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);1808 AssertRC(rc);1809 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset);1810 }1811 else1812 {1813 /* Fall back to rdtsc emulation as we would otherwise pass decreasing tsc values to the guest. */1814 LogFlow(("TSC %RX64 offset %RX64 time=%RX64 last=%RX64 (diff=%RX64, virt_tsc=%RX64)\n", u64CurTSC, pVCpu->hwaccm.s.vmx.u64TSCOffset, u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset, TMCpuTickGetLastSeen(pVCpu), TMCpuTickGetLastSeen(pVCpu) - u64CurTSC - pVCpu->hwaccm.s.vmx.u64TSCOffset, TMCpuTickGet(pVCpu)));1815 pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;1816 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);1817 AssertRC(rc);1818 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow);1819 }1820 }1821 else1822 {1823 pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT;1824 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls);1825 AssertRC(rc);1826 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCIntercept);1827 }1828 1829 1813 /* 64 bits guest mode? */ 1830 1814 if (CPUMIsGuestInLongModeEx(pCtx)) … … 1902 1886 #endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */ 1903 1887 1904 /* Done. */ 1888 if (TMCpuTickCanUseRealTSC(pVCpu, &pVCpu->hwaccm.s.vmx.u64TSCOffset)) 1889 { 1890 uint64_t u64CurTSC = ASMReadTSC(); 1891 if (u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset >= TMCpuTickGetLastSeen(pVCpu)) 1892 { 1893 /* Note: VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT takes precedence over TSC_OFFSET */ 1894 rc = VMXWriteVMCS64(VMX_VMCS_CTRL_TSC_OFFSET_FULL, pVCpu->hwaccm.s.vmx.u64TSCOffset); 1895 AssertRC(rc); 1896 1897 pVCpu->hwaccm.s.vmx.proc_ctls &= ~VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT; 1898 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls); 1899 AssertRC(rc); 1900 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCOffset); 1901 } 1902 else 1903 { 1904 /* Fall back to rdtsc emulation as we would otherwise pass decreasing tsc values to the guest. */ 1905 LogFlow(("TSC %RX64 offset %RX64 time=%RX64 last=%RX64 (diff=%RX64, virt_tsc=%RX64)\n", u64CurTSC, pVCpu->hwaccm.s.vmx.u64TSCOffset, u64CurTSC + pVCpu->hwaccm.s.vmx.u64TSCOffset, TMCpuTickGetLastSeen(pVCpu), TMCpuTickGetLastSeen(pVCpu) - u64CurTSC - pVCpu->hwaccm.s.vmx.u64TSCOffset, TMCpuTickGet(pVCpu))); 1906 pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT; 1907 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls); 1908 AssertRC(rc); 1909 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCInterceptOverFlow); 1910 } 1911 } 1912 else 1913 { 1914 pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT; 1915 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls); 1916 AssertRC(rc); 1917 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatTSCIntercept); 1918 } 1919 1920 /* Done with the major changes */ 1905 1921 pVCpu->hwaccm.s.fContextUseFlags &= ~HWACCM_CHANGED_ALL_GUEST; 1906 1922 1923 /* Minimal guest state update (esp, eip, eflags mostly) */ 1924 VMXR0LoadMinimalGuestState(pVM, pVCpu, pCtx); 1907 1925 return rc; 1908 1926 } … … 2561 2579 #endif 2562 2580 /* Save the host state first. */ 2563 rc = VMXR0SaveHostState(pVM, pVCpu); 2564 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 2565 { 2566 VMMR0LogFlushEnable(pVCpu); 2567 goto end; 2568 } 2581 if (pVCpu->hwaccm.s.fContextUseFlags & HWACCM_CHANGED_HOST_CONTEXT) 2582 { 2583 rc = VMXR0SaveHostState(pVM, pVCpu); 2584 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 2585 { 2586 VMMR0LogFlushEnable(pVCpu); 2587 goto end; 2588 } 2589 } 2590 2569 2591 /* Load the guest state */ 2570 rc = VMXR0LoadGuestState(pVM, pVCpu, pCtx); 2571 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 2572 { 2573 VMMR0LogFlushEnable(pVCpu); 2574 goto end; 2592 #if 0 2593 if (!pVCpu->hwaccm.s.fContextUseFlags) 2594 { 2595 VMXR0LoadMinimalGuestState(pVM, pVCpu, pCtx); 2596 } 2597 else 2598 #endif 2599 { 2600 rc = VMXR0LoadGuestState(pVM, pVCpu, pCtx); 2601 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 2602 { 2603 VMMR0LogFlushEnable(pVCpu); 2604 goto end; 2605 } 2575 2606 } 2576 2607 … … 3859 3890 } 3860 3891 } 3861 3862 3892 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub1, y1); 3863 3893 goto ResumeExecution;
Note:
See TracChangeset
for help on using the changeset viewer.