From ae7c38444988c3ab182d1b51cbd2cfb29a5d8afc Mon Sep 17 00:00:00 2001 From: Zhang Junyu Date: Mon, 27 Apr 2026 14:22:38 +0800 Subject: [PATCH] refine: Refine apple hypervisor vcpu --- crates/vm-core/src/virtualization/hvp/vcpu.rs | 57 +++++++++---------- crates/vm-core/src/virtualization/hvp/vm.rs | 2 +- .../src/virtualization/vcpu/command.rs | 2 + 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/crates/vm-core/src/virtualization/hvp/vcpu.rs b/crates/vm-core/src/virtualization/hvp/vcpu.rs index bab51f2..0a3e2ef 100644 --- a/crates/vm-core/src/virtualization/hvp/vcpu.rs +++ b/crates/vm-core/src/virtualization/hvp/vcpu.rs @@ -1,6 +1,7 @@ use std::ptr::null_mut; use std::sync::Arc; use std::sync::Mutex; +use std::thread::JoinHandle; use applevisor_sys::hv_error_t; use applevisor_sys::hv_vcpu_create; @@ -189,75 +190,65 @@ impl AArch64Vcpu for HvpVcpuInternal { fn handle_command( running: &mut bool, hvp_vcpu_handler: Arc>, - cmd: VcpuCommandRequest, -) -> Result<(), VcpuError> { - match cmd.cmd { + cmd: VcpuCommand, +) -> Result { + match cmd { VcpuCommand::ReadRegisters => { let mut handler = hvp_vcpu_handler.lock().unwrap(); let registers = handler.read_registers()?; - cmd.response - .send(VcpuCommandResponse::Registers(Box::new(registers))) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + Ok(VcpuCommandResponse::Registers(Box::new(registers))) } VcpuCommand::WriteRegisters(registers) => { - let mut handler = hvp_vcpu_handler.lock().unwrap(); + let mut handler: std::sync::MutexGuard<'_, HvpVcpuInternal> = + hvp_vcpu_handler.lock().unwrap(); handler.write_registers(registers)?; - cmd.response - .send(VcpuCommandResponse::Empty) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + Ok(VcpuCommandResponse::Empty) } VcpuCommand::ReadCoreRegisters => { let mut handler = hvp_vcpu_handler.lock().unwrap(); let registers = handler.read_core_registers()?; - cmd.response - .send(VcpuCommandResponse::CoreRegisters(Box::new(registers))) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + Ok(VcpuCommandResponse::CoreRegisters(Box::new(registers))) } VcpuCommand::WriteCoreRegisters(registers) => { let mut handler = hvp_vcpu_handler.lock().unwrap(); handler.write_core_registers(registers)?; - cmd.response - .send(VcpuCommandResponse::Empty) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + Ok(VcpuCommandResponse::Empty) } VcpuCommand::TranslateGvaToGpa(gva) => { let handler = hvp_vcpu_handler.lock().unwrap(); let gpa = handler.translate_gva_to_gpa(gva)?; - cmd.response - .send(VcpuCommandResponse::TranslateGvaToGpa(gpa)) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + Ok(VcpuCommandResponse::TranslateGvaToGpa(gpa)) } VcpuCommand::Resume => { *running = true; - cmd.response - .send(VcpuCommandResponse::Empty) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + + Ok(VcpuCommandResponse::Empty) } VcpuCommand::Pause => { *running = false; - cmd.response - .send(VcpuCommandResponse::Empty) - .map_err(|_| VcpuError::VcpuCommandDisconnected)?; + + Ok(VcpuCommandResponse::Empty) } } - - Ok(()) } pub struct HvpVcpu { vcpu_id: usize, handler: Arc>, command_tx: Sender, + // TODO: handle gracefully shutdown + #[allow(dead_code)] + join_handler: JoinHandle>, } impl HvpVcpu { @@ -269,7 +260,7 @@ impl HvpVcpu { let (handler_tx, handler_rx) = std::sync::mpsc::channel(); let (command_tx, mut command_rx) = tokio::sync::mpsc::channel(8); - let _join_handler = std::thread::spawn(move || -> Result<(), VcpuError> { + let join_handler = std::thread::spawn(move || -> Result<(), VcpuError> { let mut vcpu = 0; let mut exit = null_mut() as *const hv_vcpu_exit_t; hv_unsafe_call!(hv_vcpu_create(&mut vcpu, &mut exit, null_mut()))?; @@ -316,8 +307,13 @@ impl HvpVcpu { .ok_or(VcpuError::VcpuCommandDisconnected)?; } - if let Err(err) = handle_command(&mut running, hvp_vcpu_handler.clone(), cmd) { - error!(?err, "Failed to handle cmd") + if let Err(_err) = + match handle_command(&mut running, hvp_vcpu_handler.clone(), cmd.cmd) { + Ok(resp) => cmd.response.send(resp), + Err(err) => cmd.response.send(VcpuCommandResponse::Err(err)), + } + { + error!("Failed to send response of vcpu command"); } } }); @@ -328,6 +324,7 @@ impl HvpVcpu { vcpu_id, handler, command_tx, + join_handler, }) } } diff --git a/crates/vm-core/src/virtualization/hvp/vm.rs b/crates/vm-core/src/virtualization/hvp/vm.rs index 4739377..ca36380 100644 --- a/crates/vm-core/src/virtualization/hvp/vm.rs +++ b/crates/vm-core/src/virtualization/hvp/vm.rs @@ -36,7 +36,7 @@ impl From for MemPerms { } #[derive(Default)] -pub struct AppleHypervisorVm {} +pub struct AppleHypervisorVm; impl HypervisorVm for AppleHypervisorVm { fn create_vcpu( diff --git a/crates/vm-core/src/virtualization/vcpu/command.rs b/crates/vm-core/src/virtualization/vcpu/command.rs index a491082..af885d2 100644 --- a/crates/vm-core/src/virtualization/vcpu/command.rs +++ b/crates/vm-core/src/virtualization/vcpu/command.rs @@ -2,6 +2,7 @@ use tokio::sync::oneshot; use crate::arch::registers::ArchCoreRegisters; use crate::arch::registers::ArchRegisters; +use crate::virtualization::vcpu::error::VcpuError; pub enum VcpuCommand { ReadRegisters, @@ -18,6 +19,7 @@ pub enum VcpuCommandResponse { CoreRegisters(Box), Registers(Box), TranslateGvaToGpa(Option), + Err(VcpuError), } pub struct VcpuCommandRequest {