Kernel: Add API for implementing mmappable devices

This commit is contained in:
Bananymous 2023-11-28 23:50:49 +02:00
parent d86ecf4f61
commit 4a87d6052b
2 changed files with 33 additions and 17 deletions

View File

@ -1,6 +1,7 @@
#pragma once
#include <kernel/FS/TmpFS/Inode.h>
#include <kernel/Memory/MemoryRegion.h>
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<BAN::UniqPtr<MemoryRegion>> 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;

View File

@ -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<MemoryRegion> 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<Device&>(*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<long> Process::sys_munmap(void* addr, size_t len)