Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for defining tasks and switching between task contexts #61

Merged
merged 5 commits into from
Jul 12, 2023

Conversation

roy-hopkins
Copy link
Collaborator

This PR represents a step in implementing support for CPL3 and isolating tasks that run within the context of the coconut SVSM kernel. It adds a new structure: Task which allows a task context to be initialised and maintained that can be swapped in and out of execution on a vCPU.

This PR does not introduce any form of scheduling of the tasks. In fact, the task code is not currently used at all within the SVSM kernel. However, the code as it stands can be used to launch an entry point that maintains its own page table (with shared access to kernel memory) in CPL0 using a per-task stack.

The current X86Regs structure is only used by exception handlers and
interrupt routines and as such contains the interrupt routine stack
frame within the structure. This change separates that out to break
registers and other context into their respective categories to allow
the structures to be reused in other situations.

Signed-off-by: Roy Hopkins <rhopkins@suse.de>
The svsm_paging module is currently used only in svsm.rs. This change allows
the code to be used in other areas of svsm.

Signed-off-by: Roy Hopkins <rhopkins@suse.de>
src/cpu/msr.rs Outdated Show resolved Hide resolved
@roy-hopkins
Copy link
Collaborator Author

Here's an example of how the code in this PR can be used to launch and switch between tasks.

diff --git a/src/svsm.rs b/src/svsm.rs
index 73a25e5..c52265e 100644
--- a/src/svsm.rs
+++ b/src/svsm.rs
@@ -9,10 +9,12 @@
 
 extern crate alloc;
 
+use alloc::boxed::Box;
 use alloc::vec::Vec;
 use svsm::fw_meta::{parse_fw_meta_data, print_fw_meta, validate_fw_memory, SevFWMetaData};
+use svsm::task::Task;
 
-use core::arch::{asm, global_asm};
+use core::arch::global_asm;
 use core::panic::PanicInfo;
 use core::slice;
 use svsm::acpi::tables::load_acpi_cpu_info;
@@ -308,6 +310,8 @@ fn mapping_info_init(launch_info: &KernelLaunchInfo) {
     );
 }
 
+static mut MAIN_TASK: Option<Box<Task>> = None;
+
 #[no_mangle]
 pub extern "C" fn svsm_start(li: &KernelLaunchInfo, vb_addr: VirtAddr) {
     let launch_info: KernelLaunchInfo = *li;
@@ -396,15 +400,21 @@ pub extern "C" fn svsm_start(li: &KernelLaunchInfo, vb_addr: VirtAddr) {
 
     log::info!("BSP Runtime stack starts @ {:#018x}", bp);
 
-    // Enable runtime stack and jump to main function
     unsafe {
-        asm!("movq  %rax, %rsp
-              jmp   svsm_main",
-              in("rax") bp.bits(),
-              options(att_syntax));
+        MAIN_TASK = Some(Task::create(svsm_main, 0).expect("Failed to create svsm_main task"));
+        MAIN_TASK
+            .as_mut()
+            .unwrap()
+            .set_current(core::ptr::null_mut());
     }
 }
 
+pub extern "C" fn test_task() {
+    log::info!("Hello from a task");
+    let main_task = unsafe { MAIN_TASK.as_mut().expect("Invalid main task") };
+    main_task.set_current(core::ptr::null_mut());
+}
+
 #[no_mangle]
 pub extern "C" fn svsm_main() {
     // The GDB stub can be started earlier, just after the console is initialised
@@ -419,6 +429,10 @@ pub extern "C" fn svsm_main() {
     // a remote GDB connection
     //debug_break();
 
+    let previous_task = unsafe { MAIN_TASK.as_mut().expect("Invalid main task") };
+    let mut task = Task::create(test_task, 0).expect("Failed to create task");
+    task.set_current(previous_task.as_mut());
+
     invalidate_stage2().expect("Failed to invalidate Stage2 memory");
 
     let fw_cfg = FwCfg::new(&CONSOLE_IO);

Signed-off-by: Roy Hopkins <rhopkins@suse.de>
Extends the pagetable code to add support for creating tasks that can
be context-switched on a vCPU. This change adds the ability to copy an
existing pagetable and also adds helper functions that define the flags
to use for task specific pagetable entries.

Signed-off-by: Roy Hopkins <rhopkins@suse.de>
Copy link
Member

@joergroedel joergroedel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good and is a step in the right direction. Added one minor comment to the task switching assembly.

src/task/tasks.rs Outdated Show resolved Hide resolved
This adds basic support for creating tasks which equate to processes
or threads that can be executed on a vCPU. Each task is represented
by a structure that contains the relevant context, which at the moment
includes a task stack, pagetable, stack pointer.

Tasks can be created with Task::create() providing an entry point
address. The task context is activated with Task::set_current(). The
task context remains in scope until it calls Task::set_current() itself
with a new context.

This patch adds all the infrastructure to support task switching but
does not yet integrate task creation or switching into the SVSM
kernel. This is in anticipation of a scheduler being introduced.

Signed-off-by: Roy Hopkins <rhopkins@suse.de>
@joergroedel joergroedel merged commit 2e803ef into coconut-svsm:main Jul 12, 2023
2 checks passed
@roy-hopkins roy-hopkins deleted the tasks branch August 4, 2023 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants