From d374101f386baec6e451697a95cf53182ef2a0e6 Mon Sep 17 00:00:00 2001 From: Jinank Jain Date: Wed, 16 Apr 2025 05:13:01 +0000 Subject: [PATCH] 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 --- hypervisor/src/mshv/aarch64/emulator.rs | 2 +- hypervisor/src/mshv/mod.rs | 35 ++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) 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) => {