Skip to content

Commit a87a3a1

Browse files
hoshinolinajannau
authored andcommitted
drm/asahi: Hook up crashdump to devcoredump
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 12604ea commit a87a3a1

4 files changed

Lines changed: 62 additions & 9 deletions

File tree

drivers/gpu/drm/asahi/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ config DRM_ASAHI
2525
select RUST_DRM_GEM_SHMEM_HELPER
2626
select RUST_DRM_GPUVM
2727
select RUST_APPLE_RTKIT
28+
select WANT_DEV_COREDUMP
2829
help
2930
DRM driver for Apple AGX GPUs (G13x, found in the M1 SoC family)
3031

drivers/gpu/drm/asahi/asahi.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
mod alloc;
77
mod buffer;
88
mod channel;
9+
#[cfg(CONFIG_DEV_COREDUMP)]
910
mod crashdump;
1011
mod debug;
1112
mod driver;

drivers/gpu/drm/asahi/crashdump.rs

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,18 @@
77
88
use core::mem::size_of;
99

10-
use kernel::{error::Result, page::Page, prelude::*, types::Owned};
10+
use kernel::{
11+
devcoredump::DevCoreDump,
12+
error::Result,
13+
page::{Page, PAGE_MASK, PAGE_SHIFT, PAGE_SIZE},
14+
prelude::*,
15+
types::Owned,
16+
uapi,
17+
};
1118

1219
use crate::hw;
1320
use crate::pgtable::{self, DumpedPage, Prot, UAT_PGSZ};
1421
use crate::util::align;
15-
use kernel::uapi;
1622

1723
pub(crate) struct CrashDump {
1824
headers: KVVec<u8>,
@@ -261,3 +267,39 @@ impl CrashDumpBuilder {
261267
Ok(CrashDump { headers, pages })
262268
}
263269
}
270+
271+
impl DevCoreDump for CrashDump {
272+
fn read(&self, buf: &mut [u8], mut offset: usize) -> Result<usize> {
273+
let mut read = 0;
274+
let mut left = buf.len();
275+
if offset < self.headers.len() {
276+
let block = left.min(self.headers.len() - offset);
277+
buf[..block].copy_from_slice(&self.headers[offset..offset + block]);
278+
read += block;
279+
offset += block;
280+
left -= block;
281+
}
282+
if left == 0 {
283+
return Ok(read);
284+
}
285+
offset -= self.headers.len(); // Offset from the page area
286+
287+
while left > 0 {
288+
let page_index = offset >> PAGE_SHIFT;
289+
let page_offset = offset & !PAGE_MASK;
290+
let block = left.min(PAGE_SIZE - page_offset);
291+
let Some(page) = self.pages.get(page_index) else {
292+
break;
293+
};
294+
let slice = &mut buf[read..read + block];
295+
// SAFETY: We own the page, and the slice guarantees the
296+
// dst length is sufficient.
297+
unsafe { page.read_raw(slice.as_mut_ptr(), page_offset, slice.len())? };
298+
read += block;
299+
offset += block;
300+
left -= block;
301+
}
302+
303+
Ok(read)
304+
}
305+
}

drivers/gpu/drm/asahi/gpu.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use core::sync::atomic::{AtomicBool, AtomicU64, Ordering};
1717
use core::time::Duration;
1818

1919
use kernel::{
20-
c_str,
20+
c_str, devcoredump,
2121
error::code::*,
2222
macros::versions,
2323
prelude::*,
@@ -26,7 +26,7 @@ use kernel::{
2626
lock::{mutex::MutexBackend, Guard},
2727
Arc, Mutex, UniqueArc,
2828
},
29-
time::{clock, Now},
29+
time::{clock, msecs_to_jiffies, Now},
3030
types::ForeignOwnable,
3131
};
3232

@@ -36,8 +36,7 @@ use crate::driver::{AsahiDevRef, AsahiDevice, AsahiDriver};
3636
use crate::fw::channels::{ChannelErrorType, PipeType};
3737
use crate::fw::types::{U32, U64};
3838
use crate::{
39-
alloc, buffer, channel, crashdump, event, fw, gem, hw, initdata, mem, mmu, queue, regs,
40-
workqueue,
39+
alloc, buffer, channel, event, fw, gem, hw, initdata, mem, mmu, queue, regs, workqueue,
4140
};
4241

4342
const DEBUG_CLASS: DebugFlags = DebugFlags::Gpu;
@@ -336,8 +335,9 @@ impl rtkit::Operations for GpuManager::ver {
336335

337336
data.crashed.store(true, Ordering::Relaxed);
338337

338+
#[cfg(CONFIG_DEV_COREDUMP)]
339339
if let Err(e) = data.generate_crashdump(crashlog) {
340-
dev_err!(dev.as_ref(), "Could not dump kernel VM pages: {:?}\n", e);
340+
dev_err!(dev.as_ref(), "Could not generate crashdump: {:?}\n", e);
341341
}
342342

343343
if debug_enabled(DebugFlags::OopsOnGpuCrash) {
@@ -1123,19 +1123,28 @@ impl GpuManager::ver {
11231123
Ok(())
11241124
}
11251125

1126+
#[cfg(CONFIG_DEV_COREDUMP)]
11261127
fn generate_crashdump(&self, crashlog: Option<&[u8]>) -> Result {
11271128
// Lock the allocators, to block kernel/FW memory mutations (mostly)
11281129
let kalloc = self.alloc();
11291130
let pages = self.uat.dump_kernel_pages()?;
11301131
core::mem::drop(kalloc);
11311132

1132-
let mut crashdump = crashdump::CrashDumpBuilder::new(pages)?;
1133+
let mut crashdump = crate::crashdump::CrashDumpBuilder::new(pages)?;
11331134
let initdata_addr = self.initdata.gpu_va().get();
11341135
crashdump.add_agx_info(self.cfg, &self.dyncfg, initdata_addr)?;
11351136
if let Some(crashlog) = crashlog {
11361137
crashdump.add_crashlog(crashlog)?;
11371138
}
1138-
let crashdump = crashdump.finalize();
1139+
let crashdump = KBox::new(crashdump.finalize()?, GFP_KERNEL)?;
1140+
1141+
devcoredump::dev_coredump(
1142+
self.dev.as_ref(),
1143+
&crate::THIS_MODULE,
1144+
crashdump,
1145+
GFP_KERNEL,
1146+
msecs_to_jiffies(60 * 60 * 1000),
1147+
);
11391148

11401149
Ok(())
11411150
}

0 commit comments

Comments
 (0)