1 /*
2  * Copyright 2024 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 #include "hf/ffa/indirect_messaging.h"
10 
11 #include "hf/ffa_internal.h"
12 #include "hf/vm.h"
13 
14 /**
15  * Check that sender and receiver support indirect messages, in accordance
16  * to their configurations in the respective partition's FF-A manifest.
17  * Note: check is done at virtual FF-A instance only.
18  */
ffa_indirect_msg_is_supported(struct vm_locked sender_locked,struct vm_locked receiver_locked)19 bool ffa_indirect_msg_is_supported(struct vm_locked sender_locked,
20 				   struct vm_locked receiver_locked)
21 {
22 	struct vm *sender_vm = sender_locked.vm;
23 	struct vm *receiver_vm = receiver_locked.vm;
24 
25 	/*
26 	 * SPMC doesn't have information about VMs' configuration hence can't
27 	 * check if they are allowed to send indirect messages, but it's not a
28 	 * security threat.
29 	 */
30 	if (sender_vm->ffa_version < FFA_VERSION_1_1) {
31 		dlog_verbose(
32 			"Sender %x FF-A version (%x) doesn't support Indirect "
33 			"Message. FF-A v1.1 is needed.\n",
34 			sender_vm->id, sender_vm->ffa_version);
35 		return false;
36 	}
37 
38 	if (receiver_vm->ffa_version < FFA_VERSION_1_1) {
39 		dlog_verbose(
40 			"Receiver %x FF-A version (%x) doesn't support "
41 			"Indirect Message. FF-A v1.1 is needed.\n",
42 			receiver_vm->id, receiver_vm->ffa_version);
43 		return false;
44 	}
45 
46 	if (vm_id_is_current_world(sender_vm->id) &&
47 	    !vm_supports_messaging_method(sender_vm,
48 					  FFA_PARTITION_INDIRECT_MSG)) {
49 		dlog_verbose("VM %#x can't send indirect messages.\n",
50 			     sender_vm->id);
51 		return false;
52 	}
53 
54 	if (vm_id_is_current_world(receiver_vm->id) &&
55 	    !vm_supports_messaging_method(receiver_vm,
56 					  FFA_PARTITION_INDIRECT_MSG)) {
57 		dlog_verbose("VM %#x can't receive indirect messages.\n",
58 			     receiver_vm->id);
59 		return false;
60 	}
61 
62 	return true;
63 }
ffa_indirect_msg_send2_forward(ffa_id_t receiver_vm_id,ffa_id_t sender_vm_id,struct ffa_value * ret)64 bool ffa_indirect_msg_send2_forward(ffa_id_t receiver_vm_id,
65 				    ffa_id_t sender_vm_id,
66 				    struct ffa_value *ret)
67 {
68 	/* SPMC never needs to forward a FFA_MSG_SEND2, it always handles it. */
69 	(void)receiver_vm_id;
70 	(void)sender_vm_id;
71 	(void)ret;
72 	return false;
73 }
74 
ffa_indirect_msg_send(ffa_id_t sender_vm_id,ffa_id_t receiver_vm_id,uint32_t size,struct vcpu * current,struct vcpu ** next)75 struct ffa_value ffa_indirect_msg_send(ffa_id_t sender_vm_id,
76 				       ffa_id_t receiver_vm_id, uint32_t size,
77 				       struct vcpu *current, struct vcpu **next)
78 {
79 	(void)sender_vm_id;
80 	(void)receiver_vm_id;
81 	(void)size;
82 	(void)current;
83 	(void)next;
84 
85 	return ffa_error(FFA_NOT_SUPPORTED);
86 }
87