From d65347d39dd89013a0c46d8206c77e65d6dceda1 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Thu, 20 Jan 2022 21:10:46 +0200 Subject: [PATCH] Kernel: Make Memory::RingBuffer construction fallible --- Kernel/Bus/VirtIO/Console.cpp | 4 ++-- Kernel/Bus/VirtIO/ConsolePort.cpp | 4 ++-- Kernel/Memory/RingBuffer.cpp | 11 +++++++++-- Kernel/Memory/RingBuffer.h | 6 ++++-- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Kernel/Bus/VirtIO/Console.cpp b/Kernel/Bus/VirtIO/Console.cpp index de4f2779bc..b46475286e 100644 --- a/Kernel/Bus/VirtIO/Console.cpp +++ b/Kernel/Bus/VirtIO/Console.cpp @@ -123,8 +123,8 @@ void Console::handle_queue_update(u16 queue_index) void Console::setup_multiport() { - m_control_receive_buffer = make("VirtIOConsole control receive queue"sv, CONTROL_BUFFER_SIZE); - m_control_transmit_buffer = make("VirtIOConsole control transmit queue"sv, CONTROL_BUFFER_SIZE); + m_control_receive_buffer = Memory::RingBuffer::try_create("VirtIOConsole control receive queue"sv, CONTROL_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(); + m_control_transmit_buffer = Memory::RingBuffer::try_create("VirtIOConsole control transmit queue"sv, CONTROL_BUFFER_SIZE).release_value_but_fixme_should_propagate_errors(); auto& queue = get_queue(CONTROL_RECEIVEQ); SpinlockLocker queue_lock(queue.lock()); diff --git a/Kernel/Bus/VirtIO/ConsolePort.cpp b/Kernel/Bus/VirtIO/ConsolePort.cpp index 78149e2380..8545aac8ae 100644 --- a/Kernel/Bus/VirtIO/ConsolePort.cpp +++ b/Kernel/Bus/VirtIO/ConsolePort.cpp @@ -17,8 +17,8 @@ ConsolePort::ConsolePort(unsigned port, VirtIO::Console& console) , m_console(console) , m_port(port) { - m_receive_buffer = make("VirtIO::ConsolePort Receive"sv, RINGBUFFER_SIZE); - m_transmit_buffer = make("VirtIO::ConsolePort Transmit"sv, RINGBUFFER_SIZE); + m_receive_buffer = Memory::RingBuffer::try_create("VirtIO::ConsolePort Receive"sv, RINGBUFFER_SIZE).release_value_but_fixme_should_propagate_errors(); + m_transmit_buffer = Memory::RingBuffer::try_create("VirtIO::ConsolePort Transmit"sv, RINGBUFFER_SIZE).release_value_but_fixme_should_propagate_errors(); m_receive_queue = m_port == 0 ? 0 : m_port * 2 + 2; m_transmit_queue = m_port == 0 ? 1 : m_port * 2 + 3; } diff --git a/Kernel/Memory/RingBuffer.cpp b/Kernel/Memory/RingBuffer.cpp index 388e4ae1fe..ca0f38602e 100644 --- a/Kernel/Memory/RingBuffer.cpp +++ b/Kernel/Memory/RingBuffer.cpp @@ -10,8 +10,15 @@ namespace Kernel::Memory { -RingBuffer::RingBuffer(StringView region_name, size_t capacity) - : m_region(MM.allocate_contiguous_kernel_region(page_round_up(capacity).release_value_but_fixme_should_propagate_errors(), region_name, Region::Access::Read | Region::Access::Write).release_value()) +ErrorOr> RingBuffer::try_create(StringView region_name, size_t capacity) +{ + auto region_size = TRY(page_round_up(capacity)); + auto region = TRY(MM.allocate_contiguous_kernel_region(region_size, region_name, Region::Access::Read | Region::Access::Write)); + return adopt_nonnull_own_or_enomem(new (nothrow) RingBuffer(move(region), capacity)); +} + +RingBuffer::RingBuffer(NonnullOwnPtr region, size_t capacity) + : m_region(move(region)) , m_capacity_in_bytes(capacity) { } diff --git a/Kernel/Memory/RingBuffer.h b/Kernel/Memory/RingBuffer.h index 8151fa2490..0e36428e58 100644 --- a/Kernel/Memory/RingBuffer.h +++ b/Kernel/Memory/RingBuffer.h @@ -13,7 +13,7 @@ namespace Kernel::Memory { class RingBuffer { public: - RingBuffer(StringView region_name, size_t capacity); + static ErrorOr> try_create(StringView region_name, size_t capacity); bool has_space() const { return m_num_used_bytes < m_capacity_in_bytes; } bool copy_data_in(const UserOrKernelBuffer& buffer, size_t offset, size_t length, PhysicalAddress& start_of_copied_data, size_t& bytes_copied); @@ -29,7 +29,9 @@ public: size_t bytes_till_end() const { return (m_capacity_in_bytes - ((m_start_of_used + m_num_used_bytes) % m_capacity_in_bytes)) % m_capacity_in_bytes; }; private: - OwnPtr m_region; + RingBuffer(NonnullOwnPtr region, size_t capacity); + + NonnullOwnPtr m_region; Spinlock m_lock; size_t m_start_of_used {}; size_t m_num_used_bytes {};