VirtualBox

Changeset 76836 in vbox for trunk


Ignore:
Timestamp:
Jan 16, 2019 12:25:17 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
128194
Message:

VMM/IEM: Nested VMX: bugref:9180 Initialize all read-only VMCS data fields to 0 on VM-entry because we don't set every one of these fields on every VM-exit but some of them are not undefined (like Exit-qualification and VM-exit interruption info's valid bit). If we don't initialize these on VM-entry (or on every VM-exit), we risk confusing the nested hypervisor.

File:
1 edited

Legend:

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

    r76831 r76836  
    30773077
    30783078    /* Cause the MTF VM-exit. The VM-exit qualification MBZ. */
    3079     iemVmxVmcsSetExitQual(pVCpu, 0);
    30803079    return iemVmxVmexit(pVCpu, VMX_EXIT_MTF);
    30813080}
     
    37953794
    37963795            /* Cause the VMX-preemption timer VM-exit. The VM-exit qualification MBZ. */
    3797             iemVmxVmcsSetExitQual(pVCpu, 0);
    37983796            return iemVmxVmexit(pVCpu, VMX_EXIT_PREEMPT_TIMER);
    37993797        }
     
    38303828             */
    38313829            if (!(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_ACK_EXT_INT))
    3832             {
    3833                 iemVmxVmcsSetExitIntInfo(pVCpu, 0);
    3834                 iemVmxVmcsSetExitIntErrCode(pVCpu, 0);
    3835                 iemVmxVmcsSetExitQual(pVCpu, 0);
    38363830                return iemVmxVmexit(pVCpu, VMX_EXIT_EXT_INT);
    3837             }
    38383831
    38393832            /*
     
    38613854                                          | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID,            1);
    38623855            iemVmxVmcsSetExitIntInfo(pVCpu, uExitIntInfo);
    3863             iemVmxVmcsSetExitIntErrCode(pVCpu, 0);
    3864             iemVmxVmcsSetExitQual(pVCpu, 0);
    38653856            return iemVmxVmexit(pVCpu, VMX_EXIT_EXT_INT);
    38663857        }
     
    38933884IEM_STATIC VBOXSTRICTRC iemVmxVmexitInitIpi(PVMCPU pVCpu)
    38943885{
    3895     iemVmxVmcsSetExitQual(pVCpu, 0);
    38963886    return iemVmxVmexit(pVCpu, VMX_EXIT_INIT_SIGNAL);
    38973887}
     
    39063896IEM_STATIC VBOXSTRICTRC iemVmxVmexitIntWindow(PVMCPU pVCpu)
    39073897{
    3908     iemVmxVmcsSetExitQual(pVCpu, 0);
    39093898    return iemVmxVmexit(pVCpu, VMX_EXIT_INT_WINDOW);
    39103899}
     
    40584047IEM_STATIC VBOXSTRICTRC iemVmxVmexitTripleFault(PVMCPU pVCpu)
    40594048{
    4060     iemVmxVmcsSetExitQual(pVCpu, 0);
    40614049    return iemVmxVmexit(pVCpu, VMX_EXIT_TRIPLE_FAULT);
    40624050}
     
    48074795        {
    48084796            Log2(("tpr_virt: uTpr=%u uTprThreshold=%u -> VM-exit\n", uTpr, uTprThreshold));
    4809             iemVmxVmcsSetExitQual(pVCpu, 0);
    48104797            return iemVmxVmexit(pVCpu, VMX_EXIT_TPR_BELOW_THRESHOLD);
    48114798        }
     
    71897176
    71907177/**
     7178 * Initializes all read-only VMCS fields as part of VM-entry.
     7179 *
     7180 * @param   pVCpu       The cross context virtual CPU structure.
     7181 */
     7182IEM_STATIC void iemVmxVmentryInitReadOnlyFields(PVMCPU pVCpu)
     7183{
     7184    /*
     7185     * Any VMCS field which we do not establish on every VM-exit but may potentially
     7186     * be used on the VM-exit path of a nested hypervisor -and- is not explicitly
     7187     * specified to be undefined needs to be initialized here.
     7188     *
     7189     * Thus, it is especially important to clear the VM-exit qualification field
     7190     * since it must be zero for VM-exits where it is not used. Similarly, the
     7191     * VM-exit interruption information field's valid bit needs to be cleared for
     7192     * the same reasons.
     7193     */
     7194    PVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     7195    Assert(pVmcs);
     7196
     7197    /* 16-bit (none currently). */
     7198    /* 32-bit. */
     7199    pVmcs->u32RoVmInstrError        = 0;
     7200    pVmcs->u32RoExitReason          = 0;
     7201    pVmcs->u32RoExitIntInfo         = 0;
     7202    pVmcs->u32RoExitIntErrCode      = 0;
     7203    pVmcs->u32RoIdtVectoringInfo    = 0;
     7204    pVmcs->u32RoIdtVectoringErrCode = 0;
     7205    pVmcs->u32RoExitInstrLen        = 0;
     7206    pVmcs->u32RoExitInstrInfo       = 0;
     7207
     7208    /* 64-bit. */
     7209    pVmcs->u64RoGuestPhysAddr.u     = 0;
     7210
     7211    /* Natural-width. */
     7212    pVmcs->u64RoExitQual.u          = 0;
     7213    pVmcs->u64RoIoRcx.u             = 0;
     7214    pVmcs->u64RoIoRsi.u             = 0;
     7215    pVmcs->u64RoIoRdi.u             = 0;
     7216    pVmcs->u64RoIoRip.u             = 0;
     7217    pVmcs->u64RoGuestLinearAddr.u   = 0;
     7218}
     7219
     7220
     7221/**
    71917222 * VMLAUNCH/VMRESUME instruction execution worker.
    71927223 *
     
    72997330                if (RT_SUCCESS(rc))
    73007331                {
    7301                     /* Initialize the VM-exit qualification field as it MBZ for VM-exits where it isn't specified. */
    7302                     iemVmxVmcsSetExitQual(pVCpu, 0);
     7332                    /* Initialize read-only VMCS fields before VM-entry since we don't update all of them for every VM-exit. */
     7333                    iemVmxVmentryInitReadOnlyFields(pVCpu);
    73037334
    73047335                    /*
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