Create a new user task.
(name: &str, mut uctx: UserContext, set_child_tid: usize)
| 25 | |
| 26 | /// Create a new user task. |
| 27 | pub fn new_user_task(name: &str, mut uctx: UserContext, set_child_tid: usize) -> TaskInner { |
| 28 | TaskInner::new( |
| 29 | move || { |
| 30 | let curr = axtask::current(); |
| 31 | |
| 32 | if let Some(tid) = (set_child_tid as *mut Pid).nullable() { |
| 33 | tid.vm_write(curr.id().as_u64() as Pid).ok(); |
| 34 | } |
| 35 | |
| 36 | info!("Enter user space: ip={:#x}, sp={:#x}", uctx.ip(), uctx.sp()); |
| 37 | |
| 38 | let thr = curr.as_thread(); |
| 39 | while !thr.pending_exit() { |
| 40 | let reason = uctx.run(); |
| 41 | |
| 42 | set_timer_state(&curr, TimerState::Kernel); |
| 43 | |
| 44 | match reason { |
| 45 | ReturnReason::Syscall => handle_syscall(&mut uctx), |
| 46 | ReturnReason::PageFault(addr, flags) => { |
| 47 | if !thr.proc_data.aspace.lock().handle_page_fault(addr, flags) { |
| 48 | info!( |
| 49 | "{:?}: segmentation fault at {:#x} {:?}", |
| 50 | thr.proc_data.proc, addr, flags |
| 51 | ); |
| 52 | raise_signal_fatal(SignalInfo::new_kernel(Signo::SIGSEGV)) |
| 53 | .expect("Failed to send SIGSEGV"); |
| 54 | } |
| 55 | } |
| 56 | ReturnReason::Interrupt => {} |
| 57 | #[allow(unused_labels)] |
| 58 | ReturnReason::Exception(exc_info) => 'exc: { |
| 59 | // TODO: detailed handling |
| 60 | let signo = match exc_info.kind() { |
| 61 | ExceptionKind::Misaligned => { |
| 62 | #[cfg(target_arch = "loongarch64")] |
| 63 | if unsafe { uctx.emulate_unaligned() }.is_ok() { |
| 64 | break 'exc; |
| 65 | } |
| 66 | Signo::SIGBUS |
| 67 | } |
| 68 | ExceptionKind::Breakpoint => Signo::SIGTRAP, |
| 69 | ExceptionKind::IllegalInstruction => Signo::SIGILL, |
| 70 | _ => Signo::SIGTRAP, |
| 71 | }; |
| 72 | raise_signal_fatal(SignalInfo::new_kernel(signo)) |
| 73 | .expect("Failed to send SIGTRAP"); |
| 74 | } |
| 75 | r => { |
| 76 | warn!("Unexpected return reason: {r:?}"); |
| 77 | raise_signal_fatal(SignalInfo::new_kernel(Signo::SIGSEGV)) |
| 78 | .expect("Failed to send SIGSEGV"); |
| 79 | } |
| 80 | } |
| 81 | |
| 82 | if !unblock_next_signal() { |
| 83 | while check_signals(thr, &mut uctx, None) {} |
| 84 | } |
no test coverage detected