VirtualBox

Changeset 90189 in vbox


Ignore:
Timestamp:
Jul 14, 2021 4:39:09 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
145709
Message:

VMM: Make the setjmp code a bit stricter with when to resume a call. bugref:10064 ticketref:20090 ticketref:20456

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/gvm.h

    r87792 r90189  
    104104#endif
    105105
     106    union
     107    {
     108#if defined(VMM_INCLUDED_SRC_include_VMMInternal_h) && defined(IN_RING0)
     109        struct VMMR0PERVCPU s;
     110#endif
     111        uint8_t             padding[64];
     112    } vmmr0;
     113
    106114    /** Padding the structure size to page boundrary. */
    107115#ifdef VBOX_WITH_NEM_R0
     116    uint8_t                 abPadding2[4096 - 64 - 64 - 1024 - 64 - 64];
     117#else
    108118    uint8_t                 abPadding2[4096 - 64 - 64 - 1024 - 64];
    109 #else
    110     uint8_t                 abPadding2[4096 - 64 - 64 - 1024];
    111119#endif
    112120} GVMCPU;
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r90161 r90189  
    16781678 * @remarks Assume called with interrupts _enabled_.
    16791679 */
    1680 static int vmmR0EntryExWorker(PGVM pGVM, VMCPUID idCpu, VMMR0OPERATION enmOperation,
    1681                               PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
     1680DECL_NO_INLINE(static, int) vmmR0EntryExWorker(PGVM pGVM, VMCPUID idCpu, VMMR0OPERATION enmOperation,
     1681                                               PSUPVMMR0REQHDR pReqHdr, uint64_t u64Arg, PSUPDRVSESSION pSession)
    16821682{
    16831683    /*
     
    24292429
    24302430/**
    2431  * Argument for vmmR0EntryExWrapper containing the arguments for VMMR0EntryEx.
    2432  */
    2433 typedef struct VMMR0ENTRYEXARGS
    2434 {
    2435     PGVM                pGVM;
    2436     VMCPUID             idCpu;
    2437     VMMR0OPERATION      enmOperation;
    2438     PSUPVMMR0REQHDR     pReq;
    2439     uint64_t            u64Arg;
    2440     PSUPDRVSESSION      pSession;
    2441 } VMMR0ENTRYEXARGS;
    2442 /** Pointer to a vmmR0EntryExWrapper argument package. */
    2443 typedef VMMR0ENTRYEXARGS *PVMMR0ENTRYEXARGS;
    2444 
    2445 /**
    24462431 * This is just a longjmp wrapper function for VMMR0EntryEx calls.
    24472432 *
     
    24512436static DECLCALLBACK(int) vmmR0EntryExWrapper(void *pvArgs)
    24522437{
    2453     return vmmR0EntryExWorker(((PVMMR0ENTRYEXARGS)pvArgs)->pGVM,
    2454                               ((PVMMR0ENTRYEXARGS)pvArgs)->idCpu,
    2455                               ((PVMMR0ENTRYEXARGS)pvArgs)->enmOperation,
    2456                               ((PVMMR0ENTRYEXARGS)pvArgs)->pReq,
    2457                               ((PVMMR0ENTRYEXARGS)pvArgs)->u64Arg,
    2458                               ((PVMMR0ENTRYEXARGS)pvArgs)->pSession);
     2438    PGVMCPU pGVCpu = (PGVMCPU)pvArgs;
     2439    return vmmR0EntryExWorker(pGVCpu->vmmr0.s.pGVM,
     2440                              pGVCpu->vmmr0.s.idCpu,
     2441                              pGVCpu->vmmr0.s.enmOperation,
     2442                              pGVCpu->vmmr0.s.pReq,
     2443                              pGVCpu->vmmr0.s.u64Arg,
     2444                              pGVCpu->vmmr0.s.pSession);
    24592445}
    24602446
     
    25162502                        break;
    25172503
    2518                     /** @todo validate this EMT claim... GVM knows. */
    2519                     VMMR0ENTRYEXARGS Args;
    2520                     Args.pGVM = pGVM;
    2521                     Args.idCpu = idCpu;
    2522                     Args.enmOperation = enmOperation;
    2523                     Args.pReq = pReq;
    2524                     Args.u64Arg = u64Arg;
    2525                     Args.pSession = pSession;
    2526                     return vmmR0CallRing3SetJmpEx(&pGVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, &Args);
     2504                    pGVCpu->vmmr0.s.pGVM         = pGVM;
     2505                    pGVCpu->vmmr0.s.idCpu        = idCpu;
     2506                    pGVCpu->vmmr0.s.enmOperation = enmOperation;
     2507                    pGVCpu->vmmr0.s.pReq         = pReq;
     2508                    pGVCpu->vmmr0.s.u64Arg       = u64Arg;
     2509                    pGVCpu->vmmr0.s.pSession     = pSession;
     2510                    return vmmR0CallRing3SetJmpEx(&pGVCpu->vmm.s.CallRing3JmpBufR0, vmmR0EntryExWrapper, pGVCpu,
     2511                                                  ((uintptr_t)u64Arg << 16) | (uintptr_t)enmOperation);
    25272512                }
    25282513                return VERR_VM_THREAD_NOT_EMT;
  • trunk/src/VBox/VMM/VMMR0/VMMR0JmpA-amd64.asm

    r90177 r90189  
    128128    jnz     .resume
    129129
     130.different_call_continue:
     131    mov     [xDX + VMMR0JMPBUF.pfn], r11
     132    mov     [xDX + VMMR0JMPBUF.pvUser1], r8
     133    mov     [xDX + VMMR0JMPBUF.pvUser2], r9
     134
    130135 %ifdef VMM_R0_SWITCH_STACK
    131136    mov     r15, [xDX + VMMR0JMPBUF.pvSavedStack]
     
    224229
    225230    ;
     231    ; Not the same call as went to ring-3.
     232    ;
     233.different_call:
     234    mov     byte [xDX + VMMR0JMPBUF.fInRing3Call], 0
     235    ;; @todo or should we fail here instead?
     236    jmp     .different_call_continue
     237
     238    ;
    226239    ; Resume VMMRZCallRing3 the call.
    227240    ;
    228241.resume:
     242    ; Check if it's actually the same call, if not just continue with it
     243    ; as a regular call (ring-0 assert, then VM destroy).
     244    cmp     [xDX + VMMR0JMPBUF.pfn], r11
     245    jne     .different_call
     246    cmp     [xDX + VMMR0JMPBUF.pvUser1], r8
     247    jne     .different_call
     248    cmp     [xDX + VMMR0JMPBUF.pvUser2], r9
     249    jne     .different_call
     250
    229251 %ifndef VMM_R0_SWITCH_STACK
    230252    ; Sanity checks incoming stack, applying fuzz if needed.
  • trunk/src/VBox/VMM/VMMR3/VMMGuruMeditation.cpp

    r90161 r90189  
    406406                                pVCpu->vmm.s.CallRing3JmpBufR0.cbUsedTotal,
    407407                                pVCpu->vmm.s.CallRing3JmpBufR0.cUsedTotal);
     408                pHlp->pfnPrintf(pHlp,
     409                                "pfn=%RHv pvUser1=%RHv pvUser2=%RHv\n",
     410                                pVCpu->vmm.s.CallRing3JmpBufR0.pfn,
     411                                pVCpu->vmm.s.CallRing3JmpBufR0.pvUser1,
     412                                pVCpu->vmm.s.CallRing3JmpBufR0.pvUser2);
    408413
    409414                /* Dump the resume register frame on the stack. */
  • trunk/src/VBox/VMM/include/VMMInternal.h

    r88347 r90189  
    164164    /** Unwind: The vmmR0CallRing3SetJmp return address stack location. */
    165165    RTHCUINTREG                 UnwindRetPcLocation;
     166
     167    /** The function last being executed here. */
     168    RTHCUINTREG                 pfn;
     169    /** The first argument to the function. */
     170    RTHCUINTREG                 pvUser1;
     171    /** The second argument to the function. */
     172    RTHCUINTREG                 pvUser2;
     173
    166174#if HC_ARCH_BITS == 32
    167175    /** Alignment padding. */
     
    448456typedef VMMCPU *PVMMCPU;
    449457
     458/**
     459 * VMM per-VCpu ring-0 only instance data.
     460 */
     461typedef struct VMMR0PERVCPU
     462{
     463    /** @name Arguments passed by VMMR0EntryEx via vmmR0CallRing3SetJmpEx.
     464     * @note Cannot be put on the stack as the location may change and upset the
     465     *       validation of resume-after-ring-3-call logic.
     466     * @{ */
     467    PGVM                pGVM;
     468    VMCPUID             idCpu;
     469    VMMR0OPERATION      enmOperation;
     470    PSUPVMMR0REQHDR     pReq;
     471    uint64_t            u64Arg;
     472    PSUPDRVSESSION      pSession;
     473    /** @} */
     474} VMMR0PERVCPU;
     475/** Pointer to VMM ring-0 VMCPU instance data. */
     476typedef VMMR0PERVCPU *PVMMR0PERVCPU;
    450477
    451478
     
    539566 * @param   pfn         The function to be called when not resuming.
    540567 * @param   pvUser      The argument of that function.
    541  */
    542 DECLASM(int)    vmmR0CallRing3SetJmpEx(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMPEX pfn, void *pvUser);
     568 * @param   uCallKey    Unused call parameter that should be used to help
     569 *                      uniquely identify the call.
     570 */
     571DECLASM(int)    vmmR0CallRing3SetJmpEx(PVMMR0JMPBUF pJmpBuf, PFNVMMR0SETJMPEX pfn, void *pvUser, uintptr_t uCallKey);
    543572
    544573
  • trunk/src/VBox/VMM/include/VMMInternal.mac

    r82968 r90189  
    5353    .UnwindRetPcValue       resd 1
    5454    .UnwindRetPcLocation    resd 1
     55    .pfn            resd 1
     56    .pvUser1        resd 1
     57    .pvUser2        resd 1
    5558%endif
    5659%ifdef RT_ARCH_AMD64
     
    9396    .UnwindRetPcValue       resq 1
    9497    .UnwindRetPcLocation    resq 1
     98    .pfn            resq 1
     99    .pvUser1        resq 1
     100    .pvUser2        resq 1
    95101%endif
    96102
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