signal.rs 13 KB

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