kernel - Implement spectre mitigations part 2
commit9283c84bb165f90825ff030ecf1116089353e765
authorMatthew Dillon <dillon@apollo.backplane.com>
Wed, 10 Jan 2018 22:59:47 +0000 (10 14:59 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Wed, 10 Jan 2018 23:13:43 +0000 (10 15:13 -0800)
tree5d28751d2e537ee33a753af1f061ef1b049a85e0
parente769d4a5129a8d0fa3c74e92423fce020daf576f
kernel - Implement spectre mitigations part 2

* NOTE: The last few commits may have said 'IBPB' but they really
  meant 'IBRS.  The last few commits addde IBRS support, this one
  cleans that up and adds IBPB support.

* Intel says for IBRS always-on mode (mode 2), SPEC_CTRL still has
  to be poked on every user->kernel entry as a barrier, even though
  the value is not being changed.  So make this change.  This actually
  somewhat improves performance a little on Skylake and later verses
  when I just set it globally and left it that way.

* Implement IBPB detection and support on Intel.  At the moment
  we default to turning it off because the performance hit is pretty
  massive.  Currently the work on linux is only using IBPB for
  VMM related operations and not for user->kernel entry.

* Enhance the machdep.spectre_mitigation sysctl to print out
  what the mode matrix is whenever you change it, in human
  readable terms.

  0 IBRS disabled IBPB disabled
  1 IBRS mode 1 (kernel-only) IBPB disabled
  2 IBRS mode 2 (at all times) IBPB disabled

  4 IBRS disabled IBPB enabled
  5 IBRS mode 1 (kernel-only) IBPB enabled
  6 IBRS mode 2 (at all times) IBPB enabled

  Currently we default to (1) instead of (5) when we detect that
  the microcode detects both features.  IBPB is not turned on by default
  (you can see why below).

* Haswell and Skylake performance loss matrix using the following
  test.  This tests a high-concurrency compile, which is approximately
  a 5:1 user:kernel test with high concurrency.

  The haswell box is:  i3-4130 CPU @ 3.40GHz  (2-core/4-thread)
  The skylake box is:  i5-6500 CPU @ 3.20GHz  (4-core/4-thread)

  This does not include MMU isolation losses, which will add another
  3-4% or so in losses.

  (/usr/obj on tmpfs)
  time make -j 8 nativekernel NO_MODULES=TRUE

    PERFORMANCE LOSS MATRIX
       HASWELL                 SKYLAKE
    IBPB=0  IBPB=1          IBPB=0  IBPB=1
    IBRS=0     0%    12%              0%     17%
    IBRS=1   >12%<   21%           >2.4%<    15%
    IBRS=2    58%    60%             23%     32%

  Note that the automatic default when microcode support is detected
  is IBRS=1, IBPB=0 (12% loss on Haswell and 2.4% loss on Skylake
  for this test).  If we add 3-4% or so for MMU isolation, a Haswell
  cpu loses around 16% and a Skylake cpu loses around 6% or so in
  performance.

    PERFORMANCE LOSS MATRIX
      (including 3% MMU isolation losses)
       HASWELL                 SKYLAKE
    IBPB=0  IBPB=1          IBPB=0  IBPB=1
    IBRS=0     3%    15%              3%     20%
    IBRS=1   >15%<   24%           >5.4%<    18%
    IBRS=2    61%    63%             26%     35%
sys/cpu/x86_64/include/asmacros.h
sys/cpu/x86_64/include/specialreg.h
sys/platform/pc64/include/pcb.h
sys/platform/pc64/x86_64/exception.S
sys/platform/pc64/x86_64/genassym.c
sys/platform/pc64/x86_64/vm_machdep.c