On Sun, Nov 22, 2020 at 5:33 AM David Howells <dhowells@xxxxxxxxxx> wrote: > > I don't know enough about how spectre v2 works to say if this would be a > problem for the ops-table approach, but wouldn't it also affect the chain of > conditional branches that we currently use, since it's branch-prediction > based? No, regular conditional branches aren't a problem. Yes, they may mispredict, but outside of a few very rare cases that we handle specially, that's not an issue. Why? Because they always mispredict to one or the other side, so the code flow may be mis-predicted, but it is fairly controlled. In contrast, an indirect jump can mispredict the target, and branch _anywhere_, and the attack vectors can poison the BTB (branch target buffer), so our mitigation for that is that every single indirect branch isn't predicted at all (using "retpoline"). So a conditional branch takes zero cycles when predicted (and most will predict quite well). And as David Laight pointed out a compiler can also turn a series of conditional branches into a tree, means that N conditional branches basically only needs log2(N) conditionals executed. In contrast, with retpoline in place, an indirect branch will basically always take something like 25-30 cycles, because it always mispredicts. End result: - well-predicted conditional branches are basically free (apart from code layout issues) - even with average prediction, a series of conditional branches has to be fairly long for it to be worse than an indirect branch - only completely unpredictable conditional branches end up basically losing, and even then you probably need more than one. And while completely unpredictable conditional branches do exist, they are pretty rare. The other side of the coin, of course, is - often this is not measurable anyway. - code cleanliness is important - not everything needs retpolines and the expensive indirect branches. So this is not in any way "indirect branches are bad". It's more of a "indirect branches really aren't necessarily better than a couple of conditionals, and _may_ be much worse". For example, look at this gcc bugzilla: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86952 which basically is about the compiler generating a jump table (is a single indirect branch) vs a series of conditional branches. With retpoline, the cross-over point is basically when you need to have over 10 conditional branches - and because of the log2(N) behavior, that's around a thousand cases! (But this depends hugely on microarchitectural details). Linus