diff --git a/kernel/src/task/exec.rs b/kernel/src/task/exec.rs index 3890664ef..68950de2c 100644 --- a/kernel/src/task/exec.rs +++ b/kernel/src/task/exec.rs @@ -9,7 +9,7 @@ use crate::error::SvsmError; use crate::fs::open; use crate::mm::vm::VMFileMappingFlags; use crate::mm::USER_MEM_END; -use crate::task::{create_user_task, current_task, schedule}; +use crate::task::{create_user_task, current_task, finish_user_task, schedule}; use crate::types::PAGE_SIZE; use crate::utils::align_up; use elf::{Elf64File, Elf64PhdrFlags}; @@ -28,6 +28,15 @@ fn convert_elf_phdr_flags(flags: Elf64PhdrFlags) -> VMFileMappingFlags { vm_flags } +/// Loads and executes an ELF binary in user-mode. +/// +/// # Arguments +/// +/// * binary: Path to file in the file-system +/// +/// # Returns +/// +/// `()` on success, [`SvsmError`] on failure. pub fn exec_user(binary: &str) -> Result<(), SvsmError> { let fh = open(binary)?; let file_size = fh.size(); @@ -88,6 +97,7 @@ pub fn exec_user(binary: &str) -> Result<(), SvsmError> { let stack_addr = USER_MEM_END - user_stack_size; task.mmap_user(stack_addr, None, 0, user_stack_size, stack_flags)?; + finish_user_task(task); schedule(); Ok(()) diff --git a/kernel/src/task/mod.rs b/kernel/src/task/mod.rs index 8d46602cc..74e2b0b3d 100644 --- a/kernel/src/task/mod.rs +++ b/kernel/src/task/mod.rs @@ -10,8 +10,8 @@ mod tasks; mod waiting; pub use schedule::{ - create_user_task, current_task, current_task_terminated, is_current_task, schedule, - schedule_init, schedule_task, start_kernel_task, terminate, RunQueue, TASKLIST, + create_user_task, current_task, current_task_terminated, finish_user_task, is_current_task, + schedule, schedule_init, schedule_task, start_kernel_task, terminate, RunQueue, TASKLIST, }; pub use tasks::{ diff --git a/kernel/src/task/schedule.rs b/kernel/src/task/schedule.rs index 243ecd02b..c1745fae7 100644 --- a/kernel/src/task/schedule.rs +++ b/kernel/src/task/schedule.rs @@ -255,15 +255,33 @@ pub fn start_kernel_task(entry: extern "C" fn()) -> Result Result { let cpu = this_cpu(); - let task = Task::create_user(cpu, user_entry)?; + Task::create_user(cpu, user_entry) +} + +/// Finished user-space task creation by putting the task on the global +/// TASKLIST and adding it to the run-queue. +/// +/// # Arguments +/// +/// * task: Pointer to user task +pub fn finish_user_task(task: TaskPointer) { + // Add task to global TASKLIST TASKLIST.lock().list().push_back(task.clone()); // Put task on the runqueue of this CPU - cpu.runqueue().lock_write().handle_task(task.clone()); - - Ok(task) + this_cpu().runqueue().lock_write().handle_task(task); } pub fn current_task() -> TaskPointer {