@@ -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+
127135static 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
180190void 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
197207int 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 }
313311done :
314312 kvm_vm_free (vm );
0 commit comments