Skip to content

Commit

Permalink
fix(syscalls): don't call foreign __sys functions
Browse files Browse the repository at this point in the history
Signed-off-by: Martin Kröning <[email protected]>
  • Loading branch information
mkroening committed Mar 23, 2024
1 parent d3b7516 commit 7214696
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/arch/x86_64/kernel/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,7 +846,7 @@ pub fn configure() {
#[cfg(feature = "fsgsbase")]
if !supports_fsgs() {
error!("FSGSBASE support is enabled, but the processor doesn't support it!");
crate::__sys_shutdown(1);
crate::shutdown(1);
}

debug!("Set CR4 to {:#x}", cr4);
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,5 +267,5 @@ fn panic(info: &core::panic::PanicInfo<'_>) -> ! {
let core_id = crate::arch::core_local::core_id();
println!("[{core_id}][PANIC] {info}");

crate::__sys_shutdown(1);
crate::shutdown(1);
}
2 changes: 1 addition & 1 deletion src/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static mut SHELL: Lazy<Shell<'_>> = Lazy::new(|| {
ShellCommand {
help: "Shutdown HermitOS",
func: |_, shell| {
crate::__sys_shutdown(0);
crate::shutdown(0);
Ok(())
},
aliases: &["s"],
Expand Down
12 changes: 10 additions & 2 deletions src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,17 @@ pub(crate) fn get_application_parameters() -> (i32, *const *const u8, *const *co
SYS.get_application_parameters()
}

pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! {
pub(crate) fn shutdown(arg: i32) -> ! {
// print some performance statistics
crate::arch::kernel::print_statistics();

SYS.shutdown(arg)
}

pub(crate) extern "C" fn __sys_shutdown(arg: i32) -> ! {
shutdown(arg)
}

#[no_mangle]
pub extern "C" fn sys_shutdown(arg: i32) -> ! {
kernel_function!(__sys_shutdown(arg))
Expand Down Expand Up @@ -386,14 +390,18 @@ pub extern "C" fn sys_read(fd: FileDescriptor, buf: *mut u8, len: usize) -> isiz
kernel_function!(__sys_read(fd, buf, len))
}

extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
fn write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
let slice = unsafe { core::slice::from_raw_parts(buf, len) };
crate::fd::write(fd, slice).map_or_else(
|e| -num::ToPrimitive::to_isize(&e).unwrap(),
|v| v.try_into().unwrap(),
)
}

extern "C" fn __sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
write(fd, buf, len)
}

#[no_mangle]
pub extern "C" fn sys_write(fd: FileDescriptor, buf: *const u8, len: usize) -> isize {
kernel_function!(__sys_write(fd, buf, len))
Expand Down
22 changes: 15 additions & 7 deletions src/syscalls/semaphore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,7 @@ pub extern "C" fn sys_sem_trywait(sem: *const Semaphore) -> i32 {
kernel_function!(__sys_sem_trywait(sem))
}

/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds.
///
/// Blocks until semaphore is acquired or until wake-up time has elapsed.
///
/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout.
extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
fn sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
if sem.is_null() {
return -EINVAL;
}
Expand All @@ -119,12 +114,25 @@ extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
}
}

/// Try to acquire a lock on a semaphore, blocking for a given amount of milliseconds.
///
/// Blocks until semaphore is acquired or until wake-up time has elapsed.
///
/// Returns `0` on lock acquire, `-EINVAL` if sem is null, or `-ETIME` on timeout.
extern "C" fn __sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
sem_timedwait(sem, ms)
}

#[no_mangle]
pub extern "C" fn sys_sem_timedwait(sem: *const Semaphore, ms: u32) -> i32 {
kernel_function!(__sys_sem_timedwait(sem, ms))
}

extern "C" fn __sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 {
sem_timedwait(sem, ms)
}

