blob: 2555545995c79fb148d55df74817bfb51d8893bf [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
Karl Meakin902af082024-11-28 14:58:38 +00009#include "hf/ffa/direct_messaging.h"
Karl Meakin07de26a2024-07-23 17:59:33 +010010
11#include "hf/arch/other_world.h"
12
Karl Meakind8c9fff2025-02-10 12:26:48 +000013#include "hf/ffa/init.h"
Karl Meakin07de26a2024-07-23 17:59:33 +010014#include "hf/vcpu.h"
15#include "hf/vm.h"
16
Karl Meakin07de26a2024-07-23 17:59:33 +010017/**
18 * Check validity of a FF-A direct message request.
19 */
Karl Meakin117c8082024-12-04 16:03:28 +000020bool ffa_direct_msg_is_direct_request_valid(struct vcpu *current,
21 ffa_id_t sender_vm_id,
22 ffa_id_t receiver_vm_id)
Karl Meakin07de26a2024-07-23 17:59:33 +010023{
24 ffa_id_t current_vm_id = current->vm->id;
25
26 /*
27 * The primary VM can send direct message request to
28 * any other VM (but itself) or SP, but can't spoof
29 * a different sender.
30 */
31 return sender_vm_id != receiver_vm_id &&
32 sender_vm_id == current_vm_id && vm_is_primary(current->vm);
33}
34
Karl Meakin117c8082024-12-04 16:03:28 +000035bool ffa_direct_msg_is_direct_request_supported(struct vm *sender_vm,
36 struct vm *receiver_vm,
37 uint32_t func)
Karl Meakin07de26a2024-07-23 17:59:33 +010038{
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 */
Karl Meakin117c8082024-12-04 16:03:28 +000053bool ffa_direct_msg_is_direct_response_valid(struct vcpu *current,
54 ffa_id_t sender_vm_id,
55 ffa_id_t receiver_vm_id)
Karl Meakin07de26a2024-07-23 17:59:33 +010056{
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
Karl Meakin117c8082024-12-04 16:03:28 +000068bool ffa_direct_msg_direct_request_forward(ffa_id_t receiver_vm_id,
69 struct ffa_value args,
70 struct ffa_value *ret)
Karl Meakin07de26a2024-07-23 17:59:33 +010071{
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
Karl Meakin117c8082024-12-04 16:03:28 +0000104void ffa_direct_msg_wind_call_chain_ffa_direct_req(
Karl Meakin07de26a2024-07-23 17:59:33 +0100105 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
Karl Meakin117c8082024-12-04 16:03:28 +0000114void ffa_direct_msg_unwind_call_chain_ffa_direct_resp(
Karl Meakin07de26a2024-07-23 17:59:33 +0100115 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}
Karl Meakina1150492025-01-31 13:22:08 +0000121
122bool plat_ffa_handle_framework_msg(struct ffa_value args, struct ffa_value *ret)
123{
124 (void)args;
125 (void)ret;
126
127 return false;
128}
129
130bool plat_ffa_is_spmd_lp_id(ffa_id_t vm_id)
131{
132 (void)vm_id;
133 return false;
134}