linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] KVM: arm64: Fix error checking for FFA_VERSION
@ 2025-11-14 11:11 Kornel Dulęba
  2025-11-22 11:36 ` Marc Zyngier
  0 siblings, 1 reply; 5+ messages in thread
From: Kornel Dulęba @ 2025-11-14 11:11 UTC (permalink / raw)
  To: Marc Zyngier, Oliver Upton, Joey Gouly, Suzuki K Poulose,
	Zenghui Yu, Catalin Marinas, Will Deacon
  Cc: Bartlomiej Grzesik, Tomasz Nowicki, Sebastian Ene,
	linux-arm-kernel, kvmarm, linux-kernel, Kornel Dulęba

According to section 13.2 of the DEN0077 FF-A specification, when
firmware does not support the requested version, it should reply with
FFA_RET_NOT_SUPPORTED(-1). Table 13.6 specifies the type of the error
code as int32.
Currently, the error checking logic compares the unsigned long return
value it got from the SMC layer, against a "-1" literal. This fails due
to a type mismatch: the literal is extended to 64 bits, whereas the
register contains only 32 bits of ones(0x00000000ffffffff).
Consequently, hyp_ffa_init misinterprets the "-1" return value as an
invalid FF-A version. This prevents pKVM initialization on devices where
FF-A is not supported in firmware.
Fix this by explicitly casting res.a0 to s32.

Signed-off-by: Kornel Dulęba <korneld@google.com>
---
 arch/arm64/kvm/hyp/nvhe/ffa.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/ffa.c b/arch/arm64/kvm/hyp/nvhe/ffa.c
index 58b7d0c477d7fce235fc70d089d175c7879861b5..ab1e53bd4ceeea431fc30a875482ed1523b01ab5 100644
--- a/arch/arm64/kvm/hyp/nvhe/ffa.c
+++ b/arch/arm64/kvm/hyp/nvhe/ffa.c
@@ -792,7 +792,7 @@ static void do_ffa_version(struct arm_smccc_1_2_regs *res,
 			.a0 = FFA_VERSION,
 			.a1 = ffa_req_version,
 		}, res);
-		if (res->a0 == FFA_RET_NOT_SUPPORTED)
+		if ((s32)res->a0 == FFA_RET_NOT_SUPPORTED)
 			goto unlock;
 
 		hyp_ffa_version = ffa_req_version;
@@ -943,7 +943,7 @@ int hyp_ffa_init(void *pages)
 		.a0 = FFA_VERSION,
 		.a1 = FFA_VERSION_1_2,
 	}, &res);
-	if (res.a0 == FFA_RET_NOT_SUPPORTED)
+	if ((s32)res.a0 == FFA_RET_NOT_SUPPORTED)
 		return 0;
 
 	/*

---
base-commit: 6fa9041b7177f6771817b95e83f6df17b147c8c6
change-id: 20251114-pkvm_init_noffa-ac880547e727

Best regards,
-- 
Kornel Dulęba <korneld@google.com>



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: arm64: Fix error checking for FFA_VERSION
  2025-11-14 11:11 [PATCH] KVM: arm64: Fix error checking for FFA_VERSION Kornel Dulęba
@ 2025-11-22 11:36 ` Marc Zyngier
  2025-11-24 11:49   ` Kornel Dulęba
  0 siblings, 1 reply; 5+ messages in thread
From: Marc Zyngier @ 2025-11-22 11:36 UTC (permalink / raw)
  To: Kornel Dulęba
  Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Bartlomiej Grzesik, Tomasz Nowicki,
	Sebastian Ene, linux-arm-kernel, kvmarm, linux-kernel

On Fri, 14 Nov 2025 11:11:53 +0000,
"=?utf-8?q?Kornel_Dul=C4=99ba?=" <korneld@google.com> wrote:
> 
> According to section 13.2 of the DEN0077 FF-A specification, when
> firmware does not support the requested version, it should reply with
> FFA_RET_NOT_SUPPORTED(-1). Table 13.6 specifies the type of the error
> code as int32.
> Currently, the error checking logic compares the unsigned long return
> value it got from the SMC layer, against a "-1" literal. This fails due
> to a type mismatch: the literal is extended to 64 bits, whereas the
> register contains only 32 bits of ones(0x00000000ffffffff).
> Consequently, hyp_ffa_init misinterprets the "-1" return value as an
> invalid FF-A version. This prevents pKVM initialization on devices where
> FF-A is not supported in firmware.

Is this statement accurate? I regularly boot KVM in protected mode in
environments that really cannot be suspected of implementing FF-A
(there is no EL3 to start with). And yet I don't see any failure of
the sort.

Please clarify the circumstances this is triggered.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: arm64: Fix error checking for FFA_VERSION
  2025-11-22 11:36 ` Marc Zyngier
