VirtualBox

Changeset 17707 in vbox


Ignore:
Timestamp:
Mar 11, 2009 4:16:42 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
44216
Message:

Use standard V86 mode and emulate faulting instructions. (VT-x)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r17687 r17707  
    608608    {
    609609        LogFlow(("INJ-EI: %x at %RGv\n", iGate, (RTGCPTR)pCtx->rip));
    610         Assert(!VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS));
    611         Assert(pCtx->eflags.u32 & X86_EFL_IF);
     610        Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || !VM_FF_ISSET(pVM, VM_FF_INHIBIT_INTERRUPTS));
     611        Assert(VMX_EXIT_INTERRUPTION_INFO_TYPE(intInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_SW || pCtx->eflags.u32 & X86_EFL_IF);
    612612    }
    613613#endif
     
    14871487        }
    14881488
    1489 #ifdef HWACCM_VMX_EMULATE_REALMODE
    1490         /* Real mode emulation using v86 mode with CR4.VME (interrupt redirection using the int bitmap in the TSS) */
    1491         if (CPUMIsGuestInRealModeEx(pCtx))
    1492             val |= X86_CR4_VME;
    1493 #endif /* HWACCM_VMX_EMULATE_REALMODE */
    1494 
    14951489        rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_CR4,            val);
    14961490        Log2(("Guest CR4 %08x\n", val));
     
    14991493         */
    15001494        val =   0
    1501 #ifdef HWACCM_VMX_EMULATE_REALMODE
    1502               | (pVM->hwaccm.s.vmx.pRealModeTSS ? X86_CR4_VME : 0)
    1503 #endif
    15041495              | X86_CR4_PAE
    15051496              | X86_CR4_PGE
     
    16111602
    16121603#ifdef HWACCM_VMX_EMULATE_REALMODE
    1613     /* Real mode emulation using v86 mode with CR4.VME (interrupt redirection using the int bitmap in the TSS) */
     1604    /* Real mode emulation using v86 mode. */
    16141605    if (CPUMIsGuestInRealModeEx(pCtx))
    16151606    {
     
    16171608
    16181609        eflags.Bits.u1VM   = 1;
    1619         eflags.Bits.u2IOPL = 3;
     1610        eflags.Bits.u2IOPL = 0; /* must always be 0 or else certain instructions won't cause faults. */
    16201611    }
    16211612#endif /* HWACCM_VMX_EMULATE_REALMODE */
     
    17921783
    17931784#ifdef HWACCM_VMX_EMULATE_REALMODE
    1794     /* Real mode emulation using v86 mode with CR4.VME (interrupt redirection using the int bitmap in the TSS) */
     1785    /* Real mode emulation using v86 mode. */
    17951786    if (CPUMIsGuestInRealModeEx(pCtx))
    17961787    {
    17971788        /* Hide our emulation flags */
    17981789        pCtx->eflags.Bits.u1VM   = 0;
     1790
     1791        /* Restore original IOPL setting as we always use 0. */
    17991792        pCtx->eflags.Bits.u2IOPL = pVCpu->hwaccm.s.vmx.RealMode.eflags.Bits.u2IOPL;
    18001793
     
    25432536            case X86_XCPT_GP:   /* General protection failure exception.*/
    25442537            {
    2545                 uint32_t cbSize;
     2538                uint32_t    cbOp;
     2539                uint32_t    cbSize;
     2540                DISCPUSTATE Cpu;
    25462541
    25472542                STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestGP);
     
    25592554
    25602555                LogFlow(("Real mode X86_XCPT_GP instruction emulation at %RGv\n", (RTGCPTR)pCtx->rip));
     2556
     2557#if 0
     2558                /* For testing purposes */
    25612559                rc = EMInterpretInstruction(pVM, CPUMCTX2CORE(pCtx), 0, &cbSize);
    25622560                if (rc == VINF_SUCCESS)
    25632561                {
    25642562                    /* EIP has been updated already. */
    2565 
     2563 
    25662564                    /* lidt, lgdt can end up here. In the future crx changes as well. Just reload the whole context to be done with it. */
    25672565                    pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
    2568 
    25692566                    /* Only resume if successful. */
    25702567                    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
    25712568                    goto ResumeExecution;
    25722569                }
     2570#else
     2571                rc = EMInterpretDisasOne(pVM, CPUMCTX2CORE(pCtx), &Cpu, &cbOp);
     2572                if (RT_SUCCESS(rc))
     2573                {
     2574                    bool fUpdateRIP = true;
     2575
     2576                    Assert(cbOp == Cpu.opsize);
     2577                    switch (Cpu.pCurInstr->opcode)
     2578                    {
     2579                    case OP_CLI:
     2580                        pCtx->eflags.Bits.u1IF = 0;
     2581                        break;
     2582
     2583                    case OP_STI:
     2584                        pCtx->eflags.Bits.u1IF = 1;
     2585                        break;
     2586
     2587                    case OP_POPF:
     2588                    {
     2589                        RTGCPTR   GCPtrStack;
     2590                        uint32_t  cbParm;
     2591                        uint32_t  uMask;
     2592                        X86EFLAGS eflags;
     2593
     2594                        cbParm  = (Cpu.prefix & PREFIX_OPSIZE) ? 4 : 2;
     2595                        uMask   = (Cpu.prefix & PREFIX_ADDRSIZE) ? 0xffffffff : 0xffff;
     2596
     2597                        rc = SELMToFlatEx(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), pCtx->esp & uMask, 0, &GCPtrStack);
     2598                        if (RT_FAILURE(rc))
     2599                        {
     2600                            rc = VERR_EM_INTERPRETER;
     2601                            break;
     2602                        }
     2603#ifdef VBOX_WITH_NEW_PHYS_CODE
     2604                        eflags.u = 0;
     2605                        rc = PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
     2606                        if (RT_FAILURE(rc))
     2607                        {
     2608                            rc = VERR_EM_INTERPRETER;
     2609                            break;
     2610                        }
     2611#else
     2612                        PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
     2613#endif
     2614                        LogFlow(("POPF %x -> %RGv\n", eflags.u, pCtx->rsp));
     2615                        pCtx->eflags.u = (pCtx->eflags.u & ~(X86_EFL_POPF_BITS & uMask)) | (eflags.u & X86_EFL_POPF_BITS & uMask);
     2616                        /* RF cleared when popped in real mode; see pushf description in AMD manual. */
     2617                        pCtx->eflags.Bits.u1RF = 0;
     2618                        pCtx->esp += cbParm;
     2619                        pCtx->esp &= uMask;
     2620                        break;
     2621                    }
     2622
     2623                    case OP_PUSHF:
     2624                    {
     2625                        RTGCPTR   GCPtrStack;
     2626                        uint32_t  cbParm;
     2627                        uint32_t  uMask;
     2628                        X86EFLAGS eflags;
     2629
     2630                        cbParm  = (Cpu.prefix & PREFIX_OPSIZE) ? 4 : 2;
     2631                        uMask   = (Cpu.prefix & PREFIX_ADDRSIZE) ? 0xffffffff : 0xffff;
     2632
     2633                        rc = SELMToFlatEx(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), (pCtx->esp - cbParm) & uMask, 0, &GCPtrStack);
     2634                        if (RT_FAILURE(rc))
     2635                        {
     2636                            rc = VERR_EM_INTERPRETER;
     2637                            break;
     2638                        }
     2639                        eflags = pCtx->eflags;
     2640                        /* RF & VM cleared when pushed in real mode; see pushf description in AMD manual. */
     2641                        eflags.Bits.u1RF = 0;
     2642                        eflags.Bits.u1VM = 0;
     2643
     2644#ifdef VBOX_WITH_NEW_PHYS_CODE
     2645                        rc = PGMPhysWrite(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
     2646                        if (RT_FAILURE(rc))
     2647                        {
     2648                            rc = VERR_EM_INTERPRETER;
     2649                            break;
     2650                        }
     2651#else
     2652                        PGMPhysWrite(pVM, (RTGCPHYS)GCPtrStack, &eflags.u, cbParm);
     2653#endif
     2654                        LogFlow(("PUSHF %x -> %RGv\n", eflags.u, GCPtrStack));
     2655                        pCtx->esp -= cbParm;
     2656                        pCtx->esp &= uMask;
     2657                        break;
     2658
     2659                    }
     2660
     2661                    case OP_IRET:
     2662                    {
     2663                        RTGCPTR   GCPtrStack;
     2664                        uint32_t  uMask = 0xffff;
     2665                        uint16_t  aIretFrame[3];
     2666
     2667                        if (Cpu.prefix & (PREFIX_OPSIZE | PREFIX_ADDRSIZE))
     2668                        {
     2669                            rc = VERR_EM_INTERPRETER;
     2670                            break;
     2671                        }
     2672
     2673                        rc = SELMToFlatEx(pVM, DIS_SELREG_SS, CPUMCTX2CORE(pCtx), pCtx->esp & uMask, 0, &GCPtrStack);
     2674                        if (RT_FAILURE(rc))
     2675                        {
     2676                            rc = VERR_EM_INTERPRETER;
     2677                            break;
     2678                        }
     2679#ifdef VBOX_WITH_NEW_PHYS_CODE
     2680                        rc = PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &aIretFrame[0], sizeof(aIretFrame));
     2681                        if (RT_FAILURE(rc))
     2682                        {
     2683                            rc = VERR_EM_INTERPRETER;
     2684                            break;
     2685                        }
     2686#else
     2687                        PGMPhysRead(pVM, (RTGCPHYS)GCPtrStack, &aIretFrame[0], sizeof(aIretFrame));
     2688#endif
     2689                        pCtx->ip            = aIretFrame[0];
     2690                        pCtx->cs            = aIretFrame[1];
     2691                        pCtx->csHid.u64Base = pCtx->cs << 4;
     2692                        pCtx->eflags.u      = (pCtx->eflags.u & ~(X86_EFL_POPF_BITS & uMask)) | (aIretFrame[2] & X86_EFL_POPF_BITS & uMask);
     2693                        pCtx->sp           += sizeof(aIretFrame);
     2694
     2695                        LogFlow(("iret to %04x:%x\n", pCtx->cs, pCtx->ip));
     2696                        fUpdateRIP = false;
     2697                        break;
     2698                    }
     2699
     2700                    case OP_INT:
     2701                    {
     2702                        RTGCUINTPTR intInfo;
     2703
     2704                        LogFlow(("Realmode: INT %x\n", Cpu.param1.parval & 0xff));
     2705                        intInfo  = Cpu.param1.parval & 0xff;
     2706                        intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
     2707                        intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
     2708
     2709                        rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, cbOp, 0);
     2710                        AssertRC(rc);
     2711                        fUpdateRIP = false;
     2712                        break;
     2713                    }
     2714
     2715                    case OP_INTO:
     2716                    {
     2717                        if (pCtx->eflags.Bits.u1OF)
     2718                        {
     2719                            RTGCUINTPTR intInfo;
     2720
     2721                            LogFlow(("Realmode: INTO\n"));
     2722                            intInfo  = X86_XCPT_OF;
     2723                            intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
     2724                            intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
     2725
     2726                            rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, cbOp, 0);
     2727                            AssertRC(rc);
     2728                            fUpdateRIP = false;
     2729                        }
     2730                        break;
     2731                    }
     2732
     2733                    case OP_INT3:
     2734                    {
     2735                        RTGCUINTPTR intInfo;
     2736
     2737                        LogFlow(("Realmode: INT 3\n"));
     2738                        intInfo  = 3;
     2739                        intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);
     2740                        intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT);
     2741
     2742                        rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, cbOp, 0);
     2743                        AssertRC(rc);
     2744                        fUpdateRIP = false;
     2745                        break;
     2746                    }
     2747
     2748                    default:
     2749                        rc = EMInterpretInstructionCPU(pVM, &Cpu, CPUMCTX2CORE(pCtx), 0, &cbSize);
     2750                        break;
     2751                    }
     2752
     2753                    if (rc == VINF_SUCCESS)
     2754                    {
     2755                        if (fUpdateRIP)
     2756                            pCtx->rip += cbOp; /* Move on to the next instruction. */
     2757
     2758                        /* lidt, lgdt can end up here. In the future crx changes as well. Just reload the whole context to be done with it. */
     2759                        pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL;
     2760
     2761                        /* Only resume if successful. */
     2762                        STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3);
     2763                        goto ResumeExecution;
     2764                    }
     2765                }
     2766                else
     2767                    rc = VERR_EM_INTERPRETER;
     2768#endif
    25732769                AssertMsg(rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT, ("Unexpected rc=%Rrc\n", rc));
    25742770                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