Skip to content

Commit a1025dc

Browse files
committed
selftests: kvm: replace numbered sync points with actions
Rework the guest=>host syncs in the AMX test to use named actions instead of arbitrary, incrementing numbers. The "stage" of the test has no real meaning, what matters is what action the test wants the host to perform. The incrementing numbers are somewhat helpful for triaging failures, but fully debugging failures almost always requires a much deeper dive into the test (and KVM). Using named actions not only makes it easier to extend the test without having to shift all sync point numbers, it makes the code easier to read. [Commit message by Sean Christopherson] Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent b45f721 commit a1025dc

File tree

1 file changed

+43
-45
lines changed

1 file changed

+43
-45
lines changed

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

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -124,27 +124,35 @@ static void set_tilecfg(struct tile_config *cfg)
124124
}
125125
}
126126

127+
enum {
128+
/* Check TMM0 against tiledata */
129+
TEST_COMPARE_TILEDATA = 1,
130+
131+
/* Full VM save/restore */
132+
TEST_SAVE_RESTORE = 2,
133+
};
134+
127135
static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg,
128136
struct tile_data *tiledata,
129137
struct xstate *xstate)
130138
{
131139
GUEST_ASSERT(this_cpu_has(X86_FEATURE_XSAVE) &&
132140
this_cpu_has(X86_FEATURE_OSXSAVE));
133141
check_xtile_info();
134-
GUEST_SYNC(1);
142+
GUEST_SYNC(TEST_SAVE_RESTORE);
135143

136144
/* xfd=0, enable amx */
137145
wrmsr(MSR_IA32_XFD, 0);
138-
GUEST_SYNC(2);
146+
GUEST_SYNC(TEST_SAVE_RESTORE);
139147
GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == 0);
140148
set_tilecfg(amx_cfg);
141149
__ldtilecfg(amx_cfg);
142-
GUEST_SYNC(3);
150+
GUEST_SYNC(TEST_SAVE_RESTORE);
143151
/* Check save/restore when trap to userspace */
144152
__tileloadd(tiledata);
145-
GUEST_SYNC(4);
153+
GUEST_SYNC(TEST_COMPARE_TILEDATA | TEST_SAVE_RESTORE);
146154
__tilerelease();
147-
GUEST_SYNC(5);
155+
GUEST_SYNC(TEST_SAVE_RESTORE);
148156
/*
149157
* After XSAVEC, XTILEDATA is cleared in the xstate_bv but is set in
150158
* the xcomp_bv.
@@ -154,6 +162,8 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg,
154162
GUEST_ASSERT(!(xstate->header.xstate_bv & XFEATURE_MASK_XTILE_DATA));
155163
GUEST_ASSERT(xstate->header.xcomp_bv & XFEATURE_MASK_XTILE_DATA);
156164

165+
/* #NM test */
166+
157167
/* xfd=0x40000, disable amx tiledata */
158168
wrmsr(MSR_IA32_XFD, XFEATURE_MASK_XTILE_DATA);
159169

@@ -166,32 +176,32 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg,
166176
GUEST_ASSERT(!(xstate->header.xstate_bv & XFEATURE_MASK_XTILE_DATA));
167177
GUEST_ASSERT((xstate->header.xcomp_bv & XFEATURE_MASK_XTILE_DATA));
168178

169-
GUEST_SYNC(6);
179+
GUEST_SYNC(TEST_SAVE_RESTORE);
170180
GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == XFEATURE_MASK_XTILE_DATA);
171181
set_tilecfg(amx_cfg);
172182
__ldtilecfg(amx_cfg);
173183
/* Trigger #NM exception */
174184
__tileloadd(tiledata);
175-
GUEST_SYNC(10);
185+
GUEST_SYNC(TEST_COMPARE_TILEDATA | TEST_SAVE_RESTORE);
176186

177187
GUEST_DONE();
178188
}
179189

180190
void guest_nm_handler(struct ex_regs *regs)
181191
{
182192
/* Check if #NM is triggered by XFEATURE_MASK_XTILE_DATA */
183-
GUEST_SYNC(7);
193+
GUEST_SYNC(TEST_SAVE_RESTORE);
184194
GUEST_ASSERT(!(get_cr0() & X86_CR0_TS));
185195
GUEST_ASSERT(rdmsr(MSR_IA32_XFD_ERR) == XFEATURE_MASK_XTILE_DATA);
186196
GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == XFEATURE_MASK_XTILE_DATA);
187-
GUEST_SYNC(8);
197+
GUEST_SYNC(TEST_SAVE_RESTORE);
188198
GUEST_ASSERT(rdmsr(MSR_IA32_XFD_ERR) == XFEATURE_MASK_XTILE_DATA);
189199
GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == XFEATURE_MASK_XTILE_DATA);
190200
/* Clear xfd_err */
191201
wrmsr(MSR_IA32_XFD_ERR, 0);
192202
/* xfd=0, enable amx */
193203
wrmsr(MSR_IA32_XFD, 0);
194-
GUEST_SYNC(9);
204+
GUEST_SYNC(TEST_SAVE_RESTORE);
195205
}
196206

