1 /*
2  * Copyright 2018 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #pragma once
10 
11 #include <stdatomic.h>
12 
13 #include "hf/arch/types.h"
14 
15 #include "hf/cpu.h"
16 #include "hf/interrupt_desc.h"
17 #include "hf/list.h"
18 #include "hf/mm.h"
19 #include "hf/mpool.h"
20 
21 #include "vmapi/hf/ffa.h"
22 
23 #define MAX_SMCS 32
24 #define LOG_BUFFER_SIZE 256
25 #define VM_MANIFEST_MAX_INTERRUPTS 32
26 
27 /**
28  * The state of an RX buffer.
29  *
30  * EMPTY is the initial state. The follow state transitions are possible:
31  * * EMPTY => RECEIVED: message sent to the VM.
32  * * RECEIVED => READ: secondary VM receives an RX buffer full notification
33  *   or primary VM returns from FFA_RUN with an FFA_MSG_SEND where the receiver
34  *   is itself.
35  * * READ => EMPTY: VM called FFA_RX_RELEASE.
36  */
37 enum mailbox_state {
38 	/** There is no message in the mailbox. */
39 	MAILBOX_STATE_EMPTY,
40 
41 	/** There is a message in the mailbox that is waiting for a reader. */
42 	MAILBOX_STATE_RECEIVED,
43 
44 	/** There is a message in the mailbox that has been read. */
45 	MAILBOX_STATE_READ,
46 };
47 
48 struct wait_entry {
49 	/** The VM that is waiting for a mailbox to become writable. */
50 	struct vm *waiting_vm;
51 
52 	/**
53 	 * Links used to add entry to a VM's waiter_list. This is protected by
54 	 * the notifying VM's lock.
55 	 */
56 	struct list_entry wait_links;
57 
58 	/**
59 	 * Links used to add entry to a VM's ready_list. This is protected by
60 	 * the waiting VM's lock.
61 	 */
62 	struct list_entry ready_links;
63 };
64 
65 struct mailbox {
66 	enum mailbox_state state;
67 	void *recv;
68 	const void *send;
69 
70 	/** The ID of the VM which sent the message currently in `recv`. */
71 	ffa_vm_id_t recv_sender;
72 
73 	/** The size of the message currently in `recv`. */
74 	uint32_t recv_size;
75 
76 	/**
77 	 * The FF-A function ID to use to deliver the message currently in
78 	 * `recv`.
79 	 */
80 	uint32_t recv_func;
81 
82 	/**
83 	 * List of wait_entry structs representing VMs that want to be notified
84 	 * when the mailbox becomes writable. Once the mailbox does become
85 	 * writable, the entry is removed from this list and added to the
86 	 * waiting VM's ready_list.
87 	 */
88 	struct list_entry waiter_list;
89 
90 	/**
91 	 * List of wait_entry structs representing VMs whose mailboxes became
92 	 * writable since the owner of the mailbox registers for notification.
93 	 */
94 	struct list_entry ready_list;
95 };
96 
97 struct notifications_state {
98 	/**
99 	 * To keep track of the notifications pending.
100 	 * Set on call to FFA_NOTIFICATION_SET, and cleared on call to
101 	 * FFA_NOTIFICATION_GET.
102 	 */
103 	ffa_notifications_bitmap_t pending;
104 
105 	/**
106 	 * Set on FFA_NOTIFICATION_INFO_GET to keep track of the notifications
107 	 * whose information has been retrieved by the referred ABI.
108 	 * Cleared on call to FFA_NOTIFICATION_GET.
109 	 */
110 	ffa_notifications_bitmap_t info_get_retrieved;
111 };
112 
113 struct notifications {
114 	/**
115 	 * The following array maps the notifications to the bound FF-A
116 	 * endpoint.
117 	 * The index in the bindings array relates to the notification
118 	 * ID, and bit position in 'ffa_notifications_bitmap_t'.
119 	 */
120 	ffa_vm_id_t bindings_sender_id[MAX_FFA_NOTIFICATIONS];
121 	ffa_notifications_bitmap_t bindings_per_vcpu;
122 
123 	/* The index of the array below relates to the ID of the VCPU.
124 	 * This is a dynamically allocated array of struct
125 	 * notifications_state and has as many entries as vcpu_count.
126 	 */
127 	struct notifications_state *per_vcpu;
128 	struct notifications_state global;
129 };
130 
131 /**
132  * The following enum relates to a state machine to guide the insertion of
133  * IDs in the respective list as a result of a FFA_NOTIFICATION_INFO_GET call.
134  * As per the FF-A v1.1 specification, the return of the interface
135  * FFA_NOTIFICATION_INFO_GET, is a list of 16-bit values, regarding the VM ID
136  * and VCPU IDs of those with pending notifications.
137  * The overall list, is composed of "sub-lists", that starts with the VM ID, and
138  * can follow with up to 3 more VCPU IDs. A VM can have multiple 'sub-lists'.
139  * The states are traversed on a per VM basis, and should help with filling the
140  * list of IDs.
141  *
142  * INIT is the initial state. The following state transitions are possible:
143  * * INIT => INSERTING: no list has been created for the VM prior. There are
144  * notifications pending and VM ID should be inserted first. If it regards to
145  * a per VCPU notification the VCPU ID should follow. Only VCPU IDs should be
146  * inserted from this point, until reaching "sub-list" size limit.
147  * * INIT => FULL: There is no space in the ID list to insert IDs.
148  * * INSERTING => STARTING_NEW: list has been created. Adding only VCPU IDs,
149  * however "sub-list" limit has been reached. If there are more pending per VCPU
150  * notifications pending for the VM, a new list should be created starting with
151  * VM ID.
152  * * INSERTING => FULL: There is no space in the ID list to insert IDs.
153  * * STARTING_NEW => INSERTING: Started a new 'sub-list' for the given VM, for
154  * the remaining pending per VCPU notifications, only the VCPU ID should be
155  * inserted.
156  * * STARTING_NEW => FULL: There is no space in the ID list to insert IDs.
157  */
158 enum notifications_info_get_state {
159 	INIT,
160 	INSERTING,
161 	STARTING_NEW,
162 	FULL,
163 };
164 
165 struct smc_whitelist {
166 	uint32_t smcs[MAX_SMCS];
167 	uint16_t smc_count;
168 	bool permissive;
169 };
170 
171 struct vm {
172 	ffa_vm_id_t id;
173 	struct ffa_uuid uuid;
174 	uint32_t ffa_version;
175 	struct smc_whitelist smc_whitelist;
176 
177 	/** See api.c for the partial ordering on locks. */
178 	struct spinlock lock;
179 	ffa_vcpu_count_t vcpu_count;
180 	struct vcpu *vcpus;
181 	struct mm_ptable ptable;
182 	struct mailbox mailbox;
183 
184 	struct {
185 		/**
186 		 * State structures for notifications coming from VMs or coming
187 		 * from SPs. Both fields are maintained by the SPMC.
188 		 * The hypervisor ignores the 'from_sp' field, given VM
189 		 * notifications from SPs are managed by the SPMC.
190 		 */
191 		struct notifications from_vm;
192 		struct notifications from_sp;
193 		struct notifications_state framework;
194 		bool enabled;
195 		bool npi_injected;
196 	} notifications;
197 
198 	char log_buffer[LOG_BUFFER_SIZE];
199 	uint16_t log_buffer_length;
200 
201 	/**
202 	 * Wait entries to be used when waiting on other VM mailboxes. See
203 	 * comments on `struct wait_entry` for the lock discipline of these.
204 	 */
205 	struct wait_entry wait_entries[MAX_VMS];
206 
207 	atomic_bool aborting;
208 
209 	/**
210 	 * Booting parameters (FF-A SP partitions).
211 	 */
212 	bool initialized;
213 	uint16_t boot_order;
214 
215 	/** Entries to pass boot data to the VM. */
216 	struct {
217 		uint32_t gp_register_num;
218 		ipaddr_t blob_addr;
219 	} boot_info;
220 
221 	uint8_t messaging_method;
222 
223 	/**
224 	 * Action specified by a Partition through the manifest in response to
225 	 * non secure interrupt.
226 	 */
227 	uint8_t ns_interrupts_action;
228 	bool me_signal_virq;
229 	struct vm *next_boot;
230 
231 	/**
232 	 * Secondary entry point supplied by FFA_SECONDARY_EP_REGISTER used
233 	 * for cold and warm boot of SP execution contexts.
234 	 */
235 	ipaddr_t secondary_ep;
236 
237 	/** Arch-specific VM information. */
238 	struct arch_vm arch;
239 	bool el0_partition;
240 
241 	/** Interrupt descriptor */
242 	struct interrupt_descriptor interrupt_desc[VM_MANIFEST_MAX_INTERRUPTS];
243 };
244 
245 /** Encapsulates a VM whose lock is held. */
246 struct vm_locked {
247 	struct vm *vm;
248 };
249 
250 /** Container for two vm_locked structures */
251 struct two_vm_locked {
252 	struct vm_locked vm1;
253 	struct vm_locked vm2;
254 };
255 
256 struct vm *vm_init(ffa_vm_id_t id, ffa_vcpu_count_t vcpu_count,
257 		   struct mpool *ppool, bool el0_partition);
258 bool vm_init_next(ffa_vcpu_count_t vcpu_count, struct mpool *ppool,
259 		  struct vm **new_vm, bool el0_partition);
260 ffa_vm_count_t vm_get_count(void);
261 struct vm *vm_find(ffa_vm_id_t id);
262 struct vm_locked vm_find_locked(ffa_vm_id_t id);
263 struct vm *vm_find_index(uint16_t index);
264 struct vm_locked vm_lock(struct vm *vm);
265 struct two_vm_locked vm_lock_both(struct vm *vm1, struct vm *vm2);
266 void vm_unlock(struct vm_locked *locked);
267 struct vcpu *vm_get_vcpu(struct vm *vm, ffa_vcpu_index_t vcpu_index);
268 struct wait_entry *vm_get_wait_entry(struct vm *vm, ffa_vm_id_t for_vm);
269 ffa_vm_id_t vm_id_for_wait_entry(struct vm *vm, struct wait_entry *entry);
270 bool vm_id_is_current_world(ffa_vm_id_t vm_id);
271 
272 bool vm_identity_map(struct vm_locked vm_locked, paddr_t begin, paddr_t end,
273 		     uint32_t mode, struct mpool *ppool, ipaddr_t *ipa);
274 bool vm_identity_prepare(struct vm_locked vm_locked, paddr_t begin, paddr_t end,
275 			 uint32_t mode, struct mpool *ppool);
276 void vm_identity_commit(struct vm_locked vm_locked, paddr_t begin, paddr_t end,
277 			uint32_t mode, struct mpool *ppool, ipaddr_t *ipa);
278 bool vm_unmap(struct vm_locked vm_locked, paddr_t begin, paddr_t end,
279 	      struct mpool *ppool);
280 void vm_ptable_defrag(struct vm_locked vm_locked, struct mpool *ppool);
281 bool vm_unmap_hypervisor(struct vm_locked vm_locked, struct mpool *ppool);
282 
283 void vm_update_boot(struct vm *vm);
284 struct vm *vm_get_first_boot(void);
285 
286 bool vm_mem_get_mode(struct vm_locked vm_locked, ipaddr_t begin, ipaddr_t end,
287 		     uint32_t *mode);
288 
289 void vm_notifications_init(struct vm *vm, ffa_vcpu_count_t vcpu_count,
290 			   struct mpool *ppool);
291 bool vm_are_notifications_pending(struct vm_locked vm_locked, bool from_vm,
292 				  ffa_notifications_bitmap_t notifications);
293 bool vm_are_global_notifications_pending(struct vm_locked vm_locked);
294 bool vm_are_per_vcpu_notifications_pending(struct vm_locked vm_locked,
295 					   ffa_vcpu_index_t vcpu_id);
296 bool vm_are_notifications_enabled(struct vm *vm);
297 bool vm_locked_are_notifications_enabled(struct vm_locked vm_locked);
298 bool vm_notifications_validate_per_vcpu(struct vm_locked vm_locked,
299 					bool is_from_vm, bool is_per_vcpu,
300 					ffa_notifications_bitmap_t notif);
301 bool vm_notifications_validate_bound_sender(
302 	struct vm_locked vm_locked, bool is_from_vm, ffa_vm_id_t sender_id,
303 	ffa_notifications_bitmap_t notifications);
304 bool vm_notifications_validate_binding(struct vm_locked vm_locked,
305 				       bool is_from_vm, ffa_vm_id_t sender_id,
306 				       ffa_notifications_bitmap_t notifications,
307 				       bool is_per_vcpu);
308 void vm_notifications_update_bindings(struct vm_locked vm_locked,
309 				      bool is_from_vm, ffa_vm_id_t sender_id,
310 				      ffa_notifications_bitmap_t notifications,
311 				      bool is_per_vcpu);
312 void vm_notifications_partition_set_pending(
313 	struct vm_locked vm_locked, bool is_from_vm,
314 	ffa_notifications_bitmap_t notifications, ffa_vcpu_index_t vcpu_id,
315 	bool is_per_vcpu);
316 ffa_notifications_bitmap_t vm_notifications_partition_get_pending(
317 	struct vm_locked vm_locked, bool is_from_vm, ffa_vcpu_index_t vcpu_id);
318 void vm_notifications_framework_set_pending(
319 	struct vm_locked vm_locked, ffa_notifications_bitmap_t notifications);
320 ffa_notifications_bitmap_t vm_notifications_framework_get_pending(
321 	struct vm_locked vm_locked);
322 void vm_notifications_info_get_pending(
323 	struct vm_locked vm_locked, bool is_from_vm, uint16_t *ids,
324 	uint32_t *ids_count, uint32_t *lists_sizes, uint32_t *lists_count,
325 	const uint32_t ids_max_count,
326 	enum notifications_info_get_state *info_get_state);
327 bool vm_notifications_pending_not_retrieved_by_scheduler(void);
328 bool vm_is_notifications_pending_count_zero(void);
329 bool vm_notifications_info_get(struct vm_locked vm_locked, uint16_t *ids,
330 			       uint32_t *ids_count, uint32_t *lists_sizes,
331 			       uint32_t *lists_count,
332 			       const uint32_t ids_max_count);
333 bool vm_supports_messaging_method(struct vm *vm, uint8_t messaging_method);
334 void vm_notifications_set_npi_injected(struct vm_locked vm_locked,
335 				       bool npi_injected);
336 bool vm_notifications_is_npi_injected(struct vm_locked vm_locked);
337 void vm_set_boot_info_gp_reg(struct vm *vm, struct vcpu *vcpu);
338