Changeset 73203 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jul 18, 2018 1:00:43 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123808
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r73097 r73203 13610 13610 || rcStrict == VINF_EM_RAW_EMULATE_INSTR 13611 13611 || rcStrict == VINF_EM_RAW_TO_R3 13612 || rcStrict == VINF_EM_RAW_EMULATE_IO_BLOCK13613 13612 || rcStrict == VINF_EM_TRIPLE_FAULT 13614 13613 || rcStrict == VINF_GIM_R3_HYPERCALL -
trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp
r72493 r73203 818 818 || rcStrict == VINF_EM_SUSPEND 819 819 || rcStrict == VINF_EM_RESET 820 || rcStrict == VINF_EM_RAW_EMULATE_IO_BLOCK821 820 //|| rcStrict == VINF_EM_HALT /* ?? */ 822 821 //|| rcStrict == VINF_EM_NO_MEMORY /* ?? */ -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r73199 r73203 76 76 || (a_rcStrict) == VINF_IOM_R3_MMIO_READ_WRITE \ 77 77 || ((a_rcStrict) == VINF_IOM_R3_MMIO_COMMIT_WRITE && (a_fWrite)) \ 78 \79 || ((a_fWrite) ? (a_rcStrict) == VINF_EM_RAW_EMULATE_IO_BLOCK : false) \80 78 \ 81 79 || (a_rcStrict) == VINF_EM_RAW_EMULATE_INSTR \ … … 3112 3110 * @retval VINF_IOM_R3_MMIO_READ_WRITE in RC and R0. 3113 3111 * @retval VINF_IOM_R3_MMIO_COMMIT_WRITE in RC and R0. 3114 *3115 * @retval VINF_EM_RAW_EMULATE_IO_BLOCK in R0 only.3116 3112 * 3117 3113 * @retval VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT in RC only - write completed. -
trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp
r69111 r73203 402 402 LogFlow(("pdmR3DevHlp_DBGFTraceBuf: caller='%p'/%d: returns %p\n", pDevIns, pDevIns->iInstance, hTraceBuf)); 403 403 return hTraceBuf; 404 }405 406 407 /** @interface_method_impl{PDMDEVHLPR0,pfnCanEmulateIoBlock} */408 static DECLCALLBACK(bool) pdmR0DevHlp_CanEmulateIoBlock(PPDMDEVINS pDevIns)409 {410 PDMDEV_ASSERT_DEVINS(pDevIns);411 LogFlow(("pdmR0DevHlp_GetVM: caller='%p'/%d\n", pDevIns, pDevIns->iInstance));412 return HMCanEmulateIoBlock(VMMGetCpu(pDevIns->Internal.s.pVMR0));413 404 } 414 405 … … 435 426 pdmR0DevHlp_PATMSetMMIOPatchInfo, 436 427 pdmR0DevHlp_GetVM, 437 pdmR0DevHlp_CanEmulateIoBlock,438 428 pdmR0DevHlp_GetVMCPU, 439 429 pdmR0DevHlp_GetCurrentCpuId, -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r73097 r73203 866 866 STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetEmulate); 867 867 break; 868 case VINF_EM_RAW_EMULATE_IO_BLOCK:869 STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetIOBlockEmulate);870 break;871 868 case VINF_PATCH_EMULATE_INSTR: 872 869 STAM_COUNTER_INC(&pVM->vmm.s.StatRZRetPatchEmulate); -
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."); -
trunk/src/VBox/VMM/include/EMHandleRCTmpl.h
r72983 r73203 253 253 254 254 #ifdef EMHANDLERC_WITH_HM 255 /*256 * (MM)IO intensive code block detected; fall back to the recompiler for better performance257 */258 case VINF_EM_RAW_EMULATE_IO_BLOCK:259 rc = HMR3EmulateIoBlock(pVM, &pVCpu->cpum.GstCtx);260 break;261 262 255 case VINF_EM_HM_PATCH_TPR_INSTR: 263 256 rc = HMR3PatchTprInstr(pVM, pVCpu); -
trunk/src/VBox/VMM/include/HMInternal.h
r73016 r73203 908 908 RTGCUINTPTR GCPtrFaultAddress; 909 909 } Event; 910 911 /** IO Block emulation state. */912 struct913 {914 bool fEnabled;915 uint8_t u8Align[7];916 917 /** RIP at the start of the io code we wish to emulate in the recompiler. */918 RTGCPTR GCPtrFunctionEip;919 920 uint64_t cr0;921 } EmulateIoBlock;922 910 923 911 /* Pending IO operation. */ -
trunk/src/VBox/VMM/include/VMMInternal.h
r72778 r73203 363 363 STAMCOUNTER StatRZRetIRETTrap; 364 364 STAMCOUNTER StatRZRetEmulate; 365 STAMCOUNTER StatRZRetIOBlockEmulate;366 365 STAMCOUNTER StatRZRetPatchEmulate; 367 366 STAMCOUNTER StatRZRetIORead;
Note:
See TracChangeset
for help on using the changeset viewer.