Commit 47855fce76 for ffmpeg
commit 47855fce760b474e75e6fae232c4806129382fa8
Author: Martin Storsjö <martin@martin.st>
Date: Wed Sep 30 09:46:33 2026 +0300
arm, aarch64: Don't use the ccnt / pmccntr_el0 registers for READ_TIME
These registers aren't universally readable - on Linux, they are
inaccessible from user space by default, unless they have been
unlocked (e.g. with a custom kernel module). Attempting to read them
triggers an illegal instruction.
This doesn't make any difference for checkasm, which uses its own
definitions of timers. Checkasm dynamically tests which timers are
accessible and picks the best one that is usable.
This avoids surprises if READ_TIME is used outside of a benchmarking
context. (av_get_random_seed() has got a final fallback through
get_generic_seed(), which uses READ_TIME.)
The recently added test fate-softfloat also contains START_TIMER /
STOP_TIMER, which uses READ_TIME. This would cause the fate-softfloat
test to fail on Linux on arm or aarch64, if built with
--disable-linux-perf.
The default on Linux is to try to detect perf by default. In these
cases, the test doesn't trigger the illegal instruction, even
if the START_TIMER / STOP_TIMER benchmarking fails if perf isn't
accessible to the current user.
On Windows, these registers actually are documented to always be
readable from user space. However, if Windows binaries are run in
Wine on Linux, and the register hasn't been unlocked for user space,
then we hit the illegal instruction.
Thus: This fixes illegal instructions in the fate-softfloat test
in some build configurations, and avoids potential issues if any
other code ends up calling READ_TIME.
diff --git a/libavutil/aarch64/timer.h b/libavutil/aarch64/timer.h
index 922b0c5598..a11fa8f8c7 100644
--- a/libavutil/aarch64/timer.h
+++ b/libavutil/aarch64/timer.h
@@ -33,16 +33,9 @@ static inline uint64_t read_time(void)
uint64_t cycle_counter;
__asm__ volatile(
"isb \t\n"
-#if defined(__ANDROID__) || defined(__APPLE__)
// cntvct_el0 has lower resolution than pmccntr_el0, but is usually
// accessible from user space by default.
"mrs %0, cntvct_el0 "
-#else
- // pmccntr_el0 has higher resolution, but is usually not accessible
- // from user space by default (but access can be enabled with a custom
- // kernel module).
- "mrs %0, pmccntr_el0 "
-#endif
: "=r"(cycle_counter) :: "memory" );
return cycle_counter;
diff --git a/libavutil/arm/timer.h b/libavutil/arm/timer.h
index 08e4095d84..89d825eeb7 100644
--- a/libavutil/arm/timer.h
+++ b/libavutil/arm/timer.h
@@ -30,17 +30,6 @@
#define AV_READ_TIME mach_absolute_time
-#elif HAVE_INLINE_ASM && defined(__ARM_ARCH_7A__) && !defined(__ANDROID__)
-
-#define AV_READ_TIME read_time
-
-static inline uint64_t read_time(void)
-{
- unsigned cc;
- __asm__ volatile ("mrc p15, 0, %0, c9, c13, 0" : "=r"(cc));
- return cc;
-}
-
-#endif /* HAVE_INLINE_ASM && __ARM_ARCH_7A__ */
+#endif /* __APPLE__ */
#endif /* AVUTIL_ARM_TIMER_H */