@@ -4,12 +4,17 @@ use core::{arch, mem};
44// Kernel-provided user-mode helper functions:
55// https://www.kernel.org/doc/Documentation/arm/kernel_user_helpers.txt
66unsafe fn __kuser_cmpxchg ( oldval : u32 , newval : u32 , ptr : * mut u32 ) -> bool {
7- let f: extern "C" fn ( u32 , u32 , * mut u32 ) -> u32 = mem:: transmute ( 0xffff0fc0usize as * const ( ) ) ;
7+ // FIXME(volatile): the third parameter is a volatile pointer
8+ // SAFETY: kernel docs specify a known address with the given signature
9+ let f = unsafe {
10+ mem:: transmute :: < _ , extern "C" fn ( u32 , u32 , * mut u32 ) -> u32 > ( 0xffff0fc0usize as * const ( ) )
11+ } ;
812 f ( oldval, newval, ptr) == 0
913}
1014
1115unsafe fn __kuser_memory_barrier ( ) {
12- let f: extern "C" fn ( ) = mem:: transmute ( 0xffff0fa0usize as * const ( ) ) ;
16+ // SAFETY: kernel docs specify a known address with the given signature
17+ let f = unsafe { mem:: transmute :: < _ , extern "C" fn ( ) > ( 0xffff0fa0usize as * const ( ) ) } ;
1318 f ( ) ;
1419}
1520
@@ -67,8 +72,10 @@ fn insert_aligned(aligned: u32, val: u32, shift: u32, mask: u32) -> u32 {
6772/// - if `size_of::<T>() == 2`, `ptr` or `ptr` offset by 2 bytes must be valid for a relaxed atomic
6873/// read of 2 bytes.
6974/// - if `size_of::<T>() == 4`, `ptr` must be valid for a relaxed atomic read of 4 bytes.
75+ // FIXME: assert some of the preconditions in debug mode
7076unsafe fn atomic_load_aligned < T > ( ptr : * mut u32 ) -> u32 {
71- if mem:: size_of :: < T > ( ) == 4 {
77+ const { assert ! ( size_of:: <T >( ) <= 4 ) } ;
78+ if size_of :: < T > ( ) == 4 {
7279 // SAFETY: As `T` has a size of 4, the caller garantees this is sound.
7380 unsafe { AtomicU32 :: from_ptr ( ptr) . load ( Ordering :: Relaxed ) }
7481 } else {
@@ -100,11 +107,13 @@ unsafe fn atomic_rmw<T, F: Fn(u32) -> u32, G: Fn(u32, u32) -> u32>(ptr: *mut T,
100107 let ( shift, mask) = get_shift_mask ( ptr) ;
101108
102109 loop {
103- let curval_aligned = atomic_load_aligned :: < T > ( aligned_ptr) ;
110+ // FIXME(safety): preconditions review needed
111+ let curval_aligned = unsafe { atomic_load_aligned :: < T > ( aligned_ptr) } ;
104112 let curval = extract_aligned ( curval_aligned, shift, mask) ;
105113 let newval = f ( curval) ;
106114 let newval_aligned = insert_aligned ( curval_aligned, newval, shift, mask) ;
107- if __kuser_cmpxchg ( curval_aligned, newval_aligned, aligned_ptr) {
115+ // FIXME(safety): preconditions review needed
116+ if unsafe { __kuser_cmpxchg ( curval_aligned, newval_aligned, aligned_ptr) } {
108117 return g ( curval, newval) ;
109118 }
110119 }
@@ -116,13 +125,15 @@ unsafe fn atomic_cmpxchg<T>(ptr: *mut T, oldval: u32, newval: u32) -> u32 {
116125 let ( shift, mask) = get_shift_mask ( ptr) ;
117126
118127 loop {
119- let curval_aligned = atomic_load_aligned :: < T > ( aligned_ptr) ;
128+ // FIXME(safety): preconditions review needed
129+ let curval_aligned = unsafe { atomic_load_aligned :: < T > ( aligned_ptr) } ;
120130 let curval = extract_aligned ( curval_aligned, shift, mask) ;
121131 if curval != oldval {
122132 return curval;
123133 }
124134 let newval_aligned = insert_aligned ( curval_aligned, newval, shift, mask) ;
125- if __kuser_cmpxchg ( curval_aligned, newval_aligned, aligned_ptr) {
135+ // FIXME(safety): preconditions review needed
136+ if unsafe { __kuser_cmpxchg ( curval_aligned, newval_aligned, aligned_ptr) } {
126137 return oldval;
127138 }
128139 }
@@ -132,7 +143,14 @@ macro_rules! atomic_rmw {
132143 ( $name: ident, $ty: ty, $op: expr, $fetch: expr) => {
133144 intrinsics! {
134145 pub unsafe extern "C" fn $name( ptr: * mut $ty, val: $ty) -> $ty {
135- atomic_rmw( ptr, |x| $op( x as $ty, val) as u32 , |old, new| $fetch( old, new) ) as $ty
146+ // FIXME(safety): preconditions review needed
147+ unsafe {
148+ atomic_rmw(
149+ ptr,
150+ |x| $op( x as $ty, val) as u32 ,
151+ |old, new| $fetch( old, new)
152+ ) as $ty
153+ }
136154 }
137155 }
138156 } ;
@@ -149,7 +167,8 @@ macro_rules! atomic_cmpxchg {
149167 ( $name: ident, $ty: ty) => {
150168 intrinsics! {
151169 pub unsafe extern "C" fn $name( ptr: * mut $ty, oldval: $ty, newval: $ty) -> $ty {
152- atomic_cmpxchg( ptr, oldval as u32 , newval as u32 ) as $ty
170+ // FIXME(safety): preconditions review needed
171+ unsafe { atomic_cmpxchg( ptr, oldval as u32 , newval as u32 ) as $ty }
153172 }
154173 }
155174 } ;
@@ -285,6 +304,7 @@ atomic_cmpxchg!(__sync_val_compare_and_swap_4, u32);
285304
286305intrinsics ! {
287306 pub unsafe extern "C" fn __sync_synchronize( ) {
288- __kuser_memory_barrier( ) ;
307+ // SAFETY: preconditions are the same as the calling function.
308+ unsafe { __kuser_memory_barrier( ) } ;
289309 }
290310}
0 commit comments