Skip to content

Commit dab1fb5

Browse files
fix(mm): fix brk syscall to properly map heap pages (#92)
* fix(mm): fix brk syscall to properly map heap pages The original brk implementation had several issues: 1. Never actually mapped pages - only updated the heap_top pointer 2. Limit was USER_HEAP_SIZE (64KB), too small for real programs 3. Did not track initial heap region, causing double-mapping errors Changes: - Actually call aspace.map() to map new heap pages on expansion - Increase limit to USER_HEAP_SIZE_MAX (512MB) - Track initial_heap_end to avoid re-mapping already mapped pages - Add USER_HEAP_SIZE_MAX config for all architectures * modify files matching rustmft expects * Change signal trampoline address * adjust signal trampoline address * modify brk as comments * fix clippy --------- Co-authored-by: sunhaosheng <sunhaosheng@kylinos.cn>
1 parent 05366f4 commit dab1fb5

File tree

5 files changed

+64
-17
lines changed

5 files changed

+64
-17
lines changed

api/src/syscall/mm/brk.rs

Lines changed: 47 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,55 @@
11
use axerrno::AxResult;
2+
use axhal::paging::{MappingFlags, PageSize};
3+
use axmm::backend::Backend;
24
use axtask::current;
3-
use starry_core::task::AsThread;
5+
use memory_addr::{VirtAddr, align_up_4k};
6+
use starry_core::{
7+
config::{USER_HEAP_BASE, USER_HEAP_SIZE, USER_HEAP_SIZE_MAX},
8+
task::AsThread,
9+
};
410

511
pub fn sys_brk(addr: usize) -> AxResult<isize> {
612
let curr = current();
713
let proc_data = &curr.as_thread().proc_data;
8-
let mut return_val: isize = proc_data.get_heap_top() as isize;
9-
let heap_bottom = proc_data.get_heap_bottom() as usize;
10-
if addr != 0 && addr >= heap_bottom && addr <= heap_bottom + starry_core::config::USER_HEAP_SIZE
11-
{
12-
proc_data.set_heap_top(addr);
13-
return_val = addr as isize;
14+
let current_top = proc_data.get_heap_top() as usize;
15+
let heap_limit = USER_HEAP_BASE + USER_HEAP_SIZE_MAX;
16+
17+
if addr == 0 {
18+
return Ok(current_top as isize);
19+
}
20+
21+
if addr < USER_HEAP_BASE || addr > heap_limit {
22+
return Ok(current_top as isize);
23+
}
24+
25+
let new_top_aligned = align_up_4k(addr);
26+
let current_top_aligned = align_up_4k(current_top);
27+
// Initial heap region end address (already mapped during ELF loading)
28+
let initial_heap_end = USER_HEAP_BASE + USER_HEAP_SIZE;
29+
30+
// Only map new pages when expanding beyond already mapped region
31+
// Expansion start should be the greater of initial_heap_end and current_top_aligned
32+
if new_top_aligned > current_top_aligned {
33+
let expand_start = VirtAddr::from(initial_heap_end.max(current_top_aligned));
34+
let expand_size = new_top_aligned.saturating_sub(expand_start.as_usize());
35+
36+
if expand_size > 0
37+
&& proc_data
38+
.aspace
39+
.lock()
40+
.map(
41+
expand_start,
42+
expand_size,
43+
MappingFlags::READ | MappingFlags::WRITE | MappingFlags::USER,
44+
false,
45+
Backend::new_alloc(expand_start, PageSize::Size4K),
46+
)
47+
.is_err()
48+
{
49+
return Ok(current_top as isize);
50+
}
1451
}
15-
Ok(return_val)
52+
53+
proc_data.set_heap_top(addr);
54+
Ok(addr as isize)
1655
}

core/src/config/aarch64.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ pub const USER_STACK_SIZE: usize = 0x8_0000;
1515
pub const USER_HEAP_BASE: usize = 0x4000_0000;
1616
/// The size of the user heap.
1717
pub const USER_HEAP_SIZE: usize = 0x1_0000;
18+
/// The maximum size of the user heap (for brk expansion).
19+
pub const USER_HEAP_SIZE_MAX: usize = 0x2000_0000;
1820

1921
/// The base address for user interpreter.
2022
pub const USER_INTERP_BASE: usize = 0x400_0000;
2123

22-
/// The address of signal trampoline.
23-
pub const SIGNAL_TRAMPOLINE: usize = 0x4001_0000;
24+
/// The address of signal trampoline (placed at top of user heap).
25+
pub const SIGNAL_TRAMPOLINE: usize = 0x6000_1000;

core/src/config/loongarch64.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ pub const USER_STACK_SIZE: usize = 0x8_0000;
1414
/// The lowest address of the user heap.
1515
pub const USER_HEAP_BASE: usize = 0x4000_0000;
1616
/// The size of the user heap.
17-
pub const USER_HEAP_SIZE: usize = 0x1_0000;
17+
pub const USER_HEAP_SIZE: usize = 0x1_0000; // 64KB
18+
/// The maximum size of the user heap (for brk expansion).
19+
pub const USER_HEAP_SIZE_MAX: usize = 0x2000_0000; // 512MB
1820

1921
/// The base address for user interpreter.
2022
pub const USER_INTERP_BASE: usize = 0x400_0000;
2123

22-
/// The address of signal trampoline.
23-
pub const SIGNAL_TRAMPOLINE: usize = 0x4001_0000;
24+
/// The address of signal trampoline (placed at top of user heap).
25+
pub const SIGNAL_TRAMPOLINE: usize = 0x6000_1000;

core/src/config/riscv64.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ pub const USER_STACK_SIZE: usize = 0x8_0000;
1515
pub const USER_HEAP_BASE: usize = 0x4000_0000;
1616
/// The size of the user heap.
1717
pub const USER_HEAP_SIZE: usize = 0x1_0000;
18+
/// The maximum size of the user heap (for brk expansion).
19+
pub const USER_HEAP_SIZE_MAX: usize = 0x2000_0000;
1820

1921
/// The base address for user interpreter.
2022
pub const USER_INTERP_BASE: usize = 0x400_0000;
2123

22-
/// The address of signal trampoline.
23-
pub const SIGNAL_TRAMPOLINE: usize = 0x4001_0000;
24+
/// The address of signal trampoline (placed at top of user heap).
25+
pub const SIGNAL_TRAMPOLINE: usize = 0x6000_1000;

core/src/config/x86_64.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ pub const USER_STACK_SIZE: usize = 0x8_0000;
1515
pub const USER_HEAP_BASE: usize = 0x4000_0000;
1616
/// The size of the user heap.
1717
pub const USER_HEAP_SIZE: usize = 0x1_0000;
18+
/// The maximum size of the user heap (for brk expansion).
19+
pub const USER_HEAP_SIZE_MAX: usize = 0x2000_0000;
1820

1921
/// The base address for user interpreter.
2022
pub const USER_INTERP_BASE: usize = 0x400_0000;
2123

22-
/// The address of signal trampoline.
23-
pub const SIGNAL_TRAMPOLINE: usize = 0x4001_0000;
24+
/// The address of signal trampoline (placed at top of user heap).
25+
pub const SIGNAL_TRAMPOLINE: usize = 0x6000_1000;

0 commit comments

Comments
 (0)