diff --git a/kernel/include/kernel/Memory/VirtualRange.h b/kernel/include/kernel/Memory/VirtualRange.h index a824cb89..5a1c7013 100644 --- a/kernel/include/kernel/Memory/VirtualRange.h +++ b/kernel/include/kernel/Memory/VirtualRange.h @@ -15,21 +15,21 @@ namespace Kernel public: // Create virtual range to fixed virtual address - static BAN::ErrorOr> create_to_vaddr(PageTable&, vaddr_t, size_t, PageTable::flags_t flags, bool preallocate_pages); + static BAN::ErrorOr> create_to_vaddr(PageTable&, vaddr_t, size_t, PageTable::flags_t flags, bool preallocate_pages, bool add_guard_pages); // Create virtual range to virtual address range - static BAN::ErrorOr> create_to_vaddr_range(PageTable&, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t, PageTable::flags_t flags, bool preallocate_pages); + static BAN::ErrorOr> create_to_vaddr_range(PageTable&, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t, PageTable::flags_t flags, bool preallocate_pages, bool add_guard_pages); ~VirtualRange(); BAN::ErrorOr> clone(PageTable&); - vaddr_t vaddr() const { return m_vaddr; } - size_t size() const { return m_size; } + vaddr_t vaddr() const { return m_vaddr + (m_has_guard_pages ? PAGE_SIZE : 0); } + size_t size() const { return m_size - (m_has_guard_pages ? 2 * PAGE_SIZE : 0); } PageTable::flags_t flags() const { return m_flags; } paddr_t paddr_of(vaddr_t vaddr) const { ASSERT(vaddr % PAGE_SIZE == 0); - const size_t index = (vaddr - m_vaddr) / PAGE_SIZE; + const size_t index = (vaddr - this->vaddr()) / PAGE_SIZE; ASSERT(index < m_paddrs.size()); const paddr_t paddr = m_paddrs[index]; ASSERT(paddr); @@ -41,12 +41,13 @@ namespace Kernel BAN::ErrorOr allocate_page_for_demand_paging(vaddr_t address); private: - VirtualRange(PageTable&, bool preallocated, vaddr_t, size_t, PageTable::flags_t); + VirtualRange(PageTable&, bool preallocated, bool has_guard_pages, vaddr_t, size_t, PageTable::flags_t); BAN::ErrorOr initialize(); private: PageTable& m_page_table; const bool m_preallocated; + const bool m_has_guard_pages; const vaddr_t m_vaddr; const size_t m_size; const PageTable::flags_t m_flags; diff --git a/kernel/kernel/Device/FramebufferDevice.cpp b/kernel/kernel/Device/FramebufferDevice.cpp index 5dffa9ea..910a8bc8 100644 --- a/kernel/kernel/Device/FramebufferDevice.cpp +++ b/kernel/kernel/Device/FramebufferDevice.cpp @@ -78,7 +78,7 @@ namespace Kernel KERNEL_OFFSET, UINTPTR_MAX, BAN::Math::div_round_up(m_width * m_height * (BANAN_FB_BPP / 8), PAGE_SIZE) * PAGE_SIZE, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); return {}; diff --git a/kernel/kernel/Memory/VirtualRange.cpp b/kernel/kernel/Memory/VirtualRange.cpp index ea821d2e..8d640bdd 100644 --- a/kernel/kernel/Memory/VirtualRange.cpp +++ b/kernel/kernel/Memory/VirtualRange.cpp @@ -4,21 +4,30 @@ namespace Kernel { - BAN::ErrorOr> VirtualRange::create_to_vaddr(PageTable& page_table, vaddr_t vaddr, size_t size, PageTable::flags_t flags, bool preallocate_pages) + BAN::ErrorOr> VirtualRange::create_to_vaddr(PageTable& page_table, vaddr_t vaddr, size_t size, PageTable::flags_t flags, bool preallocate_pages, bool add_guard_pages) { ASSERT(size % PAGE_SIZE == 0); ASSERT(vaddr % PAGE_SIZE == 0); ASSERT(vaddr > 0); - auto result = TRY(BAN::UniqPtr::create(page_table, preallocate_pages, vaddr, size, flags)); + if (add_guard_pages) + { + vaddr -= PAGE_SIZE; + size += 2 * PAGE_SIZE; + } + + auto result = TRY(BAN::UniqPtr::create(page_table, preallocate_pages, add_guard_pages, vaddr, size, flags)); ASSERT(page_table.reserve_range(vaddr, size)); TRY(result->initialize()); return result; } - BAN::ErrorOr> VirtualRange::create_to_vaddr_range(PageTable& page_table, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t size, PageTable::flags_t flags, bool preallocate_pages) + BAN::ErrorOr> VirtualRange::create_to_vaddr_range(PageTable& page_table, vaddr_t vaddr_start, vaddr_t vaddr_end, size_t size, PageTable::flags_t flags, bool preallocate_pages, bool add_guard_pages) { + if (add_guard_pages) + size += 2 * PAGE_SIZE; + ASSERT(size % PAGE_SIZE == 0); ASSERT(vaddr_start > 0); ASSERT(vaddr_start + size <= vaddr_end); @@ -31,13 +40,13 @@ namespace Kernel ASSERT(vaddr_start < vaddr_end); ASSERT(vaddr_end - vaddr_start + 1 >= size / PAGE_SIZE); - vaddr_t vaddr = page_table.reserve_free_contiguous_pages(size / PAGE_SIZE, vaddr_start, vaddr_end); + const vaddr_t vaddr = page_table.reserve_free_contiguous_pages(size / PAGE_SIZE, vaddr_start, vaddr_end); if (vaddr == 0) return BAN::Error::from_errno(ENOMEM); ASSERT(vaddr >= vaddr_start); ASSERT(vaddr + size <= vaddr_end); - auto result_or_error = BAN::UniqPtr::create(page_table, preallocate_pages, vaddr, size, flags); + auto result_or_error = BAN::UniqPtr::create(page_table, preallocate_pages, add_guard_pages, vaddr, size, flags); if (result_or_error.is_error()) { page_table.unmap_range(vaddr, size); @@ -50,9 +59,10 @@ namespace Kernel return result; } - VirtualRange::VirtualRange(PageTable& page_table, bool preallocated, vaddr_t vaddr, size_t size, PageTable::flags_t flags) + VirtualRange::VirtualRange(PageTable& page_table, bool preallocated, bool has_guard_pages, vaddr_t vaddr, size_t size, PageTable::flags_t flags) : m_page_table(page_table) , m_preallocated(preallocated) + , m_has_guard_pages(has_guard_pages) , m_vaddr(vaddr) , m_size(size) , m_flags(flags) @@ -70,26 +80,26 @@ namespace Kernel BAN::ErrorOr VirtualRange::initialize() { - TRY(m_paddrs.resize(m_size / PAGE_SIZE, 0)); + TRY(m_paddrs.resize(size() / PAGE_SIZE, 0)); if (!m_preallocated) return {}; - const size_t page_count = m_size / PAGE_SIZE; + const size_t page_count = size() / PAGE_SIZE; for (size_t i = 0; i < page_count; i++) { m_paddrs[i] = Heap::get().take_free_page(); if (m_paddrs[i] == 0) return BAN::Error::from_errno(ENOMEM); - m_page_table.map_page_at(m_paddrs[i], m_vaddr + i * PAGE_SIZE, m_flags); + m_page_table.map_page_at(m_paddrs[i], vaddr() + i * PAGE_SIZE, m_flags); } if (&PageTable::current() == &m_page_table || &PageTable::kernel() == &m_page_table) - memset(reinterpret_cast(m_vaddr), 0, m_size); + memset(reinterpret_cast(vaddr()), 0, size()); else { - const size_t page_count = m_size / PAGE_SIZE; - for (size_t i = 0; i < page_count; i++) + const size_t page_count = size() / PAGE_SIZE; + for (size_t i = m_has_guard_pages; i < page_count; i++) { PageTable::with_fast_page(m_paddrs[i], [&] { memset(PageTable::fast_page_as_ptr(), 0, PAGE_SIZE); @@ -107,10 +117,10 @@ namespace Kernel SpinLockGuard _(m_lock); - auto result = TRY(create_to_vaddr(page_table, m_vaddr, m_size, m_flags, m_preallocated)); + auto result = TRY(create_to_vaddr(page_table, vaddr(), size(), m_flags, m_preallocated, m_has_guard_pages)); - const size_t page_count = m_size / PAGE_SIZE; - for (size_t i = 0; i < page_count; i++) + const size_t page_count = size() / PAGE_SIZE; + for (size_t i = m_has_guard_pages; i < page_count; i++) { if (m_paddrs[i] == 0) continue; @@ -119,11 +129,11 @@ namespace Kernel result->m_paddrs[i] = Heap::get().take_free_page(); if (result->m_paddrs[i] == 0) return BAN::Error::from_errno(ENOMEM); - result->m_page_table.map_page_at(result->m_paddrs[i], m_vaddr + i * PAGE_SIZE, m_flags); + result->m_page_table.map_page_at(result->m_paddrs[i], vaddr() + i * PAGE_SIZE, m_flags); } PageTable::with_fast_page(result->m_paddrs[i], [&] { - memcpy(PageTable::fast_page_as_ptr(), reinterpret_cast(m_vaddr + i * PAGE_SIZE), PAGE_SIZE); + memcpy(PageTable::fast_page_as_ptr(), reinterpret_cast(vaddr() + i * PAGE_SIZE), PAGE_SIZE); }); } @@ -137,7 +147,7 @@ namespace Kernel ASSERT(contains(vaddr)); ASSERT(&PageTable::current() == &m_page_table); - const size_t index = (vaddr - m_vaddr) / PAGE_SIZE; + const size_t index = (vaddr - this->vaddr()) / PAGE_SIZE; ASSERT(m_paddrs[index] == 0); SpinLockGuard _(m_lock); diff --git a/kernel/kernel/Networking/IPv4Layer.cpp b/kernel/kernel/Networking/IPv4Layer.cpp index 4106970b..3a9dc8b1 100644 --- a/kernel/kernel/Networking/IPv4Layer.cpp +++ b/kernel/kernel/Networking/IPv4Layer.cpp @@ -35,7 +35,7 @@ namespace Kernel ~(uintptr_t)0, pending_packet_buffer_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); ipv4_manager->m_arp_table = TRY(ARPTable::create()); return ipv4_manager; diff --git a/kernel/kernel/Networking/Loopback.cpp b/kernel/kernel/Networking/Loopback.cpp index 3ec98106..9c1b6e58 100644 --- a/kernel/kernel/Networking/Loopback.cpp +++ b/kernel/kernel/Networking/Loopback.cpp @@ -16,7 +16,7 @@ namespace Kernel BAN::numeric_limits::max(), buffer_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); loopback->set_ipv4_address({ 127, 0, 0, 1 }); loopback->set_netmask({ 255, 0, 0, 0 }); diff --git a/kernel/kernel/Networking/TCPSocket.cpp b/kernel/kernel/Networking/TCPSocket.cpp index a8a41db6..a04535b2 100644 --- a/kernel/kernel/Networking/TCPSocket.cpp +++ b/kernel/kernel/Networking/TCPSocket.cpp @@ -32,7 +32,7 @@ namespace Kernel ~(vaddr_t)0, s_recv_window_buffer_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); socket->m_recv_window.scale_shift = PAGE_SIZE_SHIFT; // use PAGE_SIZE windows socket->m_send_window.buffer = TRY(VirtualRange::create_to_vaddr_range( @@ -41,7 +41,7 @@ namespace Kernel ~(vaddr_t)0, s_send_window_buffer_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); socket->m_thread = TRY(Thread::create_kernel( [](void* socket_ptr) diff --git a/kernel/kernel/Networking/UDPSocket.cpp b/kernel/kernel/Networking/UDPSocket.cpp index 03aa47d6..ce0b9fba 100644 --- a/kernel/kernel/Networking/UDPSocket.cpp +++ b/kernel/kernel/Networking/UDPSocket.cpp @@ -17,7 +17,7 @@ namespace Kernel ~(uintptr_t)0, packet_buffer_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); return socket; } diff --git a/kernel/kernel/Networking/UNIX/Socket.cpp b/kernel/kernel/Networking/UNIX/Socket.cpp index 5d9936c2..ebe5958d 100644 --- a/kernel/kernel/Networking/UNIX/Socket.cpp +++ b/kernel/kernel/Networking/UNIX/Socket.cpp @@ -29,7 +29,7 @@ namespace Kernel ~(uintptr_t)0, s_packet_buffer_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, false )); return socket; } diff --git a/kernel/kernel/Terminal/PseudoTerminal.cpp b/kernel/kernel/Terminal/PseudoTerminal.cpp index 43f30fe1..7132834a 100644 --- a/kernel/kernel/Terminal/PseudoTerminal.cpp +++ b/kernel/kernel/Terminal/PseudoTerminal.cpp @@ -44,7 +44,8 @@ namespace Kernel PageTable::kernel(), KERNEL_OFFSET, static_cast(-1), 16 * PAGE_SIZE, - PageTable::Flags::ReadWrite | PageTable::Flags::Present, true + PageTable::Flags::ReadWrite | PageTable::Flags::Present, + true, false )); auto pts_master = TRY(BAN::RefPtr::create(BAN::move(pts_master_buffer), mode, uid, gid)); DevFileSystem::get().remove_from_cache(pts_master); diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 7332e630..f58072c2 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -84,7 +84,7 @@ namespace Kernel ~(uintptr_t)0, kernel_stack_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, true )); // Initialize stack for returning @@ -124,7 +124,7 @@ namespace Kernel 0x200000, USERSPACE_END, kernel_stack_size, PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, true )); thread->m_userspace_stack = TRY(VirtualRange::create_to_vaddr_range( @@ -132,7 +132,7 @@ namespace Kernel 0x200000, USERSPACE_END, userspace_stack_size, PageTable::Flags::UserSupervisor | PageTable::Flags::ReadWrite | PageTable::Flags::Present, - true + true, true )); thread_deleter.disable();