197207
int main(int argc, char *argv[])
@@ -244,6 +254,7 @@ int main(int argc, char *argv[])
244254
memset(addr_gva2hva(vm, xstate), 0, PAGE_SIZE * DIV_ROUND_UP(XSAVE_SIZE, PAGE_SIZE));
245255
vcpu_args_set(vcpu, 3, amx_cfg, tiledata, xstate);
246256

257+
int iter = 0;
247258
for (;;) {
248259
vcpu_run(vcpu);
249260
TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
@@ -253,20 +264,9 @@ int main(int argc, char *argv[])
253264
REPORT_GUEST_ASSERT(uc);
254265
/* NOT REACHED */
255266
case UCALL_SYNC:
256-
switch (uc.args[1]) {
257-
case 1:
258-
case 2:
259-
case 3:
260-
case 5:
261-
case 6:
262-
case 7:
263-
case 8:
264-
fprintf(stderr, "GUEST_SYNC(%ld)\n", uc.args[1]);
265-
break;
266-
case 4:
267-
case 10:
268-
fprintf(stderr,
269-
"GUEST_SYNC(%ld), check save/restore status\n", uc.args[1]);
267+
++iter;
268+
if (uc.args[1] & TEST_COMPARE_TILEDATA) {
269+
fprintf(stderr, "GUEST_SYNC #%d, check TMM0 contents\n", iter);
270270

271271
/* Compacted mode, get amx offset by xsave area
272272
* size subtract 8K amx size.
@@ -279,11 +279,25 @@ int main(int argc, char *argv[])
279279
ret = memcmp(amx_start, tiles_data, TILE_SIZE);
280280
TEST_ASSERT(ret == 0, "memcmp failed, ret=%d", ret);
281281
kvm_x86_state_cleanup(state);
282-
break;
283-
case 9:
284-
fprintf(stderr,
285-
"GUEST_SYNC(%ld), #NM exception and enable amx\n", uc.args[1]);
286-
break;
282+
}
283+
if (uc.args[1] & TEST_SAVE_RESTORE) {
284+
fprintf(stderr, "GUEST_SYNC #%d, save/restore VM state\n", iter);
285+
state = vcpu_save_state(vcpu);
286+
memset(&regs1, 0, sizeof(regs1));
287+
vcpu_regs_get(vcpu, &regs1);
288+
289+
kvm_vm_release(vm);
290+
291+
/* Restore state in a new VM. */
292+
vcpu = vm_recreate_with_one_vcpu(vm);
293+
vcpu_load_state(vcpu, state);
294+
kvm_x86_state_cleanup(state);
295+
296+
memset(&regs2, 0, sizeof(regs2));
297+
vcpu_regs_get(vcpu, &regs2);
298+
TEST_ASSERT(!memcmp(&regs1, &regs2, sizeof(regs2)),
299+
"Unexpected register values after vcpu_load_state; rdi: %lx rsi: %lx",
300+
(ulong) regs2.rdi, (ulong) regs2.rsi);
287301
}
288302
break;
289303
case UCALL_DONE:
@@ -293,22 +307,6 @@ int main(int argc, char *argv[])
293307
TEST_FAIL("Unknown ucall %lu", uc.cmd);
294308
}
295309

296-
state = vcpu_save_state(vcpu);
297-
memset(&regs1, 0, sizeof(regs1));
298-
vcpu_regs_get(vcpu, &regs1);
299-
300-
kvm_vm_release(vm);
301-
302-
/* Restore state in a new VM. */
303-
vcpu = vm_recreate_with_one_vcpu(vm);
304-
vcpu_load_state(vcpu, state);
305-
kvm_x86_state_cleanup(state);
306-
307-
memset(&regs2, 0, sizeof(regs2));
308-
vcpu_regs_get(vcpu, &regs2);
309-
TEST_ASSERT(!memcmp(&regs1, &regs2, sizeof(regs2)),
310-
"Unexpected register values after vcpu_load_state; rdi: %lx rsi: %lx",
311-
(ulong) regs2.rdi, (ulong) regs2.rsi);
312310
}
313311
done:
314312
kvm_vm_free(vm);

0 commit comments

Comments
 (0)