Skip to content

Commit

Permalink
core: ffa: handle VM availability messages for SPs
Browse files Browse the repository at this point in the history
The VM availability messages sent by the hypervisor to an SP should be
forwarded to the SP, if the SP has subscribed for these based on the SP
manifest.

Signed-off-by: Balint Dobszay <[email protected]>
  • Loading branch information
balint-dobszay-arm committed Jul 23, 2024
1 parent f152198 commit 8302e60
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 13 deletions.
4 changes: 3 additions & 1 deletion core/arch/arm/include/kernel/secure_partition.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2020-2023, Arm Limited.
* Copyright (c) 2020-2024, Arm Limited.
*/
#ifndef __KERNEL_SECURE_PARTITION_H
#define __KERNEL_SECURE_PARTITION_H
Expand Down Expand Up @@ -33,6 +33,8 @@ struct sp_session {
TEE_UUID ffa_uuid;
uint32_t ns_int_mode;
uint32_t ns_int_mode_inherited;
bool notif_vm_created;
bool notif_vm_destroyed;
TAILQ_ENTRY(sp_session) link;
};

Expand Down
52 changes: 48 additions & 4 deletions core/arch/arm/kernel/secure_partition.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@
#define SP_MANIFEST_NS_INT_MANAGED_EXIT (0x1)
#define SP_MANIFEST_NS_INT_SIGNALED (0x2)

#define SP_MANIFEST_VM_CREATED_MSG BIT(0)
#define SP_MANIFEST_VM_DESTROYED_MSG BIT(1)

