arch/arm64/include/asm/kvm_hyp.h | 2 +- arch/arm64/kvm/hyp/include/nvhe/ffa.h | 2 +- arch/arm64/kvm/hyp/nvhe/ffa.c | 2 +- arch/arm64/kvm/hyp/nvhe/psci-relay.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-)
Make the SMC handlers accept a 64bit value for the function-id to keep
it uniform with the rest of the code and prevent a u64 -> u32 -> u64
conversion as it currently happens when we handle PSCI.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
---
arch/arm64/include/asm/kvm_hyp.h | 2 +-
arch/arm64/kvm/hyp/include/nvhe/ffa.h | 2 +-
arch/arm64/kvm/hyp/nvhe/ffa.c | 2 +-
arch/arm64/kvm/hyp/nvhe/psci-relay.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h
index 76ce2b94bd97..c9976425a85c 100644
--- a/arch/arm64/include/asm/kvm_hyp.h
+++ b/arch/arm64/include/asm/kvm_hyp.h
@@ -119,7 +119,7 @@ void __sve_restore_state(void *sve_pffr, u32 *fpsr, int restore_ffr);
u64 __guest_enter(struct kvm_vcpu *vcpu);
-bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
+bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u64 func_id);
#ifdef __KVM_NVHE_HYPERVISOR__
void __noreturn __hyp_do_panic(struct kvm_cpu_context *host_ctxt, u64 spsr,
diff --git a/arch/arm64/kvm/hyp/include/nvhe/ffa.h b/arch/arm64/kvm/hyp/include/nvhe/ffa.h
index 146e0aebfa1c..21afca11ae0b 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/ffa.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/ffa.h
@@ -12,6 +12,6 @@
#define FFA_MAX_FUNC_NUM 0xFF
int hyp_ffa_init(void *pages);
-bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id);
+bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u64 func_id);
#endif /* __KVM_HYP_FFA_H */
diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 94161ea1cd60..87e6d36f120a 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -862,7 +862,7 @@ static void do_ffa_part_get(struct arm_smccc_1_2_regs *res,
hyp_spin_unlock(&host_buffers.lock);
}
-bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
+bool kvm_host_ffa_handler(struct kvm_cpu_context *host_ctxt, u64 func_id)
{
struct arm_smccc_1_2_regs res;
diff --git a/arch/arm64/kvm/hyp/nvhe/psci-relay.c b/arch/arm64/kvm/hyp/nvhe/psci-relay.c
index c3e196fb8b18..79f390057c19 100644
--- a/arch/arm64/kvm/hyp/nvhe/psci-relay.c
+++ b/arch/arm64/kvm/hyp/nvhe/psci-relay.c
@@ -278,7 +278,7 @@ static unsigned long psci_1_0_handler(u64 func_id, struct kvm_cpu_context *host_
}
}
-bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u32 func_id)
+bool kvm_host_psci_handler(struct kvm_cpu_context *host_ctxt, u64 func_id)
{
unsigned long ret;
--
2.53.0.1185.g05d4b7b318-goog
On Wed, 01 Apr 2026 13:32:01 +0100, Sebastian Ene <sebastianene@google.com> wrote: > > Make the SMC handlers accept a 64bit value for the function-id to keep > it uniform with the rest of the code and prevent a u64 -> u32 -> u64 > conversion as it currently happens when we handle PSCI. That seems overly creative. The spec says (2.5, from ARM DEN 0028 1.6 G): "The Function Identifier is passed on W0 on every SMC and HVC call. Its 32-bit integer value indicates which function is being requested by the caller. It is always passed as the first argument to every SMC or HVC call in R0 or W0." which indicates that it is *always* a 32bit value. So if you have a 64bit value somewhere, *that* should be fixed, not propagated arbitrarily. Thanks, M. -- Without deviation from the norm, progress is not possible.
On Wed, Apr 01, 2026 at 03:55:11PM +0100, Marc Zyngier wrote: > On Wed, 01 Apr 2026 13:32:01 +0100, > Sebastian Ene <sebastianene@google.com> wrote: > > > > Make the SMC handlers accept a 64bit value for the function-id to keep > > it uniform with the rest of the code and prevent a u64 -> u32 -> u64 > > conversion as it currently happens when we handle PSCI. > > That seems overly creative. The spec says (2.5, from ARM DEN 0028 1.6 > G): I'm not plannig to be *overly creative*. Thanks for pointing out the ARM spec. > > "The Function Identifier is passed on W0 on every SMC and HVC > call. Its 32-bit integer value indicates which function is being > requested by the caller. It is always passed as the first argument to > every SMC or HVC call in R0 or W0." > > which indicates that it is *always* a 32bit value. > > So if you have a 64bit value somewhere, *that* should be fixed, not > propagated arbitrarily. If you have a non SMCCC call that happen to have the first 32-bits of the function-id matching either PSCI or FF-A you will end up handling them instead of forwarding it to Trustzone because func_id is declared as: DECLARE_REG(u64, func_id, host_ctxt, 0); > > Thanks, > > M. > > -- > Without deviation from the norm, progress is not possible. Thanks, Sebastian
On Wed, 01 Apr 2026 18:21:58 +0100,
Sebastian Ene <sebastianene@google.com> wrote:
>
> On Wed, Apr 01, 2026 at 03:55:11PM +0100, Marc Zyngier wrote:
> > On Wed, 01 Apr 2026 13:32:01 +0100,
> > Sebastian Ene <sebastianene@google.com> wrote:
> > >
> > > Make the SMC handlers accept a 64bit value for the function-id to keep
> > > it uniform with the rest of the code and prevent a u64 -> u32 -> u64
> > > conversion as it currently happens when we handle PSCI.
> >
> > That seems overly creative. The spec says (2.5, from ARM DEN 0028 1.6
> > G):
>
> I'm not plannig to be *overly creative*. Thanks for pointing out the ARM
> spec.
>
> >
> > "The Function Identifier is passed on W0 on every SMC and HVC
> > call. Its 32-bit integer value indicates which function is being
> > requested by the caller. It is always passed as the first argument to
> > every SMC or HVC call in R0 or W0."
> >
> > which indicates that it is *always* a 32bit value.
> >
> > So if you have a 64bit value somewhere, *that* should be fixed, not
> > propagated arbitrarily.
>
> If you have a non SMCCC call that happen to have the first 32-bits of
> the function-id matching either PSCI or FF-A you will end up handling
> them instead of forwarding it to Trustzone because func_id is declared as:
>
> DECLARE_REG(u64, func_id, host_ctxt, 0);
Again, the correct approach to prevent the propagation of something
that is known to be wrong. Something like this:
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 007fc993f2319..dae993a1d081b 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -694,6 +694,11 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
DECLARE_REG(u64, func_id, host_ctxt, 0);
bool handled;
+ if (upper_32_bits(func_id)) {
+ cpu_reg(host_ctxt, 0) = SMCCC_RET_NOT_SUPPORTED;
+ kvm_skip_host_instr();
+ }
+
func_id &= ~ARM_SMCCC_CALL_HINTS;
handled = kvm_host_psci_handler(host_ctxt, func_id);
Because forwarding something that is blatantly illegal to the secure
side is not something we should accept at all (just like we now refuse
non-zero SMC immediate values).
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
On Wed, 01 Apr 2026 19:28:28 +0100,
Marc Zyngier <maz@kernel.org> wrote:
>
> On Wed, 01 Apr 2026 18:21:58 +0100,
> Sebastian Ene <sebastianene@google.com> wrote:
> >
> > On Wed, Apr 01, 2026 at 03:55:11PM +0100, Marc Zyngier wrote:
> > > On Wed, 01 Apr 2026 13:32:01 +0100,
> > > Sebastian Ene <sebastianene@google.com> wrote:
> > > >
> > > > Make the SMC handlers accept a 64bit value for the function-id to keep
> > > > it uniform with the rest of the code and prevent a u64 -> u32 -> u64
> > > > conversion as it currently happens when we handle PSCI.
> > >
> > > That seems overly creative. The spec says (2.5, from ARM DEN 0028 1.6
> > > G):
> >
> > I'm not plannig to be *overly creative*. Thanks for pointing out the ARM
> > spec.
> >
> > >
> > > "The Function Identifier is passed on W0 on every SMC and HVC
> > > call. Its 32-bit integer value indicates which function is being
> > > requested by the caller. It is always passed as the first argument to
> > > every SMC or HVC call in R0 or W0."
> > >
> > > which indicates that it is *always* a 32bit value.
> > >
> > > So if you have a 64bit value somewhere, *that* should be fixed, not
> > > propagated arbitrarily.
> >
> > If you have a non SMCCC call that happen to have the first 32-bits of
> > the function-id matching either PSCI or FF-A you will end up handling
> > them instead of forwarding it to Trustzone because func_id is declared as:
> >
> > DECLARE_REG(u64, func_id, host_ctxt, 0);
>
> Again, the correct approach to prevent the propagation of something
> that is known to be wrong. Something like this:
>
> diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> index 007fc993f2319..dae993a1d081b 100644
> --- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> +++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
> @@ -694,6 +694,11 @@ static void handle_host_smc(struct kvm_cpu_context *host_ctxt)
> DECLARE_REG(u64, func_id, host_ctxt, 0);
> bool handled;
>
> + if (upper_32_bits(func_id)) {
> + cpu_reg(host_ctxt, 0) = SMCCC_RET_NOT_SUPPORTED;
> + kvm_skip_host_instr();
Plus the obviously missing:
+ return;
> + }
> +
M.
--
Jazz isn't dead. It just smells funny.
© 2016 - 2026 Red Hat, Inc.