Changeset 104516 in vbox
- Timestamp:
- May 4, 2024 1:53:42 AM (9 months ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r104407 r104516 3272 3272 /** @} */ 3273 3273 3274 /** @name Guest Compatibility Manage Status Codes. 3275 * @{ 3276 */ 3277 /** The intercepted situation was completely handled, continue execution. */ 3278 #define VINF_GCM_HANDLED (7600) 3279 /** The intercepted instruction handled, advance RIP and continue execution. */ 3280 #define VINF_GCM_HANDLED_ADVANCE_RIP (7601) 3281 /** The intercepted operation was not handled, take default action. */ 3282 #define VERR_GCM_NOT_HANDLED (-7602) 3283 /** @} */ 3284 3274 3285 /* SED-END */ 3275 3286 -
trunk/include/VBox/vmm/cpum-common.h
r98970 r104516 124 124 } while (0) 125 125 126 /** @def CPUM_IMPORT_EXTRN_WITH_CTX_RET 127 * Macro for making sure the state specified by @a fExtrnImport is present, 128 * calling CPUMImportGuestStateOnDemand() to get it if necessary. 129 * 130 * Will return if CPUMImportGuestStateOnDemand() fails. 131 * 132 * @param a_pVCpu The cross context virtual CPU structure of the calling EMT. 133 * @param a_pCtx Pointer to the CPU context (CPUMCTX). 134 * @param a_fExtrnImport Mask of CPUMCTX_EXTRN_XXX bits to get. 135 * @thread EMT(a_pVCpu) 136 */ 137 #define CPUM_IMPORT_EXTRN_WITH_CTX_RET(a_pVCpu, a_pCtx, a_fExtrnImport) \ 138 do { \ 139 if (!((a_pCtx)->fExtrn & (a_fExtrnImport))) \ 140 { /* already present, consider this likely */ } \ 141 else \ 142 { \ 143 int rcCpumImport = CPUMImportGuestStateOnDemand(a_pVCpu, a_fExtrnImport); \ 144 AssertRCReturn(rcCpumImport, rcCpumImport); \ 145 } \ 146 } while (0) 147 126 148 VMM_INT_DECL(int) CPUMImportGuestStateOnDemand(PVMCPUCC pVCpu, uint64_t fExtrnImport); 127 149 /** @} */ -
trunk/include/VBox/vmm/gcm.h
r104511 r104516 61 61 VMM_INT_DECL(bool) GCMIsInterceptingXcptDE(PVMCPUCC pVCpu); 62 62 VMM_INT_DECL(int) GCMXcptDE(PVMCPUCC pVCpu, PCPUMCTX pCtx); 63 64 VMM_INT_DECL(bool) GCMIsInterceptingXcptGP(PVMCPUCC pVCpu); 65 VMM_INT_DECL(int) GCMXcptGP(PVMCPUCC pVCpu, PCPUMCTX pCtx); 66 67 VMM_INT_DECL(VBOXSTRICTRC) GCMInterceptedIOPortRead(PVMCPUCC pVCpu, PCPUMCTX pCtx, uint16_t u16Port, uint8_t cbReg); 68 VMM_INT_DECL(bool) GCMIsInterceptingIOPortReadSlow(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg); 69 70 /** 71 * Checks if the given IN instruction is intercepted. 72 */ 73 DECLINLINE(bool) GCMIsInterceptingIOPortRead(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg) 74 { 75 return u16Port == 0x5658 /* vmware hypervisor port */ 76 && cbReg == 4 77 && GCMIsInterceptingIOPortReadSlow(pVCpu, u16Port, cbReg); 78 } 79 80 #if 0 /* If we need to deal with high speed vmware hypervisor calls */ 81 VMM_INT_DECL(bool) GCMIsInterceptingIOPortReadStringSlow(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg); 82 VMM_INT_DECL(bool) GCMIsInterceptingIOPortWriteStringSlow(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg); 83 84 /** 85 * Checks if the given INS instruction is intercepted. 86 */ 87 DECLINLINE(bool) GCMIsInterceptingIOPortReadString(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg) 88 { 89 return u16Port == 0x5659 /* new vmware hypervisor port */ 90 && cbReg == 1 91 && GCMIsInterceptingIOPortReadStringSlow(pVCpu, u16Port, cbReg); 92 } 93 94 /** 95 * Checks if the given OUTS instruction is intercepted. 96 */ 97 DECLINLINE(bool) GCMIsInterceptingIOPortWriteString(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg) 98 { 99 return u16Port == 0x5659 /* new vmware hypervisor port */ 100 && cbReg == 1 101 && GCMIsInterceptingIOPortWriteStringSlow(pVCpu, u16Port, cbReg); 102 } 103 #endif 104 63 105 /** @} */ 64 106 -
trunk/src/VBox/Main/src-client/ConsoleImplConfigX86.cpp
r104507 r104516 1078 1078 if (fW9xGuest) 1079 1079 InsertConfigInteger(pGcmNode, "DivByZeroWin9x", 1); 1080 /* MesaVmsvgaDrv (formerly LovelyMesaDrvWorkaround) is set futher down. */ 1080 1081 1081 1082 /* … … 1407 1408 #ifdef VBOX_WITH_VMSVGA 1408 1409 case GraphicsControllerType_VMSVGA: 1409 InsertConfigInteger(pHM, "LovelyMesaDrvWorkaround", 1); /* hits someone else logging backdoor. */ 1410 InsertConfigInteger(pNEM, "LovelyMesaDrvWorkaround", 1); /* hits someone else logging backdoor. */ 1410 InsertConfigInteger(pHM, "LovelyMesaDrvWorkaround", 1); /* hits someone else's logging backdoor. */ 1411 InsertConfigInteger(pNEM, "LovelyMesaDrvWorkaround", 1); /* hits someone else's logging backdoor. */ 1412 InsertConfigInteger(pGcmNode, "MesaVmsvgaDrv", 1); /* hits someone else's logging backdoor. */ 1411 1413 RT_FALL_THROUGH(); 1412 1414 case GraphicsControllerType_VBoxSVGA: -
trunk/src/VBox/VMM/VMMAll/GCMAll.cpp
r104511 r104516 35 35 36 36 #include <VBox/dis.h> /* For DISSTATE */ 37 #include < iprt/errcore.h>37 #include <VBox/err.h> 38 38 #include <iprt/string.h> 39 40 41 /********************************************************************************************************************************* 42 * Defined Constants And Macros * 43 *********************************************************************************************************************************/ 44 #define VMWARE_HYPERVISOR_PORT UINT16_C(0x5658) 45 #define VMWARE_HYPERVISOR_PORT_HB UINT16_C(0x5659) 46 #define VMWARE_HYPERVISOR_MAGIC UINT32_C(0x564d5868) /**< eax value */ 47 48 #define VMWARE_HYPERVISOR_CMD_MSG 0x001e 49 #define VMWARE_HYPERVISOR_CMD_HB_MSG 0x0000 50 #define VMWARE_HYPERVISOR_CMD_OPEN_CHANNEL RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 0) /**< ecx */ 51 #define VMWARE_OC_RPCI_PROTOCOL_NUM UINT32_C(0x49435052) /**< VMWARE_HYPERVISOR_CMD_OPEN_CHANNEL: ebx[30:0] */ 52 #define VMWARE_OC_GUESTMSG_FLAG_COOKIE UINT32_C(0x80000000) /**< VMWARE_HYPERVISOR_CMD_OPEN_CHANNEL: ebx bit 31 */ 53 #define VMWARE_HYPERVISOR_CMD_SEND_SIZE RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 1) /**< ecx */ 54 #define VMWARE_HYPERVISOR_CMD_SEND_PAYLOAD RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 2) /**< ecx */ 55 #define VMWARE_HYPERVISOR_CMD_RECV_SIZE RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 3) /**< ecx */ 56 #define VMWARE_HYPERVISOR_CMD_RECV_PAYLOAD RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 4) /**< ecx */ 57 #define VMWARE_HYPERVISOR_CMD_RECV_STATUS RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 5) /**< ecx */ 58 #define VMWARE_HYPERVISOR_CMD_CLOSE_CHANNEL RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MSG, 6) /**< ecx */ 59 60 #define VMWARE_HYPERVISOR_CMD_MKS_GUEST_STATS 0x0055 61 #define VMWARE_HYPERVISOR_CMD_MKSGS_RESET RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MKS_GUEST_STATS, 0) /**< ecx */ 62 #define VMWARE_HYPERVISOR_CMD_MKSGS_ADD_PPN RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MKS_GUEST_STATS, 1) /**< ecx */ 63 #define VMWARE_HYPERVISOR_CMD_MKSGS_REMOVE_PPN RT_MAKE_U32(VMWARE_HYPERVISOR_CMD_MKS_GUEST_STATS, 2) /**< ecx */ 64 65 /** @name Message status return flags (ecx). 66 * @{ */ 67 #define VMWARE_MSG_STATUS_F_SUCCESS UINT32_C(0x00010000) 68 #define VMWARE_MSG_STATUS_F_DO_RECV UINT32_C(0x00020000) 69 #define VMWARE_MSG_STATUS_F_CPT UINT32_C(0x00100000) 70 #define VMWARE_MSG_STATUS_F_HB UINT32_C(0x00800000) 71 /** @} */ 39 72 40 73 … … 198 231 } 199 232 233 234 #if 0 235 /** 236 * Whether \#GP exceptions in the guest should be intercepted by GCM and 237 * possibly fixed up. 238 * 239 * @returns true if needed, false otherwise. 240 * @param pVCpu The cross context virtual CPU structure. 241 */ 242 VMM_INT_DECL(bool) GCMIsInterceptingXcptGP(PVMCPUCC pVCpu) 243 { 244 /* See if the enabled fixers require #GP interception. */ 245 PVM const pVM = pVCpu->CTX_SUFF(pVM); 246 bool const fRet = (pVM->gcm.s.fFixerSet & GCMFIXER_MESA_VMSVGA_DRV) != 0; 247 LogFlow(("GCMIsInterceptingXcptDE: returns %d\n", fRet)); 248 return fRet; 249 } 250 251 252 /** 253 * Exception handler for \#GP when registered by GCM. 254 * 255 * @returns VBox status code. 256 * @retval VINF_SUCCESS retry the instruction and continue. 257 * @retval VERR_NOT_FOUND deliver exception to guest. 258 * 259 * @param pVCpu The cross context virtual CPU structure. 260 * @param pCtx Pointer to the guest-CPU context. 261 * 262 * @thread EMT(pVCpu). 263 */ 264 VMM_INT_DECL(int) GCMXcptGP(PVMCPUCC pVCpu, PCPUMCTX pCtx) 265 { 266 267 } 268 #endif 269 270 271 /** 272 * Checks if I/O port reads for the given port need GCM attention. 273 * 274 * @returns true if needed, false otherwise. 275 * @param pVCpu The cross context virtual CPU structure. 276 * @param u16Port The port being accessed. UINT16_MAX and cbReg == 277 * UINT8_MAX for any port. 278 * @param cbReg The access size. UINT8_MAX and u16Port == UINT16_MAX for 279 * any size. 280 */ 281 VMM_INT_DECL(bool) GCMIsInterceptingIOPortReadSlow(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg) 282 { 283 PVM const pVM = pVCpu->CTX_SUFF(pVM); 284 bool const fRet = (pVM->gcm.s.fFixerSet & GCMFIXER_MESA_VMSVGA_DRV) != 0 285 && ( (u16Port == VMWARE_HYPERVISOR_PORT && cbReg == 4) 286 || (u16Port == UINT16_MAX && cbReg == UINT8_MAX) ); 287 LogFlow(("GCMIsInterceptingIOPortReadSlow(,%#x,%#x): returns %d\n", u16Port, cbReg, fRet)); 288 return fRet; 289 } 290 291 292 /** 293 * Processes an intercepted IO port read instruction. 294 * 295 * @returns Strict VBox status code. Only two informational status codes 296 * are returned VINF_GCM_HANDLED and VINF_GCM_HANDLED_ADVANCE_RIP. 297 * @retval VINF_GCM_HANDLED 298 * @retval VINF_GCM_HANDLED_ADVANCE_RIP 299 * @retval VERR_GCM_NOT_HANDLED 300 * @param pVCpu The cross context virtual CPU structure. 301 * @param pCtx The CPU context. 302 * @param u16Port The port being accessed. 303 * @param cbReg The size of the access. 304 */ 305 VMM_INT_DECL(VBOXSTRICTRC) GCMInterceptedIOPortRead(PVMCPUCC pVCpu, PCPUMCTX pCtx, uint16_t u16Port, uint8_t cbReg) 306 { 307 Assert((pVCpu->CTX_SUFF(pVM)->gcm.s.fFixerSet & GCMFIXER_MESA_VMSVGA_DRV) != 0); 308 if (u16Port == VMWARE_HYPERVISOR_PORT && cbReg == 4) 309 { 310 CPUM_IMPORT_EXTRN_WITH_CTX_RET(pVCpu, pCtx, 311 CPUMCTX_EXTRN_RAX | CPUMCTX_EXTRN_RCX | CPUMCTX_EXTRN_RDX 312 | CPUMCTX_EXTRN_RBX | CPUMCTX_EXTRN_RSI | CPUMCTX_EXTRN_RDI); 313 if (pCtx->rax == VMWARE_HYPERVISOR_MAGIC) 314 { 315 switch (pCtx->rcx) 316 { 317 case VMWARE_HYPERVISOR_CMD_OPEN_CHANNEL: 318 Log(("GCMInterceptedIOPortRead: vmware open channel: protocol=%#RX64\n", pCtx->rbx)); 319 break; 320 case VMWARE_HYPERVISOR_CMD_SEND_SIZE: 321 Log(("GCMInterceptedIOPortRead: vmware send size\n")); 322 break; 323 case VMWARE_HYPERVISOR_CMD_SEND_PAYLOAD: 324 Log(("GCMInterceptedIOPortRead: vmware send payload\n")); 325 break; 326 case VMWARE_HYPERVISOR_CMD_RECV_SIZE: 327 Log(("GCMInterceptedIOPortRead: vmware recv size\n")); 328 break; 329 case VMWARE_HYPERVISOR_CMD_RECV_PAYLOAD: 330 Log(("GCMInterceptedIOPortRead: vmware recv payload\n")); 331 break; 332 case VMWARE_HYPERVISOR_CMD_RECV_STATUS: 333 Log(("GCMInterceptedIOPortRead: vmware recv status\n")); 334 break; 335 case VMWARE_HYPERVISOR_CMD_CLOSE_CHANNEL: 336 Log(("GCMInterceptedIOPortRead: vmware close channel\n")); 337 break; 338 339 case VMWARE_HYPERVISOR_CMD_MKSGS_RESET: 340 Log(("GCMInterceptedIOPortRead: vmware mks guest stats reset\n")); 341 break; 342 case VMWARE_HYPERVISOR_CMD_MKSGS_ADD_PPN: 343 Log(("GCMInterceptedIOPortRead: vmware mks guest stats add ppn\n")); 344 break; 345 case VMWARE_HYPERVISOR_CMD_MKSGS_REMOVE_PPN: 346 Log(("GCMInterceptedIOPortRead: vmware mks guest stats remove ppn\n")); 347 break; 348 349 default: 350 LogRelMax(64, ("GCMInterceptedIOPortRead: Unknown vmware hypervisor call: rcx=%#RX64 (cmd), rbx=%#RX64 (len/whatever), rsi=%#RX64 (input), rdi=%#RX64 (input), rdx=%#RX64 (flags + chid) at %04x:%08RX64\n", 351 pCtx->rcx, pCtx->rbx, pCtx->rsi, pCtx->rdi, pCtx->rdx, pCtx->cs.Sel, pCtx->rip)); 352 return VERR_GCM_NOT_HANDLED; 353 } 354 355 /* Just fail the command. */ 356 pCtx->ecx &= ~VMWARE_MSG_STATUS_F_SUCCESS; 357 return VINF_GCM_HANDLED_ADVANCE_RIP; 358 } 359 } 360 return VERR_GCM_NOT_HANDLED; 361 } 362 363 364 #if 0 /* If we need to deal with high speed vmware hypervisor calls */ 365 366 /** 367 * Checks if I/O port string reads for the given port need GCM attention. 368 * 369 * @returns true if needed, false otherwise. 370 * @param pVCpu The cross context virtual CPU structure. 371 * @param u16Port The port being accessed. UINT16_MAX and cbReg == 372 * UINT8_MAX for any port. 373 * @param cbReg The access size. UINT8_MAX and u16Port == UINT16_MAX for 374 * any size. 375 */ 376 VMM_INT_DECL(bool) GCMIsInterceptingIOPortReadStringSlow(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg) 377 { 378 PVM const pVM = pVCpu->CTX_SUFF(pVM); 379 bool const fRet = (pVM->gcm.s.fFixerSet & GCMFIXER_MESA_VMSVGA_DRV) != 0 380 && ( (u16Port == VMWARE_HYPERVISOR_PORT_HB && cbReg == 1) 381 || (u16Port == UINT16_MAX && cbReg == UINT8_MAX) ); 382 LogFlow(("GCMIsInterceptingIOPortReadStringSlow(,%#x,%#x): returns %d\n", u16Port, cbReg, fRet)); 383 return fRet; 384 } 385 386 387 /** 388 * Checks if I/O port string writes for the given port need GCM attention. 389 * 390 * @returns true if needed, false otherwise. 391 * @param pVCpu The cross context virtual CPU structure. 392 * @param u16Port The port being accessed. UINT16_MAX and cbReg == 393 * UINT8_MAX for any port. 394 * @param cbReg The access size. UINT8_MAX and u16Port == UINT16_MAX for 395 * any size. 396 */ 397 VMM_INT_DECL(bool) GCMIsInterceptingIOPortWriteStringSlow(PVMCPUCC pVCpu, uint16_t u16Port, uint8_t cbReg) 398 { 399 PVM const pVM = pVCpu->CTX_SUFF(pVM); 400 bool const fRet = (pVM->gcm.s.fFixerSet & GCMFIXER_MESA_VMSVGA_DRV) != 0 401 && ( (u16Port == VMWARE_HYPERVISOR_PORT_HB && cbReg == 1) 402 || (u16Port == UINT16_MAX && cbReg == UINT8_MAX) ); 403 LogFlow(("GCMIsInterceptingIOPortWriteStringSlow(,%#x,%#x): returns %d\n", u16Port, cbReg, fRet)); 404 return fRet; 405 } 406 407 #endif 408 -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r104129 r104516 131 131 #include <VBox/vmm/hm.h> 132 132 #include <VBox/vmm/nem.h> 133 #include <VBox/vmm/gcm.h> 133 134 #include <VBox/vmm/gim.h> 134 135 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM … … 4197 4198 VBOXSTRICTRC iemRaiseDivideError(PVMCPUCC pVCpu) RT_NOEXCEPT 4198 4199 { 4200 if (GCMIsInterceptingXcptDE(pVCpu)) 4201 { 4202 int rc = GCMXcptDE(pVCpu, &pVCpu->cpum.GstCtx); 4203 if (rc == VINF_SUCCESS) 4204 { 4205 Log(("iemRaiseDivideError: Restarting instruction because of GCMXcptDE\n")); 4206 return VINF_IEM_RAISED_XCPT; /* must return non-zero status here to cause a instruction restart */ 4207 } 4208 } 4199 4209 return iemRaiseXcptOrInt(pVCpu, 0, X86_XCPT_DE, IEM_XCPT_FLAGS_T_CPU_XCPT, 0, 0); 4200 4210 } -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp
r104419 r104516 43 43 #include <VBox/vmm/nem.h> 44 44 #include <VBox/vmm/gim.h> 45 #include <VBox/vmm/gcm.h> 45 46 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 46 47 # include <VBox/vmm/em.h> … … 7294 7295 IEM_CIMPL_DEF_3(iemCImpl_in, uint16_t, u16Port, uint8_t, cbReg, uint8_t, bImmAndEffAddrMode) 7295 7296 { 7297 /* 7298 * GCM intercept. 7299 * 7300 * This must be placed before the IOPL check as the mesa driver intercept 7301 * would otherwise trigger a #GP(0). 7302 */ 7303 if (!IEM_IS_IN_GUEST(pVCpu) && GCMIsInterceptingIOPortRead(pVCpu, u16Port, cbReg)) 7304 { 7305 VBOXSTRICTRC rcStrict = GCMInterceptedIOPortRead(pVCpu, &pVCpu->cpum.GstCtx, u16Port, cbReg); 7306 if (rcStrict == VINF_GCM_HANDLED_ADVANCE_RIP || rcStrict == VINF_GCM_HANDLED) 7307 { 7308 Log(("iemCImpl_in: u16Port=%#x cbReg=%d was handled by GCMIOPortRead (%d)\n", u16Port, cbReg, VBOXSTRICTRC_VAL(rcStrict))); 7309 if (rcStrict == VINF_GCM_HANDLED_ADVANCE_RIP) 7310 rcStrict = iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr); 7311 else 7312 rcStrict = VINF_SUCCESS; 7313 return rcStrict; 7314 } 7315 Assert(rcStrict == VERR_GCM_NOT_HANDLED); 7316 } 7317 7296 7318 /* 7297 7319 * CPL check -
trunk/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
r104512 r104516 9003 9003 else 9004 9004 { 9005 uint32_t u32Result = 0; 9006 rcStrict = IOMIOPortRead(pVM, pVCpu, uIOPort, &u32Result, cbValue); 9007 if (IOM_SUCCESS(rcStrict)) 9005 rcStrict = VERR_GCM_NOT_HANDLED; 9006 if (GCMIsInterceptingIOPortRead(pVCpu, uIOPort, cbValue)) 9008 9007 { 9009 /* Save result of I/O IN instr. in AL/AX/EAX. */ 9010 pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Result & uAndVal); 9008 rcStrict = GCMInterceptedIOPortRead(pVCpu, pCtx, uIOPort, cbValue); 9009 if (rcStrict == VINF_GCM_HANDLED_ADVANCE_RIP || rcStrict == VINF_GCM_HANDLED) 9010 { 9011 /* ASSUMES we don't need to update fCtxChanged when regular GPRs change here. */ 9012 fUpdateRipAlready = rcStrict == VINF_GCM_HANDLED; 9013 if (rcStrict == VINF_GCM_HANDLED) 9014 ASMAtomicUoOrU64(&VCPU_2_VMXSTATE(pVCpu).fCtxChanged, HM_CHANGED_GUEST_RIP); 9015 rcStrict = VINF_SUCCESS; 9016 } 9017 else 9018 Assert(rcStrict == VERR_GCM_NOT_HANDLED); 9011 9019 } 9020 9021 if (rcStrict == VERR_GCM_NOT_HANDLED) 9022 { 9023 uint32_t u32Result = 0; 9024 rcStrict = IOMIOPortRead(pVM, pVCpu, uIOPort, &u32Result, cbValue); 9025 if (IOM_SUCCESS(rcStrict)) 9026 { 9027 /* Save result of I/O IN instr. in AL/AX/EAX. */ 9028 /** @todo r=bird: 32-bit op size should clear high bits of rax! */ 9029 pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Result & uAndVal); 9030 } 9012 9031 #ifndef IN_NEM_DARWIN 9013 if ( rcStrict == VINF_IOM_R3_IOPORT_READ 9014 && !pCtx->eflags.Bits.u1TF) 9015 rcStrict = EMRZSetPendingIoPortRead(pVCpu, uIOPort, cbInstr, cbValue); 9016 #endif 9032 if ( rcStrict == VINF_IOM_R3_IOPORT_READ 9033 && !pCtx->eflags.Bits.u1TF) 9034 rcStrict = EMRZSetPendingIoPortRead(pVCpu, uIOPort, cbInstr, cbValue); 9035 #endif 9036 } 9017 9037 STAM_COUNTER_INC(&VCPU_2_VMXSTATS(pVCpu).StatExitIORead); 9018 9038 } -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r104512 r104516 7634 7634 static uint32_t const s_aIOOpAnd[8] = { 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0 }; /* AND masks for saving 7635 7635 the result (in AL/AX/EAX). */ 7636 PVMCC 7636 PVMCC pVM = pVCpu->CTX_SUFF(pVM); 7637 7637 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 7638 7638 PSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu); … … 7752 7752 else 7753 7753 { 7754 uint32_t u32Val = 0; 7755 rcStrict = IOMIOPortRead(pVM, pVCpu, IoExitInfo.n.u16Port, &u32Val, cbValue); 7756 if (IOM_SUCCESS(rcStrict)) 7754 rcStrict = VERR_GCM_NOT_HANDLED; 7755 if (GCMIsInterceptingIOPortRead(pVCpu, IoExitInfo.n.u16Port, cbValue)) 7757 7756 { 7758 /* Save result of I/O IN instr. in AL/AX/EAX. */ 7759 /** @todo r=bird: 32-bit op size should clear high bits of rax! */ 7760 pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal); 7757 rcStrict = GCMInterceptedIOPortRead(pVCpu, pCtx, IoExitInfo.n.u16Port, cbValue); 7758 if (rcStrict == VINF_GCM_HANDLED_ADVANCE_RIP || rcStrict == VINF_GCM_HANDLED) 7759 { 7760 fUpdateRipAlready = rcStrict != VINF_GCM_HANDLED_ADVANCE_RIP; 7761 rcStrict = VINF_SUCCESS; 7762 } 7763 else 7764 Assert(rcStrict == VERR_GCM_NOT_HANDLED); 7761 7765 } 7762 else if ( rcStrict == VINF_IOM_R3_IOPORT_READ 7763 && !pCtx->eflags.Bits.u1TF) 7764 rcStrict = EMRZSetPendingIoPortRead(pVCpu, IoExitInfo.n.u16Port, cbInstr, cbValue); 7766 7767 if (RT_LIKELY(rcStrict == VERR_GCM_NOT_HANDLED)) 7768 { 7769 uint32_t u32Val = 0; 7770 rcStrict = IOMIOPortRead(pVM, pVCpu, IoExitInfo.n.u16Port, &u32Val, cbValue); 7771 if (IOM_SUCCESS(rcStrict)) 7772 { 7773 /* Save result of I/O IN instr. in AL/AX/EAX. */ 7774 /** @todo r=bird: 32-bit op size should clear high bits of rax! */ 7775 pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal); 7776 } 7777 else if ( rcStrict == VINF_IOM_R3_IOPORT_READ 7778 && !pCtx->eflags.Bits.u1TF) 7779 rcStrict = EMRZSetPendingIoPortRead(pVCpu, IoExitInfo.n.u16Port, cbInstr, cbValue); 7780 } 7765 7781 7766 7782 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIORead); -
trunk/src/VBox/VMM/VMMR3/GCM.cpp
r104511 r104516 115 115 { RT_STR_TUPLE("DivByZeroOS2"), GCMFIXER_DBZ_OS2 }, 116 116 { RT_STR_TUPLE("DivByZeroWin9x"), GCMFIXER_DBZ_WIN9X }, 117 { RT_STR_TUPLE("MesaVmsvgaDrv"), GCMFIXER_MESA_VMSVGA_DRV }, 117 118 }; 118 119 -
trunk/src/VBox/VMM/include/GCMInternal.h
r104509 r104516 56 56 /** Windows 9x division by zero. */ 57 57 #define GCMFIXER_DBZ_WIN9X RT_BIT_32(2) 58 /** Workaround for the Mesa vmsvga driver using a IN/OUT backdoor. */ 59 #define GCMFIXER_MESA_VMSVGA_DRV RT_BIT_32(3) 58 60 /** @} */ 59 61
Note:
See TracChangeset
for help on using the changeset viewer.