/**
 * 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;
}
Example #2
0
/**
 * 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;
}