[PATCH 00/11] x86/kvm/emulate: Avoid RET for FASTOPs

From: Peter Zijlstra
Date: Mon Dec 04 2023 - 04:40:24 EST


Hi!

Because I needed a new objtool annotation, and I'd promised Josh I'd clean all
that up a while ago, now with a healy sprinking of objtool patches...

Anyway... FASTOP is special in that it relies on RET to preserve FLAGS, while
normal C calling convention does not. This has been a problem before, see
ba5ca5e5e6a1 ("x86/retpoline: Don't clobber RFLAGS during srso_safe_ret()") but
is also a problem for call depth tracking.

Fixing the call-depth tracking return thunk would be significantly harder (and
more expensive), so instead change fastops to not use return.

There are two separate instances, test_cc() and fastop(). The first is
basically a SETCC wrapper, which seems like a very complicated (and somewhat
expensive) way to read FLAGS. Instead use the code we already have to emulate
JCC to fully emulate the instruction.

That then leaves fastop(), which when marked noinline is guaranteed to exist
only once. As such, CALL+RET isn't needed, because we'll always be RETurning to
the same location, as such replace with JMP+JMP.


---
arch/x86/include/asm/alternative.h | 14 +-
arch/x86/include/asm/nospec-branch.h | 45 ++++--
arch/x86/include/asm/text-patching.h | 20 ++-
arch/x86/kvm/emulate.c | 54 +++----
include/linux/instrumentation.h | 11 +-
include/linux/objtool.h | 62 +++++----
include/linux/objtool_types.h | 12 ++
tools/include/linux/objtool_types.h | 12 ++
tools/objtool/check.c | 263 +++++++++++------------------------
9 files changed, 208 insertions(+), 285 deletions(-)