Skip to content
This repository was archived by the owner on Nov 26, 2025. It is now read-only.

Commit 0b67ced

Browse files
committed
feat: tls
1 parent 0c84473 commit 0b67ced

File tree

3 files changed

+40
-60
lines changed

3 files changed

+40
-60
lines changed

api/src/imp/task/clone.rs

Lines changed: 10 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,12 @@ use axsync::Mutex;
88
use axtask::{TaskExtRef, current};
99
use bitflags::bitflags;
1010
use linux_raw_sys::general::*;
11-
use macro_rules_attribute::apply;
1211
use starry_core::{
1312
mm::copy_from_kernel,
1413
task::{ProcessData, TaskExt, ThreadData, add_thread_to_table, new_user_task},
1514
};
1615

17-
use crate::{
18-
ptr::{PtrWrapper, UserPtr},
19-
syscall_instrument,
20-
};
16+
use crate::ptr::{PtrWrapper, UserPtr};
2117

2218
bitflags! {
2319
/// Options for use with [`sys_clone`].
@@ -82,13 +78,14 @@ bitflags! {
8278
}
8379
}
8480

85-
#[apply(syscall_instrument)]
8681
pub fn sys_clone(
82+
tf: &TrapFrame,
8783
flags: u32,
8884
stack: usize,
8985
parent_tid: usize,
90-
child_tid: usize,
86+
#[cfg(any(target_arch = "x86_64", target_arch = "loongarch64"))] child_tid: usize,
9187
tls: usize,
88+
#[cfg(not(any(target_arch = "x86_64", target_arch = "loongarch64")))] child_tid: usize,
9289
) -> LinuxResult<isize> {
9390
const FLAG_MASK: u32 = 0xff;
9491
let exit_signal = flags & FLAG_MASK;
@@ -103,23 +100,12 @@ pub fn sys_clone(
103100
return Err(LinuxError::EINVAL);
104101
}
105102

106-
let curr = current();
107-
108-
let trap_frame = read_trapframe_from_kstack(curr.get_kernel_stack_top().unwrap());
109-
let mut new_uctx = UspaceContext::from(&trap_frame);
103+
let mut new_uctx = UspaceContext::from(tf);
110104
if stack != 0 {
111105
new_uctx.set_sp(stack);
112106
}
113-
// Skip current instruction
114-
// FIXME: we should do this in arceos before calling `handle_syscall`.
115-
// See: https://github.com/oscomp/arceos/commit/13ff3f58bd825c37ea5eef3393a4f8c0bb5b4f41
116-
#[cfg(any(target_arch = "riscv64", target_arch = "loongarch64"))]
117-
{
118-
let new_uctx_ip = new_uctx.ip();
119-
new_uctx.set_ip(new_uctx_ip + 4);
120-
}
121107
if flags.contains(CloneFlags::SETTLS) {
122-
warn!("sys_clone: CLONE_SETTLS is not supported yet");
108+
new_uctx.set_tls(tls);
123109
}
124110
new_uctx.set_retval(0);
125111

@@ -128,13 +114,9 @@ pub fn sys_clone(
128114
} else {
129115
None
130116
};
131-
let mut new_task = new_user_task(curr.name(), new_uctx, set_child_tid);
132117

133-
// FIXME: remove this when we fix the tls issue
134-
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
135-
new_task
136-
.ctx_mut()
137-
.set_tls(axhal::arch::read_thread_pointer().into());
118+
let curr = current();
119+
let mut new_task = new_user_task(curr.name(), new_uctx, set_child_tid);
138120

139121
let tid = new_task.id().as_u64() as Pid;
140122
if flags.contains(CloneFlags::PARENT_SETTID) {
@@ -218,12 +200,6 @@ pub fn sys_clone(
218200
Ok(tid as _)
219201
}
220202

221-
fn read_trapframe_from_kstack(kstack_top: usize) -> TrapFrame {
222-
let trap_frame_size = core::mem::size_of::<TrapFrame>();
223-
let trap_frame_ptr = (kstack_top - trap_frame_size) as *mut TrapFrame;
224-
unsafe { *trap_frame_ptr }
225-
}
226-
227-
pub fn sys_fork() -> LinuxResult<isize> {
228-
sys_clone(SIGCHLD, 0, 0, 0, 0)
203+
pub fn sys_fork(tf: &TrapFrame) -> LinuxResult<isize> {
204+
sys_clone(tf, SIGCHLD, 0, 0, 0, 0)
229205
}

api/src/imp/task/thread.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,38 @@ pub fn sys_set_tid_address(clear_child_tid: usize) -> LinuxResult<isize> {
6161

6262
#[cfg(target_arch = "x86_64")]
6363
#[apply(syscall_instrument)]
64-
pub fn sys_arch_prctl(code: i32, addr: crate::ptr::UserPtr<u64>) -> LinuxResult<isize> {
65-
use crate::ptr::PtrWrapper;
66-
match ArchPrctlCode::try_from(code).map_err(|_| axerrno::LinuxError::EINVAL)? {
64+
pub fn sys_arch_prctl(
65+
tf: &mut axhal::arch::TrapFrame,
66+
code: i32,
67+
addr: usize,
68+
) -> LinuxResult<isize> {
69+
use crate::ptr::{PtrWrapper, UserPtr};
70+
71+
let code = ArchPrctlCode::try_from(code).map_err(|_| axerrno::LinuxError::EINVAL)?;
72+
debug!("sys_arch_prctl: code = {:?}, addr = {:#x}", code, addr);
73+
74+
match code {
6775
// According to Linux implementation, SetFs & SetGs does not return
6876
// error at all
69-
ArchPrctlCode::SetFs => {
77+
ArchPrctlCode::GetFs => {
7078
unsafe {
71-
axhal::arch::write_thread_pointer(addr.address().as_usize());
79+
*UserPtr::from(addr).get()? = tf.tls();
7280
}
7381
Ok(0)
7482
}
75-
ArchPrctlCode::SetGs => {
76-
unsafe {
77-
x86::msr::wrmsr(x86::msr::IA32_KERNEL_GSBASE, addr.address().as_usize() as _);
78-
}
83+
ArchPrctlCode::SetFs => {
84+
tf.set_tls(addr);
7985
Ok(0)
8086
}
81-
ArchPrctlCode::GetFs => {
87+
ArchPrctlCode::GetGs => {
8288
unsafe {
83-
*addr.get()? = axhal::arch::read_thread_pointer() as u64;
89+
*UserPtr::from(addr).get()? = x86::msr::rdmsr(x86::msr::IA32_KERNEL_GSBASE);
8490
}
8591
Ok(0)
8692
}
87-
88-
ArchPrctlCode::GetGs => {
93+
ArchPrctlCode::SetGs => {
8994
unsafe {
90-
*addr.get()? = x86::msr::rdmsr(x86::msr::IA32_KERNEL_GSBASE);
95+
x86::msr::wrmsr(x86::msr::IA32_KERNEL_GSBASE, addr as _);
9196
}
9297
Ok(0)
9398
}

src/syscall.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use starry_core::task::{time_stat_from_kernel_to_user, time_stat_from_user_to_ke
88
use syscalls::Sysno;
99

1010
#[register_trap_handler(SYSCALL)]
11-
fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
11+
fn handle_syscall(tf: &mut TrapFrame, syscall_num: usize) -> isize {
1212
let sysno = Sysno::from(syscall_num as u32);
1313
info!("Syscall {}", sysno);
1414
time_stat_from_user_to_kernel();
@@ -37,17 +37,16 @@ fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
3737
Sysno::dup => sys_dup(tf.arg0() as _),
3838
Sysno::dup3 => sys_dup3(tf.arg0() as _, tf.arg1() as _),
3939
Sysno::fcntl => sys_fcntl(tf.arg0() as _, tf.arg1() as _, tf.arg2() as _),
40-
Sysno::clone => {
41-
let (child_tid, tls) = if cfg!(any(target_arch = "x86_64", target_arch = "loongarch64"))
42-
{
43-
(tf.arg3() as _, tf.arg4() as _)
44-
} else {
45-
(tf.arg4() as _, tf.arg3() as _)
46-
};
47-
sys_clone(tf.arg0() as _, tf.arg1() as _, tf.arg2(), child_tid, tls)
48-
}
40+
Sysno::clone => sys_clone(
41+
tf,
42+
tf.arg0() as _,
43+
tf.arg1() as _,
44+
tf.arg2(),
45+
tf.arg3(),
46+
tf.arg4(),
47+
),
4948
#[cfg(target_arch = "x86_64")]
50-
Sysno::fork => sys_fork(),
49+
Sysno::fork => sys_fork(tf),
5150
Sysno::wait4 => sys_waitpid(tf.arg0() as _, tf.arg1().into(), tf.arg2() as _),
5251
Sysno::pipe2 => sys_pipe2(tf.arg0().into()),
5352
Sysno::close => sys_close(tf.arg0() as _),
@@ -107,7 +106,7 @@ fn handle_syscall(tf: &TrapFrame, syscall_num: usize) -> isize {
107106
Sysno::times => sys_times(tf.arg0().into()),
108107
Sysno::brk => sys_brk(tf.arg0() as _),
109108
#[cfg(target_arch = "x86_64")]
110-
Sysno::arch_prctl => sys_arch_prctl(tf.arg0() as _, tf.arg1().into()),
109+
Sysno::arch_prctl => sys_arch_prctl(tf, tf.arg0() as _, tf.arg1() as _),
111110
Sysno::set_tid_address => sys_set_tid_address(tf.arg0()),
112111
Sysno::clock_gettime => sys_clock_gettime(tf.arg0() as _, tf.arg1().into()),
113112
Sysno::getuid => sys_getuid(),

0 commit comments

Comments
 (0)