hypervisor: Use instruction emulator to handle unmapped gpa

Use the context from Unmapped Gpa exit from the hypervisor to initialize
the MshvEmulatorContext and later call the emulator to decode the
instruction.

Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
This commit is contained in:
Jinank Jain 2025-04-16 05:13:01 +00:00
parent 461e31e6d8
commit d374101f38
2 changed files with 35 additions and 2 deletions

View file

@ -28,7 +28,7 @@ impl<'a> Emulator<'a> {
Emulator { context }
}
/// Decode the instruction using the syndrome register.
/// Decode & emulate the instruction using the syndrome register.
pub fn emulate_with_syndrome(&mut self) -> Result<bool, PlatformError> {
let esr_el2 = EsrEl2::from(self.context.syndrome);
if !matches!(

View file

@ -24,7 +24,8 @@ use vm_memory::bitmap::AtomicBitmap;
use crate::arch::emulator::PlatformEmulator;
#[cfg(target_arch = "x86_64")]
use crate::arch::x86::emulator::Emulator;
#[cfg(target_arch = "x86_64")]
#[cfg(target_arch = "aarch64")]
use crate::mshv::aarch64::emulator;
use crate::mshv::emulator::MshvEmulatorContext;
use crate::vm::{self, InterruptSourceConfig, VmOps};
use crate::{cpu, hypervisor, vec_with_array_field, HypervisorType};
@ -777,6 +778,38 @@ impl cpu::Vcpu for MshvVcpu {
.map_err(|e| cpu::HypervisorCpuError::SetRegister(e.into()))?;
Ok(cpu::VmExit::Ignore)
}
#[cfg(target_arch = "aarch64")]
hv_message_type_HVMSG_UNMAPPED_GPA => {
let info = x.to_memory_info().unwrap();
let gva = info.guest_virtual_address;
let gpa = info.guest_physical_address;
debug!("Unmapped GPA exit: GVA {:x} GPA {:x}", gva, gpa);
let context = MshvEmulatorContext {
vcpu: self,
map: (gva, gpa),
syndrome: info.syndrome,
instruction_bytes: info.instruction_bytes,
instruction_byte_count: info.instruction_byte_count,
// SAFETY: Accessing a union element from bindgen generated bindings.
interruption_pending: unsafe {
info.header
.execution_state
.__bindgen_anon_1
.interruption_pending()
!= 0
},
pc: info.header.pc,
};
let mut emulator = emulator::Emulator::new(context);
emulator
.emulate()
.map_err(|e| cpu::HypervisorCpuError::RunVcpu(e.into()))?;
Ok(cpu::VmExit::Ignore)
}
#[cfg(target_arch = "x86_64")]
msg_type @ (hv_message_type_HVMSG_UNMAPPED_GPA
| hv_message_type_HVMSG_GPA_INTERCEPT) => {