- Timestamp:
- Oct 8, 2018 9:46:26 AM (6 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r74603 r74661 14968 14968 * @param cbInstr The instruction length in bytes. 14969 14969 * @param u16Port The port to read. 14970 * @param fImm Whether the port is specified using an immediate operand or 14971 * using the implicit DX register. 14970 14972 * @param cbReg The register size. 14971 14973 * 14972 14974 * @remarks In ring-0 not all of the state needs to be synced in. 14973 14975 */ 14974 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedOut(PVMCPU pVCpu, uint8_t cbInstr, uint16_t u16Port, uint8_t cbReg)14976 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedOut(PVMCPU pVCpu, uint8_t cbInstr, uint16_t u16Port, bool fImm, uint8_t cbReg) 14975 14977 { 14976 14978 IEMEXEC_ASSERT_INSTR_LEN_RETURN(cbInstr, 1); … … 14978 14980 14979 14981 iemInitExec(pVCpu, false /*fBypassHandlers*/); 14980 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_ 2(iemCImpl_out, u16Port, cbReg);14982 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_3(iemCImpl_out, u16Port, fImm, cbReg); 14981 14983 Assert(!pVCpu->iem.s.cActiveMappings); 14982 14984 return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict); … … 14991 14993 * @param cbInstr The instruction length in bytes. 14992 14994 * @param u16Port The port to read. 14995 * @param fImm Whether the port is specified using an immediate operand or 14996 * using the implicit DX. 14993 14997 * @param cbReg The register size. 14994 14998 */ 14995 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedIn(PVMCPU pVCpu, uint8_t cbInstr, uint16_t u16Port, uint8_t cbReg)14999 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedIn(PVMCPU pVCpu, uint8_t cbInstr, uint16_t u16Port, bool fImm, uint8_t cbReg) 14996 15000 { 14997 15001 IEMEXEC_ASSERT_INSTR_LEN_RETURN(cbInstr, 1); … … 14999 15003 15000 15004 iemInitExec(pVCpu, false /*fBypassHandlers*/); 15001 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_ 2(iemCImpl_in, u16Port, cbReg);15005 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_3(iemCImpl_in, u16Port, fImm, cbReg); 15002 15006 Assert(!pVCpu->iem.s.cActiveMappings); 15003 15007 return iemUninitExecAndFiddleStatusAndMaybeReenter(pVCpu, rcStrict); -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r74659 r74661 6677 6677 * 6678 6678 * @param u16Port The source port. 6679 * @param fImm Whether the port was specified through an immediate operand 6680 * or the implicit DX register. 6679 6681 * @param cbReg The register size. 6680 6682 */ 6681 IEM_CIMPL_DEF_ 2(iemCImpl_in, uint16_t, u16Port, uint8_t, cbReg)6683 IEM_CIMPL_DEF_3(iemCImpl_in, uint16_t, u16Port, bool, fImm, uint8_t, cbReg) 6682 6684 { 6683 6685 /* … … 6687 6689 if (rcStrict != VINF_SUCCESS) 6688 6690 return rcStrict; 6691 6692 /* 6693 * Check VMX nested-guest IO intercept. 6694 */ 6695 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 6696 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 6697 { 6698 rcStrict = iemVmxVmexitInstrIo(pVCpu, VMXINSTRID_IO_IN, u16Port, fImm, cbReg, cbInstr); 6699 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 6700 return rcStrict; 6701 } 6702 #else 6703 RT_NOREF(fImm); 6704 #endif 6689 6705 6690 6706 /* … … 6762 6778 IEM_CIMPL_DEF_1(iemCImpl_in_eAX_DX, uint8_t, cbReg) 6763 6779 { 6764 return IEM_CIMPL_CALL_ 2(iemCImpl_in, pVCpu->cpum.GstCtx.dx, cbReg);6780 return IEM_CIMPL_CALL_3(iemCImpl_in, pVCpu->cpum.GstCtx.dx, false /* fImm */, cbReg); 6765 6781 } 6766 6782 … … 6770 6786 * 6771 6787 * @param u16Port The destination port. 6788 * @param fImm Whether the port was specified through an immediate operand 6789 * or the implicit DX register. 6772 6790 * @param cbReg The register size. 6773 6791 */ 6774 IEM_CIMPL_DEF_ 2(iemCImpl_out, uint16_t, u16Port, uint8_t, cbReg)6792 IEM_CIMPL_DEF_3(iemCImpl_out, uint16_t, u16Port, bool, fImm, uint8_t, cbReg) 6775 6793 { 6776 6794 /* … … 6782 6800 6783 6801 /* 6784 * Check SVM nested-guest IO intercept. 6802 * Check VMX nested-guest I/O intercept. 6803 */ 6804 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 6805 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 6806 { 6807 rcStrict = iemVmxVmexitInstrIo(pVCpu, VMXINSTRID_IO_OUT, u16Port, fImm, cbReg, cbInstr); 6808 if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE) 6809 return rcStrict; 6810 } 6811 #else 6812 RT_NOREF(fImm); 6813 #endif 6814 6815 /* 6816 * Check SVM nested-guest I/O intercept. 6785 6817 */ 6786 6818 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM … … 6854 6886 IEM_CIMPL_DEF_1(iemCImpl_out_DX_eAX, uint8_t, cbReg) 6855 6887 { 6856 return IEM_CIMPL_CALL_ 2(iemCImpl_out, pVCpu->cpum.GstCtx.dx, cbReg);6888 return IEM_CIMPL_CALL_3(iemCImpl_out, pVCpu->cpum.GstCtx.dx, false /* fImm */, cbReg); 6857 6889 } 6858 6890 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74660 r74661 2866 2866 * @returns @c true if the instruction is intercepted, @c false otherwise. 2867 2867 * @param pVCpu The cross context virtual CPU structure. 2868 * @param u PortThe I/O port being accessed by the instruction.2869 */ 2870 IEM_STATIC bool iemVmxIsIoInterceptSet(PVMCPU pVCpu, uint16_t u Port)2868 * @param u16Port The I/O port being accessed by the instruction. 2869 */ 2870 IEM_STATIC bool iemVmxIsIoInterceptSet(PVMCPU pVCpu, uint16_t u16Port) 2871 2871 { 2872 2872 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); … … 2874 2874 2875 2875 /* 2876 * Check whether the I O instruction must cause a VM-exit or not.2876 * Check whether the I/O instruction must cause a VM-exit or not. 2877 2877 * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally". 2878 2878 */ … … 2886 2886 Assert(pbIoBitmapA); 2887 2887 Assert(pbIoBitmapB); 2888 return HMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u Port);2888 return HMVmxGetIoBitmapPermission(pbIoBitmapA, pbIoBitmapB, u16Port); 2889 2889 } 2890 2890 … … 3285 3285 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_ACCESS, VMX_EXIT_QUAL_CRX_ACCESS_WRITE) 3286 3286 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_CRX_GENREG, iGReg); 3287 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3288 } 3289 3290 return VINF_VMX_INTERCEPT_NOT_ACTIVE; 3291 } 3292 3293 3294 /** 3295 * VMX VM-exit handler for VM-exits due to I/O instructions (IN and OUT). 3296 * 3297 * @returns VBox strict status code. 3298 * @param pVCpu The cross context virtual CPU structure. 3299 * @param uInstrId The VM-exit instruction identity (VMXINSTRID_IO_IN or 3300 * VMXINSTRID_IO_OUT). 3301 * @param u16Port The I/O port being accessed. 3302 * @param fImm Whether the I/O port was encoded using an immediate operand 3303 * or the implicit DX register. 3304 * @param cbAccess The size of the I/O access in bytes (1, 2 or 4 bytes). 3305 * @param cbInstr The instruction length in bytes. 3306 */ 3307 IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrIo(PVMCPU pVCpu, VMXINSTRID uInstrId, uint16_t u16Port, bool fImm, uint8_t cbAccess, 3308 uint8_t cbInstr) 3309 { 3310 Assert(uInstrId == VMXINSTRID_IO_IN || uInstrId == VMXINSTRID_IO_OUT); 3311 Assert(cbAccess == 1 || cbAccess == 2 || cbAccess == 4); 3312 3313 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 3314 Assert(pVmcs); 3315 3316 bool const fIntercept = iemVmxIsIoInterceptSet(pVCpu, u16Port); 3317 if (fIntercept) 3318 { 3319 uint32_t const uDirection = uInstrId == VMXINSTRID_IO_IN ? VMX_EXIT_QUAL_IO_DIRECTION_IN 3320 : VMX_EXIT_QUAL_IO_DIRECTION_OUT; 3321 VMXVEXITINFO ExitInfo; 3322 RT_ZERO(ExitInfo); 3323 ExitInfo.uReason = VMX_EXIT_MOV_CRX; 3324 ExitInfo.cbInstr = cbInstr; 3325 ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_WIDTH, cbAccess - 1) 3326 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_DIRECTION, uDirection) 3327 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_ENCODING, fImm) 3328 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_PORT, u16Port); 3287 3329 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3288 3330 } … … 4727 4769 IEM_VMX_VMENTRY_FAILED_RET(pVCpu, pszInstr, pszFailure, kVmxVDiag_Vmentry_Cr3TargetCount); 4728 4770 4729 /* I O bitmaps physical addresses. */4771 /* I/O bitmaps physical addresses. */ 4730 4772 if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_USE_IO_BITMAPS) 4731 4773 { -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsOneByte.cpp.h
r74490 r74661 10399 10399 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); 10400 10400 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10401 return IEM_MC_DEFER_TO_CIMPL_ 2(iemCImpl_in, u8Imm, 1);10401 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_in, u8Imm, true /* fImm */, 1); 10402 10402 } 10403 10403 … … 10409 10409 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); 10410 10410 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10411 return IEM_MC_DEFER_TO_CIMPL_ 2(iemCImpl_in, u8Imm, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4);10411 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_in, u8Imm, true /* fImm */, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4); 10412 10412 } 10413 10413 … … 10419 10419 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); 10420 10420 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10421 return IEM_MC_DEFER_TO_CIMPL_ 2(iemCImpl_out, u8Imm, 1);10421 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_out, u8Imm, true /* fImm */, 1); 10422 10422 } 10423 10423 … … 10429 10429 uint8_t u8Imm; IEM_OPCODE_GET_NEXT_U8(&u8Imm); 10430 10430 IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX(); 10431 return IEM_MC_DEFER_TO_CIMPL_ 2(iemCImpl_out, u8Imm, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4);10431 return IEM_MC_DEFER_TO_CIMPL_3(iemCImpl_out, u8Imm, true /* fImm */, pVCpu->iem.s.enmEffOpSize == IEMMODE_16BIT ? 2 : 4); 10432 10432 } 10433 10433 -
trunk/src/VBox/VMM/VMMRC/IOMRC.cpp
r72655 r74661 84 84 STAM_COUNTER_INC(&pVM->iom.s.StatInstIn); RT_NOREF_PV(pVM); 85 85 Assert(pCpu->Param2.fUse & (DISUSE_IMMEDIATE8 | DISUSE_REG_GEN16)); 86 uint16_t u16Port = pCpu->Param2.fUse & DISUSE_REG_GEN16 ? pRegFrame->dx : (uint16_t)pCpu->Param2.uValue; 86 bool const fUseReg = RT_BOOL(pCpu->Param2.fUse & DISUSE_REG_GEN16); 87 uint16_t const u16Port = fUseReg ? pRegFrame->dx : (uint16_t)pCpu->Param2.uValue; 87 88 88 89 Assert(pCpu->Param1.fUse & (DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8)); 89 90 uint8_t cbValue = pCpu->Param1.fUse & DISUSE_REG_GEN32 ? 4 : pCpu->Param1.fUse & DISUSE_REG_GEN16 ? 2 : 1; 90 91 91 return IEMExecDecodedIn(pVCpu, pCpu->cbInstr, u16Port, cbValue);92 return IEMExecDecodedIn(pVCpu, pCpu->cbInstr, u16Port, !fUseReg, cbValue); 92 93 } 93 94 … … 116 117 STAM_COUNTER_INC(&pVM->iom.s.StatInstOut); RT_NOREF_PV(pVM); 117 118 Assert(pCpu->Param1.fUse & (DISUSE_IMMEDIATE8 | DISUSE_REG_GEN16)); 118 uint16_t const u16Port = pCpu->Param1.fUse & DISUSE_REG_GEN16 ? pRegFrame->dx : (uint16_t)pCpu->Param1.uValue; 119 bool const fUseReg = RT_BOOL(pCpu->Param1.fUse & DISUSE_REG_GEN16); 120 uint16_t const u16Port = fUseReg ? pRegFrame->dx : (uint16_t)pCpu->Param1.uValue; 119 121 120 122 Assert(pCpu->Param2.fUse & (DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8)); 121 123 uint8_t const cbValue = pCpu->Param2.fUse & DISUSE_REG_GEN32 ? 4 : pCpu->Param2.fUse & DISUSE_REG_GEN16 ? 2 : 1; 122 124 123 return IEMExecDecodedOut(pVCpu, pCpu->cbInstr, u16Port, cbValue);125 return IEMExecDecodedOut(pVCpu, pCpu->cbInstr, u16Port, !fUseReg, cbValue); 124 126 } 125 127
Note:
See TracChangeset
for help on using the changeset viewer.