17
17
#include <sys/ioctl.h>
18
18
#include <pthread.h>
19
19
20
+ #include "kvm_test_harness.h"
20
21
#include "test_util.h"
21
22
#include "kvm_util.h"
22
23
#include "processor.h"
@@ -41,6 +42,8 @@ void guest_code(void)
41
42
: "rax" , "rbx" );
42
43
}
43
44
45
+ KVM_ONE_VCPU_TEST_SUITE (sync_regs_test );
46
+
44
47
static void compare_regs (struct kvm_regs * left , struct kvm_regs * right )
45
48
{
46
49
#define REG_COMPARE (reg ) \
@@ -152,18 +155,15 @@ static noinline void *race_sregs_cr4(void *arg)
152
155
return NULL ;
153
156
}
154
157
155
- static void race_sync_regs (void * racer )
158
+ static void race_sync_regs (struct kvm_vcpu * vcpu , void * racer )
156
159
{
157
160
const time_t TIMEOUT = 2 ; /* seconds, roughly */
158
161
struct kvm_x86_state * state ;
159
162
struct kvm_translation tr ;
160
- struct kvm_vcpu * vcpu ;
161
163
struct kvm_run * run ;
162
- struct kvm_vm * vm ;
163
164
pthread_t thread ;
164
165
time_t t ;
165
166
166
- vm = vm_create_with_one_vcpu (& vcpu , guest_code );
167
167
run = vcpu -> run ;
168
168
169
169
run -> kvm_valid_regs = KVM_SYNC_X86_SREGS ;
@@ -205,26 +205,12 @@ static void race_sync_regs(void *racer)
205
205
TEST_ASSERT_EQ (pthread_join (thread , NULL ), 0 );
206
206
207
207
kvm_x86_state_cleanup (state );
208
- kvm_vm_free (vm );
209
208
}
210
209
211
- int main ( int argc , char * argv [] )
210
+ KVM_ONE_VCPU_TEST ( sync_regs_test , read_invalid , guest_code )
212
211
{
213
- struct kvm_vcpu * vcpu ;
214
- struct kvm_vm * vm ;
215
- struct kvm_run * run ;
216
- struct kvm_regs regs ;
217
- struct kvm_sregs sregs ;
218
- struct kvm_vcpu_events events ;
219
- int rv , cap ;
220
-
221
- cap = kvm_check_cap (KVM_CAP_SYNC_REGS );
222
- TEST_REQUIRE ((cap & TEST_SYNC_FIELDS ) == TEST_SYNC_FIELDS );
223
- TEST_REQUIRE (!(cap & INVALID_SYNC_FIELD ));
224
-
225
- vm = vm_create_with_one_vcpu (& vcpu , guest_code );
226
-
227
- run = vcpu -> run ;
212
+ struct kvm_run * run = vcpu -> run ;
213
+ int rv ;
228
214
229
215
/* Request reading invalid register set from VCPU. */
230
216
run -> kvm_valid_regs = INVALID_SYNC_FIELD ;
@@ -240,6 +226,12 @@ int main(int argc, char *argv[])
240
226
"Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n" ,
241
227
rv );
242
228
run -> kvm_valid_regs = 0 ;
229
+ }
230
+
231
+ KVM_ONE_VCPU_TEST (sync_regs_test , set_invalid , guest_code )
232
+ {
233
+ struct kvm_run * run = vcpu -> run ;
234
+ int rv ;
243
235
244
236
/* Request setting invalid register set into VCPU. */
245
237
run -> kvm_dirty_regs = INVALID_SYNC_FIELD ;
@@ -255,6 +247,14 @@ int main(int argc, char *argv[])
255
247
"Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n" ,
256
248
rv );
257
249
run -> kvm_dirty_regs = 0 ;
250
+ }
251
+
252
+ KVM_ONE_VCPU_TEST (sync_regs_test , req_and_verify_all_valid , guest_code )
253
+ {
254
+ struct kvm_run * run = vcpu -> run ;
255
+ struct kvm_vcpu_events events ;
256
+ struct kvm_sregs sregs ;
257
+ struct kvm_regs regs ;
258
258
259
259
/* Request and verify all valid register sets. */
260
260
/* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */
@@ -270,6 +270,19 @@ int main(int argc, char *argv[])
270
270
271
271
vcpu_events_get (vcpu , & events );
272
272
compare_vcpu_events (& events , & run -> s .regs .events );
273
+ }
274
+
275
+ KVM_ONE_VCPU_TEST (sync_regs_test , set_and_verify_various , guest_code )
276
+ {
277
+ struct kvm_run * run = vcpu -> run ;
278
+ struct kvm_vcpu_events events ;
279
+ struct kvm_sregs sregs ;
280
+ struct kvm_regs regs ;
281
+
282
+ /* Run once to get register set */
283
+ run -> kvm_valid_regs = TEST_SYNC_FIELDS ;
284
+ vcpu_run (vcpu );
285
+ TEST_ASSERT_KVM_EXIT_REASON (vcpu , KVM_EXIT_IO );
273
286
274
287
/* Set and verify various register values. */
275
288
run -> s .regs .regs .rbx = 0xBAD1DEA ;
@@ -295,6 +308,11 @@ int main(int argc, char *argv[])
295
308
296
309
vcpu_events_get (vcpu , & events );
297
310
compare_vcpu_events (& events , & run -> s .regs .events );
311
+ }
312
+
313
+ KVM_ONE_VCPU_TEST (sync_regs_test , clear_kvm_dirty_regs_bits , guest_code )
314
+ {
315
+ struct kvm_run * run = vcpu -> run ;
298
316
299
317
/* Clear kvm_dirty_regs bits, verify new s.regs values are
300
318
* overwritten with existing guest values.
@@ -307,6 +325,17 @@ int main(int argc, char *argv[])
307
325
TEST_ASSERT (run -> s .regs .regs .rbx != 0xDEADBEEF ,
308
326
"rbx sync regs value incorrect 0x%llx." ,
309
327
run -> s .regs .regs .rbx );
328
+ }
329
+
330
+ KVM_ONE_VCPU_TEST (sync_regs_test , clear_kvm_valid_and_dirty_regs , guest_code )
331
+ {
332
+ struct kvm_run * run = vcpu -> run ;
333
+ struct kvm_regs regs ;
334
+
335
+ /* Run once to get register set */
336
+ run -> kvm_valid_regs = TEST_SYNC_FIELDS ;
337
+ vcpu_run (vcpu );
338
+ TEST_ASSERT_KVM_EXIT_REASON (vcpu , KVM_EXIT_IO );
310
339
311
340
/* Clear kvm_valid_regs bits and kvm_dirty_bits.
312
341
* Verify s.regs values are not overwritten with existing guest values
@@ -327,6 +356,17 @@ int main(int argc, char *argv[])
327
356
TEST_ASSERT (regs .rbx == 0xBAC0 + 1 ,
328
357
"rbx guest value incorrect 0x%llx." ,
329
358
regs .rbx );
359
+ }
360
+
361
+ KVM_ONE_VCPU_TEST (sync_regs_test , clear_kvm_valid_regs_bits , guest_code )
362
+ {
363
+ struct kvm_run * run = vcpu -> run ;
364
+ struct kvm_regs regs ;
365
+
366
+ /* Run once to get register set */
367
+ run -> kvm_valid_regs = TEST_SYNC_FIELDS ;
368
+ vcpu_run (vcpu );
369
+ TEST_ASSERT_KVM_EXIT_REASON (vcpu , KVM_EXIT_IO );
330
370
331
371
/* Clear kvm_valid_regs bits. Verify s.regs values are not overwritten
332
372
* with existing guest values but that guest values are overwritten
@@ -344,12 +384,30 @@ int main(int argc, char *argv[])
344
384
TEST_ASSERT (regs .rbx == 0xBBBB + 1 ,
345
385
"rbx guest value incorrect 0x%llx." ,
346
386
regs .rbx );
387
+ }
388
+
389
+ KVM_ONE_VCPU_TEST (sync_regs_test , race_cr4 , guest_code )
390
+ {
391
+ race_sync_regs (vcpu , race_sregs_cr4 );
392
+ }
393
+
394
+ KVM_ONE_VCPU_TEST (sync_regs_test , race_exc , guest_code )
395
+ {
396
+ race_sync_regs (vcpu , race_events_exc );
397
+ }
347
398
348
- kvm_vm_free (vm );
399
+ KVM_ONE_VCPU_TEST (sync_regs_test , race_inj_pen , guest_code )
400
+ {
401
+ race_sync_regs (vcpu , race_events_inj_pen );
402
+ }
403
+
404
+ int main (int argc , char * argv [])
405
+ {
406
+ int cap ;
349
407
350
- race_sync_regs ( race_sregs_cr4 );
351
- race_sync_regs ( race_events_exc );
352
- race_sync_regs ( race_events_inj_pen );
408
+ cap = kvm_check_cap ( KVM_CAP_SYNC_REGS );
409
+ TEST_REQUIRE (( cap & TEST_SYNC_FIELDS ) == TEST_SYNC_FIELDS );
410
+ TEST_REQUIRE (!( cap & INVALID_SYNC_FIELD ) );
353
411
354
- return 0 ;
412
+ return test_harness_run ( argc , argv ) ;
355
413
}
0 commit comments