pkru.rs 1.5 KB

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