VirtualBox

Changeset 30338 in vbox for trunk/src/VBox/VMM/VMMGC


Ignore:
Timestamp:
Jun 21, 2010 2:48:17 PM (15 years ago)
Author:
vboxsync
Message:

EM,IOM: Don't try write directly to the fault address as the backing page might be read-only (shared page, write monitored page or zero page) and require special handle. Took the simple way out, which is to take the same path as in ring-0/3. Converted the remaining EMGCA.asm bits to EMAllA.asm code.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMGC/EMGCA.asm

    r28800 r30338  
    2525BEGINCODE
    2626
    27 ;;
    28 ; Emulate LOCK CMPXCHG instruction, CDECL calling conv.
    29 ; VMMRCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    30 ;
    31 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    32 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    33 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (eax)
    34 ; @param    [esp + 0ch]    Param 3 - Third parameter - third parameter
    35 ; @param    [esp + 10h]    Param 4 - Size of parameters, only 1/2/4 is valid.
    36 ; @param    [esp + 14h]    Param 4 - Pointer to eflags (out)
    37 ; @uses     eax, ecx, edx
    38 ;
    39 align 16
    40 BEGINPROC   EMGCEmulateLockCmpXchg
    41     push    ebx
    42     mov     ecx, [esp + 04h + 4]        ; ecx = first parameter
    43     mov     ebx, [esp + 08h + 4]        ; ebx = 2nd parameter (eax)
    44     mov     edx, [esp + 0ch + 4]        ; edx = third parameter
    45     mov     eax, [esp + 10h + 4]        ; eax = size of parameters
    46 
    47     cmp     al, 4
    48     je short .do_dword                  ; 4 bytes variant
    49     cmp     al, 2
    50     je short .do_word                   ; 2 byte variant
    51     cmp     al, 1
    52     je short .do_byte                   ; 1 bytes variant
    53     int3
    54 
    55 .do_dword:
    56     ; load 2nd parameter's value
    57     mov     eax, dword [ebx]
    58 
    59     lock cmpxchg dword [ecx], edx            ; do 4 bytes CMPXCHG
    60     mov     dword [ebx], eax
    61     jmp     short .done
    62 
    63 .do_word:
    64     ; load 2nd parameter's value
    65     mov     eax, dword [ebx]
    66 
    67     lock cmpxchg word [ecx], dx              ; do 2 bytes CMPXCHG
    68     mov     word [ebx], ax
    69     jmp     short .done
    70 
    71 .do_byte:
    72     ; load 2nd parameter's value
    73     mov     eax, dword [ebx]
    74 
    75     lock cmpxchg byte [ecx], dl              ; do 1 bytes CMPXCHG
    76     mov     byte [ebx], al
    77 
    78 .done:
    79     ; collect flags and return.
    80     pushf
    81     pop     eax
    82 
    83     mov     edx, [esp + 14h + 4]            ; eflags pointer
    84     mov     dword [edx], eax
    85 
    86     pop     ebx
    87     mov     eax, VINF_SUCCESS
    88     retn
    89 
    90 ; Read error - we will be here after our page fault handler.
    91 GLOBALNAME EMGCEmulateLockCmpXchg_Error
    92     pop     ebx
    93     mov     eax, VERR_ACCESS_DENIED
    94     ret
    95 
    96 ENDPROC     EMGCEmulateLockCmpXchg
    97 
    98 ;;
    99 ; Emulate CMPXCHG instruction, CDECL calling conv.
    100 ; VMMRCDECL(uint32_t) EMGCEmulateCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    101 ;
    102 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    103 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    104 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (eax)
    105 ; @param    [esp + 0ch]    Param 3 - Third parameter - third parameter
    106 ; @param    [esp + 10h]    Param 4 - Size of parameters, only 1/2/4 is valid.
    107 ; @param    [esp + 14h]    Param 4 - Pointer to eflags (out)
    108 ; @uses     eax, ecx, edx
    109 ;
    110 align 16
    111 BEGINPROC   EMGCEmulateCmpXchg
    112     push    ebx
    113     mov     ecx, [esp + 04h + 4]        ; ecx = first parameter
    114     mov     ebx, [esp + 08h + 4]        ; ebx = 2nd parameter (eax)
    115     mov     edx, [esp + 0ch + 4]        ; edx = third parameter
    116     mov     eax, [esp + 10h + 4]        ; eax = size of parameters
    117 
    118     cmp     al, 4
    119     je short .do_dword                  ; 4 bytes variant
    120     cmp     al, 2
    121     je short .do_word                   ; 2 byte variant
    122     cmp     al, 1
    123     je short .do_byte                   ; 1 bytes variant
    124     int3
    125 
    126 .do_dword:
    127     ; load 2nd parameter's value
    128     mov     eax, dword [ebx]
    129 
    130     cmpxchg dword [ecx], edx            ; do 4 bytes CMPXCHG
    131     mov     dword [ebx], eax
    132     jmp     short .done
    133 
    134 .do_word:
    135     ; load 2nd parameter's value
    136     mov     eax, dword [ebx]
    137 
    138     cmpxchg word [ecx], dx              ; do 2 bytes CMPXCHG
    139     mov     word [ebx], ax
    140     jmp     short .done
    141 
    142 .do_byte:
    143     ; load 2nd parameter's value
    144     mov     eax, dword [ebx]
    145 
    146     cmpxchg byte [ecx], dl              ; do 1 bytes CMPXCHG
    147     mov     byte [ebx], al
    148 
    149 .done:
    150     ; collect flags and return.
    151     pushf
    152     pop     eax
    153 
    154     mov     edx, [esp + 14h + 4]        ; eflags pointer
    155     mov     dword [edx], eax
    156 
    157     pop     ebx
    158     mov     eax, VINF_SUCCESS
    159     retn
    160 
    161 ; Read error - we will be here after our page fault handler.
    162 GLOBALNAME EMGCEmulateCmpXchg_Error
    163     pop     ebx
    164     mov     eax, VERR_ACCESS_DENIED
    165     ret
    166 ENDPROC     EMGCEmulateCmpXchg
    167 
    168 ;;
    169 ; Emulate LOCK CMPXCHG8B instruction, CDECL calling conv.
    170 ; VMMRCDECL(uint32_t) EMGCEmulateLockCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags);
    171 ;
    172 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    173 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    174 ; @param    [esp + 08h]    Param 2 - Address of the eax register
    175 ; @param    [esp + 0ch]    Param 3 - Address of the edx register
    176 ; @param    [esp + 10h]    Param 4 - EBX
    177 ; @param    [esp + 14h]    Param 5 - ECX
    178 ; @param    [esp + 18h]    Param 6 - Pointer to eflags (out)
    179 ; @uses     eax, ecx, edx
    180 ;
    181 align 16
    182 BEGINPROC   EMGCEmulateLockCmpXchg8b
    183     push    ebp
    184     push    ebx
    185     mov     ebp, [esp + 04h + 8]        ; ebp = first parameter
    186     mov     eax, [esp + 08h + 8]        ; &EAX
    187     mov     eax, dword [eax]
    188     mov     edx, [esp + 0ch + 8]        ; &EDX
    189     mov     edx, dword [edx]
    190     mov     ebx, [esp + 10h + 8]        ; EBX
    191     mov     ecx, [esp + 14h + 8]        ; ECX
    192 
    193 %ifdef RT_OS_OS2
    194     lock cmpxchg8b [ebp]                ; do CMPXCHG8B
    195 %else
    196     lock cmpxchg8b qword [ebp]          ; do CMPXCHG8B
    197 %endif
    198     mov     ebx, dword [esp + 08h + 8]
    199     mov     dword [ebx], eax
    200     mov     ebx, dword [esp + 0ch + 8]
    201     mov     dword [ebx], edx
    202 
    203     ; collect flags and return.
    204     pushf
    205     pop     eax
    206 
    207     mov     edx, [esp + 18h + 8]            ; eflags pointer
    208     mov     dword [edx], eax
    209 
    210     pop     ebx
    211     pop     ebp
    212     mov     eax, VINF_SUCCESS
    213     retn
    214 
    215 ; Read error - we will be here after our page fault handler.
    216 GLOBALNAME EMGCEmulateLockCmpXchg8b_Error
    217     pop     ebx
    218     pop     ebp
    219     mov     eax, VERR_ACCESS_DENIED
    220     ret
    221 
    222 ENDPROC     EMGCEmulateLockCmpXchg8b
    223 
    224 ;;
    225 ; Emulate CMPXCHG8B instruction, CDECL calling conv.
    226 ; VMMRCDECL(uint32_t) EMGCEmulateCmpXchg8b(RTGCPTR pu32Param1, uint32_t *pEAX, uint32_t *pEDX, uint32_t uEBX, uint32_t uECX, uint32_t *pEflags);
    227 ;
    228 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    229 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    230 ; @param    [esp + 08h]    Param 2 - Address of the eax register
    231 ; @param    [esp + 0ch]    Param 3 - Address of the edx register
    232 ; @param    [esp + 10h]    Param 4 - EBX
    233 ; @param    [esp + 14h]    Param 5 - ECX
    234 ; @param    [esp + 18h]    Param 6 - Pointer to eflags (out)
    235 ; @uses     eax, ecx, edx
    236 ;
    237 align 16
    238 BEGINPROC   EMGCEmulateCmpXchg8b
    239     push    ebp
    240     push    ebx
    241     mov     ebp, [esp + 04h + 8]        ; ebp = first parameter
    242     mov     eax, [esp + 08h + 8]        ; &EAX
    243     mov     eax, dword [eax]
    244     mov     edx, [esp + 0ch + 8]        ; &EDX
    245     mov     edx, dword [edx]
    246     mov     ebx, [esp + 10h + 8]        ; EBX
    247     mov     ecx, [esp + 14h + 8]        ; ECX
    248 
    249 %ifdef RT_OS_OS2
    250     cmpxchg8b [ebp]                     ; do CMPXCHG8B
    251 %else
    252     cmpxchg8b qword [ebp]               ; do CMPXCHG8B
    253 %endif
    254     mov     ebx, dword [esp + 08h + 8]
    255     mov     dword [ebx], eax
    256     mov     ebx, dword [esp + 0ch + 8]
    257     mov     dword [ebx], edx
    258 
    259     ; collect flags and return.
    260     pushf
    261     pop     eax
    262 
    263     mov     edx, [esp + 18h + 8]            ; eflags pointer
    264     mov     dword [edx], eax
    265 
    266     pop     ebx
    267     pop     ebp
    268     mov     eax, VINF_SUCCESS
    269     retn
    270 
    271 ; Read error - we will be here after our page fault handler.
    272 GLOBALNAME EMGCEmulateCmpXchg8b_Error
    273     pop     ebx
    274     pop     ebp
    275     mov     eax, VERR_ACCESS_DENIED
    276     ret
    277 ENDPROC     EMGCEmulateCmpXchg8b
    278 
    279 ;;
    280 ; Emulate LOCK XADD instruction, CDECL calling conv.
    281 ; VMMRCDECL(uint32_t) EMGCEmulateLockXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    282 ;
    283 ; @returns eax=0 if data exchanged, other code - invalid access, #PF was generated.
    284 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    285 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (general register)
    286 ; @param    [esp + 0ch]    Param 3 - Size of parameters, only 1/2/4 is valid.
    287 ; @param    [esp + 10h]    Param 4 - Pointer to eflags (out)
    288 ; @uses     eax, ecx, edx
    289 ;
    290 align 16
    291 BEGINPROC   EMGCEmulateLockXAdd
    292     mov     ecx, [esp + 04h + 0]        ; ecx = first parameter
    293     mov     edx, [esp + 08h + 0]        ; edx = 2nd parameter
    294     mov     eax, [esp + 0ch + 0]        ; eax = size of parameters
    295 
    296     cmp     al, 4
    297     je short .do_dword                  ; 4 bytes variant
    298     cmp     al, 2
    299     je short .do_word                   ; 2 byte variant
    300     cmp     al, 1
    301     je short .do_byte                   ; 1 bytes variant
    302     int3
    303 
    304 .do_dword:
    305     ; load 2nd parameter's value
    306     mov     eax, dword [edx]
    307     lock xadd dword [ecx], eax              ; do 4 bytes XADD
    308     mov     dword [edx], eax
    309     jmp     short .done
    310 
    311 .do_word:
    312     ; load 2nd parameter's value
    313     mov     eax, dword [edx]
    314     lock xadd word [ecx], ax                ; do 2 bytes XADD
    315     mov     word [edx], ax
    316     jmp     short .done
    317 
    318 .do_byte:
    319     ; load 2nd parameter's value
    320     mov     eax, dword [edx]
    321     lock xadd byte [ecx], al                ; do 1 bytes XADD
    322     mov     byte [edx], al
    323 
    324 .done:
    325     ; collect flags and return.
    326     mov     edx, [esp + 10h + 0]            ; eflags pointer
    327     pushf
    328     pop     dword [edx]
    329 
    330     mov     eax, VINF_SUCCESS
    331     retn
    332 
    333 ; Read error - we will be here after our page fault handler.
    334 GLOBALNAME EMGCEmulateLockXAdd_Error
    335     mov     eax, VERR_ACCESS_DENIED
    336     ret
    337 
    338 ENDPROC     EMGCEmulateLockXAdd
    339 
    340 ;;
    341 ; Emulate XADD instruction, CDECL calling conv.
    342 ; VMMRCDECL(uint32_t) EMGCEmulateXAdd(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
    343 ;
    344 ; @returns eax=0 if data written, other code - invalid access, #PF was generated.
    345 ; @param    [esp + 04h]    Param 1 - First parameter - pointer to first parameter
    346 ; @param    [esp + 08h]    Param 2 - Second parameter - pointer to second parameter (general register)
    347 ; @param    [esp + 0ch]    Param 3 - Size of parameters, only 1/2/4 is valid.
    348 ; @param    [esp + 10h]    Param 4 - Pointer to eflags (out)
    349 ; @uses     eax, ecx, edx
    350 ;
    351 align 16
    352 BEGINPROC   EMGCEmulateXAdd
    353     mov     ecx, [esp + 04h + 0]        ; ecx = first parameter
    354     mov     edx, [esp + 08h + 0]        ; edx = 2nd parameter (eax)
    355     mov     eax, [esp + 0ch + 0]        ; eax = size of parameters
    356 
    357     cmp     al, 4
    358     je short .do_dword                  ; 4 bytes variant
    359     cmp     al, 2
    360     je short .do_word                   ; 2 byte variant
    361     cmp     al, 1
    362     je short .do_byte                   ; 1 bytes variant
    363     int3
    364 
    365 .do_dword:
    366     ; load 2nd parameter's value
    367     mov     eax, dword [edx]
    368     xadd    dword [ecx], eax            ; do 4 bytes XADD
    369     mov     dword [edx], eax
    370     jmp     short .done
    371 
    372 .do_word:
    373     ; load 2nd parameter's value
    374     mov     eax, dword [edx]
    375     xadd    word [ecx], ax              ; do 2 bytes XADD
    376     mov     word [edx], ax
    377     jmp     short .done
    378 
    379 .do_byte:
    380     ; load 2nd parameter's value
    381     mov     eax, dword [edx]
    382     xadd    byte [ecx], al              ; do 1 bytes XADD
    383     mov     byte [edx], al
    384 
    385 .done:
    386     ; collect flags and return.
    387     mov     edx, [esp + 10h + 0]        ; eflags pointer
    388     pushf
    389     pop     dword [edx]
    390 
    391     mov     eax, VINF_SUCCESS
    392     retn
    393 
    394 ; Read error - we will be here after our page fault handler.
    395 GLOBALNAME EMGCEmulateXAdd_Error
    396     mov     eax, VERR_ACCESS_DENIED
    397     ret
    398 ENDPROC     EMGCEmulateXAdd
  • trunk/src/VBox/VMM/VMMGC/MMRamGC.cpp

    r28800 r30338  
    4242DECLASM(void) MMGCRamReadNoTrapHandler_EndProc(void);
    4343DECLASM(void) MMGCRamWriteNoTrapHandler_EndProc(void);
    44 DECLASM(void) EMGCEmulateLockCmpXchg_EndProc(void);
    45 DECLASM(void) EMGCEmulateLockCmpXchg_Error(void);
    46 DECLASM(void) EMGCEmulateCmpXchg_EndProc(void);
    47 DECLASM(void) EMGCEmulateCmpXchg_Error(void);
    48 DECLASM(void) EMGCEmulateLockCmpXchg8b_EndProc(void);
    49 DECLASM(void) EMGCEmulateLockCmpXchg8b_Error(void);
    50 DECLASM(void) EMGCEmulateCmpXchg8b_EndProc(void);
    51 DECLASM(void) EMGCEmulateCmpXchg8b_Error(void);
    52 DECLASM(void) EMGCEmulateLockXAdd_EndProc(void);
    53 DECLASM(void) EMGCEmulateLockXAdd_Error(void);
    54 DECLASM(void) EMGCEmulateXAdd_EndProc(void);
    55 DECLASM(void) EMGCEmulateXAdd_Error(void);
    56 DECLASM(void) EMEmulateLockOr_EndProc(void);
    57 DECLASM(void) EMEmulateLockOr_Error(void);
    58 DECLASM(void) EMEmulateLockBtr_EndProc(void);
    59 DECLASM(void) EMEmulateLockBtr_Error(void);
    6044DECLASM(void) MMGCRamRead_Error(void);
    6145DECLASM(void) MMGCRamWrite_Error(void);
     
    122106 * @param   pSrc        Pointer to the data to write.
    123107 * @param   cb          Size of data to write, only 1/2/4 is valid.
     108 *
     109 * @deprecated Don't use this as it doesn't check the page state.
    124110 */
    125111VMMRCDECL(int) MMGCRamWrite(PVM pVM, void *pDst, void *pSrc, size_t cb)
     
    175161
    176162    /*
    177      * Page fault inside EMGCEmulateLockCmpXchg()? Resume at _Error.
    178      */
    179     if (    (uintptr_t)&EMGCEmulateLockCmpXchg < (uintptr_t)pRegFrame->eip
    180         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg_EndProc)
    181     {
    182         pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg_Error;
    183         return VINF_SUCCESS;
    184     }
    185 
    186     /*
    187      * Page fault inside EMGCEmulateCmpXchg()? Resume at _Error.
    188      */
    189     if (    (uintptr_t)&EMGCEmulateCmpXchg < (uintptr_t)pRegFrame->eip
    190         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg_EndProc)
    191     {
    192         pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg_Error;
    193         return VINF_SUCCESS;
    194     }
    195 
    196     /*
    197      * Page fault inside EMGCEmulateLockCmpXchg8b()? Resume at _Error.
    198      */
    199     if (    (uintptr_t)&EMGCEmulateLockCmpXchg8b < (uintptr_t)pRegFrame->eip
    200         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockCmpXchg8b_EndProc)
    201     {
    202         pRegFrame->eip = (uintptr_t)&EMGCEmulateLockCmpXchg8b_Error;
    203         return VINF_SUCCESS;
    204     }
    205 
    206     /*
    207      * Page fault inside EMGCEmulateCmpXchg8b()? Resume at _Error.
    208      */
    209     if (    (uintptr_t)&EMGCEmulateCmpXchg8b < (uintptr_t)pRegFrame->eip
    210         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateCmpXchg8b_EndProc)
    211     {
    212         pRegFrame->eip = (uintptr_t)&EMGCEmulateCmpXchg8b_Error;
    213         return VINF_SUCCESS;
    214     }
    215 
    216     /*
    217      * Page fault inside EMGCEmulateLockXAdd()? Resume at _Error.
    218      */
    219     if (    (uintptr_t)&EMGCEmulateLockXAdd < (uintptr_t)pRegFrame->eip
    220         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateLockXAdd_EndProc)
    221     {
    222         pRegFrame->eip = (uintptr_t)&EMGCEmulateLockXAdd_Error;
    223         return VINF_SUCCESS;
    224     }
    225 
    226     /*
    227      * Page fault inside EMGCEmulateXAdd()? Resume at _Error.
    228      */
    229     if (    (uintptr_t)&EMGCEmulateXAdd < (uintptr_t)pRegFrame->eip
    230         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMGCEmulateXAdd_EndProc)
    231     {
    232         pRegFrame->eip = (uintptr_t)&EMGCEmulateXAdd_Error;
    233         return VINF_SUCCESS;
    234     }
    235 
    236     /*
    237      * Page fault inside EMEmulateLockOr()? Resume at *_Error.
    238      */
    239     if (    (uintptr_t)&EMEmulateLockOr < (uintptr_t)pRegFrame->eip
    240         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockOr_EndProc)
    241     {
    242         pRegFrame->eip = (uintptr_t)&EMEmulateLockOr_Error;
    243         return VINF_SUCCESS;
    244     }
    245 
    246     /*
    247      * Page fault inside EMEmulateLockBtr()? Resume at *_Error.
    248      */
    249     if (    (uintptr_t)&EMEmulateLockBtr < (uintptr_t)pRegFrame->eip
    250         &&  (uintptr_t)pRegFrame->eip < (uintptr_t)&EMEmulateLockBtr_EndProc)
    251     {
    252         pRegFrame->eip = (uintptr_t)&EMEmulateLockBtr_Error;
    253         return VINF_SUCCESS;
    254     }
    255 
    256     /*
    257163     * #PF is not handled - cause guru meditation.
    258164     */
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