xref: /DragonOS/kernel/src/arch/x86_64/mm/pkru.rs (revision cf7f801e1d50ee5b04cb728e4251a57f4183bfbc)
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>) -> u1618a17651b1SMemoryShore pub 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) -> bool29a17651b1SMemoryShore pub 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) -> bool42a17651b1SMemoryShore pub 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) -> bool47a17651b1SMemoryShore pub 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() -> u3252a17651b1SMemoryShore pub 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