diff options
Diffstat (limited to 'arch/x86_64/syscall-invoke-mapping.c')
-rw-r--r-- | arch/x86_64/syscall-invoke-mapping.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/arch/x86_64/syscall-invoke-mapping.c b/arch/x86_64/syscall-invoke-mapping.c index efecbdf..5b79239 100644 --- a/arch/x86_64/syscall-invoke-mapping.c +++ b/arch/x86_64/syscall-invoke-mapping.c @@ -4,6 +4,9 @@ #include <stddef.h> #include "error.h" #include "lock.h" +#include "string.h" +#include "memory.h" +#include "print.h" static int s_handle_invoke_mapping_release( @@ -13,6 +16,9 @@ s_handle_invoke_mapping_release( size_t payload_at ) { +#ifdef DBG_SYSCALL + klogf("release mapping %p\n", target_entry); +#endif target_entry->data = 0; target_entry->type = KO_NONE; return 0; @@ -29,25 +35,29 @@ s_handle_invoke_mapping_get( pmli_t pmli; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t); - if(pmli > 511) return -KE_OOB; + if(pmli > 511) return KE_OOB; uint8_t level = target_entry->data & 3; pmle_t *target_pml = (pmle_t*)vmem_phys_tovirt(target_entry->data & ~3ULL); - if(level == 3 && pmli > 255) return -KE_OOB; - if(level == 0) return -KE_BADOBJ; - + if(level == 3 && pmli > 255) return KE_OOB; + if(level < 0) return KE_BADOBJ; + size_t dest_pathw; objdir_entry_t *dest_entry; SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry); - if(dest_entry->type != KO_NONE) return -KE_FULL; + + if(dest_entry->type != KO_NONE) return KE_FULL; pmle_t pmle = target_pml[pmli]; - if(!pmle.p) return -KE_DNE; + if(!pmle.p) return KE_DNE; *dest_entry = (objdir_entry_t) { .type = KO_MEMORY_MAPPING, .data = (((uintptr_t)target_pml[pmli].paddr) << 12ULL) | (level - 1) }; +#ifdef DBG_SYSCALL + klogf("Get pml%i %p[%i] -> %p\n", level, target_pml, pmli, dest_entry->data & ~3ULL); +#endif return 0; } @@ -65,37 +75,47 @@ s_handle_invoke_mapping_map( pmli_t pmli; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t); - if(pmli > 511) return -KE_OOB; - if(level == 3 && pmli > 255) return -KE_OOB; + if(pmli > 511) return KE_OOB; + if(level == 3 && pmli > 255) return KE_OOB; + if(level < 0) return KE_BADOBJ; size_t untyped_pathw; objdir_entry_t *untyped_entry; SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, untyped_pathw, untyped_entry); - if(untyped_entry->type != KO_MEMORY_UNTYPED) return -KE_BADOBJ; + if(untyped_entry->type != KO_MEMORY_UNTYPED) return KE_BADOBJ; mtx_acquire(&untyped_entry->lock); if((untyped_entry->data & 0xFFF) != 0) { mtx_release(&untyped_entry->lock); - return -KE_ALIGN; + return KE_ALIGN; } - size_t *untyped_data = (size_t*)untyped_entry->data; - size_t untyped_size = *untyped_data; + + uintptr_t untyped_phys = untyped_entry->data; + size_t *untyped = ko_entry_data(untyped_entry); + size_t untyped_size = *untyped; if(untyped_size != 0x1000) { mtx_release(&untyped_entry->lock); - return -KE_BADSIZE; + return KE_BADSIZE; } pmle_t pmle = target_pml[pmli]; if(pmle.p) { mtx_release(&untyped_entry->lock); - return -KE_OCCUPIED; + return KE_OCCUPIED; } - target_pml[pmli].value = vmem_ident_tophys((void*)untyped_entry->data) | PAGE_RW | PAGE_US | PAGE_PRESENT; + target_pml[pmli].value = untyped_phys | PAGE_RW | PAGE_US | PAGE_PRESENT; + if(level != 0) { + memset(untyped, 0, 0x1000); + } untyped_entry->type = KO_MEMORY_MAPPING; untyped_entry->data |= level - 1; +#ifdef DBG_SYSCALL + klogf("map %p[%p] to pml%i %p[%i]\n", untyped_entry, untyped_phys, level, target_pml, pmli); +#endif + mtx_release(&untyped_entry->lock); return 0; } @@ -119,6 +139,10 @@ syscall_handle_invoke_mapping( uint8_t funcid; SYSCALL_PAYLOAD_TAKEL(payload, payload_at, funcid, uint8_t); - if(funcid >= s_invoke_handles_count) return -KE_BADFUNC; - return s_invoke_handles[funcid](root_dir, target, payload, payload_at); + if(funcid >= s_invoke_handles_count) return KE_BADFUNC; + int r = s_invoke_handles[funcid](root_dir, target, payload, payload_at); +#ifdef DBG_SYSCALL + klogf("Call returns %i\n", r); +#endif + return r; } |