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 <skinsburskii@linux.microsoft.com>
This commit is contained in:
Stanislav Kinsburskii 2026-01-13 08:03:26 -08:00 committed by Rob Bradford
parent 5aba9b4308
commit de2d8f486b
3 changed files with 34 additions and 2 deletions

View file

@ -711,7 +711,7 @@ mod mock_vmm {
insn: &[u8],
num_insn: Option<usize>,
) -> MockResult {
let mut state = self
let state = self
.cpu_state(cpu_id)
.map_err(EmulationError::PlatformEmulationError)?;
let ip = state.ip();

View file

@ -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)

View file

@ -106,6 +106,38 @@ impl MshvEmulatorContext<'_> {
Ok(())
}
pub fn update_cpu_state(
&self,
cpu_id: usize,
old_state: <Self as PlatformEmulator>::CpuState,
new_state: <Self as PlatformEmulator>::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