refactor: 清理跨模块架构常量访问#254
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors architectural constants by integrating USER_TOP into the VirtualMemory trait and updating memory layout, user buffer validation, and interrupt management to use this abstracted constant. Review feedback identifies several critical improvements, including ensuring USER_STACK_TOP is page-aligned, fixing off-by-one errors in user space boundary checks, and preventing potential overflows in address calculations. Additionally, it is recommended to further abstract USER_BASE into the trait to maintain architectural consistency across the codebase.
|
|
||
| pub const USER_STACK_TOP: usize = SV39_BOT_HALF_TOP - PAGE_SIZE; // leave another guard page | ||
| /// Leave one guard page below the top of the user address space. | ||
| pub const USER_STACK_TOP: usize = <ArchImpl as VirtualMemory>::USER_TOP - PAGE_SIZE; |
There was a problem hiding this comment.
The current calculation USER_TOP - PAGE_SIZE results in a non-page-aligned address (e.g., 0x...EFFF if USER_TOP is 0x...FFFF). This is unconventional for a stack top and may lead to alignment issues or unexpected behavior in memory mapping. It should typically be page-aligned. If the intention is to place the stack immediately below the trampoline page, it should be aligned to the page boundary.
| pub const USER_STACK_TOP: usize = <ArchImpl as VirtualMemory>::USER_TOP - PAGE_SIZE; | |
| pub const USER_STACK_TOP: usize = align_down(<ArchImpl as VirtualMemory>::USER_TOP, PAGE_SIZE); |
| return false; | ||
| }; | ||
| end <= USER_TOP | ||
| end <= <ArchImpl as VirtualMemory>::USER_TOP |
There was a problem hiding this comment.
The check end <= USER_TOP is too strict. Since USER_TOP is defined as the "highest accessible address" (inclusive), a buffer that ends exactly at USER_TOP + 1 (meaning its last byte is at USER_TOP) should be considered valid. The current logic excludes the last byte of the user address space.
if self.len == 0 {
return start <= <ArchImpl as VirtualMemory>::USER_TOP;
}
end - 1 <= <ArchImpl as VirtualMemory>::USER_TOP| /// 用户地址空间最高可访问地址 | ||
| const USER_TOP: usize; |
There was a problem hiding this comment.
To fully achieve the goal of converging architecture constants and reducing leakage of the constant module, consider adding USER_BASE to the VirtualMemory trait as well. Currently, constant::USER_BASE is still accessed directly in the impl_arch! macro. This ensures consistency with how other architectural constants like USER_TOP are handled.
References
- Prioritize consistency with existing architecture implementations when adding support for a new architecture.
| type KernelAddressSpace = $kernel_space; | ||
|
|
||
| const PAGE_OFFSET: usize = mm::VADDR_START; | ||
| const USER_TOP: usize = constant::USER_TOP; |
There was a problem hiding this comment.
If USER_BASE is added to the VirtualMemory trait, it should be implemented here in the macro to maintain consistency with USER_TOP and existing architecture implementations.
| const USER_TOP: usize = constant::USER_TOP; | |
| const USER_BASE: usize = constant::USER_BASE; | |
| const USER_TOP: usize = constant::USER_TOP; |
References
- Prioritize consistency with existing architecture implementations when adding support for a new architecture.
| // 检查是否会溢出用户空间 | ||
| if let Some(end_addr) = addr.checked_add(size) { | ||
| if end_addr > USER_TOP + 1 { | ||
| if end_addr > <ArchImpl as VirtualMemory>::USER_TOP + 1 { |
There was a problem hiding this comment.
Using ::USER_TOP + 1 can potentially overflow if USER_TOP is usize::MAX. While unlikely on current supported architectures, it is safer and more consistent with the logic in arch_impl.rs to use a subtraction-based check or handle the size > 0 case explicitly.
| if end_addr > <ArchImpl as VirtualMemory>::USER_TOP + 1 { | |
| if size > 0 && end_addr - 1 > <ArchImpl as VirtualMemory>::USER_TOP { |
变更内容
本 PR 处理 #250,主要收敛通用代码对架构常量的跨模块直接访问,减少
arch::constant泄漏到 common code。VirtualMemory中新增架构无关的USER_TOP关联常量config.rs通过VirtualMemory::USER_TOP计算用户栈布局,并在 common config 中明确保留 guard pageuser_buffer.rs和用户拷贝校验逻辑改为通过VirtualMemory::USER_TOP做用户地址范围检查PLIC保留SUPERVISOR_EXTERNAL使用,但改为通过crate::arch::SUPERVISOR_EXTERNAL短路径访问align_down改为const fn,用于编译期计算 sigreturn trampoline 地址验证情况
cargo check --target riscv64gc-unknown-none-elfcargo fmt --all -- --checkcargo clippy --target riscv64gc-unknown-none-elfmake run TEST=1make run TEST=1结果:Total: 510, Passed: 510, Failed: 0Closes #250