@ 2025-11-24 11:49   ` Kornel Dulęba
  2025-11-24 13:22     ` Marc Zyngier
  0 siblings, 1 reply; 5+ messages in thread
From: Kornel Dulęba @ 2025-11-24 11:49 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Bartlomiej Grzesik, Tomasz Nowicki,
	Sebastian Ene, linux-arm-kernel, kvmarm, linux-kernel

On Sat, Nov 22, 2025 at 12:36 PM Marc Zyngier <maz@kernel.org> wrote:
>
> On Fri, 14 Nov 2025 11:11:53 +0000,
> "=?utf-8?q?Kornel_Dul=C4=99ba?=" <korneld@google.com> wrote:
> >
> > According to section 13.2 of the DEN0077 FF-A specification, when
> > firmware does not support the requested version, it should reply with
> > FFA_RET_NOT_SUPPORTED(-1). Table 13.6 specifies the type of the error
> > code as int32.
> > Currently, the error checking logic compares the unsigned long return
> > value it got from the SMC layer, against a "-1" literal. This fails due
> > to a type mismatch: the literal is extended to 64 bits, whereas the
> > register contains only 32 bits of ones(0x00000000ffffffff).
> > Consequently, hyp_ffa_init misinterprets the "-1" return value as an
> > invalid FF-A version. This prevents pKVM initialization on devices where
> > FF-A is not supported in firmware.
>
> Is this statement accurate? I regularly boot KVM in protected mode in
> environments that really cannot be suspected of implementing FF-A
> (there is no EL3 to start with). And yet I don't see any failure of
> the sort.
>
> Please clarify the circumstances this is triggered.

I do have EL3 enabled, but the FF-A itself is not implemented.

Without this change kvm initialization fails with the following:

[    0.946776][    T1] kvm [1]: nv: 554 coarse grained trap handlers
[    0.952880][    T1] kvm [1]: nv: 669 fine grained trap handlers
[    0.958813][    T1] kvm [1]: IPA Size Limit: 44 bits
(...)
[    1.034089][    T1] kvm [1]: Failed to init hyp memory protection
[    1.041213][    T1] kvm [1]: error initializing Hyp mode: -95

I managed to narrow this down to the FFA version check by examining
all of the places in kvm initialization logic where -EOPNOTSUPP is
returned. Since printing anything in this part of the code is somewhat
problematic I replaced “return -EOPNOTSUPP” with “return res.s0” to
examine the problematic register value:

[1.041229][    T1] kvm [1]: error initializing Hyp mode: -1

Note that the return code itself is cast to int before being printed.
Then a colleague of mine recommended looking into the arm_ffa driver.
(“drivers/firmware/arm_ffa/driver.c”) There I found that in the
ffa_version_check function, the return value from the SMC call is cast
to s32 before being checked for errors.
I did the same in the kvm initialization logic, which is how this
patch was created. Furthermore I also examined the FF-A
specification(DEN0077), where the error code value type is specified
as int32.
With this change applied I can now see that kvm is up and running:

