Skip to content

Commit 02f1441

Browse files
hoshinolinajannau
authored andcommitted
rust: devcoredump: Add devcoredump abstraction
Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 267a96e commit 02f1441

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
@@ -46,6 +46,7 @@
4646
#include <linux/completion.h>
4747
#include <linux/cpumask.h>
4848
#include <linux/cred.h>
49+
#include <linux/devcoredump.h>
4950
#include <linux/device/faux.h>
5051
#include <linux/dma-direction.h>
5152
#include <linux/dma-fence.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.cast()) };
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.cast());
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
@@ -71,6 +71,7 @@ pub mod block;
7171
#[doc(hidden)]
7272
pub mod build_assert;
7373
pub mod cred;
74+
pub mod devcoredump;
7475
pub mod device;
7576
pub mod device_id;
7677
pub mod devres;

0 commit comments

Comments
 (0)