@@ -339,8 +339,16 @@ void kvm_timer_unschedule(struct kvm_vcpu *vcpu)
static void set_cntvoff(u64 cntvoff)
{
- u32 low = cntvoff & GENMASK(31, 0);
- u32 high = (cntvoff >> 32) & GENMASK(31, 0);
+ u32 low = lower_32_bits(cntvoff);
+ u32 high = upper_32_bits(cntvoff);
+
+ /*
+ * Since kvm_call_hyp doesn't fully support the ARM PCS especially on
+ * 32-bit systems, but rather passes register by register shifted one
+ * place (we put the function address in r0/x0), we cannot simply pass
+ * a 64-bit value as an argument, but have to split the value in two
+ * 32-bit halves.
+ */
kvm_call_hyp(__kvm_timer_set_cntvoff, low, high);
}