@@ -2,11 +2,9 @@ use alloc::vec;
2
2
use axerrno:: { LinuxError , LinuxResult } ;
3
3
use axhal:: paging:: MappingFlags ;
4
4
use axtask:: { TaskExtRef , current} ;
5
- use linux_raw_sys:: general:: {
6
- MAP_ANONYMOUS , MAP_FIXED , MAP_NORESERVE , MAP_PRIVATE , MAP_SHARED , MAP_STACK , PROT_EXEC ,
7
- PROT_GROWSDOWN , PROT_GROWSUP , PROT_READ , PROT_WRITE ,
8
- } ;
9
- use memory_addr:: { VirtAddr , VirtAddrRange } ;
5
+ use linux_raw_sys:: general:: * ;
6
+ use memory_addr:: { MemoryAddr , VirtAddr , VirtAddrRange } ;
7
+ use page_table_multiarch:: PageSize ;
10
8
11
9
use crate :: file:: { File , FileLike } ;
12
10
@@ -81,14 +79,26 @@ pub fn sys_mmap(
81
79
// TODO: check illegal flags for mmap
82
80
// An example is the flags contained none of MAP_PRIVATE, MAP_SHARED, or MAP_SHARED_VALIDATE.
83
81
let map_flags = MmapFlags :: from_bits_truncate ( flags) ;
82
+ if map_flags. contains ( MmapFlags :: from_bits_truncate ( MAP_PRIVATE | MAP_SHARED ) ) {
83
+ return Err ( LinuxError :: EINVAL ) ;
84
+ }
84
85
85
86
info ! (
86
87
"sys_mmap: addr: {:x?}, length: {:x?}, prot: {:?}, flags: {:?}, fd: {:?}, offset: {:?}" ,
87
88
addr, length, permission_flags, map_flags, fd, offset
88
89
) ;
89
90
90
- let start = memory_addr:: align_down_4k ( addr) ;
91
- let end = memory_addr:: align_up_4k ( addr + length) ;
91
+ let page_size = if flags & MAP_HUGETLB == 0 {
92
+ PageSize :: Size4K
93
+ } else {
94
+ match flags & MAP_HUGE_MASK << MAP_HUGE_SHIFT {
95
+ MAP_HUGE_1GB => PageSize :: Size1G ,
96
+ _ => PageSize :: Size2M ,
97
+ }
98
+ } ;
99
+
100
+ let start = addr. align_down ( page_size) ;
101
+ let end = ( addr + length) . align_up ( page_size) ;
92
102
let aligned_length = end - start;
93
103
debug ! (
94
104
"start: {:x?}, end: {:x?}, aligned_length: {:x?}" ,
@@ -108,11 +118,13 @@ pub fn sys_mmap(
108
118
VirtAddr :: from ( start) ,
109
119
aligned_length,
110
120
VirtAddrRange :: new ( aspace. base ( ) , aspace. end ( ) ) ,
121
+ page_size,
111
122
)
112
123
. or ( aspace. find_free_area (
113
124
aspace. base ( ) ,
114
125
aligned_length,
115
126
VirtAddrRange :: new ( aspace. base ( ) , aspace. end ( ) ) ,
127
+ page_size,
116
128
) )
117
129
. ok_or ( LinuxError :: ENOMEM ) ?
118
130
} ;
@@ -128,6 +140,7 @@ pub fn sys_mmap(
128
140
aligned_length,
129
141
permission_flags. into ( ) ,
130
142
populate,
143
+ page_size,
131
144
) ?;
132
145
133
146
if populate {
@@ -141,7 +154,7 @@ pub fn sys_mmap(
141
154
let length = core:: cmp:: min ( length, file_size - offset) ;
142
155
let mut buf = vec ! [ 0u8 ; length] ;
143
156
file. read_at ( offset as u64 , & mut buf) ?;
144
- aspace. write ( start_addr, & buf) ?;
157
+ aspace. write ( start_addr, page_size , & buf) ?;
145
158
}
146
159
Ok ( start_addr. as_usize ( ) as _ )
147
160
}
@@ -150,8 +163,8 @@ pub fn sys_munmap(addr: usize, length: usize) -> LinuxResult<isize> {
150
163
let curr = current ( ) ;
151
164
let process_data = curr. task_ext ( ) . process_data ( ) ;
152
165
let mut aspace = process_data. aspace . lock ( ) ;
153
- let length = memory_addr:: align_up_4k ( length) ;
154
166
let start_addr = VirtAddr :: from ( addr) ;
167
+ let length = memory_addr:: align_up_4k ( length) ;
155
168
aspace. unmap ( start_addr, length) ?;
156
169
axhal:: arch:: flush_tlb ( None ) ;
157
170
Ok ( 0 )
0 commit comments