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

Commit

Permalink
COM logger removed due to Sync issues and custom panic handler added
Browse files Browse the repository at this point in the history
  • Loading branch information
memN0ps committed Feb 18, 2024
1 parent 8077d3e commit da39986
Show file tree
Hide file tree
Showing 7 changed files with 158 additions and 18 deletions.
3 changes: 1 addition & 2 deletions driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ edition = "2021"

[dependencies]
uefi = {version = "0.26.0", features = ["global_allocator", "alloc"] } # https://crates.io/crates/uefi
uefi-services = { version = "0.23.0", default-features = false, features = ["panic_handler"] }
uefi-services = { version = "0.23.0", default-features = false } # https://crates.io/crates/uefi-services
log = { version = "0.4.20", default-features = false } # https://crates.io/crates/log
com_logger = "0.1.1" # https://crates.io/crates/com_logger
once_cell = "1.19.0" # https://crates.io/crates/once_cell

hypervisor = { path = "../hypervisor" }
30 changes: 23 additions & 7 deletions driver/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![feature(new_uninit)]
#![feature(panic_info_message)]
#![no_main]
#![no_std]

Expand All @@ -18,6 +19,7 @@ use {
ept::paging::{AccessType, Ept},
shared_data::SharedData,
},
logger::init_uart_logger,
},
log::*,
uefi::prelude::*,
Expand All @@ -26,14 +28,28 @@ use {
pub mod processor;
pub mod virtualize;

// Change as you like
#[cfg(not(test))]
#[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! {
if let Some(location) = info.location() {
error!(
"[-] Panic in {} at ({}, {}):",
location.file(),
location.line(),
location.column()
);
if let Some(message) = info.message() {
error!("[-] {}", message);
}
}

loop {}
}

#[entry]
fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
// Initialize the COM2 port logger with level filter set to Info.
com_logger::builder()
.base(0x2f8)
.filter(LevelFilter::Trace)
.setup();

init_uart_logger();
uefi_services::init(&mut system_table).unwrap();

