idt_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 IDT_X64_H
23 #define IDT_X64_H
24 
25 #include <gsl/gsl>
26 
27 #include <vector>
28 #include <algorithm>
29 #include <exception>
30 
31 #include <guard_exceptions.h>
32 
33 // -----------------------------------------------------------------------------
34 // Interrupt Descriptor Table Register
35 // -----------------------------------------------------------------------------
36 
37 #pragma pack(push, 1)
38 
40 {
41  using limit_type = uint16_t;
42  using base_type = uint64_t *;
43 
46 
48  limit(0),
49  base(nullptr)
50  {}
51 
53  limit(l),
54  base(b)
55  {}
56 };
57 
58 #pragma pack(pop)
59 
60 // -----------------------------------------------------------------------------
61 // Intrinsics
62 // -----------------------------------------------------------------------------
63 
64 extern "C" void __read_idt(idt_reg_x64_t *idt_reg) noexcept;
65 extern "C" void __write_idt(idt_reg_x64_t *idt_reg) noexcept;
66 
67 // -----------------------------------------------------------------------------
68 // IDT Functions
69 // -----------------------------------------------------------------------------
70 
71 // *INDENT-OFF*
72 
73 namespace x64
74 {
75 namespace idt
76 {
77  inline auto get() noexcept
78  {
79  auto &&reg = idt_reg_x64_t{};
80  __read_idt(&reg);
81 
82  return reg;
83  }
84 
86  {
87  auto &&reg = idt_reg_x64_t{base, limit};
88  __write_idt(&reg);
89  }
90 
91  namespace base
92  {
93  inline auto get() noexcept
94  {
95  auto &&reg = idt_reg_x64_t{};
96  __read_idt(&reg);
97 
98  return reg.base;
99  }
100 
101  inline void set(idt_reg_x64_t::base_type base) noexcept
102  {
103  auto &&reg = idt_reg_x64_t{};
104  __read_idt(&reg);
105 
106  reg.base = base;
107  __write_idt(&reg);
108  }
109  }
110 
111  namespace limit
112  {
113  inline auto get() noexcept
114  {
115  auto &&reg = idt_reg_x64_t{};
116  __read_idt(&reg);
117 
118  return reg.limit;
119  }
120 
121  inline void set(idt_reg_x64_t::limit_type limit) noexcept
122  {
123  auto &&reg = idt_reg_x64_t{};
124  __read_idt(&reg);
125 
126  reg.limit = limit;
127  __write_idt(&reg);
128  }
129  }
130 }
131 }
132 // *INDENT-ON*
133 
134 // -----------------------------------------------------------------------------
135 // Interrupt Descriptor Table
136 // -----------------------------------------------------------------------------
137 
154 class idt_x64
155 {
156 public:
157 
158  using size_type = uint16_t;
159  using integer_pointer = uintptr_t;
160  using interrupt_descriptor_type = uint64_t;
161 
170  {
171  guard_exceptions([&]
172  {
173  m_idt_reg.base = x64::idt::base::get();
174  m_idt_reg.limit = x64::idt::limit::get();
175  });
176  }
177 
189  m_idt(size)
190  {
191  guard_exceptions([&]
192  {
193  m_idt_reg.base = m_idt.data();
194  m_idt_reg.limit = gsl::narrow_cast<size_type>((size << 3) - 1);
195  });
196  }
197 
203  ~idt_x64() = default;
204 
212  auto base() const
213  { return reinterpret_cast<integer_pointer>(m_idt_reg.base); }
214 
222  auto limit() const
223  { return m_idt_reg.limit; }
224 
225 private:
226 
227  friend class intrinsics_ut;
228 
229  idt_reg_x64_t m_idt_reg;
230  std::vector<interrupt_descriptor_type> m_idt;
231 };
232 
233 #endif
uint16_t limit_type
Definition: idt_x64.h:41
auto get() noexcept
Definition: idt_x64.h:93
auto base() const
Definition: idt_x64.h:212
uint64_t interrupt_descriptor_type
Definition: idt_x64.h:160
uint64_t * base_type
Definition: idt_x64.h:42
void __read_idt(idt_reg_x64_t *idt_reg) noexcept
auto get() noexcept
Definition: idt_x64.h:113
constexpr const auto size
base_type base
Definition: idt_x64.h:45
void uint64_t uint64_t uint64_t *rdx noexcept
uintptr_t integer_pointer
Definition: idt_x64.h:159
idt_x64(size_type size) noexcept
Definition: idt_x64.h:188
void __write_idt(idt_reg_x64_t *idt_reg) noexcept
limit_type limit
Definition: idt_x64.h:44
uint16_t size_type
Definition: idt_x64.h:158
idt_x64() noexcept
Definition: idt_x64.h:169
idt_reg_x64_t(base_type b, limit_type l) noexcept
Definition: idt_x64.h:52
E guard_exceptions(E error_code, T func)
~idt_x64()=default
idt_reg_x64_t() noexcept
Definition: idt_x64.h:47
Definition: cache_x64.h:31
auto limit() const
Definition: idt_x64.h:222