@@ -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:: * ;
@@ -51,8 +52,8 @@ const PTE_TYPE_LEAF_TABLE: u64 = 3;
5152
5253const UAT_AP_SHIFT : u32 = 6 ;
5354const UAT_AP_BITS : u64 = 3 << UAT_AP_SHIFT ;
54- const UAT_HIGH_BITS_SHIFT : u32 = 53 ;
55- const UAT_HIGH_BITS : u64 = 7 << UAT_HIGH_BITS_SHIFT ;
55+ const UAT_HIGH_BITS_SHIFT : u32 = 52 ;
56+ const UAT_HIGH_BITS : u64 = 0xfff << UAT_HIGH_BITS_SHIFT ;
5657const UAT_MEMATTR_SHIFT : u32 = 2 ;
5758const UAT_MEMATTR_BITS : u64 = 7 << UAT_MEMATTR_SHIFT ;
5859
@@ -68,15 +69,17 @@ const AP_FW_GPU: u8 = 0;
6869const AP_FW : u8 = 1 ;
6970const AP_GPU : u8 = 2 ;
7071
71- const HIGH_BITS_PXN : u8 = 1 << 0 ;
72- const HIGH_BITS_UXN : u8 = 1 << 1 ;
73- const HIGH_BITS_GPU_ACCESS : u8 = 1 << 2 ;
72+ const HIGH_BITS_PXN : u16 = 1 << 1 ;
73+ const HIGH_BITS_UXN : u16 = 1 << 2 ;
74+ const HIGH_BITS_GPU_ACCESS : u16 = 1 << 3 ;
75+
76+ pub ( crate ) const PTE_ADDR_BITS : u64 = ( !0u64 ) & ( !UAT_PGMSK as u64 ) & ( !UAT_HIGH_BITS ) ;
7477
7578#[ derive( Debug , Copy , Clone ) ]
7679pub ( crate ) struct Prot {
7780 memattr : u8 ,
7881 ap : u8 ,
79- high_bits : u8 ,
82+ high_bits : u16 ,
8083}
8184
8285// Firmware + GPU access
@@ -97,6 +100,23 @@ const PROT_GPU_WO: Prot = Prot::from_bits(AP_GPU, 0, 1);
97100const PROT_GPU_RW : Prot = Prot :: from_bits ( AP_GPU , 1 , 0 ) ;
98101const _PROT_GPU_NA: Prot = Prot :: from_bits ( AP_GPU , 1 , 1 ) ;
99102
103+ const PF_RW : u32 = PF_R | PF_W ;
104+ const PF_RX : u32 = PF_R | PF_X ;
105+
106+ // For crash dumps
107+ const PROT_TO_PERMS_FW : [ [ u32 ; 4 ] ; 4 ] = [
108+ [ 0 , 0 , 0 , PF_RW ] ,
109+ [ 0 , PF_RW , 0 , PF_RW ] ,
110+ [ PF_RX , PF_RX , 0 , PF_R ] ,
111+ [ PF_RX , PF_RW , 0 , PF_R ] ,
112+ ] ;
113+ const PROT_TO_PERMS_OS : [ [ u32 ; 4 ] ; 4 ] = [
114+ [ 0 , PF_R , PF_W , PF_RW ] ,
115+ [ PF_R , 0 , PF_RW , PF_RW ] ,
116+ [ 0 , 0 , 0 , 0 ] ,
117+ [ 0 , 0 , 0 , 0 ] ,
118+ ] ;
119+
100120pub ( crate ) mod prot {
101121 pub ( crate ) use super :: Prot ;
102122 use super :: * ;
@@ -126,7 +146,7 @@ pub(crate) mod prot {
126146}
127147
128148impl Prot {
129- const fn from_bits ( ap : u8 , uxn : u8 , pxn : u8 ) -> Self {
149+ const fn from_bits ( ap : u8 , uxn : u16 , pxn : u16 ) -> Self {
130150 assert ! ( uxn <= 1 ) ;
131151 assert ! ( pxn <= 1 ) ;
132152 assert ! ( ap <= 3 ) ;
@@ -138,6 +158,42 @@ impl Prot {
138158 }
139159 }
140160
161+ pub ( crate ) const fn from_pte ( pte : u64 ) -> Self {
162+ Prot {
163+ high_bits : ( pte >> UAT_HIGH_BITS_SHIFT ) as u16 ,
164+ ap : ( ( pte & UAT_AP_BITS ) >> UAT_AP_SHIFT ) as u8 ,
165+ memattr : ( ( pte & UAT_MEMATTR_BITS ) >> UAT_MEMATTR_SHIFT ) as u8 ,
166+ }
167+ }
168+
169+ pub ( crate ) const fn elf_flags ( & self ) -> u32 {
170+ let ap = ( self . ap & 3 ) as usize ;
171+ let uxn = if self . high_bits & HIGH_BITS_UXN != 0 {
172+ 1
173+ } else {
174+ 0
175+ } ;
176+ let pxn = if self . high_bits & HIGH_BITS_PXN != 0 {
177+ 1
178+ } else {
179+ 0
180+ } ;
181+ let gpu = self . high_bits & HIGH_BITS_GPU_ACCESS != 0 ;
182+
183+ // Format:
184+ // [12 top bits of PTE] [12 bottom bits of PTE] [5 bits pad] [ELF RWX]
185+ let mut perms = if gpu {
186+ PROT_TO_PERMS_OS [ ap] [ ( uxn << 1 ) | pxn]
187+ } else {
188+ PROT_TO_PERMS_FW [ ap] [ ( uxn << 1 ) | pxn]
189+ } ;
190+
191+ perms |= ( ( self . as_pte ( ) >> 52 ) << 20 ) as u32 ;
192+ perms |= ( ( self . as_pte ( ) & 0xfff ) << 8 ) as u32 ;
193+
194+ perms
195+ }
196+
141197 const fn memattr ( & self , memattr : u8 ) -> Self {
142198 Self { memattr, ..* self }
143199 }
0 commit comments