Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FF-A VM availability messages #6958

Merged
merged 2 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 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,7 @@ struct sp_session {
TEE_UUID ffa_uuid;
uint32_t ns_int_mode;
uint32_t ns_int_mode_inherited;
uint32_t props;
TAILQ_ENTRY(sp_session) link;
};

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

#define SP_MANIFEST_EXEC_STATE_AARCH64 (0x0)
#define SP_MANIFEST_EXEC_STATE_AARCH32 (0x1)

#define SP_MANIFEST_DIRECT_REQ_RECEIVE BIT(0)
#define SP_MANIFEST_DIRECT_REQ_SEND BIT(1)
#define SP_MANIFEST_INDIRECT_REQ BIT(2)

#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,8 +129,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;
struct sp_session *s = NULL;

TAILQ_FOREACH(s, &open_sp_sessions, link) {
Expand All @@ -137,7 +145,7 @@ TEE_Result sp_partition_info_get(uint32_t ffa_vers, void *buf, size_t buf_size,
res = spmc_fill_partition_entry(ffa_vers, buf, buf_size,
*elem_count,
s->endpoint_id, 1,
part_props, uuid_words);
s->props, uuid_words);
}
*elem_count += 1;
}
Expand Down Expand Up @@ -257,6 +265,9 @@ static TEE_Result sp_create_session(struct sp_sessions_head *open_sessions,

s->boot_order = boot_order;

/* Other properties are filled later, based on the SP's manifest */
s->props = FFA_PART_PROP_IS_PE_ID;

res = new_session_id(&s->endpoint_id);
if (res)
goto err;
Expand Down Expand Up @@ -1432,6 +1443,80 @@ static TEE_Result read_ffa_version(const void *fdt, struct sp_session *s)
return TEE_SUCCESS;
}

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

res = sp_dt_get_u32(fdt, 0, "execution-state", &exec_state);
if (res) {
EMSG("Mandatory property is missing: execution-state");
return res;
}

/* Currently only AArch64 SPs are supported */
if (exec_state == SP_MANIFEST_EXEC_STATE_AARCH64) {
s->props |= FFA_PART_PROP_AARCH64_STATE;
} else {
EMSG("Invalid execution-state value: %"PRIu32, exec_state);
return TEE_ERROR_BAD_PARAMETERS;
}

return TEE_SUCCESS;
}

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

res = sp_dt_get_u32(fdt, 0, "messaging-method", &msg_method);
if (res) {
EMSG("Mandatory property is missing: messaging-method");
return res;
}

if (msg_method & SP_MANIFEST_DIRECT_REQ_RECEIVE)
s->props |= FFA_PART_PROP_DIRECT_REQ_RECV;

if (msg_method & SP_MANIFEST_DIRECT_REQ_SEND)
s->props |= FFA_PART_PROP_DIRECT_REQ_SEND;

if (msg_method & SP_MANIFEST_INDIRECT_REQ)
IMSG("Indirect messaging is not supported");

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)
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->props |= FFA_PART_PROP_NOTIF_CREATED;

if (v & SP_MANIFEST_VM_DESTROYED_MSG)
s->props |= FFA_PART_PROP_NOTIF_DESTROYED;

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 @@ -1475,6 +1560,18 @@ static TEE_Result sp_init_uuid(const TEE_UUID *bin_uuid, const void * const fdt)
if (res)
return res;

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

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

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

return TEE_SUCCESS;
}

Expand Down
97 changes: 89 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,58 @@ ffa_handle_sp_direct_req(struct thread_smc_args *args,
return caller_sp;
}

if (caller_sp &&
!(caller_sp->props & FFA_PART_PROP_DIRECT_REQ_SEND)) {
EMSG("SP 0x%"PRIx16" doesn't support sending direct requests",
caller_sp->endpoint_id);
ffa_set_error(args, FFA_NOT_SUPPORTED);
return caller_sp;
}

if (!(dst->props & FFA_PART_PROP_DIRECT_REQ_RECV)) {
EMSG("SP 0x%"PRIx16" doesn't support receipt of direct requests",
dst->endpoint_id);
ffa_set_error(args, FFA_NOT_SUPPORTED);
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) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!(dst->props & FFA_PART_PROP_NOTIF_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) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!(dst->props & FFA_PART_PROP_NOTIF_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 +991,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) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!(dst->props & FFA_PART_PROP_NOTIF_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) {
ffa_set_error(args, FFA_INVALID_PARAMETERS);
return caller_sp;
}

/* The SP must be subscribed for this message */
if (!(dst->props & FFA_PART_PROP_NOTIF_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
6 changes: 6 additions & 0 deletions core/arch/arm/kernel/thread_spmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,12 @@ TEE_Result spmc_fill_partition_entry(uint32_t ffa_vers, void *buf, size_t blen,

fpi->partition_properties = part_props;

/* In FF-A 1.0 only bits [2:0] are defined, let's mask others */
if (ffa_vers < FFA_VERSION_1_1)
fpi->partition_properties &= FFA_PART_PROP_DIRECT_REQ_RECV |
FFA_PART_PROP_DIRECT_REQ_SEND |
FFA_PART_PROP_INDIRECT_MSGS;

if (ffa_vers >= FFA_VERSION_1_1) {
if (uuid_words)
memcpy(fpi->uuid, uuid_words, FFA_UUID_SIZE);
Expand Down
Loading