blob: e9c056244e92528591681406552b5e83fea89ae2 [file] [log] [blame]
Karl Meakin07de26a2024-07-23 17:59:33 +01001/*
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/arch/plat/ffa/direct_messaging.h"
10
11#include "hf/arch/other_world.h"
12
13#include "hf/vcpu.h"
14#include "hf/vm.h"
15
16#include "hypervisor.h"
17
18/**
19 * Check validity of a FF-A direct message request.
20 */
21bool plat_ffa_is_direct_request_valid(struct vcpu *current,
22 ffa_id_t sender_vm_id,
23 ffa_id_t receiver_vm_id)
24{
25 ffa_id_t current_vm_id = current->vm->id;
26
27 /*
28 * The primary VM can send direct message request to
29 * any other VM (but itself) or SP, but can't spoof
30 * a different sender.
31 */
32 return sender_vm_id != receiver_vm_id &&
33 sender_vm_id == current_vm_id && vm_is_primary(current->vm);
34}
35
36bool plat_ffa_is_direct_request_supported(struct vm *sender_vm,
37 struct vm *receiver_vm, uint32_t func)
38{
39 (void)sender_vm;
40 (void)receiver_vm;
41 (void)func;
42
43 /*
44 * As Hypervisor is only meant to be used as a test artifact, allow
45 * direct messaging for all VMs.
46 */
47 return true;
48}
49
50/**
51 * Check validity of a FF-A direct message response.
52 */
53bool plat_ffa_is_direct_response_valid(struct vcpu *current,
54 ffa_id_t sender_vm_id,
55 ffa_id_t receiver_vm_id)
56{
57 ffa_id_t current_vm_id = current->vm->id;
58
59 /*
60 * Secondary VMs can send direct message responses to
61 * the PVM, but can't spoof a different sender.
62 */
63 return sender_vm_id != receiver_vm_id &&
64 sender_vm_id == current_vm_id &&
65 receiver_vm_id == HF_PRIMARY_VM_ID;
66}
67
68bool plat_ffa_direct_request_forward(ffa_id_t receiver_vm_id,
69 struct ffa_value args,
70 struct ffa_value *ret)
71{
72 if (!plat_ffa_is_tee_enabled()) {
73 dlog_verbose("Not forwarding: ffa_tee_enabled is false\n");
74 return false;
75 }
76
77 /*
78 * VM's requests should be forwarded to the SPMC, if receiver is an SP.
79 */
80 if (vm_id_is_current_world(receiver_vm_id)) {
81 dlog_verbose(
82 "Not forwarding: receiver VM %#x is in the same "
83 "world\n",
84 receiver_vm_id);
85 return false;
86 }
87
88 switch (args.func) {
89 case FFA_MSG_SEND_DIRECT_REQ_32:
90 case FFA_MSG_SEND_DIRECT_REQ_64:
91 *ret = arch_other_world_call(args);
92 break;
93 case FFA_MSG_SEND_DIRECT_REQ2_64:
94 *ret = arch_other_world_call_ext(args);
95 break;
96 default:
97 panic("Invalid direct message function %#x\n", args.func);
98 break;
99 }
100
101 return true;
102}
103
104void plat_ffa_wind_call_chain_ffa_direct_req(
105 struct vcpu_locked current_locked,
106 struct vcpu_locked receiver_vcpu_locked, ffa_id_t sender_vm_id)
107{
108 /* Calls chains not supported in the Hypervisor/VMs. */
109 (void)current_locked;
110 (void)receiver_vcpu_locked;
111 (void)sender_vm_id;
112}
113
114void plat_ffa_unwind_call_chain_ffa_direct_resp(
115 struct vcpu_locked current_locked, struct vcpu_locked next_locked)
116{
117 /* Calls chains not supported in the Hypervisor/VMs. */
118 (void)current_locked;
119 (void)next_locked;
120}