Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


VMX is working for a 32-bit Linux kernel. It should also work for a 64-bit kernel...
[palacios.git] / palacios / src / palacios / vmx_lowlevel.S
1 #;  -*- fundamental -*-
2
3 #define VMX_SUCCESS         0
4 #define VMX_FAIL_INVALID    1
5 #define VMX_FAIL_VALID      2
6 #define VMM_FAILURE         3
7
8 #define VMCS_HOST_RSP       0x00006C14
9 #define VMCS_HOST_RIP       0x00006C16
10
11 #if defined(__V3_64BIT__)
12
13 #define save_registers(location)        \
14         pushq   %rax;                   \
15         movq    location, %rax;         \
16         movq    %rdi, (%rax);           \
17         movq    %rsi, 8(%rax);          \
18         movq    %rbp, 16(%rax);         \
19         movq    $0, 24(%rax);           \
20         movq    %rbx, 32(%rax);         \
21         movq    %rdx, 40(%rax);         \
22         movq    %rcx, 48(%rax);         \
23         pushq   %rbx;                   \
24         movq    8(%rsp), %rbx;          \
25         movq    %rbx, 56(%rax);         \
26         popq    %rbx;                   \
27                                         \
28         movq    %r8, 64(%rax);          \
29         movq    %r9, 72(%rax);          \
30         movq    %r10, 80(%rax);         \
31         movq    %r11, 88(%rax);         \
32         movq    %r12, 96(%rax);         \
33         movq    %r13, 104(%rax);        \
34         movq    %r14, 112(%rax);        \
35         movq    %r15, 120(%rax);        \
36         popq    %rax;                   
37         
38 #define restore_registers(location) \
39         mov     location, %rax;         \
40         mov     (%rax), %rdi;           \
41         mov     8(%rax), %rsi;          \
42         mov     16(%rax), %rbp;         \
43         mov     32(%rax), %rbx;         \
44         mov     40(%rax), %rdx;         \
45         mov 48(%rax), %rcx;             \
46                                         \
47         mov     64(%rax), %r8;          \
48         mov     72(%rax), %r9;          \
49         mov     80(%rax), %r10;         \
50         mov     88(%rax), %r11;         \
51         mov     96(%rax), %r12;         \
52         mov     104(%rax), %r13;        \
53         mov     112(%rax), %r14;        \
54         mov     120(%rax), %r15;        \
55     pushq %rbx;              \
56     movq 56(%rax), %rbx;     \
57     movq %rbx, %rax;         \
58     popq %rbx;;
59
60 #define save_ctrl_regs(location)    \
61     pushq %rax;              \
62     pushq %rbx;              \
63     movq location, %rax;     \
64     movq %cr2, %rbx;         \
65     movq %rbx, 8(%rax);      \
66     popq %rbx;               \
67     popq %rax
68
69 #define restore_ctrl_regs(location)  \
70     pushq %rax;              \
71     pushq %rbx;              \
72     movq location, %rax;     \
73     movq 8(%rax), %rbx;      \
74     movq %rbx, %cr2;         \
75     popq %rbx;               \
76     popq %rax
77
78 #define PUSHA    \
79     push %rax;   \
80     push %rbx;   \
81     push %rcx;   \
82     push %rdx;   \
83     push %rbp;   \
84     push %rdi;   \
85     push %rsi;   \
86     push %r8 ;   \
87     push %r9 ;   \
88     push %r10;   \
89     push %r11;   \
90     push %r12;   \
91     push %r13;   \
92     push %r14;   \
93     push %r15;   
94
95 #define POPA     \
96     pop %r15;    \
97     pop %r14;    \
98     pop %r13;    \
99     pop %r12;    \
100     pop %r11;    \
101     pop %r10;    \
102     pop %r9 ;    \
103     pop %r8 ;    \
104     pop %rsi;    \
105     pop %rdi;    \
106     pop %rbp;    \
107     pop %rdx;    \
108     pop %rcx;    \
109     pop %rbx;    \
110     pop %rax;    
111
112 .align 8
113 .globl v3_vmx_exit_handler
114 v3_vmx_exit_handler:
115     // the save_* argument is a macro expansion; it has to jump past any pushes in the macro
116     // stack: vm_regs ptr, ctrl_regs_ptr
117     // save registers macro stack: vm_regs ptr, ctrl_regs ptr, pushed rax
118     // save_ctrl_regs macro stack: vm_regs ptr, ctrl_regs_ptr, pushed rax, pushed rbx
119     // Both macros jump past 2 saved values to reach their pointers, so both are 16(rsp)
120     save_registers(16(%rsp));
121     save_ctrl_regs(16(%rsp));
122     addq $16, %rsp
123     POPA
124     popf
125     pushq %rdi
126     pushq %rsi
127     pushq %rdx
128     call v3_handle_vmx_exit
129
130     andq %rax, %rax
131     jnz .Lvmm_failure
132
133 v3_vmx_vmresume:
134     pop %rdx
135     pop %rsi
136     pop %rdi
137     pushf
138     PUSHA
139     pushq %rdi
140     pushq %rdx
141     restore_ctrl_regs(%rdx);
142     restore_registers(%rdi);
143
144     vmresume
145
146     jz .Lfail_valid
147     jc .Lfail_invalid
148     addq $16, %rsp
149     jmp .Lreturn
150
151 .align 8
152 .globl v3_vmx_vmlaunch
153 // vm_regs = %rdi, guest_info * = %rsi, ctrl_regs = %rdx
154 v3_vmx_vmlaunch:
155     pushf
156     PUSHA
157     pushq %rdi
158     pushq %rdx
159     
160     movq %rsp, %rax
161     movq $VMCS_HOST_RSP, %rbx
162     vmwrite %rax, %rbx
163     jz .Lfail_valid
164     jc .Lfail_invalid
165
166     movq $v3_vmx_exit_handler, %rax
167     movq $VMCS_HOST_RIP, %rbx
168     vmwrite %rax, %rbx
169     jz .Lfail_valid
170     jc .Lfail_invalid
171
172     restore_ctrl_regs(%rdx);
173     restore_registers(%rdi);
174
175     vmlaunch
176     jz .Lfail_valid
177     jc .Lfail_invalid
178     jmp .Lreturn
179
180 .Lfail_valid:
181     addq $16, %rsp
182     POPA
183     popf
184     movq $VMX_FAIL_VALID, %rax
185     jmp .Lreturn
186
187 .Lfail_invalid:
188     addq $16, %rsp
189     POPA
190     popf
191     movq $VMX_FAIL_INVALID, %rax
192     jmp .Lreturn
193
194 .Lvmm_failure:
195     addq $24, %rsp
196     movq $VMM_FAILURE, %rax
197     jmp .Lreturn
198
199 .Lreturn:
200     sti
201     ret
202     
203 #else
204
205 #define save_resgisters(location)       \
206         pushl   %eax;                   \
207         movl    location, %eax;         \
208         movl    %edi, (%eax);           \
209         movl    %esi, 8(%eax);          \
210         movl    %ebp, 16(%eax);         \
211         movl    $0, 24(%eax);           \
212         movl    %ebx, 32(%eax);         \
213         movl    %edx, 40(%eax);         \
214         movl    %ecx, 48(%eax);         \
215         pushl   %ebx;                   \
216         movl    8(%esp), %ebx;          \
217         movl    %ebx, 56(%eax);         \
218         popl    %ebx;                   \
219         popl    %eax;                   
220         
221
222 #define restore_registers(location) \
223         pushl   %eax;                   \
224         movl    location, %eax;         \
225         movl    (%eax), %edi;           \
226         movl    8(%eax), %esi;          \
227         movl    16(%eax), %ebp;         \
228         movl    32(%eax), %ebx;         \
229         movl    40(%eax), %edx;         \
230         movl    48(%eax), %ecx;         \
231         popl    %eax;
232  
233 #define PUSHA    \
234     push %eax;   \
235     push %ebx;   \
236     push %ecx;   \
237     push %edx;   \
238     push %ebp;   \
239     push %edi;   \
240     push %esi;
241
242 #define POPA     \
243     pop %esi;    \
244     pop %edi;    \
245     pop %ebp;    \
246     pop %edx;    \
247     pop %ecx;    \
248     pop %ebx;    \
249     pop %eax;
250
251 .align 8
252 .globl v3_vmx_exit_handler
253 v3_vmx_exit_handler:
254     save_registers(4(%esp))
255     addl $8, %esp
256     POPA
257     popf
258     pushl %edi
259     call v3_handle_vmx_exit
260
261     andl %eax, %eax
262     jnz .Lvmm_failure
263
264 v3_vmx_vmresume:
265     popl %edi
266     pushf
267     PUSHA
268     pushl %edi
269     restore_registers(%rdi)
270
271     vmresume
272
273     addl $8, %esp
274     jz .Lfail_valid
275     jc .Lfail_invalid
276     jmp .Lreturn
277
278 .align 8
279 .globl v3_vmx_vmlaunch
280 // vm_regs = %edi
281 v3_vmx_vmlaunch:
282     cli
283     pushf
284     PUSHA
285     pushl %edi
286
287     movl %esp, %eax
288     movl $VMCS_HOST_RSP, %ebx
289     vmwrite %eax, %ebx
290     jz .Lfail_valid
291     jc .Lfail_invalid
292
293     movl $v3_vmx_exit_handler, %eax
294     movl $VMCS_HOST_RIP, %ebx
295     vmwrite %eax, %ebx
296     jz .Lfail_valid
297     jc .Lfail_invalid
298
299     restore_registers(%edi)
300
301     vmlaunch
302     jz .Lfail_valid
303     jc .Lfail_invalid
304     jmp .Lreturn
305
306 .Lfail_valid:
307     addl $8, %esp
308     POPA
309     movl $VMX_FAIL_VALID, %eax
310     jmp .Lreturn
311
312 .Lfail_invalid:
313     addq $8, %esp
314     POPA
315     movl $MVX_FAIL_INVALID, %eax
316     jmp .Lreturn
317
318 .Lvmm_failure:
319     addq $8, %esp
320     POPA
321     movl $VMM_FAILURE, %eax
322     jmp .Lreturn
323
324 .Lreturn:
325     sti
326     popf
327     ret
328
329 #endif
330