vmx_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 VMX_INTEL_X64_H
23 #define VMX_INTEL_X64_H
24 
25 #include <gsl/gsl>
26 #include <debug.h>
27 
28 extern "C" bool __vmxon(void *ptr) noexcept;
29 extern "C" bool __vmxoff(void) noexcept;
30 extern "C" bool __vmclear(void *ptr) noexcept;
31 extern "C" bool __vmptrld(void *ptr) noexcept;
32 extern "C" bool __vmptrst(void *ptr) noexcept;
33 extern "C" bool __vmread(uint64_t field, uint64_t *val) noexcept;
34 extern "C" bool __vmwrite(uint64_t field, uint64_t val) noexcept;
35 extern "C" bool __vmlaunch_demote(void) noexcept;
36 extern "C" bool __invept(uint64_t type, void *ptr) noexcept;
37 extern "C" bool __invvpid(uint64_t type, void *ptr) noexcept;
38 
39 // *INDENT-OFF*
40 
41 namespace intel_x64
42 {
43 namespace vmx
44 {
45  using vpid_type = uint64_t;
46  using eptp_type = uint64_t;
47  using integer_pointer = uintptr_t;
48 
49  inline void on(gsl::not_null<void *> ptr)
50  {
51  if (!__vmxon(ptr))
52  throw std::runtime_error("vmx::on failed");
53  }
54 
55  inline void off()
56  {
57  if (!__vmxoff())
58  throw std::runtime_error("vmx::off failed");
59  }
60 
61  inline void invept_single_context(eptp_type eptp)
62  {
63  uint64_t descriptor[2] = { eptp, 0 };
64  if (!__invept(1, static_cast<void *>(descriptor)))
65  throw std::runtime_error("vm::invept_singal_context failed");
66  }
67 
68  inline void invept_global()
69  {
70  uint64_t descriptor[2] = { 0, 0 };
71  if (!__invept(2, static_cast<void *>(descriptor)))
72  throw std::runtime_error("vm::invept_global failed");
73  }
74 
76  {
77  uint64_t descriptor[2] = { vpid, addr };
78  if (!__invvpid(0, static_cast<void *>(descriptor)))
79  throw std::runtime_error("vm::invvpid_individual_address failed");
80  }
81 
83  {
84  uint64_t descriptor[2] = { vpid, 0 };
85  if (!__invvpid(1, static_cast<void *>(descriptor)))
86  throw std::runtime_error("vm::invvpid_single_context failed");
87  }
88 
89  inline void invvpid_all_contexts()
90  {
91  uint64_t descriptor[2] = { 0, 0 };
92  if (!__invvpid(2, static_cast<void *>(descriptor)))
93  throw std::runtime_error("vm::invvpid_all_contexts failed");
94  }
95 
97  {
98  uint64_t descriptor[2] = { vpid, 0 };
99  if (!__invvpid(3, static_cast<void *>(descriptor)))
100  throw std::runtime_error("vm::invvpid_single_context_global failed");
101  }
102 }
103 
104 namespace vm
105 {
106  using field_type = uint64_t;
107  using value_type = uint64_t;
108  using name_type = const char *;
109  using integer_pointer = uintptr_t;
110 
111  inline void clear(gsl::not_null<void *> ptr)
112  {
113  if (!__vmclear(ptr))
114  throw std::runtime_error("vm::clear failed");
115  }
116 
117  inline void load(gsl::not_null<void *> ptr)
118  {
119  if (!__vmptrld(ptr))
120  throw std::runtime_error("vm::load failed");
121  }
122 
123  inline void reset(gsl::not_null<void *> ptr)
124  {
125  if (!__vmptrst(ptr))
126  throw std::runtime_error("vm::reset failed");
127  }
128 
129  inline auto read(field_type field, name_type name = "")
130  {
131  value_type value;
132 
133  if (!__vmread(field, &value))
134  {
135  bferror << "vm::read failed:" << bfendl;
136  bferror << " - field: " << name << bfendl;
137 
138  throw std::runtime_error("vm::read failed");
139  }
140 
141  return value;
142  }
143 
144  inline void write(field_type field, value_type value, name_type name = "")
145  {
146  if (!__vmwrite(field, value))
147  {
148  bferror << "vm::write failed:" << bfendl;
149  bferror << " - field: " << name << bfendl;
150  bferror << " - value: " << view_as_pointer(value) << bfendl;
151 
152  throw std::runtime_error("vm::write failed");
153  }
154  }
155 
156  inline void launch_demote()
157  {
158  if (!__vmlaunch_demote())
159  throw std::runtime_error("vm::launch_demote failed");
160  }
161 }
162 }
163 
164 // *INDENT-ON*
165 
166 #endif
void load(gsl::not_null< void *> ptr)
void invvpid_all_contexts()
Definition: vmx_intel_x64.h:89
bool __invvpid(uint64_t type, void *ptr) noexcept
bool __vmwrite(uint64_t field, uint64_t val) noexcept
uint64_t vpid_type
Definition: vmx_intel_x64.h:45
bool __vmptrld(void *ptr) noexcept
void reset(gsl::not_null< void *> ptr)
void clear(gsl::not_null< void *> ptr)
uint64_t value_type
bool __vmxoff(void) noexcept
void uint64_t uint64_t uint64_t *rdx noexcept
constexpr const auto addr
Definition: cpuid_x64.h:80
bool __invept(uint64_t type, void *ptr) noexcept
bool __vmlaunch_demote(void) noexcept
const char * name_type
bool __vmptrst(void *ptr) noexcept
void invvpid_single_context_global(vpid_type vpid)
Definition: vmx_intel_x64.h:96
void write(field_type field, value_type value, name_type name="")
uintptr_t integer_pointer
Definition: vmx_intel_x64.h:47
const void * view_as_pointer(const T val)
void launch_demote()
auto read(field_type field, name_type name="")
constexpr const auto name
Definition: cpuid_x64.h:81
void invvpid_individual_address(vpid_type vpid, integer_pointer addr)
Definition: vmx_intel_x64.h:75
void invept_global()
Definition: vmx_intel_x64.h:68
bool __vmread(uint64_t field, uint64_t *val) noexcept
void on(gsl::not_null< void *> ptr)
Definition: vmx_intel_x64.h:49
uintptr_t integer_pointer
bool __vmclear(void *ptr) noexcept
void invept_single_context(eptp_type eptp)
Definition: vmx_intel_x64.h:61
uint64_t field_type
uint64_t eptp_type
Definition: vmx_intel_x64.h:46
bool __vmxon(void *ptr) noexcept
void invvpid_single_context(vpid_type vpid)
Definition: vmx_intel_x64.h:82