Borislav Petkov 0c004d
From: Borislav Petkov <bp@suse.de>
Borislav Petkov 0c004d
Date: Wed, 16 Mar 2022 22:05:52 +0100
Borislav Petkov 0c004d
Subject: kvm/emulate: Fix SETcc emulation function offsets with SLS
Borislav Petkov 0c004d
Git-commit: fe83f5eae432ccc8e90082d6ed506d5233547473
Borislav Petkov 0c004d
Patch-mainline: v5.17
Borislav Petkov 0c004d
References: bsc#1201930
Borislav Petkov 0c004d
Borislav Petkov 0c004d
The commit in Fixes started adding INT3 after RETs as a mitigation
Borislav Petkov 0c004d
against straight-line speculation.
Borislav Petkov 0c004d
Borislav Petkov 0c004d
The fastop SETcc implementation in kvm's insn emulator uses macro magic
Borislav Petkov 0c004d
to generate all possible SETcc functions and to jump to them when
Borislav Petkov 0c004d
emulating the respective instruction.
Borislav Petkov 0c004d
Borislav Petkov 0c004d
However, it hardcodes the size and alignment of those functions to 4: a
Borislav Petkov 0c004d
three-byte SETcc insn and a single-byte RET. BUT, with SLS, there's an
Borislav Petkov 0c004d
INT3 that gets slapped after the RET, which brings the whole scheme out
Borislav Petkov 0c004d
of alignment:
Borislav Petkov 0c004d
Borislav Petkov 0c004d
  15:   0f 90 c0                seto   %al
Borislav Petkov 0c004d
  18:   c3                      ret
Borislav Petkov 0c004d
  19:   cc                      int3
Borislav Petkov 0c004d
  1a:   0f 1f 00                nopl   (%rax)
Borislav Petkov 0c004d
  1d:   0f 91 c0                setno  %al
Borislav Petkov 0c004d
  20:   c3                      ret
Borislav Petkov 0c004d
  21:   cc                      int3
Borislav Petkov 0c004d
  22:   0f 1f 00                nopl   (%rax)
Borislav Petkov 0c004d
  25:   0f 92 c0                setb   %al
Borislav Petkov 0c004d
  28:   c3                      ret
Borislav Petkov 0c004d
  29:   cc                      int3
Borislav Petkov 0c004d
Borislav Petkov 0c004d
and this explodes like this:
Borislav Petkov 0c004d
Borislav Petkov 0c004d
  int3: 0000 [#1] PREEMPT SMP PTI
Borislav Petkov 0c004d
  CPU: 0 PID: 2435 Comm: qemu-system-x86 Not tainted 5.17.0-rc8-sls #1
Borislav Petkov 0c004d
  Hardware name: Dell Inc. Precision WorkStation T3400  /0TP412, BIOS A14 04/30/2012
Borislav Petkov 0c004d
  RIP: 0010:setc+0x5/0x8 [kvm]
Borislav Petkov 0c004d
  Code: 00 00 0f 1f 00 0f b6 05 43 24 06 00 c3 cc 0f 1f 80 00 00 00 00 0f 90 c0 c3 cc 0f \
Borislav Petkov 0c004d
	  1f 00 0f 91 c0 c3 cc 0f 1f 00 0f 92 c0 c3 cc <0f> 1f 00 0f 93 c0 c3 cc 0f 1f 00 \
Borislav Petkov 0c004d
	  0f 94 c0 c3 cc 0f 1f 00 0f 95 c0
Borislav Petkov 0c004d
  Call Trace:
Borislav Petkov 0c004d
   <TASK>
Borislav Petkov 0c004d
   ? x86_emulate_insn [kvm]
Borislav Petkov 0c004d
   ? x86_emulate_instruction [kvm]
Borislav Petkov 0c004d
   ? vmx_handle_exit [kvm_intel]
Borislav Petkov 0c004d
   ? kvm_arch_vcpu_ioctl_run [kvm]
Borislav Petkov 0c004d
   ? kvm_vcpu_ioctl [kvm]
Borislav Petkov 0c004d
   ? __x64_sys_ioctl
Borislav Petkov 0c004d
   ? do_syscall_64
Borislav Petkov 0c004d
   ? entry_SYSCALL_64_after_hwframe
Borislav Petkov 0c004d
   </TASK>
Borislav Petkov 0c004d
Borislav Petkov 0c004d
Raise the alignment value when SLS is enabled and use a macro for that
Borislav Petkov 0c004d
instead of hard-coding naked numbers.
Borislav Petkov 0c004d
Borislav Petkov 0c004d
Fixes: e463a09af2f0 ("x86: Add straight-line-speculation mitigation")
Borislav Petkov 0c004d
Reported-by: Jamie Heilman <jamie@audible.transient.net>
Borislav Petkov 0c004d
Signed-off-by: Borislav Petkov <bp@suse.de>
Borislav Petkov 0c004d
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Borislav Petkov 0c004d
Tested-by: Jamie Heilman <jamie@audible.transient.net>
Borislav Petkov 0c004d
Link: https://lore.kernel.org/r/YjGzJwjrvxg5YZ0Z@audible.transient.net
Borislav Petkov 0c004d
[Add a comment and a bit of safety checking, since this is going to be changed
Borislav Petkov 0c004d
 again for IBT support. - Paolo]
Borislav Petkov 0c004d
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Borislav Petkov 0c004d
Borislav Petkov 0c004d
  [ bp: Backport only the fastop offset finding - the macros are largely
Borislav Petkov 0c004d
    simplified in
Borislav Petkov 0c004d
Borislav Petkov 0c004d
    79629181607e ("KVM: emulate: do not adjust size of fastop and setcc subroutines")
Borislav Petkov 0c004d
Borislav Petkov 0c004d
    so no need to backport pieces which will get removed anyway. ]
Borislav Petkov 0c004d
Borislav Petkov 0c004d
---
Borislav Petkov 0c004d
 arch/x86/kvm/emulate.c | 19 +++++++++++++++++--
Borislav Petkov 0c004d
 1 file changed, 17 insertions(+), 2 deletions(-)
Borislav Petkov 0c004d
Borislav Petkov 0c004d
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
Borislav Petkov 0c004d
index 5719d8cfdbd9..e86d610dc6b7 100644
Borislav Petkov 0c004d
--- a/arch/x86/kvm/emulate.c
Borislav Petkov 0c004d
+++ b/arch/x86/kvm/emulate.c
Borislav Petkov 0c004d
@@ -1047,7 +1062,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
Borislav Petkov 0c004d
 static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
Borislav Petkov 0c004d
 {
Borislav Petkov 0c004d
 	u8 rc;
Borislav Petkov 0c004d
-	void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf);
Borislav Petkov 0c004d
+	void (*fop)(void) = (void *)em_setcc + SETCC_ALIGN * (condition & 0xf);
Borislav Petkov 0c004d
 
Borislav Petkov 0c004d
 	flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
Borislav Petkov 0c004d
 	asm("push %[flags]; popf; " CALL_NOSPEC
Borislav Petkov 0c004d