diff --git a/Kernel/Devices/SB16.cpp b/Kernel/Devices/SB16.cpp index fa48d20db8..2ae61c8ad2 100644 --- a/Kernel/Devices/SB16.cpp +++ b/Kernel/Devices/SB16.cpp @@ -230,6 +230,8 @@ KResultOr SB16::write(FileDescription&, u64, const UserOrKernelBuffer& d if (!page) return ENOMEM; auto vmobject = AnonymousVMObject::create_with_physical_page(*page); + if (!vmobject) + return ENOMEM; m_dma_region = MM.allocate_kernel_region_with_vmobject(*vmobject, PAGE_SIZE, "SB16 DMA buffer", Region::Access::Write); if (!m_dma_region) return ENOMEM; diff --git a/Kernel/Storage/AHCIPort.cpp b/Kernel/Storage/AHCIPort.cpp index cec7c4f3e7..0f7bfec115 100644 --- a/Kernel/Storage/AHCIPort.cpp +++ b/Kernel/Storage/AHCIPort.cpp @@ -433,7 +433,9 @@ Optional AHCIPort::prepare_and_set_scatter_li allocated_dma_regions.append(m_dma_buffers.at(index)); } - m_current_scatter_list = ScatterGatherList::create(request, allocated_dma_regions, m_connected_device->block_size()); + m_current_scatter_list = ScatterGatherList::create(request, move(allocated_dma_regions), m_connected_device->block_size()); + if (!m_current_scatter_list) + return AsyncDeviceRequest::Failure; if (request.request_type() == AsyncBlockDeviceRequest::Write) { if (!request.read_from_buffer(request.buffer(), m_current_scatter_list->dma_region().as_ptr(), m_connected_device->block_size() * request.block_count())) { return AsyncDeviceRequest::MemoryFault; diff --git a/Kernel/VM/AnonymousVMObject.cpp b/Kernel/VM/AnonymousVMObject.cpp index 038bae41a5..912e4cb275 100644 --- a/Kernel/VM/AnonymousVMObject.cpp +++ b/Kernel/VM/AnonymousVMObject.cpp @@ -60,14 +60,14 @@ RefPtr AnonymousVMObject::create_with_size(size_t size, Alloc return adopt_ref_if_nonnull(new AnonymousVMObject(size, commit)); } -NonnullRefPtr AnonymousVMObject::create_with_physical_pages(NonnullRefPtrVector physical_pages) +RefPtr AnonymousVMObject::create_with_physical_pages(NonnullRefPtrVector physical_pages) { - return adopt_ref(*new AnonymousVMObject(physical_pages)); + return adopt_ref_if_nonnull(new AnonymousVMObject(physical_pages)); } -NonnullRefPtr AnonymousVMObject::create_with_physical_page(PhysicalPage& page) +RefPtr AnonymousVMObject::create_with_physical_page(PhysicalPage& page) { - return adopt_ref(*new AnonymousVMObject(page)); + return adopt_ref_if_nonnull(new AnonymousVMObject(page)); } RefPtr AnonymousVMObject::create_for_physical_range(PhysicalAddress paddr, size_t size) diff --git a/Kernel/VM/AnonymousVMObject.h b/Kernel/VM/AnonymousVMObject.h index a2c990fa59..bdca7c0336 100644 --- a/Kernel/VM/AnonymousVMObject.h +++ b/Kernel/VM/AnonymousVMObject.h @@ -22,8 +22,8 @@ public: static RefPtr create_with_size(size_t, AllocationStrategy); static RefPtr create_for_physical_range(PhysicalAddress paddr, size_t size); - static NonnullRefPtr create_with_physical_page(PhysicalPage& page); - static NonnullRefPtr create_with_physical_pages(NonnullRefPtrVector); + static RefPtr create_with_physical_page(PhysicalPage& page); + static RefPtr create_with_physical_pages(NonnullRefPtrVector); virtual RefPtr clone() override; RefPtr allocate_committed_page(size_t); diff --git a/Kernel/VM/ScatterGatherList.cpp b/Kernel/VM/ScatterGatherList.cpp index 6ebbfece2d..a8452de263 100644 --- a/Kernel/VM/ScatterGatherList.cpp +++ b/Kernel/VM/ScatterGatherList.cpp @@ -8,13 +8,16 @@ namespace Kernel { -NonnullRefPtr ScatterGatherList::create(AsyncBlockDeviceRequest& request, NonnullRefPtrVector allocated_pages, size_t device_block_size) +RefPtr ScatterGatherList::create(AsyncBlockDeviceRequest& request, NonnullRefPtrVector allocated_pages, size_t device_block_size) { - return adopt_ref(*new ScatterGatherList(request, allocated_pages, device_block_size)); + auto vm_object = AnonymousVMObject::create_with_physical_pages(allocated_pages); + if (!vm_object) + return {}; + return adopt_ref_if_nonnull(new ScatterGatherList(vm_object.release_nonnull(), request, device_block_size)); } -ScatterGatherList::ScatterGatherList(AsyncBlockDeviceRequest& request, NonnullRefPtrVector allocated_pages, size_t device_block_size) - : m_vm_object(AnonymousVMObject::create_with_physical_pages(allocated_pages)) +ScatterGatherList::ScatterGatherList(NonnullRefPtr vm_object, AsyncBlockDeviceRequest& request, size_t device_block_size) + : m_vm_object(move(vm_object)) { m_dma_region = MM.allocate_kernel_region_with_vmobject(m_vm_object, page_round_up((request.block_count() * device_block_size)), "AHCI Scattered DMA", Region::Access::Read | Region::Access::Write, Region::Cacheable::Yes); } diff --git a/Kernel/VM/ScatterGatherList.h b/Kernel/VM/ScatterGatherList.h index 0d94cbcfa2..9998d677d4 100644 --- a/Kernel/VM/ScatterGatherList.h +++ b/Kernel/VM/ScatterGatherList.h @@ -18,13 +18,13 @@ namespace Kernel { class ScatterGatherList : public RefCounted { public: - static NonnullRefPtr create(AsyncBlockDeviceRequest&, NonnullRefPtrVector allocated_pages, size_t device_block_size); + static RefPtr create(AsyncBlockDeviceRequest&, NonnullRefPtrVector allocated_pages, size_t device_block_size); const VMObject& vmobject() const { return m_vm_object; } VirtualAddress dma_region() const { return m_dma_region->vaddr(); } size_t scatters_count() const { return m_vm_object->physical_pages().size(); } private: - ScatterGatherList(AsyncBlockDeviceRequest&, NonnullRefPtrVector allocated_pages, size_t device_block_size); + ScatterGatherList(NonnullRefPtr, AsyncBlockDeviceRequest&, size_t device_block_size); NonnullRefPtr m_vm_object; OwnPtr m_dma_region; };