- Timestamp:
- Jan 2, 2018 4:56:56 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r70380 r70408 343 343 static FNSVMEXITHANDLER hmR0SvmExitXcptAC; 344 344 static FNSVMEXITHANDLER hmR0SvmExitXcptBP; 345 static FNSVMEXITHANDLER hmR0SvmExitXcptGeneric; 345 346 #ifdef VBOX_WITH_NESTED_HWVIRT 346 347 static FNSVMEXITHANDLER hmR0SvmExitXcptPFNested; … … 351 352 static FNSVMEXITHANDLER hmR0SvmExitInvlpga; 352 353 static FNSVMEXITHANDLER hmR0SvmExitVmrun; 353 static FNSVMEXITHANDLER hmR0SvmExitXcptGeneric;354 354 static FNSVMEXITHANDLER hmR0SvmNestedExitXcptDB; 355 355 static FNSVMEXITHANDLER hmR0SvmNestedExitXcptBP; … … 822 822 AssertMsgReturn(pVmcb, ("Invalid pVmcb for vcpu[%u]\n", i), VERR_SVM_INVALID_PVMCB); 823 823 824 /* Initialize the #VMEXIT history array with end-of-array markers (UINT16_MAX). */824 /* Initialize the #VMEXIT history array with end-of-array markers (UINT16_MAX). */ 825 825 Assert(!pVCpu->hm.s.idxExitHistoryFree); 826 826 HMCPU_EXIT_HISTORY_RESET(pVCpu); … … 3532 3532 #ifdef VBOX_WITH_NESTED_HWVIRT 3533 3533 /* 3534 * If IEM emulated VMRUN and injected an event it would not clear the EVENTINJ::Valid bit3534 * If IEM emulated VMRUN and injected an event, it would not clear the EVENTINJ::Valid bit 3535 3535 * as a physical CPU clears it in the VMCB as part of the #VMEXIT (if the AMD spec. is to 3536 3536 * believed, real behavior might differ). Regardless, IEM does it only on #VMEXIT for now … … 5124 5124 if (HMIsGuestSvmXcptInterceptSet(pVCpu, pCtx, uVector)) 5125 5125 return HM_SVM_VMEXIT_NESTED(pVCpu, uExitCode, uExitInfo1, uExitInfo2); 5126 #if 05127 /* Debugging DOS6 triple-fault nested-VM. */5128 unsigned cbInstr;5129 DISCPUSTATE Dis;5130 int rc = EMInterpretDisasCurrent(pVCpu->CTX_SUFF(pVM), pVCpu, &Dis, &cbInstr);5131 if (RT_SUCCESS(rc))5132 {5133 RT_NOREF(cbInstr);5134 if ( Dis.pCurInstr->uOpcode == OP_IRET5135 && uVector == X86_XCPT_GP)5136 {5137 Log4(("#GP on IRET detected!\n"));5138 return VERR_SVM_UNKNOWN_EXIT;5139 }5140 }5141 else5142 Log4(("hmR0SvmExitXcptGeneric: failed to disassemble instr. rc=%Rrc\n", rc));5143 #endif5144 5126 return hmR0SvmExitXcptGeneric(pVCpu, pCtx, pSvmTransient); 5145 5127 } … … 5277 5259 * normal workloads (for some definition of "normal"). 5278 5260 */ 5279 uint 32_t u32ExitCode = pSvmTransient->u64ExitCode;5280 switch ( pSvmTransient->u64ExitCode)5261 uint64_t const uExitCode = pSvmTransient->u64ExitCode; 5262 switch (uExitCode) 5281 5263 { 5282 5264 case SVM_EXIT_NPF: … … 5450 5432 case SVM_EXIT_EXCEPTION_26: case SVM_EXIT_EXCEPTION_27: case SVM_EXIT_EXCEPTION_28: 5451 5433 case SVM_EXIT_EXCEPTION_29: case SVM_EXIT_EXCEPTION_30: case SVM_EXIT_EXCEPTION_31: 5452 { 5453 /** @todo r=ramshankar; We should be doing 5454 * HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY here! */ 5455 PSVMVMCB pVmcb = pVCpu->hm.s.svm.pVmcb; 5456 SVMEVENT Event; 5457 Event.u = 0; 5458 Event.n.u1Valid = 1; 5459 Event.n.u3Type = SVM_EVENT_EXCEPTION; 5460 Event.n.u8Vector = pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0; 5461 5462 switch (Event.n.u8Vector) 5463 { 5464 case X86_XCPT_DE: 5465 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE); 5466 break; 5467 5468 case X86_XCPT_NP: 5469 Event.n.u1ErrorCodeValid = 1; 5470 Event.n.u32ErrorCode = pVmcb->ctrl.u64ExitInfo1; 5471 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP); 5472 break; 5473 5474 case X86_XCPT_SS: 5475 Event.n.u1ErrorCodeValid = 1; 5476 Event.n.u32ErrorCode = pVmcb->ctrl.u64ExitInfo1; 5477 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS); 5478 break; 5479 5480 case X86_XCPT_GP: 5481 Event.n.u1ErrorCodeValid = 1; 5482 Event.n.u32ErrorCode = pVmcb->ctrl.u64ExitInfo1; 5483 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestGP); 5484 break; 5485 5486 default: 5487 AssertMsgFailed(("hmR0SvmHandleExit: Unexpected exit caused by exception %#x\n", Event.n.u8Vector)); 5488 pVCpu->hm.s.u32HMError = Event.n.u8Vector; 5489 return VERR_SVM_UNEXPECTED_XCPT_EXIT; 5490 } 5491 5492 Log4(("#Xcpt: Vector=%#x at CS:RIP=%04x:%RGv\n", Event.n.u8Vector, pCtx->cs.Sel, (RTGCPTR)pCtx->rip)); 5493 hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */); 5494 return VINF_SUCCESS; 5495 } 5434 return hmR0SvmExitXcptGeneric(pVCpu, pCtx, pSvmTransient); 5496 5435 #endif /* HMSVM_ALWAYS_TRAP_ALL_XCPTS */ 5497 5436 5498 5437 default: 5499 5438 { 5500 AssertMsgFailed(("hmR0SvmHandleExit: Unknown exit code %# x\n", u32ExitCode));5501 pVCpu->hm.s.u32HMError = u 32ExitCode;5439 AssertMsgFailed(("hmR0SvmHandleExit: Unknown exit code %#RX64\n", uExitCode)); 5440 pVCpu->hm.s.u32HMError = uExitCode; 5502 5441 return VERR_SVM_UNKNOWN_EXIT; 5503 5442 } … … 7460 7399 7461 7400 7401 /** 7402 * \#VMEXIT handler for generic exceptions. Conditional \#VMEXIT. 7403 */ 7404 HMSVM_EXIT_DECL hmR0SvmExitXcptGeneric(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient) 7405 { 7406 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS(); 7407 7408 HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY(); 7409 7410 PSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu, pCtx); 7411 uint8_t const uVector = pVmcb->ctrl.u64ExitCode - SVM_EXIT_EXCEPTION_0; 7412 uint32_t const uErrCode = pVmcb->ctrl.u64ExitInfo1; 7413 Assert(pSvmTransient->u64ExitCode == pVmcb->ctrl.u64ExitCode); 7414 Assert(uVector <= X86_XCPT_LAST); 7415 Log4(("hmR0SvmExitXcptGeneric: uVector=%#x uErrCode=%u\n", uVector, uErrCode)); 7416 7417 7418 SVMEVENT Event; 7419 Event.u = 0; 7420 Event.n.u1Valid = 1; 7421 Event.n.u3Type = SVM_EVENT_EXCEPTION; 7422 Event.n.u8Vector = uVector; 7423 switch (uVector) 7424 { 7425 /* Shouldn't be here for reflecting #PFs (among other things, the fault address isn't passed along). */ 7426 case X86_XCPT_PF: AssertMsgFailed(("hmR0SvmExitXcptGeneric: Unexpected exception")); return VERR_SVM_IPE_5; 7427 case X86_XCPT_DF: 7428 case X86_XCPT_TS: 7429 case X86_XCPT_NP: 7430 case X86_XCPT_SS: 7431 case X86_XCPT_GP: 7432 case X86_XCPT_AC: 7433 { 7434 Event.n.u1ErrorCodeValid = 1; 7435 Event.n.u32ErrorCode = uErrCode; 7436 break; 7437 } 7438 } 7439 7440 hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */); 7441 return VINF_SUCCESS; 7442 } 7443 7444 7462 7445 #ifdef VBOX_WITH_NESTED_HWVIRT 7463 7446 /** … … 7646 7629 7647 7630 /** 7648 * \#VMEXIT handler for generic exceptions. Conditional \#VMEXIT.7649 */7650 HMSVM_EXIT_DECL hmR0SvmExitXcptGeneric(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)7651 {7652 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();7653 7654 /** @todo if triple-fault is returned in nested-guest scenario convert to a7655 * shutdown VMEXIT. */7656 HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY();7657 7658 PSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu, pCtx);7659 uint8_t const uVector = pVmcb->ctrl.u64ExitCode - SVM_EXIT_EXCEPTION_0;7660 uint32_t const uErrCode = pVmcb->ctrl.u64ExitInfo1;7661 Assert(pSvmTransient->u64ExitCode == pVmcb->ctrl.u64ExitCode);7662 Assert(uVector <= X86_XCPT_LAST);7663 Log4(("hmR0SvmExitXcptGeneric: uVector=%#x uErrCode=%u\n", uVector, uErrCode));7664 7665 SVMEVENT Event;7666 Event.u = 0;7667 Event.n.u1Valid = 1;7668 Event.n.u3Type = SVM_EVENT_EXCEPTION;7669 Event.n.u8Vector = uVector;7670 switch (uVector)7671 {7672 case X86_XCPT_PF:7673 case X86_XCPT_DF:7674 case X86_XCPT_TS:7675 case X86_XCPT_NP:7676 case X86_XCPT_SS:7677 case X86_XCPT_GP:7678 case X86_XCPT_AC:7679 {7680 Event.n.u1ErrorCodeValid = 1;7681 Event.n.u32ErrorCode = uErrCode;7682 break;7683 }7684 }7685 7686 hmR0SvmSetPendingEvent(pVCpu, &Event, 0 /* GCPtrFaultAddress */);7687 return VINF_SUCCESS;7688 }7689 7690 7691 /**7692 7631 * Nested-guest \#VMEXIT handler for debug exceptions (SVM_EXIT_EXCEPTION_1). 7693 7632 * Unconditional \#VMEXIT.
Note:
See TracChangeset
for help on using the changeset viewer.