Changeset 20846 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Jun 23, 2009 2:57:46 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 48985
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r20838 r20846 426 426 } 427 427 428 if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI_BIT))429 {430 SVM_EVENT Event;431 432 Log(("CPU%d: injecting #NMI\n", pVCpu->idCpu));433 Event.n.u8Vector = X86_XCPT_NMI;434 Event.n.u1Valid = 1; 435 Event.n.u32ErrorCode = 0;436 Event.n.u3Type = SVM_EVENT_NMI;437 438 SVMR0InjectEvent(pVCpu, pVMCB, pCtx, &Event);439 return VINF_SUCCESS;440 } 441 442 /* @todo SMI interrupts. */443 444 /* When external interrupts are pending, we should exit the VM when IF is set. */ 445 if ( !TRPMHasTrap(pVCpu)446 && VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))) 447 {448 if ( !(pCtx->eflags.u32 & X86_EFL_IF)449 || VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS))450 {451 if (!pVMCB->ctrl.IntCtrl.n.u1VIrqValid)428 /* If an active trap is already pending, then we must forward it first! */ 429 if (!TRPMHasTrap(pVCpu)) 430 { 431 if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI_BIT)) 432 { 433 SVM_EVENT Event; 434 435 Log(("CPU%d: injecting #NMI\n", pVCpu->idCpu)); 436 Event.n.u8Vector = X86_XCPT_NMI; 437 Event.n.u1Valid = 1; 438 Event.n.u32ErrorCode = 0; 439 Event.n.u3Type = SVM_EVENT_NMI; 440 441 SVMR0InjectEvent(pVCpu, pVMCB, pCtx, &Event); 442 return VINF_SUCCESS; 443 } 444 445 /* @todo SMI interrupts. */ 446 447 /* When external interrupts are pending, we should exit the VM when IF is set. */ 448 if (VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))) 449 { 450 if ( !(pCtx->eflags.u32 & X86_EFL_IF) 451 || VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 452 452 { 453 if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 454 LogFlow(("Enable irq window exit!\n")); 455 else 456 Log(("Pending interrupt blocked at %RGv by VM_FF_INHIBIT_INTERRUPTS -> irq window exit\n", (RTGCPTR)pCtx->rip)); 457 458 /** @todo use virtual interrupt method to inject a pending irq; dispatched as soon as guest.IF is set. */ 459 pVMCB->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_VINTR; 460 pVMCB->ctrl.IntCtrl.n.u1VIrqValid = 1; 461 pVMCB->ctrl.IntCtrl.n.u8VIrqVector = 0; /* don't care */ 462 } 463 } 464 else 465 { 466 uint8_t u8Interrupt; 467 468 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 469 Log(("Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc)); 470 if (RT_SUCCESS(rc)) 471 { 472 rc = TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT); 473 AssertRC(rc); 453 if (!pVMCB->ctrl.IntCtrl.n.u1VIrqValid) 454 { 455 if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 456 LogFlow(("Enable irq window exit!\n")); 457 else 458 Log(("Pending interrupt blocked at %RGv by VM_FF_INHIBIT_INTERRUPTS -> irq window exit\n", (RTGCPTR)pCtx->rip)); 459 460 /** @todo use virtual interrupt method to inject a pending irq; dispatched as soon as guest.IF is set. */ 461 pVMCB->ctrl.u32InterceptCtrl1 |= SVM_CTRL1_INTERCEPT_VINTR; 462 pVMCB->ctrl.IntCtrl.n.u1VIrqValid = 1; 463 pVMCB->ctrl.IntCtrl.n.u8VIrqVector = 0; /* don't care */ 464 } 474 465 } 475 466 else 476 467 { 477 /* Can only happen in rare cases where a pending interrupt is cleared behind our back */ 478 Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))); 479 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq); 480 /* Just continue */ 468 uint8_t u8Interrupt; 469 470 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 471 Log(("Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc\n", u8Interrupt, u8Interrupt, rc)); 472 if (RT_SUCCESS(rc)) 473 { 474 rc = TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT); 475 AssertRC(rc); 476 } 477 else 478 { 479 /* Can only happen in rare cases where a pending interrupt is cleared behind our back */ 480 Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))); 481 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq); 482 /* Just continue */ 483 } 481 484 } 482 485 } -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r20838 r20846 754 754 } 755 755 756 if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI_BIT))757 {758 RTGCUINTPTR intInfo;759 760 Log(("CPU%d: injecting #NMI\n", pVCpu->idCpu));761 762 intInfo = X86_XCPT_NMI; 763 intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT);764 intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 765 766 rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, 0, 0);767 AssertRC(rc);768 769 return VINF_SUCCESS;770 }771 772 /* @todo SMI interrupts. */773 774 /* When external interrupts are pending, we should exit the VM when IF is set. */ 775 if ( !TRPMHasTrap(pVCpu)776 && VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))) 777 {778 if ( !(pCtx->eflags.u32 & X86_EFL_IF))779 { 780 if (!(p VCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT))756 /* If an active trap is already pending, then we must forward it first! */ 757 if (!TRPMHasTrap(pVCpu)) 758 { 759 if (VMCPU_FF_TESTANDCLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI_BIT)) 760 { 761 RTGCUINTPTR intInfo; 762 763 Log(("CPU%d: injecting #NMI\n", pVCpu->idCpu)); 764 765 intInfo = X86_XCPT_NMI; 766 intInfo |= (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 767 intInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 768 769 rc = VMXR0InjectEvent(pVM, pVCpu, pCtx, intInfo, 0, 0); 770 AssertRC(rc); 771 772 return VINF_SUCCESS; 773 } 774 775 /* @todo SMI interrupts. */ 776 777 /* When external interrupts are pending, we should exit the VM when IF is set. */ 778 if (VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))) 779 { 780 if (!(pCtx->eflags.u32 & X86_EFL_IF)) 781 781 { 782 LogFlow(("Enable irq window exit!\n")); 783 pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT; 784 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls); 785 AssertRC(rc); 786 } 787 /* else nothing to do but wait */ 788 } 789 else 790 if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 791 { 792 uint8_t u8Interrupt; 793 794 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 795 Log(("CPU%d: Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc cs:rip=%04X:%RGv\n", pVCpu->idCpu, u8Interrupt, u8Interrupt, rc, pCtx->cs, (RTGCPTR)pCtx->rip)); 796 if (RT_SUCCESS(rc)) 797 { 798 rc = TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT); 799 AssertRC(rc); 782 if (!(pVCpu->hwaccm.s.vmx.proc_ctls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT)) 783 { 784 LogFlow(("Enable irq window exit!\n")); 785 pVCpu->hwaccm.s.vmx.proc_ctls |= VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT; 786 rc = VMXWriteVMCS(VMX_VMCS_CTRL_PROC_EXEC_CONTROLS, pVCpu->hwaccm.s.vmx.proc_ctls); 787 AssertRC(rc); 788 } 789 /* else nothing to do but wait */ 800 790 } 801 791 else 792 if (!VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 802 793 { 803 /* Can only happen in rare cases where a pending interrupt is cleared behind our back */ 804 Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))); 805 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq); 806 /* Just continue */ 794 uint8_t u8Interrupt; 795 796 rc = PDMGetInterrupt(pVCpu, &u8Interrupt); 797 Log(("CPU%d: Dispatch interrupt: u8Interrupt=%x (%d) rc=%Rrc cs:rip=%04X:%RGv\n", pVCpu->idCpu, u8Interrupt, u8Interrupt, rc, pCtx->cs, (RTGCPTR)pCtx->rip)); 798 if (RT_SUCCESS(rc)) 799 { 800 rc = TRPMAssertTrap(pVCpu, u8Interrupt, TRPM_HARDWARE_INT); 801 AssertRC(rc); 802 } 803 else 804 { 805 /* Can only happen in rare cases where a pending interrupt is cleared behind our back */ 806 Assert(!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC|VMCPU_FF_INTERRUPT_PIC))); 807 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchGuestIrq); 808 /* Just continue */ 809 } 807 810 } 808 }809 else810 Log(("Pending interrupt blocked at %RGv by VM_FF_INHIBIT_INTERRUPTS!!\n", (RTGCPTR)pCtx->rip));811 else 812 Log(("Pending interrupt blocked at %RGv by VM_FF_INHIBIT_INTERRUPTS!!\n", (RTGCPTR)pCtx->rip)); 813 } 811 814 } 812 815
Note:
See TracChangeset
for help on using the changeset viewer.