Changeset 75631 in vbox
- Timestamp:
- Nov 21, 2018 4:55:45 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/vm.h
r75620 r75631 569 569 #define VMCPU_FF_EXTERNAL_HALTED_MASK ( VMCPU_FF_UPDATE_APIC | VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC \ 570 570 | VMCPU_FF_REQUEST | VMCPU_FF_INTERRUPT_NMI | VMCPU_FF_INTERRUPT_SMI \ 571 | VMCPU_FF_UNHALT | VMCPU_FF_TIMER | VMCPU_FF_DBGF ) 571 | VMCPU_FF_UNHALT | VMCPU_FF_TIMER | VMCPU_FF_DBGF \ 572 | VMCPU_FF_INTERRUPT_NESTED_GUEST) 572 573 573 574 /** High priority VM pre-execution actions. */ -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r75620 r75631 16044 16044 RT_NOREF4(pVM, pvPhys, enmOrigin, pvUser); 16045 16045 16046 Assert(CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu)));16047 Assert(CPUMIsGuestVmxProcCtls2Set(pVCpu, IEM_GET_CTX(pVCpu), VMX_PROC_CTLS2_VIRT_APIC_ACCESS));16048 16049 #ifdef VBOX_STRICT16050 RTGCPHYS const GCPhysApicBase = CPUMGetGuestVmxApicAccessPageAddr(pVCpu, IEM_GET_CTX(pVCpu));16051 16046 RTGCPHYS const GCPhysAccessBase = GCPhysFault & ~(RTGCPHYS)PAGE_OFFSET_MASK; 16052 Assert(GCPhysApicBase == GCPhysAccessBase); 16053 #endif 16054 16055 uint16_t const offAccess = GCPhysFault & PAGE_OFFSET_MASK; 16056 uint32_t const fAccess = enmAccessType == PGMACCESSTYPE_WRITE ? IEM_ACCESS_TYPE_WRITE : IEM_ACCESS_TYPE_READ; 16057 16058 VBOXSTRICTRC rcStrict = iemVmxVirtApicAccessMem(pVCpu, offAccess, cbBuf, pvBuf, fAccess); 16059 if (RT_FAILURE(rcStrict)) 16060 return rcStrict; 16061 16062 /* Any access on this APIC-access page has been handled, caller should not carry out the access. */ 16063 return VINF_SUCCESS; 16047 if (CPUMIsGuestInVmxNonRootMode(IEM_GET_CTX(pVCpu))) 16048 { 16049 Assert(CPUMIsGuestVmxProcCtls2Set(pVCpu, IEM_GET_CTX(pVCpu), VMX_PROC_CTLS2_VIRT_APIC_ACCESS)); 16050 Assert(CPUMGetGuestVmxApicAccessPageAddr(pVCpu, IEM_GET_CTX(pVCpu)) == GCPhysAccessBase); 16051 16052 /** @todo NSTVMX: How are we to distinguish instruction fetch accesses here? 16053 * Currently they will go through as read accesses. */ 16054 uint32_t const fAccess = enmAccessType == PGMACCESSTYPE_WRITE ? IEM_ACCESS_TYPE_WRITE : IEM_ACCESS_TYPE_READ; 16055 uint16_t const offAccess = GCPhysFault & PAGE_OFFSET_MASK; 16056 VBOXSTRICTRC rcStrict = iemVmxVirtApicAccessMem(pVCpu, offAccess, cbBuf, pvBuf, fAccess); 16057 if (RT_FAILURE(rcStrict)) 16058 return rcStrict; 16059 16060 /* Any access on this APIC-access page has been handled, caller should not carry out the access. */ 16061 return VINF_SUCCESS; 16062 } 16063 16064 Log(("iemVmxApicAccessPageHandler: Access outside VMX non-root mode, deregistering page at %#RGp\n", GCPhysAccessBase)); 16065 int rc = PGMHandlerPhysicalDeregister(pVM, GCPhysAccessBase); 16066 if (RT_FAILURE(rc)) 16067 return rc; 16068 16069 /* Instruct the caller of this handler to perform the read/write as normal memory. */ 16070 return VINF_PGM_HANDLER_DO_DEFAULT; 16064 16071 } 16065 16072 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r75620 r75631 5912 5912 */ 5913 5913 uint32_t const uTpr = (uNewCrX & 0xf) << 4; 5914 Log(("iemCImpl_load_Cr%#x: Virtualizing TPR (%#x) write\n", iCrReg, uTpr)); 5914 5915 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_TPR, uTpr); 5915 5916 iemVmxVirtApicSetPendingWrite(pVCpu, XAPIC_OFF_TPR); -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r75620 r75631 2182 2182 * 2183 2183 * If Delta >= VmcsPreemptTimer * RT_BIT(PreemptTimerShift) cause a VMX-preemption timer VM-exit. 2184 *2185 2184 * The saved VMX-preemption timer value is calculated as follows: 2186 2185 * PreemptTimerVal = VmcsPreemptTimer - (Delta / (VmcsPreemptTimer * RT_BIT(PreemptTimerShift))) … … 2750 2749 /* Clear address range monitoring. */ 2751 2750 EMMonitorWaitClear(pVCpu); 2752 2753 /* De-register the handler for the APIC-access page. */2754 if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_APIC_ACCESS)2755 {2756 PVM pVM = pVCpu->CTX_SUFF(pVM);2757 RTGCPHYS const GCPhysApicAccess = pVmcs->u64AddrApicAccess.u;2758 if (PGMHandlerPhysicalIsRegistered(pVM, GCPhysApicAccess))2759 {2760 /** @todo NSTVMX: This is broken! We cannot simply deregister the handler for the2761 * physical address as other VCPUs executing other nested-VCPUs might have2762 * it registered! */2763 int rc = PGMHandlerPhysicalDeregister(pVM, GCPhysApicAccess);2764 if (RT_FAILURE(rc))2765 return rc;2766 }2767 }2768 2751 2769 2752 /* Perform the VMX transition (PGM updates). */ … … 4638 4621 Assert(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY); 4639 4622 4640 /** @todo NSTVMX: evaluate pending virtual interrupts. */ 4641 RT_NOREF(pVCpu); 4623 if (!(pVmcs->u32ProcCtls & VMX_PROC_CTLS_INT_WINDOW_EXIT)) 4624 { 4625 uint8_t const uRvi = RT_LO_U8(pVmcs->u16GuestIntStatus); 4626 uint8_t const uPpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_PPR); 4627 4628 if ((uRvi >> 4) > (uPpr >> 4)) 4629 { 4630 Log2(("eval_virt_intrs: uRvi=%#x uPpr=%#x - Signaling pending interrupt\n", uRvi, uPpr)); 4631 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NESTED_GUEST); 4632 } 4633 else 4634 Log2(("eval_virt_intrs: uRvi=%#x uPpr=%#x - Nothing to do\n", uRvi, uPpr)); 4635 } 4642 4636 } 4643 4637 … … 4663 4657 */ 4664 4658 uint32_t const uTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR); 4665 uint32_t const uSvi 4666 4667 uint32_t u VPpr;4659 uint32_t const uSvi = RT_HI_U8(pVmcs->u16GuestIntStatus); 4660 4661 uint32_t uPpr; 4668 4662 if (((uTpr >> 4) & 0xf) >= ((uSvi >> 4) & 0xf)) 4669 u VPpr = uTpr & 0xff;4663 uPpr = uTpr & 0xff; 4670 4664 else 4671 uVPpr = uSvi & 0xf0; 4672 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_PPR, uVPpr); 4673 Log2(("ppr_virt: uTpr=%u uSvi=%u -> VM-exit\n", uTpr, uSvi)); 4665 uPpr = uSvi & 0xf0; 4666 4667 Log2(("ppr_virt: uTpr=%#x uSvi=%#x uPpr=%#x\n", uTpr, uSvi, uPpr)); 4668 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_PPR, uPpr); 4674 4669 } 4675 4670 … … 4763 4758 uint8_t const uRvi = RT_LO_U8(pVmcs->u16GuestIntStatus); 4764 4759 uint8_t const uSvi = RT_HI_U8(pVmcs->u16GuestIntStatus); 4760 Log2(("eoi_virt: uRvi=%#x uSvi=%#x\n", uRvi, uSvi)); 4765 4761 4766 4762 uint8_t uVector = uSvi; … … 4769 4765 uVector = 0; 4770 4766 iemVmxVirtApicGetHighestSetBitInReg(pVCpu, XAPIC_OFF_ISR0, &uVector); 4767 4768 if (uVector) 4769 Log2(("eoi_virt: next interrupt %#x\n", uVector)); 4770 else 4771 Log2(("eoi_virt: no interrupt pending in ISR\n")); 4771 4772 4772 4773 /* Update guest-interrupt status SVI (leave RVI portion as it is) in the VMCS. */ … … 4799 4800 * See Intel spec. 29.1.5 "Self-IPI Virtualization". 4800 4801 */ 4801 uint8_t const uVector = iemVmxVirtApicReadRaw32(pVCpu, X 2APIC_OFF_SELF_IPI);4802 4802 uint8_t const uVector = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_ICR_LO); 4803 Log2(("self_ipi_virt: uVector=%#x\n", uVector)); 4803 4804 iemVmxVirtApicSetVector(pVCpu, XAPIC_OFF_IRR0, uVector); 4804 4805 uint8_t const uRvi = RT_LO_U8(pVmcs->u16GuestIntStatus); … … 4837 4838 uTpr &= UINT32_C(0x000000ff); 4838 4839 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_TPR, uTpr); 4840 Log2(("iemVmxApicWriteEmulation: TPR write %#x\n", uTpr)); 4839 4841 rcStrict = iemVmxTprVirtualization(pVCpu); 4840 4842 break; … … 4847 4849 /* Clear VEOI and perform EOI virtualization. */ 4848 4850 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_EOI, 0); 4851 Log2(("iemVmxApicWriteEmulation: EOI write\n")); 4849 4852 rcStrict = iemVmxEoiVirtualization(pVCpu); 4850 4853 } … … 4864 4867 if ( !(uIcrLo & fIcrLoMb0) 4865 4868 && (uIcrLo & fIcrLoMb1)) 4869 { 4870 Log2(("iemVmxApicWriteEmulation: Self-IPI virtualization with vector %#x\n", (uIcrLo & 0xff))); 4866 4871 rcStrict = iemVmxSelfIpiVirtualization(pVCpu); 4872 } 4867 4873 else 4868 4874 rcStrict = iemVmxVmexitApicWrite(pVCpu, offApicWrite); … … 6403 6409 } 6404 6410 6405 /* Register the handler for the APIC-access page. */ 6411 /* 6412 * Register the handler for the APIC-access page. 6413 * 6414 * We don't deregister the APIC-access page handler during the VM-exit as a different 6415 * nested-VCPU might be using the same guest-physical address for its APIC-access page. 6416 * 6417 * We leave the page registered until the first access that happens outside VMX non-root 6418 * mode. Guest software is allowed to access structures such as the APIC-access page 6419 * only when no logical processor with a current VMCS references it in VMX non-root mode, 6420 * otherwise it can lead to unpredictable behavior including guest triple-faults. 6421 * 6422 * See Intel spec. 24.11.4 "Software Access to Related Structures". 6423 */ 6406 6424 int rc = PGMHandlerPhysicalRegister(pVCpu->CTX_SUFF(pVM), GCPhysApicAccess, GCPhysApicAccess, 6407 6425 pVCpu->iem.s.hVmxApicAccessPage, NIL_RTR3PTR /* pvUserR3 */,
Note:
See TracChangeset
for help on using the changeset viewer.