Closed Bug 1338179 Opened 4 years ago Closed 4 years ago

Disable W^X JIT code page switching when running on Valgrind on Linux/Mac

Categories

(Core :: JavaScript Engine: JIT, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla54
Tracking Status
firefox54 --- fixed

People

(Reporter: jseward, Unassigned)

Details

Attachments

(1 file)

For approximately a year (??) Spidermonkey has used a W^X scheme
for JIT code pages to improve security.  Code pages are normally
kept not-W-and-X to execute, switching temporarily to W-and-not-X
when the JIT needs to update the page (add new code, patch existing
code).

Valgrind observes the mprotect calls, and when pages lose X 
permission, it discards all the instrumented translations that
originate from the page.  It has to do that in order to maintain
correctness of the simulation.  This unfortunately gives a large
overhead because:

* finding all translations that intersect with the page is
  costly, since there are easily 700000 or more once Firefox
  gets up and running, and each translation can contain code from
  three different address ranges

* When they are subsequently later executed, it has to re-make them,
  which is expensive in itself.

Despite considerable efforts to speed up Valgrind's translation-discard
and JIT, this is still source of significant cost (20% ?) when running
Firefox.  The worst of it is that each ~W & X --> W & ~X --> ~W & X
cycle causes Valgrind a multimillion cycle cost even if SM's JITs
only patch a single byte on the page.

The proposal is therefore to weaken the switching when both configured
for and running on Valgrind, to ~W & X --> W & X --> ~W & X, so that
the X property remains unchanged.

Since getting this wrong would have potentially serious security
consequences, the implementation is defensive:

* behaviour is only changed when compiled --enable-valgrind,
  hence only on non-Windows targets.

* and when actually running on Valgrind

* and code is still non-writable when executing.  The change is
  that it is executable whilst it is being modified by the JIT;
  I'm not sure what dangers that gives.  Presumably that window
  of danger is relatively short, if the JIT patches or copies in
  code quickly.
Summary: Disable W^X switching when running on Valgrind on Linux/Mac → Disable W^X JIT code page switching when running on Valgrind on Linux/Mac
Attachment #8835540 - Flags: review?(nicolas.b.pierron)
Some not-very-exact numbers on a 2.8GHz Haswell, starting
Fx, waiting till idle on the "new tab" page, then quit:

  Original:
  real    4m19.536s
  user    5m8.514s
  12,228 discard requests handled by V, covering 94,134,488 bytes

  Patched:
  real    3m34.778s
  user    4m26.652s
  472 discard requests handled by V, covering 19,909,193 bytes

So it's very effective at reducing discard requests.  The discard
request numbers are for the chrome process only.  The times are
for the combined chrome and content process(es).
Attachment #8835540 - Flags: review?(nicolas.b.pierron) → review+
Pushed by jseward@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/1de058eb8231
Disable W^X JIT code page switching when running on Valgrind on Linux/Mac.  r=nicolas.b.pierron.
https://hg.mozilla.org/mozilla-central/rev/1de058eb8231
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla54
You need to log in before you can comment on or make changes to this bug.