@@ -11,6 +11,7 @@ use core::mem::size_of;
1111use core:: ops:: Range ;
1212use core:: sync:: atomic:: { AtomicU64 , Ordering } ;
1313
14+ use kernel:: uapi:: { PF_R , PF_W , PF_X } ;
1415use kernel:: { addr:: PhysicalAddr , error:: Result , page:: Page , prelude:: * , types:: Owned } ;
1516
1617use crate :: debug:: * ;
@@ -52,8 +53,8 @@ const PTE_TYPE_LEAF_TABLE: u64 = 3;
5253const UAT_NON_GLOBAL : u64 = 1 << 11 ;
5354const UAT_AP_SHIFT : u32 = 6 ;
5455const UAT_AP_BITS : u64 = 3 << UAT_AP_SHIFT ;
55- const UAT_HIGH_BITS_SHIFT : u32 = 53 ;
56- const UAT_HIGH_BITS : u64 = 7 << UAT_HIGH_BITS_SHIFT ;
56+ const UAT_HIGH_BITS_SHIFT : u32 = 52 ;
57+ const UAT_HIGH_BITS : u64 = 0xfff << UAT_HIGH_BITS_SHIFT ;
5758const UAT_MEMATTR_SHIFT : u32 = 2 ;
5859const UAT_MEMATTR_BITS : u64 = 7 << UAT_MEMATTR_SHIFT ;
5960
@@ -69,15 +70,17 @@ const AP_FW_GPU: u8 = 0;
6970const AP_FW : u8 = 1 ;
7071const AP_GPU : u8 = 2 ;
7172
72- const HIGH_BITS_PXN : u8 = 1 << 0 ;
73- const HIGH_BITS_UXN : u8 = 1 << 1 ;
74- const HIGH_BITS_GPU_ACCESS : u8 = 1 << 2 ;
73+ const HIGH_BITS_PXN : u16 = 1 << 1 ;
74+ const HIGH_BITS_UXN : u16 = 1 << 2 ;
75+ const HIGH_BITS_GPU_ACCESS : u16 = 1 << 3 ;
76+
77+ pub ( crate ) const PTE_ADDR_BITS : u64 = ( !UAT_PGMSK as u64 ) & ( !UAT_HIGH_BITS ) ;
7578
7679#[ derive( Debug , Copy , Clone ) ]
7780pub ( crate ) struct Prot {
7881 memattr : u8 ,
7982 ap : u8 ,
80- high_bits : u8 ,
83+ high_bits : u16 ,
8184}
8285
8386// Firmware + GPU access
@@ -98,6 +101,23 @@ const PROT_GPU_WO: Prot = Prot::from_bits(AP_GPU, 0, 1);
98101const PROT_GPU_RW : Prot = Prot :: from_bits ( AP_GPU , 1 , 0 ) ;
99102const _PROT_GPU_NA: Prot = Prot :: from_bits ( AP_GPU , 1 , 1 ) ;
100103
104+ const PF_RW : u32 = PF_R | PF_W ;
105+ const PF_RX : u32 = PF_R | PF_X ;
106+
107+ // For crash dumps
108+ const PROT_TO_PERMS_FW : [ [ u32 ; 4 ] ; 4 ] = [
109+ [ 0 , 0 , 0 , PF_RW ] ,
110+ [ 0 , PF_RW , 0 , PF_RW ] ,
111+ [ PF_RX , PF_RX , 0 , PF_R ] ,
112+ [ PF_RX , PF_RW , 0 , PF_R ] ,
113+ ] ;
114+ const PROT_TO_PERMS_OS : [ [ u32 ; 4 ] ; 4 ] = [
115+ [ 0 , PF_R , PF_W , PF_RW ] ,
116+ [ PF_R , 0 , PF_RW , PF_RW ] ,
117+ [ 0 , 0 , 0 , 0 ] ,
118+ [ 0 , 0 , 0 , 0 ] ,
119+ ] ;
120+
101121pub ( crate ) mod prot {
102122 pub ( crate ) use super :: Prot ;
103123 use super :: * ;
@@ -127,7 +147,7 @@ pub(crate) mod prot {
127147}
128148
129149impl Prot {
130- const fn from_bits ( ap : u8 , uxn : u8 , pxn : u8 ) -> Self {
150+ const fn from_bits ( ap : u8 , uxn : u16 , pxn : u16 ) -> Self {
131151 assert ! ( uxn <= 1 ) ;
132152 assert ! ( pxn <= 1 ) ;
133153 assert ! ( ap <= 3 ) ;
@@ -139,6 +159,42 @@ impl Prot {
139159 }
140160 }
141161
162+ pub ( crate ) const fn from_pte ( pte : u64 ) -> Self {
163+ Prot {
164+ high_bits : ( pte >> UAT_HIGH_BITS_SHIFT ) as u16 ,
165+ ap : ( ( pte & UAT_AP_BITS ) >> UAT_AP_SHIFT ) as u8 ,
166+ memattr : ( ( pte & UAT_MEMATTR_BITS ) >> UAT_MEMATTR_SHIFT ) as u8 ,
167+ }
168+ }
169+
170+ pub ( crate ) const fn elf_flags ( & self ) -> u32 {
171+ let ap = ( self . ap & 3 ) as usize ;
172+ let uxn = if self . high_bits & HIGH_BITS_UXN != 0 {
173+ 1
174+ } else {
175+ 0
176+ } ;
177+ let pxn = if self . high_bits & HIGH_BITS_PXN != 0 {
178+ 1
179+ } else {
180+ 0
181+ } ;
182+ let gpu = self . high_bits & HIGH_BITS_GPU_ACCESS != 0 ;
183+
184+ // Format:
185+ // [12 top bits of PTE] [12 bottom bits of PTE] [5 bits pad] [ELF RWX]
186+ let mut perms = if gpu {
187+ PROT_TO_PERMS_OS [ ap] [ ( uxn << 1 ) | pxn]
188+ } else {
189+ PROT_TO_PERMS_FW [ ap] [ ( uxn << 1 ) | pxn]
190+ } ;
191+
192+ perms |= ( ( self . as_pte ( ) >> 52 ) << 20 ) as u32 ;
193+ perms |= ( ( self . as_pte ( ) & 0xfff ) << 8 ) as u32 ;
194+
195+ perms
196+ }
197+
142198 const fn memattr ( & self , memattr : u8 ) -> Self {
143199 Self { memattr, ..* self }
144200 }
0 commit comments