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.


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