diff --git a/kernel/src/rvm/inode.rs b/kernel/src/rvm/inode.rs index b5955965..dc38245e 100644 --- a/kernel/src/rvm/inode.rs +++ b/kernel/src/rvm/inode.rs @@ -26,6 +26,11 @@ const RVM_VCPU_READ_STATE: u32 = RVM_IO + 0x13; const RVM_VCPU_WRITE_STATE: u32 = RVM_IO + 0x14; const RVM_VCPU_INTERRUPT: u32 = RVM_IO + 0x15; +const RVM_RISCV_SET_SSIP: u32 = 0; +const RVM_RISCV_CLEAR_SSIP: u32 = 1; +const RVM_RISCV_SET_SEIP: u32 = 2; +const RVM_RISCV_CLEAR_SEIP: u32 = 3; + pub struct RvmINode { guests: RwLock>, vcpus: RwLock>, @@ -44,6 +49,7 @@ struct RvmGuestAddMemoryRegionArgs { vmid: u16, guest_start_paddr: u64, memory_size: u64, + userspace_addr: u64, } #[repr(C)] @@ -118,16 +124,19 @@ impl INode for RvmINode { self.guest_create().map_err(into_fs_error) } RVM_GUEST_ADD_MEMORY_REGION => { - let args = UserInPtr::::from(data) - .read() - .or(Err(FsError::InvalidParam))?; + let mut ptr = UserInOutPtr::::from(data); + let mut args = ptr.read().or(Err(FsError::InvalidParam))?; info!("[RVM] ioctl RVM_GUEST_ADD_MEMORY_REGION {:x?}", args); - self.guest_add_memory_region( - args.vmid as usize, - args.guest_start_paddr as usize, - args.memory_size as usize, - ) - .map_err(into_fs_error) + let userspace_addr = self + .guest_add_memory_region( + args.vmid as usize, + args.guest_start_paddr as usize, + args.memory_size as usize, + ) + .map_err(into_fs_error)?; + args.userspace_addr = userspace_addr as u64; + ptr.write(args).or(Err(FsError::DeviceError))?; + Ok(0) } RVM_GUEST_SET_TRAP => { let args = UserInPtr::::from(data) @@ -354,7 +363,7 @@ impl RvmINode { Err(RvmError::InvalidParam) } } - + #[cfg(any(target_arch = "x86_64"))] fn vcpu_interrupt(&self, vcpu_id: usize, vector: u32) -> RvmResult<()> { if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) { vcpu.inner.lock().virtual_interrupt(vector) @@ -362,6 +371,25 @@ impl RvmINode { Err(RvmError::InvalidParam) } } + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + fn vcpu_interrupt(&self, vcpu_id: usize, arg: u32) -> RvmResult<()> { + if let Some(vcpu) = self.vcpus.write().get_mut(&vcpu_id) { + //vcpu.inner.lock().virtual_interrupt(vector) + let irq = &vcpu.irq; + match arg { + self::RVM_RISCV_SET_SSIP => irq.set_software_interrupt(true), + self::RVM_RISCV_CLEAR_SSIP => irq.set_software_interrupt(false), + self::RVM_RISCV_SET_SEIP => irq.set_external_interrupt(true), + self::RVM_RISCV_CLEAR_SEIP => irq.set_external_interrupt(false), + _ => { + return Err(RvmError::InvalidParam); + } + } + Ok(()) + } else { + Err(RvmError::InvalidParam) + } + } // TODO: remove guest & vcpu } diff --git a/kernel/src/rvm/structs.rs b/kernel/src/rvm/structs.rs index 7934b8ba..8bb7f3ba 100644 --- a/kernel/src/rvm/structs.rs +++ b/kernel/src/rvm/structs.rs @@ -17,6 +17,10 @@ pub(super) struct Guest { pub(super) struct Vcpu { pub(super) inner: Mutex, + //#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + //inner_id: usize, + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + pub(super) irq: Arc, } impl Guest { @@ -47,8 +51,22 @@ impl Guest { impl Vcpu { pub fn new(entry: u64, guest: Arc) -> RvmResult { - Ok(Self { - inner: Mutex::new(VcpuInner::new(entry, guest)?), - }) + #[cfg(any(target_arch = "x86_64"))] + { + Ok(Self { + inner: Mutex::new(VcpuInner::new(entry, guest)?), + }) + } + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + { + let inner = VcpuInner::new(entry, Arc::clone(&guest))?; + let inner_id = inner.get_id(); + let irq = guest.get_irq_by_id(inner_id); + return Ok(Self { + inner: Mutex::new(inner), + //inner_id, + irq, + }); + } } }