diff --git a/src/acpi/hpet.rs b/src/acpi/hpet.rs index b1cafb5d986b575539a5f210428a2441e2ce3c74..a2546b8e3718152d8dbae0773a04fa81033cb638 100644 --- a/src/acpi/hpet.rs +++ b/src/acpi/hpet.rs @@ -1,6 +1,6 @@ use core::{mem, ptr}; -use core::intrinsics::{volatile_load, volatile_store}; +use core::ptr::{read_volatile, write_volatile}; use crate::memory::Frame; use crate::paging::{KernelMapper, PhysicalAddress, PageFlags}; @@ -82,11 +82,11 @@ impl GenericAddressStructure { } pub unsafe fn read_u64(&self, offset: usize) -> u64{ - volatile_load((crate::HPET_OFFSET + offset) as *const u64) + read_volatile((crate::HPET_OFFSET + offset) as *const u64) } pub unsafe fn write_u64(&mut self, offset: usize, value: u64) { - volatile_store((crate::HPET_OFFSET + offset) as *mut u64, value); + write_volatile((crate::HPET_OFFSET + offset) as *mut u64, value); } } @@ -103,10 +103,10 @@ impl GenericAddressStructure { } pub unsafe fn read_u64(&self, offset: usize) -> u64{ - volatile_load((self.address as usize + offset + crate::PHYS_OFFSET) as *const u64) + read_volatile((self.address as usize + offset + crate::PHYS_OFFSET) as *const u64) } pub unsafe fn write_u64(&mut self, offset: usize, value: u64) { - volatile_store((self.address as usize + offset + crate::PHYS_OFFSET) as *mut u64, value); + write_volatile((self.address as usize + offset + crate::PHYS_OFFSET) as *mut u64, value); } } diff --git a/src/acpi/madt.rs b/src/acpi/madt.rs index 7151e4b59050abcae1f64356cdf4042b0047cdff..64d7c06fbb8f271029e57c989852dab0eefc9cb2 100644 --- a/src/acpi/madt.rs +++ b/src/acpi/madt.rs @@ -6,8 +6,7 @@ use crate::paging::{KernelMapper, Page, PageFlags, PhysicalAddress, RmmA, RmmArc use super::sdt::Sdt; use super::find_sdt; -use core::intrinsics::{atomic_load_seqcst, atomic_store_seqcst}; -use core::sync::atomic::Ordering; +use core::sync::atomic::{AtomicU8, AtomicU64, Ordering}; use crate::device::local_apic::LOCAL_APIC; use crate::interrupt; @@ -73,7 +72,8 @@ impl Madt { // Write trampoline, make sure TRAMPOLINE page is free for use for i in 0..TRAMPOLINE_DATA.len() { unsafe { - atomic_store_seqcst((TRAMPOLINE as *mut u8).add(i), TRAMPOLINE_DATA[i]); + (*((TRAMPOLINE as *mut u8).add(i) as *const AtomicU8)) + .store(TRAMPOLINE_DATA[i], Ordering::SeqCst); } } @@ -91,7 +91,7 @@ impl Madt { let stack_start = allocate_frames(64).expect("no more frames in acpi stack_start").start_address().data() + crate::PHYS_OFFSET; let stack_end = stack_start + 64 * 4096; - let ap_ready = (TRAMPOLINE + 8) as *mut u64; + let ap_ready = (TRAMPOLINE + 8) as *const AtomicU64; let ap_cpu_id = unsafe { ap_ready.offset(1) }; let ap_page_table = unsafe { ap_ready.offset(2) }; let ap_stack_start = unsafe { ap_ready.offset(3) }; @@ -99,12 +99,17 @@ impl Madt { let ap_code = unsafe { ap_ready.offset(5) }; // Set the ap_ready to 0, volatile - unsafe { atomic_store_seqcst(ap_ready, 0) }; - unsafe { atomic_store_seqcst(ap_cpu_id, ap_local_apic.id as u64) }; - unsafe { atomic_store_seqcst(ap_page_table, page_table_physaddr as u64) }; - unsafe { atomic_store_seqcst(ap_stack_start, stack_start as u64) }; - unsafe { atomic_store_seqcst(ap_stack_end, stack_end as u64) }; - unsafe { atomic_store_seqcst(ap_code, kstart_ap as u64) }; + unsafe { + (*ap_ready).store(0, Ordering::SeqCst); + (*ap_cpu_id) + .store(ap_local_apic.id as u64, Ordering::SeqCst); + (*ap_page_table) + .store(page_table_physaddr as u64, Ordering::SeqCst); + (*ap_stack_start) + .store(stack_start as u64, Ordering::SeqCst); + (*ap_stack_end).store(stack_end as u64, Ordering::SeqCst); + (*ap_code).store(kstart_ap as u64, Ordering::SeqCst); + }; AP_READY.store(false, Ordering::SeqCst); print!(" AP {}:", ap_local_apic.id); @@ -139,7 +144,7 @@ impl Madt { // Wait for trampoline ready print!(" Wait..."); - while unsafe { atomic_load_seqcst(ap_ready) } == 0 { + while unsafe { (*ap_ready).load(Ordering::SeqCst) } == 0 { interrupt::pause(); } print!(" Trampoline..."); diff --git a/src/arch/aarch64/device/gic.rs b/src/arch/aarch64/device/gic.rs index 20a6f117286c7cf80923bb71a3a963b7ff122e39..04a383cd3aba3561be61953f8ad98d42f0f2f70f 100644 --- a/src/arch/aarch64/device/gic.rs +++ b/src/arch/aarch64/device/gic.rs @@ -1,4 +1,4 @@ -use core::intrinsics::{volatile_load, volatile_store}; +use core::ptr::{read_volatile, write_volatile}; use crate::memory::Frame; use crate::paging::{KernelMapper, PhysicalAddress, Page, PageFlags, TableKind, VirtualAddress}; @@ -149,12 +149,12 @@ impl GicDistIf { } unsafe fn read(&self, reg: u32) -> u32 { - let val = volatile_load((self.address + reg as usize) as *const u32); + let val = read_volatile((self.address + reg as usize) as *const u32); val } unsafe fn write(&mut self, reg: u32, value: u32) { - volatile_store((self.address + reg as usize) as *mut u32, value); + write_volatile((self.address + reg as usize) as *mut u32, value); } } @@ -179,11 +179,11 @@ impl GicCpuIf { } unsafe fn read(&self, reg: u32) -> u32 { - let val = volatile_load((self.address + reg as usize) as *const u32); + let val = read_volatile((self.address + reg as usize) as *const u32); val } unsafe fn write(&mut self, reg: u32, value: u32) { - volatile_store((self.address + reg as usize) as *mut u32, value); + write_volatile((self.address + reg as usize) as *mut u32, value); } } diff --git a/src/arch/aarch64/device/rtc.rs b/src/arch/aarch64/device/rtc.rs index d7aaa9ab3bfdf2fda279862883fc3982689d329c..b47d7bf735514d5e0aa34ee14fa4d271786d734d 100644 --- a/src/arch/aarch64/device/rtc.rs +++ b/src/arch/aarch64/device/rtc.rs @@ -1,4 +1,4 @@ -use core::intrinsics::{volatile_load, volatile_store}; +use core::ptr::{read_volatile, write_volatile}; use crate::memory::Frame; use crate::paging::{KernelMapper, PhysicalAddress, Page, PageFlags, TableKind, VirtualAddress}; @@ -47,12 +47,12 @@ impl Pl031rtc { } unsafe fn read(&self, reg: u32) -> u32 { - let val = volatile_load((self.address + reg as usize) as *const u32); + let val = read_volatile((self.address + reg as usize) as *const u32); val } unsafe fn write(&mut self, reg: u32, value: u32) { - volatile_store((self.address + reg as usize) as *mut u32, value); + write_volatile((self.address + reg as usize) as *mut u32, value); } pub fn time(&mut self) -> u64 { diff --git a/src/arch/aarch64/rmm.rs b/src/arch/aarch64/rmm.rs index 059cc1fe49f16444e30ac5d6d51c78744c40ab06..5af88af91fe5aa07fc34f5001fdb93dbcc31c6f7 100644 --- a/src/arch/aarch64/rmm.rs +++ b/src/arch/aarch64/rmm.rs @@ -57,18 +57,14 @@ pub struct BootloaderMemoryEntry { unsafe fn page_flags<A: Arch>(virt: VirtualAddress) -> PageFlags<A> { let virt_addr = virt.data(); - // Test for being inside a region - macro_rules! in_section { - ($n: ident) => { - virt_addr >= &concat_idents!(__, $n, _start) as *const u8 as usize - && virt_addr < &concat_idents!(__, $n, _end) as *const u8 as usize - }; - } - - if in_section!(text) { + if virt_addr >= &__text_start as *const u8 as usize + && virt_addr < &__text_end as *const u8 as usize + { // Remap text read-only, execute PageFlags::new().execute(true) - } else if in_section!(rodata) { + } else if virt_addr >= &__rodata_start as *const u8 as usize + && virt_addr < &__rodata_end as *const u8 as usize + { // Remap rodata read-only, no execute PageFlags::new() } else { diff --git a/src/arch/aarch64/stop.rs b/src/arch/aarch64/stop.rs index 90f55227f13a2f37409edd679da920f87d8dc295..6f12001777869276ba1b32761c757a029f8514bd 100644 --- a/src/arch/aarch64/stop.rs +++ b/src/arch/aarch64/stop.rs @@ -6,9 +6,13 @@ pub unsafe extern fn kreset() -> ! { let val: u32 = 0x8400_0009; asm!("mov x0, {}", in(reg) val); - asm!("hvc #0"); + asm!("hvc #0", options(noreturn)); +} - unreachable!(); +pub unsafe fn emergency_reset() -> ! { + let val: u32 = 0x8400_0009; + asm!("mov x0, {}", in(reg) val); + asm!("hvc #0", options(noreturn)); } #[no_mangle] @@ -17,7 +21,5 @@ pub unsafe extern fn kstop() -> ! { let val: u32 = 0x8400_0008; asm!("mov x0, {}", in(reg) val); - asm!("hvc #0"); - - unreachable!(); + asm!("hvc #0", options(noreturn)); } diff --git a/src/arch/x86/device/local_apic.rs b/src/arch/x86/device/local_apic.rs index 9ad4f575e5be457e455d71b2be6f70158c6cc815..04654722fa132fab9f5f207816a29778fb8f9a72 100644 --- a/src/arch/x86/device/local_apic.rs +++ b/src/arch/x86/device/local_apic.rs @@ -1,5 +1,5 @@ use core::sync::atomic::{self, AtomicU32}; -use core::intrinsics::{volatile_load, volatile_store}; +use core::ptr::{read_volatile, write_volatile}; use x86::msr::*; use crate::paging::{KernelMapper, PhysicalAddress, PageFlags, RmmA, RmmArch, VirtualAddress}; @@ -84,11 +84,11 @@ impl LocalApic { } unsafe fn read(&self, reg: u32) -> u32 { - volatile_load((self.address + reg as usize) as *const u32) + read_volatile((self.address + reg as usize) as *const u32) } unsafe fn write(&mut self, reg: u32, value: u32) { - volatile_store((self.address + reg as usize) as *mut u32, value); + write_volatile((self.address + reg as usize) as *mut u32, value); } pub fn id(&self) -> u32 { diff --git a/src/arch/x86/rmm.rs b/src/arch/x86/rmm.rs index 4593c15977b621d73c3dafcade92557f1bfbec5f..4c635aaeacab9a030e5cf759b57876b0f06b7fc6 100644 --- a/src/arch/x86/rmm.rs +++ b/src/arch/x86/rmm.rs @@ -58,18 +58,14 @@ pub struct BootloaderMemoryEntry { unsafe fn page_flags<A: Arch>(virt: VirtualAddress) -> PageFlags<A> { let virt_addr = virt.data(); - // Test for being inside a region - macro_rules! in_section { - ($n: ident) => { - virt_addr >= &concat_idents!(__, $n, _start) as *const u8 as usize - && virt_addr < &concat_idents!(__, $n, _end) as *const u8 as usize - }; - } - - if in_section!(text) { + if virt_addr >= &__text_start as *const u8 as usize + && virt_addr < &__text_end as *const u8 as usize + { // Remap text read-only, execute PageFlags::new().execute(true) - } else if in_section!(rodata) { + } else if virt_addr >= &__rodata_start as *const u8 as usize + && virt_addr < &__rodata_end as *const u8 as usize + { // Remap rodata read-only, no execute PageFlags::new() } else { diff --git a/src/arch/x86/stop.rs b/src/arch/x86/stop.rs index 38aaef8739f5fe06695ae67c3911b0c25d93cd69..246d1ddde21833fd124292ffead65cae27bceb43 100644 --- a/src/arch/x86/stop.rs +++ b/src/arch/x86/stop.rs @@ -19,14 +19,16 @@ pub unsafe extern fn kreset() -> ! { port.write(0xFE); } + emergency_reset(); +} + +pub unsafe fn emergency_reset() -> ! { // Use triple fault to guarantee reset core::arch::asm!(" cli lidt cs:0 int $3 - "); - - unreachable!(); + ", options(noreturn)); } #[cfg(feature = "acpi")] diff --git a/src/arch/x86_64/device/local_apic.rs b/src/arch/x86_64/device/local_apic.rs index fe181731b6976fefdbb87894dacb71d2ebed3fc1..5b3b23ae4fc38a315b3454ca38b5bb645c7cc8dc 100644 --- a/src/arch/x86_64/device/local_apic.rs +++ b/src/arch/x86_64/device/local_apic.rs @@ -1,5 +1,5 @@ use core::sync::atomic::{self, AtomicU64}; -use core::intrinsics::{volatile_load, volatile_store}; +use core::ptr::{read_volatile, write_volatile}; use x86::msr::*; use crate::paging::{KernelMapper, PhysicalAddress, PageFlags, RmmA, RmmArch}; @@ -84,11 +84,11 @@ impl LocalApic { } unsafe fn read(&self, reg: u32) -> u32 { - volatile_load((self.address + reg as usize) as *const u32) + read_volatile((self.address + reg as usize) as *const u32) } unsafe fn write(&mut self, reg: u32, value: u32) { - volatile_store((self.address + reg as usize) as *mut u32, value); + write_volatile((self.address + reg as usize) as *mut u32, value); } pub fn id(&self) -> u32 { diff --git a/src/arch/x86_64/stop.rs b/src/arch/x86_64/stop.rs index 38aaef8739f5fe06695ae67c3911b0c25d93cd69..246d1ddde21833fd124292ffead65cae27bceb43 100644 --- a/src/arch/x86_64/stop.rs +++ b/src/arch/x86_64/stop.rs @@ -19,14 +19,16 @@ pub unsafe extern fn kreset() -> ! { port.write(0xFE); } + emergency_reset(); +} + +pub unsafe fn emergency_reset() -> ! { // Use triple fault to guarantee reset core::arch::asm!(" cli lidt cs:0 int $3 - "); - - unreachable!(); + ", options(noreturn)); } #[cfg(feature = "acpi")] diff --git a/src/context/memory.rs b/src/context/memory.rs index 37b0ec4d79a4e5cfa4ea88c8951f01f7b3d4dc80..6a07d3784e1c917c00aa358c5b3c99c2ca7eb3d0 100644 --- a/src/context/memory.rs +++ b/src/context/memory.rs @@ -158,16 +158,16 @@ impl AddrSpace { } Ok(()) } - pub fn munmap(mut self: RwLockWriteGuard<'_, Self>, page: Page, page_count: usize) { + pub fn munmap(mut this: RwLockWriteGuard<'_, Self>, page: Page, page_count: usize) { let mut notify_files = Vec::new(); let requested = Region::new(page.start_address(), page_count * PAGE_SIZE); let mut flusher = PageFlushAll::new(); - let conflicting: Vec<Region> = self.grants.conflicts(requested).map(Region::from).collect(); + let conflicting: Vec<Region> = this.grants.conflicts(requested).map(Region::from).collect(); for conflict in conflicting { - let grant = self.grants.take(&conflict).expect("conflicting region didn't exist"); + let grant = this.grants.take(&conflict).expect("conflicting region didn't exist"); let intersection = grant.intersect(requested); let (before, mut grant, after) = grant.extract(intersection.round()).expect("conflicting region shared no common parts"); @@ -178,16 +178,16 @@ impl AddrSpace { // Keep untouched regions if let Some(before) = before { - self.grants.insert(before); + this.grants.insert(before); } if let Some(after) = after { - self.grants.insert(after); + this.grants.insert(after); } // Remove irrelevant region - grant.unmap(&mut self.table.utable, &mut flusher); + grant.unmap(&mut this.table.utable, &mut flusher); } - drop(self); + drop(this); for (file_ref, intersection) in notify_files { let scheme_id = { file_ref.desc.description.read().scheme }; diff --git a/src/context/switch.rs b/src/context/switch.rs index 5d3a4d1803273f1ea89d45c3f959dfc8499e8427..bca5f7aca52c4f6fdd7436cf7cbf53da26f13ea1 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -97,7 +97,7 @@ pub unsafe extern "C" fn switch_finish_hook() { next_lock.force_write_unlock(); } else { // TODO: unreachable_unchecked()? - core::intrinsics::abort(); + crate::arch::stop::emergency_reset(); } arch::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst); } diff --git a/src/lib.rs b/src/lib.rs index c3611bbaa141c59a375401f630abde63bff94968..3be0afc1132c271abe0a65e8dc2b09f9eed088e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,16 +44,11 @@ #![feature(alloc_error_handler)] #![feature(allocator_api)] -#![feature(arbitrary_self_types)] #![feature(array_chunks)] #![feature(iter_array_chunks)] #![feature(asm_const)] // TODO: Relax requirements of most asm invocations -#![feature(concat_idents)] -#![feature(core_intrinsics)] -#![feature(integer_atomics)] #![feature(int_roundings)] #![feature(naked_functions)] -#![feature(ptr_internals)] #![feature(slice_ptr_get, slice_ptr_len)] #![feature(sync_unsafe_cell)] #![feature(thread_local)] diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index df2d2633c5b2568672963a3904cfced8e7145639..e57894df20bd79a69cfb71cb52853367bc3ed000 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -1030,7 +1030,7 @@ impl KernelScheme for ProcScheme { ADDRSPACE_OP_MUNMAP => { let (page, page_count) = crate::syscall::validate_region(next()??, next()??)?; - addrspace.write().munmap(page, page_count); + AddrSpace::munmap(addrspace.write(), page, page_count); } ADDRSPACE_OP_MPROTECT => { let (page, page_count) = crate::syscall::validate_region(next()??, next()??)?; diff --git a/src/scheme/user.rs b/src/scheme/user.rs index cd13c36237933a797bffbd82eaaa9095bed6f410..7b0725228f80adee2032da8c53b45b18cc4cad8c 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -529,7 +529,7 @@ impl<const READ: bool, const WRITE: bool> CaptureGuard<READ, WRITE> { let (first_page, page_count, _offset) = page_range_containing(self.base, self.len); - space.write().munmap(first_page, page_count); + AddrSpace::munmap(space.write(), first_page, page_count); result } diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index 2661ef5e8b65f11fac2a6e03a47ce58ace446711..2f6e185fb69e42ca45410d94f715afd115b3e5ba 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -3,6 +3,7 @@ use alloc::sync::Arc; use spin::RwLock; use crate::context::file::{FileDescriptor, FileDescription}; +use crate::context::memory::AddrSpace; use crate::context; use crate::memory::PAGE_SIZE; use crate::scheme::{self, FileHandle, OpenResult, current_caller_ctx, KernelScheme, SchemeId}; @@ -394,7 +395,7 @@ pub fn funmap(virtual_address: usize, length: usize) -> Result<usize> { let (page, page_count) = crate::syscall::validate_region(virtual_address, length_aligned)?; let addr_space = Arc::clone(context::current()?.read().addr_space()?); - addr_space.write().munmap(page, page_count); + AddrSpace::munmap(addr_space.write(), page, page_count); Ok(0) } diff --git a/src/syscall/futex.rs b/src/syscall/futex.rs index d6c903a7717327a2270fe2fa6b9db851bf455da7..5051817ce2abaecddda030683d00d19f28277c75 100644 --- a/src/syscall/futex.rs +++ b/src/syscall/futex.rs @@ -5,7 +5,7 @@ use alloc::collections::VecDeque; use alloc::sync::Arc; use rmm::Arch; -use core::intrinsics; +use core::sync::atomic::{AtomicU32, AtomicU64, Ordering}; use spin::RwLock; use crate::context::{self, memory::AddrSpace, Context}; @@ -79,7 +79,7 @@ pub fn futex(addr: usize, op: usize, val: usize, val2: usize, addr2: usize) -> R ( u64::from(unsafe { - intrinsics::atomic_load_seqcst::<u32>(accessible_addr as *const u32) + (*(accessible_addr as *const AtomicU32)).load(Ordering::SeqCst) }), u64::from(val as u32), ) @@ -89,7 +89,7 @@ pub fn futex(addr: usize, op: usize, val: usize, val2: usize, addr2: usize) -> R return Err(Error::new(EINVAL)); } ( - unsafe { intrinsics::atomic_load_seqcst::<u64>(addr as *const u64) }, + u64::from(unsafe { (*(addr as *const AtomicU64)).load(Ordering::SeqCst) }), val as u64, ) };