From 016957cc6fc2356df8649ea4399c590893660055 Mon Sep 17 00:00:00 2001 From: ZhiyuanSue <108735103+ZhiyuanSue@users.noreply.github.com> Date: Thu, 26 Sep 2024 16:04:47 +0800 Subject: [PATCH] Update kernel (#16) * almost done all the data structure changes and sync (#11) * update the sel4_cspace/src/arch/aarch64/mod.rs with some definations * add some funcitons * update the objecttype definations * clean the pgde/pude/pde structures definetions * change the definetions of lookup and update 4 todos * Update kernel 3 (#12) * update the sel4_cspace/src/arch/aarch64/mod.rs with some definations * add some funcitons * update the objecttype definations * clean the pgde/pude/pde structures definetions * change the definetions of lookup and update 4 todos * try to fix some functions * fix some errors with more errors generated * clean some unused functions * update and pass the complier, but still have unimplement * Update kernel 4 (#13) * fill in the unimplement code * clean the warnings * add the 4k page * FIX:the page entry problem of map kernel window * Update kernel 5 (#14) * fix the word the vs used * fix the page bug, and let the root task work * Update kernel 6 (#15) * fix make user pte todo * fix the unmap assert * fix the bug of the unmap page * fix another bug * seems fix bug --- kernel/src/arch/aarch64/exception.rs | 12 +- kernel/src/arch/aarch64/pg.rs | 2 +- kernel/src/arch/riscv/exception.rs | 14 +- kernel/src/boot/root_server.rs | 2 +- kernel/src/interfaces_impl/cspace.rs | 53 +- kernel/src/interrupt/handler.rs | 4 +- kernel/src/syscall/invocation/arch/aarch64.rs | 29 +- kernel/src/syscall/invocation/arch/riscv64.rs | 6 +- .../syscall/invocation/decode/arch/aarch64.rs | 690 ++++++++------- .../syscall/invocation/decode/arch/riscv64.rs | 12 +- .../decode/decode_tcb_invocation.rs | 24 +- .../src/syscall/invocation/invoke_mmu_op.rs | 211 +++-- kernel/src/syscall/invocation/mod.rs | 2 +- kernel/src/utils.rs | 26 +- sel4_common/src/arch/aarch64/message_info.rs | 5 +- sel4_common/src/arch/aarch64/object.rs | 23 +- sel4_common/src/object.rs | 2 +- sel4_common/src/sel4_config.rs | 3 + sel4_cspace/src/arch/aarch64/mod.rs | 122 +-- sel4_task/src/tcb.rs | 4 +- sel4_vspace/src/arch/aarch64/asid.rs | 9 +- sel4_vspace/src/arch/aarch64/boot.rs | 64 +- sel4_vspace/src/arch/aarch64/interface.rs | 420 +++++---- sel4_vspace/src/arch/aarch64/mod.rs | 2 +- sel4_vspace/src/arch/aarch64/pagetable.rs | 2 +- sel4_vspace/src/arch/aarch64/pte.rs | 137 ++- sel4_vspace/src/arch/aarch64/structures.rs | 55 +- sel4_vspace/src/arch/aarch64/utils.rs | 825 +++++++++--------- sel4_vspace/src/structures.rs | 5 +- 29 files changed, 1431 insertions(+), 1334 deletions(-) diff --git a/kernel/src/arch/aarch64/exception.rs b/kernel/src/arch/aarch64/exception.rs index a82ad96..5ea1155 100644 --- a/kernel/src/arch/aarch64/exception.rs +++ b/kernel/src/arch/aarch64/exception.rs @@ -15,8 +15,8 @@ use aarch64_cpu::registers::Readable; use aarch64_cpu::registers::TTBR0_EL1; use log::debug; use sel4_common::arch::ArchReg::*; -use sel4_common::print; use sel4_common::fault::seL4_Fault_t; +use sel4_common::print; use sel4_common::sel4_config::seL4_MsgMaxLength; use sel4_common::structures::exception_t; use sel4_common::utils::global_read; @@ -27,23 +27,23 @@ use super::instruction::*; #[no_mangle] pub fn handleUnknownSyscall(w: isize) -> exception_t { - let thread = get_currenct_thread(); + let thread = get_currenct_thread(); if w == SysDebugPutChar { - print!("{}",thread.tcbArch.get_register(Cap) as u8 as char); + print!("{}", thread.tcbArch.get_register(Cap) as u8 as char); return exception_t::EXCEPTION_NONE; } if w == SysDebugDumpScheduler { - // unimplement debug + // unimplement debug // println!("debug dump scheduler"); return exception_t::EXCEPTION_NONE; } if w == SysDebugHalt { - // unimplement debug + // unimplement debug // println!("debug halt"); return exception_t::EXCEPTION_NONE; } if w == SysDebugSnapshot { - // unimplement debug + // unimplement debug // println!("debug snapshot"); return exception_t::EXCEPTION_NONE; } diff --git a/kernel/src/arch/aarch64/pg.rs b/kernel/src/arch/aarch64/pg.rs index 464f5b0..fd87e64 100644 --- a/kernel/src/arch/aarch64/pg.rs +++ b/kernel/src/arch/aarch64/pg.rs @@ -67,7 +67,7 @@ extern "C" fn decodeARMMMUInvocation( pub fn set_vm_root_for_flush(vspace: usize, asid: asid_t) -> bool { let thread_root = get_currenct_thread().get_cspace(tcbVTable).cap; - if thread_root.is_valid_native_root() && thread_root.get_pgd_base_ptr() == vspace as usize { + if thread_root.is_valid_native_root() && thread_root.get_vs_base_ptr() == vspace as usize { return false; } diff --git a/kernel/src/arch/riscv/exception.rs b/kernel/src/arch/riscv/exception.rs index 643ee31..630c592 100644 --- a/kernel/src/arch/riscv/exception.rs +++ b/kernel/src/arch/riscv/exception.rs @@ -13,31 +13,31 @@ use crate::syscall::{ use log::debug; use sel4_common::arch::ArchReg::*; use sel4_common::fault::seL4_Fault_t; +use sel4_common::print; use sel4_common::sel4_config::seL4_MsgMaxLength; use sel4_common::structures::exception_t; use sel4_cspace::arch::CapTag; -use sel4_common::print; use sel4_task::{activateThread, get_currenct_thread, schedule}; #[no_mangle] pub fn handleUnknownSyscall(w: isize) -> exception_t { - let thread = get_currenct_thread(); + let thread = get_currenct_thread(); if w == SysDebugPutChar { - print!("{}",thread.tcbArch.get_register(Cap) as u8 as char); + print!("{}", thread.tcbArch.get_register(Cap) as u8 as char); return exception_t::EXCEPTION_NONE; } if w == SysDebugDumpScheduler { - // unimplement debug + // unimplement debug // println!("debug dump scheduler"); return exception_t::EXCEPTION_NONE; } if w == SysDebugHalt { - // unimplement debug + // unimplement debug // println!("debug halt"); return exception_t::EXCEPTION_NONE; } if w == SysDebugSnapshot { - // unimplement debug + // unimplement debug // println!("debug snap shot"); return exception_t::EXCEPTION_NONE; } @@ -68,7 +68,7 @@ pub fn handleUnknownSyscall(w: isize) -> exception_t { debug!("SysDebugNameThread: Name too long, halting"); halt(); } - + // setThreadName(TCB_PTR(cap_thread_cap_get_capTCBPtr(lu_ret.cap)), name); return exception_t::EXCEPTION_NONE; } diff --git a/kernel/src/boot/root_server.rs b/kernel/src/boot/root_server.rs index 9378f6c..427d05d 100644 --- a/kernel/src/boot/root_server.rs +++ b/kernel/src/boot/root_server.rs @@ -442,7 +442,7 @@ unsafe fn rust_create_it_address_space(root_cnode_cap: &cap_t, it_v_reg: v_regio #[cfg(target_arch = "aarch64")] unsafe fn rust_create_it_address_space(root_cnode_cap: &cap_t, it_v_reg: v_region_t) -> cap_t { // create the PGD - let vspace_cap = cap_t::new_page_global_directory_cap(IT_ASID, rootserver.vspace, 1); + let vspace_cap = cap_t::new_vspace_cap(IT_ASID, rootserver.vspace, 1); let ptr = root_cnode_cap.get_cap_ptr() as *mut cte_t; let slot_pos_before = ndks_boot.slot_pos_cur; write_slot(ptr.add(seL4_CapInitThreadVspace), vspace_cap.clone()); diff --git a/kernel/src/interfaces_impl/cspace.rs b/kernel/src/interfaces_impl/cspace.rs index 03409e4..c71921c 100644 --- a/kernel/src/interfaces_impl/cspace.rs +++ b/kernel/src/interfaces_impl/cspace.rs @@ -12,11 +12,9 @@ use sel4_ipc::{endpoint_t, notification_t, Transfer}; use sel4_task::{get_currenct_thread, ksWorkUnitsCompleted, tcb_t}; #[cfg(target_arch = "riscv64")] use sel4_vspace::find_vspace_for_asid; -use sel4_vspace::{asid_pool_t, asid_t, delete_asid, delete_asid_pool, unmapPage, PTE}; #[cfg(target_arch = "aarch64")] -use sel4_vspace::{ - unmap_page_directory, unmap_page_table, unmap_page_upper_directory, PDE, PGDE, PUDE, -}; +use sel4_vspace::unmap_page_table; +use sel4_vspace::{asid_pool_t, asid_t, delete_asid, delete_asid_pool, unmapPage, PTE}; #[cfg(target_arch = "riscv64")] #[no_mangle] @@ -89,27 +87,32 @@ pub fn Arch_finaliseCap(cap: &cap_t, final_: bool) -> finaliseCap_ret { } } } - CapTag::CapPageGlobalDirectoryCap => { - if final_ && cap.get_pgd_is_mapped() == 1 { - deleteASID(cap.get_pgd_is_mapped(), cap.get_pgd_base_ptr() as _); - } - } - CapTag::CapPageUpperDirectoryCap => { - if final_ && cap.get_pud_is_mapped() == 1 { - let pud = ptr_to_mut(cap.get_pt_base_ptr() as *mut PUDE); - unmap_page_upper_directory( - cap.get_pud_mapped_asid(), - cap.get_pud_mapped_address(), - pud, - ); - } - } - CapTag::CapPageDirectoryCap => { - if final_ && cap.get_pd_is_mapped() == 1 { - let pd = ptr_to_mut(cap.get_pt_base_ptr() as *mut PDE); - unmap_page_directory(cap.get_pd_mapped_asid(), cap.get_pd_mapped_address(), pd); + CapTag::CapVspaceCap => { + if final_ && cap.get_vs_is_mapped() == 1 { + deleteASID(cap.get_vs_is_mapped(), cap.get_vs_base_ptr() as _); } } + // CapTag::CapPageGlobalDirectoryCap => { + // if final_ && cap.get_pgd_is_mapped() == 1 { + // deleteASID(cap.get_pgd_is_mapped(), cap.get_pgd_base_ptr() as _); + // } + // } + // CapTag::CapPageUpperDirectoryCap => { + // if final_ && cap.get_pud_is_mapped() == 1 { + // let pud = ptr_to_mut(cap.get_pt_base_ptr() as *mut PUDE); + // unmap_page_upper_directory( + // cap.get_pud_mapped_asid(), + // cap.get_pud_mapped_address(), + // pud, + // ); + // } + // } + // CapTag::CapPageDirectoryCap => { + // if final_ && cap.get_pd_is_mapped() == 1 { + // let pd = ptr_to_mut(cap.get_pt_base_ptr() as *mut PDE); + // unmap_page_directory(cap.get_pd_mapped_asid(), cap.get_pd_mapped_address(), pd); + // } + // } CapTag::CapPageTableCap => { if final_ && cap.get_pt_is_mapped() == 1 { let pte = ptr_to_mut(cap.get_pt_base_ptr() as *mut PTE); @@ -259,7 +262,6 @@ pub fn preemptionPoint() -> exception_t { } } - #[no_mangle] #[cfg(target_arch = "riscv64")] pub fn deleteASID(asid: asid_t, vspace: *mut PTE) { @@ -276,7 +278,7 @@ pub fn deleteASID(asid: asid_t, vspace: *mut PTE) { #[no_mangle] #[cfg(target_arch = "aarch64")] -pub fn deleteASID(asid: asid_t, vspace: *mut PGDE) { +pub fn deleteASID(asid: asid_t, vspace: *mut PTE) { unsafe { if let Err(lookup_fault) = delete_asid( asid, @@ -288,7 +290,6 @@ pub fn deleteASID(asid: asid_t, vspace: *mut PGDE) { } } - #[no_mangle] pub fn deleteASIDPool(asid_base: asid_t, pool: *mut asid_pool_t) { unsafe { diff --git a/kernel/src/interrupt/handler.rs b/kernel/src/interrupt/handler.rs index 06b34ad..efdd868 100644 --- a/kernel/src/interrupt/handler.rs +++ b/kernel/src/interrupt/handler.rs @@ -1,12 +1,12 @@ use crate::arch::resetTimer; -use crate::config::{irqInvalid,maxIRQ}; +use crate::config::{irqInvalid, maxIRQ}; use crate::interrupt::*; use core::intrinsics::unlikely; use log::debug; use sel4_common::structures::exception_t; use sel4_cspace::interface::CapTag; use sel4_ipc::notification_t; -use sel4_task::{activateThread, schedule,timerTick}; +use sel4_task::{activateThread, schedule, timerTick}; #[no_mangle] pub fn handleInterruptEntry() -> exception_t { diff --git a/kernel/src/syscall/invocation/arch/aarch64.rs b/kernel/src/syscall/invocation/arch/aarch64.rs index 0f84415..d46cb77 100644 --- a/kernel/src/syscall/invocation/arch/aarch64.rs +++ b/kernel/src/syscall/invocation/arch/aarch64.rs @@ -1,4 +1,7 @@ -use sel4_common::{arch::{vm_rights_t, ObjectType}, sel4_config::{asidInvalid, ARM_Large_Page, ARM_Small_Page}}; +use sel4_common::{ + arch::{vm_rights_t, ObjectType}, + sel4_config::{asidInvalid, ARM_Huge_Page, ARM_Large_Page, ARM_Small_Page}, +}; use sel4_cspace::arch::cap_t; use sel4_vspace::pptr_t; @@ -17,18 +20,6 @@ pub fn arch_create_object( asidInvalid, region_base, ), - ObjectType::seL4_ARM_PageUpperDirectoryObject => { - cap_t::new_page_upper_directory_cap(asidInvalid, region_base, 0, 0) - } - ObjectType::seL4_ARM_PageDirectoryObject => { - cap_t::new_page_directory_cap(asidInvalid, region_base, 0, 0) - } - ObjectType::seL4_ARM_PageTableObject => { - cap_t::new_page_table_cap(asidInvalid, region_base, 0, 0) - } - ObjectType::seL4_ARM_PageGlobalDirectoryObject => { - cap_t::new_page_global_directory_cap(asidInvalid, region_base, 0) - } ObjectType::seL4_ARM_LargePageObject => cap_t::new_frame_cap( device_mem, vm_rights_t::VMReadWrite as _, @@ -37,6 +28,18 @@ pub fn arch_create_object( asidInvalid, region_base, ), + ObjectType::seL4_ARM_HugePageObject => cap_t::new_frame_cap( + device_mem, + vm_rights_t::VMReadWrite as _, + 0, + ARM_Huge_Page, + asidInvalid, + region_base, + ), + ObjectType::seL4_ARM_VSpaceObject => cap_t::new_vspace_cap(asidInvalid, region_base, 0), + ObjectType::seL4_ARM_PageTableObject => { + cap_t::new_page_table_cap(asidInvalid, region_base, 0, 0) + } _ => { unimplemented!( "create object: {:?} region: {:#x} - {:#x}", diff --git a/kernel/src/syscall/invocation/arch/riscv64.rs b/kernel/src/syscall/invocation/arch/riscv64.rs index 7804abd..792e3b7 100644 --- a/kernel/src/syscall/invocation/arch/riscv64.rs +++ b/kernel/src/syscall/invocation/arch/riscv64.rs @@ -1,8 +1,10 @@ -use sel4_common::{arch::{vm_rights_t, ObjectType}, sel4_config::asidInvalid}; +use sel4_common::{ + arch::{vm_rights_t, ObjectType}, + sel4_config::asidInvalid, +}; use sel4_cspace::arch::cap_t; use sel4_vspace::pptr_t; - pub fn arch_create_object( obj_type: ObjectType, region_base: pptr_t, diff --git a/kernel/src/syscall/invocation/decode/arch/aarch64.rs b/kernel/src/syscall/invocation/decode/arch/aarch64.rs index 7e55388..79f329f 100644 --- a/kernel/src/syscall/invocation/decode/arch/aarch64.rs +++ b/kernel/src/syscall/invocation/decode/arch/aarch64.rs @@ -5,19 +5,17 @@ use crate::syscall::invocation::decode::current_syscall_error; use crate::syscall::ThreadState; use crate::syscall::{current_lookup_fault, get_syscall_arg, set_thread_state, unlikely}; use crate::syscall::{ensure_empty_slot, get_currenct_thread, lookup_slot_for_cnode_op}; -use crate::utils::clear_memory_pt; use log::debug; use sel4_common::arch::maskVMRights; use sel4_common::cap_rights::seL4_CapRights_t; use sel4_common::fault::lookup_fault_t; use sel4_common::sel4_config::{ - asidInvalid, asidLowBits, nASIDPools, seL4_AlignmentError, seL4_FailedLookup, seL4_RangeError, - ARM_Huge_Page, ARM_Large_Page, ARM_Small_Page, PAGE_BITS, PGD_INDEX_OFFSET, PUD_INDEX_OFFSET, + asidInvalid, asidLowBits, nASIDPools, seL4_AlignmentError, seL4_FailedLookup, seL4_PageBits, + seL4_RangeError, }; use sel4_common::sel4_config::{seL4_DeleteFirst, seL4_InvalidArgument}; use sel4_common::sel4_config::{ seL4_IllegalOperation, seL4_InvalidCapability, seL4_RevokeFirst, seL4_TruncatedMessage, - PD_INDEX_OFFSET, }; use sel4_common::utils::{ convert_ref_type_to_usize, convert_to_mut_type_ref, global_ops, pageBitsForSize, ptr_to_mut, @@ -33,13 +31,12 @@ use sel4_cspace::interface::{cap_t, cte_insert, cte_t, CapTag}; use sel4_vspace::{ asid_map_t, asid_pool_t, asid_t, clean_by_va_pou, doFlush, find_vspace_for_asid, - get_asid_pool_by_index, makeUser3rdLevel, make_user_1st_level, make_user_2nd_level, - pptr_to_paddr, set_asid_pool_by_index, vm_attributes_t, vptr_t, PDE, PGDE, PTE, PUDE, + get_asid_pool_by_index, pptr_to_paddr, pte_tag_t, set_asid_pool_by_index, vm_attributes_t, + vptr_t, PTE, }; use crate::syscall::invocation::invoke_mmu_op::{ - invoke_huge_page_map, invoke_large_page_map, invoke_page_get_address, invoke_page_table_unmap, - invoke_page_unmap, invoke_small_page_map, + invoke_page_get_address, invoke_page_map, invoke_page_table_unmap, invoke_page_unmap, }; use crate::{ config::maxIRQ, @@ -55,15 +52,7 @@ pub fn decode_mmu_invocation( buffer: &seL4_IPCBuffer, ) -> exception_t { match slot.cap.get_cap_type() { - CapTag::CapPageGlobalDirectoryCap => { - decode_vspace_root_invocation(label, length, slot, buffer) - } - CapTag::CapPageUpperDirectoryCap => { - decode_page_upper_directory_invocation(label, length, slot, buffer) - } - CapTag::CapPageDirectoryCap => { - decode_page_directory_invocation(label, length, slot, buffer) - } + CapTag::CapVspaceCap => decode_vspace_root_invocation(label, length, slot, buffer), CapTag::CapPageTableCap => decode_page_table_invocation(label, length, slot, buffer), CapTag::CapFrameCap => decode_frame_invocation(label, length, slot, call, buffer), CapTag::CapASIDControlCap => decode_asid_control(label, length, buffer), @@ -116,7 +105,7 @@ fn decode_page_table_invocation( return exception_t::EXCEPTION_SYSCALL_ERROR; } - let vaddr = get_syscall_arg(0, buffer) & !(MASK!(PD_INDEX_OFFSET)); + let vaddr = get_syscall_arg(0, buffer); let vspace_root_cap = convert_to_mut_type_ref::(global_ops!(current_extra_caps.excaprefs[0])); @@ -126,8 +115,8 @@ fn decode_page_table_invocation( return exception_t::EXCEPTION_SYSCALL_ERROR; } - let vspace_root = vspace_root_cap.get_pgd_base_ptr(); - let asid = vspace_root_cap.get_pgd_mapped_asid(); + let vspace_root = vspace_root_cap.get_vs_base_ptr(); + let asid = vspace_root_cap.get_vs_mapped_asid(); if unlikely(vaddr > USER_TOP) { global_ops!(current_syscall_error._type = seL4_InvalidArgument); @@ -148,31 +137,27 @@ fn decode_page_table_invocation( return exception_t::EXCEPTION_SYSCALL_ERROR; } - let pd_slot = PGDE::new_from_pte(vspace_root).lookup_pd_slot(vaddr); + let pd_slot = PTE(vspace_root).lookup_pt_slot(vaddr); - if pd_slot.status != exception_t::EXCEPTION_NONE { - global_ops!(current_syscall_error._type = seL4_FailedLookup); - global_ops!(current_syscall_error.failedLookupWasSource = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } if unlikely( - ptr_to_ref(pd_slot.pdSlot).get_present() || ptr_to_ref(pd_slot.pdSlot).is_larger_page(), + pd_slot.ptBitsLeft == seL4_PageBits + || (ptr_to_ref(pd_slot.ptSlot).get_type() != (pte_tag_t::pte_invalid) as usize), ) { global_ops!(current_syscall_error._type = seL4_DeleteFirst); return exception_t::EXCEPTION_SYSCALL_ERROR; } - - let pde = PDE::new_page(pptr_to_paddr(cte.cap.get_pt_base_ptr()), 0x3); + let pte = PTE::pte_new_table(pptr_to_paddr(cte.cap.get_pt_base_ptr())); cte.cap.set_pt_is_mapped(1); cte.cap.set_pt_mapped_asid(asid); - cte.cap.set_pt_mapped_address(vaddr); + cte.cap + .set_pt_mapped_address(vaddr & !(MASK!(pd_slot.ptBitsLeft))); get_currenct_thread().set_state(ThreadState::ThreadStateRestart); - *ptr_to_mut(pd_slot.pdSlot) = pde; + *ptr_to_mut(pd_slot.ptSlot) = pte; // log::warn!("Need to clean D-Cache using cleanByVA_PoU"); clean_by_va_pou( - convert_ref_type_to_usize(ptr_to_mut(pd_slot.pdSlot)), - pptr_to_paddr(convert_ref_type_to_usize(ptr_to_mut(pd_slot.pdSlot))), + convert_ref_type_to_usize(ptr_to_mut(pd_slot.ptSlot)), + pptr_to_paddr(convert_ref_type_to_usize(ptr_to_mut(pd_slot.ptSlot))), ); exception_t::EXCEPTION_NONE } @@ -296,11 +281,7 @@ fn decode_frame_invocation( } } -fn decode_asid_control( - label: MessageLabel, - length: usize, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_asid_control(label: MessageLabel, length: usize, buffer: &seL4_IPCBuffer) -> exception_t { if unlikely(label != MessageLabel::ARMASIDControlMakePool) { global_ops!(current_syscall_error._type = seL4_IllegalOperation); return exception_t::EXCEPTION_SYSCALL_ERROR; @@ -386,7 +367,7 @@ fn decode_asid_pool(label: MessageLabel, cte: &mut cte_t) -> exception_t { let vspace_cap_slot = global_ops!(current_extra_caps.excaprefs[0]); let vspace_cap = convert_to_mut_type_ref::(vspace_cap_slot); - if unlikely(!vspace_cap.is_vtable_root() || vspace_cap.get_pgd_is_mapped() == 1) { + if unlikely(!vspace_cap.is_vtable_root() || vspace_cap.get_vs_is_mapped() == 1) { log::debug!("is not a valid vtable root"); global_ops!(current_syscall_error._type = seL4_InvalidCapability); global_ops!(current_syscall_error.invalidArgumentNumber = 1); @@ -429,18 +410,14 @@ fn decode_asid_pool(label: MessageLabel, cte: &mut cte_t) -> exception_t { asid += i; get_currenct_thread().set_state(ThreadState::ThreadStateRestart); - vspace_cap.set_pgd_mapped_asid(asid); - vspace_cap.set_pgd_is_mapped(1); - let asid_map = asid_map_t::new_vspace(vspace_cap.get_pgd_base_ptr()); + vspace_cap.set_vs_mapped_asid(asid); + vspace_cap.set_vs_is_mapped(1); + let asid_map = asid_map_t::new_vspace(vspace_cap.get_vs_base_ptr()); pool[asid & MASK!(asidLowBits)] = asid_map; exception_t::EXCEPTION_NONE } -fn decode_frame_map( - length: usize, - frame_slot: &mut cte_t, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_frame_map(length: usize, frame_slot: &mut cte_t, buffer: &seL4_IPCBuffer) -> exception_t { if length < 3 || get_extra_cap_by_index(0).is_none() { debug!("ARMPageMap: Truncated message."); global_ops!(current_syscall_error._type = seL4_TruncatedMessage); @@ -460,8 +437,8 @@ fn decode_frame_map( global_ops!(current_syscall_error.invalidCapNumber = 1); return exception_t::EXCEPTION_SYSCALL_ERROR; } - let vspace_root = vspace_root_cap.get_pgd_base_ptr(); - let asid = vspace_root_cap.get_pgd_mapped_asid(); + let vspace_root = vspace_root_cap.get_vs_base_ptr(); + let asid = vspace_root_cap.get_vs_mapped_asid(); let find_ret = find_vspace_for_asid(asid); if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { global_ops!(current_syscall_error._type = seL4_FailedLookup); @@ -499,72 +476,88 @@ fn decode_frame_map( return exception_t::EXCEPTION_SYSCALL_ERROR; } } - // TODO: copy cap in the here. Not write slot when the address is not need to write. - // frame_slot.cap.set_frame_mapped_asid(asid); - // frame_slot.cap.set_frame_mapped_address(vaddr); - - let vspace_root = PGDE::new_from_pte(vspace_root); + let mut vspace_root_pte = PTE::new_from_pte(vspace_root); let base = pptr_to_paddr(frame_slot.cap.get_frame_base_ptr()); - match frame_size { - ARM_Small_Page => { - let lu_ret = vspace_root.lookup_pt_slot(vaddr); - if lu_ret.status != exception_t::EXCEPTION_NONE { - unsafe { - current_syscall_error._type = seL4_FailedLookup; - current_syscall_error.failedLookupWasSource = 0; - } - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); - let ptSlot = convert_to_mut_type_ref::(lu_ret.ptSlot as usize); - invoke_small_page_map( - vaddr, - asid, - frame_slot, - makeUser3rdLevel(base, vm_rights, attr), - ptSlot, - ) - } - ARM_Large_Page => { - let lu_ret = vspace_root.lookup_pd_slot(vaddr); - if lu_ret.status != exception_t::EXCEPTION_NONE { - unsafe { - current_syscall_error._type = seL4_FailedLookup; - current_syscall_error.failedLookupWasSource = 0; - } - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); - let pdSlot = convert_to_mut_type_ref::(lu_ret.pdSlot as usize); - invoke_large_page_map( - vaddr, - asid, - frame_slot, - make_user_2nd_level(base, vm_rights, attr), - pdSlot, - ) - } - ARM_Huge_Page => { - let lu_ret = vspace_root.lookup_pud_slot(vaddr); - if lu_ret.status != exception_t::EXCEPTION_NONE { - unsafe { - current_syscall_error._type = seL4_FailedLookup; - current_syscall_error.failedLookupWasSource = 0; - } - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); - let pudSlot = convert_to_mut_type_ref::(lu_ret.pudSlot as usize); - invoke_huge_page_map( - vaddr, - asid, - frame_slot, - make_user_1st_level(base, vm_rights, attr), - pudSlot, - ) + let lu_ret = vspace_root_pte.lookup_pt_slot(vaddr); + if unlikely(lu_ret.ptBitsLeft != pageBitsForSize(frame_size)) { + unsafe { + current_lookup_fault = lookup_fault_t::new_missing_cap(lu_ret.ptBitsLeft); + current_syscall_error._type = seL4_FailedLookup; + current_syscall_error.failedLookupWasSource = 0; + return exception_t::EXCEPTION_SYSCALL_ERROR; } - _ => exception_t::EXCEPTION_SYSCALL_ERROR, } + let pt_slot = convert_to_mut_type_ref::(lu_ret.ptSlot as usize); + set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); + frame_slot.cap.set_frame_mapped_asid(asid); + frame_slot.cap.set_frame_mapped_address(vaddr); + return invoke_page_map( + asid, + frame_slot.cap.clone(), + frame_slot, + PTE::make_user_pte(base, vm_rights, attr, frame_size), + pt_slot, + ); + // match frame_size { + // ARM_Small_Page => { + // let lu_ret = vspace_root.lookup_pt_slot(vaddr); + // if lu_ret.status != exception_t::EXCEPTION_NONE { + // unsafe { + // current_syscall_error._type = seL4_FailedLookup; + // current_syscall_error.failedLookupWasSource = 0; + // } + // return exception_t::EXCEPTION_SYSCALL_ERROR; + // } + // set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); + // let ptSlot = convert_to_mut_type_ref::(lu_ret.ptSlot as usize); + // invoke_small_page_map( + // vaddr, + // asid, + // frame_slot, + // makeUser3rdLevel(base, vm_rights, attr), + // ptSlot, + // ) + // } + // ARM_Large_Page => { + // let lu_ret = vspace_root.lookup_pd_slot(vaddr); + // if lu_ret.status != exception_t::EXCEPTION_NONE { + // unsafe { + // current_syscall_error._type = seL4_FailedLookup; + // current_syscall_error.failedLookupWasSource = 0; + // } + // return exception_t::EXCEPTION_SYSCALL_ERROR; + // } + // set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); + // let pdSlot = convert_to_mut_type_ref::(lu_ret.pdSlot as usize); + // invoke_large_page_map( + // vaddr, + // asid, + // frame_slot, + // make_user_2nd_level(base, vm_rights, attr), + // pdSlot, + // ) + // } + // ARM_Huge_Page => { + // let lu_ret = vspace_root.lookup_pud_slot(vaddr); + // if lu_ret.status != exception_t::EXCEPTION_NONE { + // unsafe { + // current_syscall_error._type = seL4_FailedLookup; + // current_syscall_error.failedLookupWasSource = 0; + // } + // return exception_t::EXCEPTION_SYSCALL_ERROR; + // } + // set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart); + // let pudSlot = convert_to_mut_type_ref::(lu_ret.pudSlot as usize); + // invoke_huge_page_map( + // vaddr, + // asid, + // frame_slot, + // make_user_1st_level(base, vm_rights, attr), + // pudSlot, + // ) + // } + // _ => exception_t::EXCEPTION_SYSCALL_ERROR, + // } // if length < 3 || get_extra_cap_by_index(0).is_none() { // debug!("ARMPageMap: Truncated message."); // unsafe { @@ -688,7 +681,7 @@ fn decode_frame_map( #[allow(unused)] fn decode_page_table_unmap(pt_cte: &mut cte_t) -> exception_t { if !pt_cte.is_final_cap() { - debug!("RISCVPageTableUnmap: cannot unmap if more than once cap exists"); + debug!("PageTableUnmap: cannot unmap if more than once cap exists"); global_ops!(current_syscall_error._type = seL4_RevokeFirst); return exception_t::EXCEPTION_SYSCALL_ERROR; } @@ -699,32 +692,32 @@ fn decode_page_table_unmap(pt_cte: &mut cte_t) -> exception_t { return invoke_page_table_unmap(cap); } -fn decode_upper_page_directory_unmap(ctSlot: &mut cte_t) -> exception_t { - let cap = &mut ctSlot.cap; - if cap.get_pud_is_mapped() != 0 { - let pud = &mut PUDE(cap.get_pud_base_ptr()); - // TODO:: llh implement unmap_page_upper_directory as PUDE's method , but below two lines code both will cause sel4test end panic - pud.unmap_page_upper_directory(cap.get_pud_mapped_asid(), cap.get_pud_mapped_address()); - // unmap_page_upper_directory(cap.get_pud_mapped_asid(), cap.get_pud_mapped_address(), pud); - clear_memory_pt(pud.self_addr() as *mut u8, cap.get_cap_size_bits()); - } - cap.set_pud_is_mapped(0); - exception_t::EXCEPTION_NONE -} - -fn decode_page_directory_unmap(ctSlot: &mut cte_t) -> exception_t { - let cap = &mut ctSlot.cap; - if cap.get_pd_is_mapped() != 0 { - let pd = &mut PDE(cap.get_pud_base_ptr()); - // clear_memory(ptr, bits); - // TODO:: llh implement unmap_page_upper_directory as PUDE's method , but below two lines code both will cause sel4test end panic - pd.unmap_page_directory(cap.get_pd_mapped_asid(), cap.get_pd_mapped_address()); - // unmap_page_directory(cap.get_pd_mapped_asid(), cap.get_pd_mapped_address(), pd); - clear_memory_pt(pd.self_addr() as *mut u8, cap.get_cap_size_bits()); - } - cap.set_pud_is_mapped(0); - exception_t::EXCEPTION_NONE -} +// fn decode_upper_page_directory_unmap(ctSlot: &mut cte_t) -> exception_t { +// let cap = &mut ctSlot.cap; +// if cap.get_pud_is_mapped() != 0 { +// let pud = &mut PUDE(cap.get_pud_base_ptr()); +// // TODO:: llh implement unmap_page_upper_directory as PUDE's method , but below two lines code both will cause sel4test end panic +// pud.unmap_page_upper_directory(cap.get_pud_mapped_asid(), cap.get_pud_mapped_address()); +// // unmap_page_upper_directory(cap.get_pud_mapped_asid(), cap.get_pud_mapped_address(), pud); +// clear_memory_pt(pud.self_addr() as *mut u8, cap.get_cap_size_bits()); +// } +// cap.set_pud_is_mapped(0); +// exception_t::EXCEPTION_NONE +// } + +// fn decode_page_directory_unmap(ctSlot: &mut cte_t) -> exception_t { +// let cap = &mut ctSlot.cap; +// if cap.get_pd_is_mapped() != 0 { +// let pd = &mut PDE(cap.get_pud_base_ptr()); +// // clear_memory(ptr, bits); +// // TODO:: llh implement unmap_page_upper_directory as PUDE's method , but below two lines code both will cause sel4test end panic +// pd.unmap_page_directory(cap.get_pd_mapped_asid(), cap.get_pd_mapped_address()); +// // unmap_page_directory(cap.get_pd_mapped_asid(), cap.get_pd_mapped_address(), pd); +// clear_memory_pt(pd.self_addr() as *mut u8, cap.get_cap_size_bits()); +// } +// cap.set_pud_is_mapped(0); +// exception_t::EXCEPTION_NONE +// } fn decode_vspace_root_invocation( label: MessageLabel, @@ -766,7 +759,7 @@ fn decode_vspace_root_invocation( }; return exception_t::EXCEPTION_SYSCALL_ERROR; } - let vspace_root = PGDE::new_from_pte(cte.cap.get_pgd_base_ptr()); + let vspace_root = cte.cap.get_vs_base_ptr() as *mut PTE; let asid = cte.cap.get_asid_base(); let find_ret = find_vspace_for_asid(asid); if find_ret.status != exception_t::EXCEPTION_NONE { @@ -777,7 +770,7 @@ fn decode_vspace_root_invocation( return exception_t::EXCEPTION_SYSCALL_ERROR; } } - if find_ret.vspace_root.unwrap() as usize != vspace_root.get_ptr() { + if find_ret.vspace_root.unwrap() as usize != ptr_to_ref(vspace_root).get_ptr() { debug!("VSpaceRoot Flush: Invalid VSpace Cap"); unsafe { current_syscall_error._type = seL4_InvalidCapability; @@ -785,24 +778,25 @@ fn decode_vspace_root_invocation( } return exception_t::EXCEPTION_SYSCALL_ERROR; } - let resolve_ret = vspace_root.lookup_frame(start); - if !resolve_ret.valid { + let resolve_ret = ptr_to_mut(vspace_root).lookup_pt_slot(start); + let pte = resolve_ret.ptSlot; + if ptr_to_ref(pte).get_type() != (pte_tag_t::pte_page) as usize { get_currenct_thread().set_state(ThreadState::ThreadStateRestart); return exception_t::EXCEPTION_NONE; } - let page_base_start = start & !MASK!(pageBitsForSize(resolve_ret.frameSize)); - let page_base_end = (end - 1) & !MASK!(pageBitsForSize(resolve_ret.frameSize)); + let page_base_start = start & !MASK!(pageBitsForSize(resolve_ret.ptBitsLeft)); + let page_base_end = (end - 1) & !MASK!(pageBitsForSize(resolve_ret.ptBitsLeft)); if page_base_start != page_base_end { unsafe { current_syscall_error._type = seL4_RangeError; current_syscall_error.rangeErrorMin = start; current_syscall_error.rangeErrorMax = - page_base_start + MASK!(pageBitsForSize(resolve_ret.frameSize)); + page_base_start + MASK!(pageBitsForSize(resolve_ret.ptBitsLeft)); } return exception_t::EXCEPTION_SYSCALL_ERROR; } - let pstart = - resolve_ret.frameBase + start & MASK!(pageBitsForSize(resolve_ret.frameSize)); + let pstart = ptr_to_ref(pte).get_page_base_address() + start + & MASK!(pageBitsForSize(resolve_ret.ptBitsLeft)); get_currenct_thread().set_state(ThreadState::ThreadStateRestart); return decode_vspace_flush_invocation( label, @@ -838,206 +832,206 @@ fn decode_vspace_flush_invocation( exception_t::EXCEPTION_NONE } -fn decode_page_upper_directory_invocation( - label: MessageLabel, - length: usize, - cte: &mut cte_t, - buffer: &seL4_IPCBuffer, -) -> exception_t { - /* - lookupPGDSlot_ret_t pgdSlot; - findVSpaceForASID_ret_t find_ret; - if (invLabel == ARMPageUpperDirectoryUnmap) { - if (unlikely(!isFinalCapability(cte))) { - current_syscall_error.type = seL4_RevokeFirst; - return EXCEPTION_SYSCALL_ERROR; - } - setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); - return performUpperPageDirectoryInvocationUnmap(cap, cte); - } - */ - if label == MessageLabel::ARMPageUpperDirectoryUnmap { - // log::warn!("Need to check is FinalCapability here"); - if unlikely(!cte.is_final_cap()) { - global_ops!(current_syscall_error._type = seL4_RevokeFirst); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - get_currenct_thread().set_state(ThreadState::ThreadStateRestart); - // unimplemented!("performUpperPageDirectoryInvocationUnmap"); - return decode_upper_page_directory_unmap(cte); - } - - // Return SYSCALL_ERROR if message is not ARMPageUpperDirectoryUnmap - if unlikely(label != MessageLabel::ARMPageUpperDirectoryMap) { - global_ops!(current_syscall_error._type = seL4_IllegalOperation); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - if unlikely(length < 2 || unsafe { current_extra_caps.excaprefs[0] == 0 }) { - global_ops!(current_syscall_error._type = seL4_TruncatedMessage); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - if unlikely(cte.cap.get_pud_is_mapped() == 1) { - global_ops!(current_syscall_error._type = seL4_InvalidCapability); - global_ops!(current_syscall_error.invalidCapNumber = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - let vaddr = get_syscall_arg(0, buffer) & (!MASK!(PGD_INDEX_OFFSET)); - let pgd_cap = convert_to_mut_type_ref::(global_ops!(current_extra_caps.excaprefs[0])); - - if unlikely(!pgd_cap.is_valid_native_root()) { - global_ops!(current_syscall_error._type = seL4_InvalidCapability); - global_ops!(current_syscall_error.invalidCapNumber = 1); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - let pgd = pgd_cap.get_pgd_base_ptr(); - let asid = pgd_cap.get_pgd_mapped_asid(); - - if unlikely(vaddr > USER_TOP) { - global_ops!(current_syscall_error._type = seL4_InvalidArgument); - global_ops!(current_syscall_error.failedLookupWasSource = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - let find_ret = find_vspace_for_asid(asid); - - if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { - global_ops!(current_syscall_error._type = seL4_FailedLookup); - global_ops!(current_syscall_error.failedLookupWasSource = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - // vspace_root is Some(_) when Exception is NONE - if unlikely(find_ret.vspace_root.unwrap() as usize != pgd) { - global_ops!(current_syscall_error._type = seL4_InvalidCapability); - global_ops!(current_syscall_error.invalidCapNumber = 1); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - // Ensure that pgd is aligned 4K. - assert!(pgd & MASK!(PAGE_BITS) == 0); - - let pgd_slot = PGDE::new_from_pte(pgd).lookup_pgd_slot(vaddr); - - if unlikely(ptr_to_ref(pgd_slot.pgdSlot).get_present()) { - global_ops!(current_syscall_error._type = seL4_DeleteFirst); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - // TODO: make 0x3 in a pagetable-specific position - let pgde = PGDE::new_page(pptr_to_paddr(cte.cap.get_pud_base_ptr()), 0x3); - cte.cap.set_pud_is_mapped(1); - cte.cap.set_pud_mapped_asid(asid); - cte.cap.set_pud_mapped_address(vaddr); - - get_currenct_thread().set_state(ThreadState::ThreadStateRestart); - *ptr_to_mut(pgd_slot.pgdSlot) = pgde; - clean_by_va_pou( - convert_ref_type_to_usize(ptr_to_mut(pgd_slot.pgdSlot)), - pptr_to_paddr(convert_ref_type_to_usize(ptr_to_mut(pgd_slot.pgdSlot))), - ); - exception_t::EXCEPTION_NONE -} -fn decode_page_directory_invocation( - label: MessageLabel, - length: usize, - cte: &mut cte_t, - buffer: &seL4_IPCBuffer, -) -> exception_t { - /* - if (invLabel == ARMPageDirectoryUnmap) { - if (unlikely(!isFinalCapability(cte))) { - current_syscall_error.type = seL4_RevokeFirst; - return EXCEPTION_SYSCALL_ERROR; - } - setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); - return performPageDirectoryInvocationUnmap(cap, cte); - } - */ - // Call performPageDirectoryInvocationUnmap if message is unmap - if label == MessageLabel::ARMPageDirectoryUnmap { - // log::warn!("Need to check is FinalCapability here"); - if unlikely(!cte.is_final_cap()) { - global_ops!(current_syscall_error._type = seL4_RevokeFirst); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - get_currenct_thread().set_state(ThreadState::ThreadStateRestart); - // unimplemented!("performPageDirectoryInvocationUnmap"); - return decode_page_directory_unmap(cte); - } - - // Return SYSCALL_ERROR if message is not ARMPageDirectoryUnmap - if unlikely(label != MessageLabel::ARMPageDirectoryMap) { - global_ops!(current_syscall_error._type = seL4_IllegalOperation); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - if unlikely(length < 2 || global_ops!(current_extra_caps.excaprefs[0] == 0)) { - global_ops!(current_syscall_error._type = seL4_TruncatedMessage); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - if unlikely(cte.cap.get_pd_is_mapped() == 1) { - global_ops!(current_syscall_error._type = seL4_InvalidCapability); - global_ops!(current_syscall_error.invalidCapNumber = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - let vaddr = get_syscall_arg(0, buffer) & (!MASK!(PUD_INDEX_OFFSET)); - let vspace_root_cap = - convert_to_mut_type_ref::(global_ops!(current_extra_caps.excaprefs[0])); - - if unlikely(!vspace_root_cap.is_valid_native_root()) { - global_ops!(current_syscall_error._type = seL4_InvalidCapability); - global_ops!(current_syscall_error.invalidCapNumber = 1); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - let vspace_root = vspace_root_cap.get_pgd_base_ptr(); - let asid = vspace_root_cap.get_pgd_mapped_asid(); - - if unlikely(vaddr > USER_TOP) { - global_ops!(current_syscall_error._type = seL4_InvalidArgument); - global_ops!(current_syscall_error.failedLookupWasSource = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - let find_ret = find_vspace_for_asid(asid); - - if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { - global_ops!(current_syscall_error._type = seL4_FailedLookup); - global_ops!(current_syscall_error.failedLookupWasSource = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - if unlikely(find_ret.vspace_root.unwrap() as usize != vspace_root) { - global_ops!(current_syscall_error._type = seL4_InvalidCapability); - global_ops!(current_syscall_error.invalidCapNumber = 1); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - - let pud_slot = PGDE::new_from_pte(vspace_root).lookup_pud_slot(vaddr); - - if pud_slot.status != exception_t::EXCEPTION_NONE { - global_ops!(current_syscall_error._type = seL4_FailedLookup); - global_ops!(current_syscall_error.failedLookupWasSource = 0); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - if unlikely( - ptr_to_ref(pud_slot.pudSlot).get_present() || ptr_to_ref(pud_slot.pudSlot).is_1g_page(), - ) { - global_ops!(current_syscall_error._type = seL4_DeleteFirst); - return exception_t::EXCEPTION_SYSCALL_ERROR; - } - // TODO: make 0x3 in a pagetable-specific position - let pude = PUDE::new_page(pptr_to_paddr(cte.cap.get_pd_base_ptr()), 0x3); - cte.cap.set_pd_is_mapped(1); - cte.cap.set_pd_mapped_asid(asid); - cte.cap.set_pd_mapped_address(vaddr); - get_currenct_thread().set_state(ThreadState::ThreadStateRestart); - *ptr_to_mut(pud_slot.pudSlot) = pude; - // log::warn!("Need to clean D-Cache using cleanByVA_PoU"); - clean_by_va_pou( - convert_ref_type_to_usize(ptr_to_mut(pud_slot.pudSlot)), - pptr_to_paddr(convert_ref_type_to_usize(ptr_to_mut(pud_slot.pudSlot))), - ); - exception_t::EXCEPTION_NONE -} +// fn decode_page_upper_directory_invocation( +// label: MessageLabel, +// length: usize, +// cte: &mut cte_t, +// buffer: &seL4_IPCBuffer, +// ) -> exception_t { +// /* +// lookupPGDSlot_ret_t pgdSlot; +// findVSpaceForASID_ret_t find_ret; +// if (invLabel == ARMPageUpperDirectoryUnmap) { +// if (unlikely(!isFinalCapability(cte))) { +// current_syscall_error.type = seL4_RevokeFirst; +// return EXCEPTION_SYSCALL_ERROR; +// } +// setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); +// return performUpperPageDirectoryInvocationUnmap(cap, cte); +// } +// */ +// if label == MessageLabel::ARMPageUpperDirectoryUnmap { +// // log::warn!("Need to check is FinalCapability here"); +// if unlikely(!cte.is_final_cap()) { +// global_ops!(current_syscall_error._type = seL4_RevokeFirst); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// get_currenct_thread().set_state(ThreadState::ThreadStateRestart); +// // unimplemented!("performUpperPageDirectoryInvocationUnmap"); +// return decode_upper_page_directory_unmap(cte); +// } + +// // Return SYSCALL_ERROR if message is not ARMPageUpperDirectoryUnmap +// if unlikely(label != MessageLabel::ARMPageUpperDirectoryMap) { +// global_ops!(current_syscall_error._type = seL4_IllegalOperation); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// if unlikely(length < 2 || unsafe { current_extra_caps.excaprefs[0] == 0 }) { +// global_ops!(current_syscall_error._type = seL4_TruncatedMessage); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// if unlikely(cte.cap.get_pud_is_mapped() == 1) { +// global_ops!(current_syscall_error._type = seL4_InvalidCapability); +// global_ops!(current_syscall_error.invalidCapNumber = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// let vaddr = get_syscall_arg(0, buffer) & (!MASK!(PGD_INDEX_OFFSET)); +// let pgd_cap = convert_to_mut_type_ref::(global_ops!(current_extra_caps.excaprefs[0])); + +// if unlikely(!pgd_cap.is_valid_native_root()) { +// global_ops!(current_syscall_error._type = seL4_InvalidCapability); +// global_ops!(current_syscall_error.invalidCapNumber = 1); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// let pgd = pgd_cap.get_pgd_base_ptr(); +// let asid = pgd_cap.get_pgd_mapped_asid(); + +// if unlikely(vaddr > USER_TOP) { +// global_ops!(current_syscall_error._type = seL4_InvalidArgument); +// global_ops!(current_syscall_error.failedLookupWasSource = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// let find_ret = find_vspace_for_asid(asid); + +// if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { +// global_ops!(current_syscall_error._type = seL4_FailedLookup); +// global_ops!(current_syscall_error.failedLookupWasSource = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// // vspace_root is Some(_) when Exception is NONE +// if unlikely(find_ret.vspace_root.unwrap() as usize != pgd) { +// global_ops!(current_syscall_error._type = seL4_InvalidCapability); +// global_ops!(current_syscall_error.invalidCapNumber = 1); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// // Ensure that pgd is aligned 4K. +// assert!(pgd & MASK!(PAGE_BITS) == 0); + +// let pgd_slot = PGDE::new_from_pte(pgd).lookup_pgd_slot(vaddr); + +// if unlikely(ptr_to_ref(pgd_slot.pgdSlot).get_present()) { +// global_ops!(current_syscall_error._type = seL4_DeleteFirst); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// // TODO: make 0x3 in a pagetable-specific position +// let pgde = PGDE::new_page(pptr_to_paddr(cte.cap.get_pud_base_ptr()), 0x3); +// cte.cap.set_pud_is_mapped(1); +// cte.cap.set_pud_mapped_asid(asid); +// cte.cap.set_pud_mapped_address(vaddr); + +// get_currenct_thread().set_state(ThreadState::ThreadStateRestart); +// *ptr_to_mut(pgd_slot.pgdSlot) = pgde; +// clean_by_va_pou( +// convert_ref_type_to_usize(ptr_to_mut(pgd_slot.pgdSlot)), +// pptr_to_paddr(convert_ref_type_to_usize(ptr_to_mut(pgd_slot.pgdSlot))), +// ); +// exception_t::EXCEPTION_NONE +// } +// fn decode_page_directory_invocation( +// label: MessageLabel, +// length: usize, +// cte: &mut cte_t, +// buffer: &seL4_IPCBuffer, +// ) -> exception_t { +// /* +// if (invLabel == ARMPageDirectoryUnmap) { +// if (unlikely(!isFinalCapability(cte))) { +// current_syscall_error.type = seL4_RevokeFirst; +// return EXCEPTION_SYSCALL_ERROR; +// } +// setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart); +// return performPageDirectoryInvocationUnmap(cap, cte); +// } +// */ +// // Call performPageDirectoryInvocationUnmap if message is unmap +// if label == MessageLabel::ARMPageDirectoryUnmap { +// // log::warn!("Need to check is FinalCapability here"); +// if unlikely(!cte.is_final_cap()) { +// global_ops!(current_syscall_error._type = seL4_RevokeFirst); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// get_currenct_thread().set_state(ThreadState::ThreadStateRestart); +// // unimplemented!("performPageDirectoryInvocationUnmap"); +// return decode_page_directory_unmap(cte); +// } + +// // Return SYSCALL_ERROR if message is not ARMPageDirectoryUnmap +// if unlikely(label != MessageLabel::ARMPageDirectoryMap) { +// global_ops!(current_syscall_error._type = seL4_IllegalOperation); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// if unlikely(length < 2 || global_ops!(current_extra_caps.excaprefs[0] == 0)) { +// global_ops!(current_syscall_error._type = seL4_TruncatedMessage); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// if unlikely(cte.cap.get_pd_is_mapped() == 1) { +// global_ops!(current_syscall_error._type = seL4_InvalidCapability); +// global_ops!(current_syscall_error.invalidCapNumber = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// let vaddr = get_syscall_arg(0, buffer) & (!MASK!(PUD_INDEX_OFFSET)); +// let vspace_root_cap = +// convert_to_mut_type_ref::(global_ops!(current_extra_caps.excaprefs[0])); + +// if unlikely(!vspace_root_cap.is_valid_native_root()) { +// global_ops!(current_syscall_error._type = seL4_InvalidCapability); +// global_ops!(current_syscall_error.invalidCapNumber = 1); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// let vspace_root = vspace_root_cap.get_pgd_base_ptr(); +// let asid = vspace_root_cap.get_pgd_mapped_asid(); + +// if unlikely(vaddr > USER_TOP) { +// global_ops!(current_syscall_error._type = seL4_InvalidArgument); +// global_ops!(current_syscall_error.failedLookupWasSource = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// let find_ret = find_vspace_for_asid(asid); + +// if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { +// global_ops!(current_syscall_error._type = seL4_FailedLookup); +// global_ops!(current_syscall_error.failedLookupWasSource = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// if unlikely(find_ret.vspace_root.unwrap() as usize != vspace_root) { +// global_ops!(current_syscall_error._type = seL4_InvalidCapability); +// global_ops!(current_syscall_error.invalidCapNumber = 1); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } + +// let pud_slot = PGDE::new_from_pte(vspace_root).lookup_pud_slot(vaddr); + +// if pud_slot.status != exception_t::EXCEPTION_NONE { +// global_ops!(current_syscall_error._type = seL4_FailedLookup); +// global_ops!(current_syscall_error.failedLookupWasSource = 0); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// if unlikely( +// ptr_to_ref(pud_slot.pudSlot).get_present() || ptr_to_ref(pud_slot.pudSlot).is_1g_page(), +// ) { +// global_ops!(current_syscall_error._type = seL4_DeleteFirst); +// return exception_t::EXCEPTION_SYSCALL_ERROR; +// } +// // TODO: make 0x3 in a pagetable-specific position +// let pude = PUDE::new_page(pptr_to_paddr(cte.cap.get_pd_base_ptr()), 0x3); +// cte.cap.set_pd_is_mapped(1); +// cte.cap.set_pd_mapped_asid(asid); +// cte.cap.set_pd_mapped_address(vaddr); +// get_currenct_thread().set_state(ThreadState::ThreadStateRestart); +// *ptr_to_mut(pud_slot.pudSlot) = pude; +// // log::warn!("Need to clean D-Cache using cleanByVA_PoU"); +// clean_by_va_pou( +// convert_ref_type_to_usize(ptr_to_mut(pud_slot.pudSlot)), +// pptr_to_paddr(convert_ref_type_to_usize(ptr_to_mut(pud_slot.pudSlot))), +// ); +// exception_t::EXCEPTION_NONE +// } pub(crate) fn check_irq(irq: usize) -> exception_t { if irq > maxIRQ { diff --git a/kernel/src/syscall/invocation/decode/arch/riscv64.rs b/kernel/src/syscall/invocation/decode/arch/riscv64.rs index 2624159..cfa6b57 100644 --- a/kernel/src/syscall/invocation/decode/arch/riscv64.rs +++ b/kernel/src/syscall/invocation/decode/arch/riscv64.rs @@ -108,11 +108,7 @@ fn decode_frame_invocation( } } -fn decode_asid_control( - label: MessageLabel, - length: usize, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_asid_control(label: MessageLabel, length: usize, buffer: &seL4_IPCBuffer) -> exception_t { if label != MessageLabel::RISCVASIDControlMakePool { unsafe { current_syscall_error._type = seL4_IllegalOperation; @@ -249,11 +245,7 @@ fn decode_asid_pool(label: MessageLabel, cte: &mut cte_t) -> exception_t { } } -fn decode_frame_map( - length: usize, - frame_slot: &mut cte_t, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_frame_map(length: usize, frame_slot: &mut cte_t, buffer: &seL4_IPCBuffer) -> exception_t { if length < 3 || get_extra_cap_by_index(0).is_none() { debug!("RISCVPageMap: Truncated message."); unsafe { diff --git a/kernel/src/syscall/invocation/decode/decode_tcb_invocation.rs b/kernel/src/syscall/invocation/decode/decode_tcb_invocation.rs index 0f0a24d..8d2fba9 100644 --- a/kernel/src/syscall/invocation/decode/decode_tcb_invocation.rs +++ b/kernel/src/syscall/invocation/decode/decode_tcb_invocation.rs @@ -157,11 +157,7 @@ fn decode_read_registers( invoke_tcb_read_registers(thread, flags & BIT!(ReadRegisters_suspend), n, 0, call) } -fn decode_write_registers( - cap: &cap_t, - length: usize, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_write_registers(cap: &cap_t, length: usize, buffer: &seL4_IPCBuffer) -> exception_t { if length < 2 { unsafe { debug!("TCB CopyRegisters: Truncated message."); @@ -196,11 +192,7 @@ fn decode_write_registers( invoke_tcb_write_registers(thread, flags & BIT!(0), w, 0, buffer) } -fn decode_copy_registers( - cap: &cap_t, - _length: usize, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_copy_registers(cap: &cap_t, _length: usize, buffer: &seL4_IPCBuffer) -> exception_t { let flags = get_syscall_arg(0, buffer); let source_cap = get_extra_cap_by_index(0).unwrap().cap; @@ -369,11 +361,7 @@ fn decode_set_priority(cap: &cap_t, length: usize, buffer: &seL4_IPCBuffer) -> e ) } -fn decode_set_mc_priority( - cap: &cap_t, - length: usize, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_set_mc_priority(cap: &cap_t, length: usize, buffer: &seL4_IPCBuffer) -> exception_t { if length < 1 || get_extra_cap_by_index(0).is_none() { debug!("TCB SetMCPPriority: Truncated message."); unsafe { @@ -405,11 +393,7 @@ fn decode_set_mc_priority( invoke_tcb_set_mcp(convert_to_mut_type_ref::(cap.get_tcb_ptr()), new_mcp) } -fn decode_set_sched_params( - cap: &cap_t, - length: usize, - buffer: &seL4_IPCBuffer, -) -> exception_t { +fn decode_set_sched_params(cap: &cap_t, length: usize, buffer: &seL4_IPCBuffer) -> exception_t { if length < 2 || get_extra_cap_by_index(0).is_some() { debug!("TCB SetSchedParams: Truncated message."); unsafe { diff --git a/kernel/src/syscall/invocation/invoke_mmu_op.rs b/kernel/src/syscall/invocation/invoke_mmu_op.rs index 18a4a56..428e157 100644 --- a/kernel/src/syscall/invocation/invoke_mmu_op.rs +++ b/kernel/src/syscall/invocation/invoke_mmu_op.rs @@ -1,8 +1,11 @@ #[cfg(target_arch = "aarch64")] -use core::arch::asm; +use core::intrinsics::unlikely; use sel4_common::arch::ArchReg; #[cfg(target_arch = "aarch64")] use sel4_common::BIT; + +#[cfg(target_arch = "aarch64")] +use sel4_common::utils::convert_ref_type_to_usize; #[cfg(target_arch = "riscv64")] use sel4_common::{ arch::maskVMRights, @@ -24,7 +27,7 @@ use sel4_vspace::{ PTEFlags, }; #[cfg(target_arch = "aarch64")] -use sel4_vspace::{invalidate_tlb_by_asid_va, PDE, PUDE}; +use sel4_vspace::{clean_by_va_pou, invalidate_tlb_by_asid_va, pte_tag_t}; use sel4_vspace::{pptr_to_paddr, unmapPage, unmap_page_table, PTE}; use crate::{kernel::boot::current_lookup_fault, utils::clear_memory}; @@ -54,29 +57,29 @@ pub fn invoke_page_table_map( sfence(); exception_t::EXCEPTION_NONE } -#[allow(unused)] -#[cfg(target_arch = "aarch64")] -pub fn invoke_page_table_map( - pt_cap: &mut cap_t, - pd_slot: &mut PDE, - asid: usize, - vaddr: usize, -) -> exception_t { - let paddr = pptr_to_paddr(pt_cap.get_pt_base_ptr()); - let pde = PDE::new_small(paddr >> seL4_PageBits); - *pd_slot = pde; - pt_cap.set_pt_is_mapped(1); - pt_cap.set_pt_mapped_asid(asid); - pt_cap.set_pt_mapped_address(vaddr); - unsafe { - asm!( - "dc cvau, {}", - "dmb sy", - in(reg) pd_slot, - ); - } - exception_t::EXCEPTION_NONE -} +// #[allow(unused)] +// #[cfg(target_arch = "aarch64")] +// pub fn invoke_page_table_map( +// pt_cap: &mut cap_t, +// pd_slot: &mut PDE, +// asid: usize, +// vaddr: usize, +// ) -> exception_t { +// let paddr = pptr_to_paddr(pt_cap.get_pt_base_ptr()); +// let pde = PDE::new_small(paddr >> seL4_PageBits); +// *pd_slot = pde; +// pt_cap.set_pt_is_mapped(1); +// pt_cap.set_pt_mapped_asid(asid); +// pt_cap.set_pt_mapped_address(vaddr); +// unsafe { +// asm!( +// "dc cvau, {}", +// "dmb sy", +// in(reg) pd_slot, +// ); +// } +// exception_t::EXCEPTION_NONE +// } pub fn invoke_page_get_address(vbase_ptr: usize, call: bool) -> exception_t { let thread = get_currenct_thread(); @@ -108,7 +111,7 @@ pub fn invoke_page_unmap(frame_slot: &mut cte_t) -> exception_t { } } frame_slot.cap.set_frame_mapped_address(0); - frame_slot.cap.set_pt_mapped_asid(asidInvalid); + frame_slot.cap.set_frame_mapped_asid(asidInvalid); exception_t::EXCEPTION_NONE } @@ -138,82 +141,104 @@ pub fn invoke_page_map( exception_t::EXCEPTION_NONE } #[cfg(target_arch = "aarch64")] -pub fn invoke_huge_page_map( - vaddr: usize, +pub fn invoke_page_map( asid: usize, + cap: cap_t, frame_slot: &mut cte_t, - pude: PUDE, - pudSlot: &mut PUDE, + pte: PTE, + pt_slot: &mut PTE, ) -> exception_t { - frame_slot.cap.set_frame_mapped_address(vaddr); - frame_slot.cap.set_frame_mapped_asid(asid); - *pudSlot = pude; - unsafe { - asm!( - "dc cvau, {}", - "dmb sy", - in(reg) pudSlot, - ); - } - let tlbflush_required = pudSlot.get_pude_type() == 1; - if tlbflush_required { - assert!(asid < BIT!(16)); - invalidate_tlb_by_asid_va(asid, vaddr); - } - exception_t::EXCEPTION_NONE -} + let tlbflush_required: bool = pt_slot.get_type() != (pte_tag_t::pte_invalid) as usize; + // frame_slot.cap = cap; + pt_slot.update(pte); -#[cfg(target_arch = "aarch64")] -pub fn invoke_large_page_map( - vaddr: usize, - asid: usize, - frame_slot: &mut cte_t, - pde: PDE, - pdSlot: &mut PDE, -) -> exception_t { - frame_slot.cap.set_frame_mapped_address(vaddr); - frame_slot.cap.set_frame_mapped_asid(asid); - *pdSlot = pde; - unsafe { - asm!( - "dc cvau, {}", - "dmb sy", - in(reg) pdSlot, - ); - } - let tlbflush_required = pdSlot.get_pde_type() == 1; - if tlbflush_required { + clean_by_va_pou( + convert_ref_type_to_usize(pt_slot), + pptr_to_paddr(convert_ref_type_to_usize(pt_slot)), + ); + if unlikely(tlbflush_required) { assert!(asid < BIT!(16)); - invalidate_tlb_by_asid_va(asid, vaddr); + invalidate_tlb_by_asid_va(asid, cap.get_frame_mapped_address()); } exception_t::EXCEPTION_NONE } +// #[cfg(target_arch = "aarch64")] +// pub fn invoke_huge_page_map( +// vaddr: usize, +// asid: usize, +// frame_slot: &mut cte_t, +// pude: PUDE, +// pudSlot: &mut PUDE, +// ) -> exception_t { +// frame_slot.cap.set_frame_mapped_address(vaddr); +// frame_slot.cap.set_frame_mapped_asid(asid); +// *pudSlot = pude; +// unsafe { +// asm!( +// "dc cvau, {}", +// "dmb sy", +// in(reg) pudSlot, +// ); +// } +// let tlbflush_required = pudSlot.get_pude_type() == 1; +// if tlbflush_required { +// assert!(asid < BIT!(16)); +// invalidate_tlb_by_asid_va(asid, vaddr); +// } +// exception_t::EXCEPTION_NONE +// } -#[cfg(target_arch = "aarch64")] -pub fn invoke_small_page_map( - vaddr: usize, - asid: usize, - frame_slot: &mut cte_t, - pte: PTE, - ptSlot: &mut PTE, -) -> exception_t { - frame_slot.cap.set_frame_mapped_address(vaddr); - frame_slot.cap.set_frame_mapped_asid(asid); - *ptSlot = pte; - unsafe { - asm!( - "dc cvau, {}", - "dmb sy", - in(reg) ptSlot, - ); - } - let tlbflush_required = ptSlot.is_present(); - if tlbflush_required { - assert!(asid < BIT!(16)); - invalidate_tlb_by_asid_va(asid, vaddr); - } - exception_t::EXCEPTION_NONE -} +// #[cfg(target_arch = "aarch64")] +// pub fn invoke_large_page_map( +// vaddr: usize, +// asid: usize, +// frame_slot: &mut cte_t, +// pde: PDE, +// pdSlot: &mut PDE, +// ) -> exception_t { +// frame_slot.cap.set_frame_mapped_address(vaddr); +// frame_slot.cap.set_frame_mapped_asid(asid); +// *pdSlot = pde; +// unsafe { +// asm!( +// "dc cvau, {}", +// "dmb sy", +// in(reg) pdSlot, +// ); +// } +// let tlbflush_required = pdSlot.get_pde_type() == 1; +// if tlbflush_required { +// assert!(asid < BIT!(16)); +// invalidate_tlb_by_asid_va(asid, vaddr); +// } +// exception_t::EXCEPTION_NONE +// } + +// #[cfg(target_arch = "aarch64")] +// pub fn invoke_small_page_map( +// vaddr: usize, +// asid: usize, +// frame_slot: &mut cte_t, +// pte: PTE, +// ptSlot: &mut PTE, +// ) -> exception_t { +// frame_slot.cap.set_frame_mapped_address(vaddr); +// frame_slot.cap.set_frame_mapped_asid(asid); +// *ptSlot = pte; +// unsafe { +// asm!( +// "dc cvau, {}", +// "dmb sy", +// in(reg) ptSlot, +// ); +// } +// let tlbflush_required = ptSlot.is_present(); +// if tlbflush_required { +// assert!(asid < BIT!(16)); +// invalidate_tlb_by_asid_va(asid, vaddr); +// } +// exception_t::EXCEPTION_NONE +// } #[cfg(target_arch = "riscv64")] pub fn invoke_asid_control( diff --git a/kernel/src/syscall/invocation/mod.rs b/kernel/src/syscall/invocation/mod.rs index 8d5f7b4..56a4859 100644 --- a/kernel/src/syscall/invocation/mod.rs +++ b/kernel/src/syscall/invocation/mod.rs @@ -1,10 +1,10 @@ +pub(crate) mod arch; pub mod decode; mod invoke_cnode; pub mod invoke_irq; mod invoke_mmu_op; mod invoke_tcb; mod invoke_untyped; -pub(crate) mod arch; use core::intrinsics::unlikely; diff --git a/kernel/src/utils.rs b/kernel/src/utils.rs index 8996159..7f7d74a 100644 --- a/kernel/src/utils.rs +++ b/kernel/src/utils.rs @@ -46,20 +46,20 @@ pub fn clear_memory(ptr: *mut u8, bits: usize) { // addrFromPPtr(ptr)); // } -#[cfg(target_arch = "aarch64")] -#[inline] -pub fn clear_memory_pt(ptr: *mut u8, bits: usize) { - use sel4_vspace::{clean_cache_range_pou, pptr_to_paddr}; +// #[cfg(target_arch = "aarch64")] +// #[inline] +// pub fn clear_memory_pt(ptr: *mut u8, bits: usize) { +// use sel4_vspace::{clean_cache_range_pou, pptr_to_paddr}; - unsafe { - core::slice::from_raw_parts_mut(ptr, BIT!(bits)).fill(0); - clean_cache_range_pou( - ptr as usize, - ptr.add(BIT!(bits) - 1) as usize, - pptr_to_paddr(ptr as usize), - ); - } -} +// unsafe { +// core::slice::from_raw_parts_mut(ptr, BIT!(bits)).fill(0); +// clean_cache_range_pou( +// ptr as usize, +// ptr.add(BIT!(bits) - 1) as usize, +// pptr_to_paddr(ptr as usize), +// ); +// } +// } #[inline] #[cfg(target_arch = "aarch64")] diff --git a/sel4_common/src/arch/aarch64/message_info.rs b/sel4_common/src/arch/aarch64/message_info.rs index 97241af..e41dd23 100644 --- a/sel4_common/src/arch/aarch64/message_info.rs +++ b/sel4_common/src/arch/aarch64/message_info.rs @@ -38,10 +38,7 @@ pub enum MessageLabel { ARMVSpaceInvalidate_Data, ARMVSpaceCleanInvalidate_Data, ARMVSpaceUnify_Instruction, - ARMPageUpperDirectoryMap, - ARMPageUpperDirectoryUnmap, - ARMPageDirectoryMap, - ARMPageDirectoryUnmap, + ARMSMCCall, ARMPageTableMap, ARMPageTableUnmap, ARMPageMap, diff --git a/sel4_common/src/arch/aarch64/object.rs b/sel4_common/src/arch/aarch64/object.rs index 991235e..00be433 100644 --- a/sel4_common/src/arch/aarch64/object.rs +++ b/sel4_common/src/arch/aarch64/object.rs @@ -1,6 +1,7 @@ use crate::sel4_config::{ - seL4_PGDBits, seL4_PUDBits, seL4_PageDirBits, seL4_PageTableBits, ARMHugePageBits, - ARMLargePageBits, ARMSmallPageBits, ARM_Huge_Page, ARM_Large_Page, ARM_Small_Page, + seL4_PGDBits, seL4_PUDBits, seL4_PageDirBits, seL4_PageTableBits, seL4_VSpaceBits, + ARMHugePageBits, ARMLargePageBits, ARMSmallPageBits, ARM_Huge_Page, ARM_Large_Page, + ARM_Small_Page, }; #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)] @@ -12,12 +13,10 @@ pub enum ObjectType { NotificationObject = 3, CapTableObject = 4, seL4_ARM_HugePageObject = 5, - seL4_ARM_PageUpperDirectoryObject = 6, - seL4_ARM_PageGlobalDirectoryObject = 7, - seL4_ARM_SmallPageObject = 8, - seL4_ARM_LargePageObject = 9, - seL4_ARM_PageTableObject = 10, - seL4_ARM_PageDirectoryObject = 11, + seL4_ARM_VSpaceObject = 6, + seL4_ARM_SmallPageObject = 7, + seL4_ARM_LargePageObject = 8, + seL4_ARM_PageTableObject = 9, } impl ObjectType { @@ -27,9 +26,7 @@ impl ObjectType { Self::seL4_ARM_LargePageObject => ARMLargePageBits, Self::seL4_ARM_HugePageObject => ARMHugePageBits, Self::seL4_ARM_PageTableObject => seL4_PageTableBits, - Self::seL4_ARM_PageUpperDirectoryObject => seL4_PUDBits, - Self::seL4_ARM_PageDirectoryObject => seL4_PageDirBits, - Self::seL4_ARM_PageGlobalDirectoryObject => seL4_PGDBits, + Self::seL4_ARM_VSpaceObject => seL4_VSpaceBits, _ => panic!("unsupported object type:{}", *self as usize), } } @@ -58,12 +55,10 @@ impl ObjectType { matches!( self, Self::seL4_ARM_HugePageObject - | Self::seL4_ARM_PageUpperDirectoryObject - | Self::seL4_ARM_PageGlobalDirectoryObject | Self::seL4_ARM_SmallPageObject | Self::seL4_ARM_LargePageObject | Self::seL4_ARM_PageTableObject - | Self::seL4_ARM_PageDirectoryObject + | Self::seL4_ARM_VSpaceObject ) } } diff --git a/sel4_common/src/object.rs b/sel4_common/src/object.rs index f316de5..9487800 100644 --- a/sel4_common/src/object.rs +++ b/sel4_common/src/object.rs @@ -11,7 +11,7 @@ use super::sel4_config::*; pub const seL4_ObjectTypeCount: usize = ObjectType::PageTableObject as usize + 1; // FIXED: Need to add 1 to cover all possible object types #[cfg(any(target_arch = "aarch64", test))] -pub const seL4_ObjectTypeCount: usize = ObjectType::seL4_ARM_PageDirectoryObject as usize + 1; +pub const seL4_ObjectTypeCount: usize = ObjectType::seL4_ARM_PageTableObject as usize + 1; pub const seL4_NonArchObjectTypeCount: usize = ObjectType::CapTableObject as usize + 1; impl ObjectType { diff --git a/sel4_common/src/sel4_config.rs b/sel4_common/src/sel4_config.rs index cd8f764..6e8c7b8 100644 --- a/sel4_common/src/sel4_config.rs +++ b/sel4_common/src/sel4_config.rs @@ -45,6 +45,9 @@ pub const seL4_PGDBits: usize = 12; pub const seL4_HugePageBits: usize = 30; pub const seL4_LargePageBits: usize = 21; +pub const seL4_PML4Bits: usize = 12; +pub const seL4_VSpaceBits: usize = seL4_PML4Bits; + pub const PT_INDEX_OFFSET: usize = seL4_PageBits; pub const PD_INDEX_OFFSET: usize = PT_INDEX_OFFSET + PT_INDEX_BITS; pub const PUD_INDEX_OFFSET: usize = PD_INDEX_OFFSET + PD_INDEX_BITS; diff --git a/sel4_cspace/src/arch/aarch64/mod.rs b/sel4_cspace/src/arch/aarch64/mod.rs index e16513e..b3718c3 100644 --- a/sel4_cspace/src/arch/aarch64/mod.rs +++ b/sel4_cspace/src/arch/aarch64/mod.rs @@ -21,9 +21,7 @@ pub enum CapTag { CapDomainCap = 20, CapFrameCap = 1, CapPageTableCap = 3, - CapPageDirectoryCap = 5, - CapPageUpperDirectoryCap = 7, - CapPageGlobalDirectoryCap = 9, + CapVspaceCap = 9, CapASIDControlCap = 11, CapASIDPoolCap = 13, } @@ -87,24 +85,29 @@ plus_define_bitfield! { capPTMappedASID, get_pt_mapped_asid, set_pt_mapped_asid, 1, 48, 16, 0, false, capPTBasePtr, get_pt_base_ptr, set_pt_base_ptr, 1, 0, 48, 0, true, capPTIsMapped, get_pt_is_mapped, set_pt_is_mapped, 0, 48, 1, 0, false, - capPTMappedAddress, get_pt_mapped_address, set_pt_mapped_address, 0, 20, 28, 0, true + capPTMappedAddress, get_pt_mapped_address, set_pt_mapped_address, 0, 20, 28, 20, true }, - new_page_directory_cap, CapTag::CapPageDirectoryCap as usize => { - capPDMappedASID, get_pd_mapped_asid, set_pd_mapped_asid, 1, 48, 16, 0, false, - capPDBasePtr, get_pd_base_ptr, set_pd_base_ptr, 1, 0, 48, 0, true, - capPDIsMapped, get_pd_is_mapped, set_pd_is_mapped, 0, 48, 1, 0, false, - capPDMappedAddress, get_pd_mapped_address, set_pd_mapped_address, 0, 29, 19, 0, true - }, - new_page_upper_directory_cap, CapTag::CapPageUpperDirectoryCap as usize => { - capPUDMappedASID, get_pud_mapped_asid, set_pud_mapped_asid, 1, 48, 16, 0, false, - capPUDBasePtr, get_pud_base_ptr, set_pud_base_ptr, 1, 0, 48, 0, true, - capPUDIsMapped, get_pud_is_mapped, set_pud_is_mapped, 0, 58, 1, 0, false, - capPUDMappedAddress, get_pud_mapped_address, set_pud_mapped_address, 0, 48, 10, 0, true - }, - new_page_global_directory_cap, CapTag::CapPageGlobalDirectoryCap as usize => { - capPGDMappedASID, get_pgd_mapped_asid, set_pgd_mapped_asid, 1, 48, 16, 0, false, - capPGDBasePtr, get_pgd_base_ptr, set_pgd_base_ptr, 1, 0, 48, 0, true, - capPGDIsMapped, get_pgd_is_mapped, set_pgd_is_mapped, 0, 58, 1, 0, false + // new_page_directory_cap, CapTag::CapPageDirectoryCap as usize => { + // capPDMappedASID, get_pd_mapped_asid, set_pd_mapped_asid, 1, 48, 16, 0, false, + // capPDBasePtr, get_pd_base_ptr, set_pd_base_ptr, 1, 0, 48, 0, true, + // capPDIsMapped, get_pd_is_mapped, set_pd_is_mapped, 0, 48, 1, 0, false, + // capPDMappedAddress, get_pd_mapped_address, set_pd_mapped_address, 0, 29, 19, 0, true + // }, + // new_page_upper_directory_cap, CapTag::CapPageUpperDirectoryCap as usize => { + // capPUDMappedASID, get_pud_mapped_asid, set_pud_mapped_asid, 1, 48, 16, 0, false, + // capPUDBasePtr, get_pud_base_ptr, set_pud_base_ptr, 1, 0, 48, 0, true, + // capPUDIsMapped, get_pud_is_mapped, set_pud_is_mapped, 0, 58, 1, 0, false, + // capPUDMappedAddress, get_pud_mapped_address, set_pud_mapped_address, 0, 48, 10, 0, true + // }, + // new_page_global_directory_cap, CapTag::CapPageGlobalDirectoryCap as usize => { + // capPGDMappedASID, get_pgd_mapped_asid, set_pgd_mapped_asid, 1, 48, 16, 0, false, + // capPGDBasePtr, get_pgd_base_ptr, set_pgd_base_ptr, 1, 0, 48, 0, true, + // capPGDIsMapped, get_pgd_is_mapped, set_pgd_is_mapped, 0, 58, 1, 0, false + // }, + new_vspace_cap, CapTag::CapVspaceCap as usize => { + capVSMappedASID, get_vs_mapped_asid, set_vs_mapped_asid, 1, 48, 16, 0, false, + capVSBasePtr, get_vs_base_ptr, set_vs_base_ptr, 1, 0, 48, 0, true, + capVSIsMapped, get_vs_is_mapped, set_vs_is_mapped, 0, 58, 1, 0, false }, new_asid_control_cap, CapTag::CapASIDControlCap as usize => {}, new_asid_pool_cap, CapTag::CapASIDPoolCap as usize => { @@ -126,9 +129,10 @@ impl cap_t { CapTag::CapZombieCap => self.get_zombie_ptr(), CapTag::CapFrameCap => self.get_frame_base_ptr(), CapTag::CapPageTableCap => self.get_pt_base_ptr(), - CapTag::CapPageDirectoryCap => self.get_pd_base_ptr(), - CapTag::CapPageUpperDirectoryCap => self.get_pud_base_ptr(), - CapTag::CapPageGlobalDirectoryCap => self.get_pgd_base_ptr(), + CapTag::CapVspaceCap => self.get_vs_base_ptr(), + // CapTag::CapPageDirectoryCap => self.get_pd_base_ptr(), + // CapTag::CapPageUpperDirectoryCap => self.get_pud_base_ptr(), + // CapTag::CapPageGlobalDirectoryCap => self.get_pgd_base_ptr(), CapTag::CapASIDControlCap => 0, CapTag::CapASIDPoolCap => self.get_asid_pool(), _ => 0, @@ -137,12 +141,12 @@ impl cap_t { #[inline] pub fn is_vtable_root(&self) -> bool { - self.get_cap_type() == CapTag::CapPageGlobalDirectoryCap + self.get_cap_type() == CapTag::CapVspaceCap } #[inline] pub fn is_valid_native_root(&self) -> bool { - self.is_vtable_root() && self.get_pgd_is_mapped() != 0 + self.is_vtable_root() && self.get_vs_is_mapped() != 0 } #[inline] @@ -158,26 +162,35 @@ impl cte_t { cap: cap_t::default(), }; match cap.get_cap_type() { - CapTag::CapPageGlobalDirectoryCap => { - if cap.get_pgd_is_mapped() != 0 { - ret.cap = cap.clone(); - ret.status = exception_t::EXCEPTION_NONE; - } else { - ret.cap = cap_t::new_null_cap(); - ret.status = exception_t::EXCEPTION_SYSCALL_ERROR; - } - } - CapTag::CapPageUpperDirectoryCap => { - if cap.get_pud_is_mapped() != 0 { - ret.cap = cap.clone(); - ret.status = exception_t::EXCEPTION_NONE; - } else { - ret.cap = cap_t::new_null_cap(); - ret.status = exception_t::EXCEPTION_SYSCALL_ERROR; - } - } - CapTag::CapPageDirectoryCap => { - if cap.get_pud_is_mapped() != 0 { + // CapTag::CapPageGlobalDirectoryCap => { + // if cap.get_pgd_is_mapped() != 0 { + // ret.cap = cap.clone(); + // ret.status = exception_t::EXCEPTION_NONE; + // } else { + // ret.cap = cap_t::new_null_cap(); + // ret.status = exception_t::EXCEPTION_SYSCALL_ERROR; + // } + // } + // CapTag::CapPageUpperDirectoryCap => { + // if cap.get_pud_is_mapped() != 0 { + // ret.cap = cap.clone(); + // ret.status = exception_t::EXCEPTION_NONE; + // } else { + // ret.cap = cap_t::new_null_cap(); + // ret.status = exception_t::EXCEPTION_SYSCALL_ERROR; + // } + // } + // CapTag::CapPageDirectoryCap => { + // if cap.get_pud_is_mapped() != 0 { + // ret.cap = cap.clone(); + // ret.status = exception_t::EXCEPTION_NONE; + // } else { + // ret.cap = cap_t::new_null_cap(); + // ret.status = exception_t::EXCEPTION_SYSCALL_ERROR; + // } + // } + CapTag::CapVspaceCap => { + if cap.get_vs_is_mapped() != 0 { ret.cap = cap.clone(); ret.status = exception_t::EXCEPTION_NONE; } else { @@ -186,7 +199,7 @@ impl cte_t { } } CapTag::CapPageTableCap => { - if cap.get_pud_is_mapped() != 0 { + if cap.get_pt_is_mapped() != 0 { ret.cap = cap.clone(); ret.status = exception_t::EXCEPTION_NONE; } else { @@ -238,20 +251,9 @@ pub fn arch_same_region_as(cap1: &cap_t, cap2: &cap_t) -> bool { return cap1.get_pt_base_ptr() == cap2.get_pt_base_ptr(); } } - CapTag::CapPageDirectoryCap => { - if cap2.get_cap_type() == CapTag::CapPageDirectoryCap { - return cap1.get_pd_base_ptr() == cap2.get_pd_base_ptr(); - } - } - CapTag::CapPageUpperDirectoryCap => { - if cap2.get_cap_type() == CapTag::CapPageUpperDirectoryCap { - return cap1.get_pud_base_ptr() == cap2.get_pud_base_ptr(); - } - } - CapTag::CapPageGlobalDirectoryCap => { - // FIXED: Here should be CapTag::CapPageGlobalDirectoryCap - if cap2.get_cap_type() == CapTag::CapPageGlobalDirectoryCap { - return cap1.get_pgd_base_ptr() == cap2.get_pgd_base_ptr(); + CapTag::CapVspaceCap => { + if cap2.get_cap_type() == CapTag::CapVspaceCap { + return cap1.get_vs_base_ptr() == cap2.get_vs_base_ptr(); } } CapTag::CapASIDControlCap => { diff --git a/sel4_task/src/tcb.rs b/sel4_task/src/tcb.rs index dc0b47e..095cf23 100644 --- a/sel4_task/src/tcb.rs +++ b/sel4_task/src/tcb.rs @@ -316,8 +316,8 @@ impl tcb_t { )); return Ok(()); } - let vspace_root = thread_root.get_pgd_base_ptr(); - let asid = thread_root.get_pgd_mapped_asid(); + let vspace_root = thread_root.get_vs_base_ptr(); + let asid = thread_root.get_vs_mapped_asid(); let find_ret = find_vspace_for_asid(asid); if let Some(root) = find_ret.vspace_root { diff --git a/sel4_vspace/src/arch/aarch64/asid.rs b/sel4_vspace/src/arch/aarch64/asid.rs index fd71dc5..5ac08ac 100644 --- a/sel4_vspace/src/arch/aarch64/asid.rs +++ b/sel4_vspace/src/arch/aarch64/asid.rs @@ -1,3 +1,4 @@ +use crate::PTE; use sel4_common::{ fault::lookup_fault_t, sel4_config::{asidHighBits, asidLowBits, IT_ASID}, @@ -7,7 +8,7 @@ use sel4_common::{ }; use sel4_cspace::arch::cap_t; -use crate::{asid_map_t, asid_pool_t, asid_t, findVSpaceForASID_ret, set_vm_root, PGDE}; +use crate::{asid_map_t, asid_pool_t, asid_t, findVSpaceForASID_ret, set_vm_root}; use super::asid_pool_from_addr; use super::machine::invalidate_local_tlb_asid; @@ -54,7 +55,7 @@ pub fn find_vspace_for_asid(asid: usize) -> findVSpaceForASID_ret { match find_map_for_asid(asid) { Some(asid_map) => { if asid_map.get_type() == asid_map_asid_map_vspace { - ret.vspace_root = Some(asid_map.get_vspace_root() as *mut PGDE); + ret.vspace_root = Some(asid_map.get_vspace_root() as *mut PTE); ret.status = exception_t::EXCEPTION_NONE; } } @@ -64,7 +65,7 @@ pub fn find_vspace_for_asid(asid: usize) -> findVSpaceForASID_ret { } #[no_mangle] -pub fn delete_asid(asid: usize, vspace: *mut PGDE, cap: &cap_t) -> Result<(), lookup_fault_t> { +pub fn delete_asid(asid: usize, vspace: *mut PTE, cap: &cap_t) -> Result<(), lookup_fault_t> { let ptr = convert_to_option_mut_type_ref::(get_asid_table()[asid >> asidLowBits]); if let Some(pool) = ptr { let asid_map: asid_map_t = pool[asid & MASK!(asidLowBits)]; @@ -105,7 +106,7 @@ pub fn delete_asid_pool( #[inline] pub fn write_it_asid_pool(it_ap_cap: &cap_t, it_vspace_cap: &cap_t) { let ap = asid_pool_from_addr(it_ap_cap.get_cap_ptr()); - let asid_map = asid_map_t::new_vspace(it_vspace_cap.get_pgd_base_ptr()); + let asid_map = asid_map_t::new_vspace(it_vspace_cap.get_vs_base_ptr()); ap[IT_ASID] = asid_map; set_asid_pool_by_index(IT_ASID >> asidLowBits, ap as *const _ as usize); } diff --git a/sel4_vspace/src/arch/aarch64/boot.rs b/sel4_vspace/src/arch/aarch64/boot.rs index 444e738..81d1fb1 100644 --- a/sel4_vspace/src/arch/aarch64/boot.rs +++ b/sel4_vspace/src/arch/aarch64/boot.rs @@ -14,7 +14,7 @@ use crate::{ get_kernel_page_upper_directory_base, kpptr_to_paddr, mair_types, pptr_t, pptr_to_paddr, set_kernel_page_directory_by_index, set_kernel_page_global_directory_by_index, set_kernel_page_table_by_index, set_kernel_page_upper_directory_by_index, vm_attributes_t, - vptr_t, GET_KPT_INDEX, GET_PD_INDEX, GET_PT_INDEX, GET_PUD_INDEX, PDE, PGDE, PTE, PUDE, + vptr_t, PTE, }; use super::{map_kernel_devices, page_slice}; @@ -75,16 +75,17 @@ pub const RESERVED: usize = 3; #[no_mangle] #[link_section = ".boot.text"] pub fn rust_map_kernel_window() { + // println!("go into rusta map kernel window"); set_kernel_page_global_directory_by_index( - GET_KPT_INDEX(PPTR_BASE, 0), - PGDE::pude_new(kpptr_to_paddr(get_kernel_page_upper_directory_base())), + (VAddr(PPTR_BASE)).GET_KPT_INDEX(0), + PTE::pte_new_table(kpptr_to_paddr(get_kernel_page_upper_directory_base())), ); - let mut idx = GET_PUD_INDEX(PPTR_BASE); - while idx < GET_PUD_INDEX(PPTR_TOP) { + let mut idx = VAddr(PPTR_BASE).GET_KPT_INDEX(1); + while idx < VAddr(PPTR_TOP).GET_KPT_INDEX(1) { set_kernel_page_upper_directory_by_index( idx, - PUDE::pd_new(kpptr_to_paddr(get_kernel_page_directory_base_by_index(idx))), + PTE::pte_new_table(kpptr_to_paddr(get_kernel_page_directory_base_by_index(idx))), ); idx += 1; } @@ -93,9 +94,9 @@ pub fn rust_map_kernel_window() { let mut paddr = PADDR_BASE; while paddr < PADDR_TOP { set_kernel_page_directory_by_index( - GET_PUD_INDEX(vaddr), - GET_PD_INDEX(vaddr), - PDE::new_large(true, paddr, 0, 1, 0, 0, mair_types::NORMAL), + VAddr(vaddr).GET_KPT_INDEX(1), + VAddr(vaddr).GET_KPT_INDEX(2), + PTE::pte_new_page(1, paddr, 0, 1, 0, 0, mair_types::NORMAL as usize), ); vaddr += BIT!(seL4_LargePageBits); @@ -113,15 +114,15 @@ pub fn rust_map_kernel_window() { // set_kernel_page_upper_directory_by_index( - GET_PUD_INDEX(PPTR_TOP), - PUDE::pd_new(kpptr_to_paddr(get_kernel_page_directory_base_by_index( + VAddr(PPTR_TOP).GET_KPT_INDEX(1), + PTE::pte_new_table(kpptr_to_paddr(get_kernel_page_directory_base_by_index( BIT!(PUD_INDEX_BITS) - 1, ))), ); set_kernel_page_directory_by_index( BIT!(PUD_INDEX_BITS) - 1, BIT!(PUD_INDEX_BITS) - 1, - PDE::new_small(kpptr_to_paddr(get_kernel_page_table_base())), + PTE::pte_new_table(kpptr_to_paddr(get_kernel_page_table_base())), ); map_kernel_devices(); // ffi_call!(map_kernel_devices()); @@ -145,8 +146,8 @@ pub fn map_kernel_frame( shareable = 0; } set_kernel_page_table_by_index( - GET_PT_INDEX(vaddr), - PTE::pte_new( + VAddr(vaddr).GET_KPT_INDEX(3), + PTE::pte_new_4k_page( uxn, paddr, 0, @@ -154,7 +155,6 @@ pub fn map_kernel_frame( shareable, PTE::ap_from_vm_rights_t(vm_rights).bits() >> 6, attr_index, - RESERVED, ), ); } @@ -166,7 +166,7 @@ pub fn map_it_pt_cap(vspace_cap: &cap_t, pt_cap: &cap_t) { let vptr = pt_cap.get_pt_mapped_address(); let pt = pt_cap.get_pt_base_ptr(); let target_pte = - convert_to_mut_type_ref::(find_pt(vspace_root, vptr.into(), find_type::PDE)); + convert_to_mut_type_ref::(find_pt(vspace_root, vptr.into(), find_type::PDE)); target_pte.set_next_level_paddr(pptr_to_paddr(pt)); // TODO: move 0x3 into a proper position. target_pte.set_attr(3); @@ -176,25 +176,25 @@ pub fn map_it_pt_cap(vspace_cap: &cap_t, pt_cap: &cap_t) { #[no_mangle] #[link_section = ".boot.text"] pub fn map_it_pd_cap(vspace_cap: &cap_t, pd_cap: &cap_t) { - let pgd = page_slice::(vspace_cap.get_cap_ptr()); - let pd_addr = pd_cap.get_pd_base_ptr(); - let vptr: VAddr = pd_cap.get_pd_mapped_address().into(); - assert_eq!(pd_cap.get_pd_is_mapped(), 1); + let pgd = page_slice::(vspace_cap.get_cap_ptr()); + let pd_addr = pd_cap.get_pt_base_ptr(); + let vptr: VAddr = pd_cap.get_pt_mapped_address().into(); + assert_eq!(pd_cap.get_pt_is_mapped(), 1); // TODO: move 0x3 into a proper position. assert_eq!(pgd[vptr.pgd_index()].attr(), 0x3); - let pud = pgd[vptr.pgd_index()].next_level_slice::(); - pud[vptr.pud_index()] = PUDE::new_page(pptr_to_paddr(pd_addr), 0x3); + let pud = pgd[vptr.pgd_index()].next_level_slice::(); + pud[vptr.pud_index()] = PTE::new_page(pptr_to_paddr(pd_addr), 0x3); } /// TODO: Write the comments. pub fn map_it_pud_cap(vspace_cap: &cap_t, pud_cap: &cap_t) { - let pgd = page_slice::(vspace_cap.get_cap_ptr()); - let pud_addr = pud_cap.get_pud_base_ptr(); - let vptr: VAddr = pud_cap.get_pud_mapped_address().into(); - assert_eq!(pud_cap.get_pud_is_mapped(), 1); + let pgd = page_slice::(vspace_cap.get_cap_ptr()); + let pud_addr = pud_cap.get_pt_base_ptr(); + let vptr: VAddr = pud_cap.get_pt_mapped_address().into(); + assert_eq!(pud_cap.get_pt_is_mapped(), 1); // TODO: move 0x3 into a proper position. - pgd[vptr.pgd_index()] = PGDE::new_page(pptr_to_paddr(pud_addr), 0x3); + pgd[vptr.pgd_index()] = PTE::new_page(pptr_to_paddr(pud_addr), 0x3); } /// TODO: Write the comments. @@ -208,19 +208,19 @@ pub fn map_it_frame_cap(vspace_cap: &cap_t, frame_cap: &cap_t, exec: bool) { )); // TODO: Make set_attr usage more efficient. // TIPS: exec true will be cast to 1 and false to 0. - pte.set_attr(PTE::pte_new((!exec) as usize, 0, 1, 1, 0, 1, 0, 3).0); + pte.set_attr(PTE::pte_new_4k_page((!exec) as usize, 0, 1, 1, 0, 1, 0).0); pte.set_next_level_paddr(pptr_to_paddr(frame_cap.get_frame_base_ptr())); } /// TODO: Write the comments. #[link_section = ".boot.text"] fn find_pt(vspace_root: usize, vptr: VAddr, ftype: find_type) -> usize { - let pgd = page_slice::(vspace_root); - let pud = pgd[vptr.pgd_index()].next_level_slice::(); + let pgd = page_slice::(vspace_root); + let pud = pgd[vptr.pgd_index()].next_level_slice::(); if ftype == find_type::PUDE { return pud[vptr.pud_index()].self_addr(); } - let pd = pud[vptr.pud_index()].next_level_slice::(); + let pd = pud[vptr.pud_index()].next_level_slice::(); if ftype == find_type::PDE { return pd[vptr.pd_index()].self_addr(); } @@ -232,7 +232,7 @@ fn find_pt(vspace_root: usize, vptr: VAddr, ftype: find_type) -> usize { #[no_mangle] #[link_section = ".boot.text"] pub fn create_it_pd_cap(vspace_cap: &cap_t, pptr: usize, vptr: usize, asid: usize) -> cap_t { - let cap = cap_t::new_page_directory_cap(asid, pptr, 1, vptr); + let cap = cap_t::new_page_table_cap(asid, pptr, 1, vptr); map_it_pd_cap(vspace_cap, &cap); return cap; } diff --git a/sel4_vspace/src/arch/aarch64/interface.rs b/sel4_vspace/src/arch/aarch64/interface.rs index 2805a18..91b84b5 100644 --- a/sel4_vspace/src/arch/aarch64/interface.rs +++ b/sel4_vspace/src/arch/aarch64/interface.rs @@ -1,17 +1,14 @@ use core::intrinsics::unlikely; use core::ops::{Deref, DerefMut}; -use super::{kpptr_to_paddr, machine::*}; -use crate::{ - ap_from_vm_rights, asid_t, find_map_for_asid, find_vspace_for_asid, paddr_to_pptr, pptr_t, - pptr_to_paddr, vm_attributes_t, vptr_t, PDE, PGDE, PTE, PUDE, -}; +use super::pte::pte_tag_t; +use super::{kpptr_to_paddr, machine::*, UPT_LEVELS}; +use crate::arch::VAddr; +use crate::{asid_t, find_vspace_for_asid, paddr_to_pptr, pptr_t, pptr_to_paddr, vptr_t, PTE}; use sel4_common::arch::MessageLabel; -use sel4_common::sel4_config::{ARM_Large_Page, ARM_Small_Page}; use sel4_common::structures::exception_t; -use sel4_common::utils::{convert_ref_type_to_usize, ptr_to_mut}; +use sel4_common::utils::{pageBitsForSize, ptr_to_mut}; use sel4_common::{ - arch::vm_rights_t, fault::lookup_fault_t, sel4_config::{seL4_PageBits, PT_INDEX_BITS}, BIT, @@ -44,8 +41,7 @@ impl DerefMut for PageAligned { #[no_mangle] #[link_section = ".page_table"] -pub(crate) static mut armKSGlobalKernelPGD: PageAligned = - PageAligned::new(PGDE::invalid_new()); +pub(crate) static mut armKSGlobalKernelPGD: PageAligned = PageAligned::new(PTE(0)); #[inline] pub fn get_kernel_page_global_directory_base() -> usize { @@ -53,7 +49,7 @@ pub fn get_kernel_page_global_directory_base() -> usize { } #[inline] -pub fn set_kernel_page_global_directory_by_index(idx: usize, pgde: PGDE) { +pub fn set_kernel_page_global_directory_by_index(idx: usize, pgde: PTE) { unsafe { armKSGlobalKernelPGD[idx] = pgde; } @@ -61,8 +57,7 @@ pub fn set_kernel_page_global_directory_by_index(idx: usize, pgde: PGDE) { #[no_mangle] #[link_section = ".page_table"] -pub(crate) static mut armKSGlobalKernelPUD: PageAligned = - PageAligned::new(PUDE::invalid_new()); +pub(crate) static mut armKSGlobalKernelPUD: PageAligned = PageAligned::new(PTE(0)); #[inline] pub fn get_kernel_page_upper_directory_base() -> usize { @@ -70,7 +65,7 @@ pub fn get_kernel_page_upper_directory_base() -> usize { } #[inline] -pub fn set_kernel_page_upper_directory_by_index(idx: usize, pude: PUDE) { +pub fn set_kernel_page_upper_directory_by_index(idx: usize, pude: PTE) { unsafe { armKSGlobalKernelPUD[idx] = pude; } @@ -81,8 +76,8 @@ pub fn set_kernel_page_upper_directory_by_index(idx: usize, pude: PUDE) { // [[PTE(0); BIT!(PT_INDEX_BITS)]; BIT!(PT_INDEX_BITS)]; #[no_mangle] #[link_section = ".page_table"] -pub(crate) static mut armKSGlobalKernelPDs: PageAligned> = - PageAligned::new(PageAligned::new(PDE::new_invalid())); +pub(crate) static mut armKSGlobalKernelPDs: PageAligned> = + PageAligned::new(PageAligned::new(PTE(0))); #[inline] pub fn get_kernel_page_directory_base_by_index(idx: usize) -> usize { @@ -90,7 +85,7 @@ pub fn get_kernel_page_directory_base_by_index(idx: usize) -> usize { } #[inline] -pub fn set_kernel_page_directory_by_index(idx1: usize, idx2: usize, pde: PDE) { +pub fn set_kernel_page_directory_by_index(idx1: usize, idx2: usize, pde: PTE) { unsafe { armKSGlobalKernelPDs[idx1][idx2] = pde; } @@ -124,7 +119,7 @@ pub fn set_kernel_page_table_by_index(idx: usize, pte: PTE) { /// /// Use page table in vspace_root to set the satp register. pub fn set_vm_root(vspace_root: &cap_t) -> Result<(), lookup_fault_t> { - setCurrentUserVSpaceRoot(pptr_to_paddr(vspace_root.get_pgd_base_ptr())); + setCurrentUserVSpaceRoot(pptr_to_paddr(vspace_root.get_vs_base_ptr())); Ok(()) } @@ -144,50 +139,50 @@ pub fn activate_kernel_vspace() { /* A53 hardware does not support TLB locking */ } -pub fn make_user_1st_level( - paddr: pptr_t, - vm_rights: vm_rights_t, - attributes: vm_attributes_t, -) -> PUDE { - PUDE::new_1g( - attributes.get_armExecuteNever(), - paddr, - 1, - 1, - 0, - ap_from_vm_rights(vm_rights), - attributes.get_attr_index(), - ) -} - -pub fn make_user_2nd_level( - paddr: pptr_t, - vm_rights: vm_rights_t, - attributes: vm_attributes_t, -) -> PDE { - PDE::new_large( - attributes.get_armExecuteNever(), - paddr, - 1, - 1, - 0, - ap_from_vm_rights(vm_rights), - attributes.get_attr_index(), - ) -} - -pub fn makeUser3rdLevel(paddr: pptr_t, vm_rights: vm_rights_t, attributes: vm_attributes_t) -> PTE { - PTE::pte_new( - attributes.get_armExecuteNever() as usize, - paddr, - 1, - 1, - 0, - ap_from_vm_rights(vm_rights), - attributes.get_attr_index() as usize, - 3, // RESERVED - ) -} +// pub fn make_user_1st_level( +// paddr: pptr_t, +// vm_rights: vm_rights_t, +// attributes: vm_attributes_t, +// ) -> PUDE { +// PUDE::new_1g( +// attributes.get_armExecuteNever(), +// paddr, +// 1, +// 1, +// 0, +// ap_from_vm_rights(vm_rights), +// attributes.get_attr_index(), +// ) +// } + +// pub fn make_user_2nd_level( +// paddr: pptr_t, +// vm_rights: vm_rights_t, +// attributes: vm_attributes_t, +// ) -> PDE { +// PDE::new_large( +// attributes.get_armExecuteNever(), +// paddr, +// 1, +// 1, +// 0, +// ap_from_vm_rights(vm_rights), +// attributes.get_attr_index(), +// ) +// } + +// pub fn makeUser3rdLevel(paddr: pptr_t, vm_rights: vm_rights_t, attributes: vm_attributes_t) -> PTE { +// PTE::pte_new( +// attributes.get_armExecuteNever() as usize, +// paddr, +// 1, +// 1, +// 0, +// ap_from_vm_rights(vm_rights), +// attributes.get_attr_index() as usize, +// 3, // RESERVED +// ) +// } #[no_mangle] pub fn set_vm_root_for_flush_with_thread_root( @@ -195,9 +190,9 @@ pub fn set_vm_root_for_flush_with_thread_root( asid: asid_t, thread_root: &cap_t, ) -> bool { - if thread_root.get_cap_type() == CapTag::CapPageGlobalDirectoryCap - && thread_root.get_pgd_is_mapped() != 0 - && thread_root.get_pgd_base_ptr() == vspace as usize + if thread_root.get_cap_type() == CapTag::CapVspaceCap + && thread_root.get_vs_is_mapped() != 0 + && thread_root.get_vs_base_ptr() == vspace as usize { return false; } @@ -207,70 +202,70 @@ pub fn set_vm_root_for_flush_with_thread_root( true } -pub fn page_upper_directory_mapped(asid: asid_t, vaddr: vptr_t, pud: &PUDE) -> Option<*mut PGDE> { - match find_map_for_asid(asid) { - Some(asid_map) => { - let lookup_ret = PGDE::new_from_pte(asid_map.get_vspace_root()).lookup_pgd_slot(vaddr); - if lookup_ret.status != exception_t::EXCEPTION_NONE { - return None; - } - - let slot = unsafe { &mut (*lookup_ret.pgdSlot) }; - - if !slot.get_present() - || slot.get_pud_base_address() != pptr_to_paddr(pud as *const _ as _) - { - return None; - } - - return Some(slot); - } - None => None, - } -} - -pub fn page_directory_mapped(asid: asid_t, vaddr: vptr_t, pd: &PDE) -> Option<*mut PUDE> { - match find_map_for_asid(asid) { - Some(asid_map) => { - let lookup_ret = PGDE::new_from_pte(asid_map.get_vspace_root()).lookup_pud_slot(vaddr); - if lookup_ret.status != exception_t::EXCEPTION_NONE { - return None; - } - - let slot = unsafe { &mut (*lookup_ret.pudSlot) }; - - if !slot.get_present() - || slot.get_pd_base_address() != pptr_to_paddr(pd as *const _ as _) - { - return None; - } - - return Some(slot); - } - None => None, - } -} +// pub fn page_upper_directory_mapped(asid: asid_t, vaddr: vptr_t, pud: &PUDE) -> Option<*mut PGDE> { +// match find_map_for_asid(asid) { +// Some(asid_map) => { +// let lookup_ret = PGDE::new_from_pte(asid_map.get_vspace_root()).lookup_pgd_slot(vaddr); +// if lookup_ret.status != exception_t::EXCEPTION_NONE { +// return None; +// } + +// let slot = unsafe { &mut (*lookup_ret.pgdSlot) }; + +// if !slot.get_present() +// || slot.get_pud_base_address() != pptr_to_paddr(pud as *const _ as _) +// { +// return None; +// } + +// return Some(slot); +// } +// None => None, +// } +// } + +// pub fn page_directory_mapped(asid: asid_t, vaddr: vptr_t, pd: &PDE) -> Option<*mut PUDE> { +// match find_map_for_asid(asid) { +// Some(asid_map) => { +// let lookup_ret = PGDE::new_from_pte(asid_map.get_vspace_root()).lookup_pud_slot(vaddr); +// if lookup_ret.status != exception_t::EXCEPTION_NONE { +// return None; +// } + +// let slot = unsafe { &mut (*lookup_ret.pudSlot) }; + +// if !slot.get_present() +// || slot.get_pd_base_address() != pptr_to_paddr(pd as *const _ as _) +// { +// return None; +// } + +// return Some(slot); +// } +// None => None, +// } +// } /// TODO: Make pt as usize of -pub fn page_table_mapped(asid: asid_t, vaddr: vptr_t, pt: &PTE) -> Option<*mut PDE> { - match find_map_for_asid(asid) { - Some(asid_map) => { - let lookup_ret = PGDE::new_from_pte(asid_map.get_vspace_root()).lookup_pd_slot(vaddr); - if lookup_ret.status != exception_t::EXCEPTION_NONE { - return None; - } - - let slot = unsafe { &mut (*lookup_ret.pdSlot) }; - - if !slot.get_present() || slot.get_base_address() != pptr_to_paddr(pt.0) { - return None; - } - - return Some(slot); - } - None => None, - } -} +// pub fn page_table_mapped(asid: asid_t, vaddr: vptr_t, pt: &PTE) -> Option<*mut PDE> { +// match find_map_for_asid(asid) { +// Some(asid_map) => { +// let lookup_ret = PGDE::new_from_pte(asid_map.get_vspace_root()).lookup_pd_slot(vaddr); +// if lookup_ret.status != exception_t::EXCEPTION_NONE { +// return None; +// } + +// let slot = unsafe { &mut (*lookup_ret.pdSlot) }; + +// if !slot.get_present() || slot.get_base_address() != pptr_to_paddr(pt.0) { +// return None; +// } + +// return Some(slot); +// } +// None => None, +// } +// } #[inline] pub fn invalidate_tlb_by_asid(asid: asid_t) { @@ -282,40 +277,55 @@ pub fn invalidate_tlb_by_asid_va(asid: asid_t, vaddr: vptr_t) { invalidate_local_tlb_va_asid((asid << 48) | vaddr >> seL4_PageBits); } -pub fn unmap_page_upper_directory(asid: asid_t, vaddr: vptr_t, pud: &PUDE) { - match page_upper_directory_mapped(asid, vaddr, pud) { - Some(slot) => { - let slot = unsafe { &mut (*slot) }; - slot.invalidate(); - clean_by_va_pou(slot.get_ptr(), pptr_to_paddr(slot.get_ptr())); - invalidate_tlb_by_asid(asid); - } - None => {} - } -} - -pub fn unmap_page_directory(asid: asid_t, vaddr: vptr_t, pd: &PDE) { - match page_directory_mapped(asid, vaddr, pd) { - Some(slot) => { - let slot = unsafe { &mut (*slot) }; - slot.invalidate(); - clean_by_va_pou(slot.get_ptr(), pptr_to_paddr(slot.get_ptr())); - invalidate_tlb_by_asid(asid); - } - None => {} - } -} +// pub fn unmap_page_upper_directory(asid: asid_t, vaddr: vptr_t, pud: &PUDE) { +// match page_upper_directory_mapped(asid, vaddr, pud) { +// Some(slot) => { +// let slot = unsafe { &mut (*slot) }; +// slot.invalidate(); +// clean_by_va_pou(slot.get_ptr(), pptr_to_paddr(slot.get_ptr())); +// invalidate_tlb_by_asid(asid); +// } +// None => {} +// } +// } + +// pub fn unmap_page_directory(asid: asid_t, vaddr: vptr_t, pd: &PDE) { +// match page_directory_mapped(asid, vaddr, pd) { +// Some(slot) => { +// let slot = unsafe { &mut (*slot) }; +// slot.invalidate(); +// clean_by_va_pou(slot.get_ptr(), pptr_to_paddr(slot.get_ptr())); +// invalidate_tlb_by_asid(asid); +// } +// None => {} +// } +// } pub fn unmap_page_table(asid: asid_t, vaddr: vptr_t, pt: &PTE) { - match page_table_mapped(asid, vaddr, pt) { - Some(slot) => { - let slot = unsafe { &mut (*slot) }; - slot.invalidate(); - clean_by_va_pou(slot.get_ptr(), pptr_to_paddr(slot.get_ptr())); - invalidate_tlb_by_asid(asid); + let find_ret = find_vspace_for_asid(asid); + if find_ret.status != exception_t::EXCEPTION_NONE { + return; + } + let mut ptSlot: *mut PTE = core::ptr::null_mut::(); + let mut pte = find_ret.vspace_root.unwrap(); + let mut level: usize = 0; + while level < UPT_LEVELS - 1 && pte as usize != pt as *const PTE as usize { + ptSlot = unsafe { pte.add(VAddr(vaddr).GET_UPT_INDEX(level)) }; + if ptr_to_mut(ptSlot).get_type() != (pte_tag_t::pte_table) as usize { + return; } - None => {} + pte = paddr_to_pptr(ptr_to_mut(ptSlot).next_level_paddr()) as *mut PTE; + level = level + 1; + } + if pte as usize != pt as *const PTE as usize { + return; } + assert!(!ptSlot.is_null()); + unsafe { + *(ptSlot) = PTE(0); + ptr_to_mut(ptSlot).update(*(pte)); + } + invalidate_tlb_by_asid(asid); } /// Unmap a page table @@ -331,44 +341,66 @@ pub fn unmapPage( if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { return Ok(()); } - match page_size { - ARM_Small_Page => { - let lu_ret = - PGDE::new_from_pte(find_ret.vspace_root.unwrap() as usize).lookup_pt_slot(vptr); - if unlikely(lu_ret.status != exception_t::EXCEPTION_NONE) { - return Ok(()); - } - let pte = ptr_to_mut(lu_ret.ptSlot); - if pte.is_present() && pte.pte_ptr_get_page_base_address() == addr { - *pte = PTE(0); - unsafe { core::arch::asm!("tlbi vmalle1; dsb sy; isb") }; - clean_by_va_pou( - convert_ref_type_to_usize(pte), - paddr_to_pptr(convert_ref_type_to_usize(pte)), - ); - } - Ok(()) - } - ARM_Large_Page => { - log::info!("unmap large page: {:#x?}", vptr); - let lu_ret = - PGDE::new_from_pte(find_ret.vspace_root.unwrap() as usize).lookup_pd_slot(vptr); - if unlikely(lu_ret.status != exception_t::EXCEPTION_NONE) { - return Ok(()); - } - let pde = ptr_to_mut(lu_ret.pdSlot); - if pde.get_present() && pde.get_base_address() == addr { - *pde = PDE(0); - unsafe { core::arch::asm!("tlbi vmalle1; dsb sy; isb") }; - clean_by_va_pou( - convert_ref_type_to_usize(pde), - paddr_to_pptr(convert_ref_type_to_usize(pde)), - ); - } - Ok(()) - } - _ => unimplemented!("unMapPage: {page_size}"), + let lu_ret = PTE::new_from_pte(find_ret.vspace_root.unwrap() as usize).lookup_pt_slot(vptr); + if unlikely(lu_ret.ptBitsLeft != pageBitsForSize(page_size)) { + return Ok(()); } + + let pte = ptr_to_mut(lu_ret.ptSlot); + if !(pte.get_type() == (pte_tag_t::pte_4k_page) as usize + || pte.get_type() == (pte_tag_t::pte_page) as usize) + { + return Ok(()); + } + if pte.get_page_base_address() != addr { + return Ok(()); + } + unsafe { + *(lu_ret.ptSlot) = PTE(0); + pte.update(*(lu_ret.ptSlot)); + } + assert!(asid < BIT!(16)); + invalidate_tlb_by_asid(asid); + Ok(()) + + // match page_size { + // ARM_Small_Page => { + // let lu_ret = + // PGDE::new_from_pte(find_ret.vspace_root.unwrap() as usize).lookup_pt_slot(vptr); + // if unlikely(lu_ret.status != exception_t::EXCEPTION_NONE) { + // return Ok(()); + // } + // let pte = ptr_to_mut(lu_ret.ptSlot); + // if pte.is_present() && pte.pte_ptr_get_page_base_address() == addr { + // *pte = PTE(0); + // unsafe { core::arch::asm!("tlbi vmalle1; dsb sy; isb") }; + // clean_by_va_pou( + // convert_ref_type_to_usize(pte), + // paddr_to_pptr(convert_ref_type_to_usize(pte)), + // ); + // } + // Ok(()) + // } + // ARM_Large_Page => { + // log::info!("unmap large page: {:#x?}", vptr); + // let lu_ret = + // PGDE::new_from_pte(find_ret.vspace_root.unwrap() as usize).lookup_pd_slot(vptr); + // if unlikely(lu_ret.status != exception_t::EXCEPTION_NONE) { + // return Ok(()); + // } + // let pde = ptr_to_mut(lu_ret.pdSlot); + // if pde.get_present() && pde.get_base_address() == addr { + // *pde = PDE(0); + // unsafe { core::arch::asm!("tlbi vmalle1; dsb sy; isb") }; + // clean_by_va_pou( + // convert_ref_type_to_usize(pde), + // paddr_to_pptr(convert_ref_type_to_usize(pde)), + // ); + // } + // Ok(()) + // } + // _ => unimplemented!("unMapPage: {page_size}"), + // } /* switch (page_size) { case ARMLargePage: { diff --git a/sel4_vspace/src/arch/aarch64/mod.rs b/sel4_vspace/src/arch/aarch64/mod.rs index 34b502c..7c08acf 100644 --- a/sel4_vspace/src/arch/aarch64/mod.rs +++ b/sel4_vspace/src/arch/aarch64/mod.rs @@ -13,6 +13,6 @@ pub use device::*; pub use interface::*; pub use machine::*; pub use pagetable::create_it_pud_cap; -pub use pte::PTEFlags; +pub use pte::{pte_tag_t, PTEFlags}; pub use structures::*; pub use utils::*; diff --git a/sel4_vspace/src/arch/aarch64/pagetable.rs b/sel4_vspace/src/arch/aarch64/pagetable.rs index 506e986..958246d 100644 --- a/sel4_vspace/src/arch/aarch64/pagetable.rs +++ b/sel4_vspace/src/arch/aarch64/pagetable.rs @@ -12,7 +12,7 @@ impl PageTable { #[no_mangle] #[link_section = ".boot.text"] pub fn create_it_pud_cap(vspace_cap: &cap_t, pptr: pptr_t, vptr: vptr_t, asid: usize) -> cap_t { - let cap = cap_t::new_page_upper_directory_cap(asid, pptr, 1, vptr); + let cap = cap_t::new_page_table_cap(asid, pptr, 1, vptr); map_it_pud_cap(vspace_cap, &cap); return cap; } diff --git a/sel4_vspace/src/arch/aarch64/pte.rs b/sel4_vspace/src/arch/aarch64/pte.rs index d26b8a4..07db497 100644 --- a/sel4_vspace/src/arch/aarch64/pte.rs +++ b/sel4_vspace/src/arch/aarch64/pte.rs @@ -1,9 +1,13 @@ -use crate::{arch::aarch64::machine::clean_by_va_pou, vm_attributes_t, PDE, PGDE, PTE, PUDE}; +use crate::{arch::aarch64::machine::clean_by_va_pou, vm_attributes_t, PTE}; use super::utils::paddr_to_pptr; +use super::{mair_types, seL4_VSpaceIndexBits, UPT_LEVELS}; +use crate::{lookupPTSlot_ret_t, vptr_t}; +use sel4_common::utils::ptr_to_mut; +use sel4_common::MASK; use sel4_common::{ arch::vm_rights_t, - sel4_config::seL4_PageTableBits, + sel4_config::{seL4_PageBits, seL4_PageTableBits, PT_INDEX_BITS}, utils::{convert_ref_type_to_usize, convert_to_mut_type_ref}, BIT, }; @@ -28,11 +32,11 @@ impl VMPageSize { } } -#[allow(unused)] -pub enum pgde_tag_t { - pgde_invalid = 0, - pgde_pud = 3, -} +// #[allow(unused)] +// pub enum pgde_tag_t { +// pgde_invalid = 0, +// pgde_pud = 3, +// } #[allow(unused)] pub enum pte_tag_t { @@ -42,18 +46,18 @@ pub enum pte_tag_t { pte_invalid = 0, } -#[allow(unused)] -pub enum pude_tag_t { - pude_invalid = 0, - pude_1g = 1, - pude_pd = 3, -} +// #[allow(unused)] +// pub enum pude_tag_t { +// pude_invalid = 0, +// pude_1g = 1, +// pude_pd = 3, +// } -#[allow(unused)] -pub enum pde_tag_t { - pde_large = 1, - pde_small = 3, -} +// #[allow(unused)] +// pub enum pde_tag_t { +// pde_large = 1, +// pde_small = 3, +// } bitflags::bitflags! { /// Possible flags for a page table entry. @@ -114,8 +118,12 @@ impl PTE { pub fn pte_next_table(addr: usize, _: bool) -> Self { Self::new(addr, PTEFlags::VALID | PTEFlags::NON_BLOCK) } - fn new_4k_page(addr: usize, flags: PTEFlags) -> Self { - Self((addr & 0xfffffffff000) | flags.bits() | 0x400000000000003) + // fn new_4k_page(addr: usize, flags: PTEFlags) -> Self { + // Self((addr & 0xfffffffff000) | flags.bits() | 0x400000000000003) + // } + + pub fn get_page_base_address(&self) -> usize { + self.0 & 0xfffffffff000 } pub fn get_pte_from_ppn_mut(&self) -> &mut PTE { @@ -126,18 +134,23 @@ impl PTE { (self.0 & 0xfffffffff000) >> 10 } - pub fn as_pgde(&self) -> PGDE { - PGDE::new_from_pte(self.0) - } + // pub fn as_pgde(&self) -> PGDE { + // PGDE::new_from_pte(self.0) + // } - pub fn as_pude(&self) -> PUDE { - PUDE::new_from_pte(self.0) - } + // pub fn as_pude(&self) -> PUDE { + // PUDE::new_from_pte(self.0) + // } - pub fn as_pde(&self) -> PDE { - PDE::new_from_pte(self.0) - } + // pub fn as_pde(&self) -> PDE { + // PDE::new_from_pte(self.0) + // } + #[inline] + pub const fn pte_is_page_type(&self) -> bool { + self.get_type() == (pte_tag_t::pte_4k_page) as usize + || self.get_type() == (pte_tag_t::pte_page) as usize + } pub fn is_pte_table(&self) -> bool { self.get_type() != pte_tag_t::pte_table as usize } @@ -174,22 +187,25 @@ impl PTE { ) -> Self { let nonexecutable = attr.get_armExecuteNever(); let cacheable = attr.get_armPageCacheable(); - let mut flags = PTEFlags::NG; + let mut attrindx = mair_types::DEVICE_nGnRnE as usize; if cacheable { - flags |= PTEFlags::NORMAL; - } - if nonexecutable { - flags |= PTEFlags::UXN; + attrindx = mair_types::NORMAL as usize; } - flags |= Self::ap_from_vm_rights_t(rights); + let nG: usize = 1; + let vm_right: usize = Self::ap_from_vm_rights_t(rights).bits() >> 6; if VMPageSize::ARMSmallPage as usize == page_size { - PTE::new_4k_page(paddr, flags) + PTE::pte_new_4k_page(nonexecutable as usize, paddr, nG, 1, 0, vm_right, attrindx) } else { - PTE::new(paddr, flags) + PTE::pte_new_page(nonexecutable as usize, paddr, nG, 1, 0, vm_right, attrindx) } } - pub fn pte_new( + pub fn pte_new_table(pt_base_address: usize) -> PTE { + let val = 0 | (pt_base_address & 0xfffffffff000) | (0x3); + PTE(val) + } + + pub fn pte_new_page( UXN: usize, page_base_address: usize, nG: usize, @@ -197,7 +213,6 @@ impl PTE { SH: usize, AP: usize, AttrIndx: usize, - reserved: usize, ) -> PTE { let val = 0 | (UXN & 0x1) << 54 @@ -207,8 +222,50 @@ impl PTE { | (SH & 0x3) << 8 | (AP & 0x3) << 6 | (AttrIndx & 0x7) << 2 - | (reserved & 0x3) << 0; + | (0x1 << 0); + + PTE(val) + } + pub fn pte_new_4k_page( + UXN: usize, + page_base_address: usize, + nG: usize, + AF: usize, + SH: usize, + AP: usize, + AttrIndx: usize, + ) -> PTE { + let val = 0 + | (UXN & 0x1) << 54 + | (page_base_address & 0xfffffffff000) >> 0 + | (nG & 0x1) << 11 + | (AF & 0x1) << 10 + | (SH & 0x3) << 8 + | (AP & 0x3) << 6 + | (AttrIndx & 0x7) << 2 + | 0x400000000000003; PTE(val) } + ///用于记录某个虚拟地址`vptr`对应的pte表项在内存中的位置 + pub fn lookup_pt_slot(&mut self, vptr: vptr_t) -> lookupPTSlot_ret_t { + let mut pt = self.0 as *mut PTE; + let mut level: usize = UPT_LEVELS - 1; + let ptBitsLeft = PT_INDEX_BITS * level + seL4_PageBits; + pt = unsafe { pt.add((vptr >> ptBitsLeft) & MASK!(seL4_VSpaceIndexBits)) }; + let mut ret: lookupPTSlot_ret_t = lookupPTSlot_ret_t { + ptSlot: pt, + ptBitsLeft: ptBitsLeft, + }; + + while ptr_to_mut(ret.ptSlot).get_type() == (pte_tag_t::pte_table) as usize && level > 0 { + level = level - 1; + ret.ptBitsLeft = ret.ptBitsLeft - PT_INDEX_BITS; + let paddr = ptr_to_mut(ret.ptSlot).next_level_paddr(); + pt = paddr_to_pptr(paddr) as *mut PTE; + pt = unsafe { pt.add((vptr >> ret.ptBitsLeft) & MASK!(PT_INDEX_BITS)) }; + ret.ptSlot = pt; + } + ret + } } diff --git a/sel4_vspace/src/arch/aarch64/structures.rs b/sel4_vspace/src/arch/aarch64/structures.rs index 6002cd5..e883d3e 100644 --- a/sel4_vspace/src/arch/aarch64/structures.rs +++ b/sel4_vspace/src/arch/aarch64/structures.rs @@ -1,9 +1,8 @@ use core::ops::{Deref, DerefMut}; -use crate::{vm_attributes_t, PDE, PGDE, PTE, PUDE}; +use crate::{vm_attributes_t, PTE}; use sel4_common::{ - plus_define_bitfield, sel4_config::asidLowBits, structures::exception_t, - utils::convert_to_mut_type_ref, BIT, + plus_define_bitfield, sel4_config::asidLowBits, utils::convert_to_mut_type_ref, BIT, }; use super::machine::mair_types; @@ -40,34 +39,34 @@ impl vm_attributes_t { #[repr(C)] #[derive(Copy, Clone)] pub struct lookupPTSlot_ret_t { - pub status: exception_t, pub ptSlot: *mut PTE, + pub ptBitsLeft: usize, } -#[repr(C)] -pub struct lookupPGDSlot_ret_t { - pub status: exception_t, - pub pgdSlot: *mut PGDE, // *mut pgde_t -} - -#[repr(C)] -pub struct lookupPDSlot_ret_t { - pub status: exception_t, - pub pdSlot: *mut PDE, // *mut pde_t -} - -#[repr(C)] -pub struct lookupPUDSlot_ret_t { - pub status: exception_t, - pub pudSlot: *mut PUDE, // *mut pude_t -} - -#[repr(C)] -pub struct lookupFrame_ret_t { - pub frameBase: usize, - pub frameSize: usize, - pub valid: bool, -} +// #[repr(C)] +// pub struct lookupPGDSlot_ret_t { +// pub status: exception_t, +// pub pgdSlot: *mut PGDE, // *mut pgde_t +// } + +// #[repr(C)] +// pub struct lookupPDSlot_ret_t { +// pub status: exception_t, +// pub pdSlot: *mut PDE, // *mut pde_t +// } + +// #[repr(C)] +// pub struct lookupPUDSlot_ret_t { +// pub status: exception_t, +// pub pudSlot: *mut PUDE, // *mut pude_t +// } + +// #[repr(C)] +// pub struct lookupFrame_ret_t { +// pub frameBase: usize, +// pub frameSize: usize, +// pub valid: bool, +// } /// 用于存放`asid`对应的根页表基址,是一个`usize`的数组,其中`asid`按低`asidLowBits`位进行索引 #[repr(C)] diff --git a/sel4_vspace/src/arch/aarch64/utils.rs b/sel4_vspace/src/arch/aarch64/utils.rs index 2719e11..5bf28bd 100644 --- a/sel4_vspace/src/arch/aarch64/utils.rs +++ b/sel4_vspace/src/arch/aarch64/utils.rs @@ -1,31 +1,28 @@ -use core::intrinsics::unlikely; - -use super::machine::mair_types; -use super::pte::{pde_tag_t, pgde_tag_t, pude_tag_t}; -use super::structures::{ - lookupFrame_ret_t, lookupPDSlot_ret_t, lookupPGDSlot_ret_t, lookupPTSlot_ret_t, - lookupPUDSlot_ret_t, -}; -use super::{clean_by_va_pou, find_vspace_for_asid, invalidate_tlb_by_asid}; use crate::arch::VAddr; -use crate::vptr_t; -use sel4_common::utils::convert_ref_type_to_usize; +use sel4_common::BIT; use sel4_common::{ arch::{ config::{KERNEL_ELF_BASE_OFFSET, PPTR_BASE_OFFSET}, vm_rights_t, }, - fault::lookup_fault_t, - ffi_addr, sel4_config::*, - structures::exception_t, - utils::{convert_to_mut_slice, convert_to_type_ref}, + utils::convert_to_mut_slice, MASK, }; pub const KPT_LEVELS: usize = 4; +pub const UPT_LEVELS: usize = 4; pub const seL4_VSpaceIndexBits: usize = 9; pub(self) const PAGE_ADDR_MASK: usize = MASK!(48) & !0xfff; +#[inline] +pub fn ULVL_FRM_ARM_PT_LVL(n: usize) -> usize { + n +} +#[inline] +pub fn KLVL_FRM_ARM_PT_LVL(n: usize) -> usize { + n +} + #[inline] pub fn GET_PT_INDEX(addr: usize) -> usize { (addr >> PT_INDEX_OFFSET) & MASK!(PT_INDEX_BITS) @@ -46,17 +43,21 @@ pub fn GET_PUD_INDEX(addr: usize) -> usize { pub fn GET_PGD_INDEX(addr: usize) -> usize { (addr >> PGD_INDEX_OFFSET) & MASK!(PGD_INDEX_BITS) } - #[inline] -pub fn GET_KPT_INDEX(addr: usize, n: usize) -> usize { - ((addr) >> (((PT_INDEX_BITS) * (((KPT_LEVELS) - 1) - (n))) + seL4_PageBits)) - & MASK!(PT_INDEX_BITS) +pub fn KPT_LEVEL_SHIFT(n: usize) -> usize { + ((PT_INDEX_BITS) * (((KPT_LEVELS) - 1) - (n))) + seL4_PageBits } - #[inline] -pub fn GET_UPT_INDEX(addr: usize, n: usize) -> usize { - ((addr) >> (((PT_INDEX_BITS) * (((KPT_LEVELS) - 1) - (n))) + seL4_PageBits)) - & MASK!(PT_INDEX_BITS) +pub fn UPT_LEVEL_SHIFT(n: usize) -> usize { + ((PT_INDEX_BITS) * (((UPT_LEVELS) - 1) - (n))) + seL4_PageBits +} +#[inline] +pub fn GET_ULVL_PGSIZE_BITS(n: usize) -> usize { + UPT_LEVEL_SHIFT(n) +} +#[inline] +pub fn GET_ULVL_PGSIZE(n: usize) -> usize { + BIT!(UPT_LEVEL_SHIFT(n)) } #[inline] @@ -77,6 +78,13 @@ pub fn paddr_to_pptr(x: usize) -> usize { } impl VAddr { + pub(super) fn GET_KPT_INDEX(&self, n: usize) -> usize { + ((self.0) >> (KPT_LEVEL_SHIFT(n))) & MASK!(PT_INDEX_BITS) + } + pub(super) fn GET_UPT_INDEX(&self, n: usize) -> usize { + ((self.0) >> (UPT_LEVEL_SHIFT(n))) & MASK!(PT_INDEX_BITS) + } + /// Get the index of the pt(last level, bit 12..20) pub(super) const fn pt_index(&self) -> usize { (self.0 >> 12) & 0x1ff @@ -119,15 +127,15 @@ pub fn ap_from_vm_rights(rights: vm_rights_t) -> usize { rights as usize } -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct PGDE(pub usize); -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct PUDE(pub usize); -#[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct PDE(pub usize); +// #[repr(C)] +// #[derive(Debug, Clone, Copy)] +// pub struct PGDE(pub usize); +// #[repr(C)] +// #[derive(Debug, Clone, Copy)] +// pub struct PUDE(pub usize); +// #[repr(C)] +// #[derive(Debug, Clone, Copy)] +// pub struct PDE(pub usize); #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct PTE(pub usize); @@ -153,18 +161,18 @@ macro_rules! impl_multi { } } -// Implemente generic function for PGDE PUDE PDE -impl_multi!(PGDE, PUDE, PDE { - /// Get the slice of the next level page. - /// - /// PGDE -> PUDE[PAGE_ITEMS] - #[inline] - pub fn next_level_slice(&self) -> &'static mut [T] { - page_slice(paddr_to_pptr(self.next_level_paddr())) - } -}); +// // Implemente generic function for PGDE PUDE PDE +// impl_multi!(PGDE, PUDE, PDE { +// /// Get the slice of the next level page. +// /// +// /// PGDE -> PUDE[PAGE_ITEMS] +// #[inline] +// pub fn next_level_slice(&self) -> &'static mut [T] { +// page_slice(paddr_to_pptr(self.next_level_paddr())) +// } +// }); -impl_multi!(PGDE, PUDE, PDE, PTE { +impl_multi!( PTE { #[inline] pub fn get_ptr(&self) -> usize { self as *const Self as usize @@ -212,7 +220,7 @@ impl_multi!(PGDE, PUDE, PDE, PTE { /// Get the page's type info #[inline] pub const fn get_type(&self) -> usize { - self.0 & 0x3 + self.0 & 0x3 | ((self.0 &(1<<58) )>>56) } #[inline] @@ -224,364 +232,369 @@ impl_multi!(PGDE, PUDE, PDE, PTE { pub fn invalidate(&mut self) { self.0 = 0; } -}); - -impl PGDE { - #[inline] - pub const fn invalid_new() -> Self { - Self(0) - } - - // static inline pgde_t CONST - // pgde_pgde_pud_new(uint64_t pud_base_address) { - // pgde_t pgde; - - // /* fail if user has passed bits that we will override */ - // assert((pud_base_address & ~0xfffffffff000ull) == ((0 && (pud_base_address & (1ull << 47))) ? 0x0 : 0)); - // assert(((uint64_t)pgde_pgde_pud & ~0x3ull) == ((0 && ((uint64_t)pgde_pgde_pud & (1ull << 47))) ? 0x0 : 0)); - - // pgde.words[0] = 0 - // | (pud_base_address & 0xfffffffff000ull) >> 0 - // | ((uint64_t)pgde_pgde_pud & 0x3ull) << 0; - - // return pgde; - // } - - #[inline] - pub const fn pude_new(pud_base_address: usize) -> Self { - PGDE(pud_base_address & 0xfffffffff000 | pgde_tag_t::pgde_pud as usize) - } - - #[inline] - pub const fn get_pgde_type(&self) -> usize { - self.0 & 0x3 - } #[inline] - pub const fn get_present(&self) -> bool { - self.get_pgde_type() == 3 // pgde_pgde_pud - } - - #[inline] - pub const fn get_pud_base_address(&self) -> usize { - self.0 & 0xfffffffff000 - } - - ///用于记录某个虚拟地址`vptr`对应的pte表项在内存中的位置 - pub fn lookup_pt_slot(&self, vptr: vptr_t) -> lookupPTSlot_ret_t { - let pdSlot = self.lookup_pd_slot(vptr); - if pdSlot.status != exception_t::EXCEPTION_NONE { - let ret = lookupPTSlot_ret_t { - status: pdSlot.status, - ptSlot: 0 as *mut PTE, - }; - return ret; - } - unsafe { - if (*pdSlot.pdSlot).get_present() == false { - *get_current_lookup_fault() = - lookup_fault_t::new_missing_cap(seL4_PageBits + PT_INDEX_BITS); - - let ret = lookupPTSlot_ret_t { - status: exception_t::EXCEPTION_LOOKUP_FAULT, - ptSlot: 0 as *mut PTE, - }; - return ret; - } - } - let ptIndex = GET_PT_INDEX(vptr); - let pt = unsafe { paddr_to_pptr((*pdSlot.pdSlot).get_base_address()) as *mut PTE }; - - let ret = lookupPTSlot_ret_t { - status: exception_t::EXCEPTION_NONE, - ptSlot: unsafe { pt.add(ptIndex) }, - }; - ret - } - - // acturally the lookup pd slot can only be seen under aarch64 and x86 in sel4 - // and in sel4, it should be the impl function of vspace_root_t - // but as it define the pde_t as vspace_root_t and define PTE as vspace_root_t - // so I think it is reasonable here to let those functions as a member funcion of PTE - // commented by ZhiyuanSue - pub fn lookup_pd_slot(&self, vptr: vptr_t) -> lookupPDSlot_ret_t { - let pudSlot: lookupPUDSlot_ret_t = self.lookup_pud_slot(vptr); - if pudSlot.status != exception_t::EXCEPTION_NONE { - let ret = lookupPDSlot_ret_t { - status: pudSlot.status, - pdSlot: 0 as *mut PDE, - }; - return ret; - } - unsafe { - if (*pudSlot.pudSlot).get_present() == false { - *get_current_lookup_fault() = - lookup_fault_t::new_missing_cap(seL4_PageBits + PT_INDEX_BITS + PD_INDEX_BITS); - - let ret = lookupPDSlot_ret_t { - status: exception_t::EXCEPTION_LOOKUP_FAULT, - pdSlot: 0 as *mut PDE, - }; - return ret; - } - } - let pdIndex = GET_PD_INDEX(vptr); - let pd = unsafe { paddr_to_pptr((*pudSlot.pudSlot).get_pd_base_address()) as *mut PDE }; - - let ret = lookupPDSlot_ret_t { - status: exception_t::EXCEPTION_NONE, - pdSlot: unsafe { pd.add(pdIndex) }, - }; - ret - } - - pub fn lookup_pud_slot(&self, vptr: vptr_t) -> lookupPUDSlot_ret_t { - let pgdSlot = self.lookup_pgd_slot(vptr); - unsafe { - if (*pgdSlot.pgdSlot).get_present() == false { - *get_current_lookup_fault() = lookup_fault_t::new_missing_cap( - seL4_PageBits + PT_INDEX_BITS + PD_INDEX_BITS + PUD_INDEX_BITS, - ); - let ret = lookupPUDSlot_ret_t { - status: exception_t::EXCEPTION_LOOKUP_FAULT, - pudSlot: 0 as *mut PUDE, - }; - return ret; - } - } - let pudIndex = GET_UPUD_INDEX(vptr); - let pud = unsafe { paddr_to_pptr((*pgdSlot.pgdSlot).get_pud_base_address()) as *mut PUDE }; - let ret = lookupPUDSlot_ret_t { - status: exception_t::EXCEPTION_NONE, - pudSlot: unsafe { pud.add(pudIndex) }, - }; - ret - } - - pub fn lookup_pgd_slot(&self, vptr: vptr_t) -> lookupPGDSlot_ret_t { - let pgdIndex = GET_PGD_INDEX(vptr); - let ret = lookupPGDSlot_ret_t { - status: exception_t::EXCEPTION_NONE, - pgdSlot: unsafe { (self.0 as *mut PGDE).add(pgdIndex) }, - }; - ret - } - pub fn lookup_frame(&self, vptr: vptr_t) -> lookupFrame_ret_t { - let mut ret = lookupFrame_ret_t { - valid: false, - frameBase: 0, - frameSize: 0, - }; - let pudSlot = self.lookup_pud_slot(vptr); - if pudSlot.status != exception_t::EXCEPTION_NONE { - ret.valid = false; - return ret; - } - let pudSlot = convert_to_type_ref::(pudSlot.pudSlot as usize); - unsafe { - match core::mem::transmute::(pudSlot.get_type() as _) { - pude_tag_t::pude_1g => { - ret.frameBase = pudSlot.pude_1g_ptr_get_page_base_address(); - ret.frameSize = ARM_Huge_Page; - ret.valid = true; - return ret; - } - pude_tag_t::pude_pd => { - let pdSlot: &PDE = pudSlot.next_level_slice()[GET_PD_INDEX(vptr)]; - - if pdSlot.get_type() == pde_tag_t::pde_large as usize { - ret.frameBase = pdSlot.pde_large_ptr_get_page_base_address(); - ret.frameSize = ARM_Large_Page; - ret.valid = true; - return ret; - } - - if pdSlot.get_type() == pde_tag_t::pde_small as usize { - let ptSlot: &PTE = pdSlot.next_level_slice()[GET_PT_INDEX(vptr)]; - if ptSlot.pte_table_get_present() { - ret.frameBase = ptSlot.pte_ptr_get_page_base_address(); - ret.frameSize = ARM_Small_Page; - ret.valid = true; - return ret; - } - } - } - _ => panic!("invalid pt slot type:{}", pudSlot.get_type()), - } - } - ret - } -} - -impl PUDE { - #[inline] - pub const fn invalid_new() -> Self { - Self(0) - } - - #[inline] - pub const fn new_1g( - uxn: bool, - page_base_address: usize, - ng: usize, - af: usize, - sh: usize, - ap: usize, - attr_index: mair_types, - ) -> Self { - Self( - (uxn as usize & 0x1) << 54 - | (page_base_address & 0xffffc0000000) - | (ng & 0x1) << 11 - | (af & 0x1) << 10 - | (sh & 0x1) << 8 - | (ap & 0x1) << 6 - | (attr_index as usize & 0x7) << 2 - | 0x1, // pude_1g_tag - ) - } - - #[inline] - pub const fn pd_new(pd_base_address: usize) -> Self { - Self((pd_base_address & 0xfffffffff000) | (pude_tag_t::pude_pd as usize & 0x3)) - } - - #[inline] - pub const fn get_pude_type(&self) -> usize { - self.0 & 0x3 - } - - // Check whether the pude is a 1g huge page. - #[inline] - pub const fn is_1g_page(&self) -> bool { - self.0 & 0x3 == 1 - } - - #[inline] - pub const fn get_present(&self) -> bool { - self.get_pude_type() == 3 // pude_pude_pd - } - - #[inline] - pub fn pude_1g_ptr_get_page_base_address(&self) -> usize { - self.0 & 0xffffc0000000 - } - #[inline] - pub fn get_pd_base_address(&self) -> usize { - self.0 & 0xfffffffff000 - } - - #[inline] - pub fn unmap_page_upper_directory(&self, asid: usize, vptr: vptr_t) { - let find_ret = find_vspace_for_asid(asid); - if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { - return; - } - - let pt = find_ret.vspace_root.unwrap(); - if pt as usize == 0 { - return; - } - - let lu_ret = unsafe { (*pt).lookup_pgd_slot(vptr) }; - let pgdSlot = unsafe { &mut *lu_ret.pgdSlot }; - if lu_ret.pgdSlot as usize != 0 { - if pgdSlot.get_present() && pgdSlot.get_pud_base_address() == pptr_to_paddr(self.0) { - *pgdSlot = PGDE::invalid_new(); - clean_by_va_pou( - convert_ref_type_to_usize(pgdSlot), - pptr_to_paddr(convert_ref_type_to_usize(pgdSlot)), - ); - invalidate_tlb_by_asid(asid); - } - } - } -} - -impl PDE { - #[inline] - pub const fn new_large( - uxn: bool, - page_base_address: usize, - ng: usize, - af: usize, - sh: usize, - ap: usize, - attr_index: mair_types, - ) -> Self { - Self( - (uxn as usize & 0x1) << 54 - | (page_base_address & 0xffffffe00000) - | (ng & 0x1) << 11 - | (af & 0x1) << 10 - | (sh & 0x1) << 8 - | (ap & 0x1) << 6 - | (attr_index as usize & 0x7) << 2 - | 0x1, // pde_large_tag - ) - } - - #[inline] - pub const fn new_small(pt_base_address: usize) -> Self { - Self((pt_base_address & 0xfffffffff000) | (pde_tag_t::pde_small as usize & 0x3)) - } - - #[inline] - pub const fn new_invalid() -> Self { - Self(0) - } - - #[inline] - pub const fn get_pde_type(&self) -> usize { - self.0 & 0x3 - } - - #[inline] - pub const fn get_present(&self) -> bool { - self.get_pde_type() == 3 // pde_pde_small - } - - /// Check whether it is a 2M huge page. - #[inline] - pub const fn is_larger_page(&self) -> bool { - self.get_pde_type() == 3 - } - - #[inline] - pub const fn pde_large_ptr_get_page_base_address(&self) -> usize { - self.0 & 0xffffffe00000 - } - - #[inline] - pub const fn get_base_address(&self) -> usize { - self.0 & 0xfffffffff000 + pub fn next_level_slice(&self) -> &'static mut [T] { + page_slice(paddr_to_pptr(self.next_level_paddr())) } +}); - #[inline] - pub fn unmap_page_directory(&self, asid: usize, vaddr: usize) { - let find_ret = find_vspace_for_asid(asid); - if find_ret.status != exception_t::EXCEPTION_NONE { - return; - } - - let pt = unsafe { &mut *(find_ret.vspace_root.unwrap()) }; - let lu_ret = pt.lookup_pud_slot(vaddr); - if lu_ret.status != exception_t::EXCEPTION_NONE { - return; - } - - let pud = unsafe { &mut *lu_ret.pudSlot }; - - if pud.get_present() && pud.get_pd_base_address() == pptr_to_paddr(self.0) { - pud.invalidate(); - clean_by_va_pou( - convert_ref_type_to_usize(pud), - pptr_to_paddr(convert_ref_type_to_usize(pud)), - ); - invalidate_tlb_by_asid(asid); - } - } -} +// impl PGDE { +// #[inline] +// pub const fn invalid_new() -> Self { +// Self(0) +// } + +// // static inline pgde_t CONST +// // pgde_pgde_pud_new(uint64_t pud_base_address) { +// // pgde_t pgde; + +// // /* fail if user has passed bits that we will override */ +// // assert((pud_base_address & ~0xfffffffff000ull) == ((0 && (pud_base_address & (1ull << 47))) ? 0x0 : 0)); +// // assert(((uint64_t)pgde_pgde_pud & ~0x3ull) == ((0 && ((uint64_t)pgde_pgde_pud & (1ull << 47))) ? 0x0 : 0)); + +// // pgde.words[0] = 0 +// // | (pud_base_address & 0xfffffffff000ull) >> 0 +// // | ((uint64_t)pgde_pgde_pud & 0x3ull) << 0; + +// // return pgde; +// // } + +// #[inline] +// pub const fn pude_new(pud_base_address: usize) -> Self { +// PGDE(pud_base_address & 0xfffffffff000 | pgde_tag_t::pgde_pud as usize) +// } + +// #[inline] +// pub const fn get_pgde_type(&self) -> usize { +// self.0 & 0x3 +// } + +// #[inline] +// pub const fn get_present(&self) -> bool { +// self.get_pgde_type() == 3 // pgde_pgde_pud +// } + +// #[inline] +// pub const fn get_pud_base_address(&self) -> usize { +// self.0 & 0xfffffffff000 +// } + +// ///用于记录某个虚拟地址`vptr`对应的pte表项在内存中的位置 +// pub fn lookup_pt_slot(&self, vptr: vptr_t) -> lookupPTSlot_ret_t { +// let pdSlot = self.lookup_pd_slot(vptr); +// if pdSlot.status != exception_t::EXCEPTION_NONE { +// let ret = lookupPTSlot_ret_t { +// status: pdSlot.status, +// ptSlot: 0 as *mut PTE, +// }; +// return ret; +// } +// unsafe { +// if (*pdSlot.pdSlot).get_present() == false { +// *get_current_lookup_fault() = +// lookup_fault_t::new_missing_cap(seL4_PageBits + PT_INDEX_BITS); + +// let ret = lookupPTSlot_ret_t { +// status: exception_t::EXCEPTION_LOOKUP_FAULT, +// ptSlot: 0 as *mut PTE, +// }; +// return ret; +// } +// } +// let ptIndex = GET_PT_INDEX(vptr); +// let pt = unsafe { paddr_to_pptr((*pdSlot.pdSlot).get_base_address()) as *mut PTE }; + +// let ret = lookupPTSlot_ret_t { +// status: exception_t::EXCEPTION_NONE, +// ptSlot: unsafe { pt.add(ptIndex) }, +// }; +// ret +// } + +// // acturally the lookup pd slot can only be seen under aarch64 and x86 in sel4 +// // and in sel4, it should be the impl function of vspace_root_t +// // but as it define the pde_t as vspace_root_t and define PTE as vspace_root_t +// // so I think it is reasonable here to let those functions as a member funcion of PTE +// // commented by ZhiyuanSue +// pub fn lookup_pd_slot(&self, vptr: vptr_t) -> lookupPDSlot_ret_t { +// let pudSlot: lookupPUDSlot_ret_t = self.lookup_pud_slot(vptr); +// if pudSlot.status != exception_t::EXCEPTION_NONE { +// let ret = lookupPDSlot_ret_t { +// status: pudSlot.status, +// pdSlot: 0 as *mut PDE, +// }; +// return ret; +// } +// unsafe { +// if (*pudSlot.pudSlot).get_present() == false { +// *get_current_lookup_fault() = +// lookup_fault_t::new_missing_cap(seL4_PageBits + PT_INDEX_BITS + PD_INDEX_BITS); + +// let ret = lookupPDSlot_ret_t { +// status: exception_t::EXCEPTION_LOOKUP_FAULT, +// pdSlot: 0 as *mut PDE, +// }; +// return ret; +// } +// } +// let pdIndex = GET_PD_INDEX(vptr); +// let pd = unsafe { paddr_to_pptr((*pudSlot.pudSlot).get_pd_base_address()) as *mut PDE }; + +// let ret = lookupPDSlot_ret_t { +// status: exception_t::EXCEPTION_NONE, +// pdSlot: unsafe { pd.add(pdIndex) }, +// }; +// ret +// } + +// pub fn lookup_pud_slot(&self, vptr: vptr_t) -> lookupPUDSlot_ret_t { +// let pgdSlot = self.lookup_pgd_slot(vptr); +// unsafe { +// if (*pgdSlot.pgdSlot).get_present() == false { +// *get_current_lookup_fault() = lookup_fault_t::new_missing_cap( +// seL4_PageBits + PT_INDEX_BITS + PD_INDEX_BITS + PUD_INDEX_BITS, +// ); +// let ret = lookupPUDSlot_ret_t { +// status: exception_t::EXCEPTION_LOOKUP_FAULT, +// pudSlot: 0 as *mut PUDE, +// }; +// return ret; +// } +// } +// let pudIndex = GET_UPUD_INDEX(vptr); +// let pud = unsafe { paddr_to_pptr((*pgdSlot.pgdSlot).get_pud_base_address()) as *mut PUDE }; +// let ret = lookupPUDSlot_ret_t { +// status: exception_t::EXCEPTION_NONE, +// pudSlot: unsafe { pud.add(pudIndex) }, +// }; +// ret +// } + +// pub fn lookup_pgd_slot(&self, vptr: vptr_t) -> lookupPGDSlot_ret_t { +// let pgdIndex = GET_PGD_INDEX(vptr); +// let ret = lookupPGDSlot_ret_t { +// status: exception_t::EXCEPTION_NONE, +// pgdSlot: unsafe { (self.0 as *mut PGDE).add(pgdIndex) }, +// }; +// ret +// } +// pub fn lookup_frame(&self, vptr: vptr_t) -> lookupFrame_ret_t { +// let mut ret = lookupFrame_ret_t { +// valid: false, +// frameBase: 0, +// frameSize: 0, +// }; +// let pudSlot = self.lookup_pud_slot(vptr); +// if pudSlot.status != exception_t::EXCEPTION_NONE { +// ret.valid = false; +// return ret; +// } +// let pudSlot = convert_to_type_ref::(pudSlot.pudSlot as usize); +// unsafe { +// match core::mem::transmute::(pudSlot.get_type() as _) { +// pude_tag_t::pude_1g => { +// ret.frameBase = pudSlot.pude_1g_ptr_get_page_base_address(); +// ret.frameSize = ARM_Huge_Page; +// ret.valid = true; +// return ret; +// } +// pude_tag_t::pude_pd => { +// let pdSlot: &PDE = pudSlot.next_level_slice()[GET_PD_INDEX(vptr)]; + +// if pdSlot.get_type() == pde_tag_t::pde_large as usize { +// ret.frameBase = pdSlot.pde_large_ptr_get_page_base_address(); +// ret.frameSize = ARM_Large_Page; +// ret.valid = true; +// return ret; +// } + +// if pdSlot.get_type() == pde_tag_t::pde_small as usize { +// let ptSlot: &PTE = pdSlot.next_level_slice()[GET_PT_INDEX(vptr)]; +// if ptSlot.pte_table_get_present() { +// ret.frameBase = ptSlot.pte_ptr_get_page_base_address(); +// ret.frameSize = ARM_Small_Page; +// ret.valid = true; +// return ret; +// } +// } +// } +// _ => panic!("invalid pt slot type:{}", pudSlot.get_type()), +// } +// } +// ret +// } +// } + +// impl PUDE { +// #[inline] +// pub const fn invalid_new() -> Self { +// Self(0) +// } + +// #[inline] +// pub const fn new_1g( +// uxn: bool, +// page_base_address: usize, +// ng: usize, +// af: usize, +// sh: usize, +// ap: usize, +// attr_index: mair_types, +// ) -> Self { +// Self( +// (uxn as usize & 0x1) << 54 +// | (page_base_address & 0xffffc0000000) +// | (ng & 0x1) << 11 +// | (af & 0x1) << 10 +// | (sh & 0x1) << 8 +// | (ap & 0x1) << 6 +// | (attr_index as usize & 0x7) << 2 +// | 0x1, // pude_1g_tag +// ) +// } + +// #[inline] +// pub const fn pd_new(pd_base_address: usize) -> Self { +// Self((pd_base_address & 0xfffffffff000) | (pude_tag_t::pude_pd as usize & 0x3)) +// } + +// #[inline] +// pub const fn get_pude_type(&self) -> usize { +// self.0 & 0x3 +// } + +// // Check whether the pude is a 1g huge page. +// #[inline] +// pub const fn is_1g_page(&self) -> bool { +// self.0 & 0x3 == 1 +// } + +// #[inline] +// pub const fn get_present(&self) -> bool { +// self.get_pude_type() == 3 // pude_pude_pd +// } + +// #[inline] +// pub fn pude_1g_ptr_get_page_base_address(&self) -> usize { +// self.0 & 0xffffc0000000 +// } +// #[inline] +// pub fn get_pd_base_address(&self) -> usize { +// self.0 & 0xfffffffff000 +// } + +// #[inline] +// pub fn unmap_page_upper_directory(&self, asid: usize, vptr: vptr_t) { +// let find_ret = find_vspace_for_asid(asid); +// if unlikely(find_ret.status != exception_t::EXCEPTION_NONE) { +// return; +// } + +// let pt = find_ret.vspace_root.unwrap(); +// if pt as usize == 0 { +// return; +// } + +// let lu_ret = unsafe { (*pt).lookup_pgd_slot(vptr) }; +// let pgdSlot = unsafe { &mut *lu_ret.pgdSlot }; +// if lu_ret.pgdSlot as usize != 0 { +// if pgdSlot.get_present() && pgdSlot.get_pud_base_address() == pptr_to_paddr(self.0) { +// *pgdSlot = PGDE::invalid_new(); +// clean_by_va_pou( +// convert_ref_type_to_usize(pgdSlot), +// pptr_to_paddr(convert_ref_type_to_usize(pgdSlot)), +// ); +// invalidate_tlb_by_asid(asid); +// } +// } +// } +// } + +// impl PDE { +// #[inline] +// pub const fn new_large( +// uxn: bool, +// page_base_address: usize, +// ng: usize, +// af: usize, +// sh: usize, +// ap: usize, +// attr_index: mair_types, +// ) -> Self { +// Self( +// (uxn as usize & 0x1) << 54 +// | (page_base_address & 0xffffffe00000) +// | (ng & 0x1) << 11 +// | (af & 0x1) << 10 +// | (sh & 0x1) << 8 +// | (ap & 0x1) << 6 +// | (attr_index as usize & 0x7) << 2 +// | 0x1, // pde_large_tag +// ) +// } + +// #[inline] +// pub const fn new_small(pt_base_address: usize) -> Self { +// Self((pt_base_address & 0xfffffffff000) | (pde_tag_t::pde_small as usize & 0x3)) +// } + +// #[inline] +// pub const fn new_invalid() -> Self { +// Self(0) +// } + +// #[inline] +// pub const fn get_pde_type(&self) -> usize { +// self.0 & 0x3 +// } + +// #[inline] +// pub const fn get_present(&self) -> bool { +// self.get_pde_type() == 3 // pde_pde_small +// } + +// /// Check whether it is a 2M huge page. +// #[inline] +// pub const fn is_larger_page(&self) -> bool { +// self.get_pde_type() == 3 +// } + +// #[inline] +// pub const fn pde_large_ptr_get_page_base_address(&self) -> usize { +// self.0 & 0xffffffe00000 +// } + +// #[inline] +// pub const fn get_base_address(&self) -> usize { +// self.0 & 0xfffffffff000 +// } + +// #[inline] +// pub fn unmap_page_directory(&self, asid: usize, vaddr: usize) { +// let find_ret = find_vspace_for_asid(asid); +// if find_ret.status != exception_t::EXCEPTION_NONE { +// return; +// } + +// let pt = unsafe { &mut *(find_ret.vspace_root.unwrap()) }; +// let lu_ret = pt.lookup_pud_slot(vaddr); +// if lu_ret.status != exception_t::EXCEPTION_NONE { +// return; +// } + +// let pud = unsafe { &mut *lu_ret.pudSlot }; + +// if pud.get_present() && pud.get_pd_base_address() == pptr_to_paddr(self.0) { +// pud.invalidate(); +// clean_by_va_pou( +// convert_ref_type_to_usize(pud), +// pptr_to_paddr(convert_ref_type_to_usize(pud)), +// ); +// invalidate_tlb_by_asid(asid); +// } +// } +// } impl PTE { #[inline] @@ -600,11 +613,11 @@ impl PTE { } } -/// Get current lookup fault object. -pub(super) fn get_current_lookup_fault() -> &'static mut lookup_fault_t { - unsafe { - (ffi_addr!(current_lookup_fault) as *mut lookup_fault_t) - .as_mut() - .unwrap() - } -} +// /// Get current lookup fault object. +// pub(super) fn get_current_lookup_fault() -> &'static mut lookup_fault_t { +// unsafe { +// (ffi_addr!(current_lookup_fault) as *mut lookup_fault_t) +// .as_mut() +// .unwrap() +// } +// } diff --git a/sel4_vspace/src/structures.rs b/sel4_vspace/src/structures.rs index e57af7f..1b502fa 100644 --- a/sel4_vspace/src/structures.rs +++ b/sel4_vspace/src/structures.rs @@ -5,9 +5,6 @@ use core::{ use sel4_common::{arch::config::PPTR_BASE, fault::lookup_fault_t, structures::exception_t}; -#[cfg(target_arch = "aarch64")] -use crate::PGDE; -#[cfg(target_arch = "riscv64")] use crate::PTE; /// 在`PSpace`段的虚拟地址空间中的指针 @@ -35,7 +32,7 @@ pub struct findVSpaceForASID_ret { #[derive(Copy, Clone)] pub struct findVSpaceForASID_ret { pub status: exception_t, - pub vspace_root: Option<*mut PGDE>, + pub vspace_root: Option<*mut PTE>, pub lookup_fault: Option, }