Commit e5cf6efa authored by Jeremy Soller's avatar Jeremy Soller

Support specification of stack with clone system call and CLONE_STACK flag

parent 9ccaed71
This diff is collapsed.
[package]
name = "kernel"
version = "0.1.51"
version = "0.1.52"
build = "build.rs"
[lib]
......
......@@ -159,10 +159,16 @@ pub struct SyscallStack {
pub rip: usize,
pub cs: usize,
pub rflags: usize,
// Will only be present if syscall is called from another ring
pub rsp: usize,
pub ss: usize,
}
#[naked]
pub unsafe extern fn clone_ret() {
asm!("pop rbp" : : : : "intel", "volatile");
asm!("" : : "{rax}"(0) : : "intel", "volatile");
asm!("
pop rbp
xor rax, rax
"
: : : : "intel", "volatile");
}
......@@ -148,7 +148,7 @@ pub struct Context {
/// User heap
pub heap: Option<SharedMemory>,
/// User stack
pub stack: Option<Memory>,
pub stack: Option<SharedMemory>,
/// User signal stack
pub sigstack: Option<Memory>,
/// User Thread local storage
......
......@@ -75,7 +75,9 @@ pub fn resource() -> Result<Vec<u8>> {
});
}
if let Some(ref stack) = context.stack {
memory += stack.size();
stack.with(|stack| {
memory += stack.size();
});
}
if let Some(ref sigstack) = context.sigstack {
memory += sigstack.size();
......
......@@ -93,7 +93,15 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, bp: u
SYS_GETPID => getpid().map(ContextId::into),
SYS_GETPGID => getpgid(ContextId::from(b)).map(ContextId::into),
SYS_GETPPID => getppid().map(ContextId::into),
SYS_CLONE => clone(b, bp).map(ContextId::into),
SYS_CLONE => {
let old_rsp = stack.rsp;
if b & flag::CLONE_STACK == flag::CLONE_STACK {
stack.rsp = c;
}
let ret = clone(b, bp).map(ContextId::into);
stack.rsp = old_rsp;
ret
},
SYS_EXIT => exit((b & 0xFF) << 8),
SYS_KILL => kill(ContextId::from(b), c),
SYS_WAITPID => waitpid(ContextId::from(b), c, d).map(ContextId::into),
......
......@@ -23,7 +23,7 @@ use scheme::FileHandle;
use syscall;
use syscall::data::{SigAction, Stat};
use syscall::error::*;
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND,
use syscall::flag::{CLONE_VFORK, CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_STACK,
PROT_EXEC, PROT_READ, PROT_WRITE, SIG_DFL, SIGCONT, SIGTERM,
WCONTINUED, WNOHANG, WUNTRACED, wifcontinued, wifstopped};
use syscall::validate::{validate_slice, validate_slice_mut};
......@@ -186,22 +186,28 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
}
}
if let Some(ref stack) = context.stack {
let mut new_stack = context::memory::Memory::new(
VirtualAddress::new(::USER_TMP_STACK_OFFSET),
stack.size(),
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
false
);
if let Some(ref stack_shared) = context.stack {
if flags & CLONE_STACK == CLONE_STACK {
stack_option = Some(stack_shared.clone());
} else {
stack_shared.with(|stack| {
let mut new_stack = context::memory::Memory::new(
VirtualAddress::new(::USER_TMP_STACK_OFFSET),
stack.size(),
EntryFlags::PRESENT | EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE,
false
);
unsafe {
intrinsics::copy(stack.start_address().get() as *const u8,
new_stack.start_address().get() as *mut u8,
stack.size());
}
unsafe {
intrinsics::copy(stack.start_address().get() as *const u8,
new_stack.start_address().get() as *mut u8,
stack.size());
}
new_stack.remap(stack.flags());
stack_option = Some(new_stack);
new_stack.remap(stack.flags());
stack_option = Some(new_stack.to_shared());
});
}
}
if let Some(ref sigstack) = context.sigstack {
......@@ -457,9 +463,19 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<ContextId> {
}
// Setup user stack
if let Some(mut stack) = stack_option {
stack.move_to(VirtualAddress::new(::USER_STACK_OFFSET), &mut new_table, &mut temporary_page);
context.stack = Some(stack);
if let Some(stack_shared) = stack_option {
if flags & CLONE_STACK == CLONE_STACK {
let frame = active_table.p4()[::USER_STACK_PML4].pointed_frame().expect("user stack not mapped");
let flags = active_table.p4()[::USER_STACK_PML4].flags();
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
mapper.p4_mut()[::USER_STACK_PML4].set(frame, flags);
});
} else {
stack_shared.with(|stack| {
stack.move_to(VirtualAddress::new(::USER_STACK_OFFSET), &mut new_table, &mut temporary_page);
});
}
context.stack = Some(stack_shared);
}
// Setup user sigstack
......@@ -652,7 +668,7 @@ fn fexec_noreturn(
::USER_STACK_SIZE,
EntryFlags::NO_EXECUTE | EntryFlags::WRITABLE | EntryFlags::USER_ACCESSIBLE,
true
));
).to_shared());
// Map stack
context.sigstack = Some(context::memory::Memory::new(
......
Subproject commit 54839d42f495e339062b1d3480415544033d0c0c
Subproject commit 11fb32afb0371789be1849e504d3421b34ef1c01
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