[    0.946839][    T1] kvm [1]: nv: 554 coarse grained trap handlers
[    0.952940][    T1] kvm [1]: nv: 669 fine grained trap handlers
[    0.958867][    T1] kvm [1]: IPA Size Limit: 44 bits
(...)
[    1.061717][    T1] kvm [1]: Protected hVHE mode initialized successfully

The /dev/kvm file is also there.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: arm64: Fix error checking for FFA_VERSION
  2025-11-24 11:49   ` Kornel Dulęba
@ 2025-11-24 13:22     ` Marc Zyngier
  2025-11-25 13:54       ` Kornel Dulęba
  0 siblings, 1 reply; 5+ messages in thread
From: Marc Zyngier @ 2025-11-24 13:22 UTC (permalink / raw)
  To: Kornel Dulęba
  Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Bartlomiej Grzesik, Tomasz Nowicki,
	Sebastian Ene, linux-arm-kernel, kvmarm, linux-kernel

On Mon, 24 Nov 2025 11:49:08 +0000,
Kornel Dulęba <korneld@google.com> wrote:
> 
> On Sat, Nov 22, 2025 at 12:36 PM Marc Zyngier <maz@kernel.org> wrote:
> >
> > On Fri, 14 Nov 2025 11:11:53 +0000,
> > "=?utf-8?q?Kornel_Dul=C4=99ba?=" <korneld@google.com> wrote:
> > >
> > > According to section 13.2 of the DEN0077 FF-A specification, when
> > > firmware does not support the requested version, it should reply with
> > > FFA_RET_NOT_SUPPORTED(-1). Table 13.6 specifies the type of the error
> > > code as int32.
> > > Currently, the error checking logic compares the unsigned long return
> > > value it got from the SMC layer, against a "-1" literal. This fails due
> > > to a type mismatch: the literal is extended to 64 bits, whereas the
> > > register contains only 32 bits of ones(0x00000000ffffffff).
> > > Consequently, hyp_ffa_init misinterprets the "-1" return value as an
> > > invalid FF-A version. This prevents pKVM initialization on devices where
> > > FF-A is not supported in firmware.
> >
> > Is this statement accurate? I regularly boot KVM in protected mode in
> > environments that really cannot be suspected of implementing FF-A
> > (there is no EL3 to start with). And yet I don't see any failure of
> > the sort.
> >
> > Please clarify the circumstances this is triggered.
> 
> I do have EL3 enabled, but the FF-A itself is not implemented.
> 
> Without this change kvm initialization fails with the following:
> 
> [    0.946776][    T1] kvm [1]: nv: 554 coarse grained trap handlers
> [    0.952880][    T1] kvm [1]: nv: 669 fine grained trap handlers
> [    0.958813][    T1] kvm [1]: IPA Size Limit: 44 bits
> (...)
> [    1.034089][    T1] kvm [1]: Failed to init hyp memory protection
> [    1.041213][    T1] kvm [1]: error initializing Hyp mode: -95

[    0.045492] kvm [1]: nv: 568 coarse grained trap handlers
[    0.045860] kvm [1]: nv: 664 fine grained trap handlers
[    0.046194] kvm [1]: IPA Size Limit: 42 bits
[    0.220184] kvm [1]: GICv3: no GICV resource entry
[    0.220525] kvm [1]: disabling GICv2 emulation
[    0.220852] kvm [1]: GIC system register CPU interface enabled
[    0.221264] kvm [1]: vgic interrupt IRQ9
[    0.221565] kvm [1]: Protected hVHE mode initialized successfully

Ergo, it works here without FFA (this is in a nested guest that is not
exposed anything but PSCI in the FW emulation).

> I managed to narrow this down to the FFA version check by examining
> all of the places in kvm initialization logic where -EOPNOTSUPP is
> returned. Since printing anything in this part of the code is somewhat
> problematic I replaced “return -EOPNOTSUPP” with “return res.s0” to
> examine the problematic register value:
> 
> [1.041229][    T1] kvm [1]: error initializing Hyp mode: -1
> 
> Note that the return code itself is cast to int before being printed.
> Then a colleague of mine recommended looking into the arm_ffa driver.
> (“drivers/firmware/arm_ffa/driver.c”) There I found that in the
> ffa_version_check function, the return value from the SMC call is cast
> to s32 before being checked for errors.
> I did the same in the kvm initialization logic, which is how this
> patch was created. Furthermore I also examined the FF-A
> specification(DEN0077), where the error code value type is specified
> as int32.
> With this change applied I can now see that kvm is up and running:
> 
> [    0.946839][    T1] kvm [1]: nv: 554 coarse grained trap handlers
> [    0.952940][    T1] kvm [1]: nv: 669 fine grained trap handlers
> [    0.958867][    T1] kvm [1]: IPA Size Limit: 44 bits
> (...)
> [    1.061717][    T1] kvm [1]: Protected hVHE mode initialized successfully
> 
> The /dev/kvm file is also there.

I don't dispute the bug. I dispute the assertion that the absence of
FFA triggers it. So either your testing environment influences the
behaviour, or you have extra patches that also change the behaviour,
or something else.

Thanks,

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] KVM: arm64: Fix error checking for FFA_VERSION
  2025-11-24 13:22     ` Marc Zyngier
