1717#include <sys/ioctl.h>
1818#include <pthread.h>
1919
20+ #include "kvm_test_harness.h"
2021#include "test_util.h"
2122#include "kvm_util.h"
2223#include "processor.h"
@@ -41,6 +42,8 @@ void guest_code(void)
4142 : "rax" , "rbx" );
4243}
4344
45+ KVM_ONE_VCPU_TEST_SUITE (sync_regs_test );
46+
4447static void compare_regs (struct kvm_regs * left , struct kvm_regs * right )
4548{
4649#define REG_COMPARE (reg ) \
@@ -152,18 +155,15 @@ static noinline void *race_sregs_cr4(void *arg)
152155 return NULL ;
153156}
154157
155- static void race_sync_regs (void * racer )
158+ static void race_sync_regs (struct kvm_vcpu * vcpu , void * racer )
156159{
157160 const time_t TIMEOUT = 2 ; /* seconds, roughly */
158161 struct kvm_x86_state * state ;
159162 struct kvm_translation tr ;
160- struct kvm_vcpu * vcpu ;
161163 struct kvm_run * run ;
162- struct kvm_vm * vm ;
163164 pthread_t thread ;
164165 time_t t ;
165166
166- vm = vm_create_with_one_vcpu (& vcpu , guest_code );
167167 run = vcpu -> run ;
168168
169169 run -> kvm_valid_regs = KVM_SYNC_X86_SREGS ;
@@ -205,26 +205,12 @@ static void race_sync_regs(void *racer)
205205 TEST_ASSERT_EQ (pthread_join (thread , NULL ), 0 );
206206
207207 kvm_x86_state_cleanup (state );
208- kvm_vm_free (vm );
209208}
210209
211- int main ( int argc , char * argv [] )
210+ KVM_ONE_VCPU_TEST ( sync_regs_test , read_invalid , guest_code )
212211{
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 ;
228214
229215 /* Request reading invalid register set from VCPU. */
230216 run -> kvm_valid_regs = INVALID_SYNC_FIELD ;
@@ -240,6 +226,12 @@ int main(int argc, char *argv[])
240226 "Invalid kvm_valid_regs did not cause expected KVM_RUN error: %d\n" ,
241227 rv );
242228 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 ;
243235
244236 /* Request setting invalid register set into VCPU. */
245237 run -> kvm_dirty_regs = INVALID_SYNC_FIELD ;
@@ -255,6 +247,14 @@ int main(int argc, char *argv[])
255247 "Invalid kvm_dirty_regs did not cause expected KVM_RUN error: %d\n" ,
256248 rv );
257249 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 ;
258258
259259 /* Request and verify all valid register sets. */
260260 /* TODO: BUILD TIME CHECK: TEST_ASSERT(KVM_SYNC_X86_NUM_FIELDS != 3); */
@@ -270,6 +270,19 @@ int main(int argc, char *argv[])
270270
271271 vcpu_events_get (vcpu , & events );
272272 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 );
273286
274287 /* Set and verify various register values. */
275288 run -> s .regs .regs .rbx = 0xBAD1DEA ;
@@ -295,6 +308,11 @@ int main(int argc, char *argv[])
295308
296309 vcpu_events_get (vcpu , & events );
297310 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 ;
298316
299317 /* Clear kvm_dirty_regs bits, verify new s.regs values are
300318 * overwritten with existing guest values.
@@ -307,6 +325,17 @@ int main(int argc, char *argv[])
307325 TEST_ASSERT (run -> s .regs .regs .rbx != 0xDEADBEEF ,
308326 "rbx sync regs value incorrect 0x%llx." ,
309327 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 );
310339
311340 /* Clear kvm_valid_regs bits and kvm_dirty_bits.
312341 * Verify s.regs values are not overwritten with existing guest values
@@ -327,6 +356,17 @@ int main(int argc, char *argv[])
327356 TEST_ASSERT (regs .rbx == 0xBAC0 + 1 ,
328357 "rbx guest value incorrect 0x%llx." ,
329358 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 );
330370
331371 /* Clear kvm_valid_regs bits. Verify s.regs values are not overwritten
332372 * with existing guest values but that guest values are overwritten
@@ -344,12 +384,30 @@ int main(int argc, char *argv[])
344384 TEST_ASSERT (regs .rbx == 0xBBBB + 1 ,
345385 "rbx guest value incorrect 0x%llx." ,
346386 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+ }
347398
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 ;
349407
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 ) );
353411
354- return 0 ;
412+ return test_harness_run ( argc , argv ) ;
355413}
0 commit comments