diff --git a/Kernel/Devices/BXVGADevice.cpp b/Kernel/Devices/BXVGADevice.cpp index 32f470ffa2..c915a46ee7 100644 --- a/Kernel/Devices/BXVGADevice.cpp +++ b/Kernel/Devices/BXVGADevice.cpp @@ -172,19 +172,18 @@ u32 BXVGADevice::find_framebuffer_address() return framebuffer_address; } -KResultOr BXVGADevice::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) +KResultOr BXVGADevice::mmap(Process& process, FileDescription&, const Range& range, size_t offset, int prot, bool shared) { REQUIRE_PROMISE(video); if (!shared) return ENODEV; ASSERT(offset == 0); - ASSERT(size == framebuffer_size_in_bytes()); + ASSERT(range.size() == framebuffer_size_in_bytes()); auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes()); if (!vmobject) return ENOMEM; return process.allocate_region_with_vmobject( - preferred_vaddr, - framebuffer_size_in_bytes(), + range, vmobject.release_nonnull(), 0, "BXVGA Framebuffer", diff --git a/Kernel/Devices/BXVGADevice.h b/Kernel/Devices/BXVGADevice.h index 4e54649284..236aad8fa8 100644 --- a/Kernel/Devices/BXVGADevice.h +++ b/Kernel/Devices/BXVGADevice.h @@ -42,7 +42,7 @@ public: BXVGADevice(); virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override; - virtual KResultOr mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t, int prot, bool shared) override; + virtual KResultOr mmap(Process&, FileDescription&, const Range&, size_t offset, int prot, bool shared) override; // ^Device virtual mode_t required_mode() const override { return 0660; } diff --git a/Kernel/Devices/MBVGADevice.cpp b/Kernel/Devices/MBVGADevice.cpp index 2335eb952c..b255c1739e 100644 --- a/Kernel/Devices/MBVGADevice.cpp +++ b/Kernel/Devices/MBVGADevice.cpp @@ -51,19 +51,18 @@ MBVGADevice::MBVGADevice(PhysicalAddress addr, size_t pitch, size_t width, size_ s_the = this; } -KResultOr MBVGADevice::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) +KResultOr MBVGADevice::mmap(Process& process, FileDescription&, const Range& range, size_t offset, int prot, bool shared) { REQUIRE_PROMISE(video); if (!shared) return ENODEV; ASSERT(offset == 0); - ASSERT(size == framebuffer_size_in_bytes()); + ASSERT(range.size() == framebuffer_size_in_bytes()); auto vmobject = AnonymousVMObject::create_for_physical_range(m_framebuffer_address, framebuffer_size_in_bytes()); if (!vmobject) return ENOMEM; return process.allocate_region_with_vmobject( - preferred_vaddr, - framebuffer_size_in_bytes(), + range, vmobject.release_nonnull(), 0, "MBVGA Framebuffer", diff --git a/Kernel/Devices/MBVGADevice.h b/Kernel/Devices/MBVGADevice.h index d89134f6b8..f07cc238fc 100644 --- a/Kernel/Devices/MBVGADevice.h +++ b/Kernel/Devices/MBVGADevice.h @@ -41,7 +41,7 @@ public: MBVGADevice(PhysicalAddress addr, size_t pitch, size_t width, size_t height); virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg) override; - virtual KResultOr mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t, int prot, bool shared) override; + virtual KResultOr mmap(Process&, FileDescription&, const Range&, size_t offset, int prot, bool shared) override; // ^Device virtual mode_t required_mode() const override { return 0660; } diff --git a/Kernel/FileSystem/AnonymousFile.cpp b/Kernel/FileSystem/AnonymousFile.cpp index a0fa76fd42..aede4e9474 100644 --- a/Kernel/FileSystem/AnonymousFile.cpp +++ b/Kernel/FileSystem/AnonymousFile.cpp @@ -39,15 +39,15 @@ AnonymousFile::~AnonymousFile() { } -KResultOr AnonymousFile::mmap(Process& process, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) +KResultOr AnonymousFile::mmap(Process& process, FileDescription&, const Range& range, size_t offset, int prot, bool shared) { if (offset != 0) return EINVAL; - if (size != m_vmobject->size()) + if (range.size() != m_vmobject->size()) return EINVAL; - return process.allocate_region_with_vmobject(preferred_vaddr, size, m_vmobject, offset, {}, prot, shared); + return process.allocate_region_with_vmobject(range, m_vmobject, offset, {}, prot, shared); } } diff --git a/Kernel/FileSystem/AnonymousFile.h b/Kernel/FileSystem/AnonymousFile.h index d95fc5fcb0..6e1dd99f40 100644 --- a/Kernel/FileSystem/AnonymousFile.h +++ b/Kernel/FileSystem/AnonymousFile.h @@ -39,7 +39,7 @@ public: virtual ~AnonymousFile() override; - virtual KResultOr mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) override; + virtual KResultOr mmap(Process&, FileDescription&, const Range&, size_t offset, int prot, bool shared) override; private: virtual const char* class_name() const override { return "AnonymousFile"; } diff --git a/Kernel/FileSystem/File.cpp b/Kernel/FileSystem/File.cpp index 13148d1f91..fcf1f99075 100644 --- a/Kernel/FileSystem/File.cpp +++ b/Kernel/FileSystem/File.cpp @@ -59,7 +59,7 @@ int File::ioctl(FileDescription&, unsigned, FlatPtr) return -ENOTTY; } -KResultOr File::mmap(Process&, FileDescription&, VirtualAddress, size_t, size_t, int, bool) +KResultOr File::mmap(Process&, FileDescription&, const Range&, size_t, int, bool) { return ENODEV; } diff --git a/Kernel/FileSystem/File.h b/Kernel/FileSystem/File.h index b36bde45cd..98f35993ec 100644 --- a/Kernel/FileSystem/File.h +++ b/Kernel/FileSystem/File.h @@ -114,7 +114,7 @@ public: virtual KResultOr read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) = 0; virtual KResultOr write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) = 0; virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg); - virtual KResultOr mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared); + virtual KResultOr mmap(Process&, FileDescription&, const Range&, size_t offset, int prot, bool shared); virtual KResult stat(::stat&) const { return EBADF; } virtual String absolute_path(const FileDescription&) const = 0; diff --git a/Kernel/FileSystem/FileDescription.cpp b/Kernel/FileSystem/FileDescription.cpp index c69726fe66..4b38811c23 100644 --- a/Kernel/FileSystem/FileDescription.cpp +++ b/Kernel/FileSystem/FileDescription.cpp @@ -328,10 +328,10 @@ InodeMetadata FileDescription::metadata() const return {}; } -KResultOr FileDescription::mmap(Process& process, VirtualAddress vaddr, size_t offset, size_t size, int prot, bool shared) +KResultOr FileDescription::mmap(Process& process, const Range& range, size_t offset, int prot, bool shared) { LOCKER(m_lock); - return m_file->mmap(process, *this, vaddr, offset, size, prot, shared); + return m_file->mmap(process, *this, range, offset, prot, shared); } KResult FileDescription::truncate(u64 length) diff --git a/Kernel/FileSystem/FileDescription.h b/Kernel/FileSystem/FileDescription.h index 16bde5890c..d7c1a2a361 100644 --- a/Kernel/FileSystem/FileDescription.h +++ b/Kernel/FileSystem/FileDescription.h @@ -108,7 +108,7 @@ public: Custody* custody() { return m_custody.ptr(); } const Custody* custody() const { return m_custody.ptr(); } - KResultOr mmap(Process&, VirtualAddress, size_t offset, size_t, int prot, bool shared); + KResultOr mmap(Process&, const Range&, size_t offset, int prot, bool shared); bool is_blocking() const { return m_is_blocking; } void set_blocking(bool b) { m_is_blocking = b; } diff --git a/Kernel/FileSystem/InodeFile.cpp b/Kernel/FileSystem/InodeFile.cpp index 3cade1cf5f..5db5b8814d 100644 --- a/Kernel/FileSystem/InodeFile.cpp +++ b/Kernel/FileSystem/InodeFile.cpp @@ -69,7 +69,7 @@ KResultOr InodeFile::write(FileDescription& description, size_t offset, return nwritten; } -KResultOr InodeFile::mmap(Process& process, FileDescription& description, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) +KResultOr InodeFile::mmap(Process& process, FileDescription& description, const Range& range, size_t offset, int prot, bool shared) { // FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec. RefPtr vmobject; @@ -79,7 +79,7 @@ KResultOr InodeFile::mmap(Process& process, FileDescription& descriptio vmobject = PrivateInodeVMObject::create_with_inode(inode()); if (!vmobject) return ENOMEM; - return process.allocate_region_with_vmobject(preferred_vaddr, size, *vmobject, offset, description.absolute_path(), prot, shared); + return process.allocate_region_with_vmobject(range, vmobject.release_nonnull(), offset, description.absolute_path(), prot, shared); } String InodeFile::absolute_path(const FileDescription& description) const diff --git a/Kernel/FileSystem/InodeFile.h b/Kernel/FileSystem/InodeFile.h index e051476b2b..a0b7b122c0 100644 --- a/Kernel/FileSystem/InodeFile.h +++ b/Kernel/FileSystem/InodeFile.h @@ -49,7 +49,7 @@ public: virtual KResultOr read(FileDescription&, size_t, UserOrKernelBuffer&, size_t) override; virtual KResultOr write(FileDescription&, size_t, const UserOrKernelBuffer&, size_t) override; - virtual KResultOr mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared) override; + virtual KResultOr mmap(Process&, FileDescription&, const Range&, size_t offset, int prot, bool shared) override; virtual String absolute_path(const FileDescription&) const override; diff --git a/Kernel/Syscalls/mmap.cpp b/Kernel/Syscalls/mmap.cpp index 20c8b76f73..070233a841 100644 --- a/Kernel/Syscalls/mmap.cpp +++ b/Kernel/Syscalls/mmap.cpp @@ -133,16 +133,13 @@ void* Process::sys$mmap(Userspace user_params) return (void*)-EINVAL; Region* region = nullptr; - Optional range; - if (map_noreserve || map_anonymous) { - range = allocate_range(VirtualAddress(addr), size, alignment); - if (!range.value().is_valid()) - return (void*)-ENOMEM; - } + auto range = allocate_range(VirtualAddress(addr), size, alignment); + if (!range.is_valid()) + return (void*)-ENOMEM; if (map_anonymous) { auto strategy = map_noreserve ? AllocationStrategy::None : AllocationStrategy::Reserve; - auto region_or_error = allocate_region(range.value(), !name.is_null() ? name : "mmap", prot, strategy); + auto region_or_error = allocate_region(range, !name.is_null() ? name : "mmap", prot, strategy); if (region_or_error.is_error() && (!map_fixed && addr != 0)) region_or_error = allocate_region(allocate_range({}, size), !name.is_null() ? name : "mmap", prot, strategy); if (region_or_error.is_error()) @@ -169,13 +166,8 @@ void* Process::sys$mmap(Userspace user_params) if (!validate_inode_mmap_prot(*this, prot, *description->inode(), map_shared)) return (void*)-EACCES; } - auto region_or_error = description->mmap(*this, VirtualAddress(addr), static_cast(offset), size, prot, map_shared); - if (region_or_error.is_error()) { - // Fail if MAP_FIXED or address is 0, retry otherwise - if (map_fixed || addr == 0) - return (void*)region_or_error.error().error(); - region_or_error = description->mmap(*this, {}, static_cast(offset), size, prot, map_shared); - } + + auto region_or_error = description->mmap(*this, range, static_cast(offset), prot, map_shared); if (region_or_error.is_error()) return (void*)region_or_error.error().error(); region = region_or_error.value();