signal.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. use core::cmp::Reverse;
  2. use crate::{io::BufferFill, kernel::user::dataflow::UserBuffer, prelude::*};
  3. use alloc::collections::{binary_heap::BinaryHeap, btree_map::BTreeMap};
  4. use bindings::{
  5. interrupt_stack, mmx_registers, EFAULT, EINVAL, SA_RESTORER, SIGABRT, SIGBUS, SIGCHLD, SIGCONT,
  6. SIGFPE, SIGILL, SIGKILL, SIGQUIT, SIGSEGV, SIGSTOP, SIGSYS, SIGTRAP, SIGTSTP, SIGTTIN, SIGTTOU,
  7. SIGURG, SIGWINCH, SIGXCPU, SIGXFSZ,
  8. };
  9. use super::{ProcessList, Thread};
  10. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
  11. pub struct Signal(u32);
  12. impl Signal {
  13. pub const SIGHUP: Signal = Signal(1);
  14. pub const SIGINT: Signal = Signal(2);
  15. pub const SIGQUIT: Signal = Signal(3);
  16. pub const SIGILL: Signal = Signal(4);
  17. pub const SIGTRAP: Signal = Signal(5);
  18. pub const SIGABRT: Signal = Signal(6);
  19. pub const SIGIOT: Signal = Signal(6);
  20. pub const SIGBUS: Signal = Signal(7);
  21. pub const SIGFPE: Signal = Signal(8);
  22. pub const SIGKILL: Signal = Signal(9);
  23. pub const SIGUSR1: Signal = Signal(10);
  24. pub const SIGSEGV: Signal = Signal(11);
  25. pub const SIGUSR2: Signal = Signal(12);
  26. pub const SIGPIPE: Signal = Signal(13);
  27. pub const SIGALRM: Signal = Signal(14);
  28. pub const SIGTERM: Signal = Signal(15);
  29. pub const SIGSTKFLT: Signal = Signal(16);
  30. pub const SIGCHLD: Signal = Signal(17);
  31. pub const SIGCONT: Signal = Signal(18);
  32. pub const SIGSTOP: Signal = Signal(19);
  33. pub const SIGTSTP: Signal = Signal(20);
  34. pub const SIGTTIN: Signal = Signal(21);
  35. pub const SIGTTOU: Signal = Signal(22);
  36. pub const SIGURG: Signal = Signal(23);
  37. pub const SIGXCPU: Signal = Signal(24);
  38. pub const SIGXFSZ: Signal = Signal(25);
  39. pub const SIGVTALRM: Signal = Signal(26);
  40. pub const SIGPROF: Signal = Signal(27);
  41. pub const SIGWINCH: Signal = Signal(28);
  42. pub const SIGIO: Signal = Signal(29);
  43. pub const SIGPOLL: Signal = Signal(29);
  44. pub const SIGPWR: Signal = Signal(30);
  45. pub const SIGSYS: Signal = Signal(31);
  46. }
  47. #[derive(Debug, Clone, Copy)]
  48. pub struct SignalAction {
  49. sa_handler: usize,
  50. sa_flags: usize,
  51. sa_restorer: usize,
  52. sa_mask: usize,
  53. }
  54. #[derive(Debug, Clone)]
  55. struct SignalListInner {
  56. mask: u64,
  57. pending: BinaryHeap<Reverse<Signal>>,
  58. // TODO!!!!!: Signal disposition should be per-process.
  59. handlers: BTreeMap<Signal, SignalAction>,
  60. }
  61. #[derive(Debug, Clone)]
  62. pub struct SignalList {
  63. /// We might use this inside interrupt handler, so we need to use `lock_irq`.
  64. inner: Spin<SignalListInner>,
  65. }
  66. #[derive(Debug, Clone, Copy)]
  67. pub enum RaiseResult {
  68. ShouldIWakeUp,
  69. ShouldUWakeUp,
  70. Finished,
  71. Masked,
  72. }
  73. impl Signal {
  74. fn is_continue(&self) -> bool {
  75. self.0 == SIGCONT
  76. }
  77. fn is_stop(&self) -> bool {
  78. match self.0 {
  79. SIGSTOP | SIGTSTP | SIGTTIN | SIGTTOU => true,
  80. _ => false,
  81. }
  82. }
  83. fn is_ignore(&self) -> bool {
  84. match self.0 {
  85. SIGCHLD | SIGURG | SIGWINCH => true,
  86. _ => false,
  87. }
  88. }
  89. pub fn is_now(&self) -> bool {
  90. match self.0 {
  91. SIGKILL | SIGSTOP => true,
  92. _ => false,
  93. }
  94. }
  95. pub fn is_coredump(&self) -> bool {
  96. match self.0 {
  97. SIGQUIT | SIGILL | SIGABRT | SIGFPE | SIGSEGV | SIGBUS | SIGTRAP | SIGSYS | SIGXCPU
  98. | SIGXFSZ => true,
  99. _ => false,
  100. }
  101. }
  102. fn to_mask(&self) -> u64 {
  103. 1 << (self.0 - 1)
  104. }
  105. pub fn to_signum(&self) -> u32 {
  106. self.0
  107. }
  108. }
  109. impl TryFrom<u32> for Signal {
  110. type Error = u32;
  111. fn try_from(signum: u32) -> Result<Self, Self::Error> {
  112. if signum > 0 && signum <= 64 {
  113. Ok(Self(signum))
  114. } else {
  115. Err(EINVAL)
  116. }
  117. }
  118. }
  119. impl SignalAction {
  120. fn default_action() -> Self {
  121. Self {
  122. sa_handler: 0,
  123. sa_flags: 0,
  124. sa_restorer: 0,
  125. sa_mask: 0,
  126. }
  127. }
  128. fn is_ignore(&self) -> bool {
  129. const SIG_IGN: usize = 1;
  130. self.sa_handler == SIG_IGN
  131. }
  132. fn is_default(&self) -> bool {
  133. const SIG_DFL: usize = 0;
  134. self.sa_handler == SIG_DFL
  135. }
  136. /// # Might Sleep
  137. fn handle(
  138. &self,
  139. signum: u32,
  140. int_stack: &mut interrupt_stack,
  141. mmxregs: &mut mmx_registers,
  142. ) -> KResult<()> {
  143. if self.sa_flags & SA_RESTORER as usize == 0 {
  144. return Err(EINVAL);
  145. }
  146. const CONTEXT_SIZE: usize = size_of::<interrupt_stack>()
  147. + size_of::<mmx_registers>()
  148. + 2 * size_of::<u32>() // Signum and address of sa_restorer
  149. + size_of::<usize>(); // Original RSP
  150. // Save current interrupt context to 128 bytes above current user stack
  151. // and align to 16 bytes
  152. // TODO!!!: Determine the size of the return address
  153. let sp = (int_stack.rsp - (128 + CONTEXT_SIZE + size_of::<u32>())) & !0xf;
  154. let restorer_address: u32 = self.sa_restorer as u32;
  155. let mut stack = UserBuffer::new(sp as *mut _, CONTEXT_SIZE)?;
  156. stack.copy(&restorer_address)?.ok_or(EFAULT)?; // Restorer address
  157. stack.copy(&signum)?.ok_or(EFAULT)?; // Signal number
  158. stack.copy(&int_stack.rsp)?.ok_or(EFAULT)?; // Original RSP
  159. stack.copy(mmxregs)?.ok_or(EFAULT)?; // MMX registers
  160. stack.copy(int_stack)?.ok_or(EFAULT)?; // Interrupt stack
  161. int_stack.v_rip = self.sa_handler;
  162. int_stack.rsp = sp;
  163. Ok(())
  164. }
  165. }
  166. impl SignalListInner {
  167. fn get_mask(&self) -> u64 {
  168. self.mask
  169. }
  170. fn set_mask(&mut self, mask: u64) {
  171. self.mask = mask;
  172. }
  173. fn mask(&mut self, mask: u64) {
  174. self.set_mask(self.mask | mask)
  175. }
  176. fn unmask(&mut self, mask: u64) {
  177. self.set_mask(self.mask & !mask)
  178. }
  179. fn is_masked(&self, signal: Signal) -> bool {
  180. self.mask & signal.to_mask() != 0
  181. }
  182. fn pop(&mut self) -> Option<Signal> {
  183. self.pending.pop().map(|Reverse(signal)| signal)
  184. }
  185. fn raise(&mut self, signal: Signal) -> RaiseResult {
  186. if self.is_masked(signal) {
  187. return RaiseResult::Masked;
  188. }
  189. match self.handlers.get(&signal) {
  190. // Ignore action
  191. Some(handler) if handler.is_ignore() => return RaiseResult::Finished,
  192. // Default action
  193. None if signal.is_ignore() => return RaiseResult::Finished,
  194. _ => {}
  195. }
  196. self.mask(signal.to_mask());
  197. self.pending.push(Reverse(signal));
  198. if signal.is_stop() {
  199. return RaiseResult::Finished;
  200. }
  201. // TODO!!!!!!: Fix this. SIGCONT could wake up USleep threads.
  202. if signal.is_continue() {
  203. return RaiseResult::ShouldUWakeUp;
  204. }
  205. return RaiseResult::ShouldIWakeUp;
  206. }
  207. }
  208. impl SignalList {
  209. pub fn new() -> Self {
  210. Self {
  211. inner: Spin::new(SignalListInner {
  212. mask: 0,
  213. pending: BinaryHeap::new(),
  214. handlers: BTreeMap::new(),
  215. }),
  216. }
  217. }
  218. pub fn get_mask(&self) -> u64 {
  219. self.inner.lock_irq().get_mask()
  220. }
  221. pub fn set_mask(&self, mask: u64) {
  222. self.inner.lock_irq().set_mask(mask)
  223. }
  224. pub fn mask(&self, mask: u64) {
  225. self.inner.lock_irq().set_mask(mask)
  226. }
  227. pub fn unmask(&self, mask: u64) {
  228. self.inner.lock_irq().unmask(mask)
  229. }
  230. pub fn set_handler(&self, signal: Signal, action: &SignalAction) -> KResult<()> {
  231. if signal.is_now() {
  232. return Err(EINVAL);
  233. }
  234. let mut inner = self.inner.lock_irq();
  235. if action.is_default() {
  236. inner.handlers.remove(&signal);
  237. } else {
  238. inner.handlers.insert(signal, action.clone());
  239. }
  240. Ok(())
  241. }
  242. pub fn get_handler(&self, signal: Signal) -> SignalAction {
  243. self.inner
  244. .lock_irq()
  245. .handlers
  246. .get(&signal)
  247. .cloned()
  248. .unwrap_or_else(SignalAction::default_action)
  249. }
  250. /// Clear all signals except for `SIG_IGN`.
  251. /// This is used when `execve` is called.
  252. pub fn clear_non_ignore(&self) {
  253. self.inner
  254. .lock_irq()
  255. .handlers
  256. .retain(|_, action| action.is_ignore());
  257. }
  258. /// Clear all pending signals.
  259. /// This is used when `fork` is called.
  260. pub fn clear_pending(&self) {
  261. self.inner.lock_irq().pending.clear()
  262. }
  263. pub fn has_pending_signal(&self) -> bool {
  264. !self.inner.lock_irq().pending.is_empty()
  265. }
  266. /// Do not use this, use `Thread::raise` instead.
  267. pub(super) fn raise(&self, signal: Signal) -> RaiseResult {
  268. self.inner.lock_irq().raise(signal)
  269. }
  270. /// Handle signals in the context of `Thread::current()`.
  271. ///
  272. /// # Safety
  273. /// This function might never return. Caller must make sure that local variables
  274. /// that own resources are dropped before calling this function.
  275. pub fn handle(&self, int_stack: &mut interrupt_stack, mmxregs: &mut mmx_registers) {
  276. loop {
  277. let signal = {
  278. let mut inner = self.inner.lock_irq();
  279. let signal = match inner.pop() {
  280. Some(signal) => signal,
  281. None => return,
  282. };
  283. if let Some(handler) = inner.handlers.get(&signal) {
  284. if !signal.is_now() {
  285. let result = handler.handle(signal.to_signum(), int_stack, mmxregs);
  286. match result {
  287. Err(EFAULT) => inner.raise(Signal::SIGSEGV),
  288. Err(_) => inner.raise(Signal::SIGSYS),
  289. Ok(()) => return,
  290. };
  291. continue;
  292. }
  293. }
  294. // Default actions include stopping the thread, continuing the thread and
  295. // terminating the process. All these actions will block the thread or return
  296. // to the thread immediately. So we can unmask these signals now.
  297. inner.unmask(signal.to_mask());
  298. signal
  299. };
  300. // Default actions.
  301. match signal {
  302. Signal::SIGSTOP => Thread::current().do_stop(Signal::SIGSTOP),
  303. Signal::SIGCONT => Thread::current().do_continue(),
  304. Signal::SIGKILL => ProcessList::kill_current(signal),
  305. // Ignored
  306. Signal::SIGCHLD | Signal::SIGURG | Signal::SIGWINCH => continue,
  307. // "Soft" stops.
  308. Signal::SIGTSTP | Signal::SIGTTIN | Signal::SIGTTOU => {
  309. Thread::current().do_stop(signal)
  310. }
  311. // TODO!!!!!!: Check exit status format.
  312. s if s.is_coredump() => ProcessList::kill_current(signal),
  313. signal => ProcessList::kill_current(signal),
  314. }
  315. }
  316. }
  317. }