Skip to content

Commit

Permalink
ioctls/vcpu: Add hvcall_ version of translate gva and get cpuid values
Browse files Browse the repository at this point in the history
Demonstrate use of generic hypercall ioctl for vcpu. Get vp cpuid values
also demonstrates a rep hypercall (with only 1 repetition), and variable
length array usage.

Signed-off-by: Nuno Das Neves <nudasnev@microsoft.com>
  • Loading branch information
NunoDasNeves committed Apr 3, 2024
1 parent 72aee5a commit 67081e1
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions mshv-ioctls/src/ioctls/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,25 @@ impl VcpuFd {

Ok((gpa, result))
}
/// Generic hvcall version of translate guest virtual address
pub fn hvcall_translate_gva(&self, gva: u64, flags: u64) -> Result<(u64, hv_translate_gva_result)> {
let input = hv_input_translate_virtual_address {
vp_index: self.index,
control_flags: flags,
gva_page: gva >> HV_HYP_PAGE_SHIFT,
..Default::default() // NOTE: kernel will populate partition_id field
};
let output = hv_output_translate_virtual_address {
..Default::default()
};
let mut args = make_args!(HVCALL_TRANSLATE_VIRTUAL_ADDRESS, input, output);
self.hvcall(&mut args)?;

let gpa = (output.gpa_page << HV_HYP_PAGE_SHIFT) | (gva & !(1 << HV_HYP_PAGE_SHIFT));

Ok((gpa, output.translation_result))
}

/// X86 specific call that returns the vcpu's current "suspend registers".
#[cfg(not(target_arch = "aarch64"))]
pub fn get_suspend_regs(&self) -> Result<SuspendRegisters> {
Expand Down Expand Up @@ -1044,6 +1063,42 @@ impl VcpuFd {
}
Ok([parms.eax, parms.ebx, parms.ecx, parms.edx])
}
/// Generic hvcall version of get cpuid values
#[cfg(not(target_arch = "aarch64"))]
pub fn hvcall_get_cpuid_values(&self, eax: u32, ecx: u32, xfem: u64, xss: u64) -> Result<[u32; 4]> {
let mut input = make_rep_input!(
hv_input_get_vp_cpuid_values {
vp_index: self.index,
..Default::default() // NOTE: kernel will populate partition_id field
},
cpuid_leaf_info,
[hv_cpuid_leaf_info {
eax,
ecx,
xfem,
xss,
}]
);
unsafe {
input
.as_mut_struct_ref()
.flags
.__bindgen_anon_1
.set_use_vp_xfem_xss(1);
input
.as_mut_struct_ref()
.flags
.__bindgen_anon_1
.set_apply_registered_values(1);
}
let mut output_arr: [hv_output_get_vp_cpuid_values; 1] = [Default::default()];
let mut args = make_rep_args!(HVCALL_GET_VP_CPUID_VALUES, input, output_arr);
self.hvcall(&mut args)?;

// SAFETY: we know the hvcall succeeded, and both fields of the union
// are equivalent we just return the array instead of taking eax, ebx, etc...
Ok(unsafe { output_arr[0].as_uint32 })
}
/// Read GPA
pub fn gpa_read(&self, input: &mut mshv_read_write_gpa) -> Result<mshv_read_write_gpa> {
// SAFETY: we know that our file is a vCPU fd, we know the kernel honours its ABI.
Expand Down

0 comments on commit 67081e1

Please sign in to comment.