arm/timer: non-synchronised timer ticks
When reading from Armv8 system registers, like the physical counter of the Arm Generic Timer, the access sometimes need to be synchronised.
The current implementation does not include the necessary synchronisation https://github.com/au-ts/sddf/blob/ba00f2cf31ef5df47b56f298515af3fb4a455640/drivers/timer/arm/timer.c#L44-L49, which could result in incorrect value being read, as noted by this KVM commit.
We should add a isb barrier before the read as in the KVM commit. Linux also does this for general Armv8 processors (that does not support FEAT_ECV for self-synchronised counter).
A further question is whether additional synchronisations are required, e.g. a control dependency or a dsb to order the isb after instructions before the isb in the program order, or some barriers after the system register read.
I initially tried doing this on the MaaXBoard by replacing the peripheral timer with the ARM timer (I had to change the kernel flags to the Microkit build to do this though since by default it's not exported to user-level).
Adding the barriers did not seem to fix it, it seems like the timer driver never gets an interrupt. I haven't looked into this issue much so maybe it's just some of the driver code that's wrong that QEMU ignores.
Interestingly, the kernel when using the ARM timer only uses isb in certain cases. I wonder if it is wrong or due to the other isbs in other parts of kernel interrupt handling/kernel code it happens to never cause issues?
I suppose adding such a barrier has little effect on guaranteeing interrupt delivery.
Interestingly, the kernel when using the ARM timer only uses isb in certain cases.
Could you provide some examples? The kernel uses isb in all cases in this file.
Sorry, was referring to seL4.
Oh sorry. Without using the isb barrier, the timer tick value returned might be off by at most hundreds of cycles on existing hardware (I guess, based on the size of the re-order buffer); whether this is a practical concern is another story.
Q: How much hardware has self-synchronised counters? (The FEAT_ECV)
Is it common? Not? At what point did ARM introduce it in their cores?
Q: How much hardware has self-synchronised counters? (The FEAT_ECV)
Is it common? Not? At what point did ARM introduce it in their cores?
Doesn't seem to be common, at least not with the hardware we deal with:
FEAT_ECV is OPTIONAL from Armv8.5.
FEAT_ECV is mandatory from Armv8.6.
A2.2.7 from the ARMv8-A manual (version L.b)
FEAT_ECV is mandatory from Armv8.6.
Which implies Cortex-A520 or later. A520 was launched in 2023.