Changeset 75620 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Nov 20, 2018 2:42:07 PM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r75611 r75620 15715 15715 15716 15716 /** 15717 * Interface for HM and EM to perform a post-instruction virtual-APIC update.15717 * Interface for HM and EM to perform a APIC-write emulation. 15718 15718 * 15719 15719 * @returns Strict VBox status code. 15720 * @retval VINF_VMX_VMEXIT if the virtual-APIC update causes a VM-exit.15721 * @retval VINF_VMX_INTERCEPT_NOT_ACTIVE if no change was made.15722 *15723 15720 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 15724 15721 * @thread EMT(pVCpu) 15725 15722 */ 15726 VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVirtApic Update(PVMCPU pVCpu)15723 VMM_INT_DECL(VBOXSTRICTRC) IEMExecVmxVirtApicWriteEmulation(PVMCPU pVCpu) 15727 15724 { 15728 15725 IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_VMX_VMEXIT_MASK); 15729 15726 15730 /* 15731 * Record the virtual-APIC offset which was just updated and clear 15732 * the virtual-APIC update force-flag and process it now. 15733 */ 15734 uint16_t const offApicWrite = iemVmxVirtApicClearPostAction(pVCpu); 15735 VBOXSTRICTRC rcStrict; 15736 switch (offApicWrite) 15737 { 15738 case XAPIC_OFF_TPR: rcStrict = iemVmxTprVirtualization(pVCpu); break; 15739 case XAPIC_OFF_EOI: rcStrict = iemVmxEoiVirtualization(pVCpu); break; 15740 case X2APIC_OFF_SELF_IPI: rcStrict = iemVmxSelfIpiVirtualization(pVCpu); break; 15741 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 15742 } 15727 VBOXSTRICTRC rcStrict = iemVmxApicWriteEmulation(pVCpu); 15743 15728 if (pVCpu->iem.s.cActiveMappings) 15744 15729 iemMemRollback(pVCpu); -
trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h
r75604 r75620 5368 5368 if (IEM_VMX_IS_PROCCTLS_SET(pVCpu, VMX_PROC_CTLS_USE_TPR_SHADOW)) 5369 5369 { 5370 uint32_t const u VTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR);5371 crX = (u VTpr >> 4) & 0xf;5370 uint32_t const uTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR); 5371 crX = (uTpr >> 4) & 0xf; 5372 5372 break; 5373 5373 } … … 5905 5905 * cleared. Following this the processor performs TPR virtualization. 5906 5906 * 5907 * See Intel Spec. 29.3 "Virtualizing CR8-based TPR Accesses" 5907 * However, we should not perform TPR virtualization immediately here but 5908 * after this instruction has completed. 5909 * 5910 * See Intel spec. 29.3 "Virtualizing CR8-based TPR Accesses" 5911 * See Intel spec. 27.1 "Architectural State Before A VM-exit" 5908 5912 */ 5909 uint32_t const u VTpr = (uNewCrX & 0xf) << 4;5910 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_TPR, u VTpr);5911 iemVmxVirtApicSetP ostAction(pVCpu, XAPIC_OFF_TPR);5913 uint32_t const uTpr = (uNewCrX & 0xf) << 4; 5914 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_TPR, uTpr); 5915 iemVmxVirtApicSetPendingWrite(pVCpu, XAPIC_OFF_TPR); 5912 5916 rcStrict = VINF_SUCCESS; 5913 5917 break; -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r75611 r75620 911 911 912 912 /** 913 * Signal that a virtual-APIC post instruction-execution action needs to be 914 * performed at a later time (post instruction execution). 913 * Sets virtual-APIC write emulation as pending. 915 914 * 916 915 * @param pVCpu The cross context virtual CPU structure. 917 * @param offApic The virtual-APIC page offset that was updated pertaining to 918 * the event. 919 */ 920 DECLINLINE(void) iemVmxVirtApicSetPostAction(PVMCPU pVCpu, uint16_t offApic) 916 * @param offApic The offset in the virtual-APIC page that was written. 917 */ 918 DECLINLINE(void) iemVmxVirtApicSetPendingWrite(PVMCPU pVCpu, uint16_t offApic) 921 919 { 922 920 Assert(offApic < XAPIC_OFF_END + 4); … … 930 928 931 929 /* 932 * Signal that we need to perform a virtual-APIC action (TPR/PPR/EOI/Self-IPI930 * Signal that we need to perform virtual-APIC write emulation (TPR/PPR/EOI/Self-IPI 933 931 * virtualization or APIC-write emulation). 934 932 */ 935 if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_ UPDATE_VAPIC))936 VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_ UPDATE_VAPIC);937 } 938 939 940 /** 941 * Clears any virtual-APIC post instruction-execution action.942 * 943 * @returns The virtual-APIC write offsetbefore clearing it.933 if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)) 934 VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE); 935 } 936 937 938 /** 939 * Clears any pending virtual-APIC write emulation. 940 * 941 * @returns The virtual-APIC offset that was written before clearing it. 944 942 * @param pVCpu The cross context virtual CPU structure. 945 * @param offApic The virtual-APIC page offset that was updated pertaining to 946 * the event. 947 */ 948 DECLINLINE(uint16_t) iemVmxVirtApicClearPostAction(PVMCPU pVCpu) 943 */ 944 DECLINLINE(uint16_t) iemVmxVirtApicClearPendingWrite(PVMCPU pVCpu) 949 945 { 950 946 uint8_t const offVirtApicWrite = pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite; 951 947 pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = 0; 952 Assert(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_ UPDATE_VAPIC));953 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_VMX_ UPDATE_VAPIC);948 Assert(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)); 949 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_VMX_APIC_WRITE); 954 950 return offVirtApicWrite; 955 951 } … … 4164 4160 * virtualized a virtual-APIC write, we must cause a VM-exit. 4165 4161 */ 4166 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_ UPDATE_VAPIC))4162 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE)) 4167 4163 return true; 4168 4164 … … 4330 4326 * 4331 4327 * @param pVCpu The cross context virtual CPU structure. 4332 */ 4333 IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicWrite(PVMCPU pVCpu) 4334 { 4335 iemVmxVmcsSetExitQual(pVCpu, pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite); 4328 * @param offApic The write to the virtual-APIC page offset that caused this 4329 * VM-exit. 4330 */ 4331 IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicWrite(PVMCPU pVCpu, uint16_t offApic) 4332 { 4333 Assert(offApic < XAPIC_OFF_END + 4); 4334 iemVmxVmcsSetExitQual(pVCpu, offApic); 4336 4335 return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_WRITE); 4337 4336 } … … 4444 4443 * See Intel spec. 29.4.3.2 "APIC-Write Emulation". 4445 4444 */ 4446 iemVmxVirtApicSetP ostAction(pVCpu, offAccess);4445 iemVmxVirtApicSetPendingWrite(pVCpu, offAccess); 4447 4446 } 4448 4447 else … … 4575 4574 * as for supplying the exit qualification when causing an APIC-write VM-exit. 4576 4575 */ 4577 iemVmxVirtApicSetP ostAction(pVCpu, offReg);4576 iemVmxVirtApicSetPendingWrite(pVCpu, offReg); 4578 4577 4579 4578 return VINF_VMX_MODIFIES_BEHAVIOR; … … 4663 4662 * See Intel spec. 29.1.3 "PPR Virtualization". 4664 4663 */ 4665 uint32_t const u VTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR);4664 uint32_t const uTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR); 4666 4665 uint32_t const uSvi = RT_HI_U8(pVmcs->u16GuestIntStatus); 4667 4666 4668 4667 uint32_t uVPpr; 4669 if (((u VTpr >> 4) & 0xf) >= ((uSvi >> 4) & 0xf))4670 uVPpr = u VTpr & 0xff;4668 if (((uTpr >> 4) & 0xf) >= ((uSvi >> 4) & 0xf)) 4669 uVPpr = uTpr & 0xff; 4671 4670 else 4672 4671 uVPpr = uSvi & 0xf0; 4673 4672 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_PPR, uVPpr); 4674 Log2(("ppr_virt: u VTpr=%u uSvi=%u -> VM-exit\n", uVTpr, uSvi));4673 Log2(("ppr_virt: uTpr=%u uSvi=%u -> VM-exit\n", uTpr, uSvi)); 4675 4674 } 4676 4675 … … 4697 4696 { 4698 4697 uint32_t const uTprThreshold = pVmcs->u32TprThreshold; 4699 uint32_t const u VTpr= iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR);4698 uint32_t const uTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR); 4700 4699 4701 4700 /* … … 4703 4702 * See Intel spec. 29.1.2 "TPR Virtualization". 4704 4703 */ 4705 if (((u VTpr >> 4) & 0xf) < uTprThreshold)4706 { 4707 Log2(("tpr_virt: u VTpr=%u uTprThreshold=%u -> VM-exit\n", uVTpr, uTprThreshold));4704 if (((uTpr >> 4) & 0xf) < uTprThreshold) 4705 { 4706 Log2(("tpr_virt: uTpr=%u uTprThreshold=%u -> VM-exit\n", uTpr, uTprThreshold)); 4708 4707 iemVmxVmcsSetExitQual(pVCpu, 0); 4709 4708 return iemVmxVmexit(pVCpu, VMX_EXIT_TPR_BELOW_THRESHOLD); … … 4824 4823 Assert(pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_APIC_REG_VIRT); 4825 4824 4826 /** @todo NSTVMX: APIC-write emulation. */ 4827 RT_NOREF(pVCpu); 4828 4829 return VERR_IEM_ASPECT_NOT_IMPLEMENTED; 4825 /* 4826 * Perform APIC-write emulation based on the virtual-APIC register written. 4827 * See Intel spec. 29.4.3.2 "APIC-Write Emulation". 4828 */ 4829 uint16_t const offApicWrite = iemVmxVirtApicClearPendingWrite(pVCpu); 4830 VBOXSTRICTRC rcStrict; 4831 switch (offApicWrite) 4832 { 4833 case XAPIC_OFF_TPR: 4834 { 4835 /* Clear bytes 3:1 of the VTPR and perform TPR virtualization. */ 4836 uint32_t uTpr = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR); 4837 uTpr &= UINT32_C(0x000000ff); 4838 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_TPR, uTpr); 4839 rcStrict = iemVmxTprVirtualization(pVCpu); 4840 break; 4841 } 4842 4843 case XAPIC_OFF_EOI: 4844 { 4845 if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY) 4846 { 4847 /* Clear VEOI and perform EOI virtualization. */ 4848 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_EOI, 0); 4849 rcStrict = iemVmxEoiVirtualization(pVCpu); 4850 } 4851 else 4852 rcStrict = iemVmxVmexitApicWrite(pVCpu, offApicWrite); 4853 break; 4854 } 4855 4856 case XAPIC_OFF_ICR_LO: 4857 { 4858 if (pVmcs->u32ProcCtls2 & VMX_PROC_CTLS2_VIRT_INT_DELIVERY) 4859 { 4860 /* If the ICR_LO is valid, write it and perform self-IPI virtualization. */ 4861 uint32_t const uIcrLo = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_TPR); 4862 uint32_t const fIcrLoMb0 = UINT32_C(0xfffbb700); 4863 uint32_t const fIcrLoMb1 = UINT32_C(0x000000f0); 4864 if ( !(uIcrLo & fIcrLoMb0) 4865 && (uIcrLo & fIcrLoMb1)) 4866 rcStrict = iemVmxSelfIpiVirtualization(pVCpu); 4867 else 4868 rcStrict = iemVmxVmexitApicWrite(pVCpu, offApicWrite); 4869 } 4870 else 4871 rcStrict = iemVmxVmexitApicWrite(pVCpu, offApicWrite); 4872 break; 4873 } 4874 4875 case XAPIC_OFF_ICR_HI: 4876 { 4877 /* Clear bytes 2:0 of VICR_HI. No other virtualization or VM-exit must occur. */ 4878 uint32_t uIcrHi = iemVmxVirtApicReadRaw32(pVCpu, XAPIC_OFF_ICR_HI); 4879 uIcrHi &= UINT32_C(0xff000000); 4880 iemVmxVirtApicWriteRaw32(pVCpu, XAPIC_OFF_ICR_HI, uIcrHi); 4881 rcStrict = VINF_SUCCESS; 4882 break; 4883 } 4884 4885 default: 4886 { 4887 /* Writes to any other virtual-APIC register causes an APIC-write VM-exit. */ 4888 rcStrict = iemVmxVmexitApicWrite(pVCpu, offApicWrite); 4889 break; 4890 } 4891 } 4892 4893 return rcStrict; 4830 4894 } 4831 4895
Note:
See TracChangeset
for help on using the changeset viewer.