From 08d10522ff2e1d0357c0cead8bc15e5df0e76333 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 4 May 2019 00:19:35 +0800 Subject: [PATCH] impl sys_set_tid_address. ignore invalid 'clear_child_tid' on exit --- kernel/src/arch/x86_64/paging.rs | 25 +++++++++++++------------ kernel/src/syscall/mem.rs | 8 -------- kernel/src/syscall/mod.rs | 2 +- kernel/src/syscall/proc.rs | 21 +++++++++++++++------ 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/kernel/src/arch/x86_64/paging.rs b/kernel/src/arch/x86_64/paging.rs index fb45522..b280446 100644 --- a/kernel/src/arch/x86_64/paging.rs +++ b/kernel/src/arch/x86_64/paging.rs @@ -47,23 +47,21 @@ impl PageTable for ActivePageTable { fn map(&mut self, addr: usize, target: usize) -> &mut Entry { let flags = EF::PRESENT | EF::WRITABLE | EF::NO_EXECUTE; unsafe { - if let Ok(flush) = self.0.map_to( - Page::of_addr(addr), - Frame::of_addr(target), - flags, - &mut FrameAllocatorForX86, - ) { - flush.flush(); - } + self.0 + .map_to( + Page::of_addr(addr), + Frame::of_addr(target), + flags, + &mut FrameAllocatorForX86, + ) + .unwrap() + .flush(); } unsafe { &mut *(get_entry_ptr(addr, 1)) } } fn unmap(&mut self, addr: usize) { - // unmap and flush if it is mapped - if let Ok((_, flush)) = self.0.unmap(Page::of_addr(addr)) { - flush.flush(); - } + self.0.unmap(Page::of_addr(addr)).unwrap().1.flush(); } fn get_entry(&mut self, addr: usize) -> Option<&mut Entry> { @@ -238,6 +236,9 @@ impl InactivePageTable for InactivePageTable0 { fn edit(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { let target = Cr3::read().0.start_address().as_u64() as usize; + if self.p4_frame == Cr3::read().0 { + return f(&mut active_table()); + } active_table().with_temporary_map(target, |active_table, p4_table: &mut x86PageTable| { let backup = p4_table[0o777].clone(); diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 1a241ac..9884264 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -88,14 +88,6 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult { if memory_area.is_none() { return Err(SysError::ENOMEM); } - proc.vm.edit(|pt| { - for page in Page::range_of(addr, addr + len) { - let entry = pt - .get_entry(page.start_address()) - .expect("failed to get entry"); - attr.apply(entry); - } - }); Ok(0) } diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 3f183d8..7303ae7 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -187,7 +187,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { SYS_EXIT => sys_exit(args[0] as usize), SYS_EXIT_GROUP => sys_exit_group(args[0]), SYS_WAIT4 => sys_wait4(args[0] as isize, args[1] as *mut i32), // TODO: wait4 - SYS_SET_TID_ADDRESS => unimplemented("set_tid_address", Ok(thread::current().id())), + SYS_SET_TID_ADDRESS => sys_set_tid_address(args[0] as *mut u32), SYS_FUTEX => sys_futex( args[0], args[1] as u32, diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index b24c960..54e1981 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -281,14 +281,17 @@ pub fn sys_exit(exit_code: usize) -> ! { // ref: http://man7.org/linux/man-pages/man2/set_tid_address.2.html // FIXME: do it in all possible ways a thread can exit // it has memory access so we can't move it to Thread::drop? - let clear_child_tid = current_thread().clear_child_tid; - if clear_child_tid != 0 { - unsafe { - (clear_child_tid as *mut u32).write(0); + let mut proc = process(); + let clear_child_tid = current_thread().clear_child_tid as *mut u32; + if !clear_child_tid.is_null() { + info!("exit: futex {:#?} wake 1", clear_child_tid); + if let Ok(clear_child_tid_ref) = unsafe { proc.vm.check_write_ptr(clear_child_tid) } { + *clear_child_tid_ref = 0; + let queue = proc.get_futex(clear_child_tid as usize); + queue.notify_one(); } - let queue = process().get_futex(clear_child_tid); - queue.notify_one(); } + drop(proc); processor().manager().exit(tid, exit_code as usize); processor().yield_now(); @@ -334,6 +337,12 @@ pub fn sys_set_priority(priority: usize) -> SysResult { Ok(0) } +pub fn sys_set_tid_address(tidptr: *mut u32) -> SysResult { + info!("set_tid_address: {:?}", tidptr); + current_thread().clear_child_tid = tidptr as usize; + Ok(thread::current().id()) +} + bitflags! { pub struct CloneFlags: usize { const CSIGNAL = 0x000000ff;