On Tue, Nov 15, 2022 at 11:32:49AM +0100, Jens Wiklander wrote: > On Fri, Nov 11, 2022 at 02:36:11PM +0000, Abdellatif El Khlifi wrote: > > On Wed, Nov 09, 2022 at 12:51:26PM +0100, Jens Wiklander wrote: > > > On Mon, Nov 07, 2022 at 07:20:48PM +0000, Abdellatif El Khlifi wrote: > [snip] > > > > +/** > > > > + * ffa_msg_send_direct_req - FFA_MSG_SEND_DIRECT_{REQ,RESP} handler > > > > function > > > > + * @dst_part_id: destination partition ID > > > > + * @msg: pointer to the message data preallocated by the client > > > > (in/out) > > > > + * @is_smc64: select 64-bit or 32-bit FF-A ABI > > > > + * > > > > + * This function implements FFA_MSG_SEND_DIRECT_{REQ,RESP} > > > > + * FF-A functions. > > > > + * > > > > + * FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure > > > > partition. > > > > + * The response from the secure partition is handled by reading the > > > > + * FFA_MSG_SEND_DIRECT_RESP arguments. > > > > + * > > > > + * The maximum size of the data that can be exchanged is 40 bytes > > > > which is > > > > + * sizeof(struct ffa_send_direct_data) as defined by the FF-A > > > > specification 1.0 > > > > + * in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP} > > > > + * > > > > + * Return: > > > > + * > > > > + * 0 on success. Otherwise, failure > > > > + */ > > > > +static int ffa_msg_send_direct_req(u16 dst_part_id, struct > > > > ffa_send_direct_data *msg, bool is_smc64) > > > > +{ > > > > + ffa_value_t res = {0}; > > > > + int ffa_errno; > > > > + u64 req_mode, resp_mode; > > > > + > > > > + if (!ffa_priv_data || !ffa_priv_data->invoke_ffa_fn) > > > > + return -EINVAL; > > > > + > > > > + /* No partition installed */ > > > > + if (!ffa_priv_data->partitions.count || > > > > !ffa_priv_data->partitions.descs) > > > > + return -ENODEV; > > > > > > This check isn't needed. What if the partition ID is known by other > > > means? > > > > I'm happy to remove this check. I'd like to add a comment explaining > > what the other means are. Could you please explain what are they ? > > In some systems perhaps you have well known partition ids reserved for > certain services.
I double checked with Achin about this. FFA_PARTITION_INFO_GET provides the partitions information for all partitions including the reserved ones. The driver will cache the information of all the partitions. Not finding any partition cached before a direct request means: there is no partition in the system. I think we need to keep the check. > > > > > > > > > > + > > > > + if (is_smc64) { > > > > + req_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_REQ); > > > > + resp_mode = FFA_SMC_64(FFA_MSG_SEND_DIRECT_RESP); > > > > + } else { > > > > + req_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_REQ); > > > > + resp_mode = FFA_SMC_32(FFA_MSG_SEND_DIRECT_RESP); > > > > + } > > > > + > > > > + ffa_priv_data->invoke_ffa_fn((ffa_value_t){ > > > > + .a0 = req_mode, > > > > + .a1 = PREP_SELF_ENDPOINT_ID(ffa_priv_data->id) | > > > > + PREP_PART_ENDPOINT_ID(dst_part_id), > > > > + .a2 = 0, > > > > + .a3 = msg->data0, > > > > + .a4 = msg->data1, > > > > + .a5 = msg->data2, > > > > + .a6 = msg->data3, > > > > + .a7 = msg->data4, > > > > + }, &res); > > > > + > > > > + while (res.a0 == FFA_SMC_32(FFA_INTERRUPT)) > > > > + ffa_priv_data->invoke_ffa_fn((ffa_value_t){ > > > > + .a0 = FFA_SMC_32(FFA_RUN), > > > > + .a1 = res.a1, > > > > + }, &res); > > > > + > > > > + if (res.a0 == FFA_SMC_32(FFA_SUCCESS)) { > > > > + /* Message sent with no response */ > > > > + return 0; > > > > + } > > > > + > > > > + if (res.a0 == resp_mode) { > > > > + /* > > > > + * Message sent with response > > > > + * extract the return data > > > > + */ > > > > + msg->data0 = res.a3; > > > > + msg->data1 = res.a4; > > > > + msg->data2 = res.a5; > > > > + msg->data3 = res.a6; > > > > + msg->data4 = res.a7; > > > > + > > > > + return 0; > > > > + } > > > > + > > > > + ffa_errno = res.a2; > > > > + return ffa_to_std_errno(ffa_errno); > > > > +} > > > > + > > [snip] > > > > > +/** > > > > + * ffa_bus_prvdata_get - bus driver private data getter > > > > + * > > > > + * Return: > > > > + * This function returns a pointer to the main private data structure > > > > + */ > > > > +struct ffa_prvdata **ffa_bus_prvdata_get(void) > > > > > > Why a pointer to a pointer, isn't "struct ffa_prvdata *" enough? > > > > Because ffa_priv_data is a pointer. ffa_bus_prvdata_get() returns an > > address of a pointer so the returned type should be struct ffa_prvdata > > ** > > > > Otherwise, a compiler warning: > > > > drivers/firmware/arm-ffa/core.c: In function ‘ffa_bus_prvdata_get’: > > drivers/firmware/arm-ffa/core.c:1278:9: warning: return from incompatible > > pointer type [-Wincompatible-pointer-types] > > return &ffa_priv_data; > > ^~~~~~~~~~~~~~ > > Why not return ffa_priv_data instead? Thanks, addressed in v8 patchset. > > > > > > > > > > +{ > > > > + return &ffa_priv_data; > > > > +} > > [snip] > > > > +++ b/include/arm_ffa.h > > > > @@ -0,0 +1,93 @@ > > > > +/* SPDX-License-Identifier: GPL-2.0+ */ > > > > +/* > > > > + * (C) Copyright 2022 ARM Limited > > > > + * Abdellatif El Khlifi <abdellatif.elkhl...@arm.com> > > > > + */ > > > > + > > > > +#ifndef __ARM_FFA_H > > > > +#define __ARM_FFA_H > > > > + > > > > +#include <linux/printk.h> > > > > + > > > > +/* > > > > + * This header is public. It can be used by clients to access > > > > + * data structures and definitions they need > > > > + */ > > > > + > > > > +/* > > > > + * Macros for displaying logs > > > > + */ > > > > + > > > > +#define ffa_info(fmt, ...) pr_info("[FFA] " fmt "\n", ##__VA_ARGS__) > > > > +#define ffa_err(fmt, ...) pr_err("[FFA] " fmt "\n", ##__VA_ARGS__) > > > > + > > > > +/* > > > > + * struct ffa_partition_info - Partition information descriptor > > > > + * @id: Partition ID > > > > + * @exec_ctxt: Execution context count > > > > + * @properties: Partition properties > > > > + * > > > > + * Data structure containing information about partitions instantiated > > > > in the system > > > > + * This structure is filled with the data queried by > > > > FFA_PARTITION_INFO_GET > > > > + */ > > > > +struct __packed ffa_partition_info { > > > > + u16 id; > > > > + u16 exec_ctxt; > > > > +/* partition supports receipt of direct requests */ > > > > +#define FFA_PARTITION_DIRECT_RECV BIT(0) > > > > +/* partition can send direct requests. */ > > > > +#define FFA_PARTITION_DIRECT_SEND BIT(1) > > > > +/* partition can send and receive indirect messages. */ > > > > +#define FFA_PARTITION_INDIRECT_MSG BIT(2) > > > > + u32 properties; > > > > +}; > > > > > > Perhaps this has been discussed before. Why is this packed? Is it to allow > > > unaligned access or to be sure that there is not implicitly added padding? > > > The Linux kernel does seem to need it. > > > > When not using __packed the compiler will add paddings. > > ffa_partition_info structure is used for reading SP information > > from the secure world. > > > > The issue arises when the non secure world and the secure world > > have different architectures (Aarch64 vs Aarch32) or different > > endianess. In these cases, the data will be corrupted. > > > > I think we need to use __packed for all the comms structures. > > > > I'm aware ffa_partition_info in the kernel is not packed. I'm happy > > to remove __packed from here to align it with Linux. > > > > But please share your thoughts about the padding issues when > > working with different architecures/endianess. > > __packed doesn't help with endianess, besides if I remember correctly > these are always expected to be little endian. But I guess that could be > a problem for another day. > > I believe the layout of these structs are designed in a way that a > reasonable compiler wouldn't add padding on AArch32 or AArch64. Note > that packed does more than just force generation of inefficient code on > Arm (unaligned access), it also makes it invalid to take the address of > a member inside such a struct. Packing removed from ffa_partition_info and ffa_send_direct_data structures in v8 patchset. > > Cheers, > Jens