>From 4031198ac76584a0e906e36796a3b41f6e428d1b Mon Sep 17 00:00:00 2001 From: Sean Christopherson Date: Wed, 24 Dec 2025 01:12:47 +0100 Subject: [PATCH 1/4] KVM: selftests: Use named sync actions in AMX test instead of arbitrary numbers 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). Opportunistically delete all prints to stderr as they aren't helpful without the arbitrary numbers. Using named actions will make it easier to extend the test to validate more obscure/specific scenarios without creating a maintenance nightmare. Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/x86/amx_test.c | 88 +++++++++++----------- 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/amx_test.c b/tools/testing/selftests/kvm/x86/amx_test.c index f4ce5a185a7d..3bcb10f26a70 100644 --- a/tools/testing/selftests/kvm/x86/amx_test.c +++ b/tools/testing/selftests/kvm/x86/amx_test.c @@ -124,6 +124,14 @@ static void set_tilecfg(struct tile_config *cfg) } } +enum amx_test_syncs { + AMX_SYNC_SAVE = BIT(0), + AMX_SYNC_RESTORE = BIT(1), + AMX_SYNC_CHECK_TILEDATA = BIT(2), + + AMX_SYNC_SAVE_RESTORE = AMX_SYNC_SAVE | AMX_SYNC_RESTORE, +}; + static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg, struct tile_data *tiledata, struct xstate *xstate) @@ -131,20 +139,20 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg, GUEST_ASSERT(this_cpu_has(X86_FEATURE_XSAVE) && this_cpu_has(X86_FEATURE_OSXSAVE)); check_xtile_info(); - GUEST_SYNC(1); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); /* xfd=0, enable amx */ wrmsr(MSR_IA32_XFD, 0); - GUEST_SYNC(2); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == 0); set_tilecfg(amx_cfg); __ldtilecfg(amx_cfg); - GUEST_SYNC(3); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); /* Check save/restore when trap to userspace */ __tileloadd(tiledata); - GUEST_SYNC(4); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE | AMX_SYNC_CHECK_TILEDATA); __tilerelease(); - GUEST_SYNC(5); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); /* * After XSAVEC, XTILEDATA is cleared in the xstate_bv but is set in * the xcomp_bv. @@ -166,13 +174,13 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg, GUEST_ASSERT(!(xstate->header.xstate_bv & XFEATURE_MASK_XTILE_DATA)); GUEST_ASSERT((xstate->header.xcomp_bv & XFEATURE_MASK_XTILE_DATA)); - GUEST_SYNC(6); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == XFEATURE_MASK_XTILE_DATA); set_tilecfg(amx_cfg); __ldtilecfg(amx_cfg); /* Trigger #NM exception */ __tileloadd(tiledata); - GUEST_SYNC(10); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE | AMX_SYNC_CHECK_TILEDATA); GUEST_DONE(); } @@ -180,18 +188,18 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg, void guest_nm_handler(struct ex_regs *regs) { /* Check if #NM is triggered by XFEATURE_MASK_XTILE_DATA */ - GUEST_SYNC(7); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); GUEST_ASSERT(!(get_cr0() & X86_CR0_TS)); GUEST_ASSERT(rdmsr(MSR_IA32_XFD_ERR) == XFEATURE_MASK_XTILE_DATA); GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == XFEATURE_MASK_XTILE_DATA); - GUEST_SYNC(8); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); GUEST_ASSERT(rdmsr(MSR_IA32_XFD_ERR) == XFEATURE_MASK_XTILE_DATA); GUEST_ASSERT(rdmsr(MSR_IA32_XFD) == XFEATURE_MASK_XTILE_DATA); /* Clear xfd_err */ wrmsr(MSR_IA32_XFD_ERR, 0); /* xfd=0, enable amx */ wrmsr(MSR_IA32_XFD, 0); - GUEST_SYNC(9); + GUEST_SYNC(AMX_SYNC_SAVE_RESTORE); } int main(int argc, char *argv[]) @@ -199,11 +207,10 @@ int main(int argc, char *argv[]) struct kvm_regs regs1, regs2; struct kvm_vcpu *vcpu; struct kvm_vm *vm; - struct kvm_x86_state *state; + struct kvm_x86_state *state = NULL; int xsave_restore_size; vm_vaddr_t amx_cfg, tiledata, xstate; struct ucall uc; - u32 amx_offset; int ret; /* @@ -253,47 +260,35 @@ int main(int argc, char *argv[]) REPORT_GUEST_ASSERT(uc); /* NOT REACHED */ case UCALL_SYNC: - switch (uc.args[1]) { - case 1: - case 2: - case 3: - case 5: - case 6: - case 7: - case 8: - fprintf(stderr, "GUEST_SYNC(%ld)\n", uc.args[1]); - break; - case 4: - case 10: - fprintf(stderr, - "GUEST_SYNC(%ld), check save/restore status\n", uc.args[1]); - - /* Compacted mode, get amx offset by xsave area - * size subtract 8K amx size. - */ - amx_offset = xsave_restore_size - NUM_TILES*TILE_SIZE; - state = vcpu_save_state(vcpu); - void *amx_start = (void *)state->xsave + amx_offset; - void *tiles_data = (void *)addr_gva2hva(vm, tiledata); - /* Only check TMM0 register, 1 tile */ - ret = memcmp(amx_start, tiles_data, TILE_SIZE); - TEST_ASSERT(ret == 0, "memcmp failed, ret=%d", ret); - kvm_x86_state_cleanup(state); - break; - case 9: - fprintf(stderr, - "GUEST_SYNC(%ld), #NM exception and enable amx\n", uc.args[1]); - break; - } break; case UCALL_DONE: - fprintf(stderr, "UCALL_DONE\n"); goto done; default: TEST_FAIL("Unknown ucall %lu", uc.cmd); } - state = vcpu_save_state(vcpu); + if (uc.args[1] & AMX_SYNC_SAVE) + state = vcpu_save_state(vcpu); + + if (uc.args[1] & AMX_SYNC_CHECK_TILEDATA) { + /* Compacted mode, get amx offset by xsave area + * size subtract 8K amx size. + */ + u32 amx_offset = xsave_restore_size - NUM_TILES*TILE_SIZE; + void *amx_start = (void *)state->xsave + amx_offset; + void *tiles_data = (void *)addr_gva2hva(vm, tiledata); + + /* Only check TMM0 register, 1 tile */ + ret = memcmp(amx_start, tiles_data, TILE_SIZE); + TEST_ASSERT(ret == 0, "memcmp failed, ret=%d", ret); + } + + + if (!(uc.args[1] & AMX_SYNC_RESTORE)) + continue; + + TEST_ASSERT(state, "RESTORE without a SAVE"); + memset(®s1, 0, sizeof(regs1)); vcpu_regs_get(vcpu, ®s1); @@ -303,6 +298,7 @@ int main(int argc, char *argv[]) vcpu = vm_recreate_with_one_vcpu(vm); vcpu_load_state(vcpu, state); kvm_x86_state_cleanup(state); + state = NULL; memset(®s2, 0, sizeof(regs2)); vcpu_regs_get(vcpu, ®s2); base-commit: d5228761ade7dda4bd54d273374041c15041c29e -- 2.52.0.351.gbe84eed79e-goog