Skip to content

Commit

Permalink
feat(vm): change UhyveVm struct parameters
Browse files Browse the repository at this point in the history
As I was moving some functionality away from new(...) so as to progress
with my work on ASLR and some future work, I found it necessary to use
certain parameters later. A particular example from UhyveVm's current
structure would be params.thp and params.ksm, which pose one of the
obstacles preventing us from initializing the memory later (e.g. in
load_kernel or init_guest_mem, after loading the kernel and being able
to establish a guest address), even though separate variables for those
don't make much sense.

This change will mostly be useful for future work, but aims to
establish a consistent convention now.
  • Loading branch information
n0toose committed Sep 18, 2024
1 parent 5c9a2fd commit 9749700
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 33 deletions.
8 changes: 5 additions & 3 deletions src/linux/x86_64/kvm_cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,12 +402,14 @@ impl VirtualCPU for KvmCpu {
hypercall::address_to_hypercall(&self.parent_vm.mem, port, data_addr)
} {
match hypercall {
Hypercall::Cmdsize(syssize) => syssize
.update(self.parent_vm.kernel_path(), self.parent_vm.args()),
Hypercall::Cmdsize(syssize) => syssize.update(
self.parent_vm.kernel_path(),
&self.parent_vm.params.kernel_args,
),
Hypercall::Cmdval(syscmdval) => {
hypercall::copy_argv(
self.parent_vm.kernel_path().as_os_str(),
self.parent_vm.args(),
&self.parent_vm.params.kernel_args,
syscmdval,
&self.parent_vm.mem,
);
Expand Down
8 changes: 5 additions & 3 deletions src/macos/aarch64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,12 +174,14 @@ impl VirtualCPU for XhyveCpu {
Hypercall::Exit(sysexit) => {
return Ok(VcpuStopReason::Exit(sysexit.arg));
}
Hypercall::Cmdsize(syssize) => syssize
.update(self.parent_vm.kernel_path(), self.parent_vm.args()),
Hypercall::Cmdsize(syssize) => syssize.update(
self.parent_vm.kernel_path(),
&self.parent_vm.params.kernel_args
),
Hypercall::Cmdval(syscmdval) => {
copy_argv(
self.parent_vm.kernel_path().as_os_str(),
self.parent_vm.args(),
&self.parent_vm.params.kernel_args,
syscmdval,
&self.parent_vm.mem,
);
Expand Down
9 changes: 5 additions & 4 deletions src/macos/x86_64/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -720,13 +720,14 @@ impl VirtualCPU for XhyveCpu {
hypercall::address_to_hypercall(&self.parent_vm.mem, port, data_addr)
} {
match hypercall {
Hypercall::Cmdsize(syssize) => {
syssize.update(self.parent_vm.kernel_path(), self.parent_vm.args())
}
Hypercall::Cmdsize(syssize) => syssize.update(
self.parent_vm.kernel_path(),
&self.parent_vm.params.kernel_args,
),
Hypercall::Cmdval(syscmdval) => {
copy_argv(
self.parent_vm.kernel_path().as_os_str(),
self.parent_vm.args(),
&self.parent_vm.params.kernel_args,
syscmdval,
&self.parent_vm.mem,
);
Expand Down
51 changes: 28 additions & 23 deletions src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use std::{
ffi::OsString,
fmt, fs, io,
marker::PhantomData,
num::NonZeroU32,
Expand Down Expand Up @@ -105,19 +104,24 @@ pub struct UhyveVm<VCpuType: VirtualCPU = VcpuDefault> {
entry_point: u64,
stack_address: u64,
pub mem: Arc<MmapMemory>,
pub params: Params,
memory_size: usize,
num_cpus: u32,
path: PathBuf,
args: Vec<OsString>,
boot_info: *const RawBootInfo,
verbose: bool,
pub virtio_device: Arc<Mutex<VirtioNetPciDevice>>,
#[allow(dead_code)] // gdb is not supported on macos
pub(super) gdb_port: Option<u16>,
_vcpu_type: PhantomData<VCpuType>,
}
impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
pub fn new(kernel_path: PathBuf, params: Params) -> HypervisorResult<UhyveVm<VCpuType>> {
// We expose the params struct, but use some extra variables for the
// gdb_port (because of pub(super)) and for anything requiring a get()
// for less overhead and, most importantly, more flexibility.
let memory_size = params.memory_size.get();
let num_cpus = params.cpu_count.get();
let gdb_port = params.gdb_port;

#[cfg(target_os = "linux")]
let mem = MmapMemory::new(0, memory_size, arch::RAM_START, params.thp, params.ksm);
Expand All @@ -133,14 +137,12 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
#[cfg(target_os = "linux")]
initialize_kvm(&mem, params.pit)?;

let cpu_count = params.cpu_count.get();

assert!(
params.gdb_port.is_none() || cfg!(target_os = "linux"),
gdb_port.is_none() || cfg!(target_os = "linux"),
"gdb is only supported on linux (yet)"
);
assert!(
params.gdb_port.is_none() || cpu_count == 1,
gdb_port.is_none() || num_cpus == 1,
"gdbstub is only supported with one CPU"
);

Expand All @@ -149,13 +151,13 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
entry_point: 0,
stack_address: 0,
mem: mem.into(),
num_cpus: cpu_count,
params,
memory_size,
num_cpus,
path: kernel_path,
args: params.kernel_args,
boot_info: ptr::null(),
verbose: params.verbose,
virtio_device,
gdb_port: params.gdb_port,
gdb_port,
_vcpu_type: PhantomData,
};

Expand All @@ -164,10 +166,6 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
Ok(vm)
}

fn verbose(&self) -> bool {
self.verbose
}

/// Returns the section offsets relative to their base addresses
pub fn get_offset(&self) -> u64 {
self.offset
Expand All @@ -181,7 +179,17 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
self.stack_address
}

/// Returns the number of cores for the vm.
// Returns the struct containing all parameters.
pub fn params(&self) -> &Params {
&self.params
}

// Returns the total memory size made available.
pub fn memory_size(&self) -> usize {
self.memory_size
}

// Returns number of cores for the VM.
pub fn num_cpus(&self) -> u32 {
self.num_cpus
}
Expand All @@ -190,10 +198,6 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
&self.path
}

pub fn args(&self) -> &Vec<OsString> {
&self.args
}

/// Initialize the page tables for the guest
fn init_guest_mem(&mut self) {
debug!("Initialize guest memory");
Expand Down Expand Up @@ -232,7 +236,7 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
hardware_info: HardwareInfo {
phys_addr_range: self.mem.guest_address.as_u64()
..self.mem.guest_address.as_u64() + self.mem.memory_size as u64,
serial_port_base: self.verbose().then(|| {
serial_port_base: self.params.verbose.then(|| {
SerialPortBase::new((uhyve_interface::HypercallAddress::Uart as u16).into())
.unwrap()
}),
Expand All @@ -241,7 +245,7 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
load_info,
platform_info: PlatformInfo::Uhyve {
has_pci: cfg!(target_os = "linux"),
num_cpus: u64::from(self.num_cpus()).try_into().unwrap(),
num_cpus: u64::from(self.num_cpus).try_into().unwrap(),
cpu_freq: NonZeroU32::new(detect_cpu_freq() * 1000),
boot_time: SystemTime::now().into(),
},
Expand Down Expand Up @@ -269,10 +273,11 @@ impl<VCpuType: VirtualCPU> fmt::Debug for UhyveVm<VCpuType> {
.field("entry_point", &self.entry_point)
.field("stack_address", &self.stack_address)
.field("mem", &self.mem)
.field("params", &self.params)
.field("memory_size", &self.memory_size)
.field("num_cpus", &self.num_cpus)
.field("path", &self.path)
.field("boot_info", &self.boot_info)
.field("verbose", &self.verbose)
.field("virtio_device", &self.virtio_device)
.finish()
}
Expand Down

0 comments on commit 9749700

Please sign in to comment.