vmxon_intel_x64.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 //
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 #include <gsl/gsl>
23 
24 #include <debug.h>
25 #include <vmxon/vmxon_intel_x64.h>
27 
28 #include <intrinsics/x64.h>
29 #include <intrinsics/cpuid_x64.h>
30 #include <intrinsics/rflags_x64.h>
34 
35 using namespace x64;
36 using namespace intel_x64;
37 
39  m_vmxon_enabled(false),
40  m_vmxon_region_phys(0)
41 { }
42 
43 void
45 {
46  if (cr4::vmx_enable_bit::get())
47  throw std::logic_error("vmxon already enabled");
48 
53  this->check_v8086_disabled();
54 
55  this->create_vmxon_region();
56 
57  auto ___ = gsl::on_failure([&]
58  { this->release_vmxon_region(); });
59 
61 
62  auto ___ = gsl::on_failure([&]
63  { cr4::vmx_enable_bit::set(false); });
64 
65  if (!cr4::vmx_enable_bit::get())
66  throw std::logic_error("failed to enable VMXON");
67 
69  this->execute_vmxon();
70 }
71 
72 void
74 {
75  this->execute_vmxoff();
77 
78  if (cr4::vmx_enable_bit::get())
79  throw std::logic_error("failed to disable VMXON");
80 
81  this->release_vmxon_region();
82 }
83 
84 void
86 {
87  if (!cpuid::feature_information::ecx::vmx::get())
88  throw std::logic_error("VMX extensions not supported");
89 }
90 
91 void
93 {
94  if (msrs::ia32_vmx_basic::physical_address_width::get())
95  throw std::logic_error("invalid physical address width");
96 
97  if (msrs::ia32_vmx_basic::memory_type::get() != x64::memory_type::write_back)
98  throw std::logic_error("invalid memory type");
99 
100  if (!msrs::ia32_vmx_basic::true_based_controls::get())
101  throw std::logic_error("invalid vmx true based controls");
102 }
103 
104 void
106 {
107  auto cr0 = cr0::get();
108  auto ia32_vmx_cr0_fixed0 = msrs::ia32_vmx_cr0_fixed0::get();
109  auto ia32_vmx_cr0_fixed1 = msrs::ia32_vmx_cr0_fixed1::get();
110 
111  if (0 != ((~cr0 & ia32_vmx_cr0_fixed0) | (cr0 & ~ia32_vmx_cr0_fixed1)))
112  throw std::logic_error("invalid cr0");
113 }
114 
115 void
117 {
118  auto cr4 = cr4::get();
119  auto ia32_vmx_cr4_fixed0 = msrs::ia32_vmx_cr4_fixed0::get();
120  auto ia32_vmx_cr4_fixed1 = msrs::ia32_vmx_cr4_fixed1::get();
121 
122  if (0 != ((~cr4 & ia32_vmx_cr4_fixed0) | (cr4 & ~ia32_vmx_cr4_fixed1)))
123  throw std::logic_error("invalid cr4");
124 }
125 
126 void
128 {
129  if (msrs::ia32_feature_control::lock_bit::get())
130  return;
131 
134 }
135 
136 void
138 {
139  if (rflags::virtual_8086_mode::get())
140  throw std::logic_error("v8086 mode is not supported");
141 }
142 
143 void
145 {
146  auto ___ = gsl::on_failure([&]
147  { this->release_vmxon_region(); });
148 
149  m_vmxon_region = std::make_unique<uint32_t[]>(1024);
150  m_vmxon_region_phys = g_mm->virtptr_to_physint(m_vmxon_region.get());
151 
152  gsl::span<uint32_t> id{m_vmxon_region.get(), 1024};
153  id[0] = gsl::narrow<uint32_t>(msrs::ia32_vmx_basic::revision_id::get());
154 }
155 
156 void
158 {
159  m_vmxon_region.reset();
160  m_vmxon_region_phys = 0;
161 }
162 
163 void
165 {
166  auto ___ = gsl::on_success([&]
167  { m_vmxon_enabled = true; });
168 
169  if (m_vmxon_enabled)
170  throw std::logic_error("vmxon has already been executed");
171 
172  vmx::on(&m_vmxon_region_phys);
173 }
174 
175 void
177 {
178  auto ___ = gsl::on_success([&]
179  { m_vmxon_enabled = false; });
180 
181  if (!m_vmxon_enabled)
182  {
183  bfwarning << "execute_vmxoff: VMX operation already disabled" << bfendl;
184  return;
185  }
186 
187  vmx::off();
188 }
void check_ia32_vmx_cr0_fixed_msr()
void check_vmx_capabilities_msr()
void check_ia32_vmx_cr4_fixed_msr()
void uint64_t uint64_t uint64_t *rdx noexcept
void check_ia32_feature_control_msr()
constexpr const auto write_back
Definition: x64.h:46
void check_cpuid_vmx_supported()
virtual void start()
virtual void stop()
#define g_mm
void on(gsl::not_null< void *> ptr)
Definition: vmx_intel_x64.h:49
void release_vmxon_region() noexcept
void set(T val) noexcept
Definition: crs_intel_x64.h:52
Definition: cache_x64.h:31