Hi Bertrand,

On Thu, Nov 27, 2025 at 4:53 PM Bertrand Marquis
<[email protected]> wrote:
>
> Extend the direct-request path so FF-A v1.2 guests can issue
> FFA_MSG_SEND_DIRECT_REQ2 and receive the matching RESP2.
>
> The handler now marshals registers x8–x17, and
> ffa_finish_direct_req_run() copies back the 17-register response used by
> FFA_MSG_SEND_DIRECT_RESP2. The new opcode is exposed via FFA_FEATURES
> and gated on guests that negotiated v1.2.
>
> Signed-off-by: Bertrand Marquis <[email protected]>
> ---
>  xen/arch/arm/tee/ffa.c     | 20 +++++++++++++++++++
>  xen/arch/arm/tee/ffa_msg.c | 39 ++++++++++++++++++++++++++++++++++++++
>  2 files changed, 59 insertions(+)

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 92cb6ad7ec97..8b2f042287fc 100644
> --- a/xen/arch/arm/tee/ffa.c
> +++ b/xen/arch/arm/tee/ffa.c
> @@ -234,6 +234,8 @@ out_continue:
>  static void handle_features(struct cpu_user_regs *regs)
>  {
>      uint32_t a1 = get_user_reg(regs, 1);
> +    struct domain *d = current->domain;
> +    struct ffa_ctx *ctx = d->arch.tee;
>      unsigned int n;
>
>      for ( n = 2; n <= 7; n++ )
> @@ -262,6 +264,16 @@ static void handle_features(struct cpu_user_regs *regs)
>      case FFA_MSG_SEND2:
>          ffa_set_regs_success(regs, 0, 0);
>          break;
> +    case FFA_MSG_SEND_DIRECT_REQ2:
> +        if ( ctx->guest_vers >= FFA_VERSION_1_2 )
> +        {
> +            ffa_set_regs_success(regs, 0, 0);
> +        }
> +        else
> +        {
> +            ffa_set_regs_error(regs, FFA_RET_NOT_SUPPORTED);
> +        }
> +        break;
>      case FFA_MEM_SHARE_64:
>      case FFA_MEM_SHARE_32:
>          /*
> @@ -347,6 +359,14 @@ static bool ffa_handle_call(struct cpu_user_regs *regs)
>      case FFA_MSG_SEND_DIRECT_REQ_64:
>          ffa_handle_msg_send_direct_req(regs, fid);
>          return true;
> +    case FFA_MSG_SEND_DIRECT_REQ2:
> +        if ( ctx->guest_vers >= FFA_VERSION_1_2 )
> +        {
> +            ffa_handle_msg_send_direct_req(regs, fid);
> +            return true;
> +        }
> +        e = FFA_RET_NOT_SUPPORTED;
> +        break;
>      case FFA_RUN:
>          ffa_handle_run(regs, fid);
>          return true;
> diff --git a/xen/arch/arm/tee/ffa_msg.c b/xen/arch/arm/tee/ffa_msg.c
> index 472bfad79dd3..1f42aae1e0b6 100644
> --- a/xen/arch/arm/tee/ffa_msg.c
> +++ b/xen/arch/arm/tee/ffa_msg.c
> @@ -49,6 +49,30 @@ static void ffa_finish_direct_req_run(struct cpu_user_regs 
> *regs,
>      case FFA_MSG_YIELD:
>      case FFA_INTERRUPT:
>          break;
> +    case FFA_MSG_SEND_DIRECT_RESP2:
> +        /*
> +         * REQ2 / RESP2 use a 17-register payload (x1–x17). Copy all of them
> +         * back to the guest context.
> +         */
> +        set_user_reg(regs, 0, resp.a0);
> +        set_user_reg(regs, 1, resp.a1);
> +        set_user_reg(regs, 2, resp.a2);
> +        set_user_reg(regs, 3, resp.a3);
> +        set_user_reg(regs, 4, resp.a4);
> +        set_user_reg(regs, 5, resp.a5);
> +        set_user_reg(regs, 6, resp.a6);
> +        set_user_reg(regs, 7, resp.a7);
> +        set_user_reg(regs, 8, resp.a8);
> +        set_user_reg(regs, 9, resp.a9);
> +        set_user_reg(regs, 10, resp.a10);
> +        set_user_reg(regs, 11, resp.a11);
> +        set_user_reg(regs, 12, resp.a12);
> +        set_user_reg(regs, 13, resp.a13);
> +        set_user_reg(regs, 14, resp.a14);
> +        set_user_reg(regs, 15, resp.a15);
> +        set_user_reg(regs, 16, resp.a16);
> +        set_user_reg(regs, 17, resp.a17);
> +        return;
>      default:
>          /* Bad fid, report back to the caller. */
>          ffa_set_regs_error(regs, FFA_RET_ABORTED);
> @@ -107,6 +131,21 @@ void ffa_handle_msg_send_direct_req(struct cpu_user_regs 
> *regs, uint32_t fid)
>      arg.a6 = get_user_reg(regs, 6) & mask;
>      arg.a7 = get_user_reg(regs, 7) & mask;
>
> +    if ( fid == FFA_MSG_SEND_DIRECT_REQ2 )
> +    {
> +        /* 17 registers are used for REQ2 */
> +        arg.a8 = get_user_reg(regs, 8);
> +        arg.a9 = get_user_reg(regs, 9);
> +        arg.a10 = get_user_reg(regs, 10);
> +        arg.a11 = get_user_reg(regs, 11);
> +        arg.a12 = get_user_reg(regs, 12);
> +        arg.a13 = get_user_reg(regs, 13);
> +        arg.a14 = get_user_reg(regs, 14);
> +        arg.a15 = get_user_reg(regs, 15);
> +        arg.a16 = get_user_reg(regs, 16);
> +        arg.a17 = get_user_reg(regs, 17);
> +    }
> +
>      ffa_finish_direct_req_run(regs, &arg);
>      return;
>
> --
> 2.51.2
>

Reply via email to