From 751e0b2ebf504a97d47a7a9273ca1988bae21f0f Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Sun, 22 Jun 2025 09:45:40 +0800 Subject: [PATCH] Don't jump to the end of the cursor range --- kernel/src/vm/vmar/mod.rs | 12 ++++++++---- test/apps/mmap/mmap_and_mremap.c | 31 +++++++++++++++++++------------ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/kernel/src/vm/vmar/mod.rs b/kernel/src/vm/vmar/mod.rs index 5afaa4d8c..f4ee3e433 100644 --- a/kernel/src/vm/vmar/mod.rs +++ b/kernel/src/vm/vmar/mod.rs @@ -611,14 +611,18 @@ impl Vmar_ { let new_mapping = old_mapping.clone_for_remap_at(new_range.start).unwrap(); inner.insert(new_mapping.enlarge(new_size - old_size)); - // Move the mapping. let preempt_guard = disable_preempt(); let total_range = old_range.start.min(new_range.start)..old_range.end.max(new_range.end); let vmspace = self.vm_space(); let mut cursor = vmspace.cursor_mut(&preempt_guard, &total_range).unwrap(); + + // Move the mapping. let mut current_offset = 0; - cursor.jump(old_range.start).unwrap(); - while let Some(mapped_va) = cursor.find_next(old_size - current_offset) { + while current_offset < old_size { + cursor.jump(old_range.start + current_offset).unwrap(); + let Some(mapped_va) = cursor.find_next(old_size - current_offset) else { + break; + }; let (va, Some((frame, prop))) = cursor.query().unwrap() else { panic!("Found mapped page but query failed"); }; @@ -630,8 +634,8 @@ impl Vmar_ { cursor.map(frame, prop); current_offset = offset + PAGE_SIZE; - cursor.jump(old_range.start + current_offset).unwrap(); } + cursor.flusher().dispatch_tlb_flush(); cursor.flusher().sync_tlb_flush(); diff --git a/test/apps/mmap/mmap_and_mremap.c b/test/apps/mmap/mmap_and_mremap.c index 3e42817ad..91f1de5bd 100644 --- a/test/apps/mmap/mmap_and_mremap.c +++ b/test/apps/mmap/mmap_and_mremap.c @@ -58,23 +58,30 @@ END_TEST() FN_TEST(mmap_and_mremap_fixed) { - char *addr = x_mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - strcpy(addr, content); + char *addr1 = x_mmap(NULL, PAGE_SIZE * 2, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + strcpy(addr1, content); - // Map and unmap a target region to ensure we know it's free - char *fixed_addr = x_mmap(NULL, PAGE_SIZE, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - TEST_SUCC(munmap(fixed_addr, PAGE_SIZE)); // free it for mremap + // Unmap a target region to ensure we know it's free + char *addr2 = addr1 + PAGE_SIZE; + TEST_SUCC(munmap(addr2, PAGE_SIZE)); // free it for mremap - char *new_addr = mremap(addr, PAGE_SIZE, PAGE_SIZE, - MREMAP_MAYMOVE | MREMAP_FIXED, fixed_addr); - if (new_addr != fixed_addr) { + // Remap from the first address to the second address + if (mremap(addr1, PAGE_SIZE, PAGE_SIZE, MREMAP_MAYMOVE | MREMAP_FIXED, + addr2) != addr2) { perror("mremap"); exit(EXIT_FAILURE); } + TEST_RES(strcmp(addr2, content), _ret == 0); - TEST_RES(strcmp(new_addr, content), _ret == 0); - TEST_SUCC(munmap(new_addr, PAGE_SIZE)); + // Remap from the second address to the first address + if (mremap(addr2, PAGE_SIZE, PAGE_SIZE, MREMAP_MAYMOVE | MREMAP_FIXED, + addr1) != addr1) { + perror("mremap"); + exit(EXIT_FAILURE); + } + TEST_RES(strcmp(addr1, content), _ret == 0); + + TEST_SUCC(munmap(addr1, PAGE_SIZE)); } END_TEST()