hypervisor: mshv: function to advance RIP and RAX

A separate function to advance RIP and RAX based on
register page.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam
2025-04-24 17:30:42 -07:00
committed by Muminul Islam Russell
parent 1c22c4a57b
commit 3c63779302

View File

@@ -717,35 +717,7 @@ impl cpu::Vcpu for MshvVcpu {
*/
match port {
0x402 | 0x510 | 0x511 | 0x514 => {
let insn_len = info.header.instruction_length() as u64;
/*
* Advance RIP and update RAX
* First, try to update the registers using VP register page
* which is mapped into user space for faster access.
* If the register page is not available, fall back to regular
* IOCTL to update the registers.
*/
if let Some(reg_page) = self.fd.get_vp_reg_page() {
let vp_reg_page = reg_page.0;
set_gp_regs_field_ptr!(vp_reg_page, rax, ret_rax);
// SAFETY: access union fields
unsafe {
(*vp_reg_page).__bindgen_anon_1.__bindgen_anon_1.rip =
info.header.rip + insn_len;
(*vp_reg_page).dirty |= 1 << HV_X64_REGISTER_CLASS_IP;
}
} else {
let arr_reg_name_value = [
(
hv_register_name_HV_X64_REGISTER_RIP,
info.header.rip + insn_len,
),
(hv_register_name_HV_X64_REGISTER_RAX, ret_rax),
];
set_registers_64!(self.fd, arr_reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
}
self.advance_rip_update_rax(&info, ret_rax)?;
return Ok(cpu::VmExit::Ignore);
}
_ => {}
@@ -1747,6 +1719,42 @@ impl MshvVcpu {
Ok(())
}
#[cfg(target_arch = "x86_64")]
fn advance_rip_update_rax(
&self,
info: &hv_x64_io_port_intercept_message,
ret_rax: u64,
) -> cpu::Result<()> {
let insn_len = info.header.instruction_length() as u64;
/*
* Advance RIP and update RAX
* First, try to update the registers using VP register page
* which is mapped into user space for faster access.
* If the register page is not available, fall back to regular
* IOCTL to update the registers.
*/
if let Some(reg_page) = self.fd.get_vp_reg_page() {
let vp_reg_page = reg_page.0;
set_gp_regs_field_ptr!(vp_reg_page, rax, ret_rax);
// SAFETY: access union fields
unsafe {
(*vp_reg_page).__bindgen_anon_1.__bindgen_anon_1.rip = info.header.rip + insn_len;
(*vp_reg_page).dirty |= 1 << HV_X64_REGISTER_CLASS_IP;
}
} else {
let arr_reg_name_value = [
(
hv_register_name_HV_X64_REGISTER_RIP,
info.header.rip + insn_len,
),
(hv_register_name_HV_X64_REGISTER_RAX, ret_rax),
];
set_registers_64!(self.fd, arr_reg_name_value)
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
}
Ok(())
}
}
/// Wrapper over Mshv VM ioctls.