From 6a42bb3b4a46fd24687fbf24a4015a787127adde Mon Sep 17 00:00:00 2001 From: Zejun Zhao Date: Fri, 26 Sep 2025 13:28:12 +0800 Subject: [PATCH] Make syscall restart mechanism work across all architectures --- kernel/src/arch/loongarch/cpu.rs | 4 ---- kernel/src/arch/riscv/cpu.rs | 4 ---- kernel/src/arch/x86/cpu.rs | 4 ---- kernel/src/cpu.rs | 3 --- kernel/src/process/signal/mod.rs | 10 +++++----- kernel/src/thread/task.rs | 6 +++--- 6 files changed, 8 insertions(+), 23 deletions(-) diff --git a/kernel/src/arch/loongarch/cpu.rs b/kernel/src/arch/loongarch/cpu.rs index a08984f55..a6c5a6121 100644 --- a/kernel/src/arch/loongarch/cpu.rs +++ b/kernel/src/arch/loongarch/cpu.rs @@ -17,10 +17,6 @@ impl LinuxAbi for UserContext { self.a7() } - fn set_syscall_num(&mut self, num: usize) { - self.set_a7(num); - } - fn syscall_ret(&self) -> usize { self.a0() } diff --git a/kernel/src/arch/riscv/cpu.rs b/kernel/src/arch/riscv/cpu.rs index 707c1a69e..7b5cab29d 100644 --- a/kernel/src/arch/riscv/cpu.rs +++ b/kernel/src/arch/riscv/cpu.rs @@ -17,10 +17,6 @@ impl LinuxAbi for UserContext { self.a7() } - fn set_syscall_num(&mut self, num: usize) { - self.set_a7(num); - } - fn syscall_ret(&self) -> usize { self.a0() } diff --git a/kernel/src/arch/x86/cpu.rs b/kernel/src/arch/x86/cpu.rs index 9bae0dd16..d28620730 100644 --- a/kernel/src/arch/x86/cpu.rs +++ b/kernel/src/arch/x86/cpu.rs @@ -29,10 +29,6 @@ impl LinuxAbi for UserContext { self.rax() } - fn set_syscall_num(&mut self, num: usize) { - self.set_rax(num); - } - fn set_syscall_ret(&mut self, ret: usize) { self.set_rax(ret); } diff --git a/kernel/src/cpu.rs b/kernel/src/cpu.rs index 72597874b..c872ac5df 100644 --- a/kernel/src/cpu.rs +++ b/kernel/src/cpu.rs @@ -8,9 +8,6 @@ pub trait LinuxAbi { /// Gets the return value of the system call. fn syscall_ret(&self) -> usize; - /// Sets the system call number. - fn set_syscall_num(&mut self, num: usize); - /// Sets the return value of the system call. fn set_syscall_ret(&mut self, ret: usize); diff --git a/kernel/src/process/signal/mod.rs b/kernel/src/process/signal/mod.rs index 91c9022cc..8261ab151 100644 --- a/kernel/src/process/signal/mod.rs +++ b/kernel/src/process/signal/mod.rs @@ -49,14 +49,14 @@ pub trait SignalContext { pub fn handle_pending_signal( user_ctx: &mut UserContext, ctx: &Context, - syscall_number: Option, + pre_syscall_ret: Option, ) { - let syscall_restart = if let Some(syscall_number) = syscall_number + let syscall_restart = if let Some(pre_syscall_ret) = pre_syscall_ret && user_ctx.syscall_ret() == -(Errno::ERESTARTSYS as i32) as usize { // We should never return `ERESTARTSYS` to the userspace. user_ctx.set_syscall_ret(-(Errno::EINTR as i32) as usize); - Some(syscall_number) + Some(pre_syscall_ret) } else { None }; @@ -90,7 +90,7 @@ pub fn handle_pending_signal( restorer_addr, mask, } => { - if let Some(syscall_number) = syscall_restart + if let Some(pre_syscall_ret) = syscall_restart && flags.contains(SigActionFlags::SA_RESTART) { #[cfg(target_arch = "x86_64")] @@ -100,7 +100,7 @@ pub fn handle_pending_signal( #[cfg(target_arch = "loongarch64")] const SYSCALL_INSTR_LEN: usize = 4; // syscall - user_ctx.set_syscall_num(syscall_number); + user_ctx.set_syscall_ret(pre_syscall_ret); user_ctx .set_instruction_pointer(user_ctx.instruction_pointer() - SYSCALL_INSTR_LEN); } diff --git a/kernel/src/thread/task.rs b/kernel/src/thread/task.rs index ea9e610b8..72e64a5b6 100644 --- a/kernel/src/thread/task.rs +++ b/kernel/src/thread/task.rs @@ -83,14 +83,14 @@ pub fn create_new_user_task( // Handle user events let user_ctx = user_mode.context_mut(); - let mut syscall_number = None; + let mut pre_syscall_ret = None; match return_reason { ReturnReason::UserException => { let exception = user_ctx.take_exception().unwrap(); handle_exception(&ctx, user_ctx, exception) } ReturnReason::UserSyscall => { - syscall_number = Some(user_ctx.syscall_num()); + pre_syscall_ret = Some(user_ctx.syscall_ret()); handle_syscall(&ctx, user_ctx); } ReturnReason::KernelEvent => {} @@ -102,7 +102,7 @@ pub fn create_new_user_task( } // Handle signals - handle_pending_signal(user_ctx, &ctx, syscall_number); + handle_pending_signal(user_ctx, &ctx, pre_syscall_ret); // Handle signals while the thread is stopped // FIXME: Currently, we handle all signals when the process is stopped.