Skip to content

Commit 0383a8e

Browse files
committed
selftests: kvm: try getting XFD and XSAVE state out of sync
The host is allowed to set FPU state that includes a disabled xstate component. Check that this does not cause bad effects. Cc: stable@vger.kernel.org Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent a1025dc commit 0383a8e

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

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

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,17 @@ static void set_tilecfg(struct tile_config *cfg)
125125
}
126126

127127
enum {
128+
/* Retrieve TMM0 from guest, stash it for TEST_RESTORE_TILEDATA */
129+
TEST_SAVE_TILEDATA = 1,
130+
128131
/* Check TMM0 against tiledata */
129-
TEST_COMPARE_TILEDATA = 1,
132+
TEST_COMPARE_TILEDATA = 2,
133+
134+
/* Restore TMM0 from earlier save */
135+
TEST_RESTORE_TILEDATA = 4,
130136

131137
/* Full VM save/restore */
132-
TEST_SAVE_RESTORE = 2,
138+
TEST_SAVE_RESTORE = 8,
133139
};
134140

135141
static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg,
@@ -150,7 +156,16 @@ static void __attribute__((__flatten__)) guest_code(struct tile_config *amx_cfg,
150156
GUEST_SYNC(TEST_SAVE_RESTORE);
151157
/* Check save/restore when trap to userspace */
152158
__tileloadd(tiledata);
153-
GUEST_SYNC(TEST_COMPARE_TILEDATA | TEST_SAVE_RESTORE);
159+
GUEST_SYNC(TEST_SAVE_TILEDATA | TEST_COMPARE_TILEDATA | TEST_SAVE_RESTORE);
160+
161+
/* xfd=0x40000, disable amx tiledata */
162+
wrmsr(MSR_IA32_XFD, XFEATURE_MASK_XTILE_DATA);
163+
164+
/* host tries setting tiledata while guest XFD is set */
165+
GUEST_SYNC(TEST_RESTORE_TILEDATA);
166+
GUEST_SYNC(TEST_SAVE_RESTORE);
167+
168+
wrmsr(MSR_IA32_XFD, 0);
154169
__tilerelease();
155170
GUEST_SYNC(TEST_SAVE_RESTORE);
156171
/*
@@ -210,10 +225,10 @@ int main(int argc, char *argv[])
210225
struct kvm_vcpu *vcpu;
211226
struct kvm_vm *vm;
212227
struct kvm_x86_state *state;
228+
struct kvm_x86_state *tile_state = NULL;
213229
int xsave_restore_size;
214230
vm_vaddr_t amx_cfg, tiledata, xstate;
215231
struct ucall uc;
216-
u32 amx_offset;
217232
int ret;
218233

219234
/*
@@ -265,20 +280,27 @@ int main(int argc, char *argv[])
265280
/* NOT REACHED */
266281
case UCALL_SYNC:
267282
++iter;
283+
if (uc.args[1] & TEST_SAVE_TILEDATA) {
284+
fprintf(stderr, "GUEST_SYNC #%d, save tiledata\n", iter);
285+
tile_state = vcpu_save_state(vcpu);
286+
}
268287
if (uc.args[1] & TEST_COMPARE_TILEDATA) {
269288
fprintf(stderr, "GUEST_SYNC #%d, check TMM0 contents\n", iter);
270289

271290
/* Compacted mode, get amx offset by xsave area
272291
* size subtract 8K amx size.
273292
*/
274-
amx_offset = xsave_restore_size - NUM_TILES*TILE_SIZE;
275-
state = vcpu_save_state(vcpu);
276-
void *amx_start = (void *)state->xsave + amx_offset;
293+
u32 amx_offset = xsave_restore_size - NUM_TILES*TILE_SIZE;
294+
void *amx_start = (void *)tile_state->xsave + amx_offset;
277295
void *tiles_data = (void *)addr_gva2hva(vm, tiledata);
278296
/* Only check TMM0 register, 1 tile */
279297
ret = memcmp(amx_start, tiles_data, TILE_SIZE);
280298
TEST_ASSERT(ret == 0, "memcmp failed, ret=%d", ret);
281-
kvm_x86_state_cleanup(state);
299+
}
300+
if (uc.args[1] & TEST_RESTORE_TILEDATA) {
301+
fprintf(stderr, "GUEST_SYNC #%d, before KVM_SET_XSAVE\n", iter);
302+
vcpu_xsave_set(vcpu, tile_state->xsave);
303+
fprintf(stderr, "GUEST_SYNC #%d, after KVM_SET_XSAVE\n", iter);
282304
}
283305
if (uc.args[1] & TEST_SAVE_RESTORE) {
284306
fprintf(stderr, "GUEST_SYNC #%d, save/restore VM state\n", iter);

0 commit comments

Comments
 (0)