Re: [patch RFC 5/5] x86/speculation: Add basic speculation control code
From: Andrea Arcangeli
Date: Wed Jan 10 2018 - 09:11:04 EST
Hello,
On Wed, Jan 10, 2018 at 02:46:22PM +0100, Thomas Gleixner wrote:
> So here is the simple list of questions all to be answered with YES or
> NO. I don't want to see any of the 'but, though ...'. We all know by now
> that it's CPU dependent and slow and whatever and that IBRS_ATT will be in
> future CPUs. So get your act together and tell a clear YES or NO.
Other comments/code from Tim Chen, and Dave Hansen and most important
the ibrs_enabled 2 description and implementation on lkml, makes me
still wonder if even Arjan may have misunderstood some detail about
IBRS semantics too.
Tim and Dave please comment too, Tim you originally wrote that code
that leaves IBRS always on and never toggles it in the kernel entry
point so you must know full well if Arjan is correct that you must
toggle IBRS every time you enter kernel and in turn ibrs_enabled 2
isn't valid mode.
I can answer my understanding of IBRS so far that would make perfect
sense if that code posted made sense in the first place...
https://marc.info/?l=linux-kernel&m=151520606320646
>
> 1) Does IBRS=1 when set once act as a set-and-forget option ?
Yes it can. Once set makes spectre variant#2 go away but only for IBP
BTB, stuff_RSB still needed and register hygiene too.
>
> 1a) If the answer to #1 is yes, is it more secure than toggling it?
It's equivalent, not more secure nor less secure.
Simply IBRS only protects the code that runs with IBRS set. So you if
you leave it always set, you protect more code.
IBRS set is equivalent to the code having been compiled with reptoline
on CPUS where reptoline is equaivalent to IBRS.
The act of setting IBRS does nothing, it's not a barrier (IBPB is a
barrier and flushes the CPU internal state). After IBRS is set the
code is like if it's built with reptoline.
IBRS may reduce the performance measurably and this is why it has to
be disabled in userland and that is the motivation for using
ibrs_enabled 1 the default.
The toggling at kernel entry is purely required so userland keeps
running fast with IBRS not set by default. But it would be more secure
to leave IBRS always on which is what ibrs_enabled 2, it's just
incredibly slower with current silicon in some microcode
implementations, which is why it's not the default.
>
> 1b) If the answer to #1 is yes, is retpoline required ?
reptoline is definitely not required whenever IBRS is set. IBRS set if
something is more secure than repotline as it's sure thing variant#2
is fixed and the microcode was applied if IBRS could be set.
>
> 1c) If the answer to #1 is yes, is RSB stuffing required ?
RBS is totally different piece of the CPU not covered by IBRS
AFIK. I'm not sure about this though but doing also stuff_RSB wouldn't
hurt if the CPU has no microcode update applied.
SMEP set in cr4 obviates the need of stuff_RSB in kernel entry but not
in vmexit.
> 2) Does toggle mode of IBRS require retpoline ?
Toggle mode means nothing in terms of added security. Toggle mode
simply protects only kernel space.
If you use the toggle mode (ibrs_enabled 1 default) only kernel is
protected by IBRS and in turn you don't have to build the kernel with
reptoline.
If you leave IBRS always on it's effectively like having built
everything (kernel and all userland) with reptoline.
> 3) Does toggle mode of IBRS require RSB stuffing ?
Yes, again IBRS does nothing to prevent the RSB stuffing. Only SMEP
helps there if set in cr4 but only for kernel entry, vmexit still
needs stuff_RSB.
The stuff_RSB part I'm no certain but again it won't hurt to do it and
we do it even with IBRS on. It's not measurable though.
> 4) Exist CPUs which require IBRS to be selected automatically ?
>
> 4b) If yes, provide the list as a separate answer please
Not sure if I get the question so not answering this one.
Future CPUs will have a new CPUID bit where enabling IBRS will perform
better than toggling it at kernel entry, so in those CPUs the most
secure mode (ibrs_enabled 2) that leaves IBRS always on, will perform
even better than the current default (ibrs_enabled 1). So in presence
of such future CPUID bit we should prefer ibrs_enabled 2 as default
and leave IBRS always on as default.
Thanks,
Andrea