Changeset 72918 in vbox
- Timestamp:
- Jul 5, 2018 1:53:14 PM (7 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
r72917 r72918 1286 1286 * Call worker. 1287 1287 */ 1288 rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu));1288 rc = nemR0WinExportState(pGVM, pGVCpu, &pVCpu->cpum.GstCtx); 1289 1289 } 1290 1290 return rc; … … 2207 2207 * Call worker. 2208 2208 */ 2209 rc = nemR0WinImportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat);2209 rc = nemR0WinImportState(pGVM, pGVCpu, &pVCpu->cpum.GstCtx, fWhat); 2210 2210 } 2211 2211 return rc; -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r72695 r72918 1630 1630 } 1631 1631 } 1632 1633 #if 0 //ndef NEM_WIN_USE_OUR_OWN_RUN_API - migrating to NEMAllNativeTemplate-win.cpp.h */1634 1635 # ifdef LOG_ENABLED1636 /**1637 * Log the full details of an exit reason.1638 *1639 * @param pExitReason The exit reason to log.1640 */1641 static void nemR3WinLogWHvExitReason(WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1642 {1643 bool fExitCtx = false;1644 bool fExitInstr = false;1645 switch (pExitReason->ExitReason)1646 {1647 case WHvRunVpExitReasonMemoryAccess:1648 Log2(("Exit: Memory access: GCPhys=%RGp GCVirt=%RGv %s %s %s\n",1649 pExitReason->MemoryAccess.Gpa, pExitReason->MemoryAccess.Gva,1650 g_apszWHvMemAccesstypes[pExitReason->MemoryAccess.AccessInfo.AccessType],1651 pExitReason->MemoryAccess.AccessInfo.GpaUnmapped ? "unmapped" : "mapped",1652 pExitReason->MemoryAccess.AccessInfo.GvaValid ? "" : "invalid-gc-virt"));1653 AssertMsg(!(pExitReason->MemoryAccess.AccessInfo.AsUINT32 & ~UINT32_C(0xf)),1654 ("MemoryAccess.AccessInfo=%#x\n", pExitReason->MemoryAccess.AccessInfo.AsUINT32));1655 fExitCtx = fExitInstr = true;1656 break;1657 1658 case WHvRunVpExitReasonX64IoPortAccess:1659 Log2(("Exit: I/O port access: IoPort=%#x LB %u %s%s%s rax=%#RX64 rcx=%#RX64 rsi=%#RX64 rdi=%#RX64\n",1660 pExitReason->IoPortAccess.PortNumber,1661 pExitReason->IoPortAccess.AccessInfo.AccessSize,1662 pExitReason->IoPortAccess.AccessInfo.IsWrite ? "out" : "in",1663 pExitReason->IoPortAccess.AccessInfo.StringOp ? " string" : "",1664 pExitReason->IoPortAccess.AccessInfo.RepPrefix ? " rep" : "",1665 pExitReason->IoPortAccess.Rax,1666 pExitReason->IoPortAccess.Rcx,1667 pExitReason->IoPortAccess.Rsi,1668 pExitReason->IoPortAccess.Rdi));1669 Log2(("Exit: + ds=%#x:{%#RX64 LB %#RX32, %#x} es=%#x:{%#RX64 LB %#RX32, %#x}\n",1670 pExitReason->IoPortAccess.Ds.Selector,1671 pExitReason->IoPortAccess.Ds.Base,1672 pExitReason->IoPortAccess.Ds.Limit,1673 pExitReason->IoPortAccess.Ds.Attributes,1674 pExitReason->IoPortAccess.Es.Selector,1675 pExitReason->IoPortAccess.Es.Base,1676 pExitReason->IoPortAccess.Es.Limit,1677 pExitReason->IoPortAccess.Es.Attributes ));1678 1679 AssertMsg( pExitReason->IoPortAccess.AccessInfo.AccessSize == 11680 || pExitReason->IoPortAccess.AccessInfo.AccessSize == 21681 || pExitReason->IoPortAccess.AccessInfo.AccessSize == 4,1682 ("IoPortAccess.AccessInfo.AccessSize=%d\n", pExitReason->IoPortAccess.AccessInfo.AccessSize));1683 AssertMsg(!(pExitReason->IoPortAccess.AccessInfo.AsUINT32 & ~UINT32_C(0x3f)),1684 ("IoPortAccess.AccessInfo=%#x\n", pExitReason->IoPortAccess.AccessInfo.AsUINT32));1685 fExitCtx = fExitInstr = true;1686 break;1687 1688 # if 01689 case WHvRunVpExitReasonUnrecoverableException:1690 case WHvRunVpExitReasonInvalidVpRegisterValue:1691 case WHvRunVpExitReasonUnsupportedFeature:1692 case WHvRunVpExitReasonX64InterruptWindow:1693 case WHvRunVpExitReasonX64Halt:1694 case WHvRunVpExitReasonX64MsrAccess:1695 case WHvRunVpExitReasonX64Cpuid:1696 case WHvRunVpExitReasonException:1697 case WHvRunVpExitReasonCanceled:1698 case WHvRunVpExitReasonAlerted:1699 WHV_X64_MSR_ACCESS_CONTEXT MsrAccess;1700 WHV_X64_CPUID_ACCESS_CONTEXT CpuidAccess;1701 WHV_VP_EXCEPTION_CONTEXT VpException;1702 WHV_X64_INTERRUPTION_DELIVERABLE_CONTEXT InterruptWindow;1703 WHV_UNRECOVERABLE_EXCEPTION_CONTEXT UnrecoverableException;1704 WHV_X64_UNSUPPORTED_FEATURE_CONTEXT UnsupportedFeature;1705 WHV_RUN_VP_CANCELED_CONTEXT CancelReason;1706 # endif1707 1708 case WHvRunVpExitReasonNone:1709 Log2(("Exit: No reason\n"));1710 AssertFailed();1711 break;1712 1713 default:1714 Log(("Exit: %#x\n", pExitReason->ExitReason));1715 break;1716 }1717 1718 /*1719 * Context and maybe instruction details.1720 */1721 if (fExitCtx)1722 {1723 const WHV_VP_EXIT_CONTEXT *pVpCtx = &pExitReason->VpContext;1724 Log2(("Exit: + CS:RIP=%04x:%08RX64 RFLAGS=%06RX64 cbInstr=%u CS={%RX64 L %#RX32, %#x}\n",1725 pVpCtx->Cs.Selector,1726 pVpCtx->Rip,1727 pVpCtx->Rflags,1728 pVpCtx->InstructionLength,1729 pVpCtx->Cs.Base, pVpCtx->Cs.Limit, pVpCtx->Cs.Attributes));1730 Log2(("Exit: + cpl=%d CR0.PE=%d CR0.AM=%d EFER.LMA=%d DebugActive=%d InterruptionPending=%d InterruptShadow=%d\n",1731 pVpCtx->ExecutionState.Cpl,1732 pVpCtx->ExecutionState.Cr0Pe,1733 pVpCtx->ExecutionState.Cr0Am,1734 pVpCtx->ExecutionState.EferLma,1735 pVpCtx->ExecutionState.DebugActive,1736 pVpCtx->ExecutionState.InterruptionPending,1737 pVpCtx->ExecutionState.InterruptShadow));1738 AssertMsg(!(pVpCtx->ExecutionState.AsUINT16 & ~UINT16_C(0x107f)),1739 ("ExecutionState.AsUINT16=%#x\n", pVpCtx->ExecutionState.AsUINT16));1740 1741 /** @todo Someone at Microsoft please explain why the InstructionBytes fields1742 * are 16 bytes long, when 15 would've been sufficent and saved 3-7 bytes of1743 * alignment padding? Intel max length is 15, so is this sSome ARM stuff?1744 * Aren't ARM1745 * instructions max 32-bit wide? Confused. */1746 if (fExitInstr && pExitReason->IoPortAccess.InstructionByteCount > 0)1747 Log2(("Exit: + Instruction %.*Rhxs\n",1748 pExitReason->IoPortAccess.InstructionByteCount, &pExitReason->IoPortAccess.InstructionBytes[0]));1749 }1750 }1751 # endif /* LOG_ENABLED */1752 1753 1754 static VBOXSTRICTRC nemR3WinWHvHandleHalt(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)1755 {1756 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx);1757 LogFlow(("nemR3WinWHvHandleHalt\n"));1758 return VINF_EM_HALT;1759 }1760 1761 1762 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES1763 /**1764 * @callback_method_impl{FNPGMPHYSNEMENUMCALLBACK,1765 * Hack to unmap all pages when/before we run into quota (WHv only).}1766 */1767 static DECLCALLBACK(int) nemR3WinWHvUnmapOnePageCallback(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, uint8_t *pu2NemState, void *pvUser)1768 {1769 RT_NOREF_PV(pvUser);1770 RT_NOREF_PV(pVCpu);1771 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE);1772 if (SUCCEEDED(hrc))1773 {1774 Log5(("NEM GPA unmap all: %RGp (cMappedPages=%u)\n", GCPhys, pVM->nem.s.cMappedPages - 1));1775 *pu2NemState = NEM_WIN_PAGE_STATE_UNMAPPED;1776 }1777 else1778 {1779 LogRel(("nemR3WinWHvUnmapOnePageCallback: GCPhys=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n",1780 GCPhys, g_apszPageStates[*pu2NemState], hrc, hrc, RTNtLastStatusValue(),1781 RTNtLastErrorValue(), pVM->nem.s.cMappedPages));1782 *pu2NemState = NEM_WIN_PAGE_STATE_NOT_SET;1783 }1784 if (pVM->nem.s.cMappedPages > 0)1785 ASMAtomicDecU32(&pVM->nem.s.cMappedPages);1786 return VINF_SUCCESS;1787 }1788 # endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */1789 1790 1791 /**1792 * Handles an memory access VMEXIT.1793 *1794 * This can be triggered by a number of things.1795 *1796 * @returns Strict VBox status code.1797 * @param pVM The cross context VM structure.1798 * @param pVCpu The cross context virtual CPU structure.1799 * @param pCtx The CPU context to update.1800 * @param pMemCtx The exit reason information.1801 * @param pVpContext The processor context info associated with the exit.1802 */1803 static VBOXSTRICTRC nemR3WinWHvHandleMemoryAccess(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_MEMORY_ACCESS_CONTEXT const *pMemCtx,1804 WHV_VP_EXIT_CONTEXT const *pVpContext)1805 {1806 /*1807 * Ask PGM for information about the given GCPhys. We need to check if we're1808 * out of sync first.1809 */1810 NEMHCWINHMACPCCSTATE State = { pMemCtx->AccessInfo.AccessType == WHvMemoryAccessWrite, false, false };1811 PGMPHYSNEMPAGEINFO Info;1812 int rc = PGMPhysNemPageInfoChecker(pVM, pVCpu, pMemCtx->Gpa, State.fWriteAccess, &Info,1813 nemHCWinHandleMemoryAccessPageCheckerCallback, &State);1814 if (RT_SUCCESS(rc))1815 {1816 if (Info.fNemProt & (pMemCtx->AccessInfo.AccessType == WHvMemoryAccessWrite ? NEM_PAGE_PROT_WRITE : NEM_PAGE_PROT_READ))1817 {1818 if (State.fCanResume)1819 {1820 Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; restarting (%s)\n",1821 pMemCtx->Gpa, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,1822 Info.fHasHandlers ? " handlers" : "", Info.fZeroPage ? " zero-pg" : "",1823 State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));1824 return VINF_SUCCESS;1825 }1826 }1827 Log4(("MemExit: %RGp (=>%RHp) %s fProt=%u%s%s%s; emulating (%s)\n",1828 pMemCtx->Gpa, Info.HCPhys, g_apszPageStates[Info.u2NemState], Info.fNemProt,1829 Info.fHasHandlers ? " handlers" : "", Info.fZeroPage ? " zero-pg" : "",1830 State.fDidSomething ? "" : " no-change", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));1831 }1832 else1833 Log4(("MemExit: %RGp rc=%Rrc%s; emulating (%s)\n", pMemCtx->Gpa, rc,1834 State.fDidSomething ? " modified-backing" : "", g_apszWHvMemAccesstypes[pMemCtx->AccessInfo.AccessType]));1835 1836 /*1837 * Emulate the memory access, either access handler or special memory.1838 */1839 rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);1840 AssertRCReturn(rc, rc);1841 1842 VBOXSTRICTRC rcStrict;1843 if (pMemCtx->InstructionByteCount > 0)1844 rcStrict = IEMExecOneWithPrefetchedByPC(pVCpu, CPUMCTX2CORE(pCtx), pVpContext->Rip,1845 &pMemCtx->InstructionBytes[0], pMemCtx->InstructionByteCount);1846 else1847 rcStrict = IEMExecOne(pVCpu);1848 /** @todo do we need to do anything wrt debugging here? */1849 return rcStrict;1850 }1851 1852 1853 /**1854 * Handles an I/O port access VMEXIT.1855 *1856 * We ASSUME that the hypervisor has don't I/O port access control.1857 *1858 * @returns Strict VBox status code.1859 * @param pVM The cross context VM structure.1860 * @param pVCpu The cross context virtual CPU structure.1861 * @param pCtx The CPU context to update.1862 * @param pIoPortCtx The exit reason information.1863 * @param pVpContext The processor context info associated with the exit.1864 */1865 static VBOXSTRICTRC1866 nemR3WinWHvHandleIoPortAccess(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_X64_IO_PORT_ACCESS_CONTEXT const *pIoPortCtx,1867 WHV_VP_EXIT_CONTEXT const *pVpContext)1868 {1869 Assert( pIoPortCtx->AccessInfo.AccessSize == 11870 || pIoPortCtx->AccessInfo.AccessSize == 21871 || pIoPortCtx->AccessInfo.AccessSize == 4);1872 1873 VBOXSTRICTRC rcStrict;1874 if (!pIoPortCtx->AccessInfo.StringOp)1875 {1876 /*1877 * Simple port I/O.1878 */1879 //Assert(pCtx->rax == pIoPortCtx->Rax); - sledgehammer1880 1881 static uint32_t const s_fAndMask[8] =1882 { UINT32_MAX, UINT32_C(0xff), UINT32_C(0xffff), UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX };1883 uint32_t const fAndMask = s_fAndMask[pIoPortCtx->AccessInfo.AccessSize];1884 if (pIoPortCtx->AccessInfo.IsWrite)1885 {1886 rcStrict = IOMIOPortWrite(pVM, pVCpu, pIoPortCtx->PortNumber, (uint32_t)pIoPortCtx->Rax & fAndMask,1887 pIoPortCtx->AccessInfo.AccessSize);1888 if (IOM_SUCCESS(rcStrict))1889 nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, pVpContext);1890 }1891 else1892 {1893 uint32_t uValue = 0;1894 rcStrict = IOMIOPortRead(pVM, pVCpu, pIoPortCtx->PortNumber, &uValue,1895 pIoPortCtx->AccessInfo.AccessSize);1896 if (IOM_SUCCESS(rcStrict))1897 {1898 pCtx->eax = (pCtx->eax & ~fAndMask) | (uValue & fAndMask);1899 nemR3WinAdvanceGuestRipAndClearRF(pVCpu, pCtx, pVpContext);1900 }1901 }1902 }1903 else1904 {1905 /*1906 * String port I/O.1907 */1908 /** @todo Someone at Microsoft please explain how we can get the address mode1909 * from the IoPortAccess.VpContext. CS.Attributes is only sufficient for1910 * getting the default mode, it can always be overridden by a prefix. This1911 * forces us to interpret the instruction from opcodes, which is suboptimal.1912 * Both AMD-V and VT-x includes the address size in the exit info, at least on1913 * CPUs that are reasonably new. */1914 # if 0 // requires sledgehammer1915 Assert( pIoPortCtx->Ds.Base == pCtx->ds.u64Base1916 && pIoPortCtx->Ds.Limit == pCtx->ds.u32Limit1917 && pIoPortCtx->Ds.Selector == pCtx->ds.Sel);1918 Assert( pIoPortCtx->Es.Base == pCtx->es.u64Base1919 && pIoPortCtx->Es.Limit == pCtx->es.u32Limit1920 && pIoPortCtx->Es.Selector == pCtx->es.Sel);1921 Assert(pIoPortCtx->Rdi == pCtx->rdi);1922 Assert(pIoPortCtx->Rsi == pCtx->rsi);1923 Assert(pIoPortCtx->Rcx == pCtx->rcx);1924 Assert(pIoPortCtx->Rcx == pCtx->rcx);1925 # endif1926 1927 int rc = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM);1928 AssertRCReturn(rc, rc);1929 1930 rcStrict = IEMExecOne(pVCpu);1931 }1932 if (IOM_SUCCESS(rcStrict))1933 {1934 /*1935 * Do debug checks.1936 */1937 if ( pVpContext->ExecutionState.DebugActive /** @todo Microsoft: Does DebugActive this only reflext DR7? */1938 || (pVpContext->Rflags & X86_EFL_TF)1939 || DBGFBpIsHwIoArmed(pVM) )1940 {1941 /** @todo Debugging. */1942 }1943 }1944 return rcStrict;1945 }1946 1947 1948 static VBOXSTRICTRC nemR3WinWHvHandleInterruptWindow(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1949 {1950 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1951 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1952 }1953 1954 1955 static VBOXSTRICTRC nemR3WinWHvHandleMsrAccess(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1956 {1957 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1958 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1959 }1960 1961 1962 static VBOXSTRICTRC nemR3WinWHvHandleCpuId(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1963 {1964 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1965 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1966 }1967 1968 1969 static VBOXSTRICTRC nemR3WinWHvHandleException(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1970 {1971 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1972 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1973 }1974 1975 1976 static VBOXSTRICTRC nemR3WinWHvHandleUD(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1977 {1978 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1979 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1980 }1981 1982 1983 static VBOXSTRICTRC nemR3WinWHvHandleTripleFault(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1984 {1985 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1986 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1987 }1988 1989 1990 static VBOXSTRICTRC nemR3WinWHvHandleInvalidState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, WHV_RUN_VP_EXIT_CONTEXT const *pExitReason)1991 {1992 NOREF(pVM); NOREF(pVCpu); NOREF(pCtx); NOREF(pExitReason);1993 AssertLogRelFailedReturn(VERR_NOT_IMPLEMENTED);1994 }1995 1996 1997 VBOXSTRICTRC nemR3WinWHvRunGC(PVM pVM, PVMCPU pVCpu)1998 {1999 # ifdef LOG_ENABLED2000 if (LogIs3Enabled())2001 {2002 Log3(("nemR3NativeRunGC: Entering #%u\n", pVCpu->idCpu));2003 nemHCWinLogState(pVM, pVCpu);2004 }2005 # endif2006 2007 /*2008 * The run loop.2009 */2010 PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);2011 const bool fSingleStepping = false; /** @todo get this from somewhere. */2012 VBOXSTRICTRC rcStrict = VINF_SUCCESS;2013 for (unsigned iLoop = 0;;iLoop++)2014 {2015 /*2016 * Copy the state.2017 */2018 int rc2 = nemHCWinCopyStateToHyperV(pVM, pVCpu, pCtx);2019 AssertRCBreakStmt(rc2, rcStrict = rc2);2020 2021 /*2022 * Run a bit.2023 */2024 WHV_RUN_VP_EXIT_CONTEXT ExitReason;2025 RT_ZERO(ExitReason);2026 if ( !VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS | VM_FF_TM_VIRTUAL_SYNC)2027 && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK))2028 {2029 Log8(("Calling WHvRunVirtualProcessor\n"));2030 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED);2031 HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason));2032 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM);2033 AssertLogRelMsgBreakStmt(SUCCEEDED(hrc),2034 ("WHvRunVirtualProcessor(%p, %u,,) -> %Rhrc (Last=%#x/%u)\n", pVM->nem.s.hPartition, pVCpu->idCpu,2035 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()),2036 rcStrict = VERR_INTERNAL_ERROR);2037 Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n",2038 hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemHCWinCpuGetRunningStatus(pVCpu) ));2039 }2040 else2041 {2042 LogFlow(("nemR3NativeRunGC: returning: pending FF (pre exec)\n"));2043 break;2044 }2045 2046 # if 0 /* sledgehammer approach */2047 /*2048 * Copy back the state.2049 */2050 rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, UINT64_MAX);2051 AssertRCBreakStmt(rc2, rcStrict = rc2);2052 # endif2053 2054 # ifdef LOG_ENABLED2055 /*2056 * Do some logging.2057 */2058 if (LogIs2Enabled())2059 nemR3WinLogWHvExitReason(&ExitReason);2060 if (LogIs3Enabled())2061 nemHCWinLogState(pVM, pVCpu);2062 # endif2063 2064 # if 0 //def VBOX_STRICT - requires sledgehammer2065 /* Assert that the VpContext field makes sense. */2066 switch (ExitReason.ExitReason)2067 {2068 case WHvRunVpExitReasonMemoryAccess:2069 case WHvRunVpExitReasonX64IoPortAccess:2070 case WHvRunVpExitReasonX64MsrAccess:2071 case WHvRunVpExitReasonX64Cpuid:2072 case WHvRunVpExitReasonException:2073 case WHvRunVpExitReasonUnrecoverableException:2074 Assert( ExitReason.IoPortAccess.VpContext.InstructionLength > 02075 || ( ExitReason.ExitReason == WHvRunVpExitReasonMemoryAccess2076 && ExitReason.MemoryAccess.AccessInfo.AccessType == WHvMemoryAccessExecute));2077 Assert(ExitReason.IoPortAccess.VpContext.InstructionLength < 16);2078 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cpl == CPUMGetGuestCPL(pVCpu));2079 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cr0Pe == RT_BOOL(pCtx->cr0 & X86_CR0_PE));2080 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Cr0Am == RT_BOOL(pCtx->cr0 & X86_CR0_AM));2081 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.EferLma == RT_BOOL(pCtx->msrEFER & MSR_K6_EFER_LMA));2082 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.DebugActive == RT_BOOL(pCtx->dr[7] & X86_DR7_ENABLED_MASK));2083 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Reserved0 == 0);2084 Assert(ExitReason.IoPortAccess.VpContext.ExecutionState.Reserved1 == 0);2085 Assert(ExitReason.IoPortAccess.VpContext.Rip == pCtx->rip);2086 Assert(ExitReason.IoPortAccess.VpContext.Rflags == pCtx->rflags.u);2087 Assert( ExitReason.IoPortAccess.VpContext.Cs.Base == pCtx->cs.u64Base2088 && ExitReason.IoPortAccess.VpContext.Cs.Limit == pCtx->cs.u32Limit2089 && ExitReason.IoPortAccess.VpContext.Cs.Selector == pCtx->cs.Sel);2090 break;2091 default: break; /* shut up compiler. */2092 }2093 # endif2094 2095 /*2096 * Deal with the exit.2097 */2098 switch (ExitReason.ExitReason)2099 {2100 /* Frequent exits: */2101 case WHvRunVpExitReasonCanceled:2102 //case WHvRunVpExitReasonAlerted:2103 rcStrict = VINF_SUCCESS;2104 break;2105 2106 case WHvRunVpExitReasonX64Halt:2107 rcStrict = nemR3WinWHvHandleHalt(pVM, pVCpu, pCtx);2108 break;2109 2110 case WHvRunVpExitReasonMemoryAccess:2111 rcStrict = nemR3WinWHvHandleMemoryAccess(pVM, pVCpu, pCtx, &ExitReason.MemoryAccess, &ExitReason.VpContext);2112 break;2113 2114 case WHvRunVpExitReasonX64IoPortAccess:2115 rcStrict = nemR3WinWHvHandleIoPortAccess(pVM, pVCpu, pCtx, &ExitReason.IoPortAccess, &ExitReason.VpContext);2116 break;2117 2118 case WHvRunVpExitReasonX64InterruptWindow:2119 rcStrict = nemR3WinWHvHandleInterruptWindow(pVM, pVCpu, pCtx, &ExitReason);2120 break;2121 2122 case WHvRunVpExitReasonX64MsrAccess: /* needs configuring */2123 rcStrict = nemR3WinWHvHandleMsrAccess(pVM, pVCpu, pCtx, &ExitReason);2124 break;2125 2126 case WHvRunVpExitReasonX64Cpuid: /* needs configuring */2127 rcStrict = nemR3WinWHvHandleCpuId(pVM, pVCpu, pCtx, &ExitReason);2128 break;2129 2130 case WHvRunVpExitReasonException: /* needs configuring */2131 rcStrict = nemR3WinWHvHandleException(pVM, pVCpu, pCtx, &ExitReason);2132 break;2133 2134 /* Unlikely exits: */2135 case WHvRunVpExitReasonUnsupportedFeature:2136 rcStrict = nemR3WinWHvHandleUD(pVM, pVCpu, pCtx, &ExitReason);2137 break;2138 2139 case WHvRunVpExitReasonUnrecoverableException:2140 rcStrict = nemR3WinWHvHandleTripleFault(pVM, pVCpu, pCtx, &ExitReason);2141 break;2142 2143 case WHvRunVpExitReasonInvalidVpRegisterValue:2144 rcStrict = nemR3WinWHvHandleInvalidState(pVM, pVCpu, pCtx, &ExitReason);2145 break;2146 2147 /* Undesired exits: */2148 case WHvRunVpExitReasonNone:2149 default:2150 AssertLogRelMsgFailed(("Unknown ExitReason: %#x\n", ExitReason.ExitReason));2151 rcStrict = VERR_INTERNAL_ERROR_3;2152 break;2153 }2154 if (rcStrict != VINF_SUCCESS)2155 {2156 LogFlow(("nemR3NativeRunGC: returning: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));2157 break;2158 }2159 2160 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES2161 /* Hack alert! */2162 uint32_t const cMappedPages = pVM->nem.s.cMappedPages;2163 if (cMappedPages < 4000)2164 { /* likely */ }2165 else2166 {2167 PGMPhysNemEnumPagesByState(pVM, pVCpu, NEM_WIN_PAGE_STATE_READABLE, nemR3WinWHvUnmapOnePageCallback, NULL);2168 Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages));2169 }2170 # endif2171 2172 /* If any FF is pending, return to the EM loops. That's okay for the2173 current sledgehammer approach. */2174 if ( VM_FF_IS_PENDING( pVM, !fSingleStepping ? VM_FF_HP_R0_PRE_HM_MASK : VM_FF_HP_R0_PRE_HM_STEP_MASK)2175 || VMCPU_FF_IS_PENDING(pVCpu, !fSingleStepping ? VMCPU_FF_HP_R0_PRE_HM_MASK : VMCPU_FF_HP_R0_PRE_HM_STEP_MASK) )2176 {2177 LogFlow(("nemR3NativeRunGC: returning: pending FF (%#x / %#x)\n", pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions));2178 break;2179 }2180 }2181 2182 2183 /*2184 * Copy back the state before returning.2185 */2186 if (pCtx->fExtrn & (CPUMCTX_EXTRN_ALL | (CPUMCTX_EXTRN_NEM_WIN_MASK & ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT)))2187 {2188 int rc2 = nemHCWinCopyStateFromHyperV(pVM, pVCpu, pCtx, CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_MASK);2189 if (RT_SUCCESS(rc2))2190 pCtx->fExtrn = 0;2191 else if (RT_SUCCESS(rcStrict))2192 rcStrict = rc2;2193 }2194 else2195 pCtx->fExtrn = 0;2196 2197 return rcStrict;2198 }2199 2200 #endif /* !NEM_WIN_USE_OUR_OWN_RUN_API - migrating to NEMAllNativeTemplate-win.cpp.h*/2201 1632 2202 1633
Note:
See TracChangeset
for help on using the changeset viewer.