Kernel: Implement MemoryRegion pinning
This allows process to pin a MemoryRegion into users memory space for syscall duration without allowing user to munmap the region.
This commit is contained in:
parent
808c97020a
commit
d54489bbcb
|
@ -3,8 +3,7 @@
|
|||
#include <BAN/UniqPtr.h>
|
||||
#include <kernel/Memory/PageTable.h>
|
||||
#include <kernel/Memory/Types.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <kernel/ThreadBlocker.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
@ -42,6 +41,10 @@ namespace Kernel
|
|||
size_t virtual_page_count() const { return BAN::Math::div_round_up<size_t>(m_size, PAGE_SIZE); }
|
||||
size_t physical_page_count() const { return m_physical_page_count; }
|
||||
|
||||
void pin() { m_pinned_count++; }
|
||||
void unpin() { if (--m_pinned_count == 0) m_pinned_blocker.unblock(); }
|
||||
void wait_not_pinned() { while (m_pinned_count) m_pinned_blocker.block_with_timeout_ms(100); }
|
||||
|
||||
virtual BAN::ErrorOr<void> msync(vaddr_t, size_t, int) = 0;
|
||||
|
||||
// Returns error if no memory was available
|
||||
|
@ -64,6 +67,9 @@ namespace Kernel
|
|||
const PageTable::flags_t m_flags;
|
||||
vaddr_t m_vaddr { 0 };
|
||||
size_t m_physical_page_count { 0 };
|
||||
|
||||
BAN::Atomic<size_t> m_pinned_count { 0 };
|
||||
ThreadBlocker m_pinned_blocker;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Kernel
|
|||
|
||||
MemoryRegion::~MemoryRegion()
|
||||
{
|
||||
ASSERT(m_pinned_count == 0);
|
||||
if (m_vaddr)
|
||||
m_page_table.unmap_range(m_vaddr, m_size);
|
||||
}
|
||||
|
|
|
@ -1806,7 +1806,10 @@ namespace Kernel
|
|||
const vaddr_t region_s = region->vaddr();
|
||||
const vaddr_t region_e = region->vaddr() + region->size();
|
||||
if (vaddr <= region_s && region_e <= vaddr + len)
|
||||
{
|
||||
region->wait_not_pinned();
|
||||
m_mapped_regions.remove(i--);
|
||||
}
|
||||
else if (region->overlaps(vaddr, len))
|
||||
dwarnln("TODO: partial region munmap");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue