[kvm-unit-tests PATCH 4/3] riscv: QEMU Sstc timer stop workaround

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



QEMU doesn't stop a pending timer when UINT64_MAX is written to
stimecmp, see QEMU commit ae0edf2188b3 ("target/riscv: No need to
re-start QEMU timer when timecmp == UINT64_MAX"). We should probably
change that in QEMU, but we need a solution in kvm-unit-tests anyway
in order to support older QEMU versions. A bit of an ugly workaround
is to simply subtract one from UINT64_MAX, which is still a really
big number, but not the exact number QEMU is using to decide it
should skip the timer update.

Signed-off-by: Andrew Jones <andrew.jones@xxxxxxxxx>
---
 lib/riscv/timer.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/lib/riscv/timer.c b/lib/riscv/timer.c
index 67fd031ab95f..28e1626607f7 100644
--- a/lib/riscv/timer.c
+++ b/lib/riscv/timer.c
@@ -62,9 +62,16 @@ void timer_start(unsigned long duration_us)
 void timer_stop(void)
 {
 	if (cpu_has_extension(smp_processor_id(), ISA_SSTC)) {
-		csr_write(CSR_STIMECMP, ULONG_MAX);
+		/*
+		 * Subtract one from ULONG_MAX to workaround QEMU using that
+		 * exact number to decide *not* to update the timer. IOW, if
+		 * we used ULONG_MAX, then we wouldn't stop the timer at all,
+		 * but one less is still a big number ("infinity") and it gets
+		 * QEMU to do what we want.
+		 */
+		csr_write(CSR_STIMECMP, ULONG_MAX - 1);
 		if (__riscv_xlen == 32)
-			csr_write(CSR_STIMECMPH, ULONG_MAX);
+			csr_write(CSR_STIMECMPH, ULONG_MAX - 1);
 	} else if (sbi_probe(SBI_EXT_TIME)) {
 		struct sbiret ret = sbi_set_timer(ULONG_MAX);
 		assert(ret.error == SBI_SUCCESS);
-- 
2.45.2





[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux