Changeset 17707 in vbox
- Timestamp:
- Mar 11, 2009 4:16:42 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 44216
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r17687 r17707 608 608 { 609 609 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); 612 612 } 613 613 #endif … … 1487 1487 } 1488 1488 1489 #ifdef HWACCM_VMX_EMULATE_REALMODE1490 /* 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 1495 1489 rc |= VMXWriteVMCS64(VMX_VMCS64_GUEST_CR4, val); 1496 1490 Log2(("Guest CR4 %08x\n", val)); … … 1499 1493 */ 1500 1494 val = 0 1501 #ifdef HWACCM_VMX_EMULATE_REALMODE1502 | (pVM->hwaccm.s.vmx.pRealModeTSS ? X86_CR4_VME : 0)1503 #endif1504 1495 | X86_CR4_PAE 1505 1496 | X86_CR4_PGE … … 1611 1602 1612 1603 #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. */ 1614 1605 if (CPUMIsGuestInRealModeEx(pCtx)) 1615 1606 { … … 1617 1608 1618 1609 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. */ 1620 1611 } 1621 1612 #endif /* HWACCM_VMX_EMULATE_REALMODE */ … … 1792 1783 1793 1784 #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. */ 1795 1786 if (CPUMIsGuestInRealModeEx(pCtx)) 1796 1787 { 1797 1788 /* Hide our emulation flags */ 1798 1789 pCtx->eflags.Bits.u1VM = 0; 1790 1791 /* Restore original IOPL setting as we always use 0. */ 1799 1792 pCtx->eflags.Bits.u2IOPL = pVCpu->hwaccm.s.vmx.RealMode.eflags.Bits.u2IOPL; 1800 1793 … … 2543 2536 case X86_XCPT_GP: /* General protection failure exception.*/ 2544 2537 { 2545 uint32_t cbSize; 2538 uint32_t cbOp; 2539 uint32_t cbSize; 2540 DISCPUSTATE Cpu; 2546 2541 2547 2542 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatExitGuestGP); … … 2559 2554 2560 2555 LogFlow(("Real mode X86_XCPT_GP instruction emulation at %RGv\n", (RTGCPTR)pCtx->rip)); 2556 2557 #if 0 2558 /* For testing purposes */ 2561 2559 rc = EMInterpretInstruction(pVM, CPUMCTX2CORE(pCtx), 0, &cbSize); 2562 2560 if (rc == VINF_SUCCESS) 2563 2561 { 2564 2562 /* EIP has been updated already. */ 2565 2563 2566 2564 /* lidt, lgdt can end up here. In the future crx changes as well. Just reload the whole context to be done with it. */ 2567 2565 pVCpu->hwaccm.s.fContextUseFlags |= HWACCM_CHANGED_ALL; 2568 2569 2566 /* Only resume if successful. */ 2570 2567 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit2Sub3, y3); 2571 2568 goto ResumeExecution; 2572 2569 } 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 2573 2769 AssertMsg(rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT, ("Unexpected rc=%Rrc\n", rc)); 2574 2770 break;
Note:
See TracChangeset
for help on using the changeset viewer.