info!("The Matrix is an illusion");
Expand All @@ -50,7 +66,7 @@ fn main(_image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
info!("Total processors: {}", processor_count.total);
info!("Enabled processors: {}", processor_count.enabled);

// Setup the EPT
// Setup EPT
let shared_data = match setup_ept() {
Ok(shared_data) => shared_data,
Err(e) => panic!("Failed to setup EPT: {:?}", e),
Expand Down
1 change: 0 additions & 1 deletion driver/src/virtualize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ use {
},
};

#[derive(Default)]
pub struct Virtualize {
guest_registers: GuestRegisters,
shared_data: Box<SharedData>,
Expand Down
6 changes: 3 additions & 3 deletions hypervisor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ lazy_static = { version = "1.4.0", features = ["spin_no_std"] } # https://crates
obfstr = "0.4.3" # https://crates.io/crates/obfstr/
static_assertions = "1.1.0" # https://crates.io/crates/static_assertions
log = "0.4.20" # https://crates.io/crates/log
com_logger = "0.1.1" # https://crates.io/crates/com_logger
iced-x86 = { version = "1.20.0", default-features = false, features = ["no_std", "decoder", "block_encoder", "instr_info", "no_d3now", "no_evex", "no_vex", "no_xop"] } # https://crates.io/crates/iced-x86
bstr = { version = "1.9.0", default-features = false}
derivative = { version = "2.2.0", features = ["use_core"]} # https://crates.io/crates/derivative
bstr = { version = "1.9.0", default-features = false} # https://crates.io/crates/bstr
derivative = { version = "2.2.0", features = ["use_core"]} # https://crates.io/crates/derivative
spin = "0.9" # https://crates.io/crates/spin
28 changes: 28 additions & 0 deletions hypervisor/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//! The module containing various constants that may be modified by developers.

#![allow(dead_code)]

use crate::logger::{UartComPort, UartLogger};

/// The logging level.
pub const LOGGING_LEVEL: log::LevelFilter = log::LevelFilter::Trace;

/// Once in how many iterations stats should be sent to the serial output.
/// Ignored when [`LOGGING_LEVEL`] is `Trace`.
pub const SERIAL_OUTPUT_INTERVAL: u64 = 500;

/// Once in how many iterations stats should be displayed on the console.
/// Ignored when `stdout_stats_report` is disabled.
pub const CONSOLE_OUTPUT_INTERVAL: u64 = 1000;

/// How long a single fuzzing iteration can spend within the guest-mode, in TSC.
/// If the more than this is spent, a timer fires and aborts the VM.
pub const GUEST_EXEC_TIMEOUT_IN_TSC: u64 = 200_000_000;

/// The number of fuzzing iterations to be done for single input. The lower, the
/// more frequently new files are selected, and it is slightly costly. Ignored
/// when `random_byte_modification` is disabled.
pub const MAX_ITERATION_COUNT_PER_FILE: u64 = 10_000;

/// The COM port to be used for UART logging.
pub static UART_LOGGER: UartLogger = UartLogger::new(UartComPort::Com2);
7 changes: 2 additions & 5 deletions hypervisor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@
extern crate alloc;
extern crate static_assertions;

pub mod config;
pub mod error;
pub mod intel;
//pub mod vcpu;
//pub mod vmcs;
//pub mod vmerror;
//pub mod vmexit;
//pub mod vmlaunch;
pub mod logger;
pub mod vmm;
101 changes: 101 additions & 0 deletions hypervisor/src/logger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
//! The module containing the UART (serial port) logger implementation.
// Inspired by Ian Kronquist's work: https://github.com/iankronquist/rustyvisor/blob/83b53ac104d85073858ba83326a28a6e08d1af12/pcuart/src/lib.rs
// Credits: https://github.com/tandasat/Hypervisor-101-in-Rust/blob/main/hypervisor/src/logger.rs

#![allow(dead_code)]

use {
crate::{
config::{LOGGING_LEVEL, UART_LOGGER},
intel::support::{inb, outb},
},
core::{fmt, fmt::Write},
spin::Mutex,
};

/// Initializes the logger instance.
pub fn init_uart_logger() {
log::set_logger(&UART_LOGGER)
.map(|()| log::set_max_level(LOGGING_LEVEL))
.unwrap();
}

#[derive(Clone, Copy)]
#[repr(u16)]
pub(crate) enum UartComPort {
Com1 = 0x3f8,
Com2 = 0x2f8,
}

#[derive(Default)]
struct Uart {
io_port_base: u16,
}

impl Uart {
const fn new(port: UartComPort) -> Self {
Self {
io_port_base: port as u16,
}
}
}

const UART_OFFSET_TRANSMITTER_HOLDING_BUFFER: u16 = 0;
const UART_OFFSET_LINE_STATUS: u16 = 5;

impl Write for Uart {
// Writes bytes `string` to the serial port.
fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
for byte in string.bytes() {
while (inb(self.io_port_base + UART_OFFSET_LINE_STATUS) & 0x20) == 0 {}
outb(
self.io_port_base + UART_OFFSET_TRANSMITTER_HOLDING_BUFFER,
byte,
);
}
Ok(())
}
}

pub struct UartLogger {
port: Mutex<Uart>,
}

impl UartLogger {
pub(crate) const fn new(port: UartComPort) -> Self {
Self {
port: Mutex::new(Uart::new(port)),
}
}

fn lock(&self) -> spin::MutexGuard<'_, Uart> {
self.port.lock()
}
}

impl log::Log for UartLogger {
fn enabled(&self, metadata: &log::Metadata<'_>) -> bool {
metadata.level() <= log::Level::Trace
}

fn log(&self, record: &log::Record<'_>) {
if self.enabled(record.metadata()) {
let _ = writeln!(
self.lock(),
"#{}:{}: {}",
apic_id(),
record.level(),
record.args()
);
}
}

fn flush(&self) {}
}

/// Gets an APIC ID.
fn apic_id() -> u32 {
// See: (AMD) CPUID Fn0000_0001_EBX LocalApicId, LogicalProcessorCount, CLFlush
// See: (Intel) Table 3-8. Information Returned by CPUID Instruction
x86::cpuid::cpuid!(0x1).ebx >> 24
}

0 comments on commit da39986

Please sign in to comment.