1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-22 08:06:17 +04:00

RISC-V 64 RVM support

This commit is contained in:
gjz010 2021-05-11 02:10:15 +08:00
parent 2d732a48d8
commit 067dc4e3f5
2 changed files with 59 additions and 13 deletions

View File

@ -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<BTreeMap<usize, Guest>>,
vcpus: RwLock<BTreeMap<usize, Vcpu>>,
@ -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::<RvmGuestAddMemoryRegionArgs>::from(data)
.read()
.or(Err(FsError::InvalidParam))?;
let mut ptr = UserInOutPtr::<RvmGuestAddMemoryRegionArgs>::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(
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)
.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::<RvmGuestSetTrapArgs>::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
}

View File

@ -17,6 +17,10 @@ pub(super) struct Guest {
pub(super) struct Vcpu {
pub(super) inner: Mutex<VcpuInner>,
//#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
//inner_id: usize,
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
pub(super) irq: Arc<rvm::InterruptState>,
}
impl Guest {
@ -47,8 +51,22 @@ impl Guest {
impl Vcpu {
pub fn new(entry: u64, guest: Arc<GuestInner>) -> RvmResult<Self> {
#[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,
});
}
}
}