Skip to content
Snippets Groups Projects
Commit c59b94d1 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Hacks to support aarch64 static TLS

parent b0d3e5b1
No related branches found
No related tags found
No related merge requests found
Pipeline #10545 failed
......@@ -55,7 +55,7 @@ impl Tcb {
/// Create a new TCB
pub unsafe fn new(size: usize) -> Result<&'static mut Self> {
let page_size = Sys::getpagesize();
let (tls, tcb_page) = Self::os_new(round_up(size, page_size))?;
let (abi_page, tls, tcb_page) = Self::os_new(round_up(size, page_size))?;
let tcb_ptr = tcb_page.as_mut_ptr() as *mut Self;
trace!("New TCB: {:p}", tcb_ptr);
......@@ -123,8 +123,14 @@ impl Tcb {
.filter(|m| m.len > 0)
.enumerate()
{
let range =
self.tls_len - master.offset..self.tls_len - master.offset + master.len;
let range = if cfg!(any(target_arch = "x86", target_arch = "x86_64")) {
// x86 TLS layout is backwards
self.tls_len - master.offset..self.tls_len - master.offset + master.len
} else {
//TODO: fix aarch64 TLS layout when there is more than one master
assert_eq!(i, 0, "aarch64 TLS layout only supports one master");
0..master.len
};
if let Some(tls_data) = tls.get_mut(range) {
let data = master.data();
trace!(
......@@ -165,7 +171,7 @@ impl Tcb {
/// Activate TLS
pub unsafe fn activate(&mut self) {
Self::os_arch_activate(self.tcb_ptr as usize);
Self::os_arch_activate(self.tls_end as usize, self.tls_len);
}
/// Mapping with correct flags for TCB and TLS
......@@ -189,23 +195,26 @@ impl Tcb {
/// OS specific code to create a new TLS and TCB - Linux and Redox
#[cfg(any(target_os = "linux", target_os = "redox"))]
unsafe fn os_new(size: usize) -> Result<(&'static mut [u8], &'static mut [u8])> {
unsafe fn os_new(size: usize) -> Result<(&'static mut [u8], &'static mut [u8], &'static mut [u8])> {
let page_size = Sys::getpagesize();
let tls_tcb = Self::map(size + page_size)?;
Ok(tls_tcb.split_at_mut(size))
let abi_tls_tcb = Self::map(page_size + size + page_size)?;
let (abi, tls_tcb) = abi_tls_tcb.split_at_mut(page_size);
let (tls, tcb) = tls_tcb.split_at_mut(size);
Ok((abi, tls, tcb))
}
/// Architecture specific code to read a usize from the TCB - aarch64
#[inline(always)]
#[cfg(target_arch = "aarch64")]
unsafe fn arch_read(offset: usize) -> usize {
let tp: usize;
let abi_ptr: usize;
asm!(
"mrs {}, tpidr_el0",
out(reg) tp,
out(reg) abi_ptr,
);
*((tp + offset) as *const usize)
let tcb_ptr = *(abi_ptr as *const usize);
*((tcb_ptr + offset) as *const usize)
}
/// Architecture specific code to read a usize from the TCB - x86
......@@ -240,33 +249,26 @@ impl Tcb {
/// OS and architecture specific code to activate TLS - Linux x86_64
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
unsafe fn os_arch_activate(tp: usize) {
unsafe fn os_arch_activate(tls_end: usize, _tls_len: usize) {
const ARCH_SET_FS: usize = 0x1002;
syscall!(ARCH_PRCTL, ARCH_SET_FS, tp);
syscall!(ARCH_PRCTL, ARCH_SET_FS, tls_end);
}
/// OS and architecture specific code to activate TLS - Redox aarch64
#[cfg(all(target_os = "redox", target_arch = "aarch64"))]
unsafe fn os_arch_activate(tp: usize) {
let mut env = syscall::EnvRegisters::default();
let file = syscall::open("thisproc:current/regs/env", syscall::O_CLOEXEC | syscall::O_RDWR)
.expect_notls("failed to open handle for process registers");
let _ = syscall::read(file, &mut env)
.expect_notls("failed to read thread pointer");
env.tpidr_el0 = tp;
let _ = syscall::write(file, &env)
.expect_notls("failed to write thread pointer");
let _ = syscall::close(file);
unsafe fn os_arch_activate(tls_end: usize, tls_len: usize) {
// Uses ABI page
let abi_ptr = tls_end - tls_len - 16;
ptr::write(abi_ptr as *mut usize, tls_end);
asm!(
"msr tpidr_el0, {}",
in(reg) abi_ptr,
);
}
/// OS and architecture specific code to activate TLS - Redox x86
#[cfg(all(target_os = "redox", target_arch = "x86"))]
unsafe fn os_arch_activate(tp: usize) {
unsafe fn os_arch_activate(tls_end: usize, _tls_len: usize) {
let mut env = syscall::EnvRegisters::default();
let file = syscall::open("thisproc:current/regs/env", syscall::O_CLOEXEC | syscall::O_RDWR)
......@@ -275,7 +277,7 @@ impl Tcb {
let _ = syscall::read(file, &mut env)
.expect_notls("failed to read gsbase");
env.gsbase = tp as u32;
env.gsbase = tls_end as u32;
let _ = syscall::write(file, &env)
.expect_notls("failed to write gsbase");
......@@ -285,7 +287,7 @@ impl Tcb {
/// OS and architecture specific code to activate TLS - Redox x86_64
#[cfg(all(target_os = "redox", target_arch = "x86_64"))]
unsafe fn os_arch_activate(tp: usize) {
unsafe fn os_arch_activate(tls_end: usize, _tls_len: usize) {
let mut env = syscall::EnvRegisters::default();
let file = syscall::open("thisproc:current/regs/env", syscall::O_CLOEXEC | syscall::O_RDWR)
......@@ -294,7 +296,7 @@ impl Tcb {
let _ = syscall::read(file, &mut env)
.expect_notls("failed to read fsbase");
env.fsbase = tp as u64;
env.fsbase = tls_end as u64;
let _ = syscall::write(file, &env)
.expect_notls("failed to write fsbase");
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment