xref: /DragonOS/kernel/src/arch/x86_64/mm/pkru.rs (revision 731bc2b32d7b37298883d7a15b6dca659b436ee4)
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();
20     ((guard.vm_flags().bits() & PKEY_MASK as u64) >> 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