VirtualBox

Changeset 72470 in vbox


Ignore:
Timestamp:
Jun 7, 2018 11:41:23 AM (7 years ago)
Author:
vboxsync
Message:

NEM/win: Looks like we can get a stop confirmation first time around in nemHCWinStopCpu, so just deal with it. Did the necessary #UD forwarding to GIM (not needed for NEM/win). bugref:9044

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h

    r72463 r72470  
    26832683         * We get undefined opcodes on VMMCALL(AMD) & VMCALL(Intel) instructions
    26842684         * and need to turn them over to GIM.
     2685         *
     2686         * Note! We do not check fGIMTrapXcptUD here ASSUMING that GIM only wants
     2687         *       #UD for handling non-native hypercall instructions.  (IEM will
     2688         *       decode both and let the GIM provider decide whether to accept it.)
    26852689         */
    26862690        case X86_XCPT_UD:
    26872691            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionUd);
    2688             /** @todo Call GIMXcptUD if required. */
    26892692            if (nemHcWinIsInterestingUndefinedOpcode(pMsg->InstructionByteCount, pMsg->InstructionBytes,
    26902693                                                     pMsg->Header.ExecutionState.EferLma && pMsg->Header.CsSegment.Long ))
     
    27732776         * We get undefined opcodes on VMMCALL(AMD) & VMCALL(Intel) instructions
    27742777         * and need to turn them over to GIM.
     2778         *
     2779         * Note! We do not check fGIMTrapXcptUD here ASSUMING that GIM only wants
     2780         *       #UD for handling non-native hypercall instructions.  (IEM will
     2781         *       decode both and let the GIM provider decide whether to accept it.)
    27752782         */
    27762783        case X86_XCPT_UD:
    27772784            STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatExitExceptionUd);
    2778             /** @todo Call GIMXcptUD if required. */
    27792785            if (nemHcWinIsInterestingUndefinedOpcode(pExit->VpException.InstructionByteCount, pExit->VpException.InstructionBytes,
    27802786                                                     pExit->VpContext.ExecutionState.EferLma && pExit->VpContext.Cs.Long ))
     
    29472953#endif /* IN_RING3 && !NEM_WIN_USE_OUR_OWN_RUN_API */
    29482954
     2955
    29492956#ifdef NEM_WIN_USE_OUR_OWN_RUN_API
    29502957/**
     
    31073114}
    31083115#endif /* IN_RING3 && !NEM_WIN_USE_OUR_OWN_RUN_API */
     3116
    31093117
    31103118#ifdef NEM_WIN_USE_OUR_OWN_RUN_API
     
    31713179
    31723180    /*
    3173      * First message: Exit or similar.
     3181     * First message: Exit or similar, sometimes VidMessageStopRequestComplete.
    31743182     * Note! We can safely ASSUME that rcStrict isn't an important information one.
    31753183     */
     
    31913199# endif
    31923200
    3193     /* It should be a hypervisor message and definitely not a stop request completed message. */
    31943201    VID_MESSAGE_TYPE enmVidMsgType = pMappingHeader->enmVidMsgType;
    3195     AssertLogRelMsgReturn(enmVidMsgType != VidMessageStopRequestComplete,
    3196                           ("Unexpected 1st message following ERROR_VID_STOP_PENDING: %#x LB %#x\n",
    3197                            enmVidMsgType, pMappingHeader->cbMessage),
    3198                           RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    3199 
    3200     VBOXSTRICTRC rcStrict2 = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, CPUMQueryGuestCtxPtr(pVCpu), pGVCpu);
    3201     if (rcStrict2 != VINF_SUCCESS && RT_SUCCESS(rcStrict))
    3202         rcStrict = rcStrict2;
    3203 
    3204     /*
    3205      * Mark it as handled and get the stop request completed message, then mark
    3206      * that as handled too.  CPU is back into fully stopped stated then.
    3207      */
     3202    if (enmVidMsgType != VidMessageStopRequestComplete)
     3203    {
     3204        VBOXSTRICTRC rcStrict2 = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, CPUMQueryGuestCtxPtr(pVCpu), pGVCpu);
     3205        if (rcStrict2 != VINF_SUCCESS && RT_SUCCESS(rcStrict))
     3206            rcStrict = rcStrict2;
     3207
     3208        /*
     3209         * Mark it as handled and get the stop request completed message, then mark
     3210         * that as handled too.  CPU is back into fully stopped stated then.
     3211         */
    32083212# ifdef IN_RING0
    3209     pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
    3210     pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE;
    3211     pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
    3212     rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
    3213                                    &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
    3214                                    sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
    3215                                    NULL, 0);
    3216     AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    3217                           RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
     3213        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
     3214        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE;
     3215        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
     3216        rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     3217                                       &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     3218                                       sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
     3219                                       NULL, 0);
     3220        AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
     3221                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    32183222# else
    3219     fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    3220                                                 VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
    3221     AssertLogRelMsgReturn(fWait, ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    3222                           RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
     3223        fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
     3224                                                    VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
     3225        AssertLogRelMsgReturn(fWait, ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
     3226                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    32233227# endif
    32243228
    3225     /* It should be a stop request completed message. */
    3226     enmVidMsgType = pMappingHeader->enmVidMsgType;
    3227     AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete,
    3228                           ("Unexpected 2nd message following ERROR_VID_STOP_PENDING: %#x LB %#x\n",
    3229                            enmVidMsgType, pMappingHeader->cbMessage),
    3230                           RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    3231 
    3232     /* Mark this as handled. */
     3229        /* It should be a stop request completed message. */
     3230        enmVidMsgType = pMappingHeader->enmVidMsgType;
     3231        AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete,
     3232                              ("Unexpected 2nd message following ERROR_VID_STOP_PENDING: %#x LB %#x\n",
     3233                               enmVidMsgType, pMappingHeader->cbMessage),
     3234                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
     3235    }
     3236    else
     3237        Log8(("nemHCWinStopCpu: 1st VidMessageSlotHandleAndGetNext got VidMessageStopRequestComplete.\n"));
     3238
     3239    /*
     3240     * Mark the VidMessageStopRequestComplete message as handled.
     3241     */
    32333242# ifdef IN_RING0
    32343243    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu     = pGVCpu->idCpu;
  • trunk/src/VBox/VMM/VMMR3/NEMR3.cpp

    r72343 r72470  
    3232#define LOG_GROUP LOG_GROUP_NEM
    3333#include <VBox/vmm/nem.h>
     34#include <VBox/vmm/gim.h>
    3435#include "NEMInternal.h"
    3536#include <VBox/vmm/vm.h>
     
    209210VMMR3_INT_DECL(int) NEMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
    210211{
     212    /*
     213     * Check if GIM needs #UD, since that applies to everyone.
     214     */
     215    if (enmWhat == VMINITCOMPLETED_RING3)
     216        for (VMCPUID iCpu = 0; iCpu < pVM->cCpus; iCpu++)
     217            pVM->aCpus[iCpu].nem.s.fGIMTrapXcptUD = GIMShouldTrapXcptUD(&pVM->aCpus[iCpu]);
     218
     219    /*
     220     * Call native code.
     221     */
    211222    int rc = VINF_SUCCESS;
    212223#ifdef VBOX_WITH_NATIVE_NEM
  • trunk/src/VBox/VMM/include/NEMInternal.h

    r72463 r72470  
    190190    /** NEMCPU_MAGIC. */
    191191    uint32_t                    u32Magic;
     192    /** Whether \#UD needs to be intercepted and presented to GIM. */
     193    bool                        fGIMTrapXcptUD : 1;
    192194#ifdef RT_OS_WINDOWS
    193195    /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
     
    197199    /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
    198200    bool                        fLastInterruptShadow : 1;
    199     bool                        afPadding[1];
    200201    /** Pending APIC base value.
    201202     * This is set to UINT64_MAX when not pending  */
Note: See TracChangeset for help on using the changeset viewer.

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