1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
//! A crate for managing hypervisor functionality, particularly focused on
//! Extended Page Tables (EPT) and Model-Specific Register (MSR) bitmaps.
//! Includes support for primary and optional secondary EPTs.
use {
crate::{ept::paging::Ept, error::HypervisorError, x86_64::addr::Addrtransfer}, alloc::boxed::Box
};
/// Represents shared data structures for hypervisor operations.
///
/// This struct manages the MSR (Model-Specific Register) bitmap and Extended Page Tables (EPT)
/// for the hypervisor, enabling memory virtualization and control over certain processor features.
#[repr(C)]
#[derive(Debug, Clone)]
pub struct SharedData<P: core::alloc::Allocator> {
/// A bitmap for handling MSRs.
pub msr_bitmap: Box<MsrBitmap, P>,
/// The primary Extended Page Table.
pub primary_ept: Box<Ept, P>,
/// The pointer to the primary EPT (Extended Page Table Pointer).
pub primary_eptp: u64,
/// The secondary Extended Page Table.
#[cfg(feature = "secondary-ept")]
pub secondary_ept: Box<Ept, P>,
/// The pointer to the secondary EPT.
#[cfg(feature = "secondary-ept")]
pub secondary_eptp: u64,
// The hook manager.
//pub hook_manager: Box<HookManager>,
}
impl<PYH> SharedData<PYH>
where PYH: core::alloc::Allocator,
{
/// Creates a new instance of `SharedData` with primary and optionally secondary EPTs.
///
/// This function initializes the MSR bitmap and sets up the EPTs.
///
/// # Arguments
///
/// * `primary_ept`: The primary EPT to be used.
/// * `secondary_ept`: The secondary EPT to be used if the feature is enabled.
///
/// # Returns
/// A result containing a boxed `SharedData` instance or an error of type `HypervisorError`.
#[cfg(feature = "secondary-ept")]
pub fn new<T: Addrtransfer>(
primary_ept: Box<Ept, PYH>,
secondary_ept: Box<Ept, PYH>,
msr_bitmap:Box<MsrBitmap,PYH>,
trans: &mut T
) -> Result<Box<Self>, HypervisorError> {
log::trace!("Initializing shared data");
let primary_eptp = primary_ept.create_eptp_with_wb_and_4lvl_walk(trans)?;
let secondary_eptp = secondary_ept.create_eptp_with_wb_and_4lvl_walk(trans)?;
//let bitmap = MsrBitmap::new();
//bitmap.hook_msr(IA32_EFER);
Ok(Box::new(Self {
msr_bitmap,
primary_ept,
primary_eptp,
secondary_ept,
secondary_eptp,
}))
}
/// Creates a new instance of `SharedData` with primary EPTs.
///
/// This function initializes the MSR bitmap and sets up the EPTs.
///
/// # Arguments
///
/// * `primary_ept`: The primary EPT to be used.
///
/// # Returns
/// A result containing a boxed `SharedData` instance or an error of type `HypervisorError`.
#[cfg(not(feature = "secondary-ept"))]
pub fn new(
primary_ept: Box<Ept, PYH>,
// hook_manager: Box<HookManager>,
) -> Result<Box<Self>, HypervisorError> {
log::info!("Initializing shared data");
let primary_eptp = primary_ept.create_eptp_with_wb_and_4lvl_walk()?;
let bitmap = MsrBitmap::new();
//bitmap.hook_msr(IA32_EFER);
Ok(Box::new(Self {
msr_bitmap: bitmap,
primary_ept,
primary_eptp,
// hook_manager,
}))
}
}
#[repr(C, align(4096))]
#[derive(Debug,Clone,Copy)]
pub struct MsrBitmap {
/// Read bitmap for low MSRs. Contains one bit for each MSR address in the range 00000000H to 00001FFFH.
/// Determines whether an execution of RDMSR applied to that MSR causes a VM exit.
pub read_low_msrs: [u8; 0x400],
/// Read bitmap for high MSRs. Contains one bit for each MSR address in the range C0000000H to C0001FFFH.
/// Determines whether an execution of RDMSR applied to that MSR causes a VM exit.
pub read_high_msrs: [u8; 0x400],
/// Write bitmap for low MSRs. Contains one bit for each MSR address in the range 00000000H to 00001FFFH.
/// Determines whether an execution of WRMSR applied to that MSR causes a VM exit.
pub write_low_msrs: [u8; 0x400],
/// Write bitmap for high MSRs. Contains one bit for each MSR address in the range C0000000H to C0001FFFH.
/// Determines whether an execution of WRMSR applied to that MSR causes a VM exit.
pub write_high_msrs: [u8; 0x400],
}
impl MsrBitmap {
/// Sets up the MSR Bitmap.
///
/// # Returns
/// * A `Result` indicating the success or failure of the setup process.
pub fn new<PYH: core::alloc::Allocator>(mut _instance: Box<MsrBitmap,PYH>) -> Box<MsrBitmap, PYH> {
//log::info!("Setting up MSR Bitmap");
// let instance = Self {
// read_low_msrs: [0; 0x400],
// read_high_msrs: [0; 0x400],
// write_low_msrs: [0; 0x400],
// write_high_msrs: [0; 0x400],
// };
//log::info!("newed MSR Bitmap");
// let mut instance = unsafe { Box::<Self, PYH>::try_new_zeroed_in::<PYH>(PYH).unwrap().assume_init() };
//log::info!("Initializing MSR Bitmap");
//Self::initialize_bitmap(instance.as_mut() as *mut _ as _);
log::trace!("MSR Bitmap setup successfully!");
_instance
}
// /// Initializes the MSR Bitmap.
// ///
// /// # Arguments
// /// * `bitmap_ptr` - The virtual address of the MSR Bitmap.
// fn initialize_bitmap(bitmap_ptr: *mut u64) {
// let mut bitmap_header: MaybeUninit<RTL_BITMAP> = MaybeUninit::uninit();
// let bitmap_header_ptr = bitmap_header.as_mut_ptr() as *mut _;
// unsafe {
// RtlInitializeBitMap(
// bitmap_header_ptr as _,
// bitmap_ptr as _,
// core::mem::size_of::<Self>() as u32,
// )
// }
// unsafe { RtlClearAllBits(bitmap_header_ptr as _) }
// }
}
pub trait GetEPTP {
fn get_data_eptp1(&self) -> u64 {
0
}
fn get_data_eptp2(&self) -> u64 {
0
}
}