Make syscall restart mechanism work across all architectures
This commit is contained in:
parent
4c26a7a7c5
commit
6a42bb3b4a
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,14 +49,14 @@ pub trait SignalContext {
|
|||
pub fn handle_pending_signal(
|
||||
user_ctx: &mut UserContext,
|
||||
ctx: &Context,
|
||||
syscall_number: Option<usize>,
|
||||
pre_syscall_ret: Option<usize>,
|
||||
) {
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue