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.


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