@ 2025-11-25 13:54       ` Kornel Dulęba
  0 siblings, 0 replies; 5+ messages in thread
From: Kornel Dulęba @ 2025-11-25 13:54 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Oliver Upton, Joey Gouly, Suzuki K Poulose, Zenghui Yu,
	Catalin Marinas, Will Deacon, Bartlomiej Grzesik, Tomasz Nowicki,
	Sebastian Ene, linux-arm-kernel, kvmarm, linux-kernel

On Mon, Nov 24, 2025 at 2:22 PM Marc Zyngier <maz@kernel.org> wrote:
>
> On Mon, 24 Nov 2025 11:49:08 +0000,
> Kornel Dulęba <korneld@google.com> wrote:
> >
> > On Sat, Nov 22, 2025 at 12:36 PM Marc Zyngier <maz@kernel.org> wrote:
> > >
> > > On Fri, 14 Nov 2025 11:11:53 +0000,
> > > "=?utf-8?q?Kornel_Dul=C4=99ba?=" <korneld@google.com> wrote:
> > > >
> > > > According to section 13.2 of the DEN0077 FF-A specification, when
> > > > firmware does not support the requested version, it should reply with
> > > > FFA_RET_NOT_SUPPORTED(-1). Table 13.6 specifies the type of the error
> > > > code as int32.
> > > > Currently, the error checking logic compares the unsigned long return
> > > > value it got from the SMC layer, against a "-1" literal. This fails due
> > > > to a type mismatch: the literal is extended to 64 bits, whereas the
> > > > register contains only 32 bits of ones(0x00000000ffffffff).
> > > > Consequently, hyp_ffa_init misinterprets the "-1" return value as an
> > > > invalid FF-A version. This prevents pKVM initialization on devices where
> > > > FF-A is not supported in firmware.
> > >
> > > Is this statement accurate? I regularly boot KVM in protected mode in
> > > environments that really cannot be suspected of implementing FF-A
> > > (there is no EL3 to start with). And yet I don't see any failure of
> > > the sort.
> > >
> > > Please clarify the circumstances this is triggered.
> >
> > I do have EL3 enabled, but the FF-A itself is not implemented.
> >
> > Without this change kvm initialization fails with the following:
> >
> > [    0.946776][    T1] kvm [1]: nv: 554 coarse grained trap handlers
> > [    0.952880][    T1] kvm [1]: nv: 669 fine grained trap handlers
> > [    0.958813][    T1] kvm [1]: IPA Size Limit: 44 bits
> > (...)
> > [    1.034089][    T1] kvm [1]: Failed to init hyp memory protection
> > [    1.041213][    T1] kvm [1]: error initializing Hyp mode: -95
>
> [    0.045492] kvm [1]: nv: 568 coarse grained trap handlers
> [    0.045860] kvm [1]: nv: 664 fine grained trap handlers
> [    0.046194] kvm [1]: IPA Size Limit: 42 bits
> [    0.220184] kvm [1]: GICv3: no GICV resource entry
> [    0.220525] kvm [1]: disabling GICv2 emulation
> [    0.220852] kvm [1]: GIC system register CPU interface enabled
> [    0.221264] kvm [1]: vgic interrupt IRQ9
> [    0.221565] kvm [1]: Protected hVHE mode initialized successfully
>
> Ergo, it works here without FFA (this is in a nested guest that is not
> exposed anything but PSCI in the FW emulation).

I think this all boils down to how the error code is set in reply to
the FFA_VERSION SMC. In the do_ffa_version function in this file, the
return value is set with no casts: "res->a0 = FFA_RET_NOT_SUPPORTED;".
Since res->a0 is an unsigned long and `FFA_RET_NOT_SUPPORTED` is a
(-1) literal, the latter will get promoted resulting in res->a0 being
set to 0xffs.
At the same time any implementation that returns "0x00000000ffffffff"
will still be compliant with the FF-A spec, while triggering the bug
I'm trying to fix here.

>
> > I managed to narrow this down to the FFA version check by examining
> > all of the places in kvm initialization logic where -EOPNOTSUPP is
> > returned. Since printing anything in this part of the code is somewhat
> > problematic I replaced “return -EOPNOTSUPP” with “return res.s0” to
> > examine the problematic register value:
> >
> > [1.041229][    T1] kvm [1]: error initializing Hyp mode: -1
> >
> > Note that the return code itself is cast to int before being printed.
> > Then a colleague of mine recommended looking into the arm_ffa driver.
> > (“drivers/firmware/arm_ffa/driver.c”) There I found that in the
> > ffa_version_check function, the return value from the SMC call is cast
> > to s32 before being checked for errors.
> > I did the same in the kvm initialization logic, which is how this
> > patch was created. Furthermore I also examined the FF-A
> > specification(DEN0077), where the error code value type is specified
> > as int32.
> > With this change applied I can now see that kvm is up and running:
> >
> > [    0.946839][    T1] kvm [1]: nv: 554 coarse grained trap handlers
> > [    0.952940][    T1] kvm [1]: nv: 669 fine grained trap handlers
> > [    0.958867][    T1] kvm [1]: IPA Size Limit: 44 bits
> > (...)
> > [    1.061717][    T1] kvm [1]: Protected hVHE mode initialized successfully
> >
> > The /dev/kvm file is also there.
>
> I don't dispute the bug. I dispute the assertion that the absence of
> FFA triggers it. So either your testing environment influences the
> behaviour, or you have extra patches that also change the behaviour,
> or something else.

To be completely transparent I stumbled upon this using the android
fork of the kernel, but I don't think that matters here at all.
On my device all cores start in EL2, so the problematic SMC call
should go straight to the FW. I believe that the FW sets the a0
register to "0x00000000ffffffff", indicating that FF-A is not
available. This behavior is actually what the FF-A spec says should be
done, so this is not a case of broken FW.
At the same time it does trigger a bug in the error checking logic,
which I described above.


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2025-11-25 13:54 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-14 11:11 [PATCH] KVM: arm64: Fix error checking for FFA_VERSION Kornel Dulęba
2025-11-22 11:36 ` Marc Zyngier
2025-11-24 11:49   ` Kornel Dulęba
2025-11-24 13:22     ` Marc Zyngier
2025-11-25 13:54       ` Kornel Dulęba

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).