diff --git a/kernel/include/kernel/Device/Device.h b/kernel/include/kernel/Device/Device.h index b629a3a4..0fa68681 100644 --- a/kernel/include/kernel/Device/Device.h +++ b/kernel/include/kernel/Device/Device.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace Kernel { @@ -15,6 +16,8 @@ namespace Kernel virtual bool is_partition() const { return false; } virtual bool is_storage_device() const { return false; } + virtual BAN::ErrorOr> mmap_region(PageTable&, off_t offset, size_t len, AddressRange, MemoryRegion::Type, PageTable::flags_t) { return BAN::Error::from_errno(EINVAL); } + virtual dev_t rdev() const override = 0; virtual BAN::StringView name() const = 0; diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index b00945b2..7c89e473 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -1058,33 +1058,46 @@ namespace Kernel return m_mapped_regions.back()->vaddr(); } - auto inode = TRY(m_open_file_descriptors.inode_of(args->fildes)); - if (inode->mode().ifreg()) - { - if (args->addr != nullptr) - return BAN::Error::from_errno(ENOTSUP); + if (args->addr != nullptr) + return BAN::Error::from_errno(ENOTSUP); - auto inode_flags = TRY(m_open_file_descriptors.flags_of(args->fildes)); - if (!(inode_flags & O_RDONLY)) + LockGuard _(m_lock); + + auto inode = TRY(m_open_file_descriptors.inode_of(args->fildes)); + + auto inode_flags = TRY(m_open_file_descriptors.flags_of(args->fildes)); + if (!(inode_flags & O_RDONLY)) + return BAN::Error::from_errno(EACCES); + if (region_type == MemoryRegion::Type::SHARED) + if ((args->prot & PROT_WRITE) && !(inode_flags & O_WRONLY)) return BAN::Error::from_errno(EACCES); - if (region_type == MemoryRegion::Type::SHARED) - if ((args->prot & PROT_WRITE) && !(inode_flags & O_WRONLY)) - return BAN::Error::from_errno(EACCES); - - auto region = TRY(FileBackedRegion::create( + + BAN::UniqPtr memory_region; + if (inode->mode().ifreg()) + { + memory_region = TRY(FileBackedRegion::create( inode, page_table(), args->off, args->len, { .start = 0x400000, .end = KERNEL_OFFSET }, region_type, page_flags )); - - LockGuard _(m_lock); - TRY(m_mapped_regions.push_back(BAN::move(region))); - return m_mapped_regions.back()->vaddr(); } + else if (inode->is_device()) + { + memory_region = TRY(static_cast(*inode).mmap_region( + page_table(), + args->off, args->len, + { .start = 0x400000, .end = KERNEL_OFFSET }, + region_type, page_flags + )); + } + + if (!memory_region) + return BAN::Error::from_errno(ENODEV); - return BAN::Error::from_errno(ENOTSUP); + TRY(m_mapped_regions.push_back(BAN::move(memory_region))); + return m_mapped_regions.back()->vaddr(); } BAN::ErrorOr Process::sys_munmap(void* addr, size_t len)