From dc55238989b6a822a9f9529bbd399eec5626acd4 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sat, 9 Mar 2019 00:47:02 +0800 Subject: [PATCH] fix sys_clone newtls --- kernel/src/arch/x86_64/interrupt/trapframe.rs | 21 ++++++++++++++----- kernel/src/process/structs.rs | 6 +++--- kernel/src/syscall/mod.rs | 2 +- kernel/src/syscall/proc.rs | 8 +++---- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/kernel/src/arch/x86_64/interrupt/trapframe.rs b/kernel/src/arch/x86_64/interrupt/trapframe.rs index 5b9974d..31d9d52 100644 --- a/kernel/src/arch/x86_64/interrupt/trapframe.rs +++ b/kernel/src/arch/x86_64/interrupt/trapframe.rs @@ -192,17 +192,28 @@ impl Context { tf: TrapFrame::new_user_thread(entry_addr, ustack_top, is32), }.push_at(kstack_top) } - pub unsafe fn new_fork(tf: &TrapFrame, ustack_top: Option, kstack_top: usize, cr3: usize) -> Self { + pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, cr3: usize) -> Self { InitStack { context: ContextData::new(cr3), tf: { let mut tf = tf.clone(); - if let Some(sp) = ustack_top { - tf.rsp = sp; - } tf.rax = 0; // skip syscall inst; - tf.rip = tf.rip + 2; + tf.rip += 2; + tf + }, + }.push_at(kstack_top) + } + pub unsafe fn new_clone(tf: &TrapFrame, ustack_top: usize, kstack_top: usize, cr3: usize, tls: usize) -> Self { + InitStack { + context: ContextData::new(cr3), + tf: { + let mut tf = tf.clone(); + tf.rsp = ustack_top; + tf.fsbase = tls; + tf.rax = 0; + // skip syscall inst; + tf.rip += 2; tf }, }.push_at(kstack_top) diff --git a/kernel/src/process/structs.rs b/kernel/src/process/structs.rs index bc0e979..34105d6 100644 --- a/kernel/src/process/structs.rs +++ b/kernel/src/process/structs.rs @@ -214,7 +214,7 @@ impl Thread { Box::new(Thread { - context: unsafe { Context::new_fork(tf, None, kstack.top(), memory_set.token()) }, + context: unsafe { Context::new_fork(tf, kstack.top(), memory_set.token()) }, kstack, proc: Arc::new(Mutex::new(Process { memory_set, @@ -225,11 +225,11 @@ impl Thread { } /// Create a new thread in the same process. - pub fn clone(&self, tf: &TrapFrame, stack_top: usize) -> Box { + pub fn clone(&self, tf: &TrapFrame, stack_top: usize, tls: usize) -> Box { let kstack = KernelStack::new(); let token = self.proc.lock().memory_set.token(); Box::new(Thread { - context: unsafe { Context::new_fork(tf, Some(stack_top), kstack.top(), token) }, + context: unsafe { Context::new_clone(tf, stack_top, kstack.top(), token, tls) }, kstack, proc: self.proc.clone(), }) diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index d7e81ef..964db49 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -76,7 +76,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 052 => sys_getpeername(args[0], args[1] as *mut SockaddrIn, args[2] as *mut u32), 054 => sys_setsockopt(args[0], args[1], args[2], args[3] as *const u8, args[4]), 055 => sys_getsockopt(args[0], args[1], args[2], args[3] as *mut u8, args[4] as *mut u32), - 056 => sys_clone(args[0], args[1], args[2] as *mut usize, args[3] as *mut usize, tf), + 056 => sys_clone(args[0], args[1], args[2] as *mut usize, args[3] as *mut usize, args[4], tf), 057 => sys_fork(tf), // use fork for vfork 058 => sys_fork(tf), diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 2e3c848..c9cf31b 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -14,9 +14,9 @@ pub fn sys_fork(tf: &TrapFrame) -> SysResult { /// The new thread's stack pointer will be set to `newsp`. /// The child tid will be stored at both `parent_tid` and `child_tid`. /// This is partially implemented for musl only. -pub fn sys_clone(flags: usize, newsp: usize, parent_tid: *mut usize, child_tid: *mut usize, tf: &TrapFrame) -> SysResult { - info!("clone: flags: {:#x}, newsp: {:#x}, parent_tid: {:?}, child_tid: {:?}", - flags, newsp, parent_tid, child_tid); +pub fn sys_clone(flags: usize, newsp: usize, parent_tid: *mut usize, child_tid: *mut usize, newtls: usize, tf: &TrapFrame) -> SysResult { + info!("clone: flags: {:#x}, newsp: {:#x}, parent_tid: {:?}, child_tid: {:?}, newtls: {:#x}", + flags, newsp, parent_tid, child_tid, newtls); if flags != 0x7d0f00 { warn!("sys_clone only support musl pthread_create"); return Err(SysError::ENOSYS); @@ -28,7 +28,7 @@ pub fn sys_clone(flags: usize, newsp: usize, parent_tid: *mut usize, child_tid: // proc.memory_set.check_mut_ptr(child_tid)?; } // FIXME: tf.rip => tf.ip() for all arch - let new_thread = current_thread().clone(tf, newsp); + let new_thread = current_thread().clone(tf, newsp, newtls); // FIXME: parent pid let tid = processor().manager().add(new_thread, thread::current().id()); info!("clone: {} -> {}", thread::current().id(), tid);