Changeset 76500 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Dec 28, 2018 4:51:32 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/EM.cpp
r76402 r76500 2155 2155 2156 2156 /* 2157 * NMIs. 2158 * NMIs take priority over external interrupts. 2157 * Guest event injection. 2159 2158 */ 2160 2159 bool fWakeupPending = false; 2161 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI)2162 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS)2163 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))2164 {2165 rc2 = TRPMAssertTrap(pVCpu, X86_XCPT_NMI, TRPM_TRAP);2166 if (rc2 == VINF_SUCCESS)2167 {2168 fWakeupPending = true;2169 if (pVM->em.s.fIemExecutesAll)2170 rc2 = VINF_EM_RESCHEDULE;2171 else2172 {2173 rc2 = HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM2174 : VM_IS_NEM_ENABLED(pVM) ? VINF_EM_RESCHEDULE2175 : VINF_EM_RESCHEDULE_REM;2176 }2177 }2178 UPDATE_RC();2179 }2180 2181 /*2182 * Interrupts.2183 */2184 2160 if ( !VM_FF_IS_SET(pVM, VM_FF_PGM_NO_MEMORY) 2185 2161 && (!rc || rc >= VINF_EM_RESCHEDULE_HM) 2186 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) 2187 && !TRPMHasTrap(pVCpu)) /* an interrupt could already be scheduled for dispatching in the recompiler. */ 2188 { 2162 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) /* Interrupt shadows block both NMIs and interrupts. */ 2163 && !TRPMHasTrap(pVCpu)) /* An event could already be scheduled for dispatching. */ 2164 { 2165 /* 2166 * NMIs (take priority over external interrupts). 2167 */ 2189 2168 Assert(!HMR3IsEventPending(pVCpu)); 2190 bool fGif = CPUMGetGuestGif(&pVCpu->cpum.GstCtx); 2169 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI) 2170 && !VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_BLOCK_NMIS)) 2171 { 2172 rc2 = TRPMAssertTrap(pVCpu, X86_XCPT_NMI, TRPM_TRAP); 2173 if (rc2 == VINF_SUCCESS) 2174 { 2175 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI); 2176 VMCPU_FF_SET(pVCpu, VMCPU_FF_BLOCK_NMIS); 2177 fWakeupPending = true; 2178 if (pVM->em.s.fIemExecutesAll) 2179 rc2 = VINF_EM_RESCHEDULE; 2180 else 2181 { 2182 rc2 = HMR3IsActive(pVCpu) ? VINF_EM_RESCHEDULE_HM 2183 : VM_IS_NEM_ENABLED(pVM) ? VINF_EM_RESCHEDULE 2184 : VINF_EM_RESCHEDULE_REM; 2185 } 2186 } 2187 UPDATE_RC(); 2188 } 2189 else 2190 { 2191 /* 2192 * External Interrupts. 2193 */ 2194 bool fGif = CPUMGetGuestGif(&pVCpu->cpum.GstCtx); 2191 2195 #ifdef VBOX_WITH_RAW_MODE 2192 fGif &= !PATMIsPatchGCAddr(pVM, pVCpu->cpum.GstCtx.eip); 2193 #endif 2194 if (fGif) 2195 { 2196 /* 2197 * With VMX, virtual interrupts takes priority over physical interrupts. 2198 * With SVM, physical interrupts takes priority over virtual interrupts. 2199 */ 2200 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST) 2201 && CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx) 2202 && CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx)) 2196 fGif &= !PATMIsPatchGCAddr(pVM, pVCpu->cpum.GstCtx.eip); 2197 #endif 2198 if (fGif) 2203 2199 { 2204 /** @todo NSTVMX: virtual-interrupt delivery. */ 2205 rc2 = VINF_NO_CHANGE; 2206 } 2207 else if ( VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC) 2208 && CPUMIsGuestPhysIntrEnabled(pVCpu)) 2209 { 2210 bool fInjected = false; 2211 Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI); 2212 2213 if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx)) 2214 rc2 = emR3VmxNstGstIntrWindowExit(pVCpu); 2215 else if (CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx)) 2216 rc2 = emR3SvmNstGstIntrIntercept(pVCpu); 2217 else 2200 /* 2201 * With VMX, virtual interrupts takes priority over physical interrupts. 2202 * With SVM, physical interrupts takes priority over virtual interrupts. 2203 */ 2204 if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST) 2205 && CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx) 2206 && CPUMIsGuestVmxVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx)) 2207 { 2208 /** @todo NSTVMX: virtual-interrupt delivery. */ 2218 2209 rc2 = VINF_NO_CHANGE; 2219 2220 if (rc2 == VINF_NO_CHANGE) 2210 } 2211 else if ( VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC) 2212 && CPUMIsGuestPhysIntrEnabled(pVCpu)) 2221 2213 { 2222 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_XCPT_MASK); 2223 /** @todo this really isn't nice, should properly handle this */ 2224 rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT, &fInjected); 2225 fWakeupPending = true; 2226 if ( pVM->em.s.fIemExecutesAll 2227 && ( rc2 == VINF_EM_RESCHEDULE_REM 2228 || rc2 == VINF_EM_RESCHEDULE_HM 2229 || rc2 == VINF_EM_RESCHEDULE_RAW)) 2214 bool fInjected = false; 2215 Assert(pVCpu->em.s.enmState != EMSTATE_WAIT_SIPI); 2216 2217 if (CPUMIsGuestInVmxNonRootMode(&pVCpu->cpum.GstCtx)) 2218 rc2 = emR3VmxNstGstIntrWindowExit(pVCpu); 2219 else if (CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx)) 2220 rc2 = emR3SvmNstGstIntrIntercept(pVCpu); 2221 else 2222 rc2 = VINF_NO_CHANGE; 2223 2224 if (rc2 == VINF_NO_CHANGE) 2230 2225 { 2226 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_XCPT_MASK); 2227 /** @todo this really isn't nice, should properly handle this */ 2228 rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT, &fInjected); 2229 fWakeupPending = true; 2230 if ( pVM->em.s.fIemExecutesAll 2231 && ( rc2 == VINF_EM_RESCHEDULE_REM 2232 || rc2 == VINF_EM_RESCHEDULE_HM 2233 || rc2 == VINF_EM_RESCHEDULE_RAW)) 2234 { 2235 rc2 = VINF_EM_RESCHEDULE; 2236 } 2237 } 2238 #ifdef VBOX_STRICT 2239 if (fInjected) 2240 rcIrq = rc2; 2241 #endif 2242 UPDATE_RC(); 2243 } 2244 else if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST) 2245 && CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx) 2246 && CPUMIsGuestSvmVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx)) 2247 { 2248 rc2 = emR3SvmNstGstVirtIntrIntercept(pVCpu); 2249 if (rc2 == VINF_NO_CHANGE) 2250 { 2251 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST); 2252 uint8_t const uNstGstVector = CPUMGetGuestSvmVirtIntrVector(&pVCpu->cpum.GstCtx); 2253 AssertMsg(uNstGstVector > 0 && uNstGstVector <= X86_XCPT_LAST, ("Invalid VINTR %#x\n", uNstGstVector)); 2254 TRPMAssertTrap(pVCpu, uNstGstVector, TRPM_HARDWARE_INT); 2255 Log(("EM: Asserting nested-guest virt. hardware intr: %#x\n", uNstGstVector)); 2231 2256 rc2 = VINF_EM_RESCHEDULE; 2257 #ifdef VBOX_STRICT 2258 rcIrq = rc2; 2259 #endif 2232 2260 } 2261 UPDATE_RC(); 2233 2262 } 2234 #ifdef VBOX_STRICT2235 if (fInjected)2236 rcIrq = rc2;2237 #endif2238 UPDATE_RC();2239 }2240 else if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST)2241 && CPUMIsGuestInSvmNestedHwVirtMode(&pVCpu->cpum.GstCtx)2242 && CPUMIsGuestSvmVirtIntrEnabled(pVCpu, &pVCpu->cpum.GstCtx))2243 {2244 rc2 = emR3SvmNstGstVirtIntrIntercept(pVCpu);2245 if (rc2 == VINF_NO_CHANGE)2246 {2247 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST);2248 uint8_t const uNstGstVector = CPUMGetGuestSvmVirtIntrVector(&pVCpu->cpum.GstCtx);2249 AssertMsg(uNstGstVector > 0 && uNstGstVector <= X86_XCPT_LAST, ("Invalid VINTR %#x\n", uNstGstVector));2250 TRPMAssertTrap(pVCpu, uNstGstVector, TRPM_HARDWARE_INT);2251 Log(("EM: Asserting nested-guest virt. hardware intr: %#x\n", uNstGstVector));2252 rc2 = VINF_EM_RESCHEDULE;2253 #ifdef VBOX_STRICT2254 rcIrq = rc2;2255 #endif2256 }2257 UPDATE_RC();2258 2263 } 2259 2264 }
Note:
See TracChangeset
for help on using the changeset viewer.