xref: /optee_os/core/include/kernel/virtualization.h (revision a755a64f7ed08da520da754166c2693b316d0a12)
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