aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/utils
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-03-06 08:01:34 -0500
committerJack Lloyd <[email protected]>2018-03-06 08:01:34 -0500
commitd96477e0c2239ec7a8ef721333be1e2e70e1abef (patch)
treec95b502cdd7b31e47ef39bd08b0ea30233ee41f1 /src/lib/utils
parentd1c861c280d973990c25996ab8558e784283325b (diff)
Correctly read the POWER cycle counter
The upper register can overflow so we need to re-read the upper register to ensure we we not on a boundary. GH #1460
Diffstat (limited to 'src/lib/utils')
-rw-r--r--src/lib/utils/os_utils.cpp19
1 files changed, 11 insertions, 8 deletions
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp
index b8c31234a..769615543 100644
--- a/src/lib/utils/os_utils.cpp
+++ b/src/lib/utils/os_utils.cpp
@@ -95,16 +95,19 @@ uint64_t OS::get_processor_timestamp()
}
#elif defined(BOTAN_TARGET_ARCH_IS_PPC64)
- uint32_t rtc_low = 0, rtc_high = 0;
- asm volatile("mftbu %0; mftb %1" : "=r" (rtc_high), "=r" (rtc_low));
- /*
- qemu-ppc seems to not support mftb instr, it always returns zero.
- If both time bases are 0, assume broken and return another clock.
- */
- if(rtc_high > 0 || rtc_low > 0)
+ for(;;)
{
- rtc = (static_cast<uint64_t>(rtc_high) << 32) | rtc_low;
+ uint32_t rtc_low = 0, rtc_high = 0, rtc_high2 = 0;
+ asm volatile("mftbu %0" : "=r" (rtc_high));
+ asm volatile("mftb %0" : "=r" (rtc_low));
+ asm volatile("mftbu %0" : "=r" (rtc_high2));
+
+ if(rtc_high == rtc_high2)
+ {
+ rtc = (static_cast<uint64_t>(rtc_high) << 32) | rtc_low;
+ break;
+ }
}
#elif defined(BOTAN_TARGET_ARCH_IS_ALPHA)