Hi Bertrand,

On Thu, Nov 27, 2025 at 4:52 PM Bertrand Marquis
<[email protected]> wrote:
>
> Harden the RX/TX mapping paths and keep signed FF-A return codes
> end-to-end.
>
> Reject zero-length mappings and insist on page-aligned RX/TX buffer
> addresses before touching the P2M. The unmap plumbing is switched to
> use the same signed helpers so dispatcher error handling is consistent
> across map and unmap operations.
>
> This avoids partially mapped or silently truncated buffers and makes the
> mediator behaviour match the FF-A error model more closely.
>
> While there also introduce a domain_rxtx_init to properly initialize the
> rxtx buffers spinlocks.
>
> Signed-off-by: Bertrand Marquis <[email protected]>
> ---
>  xen/arch/arm/tee/ffa.c         |  4 ++++
>  xen/arch/arm/tee/ffa_private.h |  5 +++--
>  xen/arch/arm/tee/ffa_rxtx.c    | 28 +++++++++++++++++++++-------
>  3 files changed, 28 insertions(+), 9 deletions(-)

Looks good
Reviewed-by: Jens Wiklander <[email protected]>

Cheers,
Jens

>
> diff --git a/xen/arch/arm/tee/ffa.c b/xen/arch/arm/tee/ffa.c
> index 3309ca875ec4..47f426e85864 100644
> --- a/xen/arch/arm/tee/ffa.c
> +++ b/xen/arch/arm/tee/ffa.c
> @@ -446,6 +446,10 @@ static int ffa_domain_init(struct domain *d)
>      if ( ret )
>          return ret;
>
> +    ret = ffa_rxtx_domain_init(d);
> +    if ( ret )
> +        return ret;
> +
>      return ffa_notif_domain_init(d);
>  }
>
> diff --git a/xen/arch/arm/tee/ffa_private.h b/xen/arch/arm/tee/ffa_private.h
> index 88b85c7c453a..4272afd37343 100644
> --- a/xen/arch/arm/tee/ffa_private.h
> +++ b/xen/arch/arm/tee/ffa_private.h
> @@ -427,10 +427,11 @@ void ffa_handle_partition_info_get(struct cpu_user_regs 
> *regs);
>
>  bool ffa_rxtx_init(void);
>  void ffa_rxtx_destroy(void);
> +int32_t ffa_rxtx_domain_init(struct domain *d);
>  void ffa_rxtx_domain_destroy(struct domain *d);
> -uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr,
> +int32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr,
>                              register_t rx_addr, uint32_t page_count);
> -uint32_t ffa_handle_rxtx_unmap(void);
> +int32_t ffa_handle_rxtx_unmap(void);
>  int32_t ffa_rx_acquire(struct domain *d);
>  int32_t ffa_rx_release(struct domain *d);
>
> diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c
> index a40e5b32e3a5..cd467d1dba68 100644
> --- a/xen/arch/arm/tee/ffa_rxtx.c
> +++ b/xen/arch/arm/tee/ffa_rxtx.c
> @@ -41,10 +41,10 @@ static int32_t ffa_rxtx_unmap(uint16_t id)
>      return ffa_simple_call(FFA_RXTX_UNMAP, ((uint64_t)id) << 16, 0, 0, 0);
>  }
>
> -uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr,
> +int32_t ffa_handle_rxtx_map(uint32_t fid, register_t tx_addr,
>                              register_t rx_addr, uint32_t page_count)
>  {
> -    uint32_t ret = FFA_RET_INVALID_PARAMETERS;
> +    int32_t ret = FFA_RET_INVALID_PARAMETERS;
>      struct domain *d = current->domain;
>      struct ffa_ctx *ctx = d->arch.tee;
>      struct page_info *tx_pg;
> @@ -66,13 +66,17 @@ uint32_t ffa_handle_rxtx_map(uint32_t fid, register_t 
> tx_addr,
>          rx_addr &= UINT32_MAX;
>      }
>
> -    if ( page_count > FFA_MAX_RXTX_PAGE_COUNT )
> +    if ( page_count > FFA_MAX_RXTX_PAGE_COUNT || !page_count )
>      {
>          printk(XENLOG_ERR "ffa: RXTX_MAP: error: %u pages requested (limit 
> %u)\n",
>                 page_count, FFA_MAX_RXTX_PAGE_COUNT);
>          return FFA_RET_INVALID_PARAMETERS;
>      }
>
> +    if ( !IS_ALIGNED(tx_addr, FFA_PAGE_SIZE) ||
> +         !IS_ALIGNED(rx_addr, FFA_PAGE_SIZE) )
> +        return FFA_RET_INVALID_PARAMETERS;
> +
>      /* Already mapped */
>      if ( ctx->rx )
>          return FFA_RET_DENIED;
> @@ -181,7 +185,7 @@ err_put_tx_pg:
>      return ret;
>  }
>
> -static uint32_t  rxtx_unmap(struct domain *d)
> +static int32_t rxtx_unmap(struct domain *d)
>  {
>      struct ffa_ctx *ctx = d->arch.tee;
>
> @@ -190,7 +194,7 @@ static uint32_t  rxtx_unmap(struct domain *d)
>
>      if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) )
>      {
> -        uint32_t ret;
> +        int32_t ret;
>
>          ret = ffa_rxtx_unmap(ffa_get_vm_id(d));
>          if ( ret != FFA_RET_OK )
> @@ -211,7 +215,7 @@ static uint32_t  rxtx_unmap(struct domain *d)
>      return FFA_RET_OK;
>  }
>
> -uint32_t ffa_handle_rxtx_unmap(void)
> +int32_t ffa_handle_rxtx_unmap(void)
>  {
>      return rxtx_unmap(current->domain);
>  }
> @@ -272,6 +276,16 @@ out:
>      return ret;
>  }
>
> +int32_t ffa_rxtx_domain_init(struct domain *d)
> +{
> +    struct ffa_ctx *ctx = d->arch.tee;
> +
> +    spin_lock_init(&ctx->rx_lock);
> +    spin_lock_init(&ctx->tx_lock);
> +
> +    return 0;
> +}
> +
>  void ffa_rxtx_domain_destroy(struct domain *d)
>  {
>      rxtx_unmap(d);
> @@ -298,7 +312,7 @@ void ffa_rxtx_destroy(void)
>
>  bool ffa_rxtx_init(void)
>  {
> -    int e;
> +    int32_t e;
>
>      /* Firmware not there or not supporting */
>      if ( !ffa_fw_supports_fid(FFA_RXTX_MAP_64) )
> --
> 2.51.2
>

Reply via email to