Add shutdown syscall
All checks were successful
Build / build (push) Successful in 1m50s

This commit is contained in:
Mathieu Strypsteen 2025-01-10 16:09:11 +01:00
parent 2c7b850b52
commit 6df1c6f48c
3 changed files with 45 additions and 3 deletions

View file

@ -1,5 +1,5 @@
[workspace]
resolver = "2"
resolver = "3"
members = ["lib/acpica-rs", "lib/kernel-common", "loader", "kernel", "init"]
[profile.release]

View file

@ -17,6 +17,7 @@ use super::{locks::Spinlock, scheduler::SCHEDULER, task::create_task};
pub struct Process {
pub pid: usize,
pub uid: usize,
pub address_space: AddressSpace,
pub binary: Option<&'static [u8]>,
pub num_tasks: usize,
@ -25,6 +26,7 @@ pub struct Process {
static KERNEL_PROCESS: Spinlock<LazyCell<Arc<Spinlock<Process>>>> = Spinlock::new(LazyCell::new(|| {
let process = Process {
pid: 0,
uid: 0,
address_space: AddressSpace {
is_kernel: true,
pml4: OnceCell::new(),
@ -46,6 +48,7 @@ pub fn create_process(binary: Option<&'static [u8]>) -> Arc<Spinlock<Process>> {
let pid = NEXT_PID.fetch_add(1, Ordering::SeqCst);
let mut process = Process {
pid,
uid: 0,
address_space: AddressSpace {
is_kernel: false,
pml4: OnceCell::new(),

View file

@ -1,5 +1,6 @@
use core::{error::Error, ptr::copy};
use acpica_rs::{AcpiEnterSleepState, AcpiEnterSleepStatePrep, AcpiReset};
use alloc::{boxed::Box, string::String, vec, vec::Vec};
use log::{debug, trace};
@ -8,7 +9,10 @@ use crate::cpu::{
paging::USER_END,
};
use super::task::{terminate_current_task, with_current_task};
use super::{
sync::increase_lock_count,
task::{terminate_current_task, with_current_task},
};
struct SyscallArgs {
arg1: usize,
@ -22,7 +26,7 @@ struct Syscall {
num_args: usize,
}
const SYSCALL_TABLE: [Syscall; 4] = [
const SYSCALL_TABLE: [Syscall; 5] = [
Syscall {
func: syscall_get_kernel_version,
num_args: 0,
@ -33,6 +37,7 @@ const SYSCALL_TABLE: [Syscall; 4] = [
num_args: 2,
},
Syscall { func: syscall_get_pid, num_args: 0 },
Syscall { func: syscall_shutdown, num_args: 1 },
];
fn copy_from_user(start: u64, size: usize) -> Result<Vec<u8>, Box<dyn Error>> {
@ -61,6 +66,19 @@ fn copy_from_user(start: u64, size: usize) -> Result<Vec<u8>, Box<dyn Error>> {
disable_user_memory_access();
Ok(buffer)
}
fn require_root() -> Result<(), Box<dyn Error>> {
let mut error = false;
with_current_task(|current_task| {
let process = current_task.process.lock();
if process.uid != 0 {
error = true;
}
});
if error {
return Err("Permission denied".into());
}
Ok(())
}
fn syscall_get_kernel_version(_args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
Ok(0)
}
@ -69,6 +87,7 @@ fn syscall_exit(_args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
terminate_current_task();
}
fn syscall_debug_print(args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
require_root()?;
let data = copy_from_user(args.arg1 as u64, args.arg2)?;
let string = String::from_utf8(data)?;
trace!("{}", string);
@ -79,6 +98,26 @@ fn syscall_get_pid(_args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
with_current_task(|current_task| pid = current_task.process.lock().pid);
Ok(pid)
}
fn syscall_shutdown(args: SyscallArgs) -> Result<usize, Box<dyn Error>> {
require_root()?;
// TODO: Stop all processes and sync devices first
if args.arg1 == 0 {
unsafe {
AcpiEnterSleepStatePrep(5);
}
increase_lock_count();
unsafe {
AcpiEnterSleepState(5);
}
} else if args.arg1 == 1 {
unsafe {
AcpiReset();
}
} else {
return Err("Invalid syscall argument".into());
}
panic!("Shutting down failed");
}
#[no_mangle]
extern "C" fn syscall_handler(syscall: u64, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> u64 {
if syscall as usize >= SYSCALL_TABLE.len() {