Skip to content

Commit

Permalink
Mi dev vspace 6 (#48)
Browse files Browse the repository at this point in the history
* try to adjust the root cap code from PTE to PGDE

* change to the PGDE and rename to the vspaceroot,etc.

* fix the pde new small
  • Loading branch information
ZhiyuanSue authored Jul 17, 2024
1 parent c672dda commit 318ca6f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 73 deletions.
1 change: 0 additions & 1 deletion src/boot/root_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ fn asid_init(root_cnode_cap: cap_t, it_pd_cap: cap_t) -> bool {
}
#[cfg(target_arch = "aarch64")]
{

write_it_asid_pool(&it_ap_cap, &it_pd_cap);
}
true
Expand Down
72 changes: 48 additions & 24 deletions src/syscall/invocation/decode/arch/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ use sel4_common::{
MASK,
};
use sel4_cspace::interface::{cap_t, cte_t, CapTag};
use sel4_vspace::{checkVPAlignment, find_vspace_for_asid, makeUser3rdLevel, make_user_1st_level, make_user_2nd_level, pptr_to_paddr, vm_attributes_t, PDE, PTE, PUDE};
use sel4_vspace::{
checkVPAlignment, find_vspace_for_asid, makeUser3rdLevel, make_user_1st_level,
make_user_2nd_level, pptr_to_paddr, vm_attributes_t, PDE, PGDE, PTE, PUDE,
};

use crate::syscall::invocation::invoke_mmu_op::{
invoke_asid_control, invoke_asid_pool, invoke_huge_page_map, invoke_large_page_map,
Expand Down Expand Up @@ -146,10 +149,13 @@ fn decode_frame_map(
}
let vaddr = get_syscall_arg(0, buffer);
let attr = vm_attributes_t::from_word(get_syscall_arg(2, buffer));
let lvl1pt_cap = get_extra_cap_by_index(0).unwrap().cap;
let frame_vm_rights = unsafe { core::mem::transmute(frame_slot.cap.get_frame_vm_rights()) };
let vm_rights = maskVMRights(frame_vm_rights, seL4_CapRights_t::from_word(get_syscall_arg(1, buffer)));
if let Some((lvl1pt, asid)) = get_vspace(&lvl1pt_cap) {
let vspaceRootCap = get_extra_cap_by_index(0).unwrap().cap;
let frame_vm_rights = unsafe { core::mem::transmute(frame_slot.cap.get_frame_vm_rights()) };
let vm_rights = maskVMRights(
frame_vm_rights,
seL4_CapRights_t::from_word(get_syscall_arg(1, buffer)),
);
if let Some((vspaceRoot, asid)) = get_vspace(&vspaceRootCap) {
let frame_size = frame_slot.cap.get_frame_size();
if unlikely(!checkVPAlignment(frame_size, vaddr)) {
unsafe {
Expand Down Expand Up @@ -189,7 +195,7 @@ fn decode_frame_map(
let base = pptr_to_paddr(frame_slot.cap.get_frame_base_ptr());

if frame_size == ARM_Small_Page {
let lu_ret = lvl1pt.lookup_pt_slot(vaddr);
let lu_ret = vspaceRoot.lookup_pt_slot(vaddr);
if lu_ret.status != exception_t::EXCEPTION_NONE {
unsafe {
current_syscall_error._type = seL4_FailedLookup;
Expand All @@ -199,9 +205,15 @@ fn decode_frame_map(
}
set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart);
let ptSlot = convert_to_mut_type_ref::<PTE>(lu_ret.ptSlot as usize);
invoke_small_page_map(vaddr,asid, frame_slot, makeUser3rdLevel(base, vm_rights, attr),ptSlot)
invoke_small_page_map(
vaddr,
asid,
frame_slot,
makeUser3rdLevel(base, vm_rights, attr),
ptSlot,
)
} else if frame_size == ARM_Large_Page {
let lu_ret = lvl1pt.lookup_pd_slot(vaddr);
let lu_ret = vspaceRoot.lookup_pd_slot(vaddr);
if lu_ret.status != exception_t::EXCEPTION_NONE {
unsafe {
current_syscall_error._type = seL4_FailedLookup;
Expand All @@ -211,9 +223,15 @@ fn decode_frame_map(
}
set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart);
let pdSlot = convert_to_mut_type_ref::<PDE>(lu_ret.pdSlot as usize);
invoke_large_page_map(vaddr,asid, frame_slot,make_user_2nd_level(base, vm_rights, attr), pdSlot)
invoke_large_page_map(
vaddr,
asid,
frame_slot,
make_user_2nd_level(base, vm_rights, attr),
pdSlot,
)
} else if frame_size == ARM_Huge_Page {
let lu_ret = lvl1pt.lookup_pud_slot(vaddr);
let lu_ret = vspaceRoot.lookup_pud_slot(vaddr);
if lu_ret.status != exception_t::EXCEPTION_NONE {
unsafe {
current_syscall_error._type = seL4_FailedLookup;
Expand All @@ -223,7 +241,13 @@ fn decode_frame_map(
}
set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart);
let pudSlot = convert_to_mut_type_ref::<PUDE>(lu_ret.pudSlot as usize);
invoke_huge_page_map(vaddr,asid, frame_slot,make_user_1st_level(base, vm_rights, attr), pudSlot)
invoke_huge_page_map(
vaddr,
asid,
frame_slot,
make_user_1st_level(base, vm_rights, attr),
pudSlot,
)
} else {
return exception_t::EXCEPTION_SYSCALL_ERROR;
}
Expand Down Expand Up @@ -277,10 +301,10 @@ fn decode_page_table_map(
}
return exception_t::EXCEPTION_SYSCALL_ERROR;
}
let lvl1pt_cap = get_extra_cap_by_index(0).unwrap().cap;
let vspaceRootCap = get_extra_cap_by_index(0).unwrap().cap;

if let Some((lvl1pt, asid)) = get_vspace(&lvl1pt_cap) {
let pd_ret = lvl1pt.lookup_pd_slot(vaddr);
if let Some((vspaceRoot, asid)) = get_vspace(&vspaceRootCap) {
let pd_ret = vspaceRoot.lookup_pd_slot(vaddr);
if pd_ret.status != exception_t::EXCEPTION_NONE {
debug!("ARMPageTableMap: Invalid pd Slot");
unsafe {
Expand All @@ -296,17 +320,17 @@ fn decode_page_table_map(
}
return exception_t::EXCEPTION_SYSCALL_ERROR;
}
let pdSlot = convert_to_mut_type_ref::<PTE>(pd_ret.pdSlot as usize);
let pdSlot = convert_to_mut_type_ref::<PDE>(pd_ret.pdSlot as usize);
set_thread_state(get_currenct_thread(), ThreadState::ThreadStateRestart);
return invoke_page_table_map(cap, pdSlot, asid, vaddr & !MASK!(PD_INDEX_OFFSET));
} else {
return exception_t::EXCEPTION_SYSCALL_ERROR;
}
}

fn get_vspace(lvl1pt_cap: &cap_t) -> Option<(&mut PTE, usize)> {
if lvl1pt_cap.get_cap_type() != CapTag::CapPageGlobalDirectoryCap
|| lvl1pt_cap.get_pgd_is_mapped() == asidInvalid
fn get_vspace(vspaceRootCap: &cap_t) -> Option<(&mut PGDE, usize)> {
if vspaceRootCap.get_cap_type() != CapTag::CapPageGlobalDirectoryCap
|| vspaceRootCap.get_pgd_is_mapped() == asidInvalid
{
debug!("ARMMMUInvocation: Invalid top-level PageTable.");
unsafe {
Expand All @@ -316,12 +340,12 @@ fn get_vspace(lvl1pt_cap: &cap_t) -> Option<(&mut PTE, usize)> {
return None;
}

let lvl1pt = convert_to_mut_type_ref::<PTE>(lvl1pt_cap.get_pt_base_ptr());
let asid = lvl1pt_cap.get_pt_mapped_asid();
let vspaceRoot = convert_to_mut_type_ref::<PGDE>(vspaceRootCap.get_pgd_base_ptr());
let asid = vspaceRootCap.get_pgd_mapped_asid();

let find_ret = find_vspace_for_asid(asid);
if find_ret.status != exception_t::EXCEPTION_NONE {
debug!("ARMMMUInvocation: ASID lookup failed");
debug!("ARMMMUInvocation: ASID lookup failed1");
unsafe {
current_lookup_fault = find_ret.lookup_fault.unwrap();
current_syscall_error._type = seL4_FailedLookup;
Expand All @@ -330,15 +354,15 @@ fn get_vspace(lvl1pt_cap: &cap_t) -> Option<(&mut PTE, usize)> {
return None;
}

if find_ret.vspace_root.unwrap() as usize != lvl1pt.get_ptr() {
debug!("ARMMMUInvocation: ASID lookup failed");
if find_ret.vspace_root.unwrap() as usize != vspaceRoot.get_ptr() {
debug!("ARMMMUInvocation: ASID lookup failed2");
unsafe {
current_syscall_error._type = seL4_InvalidCapability;
current_syscall_error.invalidCapNumber = 1;
}
return None;
}
Some((lvl1pt, asid))
Some((vspaceRoot, asid))
}

fn decode_vspace_root_invocation(
Expand Down
99 changes: 51 additions & 48 deletions src/syscall/invocation/invoke_mmu_op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use core::arch::asm;
use sel4_common::arch::{maskVMRights, ArchReg};
use sel4_common::cap_rights::seL4_CapRights_t;
use sel4_common::utils::MAX_FREE_INDEX;
#[cfg(target_arch = "aarch64")]
use sel4_common::BIT;
use sel4_common::MASK;
use sel4_common::{
message_info::seL4_MessageInfo_t,
Expand All @@ -19,9 +21,7 @@ use sel4_vspace::{
#[cfg(target_arch = "riscv64")]
use sel4_vspace::{copyGlobalMappings, sfence};
#[cfg(target_arch = "aarch64")]
use sel4_vspace::{PDE, PUDE,invalidate_tlb_by_asid_va};
#[cfg(target_arch = "aarch64")]
use sel4_common::BIT;
use sel4_vspace::{invalidate_tlb_by_asid_va, PDE, PUDE};

use crate::{kernel::boot::current_lookup_fault, utils::clear_memory};

Expand All @@ -34,35 +34,40 @@ pub fn invoke_page_table_unmap(cap: &mut cap_t) -> exception_t {
cap.set_pt_is_mapped(0);
exception_t::EXCEPTION_NONE
}

#[cfg(target_arch = "riscv64")]
pub fn invoke_page_table_map(
pt_cap: &mut cap_t,
pt_slot: &mut PTE,
asid: usize,
vaddr: usize,
) -> exception_t {
let paddr = pptr_to_paddr(pt_cap.get_pt_base_ptr());
#[cfg(target_arch = "riscv64")]
{
let pte = PTE::new(paddr >> seL4_PageBits, PTEFlags::V);
*pt_slot = pte;
}
#[cfg(target_arch = "aarch64")]
{
let pde = PTE::new(paddr >> seL4_PageBits, PTEFlags::VALID);
*pt_slot = pde;
}
let pte = PTE::new(paddr >> seL4_PageBits, PTEFlags::V);
*pt_slot = pte;
pt_cap.set_pt_is_mapped(1);
pt_cap.set_pt_mapped_asid(asid);
pt_cap.set_pt_mapped_address(vaddr);
#[cfg(target_arch = "riscv64")]
sfence();
#[cfg(target_arch = "aarch64")]
exception_t::EXCEPTION_NONE
}
#[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) pt_slot,
in(reg) pd_slot,
);
}
exception_t::EXCEPTION_NONE
Expand Down Expand Up @@ -126,81 +131,79 @@ pub fn invoke_page_map(
}
#[cfg(target_arch = "aarch64")]
pub fn invoke_huge_page_map(
vaddr: usize,
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;
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);
}
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_large_page_map(
vaddr: usize,
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 {
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);
}
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,
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 {
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.pte_ptr_get_present();
if tlbflush_required{
assert!(asid <BIT!(16));
invalidate_tlb_by_asid_va(asid, vaddr);
}
let tlbflush_required = ptSlot.pte_ptr_get_present();
if tlbflush_required {
assert!(asid < BIT!(16));
invalidate_tlb_by_asid_va(asid, vaddr);
}
exception_t::EXCEPTION_NONE
}

Expand Down

0 comments on commit 318ca6f

Please sign in to comment.