Skip to content

Commit 106437e

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: pgtable: Add helpers for decoding PTE perms
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent c1c9fb9 commit 106437e

1 file changed

Lines changed: 63 additions & 7 deletions

File tree

drivers/gpu/drm/asahi/pgtable.rs

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use core::mem::size_of;
1111
use core::ops::Range;
1212
use core::sync::atomic::{AtomicU64, Ordering};
1313

14+
use kernel::uapi::{PF_R, PF_W, PF_X};
1415
use kernel::{addr::PhysicalAddr, error::Result, page::Page, prelude::*, types::Owned};
1516

1617
use crate::debug::*;
@@ -52,8 +53,8 @@ const PTE_TYPE_LEAF_TABLE: u64 = 3;
5253
const UAT_NON_GLOBAL: u64 = 1 << 11;
5354
const UAT_AP_SHIFT: u32 = 6;
5455
const UAT_AP_BITS: u64 = 3 << UAT_AP_SHIFT;
55-
const UAT_HIGH_BITS_SHIFT: u32 = 53;
56-
const UAT_HIGH_BITS: u64 = 7 << UAT_HIGH_BITS_SHIFT;
56+
const UAT_HIGH_BITS_SHIFT: u32 = 52;
57+
const UAT_HIGH_BITS: u64 = 0xfff << UAT_HIGH_BITS_SHIFT;
5758
const UAT_MEMATTR_SHIFT: u32 = 2;
5859
const UAT_MEMATTR_BITS: u64 = 7 << UAT_MEMATTR_SHIFT;
5960

@@ -69,15 +70,17 @@ const AP_FW_GPU: u8 = 0;
6970
const AP_FW: u8 = 1;
7071
const AP_GPU: u8 = 2;
7172

72-
const HIGH_BITS_PXN: u8 = 1 << 0;
73-
const HIGH_BITS_UXN: u8 = 1 << 1;
74-
const HIGH_BITS_GPU_ACCESS: u8 = 1 << 2;
73+
const HIGH_BITS_PXN: u16 = 1 << 1;
74+
const HIGH_BITS_UXN: u16 = 1 << 2;
75+
const HIGH_BITS_GPU_ACCESS: u16 = 1 << 3;
76+
77+
pub(crate) const PTE_ADDR_BITS: u64 = (!UAT_PGMSK as u64) & (!UAT_HIGH_BITS);
7578

7679
#[derive(Debug, Copy, Clone)]
7780
pub(crate) struct Prot {
7881
memattr: u8,
7982
ap: u8,
80-
high_bits: u8,
83+
high_bits: u16,
8184
}
8285

8386
// Firmware + GPU access
@@ -98,6 +101,23 @@ const PROT_GPU_WO: Prot = Prot::from_bits(AP_GPU, 0, 1);
98101
const PROT_GPU_RW: Prot = Prot::from_bits(AP_GPU, 1, 0);
99102
const _PROT_GPU_NA: Prot = Prot::from_bits(AP_GPU, 1, 1);
100103

104+
const PF_RW: u32 = PF_R | PF_W;
105+
const PF_RX: u32 = PF_R | PF_X;
106+
107+
// For crash dumps
108+
const PROT_TO_PERMS_FW: [[u32; 4]; 4] = [
109+
[0, 0, 0, PF_RW],
110+
[0, PF_RW, 0, PF_RW],
111+
[PF_RX, PF_RX, 0, PF_R],
112+
[PF_RX, PF_RW, 0, PF_R],
113+
];
114+
const PROT_TO_PERMS_OS: [[u32; 4]; 4] = [
115+
[0, PF_R, PF_W, PF_RW],
116+
[PF_R, 0, PF_RW, PF_RW],
117+
[0, 0, 0, 0],
118+
[0, 0, 0, 0],
119+
];
120+
101121
pub(crate) mod prot {
102122
pub(crate) use super::Prot;
103123
use super::*;
@@ -127,7 +147,7 @@ pub(crate) mod prot {
127147
}
128148

129149
impl Prot {
130-
const fn from_bits(ap: u8, uxn: u8, pxn: u8) -> Self {
150+
const fn from_bits(ap: u8, uxn: u16, pxn: u16) -> Self {
131151
assert!(uxn <= 1);
132152
assert!(pxn <= 1);
133153
assert!(ap <= 3);
@@ -139,6 +159,42 @@ impl Prot {
139159
}
140160
}
141161

162+
pub(crate) const fn from_pte(pte: u64) -> Self {
163+
Prot {
164+
high_bits: (pte >> UAT_HIGH_BITS_SHIFT) as u16,
165+
ap: ((pte & UAT_AP_BITS) >> UAT_AP_SHIFT) as u8,
166+
memattr: ((pte & UAT_MEMATTR_BITS) >> UAT_MEMATTR_SHIFT) as u8,
167+
}
168+
}
169+
170+
pub(crate) const fn elf_flags(&self) -> u32 {
171+
let ap = (self.ap & 3) as usize;
172+
let uxn = if self.high_bits & HIGH_BITS_UXN != 0 {
173+
1
174+
} else {
175+
0
176+
};
177+
let pxn = if self.high_bits & HIGH_BITS_PXN != 0 {
178+
1
179+
} else {
180+
0
181+
};
182+
let gpu = self.high_bits & HIGH_BITS_GPU_ACCESS != 0;
183+
184+
// Format:
185+
// [12 top bits of PTE] [12 bottom bits of PTE] [5 bits pad] [ELF RWX]
186+
let mut perms = if gpu {
187+
PROT_TO_PERMS_OS[ap][(uxn << 1) | pxn]
188+
} else {
189+
PROT_TO_PERMS_FW[ap][(uxn << 1) | pxn]
190+
};
191+
192+
perms |= ((self.as_pte() >> 52) << 20) as u32;
193+
perms |= ((self.as_pte() & 0xfff) << 8) as u32;
194+
195+
perms
196+
}
197+
142198
const fn memattr(&self, memattr: u8) -> Self {
143199
Self { memattr, ..*self }
144200
}

0 commit comments

Comments
 (0)