1/* 2 * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <stdint.h> 10#include <sel4/sel4.h> 11 12#include <sel4vm/arch/guest_memory_arch.h> 13 14/*** 15 * @module guest_memory.h 16 * The libsel4vm memory interface provides useful abstractions to manage your guest VM's address space. 17 * This interface can be leveraged for uses such as mapping device memory into your VM instance 18 * or for creating emulated device regions binded with custom handlers/callbacks. 19 * The main mechanisms this interface provides involves reserving memory regions and using those reservations 20 * to either map memory into your guest VM's address space or emulate subsequent accesses. Reservations 21 * are created through either using `vm_reserve_memory_at` or `vm_reserve_anon_memory`. 22 * The user can then further back the reservation with seL4 frames by performing `vm_map_reservation`. 23 */ 24 25typedef struct vm vm_t; 26typedef struct vm_vcpu vm_vcpu_t; 27 28/*** 29 * @struct vm_frame_t 30 * Structure representing a mappable memory frame 31 * @param {seL4_CPtr} cptr Capability to frame 32 * @param {seL4_CapRights_t} rights Mapping rights of frame 33 * @param {uintptr_t} vaddr Virtual address of which to map the frame into 34 * @param {size_t} size_bits Size of frame in bits 35 */ 36typedef struct vm_frame { 37 seL4_CPtr cptr; /** Capability to frame */ 38 seL4_CapRights_t rights; /** Mapping rights of frame */ 39 uintptr_t vaddr; /** Virtual address of which to map the frame into */ 40 size_t size_bits; /** Size of frame in bits */ 41} vm_frame_t; 42 43/** 44 * Enumeration of results that can be returned by a memory fault callback (type 'memory_fault_callback_fn') 45 */ 46typedef enum memory_fault_result { 47 FAULT_HANDLED, /** The memory fault was handled, advance execution */ 48 FAULT_UNHANDLED, /** The memory fault was left unhandled */ 49 FAULT_RESTART, /** The memory fault should be restarted, restart execution */ 50 FAULT_IGNORE, /** Ignore the memory fault, advance execution */ 51 FAULT_ERROR /** Handling the memory fault resulted in an error */ 52} memory_fault_result_t; 53 54/** 55 * Type signature of memory fault handler/callback function, provided when creating a memory reservation 56 * @param {vm_t *} vm A handle to the VM 57 * @param {vm_vcpu_t} vcpu A handle to the fault vcpu 58 * @param {uintptr_t} fault addr Faulting address 59 * @param {size_t} fault_length Length of faulted access 60 * @param {void *} cookie User cookie to pass onto callback 61 * @return Fault handling status code: HANDLED, UNHANDLED, RESTART, ERROR 62 */ 63typedef memory_fault_result_t (*memory_fault_callback_fn)(vm_t *vm, vm_vcpu_t *vcpu, uintptr_t fault_addr, 64 size_t fault_length, 65 void *cookie); 66/** 67 * Type signature of memory map iterator function, provided when mapping a memory reservation 68 * @param {uintptr_t} addr Address being mapped 69 * @param {void *} cookie User cookie to pass onto iterator 70 * @return vm_frame_t describing the memory frame that corresponds with the given address 71 */ 72typedef vm_frame_t (*memory_map_iterator_fn)(uintptr_t addr, void *cookie); 73 74typedef struct vm_memory_reservation vm_memory_reservation_t; 75typedef struct vm_memory_reservation_cookie vm_memory_reservation_cookie_t; 76 77/*** 78 * @function vm_reserve_memory_at(vm, addr, size, fault_callback, cookie) 79 * Reserve a region of the VM's memory at a given base address 80 * @param {vm_t *} vm A handle to the VM 81 * @param {uintptr} addr Base address of the memory region being reserved 82 * @param {size_t} size Size of the memory region being reserved 83 * @param {memory_fault_callback_fn} fault_callback Callback function that will be invoked if memory region is faulted on 84 * @param {void *} cookie User cookie to pass onto to callback 85 * @return NULL on failure otherwise a pointer to a reservation object representing the reserved region 86 */ 87vm_memory_reservation_t *vm_reserve_memory_at(vm_t *vm, uintptr_t addr, size_t size, 88 memory_fault_callback_fn fault_callback, void *cookie); 89 90/*** 91 * @function vm_reserve_anon_memory(vm, size, fault_callback, cookie, addr) 92 * Reserve an anonymous region of the VM's memory. This uses memory previously made anonymous 93 * through the `vm_memory_make_anon` function. 94 * @param {vm_t *} vm A handle to the VM 95 * @param {size_t} size Size of the anoymous emory region being reserved 96 * @param {memory_fault_callback_fn} fault_callback Callback function that will be invoked if memory region is faulted on 97 * @param {void *} cookie User cookie to pass onto to callback 98 * @param {uintptr_t *} addr Pointer that will be set with the base address of the reserved anonymous region 99 * @return NULL on failure otherwise a pointer to a reservation object representing the reserved region 100 */ 101vm_memory_reservation_t *vm_reserve_anon_memory(vm_t *vm, size_t size, 102 memory_fault_callback_fn fault_callback, void *cookie, uintptr_t *addr); 103 104/*** vm_memory_make_anon(vm, addr, size) 105 * @function 106 * Create an anoymous region of the VM's memory. This claims a region of VM memory that can be used for the creation 107 * of anonymous reservations (achieved by calling 'vm_reserve_anon_memory'). 108 * @param {vm_t *} vm A handle to the VM 109 * @param {uintptr} addr Base address of the memory region being made into an anoymous reservation 110 * @param {size_t} size Size of the memory region being reserved 111 * @return -1 on failure otherwise 0 for success 112 */ 113int vm_memory_make_anon(vm_t *vm, uintptr_t addr, size_t size); 114 115/*** 116 * @function vm_free_reserved_memory(vm, reservation) 117 * Free memory reservation from the VM 118 * @param {vm_t *} vm A handle to the VM 119 * @param {vm_memory_reservation_t *} reservation Pointer to the reservation being free'd 120 * @return -1 on failure otherwise 0 for success 121 */ 122int vm_free_reserved_memory(vm_t *vm, vm_memory_reservation_t *reservation); 123 124/*** 125 * @function vm_map_reservation(vm, reservation, map_iterator, cookie) 126 * Map a reservation into the VM's virtual address space 127 * @param {vm_t *} vm A handle to the VM 128 * @param {vm_memory_reservation_t *} reservation Pointer to reservation object being mapped 129 * @param {memory_map_iterator_fn} map_iterator Iterator function that returns a cap to the memory region being mapped 130 * @param {void *} cookie Cookie to pass onto map_iterator function 131 * @return -1 on failure otherwise 0 for success 132 */ 133int vm_map_reservation(vm_t *vm, vm_memory_reservation_t *reservation, memory_map_iterator_fn map_iterator, 134 void *cookie); 135 136/*** 137 * @function vm_get_reservation_memory_region(reservation, addr, size) 138 * Get the memory region information (address & size) from a given reservation 139 * @param {vm_memory_reservation_t *} reservation Pointer to reservation object 140 * @param {uintptr_t *} addr Pointer that will be set with the address of reservation 141 * @param {size_t *} size Pointer that will be set with the size of reservation 142 */ 143void vm_get_reservation_memory_region(vm_memory_reservation_t *reservation, uintptr_t *addr, size_t *size); 144 145/*** 146 * @function vm_memory_init(vm) 147 * Initialise a VM's memory management interface 148 * @param {vm_t *} vm A handle to the VM 149 * @return -1 on failure otherwise 0 for success 150*/ 151int vm_memory_init(vm_t *vm); 152