x86/alternative: Rewrite optimize_nops() some
authorPeter Zijlstra <peterz@infradead.org>
Wed, 8 Feb 2023 17:10:53 +0000 (18:10 +0100)
committerBorislav Petkov (AMD) <bp@alien8.de>
Thu, 11 May 2023 15:33:36 +0000 (17:33 +0200)
commit6c480f22212826425b57932f09b1f0abbec85485
treeec67f07bab8caf9a503ae23837b495ccbf1f419f
parent14e4ec9c3e9164c6719f98d8a3065c487be2aaa5
x86/alternative: Rewrite optimize_nops() some

Address two issues:

 - it no longer hard requires single byte NOP runs - now it accepts any
   NOP and NOPL encoded instruction (but not the more complicated 32bit
   NOPs).

 - it writes a single 'instruction' replacement.

Specifically, ORC unwinder relies on the tail NOP of an alternative to
be a single instruction. In particular, it relies on the inner bytes not
being executed.

Once the max supported NOP length has been reached (currently 8, could easily
be extended to 11 on x86_64), switch to JMP.d8 and INT3 padding to
achieve the same result.

Objtool uses this guarantee in the analysis of alternative/overlapping
CFI state for the ORC unwinder data. Every instruction edge gets a CFI
state and the more instructions the larger the chance of conflicts.

  [ bp:
  - Add a comment over add_nop() to explain why it does it this way
  - Make add_nops() PARAVIRT only as it is used solely there now ]

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230208171431.373412974@infradead.org
arch/x86/kernel/alternative.c