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