summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDean Michael Berris <dberris@google.com>2017-02-02 07:51:21 +0000
committerDean Michael Berris <dberris@google.com>2017-02-02 07:51:21 +0000
commitee21d1338198a9eb2b15e0b48409752e69bd7901 (patch)
treead0d848e60fb7428f709b81b9006ad2e9d6e263b
parent7cebbf504deb1a07c7f99b69d8c8fb0f8f778d43 (diff)
[XRay] Probe for CPU features that XRay needs
Summary: In llvm.org/PR31756 it's pointed out that sometimes rdtscp isn't available. We fix it here by checking first whether it's availble before installing the logging handler. In future commits we can have alternative implementations, maybe working around some of the constraints on some systems. This change enables us to make that determination, but report an error instead when the features aren't available. Reviewers: sdardis, javed.absar, rSerge Subscribers: pelikan, llvm-commits Differential Revision: https://reviews.llvm.org/D29438 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@293870 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/xray/xray_AArch64.cc3
-rw-r--r--lib/xray/xray_arm.cc3
-rw-r--r--lib/xray/xray_emulate_tsc.h5
-rw-r--r--lib/xray/xray_inmemory_log.cc5
-rw-r--r--lib/xray/xray_x86_64.cc22
-rw-r--r--lib/xray/xray_x86_64.h3
6 files changed, 38 insertions, 3 deletions
diff --git a/lib/xray/xray_AArch64.cc b/lib/xray/xray_AArch64.cc
index af06bdbf2..952a4c7eb 100644
--- a/lib/xray/xray_AArch64.cc
+++ b/lib/xray/xray_AArch64.cc
@@ -120,4 +120,7 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
return patchSled(Enable, FuncId, Sled, __xray_FunctionTailExit);
}
+// FIXME: Maybe implement this better?
+bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }
+
} // namespace __xray
diff --git a/lib/xray/xray_arm.cc b/lib/xray/xray_arm.cc
index bf36ea067..73e9b4111 100644
--- a/lib/xray/xray_arm.cc
+++ b/lib/xray/xray_arm.cc
@@ -156,4 +156,7 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
return patchSled(Enable, FuncId, Sled, __xray_FunctionTailExit);
}
+// FIXME: Maybe implement this better?
+bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT { return true; }
+
} // namespace __xray
diff --git a/lib/xray/xray_emulate_tsc.h b/lib/xray/xray_emulate_tsc.h
index a3e8b1c92..5285931dd 100644
--- a/lib/xray/xray_emulate_tsc.h
+++ b/lib/xray/xray_emulate_tsc.h
@@ -35,6 +35,9 @@ ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
CPU = 0;
return TS.tv_sec * NanosecondsPerSecond + TS.tv_nsec;
}
-}
+
+bool probeRequiredCPUFeatures();
+
+} // namespace __xray
#endif // XRAY_EMULATE_TSC_H
diff --git a/lib/xray/xray_inmemory_log.cc b/lib/xray/xray_inmemory_log.cc
index d25a61bdb..9decfc437 100644
--- a/lib/xray/xray_inmemory_log.cc
+++ b/lib/xray/xray_inmemory_log.cc
@@ -138,6 +138,11 @@ void __xray_InMemoryRawLog(int32_t FuncId,
}
static auto Unused = [] {
+ if (!probeRequiredCPUFeatures()) {
+ Report("Required CPU features missing for XRay instrumentation, not "
+ "installing instrumentation hooks.\n");
+ return false;
+ }
if (flags()->xray_naive_log)
__xray_set_handler(__xray_InMemoryRawLog);
return true;
diff --git a/lib/xray/xray_x86_64.cc b/lib/xray/xray_x86_64.cc
index 3ee91896c..25c64957c 100644
--- a/lib/xray/xray_x86_64.cc
+++ b/lib/xray/xray_x86_64.cc
@@ -1,6 +1,8 @@
+#include "cpuid.h"
#include "sanitizer_common/sanitizer_common.h"
#include "xray_defs.h"
#include "xray_interface_internal.h"
+
#include <atomic>
#include <cstdint>
#include <errno.h>
@@ -61,8 +63,8 @@ uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT {
&CPUFrequency)) {
CPUFrequency *= 1000;
} else if (readValueFromFile(
- "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
- &CPUFrequency)) {
+ "/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq",
+ &CPUFrequency)) {
CPUFrequency *= 1000;
} else {
Report("Unable to determine CPU frequency for TSC accounting.\n");
@@ -199,4 +201,20 @@ bool patchFunctionTailExit(const bool Enable, const uint32_t FuncId,
return true;
}
+// We determine whether the CPU we're running on has the correct features we
+// need. In x86_64 this will be rdtscp support.
+bool probeRequiredCPUFeatures() XRAY_NEVER_INSTRUMENT {
+ unsigned int EAX, EBX, ECX, EDX;
+
+ // We check whether rdtscp support is enabled. According to the x86_64 manual,
+ // level should be set at 0x80000001, and we should have a look at bit 27 in
+ // EDX. That's 0x8000000 (or 1u << 26).
+ __get_cpuid(0x80000001, &EAX, &EBX, &ECX, &EDX);
+ if (!(EDX & (1u << 26))) {
+ Report("Missing rdtscp support.\n");
+ return false;
+ }
+ return true;
+}
+
} // namespace __xray
diff --git a/lib/xray/xray_x86_64.h b/lib/xray/xray_x86_64.h
index e3de99d63..6b2bbebb7 100644
--- a/lib/xray/xray_x86_64.h
+++ b/lib/xray/xray_x86_64.h
@@ -27,6 +27,9 @@ ALWAYS_INLINE uint64_t readTSC(uint8_t &CPU) XRAY_NEVER_INSTRUMENT {
CPU = LongCPU;
return TSC;
}
+
+bool probeRequiredCPUFeatures();
+
} // namespace __xray
#endif // XRAY_X86_64_H