ladybird/Kernel/Devices/KCOVInstance.cpp
Andreas Kling 75564b4a5f Kernel: Make kernel region allocators return KResultOr<NOP<Region>>
This expands the reach of error propagation greatly throughout the
kernel. Sadly, it also exposes the fact that we're allocating (and
doing other fallible things) in constructors all over the place.

This patch doesn't attempt to address that of course. That's work for
our future selves.
2021-09-06 01:55:27 +02:00

59 lines
1.6 KiB
C++

/*
* Copyright (c) 2021, Patrick Meyer <git@the-space.agency>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/String.h>
#include <Kernel/Devices/KCOVInstance.h>
namespace Kernel {
KCOVInstance::KCOVInstance(ProcessID pid)
{
m_pid = pid;
}
KResult KCOVInstance::buffer_allocate(size_t buffer_size_in_entries)
{
if (buffer_size_in_entries < 2 || buffer_size_in_entries > KCOV_MAX_ENTRIES)
return EINVAL;
// first entry contains index of last PC
m_buffer_size_in_entries = buffer_size_in_entries - 1;
m_buffer_size_in_bytes = Memory::page_round_up(buffer_size_in_entries * KCOV_ENTRY_SIZE);
// one single vmobject is representing the buffer
// - we allocate one kernel region using that vmobject
// - when an mmap call comes in, we allocate another userspace region,
// backed by the same vmobject
auto maybe_vmobject = Memory::AnonymousVMObject::try_create_with_size(
m_buffer_size_in_bytes, AllocationStrategy::AllocateNow);
if (maybe_vmobject.is_error())
return maybe_vmobject.error();
m_vmobject = maybe_vmobject.release_value();
m_kernel_region = TRY(MM.allocate_kernel_region_with_vmobject(
*m_vmobject, m_buffer_size_in_bytes, String::formatted("kcov_{}", m_pid),
Memory::Region::Access::ReadWrite));
m_buffer = (u64*)m_kernel_region->vaddr().as_ptr();
if (!has_buffer())
return ENOMEM;
return KSuccess;
}
void KCOVInstance::buffer_add_pc(u64 pc)
{
auto idx = (u64)m_buffer[0];
if (idx >= m_buffer_size_in_entries) {
// the buffer is already full
return;
}
m_buffer[idx + 1] = pc;
m_buffer[0] = idx + 1;
}
}