1
1
//! Allows for querying information about memory tokens.
2
2
3
+ use oro_mem:: mapper:: MapError ;
3
4
use oro_sysabi:: { key, syscall:: Error as SysError } ;
4
5
5
6
use super :: KernelInterface ;
6
7
use crate :: { arch:: Arch , syscall:: InterfaceResponse , tab:: Tab , thread:: Thread , token:: Token } ;
7
8
9
+ /// Interface specific errors.
10
+ #[ derive( Debug , Clone , Copy ) ]
11
+ #[ repr( u64 ) ]
12
+ pub enum Error {
13
+ /// An address conflict (existing mapping) was encountered when mapping a token.
14
+ Conflict = key ! ( "conflict" ) ,
15
+ /// The requested address is not aligned to the page size.
16
+ NotAligned = key ! ( "align" ) ,
17
+ /// The requested address is out of the address space range.
18
+ OutOfRange = key ! ( "range" ) ,
19
+ /// The system ran out of memory trying to service the request.
20
+ OutOfMemory = key ! ( "oom" ) ,
21
+ }
22
+
8
23
/// Version 0 of the memory token query interface.
9
24
#[ repr( transparent) ]
10
25
pub struct MemTokenV0 ;
@@ -13,10 +28,8 @@ impl KernelInterface for MemTokenV0 {
13
28
const TYPE_ID : u64 = oro_sysabi:: id:: iface:: KERNEL_MEM_TOKEN_V0 ;
14
29
15
30
fn get < A : Arch > ( thread : & Tab < Thread < A > > , index : u64 , key : u64 ) -> InterfaceResponse {
16
- let Some ( token) = thread
17
- . with ( |t| t. instance ( ) . clone ( ) )
18
- . with ( |i| i. token ( index) )
19
- else {
31
+ let instance = thread. with ( |t| t. instance ( ) . clone ( ) ) ;
32
+ let Some ( token) = instance. with ( |i| i. token ( index) ) else {
20
33
return InterfaceResponse :: immediate ( SysError :: BadIndex , 0 ) ;
21
34
} ;
22
35
@@ -34,6 +47,7 @@ impl KernelInterface for MemTokenV0 {
34
47
key ! ( "pages" ) => InterfaceResponse :: ok ( token. page_count ( ) as u64 ) ,
35
48
key ! ( "size" ) => InterfaceResponse :: ok ( token. size ( ) as u64 ) ,
36
49
key ! ( "commit" ) => InterfaceResponse :: ok ( token. commit ( ) as u64 ) ,
50
+ key ! ( "base" ) => InterfaceResponse :: immediate ( SysError :: WriteOnly , 0 ) ,
37
51
_ => InterfaceResponse :: immediate ( SysError :: BadKey , 0 ) ,
38
52
}
39
53
}
@@ -45,16 +59,48 @@ impl KernelInterface for MemTokenV0 {
45
59
thread : & Tab < Thread < A > > ,
46
60
index : u64 ,
47
61
key : u64 ,
48
- _value : u64 ,
62
+ value : u64 ,
49
63
) -> InterfaceResponse {
50
- if key == key ! ( "forget" ) {
51
- let instance = thread. with ( |t| t. instance ( ) . clone ( ) ) ;
52
- return instance. with_mut ( |i| i. forget_token ( index) ) . map_or_else (
53
- || InterfaceResponse :: immediate ( SysError :: BadIndex , 0 ) ,
54
- |_| InterfaceResponse :: ok ( 0 ) ,
55
- ) ;
56
- }
64
+ match key {
65
+ key ! ( "forget" ) => {
66
+ let instance = thread. with ( |t| t. instance ( ) . clone ( ) ) ;
67
+ instance. with_mut ( |i| i. forget_token ( index) ) . map_or_else (
68
+ || InterfaceResponse :: immediate ( SysError :: BadIndex , 0 ) ,
69
+ |_| InterfaceResponse :: ok ( 0 ) ,
70
+ )
71
+ }
72
+ key ! ( "base" ) => {
73
+ let instance = thread. with ( |t| t. instance ( ) . clone ( ) ) ;
74
+ instance. with_mut ( |i| {
75
+ let Some ( token) = i. token ( index) else {
76
+ return InterfaceResponse :: immediate ( SysError :: BadIndex , 0 ) ;
77
+ } ;
57
78
58
- InterfaceResponse :: immediate ( SysError :: ReadOnly , 0 )
79
+ let Ok ( virt) = usize:: try_from ( value) else {
80
+ return InterfaceResponse :: immediate (
81
+ SysError :: InterfaceError ,
82
+ Error :: OutOfRange as u64 ,
83
+ ) ;
84
+ } ;
85
+
86
+ i. map_token ( & token, virt) . map_or_else (
87
+ |err| {
88
+ InterfaceResponse :: immediate (
89
+ SysError :: InterfaceError ,
90
+ match err {
91
+ MapError :: Exists => Error :: Conflict as u64 ,
92
+ MapError :: OutOfMemory => Error :: OutOfMemory as u64 ,
93
+ MapError :: VirtNotAligned => Error :: NotAligned as u64 ,
94
+ MapError :: VirtOutOfRange
95
+ | MapError :: VirtOutOfAddressSpaceRange => Error :: OutOfRange as u64 ,
96
+ } ,
97
+ )
98
+ } ,
99
+ |( ) | InterfaceResponse :: ok ( 0 ) ,
100
+ )
101
+ } )
102
+ }
103
+ _ => InterfaceResponse :: immediate ( SysError :: ReadOnly , 0 ) ,
104
+ }
59
105
}
60
106
}
0 commit comments