VirtualBox

Changeset 21191 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 3, 2009 11:39:50 AM (16 years ago)
Author:
vboxsync
Message:

Split up RC handling for raw and hwacc modes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/EM.cpp

    r21144 r21191  
    9898static int emR3RawResumeHyper(PVM pVM, PVMCPU pVCpu);
    9999static int emR3RawStep(PVM pVM, PVMCPU pVCpu);
    100 DECLINLINE(int) emR3RawHandleRC(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
    101100DECLINLINE(int) emR3RawUpdateForceFlag(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int rc);
    102101static int emR3RawForcedActions(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
     
    108107static int emR3PatchTrap(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, int gcret);
    109108static int emR3SingleStepExecRem(PVM pVM, uint32_t cIterations);
     109static int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu);
     110static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu);
     111static int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu);
    110112static 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"
    111120
    112121/**
     
    12321241     */
    12331242    rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
    1234     rc = emR3RawHandleRC(pVM, pVCpu, pCtx, rc);
     1243    rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc);
    12351244    rc = emR3RawUpdateForceFlag(pVM, pVCpu, pCtx, rc);
    12361245    return rc;
     
    15061515 * @param   pVCpu       VMCPU handle.
    15071516 */
    1508 int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
     1517static int emR3RawExecuteIOInstruction(PVM pVM, PVMCPU pVCpu)
    15091518{
    15101519    int         rc;
     
    17801789 * @param   pVCpu       VMCPU handle.
    17811790 */
    1782 int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu)
     1791static int emR3RawRingSwitch(PVM pVM, PVMCPU pVCpu)
    17831792{
    17841793    int         rc;
     
    20252034 * @param   pVCpu   VMCPU handle;
    20262035 */
    2027 int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu)
     2036static int emR3RawPrivileged(PVM pVM, PVMCPU pVCpu)
    20282037{
    20292038    STAM_PROFILE_START(&pVCpu->em.s.StatPrivEmu, a);
     
    23092318
    23102319/**
    2311  * Process a subset of the raw-mode return code.
    2312  *
    2313  * Since we have to share this with raw-mode single stepping, this inline
    2314  * 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 handle
    2320  * @param   pVCpu   The VMCPU handle
    2321  * @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_VMI
    2392         /*
    2393          * PARAV function.
    2394          */
    2395         case VINF_EM_RESCHEDULE_PARAV:
    2396             rc = PARAVCallFunction(pVM);
    2397             break;
    2398 #endif
    2399 
    2400         /*
    2401          * Memory mapped I/O access - attempt to patch the instruction
    2402          */
    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 to
    2419          * 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 performance
    2492          */
    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 error
    2597          * 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 /**
    26082320 * Check for pending raw actions
    26092321 *
     
    30702782            break;
    30712783
    3072         rc = emR3RawHandleRC(pVM, pVCpu, pCtx, rc);
     2784        rc = emR3HwaccmHandleRC(pVM, pVCpu, pCtx, rc);
    30732785        if (rc != VINF_SUCCESS)
    30742786            break;
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette