xref: /DragonOS/kernel/src/ipc/signal_types.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
1 use core::{
2     ffi::c_void,
3     mem::size_of,
4     ops::{Deref, DerefMut},
5     sync::atomic::AtomicI64,
6 };
7 
8 use alloc::{boxed::Box, vec::Vec};
9 use system_error::SystemError;
10 
11 use crate::{
12     arch::{
13         asm::bitops::ffz,
14         interrupt::TrapFrame,
15         ipc::signal::{SigCode, SigFlags, SigSet, Signal, MAX_SIG_NUM},
16     },
17     mm::VirtAddr,
18     process::Pid,
19     syscall::user_access::UserBufferWriter,
20 };
21 
22 /// 用户态程序传入的SIG_DFL的值
23 pub const USER_SIG_DFL: u64 = 0;
24 /// 用户态程序传入的SIG_IGN的值
25 pub const USER_SIG_IGN: u64 = 1;
26 /// 用户态程序传入的SIG_ERR的值
27 pub const USER_SIG_ERR: u64 = 2;
28 
29 // 因为 Rust 编译器不能在常量声明中正确识别级联的 "|" 运算符(experimental feature: https://github.com/rust-lang/rust/issues/67792),因此
30 // 暂时只能通过这种方法来声明这些常量,这些常量暂时没有全部用到,但是都出现在 linux 的判断逻辑中,所以都保留下来了
31 #[allow(dead_code)]
32 pub const SIG_KERNEL_ONLY_MASK: SigSet =
33     Signal::into_sigset(Signal::SIGSTOP).union(Signal::into_sigset(Signal::SIGKILL));
34 
35 pub const SIG_KERNEL_STOP_MASK: SigSet = Signal::into_sigset(Signal::SIGSTOP)
36     .union(Signal::into_sigset(Signal::SIGTSTP))
37     .union(Signal::into_sigset(Signal::SIGTTIN))
38     .union(Signal::into_sigset(Signal::SIGTTOU));
39 #[allow(dead_code)]
40 pub const SIG_KERNEL_COREDUMP_MASK: SigSet = Signal::into_sigset(Signal::SIGQUIT)
41     .union(Signal::into_sigset(Signal::SIGILL))
42     .union(Signal::into_sigset(Signal::SIGTRAP))
43     .union(Signal::into_sigset(Signal::SIGABRT_OR_IOT))
44     .union(Signal::into_sigset(Signal::SIGFPE))
45     .union(Signal::into_sigset(Signal::SIGSEGV))
46     .union(Signal::into_sigset(Signal::SIGBUS))
47     .union(Signal::into_sigset(Signal::SIGSYS))
48     .union(Signal::into_sigset(Signal::SIGXCPU))
49     .union(Signal::into_sigset(Signal::SIGXFSZ));
50 #[allow(dead_code)]
51 pub const SIG_KERNEL_IGNORE_MASK: SigSet = Signal::into_sigset(Signal::SIGCONT)
52     .union(Signal::into_sigset(Signal::SIGFPE))
53     .union(Signal::into_sigset(Signal::SIGSEGV))
54     .union(Signal::into_sigset(Signal::SIGBUS))
55     .union(Signal::into_sigset(Signal::SIGTRAP))
56     .union(Signal::into_sigset(Signal::SIGCHLD))
57     .union(Signal::into_sigset(Signal::SIGIO_OR_POLL))
58     .union(Signal::into_sigset(Signal::SIGSYS));
59 
60 /// SignalStruct 在 pcb 中加锁
61 #[derive(Debug)]
62 pub struct SignalStruct {
63     inner: Box<InnerSignalStruct>,
64 }
65 
66 #[derive(Debug)]
67 #[allow(dead_code)]
68 pub struct InnerSignalStruct {
69     pub cnt: AtomicI64,
70     /// 如果对应linux,这部分会有一个引用计数,但是没发现在哪里有用到需要计算引用的地方,因此
71     /// 暂时删掉,不然这个Arc会导致其他地方的代码十分丑陋
72     pub handlers: [Sigaction; MAX_SIG_NUM],
73 }
74 
75 impl SignalStruct {
76     #[inline(never)]
new() -> Self77     pub fn new() -> Self {
78         Self {
79             inner: Box::<InnerSignalStruct>::default(),
80         }
81     }
82 }
83 
84 impl Default for SignalStruct {
default() -> Self85     fn default() -> Self {
86         Self::new()
87     }
88 }
89 
90 impl Deref for SignalStruct {
91     type Target = InnerSignalStruct;
92 
deref(&self) -> &Self::Target93     fn deref(&self) -> &Self::Target {
94         &self.inner
95     }
96 }
97 
98 impl DerefMut for SignalStruct {
deref_mut(&mut self) -> &mut Self::Target99     fn deref_mut(&mut self) -> &mut Self::Target {
100         &mut self.inner
101     }
102 }
103 
104 impl Default for InnerSignalStruct {
default() -> Self105     fn default() -> Self {
106         Self {
107             cnt: Default::default(),
108             handlers: [Sigaction::default(); MAX_SIG_NUM],
109         }
110     }
111 }
112 
113 #[derive(Debug, Copy, Clone)]
114 #[allow(dead_code)]
115 pub enum SigactionType {
116     SaHandler(SaHandlerType),
117     SaSigaction(
118         Option<
119             unsafe extern "C" fn(
120                 sig: ::core::ffi::c_int,
121                 sinfo: *mut SigInfo,
122                 arg1: *mut ::core::ffi::c_void,
123             ),
124         >,
125     ), // 暂时没有用上
126 }
127 
128 impl SigactionType {
129     /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigIgnore)`].
130     ///
131     /// [`SigIgnore`]: SaHandlerType::SigIgnore
is_ignore(&self) -> bool132     pub fn is_ignore(&self) -> bool {
133         return matches!(self, Self::SaHandler(SaHandlerType::Ignore));
134     }
135     /// Returns `true` if the sa handler type is [`SaHandler(SaHandlerType::SigCustomized(_))`].
136     ///
137     /// [`SigCustomized`]: SaHandlerType::SigCustomized(_)
is_customized(&self) -> bool138     pub fn is_customized(&self) -> bool {
139         return matches!(self, Self::SaHandler(SaHandlerType::Customized(_)));
140     }
141 }
142 
143 #[derive(Debug, Copy, Clone)]
144 #[allow(dead_code)]
145 pub enum SaHandlerType {
146     Error, // 暂时没有用上
147     Default,
148     Ignore,
149     Customized(VirtAddr),
150 }
151 
152 impl From<SaHandlerType> for usize {
from(value: SaHandlerType) -> Self153     fn from(value: SaHandlerType) -> Self {
154         match value {
155             SaHandlerType::Error => 2,
156             SaHandlerType::Ignore => 1,
157             SaHandlerType::Default => 0,
158             SaHandlerType::Customized(handler) => handler.data(),
159         }
160     }
161 }
162 
163 impl SaHandlerType {
164     /// Returns `true` if the sa handler type is [`SigDefault`].
165     ///
166     /// [`SigDefault`]: SaHandlerType::SigDefault
is_sig_default(&self) -> bool167     pub fn is_sig_default(&self) -> bool {
168         matches!(self, Self::Default)
169     }
170 
171     /// Returns `true` if the sa handler type is [`SigIgnore`].
172     ///
173     /// [`SigIgnore`]: SaHandlerType::SigIgnore
is_sig_ignore(&self) -> bool174     pub fn is_sig_ignore(&self) -> bool {
175         matches!(self, Self::Ignore)
176     }
177 
178     /// Returns `true` if the sa handler type is [`SigError`].
179     ///
180     /// [`SigError`]: SaHandlerType::SigError
is_sig_error(&self) -> bool181     pub fn is_sig_error(&self) -> bool {
182         matches!(self, Self::Error)
183     }
184 }
185 
186 /// 信号处理结构体
187 ///
188 #[derive(Debug, Copy, Clone)]
189 pub struct Sigaction {
190     action: SigactionType,
191     flags: SigFlags,
192     mask: SigSet, // 为了可扩展性而设置的sa_mask
193     /// 信号处理函数执行结束后,将会跳转到这个函数内进行执行,然后执行sigreturn系统调用
194     restorer: Option<VirtAddr>,
195 }
196 
197 impl Default for Sigaction {
default() -> Self198     fn default() -> Self {
199         Self {
200             action: SigactionType::SaHandler(SaHandlerType::Default),
201             flags: Default::default(),
202             mask: Default::default(),
203             restorer: Default::default(),
204         }
205     }
206 }
207 
208 impl Sigaction {
209     /// 判断传入的信号是否被忽略
210     ///
211     /// ## 参数
212     ///
213     /// - `sig` 传入的信号
214     ///
215     /// ## 返回值
216     ///
217     /// - `true` 被忽略
218     /// - `false`未被忽略
is_ignore(&self) -> bool219     pub fn is_ignore(&self) -> bool {
220         return self.action.is_ignore();
221     }
new( action: SigactionType, flags: SigFlags, mask: SigSet, restorer: Option<VirtAddr>, ) -> Self222     pub fn new(
223         action: SigactionType,
224         flags: SigFlags,
225         mask: SigSet,
226         restorer: Option<VirtAddr>,
227     ) -> Self {
228         Self {
229             action,
230             flags,
231             mask,
232             restorer,
233         }
234     }
235 
action(&self) -> SigactionType236     pub fn action(&self) -> SigactionType {
237         self.action
238     }
239 
flags(&self) -> SigFlags240     pub fn flags(&self) -> SigFlags {
241         self.flags
242     }
243 
restorer(&self) -> Option<VirtAddr>244     pub fn restorer(&self) -> Option<VirtAddr> {
245         self.restorer
246     }
247 
flags_mut(&mut self) -> &mut SigFlags248     pub fn flags_mut(&mut self) -> &mut SigFlags {
249         &mut self.flags
250     }
251 
set_action(&mut self, action: SigactionType)252     pub fn set_action(&mut self, action: SigactionType) {
253         self.action = action;
254     }
255 
mask(&self) -> SigSet256     pub fn mask(&self) -> SigSet {
257         self.mask
258     }
259 
mask_mut(&mut self) -> &mut SigSet260     pub fn mask_mut(&mut self) -> &mut SigSet {
261         &mut self.mask
262     }
263 
set_restorer(&mut self, restorer: Option<VirtAddr>)264     pub fn set_restorer(&mut self, restorer: Option<VirtAddr>) {
265         self.restorer = restorer;
266     }
267 
268     /// 默认信号处理程序占位符(用于在sighand结构体中的action数组中占位)
269     pub const DEFAULT_SIGACTION: Sigaction = Sigaction {
270         action: SigactionType::SaHandler(SaHandlerType::Default),
271         flags: SigFlags::empty(),
272         mask: SigSet::from_bits_truncate(0),
273         restorer: None,
274     };
275 
276     /// 默认的“忽略信号”的sigaction
277     pub const DEFAULT_SIGACTION_IGNORE: Sigaction = Sigaction {
278         action: SigactionType::SaHandler(SaHandlerType::Ignore),
279         flags: SigFlags::empty(),
280         mask: SigSet::from_bits_truncate(0),
281         restorer: None,
282     };
283 }
284 
285 /// 用户态传入的sigaction结构体(符合posix规范)
286 /// 请注意,我们会在sys_sigaction函数里面将其转换成内核使用的sigaction结构体
287 #[repr(C)]
288 #[derive(Debug, Clone, Copy)]
289 pub struct UserSigaction {
290     pub handler: *mut core::ffi::c_void,
291     pub flags: SigFlags,
292     pub restorer: *mut core::ffi::c_void,
293     pub mask: SigSet,
294 }
295 
296 /**
297  * siginfo中,根据signal的来源不同,该info中对应了不同的数据./=
298  * 请注意,该info最大占用16字节
299  */
300 #[repr(C)]
301 #[derive(Copy, Clone, Debug)]
302 pub struct SigInfo {
303     sig_no: i32,
304     sig_code: SigCode,
305     errno: i32,
306     sig_type: SigType,
307 }
308 
309 impl SigInfo {
sig_code(&self) -> SigCode310     pub fn sig_code(&self) -> SigCode {
311         self.sig_code
312     }
313 
set_sig_type(&mut self, sig_type: SigType)314     pub fn set_sig_type(&mut self, sig_type: SigType) {
315         self.sig_type = sig_type;
316     }
317     /// @brief 将siginfo结构体拷贝到用户栈
318     /// ## 参数
319     ///
320     /// `to` 用户空间指针
321     ///
322     /// ## 注意
323     ///
324     /// 该函数对应Linux中的https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3323
325     /// Linux还提供了 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/signal.c#3383 用来实现
326     /// kernel_siginfo 保存到 用户的 compact_siginfo 的功能,但是我们系统内还暂时没有对这两种
327     /// siginfo做区分,因此暂时不需要第二个函数
copy_siginfo_to_user(&self, to: *mut SigInfo) -> Result<i32, SystemError>328     pub fn copy_siginfo_to_user(&self, to: *mut SigInfo) -> Result<i32, SystemError> {
329         // 验证目标地址是否为用户空间
330         let mut user_buffer = UserBufferWriter::new(to, size_of::<SigInfo>(), true)?;
331 
332         let retval: Result<i32, SystemError> = Ok(0);
333 
334         user_buffer.copy_one_to_user(self, 0)?;
335         return retval;
336     }
337 }
338 
339 #[derive(Copy, Clone, Debug)]
340 pub enum SigType {
341     Kill(Pid),
342     Alarm(Pid),
343     // 后续完善下列中的具体字段
344     // Timer,
345     // Rt,
346     // SigChild,
347     // SigFault,
348     // SigPoll,
349     // SigSys,
350 }
351 
352 impl SigInfo {
new(sig: Signal, sig_errno: i32, sig_code: SigCode, sig_type: SigType) -> Self353     pub fn new(sig: Signal, sig_errno: i32, sig_code: SigCode, sig_type: SigType) -> Self {
354         Self {
355             sig_no: sig as i32,
356             sig_code,
357             errno: sig_errno,
358             sig_type,
359         }
360     }
361 }
362 
363 #[derive(Debug, Default)]
364 pub struct SigPending {
365     signal: SigSet,
366     queue: SigQueue,
367 }
368 
369 impl SigPending {
370     /// 判断是否有待处理的信号
has_pending(&self) -> bool371     pub fn has_pending(&self) -> bool {
372         return !self.signal.is_empty();
373     }
374 
signal(&self) -> SigSet375     pub fn signal(&self) -> SigSet {
376         self.signal
377     }
378 
queue(&self) -> &SigQueue379     pub fn queue(&self) -> &SigQueue {
380         &self.queue
381     }
382 
queue_mut(&mut self) -> &mut SigQueue383     pub fn queue_mut(&mut self) -> &mut SigQueue {
384         &mut self.queue
385     }
386 
signal_mut(&mut self) -> &mut SigSet387     pub fn signal_mut(&mut self) -> &mut SigSet {
388         &mut self.signal
389     }
390     /// @brief 获取下一个要处理的信号(sig number越小的信号,优先级越高)
391     ///
392     /// @param pending 等待处理的信号
393     /// @param sig_mask 屏蔽了的信号
394     /// @return i32 下一个要处理的信号的number. 如果为0,则无效
next_signal(&self, sig_mask: &SigSet) -> Signal395     pub fn next_signal(&self, sig_mask: &SigSet) -> Signal {
396         let mut sig = Signal::INVALID;
397 
398         let s = self.signal();
399         let m = *sig_mask;
400         m.is_empty();
401         // 获取第一个待处理的信号的号码
402         let x = s & (!m);
403         if x.bits() != 0 {
404             sig = Signal::from(ffz(x.complement().bits()) + 1);
405             return sig;
406         }
407 
408         // 暂时只支持64种信号
409         assert_eq!(MAX_SIG_NUM, 64);
410 
411         return sig;
412     }
413     /// @brief 收集信号的信息
414     ///
415     /// @param sig 要收集的信号的信息
416     /// @param pending 信号的排队等待标志
417     /// @return SigInfo 信号的信息
collect_signal(&mut self, sig: Signal) -> SigInfo418     pub fn collect_signal(&mut self, sig: Signal) -> SigInfo {
419         let (info, still_pending) = self.queue_mut().find_and_delete(sig);
420 
421         // 如果没有仍在等待的信号,则清除pending位
422         if !still_pending {
423             self.signal_mut().remove(sig.into());
424         }
425 
426         if let Some(info) = info {
427             return info;
428         } else {
429             // 信号不在sigqueue中,这意味着当前信号是来自快速路径,因此直接把siginfo设置为0即可。
430             let mut ret = SigInfo::new(sig, 0, SigCode::User, SigType::Kill(Pid::from(0)));
431             ret.set_sig_type(SigType::Kill(Pid::new(0)));
432             return ret;
433         }
434     }
435 
436     /// @brief 从当前进程的sigpending中取出下一个待处理的signal,并返回给调用者。(调用者应当处理这个信号)
437     /// 请注意,进入本函数前,当前进程应当持有current_pcb().sighand.siglock
dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>)438     pub fn dequeue_signal(&mut self, sig_mask: &SigSet) -> (Signal, Option<SigInfo>) {
439         // debug!("dequeue signal");
440         // 获取下一个要处理的信号的编号
441         let sig = self.next_signal(sig_mask);
442 
443         let info: Option<SigInfo> = if sig != Signal::INVALID {
444             // 如果下一个要处理的信号是合法的,则收集其siginfo
445             Some(self.collect_signal(sig))
446         } else {
447             None
448         };
449 
450         // 当一个进程具有多个线程之后,在这里需要重新计算线程的flag中的TIF_SIGPENDING位
451         // recalc_sigpending();
452         return (sig, info);
453     }
454     /// @brief 从sigpending中删除mask中被置位的信号。也就是说,比如mask的第1位被置为1,那么就从sigqueue中删除所有signum为2的信号的信息。
flush_by_mask(&mut self, mask: &SigSet)455     pub fn flush_by_mask(&mut self, mask: &SigSet) {
456         // 定义过滤器,从sigqueue中删除mask中被置位的信号
457         let filter = |x: &SigInfo| !mask.contains(SigSet::from_bits_truncate(x.sig_no as u64));
458         self.queue.q.retain(filter);
459     }
460 }
461 
462 /// @brief 进程接收到的信号的队列
463 #[derive(Debug, Clone, Default)]
464 pub struct SigQueue {
465     pub q: Vec<SigInfo>,
466 }
467 
468 #[allow(dead_code)]
469 impl SigQueue {
470     /// @brief 初始化一个新的信号队列
new(capacity: usize) -> Self471     pub fn new(capacity: usize) -> Self {
472         SigQueue {
473             q: Vec::with_capacity(capacity),
474         }
475     }
476 
477     /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并返回它的引用
478     ///
479     /// @return (第一个满足要求的siginfo的引用; 是否有多个满足条件的siginfo)
find(&self, sig: Signal) -> (Option<&SigInfo>, bool)480     pub fn find(&self, sig: Signal) -> (Option<&SigInfo>, bool) {
481         // 是否存在多个满足条件的siginfo
482         let mut still_pending = false;
483         let mut info: Option<&SigInfo> = None;
484 
485         for x in self.q.iter() {
486             if x.sig_no == sig as i32 {
487                 if info.is_some() {
488                     still_pending = true;
489                     break;
490                 } else {
491                     info = Some(x);
492                 }
493             }
494         }
495         return (info, still_pending);
496     }
497 
498     /// @brief 在信号队列中寻找第一个满足要求的siginfo, 并将其从队列中删除,然后返回这个siginfo
499     ///
500     /// @return (第一个满足要求的siginfo; 从队列中删除前是否有多个满足条件的siginfo)
find_and_delete(&mut self, sig: Signal) -> (Option<SigInfo>, bool)501     pub fn find_and_delete(&mut self, sig: Signal) -> (Option<SigInfo>, bool) {
502         // 是否存在多个满足条件的siginfo
503         let mut still_pending = false;
504         let mut first = true; // 标记变量,记录当前是否已经筛选出了一个元素
505 
506         let filter = |x: &mut SigInfo| {
507             if x.sig_no == sig as i32 {
508                 if !first {
509                     // 如果之前已经筛选出了一个元素,则不把当前元素删除
510                     still_pending = true;
511                     return false;
512                 } else {
513                     // 当前是第一个被筛选出来的元素
514                     first = false;
515                     return true;
516                 }
517             }
518             return false;
519         };
520         // 从sigqueue中过滤出结果
521         let mut filter_result: Vec<SigInfo> = self.q.extract_if(filter).collect();
522         // 筛选出的结果不能大于1个
523         assert!(filter_result.len() <= 1);
524 
525         return (filter_result.pop(), still_pending);
526     }
527 
528     /// @brief 从C的void*指针转换为static生命周期的可变引用
from_c_void(p: *mut c_void) -> &'static mut SigQueue529     pub fn from_c_void(p: *mut c_void) -> &'static mut SigQueue {
530         let sq = p as *mut SigQueue;
531         let sq = unsafe { sq.as_mut::<'static>() }.unwrap();
532         return sq;
533     }
534 }
535 
536 ///
537 /// 定义了不同架构下实现 Signal 要实现的接口
538 ///
539 pub trait SignalArch {
540     /// 信号处理函数
541     ///
542     /// ## 参数
543     ///
544     /// - `frame` 中断栈帧
do_signal(frame: &mut TrapFrame)545     unsafe fn do_signal(frame: &mut TrapFrame);
546 
sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64547     fn sys_rt_sigreturn(trap_frame: &mut TrapFrame) -> u64;
548 }
549