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.


added copyright tags
[palacios.git] / palacios / src / palacios / vmx_lowlevel.asm
1 ; -*- fundamental -*- 
2
3 ;; Northwestern University 
4 ;; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu> 
5
6 %ifndef VMX_ASM
7 %define VMX_ASM
8
9
10 %include "defs.asm"
11 %include "symbol.asm"
12
13
14 %include "vmcs_fields.asm"
15
16 VMX_SUCCESS equ 0x00000000
17 VMX_FAIL_INVALID equ 0x00000001
18 VMX_FAIL_VALID  equ 0x00000002
19 VMM_ERROR       equ 0x00000003
20
21 [BITS 32]
22
23 IMPORT Do_VMM
24
25
26 ; VMX Functions
27 EXPORT VMCS_READ
28 EXPORT VMCS_WRITE
29 EXPORT VMCS_CLEAR
30 EXPORT VMCS_LOAD
31 EXPORT VMCS_STORE
32 EXPORT Enable_VMX
33 EXPORT Disable_VMX
34 EXPORT Launch_VM
35 EXPORT VMCS_LAUNCH
36 EXPORT VMCS_RESUME
37 EXPORT RunVMM
38 EXPORT SAFE_VM_LAUNCH
39 EXPORT Init_VMCS_HostState
40 EXPORT Init_VMCS_GuestState
41         
42 ;
43 ; Enable_VMX - Turn on VMX
44 ;
45 align 8
46 Enable_VMX:
47         push    ebp
48         mov     ebp, esp
49         push    ebx
50         mov     ebx, cr4
51         or      ebx, dword 0x00002000
52         mov     cr4, ebx
53         mov     ebx, cr0
54         or      ebx, dword 0x80000021
55         mov     cr0, ebx
56         vmxon   [ebp+8]
57         pop     ebx
58         pop     ebp
59         mov     eax, VMX_SUCCESS
60         jnc     .return
61         mov     eax, VMX_FAIL_INVALID
62 .return
63         ret
64
65         
66 ;
67 ; VMREAD  - read a value from a VMCS
68 ;
69 align 8
70 VMCS_READ:
71         push    ebp
72         mov     ebp, esp
73         push    ecx
74         push    ebx
75
76         mov     ecx, [ebp + 8]
77         mov     ebx,[ebp + 12]
78 ;       lea     ebx, ebp
79         vmread  [ebx], ecx
80
81         pop     ebx
82         pop     ecx
83         pop     ebp
84         jz      .error_code
85         jc      .error
86
87         mov     eax, VMX_SUCCESS
88         jmp     .return
89 .error
90         mov     eax, VMX_FAIL_INVALID
91         jmp     .return
92 .error_code
93         mov     eax, VMX_FAIL_VALID
94 .return
95         ret
96
97 ;
98 ; VMWRITE - write a value to a VMCS
99 align 8
100 VMCS_WRITE:
101         push    ebp
102         mov     ebp, esp
103         push    ebx
104
105         mov     eax, [ebp + 8]
106         mov     ebx, [ebp + 12]
107         vmwrite eax, [ebx]
108
109         pop     ebx
110         pop     ebp
111         jz      .error_code
112         jc      .error
113
114         mov     eax, VMX_SUCCESS
115         jmp     .return
116 .error
117         mov     eax, VMX_FAIL_INVALID
118         jmp     .return
119 .error_code
120         mov     eax, VMX_FAIL_VALID
121 .return
122         ret
123
124 ;
125 ; VMCLEAR - Initializes a VMCS
126 ;
127 align 8
128 VMCS_CLEAR:
129         vmclear [esp+4]
130         jz      .error_code
131         jc      .error
132
133         mov     eax, VMX_SUCCESS
134         jmp     .return
135 .error
136         mov     eax, VMX_FAIL_INVALID
137         jmp     .return
138 .error_code
139         mov     eax, VMX_FAIL_VALID
140 .return
141         ret
142
143
144
145 ;
146 ; VMCS_LOAD - load a VMCS 
147 ;
148 align 8
149 VMCS_LOAD:
150         vmptrld [esp+4]
151         jz      .error_code
152         jc      .error
153
154         mov     eax, VMX_SUCCESS
155         jmp     .return
156 .error
157         mov     eax, VMX_FAIL_INVALID
158         jmp     .return
159 .error_code
160         mov     eax, VMX_FAIL_VALID
161 .return
162         ret
163
164
165
166 ;
167 ; VMCS_STORE - Store a VMCS
168 ;
169 align 8
170 VMCS_STORE:
171         mov     eax, [esp+4]
172         vmptrst [eax]
173         jz      .error_code
174         jc      .error
175
176         mov     eax, VMX_SUCCESS
177         jmp     .return
178 .error
179         mov     eax, VMX_FAIL_INVALID
180         jmp     .return
181 .error_code
182         mov     eax, VMX_FAIL_VALID
183 .return
184         ret
185
186
187 ;
188 ; VMCS_LAUNCH
189 ;
190 align 8
191 VMCS_LAUNCH:
192         vmlaunch
193         jz      .error_code
194         jc      .error
195
196         mov     eax, VMX_SUCCESS
197         jmp     .return
198 .error
199         mov     eax, VMX_FAIL_INVALID
200         jmp     .return
201 .error_code
202         mov     eax, VMX_FAIL_VALID
203 .return
204         ret
205
206
207
208 ;
209 ; VMCS_RESUME
210 ;
211 align 8
212 VMCS_RESUME:
213         vmresume
214         jz      .error_code
215         jc      .error
216
217         mov     eax, VMX_SUCCESS
218         jmp     .return
219 .error
220         mov     eax, VMX_FAIL_INVALID
221         jmp     .return
222 .error_code
223         mov     eax, VMX_FAIL_VALID
224 .return
225         ret
226
227 align 8
228 SAFE_VM_LAUNCH:
229         pushf
230         pusha
231         mov     eax, HOST_RSP
232         vmwrite eax, esp
233         jz      .esp_err
234         jc      .esp_err
235         jmp     .vm_cont
236
237 .esp_err
238         popa
239         jz      .error_code
240         jc      .error
241 .vm_cont
242         vmlaunch
243         popa
244         jz      .error_code
245         jc      .error  
246
247         mov     eax, VMX_SUCCESS
248         jmp     .return
249 .error
250         mov     eax, VMX_FAIL_INVALID
251         jmp     .return
252 .error_code
253         mov     eax, VMX_FAIL_VALID
254 .return
255         popf
256         ret
257
258
259 ;
260 ; RunVMM
261 ;
262 align 8
263 RunVMM:
264         pusha
265         call    Do_VMM
266         and     eax, eax
267         jnz     .vmm_error
268         jmp     .vm_cont
269
270 .vmm_error
271         popa
272         popa
273         mov     eax, VMM_ERROR
274         jmp     .return
275
276 .vm_cont
277         popa
278         vmresume
279         popa    ; we only get here if there is an error in the vmresume
280                 ; we restore the host state and return an error code
281
282         jz      .error_code
283         jc      .error
284
285         mov     eax, VMX_SUCCESS
286         jmp     .return
287 .error
288         mov     eax, VMX_FAIL_INVALID
289         jmp     .return
290 .error_code
291         mov     eax, VMX_FAIL_VALID
292 .return
293         popf
294         ret
295
296
297
298
299 ;
300 ; Setup_VMCS_GuestState
301 ; Copy all of the Guest registers into the guest state of a vmcs 
302 ;
303
304 align 8
305 InitGuestSelectors:
306         push    ebp
307         mov     ebp, esp
308         push    ebx
309         push    ebx
310
311         mov     ebx, VMCS_GUEST_ES_SELECTOR
312         mov     eax, es
313         vmwrite ebx, eax
314         jz      .error_code
315         jc      .error
316
317         mov     ebx, VMCS_GUEST_CS_SELECTOR
318         mov     eax, cs
319         vmwrite ebx, eax
320         jz      .error_code
321         jc      .error
322
323         mov     ebx, VMCS_GUEST_SS_SELECTOR
324         mov     eax, ss
325         vmwrite ebx, eax
326         jz      .error_code
327         jc      .error
328
329         mov     ebx, VMCS_GUEST_DS_SELECTOR
330         mov     eax, ds
331         vmwrite ebx, eax
332         jz      .error_code
333         jc      .error
334
335         mov     ebx, VMCS_GUEST_FS_SELECTOR
336         mov     eax, fs
337         vmwrite ebx, eax
338         jz      .error_code
339         jc      .error
340
341         mov     ebx, VMCS_GUEST_GS_SELECTOR
342         mov     eax, gs
343         vmwrite ebx, eax
344         jz      .error_code
345         jc      .error
346
347         str     [esp]
348         mov     eax, [esp]
349         mov     ebx, VMCS_GUEST_TR_SELECTOR
350         vmwrite ebx, eax
351         jz      .error_code
352         jc      .error
353
354         mov     eax, VMX_SUCCESS
355         jmp     .return
356 .error
357         mov     eax, VMX_FAIL_INVALID
358         jmp     .return
359 .error_code
360         mov     eax, VMX_FAIL_VALID
361 .return
362         pop     ebx
363         pop     ebx
364         pop     ebp
365         ret
366 ret
367
368 align 8
369 InitGuestDescRegs:
370         push    ebp
371         mov     ebp, esp
372         push    ebx
373         sub     esp, 6
374
375
376         sgdt    [esp]
377         mov     eax, [esp]
378         and     eax, 0xffff
379         mov     ebx, GUEST_GDTR_LIMIT
380         vmwrite ebx, eax
381         jz      .error_code
382         jc      .error
383
384         mov     eax, [esp+2]
385         mov     ebx, GUEST_GDTR_BASE
386         vmwrite ebx, eax
387         jz      .error_code
388         jc      .error
389
390
391         sidt    [esp]
392         mov     eax, [esp]
393         and     eax, 0xffff
394         mov     ebx, GUEST_IDTR_LIMIT
395         vmwrite ebx, eax
396         jz      .error_code
397         jc      .error
398
399         mov     eax, [esp+2]
400         mov     ebx, GUEST_IDTR_BASE
401         vmwrite ebx, eax
402         jz      .error_code
403         jc      .error
404
405
406         sldt    [esp]
407         mov     eax, [esp]      
408         mov     ebx, GUEST_LDTR_BASE
409         vmwrite ebx, eax
410         jz      .error_code
411         jc      .error
412
413
414         mov     eax, 0x00000000
415         mov     ebx, GUEST_LDTR_LIMIT
416         vmwrite ebx, eax
417         jz      .error_code     
418         jc      .error
419
420
421         mov     eax, VMX_SUCCESS
422         jmp     .return
423 .error
424         mov     eax, VMX_FAIL_INVALID
425         jmp     .return
426 .error_code
427         mov     eax, VMX_FAIL_VALID
428 .return
429
430         add     esp, 6
431         pop     ebx
432         pop     ebp
433         ret
434
435
436
437
438
439 align 8
440 InitGuestSegBases:
441         push    ebp
442         mov     ebp, esp
443         push    ebx
444
445
446         mov     eax, dword 0
447         mov     ebx, GUEST_ES_BASE
448         vmwrite ebx, eax
449         jz      .error_code
450         jc      .error
451
452         mov     eax, dword 0
453         mov     ebx, GUEST_CS_BASE
454         vmwrite ebx, eax
455         jz      .error_code
456         jc      .error
457
458         mov     eax, dword 0
459         mov     ebx, GUEST_SS_BASE
460         vmwrite ebx, eax
461         jz      .error_code
462         jc      .error
463
464         mov     eax, dword 0
465         mov     ebx, GUEST_DS_BASE
466         vmwrite ebx, eax
467         jz      .error_code
468         jc      .error
469
470         mov     eax, dword 0
471         mov     ebx, GUEST_FS_BASE
472         vmwrite ebx, eax
473         jz      .error_code
474         jc      .error
475
476         mov     eax, dword 0
477         mov     ebx, GUEST_GS_BASE
478         vmwrite ebx, eax
479         jz      .error_code
480         jc      .error
481
482 ;       mov     eax, dword 0
483         mov     eax, 0x000220a0
484         mov     ebx, GUEST_TR_BASE
485         vmwrite ebx, eax
486         jz      .error_code
487         jc      .error
488
489         mov     eax, VMX_SUCCESS
490         jmp     .return
491 .error
492         mov     eax, VMX_FAIL_INVALID
493         jmp     .return
494 .error_code
495         mov     eax, VMX_FAIL_VALID
496 .return
497
498         pop     ebx
499         pop     ebp
500         ret
501
502 align 8
503 InitGuestSegsAccess:
504         push    ebp
505         mov     ebp, esp
506         push    ebx
507
508         mov     eax, 1100000010010011b
509         mov     ebx, GUEST_ES_ACCESS
510         vmwrite ebx, eax
511         jz      .error_code
512         jc      .error
513
514
515
516         mov     eax, 1100000010011001b
517 ;       mov     eax, 0x0000c099
518         mov     ebx, GUEST_CS_ACCESS
519         vmwrite ebx, eax
520         jz      .error_code
521         jc      .error
522
523 ;       mov     eax, 1100000010010111b
524         mov     eax, 1100000010010011b
525         mov     ebx, GUEST_SS_ACCESS
526         vmwrite ebx, eax
527         jz      .error_code
528         jc      .error
529
530         mov     eax, 1100000010010011b
531         mov     ebx, GUEST_DS_ACCESS
532         vmwrite ebx, eax
533         jz      .error_code
534         jc      .error
535
536
537         mov     eax, 1100000010010011b
538         mov     ebx, GUEST_FS_ACCESS
539         vmwrite ebx, eax
540         jz      .error_code
541         jc      .error
542
543
544         mov     eax, 1100000010010011b
545         mov     ebx, GUEST_GS_ACCESS
546         vmwrite ebx, eax
547         jz      .error_code
548         jc      .error
549
550         mov     eax, 0x10000
551         mov     ebx, GUEST_LDTR_ACCESS
552         vmwrite ebx, eax
553         jz      .error_code
554         jc      .error
555
556         mov     eax, 01000000010001011b
557         mov     ebx, GUEST_TR_ACCESS
558         vmwrite ebx, eax
559         jz      .error_code
560         jc      .error
561
562
563
564         mov     eax, VMX_SUCCESS
565         jmp     .return
566 .error
567         mov     eax, VMX_FAIL_INVALID
568         jmp     .return
569 .error_code
570         mov     eax, VMX_FAIL_VALID
571 .return
572         pop     ebx
573         pop     ebp
574         ret
575
576 ;; Do seg limit
577 align 8
578 InitGuestSegsLimits:
579         push    ebp
580         mov     ebp, esp
581         push    ebx
582
583         
584 ;       mov     eax, 0xffffffff
585         mov     eax, 0xffffffff
586         mov     ebx, GUEST_ES_LIMIT
587         vmwrite ebx, eax
588         jz      .error_code     
589         jc      .error
590
591 ;       mov     eax, 0xffffffff
592         mov     eax, 0xffffffff
593         mov     ebx, GUEST_CS_LIMIT
594         vmwrite ebx, eax
595         jz      .error_code     
596         jc      .error
597
598 ;       mov     eax, 0xffffffff
599         mov     eax, 0xffffffff
600         mov     ebx, GUEST_SS_LIMIT
601         vmwrite ebx, eax
602         jz      .error_code     
603         jc      .error
604
605 ;       mov     eax, 0xffffffff
606         mov     eax, 0xffffffff
607         mov     ebx, GUEST_DS_LIMIT
608         vmwrite ebx, eax
609         jz      .error_code     
610         jc      .error
611
612 ;       mov     eax, 0xffffffff
613         mov     eax, 0xffffffff
614         mov     ebx, GUEST_FS_LIMIT
615         vmwrite ebx, eax
616         jz      .error_code     
617         jc      .error
618
619 ;       mov     eax, 0xffffffff
620         mov     eax, 0xffffffff
621         mov     ebx, GUEST_GS_LIMIT
622         vmwrite ebx, eax
623         jz      .error_code     
624         jc      .error
625
626 ;       mov     eax, 0xffffffff
627         mov     eax, 0x68fff
628         mov     ebx, GUEST_TR_LIMIT
629         vmwrite ebx, eax
630         jz      .error_code     
631         jc      .error
632
633         mov     eax, VMX_SUCCESS
634         jmp     .return
635 .error
636         mov     eax, VMX_FAIL_INVALID
637         jmp     .return
638 .error_code
639         mov     eax, VMX_FAIL_VALID
640 .return
641         pop     ebx
642         pop     ebp
643         ret
644
645
646 align 8
647 Init_VMCS_GuestState:
648         push    ebp
649         mov     ebp, esp
650         push    ebx
651
652         mov     ebx, GUEST_CR3
653         mov     eax, cr3
654         vmwrite ebx, eax
655         jz      .error_code
656         jc      .error
657
658         call    InitGuestSelectors
659         and     eax, 0xffffffff
660         jz      .selDone
661         jmp     .return
662 .selDone
663
664         call    InitGuestDescRegs
665         and     eax, 0xffffffff
666         jz      .descRegsDone
667         jmp     .return
668 .descRegsDone
669
670         call    InitGuestSegBases
671         and     eax, 0xffffffff
672         jz      .descSegBasesDone
673         jmp     .return
674 .descSegBasesDone
675
676
677         call    InitGuestSegsLimits
678         and     eax, 0xffffffff
679         jz      .segsLimitsDone
680         jmp     .return
681 .segsLimitsDone
682
683         call    InitGuestSegsAccess
684         and     eax, 0xffffffff
685         jz      .segsAccessDone
686         jmp     .return
687 .segsAccessDone
688
689         mov     ebx, GUEST_RSP
690         mov     eax, esp
691         vmwrite ebx, eax
692         jz      .error_code
693         jc      .error
694
695         mov     ebx, GUEST_RFLAGS
696         mov     eax, dword 0x00000002
697         vmwrite ebx, eax
698         jz      .error_code
699         jc      .error
700
701         mov     ebx, GUEST_DR7
702         mov     eax, dword 0x00000400
703         vmwrite ebx, eax
704         jz      .error_code
705         jc      .error
706
707         mov     eax, VMX_SUCCESS
708         jmp     .return
709 .error
710         mov     eax, VMX_FAIL_INVALID
711         jmp     .return
712 .error_code
713         mov     eax, VMX_FAIL_VALID
714 .return
715         pop     ebx
716         pop     ebp
717         ret
718
719 ;
720 ; Setup_VMCS_HostState
721 ; Copy all of the host registers into the host state of a vmcs 
722 ;
723
724 align 8
725 InitHostSelectors:
726         push    ebp
727         mov     ebp, esp
728         push    ebx
729         push    ebx
730
731         mov     ebx, VMCS_HOST_ES_SELECTOR
732         mov     eax, es
733         vmwrite ebx, eax
734         jz      .error_code
735         jc      .error
736
737         mov     ebx, VMCS_HOST_CS_SELECTOR
738         mov     eax, cs
739         vmwrite ebx, eax
740         jz      .error_code
741         jc      .error
742
743         mov     ebx, VMCS_HOST_SS_SELECTOR
744         mov     eax, ss
745         vmwrite ebx, eax
746         jz      .error_code
747         jc      .error
748
749         mov     ebx, VMCS_HOST_DS_SELECTOR
750         mov     eax, ds
751         vmwrite ebx, eax
752         jz      .error_code
753         jc      .error
754
755         mov     ebx, VMCS_HOST_FS_SELECTOR
756         mov     eax, fs
757         vmwrite ebx, eax
758         jz      .error_code
759         jc      .error
760
761         mov     ebx, VMCS_HOST_GS_SELECTOR
762         mov     eax, gs
763         vmwrite ebx, eax
764         jz      .error_code
765         jc      .error
766
767         str     [esp]
768         mov     eax, [esp]
769         mov     ebx, VMCS_HOST_TR_SELECTOR
770         vmwrite ebx, eax
771         jz      .error_code
772         jc      .error
773
774         mov     eax, VMX_SUCCESS
775         jmp     .return
776 .error
777         mov     eax, VMX_FAIL_INVALID
778         jmp     .return
779 .error_code
780         mov     eax, VMX_FAIL_VALID
781 .return
782         pop     ebx
783         pop     ebx
784         pop     ebp
785         ret
786 ret
787
788
789
790
791
792 align 8
793 InitHostBaseRegs:
794         push    ebp
795         mov     ebp, esp
796         push    ebx
797         sub     esp, 6
798
799         sgdt    [esp]
800         mov     eax, [esp+2]
801         mov     ebx, HOST_GDTR_BASE
802         vmwrite ebx, eax
803         jz      .error_code
804         jc      .error
805
806         sidt    [esp]
807         mov     eax, [esp+2]
808         mov     ebx, HOST_IDTR_BASE
809         vmwrite ebx, eax
810         jz      .error_code
811         jc      .error
812
813
814         mov     eax, dword 0
815         mov     ebx, HOST_FS_BASE
816         vmwrite ebx, eax
817         jz      .error_code
818         jc      .error
819
820         mov     eax, dword 0
821         mov     ebx, HOST_GS_BASE
822         vmwrite ebx, eax
823         jz      .error_code
824         jc      .error
825
826         mov     eax, dword 0
827         mov     ebx, HOST_TR_BASE
828         vmwrite ebx, eax
829         jz      .error_code
830         jc      .error
831
832         mov     eax, VMX_SUCCESS
833         jmp     .return
834 .error
835         mov     eax, VMX_FAIL_INVALID
836         jmp     .return
837 .error_code
838         mov     eax, VMX_FAIL_VALID
839 .return
840
841         add     esp, 6
842         pop     ebx
843         pop     ebp
844         ret
845
846
847 align 8
848 Init_VMCS_HostState:
849         push    ebp
850         mov     ebp, esp
851         push    ebx
852         
853         mov     ebx, HOST_CR3
854         mov     eax, cr3
855         vmwrite ebx, eax
856         jz      .error_code
857         jc      .error
858
859
860         mov     ebx, HOST_RSP
861         mov     eax, esp
862         vmwrite ebx, eax
863         jz      .error_code
864         jc      .error
865
866 ;       push    esp
867         call    InitHostSelectors
868         and     eax, 0xffffffff
869         jz      .selDone
870         jmp     .return
871 .selDone
872 ;       push    esp
873         call    InitHostBaseRegs
874         and     eax, 0xffffffff
875         jz      .baseRegsDone
876         jmp     .return
877 .baseRegsDone
878
879
880         mov     eax, VMX_SUCCESS
881         jmp     .return
882 .error
883         mov     eax, VMX_FAIL_INVALID
884         jmp     .return
885 .error_code
886         mov     eax, VMX_FAIL_VALID
887 .return
888         pop     ebx
889         pop     ebp
890         ret
891
892 ;
893 ; Launch_VM - inits a vmcs with an ip and launches it
894 ; [eip = ebp + 8], [vmcs = ebp + 12]
895 ; int Launch_VM(ullont_t VMCS, uint_t eip);
896 ;
897 align 8
898 Launch_VM:
899         push    ebp
900         mov     ebp, esp
901         push    ebx
902         mov     ebx, dword 0
903         vmclear [ebp+8]
904         jz      .error_code
905         jc      .error
906         add     ebx, dword 1
907         vmptrld [ebp+8]
908         jz      .error_code
909         jc      .error
910         mov     eax, dword 0x0000681E
911         add     ebx, dword 1
912         vmwrite eax, [ebp+16]
913         jz      .error_code
914         jc      .error
915         add     ebx, dword 1
916         vmlaunch
917         jz      .error_code
918         jc      .error
919         mov     eax, VMX_SUCCESS
920         jmp     .return
921 .error
922         shl     ebx, 4
923         mov     eax, VMX_FAIL_INVALID
924         or      eax, ebx
925         jmp     .return
926 .error_code
927         shl     ebx, 4
928         mov     eax, VMX_FAIL_VALID
929         or      eax, ebx
930         mov     ebx, dword 0x00004400
931         vmread  eax, ebx
932 .return
933         pop     ebx
934         pop     ebp
935
936         ret
937
938
939 %endif