From 5f3f8dac1290145a4364390f893a1a700708c95c Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 15 Apr 2020 16:42:36 +0200 Subject: [PATCH] add the possibility to use a user-specified stack size --- src/arch/x86_64/kernel/scheduler.rs | 34 ++++++++++++++++++++++++----- src/lib.rs | 8 ++++++- src/scheduler/mod.rs | 13 +++++------ src/scheduler/task.rs | 12 +++++++--- src/syscalls/tasks.rs | 16 +++++++++++++- 5 files changed, 65 insertions(+), 18 deletions(-) diff --git a/src/arch/x86_64/kernel/scheduler.rs b/src/arch/x86_64/kernel/scheduler.rs index a3ff5f225c..59595d52f3 100644 --- a/src/arch/x86_64/kernel/scheduler.rs +++ b/src/arch/x86_64/kernel/scheduler.rs @@ -64,21 +64,29 @@ struct State { pub struct TaskStacks { /// Whether this is a boot stack is_boot_stack: bool, + stack_size: usize, /// Stack of the task - pub stack: usize, - pub ist0: usize, + stack: usize, + ist0: usize, } impl TaskStacks { - pub fn new() -> Self { + pub fn new(size: usize) -> Self { + let stack_size = if size < KERNEL_STACK_SIZE { + KERNEL_STACK_SIZE + } else { + align_up!(size, BasePageSize::SIZE) + }; + // Allocate an executable stack to possibly support dynamically generated code on the stack (see https://security.stackexchange.com/a/47825). - let stack = ::mm::allocate(DEFAULT_STACK_SIZE, false); + let stack = ::mm::allocate(stack_size, false); debug!("Allocating stack {:#X}", stack); let ist0 = ::mm::allocate(KERNEL_STACK_SIZE, false); debug!("Allocating ist0 {:#X}", ist0); Self { is_boot_stack: false, + stack_size: stack_size, stack: stack, ist0: ist0, } @@ -93,10 +101,26 @@ impl TaskStacks { Self { is_boot_stack: true, + stack_size: KERNEL_STACK_SIZE, stack: stack, ist0: ist0, } } + + #[inline] + pub fn get_stack_size(&self) -> usize { + self.stack_size + } + + #[inline] + pub fn get_stack_address(&self) -> usize { + self.stack + } + + #[inline] + pub fn get_ist0(&self) -> usize { + self.ist0 + } } impl Drop for TaskStacks { @@ -106,7 +130,7 @@ impl Drop for TaskStacks { "Deallocating stack {:#X} and ist0 {:#X}", self.stack, self.ist0 ); - ::mm::deallocate(self.stack, DEFAULT_STACK_SIZE); + ::mm::deallocate(self.stack, self.stack_size); ::mm::deallocate(self.ist0, KERNEL_STACK_SIZE); } } diff --git a/src/lib.rs b/src/lib.rs index 4d98c2b2e1..a220c326ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -232,7 +232,13 @@ fn boot_processor_main() -> ! { } // Start the initd task. - scheduler::PerCoreScheduler::spawn(initd, 0, scheduler::task::NORMAL_PRIO, 0); + scheduler::PerCoreScheduler::spawn( + initd, + 0, + scheduler::task::NORMAL_PRIO, + 0, + DEFAULT_STACK_SIZE, + ); let core_scheduler = core_scheduler(); // Run the scheduler loop. diff --git a/src/scheduler/mod.rs b/src/scheduler/mod.rs index 30b39a3240..d22ae1efbf 100644 --- a/src/scheduler/mod.rs +++ b/src/scheduler/mod.rs @@ -79,6 +79,7 @@ impl PerCoreScheduler { arg: usize, prio: Priority, core_id: CoreId, + stack_size: usize, ) -> TaskId { // Create the new task. let tid = get_tid(); @@ -87,6 +88,7 @@ impl PerCoreScheduler { core_id, TaskStatus::TaskReady, prio, + stack_size, ))); task.borrow_mut().create_stack_frame(func, arg); @@ -290,16 +292,11 @@ impl PerCoreScheduler { #[cfg(target_arch = "x86_64")] pub fn set_current_kernel_stack(&self) { let current_task_borrowed = self.current_task.borrow(); - let stack_size = if current_task_borrowed.status == TaskStatus::TaskIdle { - KERNEL_STACK_SIZE - } else { - DEFAULT_STACK_SIZE - }; - + let stack_size = current_task_borrowed.stacks.get_stack_size(); let tss = unsafe { &mut (*PERCORE.tss.get()) }; - tss.rsp[0] = (current_task_borrowed.stacks.stack + stack_size - 0x10) as u64; - tss.ist[0] = (current_task_borrowed.stacks.ist0 + KERNEL_STACK_SIZE - 0x10) as u64; + tss.rsp[0] = (current_task_borrowed.stacks.get_stack_address() + stack_size - 0x10) as u64; + tss.ist[0] = (current_task_borrowed.stacks.get_ist0() + KERNEL_STACK_SIZE - 0x10) as u64; } /// Save the FPU context for the current FPU owner and restore it for the current task, diff --git a/src/scheduler/task.rs b/src/scheduler/task.rs index 6d842c346c..e063ef1141 100644 --- a/src/scheduler/task.rs +++ b/src/scheduler/task.rs @@ -395,7 +395,13 @@ pub trait TaskFrame { } impl Task { - pub fn new(tid: TaskId, core_id: CoreId, task_status: TaskStatus, task_prio: Priority) -> Task { + pub fn new( + tid: TaskId, + core_id: CoreId, + task_status: TaskStatus, + task_prio: Priority, + stack_size: usize, + ) -> Task { debug!("Creating new task {}", tid); Task { @@ -405,7 +411,7 @@ impl Task { last_stack_pointer: 0, last_fpu_state: arch::processor::FPUState::new(), core_id: core_id, - stacks: TaskStacks::new(), + stacks: TaskStacks::new(stack_size), next: None, prev: None, tls: None, @@ -445,7 +451,7 @@ impl Task { last_stack_pointer: 0, last_fpu_state: arch::processor::FPUState::new(), core_id: core_id, - stacks: TaskStacks::new(), + stacks: TaskStacks::new(task.stacks.get_stack_size()), next: None, prev: None, tls: task.tls.clone(), diff --git a/src/syscalls/tasks.rs b/src/syscalls/tasks.rs index 3594f54829..69c9330a00 100644 --- a/src/syscalls/tasks.rs +++ b/src/syscalls/tasks.rs @@ -8,6 +8,7 @@ use arch; use arch::kernel::get_processor_count; use arch::percore::*; +use config::DEFAULT_STACK_SIZE; use core::convert::TryInto; use core::isize; #[cfg(feature = "newlib")] @@ -171,11 +172,12 @@ pub extern "C" fn sys_signal(_handler: SignalHandler) -> i32 { } #[no_mangle] -pub extern "C" fn sys_spawn( +pub extern "C" fn sys_spawn2( id: *mut Tid, func: extern "C" fn(usize), arg: usize, prio: u8, + stack_size: usize, selector: isize, ) -> i32 { static CORE_COUNTER: AtomicU32 = AtomicU32::new(1); @@ -192,6 +194,7 @@ pub extern "C" fn sys_spawn( arg, Priority::from(prio), core_id.try_into().unwrap(), + stack_size, ); if !id.is_null() { unsafe { @@ -202,6 +205,17 @@ pub extern "C" fn sys_spawn( 0 } +#[no_mangle] +pub extern "C" fn sys_spawn( + id: *mut Tid, + func: extern "C" fn(usize), + arg: usize, + prio: u8, + selector: isize, +) -> i32 { + sys_spawn2(id, func, arg, prio, DEFAULT_STACK_SIZE, selector) +} + #[no_mangle] pub extern "C" fn sys_join(id: Tid) -> i32 { match scheduler::join(TaskId::from(id)) {