aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Walbran <qwandor@google.com>2020-09-16 13:23:23 +0100
committerAndrew Walbran <qwandor@google.com>2020-09-23 16:04:50 +0000
commit75c57d163dc41e617d8a008b3fb1c6e1bf5e0b7e (patch)
tree9a16185000ea20436f06cc4c7743af5e82087b73
parent6feffaba0133640c4a3fb225527920ba5ac27ae4 (diff)
downloadhafnium-75c57d163dc41e617d8a008b3fb1c6e1bf5e0b7e.tar.gz
Use separate function for making FF-A calls to EL3.
smc_forward was being abused. Also add some more comments. Change-Id: I0f24b89b7e0d2f56c75d7314ceda5a8bc647c410
-rw-r--r--src/arch/aarch64/hypervisor/handler.c10
-rw-r--r--src/arch/aarch64/hypervisor/tee.c3
-rw-r--r--src/arch/aarch64/smc.c17
-rw-r--r--src/arch/aarch64/smc.h2
4 files changed, 24 insertions, 8 deletions
diff --git a/src/arch/aarch64/hypervisor/handler.c b/src/arch/aarch64/hypervisor/handler.c
index 10caf405..28625fb0 100644
--- a/src/arch/aarch64/hypervisor/handler.c
+++ b/src/arch/aarch64/hypervisor/handler.c
@@ -466,12 +466,14 @@ static bool ffa_handler_loop(struct ffa_value *ret, struct vcpu **next)
* The FF-A call is handled and ffa_next is null which hints
* the result shall be passed to the other world.
*/
- *ret = smc_forward(ret->func, ret->arg1, ret->arg2, ret->arg3,
- ret->arg4, ret->arg5, ret->arg6, ret->arg7);
+ *ret = smc_ffa_call(*ret);
/*
- * Returned from EL3 thus next FF-A call is from
- * physical FF-A instance.
+ * Returned from EL3, thus *ret contains an FF-A call from the
+ * physical FF-A instance. Handle it. At this point ffa_next is
+ * NULL, which means that we will return the result of the call
+ * back to EL3 unless the API handler sets ffa_next to something
+ * different.
*/
handled = ffa_handler(ret, other_world_vcpu, &ffa_next);
}
diff --git a/src/arch/aarch64/hypervisor/tee.c b/src/arch/aarch64/hypervisor/tee.c
index 21c607ed..f642a0c3 100644
--- a/src/arch/aarch64/hypervisor/tee.c
+++ b/src/arch/aarch64/hypervisor/tee.c
@@ -53,6 +53,5 @@ void arch_tee_init(void)
struct ffa_value arch_tee_call(struct ffa_value args)
{
- return smc_forward(args.func, args.arg1, args.arg2, args.arg3,
- args.arg4, args.arg5, args.arg6, args.arg7);
+ return smc_ffa_call(args);
}
diff --git a/src/arch/aarch64/smc.c b/src/arch/aarch64/smc.c
index c640ab93..1f9ea933 100644
--- a/src/arch/aarch64/smc.c
+++ b/src/arch/aarch64/smc.c
@@ -15,7 +15,7 @@
static struct ffa_value smc_internal(uint32_t func, uint64_t arg0,
uint64_t arg1, uint64_t arg2,
uint64_t arg3, uint64_t arg4,
- uint64_t arg5, uint32_t caller_id)
+ uint64_t arg5, uint64_t arg6)
{
register uint64_t r0 __asm__("x0") = func;
register uint64_t r1 __asm__("x1") = arg0;
@@ -24,7 +24,7 @@ static struct ffa_value smc_internal(uint32_t func, uint64_t arg0,
register uint64_t r4 __asm__("x4") = arg3;
register uint64_t r5 __asm__("x5") = arg4;
register uint64_t r6 __asm__("x6") = arg5;
- register uint64_t r7 __asm__("x7") = caller_id;
+ register uint64_t r7 __asm__("x7") = arg6;
__asm__ volatile(
"smc #0"
@@ -42,6 +42,7 @@ static struct ffa_value smc_internal(uint32_t func, uint64_t arg0,
.arg7 = r7};
}
+/** Make an SMC call following the 32-bit SMC calling convention. */
struct ffa_value smc32(uint32_t func, uint32_t arg0, uint32_t arg1,
uint32_t arg2, uint32_t arg3, uint32_t arg4,
uint32_t arg5, uint32_t caller_id)
@@ -50,6 +51,7 @@ struct ffa_value smc32(uint32_t func, uint32_t arg0, uint32_t arg1,
arg5, caller_id);
}
+/** Make an SMC call following the 64-bit SMC calling convention. */
struct ffa_value smc64(uint32_t func, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4,
uint64_t arg5, uint32_t caller_id)
@@ -58,6 +60,7 @@ struct ffa_value smc64(uint32_t func, uint64_t arg0, uint64_t arg1,
arg5, caller_id);
}
+/** Forward a raw SMC on to EL3. */
struct ffa_value smc_forward(uint32_t func, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4,
uint64_t arg5, uint32_t caller_id)
@@ -65,3 +68,13 @@ struct ffa_value smc_forward(uint32_t func, uint64_t arg0, uint64_t arg1,
return smc_internal(func, arg0, arg1, arg2, arg3, arg4, arg5,
caller_id);
}
+
+/**
+ * Make an FF-A call up to EL3. Assumes the function ID is already masked
+ * appropriately for the 32-bit or 64-bit SMCCC.
+ */
+struct ffa_value smc_ffa_call(struct ffa_value args)
+{
+ return smc_internal(args.func, args.arg1, args.arg2, args.arg3,
+ args.arg4, args.arg5, args.arg6, args.arg7);
+}
diff --git a/src/arch/aarch64/smc.h b/src/arch/aarch64/smc.h
index 169661ed..d35d2a60 100644
--- a/src/arch/aarch64/smc.h
+++ b/src/arch/aarch64/smc.h
@@ -52,3 +52,5 @@ struct ffa_value smc64(uint32_t func, uint64_t arg0, uint64_t arg1,
struct ffa_value smc_forward(uint32_t func, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4,
uint64_t arg5, uint32_t caller_id);
+
+struct ffa_value smc_ffa_call(struct ffa_value args);