vmcs_intel_x64_helpers.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 // Author: Connor Davis <davisc@ainfosec.com>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 
23 #ifndef VMCS_INTEL_X64_HELPERS_H
24 #define VMCS_INTEL_X64_HELPERS_H
25 
26 #include <type_traits>
29 
30 // *INDENT-OFF*
31 
32 namespace intel_x64
33 {
34 namespace vmcs
35 {
36 
37 using field_type = uint64_t;
38 using value_type = uint64_t;
39 
40 template<class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
41 auto get_vmcs_field(T addr, const char *name, bool exists)
42 {
43  if (!exists)
44  throw std::logic_error("get_vmcs_field failed: "_s + name + " field doesn't exist");
45 
46  return intel_x64::vm::read(addr, name);
47 }
48 
49 template<class T, class = typename std::enable_if<std::is_integral<T>::value>::type>
50 auto get_vmcs_field_if_exists(T addr, const char *name, bool verbose, bool exists)
51 {
52  if (exists)
53  return intel_x64::vm::read(addr, name);
54 
55  if (!exists && verbose)
56  bfwarning << "get_vmcs_field_if_exists failed: " << name << " field doesn't exist" << bfendl;
57 
58  return 0UL;
59 }
60 
61 template <class V, class A,
62  class = typename std::enable_if<std::is_integral<V>::value>::type,
63  class = typename std::enable_if<std::is_integral<A>::value>::type>
64 auto set_vmcs_field(V val, A addr, const char *name, bool exists)
65 {
66  if (!exists)
67  throw std::logic_error("set_vmcs_field failed: "_s + name + " field doesn't exist");
68 
70 }
71 
72 template <class V, class A,
73  class = typename std::enable_if<std::is_integral<V>::value>::type,
74  class = typename std::enable_if<std::is_integral<A>::value>::type>
75 auto set_vmcs_field_if_exists(V val, A addr, const char *name, bool verbose, bool exists) noexcept
76 {
77  if (exists)
79 
80  if (!exists && verbose)
81  bfwarning << "set_vmcs_field failed: " << name << " field doesn't exist" << bfendl;
82 }
83 
84 template <class MA, class CA, class M,
85  class = typename std::enable_if<std::is_integral<MA>::value>::type,
86  class = typename std::enable_if<std::is_integral<CA>::value>::type,
87  class = typename std::enable_if<std::is_integral<M>::value>::type>
88 auto set_vm_control(bool val, MA msr_addr, CA ctls_addr, const char *name, M mask, bool field_exists)
89 {
90  if (!field_exists)
91  throw std::logic_error("set_vm_control failed: "_s + name + " control doesn't exist");
92 
93  if (!val)
94  {
96 
97  if (!is_allowed0)
98  throw std::logic_error("set_vm_control failed: "_s + name + " control is not allowed to be cleared to 0");
99 
100  intel_x64::vm::write(ctls_addr, (intel_x64::vm::read(ctls_addr, name) & ~mask), name);
101  }
102  else
103  {
104  auto is_allowed1 = (intel_x64::msrs::get(msr_addr) & (mask << 32)) != 0;
105 
106  if (!is_allowed1)
107  throw std::logic_error("set_vm_control failed: "_s + name + " control is not allowed to be set to 1");
108 
109  intel_x64::vm::write(ctls_addr, (intel_x64::vm::read(ctls_addr, name) | mask), name);
110  }
111 }
112 
113 template <class MA, class CA, class M,
114  class = typename std::enable_if<std::is_integral<MA>::value>::type,
115  class = typename std::enable_if<std::is_integral<CA>::value>::type,
116  class = typename std::enable_if<std::is_integral<M>::value>::type>
117 auto set_vm_control_if_allowed(bool val, MA msr_addr, CA ctls_addr, const char *name,
118  M mask, bool verbose, bool field_exists) noexcept
119 {
120  if (!field_exists)
121  {
122  bfwarning << "set_vm_control_if_allowed failed: " << name << " control doesn't exist" << bfendl;
123  return;
124  }
125 
126  if (!val)
127  {
129 
130  if (is_allowed0)
131  {
132  intel_x64::vm::write(ctls_addr, (intel_x64::vm::read(ctls_addr, name) & ~mask), name);
133  }
134  else
135  {
136  if (verbose)
137  {
138  bfwarning << "set_vm_control_if_allowed failed: " << name
139  << "control is not allowed to be cleared to 0" << bfendl;
140  }
141  }
142  }
143  else
144  {
145  auto is_allowed1 = (intel_x64::msrs::get(msr_addr) & (mask << 32)) != 0;
146 
147  if (is_allowed1)
148  {
149  intel_x64::vm::write(ctls_addr, (intel_x64::vm::read(ctls_addr, name) | mask), name);
150  }
151  else
152  {
153  if (verbose)
154  {
155  bfwarning << "set_vm_control_if_allowed failed: " << name
156  << "control is not allowed to be set to 1" << bfendl;
157  }
158  }
159  }
160 }
161 
162 }
163 }
164 
165 // *INDENT-ON*
166 
167 #endif
auto set_vm_control_if_allowed(bool val, MA msr_addr, CA ctls_addr, const char *name, M mask, bool verbose, bool field_exists) noexcept
auto get_vmcs_field_if_exists(T addr, const char *name, bool verbose, bool exists)
constexpr const auto mask
Definition: cpuid_x64.h:85
auto set_vmcs_field_if_exists(V val, A addr, const char *name, bool verbose, bool exists) noexcept
void uint64_t uint64_t uint64_t *rdx noexcept
constexpr const auto addr
Definition: cpuid_x64.h:80
void write(field_type field, value_type value, name_type name="")
auto get(A addr) noexcept
auto set_vmcs_field(V val, A addr, const char *name, bool exists)
auto read(field_type field, name_type name="")
constexpr const auto name
Definition: cpuid_x64.h:81
auto get_vmcs_field(T addr, const char *name, bool exists)
auto set_vm_control(bool val, MA msr_addr, CA ctls_addr, const char *name, M mask, bool field_exists)