From 26812332328605b5fc3f21b3159a7e675ef890dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Fri, 26 Jan 2024 12:06:47 +0100 Subject: [PATCH] fix(riscv64): static-mut-ref MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This improves the page table handling soundness on 64-bit RISC-V. Signed-off-by: Martin Kröning --- src/arch/riscv64/mm/paging.rs | 42 ++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/arch/riscv64/mm/paging.rs b/src/arch/riscv64/mm/paging.rs index 73cf43c54c..d5080d0d43 100644 --- a/src/arch/riscv64/mm/paging.rs +++ b/src/arch/riscv64/mm/paging.rs @@ -1,14 +1,15 @@ use core::marker::PhantomData; -use core::usize; +use core::{ptr, usize}; use align_address::Align; +use hermit_sync::SpinMutex; use riscv::asm::sfence_vma; use riscv::register::satp; use crate::arch::riscv64::kernel::get_ram_address; use crate::arch::riscv64::mm::{physicalmem, PhysAddr, VirtAddr}; -static mut ROOT_PAGETABLE: PageTable = PageTable::new(); +static ROOT_PAGETABLE: SpinMutex> = SpinMutex::new(PageTable::new()); /// Number of Offset bits of a virtual address for a 4 KiB page, which are shifted away to get its Page Frame Number (PFN). const PAGE_BITS: usize = 12; @@ -581,7 +582,8 @@ pub fn virtual_to_physical(virtual_address: VirtAddr) -> Option { ); } - let mut page_table_addr = unsafe { &ROOT_PAGETABLE as *const PageTable }; + let page_table = ROOT_PAGETABLE.lock(); + let mut page_table_addr = ptr::from_ref(&*page_table); for i in (0..PAGE_LEVELS).rev() { let pte = unsafe { (*page_table_addr).entries[(vpn[i]) as usize] }; // trace!("PTE: {:?} , i: {}, vpn[i]: {:#X}", pte, i, vpn[i]); @@ -637,9 +639,9 @@ pub fn map( ); let range = get_page_range::(virtual_address, count); - unsafe { - ROOT_PAGETABLE.map_pages(range, physical_address, flags); - } + ROOT_PAGETABLE + .lock() + .map_pages(range, physical_address, flags); //assert_eq!(virtual_address.as_u64(), physical_address.as_u64(), "Paging not implemented"); } @@ -673,9 +675,9 @@ pub fn unmap(virtual_address: VirtAddr, count: usize) { /* let root_pagetable = unsafe { &mut *mem::transmute::<*mut u64, *mut PageTable>(L2TABLE_ADDRESS.as_mut_ptr()) }; */ - unsafe { - ROOT_PAGETABLE.map_pages(range, PhysAddr::zero(), PageTableEntryFlags::BLANK); - } + ROOT_PAGETABLE + .lock() + .map_pages(range, PhysAddr::zero(), PageTableEntryFlags::BLANK); } #[inline] @@ -705,25 +707,25 @@ pub fn identity_map(start_address: PhysAddr, end_address: PhysAddr) let range = Page::::range(first_page, last_page); let mut flags = PageTableEntryFlags::empty(); flags.normal().writable(); - unsafe { - ROOT_PAGETABLE.map_pages(range, PhysAddr(first_page.address().as_u64()), flags); - } + ROOT_PAGETABLE + .lock() + .map_pages(range, PhysAddr(first_page.address().as_u64()), flags); } pub fn init_page_tables() { trace!("Identity map the physical memory using HugePages"); - unsafe { - identity_map::( - get_ram_address(), - get_ram_address() + PhysAddr(physicalmem::total_memory_size() as u64 - 1), - ); - satp::write(0x8 << 60 | ((&ROOT_PAGETABLE as *const _ as usize) >> 12)) - } + identity_map::( + get_ram_address(), + get_ram_address() + PhysAddr(physicalmem::total_memory_size() as u64 - 1), + ); + // FIXME: This is not sound, since we are ignoring races with the hardware. + satp::write(0x8 << 60 | (ROOT_PAGETABLE.data_ptr().addr() >> 12)); } #[cfg(feature = "smp")] pub fn init_application_processor() { trace!("Identity map the physical memory using HugePages"); - unsafe { satp::write(0x8 << 60 | ((&ROOT_PAGETABLE as *const _ as usize) >> 12)) } + // FIXME: This is not sound, since we are ignoring races with the hardware. + satp::write(0x8 << 60 | (ROOT_PAGETABLE.data_ptr().addr() >> 12)); }