#[no_mangle]
pub extern "C" fn sys_sem_cancelablewait(sem: *const Semaphore, ms: u32) -> i32 {
kernel_function!(__sys_sem_timedwait(sem, ms))
kernel_function!(__sys_sem_cancelablewait(sem, ms))
}
32 changes: 18 additions & 14 deletions src/syscalls/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::fd::socket::tcp;
#[cfg(feature = "udp")]
use crate::fd::socket::udp;
use crate::fd::{get_object, insert_object, replace_object, ObjectInterface, SocketOption};
use crate::syscalls::{IoCtl, __sys_write};
use crate::syscalls::IoCtl;

pub const AF_INET: i32 = 0;
pub const AF_INET6: i32 = 1;
Expand Down Expand Up @@ -565,6 +565,10 @@ extern "C" fn __sys_getaddrinfo(
-EINVAL
}

extern "C" fn __sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize {
super::write(s, mem.cast(), len)
}

extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 {
let obj = get_object(fd);
obj.map_or_else(
Expand All @@ -576,12 +580,16 @@ extern "C" fn __sys_shutdown_socket(fd: i32, how: i32) -> i32 {
)
}

extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize) -> isize {
let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) };
crate::fd::read(fd, slice).map_or_else(
|e| -num::ToPrimitive::to_isize(&e).unwrap(),
|v| v.try_into().unwrap(),
)
extern "C" fn __sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize {
if flags == 0 {
let slice = unsafe { core::slice::from_raw_parts_mut(buf, len) };
crate::fd::read(fd, slice).map_or_else(
|e| -num::ToPrimitive::to_isize(&e).unwrap(),
|v| v.try_into().unwrap(),
)
} else {
(-crate::errno::EINVAL).try_into().unwrap()
}
}

