1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2018, EPAM Systems. All rights reserved. 4 * Copyright (c) 2024, Linaro Limited 5 */ 6 7 #ifndef __KERNEL_VIRTUALIZATION_H 8 #define __KERNEL_VIRTUALIZATION_H 9 10 #include <bitstring.h> 11 #include <mm/core_mmu.h> 12 #include <stdbool.h> 13 #include <stdint.h> 14 #include <tee_api_types.h> 15 16 #define HYP_CLNT_ID 0 17 18 struct guest_partition; 19 20 #if defined(CFG_NS_VIRTUALIZATION) 21 /** 22 * virt_guest_created() - create new VM partition 23 * @guest_id: VM id provided by hypervisor 24 * 25 * This function is called by hypervisor (via fast SMC) 26 * when hypervisor creates new guest VM, so OP-TEE 27 * can prepare partition for that VM 28 */ 29 TEE_Result virt_guest_created(uint16_t guest_id); 30 31 /** 32 * virt_guest_destroyed() - destroy existing VM partition 33 * @guest_id: VM id provided by hypervisor 34 * 35 * This function is called by hypervisor (via fast SMC) 36 * when hypervisor is ready to destroy guest VM. Hypervisor 37 * must ensure that there are no ongoing calls from this 38 * VM right now. 39 */ 40 TEE_Result virt_guest_destroyed(uint16_t guest_id); 41 42 /** 43 * virt_set_guest() - set guest VM context for current core 44 * @guest_id: VM id provided by hypervisor 45 * 46 * This function switches memory partitions, so TEE part of 47 * OP-TEE will see memory associated with current guest. 48 * It should be called on entry to OP-TEE 49 */ 50 TEE_Result virt_set_guest(uint16_t guest_id); 51 52 /** 53 * virt_unset_guest() - set default memory partition 54 * 55 * This function should be called upon leaving OP-TEE, 56 * to switch to default memory partition, so all TEE-specific 57 * memory will be unmapped. This is safety measure to ensure 58 * that TEE memory is untouched when there is no active VM. 59 */ 60 void virt_unset_guest(void); 61 62 /** 63 * virt_on_stdcall() - std call hook 64 * 65 * This hook is called on every std call, but really is needed 66 * only once: to initialize TEE runtime for current guest VM 67 */ 68 void virt_on_stdcall(void); 69 70 /* 71 * Next function are needed because virtualization subsystem manages 72 * memory in own way. There is no one static memory map, instead 73 * every guest gets own memory map. 74 */ 75 76 /** 77 * virt_init_memory() - initialize memory for virtualization subsystem 78 * @memory_map: current OP-TEE memory map 79 * @secmem0_base: base of first secure memory range 80 * @secmem0_size: size of first secure memory range 81 * @secmem1_base: base of an eventual second secure memory range, 0 if unused 82 * @secmem1_size: size of an eventual second secure memory range, 0 if unused 83 */ 84 void virt_init_memory(struct tee_mmap_region *memory_map, paddr_t secmem0_base, 85 paddr_size_t secmem0_size, paddr_t secmem1_base, 86 paddr_size_t secmem1_size); 87 88 /** 89 * virt_get_memory_map() - get current memory map 90 */ 91 struct tee_mmap_region *virt_get_memory_map(void); 92 93 /** 94 * virt_get_ta_ram() - get TA RAM mapping for current VM 95 * @start: beginning of TA RAM returned here 96 * @end: end of TA RAM returned here 97 */ 98 void virt_get_ta_ram(vaddr_t *start, vaddr_t *end); 99 100 /** 101 * virt_get_current_guest_id() - return current guest ID 102 * 103 * Returns current guest ID or 0 if none is set. 104 */ 105 uint16_t virt_get_current_guest_id(void); 106 107 /** 108 * virt_get_guest_id() - return guest ID of a guest partition 109 * @prtn: Guest partition 110 * 111 * Returns guest ID or 0 if @prtn is NULL 112 */ 113 uint16_t virt_get_guest_id(struct guest_partition *prtn); 114 115 /** 116 * virt_get_current_guest() - increase reference to current guest partition 117 * 118 * Each successful call to this function must be matched by a call to 119 * virt_put_guest() in order to decrease the reference counter again. 120 * 121 * Return a pointer to the guest partition on success or NULL on failure 122 */ 123 struct guest_partition *virt_get_current_guest(void); 124 125 /** 126 * virt_get_guest() - increase reference to a guest partition 127 * @guest_id: ID of the guest partition to find 128 * 129 * Each successful call to this function must be matched by a call to 130 * virt_put_guest() in order to decrease the reference counter again. 131 * 132 * Return a pointer to the guest partition on success or NULL on failure 133 */ 134 struct guest_partition *virt_get_guest(uint16_t guest_id); 135 136 /** 137 * virt_put_guest() - decrease reference to a guest partition 138 * @prtn: Guest partition 139 * 140 * Does nothing if @prtn is NULL. 141 */ 142 void virt_put_guest(struct guest_partition *prtn); 143 144 #else 145 static inline TEE_Result virt_guest_created(uint16_t guest_id __unused) 146 { return TEE_ERROR_NOT_SUPPORTED; } 147 148 static inline TEE_Result virt_guest_destroyed(uint16_t guest_id __unused) 149 { return TEE_ERROR_NOT_SUPPORTED; } 150 151 static inline TEE_Result virt_set_guest(uint16_t guest_id __unused) 152 { return TEE_ERROR_NOT_SUPPORTED; } 153 154 static inline void virt_unset_guest(void) { } 155 static inline void virt_on_stdcall(void) { } 156 static inline struct tee_mmap_region *virt_get_memory_map(void) { return NULL; } 157 static inline void 158 virt_get_ta_ram(vaddr_t *start __unused, vaddr_t *end __unused) { } 159 static inline void virt_init_memory(struct tee_mmap_region *memory_map __unused, 160 paddr_t secmem0_base __unused, 161 paddr_size_t secmem0_size __unused, 162 paddr_t secmem1_base __unused, 163 paddr_size_t secmem1_size __unused) { } 164 static inline uint16_t virt_get_current_guest_id(void) { return 0; } 165 static inline uint16_t virt_get_guest_id(struct guest_partition *prtn __unused) 166 { 167 return 0; 168 } 169 static inline struct guest_partition *virt_get_current_guest(void) 170 { 171 return NULL; 172 } 173 static inline struct guest_partition *virt_get_guest(uint16_t guest_id __unused) 174 { 175 return NULL; 176 } 177 static inline void virt_put_guest(struct guest_partition *prtn __unused) { } 178 #endif /*CFG_NS_VIRTUALIZATION*/ 179 180 #if defined(CFG_CORE_SEL1_SPMC) && defined(CFG_NS_VIRTUALIZATION) 181 TEE_Result virt_add_cookie_to_current_guest(uint64_t cookie); 182 void virt_remove_cookie(uint64_t cookie); 183 uint16_t virt_find_guest_by_cookie(uint64_t cookie); 184 bitstr_t *virt_get_shm_bits(void); 185 186 TEE_Result virt_reclaim_cookie_from_destroyed_guest(uint16_t guest_id, 187 uint64_t cookie); 188 #else 189 static inline TEE_Result 190 virt_add_cookie_to_current_guest(uint64_t cookie __unused) 191 { return TEE_ERROR_NOT_SUPPORTED; } 192 static inline void virt_remove_cookie(uint64_t cookie __unused) { } 193 static inline uint16_t virt_find_guest_by_cookie(uint64_t cookie __unused) 194 { return 0; } 195 static inline bitstr_t *virt_get_shm_bits(void) { return NULL; } 196 static inline TEE_Result 197 virt_reclaim_cookie_from_destroyed_guest(uint16_t guest_id __unused, 198 uint64_t cookie __unused) 199 { return TEE_ERROR_NOT_SUPPORTED; } 200 #endif 201 202 #endif /* __KERNEL_VIRTUALIZATION_H */ 203