Verified Commit 01041a5d authored by 4lDO2's avatar 4lDO2 🖖

Implement (mostly) fmap2 for `memory:`

parent 92cad589
......@@ -196,10 +196,16 @@ impl Grant {
pub fn start_address(&self) -> VirtualAddress {
self.start
}
pub unsafe fn set_start_address(&mut self, start: VirtualAddress) {
self.start = start;
}
pub fn size(&self) -> usize {
self.size
}
pub unsafe fn set_size(&mut self, size: usize) {
self.size = size;
}
pub fn flags(&self) -> EntryFlags {
self.flags
......
use crate::context;
use crate::context::memory::Grant;
use crate::memory::{free_frames, used_frames};
use crate::memory::{free_frames, used_frames, PAGE_SIZE};
use crate::paging::VirtualAddress;
use crate::paging::entry::EntryFlags;
use crate::syscall::data::{Map, StatVfs};
use crate::syscall::data::{Map, Map2, StatVfs};
use crate::syscall::error::*;
use crate::syscall::flag::{PROT_EXEC, PROT_READ, PROT_WRITE};
use crate::syscall::flag::{MapFlags, PROT_EXEC, PROT_READ, PROT_WRITE};
use crate::syscall::scheme::Scheme;
pub struct MemoryScheme;
......@@ -24,7 +24,7 @@ impl Scheme for MemoryScheme {
let used = used_frames() as u64;
let free = free_frames() as u64;
stat.f_bsize = 4096;
stat.f_bsize = PAGE_SIZE as u32;
stat.f_blocks = used + free;
stat.f_bfree = free;
stat.f_bavail = stat.f_bfree;
......@@ -32,7 +32,7 @@ impl Scheme for MemoryScheme {
Ok(0)
}
fn fmap(&self, _id: usize, map: &Map) -> Result<usize> {
fn fmap2(&self, _id: usize, map: &Map2) -> Result<usize> {
//TODO: Abstract with other grant creation
if map.size == 0 {
Ok(0)
......@@ -41,10 +41,19 @@ impl Scheme for MemoryScheme {
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let fixed = map.flags.contains(MapFlags::MAP_FIXED);
let fixed_noreplace = map.flags.contains(MapFlags::MAP_FIXED_NOREPLACE);
let mut grants = context.grants.lock();
let full_size = ((map.size + 4095)/4096) * 4096;
let mut to_address = crate::USER_GRANT_OFFSET;
let full_size = ((map.size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
let mut to_address = if map.address == 0 { crate::USER_GRANT_OFFSET } else {
if map.address < crate::USER_GRANT_OFFSET || map.address + map.size > crate::USER_GRANT_OFFSET + crate::PML4_SIZE || map.address % PAGE_SIZE != 0 {
return Err(Error::new(EINVAL));
}
map.address
};
let mut entry_flags = EntryFlags::PRESENT | EntryFlags::USER_ACCESSIBLE;
if !map.flags.contains(PROT_EXEC) {
......@@ -58,27 +67,85 @@ impl Scheme for MemoryScheme {
}
let mut i = 0;
while i < grants.len() {
let start = grants[i].start_address().get();
if to_address + full_size < start {
break;
while i < grants.len() {
let grant = &mut grants[i];
let mut grant_start = grant.start_address().get();
let mut grant_len = ((grant.size() + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
let mut grant_end = grant_start + grant_len;
if grant_end <= to_address {
// grant has nothing to do with the memory to map, and thus we can safely just
// go on to the next one.
if !fixed {
to_address = grant_end;
}
i += 1;
continue;
}
// check whether this grant overlaps with the memory range to use, by checking that
// the start and end of the grant is not within the memory range to map
if grant_start <= to_address && grant_end > to_address || grant_start <= to_address + full_size && grant_end > to_address + full_size {
// the range overlaps, thus we'll have to continue to the next grant, or to
// insert a new grant at the end (if not MapFlags::MAP_FIXED).
if fixed_noreplace {
return Err(Error::new(EEXIST));
} else if fixed {
/*
// shrink the grant, removing it if necessary. since the to_address isn't
// changed at all when mapping to a fixed address, we can just continue to
// the next grant and shrink or remove that one if it was also overlapping.
if to_address + full_size > grant_start {
let new_start = core::cmp::min(grant_end, to_address + full_size);
let new_size = grant.size() - (new_start - grant_start);
unsafe { grant.set_size(new_size) };
grant_len = ((new_size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
let new_start = VirtualAddress::new(new_start);
unsafe { grant.set_start_address(new_start) };
grant_start = new_start;
grant_end = grant_start + grant_len;
}
*/
// TODO
return Err(Error::new(EOPNOTSUPP));
} else {
to_address = grant_end;
i += 1;
}
continue;
}
let pages = (grants[i].size() + 4095) / 4096;
let end = start + pages * 4096;
to_address = end;
i += 1;
}
grants.insert(i, Grant::map(
VirtualAddress::new(to_address),
full_size,
entry_flags
entry_flags,
));
Ok(to_address)
}
}
fn fmap(&self, id: usize, map: &Map) -> Result<usize> {
if map.flags.contains(MapFlags::MAP_FIXED) {
// not supported for fmap, which lacks the address argument.
return Err(Error::new(EINVAL));
}
self.fmap2(id, &Map2 {
offset: map.offset,
size: map.size,
flags: map.flags,
address: 0,
})
}
fn fcntl(&self, _id: usize, _cmd: usize, _arg: usize) -> Result<usize> {
Ok(0)
......
Subproject commit 122878874d3f4fee0fd1f19b8dc2b07d84d5df8b
Subproject commit 27fcecb30fb3154a9b45f66756d64f8f48281a7b
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment