Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix bugs in mremap and 9p's rename #125

Merged
merged 1 commit into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions api/ruxos_posix_api/src/imp/mmap/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,6 @@ pub fn sys_mmap(
syscall_body!(sys_mmap, {
// transform C-type into rust-type
let start = start as usize;
let len = VirtAddr::from(len).align_up_4k().as_usize();
if !VirtAddr::from(start).is_aligned(PAGE_SIZE_4K) || len == 0 {
error!(
"mmap failed because start:0x{:x} is not aligned or len:0x{:x} == 0",
start, len
);
return Err(LinuxError::EINVAL);
}
let prot = prot as u32;
let flags = flags as u32;
let fid = fd;
Expand All @@ -75,6 +67,22 @@ pub fn sys_mmap(
fid
};

// align len to PAGE_SIZE_4K depending on `MAP_ANONYMOUS` or not.
let len = if fid < 0 {
VirtAddr::from(len).align_up_4k().as_usize()
} else {
VirtAddr::from(len).as_usize()
};

// check if `start` is aligned to `PAGE_SIZE_4K`or len is large than 0.
if !VirtAddr::from(start).is_aligned(PAGE_SIZE_4K) || len == 0 {
error!(
"mmap failed because start:0x{:x} is not aligned or len:0x{:x} == 0",
start, len
);
return Err(LinuxError::EINVAL);
}

let mut new = Vma::new(fid, offset, prot, flags);
let mut vma_map = VMA_MAP.lock();
let addr_condition = if start == 0 { None } else { Some(start) };
Expand Down Expand Up @@ -103,7 +111,7 @@ pub fn sys_munmap(start: *mut c_void, len: ctypes::size_t) -> c_int {
syscall_body!(sys_munmap, {
// transform C-type into rust-type
let start = start as usize;
let end = VirtAddr::from(start + len).align_up_4k().as_usize();
let end = VirtAddr::from(start + len).as_usize();

if !VirtAddr::from(start).is_aligned(PAGE_SIZE_4K) || len == 0 {
error!(
Expand Down Expand Up @@ -171,7 +179,7 @@ pub fn sys_munmap(start: *mut c_void, len: ctypes::size_t) -> c_int {
}

// delete the mapped and swapped page.
release_pages_mapped(start, end);
release_pages_mapped(start, end, true);
#[cfg(feature = "fs")]
release_pages_swaped(start, end);

Expand All @@ -191,7 +199,7 @@ pub fn sys_mprotect(start: *mut c_void, len: ctypes::size_t, prot: c_int) -> c_i
syscall_body!(sys_mprotect, {
// transform C-type into rust-type
let start = start as usize;
let end = VirtAddr::from(start + len).align_up_4k().as_usize();
let end = VirtAddr::from(start + len).as_usize();
if !VirtAddr::from(start).is_aligned(PAGE_SIZE_4K) || len == 0 {
return Err(LinuxError::EINVAL);
}
Expand Down Expand Up @@ -293,7 +301,7 @@ pub fn sys_msync(start: *mut c_void, len: ctypes::size_t, flags: c_int) -> c_int
#[cfg(feature = "fs")]
{
let start = start as usize;
let end = VirtAddr::from(start + len).align_up_4k().as_usize();
let end = VirtAddr::from(start + len).as_usize();
if !VirtAddr::from(start).is_aligned(PAGE_SIZE_4K) || len == 0 {
return Err(LinuxError::EINVAL);
}
Expand Down Expand Up @@ -444,7 +452,7 @@ pub fn sys_mremap(
old_vma.end_addr = new_end;

// delete the mapped and swapped page outside of new vma.
release_pages_mapped(new_end, old_end);
release_pages_mapped(new_end, old_end, false);
#[cfg(feature = "fs")]
release_pages_swaped(new_end, old_end);

Expand Down
22 changes: 13 additions & 9 deletions api/ruxos_posix_api/src/imp/mmap/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use ruxhal::{
// use `used_fs` instead of `#[cfg(feature = "fs")]{}` to cancel the scope of code.
#[cfg(feature = "fs")]
macro_rules! used_fs {
($($code:tt)*) => {$($code)*};
}
($($code:tt)*) => {$($code)*};
}

#[cfg(not(feature = "fs"))]
macro_rules! used_fs {
Expand Down Expand Up @@ -204,9 +204,11 @@ pub(crate) fn find_free_region(
}

// Search free region on the top of VMA_LISTS first.
const ALIGN_PAGE_MASK: usize = !(PAGE_SIZE_4K - 1);
if let Some((_, last_vma)) = vma_map.last_key_value() {
if VMA_END - last_vma.end_addr >= len {
return Some(last_vma.end_addr);
let end_boundry = (last_vma.end_addr + PAGE_SIZE_4K) & ALIGN_PAGE_MASK;
if (VMA_END - end_boundry) & ALIGN_PAGE_MASK >= len {
return Some(end_boundry);
}
} else if VMA_END >= VMA_START + len {
return Some(VMA_START);
Expand Down Expand Up @@ -274,7 +276,7 @@ pub(crate) fn snatch_fixed_region(
}

// delete the mapped and swapped page.
release_pages_mapped(start, end);
release_pages_mapped(start, end, true);
#[cfg(feature = "fs")]
release_pages_swaped(start, end);

Expand All @@ -283,14 +285,16 @@ pub(crate) fn snatch_fixed_region(

/// release the range of [start, end) in mem_map
/// take care of AA-deadlock, this function should not be used after `MEM_MAP` is used.
pub(crate) fn release_pages_mapped(start: usize, end: usize) {
pub(crate) fn release_pages_mapped(start: usize, end: usize, writeback: bool) {
let mut memory_map = MEM_MAP.lock();
let mut removing_vaddr = Vec::new();
for (&vaddr, _page_info) in memory_map.range(start..end) {
#[cfg(feature = "fs")]
if let Some((file, offset, size)) = _page_info {
let src = vaddr as *mut u8;
write_into(file, src, *offset as u64, *size);
if writeback {
if let Some((file, offset, size)) = _page_info {
let src = vaddr as *mut u8;
write_into(file, src, *offset as u64, *size);
}
}
if pte_unmap_page(VirtAddr::from(vaddr)).is_err() {
panic!("Release page failed when munmapping!");
Expand Down
2 changes: 1 addition & 1 deletion modules/rux9p/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ impl VfsNodeOps for CommonNode {
("", src_path)
};

let (dst_prefixs, new_name) = if let Some(dst_sindex) = src_path.rfind('/') {
let (dst_prefixs, new_name) = if let Some(dst_sindex) = dst_path.rfind('/') {
(&dst_path[..dst_sindex], &dst_path[dst_sindex + 1..])
} else {
("", dst_path)
Expand Down
Loading