test_vmcs_intel_x64_check_controls.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 
22 #include <test.h>
29 
30 using namespace intel_x64;
31 using namespace msrs;
32 using namespace vmcs;
33 using namespace check;
34 
35 static struct control_flow_path path;
36 
37 static void
38 setup_check_control_vm_execution_control_fields_all_paths(std::vector<struct control_flow_path> &cfg)
39 {
40  path.setup = [&]
41  {
42  g_msrs[ia32_vmx_true_pinbased_ctls::addr] = 0xffffffff00000000UL;
43  g_msrs[ia32_vmx_true_procbased_ctls::addr] = 0xffffffff00000000UL;
44  g_msrs[ia32_vmx_procbased_ctls2::addr] = 0xffffffff00000000UL;
63  };
64  path.throws_exception = false;
65  cfg.push_back(path);
66 }
67 
68 static void
69 setup_check_control_vm_exit_control_fields_all_paths(std::vector<struct control_flow_path> &cfg)
70 {
71  path.setup = [&]
72  {
73  g_msrs[ia32_vmx_true_exit_ctls::addr] = 0xffffffff00000000UL;
78  };
79  path.throws_exception = false;
80  cfg.push_back(path);
81 }
82 
83 static void
84 setup_check_control_vm_entry_control_fields_all_paths(std::vector<struct control_flow_path> &cfg)
85 {
86  path.setup = [&]
87  {
88  g_msrs[ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000UL;
91  };
92  path.throws_exception = false;
93  cfg.push_back(path);
94 }
95 
96 void
97 setup_check_control_vmx_controls_all_paths(std::vector<struct control_flow_path> &cfg)
98 {
99  std::vector<struct control_flow_path> sub_cfg;
100 
101  setup_check_control_vm_execution_control_fields_all_paths(sub_cfg);
102  setup_check_control_vm_exit_control_fields_all_paths(sub_cfg);
103  setup_check_control_vm_entry_control_fields_all_paths(sub_cfg);
104 
105  path.setup = [sub_cfg]
106  {
107  for (const auto &sub_path : sub_cfg)
108  sub_path.setup();
109  };
110  path.throws_exception = false;
111  cfg.push_back(path);
112 }
113 
114 static void
115 setup_check_control_pin_based_ctls_reserved_properly_set_paths(std::vector<struct control_flow_path> &cfg)
116 {
117  path.setup = [&] { g_msrs[ia32_vmx_true_pinbased_ctls::addr] = 0xffffffff00000000UL; };
118  path.throws_exception = false;
119  cfg.push_back(path);
120 
121  path.setup = [&] { g_msrs[ia32_vmx_true_pinbased_ctls::addr] = 1; };
122  path.throws_exception = true;
123  path.exception = ""_ut_lee;
124  cfg.push_back(path);
125 
126  path.setup = [&] { pin_based_vm_execution_controls::set(1UL); };
127  path.throws_exception = true;
128  path.exception = ""_ut_lee;
129  cfg.push_back(path);
130 }
131 
132 static void
133 setup_check_control_proc_based_ctls_reserved_properly_set_paths(std::vector<struct control_flow_path> &cfg)
134 {
135  path.setup = [&] { g_msrs[ia32_vmx_true_procbased_ctls::addr] = 0xffffffff00000000UL; };
136  path.throws_exception = false;
137  cfg.push_back(path);
138 
139  path.setup = [&] { g_msrs[ia32_vmx_true_procbased_ctls::addr] = 1; };
140  path.throws_exception = true;
141  path.exception = ""_ut_lee;
142  cfg.push_back(path);
143 
145  path.throws_exception = true;
146  path.exception = ""_ut_lee;
147  cfg.push_back(path);
148 }
149 
150 static void
151 setup_check_control_proc_based_ctls2_reserved_properly_set_paths(std::vector<struct control_flow_path> &cfg)
152 {
154  path.throws_exception = true;
155  path.exception = ""_ut_lee;
156  cfg.push_back(path);
157 
158  path.setup = [&]
159  {
161  g_msrs[ia32_vmx_procbased_ctls2::addr] = 0xffffffff00000000UL;
162  };
163  path.throws_exception = false;
164  cfg.push_back(path);
165 
166  path.setup = [&]
167  {
170  };
171  path.throws_exception = true;
172  path.exception = ""_ut_lee;
173  cfg.push_back(path);
174 
175  path.setup = [&]
176  {
177  using namespace secondary_processor_based_vm_execution_controls;
178 
179  g_msrs[ia32_vmx_procbased_ctls2::addr] = 0xfffffffe00000000UL;
181 
182  // we use the _fields_ set() here rather than the controls enable()
183  // so that an exception isn't thrown in the setup function.
185  };
186  path.throws_exception = false;
187  cfg.push_back(path);
188 
190  path.throws_exception = true;
191  path.exception = ""_ut_lee;
192  cfg.push_back(path);
193 }
194 
195 static void
196 setup_check_control_cr3_count_less_than_4_paths(std::vector<struct control_flow_path> &cfg)
197 {
198  path.setup = [&] { cr3_target_count::set(3UL); };
199  path.throws_exception = false;
200  cfg.push_back(path);
201 
202  path.setup = [&] { cr3_target_count::set(5UL); };
203  path.throws_exception = true;
204  path.exception = ""_ut_lee;
205  cfg.push_back(path);
206 }
207 
208 static void
209 setup_check_control_io_bitmap_address_bits_paths(std::vector<struct control_flow_path> &cfg)
210 {
211  path.setup = [&]
212  {
216  };
217  path.throws_exception = false;
218  cfg.push_back(path);
219 
220  path.setup = [&]
221  {
225  };
226  path.throws_exception = true;
227  path.exception = ""_ut_lee;
228  cfg.push_back(path);
229 
230  path.setup = [&]
231  {
232  address_of_io_bitmap_a::set(0xff00000000000000U);
234  };
235  path.throws_exception = true;
236  path.exception = ""_ut_lee;
237  cfg.push_back(path);
238 
239  path.setup = [&] { address_of_io_bitmap_b::set(0xff00000000000000U); };
240  path.throws_exception = true;
241  path.exception = ""_ut_lee;
242  cfg.push_back(path);
243 
244  path.setup = [&] { address_of_io_bitmap_a::set(0x1000U); };
245  path.throws_exception = true;
246  path.exception = ""_ut_lee;
247  cfg.push_back(path);
248 
249  path.setup = [&] { address_of_io_bitmap_b::set(0x1000U); };
250  path.throws_exception = false;
251  cfg.push_back(path);
252 }
253 
254 static void
255 setup_check_control_msr_bitmap_address_bits_paths(std::vector<struct control_flow_path> &cfg)
256 {
257  path.setup = [&]
258  {
261  };
262  path.throws_exception = false;
263  cfg.push_back(path);
264 
265  path.setup = [&]
266  {
270  };
271  path.throws_exception = true;
272  path.exception = ""_ut_lee;
273  cfg.push_back(path);
274 
275  path.setup = [&] { address_of_msr_bitmap::set(0xff00000000000000U); };
276  path.throws_exception = true;
277  path.exception = ""_ut_lee;
278  cfg.push_back(path);
279 
280  path.setup = [&] { address_of_msr_bitmap::set(0x1000U); };
281  path.throws_exception = false;
282  cfg.push_back(path);
283 }
284 
285 
286 static void
287 setup_check_control_tpr_shadow_and_virtual_apic_paths(std::vector<struct control_flow_path> &cfg)
288 {
289  using namespace primary_processor_based_vm_execution_controls;
290  using namespace secondary_processor_based_vm_execution_controls;
291 
292  // control paths when tpr shadow is enabled
293  path.setup = [&]
294  {
298  };
299  path.throws_exception = true;
300  path.exception = ""_ut_lee;
301  cfg.push_back(path);
302 
303  path.setup = [&] { virtual_apic_address::set(1U); };
304  path.throws_exception = true;
305  path.exception = ""_ut_lee;
306  cfg.push_back(path);
307 
308  path.setup = [&] { virtual_apic_address::set(0xff00000000000000U); };
309  path.throws_exception = true;
310  path.exception = ""_ut_lee;
311  cfg.push_back(path);
312 
313  path.setup = [&]
314  {
317  virtual_apic_address::set(0x1000U);
319  };
320  path.throws_exception = true;
321  path.exception = ""_ut_lee;
322  cfg.push_back(path);
323 
324  path.setup = [&]
325  {
328  tpr_threshold::set(0xffffffffffffffffUL);
329  };
330  path.throws_exception = true;
331  path.exception = ""_ut_lee;
332  cfg.push_back(path);
333 
334  path.setup = [&]
335  {
338  tpr_threshold::set(0UL);
340  };
341  path.throws_exception = true;
342  path.exception = ""_ut_lee;
343  cfg.push_back(path);
344 
345  path.setup = [&]
346  {
350  };
351  path.throws_exception = true;
352  path.exception = ""_ut_lee;
353  cfg.push_back(path);
354 
355  path.setup = [&]
356  {
359  };
360  path.throws_exception = false;
361  cfg.push_back(path);
362 
363  path.setup = [&] { tpr_threshold::set(0xfUL); };
364  path.throws_exception = true;
365  path.exception = ""_ut_lee;
366  cfg.push_back(path);
367 
368  // control paths when tpr shadow is disabled
369  path.setup = [&]
370  {
375  };
376  path.throws_exception = false;
377  cfg.push_back(path);
378 
379  path.setup = [&]
380  {
385  };
386  path.throws_exception = true;
387  path.exception = ""_ut_lee;
388  cfg.push_back(path);
389 
390  path.setup = [&]
391  {
397  };
398  path.throws_exception = true;
399  path.exception = ""_ut_lee;
400  cfg.push_back(path);
401 
402  path.setup = [&]
403  {
409  };
410  path.throws_exception = true;
411  path.exception = ""_ut_lee;
412  cfg.push_back(path);
413 
414  path.setup = [&]
415  {
418  };
419  path.throws_exception = false;
420  cfg.push_back(path);
421 }
422 
423 static void
424 setup_check_control_nmi_exiting_and_virtual_nmi_paths(std::vector<struct control_flow_path> &cfg)
425 {
426  path.setup = [&]
427  {
430  };
431  path.throws_exception = false;
432  cfg.push_back(path);
433 
434  path.setup = [&]
435  {
440  };
441  path.throws_exception = true;
442  path.exception = ""_ut_lee;
443  cfg.push_back(path);
444 
445  path.setup = [&]
446  {
449  };
450  path.throws_exception = false;
451  cfg.push_back(path);
452 }
453 
454 static void
455 setup_check_control_virtual_nmi_and_nmi_window_paths(std::vector<struct control_flow_path> &cfg)
456 {
457  path.setup = [&]
458  {
461  };
462  path.throws_exception = false;
463  cfg.push_back(path);
464 
465  path.setup = [&]
466  {
471  };
472  path.throws_exception = true;
473  path.exception = ""_ut_lee;
474  cfg.push_back(path);
475 
476  path.setup = [&]
477  {
480  };
481  path.throws_exception = false;
482  cfg.push_back(path);
483 }
484 
485 static void
486 setup_check_control_virtual_apic_address_bits_paths(std::vector<struct control_flow_path> &cfg)
487 {
488  path.setup = [&]
489  {
492  };
493  path.throws_exception = false;
494  cfg.push_back(path);
495 
496  path.setup = [&]
497  {
501  };
502  path.throws_exception = false;
503  cfg.push_back(path);
504 
505  path.setup = [&]
506  {
511  };
512  path.throws_exception = true;
513  path.exception = ""_ut_lee;
514  cfg.push_back(path);
515 
516  path.setup = [&] { apic_access_address::set(1U); };
517  path.throws_exception = true;
518  path.exception = ""_ut_lee;
519  cfg.push_back(path);
520 
521  path.setup = [&] { apic_access_address::set(0xff00000000000000U); };
522  path.throws_exception = true;
523  path.exception = ""_ut_lee;
524  cfg.push_back(path);
525 
526  path.setup = [&] { apic_access_address::set(0x1000U); };
527  path.throws_exception = false;
528  cfg.push_back(path);
529 }
530 
531 static void
532 setup_check_control_x2apic_mode_and_virtual_apic_access_paths(std::vector<struct control_flow_path> &cfg)
533 {
534  path.setup = [&]
535  {
538  };
539  path.throws_exception = false;
540  cfg.push_back(path);
541 
542  path.setup = [&]
543  {
548  };
549  path.throws_exception = false;
550  cfg.push_back(path);
551 
552  path.setup = [&]
553  {
559  };
560  path.throws_exception = true;
561  path.exception = ""_ut_lee;
562  cfg.push_back(path);
563 
564  path.setup = [&]
565  {
569  };
570  path.throws_exception = false;
571  cfg.push_back(path);
572 }
573 
574 static void
575 setup_check_control_virtual_interrupt_and_external_interrupt_paths(std::vector<struct control_flow_path> &cfg)
576 {
577  path.setup = [&]
578  {
581  };
582  path.throws_exception = false;
583  cfg.push_back(path);
584 
585  path.setup = [&]
586  {
591  };
592  path.throws_exception = false;
593  cfg.push_back(path);
594 
595  path.setup = [&]
596  {
602  };
603  path.throws_exception = true;
604  path.exception = ""_ut_lee;
605  cfg.push_back(path);
606 
607  path.setup = [&]
608  {
611  };
612  path.throws_exception = false;
613  cfg.push_back(path);
614 }
615 
616 static void
617 setup_check_control_process_posted_interrupt_checks_paths(std::vector<struct control_flow_path> &cfg)
618 {
619  path.setup = [&]
620  {
623  };
624  path.throws_exception = false;
625  cfg.push_back(path);
626 
627  path.setup = [&]
628  {
633  };
634  path.throws_exception = true;
635  path.exception = ""_ut_lee;
636  cfg.push_back(path);
637 
638  path.setup = [&]
639  {
644  };
645  path.throws_exception = true;
646  path.exception = ""_ut_lee;
647  cfg.push_back(path);
648 
649  path.setup = [&]
650  {
656  };
657  path.throws_exception = true;
658  path.exception = ""_ut_lee;
659  cfg.push_back(path);
660 
661  path.setup = [&]
662  {
666  };
667  path.throws_exception = true;
668  path.exception = ""_ut_lee;
669  cfg.push_back(path);
670 
671  path.setup = [&]
672  {
675  };
676  path.throws_exception = true;
677  path.exception = ""_ut_lee;
678  cfg.push_back(path);
679 
680  path.setup = [&] { posted_interrupt_descriptor_address::set(0xff00000000000000U); };
681  path.throws_exception = true;
682  path.exception = ""_ut_lee;
683  cfg.push_back(path);
684 
685  path.setup = [&] { posted_interrupt_descriptor_address::set(0x1000U); };
686  path.throws_exception = false;
687  cfg.push_back(path);
688 }
689 
690 static void
691 setup_check_control_vpid_checks_paths(std::vector<struct control_flow_path> &cfg)
692 {
693  path.setup = [&]
694  {
697  };
698  path.throws_exception = false;
699  cfg.push_back(path);
700 
701  path.setup = [&]
702  {
707  };
708  path.throws_exception = false;
709  cfg.push_back(path);
710 
711  path.setup = [&]
712  {
717  };
718  path.throws_exception = true;
719  path.exception = ""_ut_lee;
720  cfg.push_back(path);
721 
722  path.setup = [&] { virtual_processor_identifier::set(1U); };
723  path.throws_exception = false;
724  cfg.push_back(path);
725 }
726 
727 static void
728 setup_check_control_enable_ept_checks_paths(std::vector<struct control_flow_path> &cfg)
729 {
730  path.setup = [&]
731  {
734  };
735  path.throws_exception = false;
736  cfg.push_back(path);
737 
738  path.setup = [&]
739  {
744  };
745  path.throws_exception = false;
746  cfg.push_back(path);
747 
748  path.setup = [&]
749  {
756  };
757  path.throws_exception = true;
758  path.exception = ""_ut_lee;
759  cfg.push_back(path);
760 
762  path.throws_exception = true;
763  path.exception = ""_ut_lee;
764  cfg.push_back(path);
765 
766  path.setup = [&] { ept_pointer::memory_type::set(3U); };
767  path.throws_exception = true;
768  path.exception = ""_ut_lee;
769  cfg.push_back(path);
770 
771  path.setup = [&]
772  {
776  };
777  path.throws_exception = true;
778  path.exception = ""_ut_lee;
779  cfg.push_back(path);
780 
781  path.setup = [&]
782  {
785  };
786  path.throws_exception = true;
787  path.exception = ""_ut_lee;
788  cfg.push_back(path);
789 
790  path.setup = [&]
791  {
794  };
795  path.throws_exception = true;
796  path.exception = ""_ut_lee;
797  cfg.push_back(path);
798 }
799 
800 static void
801 setup_check_control_enable_pml_checks_paths(std::vector<struct control_flow_path> &cfg)
802 {
803  path.setup = [&]
804  {
807  };
808  path.throws_exception = false;
809  cfg.push_back(path);
810 
811  path.setup = [&]
812  {
817  };
818  path.throws_exception = false;
819  cfg.push_back(path);
820 
821  path.setup = [&]
822  {
828  };
829  path.throws_exception = true;
830  path.exception = ""_ut_lee;
831  cfg.push_back(path);
832 
833  path.setup = [&]
834  {
838  pml_address::set(0xff00000000000000U);
839  };
840  path.throws_exception = true;
841  path.exception = ""_ut_lee;
842  cfg.push_back(path);
843 
844  path.setup = [&] { pml_address::set(1U); };
845  path.throws_exception = true;
846  path.exception = ""_ut_lee;
847  cfg.push_back(path);
848 
849  path.setup = [&] { pml_address::set(0x1000U); };
850  path.throws_exception = false;
851  cfg.push_back(path);
852 }
853 
854 static void
855 setup_check_control_unrestricted_guests_paths(std::vector<struct control_flow_path> &cfg)
856 {
857  path.setup = [&]
858  {
861  };
862  path.throws_exception = false;
863  cfg.push_back(path);
864 
865  path.setup = [&]
866  {
871  };
872  path.throws_exception = false;
873  cfg.push_back(path);
874 
875  path.setup = [&]
876  {
882  };
883  path.throws_exception = true;
884  path.exception = ""_ut_lee;
885  cfg.push_back(path);
886 
887  path.setup = [&]
888  {
892  };
893  path.throws_exception = false;
894  cfg.push_back(path);
895 }
896 
897 static void
898 setup_check_control_enable_vm_functions_paths(std::vector<struct control_flow_path> &cfg)
899 {
900  using namespace vmcs::secondary_processor_based_vm_execution_controls;
901 
902  path.setup = [&]
903  {
906  };
907  path.throws_exception = false;
908  cfg.push_back(path);
909 
910  path.setup = [&]
911  {
916  };
917  path.throws_exception = false;
918  cfg.push_back(path);
919 
920  path.setup = [&]
921  {
925  };
926  path.throws_exception = false;
927  cfg.push_back(path);
928 
929  path.setup = [&]
930  {
935  };
936  path.throws_exception = true;
937  path.exception = ""_ut_lee;
938  cfg.push_back(path);
939 
940  path.setup = [&] { vm_function_controls::set(0U); };
941  path.throws_exception = false;
942  cfg.push_back(path);
943 
944  path.setup = [&]
945  {
952  };
953  path.throws_exception = true;
954  path.exception = ""_ut_lee;
955  cfg.push_back(path);
956 
957  path.setup = [&]
958  {
962  };
963  path.throws_exception = true;
964  path.exception = ""_ut_lee;
965  cfg.push_back(path);
966 
967  path.setup = [&] { eptp_list_address::set(0xff00000000000000U); };
968  path.throws_exception = true;
969  path.exception = ""_ut_lee;
970  cfg.push_back(path);
971 
972  path.setup = [&] { eptp_list_address::set(0x1000U); };
973  path.throws_exception = false;
974  cfg.push_back(path);
975 }
976 
977 static void
978 setup_check_control_enable_vmcs_shadowing_paths(std::vector<struct control_flow_path> &cfg)
979 {
980  path.setup = [&]
981  {
984  };
985  path.throws_exception = false;
986  cfg.push_back(path);
987 
988  path.setup = [&]
989  {
994  };
995  path.throws_exception = false;
996  cfg.push_back(path);
997 
998  path.setup = [&]
999  {
1003  };
1004  path.throws_exception = true;
1005  path.exception = ""_ut_lee;
1006  cfg.push_back(path);
1007 
1008  path.setup = [&]
1009  {
1010  vmread_bitmap_address::set(0xff00000000000000U);
1012  };
1013  path.throws_exception = true;
1014  path.exception = ""_ut_lee;
1015  cfg.push_back(path);
1016 
1017  path.setup = [&] { vmwrite_bitmap_address::set(0xff00000000000000U); };
1018  path.throws_exception = true;
1019  path.exception = ""_ut_lee;
1020  cfg.push_back(path);
1021 
1022  path.setup = [&] { vmread_bitmap_address::set(0x1000U); };
1023  path.throws_exception = true;
1024  path.exception = ""_ut_lee;
1025  cfg.push_back(path);
1026 
1027  path.setup = [&] { vmwrite_bitmap_address::set(0x1000U); };
1028  path.throws_exception = false;
1029  cfg.push_back(path);
1030 }
1031 
1032 static void
1033 setup_check_control_enable_ept_violation_checks_paths(std::vector<struct control_flow_path> &cfg)
1034 {
1035  path.setup = [&]
1036  {
1039  };
1040  path.throws_exception = false;
1041  cfg.push_back(path);
1042 
1043  path.setup = [&]
1044  {
1049  };
1050  path.throws_exception = false;
1051  cfg.push_back(path);
1052 
1053  path.setup = [&]
1054  {
1059  };
1060  path.throws_exception = true;
1061  path.exception = ""_ut_lee;
1062  cfg.push_back(path);
1063 
1064  path.setup = [&] { virtualization_exception_information_address::set(0xff00000000000000U); };
1065  path.throws_exception = true;
1066  path.exception = ""_ut_lee;
1067  cfg.push_back(path);
1068 
1070  path.throws_exception = false;
1071  cfg.push_back(path);
1072 }
1073 
1074 static void
1075 setup_check_control_vm_exit_ctls_reserved_properly_set_paths(std::vector<struct control_flow_path> &cfg)
1076 {
1077  path.setup = [&]
1078  {
1080  vm_exit_controls::set(0UL);
1081  };
1082  path.throws_exception = false;
1083  cfg.push_back(path);
1084 
1085  path.setup = [&] { g_msrs[ia32_vmx_true_exit_ctls::addr] = 1; };
1086  path.throws_exception = true;
1087  path.exception = ""_ut_lee;
1088  cfg.push_back(path);
1089 
1090  path.setup = [&] { g_msrs[ia32_vmx_true_exit_ctls::addr] = 0xffffffff00000000UL; };
1091  path.throws_exception = false;
1092  cfg.push_back(path);
1093 }
1094 
1095 static void
1096 setup_check_control_activate_and_save_preemption_timer_must_be_0_paths(std::vector<struct control_flow_path> &cfg)
1097 {
1098  path.setup = [&]
1099  {
1102  };
1103  path.throws_exception = false;
1104  cfg.push_back(path);
1105 
1106  path.setup = [&]
1107  {
1112  };
1113  path.throws_exception = true;
1114  path.exception = ""_ut_lee;
1115  cfg.push_back(path);
1116 
1117  path.setup = [&]
1118  {
1121  };
1122  path.throws_exception = false;
1123  cfg.push_back(path);
1124 }
1125 
1126 static void
1127 setup_check_control_exit_msr_store_address_paths(std::vector<struct control_flow_path> &cfg)
1128 {
1129  path.setup = [&] { vm_exit_msr_store_count::set(0UL); };
1130  path.throws_exception = false;
1131  cfg.push_back(path);
1132 
1133  path.setup = [&]
1134  {
1137  };
1138  path.throws_exception = true;
1139  path.exception = ""_ut_lee;
1140  cfg.push_back(path);
1141 
1142  path.setup = [&]
1143  {
1145  vm_exit_msr_store_address::set(0xff00000000000000U);
1146  };
1147  path.throws_exception = true;
1148  path.exception = ""_ut_lee;
1149  cfg.push_back(path);
1150 
1151  path.setup = [&]
1152  {
1154  vm_exit_msr_store_address::set(0xfffffffffff0U);
1155  };
1156  path.throws_exception = true;
1157  path.exception = ""_ut_lee;
1158  cfg.push_back(path);
1159 
1160  path.setup = [&]
1161  {
1164  };
1165  path.throws_exception = false;
1166  cfg.push_back(path);
1167 }
1168 
1169 static void
1170 setup_check_control_exit_msr_load_address_paths(std::vector<struct control_flow_path> &cfg)
1171 {
1172  path.setup = [&] { vm_exit_msr_load_count::set(0UL); };
1173  path.throws_exception = false;
1174  cfg.push_back(path);
1175 
1176  path.setup = [&]
1177  {
1180  };
1181  path.throws_exception = true;
1182  path.exception = ""_ut_lee;
1183  cfg.push_back(path);
1184 
1185  path.setup = [&]
1186  {
1188  vm_exit_msr_load_address::set(0xff00000000000000U);
1189  };
1190  path.throws_exception = true;
1191  path.exception = ""_ut_lee;
1192  cfg.push_back(path);
1193 
1194  path.setup = [&]
1195  {
1197  vm_exit_msr_load_address::set(0xfffffffffff0U);
1198  };
1199  path.throws_exception = true;
1200  path.exception = ""_ut_lee;
1201  cfg.push_back(path);
1202 
1203  path.setup = [&]
1204  {
1207  };
1208  path.throws_exception = false;
1209  cfg.push_back(path);
1210 }
1211 
1212 static void
1213 setup_check_control_vm_entry_ctls_reserved_properly_set_paths(std::vector<struct control_flow_path> &cfg)
1214 {
1215  path.setup = [&]
1216  {
1219  };
1220  path.throws_exception = false;
1221  cfg.push_back(path);
1222 
1223  path.setup = [&] { g_msrs[ia32_vmx_true_entry_ctls::addr] = 1; };
1224  path.throws_exception = true;
1225  path.exception = ""_ut_lee;
1226  cfg.push_back(path);
1227 
1228  path.setup = [&] { g_msrs[ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000; };
1229  path.throws_exception = false;
1230  cfg.push_back(path);
1231 }
1232 
1233 static void
1234 setup_check_control_event_injection_type_vector_checks_paths(std::vector<struct control_flow_path> &cfg)
1235 {
1236  using namespace vm_entry_interruption_information_field;
1237 
1238  path.setup = [&] { set(0UL); };
1239  path.throws_exception = false;
1240  cfg.push_back(path);
1241 
1242  path.setup = [&]
1243  {
1246  };
1247  path.throws_exception = true;
1248  path.exception = ""_ut_lee;
1249  cfg.push_back(path);
1250 
1251  path.setup = [&]
1252  {
1255  };
1256  path.throws_exception = true;
1257  path.exception = ""_ut_lee;
1258  cfg.push_back(path);
1259 
1260  path.setup = [&]
1261  {
1263  vector::set(0xFFUL);
1264  };
1265  path.throws_exception = true;
1266  path.exception = ""_ut_lee;
1267  cfg.push_back(path);
1268 
1270  path.throws_exception = true;
1271  path.exception = ""_ut_lee;
1272  cfg.push_back(path);
1273 
1274  path.setup = [&]
1275  {
1278  };
1279  path.throws_exception = true;
1280  path.exception = ""_ut_lee;
1281  cfg.push_back(path);
1282 
1283  path.setup = [&] { vector::set(0UL); };
1284  path.throws_exception = false;
1285  cfg.push_back(path);
1286 }
1287 
1288 static void
1289 setup_check_control_event_injection_delivery_ec_checks_paths(std::vector<struct control_flow_path> &cfg)
1290 {
1291  using namespace vm_entry_interruption_information_field;
1292 
1293  path.setup = [&] { valid_bit::disable(); };
1294  path.throws_exception = false;
1295  cfg.push_back(path);
1296 
1297  path.setup = [&]
1298  {
1303  guest_cr0::set(0U);
1305  };
1306  path.throws_exception = true;
1307  path.exception = ""_ut_lee;
1308  cfg.push_back(path);
1309 
1310  path.setup = [&]
1311  {
1316  };
1317  path.throws_exception = true;
1318  path.exception = ""_ut_lee;
1319  cfg.push_back(path);
1320 
1322  path.throws_exception = true;
1323  path.exception = ""_ut_lee;
1324  cfg.push_back(path);
1325 
1326  path.setup = [&] { vector::set(0x8UL); };
1327  path.throws_exception = false;
1328  cfg.push_back(path);
1329 
1330  path.setup = [&] { deliver_error_code_bit::disable(); };
1331  path.throws_exception = true;
1332  path.exception = ""_ut_lee;
1333  cfg.push_back(path);
1334 }
1335 
1336 static void
1337 setup_check_control_event_injection_reserved_bits_checks_paths(std::vector<struct control_flow_path> &cfg)
1338 {
1339  using namespace vm_entry_interruption_information_field;
1340 
1341  path.setup = [&] { set(0UL); };
1342  path.throws_exception = false;
1343  cfg.push_back(path);
1344 
1345  path.setup = [&] { valid_bit::enable(); };
1346  path.throws_exception = false;
1347  cfg.push_back(path);
1348 
1349  path.setup = [&] { reserved::set(1UL); };
1350  path.throws_exception = true;
1351  path.exception = ""_ut_lee;
1352  cfg.push_back(path);
1353 }
1354 
1355 static void
1356 setup_check_control_event_injection_ec_checks_paths(std::vector<struct control_flow_path> &cfg)
1357 {
1358  using namespace vm_entry_interruption_information_field;
1359 
1360  path.setup = [&] { set(0UL); };
1361  path.throws_exception = false;
1362  cfg.push_back(path);
1363 
1364  path.setup = [&] { valid_bit::enable(); };
1365  path.throws_exception = false;
1366  cfg.push_back(path);
1367 
1368  path.setup = [&]
1369  {
1372  };
1373  path.throws_exception = true;
1374  path.exception = ""_ut_lee;
1375  cfg.push_back(path);
1376 
1377  path.setup = [&] { vm_entry_exception_error_code::set(0UL); };
1378  path.throws_exception = false;
1379  cfg.push_back(path);
1380 }
1381 
1382 static void
1383 setup_check_control_event_injection_instr_length_checks_paths(std::vector<struct control_flow_path> &cfg)
1384 {
1385  using namespace vm_entry_interruption_information_field;
1386 
1387  path.setup = [&] { set(0UL); };
1388  path.throws_exception = false;
1389  cfg.push_back(path);
1390 
1391  path.setup = [&]
1392  {
1395  };
1396  path.throws_exception = false;
1397  cfg.push_back(path);
1398 
1399  path.setup = [&]
1400  {
1404  };
1405  path.throws_exception = true;
1406  path.exception = ""_ut_lee;
1407  cfg.push_back(path);
1408 
1409  path.setup = [&] { vm_entry_instruction_length::set(16UL); };
1410  path.throws_exception = true;
1411  path.exception = ""_ut_lee;
1412  cfg.push_back(path);
1413 
1414  path.setup = [&] { vm_entry_instruction_length::set(1UL); };
1415  path.throws_exception = false;
1416  cfg.push_back(path);
1417 }
1418 
1419 static void
1420 setup_check_control_entry_msr_load_address_paths(std::vector<struct control_flow_path> &cfg)
1421 {
1422  path.setup = [&] { vm_entry_msr_load_count::set(0UL); };
1423  path.throws_exception = false;
1424  cfg.push_back(path);
1425 
1426  path.setup = [&]
1427  {
1430  };
1431  path.throws_exception = true;
1432  path.exception = ""_ut_lee;
1433  cfg.push_back(path);
1434 
1435  path.setup = [&]
1436  {
1438  vm_entry_msr_load_address::set(0xff00000000000000U);
1439  };
1440  path.throws_exception = true;
1441  path.exception = ""_ut_lee;
1442  cfg.push_back(path);
1443 
1444  path.setup = [&]
1445  {
1447  vm_entry_msr_load_address::set(0xfffffffffff0U);
1448  };
1449  path.throws_exception = true;
1450  path.exception = ""_ut_lee;
1451  cfg.push_back(path);
1452 
1453  path.setup = [&]
1454  {
1457  };
1458  path.throws_exception = false;
1459  cfg.push_back(path);
1460 }
1461 
1462 void
1463 vmcs_ut::test_check_control_vmx_controls_all()
1464 {
1465  std::vector<struct control_flow_path> cfg;
1467 
1469 }
1470 
1471 void
1472 vmcs_ut::test_check_control_vm_execution_control_fields_all()
1473 {
1474  std::vector<struct control_flow_path> cfg;
1475  setup_check_control_vm_execution_control_fields_all_paths(cfg);
1476 
1478 }
1479 
1480 void
1481 vmcs_ut::test_check_control_vm_exit_control_fields_all()
1482 {
1483  std::vector<struct control_flow_path> cfg;
1484  setup_check_control_vm_exit_control_fields_all_paths(cfg);
1485 
1487 }
1488 
1489 void
1490 vmcs_ut::test_check_control_vm_entry_control_fields_all()
1491 {
1492  std::vector<struct control_flow_path> cfg;
1493  setup_check_control_vm_entry_control_fields_all_paths(cfg);
1494 
1496 }
1497 
1498 void
1499 vmcs_ut::test_check_control_pin_based_ctls_reserved_properly_set()
1500 {
1501  std::vector<struct control_flow_path> cfg;
1502  setup_check_control_pin_based_ctls_reserved_properly_set_paths(cfg);
1503 
1505 }
1506 
1507 void
1508 vmcs_ut::test_check_control_proc_based_ctls_reserved_properly_set()
1509 {
1510  std::vector<struct control_flow_path> cfg;
1511  setup_check_control_proc_based_ctls_reserved_properly_set_paths(cfg);
1512 
1514 }
1515 
1516 void
1517 vmcs_ut::test_check_control_proc_based_ctls2_reserved_properly_set()
1518 {
1519  std::vector<struct control_flow_path> cfg;
1520  setup_check_control_proc_based_ctls2_reserved_properly_set_paths(cfg);
1521 
1523 }
1524 
1525 void
1526 vmcs_ut::test_check_control_cr3_count_less_than_4()
1527 {
1528  std::vector<struct control_flow_path> cfg;
1529  setup_check_control_cr3_count_less_than_4_paths(cfg);
1530 
1532 }
1533 
1534 void
1535 vmcs_ut::test_check_control_io_bitmap_address_bits()
1536 {
1537  std::vector<struct control_flow_path> cfg;
1538  setup_check_control_io_bitmap_address_bits_paths(cfg);
1539 
1541 }
1542 
1543 void
1544 vmcs_ut::test_check_control_msr_bitmap_address_bits()
1545 {
1546  std::vector<struct control_flow_path> cfg;
1547  setup_check_control_msr_bitmap_address_bits_paths(cfg);
1548 
1550 }
1551 
1552 void
1553 vmcs_ut::test_check_control_tpr_shadow_and_virtual_apic()
1554 {
1555  std::vector<struct control_flow_path> cfg;
1556  setup_check_control_tpr_shadow_and_virtual_apic_paths(cfg);
1557 
1559 }
1560 
1561 void
1562 vmcs_ut::test_check_control_nmi_exiting_and_virtual_nmi()
1563 {
1564  std::vector<struct control_flow_path> cfg;
1565  setup_check_control_nmi_exiting_and_virtual_nmi_paths(cfg);
1566 
1568 }
1569 
1570 void
1571 vmcs_ut::test_check_control_virtual_nmi_and_nmi_window()
1572 {
1573  std::vector<struct control_flow_path> cfg;
1574  setup_check_control_virtual_nmi_and_nmi_window_paths(cfg);
1575 
1577 }
1578 
1579 void
1580 vmcs_ut::test_check_control_virtual_apic_address_bits()
1581 {
1582  std::vector<struct control_flow_path> cfg;
1583  setup_check_control_virtual_apic_address_bits_paths(cfg);
1584 
1586 }
1587 
1588 void
1589 vmcs_ut::test_check_control_x2apic_mode_and_virtual_apic_access()
1590 {
1591  std::vector<struct control_flow_path> cfg;
1592  setup_check_control_x2apic_mode_and_virtual_apic_access_paths(cfg);
1593 
1595 }
1596 
1597 void
1598 vmcs_ut::test_check_control_virtual_interrupt_and_external_interrupt()
1599 {
1600  std::vector<struct control_flow_path> cfg;
1601  setup_check_control_virtual_interrupt_and_external_interrupt_paths(cfg);
1602 
1604 }
1605 
1606 void
1607 vmcs_ut::test_check_control_process_posted_interrupt_checks()
1608 {
1609  std::vector<struct control_flow_path> cfg;
1610  setup_check_control_process_posted_interrupt_checks_paths(cfg);
1611 
1613 }
1614 
1615 void
1616 vmcs_ut::test_check_control_vpid_checks()
1617 {
1618  std::vector<struct control_flow_path> cfg;
1619  setup_check_control_vpid_checks_paths(cfg);
1620 
1622 }
1623 
1624 void
1625 vmcs_ut::test_check_control_enable_ept_checks()
1626 {
1627  std::vector<struct control_flow_path> cfg;
1628  setup_check_control_enable_ept_checks_paths(cfg);
1629 
1631 }
1632 
1633 void
1634 vmcs_ut::test_check_control_enable_pml_checks()
1635 {
1636  std::vector<struct control_flow_path> cfg;
1637  setup_check_control_enable_pml_checks_paths(cfg);
1638 
1640 }
1641 
1642 void
1643 vmcs_ut::test_check_control_unrestricted_guests()
1644 {
1645  std::vector<struct control_flow_path> cfg;
1646  setup_check_control_unrestricted_guests_paths(cfg);
1647 
1649 }
1650 
1651 void
1652 vmcs_ut::test_check_control_enable_vm_functions()
1653 {
1654  std::vector<struct control_flow_path> cfg;
1655  setup_check_control_enable_vm_functions_paths(cfg);
1656 
1658 }
1659 
1660 void
1661 vmcs_ut::test_check_control_enable_vmcs_shadowing()
1662 {
1663  std::vector<struct control_flow_path> cfg;
1664  setup_check_control_enable_vmcs_shadowing_paths(cfg);
1665 
1667 }
1668 
1669 void
1670 vmcs_ut::test_check_control_enable_ept_violation_checks()
1671 {
1672  std::vector<struct control_flow_path> cfg;
1673  setup_check_control_enable_ept_violation_checks_paths(cfg);
1674 
1676 }
1677 
1678 void
1679 vmcs_ut::test_check_control_vm_exit_ctls_reserved_properly_set()
1680 {
1681  std::vector<struct control_flow_path> cfg;
1682  setup_check_control_vm_exit_ctls_reserved_properly_set_paths(cfg);
1683 
1685 }
1686 
1687 void
1688 vmcs_ut::test_check_control_activate_and_save_preemption_timer_must_be_0()
1689 {
1690  std::vector<struct control_flow_path> cfg;
1691  setup_check_control_activate_and_save_preemption_timer_must_be_0_paths(cfg);
1692 
1694 }
1695 
1696 void
1697 vmcs_ut::test_check_control_exit_msr_store_address()
1698 {
1699  std::vector<struct control_flow_path> cfg;
1700  setup_check_control_exit_msr_store_address_paths(cfg);
1701 
1703 }
1704 
1705 void
1706 vmcs_ut::test_check_control_exit_msr_load_address()
1707 {
1708  std::vector<struct control_flow_path> cfg;
1709  setup_check_control_exit_msr_load_address_paths(cfg);
1710 
1712 }
1713 
1714 void
1715 vmcs_ut::test_check_control_vm_entry_ctls_reserved_properly_set()
1716 {
1717  std::vector<struct control_flow_path> cfg;
1718  setup_check_control_vm_entry_ctls_reserved_properly_set_paths(cfg);
1719 
1721 }
1722 
1723 void
1724 vmcs_ut::test_check_control_event_injection_type_vector_checks()
1725 {
1726  std::vector<struct control_flow_path> cfg;
1727  setup_check_control_event_injection_type_vector_checks_paths(cfg);
1728 
1730 }
1731 
1732 void
1733 vmcs_ut::test_check_control_event_injection_delivery_ec_checks()
1734 {
1735  std::vector<struct control_flow_path> cfg;
1736  setup_check_control_event_injection_delivery_ec_checks_paths(cfg);
1737 
1739 }
1740 
1741 void
1742 vmcs_ut::test_check_control_event_injection_reserved_bits_checks()
1743 {
1744  std::vector<struct control_flow_path> cfg;
1745  setup_check_control_event_injection_reserved_bits_checks_paths(cfg);
1746 
1748 }
1749 
1750 void
1751 vmcs_ut::test_check_control_event_injection_ec_checks()
1752 {
1753  std::vector<struct control_flow_path> cfg;
1754  setup_check_control_event_injection_ec_checks_paths(cfg);
1755 
1757 }
1758 
1759 void
1760 vmcs_ut::test_check_control_event_injection_instr_length_checks()
1761 {
1762  std::vector<struct control_flow_path> cfg;
1763  setup_check_control_event_injection_instr_length_checks_paths(cfg);
1764 
1766 }
1767 
1768 void
1769 vmcs_ut::test_check_control_entry_msr_load_address()
1770 {
1771  std::vector<struct control_flow_path> cfg;
1772  setup_check_control_entry_msr_load_address_paths(cfg);
1773 
1775 }
1776 
1777 void
1778 vmcs_ut::test_check_control_reserved_properly_set()
1779 {
1780  g_msrs[ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000UL;
1781  vm_entry_controls::set(0x1234UL);
1782 
1784  auto ctls = vm_entry_controls::get();
1786 
1788 }
1789 
1790 void
1791 vmcs_ut::test_check_memory_type_reserved()
1792 {
1794  this->expect_true(memory_type_reserved(8U));
1795 }
void proc_ctl2_allow0(uint64_t mask)
Definition: test.cpp:86
void exit_ctl_allow0(uint64_t mask)
Definition: test.cpp:106
#define test_vmcs_check(cfg,...)
Definition: test.h:36
void pin_ctl_allow1(uint64_t mask)
Definition: test.cpp:94
std::map< uint64_t, uint64_t > g_vmcs_fields
Definition: test.cpp:32
#define expect_no_exception(f)
Definition: unittest.h:198
constexpr const auto mask
Definition: cpuid_x64.h:85
bool throws_exception
Definition: test.h:44
bool g_phys_to_virt_return_nullptr
Definition: test.cpp:41
uint64_t g_test_addr
Definition: test.cpp:43
constexpr const auto software_interrupt
auto memory_type_reserved(T memory_type)
constexpr const auto other_event
constexpr const auto hardware_exception
void proc_ctl2_disallow1(uint64_t mask)
Definition: test.cpp:90
constexpr const auto addr
Definition: cpuid_x64.h:80
std::map< msrs::field_type, msrs::value_type > g_msrs
std::map< cpuid::field_type, cpuid::value_type > g_eax_cpuid
constexpr const auto non_maskable_interrupt
std::shared_ptr< std::exception > exception
Definition: test.h:43
void pin_ctl_allow0(uint64_t mask)
Definition: test.cpp:98
constexpr const auto reserved
Definition: vcpuid.h:33
void proc_ctl2_allow1(uint64_t mask)
Definition: test.cpp:82
void proc_ctl_allow1(uint64_t mask)
Definition: test.cpp:70
constexpr const auto addr
constexpr const auto name
Definition: cpuid_x64.h:81
void proc_ctl_allow0(uint64_t mask)
Definition: test.cpp:74
#define expect_false(a)
void exit_ctl_allow1(uint64_t mask)
Definition: test.cpp:102
uint64_t g_virt_apic_addr
Definition: test.cpp:44
void set(T val) noexcept
Definition: crs_intel_x64.h:52
void vmfunc_ctl_allow1(uint64_t mask)
Definition: test.cpp:118
auto control_reserved_properly_set(MA msr_addr, C ctls, const char *ctls_name)
constexpr const auto write_through
Definition: x64.h:44
#define expect_true(a)
void setup_check_control_vmx_controls_all_paths(std::vector< struct control_flow_path > &cfg)
void proc_ctl_disallow1(uint64_t mask)
Definition: test.cpp:78
std::function< void()> setup
Definition: test.h:42