diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-20 09:46:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-20 09:46:52 -0700 |
commit | 7445b2dcd77ae8385bd08bb6c2db20ea0cfa6230 (patch) | |
tree | 8af8eb7d511f9f2aa44c69289e2e255b347eac5a | |
parent | 1e0e7a6a28f877312b93cd12a1448c8d53733b55 (diff) | |
parent | fe83f5eae432ccc8e90082d6ed506d5233547473 (diff) | |
download | linux-7445b2dcd77ae8385bd08bb6c2db20ea0cfa6230.tar.gz linux-7445b2dcd77ae8385bd08bb6c2db20ea0cfa6230.tar.bz2 linux-7445b2dcd77ae8385bd08bb6c2db20ea0cfa6230.zip |
Merge tag 'for-linus-5.17' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fix from Paolo Bonzini:
"Fix for the SLS mitigation, which makes a 'SETcc/RET' pair grow
to 'SETcc/RET/INT3'.
This doesn't fit in 4 bytes any more, so the alignment has to
change to 8 for this case"
* tag 'for-linus-5.17' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
kvm/emulate: Fix SETcc emulation function offsets with SLS
-rw-r--r-- | arch/x86/kvm/emulate.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 5719d8cfdbd9..e86d610dc6b7 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -429,8 +429,23 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop); FOP_END /* Special case for SETcc - 1 instruction per cc */ + +/* + * Depending on .config the SETcc functions look like: + * + * SETcc %al [3 bytes] + * RET [1 byte] + * INT3 [1 byte; CONFIG_SLS] + * + * Which gives possible sizes 4 or 5. When rounded up to the + * next power-of-two alignment they become 4 or 8. + */ +#define SETCC_LENGTH (4 + IS_ENABLED(CONFIG_SLS)) +#define SETCC_ALIGN (4 << IS_ENABLED(CONFIG_SLS)) +static_assert(SETCC_LENGTH <= SETCC_ALIGN); + #define FOP_SETCC(op) \ - ".align 4 \n\t" \ + ".align " __stringify(SETCC_ALIGN) " \n\t" \ ".type " #op ", @function \n\t" \ #op ": \n\t" \ #op " %al \n\t" \ @@ -1047,7 +1062,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt) static __always_inline u8 test_cc(unsigned int condition, unsigned long flags) { u8 rc; - void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); + void (*fop)(void) = (void *)em_setcc + SETCC_ALIGN * (condition & 0xf); flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF; asm("push %[flags]; popf; " CALL_NOSPEC |