diff --git a/hypervisor/src/mshv/aarch64/emulator.rs b/hypervisor/src/mshv/aarch64/emulator.rs index 08311aa93..a97659840 100644 --- a/hypervisor/src/mshv/aarch64/emulator.rs +++ b/hypervisor/src/mshv/aarch64/emulator.rs @@ -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 { let esr_el2 = EsrEl2::from(self.context.syndrome); if !matches!( diff --git a/hypervisor/src/mshv/mod.rs b/hypervisor/src/mshv/mod.rs index 77595d95c..ccf5d8ea6 100644 --- a/hypervisor/src/mshv/mod.rs +++ b/hypervisor/src/mshv/mod.rs @@ -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) => {