## Jove syscalls Every syscall in Jove is passed to the kernel via a `JOVE_OBJ_MESSAGE` object. To pass a message object to the kernel, the message object must be close to the root directory of the calling PCB. To resolve the message object, the kernel requires an object path and a path length encoded in argument registers. On x86_64, the encoding is as follows: | Message Path | Message Path Length | |--------------|---------------------| | rdi | rsi | If the message path exceeds the width of the message path register, the kernel will return `-EBADPATH`. If the message path does not point to a `JOVE_OBJ_MESSAGE` object, the kernel will return `-EBADOBJ`. If the message path points to an object locked by a mutex, the kernel will return `-EBUSY`. ### Syscall header | Size (bytes) | 2 | 2 | path_len * 2 | |--------------|---------|------------------------|--------------| | Data | Call ID | Path length (path_len) | Target path | All system calls must start with these bytes at the start of the passed message object. 1. `Call ID`: ID of the system call to invoke. 2. `Path length`: Length of the target path. 3. `Object path`: Path to the target object starting from the PCB's root directory. If the target path length exceeds the width of the message object, the kernel will return `-ETOOSMALL`. If the target path points to a `JOVE_OBJ_NONE` object, the kernel will return `-EBADOBJ`. If the target object does not support the call id, the kernel will return `-EBADCALL`. Further behavior is specified by the target syscall specification. Target syscalls may have further required bytes in the message. If the syscall does not have the correct permissions for the syscall, the kernel will return `-ENOPERM`. ### JOVE_OBJ_UNTYPED | Syscall | Permissions Required | |-------------------------|-----------------------------------| | SYSCALL_UNTYPED_ADDRESS | JOVE_PERM_READ | | SYSCALL_UNTYPED_SIZE | JOVE_PERM_READ | | SYSCALL_UNTYPED_SPLIT | JOVE_PERM_WRITE, JOVE_PERM_MUTATE | | SYSCALL_UNTYPED_MERGE | JOVE_PERM_WRITE, JOVE_PERM_MUTATE | | SYSCALL_UNTYPED_RETYPE | JOVE_PERM_WRITE, JOVE_PERM_MUTATE | #### SYSCALL_UNTYPED_ADDRESS Returns the physical address of the untyped memory span. #### SYSCALL_UNTYPED_SIZE Returns the size of the untyped memory span. #### SYSCALL_UNTYPED_SPLIT Splits the untyped memory span into the destination path sized by the split size. | Data | Split size | Destination Path Length | Destination Path | |--------------|----------------|-------------------------|------------------| | Size (bytes) | sizeof(size_t) | 2 | path_len * 2 | If the split size exceeds the size of the target untyped, the kernel will return `-ETOOBIG`. If the split size is less than `JOVE_UNTYPED_MINSIZE`, the kernel will return `-ETOOSMALL`. If the destination path length exceeds the size of the message, the kernel will return `-EBADPATH`. If the destination path does not point to a `JOVE_OBJ_NONE` object, the kernel will return `-EBADOBJ`. #### SYSCALL_UNTYPED_MERGE Merges two adjacent untyped memory spans into one untyped memory span at the first untyped object. | Data | Untyped Path Length | Untyped Path | |--------------|---------------------|--------------| | Size (bytes) | 2 | path_len * 2 | If the untyped path length exceeds the size of the message, the kernel will return `-EBADPATH`. If the untyped path does not point to a `JOVE_OBJ_NONE` object, the kernel will return `-EBADOBJ`. ### JOVE_OBJ_OBJDIR | Syscall | Permissions Required | |------------------------|----------------------| | SYSCALL_OBJDIR_OBJTYPE | JOVE_PERM_READ | #### SYSCALL_OBJDIR_OBJTYPE Returns the object type at the given entry index. | Data | Entry Index | |--------------|-------------| | Size (bytes) | 2 | If the message is too small to hold the payload, the kernel will return `-ETOOSMALL`. If the entry index exceeds `JOVE_OBJDIR_ENTRIES`, the kernel returns `-EOOB`. ### JOVE_OBJ_PAGEDIR | Syscall | Target Permissions | Subject Permissions | Subject Conditional Permissions | |-----------------------------|:-------------------------------:|:-------------------------------------------------:|:-------------------------------:| | SYSCALL_PAGEDIR_MAP_FRAME | JOVE_PERM_READ, JOVE_PERM_WRITE | JOVE_PERM_MUTATE | JOVE_PERM_READ, JOVE_PERM_WRITE | | SYSCALL_PAGEDIR_MAP_TABLE | JOVE_PERM_READ, JOVE_PERM_WRITE | JOVE_PERM_READ, JOVE_PERM_WRITE, JOVE_PERM_MUTATE | | | SYSCALL_PAGEDIR_MAP_SHMEM | JOVE_PERM_READ, JOVE_PERM_WRITE | JOVE_PERM_READ | JOVE_PERM_WRITE | | SYSCALL_PAGEDIR_UNMAP_FRAME | JOVE_PERM_READ, JOVE_PERM_WRITE | | | | SYSCALL_PAGEDIR_UNMAP_TABLE | JOVE_PERM_READ, JOVE_PERM_WRITE | | | | SYSCALL_PAGEDIR_UNMAP_SHMEM | JOVE_PERM_READ, JOVE_PERM_WRITE | | | #### SYSCALL_PAGEDIR_MAP_FRAME Attempts to map a given untyped memory span to the given virtual address with passed permissions. | Data | Page flags | Untyped Path Length | Virtual address | Untyped Path | |--------------|------------|---------------------|-------------------|--------------| | Size (bytes) | 1 | 2 | sizeof(void*) | path_len * 2 | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the virtual address exceeds `JOVE_USER_MEMORY_LIMIT`, the kernel will return `-EOOB`. If the untyped path does not point to a `JOVE_OBJ_UNTYPED` object, the kernel will return `-EBADOBJ`. If the untyped object is not aligned to `0x1000` bytes, the kernel will return `-EALIGN`. If the untyped object is not exactly `0x1000` bytes wide, the kernel will return `-EBADSIZE`. If the untyped object does not have `JOVE_PERM_MUTATE` and `JOVE_PERM_READ`, the kernel will return `-ENOPERM`. If the untyped object does not have `JOVE_PERM_WRITE` and the passed flags include the writeable bit, the kernel will return `-ENOPERM.`. If the virtual address does not have enough page table structures to support the page mapping, the kernel will return `-ENOMAP`. If the virtual address already has a page mapping, the kernel will return `-EHASMAP`. Successful mapping replaces the untyped object with a `JOVE_OBJ_NONE` object and returns `0`. #### SYSCALL_PAGEDIR_MAP_TABLE Attempts to map a given untyped memory span as a table for mapping further page frames onto `virtual address`. | Data | Virtual address | Untyped Path Length | Untyped Path | |--------------|-----------------|---------------------|--------------| | Size (bytes) | sizeof(void*) | 2 | path_len * 2 | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the virtual address exceeds `JOVE_USER_MEMORY_LIMIT`, the kernel will return `-EOOB`. If the untyped path does not point to a `JOVE_OBJ_UNTYPED` object, the kernel will return `-EBADOBJ`. If the untyped object is not aligned to `0x1000` bytes, the kernel will return `-EALIGN`. If the untyped object is not exactly `0x1000` bytes wide, the kernel will return `-EBADSIZE`. If the untyped object does not have `JOVE_PERM_MUTATE`, `JOVE_PERM_READ`, and `JOVE_PERM_WRITE`, the kernel will return `-ENOPERM`. If the virtual address already has enough tables to allocate a page frame onto them, the kernel will return `-EHASMAP`. Successful mapping replaces the untyped object with a `JOVE_OBJ_NONE` object and returns `0`. #### SYSCALL_PAGEDIR_MAP_SHMEM Attempts to map a shared memory page at `virtual address`. Does not consume the shared memory object. | Data | Page flags | Page offset | Shared Memory Path Length | Virtual address | Shared Memory Path | |--------------|------------|-------------|---------------------------|-----------------|--------------------| | Size (bytes) | 1 | 1 | 2 | sizeof(void*) | path_len * 2 | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the virtual address exceeds `JOVE_USER_MEMORY_LIMIT`, the kernel will return `-EOOB`. If the shmem path does not point to a `JOVE_OBJ_SHMEMORY` object, the kernel will return `-EBADOBJ`. If the shmem object does not have `JOVE_PERM_READ`, the kernel will return `-ENOPERM`. If the shmem object does not have `JOVE_PERM_WRITE` and the passed flags include the writeable bit, the kernel will return `-ENOPERM.`. If the virtual address does not have enough page table structures to support the page mapping, the kernel will return `-ENOMAP`. If the virtual address already has a page mapping, the kernel will return `-EHASMAP`. Successful mapping returns `0`. #### SYSCALL_PAGEDIR_UNMAP_FRAME Attempts to remove an untyped memory mapping from the page table at `virtual address`. | Data | Virtual address | Destination Path Length | Destination Path | |--------------|-----------------|-------------------------|------------------| | Size (bytes) | sizeof(void*) | 2 | path_len * 2 | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the virtual address exceeds `JOVE_USER_MEMORY_LIMIT`, the kernel will return `-EOOB`. If the destination path does not point to a `JOVE_OBJ_NONE` object, the kernel will return `-EFULL`. If the virtual address does not have a page mapping, the kernel will return `-ENOMAP`. If the virtual address does not map to an untyped page frame, the kernel will return `-EBADARG`. Successful unmapping fills the destination path with a page-sized `JOVE_OBJ_UNTYPED` object with correct permissions and return 0. #### SYSCALL_PAGEDIR_UNMAP_TABLE Attempts to remove a page table mapping from the page directory heirarchy at `virtual address` | Data | Virtual address | Destination Path Length | Destination Path | |--------------|-----------------|-------------------------|------------------| | Size (bytes) | sizeof(void*) | 2 | path_len * 2 | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the virtual address exceeds `JOVE_USER_MEMORY_LIMIT`, the kernel will return `-EOOB`. If the destination path does not point to a `JOVE_OBJ_NONE` object, the kernel will return `-EFULL`. If the table mapping the virtual address has any occupied entries, the kernel will return `-EHASMAP`. If no table mapping exists for this virtual address, the kernel will return `-ENOMAP`. Successful unmapping fills the destination path with a page-sized `JOVE_OBJ_UNTYPED` object with correct permissions and return 0. #### SYSCALL_PAGEDIR_UNMAP_SHMEM Attempts to unmap a shared memory page at `virtual address`. | Data | Virtual address | |--------------|-----------------| | Size (bytes) | sizeof(void*) | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the virtual address exceeds `JOVE_USER_MEMORY_LIMIT`, the kernel will return `-EOOB`. If the virtual address does not have a page frame associated with it, the kernel will return `-ENOMAP`. If the page frame pointed to by virtual address does not correspond to a shared memory frame, the kernel will return `-EBADOBJ`. Successful unmapping returns `0`. ### JOVE_OBJ_INITRD_FILE | Syscall | Target Permissions | |--------------------------|--------------------| | SYSCALL_INITRD_FILE_NAME | JOVE_PERM_READ | | SYSCALL_INITRD_FILE_SIZE | JOVE_PERM_READ | | SYSCALL_INITRD_FILE_READ | JOVE_PERM_READ | #### SYSCALL_INITRD_FILE_NAME Populates the message with the name of the target file. Names start with a size_t length specifier, which is followed by a NULL-terminated c-string. | Data | Name Length | Name | Null Terminator | |--------------|----------------|-------------|-----------------| | Size (bytes) | sizeof(size_t) | Name Length | 1 | If the message is too small for the file name, the kernel will return `-ETOOSMALL`. #### SYSCALL_INITRD_FILE_SIZE Returns the size of the target file in bytes. #### SYSCALL_INITRD_FILE_READ Populates the message with the bytes read from the target file. ##### Payload | Data | Starting index | Read size | |--------------|----------------|----------------| | Size (bytes) | sizeof(size_t) | sizeof(size_t) | ##### Return | Data | Data | |--------------|-----------| | Size (bytes) | Read size | If the message is too small for the syscall payload, the kernel will return `-ETOOSMALL`. If the starting index exceeds the file length, the kernel will return `-EOOB`. If the read size + starting index > file size, the kernel will return `-EOOB`. If the message is too small for the read bytes, the kernel will return `-ETOOBIG`. Successful reading returns `0`. ### JOVE_OBJ_MESSAGE