xref: /optee_os/core/include/kernel/virtualization.h (revision 29e682bdb3ec76711355c771952b7df5cd45b808)
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_current_guest() - increase reference to current guest partition
109  *
110  * Each successful call to this function must be matched by a call to
111  * virt_put_guest() in order to decrease the reference counter again.
112  *
113  * Return a pointer to the guest partition on success or NULL on failure
114  */
115 struct guest_partition *virt_get_current_guest(void);
116 
117 /**
118  * virt_get_guest() - increase reference to a guest partition
119  * @guest_id:     ID of the guest partition to find
120  *
121  * Each successful call to this function must be matched by a call to
122  * virt_put_guest() in order to decrease the reference counter again.
123  *
124  * Return a pointer to the guest partition on success or NULL on failure
125  */
126 struct guest_partition *virt_get_guest(uint16_t guest_id);
127 
128 /**
129  * virt_put_guest() - decrease reference to a guest partition
130  * @prtn:       Guest partition
131  *
132  * Does nothing if @prtn is NULL.
133  */
134 void virt_put_guest(struct guest_partition *prtn);
135 
136 #else
137 static inline TEE_Result virt_guest_created(uint16_t guest_id __unused)
138 { return TEE_ERROR_NOT_SUPPORTED; }
139 
140 static inline TEE_Result virt_guest_destroyed(uint16_t guest_id __unused)
141 { return TEE_ERROR_NOT_SUPPORTED; }
142 
143 static inline TEE_Result virt_set_guest(uint16_t guest_id __unused)
144 { return TEE_ERROR_NOT_SUPPORTED; }
145 
146 static inline void virt_unset_guest(void) { }
147 static inline void virt_on_stdcall(void) { }
148 static inline struct tee_mmap_region *virt_get_memory_map(void) { return NULL; }
149 static inline void
150 virt_get_ta_ram(vaddr_t *start __unused, vaddr_t *end __unused) { }
151 static inline void virt_init_memory(struct tee_mmap_region *memory_map __unused,
152 				    paddr_t secmem0_base __unused,
153 				    paddr_size_t secmem0_size __unused,
154 				    paddr_t secmem1_base __unused,
155 				    paddr_size_t secmem1_size __unused) { }
156 static inline uint16_t virt_get_current_guest_id(void) { return 0; }
157 
158 static inline struct guest_partition *virt_get_current_guest(void)
159 {
160 	return NULL;
161 }
162 static inline struct guest_partition *virt_get_guest(uint16_t guest_id __unused)
163 {
164 	return NULL;
165 }
166 static inline void virt_put_guest(struct guest_partition *prtn __unused) { }
167 #endif /*CFG_NS_VIRTUALIZATION*/
168 
169 #if defined(CFG_CORE_SEL1_SPMC) && defined(CFG_NS_VIRTUALIZATION)
170 TEE_Result virt_add_cookie_to_current_guest(uint64_t cookie);
171 void virt_remove_cookie(uint64_t cookie);
172 uint16_t virt_find_guest_by_cookie(uint64_t cookie);
173 bitstr_t *virt_get_shm_bits(void);
174 
175 TEE_Result virt_reclaim_cookie_from_destroyed_guest(uint16_t guest_id,
176 						    uint64_t cookie);
177 #else
178 static inline TEE_Result
179 virt_add_cookie_to_current_guest(uint64_t cookie __unused)
180 { return TEE_ERROR_NOT_SUPPORTED; }
181 static inline void virt_remove_cookie(uint64_t cookie __unused) { }
182 static inline uint16_t virt_find_guest_by_cookie(uint64_t cookie __unused)
183 { return 0; }
184 static inline bitstr_t *virt_get_shm_bits(void) { return NULL; }
185 static inline TEE_Result
186 virt_reclaim_cookie_from_destroyed_guest(uint16_t guest_id __unused,
187 					 uint64_t cookie __unused)
188 { return TEE_ERROR_NOT_SUPPORTED; }
189 #endif
190 
191 #endif	/* __KERNEL_VIRTUALIZATION_H */
192