40 using namespace check;
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();
82 if (0 != ((~cr0 & ia32_vmx_cr0_fixed0) | (cr0 & ~ia32_vmx_cr0_fixed1)))
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;
89 throw std::logic_error(
"invalid cr0");
100 throw std::logic_error(
"PE must be enabled in cr0 if PG is enabled");
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();
110 if (0 != ((~cr4 & ia32_vmx_cr4_fixed0) | (cr4 & ~ia32_vmx_cr4_fixed1)))
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;
117 throw std::logic_error(
"invalid cr4");
127 if (vmcs::guest_ia32_debugctl::reserved::get() != 0)
128 throw std::logic_error(
"debug ctrl msr reserved bits must be 0");
138 throw std::logic_error(
"paging must be enabled if ia 32e guest mode is enabled");
141 throw std::logic_error(
"pae must be enabled if ia 32e guest mode is enabled");
151 throw std::logic_error(
"pcide in cr4 must be disabled if ia 32e guest mode is disabled");
158 throw std::logic_error(
"guest cr3 too large");
167 auto dr7 = vmcs::guest_dr7::get();
169 if ((dr7 & 0xFFFFFFFF00000000) != 0)
170 throw std::logic_error(
"bits 63:32 of dr7 must be 0 if load debug controls is 1");
177 throw std::logic_error(
"guest sysenter esp must be canonical");
184 throw std::logic_error(
"guest sysenter eip must be canonical");
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");
204 throw std::logic_error(
"pat0 has a reserved memory type");
207 throw std::logic_error(
"pat1 has a reserved memory type");
210 throw std::logic_error(
"pat2 has a reserved memory type");
213 throw std::logic_error(
"pat3 has a reserved memory type");
216 throw std::logic_error(
"pat4 has a reserved memory type");
219 throw std::logic_error(
"pat5 has a reserved memory type");
222 throw std::logic_error(
"pat6 has a reserved memory type");
225 throw std::logic_error(
"pat7 has a reserved memory type");
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");
242 throw std::logic_error(
"ia 32e mode is 0, but efer.lma is 1");
245 throw std::logic_error(
"ia 32e mode is 1, but efer.lma is 0");
251 throw std::logic_error(
"efer.lme is 0, but efer.lma is 1");
254 throw std::logic_error(
"efer.lme is 1, but efer.lma is 0");
263 auto bndcfgs = vmcs::guest_ia32_bndcfgs::get();
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");
269 auto bound_addr = bndcfgs & 0xFFFFFFFFFFFFF000;
272 throw std::logic_error(
"bound address in ia32 bndcfgs msr must be " 273 "canonical if load ia32 bndcfgs entry is enabled");
371 if (guest_tr_selector::ti::get())
372 throw std::logic_error(
"guest tr's ti flag must be zero");
378 if (guest_ldtr_access_rights::unusable::get() != 0)
381 if (guest_ldtr_selector::ti::get())
382 throw std::logic_error(
"guest ldtr's ti flag must be zero");
388 using namespace primary_processor_based_vm_execution_controls;
389 using namespace secondary_processor_based_vm_execution_controls;
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");
407 auto cs = guest_cs_selector::get();
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");
419 auto ss = guest_ss_selector::get();
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");
431 auto ds = guest_ds_selector::get();
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");
443 auto es = guest_es_selector::get();
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");
455 auto fs = guest_fs_selector::get();
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");
467 auto gs = guest_gs_selector::get();
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");
477 throw std::logic_error(
"guest tr base non-canonical");
484 throw std::logic_error(
"guest fs base non-canonical");
491 throw std::logic_error(
"guest gs base non-canonical");
497 if (guest_ldtr_access_rights::unusable::get() != 0)
501 throw std::logic_error(
"guest ldtr base non-canonical");
507 if ((vmcs::guest_cs_base::get() & 0xFFFFFFFF00000000) != 0)
508 throw std::logic_error(
"guest cs base bits 63:32 must be 0");
514 if (guest_ss_access_rights::unusable::get() != 0)
517 if ((vmcs::guest_ss_base::get() & 0xFFFFFFFF00000000) != 0)
518 throw std::logic_error(
"guest ss base bits 63:32 must be 0");
524 if (guest_ds_access_rights::unusable::get() != 0)
527 if ((vmcs::guest_ds_base::get() & 0xFFFFFFFF00000000) != 0)
528 throw std::logic_error(
"guest ds base bits 63:32 must be 0");
534 if (guest_es_access_rights::unusable::get() != 0)
537 if ((vmcs::guest_es_base::get() & 0xFFFFFFFF00000000) != 0)
538 throw std::logic_error(
"guest es base bits 63:32 must be 0");
547 auto cs_limit = vmcs::guest_cs_limit::get();
549 if (cs_limit != 0x000000000000FFFF)
550 throw std::logic_error(
"if virtual 8086 mode is enabled, cs limit must be 0xFFFF");
559 auto ss_limit = vmcs::guest_ss_limit::get();
561 if (ss_limit != 0x000000000000FFFF)
562 throw std::logic_error(
"if virtual 8086 mode is enabled, ss limit must be 0xFFFF");
571 auto ds_limit = vmcs::guest_ds_limit::get();
573 if (ds_limit != 0x000000000000FFFF)
574 throw std::logic_error(
"if virtual 8086 mode is enabled, ds limit must be 0xFFFF");
583 auto es_limit = vmcs::guest_es_limit::get();
585 if (es_limit != 0x000000000000FFFF)
586 throw std::logic_error(
"if virtual 8086 mode is enabled, es limit must be 0xFFFF");
595 auto gs_limit = vmcs::guest_gs_limit::get();
597 if (gs_limit != 0x000000000000FFFF)
598 throw std::logic_error(
"if virtual 8086 mode is enabled, gs limit must be 0xFFFF");
607 auto fs_limit = vmcs::guest_fs_limit::get();
609 if (fs_limit != 0x000000000000FFFF)
610 throw std::logic_error(
"if virtual 8086 mode is enabled, fs limit must be 0xFFFF");
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");
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");
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");
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");
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");
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");
676 using namespace primary_processor_based_vm_execution_controls;
677 using namespace secondary_processor_based_vm_execution_controls;
682 switch (guest_cs_access_rights::type::get())
701 throw std::logic_error(
"guest cs type must be 9, 11, 13, 15, or " 702 "3 (if unrestricted guest support is enabled)");
711 if (guest_ss_access_rights::unusable::get() != 0)
714 switch (guest_ss_access_rights::type::get())
724 throw std::logic_error(
"guest ss type must be 3 or 7");
733 if (guest_ds_access_rights::unusable::get() != 0)
736 switch (guest_ds_access_rights::type::get())
750 throw std::logic_error(
"guest ds type must be 1, 3, 5, 7, 11, or 15");
759 if (guest_es_access_rights::unusable::get() != 0)
762 switch (guest_es_access_rights::type::get())
776 throw std::logic_error(
"guest ds type must be 1, 3, 5, 7, 11, or 15");
785 if (guest_fs_access_rights::unusable::get() != 0)
788 switch (guest_fs_access_rights::type::get())
802 throw std::logic_error(
"guest fs type must be 1, 3, 5, 7, 11, or 15");
811 if (guest_gs_access_rights::unusable::get() != 0)
814 switch (guest_gs_access_rights::type::get())
828 throw std::logic_error(
"guest gs type must be 1, 3, 5, 7, 11, or 15");
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");
847 if (guest_ss_access_rights::unusable::get() != 0)
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");
860 if (guest_ds_access_rights::unusable::get() != 0)
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");
873 if (guest_es_access_rights::unusable::get() != 0)
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");
886 if (guest_fs_access_rights::unusable::get() != 0)
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");
899 if (guest_gs_access_rights::unusable::get() != 0)
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");
912 switch (guest_cs_access_rights::type::get())
921 if (guest_cs_access_rights::dpl::get() != 0)
922 throw std::logic_error(
"cs dpl must be 0 if type == 3");
931 switch (guest_cs_access_rights::type::get())
936 auto cs_dpl = guest_cs_access_rights::dpl::get();
937 auto ss_dpl = guest_ss_access_rights::dpl::get();
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");
948 auto cs_dpl = guest_cs_access_rights::dpl::get();
949 auto ss_dpl = guest_ss_access_rights::dpl::get();
952 throw std::logic_error(
"if cs access rights type is 13, 15 cs dpl must not be greater than ss dpl");
965 using namespace primary_processor_based_vm_execution_controls;
966 using namespace secondary_processor_based_vm_execution_controls;
974 auto ss_rpl = guest_ss_selector::rpl::get();
975 auto ss_dpl = guest_ss_access_rights::dpl::get();
977 if (ss_dpl != ss_rpl)
978 throw std::logic_error(
"if unrestricted guest mode is disabled ss dpl must equal ss rpl");
987 switch (guest_cs_access_rights::type::get())
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");
1004 using namespace primary_processor_based_vm_execution_controls;
1005 using namespace secondary_processor_based_vm_execution_controls;
1013 if (guest_ds_access_rights::unusable::get() != 0)
1016 switch (guest_ds_access_rights::type::get())
1028 auto ds_rpl = guest_ds_selector::rpl::get();
1029 auto ds_dpl = guest_ds_access_rights::dpl::get();
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 " 1041 using namespace primary_processor_based_vm_execution_controls;
1042 using namespace secondary_processor_based_vm_execution_controls;
1050 if (guest_es_access_rights::unusable::get() != 0)
1053 switch (guest_es_access_rights::type::get())
1065 auto es_rpl = guest_es_selector::rpl::get();
1066 auto es_dpl = guest_es_access_rights::dpl::get();
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 " 1078 using namespace primary_processor_based_vm_execution_controls;
1079 using namespace secondary_processor_based_vm_execution_controls;
1087 if (guest_fs_access_rights::unusable::get() != 0)
1090 switch (guest_fs_access_rights::type::get())
1102 auto fs_rpl = guest_fs_selector::rpl::get();
1103 auto fs_dpl = guest_fs_access_rights::dpl::get();
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 " 1115 using namespace primary_processor_based_vm_execution_controls;
1116 using namespace secondary_processor_based_vm_execution_controls;
1124 if (guest_gs_access_rights::unusable::get() != 0)
1127 switch (guest_gs_access_rights::type::get())
1139 auto gs_rpl = guest_gs_selector::rpl::get();
1140 auto gs_dpl = guest_gs_access_rights::dpl::get();
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 " 1155 if (guest_cs_access_rights::present::get() == 0)
1156 throw std::logic_error(
"cs access rights present flag must be 1 ");
1165 if (guest_ss_access_rights::unusable::get() != 0)
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");
1178 if (guest_ds_access_rights::unusable::get() != 0)
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");
1191 if (guest_es_access_rights::unusable::get() != 0)
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");
1204 if (guest_fs_access_rights::unusable::get() != 0)
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");
1217 if (guest_gs_access_rights::unusable::get() != 0)
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");
1230 if (guest_cs_access_rights::reserved::get() != 0)
1231 throw std::logic_error(
"cs access rights reserved bits must be 0 ");
1240 if (guest_ss_access_rights::unusable::get() != 0)
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");
1253 if (guest_ds_access_rights::unusable::get() != 0)
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");
1266 if (guest_es_access_rights::unusable::get() != 0)
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");
1279 if (guest_fs_access_rights::unusable::get() != 0)
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");
1292 if (guest_gs_access_rights::unusable::get() != 0)
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");
1308 if (guest_cs_access_rights::l::get() == 0)
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");
1321 auto cs_limit = vmcs::guest_cs_limit::get();
1322 auto g = guest_cs_access_rights::granularity::get();
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");
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");
1337 auto ss_limit = vmcs::guest_ss_limit::get();
1338 auto g = guest_ss_access_rights::granularity::get();
1340 if (guest_ss_access_rights::unusable::get() != 0)
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");
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");
1356 auto ds_limit = vmcs::guest_ds_limit::get();
1357 auto g = guest_ds_access_rights::granularity::get();
1359 if (guest_ds_access_rights::unusable::get() != 0)
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");
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");
1375 auto es_limit = vmcs::guest_es_limit::get();
1376 auto g = guest_es_access_rights::granularity::get();
1378 if (guest_es_access_rights::unusable::get() != 0)
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");
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");
1394 auto fs_limit = vmcs::guest_fs_limit::get();
1395 auto g = guest_fs_access_rights::granularity::get();
1397 if (guest_fs_access_rights::unusable::get() != 0)
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");
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");
1413 auto gs_limit = vmcs::guest_gs_limit::get();
1414 auto g = guest_gs_access_rights::granularity::get();
1416 if (guest_gs_access_rights::unusable::get() != 0)
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");
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");
1432 if ((guest_cs_access_rights::get() & 0xFFFE0000UL) != 0UL)
1433 throw std::logic_error(
"guest cs access rights bits 31:17 must be 0");
1442 if (guest_ss_access_rights::unusable::get() != 0)
1445 if ((guest_ss_access_rights::get() & 0xFFFE0000UL) != 0UL)
1446 throw std::logic_error(
"guest ss access rights bits 31:17 must be 0");
1455 if (guest_ds_access_rights::unusable::get() != 0)
1458 if ((guest_ds_access_rights::get() & 0xFFFE0000UL) != 0UL)
1459 throw std::logic_error(
"guest ds access rights bits 31:17 must be 0");
1468 if (guest_es_access_rights::unusable::get() != 0)
1471 if ((guest_es_access_rights::get() & 0xFFFE0000UL) != 0UL)
1472 throw std::logic_error(
"guest es access rights bits 31:17 must be 0");
1481 if (guest_fs_access_rights::unusable::get() != 0)
1484 if ((guest_fs_access_rights::get() & 0xFFFE0000UL) != 0UL)
1485 throw std::logic_error(
"guest fs access rights bits 31:17 must be 0");
1494 if (guest_gs_access_rights::unusable::get() != 0)
1497 if ((guest_gs_access_rights::get() & 0xFFFE0000UL) != 0UL)
1498 throw std::logic_error(
"guest gs access rights bits 31:17 must be 0");
1504 switch (guest_tr_access_rights::type::get())
1508 throw std::logic_error(
"tr type cannot be 3 if ia_32e_mode_guest is enabled");
1516 throw std::logic_error(
"tr type must be 3 or 11");
1523 if (guest_tr_access_rights::s::get() != 0)
1524 throw std::logic_error(
"tr must be a system descriptor. S should equal 0");
1530 if (guest_tr_access_rights::present::get() == 0)
1531 throw std::logic_error(
"tr access rights present flag must be 1 ");
1537 if (guest_tr_access_rights::reserved::get() != 0)
1538 throw std::logic_error(
"tr access rights bits 11:8 must be 0");
1544 auto tr_limit = vmcs::guest_tr_limit::get();
1545 auto g = guest_tr_access_rights::granularity::get();
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");
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");
1557 if (guest_tr_access_rights::unusable::get() != 0)
1558 throw std::logic_error(
"tr must be usable");
1564 auto tr_access = vmcs::guest_tr_access_rights::get();
1566 if ((tr_access & 0xFFFE0000) != 0)
1567 throw std::logic_error(
"guest tr access rights bits 31:17 must be 0");
1573 if (guest_ldtr_access_rights::unusable::get() != 0)
1576 switch (guest_ldtr_access_rights::type::get())
1582 throw std::logic_error(
"guest ldtr type must 2");
1589 if (guest_ldtr_access_rights::unusable::get() != 0)
1592 if (guest_ldtr_access_rights::s::get() != 0)
1593 throw std::logic_error(
"ldtr must be a system descriptor. S should equal 0");
1599 if (guest_ldtr_access_rights::unusable::get() != 0)
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");
1609 if (guest_ldtr_access_rights::unusable::get() != 0)
1612 if (guest_ldtr_access_rights::reserved::get() != 0)
1613 throw std::logic_error(
"ldtr access rights bits 11:8 must be 0");
1619 if (guest_ldtr_access_rights::unusable::get() != 0)
1622 auto ldtr_limit = vmcs::guest_ldtr_limit::get();
1623 auto g = guest_ldtr_access_rights::granularity::get();
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");
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");
1635 if (guest_ldtr_access_rights::unusable::get() != 0)
1638 auto ldtr_access = vmcs::guest_ldtr_access_rights::get();
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");
1657 throw std::logic_error(
"gdtr base is non-canonical");
1664 throw std::logic_error(
"idtr base is non-canonical");
1670 auto gdtr_limit = vmcs::guest_gdtr_limit::get();
1672 if ((gdtr_limit & 0xFFFF0000) != 0)
1673 throw std::logic_error(
"gdtr limit bits 31:16 must be 0");
1679 auto idtr_limit = vmcs::guest_idtr_limit::get();
1681 if ((idtr_limit & 0xFFFF0000) != 0)
1682 throw std::logic_error(
"idtr limit bits 31:16 must be 0");
1698 auto cs_l = guest_cs_access_rights::l::get();
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");
1710 auto cs_l = guest_cs_access_rights::l::get();
1719 throw std::logic_error(
"rip bits must be canonical");
1725 if (guest_rflags::reserved::get() != 0)
1726 throw std::logic_error(
"reserved bits in rflags must be 0");
1728 if (guest_rflags::always_enabled::get() == 0)
1729 throw std::logic_error(
"always enabled bits in rflags must be 1");
1739 throw std::logic_error(
"rflags VM must be 0 if ia 32e mode is 1 or PE is 0");
1745 using namespace vm_entry_interruption_information_field;
1754 throw std::logic_error(
"rflags IF must be 1 if the valid bit is 1 and interrupt type is external");
1790 if (vmcs::guest_activity_state::get() > 3)
1791 throw std::logic_error(
"activity state must be 0 - 3");
1800 if (guest_ss_access_rights::dpl::get() != 0)
1801 throw std::logic_error(
"ss.dpl must be 0 if activity state is HLT");
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");
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");
1822 using namespace vm_entry_interruption_information_field;
1830 auto type = interruption_type::get();
1831 auto vector = vector::get();
1858 throw std::logic_error(
"invalid interruption combination for guest hlt");
1864 using namespace vm_entry_interruption_information_field;
1872 auto type = interruption_type::get();
1873 auto vector = vector::get();
1890 throw std::logic_error(
"invalid interruption combination for guest shutdown");
1902 throw std::logic_error(
"invalid interruption combination");
1914 throw std::logic_error(
"activity state must not equal wait for sipi if entry to smm is enabled");
1920 if (vmcs::guest_interruptibility_state::reserved::get() != 0)
1921 throw std::logic_error(
"interruptibility state reserved bits 31:5 must be 0");
1927 auto sti = vmcs::guest_interruptibility_state::blocking_by_sti::get();
1928 auto mov_ss = vmcs::guest_interruptibility_state::blocking_by_mov_ss::get();
1930 if (sti != 0U && mov_ss != 0U)
1931 throw std::logic_error(
"interruptibility state sti and mov ss cannot both be 1");
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");
1948 using namespace vm_entry_interruption_information_field;
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");
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");
1968 using namespace vm_entry_interruption_information_field;
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");
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");
2000 using namespace vm_entry_interruption_information_field;
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");
2016 using namespace vm_entry_interruption_information_field;
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");
2035 if (guest_interruptibility_state::enclave_interruption::get() == 0)
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");
2043 throw std::logic_error(
"enclave interrupt is 1 in interruptibility state " 2044 "but the processor does not support sgx");
2050 if (vmcs::guest_pending_debug_exceptions::reserved::get() != 0)
2051 throw std::logic_error(
"pending debug exception reserved bits must be 0");
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();
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");
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");
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");
2088 throw std::logic_error(
"pending debug exception bit 12 must be 1 if rtm is 1");
2091 throw std::logic_error(
"rtm is set in pending debug exception but " 2092 "rtm is unsupported by the processor");
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");
2102 auto vmcs_link_pointer = vmcs::vmcs_link_pointer::get();
2104 if (vmcs_link_pointer == 0xFFFFFFFFFFFFFFFF)
2107 if ((vmcs_link_pointer & 0x0000000000000FFF) != 0)
2108 throw std::logic_error(
"vmcs link pointer bits 11:0 must be 0");
2114 auto vmcs_link_pointer = vmcs::vmcs_link_pointer::get();
2116 if (vmcs_link_pointer == 0xFFFFFFFFFFFFFFFF)
2120 throw std::logic_error(
"vmcs link pointer invalid physical address");
2126 auto vmcs_link_pointer = vmcs::vmcs_link_pointer::get();
2128 if (vmcs_link_pointer == 0xFFFFFFFFFFFFFFFF)
2131 auto vmcs =
g_mm->physint_to_virtptr(vmcs_link_pointer);
2133 if (
vmcs ==
nullptr)
2134 throw std::logic_error(
"invalid vmcs physical address");
2136 auto revision_id = *
static_cast<uint32_t *
>(
vmcs) & 0x7FFFFFFF;
2137 auto vmcs_shadow = *
static_cast<uint32_t *
>(
vmcs) & 0x80000000;
2139 if (revision_id != msrs::ia32_vmx_basic::revision_id::get())
2140 throw std::logic_error(
"shadow vmcs must contain CPU's revision id");
2148 if (vmcs_shadow == 0)
2149 throw std::logic_error(
"shadow vmcs bit must be enabled if vmcs shadowing is enabled");
2184 auto cr3 = vmcs::guest_cr3::get();
2185 auto virt_pdpt =
static_cast<uint64_t *
>(
g_mm->physint_to_virtptr(
cr3 & 0xFFFFFFE0UL));
2187 if (virt_pdpt ==
nullptr)
2188 throw std::logic_error(
"pdpt address is null");
2191 throw std::logic_error(
"pdpte0 reserved bits set with ept disabled and pae paging enabled");
2194 throw std::logic_error(
"pdpte1 reserved bits set with ept disabled and pae paging enabled");
2197 throw std::logic_error(
"pdpte2 reserved bits set with ept disabled and pae paging enabled");
2200 throw std::logic_error(
"pdpte3 reserved bits set with ept disabled and pae paging enabled");
2221 if (vmcs::guest_pdpte0::reserved::get() != 0U)
2222 throw std::logic_error(
"pdpte0 reserved bits set with ept and pae paging enabled");
2224 if (vmcs::guest_pdpte1::reserved::get() != 0U)
2225 throw std::logic_error(
"pdpte1 reserved bits set with ept and pae paging enabled");
2227 if (vmcs::guest_pdpte2::reserved::get() != 0U)
2228 throw std::logic_error(
"pdpte2 reserved bits set with ept and pae paging enabled");
2230 if (vmcs::guest_pdpte3::reserved::get() != 0U)
2231 throw std::logic_error(
"ppdpte3 reserved bits set with ept and pae paging enabled");
void guest_valid_activity_state()
void guest_fs_must_be_present_if_usable()
void guest_gs_granularity()
void guest_ss_access_rights_type()
void guest_es_is_not_a_system_descriptor()
void uintptr_t uintptr_t cr3
void guest_ss_granularity()
void guest_vmcs_link_pointer_bits_11_0()
void guest_interruptibility_state_sti_mov_ss()
void guest_rflags_vm_bit()
void guest_interruptibility_not_in_smm()
void guest_ds_base_upper_dword_0()
void guest_ds_base_is_shifted()
void guest_cs_access_rights_type()
void guest_fs_granularity()
void guest_cr4_for_unsupported_bits()
void guest_pending_debug_exceptions_rtm()
void guest_load_debug_controls_verify_reserved()
constexpr const auto shutdown
auto is_disabled_if_exists(bool verbose=false) noexcept
void guest_ia32_sysenter_esp_canonical_address()
void guest_ss_must_be_present_if_usable()
void guest_cr0_for_unsupported_bits()
void guest_cs_type_not_equal_3()
void guest_ds_granularity()
constexpr const auto execute_only_conforming
void guest_es_access_rights_reserved_must_be_0()
void guest_tr_must_be_usable()
void guest_tr_access_rights_remaining_reserved_bit_0()
void guest_cs_access_rights_remaining_reserved_bit_0()
void guest_gdtr_limit_reserved_bits()
constexpr const auto external_interrupt
void guest_verify_load_ia32_efer()
void guest_fs_is_not_a_system_descriptor()
void guest_must_be_active_if_injecting_blocking_state()
void guest_interruptibility_state_nmi()
auto is_physical_address_valid(T addr)
void guest_gs_access_rights_remaining_reserved_bit_0()
void guest_ds_access_rights_reserved_must_be_0()
void guest_v8086_gs_access_rights()
void guest_cs_base_is_shifted()
void guest_cs_db_must_be_0_if_l_equals_1()
constexpr const auto read_execute_accessed
void guest_ss_base_upper_dword_0()
void guest_ss_base_is_shifted()
constexpr const auto read_write_expand_down_accessed
constexpr const auto read_only_expand_down_accessed
void guest_es_base_is_shifted()
void guest_gs_access_rights_type()
void guest_es_must_be_present_if_usable()
void guest_shutdown_valid_interrupts()
void guest_descriptor_table_registers_all()
auto is_linear_address_valid(T addr)
auto memory_type_reserved(T memory_type)
void guest_interruptibility_state_enclave_interrupt()
void guest_v8086_fs_access_rights()
constexpr const auto other_event
void guest_activity_state_not_hlt_when_dpl_not_0()
void guest_gs_is_not_a_system_descriptor()
void guest_tr_must_be_a_system_descriptor()
void guest_gs_access_rights_reserved_must_be_0()
void guest_ss_is_not_a_system_descriptor()
constexpr const auto read_write
constexpr const auto hardware_exception
constexpr const auto read_only_accessed
void guest_ss_and_cs_rpl_are_the_same()
constexpr const auto read_write_accessed
void guest_gs_base_is_canonical()
constexpr const auto execute_only_accessed
void guest_cs_access_rights_reserved_must_be_0()
void guest_es_access_rights_type()
void guest_cs_granularity()
void guest_pending_debug_exceptions_dbg_ctl()
void guest_tr_type_must_be_11()
void guest_verify_ia_32e_mode_enabled()
constexpr const auto debug_exception
void guest_tr_granularity()
void guest_load_debug_controls_verify_dr7()
void guest_rflag_interrupt_enable()
void guest_verify_load_ia32_bndcfgs()
void guest_ldtr_ti_bit_equals_0()
void guest_fs_access_rights_remaining_reserved_bit_0()
void guest_ldtr_access_rights_remaining_reserved_bit_0()
void guest_interruptibility_entry_to_smm()
void guest_v8086_ds_access_rights()
void guest_cs_base_upper_dword_0()
void guest_interruptibility_state_sti()
void guest_pending_debug_exceptions_reserved()
constexpr const auto non_maskable_interrupt
void guest_ss_dpl_must_equal_zero()
void guest_v8086_ss_access_rights()
void guest_verify_load_ia32_pat()
auto is_enabled_if_exists(bool verbose=false) noexcept
void guest_gs_base_is_shifted()
void guest_fs_access_rights_reserved_must_be_0()
constexpr const auto mask
void guest_valid_pdpte_with_ept_disabled()
void guest_sipi_valid_interrupts()
void guest_ldtr_base_is_canonical()
void guest_fs_access_rights_type()
void guest_verify_ia_32e_mode_disabled()
constexpr const auto machine_check
void guest_ss_access_rights_remaining_reserved_bit_0()
void guest_tr_ti_bit_equals_0()
const void * view_as_pointer(const T val)
constexpr const auto read_execute_conforming_accessed
void guest_ss_dpl_must_equal_rpl()
void guest_rip_and_rflags_all()
void guest_interruptibility_state_reserved()
void guest_rip_upper_bits()
void guest_verify_load_ia32_perf_global_ctrl()
void guest_rflags_reserved_bits()
void guest_vmcs_link_pointer_valid_addr()
void guest_ldtr_must_be_present()
void guest_idtr_limit_reserved_bits()
void guest_vmcs_link_pointer_in_smm()
void guest_tr_access_rights_reserved_must_be_0()
void guest_cs_dpl_adheres_to_ss_dpl()
void guest_control_registers_debug_registers_and_msrs_all()
void guest_idtr_base_must_be_canonical()
void guest_vmcs_link_pointer_not_in_smm()
void guest_es_access_rights_remaining_reserved_bit_0()
void guest_non_register_state_all()
void guest_interruptibility_state_sti_and_nmi()
void guest_interruptibility_state_virtual_nmi()
void guest_cr0_verify_paging_enabled()
void guest_ds_must_be_present_if_usable()
void guest_tr_must_be_present()
constexpr const auto execute_only_conforming_accessed
constexpr const auto divide_error
void guest_fs_base_is_canonical()
void guest_cs_must_be_present()
void guest_ds_access_rights_type()
auto is_address_canonical(T addr)
void guest_vmcs_link_pointer_first_word()
constexpr const auto mask
void guest_ldtr_must_be_a_system_descriptor()
void guest_cs_is_not_a_system_descriptor()
void guest_tr_base_is_canonical()
void guest_ds_is_not_a_system_descriptor()
void guest_gs_must_be_present_if_usable()
void guest_interruptibility_state_external_interrupt()
constexpr const auto wait_for_sipi
void guest_cr3_for_unsupported_bits()
void guest_ds_access_rights_remaining_reserved_bit_0()
void guest_ss_access_rights_reserved_must_be_0()
void guest_rip_valid_addr()
void guest_v8086_es_access_rights()
constexpr const auto read_execute_conforming
constexpr const auto active
void guest_gdtr_base_must_be_canonical()
void guest_v8086_cs_access_rights()
void guest_ldtr_type_must_be_2()
void guest_segment_registers_all()
void guest_valid_activity_state_and_smm()
void guest_ldtr_granularity()
void guest_ia32_sysenter_eip_canonical_address()
void guest_valid_pdpte_with_ept_enabled()
void guest_es_base_upper_dword_0()
void guest_hlt_valid_interrupts()
void guest_fs_base_is_shifted()
void guest_ldtr_access_rights_reserved_must_be_0()
void guest_es_granularity()