Skip to content

Commit aebc62b

Browse files
committed
KVM: selftests: Add support for DIV and IDIV in the fastops test
Extend the fastops test coverage to DIV and IDIV, specifically to provide coverage for #DE (divide error) exceptions, as #DE is the only exception that can occur in KVM's fastops path, i.e. that requires exception fixup. Link: https://lore.kernel.org/r/20250909202835.333554-5-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent fe08478 commit aebc62b

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

tools/testing/selftests/kvm/x86/fastops_test.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,42 @@
9292
ex_flags, insn, shift, (uint64_t)input, flags); \
9393
})
9494

95+
#define guest_execute_fastop_div(__KVM_ASM_SAFE, insn, __a, __d, __rm, __flags) \
96+
({ \
97+
uint64_t ign_error_code; \
98+
uint8_t vector; \
99+
\
100+
__asm__ __volatile__(fastop(__KVM_ASM_SAFE(insn " %[denom]")) \
101+
: "+a"(__a), "+d"(__d), flags_constraint(__flags), \
102+
KVM_ASM_SAFE_OUTPUTS(vector, ign_error_code) \
103+
: [denom]"rm"(__rm), bt_constraint(__rm) \
104+
: "cc", "memory", KVM_ASM_SAFE_CLOBBERS); \
105+
vector; \
106+
})
107+
108+
#define guest_test_fastop_div(insn, type_t, __val1, __val2) \
109+
({ \
110+
type_t _a = __val1, _d = __val1, rm = __val2; \
111+
type_t a = _a, d = _d, ex_a = _a, ex_d = _d; \
112+
uint64_t flags, ex_flags; \
113+
uint8_t v, ex_v; \
114+
\
115+
ex_v = guest_execute_fastop_div(KVM_ASM_SAFE, insn, ex_a, ex_d, rm, ex_flags); \
116+
v = guest_execute_fastop_div(KVM_ASM_SAFE_FEP, insn, a, d, rm, flags); \
117+
\
118+
GUEST_ASSERT_EQ(v, ex_v); \
119+
__GUEST_ASSERT(v == ex_v, \
120+
"Wanted vector 0x%x for '%s 0x%lx:0x%lx/0x%lx', got 0x%x", \
121+
ex_v, insn, (uint64_t)_a, (uint64_t)_d, (uint64_t)rm, v); \
122+
__GUEST_ASSERT(a == ex_a && d == ex_d, \
123+
"Wanted 0x%lx:0x%lx for '%s 0x%lx:0x%lx/0x%lx', got 0x%lx:0x%lx",\
124+
(uint64_t)ex_a, (uint64_t)ex_d, insn, (uint64_t)_a, \
125+
(uint64_t)_d, (uint64_t)rm, (uint64_t)a, (uint64_t)d); \
126+
__GUEST_ASSERT(v || ex_v || (flags == ex_flags), \
127+
"Wanted flags 0x%lx for '%s 0x%lx:0x%lx/0x%lx', got 0x%lx", \
128+
ex_flags, insn, (uint64_t)_a, (uint64_t)_d, (uint64_t)rm, flags);\
129+
})
130+
95131
static const uint64_t vals[] = {
96132
0,
97133
1,
@@ -141,6 +177,8 @@ if (sizeof(type_t) != 1) { \
141177
guest_test_fastop_cl("sar" suffix, type_t, vals[i], vals[j]); \
142178
guest_test_fastop_cl("shl" suffix, type_t, vals[i], vals[j]); \
143179
guest_test_fastop_cl("shr" suffix, type_t, vals[i], vals[j]); \
180+
\
181+
guest_test_fastop_div("div" suffix, type_t, vals[i], vals[j]); \
144182
} \
145183
} \
146184
} while (0)

0 commit comments

Comments
 (0)