@@ -23,6 +23,11 @@ use kernel::{
2323#[ cfg( CONFIG_DEV_COREDUMP ) ]
2424use kernel:: {
2525 types:: Owned ,
26+ uapi:: {
27+ PF_R ,
28+ PF_W ,
29+ PF_X , //
30+ } ,
2631} ;
2732
2833use crate :: debug:: * ;
@@ -64,8 +69,8 @@ const PTE_TYPE_LEAF_TABLE: u64 = 3;
6469const UAT_NON_GLOBAL : u64 = 1 << 11 ;
6570const UAT_AP_SHIFT : u32 = 6 ;
6671const UAT_AP_BITS : u64 = 3 << UAT_AP_SHIFT ;
67- const UAT_HIGH_BITS_SHIFT : u32 = 53 ;
68- const UAT_HIGH_BITS : u64 = 7 << UAT_HIGH_BITS_SHIFT ;
72+ const UAT_HIGH_BITS_SHIFT : u32 = 52 ;
73+ const UAT_HIGH_BITS : u64 = 0xfff << UAT_HIGH_BITS_SHIFT ;
6974const UAT_MEMATTR_SHIFT : u32 = 2 ;
7075const UAT_MEMATTR_BITS : u64 = 7 << UAT_MEMATTR_SHIFT ;
7176
@@ -81,15 +86,18 @@ const AP_FW_GPU: u8 = 0;
8186const AP_FW : u8 = 1 ;
8287const AP_GPU : u8 = 2 ;
8388
84- const HIGH_BITS_PXN : u8 = 1 << 0 ;
85- const HIGH_BITS_UXN : u8 = 1 << 1 ;
86- const HIGH_BITS_GPU_ACCESS : u8 = 1 << 2 ;
89+ const HIGH_BITS_PXN : u16 = 1 << 1 ;
90+ const HIGH_BITS_UXN : u16 = 1 << 2 ;
91+ const HIGH_BITS_GPU_ACCESS : u16 = 1 << 3 ;
92+
93+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
94+ pub ( crate ) const PTE_ADDR_BITS : u64 = ( !UAT_PGMSK as u64 ) & ( !UAT_HIGH_BITS ) ;
8795
8896#[ derive( Debug , Copy , Clone ) ]
8997pub ( crate ) struct Prot {
9098 memattr : u8 ,
9199 ap : u8 ,
92- high_bits : u8 ,
100+ high_bits : u16 ,
93101}
94102
95103// Firmware + GPU access
@@ -110,6 +118,27 @@ const PROT_GPU_WO: Prot = Prot::from_bits(AP_GPU, 0, 1);
110118const PROT_GPU_RW : Prot = Prot :: from_bits ( AP_GPU , 1 , 0 ) ;
111119const _PROT_GPU_NA: Prot = Prot :: from_bits ( AP_GPU , 1 , 1 ) ;
112120
121+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
122+ const PF_RW : u32 = PF_R | PF_W ;
123+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
124+ const PF_RX : u32 = PF_R | PF_X ;
125+
126+ // For crash dumps
127+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
128+ const PROT_TO_PERMS_FW : [ [ u32 ; 4 ] ; 4 ] = [
129+ [ 0 , 0 , 0 , PF_RW ] ,
130+ [ 0 , PF_RW , 0 , PF_RW ] ,
131+ [ PF_RX , PF_RX , 0 , PF_R ] ,
132+ [ PF_RX , PF_RW , 0 , PF_R ] ,
133+ ] ;
134+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
135+ const PROT_TO_PERMS_OS : [ [ u32 ; 4 ] ; 4 ] = [
136+ [ 0 , PF_R , PF_W , PF_RW ] ,
137+ [ PF_R , 0 , PF_RW , PF_RW ] ,
138+ [ 0 , 0 , 0 , 0 ] ,
139+ [ 0 , 0 , 0 , 0 ] ,
140+ ] ;
141+
113142pub ( crate ) mod prot {
114143 pub ( crate ) use super :: Prot ;
115144 use super :: * ;
@@ -139,7 +168,7 @@ pub(crate) mod prot {
139168}
140169
141170impl Prot {
142- const fn from_bits ( ap : u8 , uxn : u8 , pxn : u8 ) -> Self {
171+ const fn from_bits ( ap : u8 , uxn : u16 , pxn : u16 ) -> Self {
143172 assert ! ( uxn <= 1 ) ;
144173 assert ! ( pxn <= 1 ) ;
145174 assert ! ( ap <= 3 ) ;
@@ -151,6 +180,44 @@ impl Prot {
151180 }
152181 }
153182
183+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
184+ pub ( crate ) const fn from_pte ( pte : u64 ) -> Self {
185+ Prot {
186+ high_bits : ( pte >> UAT_HIGH_BITS_SHIFT ) as u16 ,
187+ ap : ( ( pte & UAT_AP_BITS ) >> UAT_AP_SHIFT ) as u8 ,
188+ memattr : ( ( pte & UAT_MEMATTR_BITS ) >> UAT_MEMATTR_SHIFT ) as u8 ,
189+ }
190+ }
191+
192+ #[ cfg( CONFIG_DEV_COREDUMP ) ]
193+ pub ( crate ) const fn elf_flags ( & self ) -> u32 {
194+ let ap = ( self . ap & 3 ) as usize ;
195+ let uxn = if self . high_bits & HIGH_BITS_UXN != 0 {
196+ 1
197+ } else {
198+ 0
199+ } ;
200+ let pxn = if self . high_bits & HIGH_BITS_PXN != 0 {
201+ 1
202+ } else {
203+ 0
204+ } ;
205+ let gpu = self . high_bits & HIGH_BITS_GPU_ACCESS != 0 ;
206+
207+ // Format:
208+ // [12 top bits of PTE] [12 bottom bits of PTE] [5 bits pad] [ELF RWX]
209+ let mut perms = if gpu {
210+ PROT_TO_PERMS_OS [ ap] [ ( uxn << 1 ) | pxn]
211+ } else {
212+ PROT_TO_PERMS_FW [ ap] [ ( uxn << 1 ) | pxn]
213+ } ;
214+
215+ perms |= ( ( self . as_pte ( ) >> 52 ) << 20 ) as u32 ;
216+ perms |= ( ( self . as_pte ( ) & 0xfff ) << 8 ) as u32 ;
217+
218+ perms
219+ }
220+
154221 const fn memattr ( & self , memattr : u8 ) -> Self {
155222 Self { memattr, ..* self }
156223 }
0 commit comments