kernel - Implement spectre mitigations part 1
* Implement machdep.spectre_mitigation. This can be set as a tunable
or sysctl'd later. The tunable is only applicable if the BIOS has
the appropriate microcode, otherwise you have to update the microcode
first and then use sysctl to set the mode.
This works similarly to Linux's IBRS support.
mode 0 - Spectre IBPB MSRs disabled
mode 1 - Sets IBPB MSR on USER->KERN transition and clear it
on KERN->USER.
mode 2 - Leave IBPB set globally. Do not toggle on USER->KERN or
KERN->USER transitions.
* Retest spectre microcode MSRs on microcode update.
* Spectre mode 1 is enabled by default if the microcode supports it.
(we might change this to disabled by default, I'm still mulling it
over).
* General performance effects (not counting the MMU separation mode,
which is machdep.meltdown_mitigation and adds another 3% in overhead):
Skylake loses around 5% for mode 1 and 12% for mode 2, verses mode 0.
Haswell loses around 12% for mode 1 and 53% for mode 2, verses mode 0.
Add another 3% if MMU separation is also turned on (aka
machdep.meltdown_mitigation).
* General system call overhead effects on Skylake:
machdep.meltdown_mitigation=0, machdep.spectre_mitigation=0 103ns
machdep.meltdown_mitigation=1, machdep.spectre_mitigation=0 360ns
machdep.meltdown_mitigation=1, machdep.spectre_mitigation=1 848ns
machdep.meltdown_mitigation=1, machdep.spectre_mitigation=2 404ns
Note that mode 1 has better overall performance for mixed user+kernel
workloads despite having a much higher system call overhead, whereas
mode 2 has lower system call overhead but generally lower overall
performance because IBPB is enabled in usermode.