- Timestamp:
- Oct 28, 2021 12:31:35 AM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h
r91958 r92120 1657 1657 uint8_t u2State = pInfo->u2NemState; 1658 1658 RTGCPHYS GCPhysSrc; 1659 # ifdef NEM_WIN_WITH_A20 1659 1660 if ( pVM->nem.s.fA20Enabled 1660 1661 || !NEM_WIN_IS_SUBJECT_TO_A20(GCPhys)) 1662 # endif 1661 1663 GCPhysSrc = GCPhys; 1664 # ifdef NEM_WIN_WITH_A20 1662 1665 else 1663 1666 { … … 1670 1673 pInfo->u2NemState = u2State; 1671 1674 } 1675 # endif 1672 1676 1673 1677 /* … … 4138 4142 if (RT_SUCCESS(rc)) 4139 4143 { 4144 Log8(("Injecting interrupt %#x on %u: %04x:%08RX64 efl=%#x\n", bInterrupt, pVCpu->idCpu, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.eflags)); 4140 4145 rcStrict = IEMInjectTrap(pVCpu, bInterrupt, TRPM_HARDWARE_INT, 0, 0, 0); 4141 4146 Log8(("Injected interrupt %#x on %u (%d)\n", bInterrupt, pVCpu->idCpu, VBOXSTRICTRC_VAL(rcStrict) )); … … 4147 4152 } 4148 4153 else 4149 Log8(("PDMGetInterrupt failed -> % d\n", rc));4154 Log8(("PDMGetInterrupt failed -> %Rrc\n", rc)); 4150 4155 } 4151 4156 return rcStrict; 4152 4157 } 4153 else if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC) && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)) 4158 4159 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC) && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)) 4154 4160 { 4155 4161 /* If only an APIC interrupt is pending, we need to know its priority. Otherwise we'll 4156 4162 * likely get pointless deliverability notifications with IF=1 but TPR still too high. 4157 4163 */ 4158 bool fPendingIntr; 4159 uint8_t u8Tpr, u8PendingIntr; 4160 int rc = APICGetTpr(pVCpu, &u8Tpr, &fPendingIntr, &u8PendingIntr); 4164 bool fPendingIntr = false; 4165 uint8_t bTpr = 0; 4166 uint8_t bPendingIntr = 0; 4167 int rc = APICGetTpr(pVCpu, &bTpr, &fPendingIntr, &bPendingIntr); 4161 4168 AssertRC(rc); 4162 *pfInterruptWindows |= (u8PendingIntr >> 4) << NEM_WIN_INTW_F_PRIO_SHIFT; 4163 } 4164 *pfInterruptWindows |= NEM_WIN_INTW_F_REGULAR; 4165 Log8(("Interrupt window pending on %u\n", pVCpu->idCpu)); 4169 *pfInterruptWindows |= (bPendingIntr >> 4) << NEM_WIN_INTW_F_PRIO_SHIFT; 4170 Log8(("Interrupt window pending on %u: %#x (bTpr=%#x fPendingIntr=%d bPendingIntr=%#x)\n", 4171 pVCpu->idCpu, *pfInterruptWindows, bTpr, fPendingIntr, bPendingIntr)); 4172 } 4173 else 4174 { 4175 *pfInterruptWindows |= NEM_WIN_INTW_F_REGULAR; 4176 Log8(("Interrupt window pending on %u: %#x\n", pVCpu->idCpu, *pfInterruptWindows)); 4177 } 4166 4178 } 4167 4179 … … 4264 4276 } 4265 4277 } 4278 4279 # ifndef NEM_WIN_WITH_A20 4280 /* 4281 * Do not execute in hyper-V if the A20 isn't enabled. 4282 */ 4283 if (PGMPhysIsA20Enabled(pVCpu)) 4284 { /* likely */ } 4285 else 4286 { 4287 rcStrict = VINF_EM_RESCHEDULE_REM; 4288 LogFlow(("NEM/%u: breaking: A20 disabled\n", pVCpu->idCpu)); 4289 break; 4290 } 4291 # endif 4266 4292 4267 4293 /* … … 4365 4391 # endif 4366 4392 # else 4367 WHV_RUN_VP_EXIT_CONTEXT ExitReason; 4368 RT_ZERO(ExitReason); 4369 LogFlow(("NEM/%u: Entry @ %04X:%08RX64 IF=%d (~~may be stale~~)\n", pVCpu->idCpu, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, pVCpu->cpum.GstCtx.rflags.Bits.u1IF)); 4393 # ifdef LOG_ENABLED 4394 if (LogIsFlowEnabled()) 4395 { 4396 static const WHV_REGISTER_NAME s_aNames[6] = { WHvX64RegisterCs, WHvX64RegisterRip, WHvX64RegisterRflags, 4397 WHvX64RegisterSs, WHvX64RegisterRsp, WHvX64RegisterCr0 }; 4398 WHV_REGISTER_VALUE aRegs[RT_ELEMENTS(s_aNames)] = {0}; 4399 WHvGetVirtualProcessorRegisters(pVM->nem.s.hPartition, pVCpu->idCpu, s_aNames, RT_ELEMENTS(s_aNames), aRegs); 4400 LogFlow(("NEM/%u: Entry @ %04x:%08RX64 IF=%d EFL=%#RX64 SS:RSP=%04x:%08RX64 cr0=%RX64\n", 4401 pVCpu->idCpu, aRegs[0].Segment.Selector, aRegs[1].Reg64, RT_BOOL(aRegs[2].Reg64 & X86_EFL_IF), 4402 aRegs[2].Reg64, aRegs[3].Segment.Selector, aRegs[4].Reg64, aRegs[5].Reg64)); 4403 } 4404 # endif 4405 WHV_RUN_VP_EXIT_CONTEXT ExitReason = {0}; 4370 4406 TMNotifyStartOfExecution(pVM, pVCpu); 4407 4371 4408 HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason)); 4409 4372 4410 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT); 4373 4411 TMNotifyEndOfExecution(pVM, pVCpu, ASMReadTSC()); 4374 LogFlow(("NEM/%u: Exit @ %04X:%08RX64 IF=%d CR8=%#x \n", pVCpu->idCpu, ExitReason.VpContext.Cs.Selector, ExitReason.VpContext.Rip, RT_BOOL(ExitReason.VpContext.Rflags & X86_EFL_IF), ExitReason.VpContext.Cr8)); 4412 # ifdef LOG_ENABLED 4413 LogFlow(("NEM/%u: Exit @ %04X:%08RX64 IF=%d CR8=%#x Reason=%#x\n", pVCpu->idCpu, ExitReason.VpContext.Cs.Selector, 4414 ExitReason.VpContext.Rip, RT_BOOL(ExitReason.VpContext.Rflags & X86_EFL_IF), ExitReason.VpContext.Cr8, 4415 ExitReason.ExitReason)); 4416 # endif 4375 4417 if (SUCCEEDED(hrc)) 4376 4418 # endif … … 4952 4994 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES 4953 4995 PVMCPUCC pVCpu = VMMGetCpu(pVM); 4996 # ifdef NEM_WIN_WITH_A20 4954 4997 if ( pVM->nem.s.fA20Enabled 4955 4998 || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys)) 4999 # endif 4956 5000 rc = nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); 5001 # ifdef NEM_WIN_WITH_A20 4957 5002 else 4958 5003 { … … 4963 5008 4964 5009 } 5010 # endif 4965 5011 #else 4966 5012 RT_NOREF_PV(fPageProt); 5013 # ifdef NEM_WIN_WITH_A20 4967 5014 if ( pVM->nem.s.fA20Enabled 4968 5015 || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys)) 5016 # endif 4969 5017 rc = nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State); 5018 # ifdef NEM_WIN_WITH_A20 4970 5019 else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys)) 4971 5020 rc = nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State); 4972 5021 else 4973 5022 rc = VINF_SUCCESS; /* ignore since we've got the alias page at this address. */ 5023 # endif 4974 5024 #endif 4975 5025 return rc; … … 4987 5037 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES 4988 5038 PVMCPUCC pVCpu = VMMGetCpu(pVM); 5039 # ifdef NEM_WIN_WITH_A20 4989 5040 if ( pVM->nem.s.fA20Enabled 4990 5041 || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys)) 5042 # endif 4991 5043 nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/); 5044 # ifdef NEM_WIN_WITH_A20 4992 5045 else 4993 5046 { … … 4997 5050 nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/); 4998 5051 } 5052 # endif 4999 5053 #else 5000 5054 RT_NOREF_PV(fPageProt); 5055 # ifdef NEM_WIN_WITH_A20 5001 5056 if ( pVM->nem.s.fA20Enabled 5002 5057 || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys)) 5058 # endif 5003 5059 nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State); 5060 # ifdef NEM_WIN_WITH_A20 5004 5061 else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys)) 5005 5062 nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State); 5006 5063 /* else: ignore since we've got the alias page at this address. */ 5064 # endif 5007 5065 #endif 5008 5066 } … … 5019 5077 #ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES 5020 5078 PVMCPUCC pVCpu = VMMGetCpu(pVM); 5079 # ifdef NEM_WIN_WITH_A20 5021 5080 if ( pVM->nem.s.fA20Enabled 5022 5081 || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys)) 5082 # endif 5023 5083 nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); 5084 # ifdef NEM_WIN_WITH_A20 5024 5085 else 5025 5086 { … … 5029 5090 nemHCNativeSetPhysPage(pVM, pVCpu, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); 5030 5091 } 5092 # endif 5031 5093 #else 5032 5094 RT_NOREF_PV(fPageProt); 5095 # ifdef NEM_WIN_WITH_A20 5033 5096 if ( pVM->nem.s.fA20Enabled 5034 5097 || !NEM_WIN_IS_RELEVANT_TO_A20(GCPhys)) 5098 # endif 5035 5099 nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State); 5100 # ifdef NEM_WIN_WITH_A20 5036 5101 else if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys)) 5037 5102 nemHCJustUnmapPageFromHyperV(pVM, GCPhys, pu2State); 5038 5103 /* else: ignore since we've got the alias page at this address. */ 5104 # endif 5039 5105 #endif 5040 5106 } -
trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
r91848 r92120 406 406 407 407 408 #ifndef VBOX_WITH_NATIVE_NEM 408 409 VMMR3_INT_DECL(bool) NEMR3CanExecuteGuest(PVM pVM, PVMCPU pVCpu) 409 410 { 410 Assert(VM_IS_NEM_ENABLED(pVM)); 411 #ifdef VBOX_WITH_NATIVE_NEM 412 return nemR3NativeCanExecuteGuest(pVM, pVCpu); 413 #else 414 NOREF(pVM); NOREF(pVCpu); 411 RT_NOREF(pVM, pVCpu); 415 412 return false; 416 #endif 417 } 413 } 414 #endif 418 415 419 416 … … 441 438 442 439 440 #ifndef VBOX_WITH_NATIVE_NEM 443 441 VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled) 444 442 { 445 #ifdef VBOX_WITH_NATIVE_NEM 446 if (pVCpu->pVMR3->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 447 nemR3NativeNotifySetA20(pVCpu, fEnabled); 448 #else 449 NOREF(pVCpu); NOREF(fEnabled); 450 #endif 451 } 452 443 RT_NOREF(pVCpu, fEnabled); 444 } 445 #endif 446 -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r91958 r92120 1279 1279 * Some state init. 1280 1280 */ 1281 #ifdef NEM_WIN_WITH_A20 1281 1282 pVM->nem.s.fA20Enabled = true; 1283 #endif 1282 1284 #if 0 1283 1285 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++) … … 1814 1816 void nemR3NativeReset(PVM pVM) 1815 1817 { 1818 #if 0 1816 1819 /* Unfix the A20 gate. */ 1817 1820 pVM->nem.s.fA20Fixed = false; 1821 #else 1822 RT_NOREF(pVM); 1823 #endif 1818 1824 } 1819 1825 … … 1828 1834 void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi) 1829 1835 { 1836 #ifdef NEM_WIN_WITH_A20 1830 1837 /* Lock the A20 gate if INIT IPI, make sure it's enabled. */ 1831 1838 if (fInitIpi && pVCpu->idCpu > 0) … … 1837 1844 pVM->nem.s.fA20Fixed = true; 1838 1845 } 1846 #else 1847 RT_NOREF(pVCpu, fInitIpi); 1848 #endif 1839 1849 } 1840 1850 … … 1886 1896 1887 1897 1888 bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu) 1889 { 1890 NOREF(pVM); NOREF(pVCpu); 1898 VMMR3_INT_DECL(bool) NEMR3CanExecuteGuest(PVM pVM, PVMCPU pVCpu) 1899 { 1900 Assert(VM_IS_NEM_ENABLED(pVM)); 1901 1902 #ifndef NEM_WIN_WITH_A20 1903 /* 1904 * Only execute when the A20 gate is enabled because this lovely Hyper-V 1905 * blackbox does not seem to have any way to enable or disable A20. 1906 */ 1907 RT_NOREF(pVM); 1908 return PGMPhysIsA20Enabled(pVCpu); 1909 #else 1910 RT_NOREF(pVM, pVCpu); 1891 1911 return true; 1912 #endif 1892 1913 } 1893 1914 … … 2023 2044 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2024 2045 } 2046 RT_NOREF(pvRam); 2025 2047 2026 2048 #else … … 2206 2228 2207 2229 2230 #ifdef NEM_WIN_WITH_A20 2208 2231 /** 2209 2232 * Unmaps a page from Hyper-V for the purpose of emulating A20 gate behavior. … … 2220 2243 nemR3WinUnsetForA20CheckerCallback, NULL); 2221 2244 } 2245 #endif 2222 2246 2223 2247 … … 2232 2256 * @param fEnabled Whether it was enabled (true) or disabled. 2233 2257 */ 2234 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled)2258 VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled) 2235 2259 { 2236 2260 Log(("nemR3NativeNotifySetA20: fEnabled=%RTbool\n", fEnabled)); 2261 Assert(VM_IS_NEM_ENABLED(pVCpu->CTX_SUFF(pVM))); 2262 #ifdef NEM_WIN_WITH_A20 2237 2263 PVM pVM = pVCpu->CTX_SUFF(pVM); 2238 2264 if (!pVM->nem.s.fA20Fixed) … … 2242 2268 nemR3WinUnmapPageForA20Gate(pVM, pVCpu, GCPhys); 2243 2269 } 2270 #else 2271 RT_NOREF(pVCpu, fEnabled); 2272 #endif 2244 2273 } 2245 2274 … … 2446 2475 * (e.g. possiblity of two CPUs with different A20 status). 2447 2476 * 2448 * Workaround: Only do A20 on CPU 0, restricting the emulation to HMA. We 2449 * unmap all pages related to HMA (0x100000..0x10ffff) when the A20 state 2450 * changes, lazily syncing the right pages back when accessed. 2477 * Workaround #1 (obsolete): Only do A20 on CPU 0, restricting the emulation 2478 * to HMA. We unmap all pages related to HMA (0x100000..0x10ffff) when the A20 2479 * state changes, lazily syncing the right pages back when accessed. 2480 * 2481 * Workaround #2 (used): Use IEM when the A20 gate is disabled. 2451 2482 * 2452 2483 * -
trunk/src/VBox/VMM/include/NEMInternal.h
r91958 r92120 167 167 /** Set if we're using the ring-0 API to do the work. */ 168 168 bool fUseRing0Runloop : 1; 169 # ifdef NEM_WIN_WITH_A20 169 170 /** Set if we've started more than one CPU and cannot mess with A20. */ 170 171 bool fA20Fixed : 1; 171 172 /** Set if A20 is enabled. */ 172 173 bool fA20Enabled : 1; 174 # endif 173 175 /** The reported CPU vendor. */ 174 176 CPUMCPUVENDOR enmCpuVendor; … … 459 461 bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable); 460 462 void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags); 461 462 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);463 463 #endif 464 464
Note:
See TracChangeset
for help on using the changeset viewer.