mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
committed by
Muminul Islam Russell
parent
1c22c4a57b
commit
3c63779302
+37
-29
@@ -717,35 +717,7 @@ impl cpu::Vcpu for MshvVcpu {
|
|||||||
*/
|
*/
|
||||||
match port {
|
match port {
|
||||||
0x402 | 0x510 | 0x511 | 0x514 => {
|
0x402 | 0x510 | 0x511 | 0x514 => {
|
||||||
let insn_len = info.header.instruction_length() as u64;
|
self.advance_rip_update_rax(&info, ret_rax)?;
|
||||||
/*
|
|
||||||
* 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()))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(cpu::VmExit::Ignore);
|
return Ok(cpu::VmExit::Ignore);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -1747,6 +1719,42 @@ impl MshvVcpu {
|
|||||||
|
|
||||||
Ok(())
|
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.
|
/// Wrapper over Mshv VM ioctls.
|
||||||
|
|||||||
Reference in New Issue
Block a user