Skip to content
This repository was archived by the owner on Sep 1, 2024. It is now read-only.

Commit 14141db

Browse files
committed
2 parents fd48191 + a8881fa commit 14141db

File tree

4 files changed

+58
-35
lines changed

4 files changed

+58
-35
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ The diagram below illustrates the structure and flow of the Windows UEFI Blue Pi
9090

9191
- :x: Neither basic nor advanced techniques to evade hypervisor detection will be implemented in the public version of this hypervisor.
9292

93+
### Isolation and Security
94+
95+
- :white_check_mark: Custom implementations of the Global Descriptor Table (GDT), Interrupt Descriptor Table (IDT), and Page Tables to enhance the security and isolation of the hypervisor.
96+
9397
## Supported Hardware
9498

9599
- :white_check_mark: Intel processors with VT-x and Extended Page Tables (EPT) support.

hypervisor/src/global_const.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
///
33
/// This value is set to 1 for testing purposes but can be adjusted up to 64 or more based on the system.
44
/// Adjusting this value will increase the total heap size accordingly.
5-
const DEFAULT_LOGICAL_PROCESSORS: usize = 8;
5+
const DEFAULT_LOGICAL_PROCESSORS: usize = 16;
66

77
/// The number of pages for the stack per processor/core.
88
///

