Force userspace to do post-syscall EINTR check.

This commit is contained in:
4lDO2
2024-06-27 21:49:19 +02:00
parent e8060b259d
commit f91b90445d
8 changed files with 9 additions and 26 deletions
+2 -1
View File
@@ -174,9 +174,10 @@ exception_stack!(synchronous_exception_at_el0, |stack| {
match exception_code(stack.iret.esr_el1) {
0b010101 => {
let scratch = &stack.scratch;
syscall::syscall(
let ret = syscall::syscall(
scratch.x8, scratch.x0, scratch.x1, scratch.x2, scratch.x3, scratch.x4, stack,
);
scratch.x0 = ret;
}
ty => {
-4
View File
@@ -132,10 +132,6 @@ impl InterruptStack {
pub fn instr_pointer(&self) -> usize {
self.iret.elr_el1
}
// TODO: This can maybe be done in userspace?
pub fn set_syscall_ret_reg(&mut self, ret: usize) {
self.scratch.x0 = ret;
}
pub fn dump(&self) {
self.iret.dump();
self.scratch.dump();
-4
View File
@@ -136,10 +136,6 @@ impl InterruptStack {
pub fn set_instr_pointer(&mut self, eip: usize) {
self.iret.eip = eip;
}
// TODO: This can maybe be done in userspace?
pub fn set_syscall_ret_reg(&mut self, ret: usize) {
self.scratch.eax = ret;
}
/// Loads all registers from a struct used by the proc:
/// scheme to read/write registers.
pub fn load(&mut self, all: &IntRegisters) {
+2 -1
View File
@@ -30,7 +30,7 @@ interrupt_stack!(syscall, |stack| {
with_interrupt_stack!(|stack| {
let scratch = &stack.scratch;
let preserved = &stack.preserved;
syscall::syscall(
let ret = syscall::syscall(
scratch.eax,
preserved.ebx,
scratch.ecx,
@@ -39,6 +39,7 @@ interrupt_stack!(syscall, |stack| {
preserved.edi,
stack,
);
stack.scratch.eax = ret;
})
});
-4
View File
@@ -116,10 +116,6 @@ impl InterruptStack {
pub fn set_instr_pointer(&mut self, rip: usize) {
self.iret.rip = rip;
}
// TODO: This can maybe be done in userspace?
pub fn set_syscall_ret_reg(&mut self, ret: usize) {
self.scratch.rax = ret;
}
pub fn dump(&self) {
self.iret.dump();
+2 -1
View File
@@ -68,7 +68,7 @@ pub unsafe extern "C" fn __inner_syscall_instruction(stack: *mut InterruptStack)
if allowed.unwrap_or(true) {
let scratch = &(*stack).scratch;
syscall::syscall(
let ret = syscall::syscall(
scratch.rax,
scratch.rdi,
scratch.rsi,
@@ -77,6 +77,7 @@ pub unsafe extern "C" fn __inner_syscall_instruction(stack: *mut InterruptStack)
scratch.r8,
&mut *stack,
);
(*stack).scratch.rax = ret;
}
ptrace::breakpoint_callback(PTRACE_STOP_POST_SYSCALL, None);
+2 -10
View File
@@ -67,7 +67,7 @@ pub fn syscall(
e: usize,
f: usize,
stack: &mut InterruptStack,
) {
) -> usize {
#[inline(always)]
fn inner(
a: usize,
@@ -247,13 +247,5 @@ pub fn syscall(
PercpuBlock::current().inside_syscall.set(false);
// errormux turns Result<usize> into -errno
stack.set_syscall_ret_reg(Error::mux(result));
if result == Err(Error::new(EINTR)) {
// Although it would be cleaner to simply run the signal trampoline right after switching
// back to any given context, where the signal set/queue is nonempty, syscalls need to
// complete *before* any signal is delivered. Otherwise the return value would probably be
// overwritten.
crate::context::signal::signal_handler();
}
Error::mux(result)
}
+1 -1
Submodule syscall updated: bda8fe89c6...9609c7bc26