Changeset 21191 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jul 3, 2009 11:39:50 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/EM.cpp
r21144 r21191 98 98 static int emR3RawResumeHyper(PVM pVM, PVMCPU pVCpu); 99 99 static int emR3RawStep(PVM pVM, PVMCPU pVCpu); 100 DECLINLINE(int) emR3RawHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);101 100 DECLINLINE(int) emR3RawUpdateForceFlag(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc); 102 101 static int emR3RawForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); … … 108 107 static int emR3PatchTrap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int gcret); 109 108 static int emR3SingleStepExecRem(PVM pVM, uint32_t cIterations); 109 static int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu); 110 static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu); 111 static int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu); 110 112 static EMSTATE emR3Reschedule(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx); 113 114 #define EMHANDLERC_WITH_PATM 115 #define EMHANDLERC_NAME emR3RawHandleRC 116 #include "EMHandleRCTmpl.h" 117 118 #define EMHANDLERC_NAME emR3HwaccmHandleRC 119 #include "EMHandleRCTmpl.h" 111 120 112 121 /** … … 1232 1241 */ 1233 1242 rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc); 1234 rc = emR3 RawHandleRC(pVM, pVCpu, pCtx, rc);1243 rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc); 1235 1244 rc = emR3RawUpdateForceFlag(pVM, pVCpu, pCtx, rc); 1236 1245 return rc; … … 1506 1515 * @param pVCpu VMCPU handle. 1507 1516 */ 1508 int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)1517 static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu) 1509 1518 { 1510 1519 int rc; … … 1780 1789 * @param pVCpu VMCPU handle. 1781 1790 */ 1782 int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu)1791 static int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu) 1783 1792 { 1784 1793 int rc; … … 2025 2034 * @param pVCpu VMCPU handle; 2026 2035 */ 2027 int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu)2036 static int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu) 2028 2037 { 2029 2038 STAM_PROFILE_START(&pVCpu->em.s.StatPrivEmu, a); … … 2309 2318 2310 2319 /** 2311 * Process a subset of the raw-mode return code.2312 *2313 * Since we have to share this with raw-mode single stepping, this inline2314 * function has been created to avoid code duplication.2315 *2316 * @returns VINF_SUCCESS if it's ok to continue raw mode.2317 * @returns VBox status code to return to the EM main loop.2318 *2319 * @param pVM The VM handle2320 * @param pVCpu The VMCPU handle2321 * @param rc The return code.2322 * @param pCtx The guest cpu context.2323 */2324 DECLINLINE(int) emR3RawHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc)2325 {2326 switch (rc)2327 {2328 /*2329 * Common & simple ones.2330 */2331 case VINF_SUCCESS:2332 break;2333 case VINF_EM_RESCHEDULE_RAW:2334 case VINF_EM_RESCHEDULE_HWACC:2335 case VINF_EM_RAW_INTERRUPT:2336 case VINF_EM_RAW_TO_R3:2337 case VINF_EM_RAW_TIMER_PENDING:2338 case VINF_EM_PENDING_REQUEST:2339 rc = VINF_SUCCESS;2340 break;2341 2342 /*2343 * Privileged instruction.2344 */2345 case VINF_EM_RAW_EXCEPTION_PRIVILEGED:2346 case VINF_PATM_PATCH_TRAP_GP:2347 rc = emR3RawPrivileged(pVM, pVCpu);2348 break;2349 2350 /*2351 * Got a trap which needs dispatching.2352 */2353 case VINF_EM_RAW_GUEST_TRAP:2354 if (PATMR3IsInsidePatchJump(pVM, pCtx->eip, NULL))2355 {2356 AssertReleaseMsgFailed(("FATAL ERROR: executing random instruction inside generated patch jump %08X\n", CPUMGetGuestEIP(pVCpu)));2357 rc = VERR_EM_RAW_PATCH_CONFLICT;2358 break;2359 }2360 rc = emR3RawGuestTrap(pVM, pVCpu);2361 break;2362 2363 /*2364 * Trap in patch code.2365 */2366 case VINF_PATM_PATCH_TRAP_PF:2367 case VINF_PATM_PATCH_INT3:2368 rc = emR3PatchTrap(pVM, pVCpu, pCtx, rc);2369 break;2370 2371 case VINF_PATM_DUPLICATE_FUNCTION:2372 Assert(PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip));2373 rc = PATMR3DuplicateFunctionRequest(pVM, pCtx);2374 AssertRC(rc);2375 rc = VINF_SUCCESS;2376 break;2377 2378 case VINF_PATM_CHECK_PATCH_PAGE:2379 rc = PATMR3HandleMonitoredPage(pVM);2380 AssertRC(rc);2381 rc = VINF_SUCCESS;2382 break;2383 2384 /*2385 * Patch manager.2386 */2387 case VERR_EM_RAW_PATCH_CONFLICT:2388 AssertReleaseMsgFailed(("%Rrc handling is not yet implemented\n", rc));2389 break;2390 2391 #ifdef VBOX_WITH_VMI2392 /*2393 * PARAV function.2394 */2395 case VINF_EM_RESCHEDULE_PARAV:2396 rc = PARAVCallFunction(pVM);2397 break;2398 #endif2399 2400 /*2401 * Memory mapped I/O access - attempt to patch the instruction2402 */2403 case VINF_PATM_HC_MMIO_PATCH_READ:2404 rc = PATMR3InstallPatch(pVM, SELMToFlat(pVM, DIS_SELREG_CS, CPUMCTX2CORE(pCtx), pCtx->eip),2405 PATMFL_MMIO_ACCESS | ((SELMGetCpuModeFromSelector(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid) == CPUMODE_32BIT) ? PATMFL_CODE32 : 0));2406 if (RT_FAILURE(rc))2407 rc = emR3RawExecuteInstruction(pVM, pVCpu, "MMIO");2408 break;2409 2410 case VINF_PATM_HC_MMIO_PATCH_WRITE:2411 AssertFailed(); /* not yet implemented. */2412 rc = emR3RawExecuteInstruction(pVM, pVCpu, "MMIO");2413 break;2414 2415 /*2416 * Conflict or out of page tables.2417 *2418 * VM_FF_PGM_SYNC_CR3 is set by the hypervisor and all we need to2419 * do here is to execute the pending forced actions.2420 */2421 case VINF_PGM_SYNC_CR3:2422 AssertMsg(VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL),2423 ("VINF_PGM_SYNC_CR3 and no VMCPU_FF_PGM_SYNC_CR3*!\n"));2424 rc = VINF_SUCCESS;2425 break;2426 2427 /*2428 * Paging mode change.2429 */2430 case VINF_PGM_CHANGE_MODE:2431 rc = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);2432 if (rc == VINF_SUCCESS)2433 rc = VINF_EM_RESCHEDULE;2434 AssertMsg(RT_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST), ("%Rrc\n", rc));2435 break;2436 2437 /*2438 * CSAM wants to perform a task in ring-3. It has set an FF action flag.2439 */2440 case VINF_CSAM_PENDING_ACTION:2441 rc = VINF_SUCCESS;2442 break;2443 2444 /*2445 * Invoked Interrupt gate - must directly (!) go to the recompiler.2446 */2447 case VINF_EM_RAW_INTERRUPT_PENDING:2448 case VINF_EM_RAW_RING_SWITCH_INT:2449 Assert(TRPMHasTrap(pVCpu));2450 Assert(!PATMIsPatchGCAddr(pVM, (RTGCPTR)pCtx->eip));2451 2452 if (TRPMHasTrap(pVCpu))2453 {2454 /* If the guest gate is marked unpatched, then we will check again if we can patch it. */2455 uint8_t u8Interrupt = TRPMGetTrapNo(pVCpu);2456 if (TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) == TRPM_INVALID_HANDLER)2457 {2458 CSAMR3CheckGates(pVM, u8Interrupt, 1);2459 Log(("emR3RawHandleRC: recheck gate %x -> valid=%d\n", u8Interrupt, TRPMR3GetGuestTrapHandler(pVM, u8Interrupt) != TRPM_INVALID_HANDLER));2460 /* Note: If it was successful, then we could go back to raw mode, but let's keep things simple for now. */2461 }2462 }2463 rc = VINF_EM_RESCHEDULE_REM;2464 break;2465 2466 /*2467 * Other ring switch types.2468 */2469 case VINF_EM_RAW_RING_SWITCH:2470 rc = emR3RawRingSwitch(pVM, pVCpu);2471 break;2472 2473 /*2474 * I/O Port access - emulate the instruction.2475 */2476 case VINF_IOM_HC_IOPORT_READ:2477 case VINF_IOM_HC_IOPORT_WRITE:2478 rc = emR3RawExecuteIOInstruction(pVM, pVCpu);2479 break;2480 2481 /*2482 * Memory mapped I/O access - emulate the instruction.2483 */2484 case VINF_IOM_HC_MMIO_READ:2485 case VINF_IOM_HC_MMIO_WRITE:2486 case VINF_IOM_HC_MMIO_READ_WRITE:2487 rc = emR3RawExecuteInstruction(pVM, pVCpu, "MMIO");2488 break;2489 2490 /*2491 * (MM)IO intensive code block detected; fall back to the recompiler for better performance2492 */2493 case VINF_EM_RAW_EMULATE_IO_BLOCK:2494 rc = HWACCMR3EmulateIoBlock(pVM, pCtx);2495 break;2496 2497 /*2498 * Execute instruction.2499 */2500 case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT:2501 rc = emR3RawExecuteInstruction(pVM, pVCpu, "LDT FAULT: ");2502 break;2503 case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT:2504 rc = emR3RawExecuteInstruction(pVM, pVCpu, "GDT FAULT: ");2505 break;2506 case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT:2507 rc = emR3RawExecuteInstruction(pVM, pVCpu, "IDT FAULT: ");2508 break;2509 case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT:2510 rc = emR3RawExecuteInstruction(pVM, pVCpu, "TSS FAULT: ");2511 break;2512 case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT:2513 rc = emR3RawExecuteInstruction(pVM, pVCpu, "PD FAULT: ");2514 break;2515 2516 case VINF_EM_RAW_EMULATE_INSTR_HLT:2517 /** @todo skip instruction and go directly to the halt state. (see REM for implementation details) */2518 rc = emR3RawPrivileged(pVM, pVCpu);2519 break;2520 2521 case VINF_PATM_PENDING_IRQ_AFTER_IRET:2522 rc = emR3RawExecuteInstruction(pVM, pVCpu, "EMUL: ", VINF_PATM_PENDING_IRQ_AFTER_IRET);2523 break;2524 2525 case VINF_EM_RAW_EMULATE_INSTR:2526 case VINF_PATCH_EMULATE_INSTR:2527 rc = emR3RawExecuteInstruction(pVM, pVCpu, "EMUL: ");2528 break;2529 2530 /*2531 * Stale selector and iret traps => REM.2532 */2533 case VINF_EM_RAW_STALE_SELECTOR:2534 case VINF_EM_RAW_IRET_TRAP:2535 /* We will not go to the recompiler if EIP points to patch code. */2536 if (PATMIsPatchGCAddr(pVM, pCtx->eip))2537 {2538 pCtx->eip = PATMR3PatchToGCPtr(pVM, (RTGCPTR)pCtx->eip, 0);2539 }2540 LogFlow(("emR3RawHandleRC: %Rrc -> %Rrc\n", rc, VINF_EM_RESCHEDULE_REM));2541 rc = VINF_EM_RESCHEDULE_REM;2542 break;2543 2544 /*2545 * Up a level.2546 */2547 case VINF_EM_TERMINATE:2548 case VINF_EM_OFF:2549 case VINF_EM_RESET:2550 case VINF_EM_SUSPEND:2551 case VINF_EM_HALT:2552 case VINF_EM_RESUME:2553 case VINF_EM_NO_MEMORY:2554 case VINF_EM_RESCHEDULE:2555 case VINF_EM_RESCHEDULE_REM:2556 case VINF_EM_WAIT_SIPI:2557 break;2558 2559 /*2560 * Up a level and invoke the debugger.2561 */2562 case VINF_EM_DBG_STEPPED:2563 case VINF_EM_DBG_BREAKPOINT:2564 case VINF_EM_DBG_STEP:2565 case VINF_EM_DBG_HYPER_BREAKPOINT:2566 case VINF_EM_DBG_HYPER_STEPPED:2567 case VINF_EM_DBG_HYPER_ASSERTION:2568 case VINF_EM_DBG_STOP:2569 break;2570 2571 /*2572 * Up a level, dump and debug.2573 */2574 case VERR_TRPM_DONT_PANIC:2575 case VERR_TRPM_PANIC:2576 case VERR_VMM_RING0_ASSERTION:2577 case VERR_VMM_HYPER_CR3_MISMATCH:2578 case VERR_VMM_RING3_CALL_DISABLED:2579 break;2580 2581 /*2582 * Up a level, after HwAccM have done some release logging.2583 */2584 case VERR_VMX_INVALID_VMCS_FIELD:2585 case VERR_VMX_INVALID_VMCS_PTR:2586 case VERR_VMX_INVALID_VMXON_PTR:2587 case VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_CODE:2588 case VERR_VMX_UNEXPECTED_EXCEPTION:2589 case VERR_VMX_UNEXPECTED_EXIT_CODE:2590 case VERR_VMX_INVALID_GUEST_STATE:2591 case VERR_VMX_UNABLE_TO_START_VM:2592 case VERR_VMX_UNABLE_TO_RESUME_VM:2593 HWACCMR3CheckError(pVM, rc);2594 break;2595 /*2596 * Anything which is not known to us means an internal error2597 * and the termination of the VM!2598 */2599 default:2600 AssertMsgFailed(("Unknown GC return code: %Rra\n", rc));2601 break;2602 }2603 return rc;2604 }2605 2606 2607 /**2608 2320 * Check for pending raw actions 2609 2321 * … … 3070 2782 break; 3071 2783 3072 rc = emR3 RawHandleRC(pVM, pVCpu, pCtx, rc);2784 rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc); 3073 2785 if (rc != VINF_SUCCESS) 3074 2786 break;
Note:
See TracChangeset
for help on using the changeset viewer.