Skip to content

Commit 49b012c

Browse files
committed
feat(vm): change UhyveVm struct parameters
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.
1 parent 5c9a2fd commit 49b012c

4 files changed

Lines changed: 44 additions & 32 deletions

File tree

src/linux/x86_64/kvm_cpu.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,12 +402,14 @@ impl VirtualCPU for KvmCpu {
402402
hypercall::address_to_hypercall(&self.parent_vm.mem, port, data_addr)
403403
} {
404404
match hypercall {
405-
Hypercall::Cmdsize(syssize) => syssize
406-
.update(self.parent_vm.kernel_path(), self.parent_vm.args()),
405+
Hypercall::Cmdsize(syssize) => syssize.update(
406+
self.parent_vm.kernel_path(),
407+
&self.parent_vm.params.kernel_args,
408+
),
407409
Hypercall::Cmdval(syscmdval) => {
408410
hypercall::copy_argv(
409411
self.parent_vm.kernel_path().as_os_str(),
410-
self.parent_vm.args(),
412+
&self.parent_vm.params.kernel_args,
411413
syscmdval,
412414
&self.parent_vm.mem,
413415
);

src/macos/aarch64/vcpu.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,12 +174,14 @@ impl VirtualCPU for XhyveCpu {
174174
Hypercall::Exit(sysexit) => {
175175
return Ok(VcpuStopReason::Exit(sysexit.arg));
176176
}
177-
Hypercall::Cmdsize(syssize) => syssize
178-
.update(self.parent_vm.kernel_path(), self.parent_vm.args()),
177+
Hypercall::Cmdsize(syssize) => syssize.update(
178+
self.parent_vm.kernel_path(),
179+
&self.parent_vm.params.kernel_args,
180+
),
179181
Hypercall::Cmdval(syscmdval) => {
180182
copy_argv(
181183
self.parent_vm.kernel_path().as_os_str(),
182-
self.parent_vm.args(),
184+
&self.parent_vm.params.kernel_args,
183185
syscmdval,
184186
&self.parent_vm.mem,
185187
);

src/macos/x86_64/vcpu.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -720,13 +720,14 @@ impl VirtualCPU for XhyveCpu {
720720
hypercall::address_to_hypercall(&self.parent_vm.mem, port, data_addr)
721721
} {
722722
match hypercall {
723-
Hypercall::Cmdsize(syssize) => {
724-
syssize.update(self.parent_vm.kernel_path(), self.parent_vm.args())
725-
}
723+
Hypercall::Cmdsize(syssize) => syssize.update(
724+
self.parent_vm.kernel_path(),
725+
&self.parent_vm.params.kernel_args,
726+
),
726727
Hypercall::Cmdval(syscmdval) => {
727728
copy_argv(
728729
self.parent_vm.kernel_path().as_os_str(),
729-
self.parent_vm.args(),
730+
&self.parent_vm.params.kernel_args,
730731
syscmdval,
731732
&self.parent_vm.mem,
732733
);

src/vm.rs

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::{
2-
ffi::OsString,
32
fmt, fs, io,
43
marker::PhantomData,
54
num::NonZeroU32,
@@ -105,19 +104,24 @@ pub struct UhyveVm<VCpuType: VirtualCPU = VcpuDefault> {
105104
entry_point: u64,
106105
stack_address: u64,
107106
pub mem: Arc<MmapMemory>,
107+
pub params: Params,
108+
memory_size: usize,
108109
num_cpus: u32,
109110
path: PathBuf,
110-
args: Vec<OsString>,
111111
boot_info: *const RawBootInfo,
112-
verbose: bool,
113112
pub virtio_device: Arc<Mutex<VirtioNetPciDevice>>,
114113
#[allow(dead_code)] // gdb is not supported on macos
115114
pub(super) gdb_port: Option<u16>,
116115
_vcpu_type: PhantomData<VCpuType>,
117116
}
118117
impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
119118
pub fn new(kernel_path: PathBuf, params: Params) -> HypervisorResult<UhyveVm<VCpuType>> {
119+
// We expose the params struct, but use some extra variables for the
120+
// gdb_port (because of pub(super)) and memory_size (later, num_cpus)
121+
// which require a get() to reduce overhead, and, most importantly,
122+
// increase flexibility.
120123
let memory_size = params.memory_size.get();
124+
let gdb_port = params.gdb_port;
121125

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

136-
let cpu_count = params.cpu_count.get();
140+
let num_cpus = params.cpu_count.get();
137141

138142
assert!(
139-
params.gdb_port.is_none() || cfg!(target_os = "linux"),
143+
gdb_port.is_none() || cfg!(target_os = "linux"),
140144
"gdb is only supported on linux (yet)"
141145
);
142146
assert!(
143-
params.gdb_port.is_none() || cpu_count == 1,
147+
gdb_port.is_none() || num_cpus == 1,
144148
"gdbstub is only supported with one CPU"
145149
);
146150

@@ -149,13 +153,13 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
149153
entry_point: 0,
150154
stack_address: 0,
151155
mem: mem.into(),
152-
num_cpus: cpu_count,
156+
params,
157+
memory_size,
158+
num_cpus,
153159
path: kernel_path,
154-
args: params.kernel_args,
155160
boot_info: ptr::null(),
156-
verbose: params.verbose,
157161
virtio_device,
158-
gdb_port: params.gdb_port,
162+
gdb_port,
159163
_vcpu_type: PhantomData,
160164
};
161165

@@ -164,10 +168,6 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
164168
Ok(vm)
165169
}
166170

167-
fn verbose(&self) -> bool {
168-
self.verbose
169-
}
170-
171171
/// Returns the section offsets relative to their base addresses
172172
pub fn get_offset(&self) -> u64 {
173173
self.offset
@@ -181,7 +181,17 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
181181
self.stack_address
182182
}
183183

184-
/// Returns the number of cores for the vm.
184+
// Returns the struct containing all parameters.
185+
pub fn params(&self) -> &Params {
186+
&self.params
187+
}
188+
189+
// Returns the total memory size made available.
190+
pub fn memory_size(&self) -> usize {
191+
self.memory_size
192+
}
193+
194+
// Returns number of cores for the VM.
185195
pub fn num_cpus(&self) -> u32 {
186196
self.num_cpus
187197
}
@@ -190,10 +200,6 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
190200
&self.path
191201
}
192202

193-
pub fn args(&self) -> &Vec<OsString> {
194-
&self.args
195-
}
196-
197203
/// Initialize the page tables for the guest
198204
fn init_guest_mem(&mut self) {
199205
debug!("Initialize guest memory");
@@ -232,7 +238,7 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
232238
hardware_info: HardwareInfo {
233239
phys_addr_range: self.mem.guest_address.as_u64()
234240
..self.mem.guest_address.as_u64() + self.mem.memory_size as u64,
235-
serial_port_base: self.verbose().then(|| {
241+
serial_port_base: self.params.verbose.then(|| {
236242
SerialPortBase::new((uhyve_interface::HypercallAddress::Uart as u16).into())
237243
.unwrap()
238244
}),
@@ -241,7 +247,7 @@ impl<VCpuType: VirtualCPU> UhyveVm<VCpuType> {
241247
load_info,
242248
platform_info: PlatformInfo::Uhyve {
243249
has_pci: cfg!(target_os = "linux"),
244-
num_cpus: u64::from(self.num_cpus()).try_into().unwrap(),
250+
num_cpus: u64::from(self.num_cpus).try_into().unwrap(),
245251
cpu_freq: NonZeroU32::new(detect_cpu_freq() * 1000),
246252
boot_time: SystemTime::now().into(),
247253
},
@@ -269,10 +275,11 @@ impl<VCpuType: VirtualCPU> fmt::Debug for UhyveVm<VCpuType> {
269275
.field("entry_point", &self.entry_point)
270276
.field("stack_address", &self.stack_address)
271277
.field("mem", &self.mem)
278+
.field("params", &self.params)
279+
.field("memory_size", &self.memory_size)
272280
.field("num_cpus", &self.num_cpus)
273281
.field("path", &self.path)
274282
.field("boot_info", &self.boot_info)
275-
.field("verbose", &self.verbose)
276283
.field("virtio_device", &self.virtio_device)
277284
.finish()
278285
}

0 commit comments

Comments
 (0)