Kernel: Implement copy-on-write memory for file backed mmaps

This commit is contained in:
2024-09-11 19:32:42 +03:00
parent 4006a04817
commit c77ad5fb34
15 changed files with 217 additions and 208 deletions

View File

@@ -159,6 +159,7 @@ namespace Kernel
private:
BAN::WeakPtr<SharedFileData> m_shared_region;
friend class FileBackedRegion;
friend class SharedFileData;
};
}

View File

@@ -12,6 +12,8 @@ namespace Kernel
void sync(size_t page_index);
Mutex mutex;
// FIXME: this should probably be ordered tree like map
// for fast lookup and less memory usage
BAN::Vector<paddr_t> pages;
@@ -33,7 +35,7 @@ namespace Kernel
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) override;
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr) override;
virtual 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);
@@ -42,7 +44,7 @@ namespace Kernel
BAN::RefPtr<Inode> m_inode;
const off_t m_offset;
// FIXME: is this even synchronized?
BAN::Vector<paddr_t> m_dirty_pages;
BAN::RefPtr<SharedFileData> m_shared_data;
};

View File

@@ -23,7 +23,7 @@ namespace Kernel
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) override;
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private:
MemoryBackedRegion(PageTable&, size_t size, Type, PageTable::flags_t);

View File

@@ -34,6 +34,8 @@ namespace Kernel
bool contains_fully(vaddr_t address, size_t size) const;
bool overlaps(vaddr_t address, size_t size) const;
bool writable() const { return m_flags & PageTable::Flags::ReadWrite; }
size_t size() const { return m_size; }
vaddr_t vaddr() const { return m_vaddr; }
@@ -45,7 +47,7 @@ namespace Kernel
// Returns error if no memory was available
// Returns true if page was succesfully allocated
// Returns false if page was already allocated
BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address);
BAN::ErrorOr<bool> allocate_page_containing(vaddr_t address, bool wants_write);
virtual BAN::ErrorOr<BAN::UniqPtr<MemoryRegion>> clone(PageTable& new_page_table) = 0;
@@ -53,7 +55,7 @@ namespace Kernel
MemoryRegion(PageTable&, size_t size, Type type, PageTable::flags_t flags);
BAN::ErrorOr<void> initialize(AddressRange);
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address) = 0;
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t address, bool wants_write) = 0;
protected:
PageTable& m_page_table;

View File

@@ -59,7 +59,7 @@ namespace Kernel
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) override { return {}; }
protected:
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr) override;
virtual BAN::ErrorOr<bool> allocate_page_containing_impl(vaddr_t vaddr, bool wants_write) override;
private:
SharedMemoryObject(BAN::RefPtr<SharedMemoryObjectManager::Object> object, PageTable& page_table)

View File

@@ -210,7 +210,7 @@ namespace Kernel
// Returns error if page could not be allocated
// Returns true if the page was allocated successfully
// Return false if access was page violation (segfault)
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t addr);
BAN::ErrorOr<bool> allocate_page_for_demand_paging(vaddr_t addr, bool wants_write);
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;
@@ -225,8 +225,8 @@ namespace Kernel
static BAN::ErrorOr<BAN::UniqPtr<LibELF::LoadableELF>> load_elf_for_exec(const Credentials&, BAN::StringView file_path, const BAN::String& cwd, Kernel::PageTable&);
BAN::ErrorOr<void> validate_string_access(const char*);
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t);
BAN::ErrorOr<void> validate_pointer_access(const void*, size_t);
BAN::ErrorOr<void> validate_pointer_access_check(const void*, size_t, bool needs_write);
BAN::ErrorOr<void> validate_pointer_access(const void*, size_t, bool needs_write);
uint64_t signal_pending_mask() const
{