From de2d8f486b64d6c62e7fb30ae210d08baf5b83f1 Mon Sep 17 00:00:00 2001 From: Stanislav Kinsburskii Date: Tue, 13 Jan 2026 08:03:26 -0800 Subject: [PATCH] hypervisor: mshv: Introduce CPU state update function and use it In most of the cases, special registers don't change after emulations, but current code sets them back unconditionally, and although some of them are set over the register page, others require a system call and a hypervisor to be updated, which is a waste it there were not changes. Introduce and CPU update method for Microsoft Hypervisor emulator and set special registers only when they were changed. This change reduces guest boot time by 4% for a single VP guest boot (in L1VH partition) in my experiments. Signed-off-by: Stanislav Kinsburskii --- hypervisor/src/arch/x86/emulator/mod.rs | 2 +- hypervisor/src/mshv/mod.rs | 2 +- hypervisor/src/mshv/x86_64/emulator.rs | 32 +++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/hypervisor/src/arch/x86/emulator/mod.rs b/hypervisor/src/arch/x86/emulator/mod.rs index 35a35a0ec..4b60ceb71 100644 --- a/hypervisor/src/arch/x86/emulator/mod.rs +++ b/hypervisor/src/arch/x86/emulator/mod.rs @@ -711,7 +711,7 @@ mod mock_vmm { insn: &[u8], num_insn: Option, ) -> MockResult { - let mut state = self + let state = self .cpu_state(cpu_id) .map_err(EmulationError::PlatformEmulationError)?; let ip = state.ip(); diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 43597ba6d..0c8d2632c 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -733,7 +733,7 @@ impl cpu::Vcpu for MshvVcpu { // Set CPU state back. context - .set_cpu_state(self.vp_index as usize, new_state) + .update_cpu_state(self.vp_index as usize, old_state, new_state) .map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?; Ok(cpu::VmExit::Ignore) diff --git a/hypervisor/src/mshv/x86_64/emulator.rs b/hypervisor/src/mshv/x86_64/emulator.rs index 3000cdf59..d668dedde 100644 --- a/hypervisor/src/mshv/x86_64/emulator.rs +++ b/hypervisor/src/mshv/x86_64/emulator.rs @@ -106,6 +106,38 @@ impl MshvEmulatorContext<'_> { Ok(()) } + + pub fn update_cpu_state( + &self, + cpu_id: usize, + old_state: ::CpuState, + new_state: ::CpuState, + ) -> Result<(), PlatformError> { + if cpu_id != self.vcpu.vp_index as usize { + return Err(PlatformError::SetCpuStateFailure(anyhow!( + "CPU id mismatch {:?} {:?}", + cpu_id, + self.vcpu.vp_index + ))); + } + + debug!("mshv emulator: Updating CPU state"); + debug!("mshv emulator: {:#x?}", new_state.regs); + + self.vcpu + .set_regs(&new_state.regs) + .map_err(|e| PlatformError::SetCpuStateFailure(e.into()))?; + + if old_state.sregs != new_state.sregs { + debug!("mshv emulator: Updating CPU special registers"); + debug!("mshv emulator: {:#x?}", new_state.sregs); + self.vcpu + .set_sregs(&new_state.sregs) + .map_err(|e| PlatformError::SetCpuStateFailure(e.into()))?; + } + + Ok(()) + } } /// Platform emulation for Hyper-V