From ca92eda5e6b6a4f3737ae001a10df6111dbb0af5 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Tue, 11 Jul 2023 16:39:07 +0200 Subject: [PATCH] Remove TLS on aarch64 too. --- linkers/aarch64.ld | 12 -- .../device/cpu/registers/control_regs.rs | 6 + src/arch/aarch64/misc.rs | 21 +++ src/arch/aarch64/mod.rs | 3 + src/arch/aarch64/paging/mod.rs | 127 +----------------- src/arch/aarch64/start.rs | 18 +-- targets/aarch64-unknown-kernel.json | 3 +- 7 files changed, 37 insertions(+), 153 deletions(-) create mode 100644 src/arch/aarch64/misc.rs diff --git a/linkers/aarch64.ld b/linkers/aarch64.ld index cccc430c23..cce4c9edc9 100644 --- a/linkers/aarch64.ld +++ b/linkers/aarch64.ld @@ -39,18 +39,6 @@ SECTIONS { __bss_end = .; } - .tdata : AT(ADDR(.tdata) - KERNEL_OFFSET) { - __tdata_start = .; - *(.tdata*) - . = ALIGN(4096); - __tdata_end = .; - __tbss_start = .; - *(.tbss*) - . += 8; - . = ALIGN(4096); - __tbss_end = .; - } - __end = .; /DISCARD/ : { diff --git a/src/arch/aarch64/device/cpu/registers/control_regs.rs b/src/arch/aarch64/device/cpu/registers/control_regs.rs index 0272fae877..a64ff40076 100644 --- a/src/arch/aarch64/device/cpu/registers/control_regs.rs +++ b/src/arch/aarch64/device/cpu/registers/control_regs.rs @@ -50,6 +50,12 @@ pub unsafe fn tpidr_el0_write(val: u64) { asm!("msr tpidr_el0, {}", in(reg) val); } +pub unsafe fn tpidr_el1() -> u64 { + let ret: u64; + asm!("mrs {}, tpidr_el1", out(reg) ret); + ret +} + pub unsafe fn tpidr_el1_write(val: u64) { asm!("msr tpidr_el1, {}", in(reg) val); } diff --git a/src/arch/aarch64/misc.rs b/src/arch/aarch64/misc.rs new file mode 100644 index 0000000000..76a65c1995 --- /dev/null +++ b/src/arch/aarch64/misc.rs @@ -0,0 +1,21 @@ +use crate::paging::{RmmA, RmmArch}; +use crate::percpu::PercpuBlock; + +impl PercpuBlock { + pub fn current() -> &'static Self { + unsafe { &*(crate::device::cpu::registers::control_regs::tpidr_el1() as *const Self) } + } +} + +#[cold] +pub unsafe fn init(cpu_id: usize) { + let frame = crate::memory::allocate_frames(1).expect("failed to allocate percpu memory"); + let virt = RmmA::phys_to_virt(frame.start_address()).data() as *mut PercpuBlock; + + virt.write(PercpuBlock { + cpu_id, + switch_internals: crate::context::switch::ContextSwitchPercpu::default(), + }); + + crate::device::cpu::registers::control_regs::tpidr_el1_write(virt as u64); +} diff --git a/src/arch/aarch64/mod.rs b/src/arch/aarch64/mod.rs index e7dd3609d9..e5b787bef0 100644 --- a/src/arch/aarch64/mod.rs +++ b/src/arch/aarch64/mod.rs @@ -16,6 +16,9 @@ pub mod interrupt; /// Inter-processor interrupts pub mod ipi; +/// Miscellaneous +pub mod misc; + /// Paging pub mod paging; diff --git a/src/arch/aarch64/paging/mod.rs b/src/arch/aarch64/paging/mod.rs index 8dfe8f6695..fe806d9d8e 100644 --- a/src/arch/aarch64/paging/mod.rs +++ b/src/arch/aarch64/paging/mod.rs @@ -29,6 +29,7 @@ pub const ENTRY_COUNT: usize = RmmA::PAGE_ENTRIES; pub const PAGE_SIZE: usize = RmmA::PAGE_SIZE; /// Setup Memory Access Indirection Register +#[cold] unsafe fn init_mair() { let mut val: control_regs::MairEl1 = control_regs::mair_el1(); @@ -39,130 +40,10 @@ unsafe fn init_mair() { control_regs::mair_el1_write(val); } -/// Map percpu -unsafe fn map_percpu(cpu_id: usize, mapper: &mut PageMapper) -> PageFlushAll { - extern "C" { - /// The starting byte of the thread data segment - static mut __tdata_start: u8; - /// The ending byte of the thread data segment - static mut __tdata_end: u8; - /// The starting byte of the thread BSS segment - static mut __tbss_start: u8; - /// The ending byte of the thread BSS segment - static mut __tbss_end: u8; - } - - let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize; - let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id; - let end = start + size; - - let mut flush_all = PageFlushAll::new(); - let start_page = Page::containing_address(VirtualAddress::new(start)); - let end_page = Page::containing_address(VirtualAddress::new(end - 1)); - for page in Page::range_inclusive(start_page, end_page) { - let result = mapper.map( - page.start_address(), - PageFlags::new().write(true).global(cfg!(not(feature = "pti"))), - ) - .expect("failed to allocate page table frames while mapping percpu"); - flush_all.consume(result); - } - flush_all -} - -/// Copy tdata, clear tbss, set TCB self pointer -unsafe fn init_tcb(cpu_id: usize) -> usize { - extern "C" { - /// The starting byte of the thread data segment - static mut __tdata_start: u8; - /// The ending byte of the thread data segment - static mut __tdata_end: u8; - /// The starting byte of the thread BSS segment - static mut __tbss_start: u8; - /// The ending byte of the thread BSS segment - static mut __tbss_end: u8; - } - - let tcb_offset; - { - let size = &__tbss_end as *const _ as usize - &__tdata_start as *const _ as usize; - let tbss_offset = &__tbss_start as *const _ as usize - &__tdata_start as *const _ as usize; - - let start = crate::KERNEL_PERCPU_OFFSET + crate::KERNEL_PERCPU_SIZE * cpu_id; - println!("SET TPIDR_EL1 TO {:X}", start - 0x10); - // FIXME: Empirically initializing tpidr to 16 bytes below start works. I do not know - // whether this is the correct way to handle TLS. Will need to revisit. - control_regs::tpidr_el1_write((start - 0x10) as u64); - println!("SET TPIDR_EL1 DONE"); - - let end = start + size; - tcb_offset = end - mem::size_of::(); - - ptr::copy(&__tdata_start as *const u8, start as *mut u8, tbss_offset); - ptr::write_bytes((start + tbss_offset) as *mut u8, 0, size - tbss_offset); - - *(tcb_offset as *mut usize) = end; - } - tcb_offset -} - -/// Initialize paging -/// -/// Returns page table and thread control block offset -pub unsafe fn init( - cpu_id: usize, -) -> usize { - extern "C" { - /// The starting byte of the text (code) data segment. - static mut __text_start: u8; - /// The ending byte of the text (code) data segment. - static mut __text_end: u8; - /// The starting byte of the _.rodata_ (read-only data) segment. - static mut __rodata_start: u8; - /// The ending byte of the _.rodata_ (read-only data) segment. - static mut __rodata_end: u8; - /// The starting byte of the _.data_ segment. - static mut __data_start: u8; - /// The ending byte of the _.data_ segment. - static mut __data_end: u8; - /// The starting byte of the thread data segment - static mut __tdata_start: u8; - /// The ending byte of the thread data segment - static mut __tdata_end: u8; - /// The starting byte of the thread BSS segment - static mut __tbss_start: u8; - /// The ending byte of the thread BSS segment - static mut __tbss_end: u8; - /// The starting byte of the _.bss_ (uninitialized data) segment. - static mut __bss_start: u8; - /// The ending byte of the _.bss_ (uninitialized data) segment. - static mut __bss_end: u8; - } - +/// Initialize MAIR +#[cold] +pub unsafe fn init() { init_mair(); - - let flush_all = map_percpu(cpu_id, KernelMapper::lock_manually(cpu_id).get_mut().expect("expected KernelMapper not to be locked re-entrant in paging::init")); - flush_all.flush(); - - return init_tcb(cpu_id); -} - -pub unsafe fn init_ap( - cpu_id: usize, - bsp_table: &mut KernelMapper, -) -> usize { - init_mair(); - - { - let flush_all = map_percpu(cpu_id, bsp_table.get_mut().expect("KernelMapper locked re-entrant for AP")); - - // The flush can be ignored as this is not the active table. See later make_current(). - flush_all.ignore(); - }; - - bsp_table.make_current(); - - init_tcb(cpu_id) } /// Page diff --git a/src/arch/aarch64/start.rs b/src/arch/aarch64/start.rs index f76a7e3c43..5db751e1b1 100644 --- a/src/arch/aarch64/start.rs +++ b/src/arch/aarch64/start.rs @@ -22,12 +22,6 @@ use crate::paging::{self, KernelMapper}; static BSS_TEST_ZERO: usize = 0; /// Test of non-zero values in data. static DATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF; -/// Test of zero values in thread BSS -#[thread_local] -static mut TBSS_TEST_ZERO: usize = 0; -/// Test of non-zero values in thread data. -#[thread_local] -static mut TDATA_TEST_NONZERO: usize = 0xFFFF_FFFF_FFFF_FFFF; pub static KERNEL_BASE: AtomicUsize = AtomicUsize::new(0); pub static KERNEL_SIZE: AtomicUsize = AtomicUsize::new(0); @@ -138,17 +132,9 @@ pub unsafe extern "C" fn kstart(args_ptr: *const KernelArgs) -> ! { ); // Initialize paging - let tcb_offset = paging::init(0); + paging::init(); - // Test tdata and tbss - { - assert_eq!(TBSS_TEST_ZERO, 0); - TBSS_TEST_ZERO += 1; - assert_eq!(TBSS_TEST_ZERO, 1); - assert_eq!(TDATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFF); - TDATA_TEST_NONZERO -= 1; - assert_eq!(TDATA_TEST_NONZERO, 0xFFFF_FFFF_FFFF_FFFE); - } + crate::misc::init(0); // Reset AP variables CPU_COUNT.store(1, Ordering::SeqCst); diff --git a/targets/aarch64-unknown-kernel.json b/targets/aarch64-unknown-kernel.json index d1299bd0ad..78d46c6b3c 100644 --- a/targets/aarch64-unknown-kernel.json +++ b/targets/aarch64-unknown-kernel.json @@ -22,6 +22,5 @@ "exe-suffix": "", "has-rpath": false, "no-default-libraries": true, - "position-independent-executables": false, - "tls-model": "global-dynamic" + "position-independent-executables": false }