Changeset 60874 in vbox for trunk/src/VBox/VMM/VMMRC
- Timestamp:
- May 7, 2016 5:55:21 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 107086
- Location:
- trunk/src/VBox/VMM/VMMRC
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMRC/IOMRC.cpp
r60847 r60874 43 43 44 44 45 #ifdef VBOX_WITH_3RD_IEM_STEP46 45 /** 47 46 * Converts disassembler mode to IEM mode. … … 61 60 } 62 61 } 63 #endif64 65 62 66 63 … … 85 82 static VBOXSTRICTRC iomRCInterpretIN(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu) 86 83 { 87 #ifdef IN_RC88 84 STAM_COUNTER_INC(&pVM->iom.s.StatInstIn); 89 #endif 90 91 /* 92 * Get port number from second parameter. 93 * And get the register size from the first parameter. 94 */ 95 uint64_t uPort = 0; 96 unsigned cbSize = 0; 97 bool fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &uPort, &cbSize); 98 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc); 99 100 cbSize = DISGetParamSize(pCpu, &pCpu->Param1); 101 Assert(cbSize > 0); 102 VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize); 103 if (rcStrict == VINF_SUCCESS) 104 { 105 /* 106 * Attempt to read the port. 107 */ 108 uint32_t u32Data = UINT32_C(0xffffffff); 109 rcStrict = IOMIOPortRead(pVM, pVCpu, uPort, &u32Data, cbSize); 110 if (IOM_SUCCESS(rcStrict)) 111 { 112 /* 113 * Store the result in the AL|AX|EAX register. 114 */ 115 fRc = iomSaveDataToReg(pCpu, &pCpu->Param1, pRegFrame, u32Data); 116 AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc); 117 } 118 else 119 AssertMsg(rcStrict == VINF_IOM_R3_IOPORT_READ || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 120 } 121 else 122 AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 123 124 return rcStrict; 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; 87 88 Assert(pCpu->Param1.fUse & (DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8)); 89 uint8_t cbValue = pCpu->Param1.fUse & DISUSE_REG_GEN32 ? 4 : pCpu->Param1.fUse & DISUSE_REG_GEN16 ? 2 : 1; 90 91 return IEMExecDecodedIn(pVCpu, pCpu->cbInstr, u16Port, cbValue); 125 92 } 126 93 … … 147 114 static VBOXSTRICTRC iomRCInterpretOUT(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu) 148 115 { 149 #ifdef IN_RC150 116 STAM_COUNTER_INC(&pVM->iom.s.StatInstOut); 151 #endif 152 153 /* 154 * Get port number from first parameter. 155 * And get the register size and value from the second parameter. 156 */ 157 uint64_t uPort = 0; 158 unsigned cbSize = 0; 159 bool fRc = iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &uPort, &cbSize); 160 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc); 161 162 VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize); 163 if (rcStrict == VINF_SUCCESS) 164 { 165 uint64_t u64Data = 0; 166 fRc = iomGetRegImmData(pCpu, &pCpu->Param2, pRegFrame, &u64Data, &cbSize); 167 AssertMsg(fRc, ("Failed to get reg value!\n")); NOREF(fRc); 168 169 /* 170 * Attempt to write to the port. 171 */ 172 rcStrict = IOMIOPortWrite(pVM, pVCpu, uPort, u64Data, cbSize); 173 AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IOM_R3_IOPORT_WRITE || rcStrict == VINF_IOM_R3_IOPORT_COMMIT_WRITE 174 || (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST) || RT_FAILURE(rcStrict), 175 ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 176 } 177 else 178 AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 179 return rcStrict; 117 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 120 Assert(pCpu->Param2.fUse & (DISUSE_REG_GEN32 | DISUSE_REG_GEN16 | DISUSE_REG_GEN8)); 121 uint8_t const cbValue = pCpu->Param2.fUse & DISUSE_REG_GEN32 ? 4 : pCpu->Param2.fUse & DISUSE_REG_GEN16 ? 2 : 1; 122 123 return IEMExecDecodedOut(pVCpu, pCpu->cbInstr, u16Port, cbValue); 180 124 } 181 125 … … 203 147 static VBOXSTRICTRC iomRCInterpretINS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu) 204 148 { 205 #ifdef VBOX_WITH_3RD_IEM_STEP206 149 uint8_t cbValue = pCpu->pCurInstr->uOpcode == OP_INSB ? 1 207 150 : pCpu->uOpMode == DISCPUMODE_16BIT ? 2 : 4; /* dword in both 32 & 64 bits mode */ … … 210 153 iomDisModeToIemMode((DISCPUMODE)pCpu->uCpuMode), 211 154 RT_BOOL(pCpu->fPrefix & (DISPREFIX_REPNE | DISPREFIX_REP)), 212 pCpu->cbInstr); 213 #else 214 /* 215 * Get port number directly from the register (no need to bother the 216 * disassembler). And get the I/O register size from the opcode / prefix. 217 */ 218 RTIOPORT Port = pRegFrame->edx & 0xffff; 219 unsigned cb; 220 if (pCpu->pCurInstr->uOpcode == OP_INSB) 221 cb = 1; 222 else 223 cb = (pCpu->uOpMode == DISCPUMODE_16BIT) ? 2 : 4; /* dword in both 32 & 64 bits mode */ 224 225 VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, Port, cb); 226 if (RT_UNLIKELY(rcStrict != VINF_SUCCESS)) 227 { 228 AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 229 return rcStrict; 230 } 231 232 return IOMInterpretINSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb); 233 #endif 155 pCpu->cbInstr, 156 false /*fIoChecked*/); 234 157 } 235 158 … … 258 181 static VBOXSTRICTRC iomRCInterpretOUTS(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu) 259 182 { 260 #ifdef VBOX_WITH_3RD_IEM_STEP261 183 uint8_t cbValue = pCpu->pCurInstr->uOpcode == OP_OUTSB ? 1 262 184 : pCpu->uOpMode == DISCPUMODE_16BIT ? 2 : 4; /* dword in both 32 & 64 bits mode */ … … 266 188 RT_BOOL(pCpu->fPrefix & (DISPREFIX_REPNE | DISPREFIX_REP)), 267 189 pCpu->cbInstr, 268 pCpu->fPrefix & DISPREFIX_SEG ? pCpu->idxSegPrefix : X86_SREG_DS); 269 #else 270 /* 271 * Get port number from the first parameter. 272 * And get the I/O register size from the opcode / prefix. 273 */ 274 uint64_t Port = 0; 275 unsigned cb; 276 bool fRc = iomGetRegImmData(pCpu, &pCpu->Param1, pRegFrame, &Port, &cb); 277 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc); 278 if (pCpu->pCurInstr->uOpcode == OP_OUTSB) 279 cb = 1; 280 else 281 cb = (pCpu->uOpMode == DISCPUMODE_16BIT) ? 2 : 4; /* dword in both 32 & 64 bits mode */ 282 283 VBOXSTRICTRC rcStrict = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, Port, cb); 284 if (RT_UNLIKELY(rcStrict != VINF_SUCCESS)) 285 { 286 AssertMsg(rcStrict == VINF_EM_RAW_GUEST_TRAP || rcStrict == VINF_TRPM_XCPT_DISPATCHED || RT_FAILURE(rcStrict), ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 287 return rcStrict; 288 } 289 290 return IOMInterpretOUTSEx(pVM, pVCpu, pRegFrame, Port, pCpu->fPrefix, (DISCPUMODE)pCpu->uAddrMode, cb); 291 #endif 190 pCpu->fPrefix & DISPREFIX_SEG ? pCpu->idxSegPrefix : X86_SREG_DS, 191 false /*fIoChecked*/); 292 192 } 293 193 -
trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
r60847 r60874 1114 1114 { 1115 1115 VBOXSTRICTRC rcStrict = IOMRCIOPortHandler(pVM, pVCpu, pRegFrame, &Cpu); 1116 if (IOM_SUCCESS(rcStrict))1117 {1118 pRegFrame->rip += cbOp;1119 1120 /*1121 * Check for I/O breakpoints. A bit clumsy, but should be short lived (moved to IEM).1122 */1123 uint32_t const uDr7 = CPUMGetGuestDR7(pVCpu);1124 if (RT_UNLIKELY( ( (uDr7 & X86_DR7_ENABLED_MASK)1125 && X86_DR7_ANY_RW_IO(uDr7)1126 && (CPUMGetGuestCR4(pVCpu) & X86_CR4_DE))1127 || DBGFBpIsHwIoArmed(pVM)))1128 {1129 uint64_t uPort = pRegFrame->dx;1130 unsigned cbValue;1131 if ( Cpu.pCurInstr->uOpcode == OP_IN1132 || Cpu.pCurInstr->uOpcode == OP_INSB1133 || Cpu.pCurInstr->uOpcode == OP_INSWD)1134 {1135 cbValue = DISGetParamSize(&Cpu, &Cpu.Param1);1136 if (Cpu.Param2.fUse & DISUSE_IMMEDIATE)1137 uPort = Cpu.Param2.uValue;1138 }1139 else1140 {1141 cbValue = DISGetParamSize(&Cpu, &Cpu.Param2);1142 if (Cpu.Param1.fUse & DISUSE_IMMEDIATE)1143 uPort = Cpu.Param1.uValue;1144 }1145 1146 VBOXSTRICTRC rcStrict2 = DBGFBpCheckIo(pVM, pVCpu, CPUMCTX_FROM_CORE(pRegFrame), uPort, cbValue);1147 if (rcStrict2 == VINF_EM_RAW_GUEST_TRAP)1148 {1149 /* Raise #DB. */1150 TRPMResetTrap(pVCpu);1151 TRPMAssertTrap(pVCpu, X86_XCPT_DE, TRPM_TRAP);1152 if (rcStrict != VINF_SUCCESS)1153 LogRel(("trpmGCTrap0dHandler: Overriding %Rrc with #DB on I/O port access.\n", VBOXSTRICTRC_VAL(rcStrict)));1154 rcStrict = VINF_EM_RAW_GUEST_TRAP;1155 }1156 /* rcStrict is VINF_SUCCESS or in [VINF_EM_FIRST..VINF_EM_LAST]. */1157 else if ( rcStrict2 != VINF_SUCCESS1158 && (rcStrict == VINF_SUCCESS || rcStrict2 < rcStrict))1159 rcStrict = rcStrict2;1160 }1161 }1162 rc = VBOXSTRICTRC_TODO(rcStrict);1163 1116 TRPM_EXIT_DBG_HOOK(0xd); 1164 return trpmGCExitTrap(pVM, pVCpu, rc, pRegFrame);1117 return trpmGCExitTrap(pVM, pVCpu, VBOXSTRICTRC_TODO(rcStrict), pRegFrame); 1165 1118 } 1166 1119
Note:
See TracChangeset
for help on using the changeset viewer.