* [PATCH v6 1/7] KVM: arm64: Forward FFA_NOTIFICATION_BITMAP calls to Trustzone
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 2/7] KVM: arm64: Support FFA_NOTIFICATION_BIND in host handler Sebastian Ene
` (5 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Allow FF-A notification bitmap messages to be forwarded to
Trustzone from the host kernel driver and enforce the host vmid
check.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 1af722771178..ecc13b795f2c 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -676,8 +676,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_BITMAP_CREATE:
- case FFA_NOTIFICATION_BITMAP_DESTROY:
case FFA_NOTIFICATION_BIND:
case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
@@ -862,6 +860,21 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
hyp_spin_unlock(&host_buffers.lock);
}
+static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, vmid, ctxt, 1);
+ struct arm_smccc_1_2_regs *args;
+
+ if (vmid != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -920,6 +933,10 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_PARTITION_INFO_GET:
do_ffa_part_get(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_BITMAP_CREATE:
+ case FFA_NOTIFICATION_BITMAP_DESTROY:
+ do_ffa_notif_bitmap(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 2/7] KVM: arm64: Support FFA_NOTIFICATION_BIND in host handler
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 1/7] KVM: arm64: Forward FFA_NOTIFICATION_BITMAP calls to Trustzone Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 3/7] KVM: arm64: Support FFA_NOTIFICATION_UNBIND " Sebastian Ene
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Verify the arguments of the FF-A notification bind call and forward the
message to Trustzone.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index ecc13b795f2c..331d9d0d8287 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -42,6 +42,8 @@
*/
#define HOST_FFA_ID 0
+#define FFA_NOTIF_RECEIVER_ENDP_MASK GENMASK(15, 0)
+
/*
* A buffer to hold the maximum descriptor size we can see from the host,
* which is required when the SPMD returns a fragmented FFA_MEM_RETRIEVE_RESP
@@ -676,7 +678,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_BIND:
case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
case FFA_NOTIFICATION_GET:
@@ -875,6 +876,27 @@ static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_bind(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, flags, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (FIELD_GET(FFA_NOTIF_RECEIVER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (flags > 1) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -937,6 +959,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_BITMAP_DESTROY:
do_ffa_notif_bitmap(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_BIND:
+ do_ffa_notif_bind(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 3/7] KVM: arm64: Support FFA_NOTIFICATION_UNBIND in host handler
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 1/7] KVM: arm64: Forward FFA_NOTIFICATION_BITMAP calls to Trustzone Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 2/7] KVM: arm64: Support FFA_NOTIFICATION_BIND in host handler Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 4/7] KVM: arm64: Support FFA_NOTIFICATION_SET " Sebastian Ene
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Verify the arguments of the FF-A notification unbind call and forward
the message to Trustzone.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 331d9d0d8287..d52d7c4d5e7f 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -678,7 +678,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_UNBIND:
case FFA_NOTIFICATION_SET:
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
@@ -897,6 +896,27 @@ static void do_ffa_notif_bind(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_unbind(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, reserved, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (reserved) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (FIELD_GET(FFA_NOTIF_RECEIVER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -962,6 +982,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_BIND:
do_ffa_notif_bind(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_UNBIND:
+ do_ffa_notif_unbind(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 4/7] KVM: arm64: Support FFA_NOTIFICATION_SET in host handler
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
` (2 preceding siblings ...)
2026-06-26 7:45 ` [PATCH v6 3/7] KVM: arm64: Support FFA_NOTIFICATION_UNBIND " Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 5/7] KVM: arm64: Support FFA_NOTIFICATION_GET " Sebastian Ene
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Allow FF-A notification SET messages to be proxied from the pKVM
hypervisor to Trustzone and verify the arguments.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index d52d7c4d5e7f..2bb16aa414f9 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -43,6 +43,7 @@
#define HOST_FFA_ID 0
#define FFA_NOTIF_RECEIVER_ENDP_MASK GENMASK(15, 0)
+#define FFA_NOTIF_SENDER_ENDP_MASK GENMASK(31, 16)
/*
* A buffer to hold the maximum descriptor size we can see from the host,
@@ -678,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_SET:
case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
@@ -917,6 +917,27 @@ static void do_ffa_notif_unbind(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_set(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, flags, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (FIELD_GET(FFA_NOTIF_SENDER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (flags & GENMASK(15, 2)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -985,6 +1006,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_UNBIND:
do_ffa_notif_unbind(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_SET:
+ do_ffa_notif_set(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 5/7] KVM: arm64: Support FFA_NOTIFICATION_GET in host handler
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
` (3 preceding siblings ...)
2026-06-26 7:45 ` [PATCH v6 4/7] KVM: arm64: Support FFA_NOTIFICATION_SET " Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 6/7] KVM: arm64: Support FFA_NOTIFICATION_INFO_GET " Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy Sebastian Ene
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Allow FF-A notification GET messages to be proxied from the pKVM
hypervisor to Trustzone and verify the arguments sent from the host
driver.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 2bb16aa414f9..c22fe4514741 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -679,7 +679,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
/* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_GET:
case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
@@ -938,6 +937,27 @@ static void do_ffa_notif_set(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_get(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ DECLARE_REG(u32, endp_id, ctxt, 1);
+ DECLARE_REG(u32, flags, ctxt, 2);
+ struct arm_smccc_1_2_regs *args;
+
+ if (FIELD_GET(FFA_NOTIF_RECEIVER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ if (flags & GENMASK(31, 4)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -1009,6 +1029,9 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_SET:
do_ffa_notif_set(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_GET:
+ do_ffa_notif_get(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 6/7] KVM: arm64: Support FFA_NOTIFICATION_INFO_GET in host handler
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
` (4 preceding siblings ...)
2026-06-26 7:45 ` [PATCH v6 5/7] KVM: arm64: Support FFA_NOTIFICATION_GET " Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 7:45 ` [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy Sebastian Ene
6 siblings, 0 replies; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Allow the host to send FF-A notification queries to Trustzone and proxy
these messages from pKVM.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index c22fe4514741..712811e89435 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -678,8 +678,6 @@ static bool ffa_call_supported(u64 func_id)
case FFA_RXTX_MAP:
case FFA_MEM_DONATE:
case FFA_MEM_RETRIEVE_REQ:
- /* Optional notification interfaces added in FF-A 1.1 */
- case FFA_NOTIFICATION_INFO_GET:
/* Optional interfaces added in FF-A 1.2 */
case FFA_MSG_SEND_DIRECT_REQ2: /* Optional per 7.5.1 */
case FFA_MSG_SEND_DIRECT_RESP2: /* Optional per 7.5.1 */
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy
2026-06-26 7:45 [PATCH v6 0/7] KVM: arm64: Forward FFA_NOTIFICATION* calls to TrustZone Sebastian Ene
` (5 preceding siblings ...)
2026-06-26 7:45 ` [PATCH v6 6/7] KVM: arm64: Support FFA_NOTIFICATION_INFO_GET " Sebastian Ene
@ 2026-06-26 7:45 ` Sebastian Ene
2026-06-26 9:11 ` Will Deacon
6 siblings, 1 reply; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 7:45 UTC (permalink / raw)
To: catalin.marinas, maz, oupton, will
Cc: joey.gouly, korneld, kvmarm, linux-arm-kernel, linux-kernel,
android-kvm, mrigendra.chaubey, perlarsen, sebastianene,
suzuki.poulose, vdonnefort, yuzenghui
Introduce a helper method ffa_check_unused_args_sbz to enforce strict
arguments checking when the hypervisor acts as a relayer between the
host and Trustzone.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
---
arch/arm64/kvm/hyp/nvhe/ffa.c | 96 ++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 712811e89435..bd50ddc5b61c 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -74,6 +74,21 @@ static u32 hyp_ffa_version;
static bool has_version_negotiated;
static hyp_spinlock_t version_lock;
+static bool ffa_check_unused_args_sbz(struct kvm_cpu_context *ctxt, int first_reg)
+{
+ DECLARE_REG(u32, func_id, ctxt, 0);
+ int reg, end_reg = 7;
+
+ if (FFA_MINOR_VERSION(hyp_ffa_version) >= 2)
+ end_reg = ARM_SMCCC_IS_64(func_id) ? 17 : 7;
+ for (reg = first_reg; reg <= end_reg; reg++) {
+ if (cpu_reg(ctxt, reg))
+ return true;
+ }
+
+ return false;
+}
+
static void ffa_to_smccc_error(struct arm_smccc_1_2_regs *res, u64 ffa_errno)
{
*res = (struct arm_smccc_1_2_regs) {
@@ -242,6 +257,11 @@ static void do_ffa_rxtx_map(struct arm_smccc_1_2_regs *res,
int ret = 0;
void *rx_virt, *tx_virt;
+ if (ffa_check_unused_args_sbz(ctxt, 4)) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out;
+ }
+
if (npages != (KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) / FFA_PAGE_SIZE) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out;
@@ -318,6 +338,11 @@ static void do_ffa_rxtx_unmap(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, id, ctxt, 1);
int ret = 0;
+ if (ffa_check_unused_args_sbz(ctxt, 2)) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out;
+ }
+
if (id != HOST_FFA_ID) {
ret = FFA_RET_INVALID_PARAMETERS;
goto out;
@@ -424,6 +449,11 @@ static void do_ffa_mem_frag_tx(struct arm_smccc_1_2_regs *res,
int ret = FFA_RET_INVALID_PARAMETERS;
u32 nr_ranges;
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
if (fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE)
goto out;
@@ -485,6 +515,11 @@ static void __do_ffa_mem_xfer(const u64 func_id,
u32 offset, nr_ranges, checked_offset;
int ret = 0;
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ret = FFA_RET_INVALID_PARAMETERS;
+ goto out;
+ }
+
if (addr_mbz || npages_mbz || fraglen > len ||
fraglen > KVM_FFA_MBOX_NR_PAGES * PAGE_SIZE) {
ret = FFA_RET_INVALID_PARAMETERS;
@@ -584,6 +619,11 @@ static void do_ffa_mem_reclaim(struct arm_smccc_1_2_regs *res,
int ret = 0;
u64 handle;
+ if (ffa_check_unused_args_sbz(ctxt, 4)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
handle = PACK_HANDLE(handle_lo, handle_hi);
hyp_spin_lock(&host_buffers.lock);
@@ -764,6 +804,11 @@ static void do_ffa_version(struct arm_smccc_1_2_regs *res,
{
DECLARE_REG(u32, ffa_req_version, ctxt, 1);
+ if (ffa_check_unused_args_sbz(ctxt, 2)) {
+ res->a0 = FFA_RET_NOT_SUPPORTED;
+ return;
+ }
+
if (FFA_MAJOR_VERSION(ffa_req_version) != 1) {
res->a0 = FFA_RET_NOT_SUPPORTED;
return;
@@ -813,6 +858,11 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, flags, ctxt, 5);
u32 count, partition_sz, copy_sz;
+ if (ffa_check_unused_args_sbz(ctxt, 6)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
hyp_spin_lock(&host_buffers.lock);
if (!host_buffers.rx) {
ffa_to_smccc_res(res, FFA_RET_BUSY);
@@ -860,9 +910,15 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
static void do_ffa_notif_bitmap(struct arm_smccc_1_2_regs *res,
struct kvm_cpu_context *ctxt)
{
+ DECLARE_REG(u32, func_id, ctxt, 0);
DECLARE_REG(u32, vmid, ctxt, 1);
struct arm_smccc_1_2_regs *args;
+ if (ffa_check_unused_args_sbz(ctxt, func_id == FFA_NOTIFICATION_BITMAP_CREATE ? 3 : 2)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
if (vmid != HOST_FFA_ID) {
ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
return;
@@ -879,6 +935,11 @@ static void do_ffa_notif_bind(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, flags, ctxt, 2);
struct arm_smccc_1_2_regs *args;
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
if (FIELD_GET(FFA_NOTIF_RECEIVER_ENDP_MASK, endp_id) != HOST_FFA_ID) {
ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
return;
@@ -900,7 +961,7 @@ static void do_ffa_notif_unbind(struct arm_smccc_1_2_regs *res,
DECLARE_REG(u32, reserved, ctxt, 2);
struct arm_smccc_1_2_regs *args;
- if (reserved) {
+ if (ffa_check_unused_args_sbz(ctxt, 5) || reserved) {
ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
return;
}
@@ -926,6 +987,11 @@ static void do_ffa_notif_set(struct arm_smccc_1_2_regs *res,
return;
}
+ if (ffa_check_unused_args_sbz(ctxt, 5)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
if (flags & GENMASK(15, 2)) {
ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
return;
@@ -947,6 +1013,11 @@ static void do_ffa_notif_get(struct arm_smccc_1_2_regs *res,
return;
}
+ if (ffa_check_unused_args_sbz(ctxt, 3)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
if (flags & GENMASK(31, 4)) {
ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
return;
@@ -956,6 +1027,20 @@ static void do_ffa_notif_get(struct arm_smccc_1_2_regs *res,
hyp_smccc_1_2_smc(args, res);
}
+static void do_ffa_notif_info_get(struct arm_smccc_1_2_regs *res,
+ struct kvm_cpu_context *ctxt)
+{
+ struct arm_smccc_1_2_regs *args;
+
+ if (ffa_check_unused_args_sbz(ctxt, 1)) {
+ ffa_to_smccc_res(res, FFA_RET_INVALID_PARAMETERS);
+ return;
+ }
+
+ args = (void *)&ctxt->regs.regs[0];
+ hyp_smccc_1_2_smc(args, res);
+}
+
bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
{
struct arm_smccc_1_2_regs res;
@@ -984,6 +1069,11 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
switch (func_id) {
case FFA_FEATURES:
+ if (ffa_check_unused_args_sbz(host_ctxt, 3)) {
+ ffa_to_smccc_res(&res, FFA_RET_INVALID_PARAMETERS);
+ goto out_handled;
+ }
+
if (!do_ffa_features(&res, host_ctxt))
return false;
goto out_handled;
@@ -1030,6 +1120,10 @@ bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
case FFA_NOTIFICATION_GET:
do_ffa_notif_get(&res, host_ctxt);
goto out_handled;
+ case FFA_NOTIFICATION_INFO_GET:
+ case FFA_FN64_NOTIFICATION_INFO_GET:
+ do_ffa_notif_info_get(&res, host_ctxt);
+ goto out_handled;
}
if (ffa_call_supported(func_id))
--
2.55.0.rc0.799.gd6f94ed593-goog
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy
2026-06-26 7:45 ` [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy Sebastian Ene
@ 2026-06-26 9:11 ` Will Deacon
2026-06-26 9:24 ` Sebastian Ene
0 siblings, 1 reply; 11+ messages in thread
From: Will Deacon @ 2026-06-26 9:11 UTC (permalink / raw)
To: Sebastian Ene
Cc: catalin.marinas, maz, oupton, joey.gouly, korneld, kvmarm,
linux-arm-kernel, linux-kernel, android-kvm, mrigendra.chaubey,
perlarsen, suzuki.poulose, vdonnefort, yuzenghui
On Fri, Jun 26, 2026 at 07:45:45AM +0000, Sebastian Ene wrote:
> Introduce a helper method ffa_check_unused_args_sbz to enforce strict
> arguments checking when the hypervisor acts as a relayer between the
> host and Trustzone.
>
> Signed-off-by: Sebastian Ene <sebastianene@google.com>
> Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> ---
> arch/arm64/kvm/hyp/nvhe/ffa.c | 96 ++++++++++++++++++++++++++++++++++-
> 1 file changed, 95 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> index 712811e89435..bd50ddc5b61c 100644
> --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> @@ -74,6 +74,21 @@ static u32 hyp_ffa_version;
> static bool has_version_negotiated;
> static hyp_spinlock_t version_lock;
>
> +static bool ffa_check_unused_args_sbz(struct kvm_cpu_context *ctxt, int first_reg)
> +{
> + DECLARE_REG(u32, func_id, ctxt, 0);
> + int reg, end_reg = 7;
> +
> + if (FFA_MINOR_VERSION(hyp_ffa_version) >= 2)
> + end_reg = ARM_SMCCC_IS_64(func_id) ? 17 : 7;
This looks like an accident waiting to happen if we don't check the major
number as well.
I think you should just check:
if (hyp_ffa_version >= FFA_VERSION_1_2)
instead.
You should also add a comment.
Will
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy
2026-06-26 9:11 ` Will Deacon
@ 2026-06-26 9:24 ` Sebastian Ene
2026-06-26 10:55 ` Will Deacon
0 siblings, 1 reply; 11+ messages in thread
From: Sebastian Ene @ 2026-06-26 9:24 UTC (permalink / raw)
To: Will Deacon
Cc: catalin.marinas, maz, oupton, joey.gouly, korneld, kvmarm,
linux-arm-kernel, linux-kernel, android-kvm, mrigendra.chaubey,
perlarsen, suzuki.poulose, vdonnefort, yuzenghui
On Fri, Jun 26, 2026 at 10:11:14AM +0100, Will Deacon wrote:
> On Fri, Jun 26, 2026 at 07:45:45AM +0000, Sebastian Ene wrote:
> > Introduce a helper method ffa_check_unused_args_sbz to enforce strict
> > arguments checking when the hypervisor acts as a relayer between the
> > host and Trustzone.
> >
> > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> > Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> > ---
> > arch/arm64/kvm/hyp/nvhe/ffa.c | 96 ++++++++++++++++++++++++++++++++++-
> > 1 file changed, 95 insertions(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > index 712811e89435..bd50ddc5b61c 100644
> > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > @@ -74,6 +74,21 @@ static u32 hyp_ffa_version;
> > static bool has_version_negotiated;
> > static hyp_spinlock_t version_lock;
> >
> > +static bool ffa_check_unused_args_sbz(struct kvm_cpu_context *ctxt, int first_reg)
> > +{
> > + DECLARE_REG(u32, func_id, ctxt, 0);
> > + int reg, end_reg = 7;
> > +
> > + if (FFA_MINOR_VERSION(hyp_ffa_version) >= 2)
> > + end_reg = ARM_SMCCC_IS_64(func_id) ? 17 : 7;
>
> This looks like an accident waiting to happen if we don't check the major
> number as well.
>
> I think you should just check:
>
> if (hyp_ffa_version >= FFA_VERSION_1_2)
>
> instead.
>
> You should also add a comment.
We restrict hyp_ffa_version major to 1.0 here
https://elixir.bootlin.com/linux/v7.1.1/source/arch/arm64/kvm/hyp/nvhe/ffa.c#L962
but since this is an easy fix I will include it.
>
> Will
Sebastian
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH v6 7/7] KVM: arm64: Enforce strict SBZ checks in the FF-A proxy
2026-06-26 9:24 ` Sebastian Ene
@ 2026-06-26 10:55 ` Will Deacon
0 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2026-06-26 10:55 UTC (permalink / raw)
To: Sebastian Ene
Cc: catalin.marinas, maz, oupton, joey.gouly, korneld, kvmarm,
linux-arm-kernel, linux-kernel, android-kvm, mrigendra.chaubey,
perlarsen, suzuki.poulose, vdonnefort, yuzenghui
On Fri, Jun 26, 2026 at 09:24:52AM +0000, Sebastian Ene wrote:
> On Fri, Jun 26, 2026 at 10:11:14AM +0100, Will Deacon wrote:
> > On Fri, Jun 26, 2026 at 07:45:45AM +0000, Sebastian Ene wrote:
> > > Introduce a helper method ffa_check_unused_args_sbz to enforce strict
> > > arguments checking when the hypervisor acts as a relayer between the
> > > host and Trustzone.
> > >
> > > Signed-off-by: Sebastian Ene <sebastianene@google.com>
> > > Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
> > > ---
> > > arch/arm64/kvm/hyp/nvhe/ffa.c | 96 ++++++++++++++++++++++++++++++++++-
> > > 1 file changed, 95 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > index 712811e89435..bd50ddc5b61c 100644
> > > --- a/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > +++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
> > > @@ -74,6 +74,21 @@ static u32 hyp_ffa_version;
> > > static bool has_version_negotiated;
> > > static hyp_spinlock_t version_lock;
> > >
> > > +static bool ffa_check_unused_args_sbz(struct kvm_cpu_context *ctxt, int first_reg)
> > > +{
> > > + DECLARE_REG(u32, func_id, ctxt, 0);
> > > + int reg, end_reg = 7;
> > > +
> > > + if (FFA_MINOR_VERSION(hyp_ffa_version) >= 2)
> > > + end_reg = ARM_SMCCC_IS_64(func_id) ? 17 : 7;
> >
> > This looks like an accident waiting to happen if we don't check the major
> > number as well.
> >
> > I think you should just check:
> >
> > if (hyp_ffa_version >= FFA_VERSION_1_2)
> >
> > instead.
> >
> > You should also add a comment.
>
> We restrict hyp_ffa_version major to 1.0 here
> https://elixir.bootlin.com/linux/v7.1.1/source/arch/arm64/kvm/hyp/nvhe/ffa.c#L962
> but since this is an easy fix I will include it.
Thanks, Seb. I'm just certain that if/when we update that check, we'll
forget to update this bit at the same time (I know I would!). So doing
it now is the simplest thing.
With that change:
Acked-by: Will Deacon <will@kernel.org>
Will
^ permalink raw reply [flat|nested] 11+ messages in thread