Skip to content

Commit a4f3a30

Browse files
Copilotsimongdavies
andcommitted
Fix hypervisor handle caching implementation
Co-authored-by: simongdavies <[email protected]>
1 parent 1e2faa8 commit a4f3a30

File tree

2 files changed

+45
-33
lines changed

2 files changed

+45
-33
lines changed

src/hyperlight_host/src/hypervisor/hyperv_linux.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -273,18 +273,24 @@ mod debug {
273273
}
274274

275275
/// Static global MSHV handle to avoid reopening /dev/mshv for every sandbox
276-
static MSHV_HANDLE: OnceLock<Option<Mshv>> = OnceLock::new();
276+
static MSHV_HANDLE: OnceLock<Mshv> = OnceLock::new();
277277

278278
/// Get the global MSHV handle, initializing it if needed
279279
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
280-
pub(crate) fn get_mshv_handle() -> &'static Option<Mshv> {
281-
MSHV_HANDLE.get_or_init(|| match Mshv::new() {
282-
Ok(mshv) => Some(mshv),
283-
Err(e) => {
284-
log::info!("MSHV is not available on this system: {}", e);
285-
None
286-
}
287-
})
280+
pub(crate) fn get_mshv_handle() -> Option<&'static Mshv> {
281+
match MSHV_HANDLE.get() {
282+
Some(mshv) => Some(mshv),
283+
None => match Mshv::new() {
284+
Ok(mshv) => {
285+
let _ = MSHV_HANDLE.set(mshv);
286+
MSHV_HANDLE.get()
287+
}
288+
Err(e) => {
289+
log::info!("MSHV is not available on this system: {}", e);
290+
None
291+
}
292+
},
293+
}
288294
}
289295

290296
/// Determine whether the HyperV for Linux hypervisor API is present
@@ -297,7 +303,7 @@ pub(crate) fn is_hypervisor_present() -> bool {
297303
/// A Hypervisor driver for HyperV-on-Linux. This hypervisor is often
298304
/// called the Microsoft Hypervisor (MSHV)
299305
pub(super) struct HypervLinuxDriver {
300-
_mshv: Mshv,
306+
_mshv: &'static Mshv,
301307
vm_fd: VmFd,
302308
vcpu_fd: VcpuFd,
303309
entrypoint: u64,
@@ -328,7 +334,7 @@ impl HypervLinuxDriver {
328334
#[cfg(gdb)] gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
329335
) -> Result<Self> {
330336
let mshv = match get_mshv_handle() {
331-
Some(mshv) => mshv.clone(),
337+
Some(mshv) => mshv,
332338
None => return Err(new_error!("MSHV is not available on this system")),
333339
};
334340

src/hyperlight_host/src/hypervisor/kvm.rs

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,37 @@ use crate::HyperlightError;
4444
use crate::{log_then_return, new_error, Result};
4545

4646
/// Static global KVM handle to avoid reopening /dev/kvm for every sandbox
47-
static KVM_HANDLE: OnceLock<Option<Kvm>> = OnceLock::new();
47+
static KVM_HANDLE: OnceLock<Kvm> = OnceLock::new();
4848

4949
/// Get the global KVM handle, initializing it if needed
5050
#[instrument(skip_all, parent = Span::current(), level = "Trace")]
51-
pub(crate) fn get_kvm_handle() -> &'static Option<Kvm> {
52-
KVM_HANDLE.get_or_init(|| match Kvm::new() {
53-
Ok(kvm) => {
54-
let api_version = kvm.get_api_version();
55-
match api_version {
56-
version if version == 12 && kvm.check_extension(UserMemory) => Some(kvm),
57-
12 => {
58-
log::info!("KVM does not have KVM_CAP_USER_MEMORY capability");
59-
None
60-
}
61-
version => {
62-
log::info!("KVM GET_API_VERSION returned {}, expected 12", version);
63-
None
51+
pub(crate) fn get_kvm_handle() -> Option<&'static Kvm> {
52+
match KVM_HANDLE.get() {
53+
Some(kvm) => Some(kvm),
54+
None => match Kvm::new() {
55+
Ok(kvm) => {
56+
let api_version = kvm.get_api_version();
57+
match api_version {
58+
version if version == 12 && kvm.check_extension(UserMemory) => {
59+
let _ = KVM_HANDLE.set(kvm);
60+
KVM_HANDLE.get()
61+
}
62+
12 => {
63+
log::info!("KVM does not have KVM_CAP_USER_MEMORY capability");
64+
None
65+
}
66+
version => {
67+
log::info!("KVM GET_API_VERSION returned {}, expected 12", version);
68+
None
69+
}
6470
}
6571
}
66-
}
67-
Err(e) => {
68-
log::info!("KVM is not available on this system: {}", e);
69-
None
70-
}
71-
})
72+
Err(e) => {
73+
log::info!("KVM is not available on this system: {}", e);
74+
None
75+
}
76+
},
77+
}
7278
}
7379

7480
/// Return `true` if the KVM API is available, version 12, and has UserMemory capability, or `false` otherwise
@@ -288,7 +294,7 @@ mod debug {
288294

289295
/// A Hypervisor driver for KVM on Linux
290296
pub(super) struct KVMDriver {
291-
_kvm: Kvm,
297+
_kvm: &'static Kvm,
292298
_vm_fd: VmFd,
293299
vcpu_fd: VcpuFd,
294300
entrypoint: u64,
@@ -314,7 +320,7 @@ impl KVMDriver {
314320
#[cfg(gdb)] gdb_conn: Option<DebugCommChannel<DebugResponse, DebugMsg>>,
315321
) -> Result<Self> {
316322
let kvm = match get_kvm_handle() {
317-
Some(kvm) => kvm.clone(),
323+
Some(kvm) => kvm,
318324
None => return Err(new_error!("KVM is not available on this system")),
319325
};
320326

0 commit comments

Comments
 (0)