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