Changeset 47444 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Jul 29, 2013 12:37:31 AM (12 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r47429 r47444 742 742 if (rcOldPassUp == VINF_SUCCESS) 743 743 pIemCpu->rcPassUp = VBOXSTRICTRC_VAL(rcPassUp); 744 /* If both are EM scheduling code , use EM priority rules. */744 /* If both are EM scheduling codes, use EM priority rules. */ 745 745 else if ( rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST 746 746 && rcPassUp >= VINF_EM_FIRST && rcPassUp <= VINF_EM_LAST) … … 764 764 Log(("IEM: rcPassUp=%Rrc rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp)); 765 765 return VINF_SUCCESS; 766 } 767 768 769 /** 770 * Initializes the execution state. 771 * 772 * @param pIemCpu The per CPU IEM state. 773 * @param fBypassHandlers Whether to bypass access handlers. 774 */ 775 DECLINLINE(void) iemInitExec(PIEMCPU pIemCpu, bool fBypassHandlers) 776 { 777 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 778 PVMCPU pVCpu = IEMCPU_TO_VMCPU(pIemCpu); 779 780 #if defined(VBOX_STRICT) && (defined(IEM_VERIFICATION_MODE_FULL) || !defined(VBOX_WITH_RAW_MODE_NOT_R0)) 781 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->cs)); 782 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ss)); 783 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->es)); 784 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ds)); 785 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->fs)); 786 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->gs)); 787 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ldtr)); 788 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->tr)); 789 #endif 790 791 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 792 CPUMGuestLazyLoadHiddenCsAndSs(pVCpu); 793 #endif 794 pIemCpu->uCpl = CPUMGetGuestCPL(pVCpu); 795 IEMMODE enmMode = CPUMIsGuestIn64BitCodeEx(pCtx) 796 ? IEMMODE_64BIT 797 : pCtx->cs.Attr.n.u1DefBig /** @todo check if this is correct... */ 798 ? IEMMODE_32BIT 799 : IEMMODE_16BIT; 800 pIemCpu->enmCpuMode = enmMode; 801 #ifdef VBOX_STRICT 802 pIemCpu->enmDefAddrMode = (IEMMODE)0xc0fe; 803 pIemCpu->enmEffAddrMode = (IEMMODE)0xc0fe; 804 pIemCpu->enmDefOpSize = (IEMMODE)0xc0fe; 805 pIemCpu->enmEffOpSize = (IEMMODE)0xc0fe; 806 pIemCpu->fPrefixes = (IEMMODE)0xfeedbeef; 807 pIemCpu->uRexReg = 127; 808 pIemCpu->uRexB = 127; 809 pIemCpu->uRexIndex = 127; 810 pIemCpu->iEffSeg = 127; 811 pIemCpu->offOpcode = 127; 812 pIemCpu->cbOpcode = 127; 813 #endif 814 815 pIemCpu->cActiveMappings = 0; 816 pIemCpu->iNextMapping = 0; 817 pIemCpu->rcPassUp = VINF_SUCCESS; 818 pIemCpu->fBypassHandlers = fBypassHandlers; 819 #ifdef VBOX_WITH_RAW_MODE_NOT_R0 820 pIemCpu->fInPatchCode = pIemCpu->uCpl == 0 821 && pCtx->cs.u64Base == 0 822 && pCtx->cs.u32Limit == UINT32_MAX 823 && PATMIsPatchGCAddr(IEMCPU_TO_VM(pIemCpu), pCtx->eip); 824 if (!pIemCpu->fInPatchCode) 825 CPUMRawLeave(pVCpu, CPUMCTX2CORE(pCtx), VINF_SUCCESS); 826 #endif 766 827 } 767 828 … … 9021 9082 9022 9083 /** 9023 * The actual code execution bits of IEMExecOne, IEMExecOneEx, and 9024 * IEMExecOneWithPrefetchedByPC. 9025 * 9026 * @return Strict VBox status code. 9027 * @param pVCpu The current virtual CPU. 9084 * Makes status code addjustments (pass up from I/O and access handler) 9085 * as well as maintaining statistics. 9086 * 9087 * @returns Strict VBox status code to pass up. 9028 9088 * @param pIemCpu The IEM per CPU data. 9029 * @param fExecuteInhibit If set, execute the instruction following CLI, 9030 * POP SS and MOV SS,GR. 9031 */ 9032 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu, bool fExecuteInhibit) 9033 { 9034 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b); 9035 VBOXSTRICTRC rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]); 9036 if (rcStrict == VINF_SUCCESS) 9037 pIemCpu->cInstructions++; 9038 //#ifdef DEBUG 9039 // AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr)); 9040 //#endif 9041 9042 /* Execute the next instruction as well if a cli, pop ss or 9043 mov ss, Gr has just completed successfully. */ 9044 if ( fExecuteInhibit 9045 && rcStrict == VINF_SUCCESS 9046 && VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) 9047 && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip ) 9048 { 9049 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, pIemCpu->fBypassHandlers); 9050 if (rcStrict == VINF_SUCCESS) 9051 { 9052 b; IEM_OPCODE_GET_NEXT_U8(&b); 9053 rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]); 9054 if (rcStrict == VINF_SUCCESS) 9055 pIemCpu->cInstructions++; 9056 } 9057 EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111)); 9058 } 9059 9060 /* 9061 * Return value fiddling and statistics. 9062 */ 9089 * @param rcStrict The status from executing an instruction. 9090 */ 9091 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecStatusCodeFiddling(PIEMCPU pIemCpu, VBOXSTRICTRC rcStrict) 9092 { 9063 9093 if (rcStrict != VINF_SUCCESS) 9064 9094 { 9065 9095 if (RT_SUCCESS(rcStrict)) 9066 9096 { 9067 AssertMsg(rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST, ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 9097 AssertMsg( (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST) 9098 || rcStrict == VINF_IOM_R3_IOPORT_READ 9099 || rcStrict == VINF_IOM_R3_IOPORT_WRITE 9100 || rcStrict == VINF_IOM_R3_MMIO_READ 9101 || rcStrict == VINF_IOM_R3_MMIO_READ_WRITE 9102 || rcStrict == VINF_IOM_R3_MMIO_WRITE 9103 , ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 9068 9104 int32_t const rcPassUp = pIemCpu->rcPassUp; 9069 9105 if (rcPassUp == VINF_SUCCESS) … … 9100 9136 } 9101 9137 9138 return rcStrict; 9139 } 9140 9141 9142 /** 9143 * The actual code execution bits of IEMExecOne, IEMExecOneEx, and 9144 * IEMExecOneWithPrefetchedByPC. 9145 * 9146 * @return Strict VBox status code. 9147 * @param pVCpu The current virtual CPU. 9148 * @param pIemCpu The IEM per CPU data. 9149 * @param fExecuteInhibit If set, execute the instruction following CLI, 9150 * POP SS and MOV SS,GR. 9151 */ 9152 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu, bool fExecuteInhibit) 9153 { 9154 uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b); 9155 VBOXSTRICTRC rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]); 9156 if (rcStrict == VINF_SUCCESS) 9157 pIemCpu->cInstructions++; 9158 //#ifdef DEBUG 9159 // AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr)); 9160 //#endif 9161 9162 /* Execute the next instruction as well if a cli, pop ss or 9163 mov ss, Gr has just completed successfully. */ 9164 if ( fExecuteInhibit 9165 && rcStrict == VINF_SUCCESS 9166 && VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS) 9167 && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip ) 9168 { 9169 rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, pIemCpu->fBypassHandlers); 9170 if (rcStrict == VINF_SUCCESS) 9171 { 9172 b; IEM_OPCODE_GET_NEXT_U8(&b); 9173 rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]); 9174 if (rcStrict == VINF_SUCCESS) 9175 pIemCpu->cInstructions++; 9176 } 9177 EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111)); 9178 } 9179 9180 /* 9181 * Return value fiddling, statistics and sanity assertions. 9182 */ 9183 rcStrict = iemExecStatusCodeFiddling(pIemCpu, rcStrict); 9184 9102 9185 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->cs)); 9103 9186 Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->ss)); … … 9481 9564 #endif 9482 9565 9566 9567 9568 /** 9569 * Interface for HM and EM for executing string I/O OUT (write) instructions. 9570 * 9571 * This API ASSUMES that the caller has already verified that the guest code is 9572 * allowed to access the I/O port. (The I/O port is in the DX register in the 9573 * guest state.) 9574 * 9575 * @returns Strict VBox status code. 9576 * @param pVCpu The cross context per virtual CPU structure. 9577 * @param cbValue The size of the I/O port access (1, 2, or 4). 9578 * @param enmAddrMode The addressing mode. 9579 * @param fRepPrefix Indicates whether a repeat prefix is used 9580 * (doesn't matter which for this instruction). 9581 * @param cbInstr The instruction length in bytes. 9582 * @param iEffSeg The effective segment address. 9583 */ 9584 VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, 9585 bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg) 9586 { 9587 AssertMsgReturn(iEffSeg < X86_SREG_COUNT, ("%#x\n", iEffSeg), VERR_IEM_INVALID_EFF_SEG); 9588 AssertReturn(cbInstr - 1U <= 14U, VERR_IEM_INVALID_INSTR_LENGTH); 9589 9590 /* 9591 * State init. 9592 */ 9593 PIEMCPU pIemCpu = &pVCpu->iem.s; 9594 iemInitExec(pIemCpu, false /*fBypassHandlers*/); 9595 9596 /* 9597 * Switch orgy for getting to the right handler. 9598 */ 9599 VBOXSTRICTRC rcStrict; 9600 if (fRepPrefix) 9601 { 9602 switch (enmAddrMode) 9603 { 9604 case IEMMODE_16BIT: 9605 switch (cbValue) 9606 { 9607 case 1: rcStrict = iemCImpl_rep_outs_op8_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9608 case 2: rcStrict = iemCImpl_rep_outs_op16_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9609 case 4: rcStrict = iemCImpl_rep_outs_op32_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9610 default: 9611 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9612 } 9613 break; 9614 9615 case IEMMODE_32BIT: 9616 switch (cbValue) 9617 { 9618 case 1: rcStrict = iemCImpl_rep_outs_op8_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9619 case 2: rcStrict = iemCImpl_rep_outs_op16_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9620 case 4: rcStrict = iemCImpl_rep_outs_op32_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9621 default: 9622 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9623 } 9624 break; 9625 9626 case IEMMODE_64BIT: 9627 switch (cbValue) 9628 { 9629 case 1: rcStrict = iemCImpl_rep_outs_op8_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9630 case 2: rcStrict = iemCImpl_rep_outs_op16_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9631 case 4: rcStrict = iemCImpl_rep_outs_op32_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9632 default: 9633 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9634 } 9635 break; 9636 9637 default: 9638 AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE); 9639 } 9640 } 9641 else 9642 { 9643 switch (enmAddrMode) 9644 { 9645 case IEMMODE_16BIT: 9646 switch (cbValue) 9647 { 9648 case 1: rcStrict = iemCImpl_outs_op8_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9649 case 2: rcStrict = iemCImpl_outs_op16_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9650 case 4: rcStrict = iemCImpl_outs_op32_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9651 default: 9652 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9653 } 9654 break; 9655 9656 case IEMMODE_32BIT: 9657 switch (cbValue) 9658 { 9659 case 1: rcStrict = iemCImpl_outs_op8_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9660 case 2: rcStrict = iemCImpl_outs_op16_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9661 case 4: rcStrict = iemCImpl_outs_op32_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9662 default: 9663 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9664 } 9665 break; 9666 9667 case IEMMODE_64BIT: 9668 switch (cbValue) 9669 { 9670 case 1: rcStrict = iemCImpl_outs_op8_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9671 case 2: rcStrict = iemCImpl_outs_op16_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9672 case 4: rcStrict = iemCImpl_outs_op32_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break; 9673 default: 9674 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9675 } 9676 break; 9677 9678 default: 9679 AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE); 9680 } 9681 } 9682 9683 return iemExecStatusCodeFiddling(pIemCpu, rcStrict); 9684 } 9685 9686 9687 /** 9688 * Interface for HM and EM for executing string I/O IN (read) instructions. 9689 * 9690 * This API ASSUMES that the caller has already verified that the guest code is 9691 * allowed to access the I/O port. (The I/O port is in the DX register in the 9692 * guest state.) 9693 * 9694 * @returns Strict VBox status code. 9695 * @param pVCpu The cross context per virtual CPU structure. 9696 * @param cbValue The size of the I/O port access (1, 2, or 4). 9697 * @param enmAddrMode The addressing mode. 9698 * @param fRepPrefix Indicates whether a repeat prefix is used 9699 * (doesn't matter which for this instruction). 9700 * @param cbInstr The instruction length in bytes. 9701 */ 9702 VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, 9703 bool fRepPrefix, uint8_t cbInstr) 9704 { 9705 AssertReturn(cbInstr - 1U <= 14U, VERR_IEM_INVALID_INSTR_LENGTH); 9706 9707 /* 9708 * State init. 9709 */ 9710 PIEMCPU pIemCpu = &pVCpu->iem.s; 9711 iemInitExec(pIemCpu, false /*fBypassHandlers*/); 9712 9713 /* 9714 * Switch orgy for getting to the right handler. 9715 */ 9716 VBOXSTRICTRC rcStrict; 9717 if (fRepPrefix) 9718 { 9719 switch (enmAddrMode) 9720 { 9721 case IEMMODE_16BIT: 9722 switch (cbValue) 9723 { 9724 case 1: rcStrict = iemCImpl_rep_ins_op8_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9725 case 2: rcStrict = iemCImpl_rep_ins_op16_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9726 case 4: rcStrict = iemCImpl_rep_ins_op32_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9727 default: 9728 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9729 } 9730 break; 9731 9732 case IEMMODE_32BIT: 9733 switch (cbValue) 9734 { 9735 case 1: rcStrict = iemCImpl_rep_ins_op8_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9736 case 2: rcStrict = iemCImpl_rep_ins_op16_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9737 case 4: rcStrict = iemCImpl_rep_ins_op32_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9738 default: 9739 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9740 } 9741 break; 9742 9743 case IEMMODE_64BIT: 9744 switch (cbValue) 9745 { 9746 case 1: rcStrict = iemCImpl_rep_ins_op8_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9747 case 2: rcStrict = iemCImpl_rep_ins_op16_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9748 case 4: rcStrict = iemCImpl_rep_ins_op32_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9749 default: 9750 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9751 } 9752 break; 9753 9754 default: 9755 AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE); 9756 } 9757 } 9758 else 9759 { 9760 switch (enmAddrMode) 9761 { 9762 case IEMMODE_16BIT: 9763 switch (cbValue) 9764 { 9765 case 1: rcStrict = iemCImpl_ins_op8_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9766 case 2: rcStrict = iemCImpl_ins_op16_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9767 case 4: rcStrict = iemCImpl_ins_op32_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9768 default: 9769 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9770 } 9771 break; 9772 9773 case IEMMODE_32BIT: 9774 switch (cbValue) 9775 { 9776 case 1: rcStrict = iemCImpl_ins_op8_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9777 case 2: rcStrict = iemCImpl_ins_op16_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9778 case 4: rcStrict = iemCImpl_ins_op32_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9779 default: 9780 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9781 } 9782 break; 9783 9784 case IEMMODE_64BIT: 9785 switch (cbValue) 9786 { 9787 case 1: rcStrict = iemCImpl_ins_op8_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9788 case 2: rcStrict = iemCImpl_ins_op16_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9789 case 4: rcStrict = iemCImpl_ins_op32_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break; 9790 default: 9791 AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE); 9792 } 9793 break; 9794 9795 default: 9796 AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE); 9797 } 9798 } 9799 9800 return iemExecStatusCodeFiddling(pIemCpu, rcStrict); 9801 } 9802 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h
r47288 r47444 1018 1018 * Implements 'INS' (no rep) 1019 1019 */ 1020 IEM_CIMPL_DEF_ 0(RT_CONCAT4(iemCImpl_ins_op,OP_SIZE,_addr,ADDR_SIZE))1020 IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_ins_op,OP_SIZE,_addr,ADDR_SIZE), bool, fIoChecked) 1021 1021 { 1022 1022 PVM pVM = IEMCPU_TO_VM(pIemCpu); … … 1038 1038 * ASSUMES nothing is read from the I/O port before traps are taken. 1039 1039 */ 1040 rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8); 1041 if (rcStrict != VINF_SUCCESS) 1042 return rcStrict; 1040 if (!fIoChecked) 1041 { 1042 rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8); 1043 if (rcStrict != VINF_SUCCESS) 1044 return rcStrict; 1045 } 1043 1046 1044 1047 OP_TYPE *puMem; … … 1077 1080 * Implements 'REP INS'. 1078 1081 */ 1079 IEM_CIMPL_DEF_ 0(RT_CONCAT4(iemCImpl_rep_ins_op,OP_SIZE,_addr,ADDR_SIZE))1082 IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_rep_ins_op,OP_SIZE,_addr,ADDR_SIZE), bool, fIoChecked) 1080 1083 { 1081 1084 PVM pVM = IEMCPU_TO_VM(pIemCpu); … … 1087 1090 */ 1088 1091 uint16_t const u16Port = pCtx->dx; 1089 VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8); 1090 if (rcStrict != VINF_SUCCESS) 1091 return rcStrict; 1092 VBOXSTRICTRC rcStrict; 1093 if (!fIoChecked) 1094 { 1095 rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8); 1096 if (rcStrict != VINF_SUCCESS) 1097 return rcStrict; 1098 } 1092 1099 1093 1100 ADDR_TYPE uCounterReg = pCtx->ADDR_rCX; … … 1148 1155 /** @todo Change the I/O manager interface to make use of 1149 1156 * mapped buffers instead of leaving those bits to the 1150 * device implementation ?*/1157 * device implementation! */ 1151 1158 PGMPAGEMAPLOCK PgLockMem; 1152 1159 OP_TYPE *puMem; … … 1171 1178 { 1172 1179 if (IOM_SUCCESS(rcStrict)) 1180 { 1173 1181 rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict); 1174 if (uCounterReg == 0) 1175 iemRegAddToRip(pIemCpu, cbInstr); 1182 if (uCounterReg == 0) 1183 iemRegAddToRip(pIemCpu, cbInstr); 1184 } 1176 1185 iemMemPageUnmap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_W, puMem, &PgLockMem); 1177 1186 return rcStrict; … … 1226 1235 if (rcStrict != VINF_SUCCESS) 1227 1236 { 1228 if (IOM_SUCCESS(rcStrict))1229 rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict);1230 1237 if (uCounterReg == 0) 1231 1238 iemRegAddToRip(pIemCpu, cbInstr); 1239 rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict); 1232 1240 return rcStrict; 1233 1241 } … … 1246 1254 * Implements 'OUTS' (no rep) 1247 1255 */ 1248 IEM_CIMPL_DEF_ 1(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)1256 IEM_CIMPL_DEF_2(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg, bool, fIoChecked) 1249 1257 { 1250 1258 PVM pVM = IEMCPU_TO_VM(pIemCpu); … … 1257 1265 * ASSUMES nothing is read from the I/O port before traps are taken. 1258 1266 */ 1259 rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8); 1260 if (rcStrict != VINF_SUCCESS) 1261 return rcStrict; 1267 if (!fIoChecked) 1268 { 1269 rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8); 1270 if (rcStrict != VINF_SUCCESS) 1271 return rcStrict; 1272 } 1262 1273 1263 1274 OP_TYPE uValue; … … 1287 1298 * Implements 'REP OUTS'. 1288 1299 */ 1289 IEM_CIMPL_DEF_ 1(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)1300 IEM_CIMPL_DEF_2(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg, bool, fIoChecked) 1290 1301 { 1291 1302 PVM pVM = IEMCPU_TO_VM(pIemCpu); … … 1297 1308 */ 1298 1309 uint16_t const u16Port = pCtx->dx; 1299 VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8); 1300 if (rcStrict != VINF_SUCCESS) 1301 return rcStrict; 1310 VBOXSTRICTRC rcStrict; 1311 if (!fIoChecked) 1312 { 1313 rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8); 1314 if (rcStrict != VINF_SUCCESS) 1315 return rcStrict; 1316 } 1302 1317 1303 1318 ADDR_TYPE uCounterReg = pCtx->ADDR_rCX; … … 1372 1387 { 1373 1388 if (IOM_SUCCESS(rcStrict)) 1389 { 1374 1390 rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict); 1375 if (uCounterReg == 0) 1376 iemRegAddToRip(pIemCpu, cbInstr); 1391 if (uCounterReg == 0) 1392 iemRegAddToRip(pIemCpu, cbInstr); 1393 } 1377 1394 iemMemPageUnmap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, puMem, &PgLockMem); 1378 1395 return rcStrict; … … 1422 1439 { 1423 1440 if (IOM_SUCCESS(rcStrict)) 1441 { 1442 if (uCounterReg == 0) 1443 iemRegAddToRip(pIemCpu, cbInstr); 1424 1444 rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict); 1425 if (uCounterReg == 0) 1426 iemRegAddToRip(pIemCpu, cbInstr); 1445 } 1427 1446 return rcStrict; 1428 1447 } -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h
r47415 r47444 8385 8385 switch (pIemCpu->enmEffAddrMode) 8386 8386 { 8387 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op8_addr16);8388 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op8_addr32);8389 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op8_addr64);8387 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr16, false); 8388 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr32, false); 8389 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr64, false); 8390 8390 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8391 8391 } … … 8396 8396 switch (pIemCpu->enmEffAddrMode) 8397 8397 { 8398 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op8_addr16);8399 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op8_addr32);8400 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op8_addr64);8398 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr16, false); 8399 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr32, false); 8400 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr64, false); 8401 8401 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8402 8402 } … … 8417 8417 switch (pIemCpu->enmEffAddrMode) 8418 8418 { 8419 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op16_addr16);8420 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op16_addr32);8421 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op16_addr64);8419 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr16, false); 8420 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr32, false); 8421 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr64, false); 8422 8422 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8423 8423 } … … 8427 8427 switch (pIemCpu->enmEffAddrMode) 8428 8428 { 8429 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op32_addr16);8430 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op32_addr32);8431 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_rep_ins_op32_addr64);8429 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr16, false); 8430 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr32, false); 8431 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr64, false); 8432 8432 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8433 8433 } … … 8444 8444 switch (pIemCpu->enmEffAddrMode) 8445 8445 { 8446 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op16_addr16);8447 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op16_addr32);8448 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op16_addr64);8446 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr16, false); 8447 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr32, false); 8448 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr64, false); 8449 8449 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8450 8450 } … … 8454 8454 switch (pIemCpu->enmEffAddrMode) 8455 8455 { 8456 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op32_addr16);8457 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op32_addr32);8458 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 0(iemCImpl_ins_op32_addr64);8456 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr16, false); 8457 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr32, false); 8458 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr64, false); 8459 8459 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8460 8460 } … … 8475 8475 switch (pIemCpu->enmEffAddrMode) 8476 8476 { 8477 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op8_addr16, pIemCpu->iEffSeg);8478 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op8_addr32, pIemCpu->iEffSeg);8479 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op8_addr64, pIemCpu->iEffSeg);8477 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr16, pIemCpu->iEffSeg, false); 8478 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr32, pIemCpu->iEffSeg, false); 8479 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr64, pIemCpu->iEffSeg, false); 8480 8480 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8481 8481 } … … 8486 8486 switch (pIemCpu->enmEffAddrMode) 8487 8487 { 8488 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op8_addr16, pIemCpu->iEffSeg);8489 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op8_addr32, pIemCpu->iEffSeg);8490 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op8_addr64, pIemCpu->iEffSeg);8488 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr16, pIemCpu->iEffSeg, false); 8489 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr32, pIemCpu->iEffSeg, false); 8490 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr64, pIemCpu->iEffSeg, false); 8491 8491 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8492 8492 } … … 8507 8507 switch (pIemCpu->enmEffAddrMode) 8508 8508 { 8509 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op16_addr16, pIemCpu->iEffSeg);8510 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op16_addr32, pIemCpu->iEffSeg);8511 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op16_addr64, pIemCpu->iEffSeg);8509 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr16, pIemCpu->iEffSeg, false); 8510 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr32, pIemCpu->iEffSeg, false); 8511 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr64, pIemCpu->iEffSeg, false); 8512 8512 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8513 8513 } … … 8517 8517 switch (pIemCpu->enmEffAddrMode) 8518 8518 { 8519 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op32_addr16, pIemCpu->iEffSeg);8520 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op32_addr32, pIemCpu->iEffSeg);8521 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_rep_outs_op32_addr64, pIemCpu->iEffSeg);8519 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr16, pIemCpu->iEffSeg, false); 8520 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr32, pIemCpu->iEffSeg, false); 8521 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr64, pIemCpu->iEffSeg, false); 8522 8522 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8523 8523 } … … 8534 8534 switch (pIemCpu->enmEffAddrMode) 8535 8535 { 8536 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op16_addr16, pIemCpu->iEffSeg);8537 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op16_addr32, pIemCpu->iEffSeg);8538 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op16_addr64, pIemCpu->iEffSeg);8536 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr16, pIemCpu->iEffSeg, false); 8537 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr32, pIemCpu->iEffSeg, false); 8538 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr64, pIemCpu->iEffSeg, false); 8539 8539 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8540 8540 } … … 8544 8544 switch (pIemCpu->enmEffAddrMode) 8545 8545 { 8546 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op32_addr16, pIemCpu->iEffSeg);8547 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op32_addr32, pIemCpu->iEffSeg);8548 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_ 1(iemCImpl_outs_op32_addr64, pIemCpu->iEffSeg);8546 case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr16, pIemCpu->iEffSeg, false); 8547 case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr32, pIemCpu->iEffSeg, false); 8548 case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr64, pIemCpu->iEffSeg, false); 8549 8549 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 8550 8550 } -
trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
r46420 r47444 1767 1767 * @remarks This must be called *AFTER* PGMUpdateCR3. 1768 1768 * 1769 * @returns VBox status code.1770 1769 * @param pVCpu Pointer to the VMCPU. 1771 1770 * @param paPdpes The four PDPE values. The array pointed to must … … 1774 1773 * @remarks No-long-jump zone!!! 1775 1774 */ 1776 VMM_INT_DECL( int) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes)1775 VMM_INT_DECL(void) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes) 1777 1776 { 1778 1777 Assert(pVCpu->pgm.s.enmShadowMode == PGMMODE_EPT); … … 1795 1794 1796 1795 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES); 1797 return VINF_SUCCESS;1798 1796 } 1799 1797 … … 2037 2035 * @returns VBox status code. 2038 2036 * @retval VINF_SUCCESS. 2039 * @retval (If applied when not in nested mode: VINF_PGM_SYNC_CR3 if monitoring2040 * requires a CR3 sync. This can safely be ignored and overridden since2041 * the FF will be set too then.)2037 * @retval VINF_PGM_SYNC_CR3 if monitoring requires a CR3 sync (not for nested 2038 * paging modes). This can safely be ignored and overridden since the 2039 * FF will be set too then. 2042 2040 * @param pVCpu Pointer to the VMCPU. 2043 2041 * @param cr3 The new cr3. -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r47441 r47444 29 29 #include <VBox/vmm/pdmapi.h> 30 30 #include <VBox/vmm/dbgf.h> 31 #include <VBox/vmm/iem.h> 31 32 #include <VBox/vmm/iom.h> 32 33 #include <VBox/vmm/selm.h> … … 111 112 /** @} */ 112 113 113 /** 114 /** @name 114 115 * Flags to skip redundant reads of some common VMCS fields that are not part of 115 116 * the guest-CPU state but are in the transient structure. … … 121 122 #define HMVMX_UPDATED_TRANSIENT_EXIT_INTERRUPTION_INFO RT_BIT(4) 122 123 #define HMVMX_UPDATED_TRANSIENT_EXIT_INTERRUPTION_ERROR_CODE RT_BIT(5) 123 124 /** 125 * @name Exception bitmap mask for real-mode guests (real-on-v86). 124 /** @} */ 125 126 /** 127 * Exception bitmap mask for real-mode guests (real-on-v86). 126 128 * 127 129 * We need to intercept all exceptions manually (except #PF). #NM is also … … 136 138 | RT_BIT(X86_XCPT_MF) | RT_BIT(X86_XCPT_AC) | RT_BIT(X86_XCPT_MC) \ 137 139 | RT_BIT(X86_XCPT_XF)) 138 /** @} */ 139 140 /** 141 * @name Exception bitmap mask for all contributory exceptions. 140 141 /** 142 * Exception bitmap mask for all contributory exceptions. 142 143 * 143 144 * Page fault is deliberately excluded here as it's conditional as to whether … … 146 147 #define HMVMX_CONTRIBUTORY_XCPT_MASK ( RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_TS) \ 147 148 | RT_BIT(X86_XCPT_DE)) 148 /** @} */149 149 150 150 /** Maximum VM-instruction error number. */ … … 164 164 * Structures and Typedefs * 165 165 *******************************************************************************/ 166 /** @name VMX transient. 166 /** 167 * VMX transient state. 167 168 * 168 169 * A state structure for holding miscellaneous information across 169 170 * VMX non-root operation and restored after the transition. 170 * 171 * @{ */ 171 */ 172 172 typedef struct VMXTRANSIENT 173 173 { … … 197 197 /** The VM-exit instruction-length field. */ 198 198 uint32_t cbInstr; 199 /** The VM-exit instruction-information field. */ 200 union 201 { 202 /** Plain unsigned int representation. */ 203 uint32_t u; 204 /** INS and OUTS information. */ 205 struct 206 { 207 uint32_t u6Reserved0 : 6; 208 /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */ 209 uint32_t u3AddrSize : 3; 210 uint32_t u5Reserved1 : 5; 211 /** The segment register (X86_SREG_XXX). */ 212 uint32_t iSegReg : 3; 213 uint32_t uReserved2 : 14; 214 } StrIo; 215 } ExitInstrInfo; 199 216 /** Whether the VM-entry failed or not. */ 200 217 bool fVMEntryFailed; 201 218 /** Alignment. */ 202 uint8_t abAlignment1[ 7];219 uint8_t abAlignment1[3]; 203 220 204 221 /** The VM-entry interruption-information field. */ … … 221 238 * contributory exception or a page-fault. */ 222 239 bool fVectoringPF; 223 } VMXTRANSIENT , *PVMXTRANSIENT;240 } VMXTRANSIENT; 224 241 AssertCompileMemberAlignment(VMXTRANSIENT, uExitReason, sizeof(uint64_t)); 225 242 AssertCompileMemberAlignment(VMXTRANSIENT, uExitIntrInfo, sizeof(uint64_t)); 226 243 AssertCompileMemberAlignment(VMXTRANSIENT, uEntryIntrInfo, sizeof(uint64_t)); 227 /** @} */ 244 AssertCompileMemberSize(VMXTRANSIENT, ExitInstrInfo, sizeof(uint32_t)); 245 /** Pointer to VMX transient state. */ 246 typedef VMXTRANSIENT *PVMXTRANSIENT; 228 247 229 248 … … 249 268 VMXMSREXIT_PASSTHRU_WRITE 250 269 } VMXMSREXITWRITE; 270 271 /** 272 * VM-exit handler. 273 * 274 * @returns VBox status code. 275 * @param pVCpu Pointer to the VMCPU. 276 * @param pMixedCtx Pointer to the guest-CPU context. The data may be 277 * out-of-sync. Make sure to update the required 278 * fields before using them. 279 * @param pVmxTransient Pointer to the VMX-transient structure. 280 */ 281 #ifndef HMVMX_USE_FUNCTION_TABLE 282 typedef int FNVMEXITHANDLER(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 283 #else 284 typedef DECLCALLBACK(int) FNVMEXITHANDLER(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 285 /** Pointer to VM-exit handler. */ 286 typedef FNVMEXITHANDLER *PFNVMEXITHANDLER; 287 #endif 251 288 252 289 … … 263 300 #ifndef HMVMX_USE_FUNCTION_TABLE 264 301 DECLINLINE(int) hmR0VmxHandleExit(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient, uint32_t rcReason); 265 # define HMVMX_EXIT_DECLstatic int302 # define HMVMX_EXIT_DECL static int 266 303 #else 267 # define HMVMX_EXIT_DECLstatic DECLCALLBACK(int)304 # define HMVMX_EXIT_DECL static DECLCALLBACK(int) 268 305 #endif 269 306 270 HMVMX_EXIT_DECL hmR0VmxExitXcptOrNmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 271 HMVMX_EXIT_DECL hmR0VmxExitExtInt(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 272 HMVMX_EXIT_DECL hmR0VmxExitTripleFault(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 273 HMVMX_EXIT_DECL hmR0VmxExitInitSignal(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 274 HMVMX_EXIT_DECL hmR0VmxExitSipi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 275 HMVMX_EXIT_DECL hmR0VmxExitIoSmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 276 HMVMX_EXIT_DECL hmR0VmxExitSmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 277 HMVMX_EXIT_DECL hmR0VmxExitIntWindow(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 278 HMVMX_EXIT_DECL hmR0VmxExitNmiWindow(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 279 HMVMX_EXIT_DECL hmR0VmxExitTaskSwitch(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 280 HMVMX_EXIT_DECL hmR0VmxExitCpuid(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 281 HMVMX_EXIT_DECL hmR0VmxExitGetsec(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 282 HMVMX_EXIT_DECL hmR0VmxExitHlt(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 283 HMVMX_EXIT_DECL hmR0VmxExitInvd(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 284 HMVMX_EXIT_DECL hmR0VmxExitInvlpg(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 285 HMVMX_EXIT_DECL hmR0VmxExitRdpmc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 286 HMVMX_EXIT_DECL hmR0VmxExitRdtsc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 287 HMVMX_EXIT_DECL hmR0VmxExitRsm(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 288 HMVMX_EXIT_DECL hmR0VmxExitSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 289 HMVMX_EXIT_DECL hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 290 HMVMX_EXIT_DECL hmR0VmxExitMovDRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 291 HMVMX_EXIT_DECL hmR0VmxExitIoInstr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 292 HMVMX_EXIT_DECL hmR0VmxExitRdmsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 293 HMVMX_EXIT_DECL hmR0VmxExitWrmsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 294 HMVMX_EXIT_DECL hmR0VmxExitErrInvalidGuestState(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 295 HMVMX_EXIT_DECL hmR0VmxExitErrMsrLoad(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 296 HMVMX_EXIT_DECL hmR0VmxExitErrUndefined(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 297 HMVMX_EXIT_DECL hmR0VmxExitMwait(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 298 HMVMX_EXIT_DECL hmR0VmxExitMtf(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 299 HMVMX_EXIT_DECL hmR0VmxExitMonitor(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 300 HMVMX_EXIT_DECL hmR0VmxExitPause(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 301 HMVMX_EXIT_DECL hmR0VmxExitErrMachineCheck(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 302 HMVMX_EXIT_DECL hmR0VmxExitTprBelowThreshold(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 303 HMVMX_EXIT_DECL hmR0VmxExitApicAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 304 HMVMX_EXIT_DECL hmR0VmxExitXdtrAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 305 HMVMX_EXIT_DECL hmR0VmxExitXdtrAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 306 HMVMX_EXIT_DECL hmR0VmxExitEptViolation(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 307 HMVMX_EXIT_DECL hmR0VmxExitEptMisconfig(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 308 HMVMX_EXIT_DECL hmR0VmxExitRdtscp(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 309 HMVMX_EXIT_DECL hmR0VmxExitPreemptTimer(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 310 HMVMX_EXIT_DECL hmR0VmxExitWbinvd(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 311 HMVMX_EXIT_DECL hmR0VmxExitXsetbv(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 312 HMVMX_EXIT_DECL hmR0VmxExitRdrand(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 313 HMVMX_EXIT_DECL hmR0VmxExitInvpcid(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 307 /** @name VM-exit handlers. 308 * @{ 309 */ 310 static FNVMEXITHANDLER hmR0VmxExitXcptOrNmi; 311 static FNVMEXITHANDLER hmR0VmxExitExtInt; 312 static FNVMEXITHANDLER hmR0VmxExitTripleFault; 313 static FNVMEXITHANDLER hmR0VmxExitInitSignal; 314 static FNVMEXITHANDLER hmR0VmxExitSipi; 315 static FNVMEXITHANDLER hmR0VmxExitIoSmi; 316 static FNVMEXITHANDLER hmR0VmxExitSmi; 317 static FNVMEXITHANDLER hmR0VmxExitIntWindow; 318 static FNVMEXITHANDLER hmR0VmxExitNmiWindow; 319 static FNVMEXITHANDLER hmR0VmxExitTaskSwitch; 320 static FNVMEXITHANDLER hmR0VmxExitCpuid; 321 static FNVMEXITHANDLER hmR0VmxExitGetsec; 322 static FNVMEXITHANDLER hmR0VmxExitHlt; 323 static FNVMEXITHANDLER hmR0VmxExitInvd; 324 static FNVMEXITHANDLER hmR0VmxExitInvlpg; 325 static FNVMEXITHANDLER hmR0VmxExitRdpmc; 326 static FNVMEXITHANDLER hmR0VmxExitRdtsc; 327 static FNVMEXITHANDLER hmR0VmxExitRsm; 328 static FNVMEXITHANDLER hmR0VmxExitSetPendingXcptUD; 329 static FNVMEXITHANDLER hmR0VmxExitMovCRx; 330 static FNVMEXITHANDLER hmR0VmxExitMovDRx; 331 static FNVMEXITHANDLER hmR0VmxExitIoInstr; 332 static FNVMEXITHANDLER hmR0VmxExitRdmsr; 333 static FNVMEXITHANDLER hmR0VmxExitWrmsr; 334 static FNVMEXITHANDLER hmR0VmxExitErrInvalidGuestState; 335 static FNVMEXITHANDLER hmR0VmxExitErrMsrLoad; 336 static FNVMEXITHANDLER hmR0VmxExitErrUndefined; 337 static FNVMEXITHANDLER hmR0VmxExitMwait; 338 static FNVMEXITHANDLER hmR0VmxExitMtf; 339 static FNVMEXITHANDLER hmR0VmxExitMonitor; 340 static FNVMEXITHANDLER hmR0VmxExitPause; 341 static FNVMEXITHANDLER hmR0VmxExitErrMachineCheck; 342 static FNVMEXITHANDLER hmR0VmxExitTprBelowThreshold; 343 static FNVMEXITHANDLER hmR0VmxExitApicAccess; 344 static FNVMEXITHANDLER hmR0VmxExitXdtrAccess; 345 static FNVMEXITHANDLER hmR0VmxExitXdtrAccess; 346 static FNVMEXITHANDLER hmR0VmxExitEptViolation; 347 static FNVMEXITHANDLER hmR0VmxExitEptMisconfig; 348 static FNVMEXITHANDLER hmR0VmxExitRdtscp; 349 static FNVMEXITHANDLER hmR0VmxExitPreemptTimer; 350 static FNVMEXITHANDLER hmR0VmxExitWbinvd; 351 static FNVMEXITHANDLER hmR0VmxExitXsetbv; 352 static FNVMEXITHANDLER hmR0VmxExitRdrand; 353 static FNVMEXITHANDLER hmR0VmxExitInvpcid; 354 /** @} */ 314 355 315 356 static int hmR0VmxExitXcptNM(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); … … 326 367 *******************************************************************************/ 327 368 #ifdef HMVMX_USE_FUNCTION_TABLE 328 /**329 * VM-exit handler.330 *331 * @returns VBox status code.332 * @param pVCpu Pointer to the VMCPU.333 * @param pMixedCtx Pointer to the guest-CPU context. The data may be334 * out-of-sync. Make sure to update the required335 * fields before using them.336 * @param pVmxTransient Pointer to the VMX-transient structure.337 */338 typedef DECLCALLBACK(int) FNVMEXITHANDLER(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);339 /** Pointer to VM-exit handler. */340 typedef FNVMEXITHANDLER *const PFNVMEXITHANDLER;341 369 342 370 /** … … 582 610 583 611 /** 612 * Reads the VM-exit instruction-information field from the VMCS into 613 * the VMX transient structure. 614 * 615 * @returns VBox status code. 616 * @param pVCpu The cross context per CPU structure. 617 * @param pVmxTransient Pointer to the VMX transient structure. 618 */ 619 DECLINLINE(int) hmR0VmxReadExitInstrInfoVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 620 { 621 if (!(pVmxTransient->fVmcsFieldsRead & HMVMX_UPDATED_TRANSIENT_EXIT_INSTR_LEN)) 622 { 623 int rc = VMXReadVmcs32(VMX_VMCS32_RO_EXIT_INSTR_INFO, &pVmxTransient->cbInstr); 624 AssertRCReturn(rc, rc); 625 pVmxTransient->fVmcsFieldsRead |= HMVMX_UPDATED_TRANSIENT_EXIT_INSTR_LEN; 626 } 627 return VINF_SUCCESS; 628 } 629 630 631 /** 584 632 * Reads the exit qualification from the VMCS into the VMX transient structure. 585 633 * … … 5717 5765 Assert(VMMRZCallRing3IsEnabled(pVCpu)); 5718 5766 5719 int rc = VERR_INTERNAL_ERROR_5;5720 5767 if ( VM_FF_IS_PENDING(pVM, VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA) 5721 5768 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL … … 5723 5770 { 5724 5771 /* We need the control registers now, make sure the guest-CPU context is updated. */ 5725 rc= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);5726 AssertRCReturn(rc , rc);5772 int rc2 = hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx); 5773 AssertRCReturn(rc2, rc2); 5727 5774 5728 5775 /* Pending HM CR3 sync. */ 5729 5776 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3)) 5730 5777 { 5731 rc = PGMUpdateCR3(pVCpu, pMixedCtx->cr3); 5732 Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3); 5778 int rc2 = PGMUpdateCR3(pVCpu, pMixedCtx->cr3); 5779 AssertMsgReturn(rc2 == VINF_SUCCESS || rc2 == VINF_PGM_SYNC_CR3, 5780 ("%Rrc\n", rc2), RT_FAILURE_NP(rc2) ? rc2 : VERR_IPE_UNEXPECTED_INFO_STATUS); 5733 5781 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3)); 5734 5782 } … … 5737 5785 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)) 5738 5786 { 5739 rc = PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]); 5740 AssertRC(rc); 5787 PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]); 5741 5788 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)); 5742 5789 } … … 5745 5792 if (VMCPU_FF_IS_PENDING(pVCpu,VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL)) 5746 5793 { 5747 rc= PGMSyncCR3(pVCpu, pMixedCtx->cr0, pMixedCtx->cr3, pMixedCtx->cr4, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));5748 if (rc != VINF_SUCCESS)5794 int rc2 = PGMSyncCR3(pVCpu, pMixedCtx->cr0, pMixedCtx->cr3, pMixedCtx->cr4, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3)); 5795 if (rc2 != VINF_SUCCESS) 5749 5796 { 5750 AssertRC(rc );5751 Log4(("hmR0VmxCheckForceFlags: PGMSyncCR3 forcing us back to ring-3. rc =%d\n", rc));5752 return rc ;5797 AssertRC(rc2); 5798 Log4(("hmR0VmxCheckForceFlags: PGMSyncCR3 forcing us back to ring-3. rc2=%d\n", rc2)); 5799 return rc2; 5753 5800 } 5754 5801 } … … 5760 5807 { 5761 5808 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchHmToR3FF); 5762 rc= RT_UNLIKELY(VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;5763 Log4(("hmR0VmxCheckForceFlags: HM_TO_R3 forcing us back to ring-3. rc=%d\n", rc ));5764 return rc ;5809 int rc2 = RT_UNLIKELY(VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3; 5810 Log4(("hmR0VmxCheckForceFlags: HM_TO_R3 forcing us back to ring-3. rc=%d\n", rc2)); 5811 return rc2; 5765 5812 } 5766 5813 … … 5789 5836 5790 5837 /* Paranoia. */ 5791 Assert(rc != VERR_EM_INTERPRETER);5792 5838 return VINF_SUCCESS; 5793 5839 } … … 7205 7251 case VMX_EXIT_RDTSCP: rc = hmR0VmxExitRdtscp(pVCpu, pMixedCtx, pVmxTransient); break; 7206 7252 case VMX_EXIT_APIC_ACCESS: rc = hmR0VmxExitApicAccess(pVCpu, pMixedCtx, pVmxTransient); break; 7207 case VMX_EXIT_XCPT_ NMI:rc = hmR0VmxExitXcptOrNmi(pVCpu, pMixedCtx, pVmxTransient); break;7253 case VMX_EXIT_XCPT_OR_NMI: rc = hmR0VmxExitXcptOrNmi(pVCpu, pMixedCtx, pVmxTransient); break; 7208 7254 case VMX_EXIT_MOV_CRX: rc = hmR0VmxExitMovCRx(pVCpu, pMixedCtx, pVmxTransient); break; 7209 7255 case VMX_EXIT_EXT_INT: rc = hmR0VmxExitExtInt(pVCpu, pMixedCtx, pVmxTransient); break; … … 8334 8380 bool fIOWrite = ( VMX_EXIT_QUALIFICATION_IO_DIRECTION(pVmxTransient->uExitQualification) 8335 8381 == VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT); 8336 bool fIOString = (VMX_EXIT_QUALIFICATION_IO_STRING(pVmxTransient->uExitQualification) == 1);8337 AssertReturn(uIOWidth <= 3 && uIOWidth != 2, VERR_HM _IPE_3);8382 bool fIOString = VMX_EXIT_QUALIFICATION_IO_IS_STRING(pVmxTransient->uExitQualification); 8383 AssertReturn(uIOWidth <= 3 && uIOWidth != 2, VERR_HMVMX_IPE_1); 8338 8384 8339 8385 /* I/O operation lookup arrays. */ … … 8343 8389 const uint32_t cbValue = s_aIOSizes[uIOWidth]; 8344 8390 const uint32_t cbInstr = pVmxTransient->cbInstr; 8391 bool fUpdateRipAlready = false; /* ugly hack, should be temporary. */ 8345 8392 PVM pVM = pVCpu->CTX_SUFF(pVM); 8346 8393 if (fIOString) 8347 8394 { 8348 /* INS/OUTS - I/O String instruction. */ 8349 /** @todo for now manually disassemble later optimize by getting the fields from 8350 * the VMCS. VMX_VMCS_RO_EXIT_GUEST_LINEAR_ADDR contains the flat pointer 8351 * operand of the instruction. VMX_VMCS32_RO_EXIT_INSTR_INFO contains 8352 * segment prefix info. 8353 * bird: The linear address isn't worth more than a few ticks, esp. for 8354 * 32-bit guests where we'd have to do limit checks. Main point, 8355 * though, is that AMD doesn't have it. They both have segment reg, 8356 * address mode (size) and operand size. Though, Intel didn't have the 8357 * segment+addrsize on the early models (Footnote 3 on table 27-8, volume 8358 * 3, July 2013 edition). */ 8395 /* 8396 * INS/OUTS - I/O String instruction. 8397 * 8398 * Use instruction-information if available, otherwise fall back on 8399 * interpreting the instruction. 8400 */ 8401 #if 0 /* Not quite ready, seem iSegReg assertion trigger once... Do we perhaps need to always read that in longjmp / preempt scenario? */ 8402 AssertReturn(pMixedCtx->dx == uIOPort, VERR_HMVMX_IPE_2); 8403 if (MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(pVM->hm.s.vmx.msr.vmx_basic_info)) 8404 { 8405 rc = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient); 8406 /** @todo optimize this, IEM should request the additional state if it needs it (GP, PF, ++). */ 8407 rc |= hmR0VmxSaveGuestState(pVCpu, pMixedCtx); 8408 AssertRCReturn(rc, rc); 8409 AssertReturn(pVmxTransient->ExitInstrInfo.StrIo.u3AddrSize <= 2, VERR_HMVMX_IPE_3); 8410 AssertCompile(IEMMODE_16BIT == 0 && IEMMODE_32BIT == 1 && IEMMODE_64BIT == 2); 8411 IEMMODE enmAddrMode = (IEMMODE)pVmxTransient->ExitInstrInfo.StrIo.u3AddrSize; 8412 bool fRep = VMX_EXIT_QUALIFICATION_IO_IS_REP(pVmxTransient->uExitQualification); 8413 if (fIOWrite) 8414 { 8415 rc = IEMExecStringIoWrite(pVCpu, cbValue, enmAddrMode, fRep, cbInstr, 8416 pVmxTransient->ExitInstrInfo.StrIo.iSegReg); 8417 //if (rc == VINF_IOM_R3_IOPORT_WRITE) 8418 // hmR0SavePendingIOPortWriteStr(pVCpu, pMixedCtx->rip, cbValue, enmAddrMode, fRep, cbInstr, 8419 // pVmxTransient->ExitInstrInfo.StrIo.iSegReg); 8420 } 8421 else 8422 { 8423 AssertMsgReturn(pVmxTransient->ExitInstrInfo.StrIo.iSegReg == X86_SREG_ES, 8424 ("%#x (%#llx)\n", pVmxTransient->ExitInstrInfo.StrIo.iSegReg, pVmxTransient->ExitInstrInfo.u), 8425 VERR_HMVMX_IPE_4); 8426 rc = IEMExecStringIoRead(pVCpu, cbValue, enmAddrMode, fRep, cbInstr); 8427 //if (rc == VINF_IOM_R3_IOPORT_READ) 8428 // hmR0SavePendingIOPortReadStr(pVCpu, pMixedCtx->rip, cbValue, enmAddrMode, fRep, cbInstr); 8429 } 8430 } 8431 else 8432 { 8433 /** @todo optimize this, IEM should request the additional state if it needs it (GP, PF, ++). */ 8434 rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx); 8435 AssertRCReturn(rc, rc); 8436 rc = IEMExecOne(pVCpu); 8437 } 8438 /** @todo IEM needs to be setting these flags somehow. */ 8439 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RIP; 8440 fUpdateRipAlready = true; 8441 8442 #else 8359 8443 PDISCPUSTATE pDis = &pVCpu->hm.s.DisState; 8360 8444 rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL); … … 8381 8465 rc = VINF_EM_RAW_EMULATE_INSTR; 8382 8466 } 8467 #endif 8383 8468 } 8384 8469 else 8385 8470 { 8386 /* IN/OUT - I/O instruction. */ 8471 /* 8472 * IN/OUT - I/O instruction. 8473 */ 8387 8474 const uint32_t uAndVal = s_aIOOpAnd[uIOWidth]; 8388 Assert(!VMX_EXIT_QUALIFICATION_IO_ REP(pVmxTransient->uExitQualification));8475 Assert(!VMX_EXIT_QUALIFICATION_IO_IS_REP(pVmxTransient->uExitQualification)); 8389 8476 if (fIOWrite) 8390 8477 { … … 8413 8500 if (IOM_SUCCESS(rc)) 8414 8501 { 8415 pMixedCtx->rip += cbInstr; 8416 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RIP; 8502 if (!fUpdateRipAlready) 8503 { 8504 pMixedCtx->rip += cbInstr; 8505 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RIP; 8506 } 8417 8507 if (RT_LIKELY(rc == VINF_SUCCESS)) 8418 8508 { … … 8422 8512 * Note that the I/O breakpoint type is undefined if CR4.DE is 0. 8423 8513 */ 8514 /** @todo We're not honoring I/O BPs if informational status code is returned. 8515 * We're also ignoring our own debugger's attempt at using I/O 8516 * breakpoints. The whole host & guest debugger stuff needs to be 8517 * looked over at some point. For now, it's just best effort. */ 8424 8518 rc = hmR0VmxSaveGuestDebugRegs(pVCpu, pMixedCtx); /* For DR7. */ 8425 8519 AssertRCReturn(rc, rc); -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r47123 r47444 1613 1613 rc = VMXReadVmcs64(VMX_VMCS64_GUEST_PDPTE3_FULL, &aPdpes[3].u); AssertRCReturn(rc, rc); 1614 1614 1615 rc =PGMGstUpdatePaePdpes(pVCpu, &aPdpes[0]);1615 PGMGstUpdatePaePdpes(pVCpu, &aPdpes[0]); 1616 1616 AssertRCReturn(rc, rc); 1617 1617 } … … 4598 4598 4599 4599 uint32_t cbSize = g_aIOSize[uIOWidth]; 4600 if (VMX_EXIT_QUALIFICATION_IO_ STRING(exitQualification))4600 if (VMX_EXIT_QUALIFICATION_IO_IS_STRING(exitQualification)) 4601 4601 { 4602 4602 /* ins/outs */ -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r47425 r47444 1499 1499 AssertPtr(pPdpes); 1500 1500 1501 int rc2 = PGMGstUpdatePaePdpes(pVCpu, pPdpes); 1502 if (RT_FAILURE(rc2)) 1503 return rc2; 1501 PGMGstUpdatePaePdpes(pVCpu, pPdpes); 1504 1502 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)); 1505 1503 } -
trunk/src/VBox/VMM/VMMR3/HM.cpp
r47202 r47444 980 980 LogRel(("HM: VMCS memory type = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(pVM->hm.s.vmx.msr.vmx_basic_info))); 981 981 LogRel(("HM: Dual-monitor treatment = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(pVM->hm.s.vmx.msr.vmx_basic_info))); 982 LogRel(("HM: OUTS & INS instruction-info = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(pVM->hm.s.vmx.msr.vmx_basic_info))); 982 983 LogRel(("HM: Max resume loops = %RX32\n", pVM->hm.s.cMaxResumeLoops)); 983 984 -
trunk/src/VBox/VMM/include/IEMInternal.h
r47413 r47444 19 19 #define ___IEMInternal_h 20 20 21 #include <VBox/vmm/cpum.h> 22 #include <VBox/vmm/iem.h> 21 23 #include <VBox/vmm/stam.h> 22 #include <VBox/vmm/cpum.h>23 24 #include <VBox/param.h> 24 25 … … 50 51 typedef RTFLOAT32U const *PCRTFLOAT32U; 51 52 52 53 /**54 * Operand or addressing mode.55 */56 typedef enum IEMMODE57 {58 IEMMODE_16BIT = 0,59 IEMMODE_32BIT,60 IEMMODE_64BIT61 } IEMMODE;62 AssertCompileSize(IEMMODE, 4);63 53 64 54 /**
Note:
See TracChangeset
for help on using the changeset viewer.