Skip to content

Commit 965b53d

Browse files
support huge page alloc
1 parent 39a2574 commit 965b53d

File tree

8 files changed

+337
-14
lines changed

8 files changed

+337
-14
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ spin = "0.9"
5555
starry-core = { path = "./core" }
5656
starry-api = { path = "./api" }
5757

58+
page_table_multiarch = { git = "https://github.com/Mivik/page_table_multiarch.git", rev = "19ededd" }
59+
5860
[package]
5961
name = "starry"
6062
version.workspace = true

api/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ spin.workspace = true
3232

3333
starry-core.workspace = true
3434

35+
page_table_multiarch.workspace = true
36+
3537
axio = "0.1.1"
3638
ctor_bare = "0.2.1"
3739
flatten_objects = "0.2.3"

api/src/imp/mm/mmap.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ use axerrno::{LinuxError, LinuxResult};
33
use axhal::paging::MappingFlags;
44
use axtask::{TaskExtRef, current};
55
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,
6+
MAP_ANONYMOUS, MAP_FIXED, MAP_HUGE_1GB, MAP_HUGE_MASK, MAP_HUGE_SHIFT, MAP_HUGETLB,
7+
MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, MAP_STACK, PROT_EXEC, PROT_GROWSDOWN, PROT_GROWSUP,
8+
PROT_READ, PROT_WRITE,
89
};
9-
use memory_addr::{VirtAddr, VirtAddrRange};
10+
use memory_addr::{MemoryAddr, VirtAddr, VirtAddrRange};
11+
use page_table_multiarch::PageSize;
1012

1113
use crate::file::{File, FileLike};
1214

@@ -82,13 +84,25 @@ pub fn sys_mmap(
8284
// An example is the flags contained none of MAP_PRIVATE, MAP_SHARED, or MAP_SHARED_VALIDATE.
8385
let map_flags = MmapFlags::from_bits_truncate(flags);
8486

87+
// The check uses bitwise operations to
88+
// verify that exactly one of the two mutually exclusive mapping flags is set
89+
if (map_flags.bits() & (MAP_PRIVATE | MAP_SHARED)).count_ones() != 1 {
90+
return Err(LinuxError::EINVAL);
91+
}
92+
8593
info!(
8694
"sys_mmap: addr: {:x?}, length: {:x?}, prot: {:?}, flags: {:?}, fd: {:?}, offset: {:?}",
8795
addr, length, permission_flags, map_flags, fd, offset
8896
);
8997

90-
let start = memory_addr::align_down_4k(addr);
91-
let end = memory_addr::align_up_4k(addr + length);
98+
let page_size = match (flags & MAP_HUGETLB, flags & MAP_HUGE_MASK << MAP_HUGE_SHIFT) {
99+
(0, _) => PageSize::Size4K,
100+
(_, MAP_HUGE_1GB) => PageSize::Size1G,
101+
(_, _) => PageSize::Size2M,
102+
};
103+
104+
let start = addr.align_down(page_size);
105+
let end = (addr + length).align_up(page_size);
92106
let aligned_length = end - start;
93107
debug!(
94108
"start: {:x?}, end: {:x?}, aligned_length: {:x?}",
@@ -108,13 +122,15 @@ pub fn sys_mmap(
108122
VirtAddr::from(start),
109123
aligned_length,
110124
VirtAddrRange::new(aspace.base(), aspace.end()),
125+
page_size,
111126
)
112127
.or(aspace.find_free_area(
113128
aspace.base(),
114129
aligned_length,
115130
VirtAddrRange::new(aspace.base(), aspace.end()),
131+
page_size,
116132
))
117-
.ok_or(LinuxError::ENOMEM)?
133+
.ok_or(LinuxError::ENOMEM)?
118134
};
119135

120136
let populate = if fd == -1 {
@@ -128,6 +144,7 @@ pub fn sys_mmap(
128144
aligned_length,
129145
permission_flags.into(),
130146
populate,
147+
page_size,
131148
)?;
132149

133150
if populate {
@@ -141,7 +158,7 @@ pub fn sys_mmap(
141158
let length = core::cmp::min(length, file_size - offset);
142159
let mut buf = vec![0u8; length];
143160
file.read_at(offset as u64, &mut buf)?;
144-
aspace.write(start_addr, &buf)?;
161+
aspace.write(start_addr, page_size, &buf)?;
145162
}
146163
Ok(start_addr.as_usize() as _)
147164
}
@@ -150,7 +167,6 @@ pub fn sys_munmap(addr: usize, length: usize) -> LinuxResult<isize> {
150167
let curr = current();
151168
let process_data = curr.task_ext().process_data();
152169
let mut aspace = process_data.aspace.lock();
153-
let length = memory_addr::align_up_4k(length);
154170
let start_addr = VirtAddr::from(addr);
155171
aspace.unmap(start_addr, length)?;
156172
axhal::arch::flush_tlb(None);
@@ -171,7 +187,7 @@ pub fn sys_mprotect(addr: usize, length: usize, prot: u32) -> LinuxResult<isize>
171187
let mut aspace = process_data.aspace.lock();
172188
let length = memory_addr::align_up_4k(length);
173189
let start_addr = VirtAddr::from(addr);
174-
aspace.protect(start_addr, length, permission_flags.into())?;
190+
aspace.protect(start_addr, length, permission_flags.into(), PageSize::Size4K)?;
175191

176192
Ok(0)
177193
}

api/src/ptr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use axerrno::{LinuxError, LinuxResult};
44
use axhal::paging::MappingFlags;
55
use axtask::{TaskExtRef, current};
66
use memory_addr::{MemoryAddr, PAGE_SIZE_4K, VirtAddr, VirtAddrRange};
7+
use page_table_multiarch::PageSize;
78
use starry_core::mm::access_user_memory;
89

910
fn check_region(start: VirtAddr, layout: Layout, access_flags: MappingFlags) -> LinuxResult<()> {
@@ -24,7 +25,7 @@ fn check_region(start: VirtAddr, layout: Layout, access_flags: MappingFlags) ->
2425

2526
let page_start = start.align_down_4k();
2627
let page_end = (start + layout.size()).align_up_4k();
27-
aspace.populate_area(page_start, page_end - page_start)?;
28+
aspace.populate_area(page_start, page_end - page_start, PageSize::Size4K)?;
2829

2930
Ok(())
3031
}

0 commit comments

Comments
 (0)