Skip to content

Commit 7e43892

Browse files
syscall_check_signals: implement todo!()
Signed-off-by: Andy-Python-Programmer <[email protected]>
1 parent 575dc67 commit 7e43892

File tree

2 files changed

+72
-10
lines changed

2 files changed

+72
-10
lines changed

src/aero_kernel/src/arch/x86_64/signals.rs

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
1818
*/
1919

20+
use aero_syscall::signal::{SigProcMask, SignalFlags};
21+
use aero_syscall::AeroSyscallError;
22+
2023
use crate::userland;
2124
use crate::userland::scheduler;
2225
use crate::utils::StackHelper;
@@ -42,6 +45,23 @@ impl SignalFrame {
4245
sigmask,
4346
}
4447
}
48+
49+
fn from_syscall(
50+
restart: bool,
51+
syscall_result: u64,
52+
frame: &mut InterruptStack,
53+
sigmask: u64,
54+
) -> SignalFrame {
55+
SignalFrame {
56+
restart_syscall: if restart {
57+
frame.scratch.rax // syscall number
58+
} else {
59+
syscall_result
60+
},
61+
frame: *frame,
62+
sigmask,
63+
}
64+
}
4565
}
4666

4767
pub fn interrupt_check_signals(stack: &mut InterruptStack) {
@@ -59,12 +79,7 @@ pub fn interrupt_check_signals(stack: &mut InterruptStack) {
5979
let old_mask = signals.blocked_mask();
6080

6181
let signal_frame = SignalFrame::from_interrupt(stack, old_mask);
62-
63-
signals.set_mask(
64-
aero_syscall::signal::SigProcMask::Block,
65-
1u64 << signal,
66-
None,
67-
);
82+
signals.set_mask(SigProcMask::Block, 1u64 << signal, None);
6883

6984
// We cannot straight away update the stack pointer from the stack
7085
// helper, since it will created a reference to a packed field which
@@ -92,10 +107,47 @@ pub fn interrupt_check_signals(stack: &mut InterruptStack) {
92107
}
93108
}
94109

95-
pub fn syscall_check_signals(_syscall_result: isize, _stack: &mut InterruptStack) {
96-
if let Some((_signal, entry)) = userland::signals::check_for_signals() {
97-
if let aero_syscall::signal::SignalHandler::Handle(_) = entry.handler() {
98-
todo!()
110+
pub fn syscall_check_signals(syscall_result: isize, stack: &mut InterruptStack) {
111+
if let Some((signal, entry)) = userland::signals::check_for_signals() {
112+
if let aero_syscall::signal::SignalHandler::Handle(func) = entry.handler() {
113+
let task = scheduler::get_scheduler().current_task();
114+
115+
let signals = task.signals();
116+
let old_mask = signals.blocked_mask();
117+
118+
let syscall_rresult = aero_syscall::isize_as_syscall_result(syscall_result);
119+
let restart_syscall = syscall_rresult == Err(AeroSyscallError::EINTR)
120+
&& entry.flags().contains(SignalFlags::SA_RESTART);
121+
122+
#[cfg(feature = "syslog")]
123+
log::warn!("syscall routine signaled: (restart={restart_syscall})");
124+
125+
let signal_frame =
126+
SignalFrame::from_syscall(restart_syscall, syscall_result as _, stack, old_mask);
127+
signals.set_mask(SigProcMask::Block, 1u64 << signal, None);
128+
129+
// We cannot straight away update the stack pointer from the stack
130+
// helper, since it will created a reference to a packed field which
131+
// is undefined behavior. So we create a copy of the current rsp and
132+
// update the actual rsp with the updated rsp.
133+
let mut ptr = stack.iret.rsp;
134+
let mut writer = StackHelper::new(&mut ptr);
135+
136+
// Signal handlers are executed on the same stack, but 128 bytes
137+
// known as the red zone is subtracted from the stack before
138+
// anything is pushed to the stack. This allows small leaf
139+
// functions to use 128 bytes of stack space without reserving
140+
// stack space by subtracting from the stack pointer.
141+
writer.skip_by(REDZONE_SIZE);
142+
143+
unsafe {
144+
writer.write(signal_frame);
145+
writer.write(entry.sigreturn());
146+
}
147+
148+
stack.iret.rsp = ptr;
149+
stack.iret.rip = func as u64;
150+
stack.scratch.rdi = signal as u64;
99151
}
100152
}
101153
}
@@ -118,6 +170,12 @@ pub fn sigreturn(stack: &mut InterruptStack) -> usize {
118170
*stack = signal_frame.frame;
119171

120172
if signal_frame.restart_syscall != u64::MAX {
173+
#[cfg(feature = "syslog")]
174+
log::debug!(
175+
"sigreturn: restarting {} syscall",
176+
aero_syscall::syscall_as_str(signal_frame.restart_syscall as _)
177+
);
178+
121179
stack.iret.rip -= SYSCALL_INSTRUCTION_SIZE;
122180
}
123181

src/aero_kernel/src/userland/signals.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ impl SignalEntry {
169169
sa_sigaction: 0,
170170
}
171171
}
172+
173+
pub fn flags(&self) -> SignalFlags {
174+
self.flags
175+
}
172176
}
173177

174178
impl SignalEntry {

0 commit comments

Comments
 (0)