@@ -23,6 +23,8 @@ use core::fmt;
23
23
use core:: iter:: Step ;
24
24
use core:: ops:: { Add , AddAssign , Sub , SubAssign } ;
25
25
26
+ use crate :: fs:: FileSystemError ;
27
+
26
28
use super :: page_table:: { PageOffset , PageTableIndex } ;
27
29
use super :: { PageSize , Size4KiB , VmFrame } ;
28
30
@@ -52,14 +54,28 @@ pub struct VirtAddr(u64);
52
54
#[ repr( transparent) ]
53
55
pub struct PhysAddr ( u64 ) ;
54
56
55
- /// A passed `u64` was not a valid virtual address.
56
- ///
57
- /// This means that bits 48 to 64 are not
58
- /// a valid sign extension and are not null either. So automatic sign extension would have
59
- /// overwritten possibly meaningful bits. This likely indicates a bug, for example an invalid
60
- /// address calculation.
61
- #[ derive( Debug ) ]
62
- pub struct VirtAddrNotValid ( u64 ) ;
57
+ #[ derive( Copy , Clone , Debug ) ]
58
+ pub enum ReadErr {
59
+ Null ,
60
+ NotAligned ,
61
+ }
62
+
63
+ impl From < ReadErr > for FileSystemError {
64
+ fn from ( _: ReadErr ) -> Self {
65
+ // `FileSystemError::NotSupported` will be converted to `EINVAL` on
66
+ // syscall error conversion.
67
+ FileSystemError :: NotSupported
68
+ }
69
+ }
70
+
71
+ impl From < ReadErr > for aero_syscall:: SyscallError {
72
+ fn from ( value : ReadErr ) -> Self {
73
+ match value {
74
+ ReadErr :: Null => Self :: EINVAL ,
75
+ ReadErr :: NotAligned => Self :: EACCES ,
76
+ }
77
+ }
78
+ }
63
79
64
80
impl VirtAddr {
65
81
/// Creates a new canonical virtual address.
@@ -99,20 +115,15 @@ impl VirtAddr {
99
115
///
100
116
/// ## Example
101
117
/// ```no_run
102
- /// let address: &mut SomeStruct = VirtAddr::new(0xcafebabe)
103
- /// .read_mut::<SomeStruct>();
104
- /// .ok_or(AeroSyscallError::EFAULT)?;
118
+ /// let address: &mut SomeStruct = VirtAddr::new(0xcafebabe).read_mut::<SomeStruct>()?;
105
119
/// ```
106
- pub fn read_mut < ' struc , T : Sized > ( & self ) -> Option < & ' struc mut T > {
107
- if self . validate_read :: < T > ( ) {
108
- Some ( unsafe { & mut * ( self . as_mut_ptr ( ) as * mut T ) } )
109
- } else {
110
- None
111
- }
120
+ pub fn read_mut < ' a , T : Sized > ( & self ) -> Result < & ' a mut T , ReadErr > {
121
+ self . validate_read :: < T > ( ) ?;
122
+ Ok ( unsafe { & mut * ( self . as_mut_ptr ( ) as * mut T ) } )
112
123
}
113
124
114
125
pub fn as_bytes_mut ( & self , size_bytes : usize ) -> & mut [ u8 ] {
115
- assert ! ( self . validate_read:: <& [ u8 ] >( ) ) ;
126
+ self . validate_read :: < & [ u8 ] > ( ) . unwrap ( ) ;
116
127
unsafe { core:: slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) , size_bytes) }
117
128
}
118
129
@@ -122,10 +133,17 @@ impl VirtAddr {
122
133
}
123
134
124
135
/// Returns if the address is valid to read `sizeof(T)` bytes at the address.
125
- fn validate_read < T : Sized > ( & self ) -> bool {
136
+ fn validate_read < T : Sized > ( & self ) -> Result < ( ) , ReadErr > {
126
137
// FIXME: (*self + core::mem::size_of::<T>()) <= crate::arch::task::userland_last_address()
127
- // // in-range
128
- self . 0 != 0 // non-null
138
+ let raw = self . as_ptr :: < T > ( ) ;
139
+
140
+ if raw. is_null ( ) {
141
+ return Err ( ReadErr :: Null ) ;
142
+ } else if !raw. is_aligned ( ) {
143
+ return Err ( ReadErr :: NotAligned ) ;
144
+ }
145
+
146
+ Ok ( ( ) )
129
147
}
130
148
131
149
/// Aligns the virtual address downwards to the given alignment.
0 commit comments