Skip to content

Commit fc6b64a

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

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::*;
@@ -51,8 +52,8 @@ const PTE_TYPE_LEAF_TABLE: u64 = 3;
5152

5253
const UAT_AP_SHIFT: u32 = 6;
5354
const UAT_AP_BITS: u64 = 3 << UAT_AP_SHIFT;
54-
const UAT_HIGH_BITS_SHIFT: u32 = 53;
55-
const UAT_HIGH_BITS: u64 = 7 << UAT_HIGH_BITS_SHIFT;
55+
const UAT_HIGH_BITS_SHIFT: u32 = 52;
56+
const UAT_HIGH_BITS: u64 = 0xfff << UAT_HIGH_BITS_SHIFT;
5657
const UAT_MEMATTR_SHIFT: u32 = 2;
5758
const UAT_MEMATTR_BITS: u64 = 7 << UAT_MEMATTR_SHIFT;
5859

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

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

7578
#[derive(Debug, Copy, Clone)]
7679
pub(crate) struct Prot {
7780
memattr: u8,
7881
ap: u8,
79-
high_bits: u8,
82+
high_bits: u16,
8083
}
8184

8285
// Firmware + GPU access
@@ -97,6 +100,23 @@ const PROT_GPU_WO: Prot = Prot::from_bits(AP_GPU, 0, 1);
97100
const PROT_GPU_RW: Prot = Prot::from_bits(AP_GPU, 1, 0);
98101
const _PROT_GPU_NA: Prot = Prot::from_bits(AP_GPU, 1, 1);
99102

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

128148
impl Prot {
129-
const fn from_bits(ap: u8, uxn: u8, pxn: u8) -> Self {
149+
const fn from_bits(ap: u8, uxn: u16, pxn: u16) -> Self {
130150
assert!(uxn <= 1);
131151
assert!(pxn <= 1);
132152
assert!(ap <= 3);
@@ -138,6 +158,42 @@ impl Prot {
138158
}
139159
}
140160

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

0 commit comments

Comments
 (0)