[PATCH v1 1/2] KVM: arm64: Prevent 64-bit overflow when computing hyp clock rate

Vincent Donnefort vdonnefort at google.com
Thu Oct 8 03:42:11 PDT 2026


The hypervisor clock rate is delta_cycles * NSEC_PER_SEC / delta_boot.
It is computed whenever a deviation occurs. If the delta between two
rate updates is big enough, delta_cycles * NSEC_PER_SEC will overflow.

Prevent overflow with mul_u64_u64_div_u64(). And as a bonus, simplify
the clock estimation with mul_u64_u32_shr().

Fixes: b22888917fa4 ("KVM: arm64: Sync boot clock with the nVHE/pKVM hyp")
Cc: stable at vger.kernel.org
Signed-off-by: Vincent Donnefort <vdonnefort at google.com>
---
 arch/arm64/kvm/hyp_trace.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index 9241d5a325fb..26fc13c16458 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -60,14 +60,8 @@ static void __hyp_clock_work(struct work_struct *work)
 	if (hyp_clock->mult) {
 		u64 err, cur = delta_cycles;
 
-		if (WARN_ON_ONCE(cur >= hyp_clock->cyc_overflow64)) {
-			__uint128_t tmp = (__uint128_t)cur * hyp_clock->mult;
-
-			cur = tmp >> hyp_clock->shift;
-		} else {
-			cur *= hyp_clock->mult;
-			cur >>= hyp_clock->shift;
-		}
+		WARN_ON_ONCE(cur >= hyp_clock->cyc_overflow64);
+		cur = mul_u64_u32_shr(cur, hyp_clock->mult, hyp_clock->shift);
 		cur += hyp_clock->boot;
 
 		err = abs_diff(cur, boot);
@@ -85,7 +79,7 @@ static void __hyp_clock_work(struct work_struct *work)
 					    err / NSEC_PER_USEC);
 	}
 
-	rate = div64_u64(delta_cycles * NSEC_PER_SEC, delta_boot);
+	rate = mul_u64_u64_div_u64(delta_cycles, NSEC_PER_SEC, delta_boot);
 
 	clocks_calc_mult_shift(&hyp_clock->mult, &hyp_clock->shift,
 			       rate, NSEC_PER_SEC, CLOCK_MAX_CONVERSION_S);
-- 
2.56.0.360.g66cac248cb-goog




More information about the linux-arm-kernel mailing list