Serenity Operating System
at master 52 lines 1.5 kB view raw
1/* 2 * Copyright (c) 2021, Patrick Meyer <git@the-space.agency> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <Kernel/Devices/KCOVInstance.h> 8 9namespace Kernel { 10 11KCOVInstance::KCOVInstance(ProcessID pid) 12{ 13 m_pid = pid; 14} 15 16ErrorOr<void> KCOVInstance::buffer_allocate(size_t buffer_size_in_entries) 17{ 18 if (buffer_size_in_entries < 2 || buffer_size_in_entries > KCOV_MAX_ENTRIES) 19 return EINVAL; 20 21 // first entry contains index of last PC 22 m_buffer_size_in_entries = buffer_size_in_entries - 1; 23 m_buffer_size_in_bytes = TRY(Memory::page_round_up(buffer_size_in_entries * KCOV_ENTRY_SIZE)); 24 25 // one single vmobject is representing the buffer 26 // - we allocate one kernel region using that vmobject 27 // - when an mmap call comes in, we allocate another userspace region, 28 // backed by the same vmobject 29 m_vmobject = TRY(Memory::AnonymousVMObject::try_create_with_size(m_buffer_size_in_bytes, AllocationStrategy::AllocateNow)); 30 31 auto region_name = TRY(KString::formatted("kcov_{}", m_pid)); 32 m_kernel_region = TRY(MM.allocate_kernel_region_with_vmobject( 33 *m_vmobject, m_buffer_size_in_bytes, region_name->view(), 34 Memory::Region::Access::ReadWrite)); 35 36 m_buffer = (u64*)m_kernel_region->vaddr().as_ptr(); 37 return {}; 38} 39 40void KCOVInstance::buffer_add_pc(u64 pc) 41{ 42 auto idx = (u64)m_buffer[0]; 43 if (idx >= m_buffer_size_in_entries) { 44 // the buffer is already full 45 return; 46 } 47 48 m_buffer[idx + 1] = pc; 49 m_buffer[0] = idx + 1; 50} 51 52}