1
0
mirror of https://github.com/rcore-os/rCore.git synced 2024-11-25 17:33:28 +04:00

Cleanup signal code

This commit is contained in:
Jiajie Chen 2020-06-28 23:21:22 +08:00
parent 25382e211e
commit bc525e1902
8 changed files with 36 additions and 102 deletions

2
kernel/Cargo.lock generated
View File

@ -708,7 +708,7 @@ checksum = "3a385d94f3f62e60445a0adb9ff8d9621faa272234530d4c0f848ec98f88e316"
[[package]] [[package]]
name = "trapframe" name = "trapframe"
version = "0.4.3" version = "0.4.3"
source = "git+https://github.com/rcore-os/trapframe-rs?rev=aaa0fa3#aaa0fa341457833e08c4f82442a1efee5c480c01" source = "git+https://github.com/rcore-os/trapframe-rs?rev=b7fb4ff#b7fb4ffb3d8d36355842867837e13384c68212a2"
dependencies = [ dependencies = [
"raw-cpuid", "raw-cpuid",
"x86_64", "x86_64",

View File

@ -70,7 +70,7 @@ rcore-fs-devfs = { git = "https://github.com/rcore-os/rcore-fs", rev = "517af47"
rlibc = "1.0" rlibc = "1.0"
smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", default-features = false, features = ["alloc", "log", "ethernet", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] } smoltcp = { git = "https://github.com/rcore-os/smoltcp", rev = "5bd87c7c", default-features = false, features = ["alloc", "log", "ethernet", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp", "socket-raw"] }
spin = "0.5" spin = "0.5"
trapframe = { git = "https://github.com/rcore-os/trapframe-rs", rev = "aaa0fa3" } trapframe = { git = "https://github.com/rcore-os/trapframe-rs", rev = "b7fb4ff" }
virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "dfa70e14" } virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "dfa70e14" }
volatile = "0.2" volatile = "0.2"
woke = "0.0.2" woke = "0.0.2"

View File

@ -67,7 +67,6 @@
use super::consts::*; use super::consts::*;
use super::TrapFrame; use super::TrapFrame;
use crate::drivers::IRQ_MANAGER; use crate::drivers::IRQ_MANAGER;
use crate::signal::do_signal;
use bitflags::*; use bitflags::*;
use log::*; use log::*;
use x86_64::registers::control::Cr2; use x86_64::registers::control::Cr2;
@ -91,11 +90,6 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
match tf.trap_num { match tf.trap_num {
Timer => { Timer => {
crate::trap::timer(); crate::trap::timer();
/*
if processor().tid_option().is_some() {
do_signal(tf);
}
*/
} }
_ => { _ => {
if IRQ_MANAGER.read().try_handle_interrupt(Some(irq)) { if IRQ_MANAGER.read().try_handle_interrupt(Some(irq)) {

View File

@ -13,7 +13,6 @@ pub mod ipi;
pub mod memory; pub mod memory;
pub mod paging; pub mod paging;
pub mod rand; pub mod rand;
pub mod signal;
pub mod syscall; pub mod syscall;
pub mod timer; pub mod timer;

View File

@ -1,69 +0,0 @@
use trapframe::TrapFrame;
#[repr(C)]
#[derive(Clone, Debug)]
pub struct MachineContext {
pub r8: usize,
pub r9: usize,
pub r10: usize,
pub r11: usize,
pub r12: usize,
pub r13: usize,
pub r14: usize,
pub r15: usize,
pub rdi: usize,
pub rsi: usize,
pub rbp: usize,
pub rbx: usize,
pub rdx: usize,
pub rax: usize,
pub rcx: usize,
pub rsp: usize,
pub rip: usize,
pub eflags: usize,
pub cs: u16,
pub gs: u16,
pub fs: u16,
pub _pad: u16,
pub err: usize,
pub trapno: usize,
pub oldmask: usize,
pub cr2: usize,
pub fpstate: usize,
pub _reserved1: [usize; 8],
}
impl MachineContext {
pub fn from_tf(tf: &TrapFrame) -> Self {
MachineContext {
r8: tf.r8,
r9: tf.r9,
r10: tf.r10,
r11: tf.r11,
r12: tf.r12,
r13: tf.r13,
r14: tf.r14,
r15: tf.r15,
rdi: tf.rdi,
rsi: tf.rsi,
rbp: tf.rbp,
rbx: tf.rbx,
rdx: tf.rdx,
rax: tf.rax,
rcx: tf.rcx,
rsp: tf.rsp,
rip: tf.rip,
eflags: 0,
cs: tf.cs as u16,
gs: 0,
fs: 0,
_pad: 0,
err: 0,
trapno: 0,
oldmask: 0,
cr2: 0,
fpstate: 0,
_reserved1: [0; 8],
}
}
}

View File

@ -18,7 +18,7 @@ use crate::memory::{
use crate::process::structs::ElfExt; use crate::process::structs::ElfExt;
use crate::sync::{Condvar, EventBus, SpinLock, SpinNoIrqLock as Mutex}; use crate::sync::{Condvar, EventBus, SpinLock, SpinNoIrqLock as Mutex};
use crate::{ use crate::{
signal::{Siginfo, Signal, SignalAction, SignalStack, Sigset}, signal::{handle_signal, Siginfo, Signal, SignalAction, SignalStack, Sigset},
syscall::handle_syscall, syscall::handle_syscall,
}; };
use alloc::{ use alloc::{
@ -503,6 +503,12 @@ pub fn spawn(thread: Arc<Thread>) {
); );
} }
} }
// check signals
if !exit {
exit = handle_signal(&thread, &mut cx);
}
thread.end_running(cx); thread.end_running(cx);
if exit { if exit {
break; break;

View File

@ -21,6 +21,7 @@ pub const SI_KERNEL: i32 = 128;
// yet there's a bug because of mismatching bits: https://sourceware.org/bugzilla/show_bug.cgi?id=25657 // yet there's a bug because of mismatching bits: https://sourceware.org/bugzilla/show_bug.cgi?id=25657
// just support 64bits size sigset // just support 64bits size sigset
/// Linux struct sigset_t
#[derive(Default, Clone, Copy, Debug)] #[derive(Default, Clone, Copy, Debug)]
#[repr(C)] #[repr(C)]
pub struct Sigset(u64); pub struct Sigset(u64);
@ -48,6 +49,7 @@ impl Sigset {
} }
} }
/// Linux struct sigaction
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Default)] #[derive(Clone, Copy, Default)]
pub struct SignalAction { pub struct SignalAction {

View File

@ -1,11 +1,10 @@
use crate::arch::signal::MachineContext;
use crate::arch::syscall::SYS_RT_SIGRETURN; use crate::arch::syscall::SYS_RT_SIGRETURN;
use crate::process::{process, process_of, Process, Thread}; use crate::process::{process, process_of, Process, Thread};
use crate::sync::{Event, MutexGuard, SpinNoIrq, SpinNoIrqLock as Mutex}; use crate::sync::{Event, MutexGuard, SpinNoIrq, SpinNoIrqLock as Mutex};
use alloc::sync::Arc; use alloc::sync::Arc;
use bitflags::*; use bitflags::*;
use num::FromPrimitive; use num::FromPrimitive;
use trapframe::TrapFrame; use trapframe::{TrapFrame, UserContext};
mod action; mod action;
@ -99,30 +98,35 @@ pub fn send_signal(process: Arc<Mutex<Process>>, tid: isize, info: Siginfo) {
process.sig_queue.push_back((info, tid)); process.sig_queue.push_back((info, tid));
process.pending_sigset.add(signal); process.pending_sigset.add(signal);
process.eventbus.lock().set(Event::RECEIVE_SIGNAL); process.eventbus.lock().set(Event::RECEIVE_SIGNAL);
info!(
"send signal {} to pid {} tid {}",
info.signo, process.pid, tid
)
} }
/// See musl struct __ucontext
/// Not exactly the same for now
#[repr(C)] #[repr(C)]
#[derive(Clone)] #[derive(Clone)]
pub struct SignalUserContext { pub struct SignalUserContext {
pub flags: usize, pub flags: usize,
pub link: usize, pub link: usize,
pub stack: SignalStack, pub stack: SignalStack,
pub mcontext: MachineContext, pub context: UserContext,
pub sig_mask: Sigset, pub sig_mask: Sigset,
pub _fpregs_mem: [usize; 64],
} }
#[repr(C)] #[repr(C)]
#[derive(Clone)] #[derive(Clone)]
pub struct SignalFrame { pub struct SignalFrame {
pub ret_code_addr: usize, // point to ret_code pub ret_code_addr: usize, // point to ret_code
pub tf: TrapFrame,
pub info: Siginfo, pub info: Siginfo,
pub ucontext: SignalUserContext, // adapt interface, a little bit waste pub ucontext: SignalUserContext, // adapt interface, a little bit waste
pub ret_code: [u8; 7], // call sys_sigreturn pub ret_code: [u8; 7], // call sys_sigreturn
} }
pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) { /// return whether this thread exits
pub fn handle_signal(thread: &Arc<Thread>, tf: &mut UserContext) -> bool {
let mut process = thread.proc.lock(); let mut process = thread.proc.lock();
while let Some((idx, info)) = while let Some((idx, info)) =
process process
@ -130,7 +134,6 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
.iter() .iter()
.enumerate() .enumerate()
.find_map(|(idx, &(info, tid))| { .find_map(|(idx, &(info, tid))| {
//if (tid == -1 || tid as usize == current().id())
if tid == -1 if tid == -1
&& !thread && !thread
.inner .inner
@ -148,7 +151,7 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
use Signal::*; use Signal::*;
let signal: Signal = <Signal as FromPrimitive>::from_i32(info.signo).unwrap(); let signal: Signal = <Signal as FromPrimitive>::from_i32(info.signo).unwrap();
info!("received signal: {:?}", signal); info!("process {} received signal: {:?}", process.pid, signal);
process.sig_queue.remove(idx); process.sig_queue.remove(idx);
process.pending_sigset.remove(signal); process.pending_sigset.remove(signal);
@ -165,8 +168,7 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
info!("default action: Term"); info!("default action: Term");
// FIXME: exit code ref please? // FIXME: exit code ref please?
process.exit(info.signo as usize + 128); process.exit(info.signo as usize + 128);
//yield_now(); return true;
unreachable!()
} }
_ => (), _ => (),
} }
@ -181,6 +183,7 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
} }
_ => { _ => {
info!("goto handler at {:#x}", action.handler); info!("goto handler at {:#x}", action.handler);
thread.inner.lock().signal_alternate_stack.flags |= thread.inner.lock().signal_alternate_stack.flags |=
SignalStackFlags::ONSTACK.bits(); SignalStackFlags::ONSTACK.bits();
let stack = thread.inner.lock().signal_alternate_stack; let stack = thread.inner.lock().signal_alternate_stack;
@ -188,15 +191,16 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
if action_flags.contains(SignalActionFlags::ONSTACK) { if action_flags.contains(SignalActionFlags::ONSTACK) {
let stack_flags = SignalStackFlags::from_bits_truncate(stack.flags); let stack_flags = SignalStackFlags::from_bits_truncate(stack.flags);
if stack_flags.contains(SignalStackFlags::DISABLE) { if stack_flags.contains(SignalStackFlags::DISABLE) {
todo!() tf.get_sp()
} else { } else {
// top of stack
stack.sp + stack.size stack.sp + stack.size
} }
} else { } else {
todo!() tf.get_sp()
//tf.get_sp()
} }
} - core::mem::size_of::<SignalFrame>(); } - core::mem::size_of::<SignalFrame>();
let frame = if let Ok(frame) = unsafe { let frame = if let Ok(frame) = unsafe {
process process
.vm .vm
@ -207,15 +211,13 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
} else { } else {
unimplemented!() unimplemented!()
}; };
frame.tf = tf.clone();
frame.info = info; frame.info = info;
frame.ucontext = SignalUserContext { frame.ucontext = SignalUserContext {
flags: 0, flags: 0,
link: 0, link: 0,
stack, stack,
mcontext: MachineContext::from_tf(tf), context: tf.clone(),
sig_mask: thread.inner.lock().sig_mask, sig_mask: thread.inner.lock().sig_mask,
_fpregs_mem: [0; 64],
}; };
if action_flags.contains(SignalActionFlags::RESTORER) { if action_flags.contains(SignalActionFlags::RESTORER) {
frame.ret_code_addr = action.restorer; // legacy frame.ret_code_addr = action.restorer; // legacy
@ -233,20 +235,19 @@ pub fn do_signal(thread: &Arc<Thread>, tf: &mut TrapFrame) {
} }
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
{ {
tf.rsp = sig_sp; tf.general.rsp = sig_sp;
tf.rip = action.handler; tf.general.rip = action.handler;
// pass handler argument // pass handler argument
tf.rdi = info.signo as usize; tf.general.rdi = info.signo as usize;
tf.rsi = &frame.info as *const Siginfo as usize; tf.general.rsi = &frame.info as *const Siginfo as usize;
// TODO: complete context tf.general.rdx = &frame.ucontext as *const SignalUserContext as usize;
tf.rdx = &frame.ucontext as *const SignalUserContext as usize;
}
return;
} }
} }
} }
} }
return false;
}
bitflags! { bitflags! {
pub struct SignalStackFlags : u32 { pub struct SignalStackFlags : u32 {
@ -256,6 +257,7 @@ bitflags! {
} }
} }
/// Linux struct stack_t
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct SignalStack { pub struct SignalStack {