Implement anonymous fmap

This commit is contained in:
Jeremy Soller
2021-09-22 21:04:04 -06:00
parent 17309754d6
commit 64f1533d6f
3 changed files with 40 additions and 21 deletions

View File

@@ -13,25 +13,8 @@ impl MemoryScheme {
pub fn new() -> Self {
MemoryScheme
}
}
impl Scheme for MemoryScheme {
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
Ok(0)
}
fn fstatvfs(&self, _file: usize, stat: &mut StatVfs) -> Result<usize> {
let used = used_frames() as u64;
let free = free_frames() as u64;
stat.f_bsize = PAGE_SIZE as u32;
stat.f_blocks = used + free;
stat.f_bfree = free;
stat.f_bavail = stat.f_bfree;
Ok(0)
}
fn fmap(&self, _id: usize, map: &Map) -> Result<usize> {
pub fn fmap_anonymous(map: &Map) -> Result<usize> {
//TODO: Abstract with other grant creation
if map.size == 0 {
Ok(0)
@@ -63,6 +46,27 @@ impl Scheme for MemoryScheme {
Ok(region.start_address().data())
}
}
}
impl Scheme for MemoryScheme {
fn open(&self, _path: &str, _flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
Ok(0)
}
fn fstatvfs(&self, _file: usize, stat: &mut StatVfs) -> Result<usize> {
let used = used_frames() as u64;
let free = free_frames() as u64;
stat.f_bsize = PAGE_SIZE as u32;
stat.f_blocks = used + free;
stat.f_bfree = free;
stat.f_bavail = stat.f_bfree;
Ok(0)
}
fn fmap(&self, _id: usize, map: &Map) -> Result<usize> {
Self::fmap_anonymous(map)
}
fn fmap_old(&self, id: usize, map: &OldMap) -> Result<usize> {
if map.flags.contains(MapFlags::MAP_FIXED) {
// not supported for fmap, which lacks the address argument.

View File

@@ -25,14 +25,14 @@ pub use self::process::*;
pub use self::time::*;
pub use self::validate::*;
use self::data::{SigAction, TimeSpec};
use self::data::{Map, SigAction, TimeSpec};
use self::error::{Error, Result, ENOSYS};
use self::flag::{CloneFlags, MapFlags, PhysmapFlags, WaitFlags};
use self::number::*;
use crate::context::ContextId;
use crate::interrupt::InterruptStack;
use crate::scheme::{FileHandle, SchemeNamespace};
use crate::scheme::{FileHandle, SchemeNamespace, memory::MemoryScheme};
/// Debug
pub mod debug;
@@ -68,7 +68,12 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
SYS_CLASS_FILE => {
let fd = FileHandle::from(b);
match a & SYS_ARG {
SYS_ARG_SLICE => file_op_slice(a, fd, validate_slice(c as *const u8, d)?),
SYS_ARG_SLICE => match a {
SYS_FMAP if b == !0 => {
MemoryScheme::fmap_anonymous(unsafe { validate_ref(c as *const Map, d)? })
},
_ => file_op_slice(a, fd, validate_slice(c as *const u8, d)?),
}
SYS_ARG_MSLICE => file_op_mut_slice(a, fd, validate_slice_mut(c as *mut u8, d)?),
_ => match a {
SYS_CLOSE => close(fd),

View File

@@ -31,6 +31,16 @@ fn validate(address: usize, size: usize, writable: bool) -> Result<()> {
Ok(())
}
/// Convert a pointer and length to reference, if valid
pub unsafe fn validate_ref<T>(ptr: *const T, size: usize) -> Result<&'static T> {
if size == mem::size_of::<T>() {
validate(ptr as usize, mem::size_of::<T>(), false)?;
Ok(unsafe { &*ptr })
} else {
Err(Error::new(EINVAL))
}
}
/// Convert a pointer and length to slice, if valid
//TODO: Mark unsafe
pub fn validate_slice<T>(ptr: *const T, len: usize) -> Result<&'static [T]> {