9
9
#[ allow( deref_nullptr) ]
10
10
pub mod bindings;
11
11
12
+ #[ macro_use]
13
+ extern crate log;
14
+
12
15
use bindings:: * ;
13
16
14
17
#[ cfg( target_arch = "aarch64" ) ]
@@ -206,11 +209,27 @@ pub fn vcpu_set_vtimer_mask(vcpuid: u64, masked: bool) -> Result<(), Error> {
206
209
}
207
210
}
208
211
209
- pub struct HvfNestedBindings {
210
- hv_vm_config_get_el2_supported :
211
- libloading:: Symbol < ' static , unsafe extern "C" fn ( * mut bool ) -> hv_return_t > ,
212
- hv_vm_config_set_el2_enabled :
213
- libloading:: Symbol < ' static , unsafe extern "C" fn ( hv_vm_config_t , bool ) -> hv_return_t > ,
212
+ /// Checks if Nested Virtualization is supported on the current system. Only
213
+ /// M3 or newer chips on macOS 15+ will satisfy the requirements.
214
+ pub fn check_nested_virt ( ) -> Result < bool , Error > {
215
+ type GetEL2Supported =
216
+ libloading:: Symbol < ' static , unsafe extern "C" fn ( * mut bool ) -> hv_return_t > ;
217
+
218
+ let get_el2_supported: Result < GetEL2Supported , libloading:: Error > =
219
+ unsafe { HVF . get ( b"hv_vm_config_get_el2_supported" ) } ;
220
+ if get_el2_supported. is_err ( ) {
221
+ info ! ( "cannot find hv_vm_config_get_el2_supported symbol" ) ;
222
+ return Ok ( false ) ;
223
+ }
224
+
225
+ let mut el2_supported: bool = false ;
226
+ let ret = unsafe { ( get_el2_supported. unwrap ( ) ) ( & mut el2_supported) } ;
227
+ if ret != HV_SUCCESS {
228
+ error ! ( "processor does not support the nested virtualization functionality" ) ;
229
+ return Err ( Error :: NestedCheck ) ;
230
+ }
231
+
232
+ Ok ( el2_supported)
214
233
}
215
234
216
235
pub struct HvfVm { }
@@ -225,30 +244,16 @@ static HVF: LazyLock<libloading::Library> = LazyLock::new(|| unsafe {
225
244
impl HvfVm {
226
245
pub fn new ( nested_enabled : bool ) -> Result < Self , Error > {
227
246
let config = unsafe { hv_vm_config_create ( ) } ;
228
-
229
247
if nested_enabled {
230
- let bindings = unsafe {
231
- HvfNestedBindings {
232
- hv_vm_config_get_el2_supported : HVF
233
- . get ( b"hv_vm_config_get_el2_supported" )
234
- . map_err ( Error :: FindSymbol ) ?,
235
- hv_vm_config_set_el2_enabled : HVF
236
- . get ( b"hv_vm_config_set_el2_enabled" )
237
- . map_err ( Error :: FindSymbol ) ?,
238
- }
248
+ let set_el2_enabled: libloading:: Symbol <
249
+ ' static ,
250
+ unsafe extern "C" fn ( hv_vm_config_t , bool ) -> hv_return_t ,
251
+ > = unsafe {
252
+ HVF . get ( b"hv_vm_config_set_el2_enabled" )
253
+ . map_err ( Error :: FindSymbol ) ?
239
254
} ;
240
255
241
- let mut el2_supported: bool = false ;
242
- let ret = unsafe { ( bindings. hv_vm_config_get_el2_supported ) ( & mut el2_supported) } ;
243
- if ret != HV_SUCCESS {
244
- return Err ( Error :: NestedCheck ) ;
245
- }
246
-
247
- if !el2_supported {
248
- return Err ( Error :: NestedCheck ) ;
249
- }
250
-
251
- let ret = unsafe { ( bindings. hv_vm_config_set_el2_enabled ) ( config, true ) } ;
256
+ let ret = unsafe { ( set_el2_enabled) ( config, true ) } ;
252
257
if ret != HV_SUCCESS {
253
258
return Err ( Error :: EnableEL2 ) ;
254
259
}
0 commit comments