crs_intel_x64.h
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 //
8 // This library is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU Lesser General Public
10 // License as published by the Free Software Foundation; either
11 // version 2.1 of the License, or (at your option) any later version.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 
22 #ifndef CRS_INTEL_X64_H
23 #define CRS_INTEL_X64_H
24 
25 #include <debug.h>
26 #include <bitmanip.h>
27 
28 extern "C" uint64_t __read_cr0(void) noexcept;
29 extern "C" void __write_cr0(uint64_t val) noexcept;
30 
31 extern "C" uint64_t __read_cr2(void) noexcept;
32 extern "C" void __write_cr2(uint64_t val) noexcept;
33 
34 extern "C" uint64_t __read_cr3(void) noexcept;
35 extern "C" void __write_cr3(uint64_t val) noexcept;
36 
37 extern "C" uint64_t __read_cr4(void) noexcept;
38 extern "C" void __write_cr4(uint64_t val) noexcept;
39 
40 // *INDENT-OFF*
41 
42 namespace intel_x64
43 {
44 namespace cr0
45 {
46  using value_type = uint64_t;
47 
48  inline auto get() noexcept
49  { return __read_cr0(); }
50 
51  template<class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
52  void set(T val) noexcept { __write_cr0(val); }
53 
54  namespace protection_enable
55  {
56  constexpr const auto mask = 0x0000000000000001UL;
57  constexpr const auto from = 0;
58  constexpr const auto name = "protection_enable";
59 
60  inline auto get() noexcept
61  { return get_bit(__read_cr0(), from) != 0; }
62 
63  inline void set(bool val) noexcept
64  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
65  }
66 
67  namespace monitor_coprocessor
68  {
69  constexpr const auto mask = 0x0000000000000002UL;
70  constexpr const auto from = 1;
71  constexpr const auto name = "monitor_coprocessor";
72 
73  inline auto get() noexcept
74  { return get_bit(__read_cr0(), from) != 0; }
75 
76  inline void set(bool val) noexcept
77  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
78  }
79 
80  namespace emulation
81  {
82  constexpr const auto mask = 0x0000000000000004UL;
83  constexpr const auto from = 2;
84  constexpr const auto name = "emulation";
85 
86  inline auto get() noexcept
87  { return get_bit(__read_cr0(), from) != 0; }
88 
89  inline void set(bool val) noexcept
90  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
91  }
92 
93  namespace task_switched
94  {
95  constexpr const auto mask = 0x0000000000000008UL;
96  constexpr const auto from = 3;
97  constexpr const auto name = "task_switched";
98 
99  inline auto get() noexcept
100  { return get_bit(__read_cr0(), from) != 0; }
101 
102  inline void set(bool val) noexcept
103  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
104  }
105 
106  namespace extension_type
107  {
108  constexpr const auto mask = 0x0000000000000010UL;
109  constexpr const auto from = 4;
110  constexpr const auto name = "extension_type";
111 
112  inline auto get() noexcept
113  { return get_bit(__read_cr0(), from) != 0; }
114 
115  inline void set(bool val) noexcept
116  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
117  }
118 
119  namespace numeric_error
120  {
121  constexpr const auto mask = 0x0000000000000020UL;
122  constexpr const auto from = 5;
123  constexpr const auto name = "numeric_error";
124 
125  inline auto get() noexcept
126  { return get_bit(__read_cr0(), from) != 0; }
127 
128  inline void set(bool val) noexcept
129  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
130  }
131 
132  namespace write_protect
133  {
134  constexpr const auto mask = 0x0000000000010000UL;
135  constexpr const auto from = 16;
136  constexpr const auto name = "write_protect";
137 
138  inline auto get() noexcept
139  { return get_bit(__read_cr0(), from) != 0; }
140 
141  inline void set(bool val) noexcept
142  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
143  }
144 
145  namespace alignment_mask
146  {
147  constexpr const auto mask = 0x0000000000040000UL;
148  constexpr const auto from = 18;
149  constexpr const auto name = "alignment_mask";
150 
151  inline auto get() noexcept
152  { return get_bit(__read_cr0(), from) != 0; }
153 
154  inline void set(bool val) noexcept
155  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
156  }
157 
158  namespace not_write_through
159  {
160  constexpr const auto mask = 0x0000000020000000UL;
161  constexpr const auto from = 29;
162  constexpr const auto name = "not_write_through";
163 
164  inline auto get() noexcept
165  { return get_bit(__read_cr0(), from) != 0; }
166 
167  inline void set(bool val) noexcept
168  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
169  }
170 
171  namespace cache_disable
172  {
173  constexpr const auto mask = 0x0000000040000000UL;
174  constexpr const auto from = 30;
175  constexpr const auto name = "cache_disable";
176 
177  inline auto get() noexcept
178  { return get_bit(__read_cr0(), from) != 0; }
179 
180  inline void set(bool val) noexcept
181  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
182  }
183 
184  namespace paging
185  {
186  constexpr const auto mask = 0x0000000080000000UL;
187  constexpr const auto from = 31;
188  constexpr const auto name = "paging";
189 
190  inline auto get() noexcept
191  { return get_bit(__read_cr0(), from) != 0; }
192 
193  inline void set(bool val) noexcept
194  { __write_cr0(val ? set_bit(__read_cr0(), from) : clear_bit(__read_cr0(), from)); }
195  }
196 
197  inline void dump() noexcept
198  {
199  bfdebug << "cr0 enabled flags:" << bfendl;
200 
202  bfdebug << " - " << protection_enable::name << bfendl;
204  bfdebug << " - " << monitor_coprocessor::name << bfendl;
205  if (emulation::get())
206  bfdebug << " - " << emulation::name << bfendl;
207  if (task_switched::get())
208  bfdebug << " - " << task_switched::name << bfendl;
209  if (extension_type::get())
210  bfdebug << " - " << extension_type::name << bfendl;
211  if (numeric_error::get())
212  bfdebug << " - " << numeric_error::name << bfendl;
213  if (write_protect::get())
214  bfdebug << " - " << write_protect::name << bfendl;
215  if (alignment_mask::get())
216  bfdebug << " - " << alignment_mask::name << bfendl;
218  bfdebug << " - " << not_write_through::name << bfendl;
219  if (cache_disable::get())
220  bfdebug << " - " << cache_disable::name << bfendl;
221  if (paging::get())
222  bfdebug << " - " << paging::name << bfendl;
223  }
224 }
225 
226 namespace cr2
227 {
228  using value_type = uint64_t;
229 
230  inline auto get() noexcept
231  { return __read_cr2(); }
232 
233  template<class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
234  void set(T val) noexcept { __write_cr2(val); }
235 }
236 
237 namespace cr3
238 {
239  using value_type = uint64_t;
240 
241  inline auto get() noexcept
242  { return __read_cr3(); }
243 
244  template<class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
245  void set(T val) noexcept { __write_cr3(val); }
246 }
247 
248 namespace cr4
249 {
250  using value_type = uint64_t;
251 
252  inline auto get() noexcept
253  { return __read_cr4(); }
254 
255  template<class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
256  void set(T val) noexcept { __write_cr4(val); }
257 
258  namespace v8086_mode_extensions
259  {
260  constexpr const auto mask = 0x0000000000000001UL;
261  constexpr const auto from = 0;
262  constexpr const auto name = "v8086_mode_extensions";
263 
264  inline auto get() noexcept
265  { return get_bit(__read_cr4(), from) != 0; }
266 
267  inline void set(bool val) noexcept
268  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
269  }
270 
271  namespace protected_mode_virtual_interrupts
272  {
273  constexpr const auto mask = 0x0000000000000002UL;
274  constexpr const auto from = 1;
275  constexpr const auto name = "protected_mode_virtual_interrupts";
276 
277  inline auto get() noexcept
278  { return get_bit(__read_cr4(), from) != 0; }
279 
280  inline void set(bool val) noexcept
281  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
282  }
283 
284  namespace time_stamp_disable
285  {
286  constexpr const auto mask = 0x0000000000000004UL;
287  constexpr const auto from = 2;
288  constexpr const auto name = "time_stamp_disable";
289 
290  inline auto get() noexcept
291  { return get_bit(__read_cr4(), from) != 0; }
292 
293  inline void set(bool val) noexcept
294  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
295  }
296 
297  namespace debugging_extensions
298  {
299  constexpr const auto mask = 0x0000000000000008UL;
300  constexpr const auto from = 3;
301  constexpr const auto name = "debugging_extensions";
302 
303  inline auto get() noexcept
304  { return get_bit(__read_cr4(), from) != 0; }
305 
306  inline void set(bool val) noexcept
307  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
308  }
309 
310  namespace page_size_extensions
311  {
312  constexpr const auto mask = 0x0000000000000010UL;
313  constexpr const auto from = 4;
314  constexpr const auto name = "page_size_extensions";
315 
316  inline auto get() noexcept
317  { return get_bit(__read_cr4(), from) != 0; }
318 
319  inline void set(bool val) noexcept
320  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
321  }
322 
323  namespace physical_address_extensions
324  {
325  constexpr const auto mask = 0x0000000000000020UL;
326  constexpr const auto from = 5;
327  constexpr const auto name = "physical_address_extensions";
328 
329  inline auto get() noexcept
330  { return get_bit(__read_cr4(), from) != 0; }
331 
332  inline void set(bool val) noexcept
333  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
334  }
335 
336  namespace machine_check_enable
337  {
338  constexpr const auto mask = 0x0000000000000040UL;
339  constexpr const auto from = 6;
340  constexpr const auto name = "machine_check_enable";
341 
342  inline auto get() noexcept
343  { return get_bit(__read_cr4(), from) != 0; }
344 
345  inline void set(bool val) noexcept
346  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
347  }
348 
349  namespace page_global_enable
350  {
351  constexpr const auto mask = 0x0000000000000080UL;
352  constexpr const auto from = 7;
353  constexpr const auto name = "page_global_enable";
354 
355  inline auto get() noexcept
356  { return get_bit(__read_cr4(), from) != 0; }
357 
358  inline void set(bool val) noexcept
359  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
360  }
361 
362  namespace performance_monitor_counter_enable
363  {
364  constexpr const auto mask = 0x0000000000000100UL;
365  constexpr const auto from = 8;
366  constexpr const auto name = "performance_monitor_counter_enable";
367 
368  inline auto get() noexcept
369  { return get_bit(__read_cr4(), from) != 0; }
370 
371  inline void set(bool val) noexcept
372  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
373  }
374 
375  namespace osfxsr
376  {
377  constexpr const auto mask = 0x0000000000000200UL;
378  constexpr const auto from = 9;
379  constexpr const auto name = "osfxsr";
380 
381  inline auto get() noexcept
382  { return get_bit(__read_cr4(), from) != 0; }
383 
384  inline void set(bool val) noexcept
385  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
386  }
387 
388  namespace osxmmexcpt
389  {
390  constexpr const auto mask = 0x0000000000000400UL;
391  constexpr const auto from = 10;
392  constexpr const auto name = "osxmmexcpt";
393 
394  inline auto get() noexcept
395  { return get_bit(__read_cr4(), from) != 0; }
396 
397  inline void set(bool val) noexcept
398  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
399  }
400 
401  namespace vmx_enable_bit
402  {
403  constexpr const auto mask = 0x0000000000002000UL;
404  constexpr const auto from = 13;
405  constexpr const auto name = "vmx_enable_bit";
406 
407  inline auto get() noexcept
408  { return get_bit(__read_cr4(), from) != 0; }
409 
410  inline void set(bool val) noexcept
411  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
412  }
413 
414  namespace smx_enable_bit
415  {
416  constexpr const auto mask = 0x0000000000004000UL;
417  constexpr const auto from = 14;
418  constexpr const auto name = "smx_enable_bit";
419 
420  inline auto get() noexcept
421  { return get_bit(__read_cr4(), from) != 0; }
422 
423  inline void set(bool val) noexcept
424  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
425  }
426 
427  namespace fsgsbase_enable_bit
428  {
429  constexpr const auto mask = 0x0000000000010000UL;
430  constexpr const auto from = 16;
431  constexpr const auto name = "fsgsbase_enable_bit";
432 
433  inline auto get() noexcept
434  { return get_bit(__read_cr4(), from) != 0; }
435 
436  inline void set(bool val) noexcept
437  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
438  }
439 
440  namespace pcid_enable_bit
441  {
442  constexpr const auto mask = 0x0000000000020000UL;
443  constexpr const auto from = 17;
444  constexpr const auto name = "pcid_enable_bit";
445 
446  inline auto get() noexcept
447  { return get_bit(__read_cr4(), from) != 0; }
448 
449  inline void set(bool val) noexcept
450  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
451  }
452 
453  namespace osxsave
454  {
455  constexpr const auto mask = 0x0000000000040000UL;
456  constexpr const auto from = 18;
457  constexpr const auto name = "osxsave";
458 
459  inline auto get() noexcept
460  { return get_bit(__read_cr4(), from) != 0; }
461 
462  inline void set(bool val) noexcept
463  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
464  }
465 
466  namespace smep_enable_bit
467  {
468  constexpr const auto mask = 0x0000000000100000UL;
469  constexpr const auto from = 20;
470  constexpr const auto name = "smep_enable_bit";
471 
472  inline auto get() noexcept
473  { return get_bit(__read_cr4(), from) != 0; }
474 
475  inline void set(bool val) noexcept
476  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
477  }
478 
479  namespace smap_enable_bit
480  {
481  constexpr const auto mask = 0x0000000000200000UL;
482  constexpr const auto from = 21;
483  constexpr const auto name = "smap_enable_bit";
484 
485  inline auto get() noexcept
486  { return get_bit(__read_cr4(), from) != 0; }
487 
488  inline void set(bool val) noexcept
489  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
490  }
491 
492  namespace protection_key_enable_bit
493  {
494  constexpr const auto mask = 0x0000000000400000UL;
495  constexpr const auto from = 22;
496  constexpr const auto name = "protection_key_enable_bit";
497 
498  inline auto get() noexcept
499  { return get_bit(__read_cr4(), from) != 0; }
500 
501  inline void set(bool val) noexcept
502  { __write_cr4(val ? set_bit(__read_cr4(), from) : clear_bit(__read_cr4(), from)); }
503  }
504 
505  inline void dump() noexcept
506  {
507  bfdebug << "cr4 enabled flags:" << bfendl;
508 
510  bfdebug << " - " << v8086_mode_extensions::name << bfendl;
512  bfdebug << " - " << protected_mode_virtual_interrupts::name << bfendl;
514  bfdebug << " - " << time_stamp_disable::name << bfendl;
516  bfdebug << " - " << debugging_extensions::name << bfendl;
518  bfdebug << " - " << page_size_extensions::name << bfendl;
520  bfdebug << " - " << physical_address_extensions::name << bfendl;
522  bfdebug << " - " << machine_check_enable::name << bfendl;
524  bfdebug << " - " << page_global_enable::name << bfendl;
526  bfdebug << " - " << performance_monitor_counter_enable::name << bfendl;
527  if (osfxsr::get())
528  bfdebug << " - " << osfxsr::name << bfendl;
529  if (osxmmexcpt::get())
530  bfdebug << " - " << osxmmexcpt::name << bfendl;
531  if (vmx_enable_bit::get())
532  bfdebug << " - " << vmx_enable_bit::name << bfendl;
533  if (smx_enable_bit::get())
534  bfdebug << " - " << smx_enable_bit::name << bfendl;
535  if (smx_enable_bit::get())
536  bfdebug << " - " << smx_enable_bit::name << bfendl;
538  bfdebug << " - " << fsgsbase_enable_bit::name << bfendl;
539  if (pcid_enable_bit::get())
540  bfdebug << " - " << pcid_enable_bit::name << bfendl;
541  if (osxsave::get())
542  bfdebug << " - " << osxsave::name << bfendl;
543  if (smep_enable_bit::get())
544  bfdebug << " - " << smep_enable_bit::name << bfendl;
545  if (smap_enable_bit::get())
546  bfdebug << " - " << smap_enable_bit::name << bfendl;
548  bfdebug << " - " << protection_key_enable_bit::name << bfendl;
549  }
550 }
551 }
552 
553 // *INDENT-ON*
554 
555 #endif
void uintptr_t uintptr_t cr3
Definition: map_ptr_x64.cpp:33
void __write_cr2(uint64_t val) noexcept
void __write_cr4(uint64_t val) noexcept
constexpr const auto mask
constexpr const auto name
constexpr const auto name
constexpr const auto from
constexpr const auto from
void dump() noexcept
constexpr const auto from
Definition: crs_intel_x64.h:83
constexpr const auto from
Definition: crs_intel_x64.h:96
constexpr const auto mask
constexpr const auto from
constexpr const auto name
constexpr const auto name
uint64_t __read_cr0(void) noexcept
constexpr const auto name
uint64_t value_type
Definition: crs_intel_x64.h:46
auto get_bit(T t, B b) noexcept
Definition: bitmanip.h:42
constexpr const auto from
constexpr const auto from
void uint64_t uint64_t uint64_t *rdx noexcept
uint64_t __read_cr2(void) noexcept
constexpr const auto mask
constexpr const auto name
auto get() noexcept
uint64_t __read_cr4(void) noexcept
constexpr const auto name
Definition: crs_intel_x64.h:84
constexpr const auto mask
constexpr const auto mask
constexpr const auto mask
constexpr const auto from
constexpr const auto name
void dump() noexcept
auto clear_bit(T t, B b) noexcept
Definition: bitmanip.h:36
constexpr const auto name
Definition: crs_intel_x64.h:97
auto set_bit(T t, B b) noexcept
Definition: bitmanip.h:30
constexpr const auto mask
constexpr const auto from
uint64_t value_type
void __write_cr3(uint64_t val) noexcept
constexpr const auto mask
constexpr const auto name
constexpr const auto mask
constexpr const auto from
constexpr const auto mask
Definition: crs_intel_x64.h:82
constexpr const auto from
uint64_t value_type
auto get() noexcept
constexpr const auto from
constexpr const auto mask
constexpr const auto from
constexpr const auto mask
constexpr const auto name
constexpr const auto name
constexpr const auto mask
Definition: crs_intel_x64.h:95
uint64_t value_type
void __write_cr0(uint64_t val) noexcept
constexpr const auto name
uint64_t __read_cr3(void) noexcept