[svsm-devel] task: Implement system call interface
Carlos Bilbao
carlos.bilbao at amd.com
Fri Sep 8 14:55:03 CEST 2023
Hello,
Just opened pull request to add a system call interface [1]. Sharing below
too in case anyone wants to review.
[1] https://github.com/roy-hopkins/svsm/pull/5
Thanks,
Carlos
---
[PATCH] scheduler: Implement system call interface
Added system call interface with enum-based invocation handling.
Signed-off-by: Carlos Bilbao <carlos.bilbao at amd.com>
---
src/task/syscall.rs | 122 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 114 insertions(+), 8 deletions(-)
diff --git a/src/task/syscall.rs b/src/task/syscall.rs
index 3ac7b92..67c0197 100644
--- a/src/task/syscall.rs
+++ b/src/task/syscall.rs
@@ -3,8 +3,13 @@
// Copyright (c) 2022-2023 SUSE LLC
//
// Author: Roy Hopkins <rhopkins at suse.de>
-
+//
+// Other contributors:
+//
+// Carlos Bilbao <carlos.bilbao at amd.com>
+//
use core::{
+ arch::asm,
arch::global_asm,
ffi::{c_char, CStr},
};
@@ -32,21 +37,122 @@ const MSR_STAR: u32 = 0xc000_0081;
const MSR_LSTAR: u32 = 0xc000_0082;
const MSR_SFMASK: u32 = 0xc000_0084;
+#[repr(u32)]
+#[derive(Debug)]
+pub enum SystemCalls {
+ Exit = 0,
+ Log = 1,
+ Sleep = 2,
+}
+
+fn map_to_syscall(index: u32) -> Option<SystemCalls> {
+ match index {
+ 1 => Some(SystemCalls::Exit),
+ 2 => Some(SystemCalls::Log),
+ 3 => Some(SystemCalls::Sleep),
+ _ => None,
+ }
+}
+
+#[inline]
+#[allow(dead_code)]
+pub fn syscall0(id: u32) -> u64 {
+ let ret: u64;
+ // syscall modifies both rcx and r11
+ unsafe {
+ asm!("syscall",
+ inout("rax") id as u64 => ret,
+ options(nostack));
+ }
+
+ ret
+}
+
+#[inline]
+#[allow(dead_code)]
+pub fn syscall1(id: u32, p1: u64) -> u64 {
+ let ret: u64;
+ unsafe {
+ asm!("syscall",
+ inout("rax") id as u64 => ret,
+ in("rdi") p1,
+ options(nostack));
+ }
+
+ ret
+}
+
+#[inline]
+#[allow(dead_code)]
+pub fn syscall2(id: u32, p1: u64, p2: u64) -> u64 {
+ let ret: u64;
+ unsafe {
+ asm!("syscall",
+ inout("rax") id as u64 => ret,
+ in("rdi") p1,
+ in("rsi") p2,
+ options(nostack));
+ }
+
+ ret
+}
+
+#[inline]
+#[allow(dead_code)]
+pub fn syscall3(id: u32, p1: u64, p2: u64, p3: u64) -> u64 {
+ let ret: u64;
+ // syscall modifies both rcx and r11
+ unsafe {
+ asm!("syscall",
+ inout("rax") id as u64 => ret,
+ in("rdi") p1,
+ in("rsi") p2,
+ in("rdx") p3,
+ options(nostack));
+ }
+
+ ret
+}
+
+// In case of adding system calls with more parameters, this is the order
+// in which to fill the registers:
+// p4=r10, p5=r8, p6=r9
+// We can't pass >6 params without using the stack
+// Don't forget to include the call in system_call!() too.
+
+/// System call macro. Example of usage:
+/// system_call!(SystemCalls:CALL_ID, param1)
+///
+#[macro_export]
+macro_rules! system_call {
+ ($id: expr) => {
+ syscall0($id)
+ };
+
+ ($id: expr, $param_1:expr) => {
+ syscall1($id, $param_1 as u64)
+ };
+ ($id: expr, $param_1:expr, $param_2:expr) => {
+ syscall2($id, $param_1 as u64, $param_2 as u64)
+ };
+
+ ($id: expr, $param_1:expr, $param_2:expr, $param_3:expr) => {
+ syscall3($id, $param_1 as u64, $param_2 as u64, $param_3 as u64)
+ };
+}
+
#[no_mangle]
extern "C" fn syscall_handler(index: u32, param1: u64) -> u64 {
- let ret = match index {
- // exit
- 0 => SyscallRet::Terminate,
- // log
- 1 => {
+ let ret = match map_to_syscall(index) {
+ Some(SystemCalls::Exit) => SyscallRet::Terminate,
+ Some(SystemCalls::Log) => {
unsafe {
let str = CStr::from_ptr(param1 as *const c_char);
log::info!("{}", str.to_str().unwrap());
}
SyscallRet::Ok
}
- // sleep
- 2 => SyscallRet::Ok,
+ Some(SystemCalls::Sleep) => SyscallRet::Ok,
_ => {
log::info!("Invalid syscall received: {}", index);
SyscallRet::Unknown
--
2.41.0
More information about the Svsm-devel
mailing list