|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v2 04/10] xen/arm: ffa: Fine granular call support
Hi Bertrand,
On Wed, Oct 16, 2024 at 10:32 AM Bertrand Marquis
<bertrand.marquis@xxxxxxx> wrote:
>
> Create a bitmap to store which feature is supported or not by the
> firmware and use it to filter which calls are done to the firmware.
>
> While there reoder ABI definition by numbers to easily find the min and
> max ones.
>
> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
> ---
> Changes in v2:
> - rename fw_feat to abi and macros to FFA_ABI to be coherent with the
> abi needed change done before
> - rework the macros to be simpler by directly defining MIN and MAX using
> only Function ids
> - check that requested function ids do not go over the bitmap size in
> ffa_fw_supports_fid
> - add an ASSERT to make sure that we do not try to set bits outside of
> the bitmap
> - turn off FF-A if there is not firmware support and adapt the commit
> message to reflect this
> - add a compile time check that FFA_ABI_MIN < FFA_ABI_MAX
> - remove spurious line removal
> - restore proper cleanup of rxtx init in case of error
> - reorder ABI by numbers
> ---
> xen/arch/arm/tee/ffa.c | 28 +++++++++++++++---------
> xen/arch/arm/tee/ffa_notif.c | 7 ++++++
> xen/arch/arm/tee/ffa_partinfo.c | 30 +++++++++++++++++++++++++-
> xen/arch/arm/tee/ffa_private.h | 38 ++++++++++++++++++++++++++++-----
> xen/arch/arm/tee/ffa_rxtx.c | 4 ++++
> xen/arch/arm/tee/ffa_shm.c | 12 +++++++++++
> 6 files changed, 103 insertions(+), 16 deletions(-)
Looks good.
Reviewed-by: Jens Wiklander <jens.wiklander@xxxxxxxxxx>
Cheers,
Jens
>
> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
> index 1ee6b2895e92..267d4435ac08 100644
> --- a/xen/arch/arm/tee/ffa.c
> +++ b/xen/arch/arm/tee/ffa.c
> @@ -72,7 +72,10 @@
> #include "ffa_private.h"
>
> /* Negotiated FF-A version to use with the SPMC, 0 if not there or supported
> */
> -static uint32_t __ro_after_init ffa_fw_version;
> +uint32_t __ro_after_init ffa_fw_version;
> +
> +/* Features supported by the SPMC or secure world when present */
> +DECLARE_BITMAP(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE);
>
> struct ffa_fw_abi {
> const uint32_t id;
> @@ -177,6 +180,13 @@ static void handle_msg_send_direct_req(struct
> cpu_user_regs *regs, uint32_t fid)
> else
> mask = GENMASK_ULL(31, 0);
>
> + if ( !ffa_fw_supports_fid(fid) )
> + {
> + resp.a0 = FFA_ERROR;
> + resp.a2 = FFA_RET_NOT_SUPPORTED;
> + goto out;
> + }
> +
> src_dst = get_user_reg(regs, 1);
> if ( (src_dst >> 16) != ffa_get_vm_id(d) )
> {
> @@ -577,19 +587,16 @@ static bool ffa_probe(void)
> else
> ffa_fw_version = vers;
>
> - /*
> - * At the moment domains must support the same features used by Xen.
> - * TODO: Rework the code to allow domain to use a subset of the
> - * features supported.
> - */
> for ( unsigned int i = 0; i < ARRAY_SIZE(ffa_fw_abi_needed); i++ )
> {
> - if ( !ffa_abi_supported(ffa_fw_abi_needed[i].id) )
> - {
> + ASSERT(FFA_ABI_BITNUM(ffa_fw_abi_needed[i].id) <
> FFA_ABI_BITMAP_SIZE);
> +
> + if ( ffa_abi_supported(ffa_fw_abi_needed[i].id) )
> + set_bit(FFA_ABI_BITNUM(ffa_fw_abi_needed[i].id),
> + ffa_fw_abi_supported);
> + else
> printk(XENLOG_INFO "ARM FF-A Firmware does not support %s\n",
> ffa_fw_abi_needed[i].name);
> - goto err_no_fw;
> - }
> }
>
> if ( !ffa_rxtx_init() )
> @@ -611,6 +618,7 @@ err_rxtx_destroy:
> ffa_rxtx_destroy();
> err_no_fw:
> ffa_fw_version = 0;
> + bitmap_zero(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE);
> printk(XENLOG_WARNING "ARM FF-A No firmware support\n");
>
> return false;
> diff --git a/xen/arch/arm/tee/ffa_notif.c b/xen/arch/arm/tee/ffa_notif.c
> index 541e61d2f606..4b3e46318f4b 100644
> --- a/xen/arch/arm/tee/ffa_notif.c
> +++ b/xen/arch/arm/tee/ffa_notif.c
> @@ -377,6 +377,13 @@ void ffa_notif_init(void)
> unsigned int irq;
> int ret;
>
> + /* Only enable fw notification if all ABIs we need are supported */
> + if ( !(ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_CREATE) &&
> + ffa_fw_supports_fid(FFA_NOTIFICATION_BITMAP_DESTROY) &&
> + ffa_fw_supports_fid(FFA_NOTIFICATION_GET) &&
> + ffa_fw_supports_fid(FFA_NOTIFICATION_INFO_GET_64)) )
> + return;
> +
> arm_smccc_1_2_smc(&arg, &resp);
> if ( resp.a0 != FFA_SUCCESS_32 )
> return;
> diff --git a/xen/arch/arm/tee/ffa_partinfo.c b/xen/arch/arm/tee/ffa_partinfo.c
> index 93a03c6bc672..99c48f0e5c05 100644
> --- a/xen/arch/arm/tee/ffa_partinfo.c
> +++ b/xen/arch/arm/tee/ffa_partinfo.c
> @@ -77,7 +77,15 @@ int32_t ffa_handle_partition_info_get(uint32_t w1,
> uint32_t w2, uint32_t w3,
> */
> if ( w5 == FFA_PARTITION_INFO_GET_COUNT_FLAG &&
> ctx->guest_vers == FFA_VERSION_1_1 )
> - return ffa_partition_info_get(w1, w2, w3, w4, w5, count, fpi_size);
> + {
> + if ( ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) )
> + return ffa_partition_info_get(w1, w2, w3, w4, w5, count,
> fpi_size);
> + else
> + {
> + *count = 0;
> + return FFA_RET_OK;
> + }
> + }
> if ( w5 )
> return FFA_RET_INVALID_PARAMETERS;
>
> @@ -87,6 +95,18 @@ int32_t ffa_handle_partition_info_get(uint32_t w1,
> uint32_t w2, uint32_t w3,
> if ( !spin_trylock(&ctx->rx_lock) )
> return FFA_RET_BUSY;
>
> + if ( !ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) )
> + {
> + if ( ctx->guest_vers == FFA_VERSION_1_0 )
> + *fpi_size = sizeof(struct ffa_partition_info_1_0);
> + else
> + *fpi_size = sizeof(struct ffa_partition_info_1_1);
> +
> + *count = 0;
> + ret = FFA_RET_OK;
> + goto out;
> + }
> +
> if ( !ctx->page_count || !ctx->rx_is_free )
> goto out;
> spin_lock(&ffa_rx_buffer_lock);
> @@ -250,6 +270,11 @@ bool ffa_partinfo_init(void)
> uint32_t count;
> int e;
>
> + if ( !ffa_fw_supports_fid(FFA_PARTITION_INFO_GET) ||
> + !ffa_fw_supports_fid(FFA_MSG_SEND_DIRECT_REQ_32) ||
> + !ffa_rx || !ffa_tx )
> + return false;
> +
> e = ffa_partition_info_get(0, 0, 0, 0, 0, &count, &fpi_size);
> if ( e )
> {
> @@ -313,6 +338,9 @@ int ffa_partinfo_domain_init(struct domain *d)
> unsigned int n;
> int32_t res;
>
> + if ( !ffa_fw_supports_fid(FFA_MSG_SEND_DIRECT_REQ_32) )
> + return 0;
> +
> ctx->vm_destroy_bitmap = xzalloc_array(unsigned long, count);
> if ( !ctx->vm_destroy_bitmap )
> return -ENOMEM;
> diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h
> index 045d9c4a0b56..85eb61c13464 100644
> --- a/xen/arch/arm/tee/ffa_private.h
> +++ b/xen/arch/arm/tee/ffa_private.h
> @@ -14,6 +14,7 @@
> #include <xen/spinlock.h>
> #include <xen/sched.h>
> #include <xen/time.h>
> +#include <xen/bitmap.h>
>
> /* Error codes */
> #define FFA_RET_OK 0
> @@ -201,18 +202,17 @@
> #define FFA_INTERRUPT 0x84000062U
> #define FFA_VERSION 0x84000063U
> #define FFA_FEATURES 0x84000064U
> -#define FFA_RX_ACQUIRE 0x84000084U
> #define FFA_RX_RELEASE 0x84000065U
> #define FFA_RXTX_MAP_32 0x84000066U
> #define FFA_RXTX_MAP_64 0xC4000066U
> #define FFA_RXTX_UNMAP 0x84000067U
> #define FFA_PARTITION_INFO_GET 0x84000068U
> #define FFA_ID_GET 0x84000069U
> -#define FFA_SPM_ID_GET 0x84000085U
> +#define FFA_MSG_POLL 0x8400006AU
> #define FFA_MSG_WAIT 0x8400006BU
> #define FFA_MSG_YIELD 0x8400006CU
> #define FFA_RUN 0x8400006DU
> -#define FFA_MSG_SEND2 0x84000086U
> +#define FFA_MSG_SEND 0x8400006EU
> #define FFA_MSG_SEND_DIRECT_REQ_32 0x8400006FU
> #define FFA_MSG_SEND_DIRECT_REQ_64 0xC400006FU
> #define FFA_MSG_SEND_DIRECT_RESP_32 0x84000070U
> @@ -230,8 +230,6 @@
> #define FFA_MEM_RECLAIM 0x84000077U
> #define FFA_MEM_FRAG_RX 0x8400007AU
> #define FFA_MEM_FRAG_TX 0x8400007BU
> -#define FFA_MSG_SEND 0x8400006EU
> -#define FFA_MSG_POLL 0x8400006AU
> #define FFA_NOTIFICATION_BITMAP_CREATE 0x8400007DU
> #define FFA_NOTIFICATION_BITMAP_DESTROY 0x8400007EU
> #define FFA_NOTIFICATION_BIND 0x8400007FU
> @@ -240,6 +238,25 @@
> #define FFA_NOTIFICATION_GET 0x84000082U
> #define FFA_NOTIFICATION_INFO_GET_32 0x84000083U
> #define FFA_NOTIFICATION_INFO_GET_64 0xC4000083U
> +#define FFA_RX_ACQUIRE 0x84000084U
> +#define FFA_SPM_ID_GET 0x84000085U
> +#define FFA_MSG_SEND2 0x84000086U
> +
> +/**
> + * Encoding of features supported or not by the fw in a bitmap:
> + * - Function IDs are going from 0x60 to 0xFF
> + * - A function can be supported in 32 and/or 64bit
> + * The bitmap has one bit for each function in 32 and 64 bit.
> + */
> +#define FFA_ABI_ID(id) ((id) & ARM_SMCCC_FUNC_MASK)
> +#define FFA_ABI_CONV(id) (((id) >> ARM_SMCCC_CONV_SHIFT) & BIT(0,U))
> +
> +#define FFA_ABI_MIN FFA_ABI_ID(FFA_ERROR)
> +#define FFA_ABI_MAX FFA_ABI_ID(FFA_MSG_SEND2)
> +
> +#define FFA_ABI_BITMAP_SIZE (2 * (FFA_ABI_MAX - FFA_ABI_MIN + 1))
> +#define FFA_ABI_BITNUM(id) ((FFA_ABI_ID(id) - FFA_ABI_MIN) << 1 | \
> + FFA_ABI_CONV(id))
>
> struct ffa_ctx_notif {
> bool enabled;
> @@ -289,6 +306,8 @@ extern void *ffa_rx;
> extern void *ffa_tx;
> extern spinlock_t ffa_rx_buffer_lock;
> extern spinlock_t ffa_tx_buffer_lock;
> +extern uint32_t __ro_after_init ffa_fw_version;
> +extern DECLARE_BITMAP(ffa_fw_abi_supported, FFA_ABI_BITMAP_SIZE);
>
> bool ffa_shm_domain_destroy(struct domain *d);
> void ffa_handle_mem_share(struct cpu_user_regs *regs);
> @@ -401,4 +420,13 @@ static inline int32_t ffa_rx_release(void)
> return ffa_simple_call(FFA_RX_RELEASE, 0, 0, 0, 0);
> }
>
> +static inline bool ffa_fw_supports_fid(uint32_t fid)
> +{
> + BUILD_BUG_ON(FFA_ABI_MIN > FFA_ABI_MAX);
> +
> + if ( FFA_ABI_BITNUM(fid) > FFA_ABI_BITMAP_SIZE)
> + return false;
> + return test_bit(FFA_ABI_BITNUM(fid), ffa_fw_abi_supported);
> +}
> +
> #endif /*__FFA_PRIVATE_H__*/
> diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c
> index 661764052e67..b6931c855779 100644
> --- a/xen/arch/arm/tee/ffa_rxtx.c
> +++ b/xen/arch/arm/tee/ffa_rxtx.c
> @@ -193,6 +193,10 @@ bool ffa_rxtx_init(void)
> {
> int e;
>
> + /* Firmware not there or not supporting */
> + if ( !ffa_fw_supports_fid(FFA_RXTX_MAP_64) )
> + return false;
> +
> ffa_rx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT),
> 0);
> if ( !ffa_rx )
> return false;
> diff --git a/xen/arch/arm/tee/ffa_shm.c b/xen/arch/arm/tee/ffa_shm.c
> index 370d83ec5cf8..efa5b67db8e1 100644
> --- a/xen/arch/arm/tee/ffa_shm.c
> +++ b/xen/arch/arm/tee/ffa_shm.c
> @@ -149,6 +149,9 @@ static int32_t ffa_mem_share(uint32_t tot_len, uint32_t
> frag_len,
> static int32_t ffa_mem_reclaim(uint32_t handle_lo, uint32_t handle_hi,
> uint32_t flags)
> {
> + if ( !ffa_fw_supports_fid(FFA_MEM_RECLAIM) )
> + return FFA_RET_NOT_SUPPORTED;
> +
> return ffa_simple_call(FFA_MEM_RECLAIM, handle_lo, handle_hi, flags, 0);
> }
>
> @@ -467,6 +470,12 @@ void ffa_handle_mem_share(struct cpu_user_regs *regs)
> uint32_t range_count;
> uint32_t region_offs;
>
> + if ( !ffa_fw_supports_fid(FFA_MEM_SHARE_64) )
> + {
> + ret = FFA_RET_NOT_SUPPORTED;
> + goto out_set_ret;
> + }
> +
> /*
> * We're only accepting memory transaction descriptors via the rx/tx
> * buffer.
> @@ -621,6 +630,9 @@ int ffa_handle_mem_reclaim(uint64_t handle, uint32_t
> flags)
> register_t handle_lo;
> int ret;
>
> + if ( !ffa_fw_supports_fid(FFA_MEM_RECLAIM) )
> + return FFA_RET_NOT_SUPPORTED;
> +
> spin_lock(&ctx->lock);
> shm = find_shm_mem(ctx, handle);
> if ( shm )
> --
> 2.47.0
>
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |