diff options
author | Andreas Kling <kling@serenityos.org> | 2021-02-14 17:35:07 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-02-14 18:11:32 +0100 |
commit | d8013c60bb52756788e747183572067d6e3f204a (patch) | |
tree | 36406e6a97c1fdc74652900102b45630092c949f /Kernel/VM/MemoryManager.cpp | |
parent | 917f7d668c85541ddd754bdd1c5a94538f132ad4 (diff) | |
download | serenity-d8013c60bb52756788e747183572067d6e3f204a.zip |
Kernel: Add mechanism to make some memory read-only after init finishes
You can now use the READONLY_AFTER_INIT macro when declaring a variable
and we will put it in a special ".ro_after_init" section in the kernel.
Data in that section remains writable during the boot and init process,
and is then marked read-only just before launching the SystemServer.
This is based on an idea from the Linux kernel. :^)
Diffstat (limited to 'Kernel/VM/MemoryManager.cpp')
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index be32f030bf..ec3e570444 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -46,6 +46,8 @@ extern u8* end_of_kernel_image; extern FlatPtr start_of_kernel_text; extern FlatPtr start_of_kernel_data; extern FlatPtr end_of_kernel_bss; +extern FlatPtr start_of_ro_after_init; +extern FlatPtr end_of_ro_after_init; extern multiboot_module_entry_t multiboot_copy_boot_modules_array[16]; extern size_t multiboot_copy_boot_modules_count; @@ -121,6 +123,18 @@ void MemoryManager::protect_kernel_image() } } +void MemoryManager::protect_readonly_after_init_memory() +{ + ScopedSpinLock mm_lock(s_mm_lock); + ScopedSpinLock page_lock(kernel_page_directory().get_lock()); + // Disable writing to the .ro_after_init section + for (auto i = (FlatPtr)&start_of_ro_after_init; i < (FlatPtr)&end_of_ro_after_init; i += PAGE_SIZE) { + auto& pte = *ensure_pte(kernel_page_directory(), VirtualAddress(i)); + pte.set_writable(false); + flush_tlb(&kernel_page_directory(), VirtualAddress(i)); + } +} + void MemoryManager::register_reserved_ranges() { ASSERT(!m_physical_memory_ranges.is_empty()); |