Skip to content

Commit

Permalink
add the possibility to use a user-specified stack size
Browse files Browse the repository at this point in the history
  • Loading branch information
stlankes committed Apr 15, 2020
1 parent 1376a8a commit 5f3f8da
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 18 deletions.
34 changes: 29 additions & 5 deletions src/arch/x86_64/kernel/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand All @@ -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 {
Expand All @@ -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);
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
13 changes: 5 additions & 8 deletions src/scheduler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -87,6 +88,7 @@ impl PerCoreScheduler {
core_id,
TaskStatus::TaskReady,
prio,
stack_size,
)));
task.borrow_mut().create_stack_frame(func, arg);

Expand Down Expand Up @@ -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,
Expand Down
12 changes: 9 additions & 3 deletions src/scheduler/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand Down Expand Up @@ -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(),
Expand Down
16 changes: 15 additions & 1 deletion src/syscalls/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -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);
Expand All @@ -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 {
Expand All @@ -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)) {
Expand Down

0 comments on commit 5f3f8da

Please sign in to comment.