From 1903c5e0c6de44eb8429540ab9306fe484daf6f1 Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sun, 9 Nov 2025 16:34:45 +0200 Subject: [PATCH] Kernel: Use user given address hint in mmap if possible --- kernel/kernel/Process.cpp | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 8402bba3..f16955d9 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -2218,23 +2218,46 @@ namespace Kernel else page_flags |= PageTable::Flags::UserSupervisor; + LockGuard _(m_process_lock); + AddressRange address_range { .start = 0x400000, .end = USERSPACE_END }; if (args.flags & MAP_FIXED) { - vaddr_t base_addr = reinterpret_cast(args.addr); - address_range.start = BAN::Math::div_round_up(base_addr, PAGE_SIZE) * PAGE_SIZE; - address_range.end = BAN::Math::div_round_up(base_addr + args.len, PAGE_SIZE) * PAGE_SIZE; + const vaddr_t vaddr = reinterpret_cast(args.addr); + if (vaddr % PAGE_SIZE) + return BAN::Error::from_errno(EINVAL); + address_range = { + .start = vaddr, + .end = vaddr + args.len, + }; for (size_t i = 0; i < m_mapped_regions.size(); i++) { - if (!m_mapped_regions[i]->overlaps(base_addr, args.len)) + if (!m_mapped_regions[i]->overlaps(vaddr, args.len)) continue; - if (!m_mapped_regions[i]->contains_fully(base_addr, args.len)) + if (!m_mapped_regions[i]->contains_fully(vaddr, args.len)) derrorln("VERY BROKEN MAP_FIXED UNMAP"); m_mapped_regions[i]->wait_not_pinned(); m_mapped_regions.remove(i--); } + } + if (const vaddr_t vaddr = reinterpret_cast(args.addr); vaddr == 0) + ; + else if (vaddr % PAGE_SIZE) + ; + else if (!PageTable::is_valid_pointer(vaddr)) + ; + else if (!PageTable::is_valid_pointer(vaddr + args.len)) + ; + else if (!page_table().is_range_free(vaddr, args.len)) + ; + else + { + address_range = { + .start = vaddr, + .end = vaddr + args.len, + }; } if (args.flags & MAP_ANONYMOUS) @@ -2250,13 +2273,10 @@ namespace Kernel O_EXEC | O_RDWR )); - LockGuard _(m_process_lock); TRY(m_mapped_regions.push_back(BAN::move(region))); return m_mapped_regions.back()->vaddr(); } - LockGuard _(m_process_lock); - auto inode = TRY(m_open_file_descriptors.inode_of(args.fildes)); const auto status_flags = TRY(m_open_file_descriptors.status_flags_of(args.fildes));