mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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:
1 parent
e040b94d0f
commit
3ca6aca20d
2 files changed
+59
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||