VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/EMGCA.asm@ 5605

Last change on this file since 5605 was 5342, checked in by vboxsync, 17 years ago

Protect cmpxchg emulation

File size: 5.4 KB
Line 
1; $Id: EMAllA.asm 20278 2007-04-09 11:56:29Z sandervl $
2;; @file
3; EM Assembly Routines.
4;
5
6;
7; Copyright (C) 2006-2007 innotek GmbH
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License as published by the Free Software Foundation,
13; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14; distribution. VirtualBox OSE is distributed in the hope that it will
15; be useful, but WITHOUT ANY WARRANTY of any kind.
16
17;*******************************************************************************
18;* Header Files *
19;*******************************************************************************
20%include "VBox/asmdefs.mac"
21%include "VBox/err.mac"
22%include "VBox/x86.mac"
23
24BEGINCODE
25
26;;
27; Emulate lock CMPXCHG instruction, CDECL calling conv.
28; EMGCDECL(uint32_t) EMGCEmulateLockCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
29;
30; @returns eax=0 if data written, other code - invalid access, #PF was generated.
31; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter
32; @param [esp + 08h] Param 2 - Second parameter - pointer to second parameter (eax)
33; @param [esp + 0ch] Param 3 - Third parameter - third parameter
34; @param [esp + 10h] Param 4 - Size of parameters, only 1/2/4 is valid.
35; @param [esp + 14h] Param 4 - Pointer to eflags (out)
36; @uses eax, ecx, edx
37;
38align 16
39BEGINPROC EMGCEmulateLockCmpXchg
40 push ebx
41 mov ecx, [esp + 04h + 4] ; ecx = first parameter
42 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
43 mov edx, [esp + 0ch + 4] ; edx = third parameter
44 mov eax, [esp + 10h + 4] ; eax = size of parameters
45
46 cmp al, 4
47 je short .do_dword ; 4 bytes variant
48 cmp al, 2
49 je short .do_word ; 2 byte variant
50 cmp al, 1
51 je short .do_byte ; 1 bytes variant
52 int3
53
54.do_dword:
55 ; load 2nd parameter's value
56 mov eax, dword [ebx]
57
58 lock cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG
59 mov dword [ebx], eax
60 jmp short .done
61
62.do_word:
63 ; load 2nd parameter's value
64 mov eax, dword [ebx]
65
66 lock cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG
67 mov word [ebx], ax
68 jmp short .done
69
70.do_byte:
71 ; load 2nd parameter's value
72 mov eax, dword [ebx]
73
74 lock cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG
75 mov byte [ebx], al
76
77.done:
78 ; collect flags and return.
79 pushf
80 pop eax
81
82 mov edx, [esp + 14h + 4] ; eflags pointer
83 mov dword [edx], eax
84
85 pop ebx
86 mov eax, VINF_SUCCESS
87 retn
88
89; Read error - we will be here after our page fault handler.
90GLOBALNAME EMGCEmulateLockCmpXchg_Error
91 pop ebx
92 mov eax, VERR_ACCESS_DENIED
93 ret
94
95ENDPROC EMGCEmulateLockCmpXchg
96
97;;
98; Emulate CMPXCHG instruction, CDECL calling conv.
99; EMGCDECL(uint32_t) EMGCEmulateCmpXchg(RTGCPTR pu32Param1, uint32_t *pu32Param2, uint32_t u32Param3, size_t cbSize, uint32_t *pEflags);
100;
101; @returns eax=0 if data written, other code - invalid access, #PF was generated.
102; @param [esp + 04h] Param 1 - First parameter - pointer to first parameter
103; @param [esp + 08h] Param 2 - Second parameter - pointer to second parameter (eax)
104; @param [esp + 0ch] Param 3 - Third parameter - third parameter
105; @param [esp + 10h] Param 4 - Size of parameters, only 1/2/4 is valid.
106; @param [esp + 14h] Param 4 - Pointer to eflags (out)
107; @uses eax, ecx, edx
108;
109align 16
110BEGINPROC EMGCEmulateCmpXchg
111 push ebx
112 mov ecx, [esp + 04h + 4] ; ecx = first parameter
113 mov ebx, [esp + 08h + 4] ; ebx = 2nd parameter (eax)
114 mov edx, [esp + 0ch + 4] ; edx = third parameter
115 mov eax, [esp + 10h + 4] ; eax = size of parameters
116
117 cmp al, 4
118 je short .do_dword ; 4 bytes variant
119 cmp al, 2
120 je short .do_word ; 2 byte variant
121 cmp al, 1
122 je short .do_byte ; 1 bytes variant
123 int3
124
125.do_dword:
126 ; load 2nd parameter's value
127 mov eax, dword [ebx]
128
129 cmpxchg dword [ecx], edx ; do 4 bytes CMPXCHG
130 mov dword [ebx], eax
131 jmp short .done
132
133.do_word:
134 ; load 2nd parameter's value
135 mov eax, dword [ebx]
136
137 cmpxchg word [ecx], dx ; do 2 bytes CMPXCHG
138 mov word [ebx], ax
139 jmp short .done
140
141.do_byte:
142 ; load 2nd parameter's value
143 mov eax, dword [ebx]
144
145 cmpxchg byte [ecx], dl ; do 1 bytes CMPXCHG
146 mov byte [ebx], al
147
148.done:
149 ; collect flags and return.
150 pushf
151 pop eax
152
153 mov edx, [esp + 14h + 4] ; eflags pointer
154 mov dword [edx], eax
155
156 pop ebx
157 mov eax, VINF_SUCCESS
158 retn
159
160; Read error - we will be here after our page fault handler.
161GLOBALNAME EMGCEmulateCmpXchg_Error
162 pop ebx
163 mov eax, VERR_ACCESS_DENIED
164 ret
165ENDPROC EMGCEmulateCmpXchg
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette