From 51e30f8f58a1eaa510163022d1f347d45eae2f43 Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Thu, 1 Aug 2024 11:32:20 +0000 Subject: [PATCH] Propagate MemoryFault exit reason in KVM_RUN Signed-off-by: Nikita Kalyazin --- src/ioctls/vcpu.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/ioctls/vcpu.rs b/src/ioctls/vcpu.rs index afa75ada..60117d88 100644 --- a/src/ioctls/vcpu.rs +++ b/src/ioctls/vcpu.rs @@ -166,6 +166,12 @@ pub enum VcpuExit<'a> { X86Rdmsr(ReadMsrExit<'a>), /// Corresponds to KVM_EXIT_X86_WRMSR. X86Wrmsr(WriteMsrExit<'a>), + /// Corresponds to KVM_EXIT_MEMORY_FAULT. + MemoryFault( + u64, /* flags */ + u64, /* gpa */ + u64, /* size */ + ), /// Corresponds to an exit reason that is unknown from the current version /// of the kvm-ioctls crate. Let the consumer decide about what to do with /// it. @@ -1568,6 +1574,17 @@ impl VcpuFd { KVM_EXIT_HYPERV => Ok(VcpuExit::Hyperv), r => Ok(VcpuExit::Unsupported(r)), } + } else if ret == -1 && errno::Error::last() == errno::Error::new(libc::EFAULT) { + let run = self.kvm_run_ptr.as_mut_ref(); + match run.exit_reason { + KVM_EXIT_MEMORY_FAULT => { + // SAFETY: Safe because the exit_reason (which comes from the kernel) told us + // which union field to use. + let fault = unsafe { &mut run.__bindgen_anon_1.memory_fault }; + Ok(VcpuExit::MemoryFault(fault.flags, fault.gpa, fault.size)) + } + _ => Err(errno::Error::last()) + } } else { Err(errno::Error::last()) }