Kernel/LibC: Implement mprotect

There may be some race conditions with this but i think this is good
enough to start with
This commit is contained in:
2025-08-05 02:39:19 +03:00
parent eb7922ab88
commit f1369c8fd6
18 changed files with 167 additions and 61 deletions

View File

@@ -27,18 +27,18 @@ namespace Kernel
BAN_NON_MOVABLE(FileBackedRegion);
public:
static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t);
static BAN::ErrorOr<BAN::UniqPtr<FileBackedRegion>> create(BAN::RefPtr<Inode>, PageTable&, off_t offset, size_t size, AddressRange address_range, Type, PageTable::flags_t, int status_flags);
~FileBackedRegion();
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override;
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override;
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private:
FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type flags, PageTable::flags_t page_flags);
FileBackedRegion(BAN::RefPtr<Inode>, PageTable&, off_t offset, ssize_t size, Type type, PageTable::flags_t flags, int status_flags);
private:
BAN::RefPtr<Inode> m_inode;

View File

@@ -11,22 +11,22 @@ namespace Kernel
BAN_NON_MOVABLE(MemoryBackedRegion);
public:
static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t);
static BAN::ErrorOr<BAN::UniqPtr<MemoryBackedRegion>> create(PageTable&, size_t size, AddressRange, Type, PageTable::flags_t, int status_flags);
~MemoryBackedRegion();
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
// Copy data from buffer into this region
// This can fail if no memory is mapped and no free memory was available
BAN::ErrorOr<void> copy_data_to_region(size_t offset_into_region, const uint8_t* buffer, size_t buffer_size);
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private:
MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t);
MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t, int status_flags);
};
}

View File

@@ -39,6 +39,10 @@ namespace Kernel
size_t size() const { return m_size; }
vaddr_t vaddr() const { return m_vaddr; }
int status_flags() const { return m_status_flags; }
Type type() const { return m_type; }
PageTable::flags_t flags() const { return m_flags; }
size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); }
size_t physical_page_count() const { return m_physical_page_count; }
@@ -46,6 +50,7 @@ namespace Kernel
void unpin();
void wait_not_pinned();
BAN::ErrorOr<void> mprotect(PageTable::flags_t);
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) = 0;
// Returns error if no memory was available
@@ -56,7 +61,7 @@ namespace Kernel
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0;
protected:
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags);
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags, int status_flags);
BAN::ErrorOr<void> initialize(AddressRange);
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address, bool wants_write) = 0;
@@ -65,7 +70,8 @@ namespace Kernel
PageTable& m_page_table;
const size_t m_size;
const Type m_type;
const PageTable::flags_t m_flags;
PageTable::flags_t m_flags;
const int m_status_flags;
vaddr_t m_vaddr { 0 };
size_t m_physical_page_count { 0 };

View File

@@ -6,6 +6,8 @@
#include <kernel/Lock/SpinLock.h>
#include <kernel/Memory/MemoryRegion.h>
#include <fcntl.h>
namespace Kernel
{
@@ -55,15 +57,16 @@ namespace Kernel
public:
static BAN::ErrorOr<BAN::UniqPtr<SharedMemoryObject>> create(BAN::RefPtr<SharedMemoryObjectManager::Object>, PageTable&, AddressRange);
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private:
SharedMemoryObject(BAN::RefPtr<SharedMemoryObjectManager::Object> object, PageTable& page_table)
: MemoryRegion(page_table, object->size, MemoryRegion::Type::SHARED, object->flags)
: MemoryRegion(page_table, object->size, MemoryRegion::Type::SHARED, object->flags, O_EXEC | O_RDWR)
, m_object(object)
{ }

View File

@@ -38,7 +38,7 @@ namespace Kernel
bool contains(vaddr_t address) const { return vaddr() <= address && address < vaddr() + size(); }
BAN::ErrorOr<void> allocate_page_for_demand_paging(vaddr_t address);
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t address);
private:
VirtualRange(PageTable&, bool preallocated, bool has_guard_pages, vaddr_t, size_t, PageTable::flags_t);