vmcs_intel_x64_check_guest.cpp
Go to the documentation of this file.
1 //
2 // Bareflank Hypervisor
3 //
4 // Copyright (C) 2015 Assured Information Security, Inc.
5 // Author: Rian Quinn <quinnr@ainfosec.com>
6 // Author: Brendan Kerrigan <kerriganb@ainfosec.com>
7 // Author: Connor Davis <davisc@ainfosec.com>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 
23 #include <vmcs/vmcs_intel_x64.h>
30 
31 #include <intrinsics/cpuid_x64.h>
32 #include <intrinsics/pdpte_x64.h>
34 
36 
37 using namespace x64;
38 using namespace intel_x64;
39 using namespace vmcs;
40 using namespace check;
41 
42 void
44 {
51 }
52 
53 void
55 {
70 }
71 
72 void
74 {
75  auto cr0 = guest_cr0::get();
76  auto ia32_vmx_cr0_fixed0 = msrs::ia32_vmx_cr0_fixed0::get();
77  auto ia32_vmx_cr0_fixed1 = msrs::ia32_vmx_cr0_fixed1::get();
78 
81 
82  if (0 != ((~cr0 & ia32_vmx_cr0_fixed0) | (cr0 & ~ia32_vmx_cr0_fixed1)))
83  {
84  bferror << " failed: check_guest_cr0_for_unsupported_bits" << bfendl;
85  bferror << " - ia32_vmx_cr0_fixed0: " << view_as_pointer(ia32_vmx_cr0_fixed0) << bfendl;
86  bferror << " - ia32_vmx_cr0_fixed1: " << view_as_pointer(ia32_vmx_cr0_fixed1) << bfendl;
87  bferror << " - cr0: " << view_as_pointer(cr0) << bfendl;
88 
89  throw std::logic_error("invalid cr0");
90  }
91 }
92 
93 void
95 {
97  return;
98 
100  throw std::logic_error("PE must be enabled in cr0 if PG is enabled");
101 }
102 
103 void
105 {
106  auto cr4 = guest_cr4::get();
107  auto ia32_vmx_cr4_fixed0 = msrs::ia32_vmx_cr4_fixed0::get();
108  auto ia32_vmx_cr4_fixed1 = msrs::ia32_vmx_cr4_fixed1::get();
109 
110  if (0 != ((~cr4 & ia32_vmx_cr4_fixed0) | (cr4 & ~ia32_vmx_cr4_fixed1)))
111  {
112  bferror << " failed: check_guest_cr4_for_unsupported_bits" << bfendl;
113  bferror << " - ia32_vmx_cr4_fixed0: " << view_as_pointer(ia32_vmx_cr4_fixed0) << bfendl;
114  bferror << " - ia32_vmx_cr4_fixed1: " << view_as_pointer(ia32_vmx_cr4_fixed1) << bfendl;
115  bferror << " - cr4: " << view_as_pointer(cr4) << bfendl;
116 
117  throw std::logic_error("invalid cr4");
118  }
119 }
120 
121 void
123 {
125  return;
126 
127  if (vmcs::guest_ia32_debugctl::reserved::get() != 0)
128  throw std::logic_error("debug ctrl msr reserved bits must be 0");
129 }
130 
131 void
133 {
135  return;
136 
138  throw std::logic_error("paging must be enabled if ia 32e guest mode is enabled");
139 
141  throw std::logic_error("pae must be enabled if ia 32e guest mode is enabled");
142 }
143 
144 void
146 {
148  return;
149 
151  throw std::logic_error("pcide in cr4 must be disabled if ia 32e guest mode is disabled");
152 }
153 
154 void
156 {
157  if (!x64::is_physical_address_valid(guest_cr3::get()))
158  throw std::logic_error("guest cr3 too large");
159 }
160 
161 void
163 {
165  return;
166 
167  auto dr7 = vmcs::guest_dr7::get();
168 
169  if ((dr7 & 0xFFFFFFFF00000000) != 0)
170  throw std::logic_error("bits 63:32 of dr7 must be 0 if load debug controls is 1");
171 }
172 
173 void
175 {
176  if (!x64::is_address_canonical(vmcs::guest_ia32_sysenter_esp::get()))
177  throw std::logic_error("guest sysenter esp must be canonical");
178 }
179 
180 void
182 {
183  if (!x64::is_address_canonical(vmcs::guest_ia32_sysenter_eip::get()))
184  throw std::logic_error("guest sysenter eip must be canonical");
185 }
186 
187 void
189 {
191  return;
192 
193  if (vmcs::guest_ia32_perf_global_ctrl::reserved::get() != 0)
194  throw std::logic_error("perf global ctrl msr reserved bits must be 0");
195 }
196 
197 void
199 {
201  return;
202 
203  if (check::memory_type_reserved(guest_ia32_pat::pa0::memory_type::get()))
204  throw std::logic_error("pat0 has a reserved memory type");
205 
206  if (check::memory_type_reserved(guest_ia32_pat::pa1::memory_type::get()))
207  throw std::logic_error("pat1 has a reserved memory type");
208 
209  if (check::memory_type_reserved(guest_ia32_pat::pa2::memory_type::get()))
210  throw std::logic_error("pat2 has a reserved memory type");
211 
212  if (check::memory_type_reserved(guest_ia32_pat::pa3::memory_type::get()))
213  throw std::logic_error("pat3 has a reserved memory type");
214 
215  if (check::memory_type_reserved(guest_ia32_pat::pa4::memory_type::get()))
216  throw std::logic_error("pat4 has a reserved memory type");
217 
218  if (check::memory_type_reserved(guest_ia32_pat::pa5::memory_type::get()))
219  throw std::logic_error("pat5 has a reserved memory type");
220 
221  if (check::memory_type_reserved(guest_ia32_pat::pa6::memory_type::get()))
222  throw std::logic_error("pat6 has a reserved memory type");
223 
224  if (check::memory_type_reserved(guest_ia32_pat::pa7::memory_type::get()))
225  throw std::logic_error("pat7 has a reserved memory type");
226 }
227 
228 void
230 {
232  return;
233 
234  if (guest_ia32_efer::reserved::get() != 0)
235  throw std::logic_error("ia32 efer msr reserved buts must be 0 if "
236  "load ia32 efer entry is enabled");
237 
240 
242  throw std::logic_error("ia 32e mode is 0, but efer.lma is 1");
243 
245  throw std::logic_error("ia 32e mode is 1, but efer.lma is 0");
246 
248  return;
249 
250  if (!lme && lma)
251  throw std::logic_error("efer.lme is 0, but efer.lma is 1");
252 
253  if (lme && !lma)
254  throw std::logic_error("efer.lme is 1, but efer.lma is 0");
255 }
256 
257 void
259 {
261  return;
262 
263  auto bndcfgs = vmcs::guest_ia32_bndcfgs::get();
264 
265  if ((bndcfgs & 0x0000000000000FFC) != 0)
266  throw std::logic_error("ia32 bndcfgs msr reserved bits must be 0 if "
267  "load ia32 bndcfgs entry is enabled");
268 
269  auto bound_addr = bndcfgs & 0xFFFFFFFFFFFFF000;
270 
271  if (!x64::is_address_canonical(bound_addr))
272  throw std::logic_error("bound address in ia32 bndcfgs msr must be "
273  "canonical if load ia32 bndcfgs entry is enabled");
274 }
275 
276 void
278 {
366 }
367 
368 void
370 {
371  if (guest_tr_selector::ti::get())
372  throw std::logic_error("guest tr's ti flag must be zero");
373 }
374 
375 void
377 {
378  if (guest_ldtr_access_rights::unusable::get() != 0)
379  return;
380 
381  if (guest_ldtr_selector::ti::get())
382  throw std::logic_error("guest ldtr's ti flag must be zero");
383 }
384 
385 void
387 {
388  using namespace primary_processor_based_vm_execution_controls;
389  using namespace secondary_processor_based_vm_execution_controls;
390 
392  return;
393 
395  return;
396 
397  if (guest_ss_selector::rpl::get() != guest_cs_selector::rpl::get())
398  throw std::logic_error("ss and cs rpl must be the same");
399 }
400 
401 void
403 {
405  return;
406 
407  auto cs = guest_cs_selector::get();
408 
409  if ((cs << 4) != vmcs::guest_cs_base::get())
410  throw std::logic_error("if virtual 8086 mode is enabled, cs base must be cs shifted 4 bits");
411 }
412 
413 void
415 {
417  return;
418 
419  auto ss = guest_ss_selector::get();
420 
421  if ((ss << 4) != vmcs::guest_ss_base::get())
422  throw std::logic_error("if virtual 8086 mode is enabled, ss base must be ss shifted 4 bits");
423 }
424 
425 void
427 {
429  return;
430 
431  auto ds = guest_ds_selector::get();
432 
433  if ((ds << 4) != vmcs::guest_ds_base::get())
434  throw std::logic_error("if virtual 8086 mode is enabled, ds base must be ds shifted 4 bits");
435 }
436 
437 void
439 {
441  return;
442 
443  auto es = guest_es_selector::get();
444 
445  if ((es << 4) != vmcs::guest_es_base::get())
446  throw std::logic_error("if virtual 8086 mode is enabled, es base must be es shifted 4 bits");
447 }
448 
449 void
451 {
453  return;
454 
455  auto fs = guest_fs_selector::get();
456 
457  if ((fs << 4) != vmcs::guest_fs_base::get())
458  throw std::logic_error("if virtual 8086 mode is enabled, fs base must be fs shifted 4 bits");
459 }
460 
461 void
463 {
465  return;
466 
467  auto gs = guest_gs_selector::get();
468 
469  if ((gs << 4) != vmcs::guest_gs_base::get())
470  throw std::logic_error("if virtual 8086 mode is enabled, gs base must be gs shift 4 bits");
471 }
472 
473 void
475 {
476  if (!x64::is_address_canonical(vmcs::guest_tr_base::get()))
477  throw std::logic_error("guest tr base non-canonical");
478 }
479 
480 void
482 {
483  if (!x64::is_address_canonical(vmcs::guest_fs_base::get()))
484  throw std::logic_error("guest fs base non-canonical");
485 }
486 
487 void
489 {
490  if (!x64::is_address_canonical(vmcs::guest_gs_base::get()))
491  throw std::logic_error("guest gs base non-canonical");
492 }
493 
494 void
496 {
497  if (guest_ldtr_access_rights::unusable::get() != 0)
498  return;
499 
500  if (!x64::is_address_canonical(vmcs::guest_ldtr_base::get()))
501  throw std::logic_error("guest ldtr base non-canonical");
502 }
503 
504 void
506 {
507  if ((vmcs::guest_cs_base::get() & 0xFFFFFFFF00000000) != 0)
508  throw std::logic_error("guest cs base bits 63:32 must be 0");
509 }
510 
511 void
513 {
514  if (guest_ss_access_rights::unusable::get() != 0)
515  return;
516 
517  if ((vmcs::guest_ss_base::get() & 0xFFFFFFFF00000000) != 0)
518  throw std::logic_error("guest ss base bits 63:32 must be 0");
519 }
520 
521 void
523 {
524  if (guest_ds_access_rights::unusable::get() != 0)
525  return;
526 
527  if ((vmcs::guest_ds_base::get() & 0xFFFFFFFF00000000) != 0)
528  throw std::logic_error("guest ds base bits 63:32 must be 0");
529 }
530 
531 void
533 {
534  if (guest_es_access_rights::unusable::get() != 0)
535  return;
536 
537  if ((vmcs::guest_es_base::get() & 0xFFFFFFFF00000000) != 0)
538  throw std::logic_error("guest es base bits 63:32 must be 0");
539 }
540 
541 void
543 {
545  return;
546 
547  auto cs_limit = vmcs::guest_cs_limit::get();
548 
549  if (cs_limit != 0x000000000000FFFF)
550  throw std::logic_error("if virtual 8086 mode is enabled, cs limit must be 0xFFFF");
551 }
552 
553 void
555 {
557  return;
558 
559  auto ss_limit = vmcs::guest_ss_limit::get();
560 
561  if (ss_limit != 0x000000000000FFFF)
562  throw std::logic_error("if virtual 8086 mode is enabled, ss limit must be 0xFFFF");
563 }
564 
565 void
567 {
569  return;
570 
571  auto ds_limit = vmcs::guest_ds_limit::get();
572 
573  if (ds_limit != 0x000000000000FFFF)
574  throw std::logic_error("if virtual 8086 mode is enabled, ds limit must be 0xFFFF");
575 }
576 
577 void
579 {
581  return;
582 
583  auto es_limit = vmcs::guest_es_limit::get();
584 
585  if (es_limit != 0x000000000000FFFF)
586  throw std::logic_error("if virtual 8086 mode is enabled, es limit must be 0xFFFF");
587 }
588 
589 void
591 {
593  return;
594 
595  auto gs_limit = vmcs::guest_gs_limit::get();
596 
597  if (gs_limit != 0x000000000000FFFF)
598  throw std::logic_error("if virtual 8086 mode is enabled, gs limit must be 0xFFFF");
599 }
600 
601 void
603 {
605  return;
606 
607  auto fs_limit = vmcs::guest_fs_limit::get();
608 
609  if (fs_limit != 0x000000000000FFFF)
610  throw std::logic_error("if virtual 8086 mode is enabled, fs limit must be 0xFFFF");
611 }
612 
613 void
615 {
617  return;
618 
619  if (guest_cs_access_rights::get() != 0x00000000000000F3)
620  throw std::logic_error("if virtual 8086 mode is enabled, cs access rights must be 0x00F3");
621 }
622 
623 void
625 {
627  return;
628 
629  if (guest_ss_access_rights::get() != 0x00000000000000F3)
630  throw std::logic_error("if virtual 8086 mode is enabled, ss access rights must be 0x00F3");
631 }
632 
633 void
635 {
637  return;
638 
639  if (guest_ds_access_rights::get() != 0x00000000000000F3)
640  throw std::logic_error("if virtual 8086 mode is enabled, ds access rights must be 0x00F3");
641 }
642 
643 void
645 {
647  return;
648 
649  if (guest_es_access_rights::get() != 0x00000000000000F3)
650  throw std::logic_error("if virtual 8086 mode is enabled, es access rights must be 0x00F3");
651 }
652 
653 void
655 {
657  return;
658 
659  if (guest_fs_access_rights::get() != 0x00000000000000F3)
660  throw std::logic_error("if virtual 8086 mode is enabled, fs access rights must be 0x00F3");
661 }
662 
663 void
665 {
667  return;
668 
669  if (guest_gs_access_rights::get() != 0x00000000000000F3)
670  throw std::logic_error("if virtual 8086 mode is enabled, gs access rights must be 0x00F3");
671 }
672 
673 void
675 {
676  using namespace primary_processor_based_vm_execution_controls;
677  using namespace secondary_processor_based_vm_execution_controls;
678 
680  return;
681 
682  switch (guest_cs_access_rights::type::get())
683  {
686  break;
687 
689  break;
690 
695  return;
696 
697  default:
698  break;
699  }
700 
701  throw std::logic_error("guest cs type must be 9, 11, 13, 15, or "
702  "3 (if unrestricted guest support is enabled)");
703 }
704 
705 void
707 {
709  return;
710 
711  if (guest_ss_access_rights::unusable::get() != 0)
712  return;
713 
714  switch (guest_ss_access_rights::type::get())
715  {
718  return;
719 
720  default:
721  break;
722  }
723 
724  throw std::logic_error("guest ss type must be 3 or 7");
725 }
726 
727 void
729 {
731  return;
732 
733  if (guest_ds_access_rights::unusable::get() != 0)
734  return;
735 
736  switch (guest_ds_access_rights::type::get())
737  {
744  return;
745 
746  default:
747  break;
748  }
749 
750  throw std::logic_error("guest ds type must be 1, 3, 5, 7, 11, or 15");
751 }
752 
753 void
755 {
757  return;
758 
759  if (guest_es_access_rights::unusable::get() != 0)
760  return;
761 
762  switch (guest_es_access_rights::type::get())
763  {
770  return;
771 
772  default:
773  break;
774  }
775 
776  throw std::logic_error("guest ds type must be 1, 3, 5, 7, 11, or 15");
777 }
778 
779 void
781 {
783  return;
784 
785  if (guest_fs_access_rights::unusable::get() != 0)
786  return;
787 
788  switch (guest_fs_access_rights::type::get())
789  {
796  return;
797 
798  default:
799  break;
800  }
801 
802  throw std::logic_error("guest fs type must be 1, 3, 5, 7, 11, or 15");
803 }
804 
805 void
807 {
809  return;
810 
811  if (guest_gs_access_rights::unusable::get() != 0)
812  return;
813 
814  switch (guest_gs_access_rights::type::get())
815  {
822  return;
823 
824  default:
825  break;
826  }
827 
828  throw std::logic_error("guest gs type must be 1, 3, 5, 7, 11, or 15");
829 }
830 
831 void
833 {
835  return;
836 
837  if (guest_cs_access_rights::s::get() == 0)
838  throw std::logic_error("cs must be a code/data descriptor. S should equal 1");
839 }
840 
841 void
843 {
845  return;
846 
847  if (guest_ss_access_rights::unusable::get() != 0)
848  return;
849 
850  if (guest_ss_access_rights::s::get() == 0)
851  throw std::logic_error("ss must be a code/data descriptor. S should equal 1");
852 }
853 
854 void
856 {
858  return;
859 
860  if (guest_ds_access_rights::unusable::get() != 0)
861  return;
862 
863  if (guest_ds_access_rights::s::get() == 0)
864  throw std::logic_error("ds must be a code/data descriptor. S should equal 1");
865 }
866 
867 void
869 {
871  return;
872 
873  if (guest_es_access_rights::unusable::get() != 0)
874  return;
875 
876  if (guest_es_access_rights::s::get() == 0)
877  throw std::logic_error("es must be a code/data descriptor. S should equal 1");
878 }
879 
880 void
882 {
884  return;
885 
886  if (guest_fs_access_rights::unusable::get() != 0)
887  return;
888 
889  if (guest_fs_access_rights::s::get() == 0)
890  throw std::logic_error("fs must be a code/data descriptor. S should equal 1");
891 }
892 
893 void
895 {
897  return;
898 
899  if (guest_gs_access_rights::unusable::get() != 0)
900  return;
901 
902  if (guest_gs_access_rights::s::get() == 0)
903  throw std::logic_error("gs must be a code/data descriptor. S should equal 1");
904 }
905 
906 void
908 {
910  return;
911 
912  switch (guest_cs_access_rights::type::get())
913  {
915  break;
916 
917  default:
918  return;
919  }
920 
921  if (guest_cs_access_rights::dpl::get() != 0)
922  throw std::logic_error("cs dpl must be 0 if type == 3");
923 }
924 
925 void
927 {
929  return;
930 
931  switch (guest_cs_access_rights::type::get())
932  {
935  {
936  auto cs_dpl = guest_cs_access_rights::dpl::get();
937  auto ss_dpl = guest_ss_access_rights::dpl::get();
938 
939  if (cs_dpl != ss_dpl)
940  throw std::logic_error("if cs access rights type is 9, 11 cs dpl must equal ss dpl");
941 
942  break;
943  }
944 
947  {
948  auto cs_dpl = guest_cs_access_rights::dpl::get();
949  auto ss_dpl = guest_ss_access_rights::dpl::get();
950 
951  if (cs_dpl > ss_dpl)
952  throw std::logic_error("if cs access rights type is 13, 15 cs dpl must not be greater than ss dpl");
953 
954  break;
955  }
956 
957  default:
958  break;
959  }
960 }
961 
962 void
964 {
965  using namespace primary_processor_based_vm_execution_controls;
966  using namespace secondary_processor_based_vm_execution_controls;
967 
969  return;
970 
972  return;
973 
974  auto ss_rpl = guest_ss_selector::rpl::get();
975  auto ss_dpl = guest_ss_access_rights::dpl::get();
976 
977  if (ss_dpl != ss_rpl)
978  throw std::logic_error("if unrestricted guest mode is disabled ss dpl must equal ss rpl");
979 }
980 
981 void
983 {
985  return;
986 
987  switch (guest_cs_access_rights::type::get())
988  {
990  break;
991 
992  default:
994  return;
995  }
996 
997  if (guest_ss_access_rights::dpl::get() != 0)
998  throw std::logic_error("if cs type is 3 or protected mode is disabled, ss DPL must be 0");
999 }
1000 
1001 void
1003 {
1004  using namespace primary_processor_based_vm_execution_controls;
1005  using namespace secondary_processor_based_vm_execution_controls;
1006 
1008  return;
1009 
1011  return;
1012 
1013  if (guest_ds_access_rights::unusable::get() != 0)
1014  return;
1015 
1016  switch (guest_ds_access_rights::type::get())
1017  {
1022  return;
1023 
1024  default:
1025  break;
1026  }
1027 
1028  auto ds_rpl = guest_ds_selector::rpl::get();
1029  auto ds_dpl = guest_ds_access_rights::dpl::get();
1030 
1031  if (ds_dpl < ds_rpl)
1032  throw std::logic_error("if unrestricted guest mode is disabled, "
1033  "and ds is usable, and the access rights "
1034  "type is in the range 0-11, dpl cannot be "
1035  "less than rpl");
1036 }
1037 
1038 void
1040 {
1041  using namespace primary_processor_based_vm_execution_controls;
1042  using namespace secondary_processor_based_vm_execution_controls;
1043 
1045  return;
1046 
1048  return;
1049 
1050  if (guest_es_access_rights::unusable::get() != 0)
1051  return;
1052 
1053  switch (guest_es_access_rights::type::get())
1054  {
1059  return;
1060 
1061  default:
1062  break;
1063  }
1064 
1065  auto es_rpl = guest_es_selector::rpl::get();
1066  auto es_dpl = guest_es_access_rights::dpl::get();
1067 
1068  if (es_dpl < es_rpl)
1069  throw std::logic_error("if unrestricted guest mode is disabled, "
1070  "and es is usable, and the access rights "
1071  "type is in the range 0-11, dpl cannot be "
1072  "less than rpl");
1073 }
1074 
1075 void
1077 {
1078  using namespace primary_processor_based_vm_execution_controls;
1079  using namespace secondary_processor_based_vm_execution_controls;
1080 
1082  return;
1083 
1085  return;
1086 
1087  if (guest_fs_access_rights::unusable::get() != 0)
1088  return;
1089 
1090  switch (guest_fs_access_rights::type::get())
1091  {
1096  return;
1097 
1098  default:
1099  break;
1100  }
1101 
1102  auto fs_rpl = guest_fs_selector::rpl::get();
1103  auto fs_dpl = guest_fs_access_rights::dpl::get();
1104 
1105  if (fs_dpl < fs_rpl)
1106  throw std::logic_error("if unrestricted guest mode is disabled, "
1107  "and fs is usable, and the access rights "
1108  "type is in the range 0-11, dpl cannot be "
1109  "less than rpl");
1110 }
1111 
1112 void
1114 {
1115  using namespace primary_processor_based_vm_execution_controls;
1116  using namespace secondary_processor_based_vm_execution_controls;
1117 
1119  return;
1120 
1122  return;
1123 
1124  if (guest_gs_access_rights::unusable::get() != 0)
1125  return;
1126 
1127  switch (guest_gs_access_rights::type::get())
1128  {
1133  return;
1134 
1135  default:
1136  break;
1137  }
1138 
1139  auto gs_rpl = guest_gs_selector::rpl::get();
1140  auto gs_dpl = guest_gs_access_rights::dpl::get();
1141 
1142  if (gs_dpl < gs_rpl)
1143  throw std::logic_error("if unrestricted guest mode is disabled, "
1144  "and gs is usable, and the access rights "
1145  "type is in the range 0-11, dpl cannot be "
1146  "less than rpl");
1147 }
1148 
1149 void
1151 {
1153  return;
1154 
1155  if (guest_cs_access_rights::present::get() == 0)
1156  throw std::logic_error("cs access rights present flag must be 1 ");
1157 }
1158 
1159 void
1161 {
1163  return;
1164 
1165  if (guest_ss_access_rights::unusable::get() != 0)
1166  return;
1167 
1168  if (guest_ss_access_rights::present::get() == 0)
1169  throw std::logic_error("ss access rights present flag must be 1 if ss is usable");
1170 }
1171 
1172 void
1174 {
1176  return;
1177 
1178  if (guest_ds_access_rights::unusable::get() != 0)
1179  return;
1180 
1181  if (guest_ds_access_rights::present::get() == 0)
1182  throw std::logic_error("ds access rights present flag must be 1 if ds is usable");
1183 }
1184 
1185 void
1187 {
1189  return;
1190 
1191  if (guest_es_access_rights::unusable::get() != 0)
1192  return;
1193 
1194  if (guest_es_access_rights::present::get() == 0)
1195  throw std::logic_error("es access rights present flag must be 1 if es is usable");
1196 }
1197 
1198 void
1200 {
1202  return;
1203 
1204  if (guest_fs_access_rights::unusable::get() != 0)
1205  return;
1206 
1207  if (guest_fs_access_rights::present::get() == 0)
1208  throw std::logic_error("fs access rights present flag must be 1 if fs is usable");
1209 }
1210 
1211 void
1213 {
1215  return;
1216 
1217  if (guest_gs_access_rights::unusable::get() != 0)
1218  return;
1219 
1220  if (guest_gs_access_rights::present::get() == 0)
1221  throw std::logic_error("gs access rights present flag must be 1 if gs is usable");
1222 }
1223 
1224 void
1226 {
1228  return;
1229 
1230  if (guest_cs_access_rights::reserved::get() != 0)
1231  throw std::logic_error("cs access rights reserved bits must be 0 ");
1232 }
1233 
1234 void
1236 {
1238  return;
1239 
1240  if (guest_ss_access_rights::unusable::get() != 0)
1241  return;
1242 
1243  if (guest_ss_access_rights::reserved::get() != 0)
1244  throw std::logic_error("ss access rights reserved bits must be 0 if ss is usable");
1245 }
1246 
1247 void
1249 {
1251  return;
1252 
1253  if (guest_ds_access_rights::unusable::get() != 0)
1254  return;
1255 
1256  if (guest_ds_access_rights::reserved::get() != 0)
1257  throw std::logic_error("ds access rights reserved bits must be 0 if ds is usable");
1258 }
1259 
1260 void
1262 {
1264  return;
1265 
1266  if (guest_es_access_rights::unusable::get() != 0)
1267  return;
1268 
1269  if (guest_es_access_rights::reserved::get() != 0)
1270  throw std::logic_error("es access rights reserved bits must be 0 if es is usable");
1271 }
1272 
1273 void
1275 {
1277  return;
1278 
1279  if (guest_fs_access_rights::unusable::get() != 0)
1280  return;
1281 
1282  if (guest_fs_access_rights::reserved::get() != 0)
1283  throw std::logic_error("fs access rights reserved bits must be 0 if fs is usable");
1284 }
1285 
1286 void
1288 {
1290  return;
1291 
1292  if (guest_gs_access_rights::unusable::get() != 0)
1293  return;
1294 
1295  if (guest_gs_access_rights::reserved::get() != 0)
1296  throw std::logic_error("gs access rights reserved bits must be 0 if gs is usable");
1297 }
1298 
1299 void
1301 {
1303  return;
1304 
1306  return;
1307 
1308  if (guest_cs_access_rights::l::get() == 0)
1309  return;
1310 
1311  if (guest_cs_access_rights::db::get() != 0)
1312  throw std::logic_error("d/b for guest cs must be 0 if in ia 32e mode and l == 1");
1313 }
1314 
1315 void
1317 {
1319  return;
1320 
1321  auto cs_limit = vmcs::guest_cs_limit::get();
1322  auto g = guest_cs_access_rights::granularity::get();
1323 
1324  if ((cs_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1325  throw std::logic_error("guest cs granularity must be 0 if any bit 11:0 is 0");
1326 
1327  if ((cs_limit & 0xFFF00000) != 0x00000000 && g == 0)
1328  throw std::logic_error("guest cs granularity must be 1 if any bit 31:20 is 1");
1329 }
1330 
1331 void
1333 {
1335  return;
1336 
1337  auto ss_limit = vmcs::guest_ss_limit::get();
1338  auto g = guest_ss_access_rights::granularity::get();
1339 
1340  if (guest_ss_access_rights::unusable::get() != 0)
1341  return;
1342 
1343  if ((ss_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1344  throw std::logic_error("guest ss granularity must be 0 if any bit 11:0 is 0");
1345 
1346  if ((ss_limit & 0xFFF00000) != 0x00000000 && g == 0)
1347  throw std::logic_error("guest ss granularity must be 1 if any bit 31:20 is 1");
1348 }
1349 
1350 void
1352 {
1354  return;
1355 
1356  auto ds_limit = vmcs::guest_ds_limit::get();
1357  auto g = guest_ds_access_rights::granularity::get();
1358 
1359  if (guest_ds_access_rights::unusable::get() != 0)
1360  return;
1361 
1362  if ((ds_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1363  throw std::logic_error("guest ds granularity must be 0 if any bit 11:0 is 0");
1364 
1365  if ((ds_limit & 0xFFF00000) != 0x00000000 && g == 0)
1366  throw std::logic_error("guest ds granularity must be 1 if any bit 31:20 is 1");
1367 }
1368 
1369 void
1371 {
1373  return;
1374 
1375  auto es_limit = vmcs::guest_es_limit::get();
1376  auto g = guest_es_access_rights::granularity::get();
1377 
1378  if (guest_es_access_rights::unusable::get() != 0)
1379  return;
1380 
1381  if ((es_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1382  throw std::logic_error("guest es granularity must be 0 if any bit 11:0 is 0");
1383 
1384  if ((es_limit & 0xFFF00000) != 0x00000000 && g == 0)
1385  throw std::logic_error("guest es granularity must be 1 if any bit 31:20 is 1");
1386 }
1387 
1388 void
1390 {
1392  return;
1393 
1394  auto fs_limit = vmcs::guest_fs_limit::get();
1395  auto g = guest_fs_access_rights::granularity::get();
1396 
1397  if (guest_fs_access_rights::unusable::get() != 0)
1398  return;
1399 
1400  if ((fs_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1401  throw std::logic_error("guest fs granularity must be 0 if any bit 11:0 is 0");
1402 
1403  if ((fs_limit & 0xFFF00000) != 0x00000000 && g == 0)
1404  throw std::logic_error("guest fs granularity must be 1 if any bit 31:20 is 1");
1405 }
1406 
1407 void
1409 {
1411  return;
1412 
1413  auto gs_limit = vmcs::guest_gs_limit::get();
1414  auto g = guest_gs_access_rights::granularity::get();
1415 
1416  if (guest_gs_access_rights::unusable::get() != 0)
1417  return;
1418 
1419  if ((gs_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1420  throw std::logic_error("guest gs granularity must be 0 if any bit 11:0 is 0");
1421 
1422  if ((gs_limit & 0xFFF00000) != 0x00000000 && g == 0)
1423  throw std::logic_error("guest gs granularity must be 1 if any bit 31:20 is 1");
1424 }
1425 
1426 void
1428 {
1430  return;
1431 
1432  if ((guest_cs_access_rights::get() & 0xFFFE0000UL) != 0UL)
1433  throw std::logic_error("guest cs access rights bits 31:17 must be 0");
1434 }
1435 
1436 void
1438 {
1440  return;
1441 
1442  if (guest_ss_access_rights::unusable::get() != 0)
1443  return;
1444 
1445  if ((guest_ss_access_rights::get() & 0xFFFE0000UL) != 0UL)
1446  throw std::logic_error("guest ss access rights bits 31:17 must be 0");
1447 }
1448 
1449 void
1451 {
1453  return;
1454 
1455  if (guest_ds_access_rights::unusable::get() != 0)
1456  return;
1457 
1458  if ((guest_ds_access_rights::get() & 0xFFFE0000UL) != 0UL)
1459  throw std::logic_error("guest ds access rights bits 31:17 must be 0");
1460 }
1461 
1462 void
1464 {
1466  return;
1467 
1468  if (guest_es_access_rights::unusable::get() != 0)
1469  return;
1470 
1471  if ((guest_es_access_rights::get() & 0xFFFE0000UL) != 0UL)
1472  throw std::logic_error("guest es access rights bits 31:17 must be 0");
1473 }
1474 
1475 void
1477 {
1479  return;
1480 
1481  if (guest_fs_access_rights::unusable::get() != 0)
1482  return;
1483 
1484  if ((guest_fs_access_rights::get() & 0xFFFE0000UL) != 0UL)
1485  throw std::logic_error("guest fs access rights bits 31:17 must be 0");
1486 }
1487 
1488 void
1490 {
1492  return;
1493 
1494  if (guest_gs_access_rights::unusable::get() != 0)
1495  return;
1496 
1497  if ((guest_gs_access_rights::get() & 0xFFFE0000UL) != 0UL)
1498  throw std::logic_error("guest gs access rights bits 31:17 must be 0");
1499 }
1500 
1501 void
1503 {
1504  switch (guest_tr_access_rights::type::get())
1505  {
1508  throw std::logic_error("tr type cannot be 3 if ia_32e_mode_guest is enabled");
1509 
1510  return;
1511 
1513  return;
1514 
1515  default:
1516  throw std::logic_error("tr type must be 3 or 11");
1517  }
1518 }
1519 
1520 void
1522 {
1523  if (guest_tr_access_rights::s::get() != 0)
1524  throw std::logic_error("tr must be a system descriptor. S should equal 0");
1525 }
1526 
1527 void
1529 {
1530  if (guest_tr_access_rights::present::get() == 0)
1531  throw std::logic_error("tr access rights present flag must be 1 ");
1532 }
1533 
1534 void
1536 {
1537  if (guest_tr_access_rights::reserved::get() != 0)
1538  throw std::logic_error("tr access rights bits 11:8 must be 0");
1539 }
1540 
1541 void
1543 {
1544  auto tr_limit = vmcs::guest_tr_limit::get();
1545  auto g = guest_tr_access_rights::granularity::get();
1546 
1547  if ((tr_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1548  throw std::logic_error("guest tr granularity must be 0 if any bit 11:0 is 0");
1549 
1550  if ((tr_limit & 0xFFF00000) != 0x00000000 && g == 0)
1551  throw std::logic_error("guest tr granularity must be 1 if any bit 31:20 is 1");
1552 }
1553 
1554 void
1556 {
1557  if (guest_tr_access_rights::unusable::get() != 0)
1558  throw std::logic_error("tr must be usable");
1559 }
1560 
1561 void
1563 {
1564  auto tr_access = vmcs::guest_tr_access_rights::get();
1565 
1566  if ((tr_access & 0xFFFE0000) != 0)
1567  throw std::logic_error("guest tr access rights bits 31:17 must be 0");
1568 }
1569 
1570 void
1572 {
1573  if (guest_ldtr_access_rights::unusable::get() != 0)
1574  return;
1575 
1576  switch (guest_ldtr_access_rights::type::get())
1577  {
1579  break;
1580 
1581  default:
1582  throw std::logic_error("guest ldtr type must 2");
1583  }
1584 }
1585 
1586 void
1588 {
1589  if (guest_ldtr_access_rights::unusable::get() != 0)
1590  return;
1591 
1592  if (guest_ldtr_access_rights::s::get() != 0)
1593  throw std::logic_error("ldtr must be a system descriptor. S should equal 0");
1594 }
1595 
1596 void
1598 {
1599  if (guest_ldtr_access_rights::unusable::get() != 0)
1600  return;
1601 
1602  if (guest_ldtr_access_rights::present::get() == 0)
1603  throw std::logic_error("ldtr access rights present flag must be 1 if ldtr is usable");
1604 }
1605 
1606 void
1608 {
1609  if (guest_ldtr_access_rights::unusable::get() != 0)
1610  return;
1611 
1612  if (guest_ldtr_access_rights::reserved::get() != 0)
1613  throw std::logic_error("ldtr access rights bits 11:8 must be 0");
1614 }
1615 
1616 void
1618 {
1619  if (guest_ldtr_access_rights::unusable::get() != 0)
1620  return;
1621 
1622  auto ldtr_limit = vmcs::guest_ldtr_limit::get();
1623  auto g = guest_ldtr_access_rights::granularity::get();
1624 
1625  if ((ldtr_limit & 0x00000FFF) != 0x00000FFF && g != 0)
1626  throw std::logic_error("guest ldtr granularity must be 0 if any bit 11:0 is 0");
1627 
1628  if ((ldtr_limit & 0xFFF00000) != 0x00000000 && g == 0)
1629  throw std::logic_error("guest ldtr granularity must be 1 if any bit 31:20 is 1");
1630 }
1631 
1632 void
1634 {
1635  if (guest_ldtr_access_rights::unusable::get() != 0)
1636  return;
1637 
1638  auto ldtr_access = vmcs::guest_ldtr_access_rights::get();
1639 
1640  if ((ldtr_access & 0xFFFE0000) != 0)
1641  throw std::logic_error("guest ldtr access rights bits 31:17 must be 0 if ldtr is usable");
1642 }
1643 
1644 void
1646 {
1651 }
1652 
1653 void
1655 {
1656  if (!x64::is_address_canonical(vmcs::guest_gdtr_base::get()))
1657  throw std::logic_error("gdtr base is non-canonical");
1658 }
1659 
1660 void
1662 {
1663  if (!x64::is_address_canonical(vmcs::guest_idtr_base::get()))
1664  throw std::logic_error("idtr base is non-canonical");
1665 }
1666 
1667 void
1669 {
1670  auto gdtr_limit = vmcs::guest_gdtr_limit::get();
1671 
1672  if ((gdtr_limit & 0xFFFF0000) != 0)
1673  throw std::logic_error("gdtr limit bits 31:16 must be 0");
1674 }
1675 
1676 void
1678 {
1679  auto idtr_limit = vmcs::guest_idtr_limit::get();
1680 
1681  if ((idtr_limit & 0xFFFF0000) != 0)
1682  throw std::logic_error("idtr limit bits 31:16 must be 0");
1683 }
1684 
1685 void
1687 {
1693 }
1694 
1695 void
1697 {
1698  auto cs_l = guest_cs_access_rights::l::get();
1699 
1701  return;
1702 
1703  if ((vmcs::guest_rip::get() & 0xFFFFFFFF00000000) != 0)
1704  throw std::logic_error("rip bits 61:32 must 0 if IA 32e mode is disabled or cs L is disabled");
1705 }
1706 
1707 void
1709 {
1710  auto cs_l = guest_cs_access_rights::l::get();
1711 
1713  return;
1714 
1715  if (cs_l == 0)
1716  return;
1717 
1718  if (!is_linear_address_valid(vmcs::guest_rip::get()))
1719  throw std::logic_error("rip bits must be canonical");
1720 }
1721 
1722 void
1724 {
1725  if (guest_rflags::reserved::get() != 0)
1726  throw std::logic_error("reserved bits in rflags must be 0");
1727 
1728  if (guest_rflags::always_enabled::get() == 0)
1729  throw std::logic_error("always enabled bits in rflags must be 1");
1730 }
1731 
1732 void
1734 {
1736  return;
1737 
1739  throw std::logic_error("rflags VM must be 0 if ia 32e mode is 1 or PE is 0");
1740 }
1741 
1742 void
1744 {
1745  using namespace vm_entry_interruption_information_field;
1746 
1747  if (valid_bit::is_disabled())
1748  return;
1749 
1750  if (interruption_type::get() != interruption_type::external_interrupt)
1751  return;
1752 
1754  throw std::logic_error("rflags IF must be 1 if the valid bit is 1 and interrupt type is external");
1755 }
1756 
1757 void
1759 {
1785 }
1786 
1787 void
1789 {
1790  if (vmcs::guest_activity_state::get() > 3)
1791  throw std::logic_error("activity state must be 0 - 3");
1792 }
1793 
1794 void
1796 {
1797  if (vmcs::guest_activity_state::get() != vmcs::guest_activity_state::hlt)
1798  return;
1799 
1800  if (guest_ss_access_rights::dpl::get() != 0)
1801  throw std::logic_error("ss.dpl must be 0 if activity state is HLT");
1802 }
1803 
1804 void
1806 {
1807  if (vmcs::guest_activity_state::get() == vmcs::guest_activity_state::active)
1808  return;
1809 
1810  if (vmcs::guest_interruptibility_state::blocking_by_sti::get() != 0U)
1811  throw std::logic_error("activity state must be active if "
1812  "interruptibility state is sti");
1813 
1814  if (vmcs::guest_interruptibility_state::blocking_by_mov_ss::get() != 0U)
1815  throw std::logic_error("activity state must be active if "
1816  "interruptibility state is mov-ss");
1817 }
1818 
1819 void
1821 {
1822  using namespace vm_entry_interruption_information_field;
1823 
1824  if (valid_bit::is_disabled())
1825  return;
1826 
1827  if (vmcs::guest_activity_state::get() != vmcs::guest_activity_state::hlt)
1828  return;
1829 
1830  auto type = interruption_type::get();
1831  auto vector = vector::get();
1832 
1833  switch (type)
1834  {
1837  return;
1838 
1840  if (vector == interrupt::debug_exception)
1841  return;
1842 
1843  if (vector == interrupt::machine_check)
1844  return;
1845 
1846  break;
1847 
1849  if (vector == interrupt::divide_error)
1850  return;
1851 
1852  break;
1853 
1854  default:
1855  break;
1856  }
1857 
1858  throw std::logic_error("invalid interruption combination for guest hlt");
1859 }
1860 
1861 void
1863 {
1864  using namespace vm_entry_interruption_information_field;
1865 
1866  if (valid_bit::is_disabled())
1867  return;
1868 
1869  if (vmcs::guest_activity_state::get() != vmcs::guest_activity_state::shutdown)
1870  return;
1871 
1872  auto type = interruption_type::get();
1873  auto vector = vector::get();
1874 
1875  switch (type)
1876  {
1878  return;
1879 
1881  if (vector == interrupt::machine_check)
1882  return;
1883 
1884  break;
1885 
1886  default:
1887  break;
1888  }
1889 
1890  throw std::logic_error("invalid interruption combination for guest shutdown");
1891 }
1892 
1893 void
1895 {
1897  return;
1898 
1899  if (vmcs::guest_activity_state::get() != vmcs::guest_activity_state::wait_for_sipi)
1900  return;
1901 
1902  throw std::logic_error("invalid interruption combination");
1903 }
1904 
1905 void
1907 {
1909  return;
1910 
1911  if (vmcs::guest_activity_state::get() != vmcs::guest_activity_state::wait_for_sipi)
1912  return;
1913 
1914  throw std::logic_error("activity state must not equal wait for sipi if entry to smm is enabled");
1915 }
1916 
1917 void
1919 {
1920  if (vmcs::guest_interruptibility_state::reserved::get() != 0)
1921  throw std::logic_error("interruptibility state reserved bits 31:5 must be 0");
1922 }
1923 
1924 void
1926 {
1927  auto sti = vmcs::guest_interruptibility_state::blocking_by_sti::get();
1928  auto mov_ss = vmcs::guest_interruptibility_state::blocking_by_mov_ss::get();
1929 
1930  if (sti != 0U && mov_ss != 0U)
1931  throw std::logic_error("interruptibility state sti and mov ss cannot both be 1");
1932 
1933 }
1934 
1935 void
1937 {
1939  return;
1940 
1941  if (vmcs::guest_interruptibility_state::blocking_by_sti::get() != 0U)
1942  throw std::logic_error("interruptibility state sti must be 0 if rflags interrupt enabled is 0");
1943 }
1944 
1945 void
1947 {
1948  using namespace vm_entry_interruption_information_field;
1949 
1950  if (valid_bit::is_disabled())
1951  return;
1952 
1953  if (interruption_type::get() != interruption_type::external_interrupt)
1954  return;
1955 
1956  if (vmcs::guest_interruptibility_state::blocking_by_sti::get() != 0U)
1957  throw std::logic_error("interruptibility state sti must be 0 if "
1958  "interrupt type is external and valid");
1959 
1960  if (vmcs::guest_interruptibility_state::blocking_by_mov_ss::get() != 0U)
1961  throw std::logic_error("activity state must be active if "
1962  "interruptibility state is mov-ss");
1963 }
1964 
1965 void
1967 {
1968  using namespace vm_entry_interruption_information_field;
1969 
1970  if (valid_bit::is_disabled())
1971  return;
1972 
1973  if (interruption_type::get() != interruption_type::non_maskable_interrupt)
1974  return;
1975 
1976  if (vmcs::guest_interruptibility_state::blocking_by_mov_ss::get() != 0U)
1977  throw std::logic_error("vali interrupt type must not be nmi if "
1978  "interruptibility state is mov-ss");
1979 }
1980 
1981 void
1983 {
1984 }
1985 
1986 void
1988 {
1990  return;
1991 
1992  if (vmcs::guest_interruptibility_state::blocking_by_smi::get() == 0U)
1993  throw std::logic_error("interruptibility state smi must be enabled "
1994  "if entry to smm is enabled");
1995 }
1996 
1997 void
1999 {
2000  using namespace vm_entry_interruption_information_field;
2001 
2002  if (valid_bit::is_disabled())
2003  return;
2004 
2005  if (interruption_type::get() != interruption_type::non_maskable_interrupt)
2006  return;
2007 
2008  if (vmcs::guest_interruptibility_state::blocking_by_sti::get() != 0U)
2009  throw std::logic_error("some processors require sti to be 0 if "
2010  "the interruption type is nmi");
2011 }
2012 
2013 void
2015 {
2016  using namespace vm_entry_interruption_information_field;
2017 
2019  return;
2020 
2021  if (valid_bit::is_disabled())
2022  return;
2023 
2024  if (interruption_type::get() != interruption_type::non_maskable_interrupt)
2025  return;
2026 
2027  if (vmcs::guest_interruptibility_state::blocking_by_nmi::get() != 0)
2028  throw std::logic_error("if virtual nmi is enabled, and the interruption "
2029  "type is NMI, blocking by nmi must be disabled");
2030 }
2031 
2032 void
2034 {
2035  if (guest_interruptibility_state::enclave_interruption::get() == 0)
2036  return;
2037 
2038  if (guest_interruptibility_state::blocking_by_mov_ss::get() != 0)
2039  throw std::logic_error("blocking by mov ss is enabled but enclave interrupt is "
2040  "also enabled in interruptibility state");
2041 
2043  throw std::logic_error("enclave interrupt is 1 in interruptibility state "
2044  "but the processor does not support sgx");
2045 }
2046 
2047 void
2049 {
2050  if (vmcs::guest_pending_debug_exceptions::reserved::get() != 0)
2051  throw std::logic_error("pending debug exception reserved bits must be 0");
2052 }
2053 
2054 void
2056 {
2057  auto sti = vmcs::guest_interruptibility_state::blocking_by_sti::get();
2058  auto mov_ss = vmcs::guest_interruptibility_state::blocking_by_mov_ss::get();
2059  auto activity_state = vmcs::guest_activity_state::get();
2060 
2061  if (sti == 0 && mov_ss == 0 && activity_state != vmcs::guest_activity_state::hlt)
2062  return;
2063 
2067 
2068  if (!bs && tf && !btf)
2069  throw std::logic_error("pending debug exception bs must be 1 if "
2070  "rflags tf is 1 and debugctl btf is 0");
2071 
2072  if (bs && !tf && btf)
2073  throw std::logic_error("pending debug exception bs must be 0 if "
2074  "rflags tf is 0 and debugctl btf is 1");
2075 }
2076 
2077 void
2079 {
2081  return;
2082 
2083  if ((guest_pending_debug_exceptions::get() & 0xFFFFFFFFFFFEAFFF) != 0)
2084  throw std::logic_error("pending debug exception reserved bits and bits 3:0 "
2085  "must be 0 if rtm is 1");
2086 
2088  throw std::logic_error("pending debug exception bit 12 must be 1 if rtm is 1");
2089 
2091  throw std::logic_error("rtm is set in pending debug exception but "
2092  "rtm is unsupported by the processor");
2093 
2094  if (guest_interruptibility_state::blocking_by_mov_ss::get() == 1)
2095  throw std::logic_error("interruptibility-state field indicates blocking by mov ss"
2096  " but rtm is set in pending debug exceptions field");
2097 }
2098 
2099 void
2101 {
2102  auto vmcs_link_pointer = vmcs::vmcs_link_pointer::get();
2103 
2104  if (vmcs_link_pointer == 0xFFFFFFFFFFFFFFFF)
2105  return;
2106 
2107  if ((vmcs_link_pointer & 0x0000000000000FFF) != 0)
2108  throw std::logic_error("vmcs link pointer bits 11:0 must be 0");
2109 }
2110 
2111 void
2113 {
2114  auto vmcs_link_pointer = vmcs::vmcs_link_pointer::get();
2115 
2116  if (vmcs_link_pointer == 0xFFFFFFFFFFFFFFFF)
2117  return;
2118 
2119  if (!x64::is_physical_address_valid(vmcs_link_pointer))
2120  throw std::logic_error("vmcs link pointer invalid physical address");
2121 }
2122 
2123 void
2125 {
2126  auto vmcs_link_pointer = vmcs::vmcs_link_pointer::get();
2127 
2128  if (vmcs_link_pointer == 0xFFFFFFFFFFFFFFFF)
2129  return;
2130 
2131  auto vmcs = g_mm->physint_to_virtptr(vmcs_link_pointer);
2132 
2133  if (vmcs == nullptr)
2134  throw std::logic_error("invalid vmcs physical address");
2135 
2136  auto revision_id = *static_cast<uint32_t *>(vmcs) & 0x7FFFFFFF;
2137  auto vmcs_shadow = *static_cast<uint32_t *>(vmcs) & 0x80000000;
2138 
2139  if (revision_id != msrs::ia32_vmx_basic::revision_id::get())
2140  throw std::logic_error("shadow vmcs must contain CPU's revision id");
2141 
2143  return;
2144 
2146  return;
2147 
2148  if (vmcs_shadow == 0)
2149  throw std::logic_error("shadow vmcs bit must be enabled if vmcs shadowing is enabled");
2150 }
2151 
2152 void
2154 {
2155 }
2156 
2157 void
2159 {
2160 }
2161 
2162 void
2164 {
2167 }
2168 
2169 void
2171 {
2173  return;
2174 
2176  return;
2177 
2179  return;
2180 
2182  return;
2183 
2184  auto cr3 = vmcs::guest_cr3::get();
2185  auto virt_pdpt = static_cast<uint64_t *>(g_mm->physint_to_virtptr(cr3 & 0xFFFFFFE0UL));
2186 
2187  if (virt_pdpt == nullptr)
2188  throw std::logic_error("pdpt address is null");
2189 
2190  if ((virt_pdpt[0] & x64::pdpte::reserved::mask()) != 0U)
2191  throw std::logic_error("pdpte0 reserved bits set with ept disabled and pae paging enabled");
2192 
2193  if ((virt_pdpt[1] & x64::pdpte::reserved::mask()) != 0U)
2194  throw std::logic_error("pdpte1 reserved bits set with ept disabled and pae paging enabled");
2195 
2196  if ((virt_pdpt[2] & x64::pdpte::reserved::mask()) != 0U)
2197  throw std::logic_error("pdpte2 reserved bits set with ept disabled and pae paging enabled");
2198 
2199  if ((virt_pdpt[3] & x64::pdpte::reserved::mask()) != 0U)
2200  throw std::logic_error("pdpte3 reserved bits set with ept disabled and pae paging enabled");
2201 }
2202 
2203 void
2205 {
2207  return;
2208 
2210  return;
2211 
2213  return;
2214 
2216  return;
2217 
2219  return;
2220 
2221  if (vmcs::guest_pdpte0::reserved::get() != 0U)
2222  throw std::logic_error("pdpte0 reserved bits set with ept and pae paging enabled");
2223 
2224  if (vmcs::guest_pdpte1::reserved::get() != 0U)
2225  throw std::logic_error("pdpte1 reserved bits set with ept and pae paging enabled");
2226 
2227  if (vmcs::guest_pdpte2::reserved::get() != 0U)
2228  throw std::logic_error("pdpte2 reserved bits set with ept and pae paging enabled");
2229 
2230  if (vmcs::guest_pdpte3::reserved::get() != 0U)
2231  throw std::logic_error("ppdpte3 reserved bits set with ept and pae paging enabled");
2232 }
void uintptr_t uintptr_t cr3
Definition: map_ptr_x64.cpp:33
auto mask() noexcept
Definition: pdpte_x64.h:48
constexpr const auto execute_only_conforming
Definition: x64.h:70
constexpr const auto external_interrupt
auto is_physical_address_valid(T addr)
Definition: x64.h:126
constexpr const auto read_execute_accessed
Definition: x64.h:69
constexpr const auto read_write_expand_down_accessed
Definition: x64.h:64
constexpr const auto read_only_expand_down_accessed
Definition: x64.h:62
auto is_linear_address_valid(T addr)
Definition: x64.h:122
auto memory_type_reserved(T memory_type)
constexpr const auto other_event
constexpr const auto read_write
Definition: x64.h:59
constexpr const auto hardware_exception
constexpr const auto read_only_accessed
Definition: x64.h:58
constexpr const auto read_write_accessed
Definition: x64.h:60
constexpr const auto execute_only_accessed
Definition: x64.h:67
constexpr const auto debug_exception
Definition: x64.h:96
constexpr const auto non_maskable_interrupt
constexpr const auto mask
constexpr const auto machine_check
Definition: x64.h:112
const void * view_as_pointer(const T val)
constexpr const auto read_execute_conforming_accessed
Definition: x64.h:73
#define g_mm
constexpr const auto execute_only_conforming_accessed
Definition: x64.h:71
constexpr const auto divide_error
Definition: x64.h:95
auto is_address_canonical(T addr)
Definition: x64.h:118
Definition: cache_x64.h:31
constexpr const auto read_execute_conforming
Definition: x64.h:72