Kernel - Additional cpu bug hardening part 1/2
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 11 Jun 2018 20:43:22 +0000 (13:43 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 11 Jun 2018 20:43:22 +0000 (13:43 -0700)
commite5aace14a443f92cdfe7f6d36df9f7dc6f86b76b
tree2d3e0d5e9f572f2f937eb8eb9600c0a111258fe8
parentdd62cb1009be64311a6460315301e1a6f3a88e04
Kernel - Additional cpu bug hardening part 1/2

* OpenBSD recently made a commit that scraps the use of delayed FP
  state saving due to a rumor that the content of FP registers owned
  by another process can be speculatively detected when they are
  present for the current process, even when the TS bit is used to
  force a DNA trap.

  This rumor has been circulating for a while.  OpenBSD felt that the
  lack of responsiveness from Intel forced their hand.  Since they've
  gone ahead and pushed a fix for this potential problem, we are
  going to as well.

* DragonFlyBSD already synchronously saves FP state on switch-out.
  However, it only cleans the state up afterwords by calling fninit
  and this isn't enough to actually erase the content in the %xmm
  registers.  We want to continue to use delayed FP state restores
  because it saves a considerable amount of switching time when we do
  not have to do a FP restore.

  Most programs touch the FP registers at startup due to rtld linking,
  and more and more programs use the %xmm registers as general purpose
  registers.  OpenBSD's solution of always proactively saving and
  restoring FP state is a reasonable one.  DragonFlyBSD is going to
  take a slightly different tact in order to try to retain more optimal
  switching behavior when the FP unit is not in continuous use.

* Our first fix is to issue a FP restore on dummy state after our
  FP save to guarantee that all FP registers are zerod after FP state
  is saved.  This allows us to continue to support delayed FP state
  loads with zero chance of leakage between processes.

* Our second fix is to add a heuristic which allows the kernel to
  detect when the FP unit is being used seriously (verses just during
  program startup).

  We have added a sysctl machdep.npx_fpu_heuristic heuristic for this
  purpose which defaults to the value 32.  Values can be:

  0 - Proactive FPU state loading disabled (old behavior retained).
  Note that the first fix remains active, the FP register state
  is still cleared after saving so no leakage can occur.  All
  processes will take a DNA trap after a thread switch when they
  access the FP state.

  1 - Proactive FPU state loading is enabled at all times for a thread
  after the first FP access made by that thread.  Upon returning
  from a thread switch, the FPU state will already be ready to go
  and a DNA trap will not occur.

  N - Proactive FPU state loading enabled for N context switches, then
  disabled.  The next DNA fault after disablement then re-enables
  proactive loading for the next N context switches.

  Default value is 32.  This ensures that program startup can use
  the FP unit but integer-centric programs which don't afterwords
  will not incur the FP switching overhead (for either switch-away
  or switch-back).
sys/platform/pc64/include/globaldata.h
sys/platform/pc64/include/md_var.h
sys/platform/pc64/x86_64/genassym.c
sys/platform/pc64/x86_64/npx.c
sys/platform/pc64/x86_64/swtch.s
sys/platform/pc64/x86_64/trap.c
sys/platform/vkernel64/x86_64/trap.c
sys/sys/thread.h