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 >
