Skip to content

Commit 12604ea

Browse files
hoshinolinajannau
authored andcommitted
rust: devcoredump: Add devcoredump abstraction
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 4eaffa3 commit 12604ea

3 files changed

Lines changed: 81 additions & 0 deletions

File tree

rust/bindings/bindings_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/blkdev.h>
2323
#include <linux/cred.h>
2424
#include <linux/delay.h>
25+
#include <linux/devcoredump.h>
2526
#include <linux/dma-fence.h>
2627
#include <linux/dma-fence-chain.h>
2728
#include <linux/dma-mapping.h>

rust/kernel/devcoredump.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// SPDX-License-Identifier: GPL-2.0-only OR MIT
2+
3+
//! Device coredump support.
4+
//!
5+
//! C header: [`include/linux/devcoredump.h`](../../../../include/linux/devcoredump.h)
6+
7+
use crate::{
8+
alloc, bindings, device, error::from_result, prelude::Result, time::Jiffies,
9+
types::ForeignOwnable, ThisModule,
10+
};
11+
12+
use core::ops::Deref;
13+
14+
/// The default timeout for device coredumps.
15+
pub const DEFAULT_TIMEOUT: Jiffies = bindings::DEVCD_TIMEOUT as Jiffies;
16+
17+
/// Trait to implement reading from a device coredump.
18+
///
19+
/// Users must implement this trait to provide device coredump support.
20+
pub trait DevCoreDump {
21+
/// Returns the IOVA (virtual address) of the buffer from RTKit's point of view, or an error if
22+
/// unavailable.
23+
fn read(&self, buf: &mut [u8], offset: usize) -> Result<usize>;
24+
}
25+
26+
unsafe extern "C" fn read_callback<
27+
'a,
28+
T: ForeignOwnable<Borrowed<'a>: Deref<Target = D>>,
29+
D: DevCoreDump,
30+
>(
31+
buffer: *mut crate::ffi::c_char,
32+
offset: bindings::loff_t,
33+
count: usize,
34+
data: *mut crate::ffi::c_void,
35+
_datalen: usize,
36+
) -> isize {
37+
// SAFETY: This pointer came from into_foreign() below.
38+
let coredump = unsafe { T::borrow(data) };
39+
// SAFETY: The caller guarantees `buffer` points to at least `count` bytes.
40+
let buf = unsafe { core::slice::from_raw_parts_mut(buffer, count) };
41+
42+
from_result(|| Ok(coredump.read(buf, offset.try_into()?)?.try_into()?))
43+
}
44+
45+
unsafe extern "C" fn free_callback<
46+
'a,
47+
T: ForeignOwnable<Borrowed<'a>: Deref<Target = D>>,
48+
D: DevCoreDump,
49+
>(
50+
data: *mut crate::ffi::c_void,
51+
) {
52+
// SAFETY: This pointer came from into_foreign() below.
53+
unsafe {
54+
T::from_foreign(data);
55+
}
56+
}
57+
58+
/// Registers a coredump for the given device.
59+
pub fn dev_coredump<'a, T: ForeignOwnable<Borrowed<'a>: Deref<Target = D>>, D: DevCoreDump>(
60+
dev: &device::Device,
61+
module: &'static ThisModule,
62+
coredump: T,
63+
gfp: alloc::Flags,
64+
timeout: Jiffies,
65+
) {
66+
// SAFETY: Call upholds dev_coredumpm lifetime requirements.
67+
unsafe {
68+
bindings::dev_coredumpm_timeout(
69+
dev.as_raw(),
70+
module.0,
71+
coredump.into_foreign() as *mut _,
72+
0,
73+
gfp.as_raw(),
74+
Some(read_callback::<'a, T, D>),
75+
Some(free_callback::<'a, T, D>),
76+
timeout,
77+
)
78+
}
79+
}

rust/kernel/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ pub mod block;
5050
pub mod build_assert;
5151
pub mod cred;
5252
pub mod delay;
53+
pub mod devcoredump;
5354
pub mod device;
5455
pub mod device_id;
5556
pub mod devres;

0 commit comments

Comments
 (0)