Merge pull request #783 from redox-os/fix_virtualbox_issues
Fix Virtualbox failures
This commit is contained in:
commit
0b04c9e3b4
|
@ -1,3 +1,2 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[macro_export]
|
|
||||||
pub mod int_like;
|
pub mod int_like;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//! The Redox OS Kernel is a hybrid kernel that supports X86_64 systems and
|
//! The Redox OS Kernel is a hybrid kernel that supports X86_64 systems and
|
||||||
//! provides Unix-like syscalls for primarily Rust applications
|
//! provides Unix-like syscalls for primarily Rust applications
|
||||||
|
|
||||||
|
#![deny(warnings)]
|
||||||
#![feature(alloc)]
|
#![feature(alloc)]
|
||||||
#![feature(arc_counts)]
|
#![feature(arc_counts)]
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
|
@ -46,7 +47,6 @@ use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||||
use scheme::FileHandle;
|
use scheme::FileHandle;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
#[macro_export]
|
|
||||||
/// Shared data structures
|
/// Shared data structures
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
|
||||||
|
|
|
@ -450,6 +450,41 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
|
||||||
Ok(pid)
|
Ok(pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn empty(context: &mut context::Context, reaping: bool) {
|
||||||
|
if reaping {
|
||||||
|
// Memory should already be unmapped
|
||||||
|
assert!(context.image.is_empty());
|
||||||
|
assert!(context.heap.is_none());
|
||||||
|
assert!(context.stack.is_none());
|
||||||
|
assert!(context.tls.is_none());
|
||||||
|
} else {
|
||||||
|
// Unmap previous image, heap, grants, stack, and tls
|
||||||
|
context.image.clear();
|
||||||
|
drop(context.heap.take());
|
||||||
|
drop(context.stack.take());
|
||||||
|
drop(context.tls.take());
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Looks like a race condition.
|
||||||
|
// Is it possible for Arc::strong_count to return 1 to two contexts that exit at the
|
||||||
|
// same time, or return 2 to both, thus either double freeing or leaking the grants?
|
||||||
|
if Arc::strong_count(&context.grants) == 1 {
|
||||||
|
let mut grants = context.grants.lock();
|
||||||
|
for grant in grants.drain(..) {
|
||||||
|
if reaping {
|
||||||
|
println!("{}: {}: Grant should not exist: {:?}", context.id.into(), unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) }, grant);
|
||||||
|
|
||||||
|
let mut new_table = unsafe { InactivePageTable::from_address(context.arch.get_page_table()) };
|
||||||
|
let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(arch::USER_TMP_GRANT_OFFSET)));
|
||||||
|
|
||||||
|
grant.unmap_inactive(&mut new_table, &mut temporary_page);
|
||||||
|
} else {
|
||||||
|
grant.unmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
let entry;
|
let entry;
|
||||||
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
|
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
|
||||||
|
@ -508,24 +543,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||||
// Set name
|
// Set name
|
||||||
context.name = Arc::new(Mutex::new(canonical));
|
context.name = Arc::new(Mutex::new(canonical));
|
||||||
|
|
||||||
// Unmap previous image, heap, grants, stack, and tls
|
empty(&mut context, false);
|
||||||
context.image.clear();
|
|
||||||
drop(context.heap.take());
|
|
||||||
drop(context.stack.take());
|
|
||||||
drop(context.tls.take());
|
|
||||||
|
|
||||||
let mut unmap_grants = Vec::new();
|
|
||||||
// FIXME: Looks like a race condition.
|
|
||||||
// Is it possible for Arc::strong_count to return 1 to two contexts that exit at the
|
|
||||||
// same time, or return 2 to both, thus either double freeing or leaking the grants?
|
|
||||||
if Arc::strong_count(&context.grants) == 1 {
|
|
||||||
mem::swap(context.grants.lock().deref_mut(), &mut unmap_grants);
|
|
||||||
}
|
|
||||||
context.grants = Arc::new(Mutex::new(Vec::new()));
|
|
||||||
|
|
||||||
for grant in unmap_grants {
|
|
||||||
grant.unmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
if stat.st_mode & syscall::flag::MODE_SETUID == syscall::flag::MODE_SETUID {
|
if stat.st_mode & syscall::flag::MODE_SETUID == syscall::flag::MODE_SETUID {
|
||||||
context.euid = stat.st_uid;
|
context.euid = stat.st_uid;
|
||||||
|
@ -807,23 +825,7 @@ pub fn exit(status: usize) -> ! {
|
||||||
let (vfork, children) = {
|
let (vfork, children) = {
|
||||||
let mut context = context_lock.write();
|
let mut context = context_lock.write();
|
||||||
|
|
||||||
context.image.clear();
|
empty(&mut context, false);
|
||||||
drop(context.heap.take());
|
|
||||||
drop(context.stack.take());
|
|
||||||
drop(context.tls.take());
|
|
||||||
|
|
||||||
let mut unmap_grants = Vec::new();
|
|
||||||
// FIXME: Looks like a race condition.
|
|
||||||
// Is it possible for Arc::strong_count to return 1 to two contexts that exit at the
|
|
||||||
// same time, or return 2 to both, thus either double freeing or leaking the grants?
|
|
||||||
if Arc::strong_count(&context.grants) == 1 {
|
|
||||||
mem::swap(context.grants.lock().deref_mut(), &mut unmap_grants);
|
|
||||||
}
|
|
||||||
context.grants = Arc::new(Mutex::new(Vec::new()));
|
|
||||||
|
|
||||||
for grant in unmap_grants {
|
|
||||||
grant.unmap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let vfork = context.vfork;
|
let vfork = context.vfork;
|
||||||
context.vfork = false;
|
context.vfork = false;
|
||||||
|
@ -911,7 +913,14 @@ fn reap(pid: ContextId) -> Result<ContextId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut contexts = context::contexts_mut();
|
let mut contexts = context::contexts_mut();
|
||||||
contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid))
|
let context_lock = contexts.remove(pid).ok_or(Error::new(ESRCH))?;
|
||||||
|
{
|
||||||
|
let mut context = context_lock.write();
|
||||||
|
empty(&mut context, true);
|
||||||
|
}
|
||||||
|
drop(context_lock);
|
||||||
|
|
||||||
|
Ok(pid)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<ContextId> {
|
pub fn waitpid(pid: ContextId, status_ptr: usize, flags: usize) -> Result<ContextId> {
|
||||||
|
|
Loading…
Reference in a new issue