>From 9f69a3c7912b3ab855567960f9a574b98355cfba Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 29 Dec 2025 10:45:43 -0800 Subject: [PATCH 3/4] KVM: selftests: Add test to verify KVM allows loading XTILE data with XFD=1 Extend the AMX test to verify that loading guest state via KVM_SET_XSAVE for a disabled component, i.e. with XSTATE_BV[i]=1 and XFD[i]=1, doesn't cause KVM to explode. To load the "bad" state, load XSAVE state from a snapshot taken before setting XFD. Take care to restore *only* XSAVE state, as restoring GPRs will corrupt the guest and restoring MSRs will make the test useless (because the test would revert to XFD=0). Signed-off-by: Paolo Bonzini Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- tools/testing/selftests/kvm/x86/amx_test.c | 44 ++++++++++++++++++---- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/tools/testing/selftests/kvm/x86/amx_test.c b/tools/testing/selftests/kvm/x86/amx_test.c index ab6d8748d7b8..1d5fffddc625 100644 --- a/tools/testing/selftests/kvm/x86/amx_test.c +++ b/tools/testing/selftests/kvm/x86/amx_test.c @@ -128,6 +128,7 @@ enum amx_test_syncs { AMX_SYNC_SAVE = BIT(0), AMX_SYNC_RESTORE = BIT(1), AMX_SYNC_CHECK_TILEDATA = BIT(2), + AMX_SYNC_RESTORE_XSTATE = BIT(3), AMX_SYNC_SAVE_RESTORE = AMX_SYNC_SAVE | AMX_SYNC_RESTORE, }; @@ -165,11 +166,19 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg, set_tilecfg(amx_cfg); __ldtilecfg(amx_cfg); __tileloadd(tiledata); - GUEST_SYNC(AMX_SYNC_SAVE_RESTORE | AMX_SYNC_CHECK_TILEDATA); + + /* Save state and check tile data, but don't restore just yet. */ + GUEST_SYNC(AMX_SYNC_SAVE | AMX_SYNC_CHECK_TILEDATA); /* xfd=0x40000, disable amx tiledata */ wrmsr(MSR_IA32_XFD, XFEATURE_MASK_XTILE_DATA); + /* + * Restore the previously saved XSTATE so that the host tries setting + * tiledata while guest XFD is set. + */ + GUEST_SYNC(AMX_SYNC_RESTORE_XSTATE); + /* * XTILEDATA is cleared in xstate_bv but set in xcomp_bv, this property * remains the same even when amx tiledata is disabled by IA32_XFD. @@ -289,20 +298,41 @@ int main(int argc, char *argv[]) TEST_ASSERT(ret == 0, "memcmp failed, ret=%d", ret); } - - if (!(uc.args[1] & AMX_SYNC_RESTORE)) + if (!(uc.args[1] & (AMX_SYNC_RESTORE | AMX_SYNC_RESTORE_XSTATE))) continue; TEST_ASSERT(state, "RESTORE without a SAVE"); + TEST_ASSERT(!(uc.args[1] & AMX_SYNC_RESTORE) || + !(uc.args[1] & AMX_SYNC_RESTORE_XSTATE), + "Only one type of restore is supported per sync"); + memset(®s1, 0, sizeof(regs1)); vcpu_regs_get(vcpu, ®s1); - kvm_vm_release(vm); + /* + * Restore XSTATE from a previous snapshot, e.g. to verify that + * KVM allows loading XTILE data when it's disabled via XFD. + */ + if (uc.args[1] & AMX_SYNC_RESTORE_XSTATE) + vcpu_xsave_set(vcpu, state->xsave); + + if (uc.args[1] & AMX_SYNC_RESTORE) { + /* + * Restoring *all* state from a previous snapshot will + * corrupt the guest, e.g. GPRs and RIP, and send it + * into the weeds. + */ + TEST_ASSERT(uc.args[1] & AMX_SYNC_SAVE, + "Restoring an old snapshot will corrupt the guest"); + + kvm_vm_release(vm); + + /* Restore state in a new VM. */ + vcpu = vm_recreate_with_one_vcpu(vm); + vcpu_load_state(vcpu, state); + } - /* Restore state in a new VM. */ - vcpu = vm_recreate_with_one_vcpu(vm); - vcpu_load_state(vcpu, state); kvm_x86_state_cleanup(state); state = NULL; -- 2.52.0.351.gbe84eed79e-goog