Skip to content

Commit

Permalink
Factor out VirtualCPU::resume
Browse files Browse the repository at this point in the history
  • Loading branch information
mkroening committed Jul 14, 2021
1 parent 9828cbf commit a35c25f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 23 deletions.
32 changes: 21 additions & 11 deletions src/linux/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::linux::virtio::*;
use crate::linux::KVM;
use crate::paging::*;
use crate::vm::HypervisorResult;
use crate::vm::VcpuStopReason;
use crate::vm::VirtualCPU;
use kvm_bindings::*;
use kvm_ioctls::{VcpuExit, VcpuFd};
Expand Down Expand Up @@ -275,14 +276,7 @@ impl VirtualCPU for UhyveCPU {
(entry & ((!0usize) << PAGE_BITS)) | (addr & !((!0usize) << PAGE_BITS))
}

fn run(&mut self) -> HypervisorResult<i32> {
//self.print_registers();

// Pause first CPU before first execution, so we have time to attach debugger
if self.id == 0 {
self.gdb_handle_exception(None);
}

fn resume(&mut self) -> HypervisorResult<VcpuStopReason> {
loop {
let exitreason = self.vcpu.run()?;
match exitreason {
Expand All @@ -291,7 +285,7 @@ impl VirtualCPU for UhyveCPU {
debug!("{:?}", VcpuExit::Hlt);
}
VcpuExit::Shutdown => {
return Ok(0);
return Ok(VcpuStopReason::Exit(0));
}
VcpuExit::IoIn(port, addr) => match port {
PCI_CONFIG_DATA_PORT => {
Expand Down Expand Up @@ -364,7 +358,9 @@ impl VirtualCPU for UhyveCPU {
UHYVE_PORT_EXIT => {
let data_addr: usize =
unsafe { (*(addr.as_ptr() as *const u32)) as usize };
return Ok(self.exit(self.host_address(data_addr)));
return Ok(VcpuStopReason::Exit(
self.exit(self.host_address(data_addr)),
));
}
UHYVE_PORT_OPEN => {
let data_addr: usize =
Expand Down Expand Up @@ -435,7 +431,7 @@ impl VirtualCPU for UhyveCPU {
}
VcpuExit::Debug => {
info!("Caught Debug Interrupt! {:?}", exitreason);
self.gdb_handle_exception(Some(VcpuExit::Debug));
return Ok(VcpuStopReason::Debug);
}
VcpuExit::InternalError => {
panic!("{:?}", VcpuExit::InternalError)
Expand All @@ -447,6 +443,20 @@ impl VirtualCPU for UhyveCPU {
}
}

fn run(&mut self) -> HypervisorResult<i32> {
// Pause first CPU before first execution, so we have time to attach debugger
if self.id == 0 {
self.gdb_handle_exception(None);
}

loop {
match self.resume()? {
VcpuStopReason::Debug => self.gdb_handle_exception(Some(VcpuExit::Debug)),
VcpuStopReason::Exit(code) => return Ok(code),
}
}
}

fn print_registers(&self) {
let regs = self.vcpu.get_regs().unwrap();
let sregs = self.vcpu.get_sregs().unwrap();
Expand Down
33 changes: 21 additions & 12 deletions src/macos/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::debug_manager::DebugManager;
use crate::macos::ioapic::IoApic;
use crate::paging::*;
use crate::vm::HypervisorResult;
use crate::vm::VcpuStopReason;
use crate::vm::VirtualCPU;
use burst::x86::{disassemble_64, InstructionOperation, OperandType};
use lazy_static::lazy_static;
Expand Down Expand Up @@ -577,15 +578,7 @@ impl VirtualCPU for UhyveCPU {
(entry & ((!0usize) << PAGE_BITS)) | (addr & !((!0usize) << PAGE_BITS))
}

fn run(&mut self) -> HypervisorResult<i32> {
//self.print_registers();

// Pause first CPU before first execution, so we have time to attach debugger
if self.id == 0 {
self.gdb_handle_exception(false);
}

debug!("Run vCPU {}", self.id);
fn resume(&mut self) -> HypervisorResult<VcpuStopReason> {
loop {
/*if self.extint_pending == true {
let irq_info = self.vcpu.read_vmcs(VMCS_CTRL_VMENTRY_IRQ_INFO)?;
Expand Down Expand Up @@ -623,7 +616,7 @@ impl VirtualCPU for UhyveCPU {
irq_vec
);
debug!("Handle breakpoint exception");
self.gdb_handle_exception(true);
return Ok(VcpuStopReason::Debug)
}
vmx_exit::VMX_REASON_CPUID => {
self.emulate_cpuid(rip)?;
Expand Down Expand Up @@ -661,7 +654,7 @@ impl VirtualCPU for UhyveCPU {

match port {
SHUTDOWN_PORT => {
return Ok(0);
return Ok(VcpuStopReason::Exit(0));
}
UHYVE_UART_PORT => {
let al = (self.vcpu.read_register(&x86Reg::RAX)? & 0xFF) as u8;
Expand All @@ -684,7 +677,9 @@ impl VirtualCPU for UhyveCPU {
UHYVE_PORT_EXIT => {
let data_addr: u64 =
self.vcpu.read_register(&x86Reg::RAX)? & 0xFFFFFFFF;
return Ok(self.exit(self.host_address(data_addr as usize)));
return Ok(VcpuStopReason::Exit(
self.exit(self.host_address(data_addr as usize)),
));
}
UHYVE_PORT_OPEN => {
let data_addr: u64 =
Expand Down Expand Up @@ -735,6 +730,20 @@ impl VirtualCPU for UhyveCPU {
}
}

fn run(&mut self) -> HypervisorResult<i32> {
// Pause first CPU before first execution, so we have time to attach debugger
if self.id == 0 {
self.gdb_handle_exception(false);
}

loop {
match self.resume()? {
VcpuStopReason::Debug => self.gdb_handle_exception(true),
VcpuStopReason::Exit(code) => return Ok(code),
}
}
}

fn print_registers(&self) {
println!("\nDump state of CPU {}", self.id);
println!("VMCS:");
Expand Down
11 changes: 11 additions & 0 deletions src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,10 +226,21 @@ pub enum LoadKernelError {

pub type LoadKernelResult<T> = Result<T, LoadKernelError>;

/// Reasons for vCPU exits.
pub enum VcpuStopReason {
/// The vCPU stopped for debugging.
Debug,
/// The vCPU exited with the specified exit code.
Exit(i32),
}

pub trait VirtualCPU {
/// Initialize the cpu to start running the code ad entry_point.
fn init(&mut self, entry_point: u64) -> HypervisorResult<()>;

/// Resumes execution.
fn resume(&mut self) -> HypervisorResult<VcpuStopReason>;

/// Start the execution of the CPU. The function will run until it crashes (`Err`) or terminate with an exit code (`Ok`).
fn run(&mut self) -> HypervisorResult<i32>;

Expand Down

0 comments on commit a35c25f

Please sign in to comment.