#define SP_PKG_HEADER_MAGIC (0x474b5053)
#define SP_PKG_HEADER_VERSION_V1 (0x1)
#define SP_PKG_HEADER_VERSION_V2 (0x2)
Expand Down Expand Up @@ -119,10 +122,6 @@ TEE_Result sp_partition_info_get(uint32_t ffa_vers, void *buf, size_t buf_size,
bool count_only)
{
TEE_Result res = TEE_SUCCESS;
uint32_t part_props = FFA_PART_PROP_DIRECT_REQ_RECV |
FFA_PART_PROP_DIRECT_REQ_SEND |
FFA_PART_PROP_AARCH64_STATE |
FFA_PART_PROP_IS_PE_ID;
struct sp_session *s = NULL;

TAILQ_FOREACH(s, &open_sp_sessions, link) {
Expand All @@ -134,6 +133,15 @@ TEE_Result sp_partition_info_get(uint32_t ffa_vers, void *buf, size_t buf_size,
continue;
if (!count_only && !res) {
uint32_t uuid_words[4] = { 0 };
uint32_t part_props = FFA_PART_PROP_DIRECT_REQ_RECV |
FFA_PART_PROP_DIRECT_REQ_SEND |
FFA_PART_PROP_AARCH64_STATE |
FFA_PART_PROP_IS_PE_ID;

if (s->notif_vm_created)
part_props |= FFA_PART_PROP_NOTIF_CREATED;
if (s->notif_vm_destroyed)
part_props |= FFA_PART_PROP_NOTIF_DESTROYED;

tee_uuid_to_octets((uint8_t *)uuid_words, &s->ffa_uuid);
res = spmc_fill_partition_entry(ffa_vers, buf, buf_size,
Expand Down Expand Up @@ -1434,6 +1442,38 @@ static TEE_Result read_ffa_version(const void *fdt, struct sp_session *s)
return TEE_SUCCESS;
}

static TEE_Result read_vm_availability_msg(const void *fdt,
struct sp_session *s)
{
TEE_Result res = TEE_ERROR_BAD_PARAMETERS;
uint32_t v = 0;

res = sp_dt_get_u32(fdt, 0, "vm-availability-messages", &v);

/* This field in the manifest is optional */
if (res == TEE_ERROR_ITEM_NOT_FOUND) {
s->notif_vm_created = false;
s->notif_vm_destroyed = false;
return TEE_SUCCESS;
}

if (res)
return res;

if (v & ~(SP_MANIFEST_VM_CREATED_MSG | SP_MANIFEST_VM_DESTROYED_MSG)) {
EMSG("Invalid vm-availability-messages value: %"PRIu32, v);
return TEE_ERROR_BAD_PARAMETERS;
}

if (v & SP_MANIFEST_VM_CREATED_MSG)
s->notif_vm_created = true;

if (v & SP_MANIFEST_VM_DESTROYED_MSG)
s->notif_vm_destroyed = true;

return TEE_SUCCESS;
}

static TEE_Result sp_init_uuid(const TEE_UUID *bin_uuid, const void * const fdt)
{
TEE_Result res = TEE_SUCCESS;
Expand Down Expand Up @@ -1477,6 +1517,10 @@ static TEE_Result sp_init_uuid(const TEE_UUID *bin_uuid, const void * const fdt)
if (res)
return res;

res = read_vm_availability_msg(fdt, sess);
if (res)
return res;

return TEE_SUCCESS;
}

Expand Down
82 changes: 74 additions & 8 deletions core/arch/arm/kernel/spmc_sp_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ static TEE_Result ffa_get_dst(struct thread_smc_args *args,
{
struct sp_session *s = NULL;

if (args->a2 != FFA_PARAM_MBZ)
return FFA_INVALID_PARAMETERS;

s = sp_get_session(FFA_DST(args->a1));

/* Message came from the NW */
Expand Down Expand Up @@ -875,11 +872,6 @@ ffa_handle_sp_direct_req(struct thread_smc_args *args,
struct sp_session *dst = NULL;
TEE_Result res = FFA_OK;

if (args->a2 != FFA_PARAM_MBZ) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

res = ffa_get_dst(args, caller_sp, &dst);
if (res) {
/* Tried to send message to an incorrect endpoint */
Expand All @@ -898,6 +890,43 @@ ffa_handle_sp_direct_req(struct thread_smc_args *args,
return caller_sp;
}

if (args->a2 & FFA_MSG_FLAG_FRAMEWORK) {
switch (args->a2 & FFA_MSG_TYPE_MASK) {
case FFA_MSG_SEND_VM_CREATED:
/* The sender must be the NWd hypervisor (ID 0) */
if (FFA_SRC(args->a1) != 0 || caller_sp != NULL) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!dst->notif_vm_created) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}
break;
case FFA_MSG_SEND_VM_DESTROYED:
/* The sender must be the NWd hypervisor (ID 0) */
if (FFA_SRC(args->a1) != 0 || caller_sp != NULL) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!dst->notif_vm_destroyed) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}
break;
default:
ffa_set_error(args, FFA_NOT_SUPPORTED);
return caller_sp;
}
} else if (args->a2 != FFA_PARAM_MBZ) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

cpu_spin_lock(&dst->spinlock);
if (dst->state != sp_idle) {
DMSG("SP is busy");
Expand Down Expand Up @@ -947,6 +976,43 @@ ffa_handle_sp_direct_resp(struct thread_smc_args *args,
return caller_sp;
}

if (args->a2 & FFA_MSG_FLAG_FRAMEWORK) {
switch (args->a2 & FFA_MSG_TYPE_MASK) {
case FFA_MSG_RESP_VM_CREATED:
/* The destination must be the NWd hypervisor (ID 0) */
if (FFA_DST(args->a1) != 0 || dst != NULL) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!dst->notif_vm_created) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}
break;
case FFA_MSG_RESP_VM_DESTROYED:
/* The destination must be the NWd hypervisor (ID 0) */
if (FFA_DST(args->a1) != 0 || dst != NULL) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!dst->notif_vm_destroyed) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}
break;
default:
ffa_set_error(args, FFA_NOT_SUPPORTED);
return caller_sp;
}
} else if (args->a2 != FFA_PARAM_MBZ) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

if (dst && dst->state != sp_busy) {
EMSG("SP is not waiting for a request");
ffa_set_error(args, FFA_INVALID_PARAMETERS);
Expand Down

0 comments on commit 8302e60

Please sign in to comment.