From b5aeb1f63ce1a9e843537553327616f13760d838 Mon Sep 17 00:00:00 2001 From: Muminul Islam Date: Thu, 17 Apr 2025 13:06:18 -0700 Subject: [PATCH] hypervisor: mshv: use mapped register page for port handling MSHV allows VMM to map the VP register page into root. This feature helps VMM to faster process most of the frequent used registers. This patch uses the VP register page for port handling in CPU run method. Signed-off-by: Muminul Islam --- hypervisor/src/mshv/mod.rs | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 555486034..81f9a5e36 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -720,17 +720,34 @@ 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()))?; + } - /* Advance RIP and update RAX */ - 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); } _ => {}