Skip to content

Commit b3dd4ac

Browse files
committed
mshv-ioctls: check capability before using extended property
Signed-off-by: Muminul Islam <muislam@microsoft.com>
1 parent 1032a5d commit b3dd4ac

1 file changed

Lines changed: 34 additions & 22 deletions

File tree

‎mshv-ioctls/src/ioctls/system.rs‎

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -199,27 +199,39 @@ impl Mshv {
199199
feature_bits.set_synthetic_cluster_ipi(1);
200200
feature_bits.set_direct_synthetic_timers(1);
201201
feature_bits.set_access_vp_regs(1);
202-
#[cfg(not(target_arch = "aarch64"))]
203-
feature_bits.set_flush_guest_physical_address_space(1);
202+
203+
let vmm_caps = self.get_vmm_caps().unwrap();
204+
205+
if vmm_caps
206+
.__bindgen_anon_1
207+
.__bindgen_anon_1
208+
.assignable_synthetic_proc_features()
209+
== 1
210+
{
211+
#[cfg(not(target_arch = "aarch64"))]
212+
feature_bits.set_flush_guest_physical_address_space(1);
213+
// Intersect our default mask with the hypervisor-advertised set of
214+
// assignable synthetic features. The property is in the extended range
215+
// (0x00090xxx) and must be fetched via HVCALL_GET_PARTITION_PROPERTY_EX.
216+
// The payload follows the banked property shape used by
217+
// `hv_partition_property_vmm_capabilities`: u16 bank_count, three u16
218+
// reserved words, then `bank_count` u64 masks. We use bank 0.
219+
let assignable_ex = self
220+
.get_host_partition_property_ex(
221+
hv_partition_property_code_HV_PARTITION_PROPERTY_ASSIGNABLE_SYNTHETIC_PROC_FEATURES,
222+
)
223+
.unwrap();
224+
// SAFETY: `hv_partition_property_ex` is a union whose `buffer` variant
225+
// covers the full 4072-byte payload; reading the first bank u64 at
226+
// offset 8 is within bounds.
227+
let assignable_features: u64 =
228+
std::ptr::read_unaligned(assignable_ex.buffer.as_ptr().add(8) as *const u64);
229+
// SAFETY: access union fields
230+
features.as_uint64[0] & assignable_features
231+
} else {
232+
features.as_uint64[0]
233+
}
204234
}
205-
// Intersect our default mask with the hypervisor-advertised set of
206-
// assignable synthetic features. The property is in the extended range
207-
// (0x00090xxx) and must be fetched via HVCALL_GET_PARTITION_PROPERTY_EX.
208-
// The payload follows the banked property shape used by
209-
// `hv_partition_property_vmm_capabilities`: u16 bank_count, three u16
210-
// reserved words, then `bank_count` u64 masks. We use bank 0.
211-
let assignable_ex = self
212-
.get_host_partition_property_ex(
213-
hv_partition_property_code_HV_PARTITION_PROPERTY_ASSIGNABLE_SYNTHETIC_PROC_FEATURES,
214-
)
215-
.unwrap();
216-
// SAFETY: `hv_partition_property_ex` is a union whose `buffer` variant
217-
// covers the full 4072-byte payload; reading the first bank u64 at
218-
// offset 8 is within bounds.
219-
let assignable_features: u64 =
220-
unsafe { std::ptr::read_unaligned(assignable_ex.buffer.as_ptr().add(8) as *const u64) };
221-
// SAFETY: access union fields
222-
unsafe { features.as_uint64[0] & assignable_features }
223235
}
224236

225237
/// Helper function to creates a VM fd using the MSHV fd with provided configuration.
@@ -282,10 +294,10 @@ impl Mshv {
282294
Ok(vmm_caps)
283295
}
284296
Err(MshvError::Hypercall {
285-
status: Some(HvError::AccessDenied),
297+
status: Some(HvError::AccessDenied | HvError::UnknownProperty),
286298
..
287299
}) => {
288-
// If the hypercall fails with AccessDenied, it means the
300+
// If the hypercall fails with AccessDenied or UnknownProperty, it means the
289301
// VMM capabilities query is not supported on this MSHV version.
290302
// As per the hypervisor team, we should treat this case as if
291303
// none of the capabilities are set. So, return a zeroed out struct.

0 commit comments

Comments
 (0)