/** * Deal with traps occurring during segment loading and IRET when resuming guest * context execution. * * @returns VBox status code. * @param pVM Pointer to the VM. * @param pRegFrame The register frame. * @param uUser User argument. In this case a combination of the * CPUM_HANDLER_* \#defines. */ DECLCALLBACK(int) cpumRCHandleNPAndGP(PVM pVM, PCPUMCTXCORE pRegFrame, uintptr_t uUser) { Log(("********************************************************\n")); Log(("cpumRCHandleNPAndGP: eip=%RX32 uUser=%#x\n", pRegFrame->eip, uUser)); Log(("********************************************************\n")); /* * Take action based on what's happened. */ switch (uUser & CPUM_HANDLER_TYPEMASK) { case CPUM_HANDLER_GS: case CPUM_HANDLER_DS: case CPUM_HANDLER_ES: case CPUM_HANDLER_FS: TRPMGCHyperReturnToHost(pVM, VINF_EM_RAW_STALE_SELECTOR); break; case CPUM_HANDLER_IRET: TRPMGCHyperReturnToHost(pVM, VINF_EM_RAW_IRET_TRAP); break; } AssertMsgFailed(("uUser=%#x eip=%#x\n", uUser, pRegFrame->eip)); return VERR_TRPM_DONT_PANIC; }
/** * Deal with hypervisor traps occurring when resuming execution on a trap. * * There is a little problem with recursive RC (hypervisor) traps. We deal with * this by not allowing recursion without it being the subject of a guru * meditation. (We used to / tried to handle this but there isn't any reason * for it.) * * So, do NOT use this for handling RC traps! * * @returns VBox status code. (Anything but VINF_SUCCESS will cause guru.) * @param pVM Pointer to the VM. * @param pRegFrame Register frame. * @param uUser User arg. */ DECLCALLBACK(int) trpmRCTrapInGeneric(PVM pVM, PCPUMCTXCORE pRegFrame, uintptr_t uUser) { Log(("********************************************************\n")); Log(("trpmRCTrapInGeneric: eip=%RX32 uUser=%#x\n", pRegFrame->eip, uUser)); Log(("********************************************************\n")); /* * This used to be kind of complicated, but since we stopped storing * the register frame on the stack and instead storing it directly * in the CPUMCPU::Guest structure, we just have to figure out which * status to hand on to the host and let the recompiler/IEM do its * job. */ switch (uUser) { case TRPM_TRAP_IN_MOV_GS: case TRPM_TRAP_IN_MOV_FS: case TRPM_TRAP_IN_MOV_ES: case TRPM_TRAP_IN_MOV_DS: TRPMGCHyperReturnToHost(pVM, VINF_EM_RAW_STALE_SELECTOR); break; case TRPM_TRAP_IN_IRET: case TRPM_TRAP_IN_IRET | TRPM_TRAP_IN_V86: TRPMGCHyperReturnToHost(pVM, VINF_EM_RAW_IRET_TRAP); break; default: AssertMsgFailed(("Invalid uUser=%#x\n", uUser)); return VERR_TRPM_BAD_TRAP_IN_OP; } AssertMsgFailed(("Impossible!\n")); return VERR_TRPM_IPE_3; }