extern "C" fn __sys_sendto(
Expand Down Expand Up @@ -734,8 +742,8 @@ pub extern "C" fn sys_getaddrinfo(
}

#[no_mangle]
pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, _flags: i32) -> isize {
kernel_function!(__sys_write(s, mem as *const u8, len))
pub extern "C" fn sys_send(s: i32, mem: *const c_void, len: usize, flags: i32) -> isize {
kernel_function!(__sys_send(s, mem, len, flags))
}

#[no_mangle]
Expand All @@ -745,11 +753,7 @@ pub extern "C" fn sys_shutdown_socket(s: i32, how: i32) -> i32 {

#[no_mangle]
pub extern "C" fn sys_recv(fd: i32, buf: *mut u8, len: usize, flags: i32) -> isize {
if flags == 0 {
kernel_function!(__sys_recv(fd, buf, len))
} else {
(-crate::errno::EINVAL).try_into().unwrap()
}
kernel_function!(__sys_recv(fd, buf, len, flags))
}

#[no_mangle]
Expand Down
46 changes: 35 additions & 11 deletions src/syscalls/tasks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::mm::{task_heap_end, task_heap_start};
use crate::scheduler::task::{Priority, TaskHandle, TaskId};
use crate::scheduler::PerCoreSchedulerExt;
use crate::time::timespec;
use crate::{arch, scheduler, syscalls};
use crate::{arch, scheduler};

#[cfg(feature = "newlib")]
pub type SignalHandler = extern "C" fn(i32);
Expand Down Expand Up @@ -52,9 +52,13 @@ pub extern "C" fn sys_setprio(_id: *const Tid, _prio: i32) -> i32 {
-ENOSYS
}

extern "C" fn __sys_exit(arg: i32) -> ! {
fn exit(arg: i32) -> ! {
debug!("Exit program with error code {}!", arg);
syscalls::__sys_shutdown(arg)
super::shutdown(arg)
}

extern "C" fn __sys_exit(arg: i32) -> ! {
exit(arg)
}

#[no_mangle]
Expand All @@ -72,9 +76,13 @@ pub extern "C" fn sys_thread_exit(arg: i32) -> ! {
kernel_function!(__sys_thread_exit(arg))
}

extern "C" fn __sys_abort() -> ! {
exit(-1)
}

#[no_mangle]
pub extern "C" fn sys_abort() -> ! {
kernel_function!(__sys_exit(-1))
kernel_function!(__sys_abort())
}

#[cfg(feature = "newlib")]
Expand Down Expand Up @@ -109,7 +117,7 @@ pub extern "C" fn sys_sbrk(incr: isize) -> usize {
kernel_function!(__sys_sbrk(incr))
}

pub(crate) extern "C" fn __sys_usleep(usecs: u64) {
pub(super) fn usleep(usecs: u64) {
if usecs >= 10_000 {
// Enough time to set a wakeup timer and block the current task.
debug!("sys_usleep blocking the task for {} microseconds", usecs);
Expand All @@ -123,19 +131,27 @@ pub(crate) extern "C" fn __sys_usleep(usecs: u64) {
// Not enough time to set a wakeup timer, so just do busy-waiting.
let end = arch::processor::get_timestamp() + u64::from(get_frequency()) * usecs;
while get_timestamp() < end {
__sys_yield();
core_scheduler().reschedule();
}
}
}

pub(crate) extern "C" fn __sys_usleep(usecs: u64) {
usleep(usecs)
}

#[no_mangle]
pub extern "C" fn sys_usleep(usecs: u64) {
kernel_function!(__sys_usleep(usecs))
}

pub(crate) extern "C" fn __sys_msleep(ms: u32) {
usleep(u64::from(ms) * 1000)
}

#[no_mangle]
pub extern "C" fn sys_msleep(ms: u32) {
kernel_function!(__sys_usleep(u64::from(ms) * 1000))
kernel_function!(__sys_msleep(ms))
}

extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i32 {
Expand All @@ -154,7 +170,7 @@ extern "C" fn __sys_nanosleep(rqtp: *const timespec, _rmtp: *mut timespec) -> i3

let microseconds =
(requested_time.tv_sec as u64) * 1_000_000 + (requested_time.tv_nsec as u64) / 1_000;
__sys_usleep(microseconds);
usleep(microseconds);

0
}
Expand Down Expand Up @@ -286,7 +302,7 @@ pub extern "C" fn sys_join(id: Tid) -> i32 {
static BLOCKED_TASKS: InterruptTicketMutex<BTreeMap<TaskId, TaskHandle>> =
InterruptTicketMutex::new(BTreeMap::new());

extern "C" fn __sys_block_current_task(timeout: &Option<u64>) {
fn block_current_task(timeout: &Option<u64>) {
let wakeup_time = timeout.map(|t| arch::processor::get_timer_ticks() + t * 1000);
let core_scheduler = core_scheduler();
let handle = core_scheduler.get_current_task_handle();
Expand All @@ -296,16 +312,24 @@ extern "C" fn __sys_block_current_task(timeout: &Option<u64>) {
core_scheduler.block_current_task(wakeup_time);
}

extern "C" fn __sys_block_current_task() {
block_current_task(&None)
}

/// Set the current task state to `blocked`
#[no_mangle]
pub extern "C" fn sys_block_current_task() {
kernel_function!(__sys_block_current_task(&None))
kernel_function!(__sys_block_current_task())
}

extern "C" fn __sys_block_current_task_with_timeout(timeout: u64) {
block_current_task(&Some(timeout))
}

/// Set the current task state to `blocked`
#[no_mangle]
pub extern "C" fn sys_block_current_task_with_timeout(timeout: u64) {
kernel_function!(__sys_block_current_task(&Some(timeout)))
kernel_function!(__sys_block_current_task_with_timeout(timeout))
}

extern "C" fn __sys_wakeup_task(id: Tid) {
Expand Down
4 changes: 2 additions & 2 deletions src/syscalls/timer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::arch;
use crate::errno::*;
use crate::syscalls::__sys_usleep;
use crate::syscalls::usleep;
use crate::time::{itimerval, timespec, timeval};

pub(crate) const CLOCK_REALTIME: u64 = 1;
Expand Down Expand Up @@ -124,7 +124,7 @@ extern "C" fn __sys_clock_nanosleep(
}
}

__sys_usleep(microseconds);
usleep(microseconds);
0
}
_ => -EINVAL,
Expand Down

0 comments on commit 7214696

Please sign in to comment.