xen/arm: ffa: add MSG_SEND_DIRECT_REQ2 support

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 <bertrand.marquis@arm.com>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
This commit is contained in:
Bertrand Marquis authored and Julien Grall committed 2026-02-02 21:19:17 +00:00
1 parent e040b94d0f
commit 3ca6aca20d
2 files changed
+59

No files matched your search

+20
View File
@@ -237,6 +237,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++ )
@@ -268,6 +270,16 @@ static void handle_features(struct cpu_user_regs *regs)
case FFA_MSG_YIELD:
ffa_set_regs_success(regs, 0, 0);
break;
case FFA_MSG_SEND_DIRECT_REQ2:
if ( ACCESS_ONCE(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:
/*
@@ -353,6 +365,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 ( ACCESS_ONCE(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;
+39
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.