Skip to content

Commit 40898fe

Browse files
committed
drm/asahi: alloc: Use tag as the guard marker
To more easily debug GPU/FW-side overreads, use the alloc tag to fill the padding instead of using a constant. Signed-off-by: Asahi Lina <[email protected]>
1 parent 9c95305 commit 40898fe

1 file changed

Lines changed: 30 additions & 14 deletions

File tree

drivers/gpu/drm/asahi/alloc.rs

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ pub(crate) struct GenericAlloc<T, U: RawAllocation> {
7878
alloc_size: usize,
7979
debug_offset: usize,
8080
padding: usize,
81+
tag: u32,
82+
pad_word: u32,
8183
_p: PhantomData<T>,
8284
}
8385

@@ -125,7 +127,7 @@ const STATE_LIVE: u32 = u32::from_le_bytes(*b"LIVE");
125127
const STATE_DEAD: u32 = u32::from_le_bytes(*b"DEAD");
126128

127129
/// Marker byte to identify when firmware/GPU write beyond the end of an allocation.
128-
const GUARD_MARKER: u8 = 0x93;
130+
const GUARD_MARKER: u32 = 0x93939393;
129131

130132
impl<T, U: RawAllocation> Drop for GenericAlloc<T, U> {
131133
fn drop(&mut self) {
@@ -151,20 +153,26 @@ impl<T, U: RawAllocation> Drop for GenericAlloc<T, U> {
151153
self.padding,
152154
)
153155
};
154-
if let Some(first_err) = guard.iter().position(|&r| r != GUARD_MARKER) {
155-
let last_err = guard
156-
.iter()
157-
.rev()
158-
.position(|&r| r != GUARD_MARKER)
159-
.unwrap_or(0);
156+
let mut first_err = None;
157+
let mut last_err = 0;
158+
for (i, p) in guard.iter().enumerate() {
159+
if *p != (self.pad_word >> (8 * (i & 3))) as u8 {
160+
if first_err.is_none() {
161+
first_err = Some(i);
162+
}
163+
last_err = i;
164+
}
165+
}
166+
if let Some(start) = first_err {
160167
dev_warn!(
161168
self.device(),
162-
"Allocator: Corruption after object of type {} at {:#x}:{:#x} + {:#x}..={:#x}\n",
169+
"Allocator: Corruption after object of type {}/{:#x} at {:#x}:{:#x} + {:#x}..={:#x}\n",
163170
core::any::type_name::<T>(),
171+
self.tag,
164172
self.gpu_ptr(),
165173
self.size(),
166-
first_err,
167-
self.padding - last_err - 1
174+
start,
175+
last_err,
168176
);
169177
}
170178
}
@@ -336,6 +344,8 @@ pub(crate) trait Allocator {
336344
alloc,
337345
alloc_size: size,
338346
debug_offset,
347+
tag: tag.unwrap_or(0),
348+
pad_word: tag.unwrap_or(GUARD_MARKER) | 0x81818181,
339349
padding,
340350
_p: PhantomData,
341351
}
@@ -344,6 +354,8 @@ pub(crate) trait Allocator {
344354
alloc: self.alloc(size + padding, align)?,
345355
alloc_size: size,
346356
debug_offset: 0,
357+
tag: tag.unwrap_or(0),
358+
pad_word: tag.unwrap_or(GUARD_MARKER) | 0x81818181,
347359
padding,
348360
_p: PhantomData,
349361
}
@@ -357,10 +369,14 @@ pub(crate) trait Allocator {
357369

358370
if padding != 0 {
359371
if let Some(p) = ret.ptr() {
360-
unsafe {
361-
(p.as_ptr() as *mut u8)
362-
.add(ret.size())
363-
.write_bytes(GUARD_MARKER, padding);
372+
let guard = unsafe {
373+
core::slice::from_raw_parts_mut(
374+
(p.as_ptr() as *mut u8).add(ret.size()),
375+
padding,
376+
)
377+
};
378+
for (i, p) in guard.iter_mut().enumerate() {
379+
*p = (ret.pad_word >> (8 * (i & 3))) as u8;
364380
}
365381
}
366382
}

0 commit comments

Comments
 (0)