hypervisor/src/intel/descriptor.rs

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
//! Manages GDT and TSS for VMX virtualization contexts.
1+
//! Manages GDT, IDT, and TSS for VMX virtualization contexts.
22
//!
3-
//! Facilitates the creation and manipulation of the Global Descriptor Table (GDT) and
4-
//! Task State Segment (TSS) necessary for VMX operations. Supports both host and guest
5-
//! environments, ensuring compatibility and proper setup for virtualization.
3+
//! Facilitates the creation and manipulation of the Global Descriptor Table (GDT),
4+
//! Interrupt Descriptor Table (IDT), and Task State Segment (TSS) necessary for VMX operations.
5+
//! Supports both host and guest environments, ensuring compatibility and proper setup for virtualization.
66
//! Credits to Satoshi Tanda: https://github.com/tandasat/Hello-VT-rp/blob/main/hypervisor/src/intel_vt/descriptors.rs
77
88
use {
9-
crate::intel::support::sgdt,
9+
crate::intel::support::{sgdt, sidt},
1010
alloc::vec::Vec,
1111
x86::{
1212
dtables::DescriptorTablePointer,
@@ -16,18 +16,22 @@ use {
1616
},
1717
};
1818

19-
/// Manages GDT and TSS for VMX operations.
20-
///
21-
/// Supports creating a new GDT that includes TSS, addressing compatibility issues in UEFI environments
22-
/// and ensuring proper VM and hypervisor states. This struct is essential for setting up the environment
23-
/// for both host and guest VMX operations.
19+
/// Represents the descriptor tables (GDT and IDT) for the host and guest.
20+
/// Contains the GDT, IDT, TSS, and their respective register pointers.
21+
#[repr(C, align(4096))]
2422
pub struct Descriptors {
2523
/// Vector holding the GDT entries.
2624
pub gdt: Vec<u64>,
2725

2826
/// Descriptor table pointer to the GDT.
2927
pub gdtr: DescriptorTablePointer<u64>,
3028

29+
/// Vector holding the IDT entries.
30+
pub idt: Vec<u64>,
31+
32+
/// Descriptor table pointer to the IDT.
33+
pub idtr: DescriptorTablePointer<u64>,
34+
3135
/// Code segment selector.
3236
pub cs: SegmentSelector,
3337

@@ -46,16 +50,22 @@ impl Descriptors {
4650
///
4751
/// # Returns
4852
/// A `Descriptors` instance with an updated GDT including TSS.
49-
pub fn new_from_current() -> Self {
53+
pub fn initialize_for_guest() -> Self {
5054
log::debug!("Creating a new GDT with TSS for guest");
5155

5256
// Get the current GDT.
5357
let current_gdtr = sgdt();
5458
let current_gdt = unsafe { core::slice::from_raw_parts(current_gdtr.base.cast::<u64>(), usize::from(current_gdtr.limit + 1) / 8) };
5559

60+
// Get the current IDT.
61+
let current_idtr = sidt();
62+
let current_idt = unsafe { core::slice::from_raw_parts(current_idtr.base.cast::<u64>(), usize::from(current_idtr.limit + 1) / 8) };
63+
5664
let mut descriptors = Descriptors {
5765
gdt: current_gdt.to_vec(),
5866
gdtr: DescriptorTablePointer::<u64>::default(),
67+
idt: current_idt.to_vec(),
68+
idtr: DescriptorTablePointer::<u64>::default(),
5969
cs: SegmentSelector::from_raw(0),
6070
tr: SegmentSelector::from_raw(0),
6171
tss: TaskStateSegment::default(),
@@ -83,12 +93,14 @@ impl Descriptors {
8393
///
8494
/// # Returns
8595
/// A `Descriptors` instance with a newly created GDT for the host.
86-
pub fn new_for_host() -> Self {
96+
pub fn initialize_for_host() -> Self {
8797
log::debug!("Creating a new GDT with TSS for host");
8898

8999
let mut descriptors = Descriptors {
90100
gdt: Vec::new(),
91101
gdtr: DescriptorTablePointer::<u64>::default(),
102+
idt: Vec::new(),
103+
idtr: DescriptorTablePointer::<u64>::default(),
92104
cs: SegmentSelector::from_raw(0),
93105
tr: SegmentSelector::from_raw(0),
94106
tss: TaskStateSegment::default(),
@@ -103,7 +115,11 @@ impl Descriptors {
103115
descriptors.cs = SegmentSelector::new(1, x86::Ring::Ring0);
104116
descriptors.tr = SegmentSelector::new(2, x86::Ring::Ring0);
105117

106-
log::debug!("New GDT with TSS created for host successfully!");
118+
// Initialize the IDT with empty descriptors for the host
119+
descriptors.idt = Self::copy_current_idt();
120+
descriptors.idtr = DescriptorTablePointer::new_from_slice(&descriptors.idt);
121+
122+
log::debug!("New GDT with TSS and IDT created for host successfully!");
107123

108124
descriptors
109125
}
@@ -144,24 +160,29 @@ impl Descriptors {
144160
.finish()
145161
}
146162

147-
/// Converts a descriptor table pointer to a slice of GDT entries.
148-
///
149-
/// # Arguments
150-
///
151-
/// - `pointer`: A reference to the `DescriptorTablePointer` for the GDT.
152-
///
153-
/// # Returns
154-
///
155-
/// A slice of the GDT entries represented as `u64` values.
156-
pub fn from_pointer(pointer: &DescriptorTablePointer<u64>) -> &[u64] {
157-
unsafe { core::slice::from_raw_parts(pointer.base.cast::<u64>(), (pointer.limit + 1) as usize / size_of::<u64>()) }
163+
/// Copies the current IDT for the guest.
164+
fn copy_current_idt() -> Vec<u64> {
165+
log::trace!("Copying current IDT");
166+
167+
// Get the current IDTR
168+
let current_idtr = sidt();
169+
170+
// Create a slice from the current IDT entries.
171+
let current_idt = unsafe { core::slice::from_raw_parts(current_idtr.base.cast::<u64>(), usize::from(current_idtr.limit + 1) / 8) };
172+
173+
// Create a new IDT from the slice.
174+
let new_idt = current_idt.to_vec();
175+
176+
log::trace!("Copied current IDT");
177+
178+
new_idt
158179
}
159180
}
160181

161182
/// Represents the Task State Segment (TSS).
162183
///
163184
/// Encapsulates the TSS, which is critical for task-switching and storing state information
164-
/// in protected mode operations. Includes fields for the base address, limit, and access rights.:
185+
/// in protected mode operations. Includes fields for the base address, limit, and access rights.
165186
#[derive(derivative::Derivative)]
166187
#[derivative(Debug)]
167188
pub struct TaskStateSegment {
@@ -203,7 +224,5 @@ impl Default for TaskStateSegment {
203224
/// Low-level representation of the 64-bit Task State Segment (TSS).
204225
///
205226
/// Encapsulates the raw structure of the TSS as defined in the x86_64 architecture.
206-
/// This structure is used internally to manage the TSS's memory layout directly.
207-
/// See: Figure 8-11. 64-Bit TSS Format
208227
#[allow(dead_code)]
209228
struct TaskStateSegmentRaw([u8; 104]);

hypervisor/src/intel/vm.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ pub struct Vm {
3838
/// The VMCS (Virtual Machine Control Structure) for the VM.
3939
pub vmcs_region: Vmcs,
4040

41-
/// Descriptor tables for the host state.
42-
pub host_descriptor: Descriptors,
43-
4441
/// Descriptor tables for the guest state.
4542
pub guest_descriptor: Descriptors,
4643

44+
/// Descriptor tables for the host state.
45+
pub host_descriptor: Descriptors,
46+
4747
/// Paging tables for the host.
4848
pub host_paging: PageTables,
4949

@@ -95,11 +95,11 @@ impl Vm {
9595
trace!("Initializing VMCS region");
9696
self.vmcs_region.init();
9797

98-
trace!("Initializing Host Descriptor Tables");
99-
self.host_descriptor = Descriptors::new_for_host();
100-
10198
trace!("Initializing Guest Descriptor Tables");
102-
self.guest_descriptor = Descriptors::new_from_current();
99+
self.guest_descriptor = Descriptors::initialize_for_guest();
100+
101+
trace!("Initializing Host Descriptor Tables");
102+
self.host_descriptor = Descriptors::initialize_for_host();
103103

104104
trace!("Initializing Host Paging Tables");
105105
self.host_paging.init();

0 commit comments

Comments
 (0)