Skip to content

Commit 0cb6f1e

Browse files
author
Peter Zijlstra
committed
KVM: x86: Implement test_cc() in C
Current test_cc() uses the fastop infrastructure to test flags using SETcc instructions. However, int3_emulate_jcc() already fully implements the flags->CC mapping, use that. Removes a pile of gnarly asm. Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Sean Christopherson <seanjc@google.com> Link: https://lkml.kernel.org/r/20250714103439.637049932@infradead.org
1 parent c17b750 commit 0cb6f1e

2 files changed

Lines changed: 15 additions & 39 deletions

File tree

arch/x86/include/asm/text-patching.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ void int3_emulate_ret(struct pt_regs *regs)
178178
}
179179

180180
static __always_inline
181-
void int3_emulate_jcc(struct pt_regs *regs, u8 cc, unsigned long ip, unsigned long disp)
181+
bool __emulate_cc(unsigned long flags, u8 cc)
182182
{
183-
static const unsigned long jcc_mask[6] = {
183+
static const unsigned long cc_mask[6] = {
184184
[0] = X86_EFLAGS_OF,
185185
[1] = X86_EFLAGS_CF,
186186
[2] = X86_EFLAGS_ZF,
@@ -193,15 +193,21 @@ void int3_emulate_jcc(struct pt_regs *regs, u8 cc, unsigned long ip, unsigned lo
193193
bool match;
194194

195195
if (cc < 0xc) {
196-
match = regs->flags & jcc_mask[cc >> 1];
196+
match = flags & cc_mask[cc >> 1];
197197
} else {
198-
match = ((regs->flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^
199-
((regs->flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT);
198+
match = ((flags & X86_EFLAGS_SF) >> X86_EFLAGS_SF_BIT) ^
199+
((flags & X86_EFLAGS_OF) >> X86_EFLAGS_OF_BIT);
200200
if (cc >= 0xe)
201-
match = match || (regs->flags & X86_EFLAGS_ZF);
201+
match = match || (flags & X86_EFLAGS_ZF);
202202
}
203203

204-
if ((match && !invert) || (!match && invert))
204+
return (match && !invert) || (!match && invert);
205+
}
206+
207+
static __always_inline
208+
void int3_emulate_jcc(struct pt_regs *regs, u8 cc, unsigned long ip, unsigned long disp)
209+
{
210+
if (__emulate_cc(regs->flags, cc))
205211
ip += disp;
206212

207213
int3_emulate_jmp(regs, ip);

arch/x86/kvm/emulate.c

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <asm/debugreg.h>
2727
#include <asm/nospec-branch.h>
2828
#include <asm/ibt.h>
29+
#include <asm/text-patching.h>
2930

3031
#include "x86.h"
3132
#include "tss.h"
@@ -416,31 +417,6 @@ static int fastop(struct x86_emulate_ctxt *ctxt, fastop_t fop);
416417
ON64(FOP3E(op##q, rax, rdx, cl)) \
417418
FOP_END
418419

419-
/* Special case for SETcc - 1 instruction per cc */
420-
#define FOP_SETCC(op) \
421-
FOP_FUNC(op) \
422-
#op " %al \n\t" \
423-
FOP_RET(op)
424-
425-
FOP_START(setcc)
426-
FOP_SETCC(seto)
427-
FOP_SETCC(setno)
428-
FOP_SETCC(setc)
429-
FOP_SETCC(setnc)
430-
FOP_SETCC(setz)
431-
FOP_SETCC(setnz)
432-
FOP_SETCC(setbe)
433-
FOP_SETCC(setnbe)
434-
FOP_SETCC(sets)
435-
FOP_SETCC(setns)
436-
FOP_SETCC(setp)
437-
FOP_SETCC(setnp)
438-
FOP_SETCC(setl)
439-
FOP_SETCC(setnl)
440-
FOP_SETCC(setle)
441-
FOP_SETCC(setnle)
442-
FOP_END;
443-
444420
FOP_START(salc)
445421
FOP_FUNC(salc)
446422
"pushf; sbb %al, %al; popf \n\t"
@@ -1068,13 +1044,7 @@ static int em_bsr_c(struct x86_emulate_ctxt *ctxt)
10681044

10691045
static __always_inline u8 test_cc(unsigned int condition, unsigned long flags)
10701046
{
1071-
u8 rc;
1072-
void (*fop)(void) = (void *)em_setcc + FASTOP_SIZE * (condition & 0xf);
1073-
1074-
flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF;
1075-
asm("push %[flags]; popf; " CALL_NOSPEC
1076-
: "=a"(rc), ASM_CALL_CONSTRAINT : [thunk_target]"r"(fop), [flags]"r"(flags));
1077-
return rc;
1047+
return __emulate_cc(flags, condition & 0xf);
10781048
}
10791049

10801050
static void fetch_register_operand(struct operand *op)

0 commit comments

Comments
 (0)