Changeset 73203 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Jul 18, 2018 1:00:43 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123808
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/EMHM.cpp
r72749 r73203 254 254 static int emR3HmExecuteIOInstruction(PVM pVM, PVMCPU pVCpu) 255 255 { 256 RT_NOREF(pVM); 256 257 STAM_PROFILE_START(&pVCpu->em.s.StatIOEmu, a); 257 258 … … 262 263 { 263 264 /* 264 * Try to restart the io instruction that was refused in ring-0.265 */266 rcStrict = HMR3RestartPendingIOInstr(pVM, pVCpu, &pVCpu->cpum.GstCtx);267 if (IOM_SUCCESS(rcStrict))268 {269 STAM_COUNTER_INC(&pVCpu->em.s.CTX_SUFF(pStats)->StatIoRestarted);270 STAM_PROFILE_STOP(&pVCpu->em.s.StatIOEmu, a);271 return VBOXSTRICTRC_TODO(rcStrict); /* rip already updated. */272 }273 AssertMsgReturn(rcStrict == VERR_NOT_FOUND, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)),274 RT_SUCCESS_NP(rcStrict) ? VERR_IPE_UNEXPECTED_INFO_STATUS : VBOXSTRICTRC_TODO(rcStrict));275 276 /*277 265 * Hand it over to the interpreter. 278 266 */ … … 285 273 RT_UNTRUSTED_VALIDATED_FENCE(); 286 274 CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 287 Assert(!HMR3HasPendingIOInstr(pVCpu));288 275 rcStrict = EMHistoryExec(pVCpu, &pVCpu->em.s.aExitRecords[idxContinueExitRec], 0); 289 276 LogFlow(("emR3HmExecuteIOInstruction: %Rrc (EMHistoryExec)\n", VBOXSTRICTRC_VAL(rcStrict))); -
trunk/src/VBox/VMM/VMMR3/HM.cpp
r73107 r73203 2784 2784 2785 2785 /** 2786 * Force execution of the current IO code in the recompiler.2787 *2788 * @returns VBox status code.2789 * @param pVM The cross context VM structure.2790 * @param pCtx Partial VM execution context.2791 */2792 VMMR3_INT_DECL(int) HMR3EmulateIoBlock(PVM pVM, PCPUMCTX pCtx)2793 {2794 PVMCPU pVCpu = VMMGetCpu(pVM);2795 2796 Assert(HMIsEnabled(pVM));2797 Log(("HMR3EmulateIoBlock\n"));2798 2799 /* This is primarily intended to speed up Grub, so we don't care about paged protected mode. */2800 if (HMCanEmulateIoBlockEx(pCtx))2801 {2802 Log(("HMR3EmulateIoBlock -> enabled\n"));2803 pVCpu->hm.s.EmulateIoBlock.fEnabled = true;2804 pVCpu->hm.s.EmulateIoBlock.GCPtrFunctionEip = pCtx->rip;2805 pVCpu->hm.s.EmulateIoBlock.cr0 = pCtx->cr0;2806 return VINF_EM_RESCHEDULE_REM;2807 }2808 return VINF_SUCCESS;2809 }2810 2811 2812 /**2813 2786 * Checks if we can currently use hardware accelerated raw mode. 2814 2787 * … … 2830 2803 } 2831 2804 #endif 2832 2833 /* If we're still executing the IO code, then return false. */2834 if ( RT_UNLIKELY(pVCpu->hm.s.EmulateIoBlock.fEnabled)2835 && pCtx->rip < pVCpu->hm.s.EmulateIoBlock.GCPtrFunctionEip + 0x2002836 && pCtx->rip > pVCpu->hm.s.EmulateIoBlock.GCPtrFunctionEip - 0x2002837 && pCtx->cr0 == pVCpu->hm.s.EmulateIoBlock.cr0)2838 return false;2839 2840 pVCpu->hm.s.EmulateIoBlock.fEnabled = false;2841 2805 2842 2806 /* AMD-V supports real & protected mode with or without paging. */ … … 3277 3241 && pVM->hm.s.vmx.fEnabled 3278 3242 && pVM->hm.s.vmx.fUsePreemptTimer; 3279 }3280 3281 3282 /**3283 * Checks if there is an I/O instruction pending.3284 *3285 * @returns true if pending, false if not.3286 * @param pVCpu The cross context virtual CPU structure.3287 */3288 VMMR3_INT_DECL(bool) HMR3HasPendingIOInstr(PVMCPU pVCpu)3289 {3290 return pVCpu->hm.s.PendingIO.enmType != HMPENDINGIO_INVALID3291 && pVCpu->hm.s.PendingIO.GCPtrRip == pVCpu->cpum.GstCtx.rip;3292 }3293 3294 3295 /**3296 * Restart an I/O instruction that was refused in ring-03297 *3298 * @returns Strict VBox status code. Informational status codes other than the one documented3299 * here are to be treated as internal failure. Use IOM_SUCCESS() to check for success.3300 * @retval VINF_SUCCESS Success.3301 * @retval VINF_EM_FIRST-VINF_EM_LAST Success with some exceptions (see IOM_SUCCESS()), the3302 * status code must be passed on to EM.3303 * @retval VERR_NOT_FOUND if no pending I/O instruction.3304 *3305 * @param pVM The cross context VM structure.3306 * @param pVCpu The cross context virtual CPU structure.3307 * @param pCtx Pointer to the guest CPU context.3308 */3309 VMMR3_INT_DECL(VBOXSTRICTRC) HMR3RestartPendingIOInstr(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)3310 {3311 /*3312 * Check if we've got relevant data pending.3313 */3314 HMPENDINGIO enmType = pVCpu->hm.s.PendingIO.enmType;3315 if (enmType == HMPENDINGIO_INVALID)3316 return VERR_NOT_FOUND;3317 pVCpu->hm.s.PendingIO.enmType = HMPENDINGIO_INVALID;3318 if (pVCpu->hm.s.PendingIO.GCPtrRip != pCtx->rip)3319 return VERR_NOT_FOUND;3320 3321 /*3322 * Execute pending I/O.3323 */3324 VBOXSTRICTRC rcStrict;3325 switch (enmType)3326 {3327 case HMPENDINGIO_PORT_READ:3328 {3329 uint32_t uAndVal = pVCpu->hm.s.PendingIO.s.Port.uAndVal;3330 uint32_t u32Val = 0;3331 3332 rcStrict = IOMIOPortRead(pVM, pVCpu, pVCpu->hm.s.PendingIO.s.Port.uPort, &u32Val,3333 pVCpu->hm.s.PendingIO.s.Port.cbSize);3334 if (IOM_SUCCESS(rcStrict))3335 {3336 /* Write back to the EAX register. */3337 pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);3338 pCtx->rip = pVCpu->hm.s.PendingIO.GCPtrRipNext;3339 }3340 break;3341 }3342 3343 default:3344 AssertLogRelFailedReturn(VERR_HM_UNKNOWN_IO_INSTRUCTION);3345 }3346 3347 if (IOM_SUCCESS(rcStrict))3348 {3349 /*3350 * Check for I/O breakpoints.3351 */3352 uint32_t const uDr7 = pCtx->dr[7];3353 if ( ( (uDr7 & X86_DR7_ENABLED_MASK)3354 && X86_DR7_ANY_RW_IO(uDr7)3355 && (pCtx->cr4 & X86_CR4_DE))3356 || DBGFBpIsHwIoArmed(pVM))3357 {3358 VBOXSTRICTRC rcStrict2 = DBGFBpCheckIo(pVM, pVCpu, pCtx, pVCpu->hm.s.PendingIO.s.Port.uPort,3359 pVCpu->hm.s.PendingIO.s.Port.cbSize);3360 if (rcStrict2 == VINF_EM_RAW_GUEST_TRAP)3361 rcStrict2 = TRPMAssertTrap(pVCpu, X86_XCPT_DB, TRPM_TRAP);3362 /* rcStrict is VINF_SUCCESS or in [VINF_EM_FIRST..VINF_EM_LAST]. */3363 else if (rcStrict2 != VINF_SUCCESS && (rcStrict == VINF_SUCCESS || rcStrict2 < rcStrict))3364 rcStrict = rcStrict2;3365 }3366 }3367 return rcStrict;3368 3243 } 3369 3244 -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r73097 r73203 519 519 STAM_REG(pVM, &pVM->vmm.s.StatRZRetIRETTrap, STAMTYPE_COUNTER, "/VMM/RZRet/IRETTrap", STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_IRET_TRAP returns."); 520 520 STAM_REG(pVM, &pVM->vmm.s.StatRZRetEmulate, STAMTYPE_COUNTER, "/VMM/RZRet/Emulate", STAMUNIT_OCCURENCES, "Number of VINF_EM_EXECUTE_INSTRUCTION returns."); 521 STAM_REG(pVM, &pVM->vmm.s.StatRZRetIOBlockEmulate, STAMTYPE_COUNTER, "/VMM/RZRet/EmulateIOBlock", STAMUNIT_OCCURENCES, "Number of VINF_EM_RAW_EMULATE_IO_BLOCK returns.");522 521 STAM_REG(pVM, &pVM->vmm.s.StatRZRetPatchEmulate, STAMTYPE_COUNTER, "/VMM/RZRet/PatchEmulate", STAMUNIT_OCCURENCES, "Number of VINF_PATCH_EMULATE_INSTR returns."); 523 522 STAM_REG(pVM, &pVM->vmm.s.StatRZRetIORead, STAMTYPE_COUNTER, "/VMM/RZRet/IORead", STAMUNIT_OCCURENCES, "Number of VINF_IOM_R3_IOPORT_READ returns.");
Note:
See TracChangeset
for help on using the changeset viewer.