diff options
author | Brian Gianforcaro <bgianf@serenityos.org> | 2021-05-28 03:56:42 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-05-29 09:04:05 +0200 |
commit | 864b1a65e39292b9c55dab6517babf38c44880fb (patch) | |
tree | 5587a6120b5c9b9069dd8903f1a3ff2215fcfb03 /Kernel | |
parent | cb45b2c001e8c50369c441207a74473105cfb362 (diff) | |
download | serenity-864b1a65e39292b9c55dab6517babf38c44880fb.zip |
Kernel: Make ContiguousVMObject factory API OOM safe
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/VM/ContiguousVMObject.cpp | 10 | ||||
-rw-r--r-- | Kernel/VM/ContiguousVMObject.h | 6 | ||||
-rw-r--r-- | Kernel/VM/MemoryManager.cpp | 6 |
3 files changed, 14 insertions, 8 deletions
diff --git a/Kernel/VM/ContiguousVMObject.cpp b/Kernel/VM/ContiguousVMObject.cpp index 2550cec829..312c9bd671 100644 --- a/Kernel/VM/ContiguousVMObject.cpp +++ b/Kernel/VM/ContiguousVMObject.cpp @@ -10,15 +10,17 @@ namespace Kernel { -NonnullRefPtr<ContiguousVMObject> ContiguousVMObject::create_with_size(size_t size, size_t physical_alignment) +RefPtr<ContiguousVMObject> ContiguousVMObject::create_with_size(size_t size, size_t physical_alignment) { - return adopt_ref(*new ContiguousVMObject(size, physical_alignment)); + auto contiguous_physical_pages = MM.allocate_contiguous_supervisor_physical_pages(size, physical_alignment); + if (contiguous_physical_pages.is_empty()) + return {}; + return adopt_ref_if_nonnull(new ContiguousVMObject(size, contiguous_physical_pages)); } -ContiguousVMObject::ContiguousVMObject(size_t size, size_t physical_alignment) +ContiguousVMObject::ContiguousVMObject(size_t size, NonnullRefPtrVector<PhysicalPage>& contiguous_physical_pages) : VMObject(size) { - auto contiguous_physical_pages = MM.allocate_contiguous_supervisor_physical_pages(size, physical_alignment); for (size_t i = 0; i < page_count(); i++) { physical_pages()[i] = contiguous_physical_pages[i]; dbgln_if(CONTIGUOUS_VMOBJECT_DEBUG, "Contiguous page[{}]: {}", i, physical_pages()[i]->paddr()); diff --git a/Kernel/VM/ContiguousVMObject.h b/Kernel/VM/ContiguousVMObject.h index 576fa696cd..c6c25ca7df 100644 --- a/Kernel/VM/ContiguousVMObject.h +++ b/Kernel/VM/ContiguousVMObject.h @@ -7,18 +7,18 @@ #pragma once #include <Kernel/PhysicalAddress.h> +#include <Kernel/VM/MemoryManager.h> #include <Kernel/VM/VMObject.h> namespace Kernel { - class ContiguousVMObject final : public VMObject { public: virtual ~ContiguousVMObject() override; - static NonnullRefPtr<ContiguousVMObject> create_with_size(size_t, size_t physical_alignment = PAGE_SIZE); + static RefPtr<ContiguousVMObject> create_with_size(size_t, size_t physical_alignment = PAGE_SIZE); private: - explicit ContiguousVMObject(size_t, size_t physical_alignment); + explicit ContiguousVMObject(size_t, NonnullRefPtrVector<PhysicalPage>&); explicit ContiguousVMObject(const ContiguousVMObject&); virtual const char* class_name() const override { return "ContiguousVMObject"; } diff --git a/Kernel/VM/MemoryManager.cpp b/Kernel/VM/MemoryManager.cpp index 0c24693355..33b7be6c76 100644 --- a/Kernel/VM/MemoryManager.cpp +++ b/Kernel/VM/MemoryManager.cpp @@ -464,7 +464,11 @@ OwnPtr<Region> MemoryManager::allocate_contiguous_kernel_region(size_t size, Str if (!range.has_value()) return {}; auto vmobject = ContiguousVMObject::create_with_size(size, physical_alignment); - return allocate_kernel_region_with_vmobject(range.value(), vmobject, name, access, cacheable); + if (!vmobject) { + kernel_page_directory().range_allocator().deallocate(range.value()); + return {}; + } + return allocate_kernel_region_with_vmobject(range.value(), *vmobject, name, access, cacheable); } OwnPtr<Region> MemoryManager::allocate_kernel_region(size_t size, StringView name, Region::Access access, AllocationStrategy strategy, Region::Cacheable cacheable) |