[PATCH 3/4] KVM: selftests: Add test to verify KVM allows loading XTILE data with XFD=1
From: Paolo Bonzini
Date: Mon Dec 29 2025 - 13:45:43 EST
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 <pbonzini@xxxxxxxxxx>
Co-developed-by: Sean Christopherson <seanjc@xxxxxxxxxx>
Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
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
--wIbW/lf6W61RV1YR
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment;
filename="0004-KVM-selftests-Verify-TILELOADD-actually-NM-faults-wh.patch"