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

Commit 4216e4a

Browse files
committed
Bug was the new logger. (EPT is now per logical processor) TODO MULTI
1 parent d37c635 commit 4216e4a

File tree

13 files changed

+198
-322
lines changed

13 files changed

+198
-322
lines changed

driver/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ uefi-services = { version = "0.23.0", default-features = false } # https://crate
1111
log = { version = "0.4.20", default-features = false } # https://crates.io/crates/log
1212
once_cell = "1.19.0" # https://crates.io/crates/once_cell
1313
spin = "0.9" # https://crates.io/crates/spin
14+
com_logger = "0.1.1" # https://crates.io/crates/com_logger
15+
1416

1517
hypervisor = { path = "../hypervisor" }

driver/src/main.rs

+32-52
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,10 @@
66
extern crate alloc;
77

88
use {
9-
crate::{
10-
processor::MpManager,
11-
virtualize::{switch_stack_and_virtualize_core, Virtualize},
12-
},
13-
alloc::boxed::Box,
14-
core::ffi::c_void,
9+
crate::{processor::MpManager, virtualize::virtualize_system},
1510
hypervisor::{
16-
error::HypervisorError,
17-
intel::{
18-
capture::{capture_registers, GuestRegisters},
19-
ept::paging::{AccessType, Ept},
20-
shared_data::SharedData,
21-
},
11+
global::GlobalState,
12+
intel::capture::{capture_registers, GuestRegisters},
2213
logger::init_uart_logger,
2314
},
2415
log::*,
@@ -49,13 +40,23 @@ fn panic_handler(info: &core::panic::PanicInfo) -> ! {
4940

5041
#[entry]
5142
fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
52-
init_uart_logger();
43+
// Initialize the COM2 port logger with level filter set to Info.
44+
// init_uart_logger();
45+
46+
com_logger::builder()
47+
.base(0x2f8)
48+
.filter(LevelFilter::Trace)
49+
.setup();
50+
5351
uefi_services::init(&mut system_table).unwrap();
5452

5553
info!("The Matrix is an illusion");
5654

57-
let mp_manager =
58-
MpManager::new(system_table.boot_services()).expect("Failed to create MpManager");
55+
// Get the MP Services (MultiProcessor Services) Protocol
56+
let mp_manager = match MpManager::new(system_table.boot_services()) {
57+
Ok(mp_manager) => mp_manager,
58+
Err(e) => panic!("Failed to get MP Services: {:?}", e),
59+
};
5960

6061
// Get the processor count
6162
let processor_count = match mp_manager.processor_count() {
@@ -66,40 +67,34 @@ fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
6667
info!("Total processors: {}", processor_count.total);
6768
info!("Enabled processors: {}", processor_count.enabled);
6869

69-
// Setup EPT
70-
let shared_data = match setup_ept() {
71-
Ok(shared_data) => shared_data,
72-
Err(e) => panic!("Failed to setup EPT: {:?}", e),
73-
};
74-
7570
// Capture the register values to be used as an initial state of the VM.
7671
let mut guest_registers = GuestRegisters::default();
7772
unsafe { capture_registers(&mut guest_registers) }
7873

7974
// Since we captured RIP just above, the VM will start running from here.
80-
// Check if our hypervisor is already loaded. If so, done, otherwise, continue
81-
// installing the hypervisor.
75+
// Check if our hypervisor is already loaded. If so, done, otherwise, continue installing the hypervisor.
8276
if !mp_manager.is_virtualized() {
8377
debug!("Virtualizing the system");
84-
85-
let mut virtualize = Virtualize::new(guest_registers, shared_data, &system_table);
86-
87-
debug!("Virtualizing each core");
8878
mp_manager.set_virtualized();
8979

80+
let mut global_state = GlobalState::new(guest_registers);
81+
9082
if processor_count.enabled == 1 {
9183
info!("Found only one processor, virtualizing it");
92-
switch_stack_and_virtualize_core(&mut virtualize as *mut _ as *mut c_void);
93-
} else {
94-
info!("Found multiple processors, virtualizing all of them");
95-
match mp_manager.start_virtualization_on_all_processors(
96-
switch_stack_and_virtualize_core,
97-
&mut virtualize as *mut _ as *mut c_void,
98-
) {
99-
Ok(_) => debug!("Virtualization started on all processors"),
100-
Err(e) => panic!("Failed to start virtualization on all processors: {:?}", e),
101-
}
84+
virtualize_system(&mut global_state, &system_table);
10285
}
86+
/*
87+
else {
88+
info!("Found multiple processors, virtualizing all of them");
89+
match mp_manager.start_virtualization_on_all_processors(
90+
switch_stack_and_virtualize_core,
91+
&mut global_state as *mut _ as *mut c_void,
92+
) {
93+
Ok(_) => debug!("Virtualization started on all processors"),
94+
Err(e) => panic!("Failed to start virtualization on all processors: {:?}", e),
95+
}
96+
}
97+
*/
10398
}
10499

105100
info!("The hypervisor has been installed successfully!");
@@ -108,18 +103,3 @@ fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
108103

109104
Status::SUCCESS
110105
}
111-
112-
pub fn setup_ept() -> Result<Box<SharedData>, HypervisorError> {
113-
let mut primary_ept: Box<Ept> = unsafe { Box::new_zeroed().assume_init() };
114-
let mut secondary_ept: Box<Ept> = unsafe { Box::new_zeroed().assume_init() };
115-
116-
debug!("Creating Primary EPT");
117-
primary_ept.identity_2mb(AccessType::READ_WRITE_EXECUTE)?;
118-
119-
debug!("Creating Secondary EPT");
120-
secondary_ept.identity_2mb(AccessType::READ_WRITE_EXECUTE)?;
121-
122-
let shared_data = SharedData::new(primary_ept, secondary_ept);
123-
124-
shared_data
125-
}

driver/src/virtualize.rs

+36-86
Original file line numberDiff line numberDiff line change
@@ -1,123 +1,73 @@
11
use {
22
alloc::alloc::{alloc_zeroed, handle_alloc_error},
3-
alloc::boxed::Box,
4-
core::ffi::c_void,
53
core::{alloc::Layout, arch::global_asm},
6-
hypervisor::{
7-
intel::{capture::GuestRegisters, page::Page, shared_data::SharedData},
8-
vmm::start_hypervisor,
9-
},
4+
hypervisor::{global::GlobalState, intel::page::Page, vmm::start_hypervisor},
105
log::debug,
116
uefi::{
127
proto::loaded_image::LoadedImage,
138
table::{Boot, SystemTable},
149
},
1510
};
1611

17-
pub struct Virtualize {
18-
guest_registers: GuestRegisters,
19-
shared_data: Box<SharedData>,
20-
landing_code: usize,
21-
stack_base: u64,
22-
}
23-
24-
impl Virtualize {
25-
pub fn new(
26-
guest_registers: GuestRegisters,
27-
shared_data: Box<SharedData>,
28-
system_table: &SystemTable<Boot>,
29-
) -> Self {
30-
debug!("Zapping the Relocation Table and allocating separate stack space");
31-
32-
let boot_service = system_table.boot_services();
33-
34-
// Open the loaded image protocol to get the current image base and image size.
35-
let loaded_image = boot_service
36-
.open_protocol_exclusive::<LoadedImage>(boot_service.image_handle())
37-
.unwrap();
38-
39-
// Get the current image base and image size.
40-
let (image_base, image_size) = loaded_image.info();
41-
42-
let image_base = image_base as usize;
12+
pub fn virtualize_system(global_state: &mut GlobalState, system_table: &SystemTable<Boot>) -> ! {
13+
let boot_service = system_table.boot_services();
4314

44-
let image_range = image_base..image_base + image_size as usize;
45-
debug!("Image base: {:#x?}", image_range);
15+
// Open the loaded image protocol to get the current image base and image size.
16+
let loaded_image = boot_service
17+
.open_protocol_exclusive::<LoadedImage>(boot_service.image_handle())
18+
.unwrap();
4619

47-
// Prevent relocation by zapping the Relocation Table in the PE header. UEFI
48-
// keeps the list of runtime drivers and applies patches into their code and
49-
// data according to relocation information, as address translation switches
50-
// from physical-mode to virtual-mode when the OS starts. This causes a problem
51-
// with us because the host part keeps running under physical-mode, as the
52-
// host has its own page tables. Relocation ends up breaking the host code.
53-
// The easiest way is prevented this from happening is to nullify the relocation
54-
// table.
55-
unsafe {
56-
*((image_base + 0x128) as *mut u32) = 0;
57-
*((image_base + 0x12c) as *mut u32) = 0;
58-
}
20+
// Get the current image base and image size.
21+
let (image_base, image_size) = loaded_image.info();
5922

60-
// Allocate separate stack space. This is never freed.
61-
let layout = Layout::array::<Page>(0x10).unwrap();
23+
let image_base = image_base as usize;
6224

63-
let stack = unsafe { alloc_zeroed(layout) };
25+
let image_range = image_base..image_base + image_size as usize;
26+
debug!("Image base: {:#x?}", image_range);
6427

65-
if stack.is_null() {
66-
handle_alloc_error(layout);
67-
}
28+
// Prevent relocation by zapping the Relocation Table in the PE header. UEFI
29+
// keeps the list of runtime drivers and applies patches into their code and
30+
// data according to relocation information, as address translation switches
31+
// from physical-mode to virtual-mode when the OS starts. This causes a problem
32+
// with us because the host part keeps running under physical-mode, as the
33+
// host has its own page tables. Relocation ends up breaking the host code.
34+
// The easiest way is prevented this from happening is to nullify the relocation
35+
// table.
36+
unsafe {
37+
*((image_base + 0x128) as *mut u32) = 0;
38+
*((image_base + 0x12c) as *mut u32) = 0;
39+
}
6840

69-
let stack_base = stack as u64 + layout.size() as u64 - 0x10;
70-
debug!("Stack range: {:#x?}", stack_base..stack as u64);
41+
// Allocate separate stack space. This is never freed.
42+
let layout = Layout::array::<Page>(0x10).unwrap();
7143

72-
debug!("Relocation Table zapped and separate stack space allocated successfully!");
44+
let stack = unsafe { alloc_zeroed(layout) };
7345

74-
Self {
75-
guest_registers,
76-
shared_data,
77-
landing_code: start_hypervisor as usize,
78-
stack_base,
79-
}
46+
if stack.is_null() {
47+
handle_alloc_error(layout);
8048
}
81-
}
82-
83-
pub extern "efiapi" fn switch_stack_and_virtualize_core(procedure_argument: *mut c_void) {
84-
let virtualize: &mut Virtualize = unsafe { &mut *(procedure_argument as *mut Virtualize) };
8549

86-
debug!("Switching stack and virtualizing core");
50+
let stack_base = stack as u64 + layout.size() as u64 - 0x10;
51+
debug!("Stack range: {:#x?}", stack_base..stack as u64);
8752

88-
// Call `switch_stack` with the context data.
89-
// Assuming `switch_stack` never returns, similar to the original `virtualize_system` behavior.
90-
unsafe {
91-
switch_stack(
92-
&virtualize.guest_registers,
93-
&mut virtualize.shared_data,
94-
virtualize.landing_code,
95-
virtualize.stack_base,
96-
);
97-
}
53+
unsafe { switch_stack(global_state, start_hypervisor as usize, stack_base) };
9854
}
9955

10056
extern "efiapi" {
10157
/// Jumps to the landing code with the new stack pointer.
102-
fn switch_stack(
103-
guest_registers: &GuestRegisters,
104-
shared_data: &mut SharedData,
105-
landing_code: usize,
106-
stack_base: u64,
107-
) -> !;
58+
fn switch_stack(global_state: &mut GlobalState, landing_code: usize, stack_base: u64) -> !;
10859
}
10960

11061
global_asm!(
11162
r#"
11263
// The module containing the `switch_stack` function.
113-
11464
// Jumps to the landing code with the new stack pointer.
11565
//
116-
// fn switch_stack(guest_registers: &GuestRegisters, shared_data: &mut SharedData, landing_code: usize, stack_base: u64) -> !
66+
// fn switch_stack(global_state: &mut GlobalState, landing_code: usize, stack_base: u64) -> !
11767
.global switch_stack
11868
switch_stack:
11969
xchg bx, bx
120-
mov rsp, r9
121-
jmp r8
70+
mov rsp, r8
71+
jmp rdx
12272
"#
12373
);

hypervisor/src/config.rs

-28
This file was deleted.

hypervisor/src/global.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
use crate::intel::capture::GuestRegisters;
2+
3+
pub struct GlobalState {
4+
pub guest_registers: GuestRegisters,
5+
}
6+
7+
impl GlobalState {
8+
pub fn new(guest_registers: GuestRegisters) -> Self {
9+
Self { guest_registers }
10+
}
11+
}

hypervisor/src/intel/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ pub mod invvpid;
99
pub mod page;
1010
pub mod paging;
1111
pub mod segmentation;
12-
pub mod shared_data;
1312
pub mod support;
1413
pub mod vm;
1514
pub mod vmcs;

0 commit comments

Comments
 (0)