Changeset 46504 in vbox
- Timestamp:
- Jun 11, 2013 5:34:21 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r46500 r46504 94 94 PHYSICAL_TABLE and AVIC LOGICAL_TABLE Pointers). */ 95 95 #define HMSVM_VMCB_CLEAN_AVIC RT_BIT(11) 96 /** Mask of all valid VMCB Clean bits. */ 97 #define HMSVM_VMCB_CLEAN_ALL ( HMSVM_VMCB_CLEAN_INTERCEPTS 98 | HMSVM_VMCB_CLEAN_IOPM_MSRPM 99 | HMSVM_VMCB_CLEAN_ASID 100 | HMSVM_VMCB_CLEAN_TPR 101 | HMSVM_VMCB_CLEAN_NP 102 | HMSVM_VMCB_CLEAN_CRX 103 | HMSVM_VMCB_CLEAN_DRX 104 | HMSVM_VMCB_CLEAN_DT 105 | HMSVM_VMCB_CLEAN_SEG 106 | HMSVM_VMCB_CLEAN_CR2 107 | HMSVM_VMCB_CLEAN_LBR 108 | HMSVM_VMCB_CLEAN_AVIC) 96 109 /** @} */ 110 111 /** @name SVM-transient. 112 * 113 * A state structure for holding miscellaneous information across AMD-V 114 * VMRUN/#VMEXIT operation, restored after the transition. 115 * 116 * @{ */ 117 typedef struct SVMTRANSIENT 118 { 119 /** The host's rflags/eflags. */ 120 RTCCUINTREG uEFlags; 121 } SVMTRANSIENT, *PSVMTRANSIENT; 122 /** @} */ 123 97 124 98 125 /** … … 416 443 if (uMsr <= 0x00001FFF) 417 444 { 418 /* Pentium-compatible MSRs */445 /* Pentium-compatible MSRs. */ 419 446 ulBit = uMsr * 2; 420 447 } … … 422 449 && uMsr <= 0xC0001FFF) 423 450 { 424 /* AMD Sixth Generation x86 Processor MSRs and SYSCALL*/451 /* AMD Sixth Generation x86 Processor MSRs. */ 425 452 ulBit = (uMsr - 0xC0000000) * 2; 426 453 pbMsrBitmap += 0x800; … … 429 456 && uMsr <= 0xC0011FFF) 430 457 { 431 /* AMD Seventh and Eighth Generation Processor MSRs */458 /* AMD Seventh and Eighth Generation Processor MSRs. */ 432 459 ulBit = (uMsr - 0xC0001000) * 2; 433 460 pbMsrBitmap += 0x1000; … … 1747 1774 * @retval VINF_* scheduling changes, we have to go back to ring-3. 1748 1775 * 1749 * @param pVCpu Pointer to the VMCPU. 1750 * @param pCtx Pointer to the guest-CPU context. 1751 */ 1752 DECLINE(int) hmR0SvmPreRunGuest(PVMCPU pVCpu, PCPUMCTX pCtx) 1776 * @param pVCpu Pointer to the VMCPU. 1777 * @param pCtx Pointer to the guest-CPU context. 1778 * @param pSvmTransient Pointer to the SVM transient structure. 1779 */ 1780 DECLINE(int) hmR0SvmPreRunGuest(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient) 1753 1781 { 1754 1782 /* Check force flag actions that might require us to go back to ring-3. */ … … 1759 1787 #ifdef VBOX_WITH_VMMR0_DISABLE_PREEMPTION 1760 1788 /* We disable interrupts so that we don't miss any interrupts that would flag preemption (IPI/timers etc.) */ 1761 p VmxTransient->uEFlags = ASMIntDisableFlags();1789 pSvmTransient->uEFlags = ASMIntDisableFlags(); 1762 1790 if (RTThreadPreemptIsPending(NIL_RTTHREAD)) 1763 1791 { 1764 ASMSetFlags(p VmxTransient->uEFlags);1792 ASMSetFlags(pSvmTransient->uEFlags); 1765 1793 STAM_COUNTER_INC(&pVCpu->hm.s.StatPendingHostIrq); 1766 1794 /* Don't use VINF_EM_RAW_INTERRUPT_HYPER as we can't assume the host does kernel preemption. Maybe some day? */ … … 1790 1818 * @param pVCpu Pointer to the VMCPU. 1791 1819 * @param pCtx Pointer to the guest-CPU context. 1820 * @param pSvmTransient Pointer to the SVM transient structure. 1792 1821 * 1793 1822 * @remarks Called with preemption disabled. 1794 1823 * @remarks No-long-jump zone!!! 1795 1824 */ 1796 DECLINLINE(void) hmR0 VmxPreRunGuestCommitted(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)1825 DECLINLINE(void) hmR0SvmPreRunGuestCommitted(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient) 1797 1826 { 1798 1827 Assert(!VMMRZCallRing3IsEnabled(pVCpu)); … … 1801 1830 #ifndef VBOX_WITH_VMMR0_DISABLE_PREEMPTION 1802 1831 /** @todo I don't see the point of this, VMMR0EntryFast() already disables interrupts for the entire period. */ 1803 p VmxTransient->uEFlags = ASMIntDisableFlags();1832 pSvmTransient->uEFlags = ASMIntDisableFlags(); 1804 1833 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC); 1805 1834 #endif … … 1818 1847 AssertRC(rc); 1819 1848 AssertMsg(!pVCpu->hm.s.fContextUseFlags, ("fContextUseFlags =%#x\n", pVCpu->hm.s.fContextUseFlags)); 1820 1849 STAM_COUNTER_INC(&pVCpu->hm.s.StatLoadFull); 1850 1851 /* Flush the appropriate tagged-TLB entries. */ 1852 ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, true); /* Used for TLB-shootdowns, set this across the world switch. */ 1853 hmR0SvmFlushTaggedTlb(pVCpu); 1854 Assert(HMR0GetCurrentCpu()->idCpu == pVCpu->hm.s.idLastCpu); 1855 1856 TMNotifyStartOfExecution(pVCpu); /* Finally, notify TM to resume its clocks as we're about 1857 to start executing. */ 1858 1859 /* 1860 * Save the current Host TSC_AUX and write the guest TSC_AUX to the host, so that 1861 * RDTSCPs (that don't cause exits) reads the guest MSR. See @bugref{3324}. 1862 * 1863 * This should be done -after- any RDTSCPs for obtaining the host timestamp (TM, STAM etc). 1864 */ 1865 u32HostExtFeatures = pVM->hm.s.cpuid.u32AMDFeatureEDX; 1866 if ( (u32HostExtFeatures & X86_CPUID_EXT_FEATURE_EDX_RDTSCP) 1867 && !(pVmcb->ctrl.u32InterceptCtrl2 & SVM_CTRL2_INTERCEPT_RDTSCP)) 1868 { 1869 pVCpu->hm.s.u64HostTscAux = ASMRdMsr(MSR_K8_TSC_AUX); 1870 uint64_t u64GuestTscAux = 0; 1871 rc2 = CPUMQueryGuestMsr(pVCpu, MSR_K8_TSC_AUX, &u64GuestTscAux); 1872 AssertRC(rc2); 1873 ASMWrMsr(MSR_K8_TSC_AUX, u64GuestTscAux); 1874 } 1821 1875 } 1822 1876 … … 1840 1894 */ 1841 1895 #ifdef VBOX_WITH_KERNEL_USING_XMM 1842 returnHMR0SVMRunWrapXMM(pVCpu->hm.s.svm.HCPhysVmcbHost, pVCpu->hm.s.svm.HCPhysVmcb, pCtx, pVM, pVCpu,1843 1896 HMR0SVMRunWrapXMM(pVCpu->hm.s.svm.HCPhysVmcbHost, pVCpu->hm.s.svm.HCPhysVmcb, pCtx, pVM, pVCpu, 1897 pVCpu->hm.s.svm.pfnVMRun); 1844 1898 #else 1845 return pVCpu->hm.s.svm.pfnStartVM(pVCpu->hm.s.fResumeVM, pCtx, &pVCpu->hm.s.vmx.VMCSCache, pVM, pVCpu);1899 pVCpu->hm.s.svm.pfnVMRun(pVCpu->hm.s.svm.HCPhysVmcbHost, pVCpu->hm.s.svm.HCPhysVmcb, pCtx, pVM, pVCpu); 1846 1900 #endif 1847 1901 } 1902 1903 1904 /** 1905 * Performs some essential restoration of state after running guest code in 1906 * AMD-V. 1907 * 1908 * @param pVM Pointer to the VM. 1909 * @param pVCpu Pointer to the VMCPU. 1910 * @param pMixedCtx Pointer to the guest-CPU context. The data maybe 1911 * out-of-sync. Make sure to update the required fields 1912 * before using them. 1913 * @param pSvmTransient Pointer to the SVM transient structure. 1914 * @param rcVMRun Return code of VMRUN. 1915 * 1916 * @remarks Called with interrupts disabled. 1917 * @remarks No-long-jump zone!!! This function will however re-enable longjmps 1918 * unconditionally when it is safe to do so. 1919 */ 1920 DECLINLINE(void) hmR0SvmPostRunGuest(PVM pVM, PVMCPU pVCpu, PCPUMCTX pMixedCtx, PSVMTRANSIENT pSvmTransient, rcVMRun) 1921 { 1922 Assert(!VMMRZCallRing3IsEnabled(pVCpu)); 1923 1924 ASMAtomicWriteBool(&pVCpu->hm.s.fCheckedTLBFlush, false); /* See HMInvalidatePageOnAllVCpus(): used for TLB-shootdowns. */ 1925 ASMAtomicIncU32(&pVCpu->hm.s.cWorldSwitchExits); /* Initialized in vmR3CreateUVM(): used for TLB-shootdowns. */ 1926 1927 PSVMVMCB pVmcb = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb; 1928 pVmcb->u64VmcbCleanBits = HMSVM_VMCB_CLEAN_ALL; /* Mark the VMCB-state cache as unmodified by VMM. */ 1929 1930 /* Restore host's TSC_AUX if required. */ 1931 if (!(pVmcb->ctrl.u32InterceptCtrl1 & SVM_CTRL1_INTERCEPT_RDTSC)) 1932 { 1933 if (u32HostExtFeatures & X86_CPUID_EXT_FEATURE_EDX_RDTSCP) 1934 ASMWrMsr(MSR_K8_TSC_AUX, pVCpu->hm.s.u64HostTscAux); 1935 1936 /** @todo Find a way to fix hardcoding a guestimate. */ 1937 TMCpuTickSetLastSeen(pVCpu, ASMReadTSC() + 1938 pVmcb->ctrl.u64TSCOffset - 0x400 /* guestimate of world switch overhead in clock ticks */); 1939 } 1940 1941 TMNotifyEndOfExecution(pVCpu); /* Notify TM that the guest is no longer running. */ 1942 Assert(!(ASMGetFlags() & X86_EFL_IF)); 1943 VMCPU_SET_STATE(pVCpu, VMCPUSTATE_STARTED_HM); 1944 1945 /* -XXX- TPR patching? */ 1946 1947 ASMSetFlags(pSvmTransient->uEFlags); /* Enable interrupts. */ 1948 1949 /* --XXX- todo */ 1950 } 1951 1848 1952 1849 1953 … … 1861 1965 Assert(!RTThreadPreemptIsEnabled(NIL_RTTHREAD)); 1862 1966 1967 SVMTRANSIENT SvmTransient; 1863 1968 uint32_t cLoops = 0; 1864 1969 PSVMVMCB pVmcb = (PSVMVMCB)pVCpu->hm.s.svm.pvVmcb; … … 1874 1979 /* Preparatory work for running guest code, this may return to ring-3 for some last minute updates. */ 1875 1980 STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatEntry, x); 1876 rc = hmR0VmxPreRunGuest(pVM, pVCpu, pCtx );1981 rc = hmR0VmxPreRunGuest(pVM, pVCpu, pCtx, &SvmTransient); 1877 1982 if (rc != VINF_SUCCESS) 1878 1983 break; … … 1885 1990 VMMRZCallRing3Disable(pVCpu); 1886 1991 VMMRZCallRing3RemoveNotification(pVCpu); 1887 hmR0 VmxPreRunGuestCommitted(pVM, pVCpu, pCtx);1992 hmR0SvmPreRunGuestCommitted(pVM, pVCpu, pCtx, &SvmTransient); 1888 1993 1889 1994 rc = hmR0SvmRunGuest(pVM, pVCpu, pCtx);
Note:
See TracChangeset
for help on using the changeset viewer.