Changeset 30263 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jun 16, 2010 6:31:42 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 62771
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
r30164 r30263 1854 1854 1855 1855 1856 1857 #ifndef IN_RING0 /** @todo I don't think we need this in R0, so move it to CPUMAll.cpp? */ 1858 1859 /** 1860 * Transforms the guest CPU state to raw-ring mode. 1861 * 1862 * This function will change the any of the cs and ss register with DPL=0 to DPL=1. 1863 * 1864 * @returns VBox status. (recompiler failure) 1865 * @param pVCpu The VMCPU handle. 1866 * @param pCtxCore The context core (for trap usage). 1867 * @see @ref pg_raw 1868 */ 1869 VMMDECL(int) CPUMRawEnter(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore) 1870 { 1871 PVM pVM = pVCpu->CTX_SUFF(pVM); 1872 1873 Assert(!pVM->cpum.s.fRawEntered); 1874 if (!pCtxCore) 1875 pCtxCore = CPUMCTX2CORE(&pVCpu->cpum.s.Guest); 1876 1877 /* 1878 * Are we in Ring-0? 1879 */ 1880 if ( pCtxCore->ss && (pCtxCore->ss & X86_SEL_RPL) == 0 1881 && !pCtxCore->eflags.Bits.u1VM) 1882 { 1883 /* 1884 * Enter execution mode. 1885 */ 1886 PATMRawEnter(pVM, pCtxCore); 1887 1888 /* 1889 * Set CPL to Ring-1. 1890 */ 1891 pCtxCore->ss |= 1; 1892 if (pCtxCore->cs && (pCtxCore->cs & X86_SEL_RPL) == 0) 1893 pCtxCore->cs |= 1; 1894 } 1895 else 1896 { 1897 AssertMsg((pCtxCore->ss & X86_SEL_RPL) >= 2 || pCtxCore->eflags.Bits.u1VM, 1898 ("ring-1 code not supported\n")); 1899 /* 1900 * PATM takes care of IOPL and IF flags for Ring-3 and Ring-2 code as well. 1901 */ 1902 PATMRawEnter(pVM, pCtxCore); 1903 } 1904 1905 /* 1906 * Assert sanity. 1907 */ 1908 AssertMsg((pCtxCore->eflags.u32 & X86_EFL_IF), ("X86_EFL_IF is clear\n")); 1909 AssertReleaseMsg( pCtxCore->eflags.Bits.u2IOPL < (unsigned)(pCtxCore->ss & X86_SEL_RPL) 1910 || pCtxCore->eflags.Bits.u1VM, 1911 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss & X86_SEL_RPL)); 1912 Assert((pVCpu->cpum.s.Guest.cr0 & (X86_CR0_PG | X86_CR0_WP | X86_CR0_PE)) == (X86_CR0_PG | X86_CR0_PE | X86_CR0_WP)); 1913 pCtxCore->eflags.u32 |= X86_EFL_IF; /* paranoia */ 1914 1915 pVM->cpum.s.fRawEntered = true; 1916 return VINF_SUCCESS; 1917 } 1918 1919 1920 /** 1921 * Transforms the guest CPU state from raw-ring mode to correct values. 1922 * 1923 * This function will change any selector registers with DPL=1 to DPL=0. 1924 * 1925 * @returns Adjusted rc. 1926 * @param pVCpu The VMCPU handle. 1927 * @param rc Raw mode return code 1928 * @param pCtxCore The context core (for trap usage). 1929 * @see @ref pg_raw 1930 */ 1931 VMMDECL(int) CPUMRawLeave(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, int rc) 1932 { 1933 PVM pVM = pVCpu->CTX_SUFF(pVM); 1934 1935 /* 1936 * Don't leave if we've already left (in GC). 1937 */ 1938 Assert(pVM->cpum.s.fRawEntered); 1939 if (!pVM->cpum.s.fRawEntered) 1940 return rc; 1941 pVM->cpum.s.fRawEntered = false; 1942 1943 PCPUMCTX pCtx = &pVCpu->cpum.s.Guest; 1944 if (!pCtxCore) 1945 pCtxCore = CPUMCTX2CORE(pCtx); 1946 Assert(pCtxCore->eflags.Bits.u1VM || (pCtxCore->ss & X86_SEL_RPL)); 1947 AssertMsg(pCtxCore->eflags.Bits.u1VM || pCtxCore->eflags.Bits.u2IOPL < (unsigned)(pCtxCore->ss & X86_SEL_RPL), 1948 ("X86_EFL_IOPL=%d CPL=%d\n", pCtxCore->eflags.Bits.u2IOPL, pCtxCore->ss & X86_SEL_RPL)); 1949 1950 /* 1951 * Are we executing in raw ring-1? 1952 */ 1953 if ( (pCtxCore->ss & X86_SEL_RPL) == 1 1954 && !pCtxCore->eflags.Bits.u1VM) 1955 { 1956 /* 1957 * Leave execution mode. 1958 */ 1959 PATMRawLeave(pVM, pCtxCore, rc); 1960 /* Not quite sure if this is really required, but shouldn't harm (too much anyways). */ 1961 /** @todo See what happens if we remove this. */ 1962 if ((pCtxCore->ds & X86_SEL_RPL) == 1) 1963 pCtxCore->ds &= ~X86_SEL_RPL; 1964 if ((pCtxCore->es & X86_SEL_RPL) == 1) 1965 pCtxCore->es &= ~X86_SEL_RPL; 1966 if ((pCtxCore->fs & X86_SEL_RPL) == 1) 1967 pCtxCore->fs &= ~X86_SEL_RPL; 1968 if ((pCtxCore->gs & X86_SEL_RPL) == 1) 1969 pCtxCore->gs &= ~X86_SEL_RPL; 1970 1971 /* 1972 * Ring-1 selector => Ring-0. 1973 */ 1974 pCtxCore->ss &= ~X86_SEL_RPL; 1975 if ((pCtxCore->cs & X86_SEL_RPL) == 1) 1976 pCtxCore->cs &= ~X86_SEL_RPL; 1977 } 1978 else 1979 { 1980 /* 1981 * PATM is taking care of the IOPL and IF flags for us. 1982 */ 1983 PATMRawLeave(pVM, pCtxCore, rc); 1984 if (!pCtxCore->eflags.Bits.u1VM) 1985 { 1986 /** @todo See what happens if we remove this. */ 1987 if ((pCtxCore->ds & X86_SEL_RPL) == 1) 1988 pCtxCore->ds &= ~X86_SEL_RPL; 1989 if ((pCtxCore->es & X86_SEL_RPL) == 1) 1990 pCtxCore->es &= ~X86_SEL_RPL; 1991 if ((pCtxCore->fs & X86_SEL_RPL) == 1) 1992 pCtxCore->fs &= ~X86_SEL_RPL; 1993 if ((pCtxCore->gs & X86_SEL_RPL) == 1) 1994 pCtxCore->gs &= ~X86_SEL_RPL; 1995 } 1996 } 1997 1998 return rc; 1999 } 2000 1856 #ifndef IN_RING0 2001 1857 /** 2002 1858 * Updates the EFLAGS while we're in raw-mode. … … 2010 1866 PVM pVM = pVCpu->CTX_SUFF(pVM); 2011 1867 2012 if (!pV M->cpum.s.fRawEntered)1868 if (!pVCpu->cpum.s.fRawEntered) 2013 1869 { 2014 1870 pCtxCore->eflags.u32 = eflags; … … 2017 1873 PATMRawSetEFlags(pVM, pCtxCore, eflags); 2018 1874 } 2019 2020 1875 #endif /* !IN_RING0 */ 1876 2021 1877 2022 1878 /** … … 2034 1890 PVM pVM = pVCpu->CTX_SUFF(pVM); 2035 1891 2036 if (!pV M->cpum.s.fRawEntered)1892 if (!pVCpu->cpum.s.fRawEntered) 2037 1893 return pCtxCore->eflags.u32; 2038 1894 return PATMRawGetEFlags(pVM, pCtxCore); 2039 1895 #endif 2040 }2041 2042 2043 /**2044 * Gets and resets the changed flags (CPUM_CHANGED_*).2045 * Only REM should call this function.2046 *2047 * @returns The changed flags.2048 * @param pVCpu The VMCPU handle.2049 */2050 VMMDECL(unsigned) CPUMGetAndClearChangedFlagsREM(PVMCPU pVCpu)2051 {2052 unsigned fFlags = pVCpu->cpum.s.fChanged;2053 pVCpu->cpum.s.fChanged = 0;2054 /** @todo change the switcher to use the fChanged flags. */2055 if (pVCpu->cpum.s.fUseFlags & CPUM_USED_FPU_SINCE_REM)2056 {2057 fFlags |= CPUM_CHANGED_FPU_REM;2058 pVCpu->cpum.s.fUseFlags &= ~CPUM_USED_FPU_SINCE_REM;2059 }2060 return fFlags;2061 1896 } 2062 1897 … … 2169 2004 2170 2005 /** 2171 * Mark the guest's debug state as inactive 2006 * Mark the guest's debug state as inactive. 2172 2007 * 2173 2008 * @returns boolean … … 2181 2016 2182 2017 /** 2183 * Mark the hypervisor's debug state as inactive 2018 * Mark the hypervisor's debug state as inactive. 2184 2019 * 2185 2020 * @returns boolean … … 2192 2027 2193 2028 /** 2194 * Checks if the hidden selector registers are valid 2029 * Checks if the hidden selector registers are valid for the specified CPU. 2030 * 2195 2031 * @returns true if they are. 2196 2032 * @returns false if not. 2197 * @param pVM The VM handle. 2198 */ 2199 VMMDECL(bool) CPUMAreHiddenSelRegsValid(PVM pVM) 2200 { 2201 return HWACCMIsEnabled(pVM); 2033 * @param pVCpu The VM handle. 2034 */ 2035 VMMDECL(bool) CPUMAreHiddenSelRegsValid(PVMCPU pVCpu) 2036 { 2037 bool const fRc = !(pVCpu->cpum.s.fChanged & CPUM_CHANGED_HIDDEN_SEL_REGS_INVALID); 2038 Assert(fRc || !HWACCMIsEnabled(pVCpu->CTX_SUFF(pVM))); 2039 Assert(!pVCpu->cpum.s.fRemEntered); 2040 return fRc; 2202 2041 } 2203 2042 … … 2215 2054 uint32_t cpl; 2216 2055 2217 if (CPUMAreHiddenSelRegsValid(pVCpu ->CTX_SUFF(pVM)))2056 if (CPUMAreHiddenSelRegsValid(pVCpu)) 2218 2057 { 2219 2058 /* -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r29676 r30263 773 773 */ 774 774 RTGCPTR PC; 775 rc = SELMValidateAndConvertCSAddr(pVM, pRegFrame->eflags, pRegFrame->ss, pRegFrame->cs, &pRegFrame->csHid, (RTGCPTR)pRegFrame->eip, &PC); 775 rc = SELMValidateAndConvertCSAddr(pVM, pRegFrame->eflags, pRegFrame->ss, pRegFrame->cs, 776 &pRegFrame->csHid, (RTGCPTR)pRegFrame->eip, &PC); 776 777 if (rc == VINF_SUCCESS) 777 778 { -
trunk/src/VBox/VMM/VMMAll/SELMAll.cpp
r28800 r30263 98 98 { 99 99 RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff; 100 if (CPUMAreHiddenSelRegsValid(pV M))100 if (CPUMAreHiddenSelRegsValid(pVCpu)) 101 101 uFlat += pHiddenSel->u64Base; 102 102 else … … 106 106 107 107 #ifdef IN_RING0 108 Assert(CPUMAreHiddenSelRegsValid(pV M));108 Assert(CPUMAreHiddenSelRegsValid(pVCpu)); 109 109 #else 110 110 /** @todo when we're in 16 bits mode, we should cut off the address as well.. */ 111 if (!CPUMAreHiddenSelRegsValid(pV M))111 if (!CPUMAreHiddenSelRegsValid(pVCpu)) 112 112 return SELMToFlatBySel(pVM, Sel, Addr); 113 113 #endif … … 170 170 { 171 171 if ( pHiddenSel 172 && CPUMAreHiddenSelRegsValid(pV M))172 && CPUMAreHiddenSelRegsValid(pVCpu)) 173 173 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat); 174 174 else … … 186 186 #ifndef IN_RC 187 187 if ( pHiddenSel 188 && CPUMAreHiddenSelRegsValid(pV M))188 && CPUMAreHiddenSelRegsValid(pVCpu)) 189 189 { 190 190 bool fCheckLimit = true; … … 460 460 * @remarks Don't use when in long mode. 461 461 */ 462 VMMDECL(int) SELMToFlatBySelEx(PVM pVM, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, CPUMSELREGHID *pHiddenSel, unsigned fFlags, PRTGCPTR ppvGC, uint32_t *pcb)462 VMMDECL(int) SELMToFlatBySelEx(PVM pVM, X86EFLAGS eflags, RTSEL Sel, RTGCPTR Addr, PCCPUMSELREGHID pHiddenSel, unsigned fFlags, PRTGCPTR ppvGC, uint32_t *pcb) 463 463 { 464 464 PVMCPU pVCpu = VMMGetCpu(pVM); … … 476 476 { 477 477 if ( pHiddenSel 478 && CPUMAreHiddenSelRegsValid(pV M))478 && CPUMAreHiddenSelRegsValid(pVCpu)) 479 479 *ppvGC = (RTGCPTR)(pHiddenSel->u64Base + uFlat); 480 480 else … … 493 493 /** @todo when we're in 16 bits mode, we should cut off the address as well.. */ 494 494 if ( pHiddenSel 495 && CPUMAreHiddenSelRegsValid(pV M))495 && CPUMAreHiddenSelRegsValid(pVCpu)) 496 496 { 497 497 u1Present = pHiddenSel->Attr.n.u1Present; … … 665 665 * 666 666 * @returns VINF_SUCCESS. 667 * @param pV M VM Handle.667 * @param pVCpu The Virtual CPU handle. 668 668 * @param SelCS Selector part. 669 669 * @param pHidCS The hidden CS register part. Optional. … … 671 671 * @param ppvFlat Where to store the flat address. 672 672 */ 673 DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVM pVM, RTSEL SelCS, PCPUMSELREGHID pHidCS, RTGCPTR Addr, PRTGCPTR ppvFlat) 673 DECLINLINE(int) selmValidateAndConvertCSAddrRealMode(PVMCPU pVCpu, RTSEL SelCS, PCCPUMSELREGHID pHidCS, RTGCPTR Addr, 674 PRTGCPTR ppvFlat) 674 675 { 675 676 RTGCUINTPTR uFlat = (RTGCUINTPTR)Addr & 0xffff; 676 if (!pHidCS || !CPUMAreHiddenSelRegsValid(pV M))677 if (!pHidCS || !CPUMAreHiddenSelRegsValid(pVCpu)) 677 678 uFlat += ((RTGCUINTPTR)SelCS << 4); 678 679 else … … 690 691 * @returns VBox status code. 691 692 * @param pVM VM Handle. 693 * @param pVCpu The virtual CPU handle. 692 694 * @param SelCPL Current privilege level. Get this from SS - CS might be conforming! 693 695 * A full selector can be passed, we'll only use the RPL part. … … 697 699 * @param pcBits Where to store the segment bitness (16/32/64). Optional. 698 700 */ 699 DECLINLINE(int) selmValidateAndConvertCSAddrStd(PVM pVM, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, PRTGCPTR ppvFlat, uint32_t *pcBits) 700 { 701 Assert(!CPUMAreHiddenSelRegsValid(pVM)); 702 701 DECLINLINE(int) selmValidateAndConvertCSAddrStd(PVM pVM, PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, RTGCPTR Addr, 702 PRTGCPTR ppvFlat, uint32_t *pcBits) 703 { 703 704 /** @todo validate limit! */ 704 705 X86DESC Desc; … … 771 772 * @param ppvFlat Where to store the flat address. 772 773 */ 773 DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCPUMSELREGHID pHidCS, RTGCPTR Addr, PRTGCPTR ppvFlat) 774 DECLINLINE(int) selmValidateAndConvertCSAddrHidden(PVMCPU pVCpu, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHidCS, 775 RTGCPTR Addr, PRTGCPTR ppvFlat) 774 776 { 775 777 /* … … 849 851 { 850 852 *pcBits = 16; 851 return selmValidateAndConvertCSAddrRealMode(pVM, SelCS, NULL, Addr, ppvFlat); 852 } 853 return selmValidateAndConvertCSAddrStd(pVM, SelCPL, SelCS, Addr, ppvFlat, pcBits); 853 return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, NULL, Addr, ppvFlat); 854 } 855 Assert(!CPUMAreHiddenSelRegsValid(pVCpu)); 856 return selmValidateAndConvertCSAddrStd(pVM, pVCpu, SelCPL, SelCS, Addr, ppvFlat, pcBits); 854 857 } 855 858 #endif /* IN_RC */ … … 869 872 * @param ppvFlat Where to store the flat address. 870 873 */ 871 VMMDECL(int) SELMValidateAndConvertCSAddr(PVM pVM, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, CPUMSELREGHID *pHiddenCSSel, RTGCPTR Addr, PRTGCPTR ppvFlat) 874 VMMDECL(int) SELMValidateAndConvertCSAddr(PVM pVM, X86EFLAGS eflags, RTSEL SelCPL, RTSEL SelCS, PCCPUMSELREGHID pHiddenCSSel, 875 RTGCPTR Addr, PRTGCPTR ppvFlat) 872 876 { 873 877 PVMCPU pVCpu = VMMGetCpu(pVM); … … 875 879 if ( eflags.Bits.u1VM 876 880 || CPUMIsGuestInRealMode(pVCpu)) 877 return selmValidateAndConvertCSAddrRealMode(pV M, SelCS, pHiddenCSSel, Addr, ppvFlat);881 return selmValidateAndConvertCSAddrRealMode(pVCpu, SelCS, pHiddenCSSel, Addr, ppvFlat); 878 882 879 883 #ifdef IN_RING0 880 Assert(CPUMAreHiddenSelRegsValid(pV M));884 Assert(CPUMAreHiddenSelRegsValid(pVCpu)); 881 885 #else 882 886 /** @todo when we're in 16 bits mode, we should cut off the address as well? (like in selmValidateAndConvertCSAddrRealMode) */ 883 if (!CPUMAreHiddenSelRegsValid(pV M))884 return selmValidateAndConvertCSAddrStd(pVM, SelCPL, SelCS, Addr, ppvFlat, NULL);887 if (!CPUMAreHiddenSelRegsValid(pVCpu) || !pHiddenCSSel) 888 return selmValidateAndConvertCSAddrStd(pVM, pVCpu, SelCPL, SelCS, Addr, ppvFlat, NULL); 885 889 #endif 886 890 return selmValidateAndConvertCSAddrHidden(pVCpu, SelCPL, SelCS, pHiddenCSSel, Addr, ppvFlat); … … 894 898 * @returns DISCPUMODE according to the selector type (16, 32 or 64 bits) 895 899 * @param pVM VM Handle. 900 * @param pVCpu The virtual CPU handle. 896 901 * @param Sel The selector. 897 902 */ 898 static DISCPUMODE selmGetCpuModeFromSelector(PVM pVM, RTSEL Sel)899 { 900 Assert(!CPUMAreHiddenSelRegsValid(pV M));903 static DISCPUMODE selmGetCpuModeFromSelector(PVM pVM, PVMCPU pVCpu, RTSEL Sel) 904 { 905 Assert(!CPUMAreHiddenSelRegsValid(pVCpu)); 901 906 902 907 /** @todo validate limit! */ … … 924 929 * @param pHiddenSel The hidden selector register. 925 930 */ 926 VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVM pVM, X86EFLAGS eflags, RTSEL Sel, CPUMSELREGHID *pHiddenSel)931 VMMDECL(DISCPUMODE) SELMGetCpuModeFromSelector(PVM pVM, X86EFLAGS eflags, RTSEL Sel, PCCPUMSELREGHID pHiddenSel) 927 932 { 928 933 PVMCPU pVCpu = VMMGetCpu(pVM); 929 934 #ifdef IN_RING0 930 Assert(CPUMAreHiddenSelRegsValid(pV M));935 Assert(CPUMAreHiddenSelRegsValid(pVCpu)); 931 936 #else /* !IN_RING0 */ 932 if (!CPUMAreHiddenSelRegsValid(pV M))937 if (!CPUMAreHiddenSelRegsValid(pVCpu)) 933 938 { 934 939 /* … … 939 944 return CPUMODE_16BIT; 940 945 941 return selmGetCpuModeFromSelector(pVM, Sel);946 return selmGetCpuModeFromSelector(pVM, pVCpu, Sel); 942 947 } 943 948 #endif /* !IN_RING0 */ … … 947 952 948 953 /* Else compatibility or 32 bits mode. */ 949 return (pHiddenSel->Attr.n.u1DefBig)? CPUMODE_32BIT : CPUMODE_16BIT;954 return pHiddenSel->Attr.n.u1DefBig ? CPUMODE_32BIT : CPUMODE_16BIT; 950 955 } 951 956 -
trunk/src/VBox/VMM/VMMAll/TRPMAll.cpp
r29250 r30263 358 358 * @internal 359 359 */ 360 VMMDECL(int) TRPMForwardTrap(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t opsize, TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap) 360 VMMDECL(int) TRPMForwardTrap(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t iGate, uint32_t opsize, 361 TRPMERRORCODE enmError, TRPMEVENT enmType, int32_t iOrgTrap) 361 362 { 362 363 #ifdef TRPM_FORWARD_TRAPS_IN_GC
Note:
See TracChangeset
for help on using the changeset viewer.