[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 07/12] xen/arm: ffa: Fix RXTX_UNMAP ownership race


  • To: Bertrand Marquis <bertrand.marquis@xxxxxxx>
  • From: Jens Wiklander <jens.wiklander@xxxxxxxxxx>
  • Date: Wed, 11 Feb 2026 08:39:13 +0100
  • Arc-authentication-results: i=1; mx.google.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=hAOqMCJadlogczB7gZP3FZlkdp68ySmqKKAKzRWZ3Cc=; fh=wNLC6Hyb5Ukz/ErppBRQBwv8vwa/OMsdh6R8bnNsiPU=; b=YBbgRt7eBuHNstkVihPyQVPQKiexGSUyxbH09fqcJ7vcroOown3TOVTqo45YCGc63i 0QfBls2xqCopOWPOlJp35DfB8rWrday2gYUKZQdrtpVoRjcPK+VMw8QXvlEvmZpccrK1 y9Nqgd9Q+HPEW/c9g1MTi1mtstsZSTX8sp3iE3D4YBPfKRu8WJhMuF0BZDvxhDYi9Y/V g0GAh1QwQtxT5k+d5OxT7jMmutifkScLIm+Xv6+ry97h+YEbiIFgC14tHm81octGzu4M tinYWPZ0krM0PnOEsGXwVqSztw1TDycm3odBanp6hCL2n57HzindrvwSlls+BJxYOMmr I4vA==; darn=lists.xenproject.org
  • Arc-seal: i=1; a=rsa-sha256; t=1770795565; cv=none; d=google.com; s=arc-20240605; b=k9oFJOJoMBPglYv+4KoKVActD2cegbVonONPDbdz6vibdWxNG6b1lLoZ92bIT1T7D+ pAdNaxSYvcFLZccOT46L+F8VWEBn0MNI0REaFuRzT1S3yo7Vy24NwCVTdxL+BZb1IlDS rYwzYDNZ1qK/6G/TfUYqMOXSLT5y+kDYH8/IGMbxL7vv2Uf4WxpCxi707GN3NSGNvnnp LiWnz6y+xuiCUOdeWldHrlH8KJ/mIR7AwOyZe6SpKnFsNiCmGdBdzj/BZIrG9VEoYzCD a0GqhbWdRg5Noxo0/DkoWP2QLYLj2w3epYmRO7Ofh+4Z+W19dNJ+ROK4UWadVoQrTMjM ftNw==
  • Cc: xen-devel@xxxxxxxxxxxxxxxxxxxx, Volodymyr Babchuk <volodymyr_babchuk@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>
  • Delivery-date: Wed, 11 Feb 2026 07:39:39 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Hi Bertrand,

On Tue, Feb 3, 2026 at 6:38 PM Bertrand Marquis
<bertrand.marquis@xxxxxxx> wrote:
>
> rxtx_unmap() checks RX ownership without holding the RX/TX locks and
> only enforces the ownership rule when FFA_RX_ACQUIRE is supported. This
> allows a vCPU to acquire RX between the check and unmap, and it lets
> RXTX_UNMAP proceed while RX is owned when buffers are not forwarded to
> firmware.
>
> Hold rx_lock/tx_lock across the ownership check and unmap, and deny
> RXTX_UNMAP whenever RX is owned, independent of RX_ACQUIRE support. For
> teardown, release RX ownership under the same lock window; use
> FFA_RX_RELEASE directly because rx_lock is held, and clear the local
> flag when the firmware path is unavailable.
>
> Functional impact: RXTX_UNMAP now reliably returns DENIED while RX is
> owned, and teardown releases/clears ownership without a race.
>
> Signed-off-by: Bertrand Marquis <bertrand.marquis@xxxxxxx>
> ---
>  xen/arch/arm/tee/ffa_rxtx.c | 36 +++++++++++++++++++++++++++++++++---
>  1 file changed, 33 insertions(+), 3 deletions(-)
>
> diff --git a/xen/arch/arm/tee/ffa_rxtx.c b/xen/arch/arm/tee/ffa_rxtx.c
> index eff95a7955d7..450ce102cbdc 100644
> --- a/xen/arch/arm/tee/ffa_rxtx.c
> +++ b/xen/arch/arm/tee/ffa_rxtx.c
> @@ -220,7 +220,7 @@ err_unlock_rxtx:
>      return ret;
>  }
>
> -static int32_t rxtx_unmap(struct domain *d)
> +static int32_t rxtx_unmap(struct domain *d, bool teardown)
>  {
>      struct ffa_ctx *ctx = d->arch.tee;
>      int32_t ret = FFA_RET_OK;
> @@ -234,6 +234,36 @@ static int32_t rxtx_unmap(struct domain *d)
>          goto err_unlock_rxtx;
>      }
>
> +    if ( !ctx->rx_is_free )
> +    {
> +        if ( teardown )
> +        {
> +            if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) )
> +            {
> +                int32_t rel_ret;
> +
> +                /* Can't use ffa_rx_release() while holding rx_lock. */
> +                rel_ret = ffa_simple_call(FFA_RX_RELEASE, ctx->ffa_id,
> +                                          0, 0, 0);
> +                if ( rel_ret )
> +                    gdprintk(XENLOG_DEBUG,
> +                             "ffa: RX release during teardown failed: %d\n",
> +                             rel_ret);
> +                else
> +                    ctx->rx_is_free = true;

I don't see why this assignment is needed, or the one just below.

> +            }
> +            else
> +                ctx->rx_is_free = true;
> +        }
> +        else
> +        {
> +            gdprintk(XENLOG_DEBUG,
> +                     "ffa: RXTX_UNMAP denied, RX buffer owned by VM\n");
> +            ret = FFA_RET_DENIED;
> +            goto err_unlock_rxtx;
> +        }
> +    }
> +
>      if ( ffa_fw_supports_fid(FFA_RX_ACQUIRE) )
>      {
>          ret = ffa_rxtx_unmap(ffa_get_vm_id(d));
> @@ -261,7 +291,7 @@ err_unlock_rxtx:
>
>  int32_t ffa_handle_rxtx_unmap(void)
>  {
> -    return rxtx_unmap(current->domain);
> +    return rxtx_unmap(current->domain, false);
>  }
>
>  int32_t ffa_rx_acquire(struct ffa_ctx *ctx, void **buf, size_t *buf_size)
> @@ -369,7 +399,7 @@ int32_t ffa_rxtx_domain_init(struct domain *d)
>
>  void ffa_rxtx_domain_destroy(struct domain *d)
>  {
> -    rxtx_unmap(d);
> +    rxtx_unmap(d, true);

How about adding a /* teardown */ just after true as a reminder of
what true is supposed to represent.

Adding such comments isn't very common, but we're doing it at a few
places in the source tree, and I think it helps when reading the code.

Cheers,
Jens

>  }
>
>  void *ffa_rxtx_spmc_rx_acquire(void)
> --
> 2.50.1 (Apple Git-155)
>



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.