Commit f3650661 authored by Jeremy Soller's avatar Jeremy Soller

Update funmap support

parent 4329aa43
This diff is collapsed.
[package]
name = "kernel"
version = "0.1.52"
version = "0.1.53"
build = "build.rs"
[lib]
......
......@@ -19,7 +19,7 @@ pub struct Grant {
flags: EntryFlags,
mapped: bool,
//TODO: This is probably a very heavy way to keep track of fmap'd files, perhaps move to the context?
desc_opt: Option<FileDescriptor>,
pub desc_opt: Option<FileDescriptor>,
}
impl Grant {
......@@ -133,6 +133,11 @@ impl Grant {
flush_all.flush(&mut active_table);
if let Some(desc) = self.desc_opt.take() {
//TODO: This imposes a large cost on unmapping, but that cost cannot be avoided without modifying fmap and funmap
let _ = desc.close();
}
self.mapped = false;
}
......
......@@ -30,6 +30,7 @@ pub struct UserInner {
context: Weak<RwLock<Context>>,
todo: WaitQueue<Packet>,
fmap: Mutex<BTreeMap<u64, (Weak<RwLock<Context>>, FileDescriptor, Map)>>,
funmap: Mutex<BTreeMap<usize, usize>>,
done: WaitMap<u64, usize>
}
......@@ -45,6 +46,7 @@ impl UserInner {
context: context,
todo: WaitQueue::new(),
fmap: Mutex::new(BTreeMap::new()),
funmap: Mutex::new(BTreeMap::new()),
done: WaitMap::new()
}
}
......@@ -192,7 +194,11 @@ impl UserInner {
if let Some((context_weak, desc, map)) = self.fmap.lock().remove(&packet.id) {
if let Ok(address) = Error::demux(packet.a) {
//TODO: Protect against sharing addresses that are not page aligned
packet.a = Error::mux(UserInner::capture_inner(&context_weak, address, map.size, map.flags, Some(desc)));
let res = UserInner::capture_inner(&context_weak, address, map.size, map.flags, Some(desc));
if let Ok(new_address) = res {
self.funmap.lock().insert(new_address, address);
}
packet.a = Error::mux(res);
} else {
let _ = desc.close();
}
......@@ -358,6 +364,19 @@ impl Scheme for UserScheme {
result
}
fn funmap(&self, new_address: usize) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address_opt = {
let mut funmap = inner.funmap.lock();
funmap.remove(&new_address)
};
if let Some(address) = address_opt {
inner.call(SYS_FUNMAP, address, 0, 0)
} else {
Err(Error::new(EINVAL))
}
}
fn fpath(&self, file: usize, buf: &mut [u8]) -> Result<usize> {
let inner = self.inner.upgrade().ok_or(Error::new(ENODEV))?;
let address = inner.capture_mut(buf)?;
......
......@@ -413,22 +413,47 @@ pub fn funmap(virtual_address: usize) -> Result<usize> {
if virtual_address == 0 {
Ok(0)
} else {
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
let mut desc_opt = None;
let mut grants = context.grants.lock();
for i in 0 .. grants.len() {
let start = grants[i].start_address().get();
let end = start + grants[i].size();
if virtual_address >= start && virtual_address < end {
grants.remove(i).unmap();
{
let contexts = context::contexts();
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
let context = context_lock.read();
return Ok(0);
let mut grants = context.grants.lock();
for i in 0 .. grants.len() {
let start = grants[i].start_address().get();
let end = start + grants[i].size();
if virtual_address >= start && virtual_address < end {
let mut grant = grants.remove(i);
if grant.desc_opt.is_some() {
desc_opt = grant.desc_opt.take();
grant.unmap();
break;
}
}
}
}
Err(Error::new(EFAULT))
if let Some(desc) = desc_opt {
let scheme_id = {
let description = desc.description.read();
description.scheme
};
let scheme = {
let schemes = scheme::schemes();
let scheme = schemes.get(scheme_id).ok_or(Error::new(EBADF))?;
scheme.clone()
};
let res = scheme.funmap(virtual_address);
let _ = desc.close();
res
} else {
Err(Error::new(EFAULT))
}
}
}
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