Bug 1421445 - Add NOP-slide before JIT code buffers on AMD Bobcat. r=jandem a=lizzard
authorTed Campbell <tcampbell@mozilla.com>
Tue, 28 Nov 2017 17:32:04 -0500
changeset 445363 7fa49bea2cd66581660b4b8af9725a291c5f0249
parent 445362 59058a3856b731ec0fc2955b11aa3dddb7ebeee4
child 445364 377dba3f7dd64e49b0f98c3f04f66fbca659172c
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem, lizzard
bugs1421445
milestone58.0
Bug 1421445 - Add NOP-slide before JIT code buffers on AMD Bobcat. r=jandem a=lizzard In order to try and mitigate crashes on 64-bit FF 57+ on AMD Bobcat CPUs, insert NOPs before the JIT code buffers. On earlier versions of these processors, hardware bugs cause crashes to occur in locations before the JIT code stub. For simplicity, the JitCode* pointer is shifted even on machines that are unaffected. With the previous patch fixing over allocation, we end up being size-neutral. MozReview-Commit-ID: 4LqBfOzv6Qy
js/src/jit/Ion.cpp
js/src/jit/IonCode.h
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -724,16 +724,28 @@ JitRuntime::getVMWrapper(const VMFunctio
     MOZ_ASSERT(functionWrappers_);
     MOZ_ASSERT(functionWrappers_->initialized());
     JitRuntime::VMWrapperMap::Ptr p = functionWrappers_->readonlyThreadsafeLookup(&f);
     MOZ_ASSERT(p);
 
     return p->value();
 }
 
+void
+JitCodeHeader::init(JitCode* jitCode)
+{
+    jitCode_ = jitCode;
+
+#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
+    // On AMD Bobcat processors that may have eratas, insert a NOP slide to reduce crashes
+    if (CPUInfo::NeedAmdBugWorkaround())
+        memset((char *)&nops_, X86Encoding::OneByteOpcodeID::OP_NOP, sizeof(nops_));
+#endif
+}
+
 template <AllowGC allowGC>
 JitCode*
 JitCode::New(JSContext* cx, uint8_t* code, uint32_t bufferSize, uint32_t headerSize,
              ExecutablePool* pool, CodeKind kind)
 {
     JitCode* codeObj = Allocate<JitCode, allowGC>(cx);
     if (!codeObj) {
         pool->release(headerSize + bufferSize, kind);
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -35,19 +35,23 @@ typedef Vector<JSObject*, 4, JitAllocPol
 typedef Vector<TraceLoggerEvent, 0, SystemAllocPolicy> TraceLoggerEventVector;
 
 // Header at start of raw code buffer
 struct JitCodeHeader
 {
     // Link back to corresponding gcthing
     JitCode*    jitCode_;
 
-    void init(JitCode* jitCode) {
-        jitCode_ = jitCode;
-    }
+    // !!! NOTE !!!
+    // If we are running on AMD Bobcat, insert a NOP-slide at end of the JitCode
+    // header so we can try to recover when the CPU screws up the branch landing
+    // site. See Bug 1281759.
+    void*       nops_;
+
+    void init(JitCode* jitCode);
 
     static JitCodeHeader* FromExecutable(uint8_t* buffer) {
         return (JitCodeHeader*)(buffer - sizeof(JitCodeHeader));
     }
 };
 
 class JitCode : public gc::TenuredCell
 {