mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-23 00:16:17 +04:00
impl sys_set_tid_address. ignore invalid 'clear_child_tid' on exit
This commit is contained in:
parent
98a99e33c6
commit
08d10522ff
@ -47,23 +47,21 @@ impl PageTable for ActivePageTable {
|
|||||||
fn map(&mut self, addr: usize, target: usize) -> &mut Entry {
|
fn map(&mut self, addr: usize, target: usize) -> &mut Entry {
|
||||||
let flags = EF::PRESENT | EF::WRITABLE | EF::NO_EXECUTE;
|
let flags = EF::PRESENT | EF::WRITABLE | EF::NO_EXECUTE;
|
||||||
unsafe {
|
unsafe {
|
||||||
if let Ok(flush) = self.0.map_to(
|
self.0
|
||||||
Page::of_addr(addr),
|
.map_to(
|
||||||
Frame::of_addr(target),
|
Page::of_addr(addr),
|
||||||
flags,
|
Frame::of_addr(target),
|
||||||
&mut FrameAllocatorForX86,
|
flags,
|
||||||
) {
|
&mut FrameAllocatorForX86,
|
||||||
flush.flush();
|
)
|
||||||
}
|
.unwrap()
|
||||||
|
.flush();
|
||||||
}
|
}
|
||||||
unsafe { &mut *(get_entry_ptr(addr, 1)) }
|
unsafe { &mut *(get_entry_ptr(addr, 1)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unmap(&mut self, addr: usize) {
|
fn unmap(&mut self, addr: usize) {
|
||||||
// unmap and flush if it is mapped
|
self.0.unmap(Page::of_addr(addr)).unwrap().1.flush();
|
||||||
if let Ok((_, flush)) = self.0.unmap(Page::of_addr(addr)) {
|
|
||||||
flush.flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_entry(&mut self, addr: usize) -> Option<&mut Entry> {
|
fn get_entry(&mut self, addr: usize) -> Option<&mut Entry> {
|
||||||
@ -238,6 +236,9 @@ impl InactivePageTable for InactivePageTable0 {
|
|||||||
|
|
||||||
fn edit<T>(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T {
|
fn edit<T>(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T {
|
||||||
let target = Cr3::read().0.start_address().as_u64() as usize;
|
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| {
|
active_table().with_temporary_map(target, |active_table, p4_table: &mut x86PageTable| {
|
||||||
let backup = p4_table[0o777].clone();
|
let backup = p4_table[0o777].clone();
|
||||||
|
|
||||||
|
@ -88,14 +88,6 @@ pub fn sys_mprotect(addr: usize, len: usize, prot: usize) -> SysResult {
|
|||||||
if memory_area.is_none() {
|
if memory_area.is_none() {
|
||||||
return Err(SysError::ENOMEM);
|
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)
|
Ok(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 => sys_exit(args[0] as usize),
|
||||||
SYS_EXIT_GROUP => sys_exit_group(args[0]),
|
SYS_EXIT_GROUP => sys_exit_group(args[0]),
|
||||||
SYS_WAIT4 => sys_wait4(args[0] as isize, args[1] as *mut i32), // TODO: wait4
|
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(
|
SYS_FUTEX => sys_futex(
|
||||||
args[0],
|
args[0],
|
||||||
args[1] as u32,
|
args[1] as u32,
|
||||||
|
@ -281,14 +281,17 @@ pub fn sys_exit(exit_code: usize) -> ! {
|
|||||||
// ref: http://man7.org/linux/man-pages/man2/set_tid_address.2.html
|
// ref: http://man7.org/linux/man-pages/man2/set_tid_address.2.html
|
||||||
// FIXME: do it in all possible ways a thread can exit
|
// FIXME: do it in all possible ways a thread can exit
|
||||||
// it has memory access so we can't move it to Thread::drop?
|
// it has memory access so we can't move it to Thread::drop?
|
||||||
let clear_child_tid = current_thread().clear_child_tid;
|
let mut proc = process();
|
||||||
if clear_child_tid != 0 {
|
let clear_child_tid = current_thread().clear_child_tid as *mut u32;
|
||||||
unsafe {
|
if !clear_child_tid.is_null() {
|
||||||
(clear_child_tid as *mut u32).write(0);
|
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().manager().exit(tid, exit_code as usize);
|
||||||
processor().yield_now();
|
processor().yield_now();
|
||||||
@ -334,6 +337,12 @@ pub fn sys_set_priority(priority: usize) -> SysResult {
|
|||||||
Ok(0)
|
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! {
|
bitflags! {
|
||||||
pub struct CloneFlags: usize {
|
pub struct CloneFlags: usize {
|
||||||
const CSIGNAL = 0x000000ff;
|
const CSIGNAL = 0x000000ff;
|
||||||
|
Loading…
Reference in New Issue
Block a user