77
88use 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
1219use crate :: hw;
1320use crate :: pgtable:: { self , DumpedPage , Prot , UAT_PGSZ } ;
1421use crate :: util:: align;
15- use kernel:: uapi;
1622
1723pub ( crate ) struct CrashDump {
1824 headers : KVVec < u8 > ,
1925 pages : KVVec < Owned < Page > > ,
2026}
2127
22- const NOTE_NAME_AGX : & str = & "AGX" ;
28+ const NOTE_NAME_AGX : & str = "AGX" ;
2329const NOTE_AGX_DUMP_INFO : u32 = 1 ;
2430
25- const NOTE_NAME_RTKIT : & str = & "RTKIT" ;
31+ const NOTE_NAME_RTKIT : & str = "RTKIT" ;
2632const NOTE_RTKIT_CRASHLOG : u32 = 1 ;
2733
2834#[ repr( C ) ]
@@ -47,8 +53,12 @@ pub(crate) struct CrashDumpBuilder {
4753 notes : KVec < ELFNote > ,
4854}
4955
50- // Helper to convert ELF headers into byte slices
51- // TODO: Hook this up into kernel::AsBytes somehow
56+ /// Helper to convert ELF headers into byte slices
57+ /// TODO: Hook this up into kernel::AsBytes somehow
58+ ///
59+ /// # Safety
60+ ///
61+ /// Types implementing this trait must have no padding bytes.
5262unsafe trait AsBytes : Sized {
5363 fn as_bytes ( & self ) -> & [ u8 ] {
5464 // SAFETY: This trait is only implemented for types with no padding bytes
@@ -57,10 +67,7 @@ unsafe trait AsBytes: Sized {
5767 fn slice_as_bytes ( slice : & [ Self ] ) -> & [ u8 ] {
5868 // SAFETY: This trait is only implemented for types with no padding bytes
5969 unsafe {
60- core:: slice:: from_raw_parts (
61- slice. as_ptr ( ) as * const u8 ,
62- slice. len ( ) * size_of :: < Self > ( ) ,
63- )
70+ core:: slice:: from_raw_parts ( slice. as_ptr ( ) as * const u8 , core:: mem:: size_of_val ( slice) )
6471 }
6572 }
6673}
@@ -118,7 +125,7 @@ impl CrashDumpBuilder {
118125
119126 pub ( crate ) fn add_crashlog ( & mut self , crashlog : & [ u8 ] ) -> Result {
120127 let mut data = KVVec :: new ( ) ;
121- data. extend_from_slice ( & crashlog, GFP_KERNEL ) ?;
128+ data. extend_from_slice ( crashlog, GFP_KERNEL ) ?;
122129
123130 self . notes . push (
124131 ELFNote {
@@ -143,7 +150,7 @@ impl CrashDumpBuilder {
143150 ehdr. e_ident [ uapi:: EI_VERSION as usize ] = uapi:: EV_CURRENT as u8 ;
144151 ehdr. e_type = uapi:: ET_CORE as u16 ;
145152 ehdr. e_machine = uapi:: EM_AARCH64 as u16 ;
146- ehdr. e_version = uapi:: EV_CURRENT as u32 ;
153+ ehdr. e_version = uapi:: EV_CURRENT ;
147154 ehdr. e_entry = FIRMWARE_ENTRYPOINT ;
148155 ehdr. e_ehsize = core:: mem:: size_of :: < uapi:: Elf64_Ehdr > ( ) as u16 ;
149156 ehdr. e_phentsize = core:: mem:: size_of :: < uapi:: Elf64_Phdr > ( ) as u16 ;
@@ -188,7 +195,6 @@ impl CrashDumpBuilder {
188195 p_memsz : UAT_PGSZ as u64 ,
189196 p_flags : flags,
190197 p_align : UAT_PGSZ as u64 ,
191- ..Default :: default ( )
192198 } ,
193199 GFP_KERNEL ,
194200 ) ?;
@@ -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+ }
0 commit comments