diff --git a/context/memory.rs b/context/memory.rs index 9cd57f2ad383bfc5bb50c24994c6d6f301fedb66..ab9033bc4e391bbf7c347c3e95c2084b8e77e175 100644 --- a/context/memory.rs +++ b/context/memory.rs @@ -101,6 +101,36 @@ impl Memory { self.flags = new_flags; } + pub fn replace(&mut self, new_start: VirtualAddress, flush: bool) { + let mut active_table = unsafe { ActivePageTable::new() }; + + let mut flush_all = false; + + for page in self.pages() { + active_table.unmap(page); + + if flush { + //active_table.flush(page); + flush_all = true; + } + } + + self.start = new_start; + + for page in self.pages() { + active_table.map(page, self.flags); + + if flush { + //active_table.flush(page); + flush_all = true; + } + } + + if flush_all { + active_table.flush_all(); + } + } + pub fn resize(&mut self, new_size: usize, flush: bool, clear: bool) { let mut active_table = unsafe { ActivePageTable::new() }; diff --git a/elf.rs b/elf.rs index 819b1ece5f337ab4abb05037448584305b5d5727..7fb7f9a81d7b11c3d04d2eb4f58a406567289bc4 100644 --- a/elf.rs +++ b/elf.rs @@ -55,8 +55,6 @@ impl<'a> Elf<'a> { /// Test function to run. Remove and replace with proper syscall pub fn run(self) -> SysResult<!> { - let stack_addr = arch::USER_STACK_OFFSET; - let stack_size = arch::USER_STACK_SIZE; { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::NoProcess)?; @@ -105,8 +103,8 @@ impl<'a> Elf<'a> { // Map stack context.stack = Some(context::memory::Memory::new( - VirtualAddress::new(stack_addr), - stack_size, + VirtualAddress::new(arch::USER_STACK_OFFSET), + arch::USER_STACK_SIZE, entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE, true, true @@ -114,7 +112,7 @@ impl<'a> Elf<'a> { } // Go to usermode - unsafe { usermode(self.entry(), stack_addr + stack_size - 256); } + unsafe { usermode(self.entry(), arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256); } } } diff --git a/syscall/process.rs b/syscall/process.rs index 3a511fb1252fdf4d99d3036f53daea23aa3e5a6e..9c3e5b4f93aefb2c0db8e433985fa6eccfb2fdb9 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -47,8 +47,9 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { println!("Clone {:X}: {:X}", flags, stack_base); let arch; - let mut stack_option = None; + let mut kstack_option = None; let mut offset = 0; + let mut stack_option = None; // Copy from old process { @@ -63,6 +64,21 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { let func_ptr = new_stack.as_mut_ptr().offset(offset as isize); *(func_ptr as *mut usize) = arch::interrupt::syscall::clone_ret as usize; } + kstack_option = Some(new_stack); + } + if let Some(ref stack) = context.stack { + let mut new_stack = context::memory::Memory::new( + VirtualAddress::new(arch::USER_TMP_STACK_OFFSET), + stack.size(), + entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE, + true, + true //TODO: Don't clear stack? + ); + unsafe { + arch::externs::memcpy(new_stack.start_address().get() as *mut u8, + stack.start_address().get() as *const u8, + stack.size()); + } stack_option = Some(new_stack); } } @@ -74,15 +90,19 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { let context_lock = contexts.new_context()?; let mut context = context_lock.write(); context.arch = arch; - if let Some(stack) = stack_option.take() { + if let Some(stack) = kstack_option.take() { context.arch.set_stack(stack.as_ptr() as usize + offset); context.kstack = Some(stack); } + if let Some(mut stack) = stack_option.take() { + //stack.replace(VirtualAddress::new(arch::USER_STACK_OFFSET), true); + context.stack = Some(stack); + } context.blocked = false; pid = context.id; } - unsafe { context::switch(); } + //unsafe { context::switch(); } Ok(pid) }