1 use alloc::sync::Arc; 2 3 use crate::mm::ucontext::LockedVMA; 4 5 const VM_PKEY_SHIFT: usize = 32; 6 7 /// X86_64架构的ProtectionKey使用32、33、34、35四个比特位 8 const PKEY_MASK: usize = 1 << 32 | 1 << 33 | 1 << 34 | 1 << 35; 9 10 /// 获取vma的protection_key 11 /// 12 /// ## 参数 13 /// 14 /// - `vma`: VMA 15 /// 16 /// ## 返回值 17 /// - `u16`: vma的protection_key 18 pub fn vma_pkey(vma: Arc<LockedVMA>) -> u16 { 19 let guard = vma.lock_irqsave(); 20 ((guard.vm_flags().bits() & PKEY_MASK) >> VM_PKEY_SHIFT) as u16 21 } 22 23 // TODO pkru实现参考:https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/include/asm/pkru.h 24 25 const PKRU_AD_BIT: u16 = 0x1; 26 const PKRU_WD_BIT: u16 = 0x2; 27 const PKRU_BITS_PER_PKEY: u32 = 2; 28 29 pub fn pkru_allows_pkey(pkey: u16, write: bool) -> bool { 30 let pkru = read_pkru(); 31 32 if !pkru_allows_read(pkru, pkey) { 33 return false; 34 } 35 if write & !pkru_allows_write(pkru, pkey) { 36 return false; 37 } 38 39 true 40 } 41 42 pub fn pkru_allows_read(pkru: u32, pkey: u16) -> bool { 43 let pkru_pkey_bits: u32 = pkey as u32 * PKRU_BITS_PER_PKEY; 44 pkru & ((PKRU_AD_BIT as u32) << pkru_pkey_bits) > 0 45 } 46 47 pub fn pkru_allows_write(pkru: u32, pkey: u16) -> bool { 48 let pkru_pkey_bits: u32 = pkey as u32 * PKRU_BITS_PER_PKEY; 49 pkru & (((PKRU_AD_BIT | PKRU_WD_BIT) as u32) << pkru_pkey_bits) > 0 50 } 51 52 pub fn read_pkru() -> u32 { 53 // TODO 实现读取pkru逻辑 54 // https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/include/asm/pkru.h?fi=read_pkru#read_pkru 55 0 56 } 57