signal.rs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. mod signal;
  2. mod signal_action;
  3. mod signal_mask;
  4. use super::{ProcessList, Thread, WaitObject, WaitType};
  5. use crate::{kernel::user::UserPointer, prelude::*};
  6. use alloc::collections::binary_heap::BinaryHeap;
  7. use arch::{FpuState, TrapContext};
  8. use bindings::{EFAULT, EINVAL};
  9. use core::{cmp::Reverse, task::Waker};
  10. use eonix_hal::traits::trap::RawTrapContext;
  11. use eonix_runtime::task::Task;
  12. use eonix_sync::AsProof as _;
  13. use intrusive_collections::UnsafeRef;
  14. use signal_action::SignalActionList;
  15. pub use signal::{Signal, SIGNAL_IGNORE, SIGNAL_NOW, SIGNAL_STOP};
  16. pub use signal_action::SignalAction;
  17. pub use signal_mask::SignalMask;
  18. pub(self) const SAVED_DATA_SIZE: usize =
  19. size_of::<TrapContext>() + size_of::<FpuState>() + size_of::<SignalMask>();
  20. struct SignalListInner {
  21. mask: SignalMask,
  22. pending: BinaryHeap<Reverse<Signal>>,
  23. signal_waker: Option<UnsafeRef<dyn Fn() + Send + Sync>>,
  24. stop_waker: Option<Waker>,
  25. // TODO!!!!!: Signal disposition should be per-process.
  26. actions: SignalActionList,
  27. }
  28. pub struct SignalList {
  29. inner: Spin<SignalListInner>,
  30. }
  31. impl Clone for SignalList {
  32. fn clone(&self) -> Self {
  33. let inner = self.inner.lock();
  34. debug_assert!(
  35. inner.stop_waker.is_none(),
  36. "We should not have a stop waker here"
  37. );
  38. Self {
  39. inner: Spin::new(SignalListInner {
  40. mask: inner.mask,
  41. pending: BinaryHeap::new(),
  42. signal_waker: None,
  43. stop_waker: None,
  44. actions: inner.actions.clone(),
  45. }),
  46. }
  47. }
  48. }
  49. #[derive(Debug, Clone, Copy)]
  50. pub enum RaiseResult {
  51. Finished,
  52. Masked,
  53. }
  54. impl SignalListInner {
  55. fn pop(&mut self) -> Option<Signal> {
  56. self.pending.pop().map(|Reverse(signal)| signal)
  57. }
  58. fn raise(&mut self, signal: Signal) -> RaiseResult {
  59. if self.mask.include(signal) {
  60. return RaiseResult::Masked;
  61. }
  62. match (signal, self.actions.get(signal)) {
  63. (_, SignalAction::Ignore) => {}
  64. (SIGNAL_IGNORE!(), SignalAction::Default) => {}
  65. _ => {
  66. self.mask.mask(SignalMask::from(signal));
  67. self.pending.push(Reverse(signal));
  68. if matches!(signal, Signal::SIGCONT) {
  69. self.stop_waker.take().map(|waker| waker.wake());
  70. } else {
  71. // If we don't have a waker here, we are not permitted to be woken up.
  72. // We would run in the end anyway.
  73. if let Some(waker) = self.signal_waker.take() {
  74. waker();
  75. }
  76. }
  77. }
  78. }
  79. RaiseResult::Finished
  80. }
  81. }
  82. impl SignalList {
  83. pub fn new() -> Self {
  84. Self {
  85. inner: Spin::new(SignalListInner {
  86. mask: SignalMask::empty(),
  87. pending: BinaryHeap::new(),
  88. signal_waker: None,
  89. stop_waker: None,
  90. actions: SignalActionList::new(),
  91. }),
  92. }
  93. }
  94. pub fn get_mask(&self) -> SignalMask {
  95. self.inner.lock().mask
  96. }
  97. pub fn set_mask(&self, mask: SignalMask) {
  98. self.inner.lock().mask = mask;
  99. }
  100. pub fn mask(&self, mask: SignalMask) {
  101. self.inner.lock().mask.mask(mask)
  102. }
  103. pub fn unmask(&self, mask: SignalMask) {
  104. self.inner.lock().mask.unmask(mask)
  105. }
  106. pub fn set_action(&self, signal: Signal, action: SignalAction) -> KResult<()> {
  107. if matches!(signal, SIGNAL_NOW!()) {
  108. return Err(EINVAL);
  109. }
  110. self.inner.lock().actions.set(signal, action);
  111. Ok(())
  112. }
  113. pub fn get_action(&self, signal: Signal) -> SignalAction {
  114. self.inner.lock().actions.get(signal)
  115. }
  116. pub fn set_signal_waker(&self, waker: Option<UnsafeRef<dyn Fn() + Send + Sync>>) {
  117. let mut inner = self.inner.lock();
  118. inner.signal_waker = waker;
  119. }
  120. /// Clear all signals except for `SIG_IGN`.
  121. /// This is used when `execve` is called.
  122. pub fn clear_non_ignore(&self) {
  123. self.inner.lock().actions.remove_non_ignore();
  124. }
  125. /// Clear all pending signals.
  126. /// This is used when `fork` is called.
  127. pub fn clear_pending(&self) {
  128. self.inner.lock().pending.clear()
  129. }
  130. pub fn has_pending_signal(&self) -> bool {
  131. !self.inner.lock().pending.is_empty()
  132. }
  133. /// Do not use this, use `Thread::raise` instead.
  134. pub(super) fn raise(&self, signal: Signal) -> RaiseResult {
  135. self.inner.lock().raise(signal)
  136. }
  137. /// Handle signals in the context of `Thread::current()`.
  138. pub async fn handle(&self, trap_ctx: &mut TrapContext, fpu_state: &mut FpuState) {
  139. loop {
  140. let signal = {
  141. let signal = match self.inner.lock().pop() {
  142. Some(signal) => signal,
  143. None => return,
  144. };
  145. let handler = self.inner.lock().actions.get(signal);
  146. if let SignalAction::SimpleHandler { mask, .. } = &handler {
  147. let old_mask = {
  148. let mut inner = self.inner.lock();
  149. let old_mask = inner.mask;
  150. inner.mask.mask(*mask);
  151. old_mask
  152. };
  153. let result = handler.handle(signal, old_mask, trap_ctx, fpu_state);
  154. if result.is_err() {
  155. self.inner.lock().mask = old_mask;
  156. }
  157. match result {
  158. Err(EFAULT) => self.inner.lock().raise(Signal::SIGSEGV),
  159. Err(_) => self.inner.lock().raise(Signal::SIGSYS),
  160. Ok(()) => return,
  161. };
  162. continue;
  163. }
  164. // TODO: The default signal handling process should be atomic.
  165. // Default actions include stopping the thread, continuing the thread and
  166. // terminating the process. All these actions will block the thread or return
  167. // to the thread immediately. So we can unmask these signals now.
  168. self.inner.lock().mask.unmask(SignalMask::from(signal));
  169. signal
  170. };
  171. // Default actions.
  172. match signal {
  173. SIGNAL_IGNORE!() => {}
  174. Signal::SIGCONT => {
  175. // SIGCONT wakeup is done in `raise()`. So no further action needed here.
  176. }
  177. SIGNAL_STOP!() => {
  178. let thread = Thread::current();
  179. if let Some(parent) = thread.process.parent.load() {
  180. parent.notify(
  181. WaitObject {
  182. pid: thread.process.pid,
  183. code: WaitType::Stopped(signal),
  184. },
  185. ProcessList::get().read().await.prove(),
  186. );
  187. }
  188. eonix_preempt::disable();
  189. // `SIGSTOP` can only be waken up by `SIGCONT` or `SIGKILL`.
  190. // SAFETY: Preempt disabled above.
  191. {
  192. let mut inner = self.inner.lock();
  193. let waker = Waker::from(Task::current().clone());
  194. let old_waker = inner.stop_waker.replace(waker);
  195. assert!(old_waker.is_none(), "We should not have a waker here");
  196. }
  197. Task::park_preempt_disabled();
  198. if let Some(parent) = thread.process.parent.load() {
  199. parent.notify(
  200. WaitObject {
  201. pid: thread.process.pid,
  202. code: WaitType::Continued,
  203. },
  204. ProcessList::get().read().await.prove(),
  205. );
  206. }
  207. }
  208. signal => {
  209. // Default to terminate the process.
  210. Thread::current().process.force_kill(signal).await;
  211. return;
  212. }
  213. }
  214. }
  215. }
  216. /// Load the signal mask, fpu state and trap context from the user stack.
  217. pub fn restore(&self, trap_ctx: &mut TrapContext, fpu_state: &mut FpuState) -> KResult<()> {
  218. let old_trap_ctx_vaddr = trap_ctx.get_stack_pointer() + 16 - 4;
  219. let old_fpu_state_vaddr = old_trap_ctx_vaddr + size_of::<TrapContext>();
  220. let old_mask_vaddr = old_fpu_state_vaddr + size_of::<FpuState>();
  221. *trap_ctx = UserPointer::<TrapContext>::new_vaddr(old_trap_ctx_vaddr)?.read()?;
  222. if !trap_ctx.is_user_mode() || !trap_ctx.is_interrupt_enabled() {
  223. return Err(EFAULT)?;
  224. }
  225. *fpu_state = UserPointer::<FpuState>::new_vaddr(old_fpu_state_vaddr)?.read()?;
  226. self.inner.lock().mask = UserPointer::<SignalMask>::new_vaddr(old_mask_vaddr)?.read()?;
  227. Ok(())
  228. }
  229. }