VirtualBox

Changeset 4979 in vbox for trunk/src


Ignore:
Timestamp:
Sep 22, 2007 12:04:09 AM (17 years ago)
Author:
vboxsync
Message:

New ring-0 assertion avoidance, now for all platforms.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMM.cpp

    r4971 r4979  
    641641        if (VBOX_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST))
    642642            break;
    643         break; // remove this when we do setjmp for all ring-0 stuff.
     643        /* Resume R0 */
    644644    }
    645645
     
    647647    {
    648648        LogRel(("R0 init failed, rc=%Vra\n", rc));
    649         if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
     649        if (VBOX_SUCCESS(rc))
    650650            rc = VERR_INTERNAL_ERROR;
    651651    }
     
    758758        if (VBOX_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST))
    759759            break;
    760         break; // remove this when we do setjmp for all ring-0 stuff.
     760        /* Resume R0 */
    761761    }
    762762    if (VBOX_FAILURE(rc) || (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST))
    763763    {
    764764        LogRel(("VMMR3Term: R0 term failed, rc=%Vra. (warning)\n", rc));
    765         if (rc >= VINF_EM_FIRST && rc <= VINF_EM_LAST)
     765        if (VBOX_SUCCESS(rc))
    766766            rc = VERR_INTERNAL_ERROR;
    767767    }
     
    22572257        /*
    22582258         * Signal a ring 0 hypervisor assertion.
     2259         * Cancel the longjmp operation that's in progress.
    22592260         */
    22602261        case VMMCALLHOST_VM_R0_HYPER_ASSERTION:
     2262            pVM->vmm.s.CallHostR0JmpBuf.fInRing3Call = false;
     2263#ifdef RT_ARCH_X86
     2264            pVM->vmm.s.CallHostR0JmpBuf.eip = 0;
     2265#else
     2266            pVM->vmm.s.CallHostR0JmpBuf.rip = 0;
     2267#endif
    22612268            return VINF_EM_DBG_HYPER_ASSERTION;
    22622269
  • trunk/src/VBox/VMM/VMMInternal.h

    r4787 r4979  
    404404
    405405/**
     406 * Callback function for vmmR0CallHostSetJmpEx.
     407 *
     408 * @returns VBox status code.
     409 * @param   pvUser      The user argument.
     410 */
     411typedef DECLCALLBACK(int) FNVMMR0SETJMPEX(void *pvUser);
     412/** Pointer to FNVMMR0SETJMP(). */
     413typedef FNVMMR0SETJMPEX *PFNVMMR0SETJMPEX;
     414
     415/**
     416 * Same as vmmR0CallHostSetJmp except for the function signature.
     417 *
     418 * @returns VINF_SUCCESS on success or whatever is passed to vmmR0CallHostLongJmp.
     419 * @param   pJmpBuf     The jmp_buf to set.
     420 * @param   pfn         The function to be called when not resuming..
     421 * @param   pvUser      The argument of that function.
     422 */
     423DECLASM(int)    vmmR0CallHostSetJmpEx(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMPEX pfn, void *pvUser);
     424
     425
     426/**
    406427 * Worker for VMMR0CallHost.
    407428 * This will save the stack and registers.
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r4971 r4979  
    5454__END_DECLS
    5555
    56 
    57 /** @def DEBUG_NO_RING0_ASSERTIONS
    58  * Define this if you don't wish to BSOD on debug assertions in
    59  * the VMMR0.r0 code. If would of course be nice to have this
    60  * feature enabled by default of course, but it's not currently
    61  * safe when more than one VM is running or when using internal
    62  * networking. */
    63 #if defined(DEBUG_sandervl) /*|| defined(DEBUG_bird)*/
    64 # define DEBUG_NO_RING0_ASSERTIONS
    65 #endif
    66 #ifdef DEBUG_NO_RING0_ASSERTIONS
    67 static PVM g_pVMAssert = 0;
    68 #endif
    6956
    7057/*******************************************************************************
     
    616603            if (VBOX_SUCCESS(rc))
    617604            {
    618 #ifdef DEBUG_NO_RING0_ASSERTIONS
    619                 g_pVMAssert = pVM;
    620 #endif
    621605                rc = vmmR0CallHostSetJmp(&pVM->vmm.s.CallHostR0JmpBuf, HWACCMR0RunGuestCode, pVM); /* this may resume code. */
    622 #ifdef DEBUG_NO_RING0_ASSERTIONS
    623                 g_pVMAssert = NULL;
    624 #endif
    625606                int rc2 = HWACCMR0Disable(pVM);
    626607                AssertRC(rc2);
     
    655636
    656637/**
    657  * The Ring 0 entry point, called by the support library (SUP).
     638 * VMMR0EntryEx worker function, either called directly or when ever possible
     639 * called thru a longjmp so we can exit safely on failure.
    658640 *
    659641 * @returns VBox status code.
     
    664646 * @remarks Assume called with interrupts _enabled_.
    665647 */
    666 VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg)
     648static int vmmR0EntryExWorker(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg)
    667649{
    668650    switch (enmOperation)
     
    672654         */
    673655        case VMMR0_DO_VMMR0_INIT:
    674         {
    675             int rc = VMMR0Init(pVM, (unsigned)u64Arg);
    676             return rc;
    677         }
     656            return VMMR0Init(pVM, (unsigned)u64Arg);
    678657
    679658        /*
     
    681660         */
    682661        case VMMR0_DO_VMMR0_TERM:
    683         {
    684             int rc = VMMR0Term(pVM);
    685             return rc;
    686         }
     662            return VMMR0Term(pVM);
    687663
    688664        /*
     
    833809
    834810
     811/**
     812 * Argument for vmmR0EntryExWrapper containing the argument s ofr VMMR0EntryEx.
     813 */
     814typedef struct VMMR0ENTRYEXARGS
     815{
     816    PVM                 pVM;
     817    VMMR0OPERATION      enmOperation;
     818    PSUPVMMR0REQHDR     pReq;
     819    uint64_t            u64Arg;
     820} VMMR0ENTRYEXARGS;
     821/** Pointer to a vmmR0EntryExWrapper argument package. */
     822typedef VMMR0ENTRYEXARGS *PVMMR0ENTRYEXARGS;
     823
     824/**
     825 * This is just a longjmp wrapper function for VMMR0EntryEx calls.
     826 *
     827 * @returns VBox status code.
     828 * @param   pvArgs      The argument package
     829 */
     830static int vmmR0EntryExWrapper(void *pvArgs)
     831{
     832    return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pVM,
     833                              ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation,
     834                              ((PVMMR0ENTRYEXARGS)pvArgs)->pReq,
     835                              ((PVMMR0ENTRYEXARGS)pvArgs)->u64Arg);
     836}
     837
     838
     839/**
     840 * The Ring 0 entry point, called by the support library (SUP).
     841 *
     842 * @returns VBox status code.
     843 * @param   pVM             The VM to operate on.
     844 * @param   enmOperation    Which operation to execute.
     845 * @param   pReq            This points to a SUPVMMR0REQHDR packet. Optional.
     846 * @param   u64Arg          Some simple constant argument.
     847 * @remarks Assume called with interrupts _enabled_.
     848 */
     849VMMR0DECL(int) VMMR0EntryEx(PVM pVM, VMMR0OPERATION enmOperation, PSUPVMMR0REQHDR pReq, uint64_t u64Arg)
     850{
     851    /*
     852     * Requests that should only happen on the EMT thread will be
     853     * wrapped in a setjmp so we can assert without causing trouble.
     854     */
     855    if (    VALID_PTR(pVM)
     856        &&  pVM->pVMR0)
     857    {
     858        switch (enmOperation)
     859        {
     860            case VMMR0_DO_VMMR0_INIT:
     861            case VMMR0_DO_VMMR0_TERM:
     862            {
     863                VMMR0ENTRYEXARGS Args;
     864                Args.pVM = pVM;
     865                Args.enmOperation = enmOperation;
     866                Args.pReq = pReq;
     867                Args.u64Arg = u64Arg;
     868                return vmmR0CallHostSetJmpEx(&pVM->vmm.s.CallHostR0JmpBuf, vmmR0EntryExWrapper, &Args);
     869            }
     870
     871            default:
     872                break;
     873        }
     874    }
     875    return vmmR0EntryExWorker(pVM, enmOperation, pReq, u64Arg);
     876}
     877
    835878
    836879
     
    883926
    884927
    885 #ifdef DEBUG_NO_RING0_ASSERTIONS
    886 /**
    887  * Check if we really want to hit a breakpoint.
    888  * Can jump back to ring-3 when the longjmp is armed.
    889  */
    890 DECLEXPORT(bool) RTCALL  RTAssertDoBreakpoint()
    891 {
    892     if (g_pVMAssert)
    893     {
    894         int rc = VMMR0CallHost(g_pVMAssert, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0);
    895         if (rc == VINF_SUCCESS)
    896             rc = g_pVMAssert->vmm.s.rcCallHost;
    897     }
    898 
    899     return false;
    900 }
    901 #endif /* !DEBUG_NO_RING0_ASSERTIONS */
     928
     929/**
     930 * Jump back to ring-3 if we're the EMT and the longjmp is armed.
     931 *
     932 * @returns true if the breakpoint should be hit, false if it should be ignored.
     933 * @remark  The RTDECL() makes this a bit difficult to override on windows. Sorry.
     934 */
     935DECLEXPORT(bool) RTCALL RTAssertDoBreakpoint()
     936{
     937    PVM pVM = GVMR0ByEMT(NIL_RTNATIVETHREAD);
     938    if (pVM)
     939    {
     940#ifdef RT_ARCH_X86
     941        if (pVM->vmm.s.CallHostR0JmpBuf.eip)
     942#else
     943        if (pVM->vmm.s.CallHostR0JmpBuf.rip)
     944#endif
     945        {
     946            int rc = VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0);
     947            return RT_FAILURE_NP(rc);
     948        }
     949    }
     950    return true;
     951}
    902952
    903953
     
    906956# define LOG_GROUP LOG_GROUP_EM
    907957
    908 DECLEXPORT(void) RTCALL RTR0AssertBreakpoint(void *pvVM)
    909 {
    910     if (pvVM)
    911     {
    912         PVM pVM = (PVM)pvVM;
    913         VMMR0CallHost(pVM, VMMCALLHOST_VM_R0_HYPER_ASSERTION, 0);
    914         /* does not return */
    915     }
    916 }
    917 
    918 
     958/**
     959 * Override this so we can push
     960 *
     961 * @param   pszExpr     Expression. Can be NULL.
     962 * @param   uLine       Location line number.
     963 * @param   pszFile     Location file name.
     964 * @param   pszFunction Location function name.
     965 * @remark  This API exists in HC Ring-3 and GC.
     966 */
    919967DECLEXPORT(void) RTCALL AssertMsg1(const char *pszExpr, unsigned uLine, const char *pszFile, const char *pszFunction)
    920968{
     
    939987    for (size_t i = 0; i < cbChars; i++)
    940988    {
    941         LogRel(("%c", pachChars[i]));
     989        LogRel(("%c", pachChars[i])); /** @todo this isn't any release logging in ring-0 from what I can tell... */
    942990        SUPR0Printf("%c", pachChars[i]);
    943991    }
     
    9591007    }
    9601008}
     1009
     1010
  • trunk/src/VBox/VMM/VMMR0/VMMR0A.asm

    r4477 r4979  
    4141; @param    pJmpBuf msc:rcx gcc:rdi x86:[esp+4]     Our jmp_buf.
    4242; @param    pfn     msc:rdx gcc:rsi x86:[esp+8]     The function to be called when not resuming.
    43 ; @param    pVM     msc:r8  gcc:rdx x86:[esp+c]     The argument of that function.
     43; @param    pvUser  msc:r8  gcc:rdx x86:[esp+c]     The argument of that function.
    4444;
    4545BEGINPROC vmmR0CallHostSetJmp
     46GLOBALNAME vmmR0CallHostSetJmpEx
    4647%ifdef RT_ARCH_X86
    4748    ;
     
    135136 %else
    136137    sub     rsp, 10h
    137     mov     r8, rdx                     ; pVM (save it like MSC)
     138    mov     r8, rdx                     ; pvUser (save it like MSC)
    138139    mov     r11, rsi                    ; pfn
    139140    mov     rdx, rdi                    ; pJmpBuf
     
    163164    mov     [rbp - 8], rdx              ; Save it and fix stack alignment (16).
    164165 %ifdef ASM_CALL64_MSC
    165     mov     rcx, r8                     ; pVM -> arg0
     166    mov     rcx, r8                     ; pvUser -> arg0
    166167 %else
    167     mov     rdi, r8                     ; pVM -> arg0
     168    mov     rdi, r8                     ; pvUser -> arg0
    168169 %endif
    169170    call    r11
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