mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[kernel] Change VMA syscall addr param to inout
This change allows the `vma_map` and `vma_create_map` syscalls to map to addresses other than the one specified, and therefore makes the address parameter to those syscalls `inout` in order to return the mapped address. Also add the `exact` flag for specifying that mapping needs to be done at the exact address given. If the mapping collides with another, the new `j6_err_collision` error is returned.
This commit is contained in:
@@ -100,7 +100,7 @@ load_init_server(bootproto::program &program, uintptr_t modules_address)
|
||||
((sect.type && section_flags::write) ? vm_flags::write : vm_flags::none);
|
||||
|
||||
obj::vm_area *vma = new obj::vm_area_fixed(sect.phys_addr, sect.size, flags);
|
||||
space.add(sect.virt_addr, vma);
|
||||
space.add(sect.virt_addr, vma, obj::vm_flags::exact);
|
||||
}
|
||||
|
||||
uint64_t iopl = (3ull << 12);
|
||||
|
||||
@@ -102,8 +102,8 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
||||
obj::vm_area *heap_map = new (&g_kernel_heapmap_area)
|
||||
obj::vm_area_untracked(mem::heapmap_size, vm_flags::write);
|
||||
|
||||
vm.add(mem::heap_offset, heap);
|
||||
vm.add(mem::heapmap_offset, heap_map);
|
||||
vm.add(mem::heap_offset, heap, vm_flags::exact);
|
||||
vm.add(mem::heapmap_offset, heap_map, vm_flags::exact);
|
||||
|
||||
new (&g_kernel_heap) heap_allocator {mem::heap_offset, mem::heap_size, mem::heapmap_offset};
|
||||
|
||||
@@ -111,7 +111,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
||||
size_t log_buffer_size = log::log_pages * arch::frame_size;
|
||||
obj::vm_area *logs = new (&g_kernel_log_area)
|
||||
obj::vm_area_ring(log_buffer_size, vm_flags::write);
|
||||
vm.add(mem::logs_offset, logs);
|
||||
vm.add(mem::logs_offset, logs, vm_flags::exact);
|
||||
|
||||
new (&g_logger) log::logger(
|
||||
util::buffer::from(mem::logs_offset, log_buffer_size));
|
||||
@@ -120,7 +120,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
||||
obj::vm_area *caps = new (&g_cap_table_area)
|
||||
obj::vm_area_untracked(mem::caps_size, vm_flags::write);
|
||||
|
||||
vm.add(mem::caps_offset, caps);
|
||||
vm.add(mem::caps_offset, caps, vm_flags::exact);
|
||||
|
||||
new (&g_cap_table) cap_table {mem::caps_offset};
|
||||
|
||||
@@ -129,7 +129,7 @@ memory_initialize_pre_ctors(bootproto::args &kargs)
|
||||
mem::kernel_stack_pages,
|
||||
mem::stacks_size,
|
||||
vm_flags::write};
|
||||
vm.add(mem::stacks_offset, &g_kernel_stacks);
|
||||
vm.add(mem::stacks_offset, &g_kernel_stacks, vm_flags::exact);
|
||||
|
||||
// Clean out any remaning bootloader page table entries
|
||||
for (unsigned i = 0; i < arch::kernel_root_index; ++i)
|
||||
@@ -140,7 +140,7 @@ void
|
||||
memory_initialize_post_ctors(bootproto::args &kargs)
|
||||
{
|
||||
vm_space &vm = vm_space::kernel_space();
|
||||
vm.add(mem::buffers_offset, &g_kernel_buffers);
|
||||
vm.add(mem::buffers_offset, &g_kernel_buffers, vm_flags::exact);
|
||||
|
||||
g_frame_allocator.free(
|
||||
get_physical_page(kargs.page_tables.pointer),
|
||||
|
||||
@@ -58,7 +58,7 @@ start(cpu_data &bsp, void *kpml4)
|
||||
uintptr_t addr = 0x8000; // TODO: find a valid address, rewrite addresses
|
||||
isr vector = static_cast<isr>(addr >> 12);
|
||||
obj::vm_area *vma = new obj::vm_area_fixed(addr, 0x1000, vm_flags::write);
|
||||
vm_space::kernel_space().add(addr, vma);
|
||||
vm_space::kernel_space().add(addr, vma, obj::vm_flags::exact);
|
||||
memcpy(
|
||||
reinterpret_cast<void*>(addr),
|
||||
reinterpret_cast<void*>(&ap_startup),
|
||||
|
||||
@@ -23,7 +23,7 @@ vma_create(j6_handle_t *self, size_t size, uint32_t flags)
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
vma_create_map(j6_handle_t *self, size_t size, uintptr_t base, uint32_t flags)
|
||||
vma_create_map(j6_handle_t *self, size_t size, uintptr_t *base, uint32_t flags)
|
||||
{
|
||||
vm_area *a = nullptr;
|
||||
vm_flags f = vm_flags::user_mask & flags;
|
||||
@@ -32,16 +32,17 @@ vma_create_map(j6_handle_t *self, size_t size, uintptr_t base, uint32_t flags)
|
||||
else
|
||||
a = construct_handle<vm_area_open>(self, size, f);
|
||||
|
||||
process::current().space().add(base, a);
|
||||
return j6_status_ok;
|
||||
*base = process::current().space().add(*base, a, f);
|
||||
return *base ? j6_status_ok : j6_err_collision;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
vma_map(vm_area *self, process *proc, uintptr_t base)
|
||||
vma_map(vm_area *self, process *proc, uintptr_t *base, uint32_t flags)
|
||||
{
|
||||
vm_space &space = proc ? proc->space() : process::current().space();
|
||||
space.add(base, self);
|
||||
return j6_status_ok;
|
||||
vm_flags f = vm_flags::user_mask & flags;
|
||||
*base = space.add(*base, self, f);
|
||||
return *base ? j6_status_ok : j6_err_collision;
|
||||
}
|
||||
|
||||
j6_status_t
|
||||
|
||||
@@ -57,7 +57,7 @@ vm_space::vm_space() :
|
||||
sizeof(system_config),
|
||||
vm_flags::none);
|
||||
|
||||
add(sysconf_user_address, sysc);
|
||||
add(sysconf_user_address, sysc, vm_flags::exact);
|
||||
}
|
||||
|
||||
vm_space::~vm_space()
|
||||
@@ -80,14 +80,34 @@ vm_space::kernel_space()
|
||||
return obj::process::kernel_process().space();
|
||||
}
|
||||
|
||||
bool
|
||||
vm_space::add(uintptr_t base, obj::vm_area *area)
|
||||
uintptr_t
|
||||
vm_space::add(uintptr_t base, obj::vm_area *area, obj::vm_flags flags)
|
||||
{
|
||||
//TODO: check for collisions
|
||||
if (!base)
|
||||
base = min_auto_address;
|
||||
|
||||
uintptr_t end = base + area->size();
|
||||
|
||||
//TODO: optimize find/insert
|
||||
bool exact = util::bits::has(flags, j6_vm_flag_exact);
|
||||
for (size_t i = 0; i < m_areas.count(); ++i) {
|
||||
const vm_space::area &a = m_areas[i];
|
||||
uintptr_t aend = a.base + a.area->size();
|
||||
if (base >= aend)
|
||||
continue;
|
||||
|
||||
if (end <= a.base)
|
||||
break;
|
||||
else if (exact)
|
||||
return 0;
|
||||
else
|
||||
base = aend;
|
||||
}
|
||||
|
||||
m_areas.sorted_insert({base, area});
|
||||
area->add_to(this);
|
||||
area->handle_retain();
|
||||
return true;
|
||||
return base;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -4,23 +4,27 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <j6/flags.h>
|
||||
#include <util/enum_bitfields.h>
|
||||
#include <util/spinlock.h>
|
||||
#include <util/vector.h>
|
||||
|
||||
#include "objects/vm_area.h"
|
||||
#include "page_table.h"
|
||||
|
||||
struct TCB;
|
||||
|
||||
namespace obj {
|
||||
class process;
|
||||
class vm_area;
|
||||
}
|
||||
|
||||
/// Tracks a region of virtual memory address space
|
||||
class vm_space
|
||||
{
|
||||
public:
|
||||
/// Never map below this address unless explicitly asked.
|
||||
static constexpr uintptr_t min_auto_address = 16 * 1024 * 1024; // 16 MiB
|
||||
|
||||
/// Constructor for the kernel address space
|
||||
/// \arg pml4 The existing kernel PML4
|
||||
vm_space(page_table *pml4);
|
||||
@@ -33,8 +37,9 @@ public:
|
||||
/// Add a virtual memorty area to this address space
|
||||
/// \arg base The starting address of the area
|
||||
/// \arg area The area to add
|
||||
/// \returns True if the add succeeded
|
||||
bool add(uintptr_t base, obj::vm_area *area);
|
||||
/// \arg flags Flags for the operation (exact, clobber, etc)
|
||||
/// \returns The base address the area was added at
|
||||
uintptr_t add(uintptr_t base, obj::vm_area *area, obj::vm_flags flags);
|
||||
|
||||
/// Remove a virtual memory area from this address space
|
||||
/// \arg area The area to remove
|
||||
|
||||
Reference in New Issue
Block a user