VirtualBox

Changeset 72687 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 26, 2018 1:52:02 AM (7 years ago)
Author:
vboxsync
Message:

NEM: Apparently the IoCtlMessageSlotHandleAndGetNext operation may be distrubed by NtAlertThread, so added a restart wrapper for the nemHCWinStopCpu() code. bugref:9044

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

Legend:

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

    r72684 r72687  
    13731373                if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED, VMCPUSTATE_STARTED_EXEC_NEM))
    13741374                {
     1375                    DBGFTRACE_CUSTOM(pVM, "VMCPUSTATE_STARTED_EXEC_NEM -> CANCELED");
    13751376                    Log8(("nemHCWinCancelRunVirtualProcessor: Switched %u to canceled state\n", pVCpu->idCpu));
    13761377                    STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatCancelChangedState);
     
    13821383                if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT))
    13831384                {
     1385                    DBGFTRACE_CUSTOM(pVM, "VMCPUSTATE_STARTED_EXEC_NEM_WAIT -> CANCELED");
    13841386#  ifdef IN_RING0
    13851387                    NTSTATUS rcNt = KeAlertThread(??);
     1388                    DBGFTRACE_CUSTOM(pVM, "KeAlertThread -> %#x", rcNt);
    13861389#  else
    13871390                    NTSTATUS rcNt = NtAlertThread(pVCpu->nem.s.hNativeThreadHandle);
     1391                    DBGFTRACE_CUSTOM(pVM, "NtAlertThread -> %#x", rcNt);
    13881392#  endif
    13891393                    Log8(("nemHCWinCancelRunVirtualProcessor: Alerted %u: %#x\n", pVCpu->idCpu, rcNt));
     
    37413745                                             PGVM pGVM, PGVMCPU pGVCpu)
    37423746{
     3747# ifdef DBGFTRACE_ENABLED
     3748    HV_MESSAGE const volatile *pMsgForTrace = (HV_MESSAGE const volatile *)(pMappingHeader + 1);
     3749# endif
     3750
    37433751    /*
    37443752     * Try stopping the processor.  If we're lucky we manage to do this before it
    37453753     * does another VM exit.
    37463754     */
     3755    DBGFTRACE_CUSTOM(pVM, "nemStop#0");
    37473756# ifdef IN_RING0
    37483757    pVCpu->nem.s.uIoCtlBuf.idCpu = pGVCpu->idCpu;
     
    37523761    if (NT_SUCCESS(rcNt))
    37533762    {
     3763        DBGFTRACE_CUSTOM(pVM, "nemStop#0: okay (%#x)", rcNt);
    37543764        Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    37553765        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuSuccess);
     
    37603770    if (fRet)
    37613771    {
     3772        DBGFTRACE_CUSTOM(pVM, "nemStop#0: okay");
    37623773        Log8(("nemHCWinStopCpu: Stopping CPU succeeded (cpu status %u)\n", nemHCWinCpuGetRunningStatus(pVCpu) ));
    37633774        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuSuccess);
     
    37713782     */
    37723783# ifdef IN_RING0
     3784    DBGFTRACE_CUSTOM(pVM, "nemStop#0: pending (%#x)", rcNt);
    37733785    AssertLogRelMsgReturn(rcNt == ERROR_VID_STOP_PENDING, ("rcNt=%#x\n", rcNt),
    37743786                          RT_SUCCESS(rcStrict) ?  VERR_NEM_IPE_5 : rcStrict);
    37753787# else
    37763788    DWORD dwErr = RTNtLastErrorValue();
     3789    DBGFTRACE_CUSTOM(pVM, "nemStop#0: pending (%#x)", dwErr);
    37773790    AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u (%#x)\n", dwErr, dwErr),
    37783791                          RT_SUCCESS(rcStrict) ?  VERR_NEM_IPE_5 : rcStrict);
     
    37893802    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_GET_NEXT_MESSAGE;
    37903803    pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
    3791     rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
    3792                                    &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
    3793                                    sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
    3794                                    NULL, 0);
    3795     AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
     3804    rcNt = nemR0NtPerformIoControlRestart(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     3805                                          &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     3806                                          sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext));
     3807    DBGFTRACE_CUSTOM(pVM, "nemStop#1: %#x / %#x %#x %#x", rcNt, pMappingHeader->enmVidMsgType, pMappingHeader->cbMessage,
     3808                     pMsgForTrace->Header.MessageType);
     3809    AssertLogRelMsgReturn(rcNt == STATUS_SUCCESS,
     3810                          ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    37963811                          RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    37973812# else
    37983813    BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    37993814                                                     VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
     3815    DBGFTRACE_CUSTOM(pVM, "nemStop#1: %d+%#x / %#x %#x %#x", fWait, RTNtLastErrorValue(), pMappingHeader->enmVidMsgType,
     3816                     pMappingHeader->cbMessage, pMsgForTrace->Header.MessageType);
    38003817    AssertLogRelMsgReturn(fWait, ("1st VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    38013818                          RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
     
    38083825        if (rcStrict2 != VINF_SUCCESS && RT_SUCCESS(rcStrict))
    38093826            rcStrict = rcStrict2;
     3827        DBGFTRACE_CUSTOM(pVM, "nemStop#1: handled %#x -> %d", pMsgForTrace->Header.MessageType, VBOXSTRICTRC_VAL(rcStrict));
    38103828
    38113829        /*
     
    38173835        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE;
    38183836        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
    3819         rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
    3820                                        &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
    3821                                        sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
    3822                                        NULL, 0);
    3823         AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
     3837        rcNt = nemR0NtPerformIoControlRestart(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     3838                                              &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     3839                                              sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext));
     3840        DBGFTRACE_CUSTOM(pVM, "nemStop#2: %#x / %#x %#x %#x", rcNt, pMappingHeader->enmVidMsgType, pMappingHeader->cbMessage,
     3841                         pMsgForTrace->Header.MessageType);
     3842        AssertLogRelMsgReturn(rcNt == STATUS_SUCCESS,
     3843                              ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    38243844                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    38253845# else
    38263846        fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu,
    38273847                                                    VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 30000 /*ms*/);
     3848        DBGFTRACE_CUSTOM(pVM, "nemStop#2: %d+%#x / %#x %#x %#x", fWait, RTNtLastErrorValue(), pMappingHeader->enmVidMsgType,
     3849                         pMappingHeader->cbMessage, pMsgForTrace->Header.MessageType);
    38283850        AssertLogRelMsgReturn(fWait, ("2nd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    38293851                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
     
    38443866        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.fFlags   = VID_MSHAGN_F_HANDLE_MESSAGE;
    38453867        pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.cMillies = 30000; /*ms*/
    3846         rcNt = nemR0NtPerformIoControl(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
    3847                                        &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
    3848                                        sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext),
    3849                                        NULL, 0);
    3850         AssertLogRelMsgReturn(NT_SUCCESS(rcNt), ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
     3868        rcNt = nemR0NtPerformIoControlRestart(pGVM, pGVM->nem.s.IoCtlMessageSlotHandleAndGetNext.uFunction,
     3869                                              &pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext,
     3870                                              sizeof(pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext));
     3871        DBGFTRACE_CUSTOM(pVM, "nemStop#3: %#x / %#x %#x %#x", rcNt, pMappingHeader->enmVidMsgType,
     3872                         pMsgForTrace->Header.MessageType, pMappingHeader->cbMessage, pMsgForTrace->Header.MessageType);
     3873        AssertLogRelMsgReturn(rcNt == STATUS_SUCCESS,
     3874                              ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %#x\n", rcNt),
    38513875                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
    38523876# else
    38533877        fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, VID_MSHAGN_F_HANDLE_MESSAGE, 30000 /*ms*/);
     3878        DBGFTRACE_CUSTOM(pVM, "nemStop#3: %d+%#x / %#x %#x %#x", fWait, RTNtLastErrorValue(), pMappingHeader->enmVidMsgType,
     3879                         pMsgForTrace->Header.MessageType, pMappingHeader->cbMessage, pMsgForTrace->Header.MessageType);
    38543880        AssertLogRelMsgReturn(fWait, ("3rd VidMessageSlotHandleAndGetNext after ERROR_VID_STOP_PENDING failed: %u\n", RTNtLastErrorValue()),
    38553881                              RT_SUCCESS(rcStrict) ? VERR_NEM_IPE_5 : rcStrict);
     
    38593885    else
    38603886    {
     3887        DBGFTRACE_CUSTOM(pVM, "nemStop#9: %#x %#x %#x", pMappingHeader->enmVidMsgType,
     3888                         pMappingHeader->cbMessage, pMsgForTrace->Header.MessageType);
    38613889        STAM_REL_COUNTER_INC(&pVCpu->nem.s.StatStopCpuPendingOdd);
    38623890        Log8(("nemHCWinStopCpu: Stopped the CPU (rcStrict=%Rrc) - 1st VidMessageSlotHandleAndGetNext got VidMessageStopRequestComplete.\n",
  • trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp

    r72546 r72687  
    3232#include <VBox/vmm/apic.h>
    3333#include <VBox/vmm/pdm.h>
     34#include <VBox/vmm/dbgftrace.h>
    3435#include "NEMInternal.h"
    3536#include <VBox/vmm/gvm.h>
     
    8788DECLINLINE(NTSTATUS) nemR0NtPerformIoControl(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput,
    8889                                             void *pvOutput, uint32_t cbOutput);
     90DECLINLINE(NTSTATUS) nemR0NtPerformIoControlRestart(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput);
    8991
    9092
     
    269271
    270272/**
     273 * Perform an I/O control operation on the partition handle (VID.SYS),
     274 * restarting on alert-like behaviour.
     275 *
     276 * @returns NT status code.
     277 * @param   pGVM            The ring-0 VM structure.
     278 * @param   uFunction       The function to perform.
     279 * @param   pvInput         The input buffer.  This must point within the VM
     280 *                          structure so we can easily convert to a ring-3
     281 *                          pointer if necessary.
     282 * @param   cbInput         The size of the input.  @a pvInput must be NULL when
     283 *                          zero.
     284 */
     285DECLINLINE(NTSTATUS) nemR0NtPerformIoControlRestart(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput)
     286{
     287#ifdef RT_STRICT
     288    /*
     289     * Input and output parameters are part of the VM CPU structure.
     290     */
     291    PVM          pVM  = pGVM->pVM;
     292    size_t const cbVM = RT_UOFFSETOF(VM, aCpus[pGVM->cCpus]);
     293    if (pvInput)
     294        AssertReturn(((uintptr_t)pvInput + cbInput) - (uintptr_t)pVM <= cbVM, VERR_INVALID_PARAMETER);
     295#endif
     296
     297    int32_t rcNt = STATUS_UNSUCCESSFUL;
     298    int rc = SUPR0IoCtlPerform(pGVM->nem.s.pIoCtlCtx, uFunction,
     299                               pvInput,
     300                               pvInput ? (uintptr_t)pvInput  + pGVM->nem.s.offRing3ConversionDelta : NIL_RTR3PTR,
     301                               cbInput,
     302                               NULL,
     303                               NIL_RTR3PTR,
     304                               0,
     305                               &rcNt);
     306    if (RT_SUCCESS(rc) || !NT_SUCCESS((NTSTATUS)rcNt))
     307    {
     308        if (RT_LIKELY(rcNt == STATUS_SUCCESS))
     309            return rcNt;
     310
     311        if (   rcNt == STATUS_TIMEOUT
     312            || rcNt == STATUS_ALERTED)
     313        {
     314            DBGFTRACE_CUSTOM(pVM, "nemR0NtPerformIoControlRestart/1 %#x", rcNt);
     315            rcNt = STATUS_UNSUCCESSFUL;
     316            rc = SUPR0IoCtlPerform(pGVM->nem.s.pIoCtlCtx, uFunction,
     317                                   pvInput,
     318                                   pvInput ? (uintptr_t)pvInput  + pGVM->nem.s.offRing3ConversionDelta : NIL_RTR3PTR,
     319                                   cbInput,
     320                                   NULL,
     321                                   NIL_RTR3PTR,
     322                                   0,
     323                                   &rcNt);
     324            if (!RT_SUCCESS(rc) && NT_SUCCESS((NTSTATUS)rcNt))
     325                rcNt = STATUS_UNSUCCESSFUL;
     326            DBGFTRACE_CUSTOM(pVM, "nemR0NtPerformIoControlRestart/2 %#x", rcNt);
     327        }
     328        return (NTSTATUS)rcNt;
     329    }
     330    return STATUS_UNSUCCESSFUL;
     331}
     332
     333
     334/**
    271335 * 2nd part of the initialization, after we've got a partition handle.
    272336 *
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r72673 r72687  
    5050#include <VBox/vmm/apic.h>
    5151#include <VBox/vmm/pdm.h>
     52#include <VBox/vmm/dbgftrace.h>
    5253#include "NEMInternal.h"
    5354#include <VBox/vmm/vm.h>
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