VirtualBox

Changeset 14672 in vbox


Ignore:
Timestamp:
Nov 27, 2008 12:19:22 AM (16 years ago)
Author:
vboxsync
Message:

VMMR0CallHostSetJmp/LongJmp: Implemented stack switching for darwin.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/VMMR0A.asm

    r14505 r14672  
    3030%ifdef RT_ARCH_X86      ; The other architecture(s) use(s) C99 variadict macros.
    3131extern IMPNAME(RTLogLogger)
     32%endif
     33
     34%ifdef RT_OS_DARWIN
     35 %define VMM_R0_SWITCH_STACK
    3236%endif
    3337
     
    7175    jnz     .resume
    7276
     77    mov     ebx, edx                    ; pJmpBuf -> ebx (persistent reg)
     78%ifdef VMM_R0_SWITCH_STACK
     79    mov     esi, [ebx + VMMR0JMPBUF.pvSavedStack]
     80    test    esi, esi
     81    jz      .entry_error
     82 %ifdef VBOX_STRICT
     83    mov      edx, esi
     84    mov      edi, esi
     85    mov      ecx, 2048
     86    mov      eax, 0eeeeeeeeh
     87    repne stosd
     88 %endif
     89    lea     esi, [esi + 8192 - 32]
     90    mov     [esi + 1ch], dword 0deadbeefh ; Marker 1.
     91    mov     [esi + 18h], ebx            ; Save pJmpBuf pointer.
     92    mov     [esi + 14h], dword 00c00ffeeh ; Marker 2.
     93    mov     [esi + 10h], dword 0f00dbeefh ; Marker 3.
     94    mov     edx, [esp + 10h]            ; pvArg2
     95    mov     [esi + 04h], edx
     96    mov     ecx, [esp + 0ch]            ; pvArg1
     97    mov     [esi      ], ecx
     98    mov     eax, [esp + 08h]            ; pfn
     99    mov     esp, esi                    ; Switch stack!
     100    call    eax
     101    and     dword [esi + 1ch], byte 0   ; clear marker.
     102
     103%else  ; !VMM_R0_SWITCH_STACK
    73104    mov     ecx, [esp + 0ch]            ; pvArg1
    74105    mov     edx, [esp + 10h]            ; pvArg2
    75106    mov     eax, [esp + 08h]            ; pfn
    76     sub     esp, 16                     ; align the stack on a 16-byte boundrary.
    77     mov     [esp], ecx
    78     mov     [esp+4], edx
     107    sub     esp, 12                     ; align the stack on a 16-byte boundrary.
     108    mov     [esp      ], ecx
     109    mov     [esp + 04h], edx
    79110    call    eax
    80     add     esp, 16
    81     mov     edx, [esp + 4h]             ; pJmpBuf
    82 
    83     ; restore the registers that we're not allowed to modify
    84     ; otherwise a resume might restore the wrong values (from the previous run)
     111%endif ; !VMM_R0_SWITCH_STACK
     112    mov     edx, ebx                    ; pJmpBuf -> edx (volatile reg)
     113
     114    ;
     115    ; Return like in the long jump.
     116    ; (It is vital that we restore all registers since they might've changed
     117    ;  by a long jump.)
     118    ;
     119.proper_return:
     120    mov     ebx, [edx + VMMR0JMPBUF.ebx]
     121    mov     esi, [edx + VMMR0JMPBUF.esi]
    85122    mov     edi, [edx + VMMR0JMPBUF.edi]
    86     mov     esi, [edx + VMMR0JMPBUF.esi]
    87     mov     ebx, [edx + VMMR0JMPBUF.ebx]
    88123    mov     ebp, [edx + VMMR0JMPBUF.ebp]
    89 
     124    mov     ecx, [edx + VMMR0JMPBUF.eip]
    90125    and     dword [edx + VMMR0JMPBUF.eip], byte 0 ; used for valid check.
    91     ret
     126    mov     esp, [edx + VMMR0JMPBUF.esp]
     127    jmp     ecx
     128
     129.entry_error:
     130    mov     eax, VERR_INTERNAL_ERROR
     131    jmp     .proper_return
    92132
    93133    ;
     
    95135    ;
    96136.resume:
     137%ifdef VMM_R0_SWITCH_STACK
     138    ; Switch stack.
     139    mov     esp, [edx + VMMR0JMPBUF.SpResume]
     140%else  ; !VMM_R0_SWITCH_STACK
    97141    ; Sanity checks.
    98142    cmp     ecx, [edx + VMMR0JMPBUF.SpCheck]
     
    120164    ; Restore the stack.
    121165    ;
    122     mov     byte [edx + VMMR0JMPBUF.fInRing3Call], 0
    123166    mov     ecx, [edx + VMMR0JMPBUF.cbSavedStack]
    124167    shr     ecx, 2
     
    127170    mov     esp, edi
    128171    rep movsd
     172%endif ; !VMM_R0_SWITCH_STACK
     173    mov     byte [edx + VMMR0JMPBUF.fInRing3Call], 0
    129174
    130175    ;
    131176    ; Continue where we left off.
    132177    ;
     178%ifdef VBOX_STRICT
     179    pop     eax                         ; magic
     180    cmp     eax, 0f00dbed0h
     181    je      .magic_ok
     182    mov     ecx, 0123h
     183    mov     [ecx], edx
     184.magic_ok:
     185%endif
    133186    popf
    134187    pop     ebx
     
    288341    push    ebx
    289342    pushf
     343%ifdef VBOX_STRICT
     344    push    dword 0f00dbed0h
     345%endif
    290346
    291347    ;
     
    302358
    303359    ;
    304     ; Save the stack.
     360    ; Sanity checks.
    305361    ;
    306362    mov     edi, [edx + VMMR0JMPBUF.pvSavedStack]
     
    308364    jz      .nok
    309365    mov     [edx + VMMR0JMPBUF.SpResume], esp
     366%ifndef VMM_R0_SWITCH_STACK
    310367    mov     esi, esp
    311368    mov     ecx, [edx + VMMR0JMPBUF.esp]
     
    314371    ; two sanity checks on the size.
    315372    cmp     ecx, 8192                   ; check max size.
    316     jbe     .ok
    317 .nok:
    318     mov     eax, VERR_INTERNAL_ERROR
    319     popf
    320     pop     ebx
    321     pop     esi
    322     pop     edi
    323     leave
    324     ret
    325 .ok:
     373    jnbe    .nok
     374
     375    ;
     376    ; Copy the stack.
     377    ;
    326378    test    ecx, 3                      ; check alignment
    327379    jnz     .nok
     
    329381    shr     ecx, 2
    330382    rep movsd
     383%endif ; !VMM_R0_SWITCH_STACK
    331384
    332385    ; store the last pieces of info.
     
    345398    mov     esp, [edx + VMMR0JMPBUF.esp]
    346399    jmp     ecx
     400
     401    ;
     402    ; Failure
     403    ;
     404.nok:
     405%ifdef VBOX_STRICT
     406    pop     eax                         ; magic
     407    cmp     eax, 0f00dbed0h
     408    je      .magic_ok
     409    mov     ecx, 0123h
     410    mov     [ecx], edx
     411.magic_ok:
     412%endif
     413    popf
     414    pop     ebx
     415    pop     esi
     416    pop     edi
     417    mov     eax, VERR_INTERNAL_ERROR
     418    leave
     419    ret
    347420%endif ; RT_ARCH_X86
    348421
  • trunk/src/VBox/VMM/testcase/tstVMMR0CallHost-1.cpp

    r13872 r14672  
    4040*******************************************************************************/
    4141/** The jump buffer. */
    42 static VMMR0JMPBUF  g_Jmp;
     42static VMMR0JMPBUF          g_Jmp;
     43/** The number of jumps we've done. */
     44static unsigned volatile    g_cJmps;
    4345/** The saved stack. */
    44 static uint8_t      g_Stack[8192];
     46static uint8_t              g_Stack[8192];
    4547
    4648
    4749int foo(int i, int iZero, int iMinusOne)
    4850{
    49     char *pv = (char *)alloca(i + 32);
    50     RTStrPrintf(pv, i + 32, "i=%d%*s\n", i, i+32, "");
     51    /* allocate a buffer which we fill up to the end. */
     52    size_t cb = (i % 5555) + 32;
     53    char  *pv = (char *)alloca(cb);
     54    RTStrPrintf(pv, cb, "i=%d%*s\n", i, cb, "");
     55
     56    /* Do long jmps every 7th time */
    5157    if ((i % 7) == 0)
    5258    {
     59        g_cJmps++;
    5360        int rc = vmmR0CallHostLongJmp(&g_Jmp, 42);
    5461        if (!rc)
     
    8491int tst(int iFrom, int iTo, int iInc)
    8592{
    86     for (int i = iFrom; i < iTo; i += iInc)
     93    g_cJmps = 0;
     94    for (int i = iFrom; i != iTo; i += iInc)
    8795    {
    8896        int rc = vmmR0CallHostSetJmp(&g_Jmp, (PFNVMMR0SETJMP)tst2, (PVM)i, 0);
     
    92100            return 1;
    93101        }
     102    }
     103    if (!g_cJmps)
     104    {
     105        RTPrintf("tstVMMR0CallHost-1: FAILURE - no jumps!\n");
     106        return 1;
    94107    }
    95108    return 0;
     
    103116     */
    104117    RTR3Init();
    105     RTPrintf("tstVMMR0CallHost-1: Testing...\n");
    106118    g_Jmp.pvSavedStack = (RTR0PTR)&g_Stack[0];
    107119
     
    109121     * Try about 1000 long jumps with increasing stack size..
    110122     */
     123    RTPrintf("tstVMMR0CallHost-1: Testing 1\n");
    111124    int rc = tst(0, 7000, 1);
    112125    if (!rc)
     126    {
     127        RTPrintf("tstVMMR0CallHost-1: Testing 2\n");
    113128        rc = tst(7599, 0, -1);
     129    }
    114130
    115131    if (!rc)
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