VirtualBox

Changeset 75632 in vbox for trunk/src


Ignore:
Timestamp:
Nov 21, 2018 9:30:42 AM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
126810
Message:

VMM/IEM: Nested VMX: bugref:9180 Re-arrange some VMX virtual-APIC functions.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r75631 r75632  
    911911
    912912/**
    913  * Sets virtual-APIC write emulation as pending.
    914  *
    915  * @param   pVCpu       The cross context virtual CPU structure.
    916  * @param   offApic     The offset in the virtual-APIC page that was written.
    917  */
    918 DECLINLINE(void) iemVmxVirtApicSetPendingWrite(PVMCPU pVCpu, uint16_t offApic)
    919 {
    920     Assert(offApic < XAPIC_OFF_END + 4);
    921 
    922     /*
    923      * Record the currently updated APIC offset, as we need this later for figuring
    924      * out whether to perform TPR, EOI or self-IPI virtualization as well as well
    925      * as for supplying the exit qualification when causing an APIC-write VM-exit.
    926      */
    927     pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offApic;
    928 
    929     /*
    930      * Signal that we need to perform virtual-APIC write emulation (TPR/PPR/EOI/Self-IPI
    931      * virtualization or APIC-write emulation).
    932      */
    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.
    942  * @param   pVCpu       The cross context virtual CPU structure.
    943  */
    944 DECLINLINE(uint16_t) iemVmxVirtApicClearPendingWrite(PVMCPU pVCpu)
    945 {
    946     uint8_t const offVirtApicWrite = pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite;
    947     pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = 0;
    948     Assert(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE));
    949     VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
    950     return offVirtApicWrite;
    951 }
    952 
    953 
    954 /**
    955913 * Masks the nested-guest CR0/CR4 mask subjected to the corresponding guest/host
    956914 * mask and the read-shadow (CR0/CR4 read).
     
    39983956    iemVmxVmcsSetExitQual(pVCpu, 0);
    39993957    return iemVmxVmexit(pVCpu, VMX_EXIT_TRIPLE_FAULT);
     3958}
     3959
     3960
     3961/**
     3962 * VMX VM-exit handler for APIC-accesses.
     3963 *
     3964 * @param   pVCpu       The cross context virtual CPU structure.
     3965 * @param   offAccess   The offset of the register being accessed.
     3966 * @param   fAccess     The type of access (must contain IEM_ACCESS_TYPE_READ or
     3967 *                      IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION).
     3968 */
     3969IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicAccess(PVMCPU pVCpu, uint16_t offAccess, uint32_t fAccess)
     3970{
     3971    Assert((fAccess & IEM_ACCESS_TYPE_READ) || (fAccess & IEM_ACCESS_TYPE_WRITE) || (fAccess & IEM_ACCESS_INSTRUCTION));
     3972
     3973    VMXAPICACCESS enmAccess;
     3974    bool const fInEventDelivery = IEMGetCurrentXcpt(pVCpu, NULL, NULL, NULL, NULL);
     3975    if (fInEventDelivery)
     3976        enmAccess = VMXAPICACCESS_LINEAR_EVENT_DELIVERY;
     3977    else if (fAccess & IEM_ACCESS_INSTRUCTION)
     3978        enmAccess = VMXAPICACCESS_LINEAR_INSTR_FETCH;
     3979    else if (fAccess & IEM_ACCESS_TYPE_WRITE)
     3980        enmAccess = VMXAPICACCESS_LINEAR_WRITE;
     3981    else
     3982        enmAccess = VMXAPICACCESS_LINEAR_WRITE;
     3983
     3984    uint64_t const uExitQual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_APIC_ACCESS_OFFSET, offAccess)
     3985                             | RT_BF_MAKE(VMX_BF_EXIT_QUAL_APIC_ACCESS_TYPE,   enmAccess);
     3986    iemVmxVmcsSetExitQual(pVCpu, uExitQual);
     3987    return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_ACCESS);
     3988}
     3989
     3990
     3991/**
     3992 * VMX VM-exit handler for APIC-write VM-exits.
     3993 *
     3994 * @param   pVCpu       The cross context virtual CPU structure.
     3995 * @param   offApic     The write to the virtual-APIC page offset that caused this
     3996 *                      VM-exit.
     3997 */
     3998IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicWrite(PVMCPU pVCpu, uint16_t offApic)
     3999{
     4000    Assert(offApic < XAPIC_OFF_END + 4);
     4001    iemVmxVmcsSetExitQual(pVCpu, offApic);
     4002    return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_WRITE);
     4003}
     4004
     4005
     4006/**
     4007 * VMX VM-exit handler for virtualized-EOIs.
     4008 *
     4009 * @param   pVCpu       The cross context virtual CPU structure.
     4010 */
     4011IEM_STATIC VBOXSTRICTRC iemVmxVmexitVirtEoi(PVMCPU pVCpu, uint8_t uVector)
     4012{
     4013    iemVmxVmcsSetExitQual(pVCpu, uVector);
     4014    return iemVmxVmexit(pVCpu, VMX_EXIT_VIRTUALIZED_EOI);
     4015}
     4016
     4017
     4018/**
     4019 * Sets virtual-APIC write emulation as pending.
     4020 *
     4021 * @param   pVCpu       The cross context virtual CPU structure.
     4022 * @param   offApic     The offset in the virtual-APIC page that was written.
     4023 */
     4024DECLINLINE(void) iemVmxVirtApicSetPendingWrite(PVMCPU pVCpu, uint16_t offApic)
     4025{
     4026    Assert(offApic < XAPIC_OFF_END + 4);
     4027
     4028    /*
     4029     * Record the currently updated APIC offset, as we need this later for figuring
     4030     * out whether to perform TPR, EOI or self-IPI virtualization as well as well
     4031     * as for supplying the exit qualification when causing an APIC-write VM-exit.
     4032     */
     4033    pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offApic;
     4034
     4035    /*
     4036     * Signal that we need to perform virtual-APIC write emulation (TPR/PPR/EOI/Self-IPI
     4037     * virtualization or APIC-write emulation).
     4038     */
     4039    if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE))
     4040        VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
     4041}
     4042
     4043
     4044/**
     4045 * Clears any pending virtual-APIC write emulation.
     4046 *
     4047 * @returns The virtual-APIC offset that was written before clearing it.
     4048 * @param   pVCpu       The cross context virtual CPU structure.
     4049 */
     4050DECLINLINE(uint16_t) iemVmxVirtApicClearPendingWrite(PVMCPU pVCpu)
     4051{
     4052    uint8_t const offVirtApicWrite = pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite;
     4053    pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = 0;
     4054    Assert(VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE));
     4055    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
     4056    return offVirtApicWrite;
    40004057}
    40014058
     
    42764333
    42774334/**
    4278  * VMX VM-exit handler for APIC-accesses.
    4279  *
    4280  * @param   pVCpu       The cross context virtual CPU structure.
    4281  * @param   offAccess   The offset of the register being accessed.
    4282  * @param   fAccess     The type of access (must contain IEM_ACCESS_TYPE_READ or
    4283  *                      IEM_ACCESS_TYPE_WRITE or IEM_ACCESS_INSTRUCTION).
    4284  */
    4285 IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicAccess(PVMCPU pVCpu, uint16_t offAccess, uint32_t fAccess)
    4286 {
    4287     Assert((fAccess & IEM_ACCESS_TYPE_READ) || (fAccess & IEM_ACCESS_TYPE_WRITE) || (fAccess & IEM_ACCESS_INSTRUCTION));
    4288 
    4289     VMXAPICACCESS enmAccess;
    4290     bool const fInEventDelivery = IEMGetCurrentXcpt(pVCpu, NULL, NULL, NULL, NULL);
    4291     if (fInEventDelivery)
    4292         enmAccess = VMXAPICACCESS_LINEAR_EVENT_DELIVERY;
    4293     else if (fAccess & IEM_ACCESS_INSTRUCTION)
    4294         enmAccess = VMXAPICACCESS_LINEAR_INSTR_FETCH;
    4295     else if (fAccess & IEM_ACCESS_TYPE_WRITE)
    4296         enmAccess = VMXAPICACCESS_LINEAR_WRITE;
    4297     else
    4298         enmAccess = VMXAPICACCESS_LINEAR_WRITE;
    4299 
    4300     uint64_t const uExitQual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_APIC_ACCESS_OFFSET, offAccess)
    4301                              | RT_BF_MAKE(VMX_BF_EXIT_QUAL_APIC_ACCESS_TYPE,   enmAccess);
    4302     iemVmxVmcsSetExitQual(pVCpu, uExitQual);
    4303     return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_ACCESS);
    4304 }
    4305 
    4306 
    4307 /**
    4308  * VMX VM-exit handler for APIC-write VM-exits.
    4309  *
    4310  * @param   pVCpu       The cross context virtual CPU structure.
    4311  * @param   offApic     The write to the virtual-APIC page offset that caused this
    4312  *                      VM-exit.
    4313  */
    4314 IEM_STATIC VBOXSTRICTRC iemVmxVmexitApicWrite(PVMCPU pVCpu, uint16_t offApic)
    4315 {
    4316     Assert(offApic < XAPIC_OFF_END + 4);
    4317     iemVmxVmcsSetExitQual(pVCpu, offApic);
    4318     return iemVmxVmexit(pVCpu, VMX_EXIT_APIC_WRITE);
    4319 }
    4320 
    4321 
    4322 /**
    4323  * VMX VM-exit handler for virtualized-EOIs.
    4324  *
    4325  * @param   pVCpu       The cross context virtual CPU structure.
    4326  */
    4327 IEM_STATIC VBOXSTRICTRC iemVmxVmexitVirtEoi(PVMCPU pVCpu, uint8_t uVector)
    4328 {
    4329     iemVmxVmcsSetExitQual(pVCpu, uVector);
    4330     return iemVmxVmexit(pVCpu, VMX_EXIT_VIRTUALIZED_EOI);
    4331 }
    4332 
    4333 
    4334 /**
    43354335 * Virtualizes a memory-based APIC-access where the address is not used to access
    43364336 * memory.
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette