KVM: selftests: Sync stage before VM is freed in hypercalls test
authorSean Christopherson <seanjc@google.com>
Thu, 2 Jun 2022 00:27:51 +0000 (17:27 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Sat, 11 Jun 2022 15:47:10 +0000 (11:47 -0400)
Sync the next stage using the VM before said VM is potentially freed by
the TEST_STAGE_HVC_IFACE_FEAT_DISABLED stage.

Opportunistically take a double pointer in anticipation of also having to
set the new vCPU pointer once the test stops hardcoding '0' everywhere.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
tools/testing/selftests/kvm/aarch64/hypercalls.c

index b1f99e786d05b66d5fdff8584e5956aaf9148372..44ca840e8219cae2e28c900f3be067bd1009d9f4 100644 (file)
@@ -246,32 +246,31 @@ static struct kvm_vm *test_vm_create(void)
        return vm;
 }
 
-static struct kvm_vm *test_guest_stage(struct kvm_vm *vm)
+static void test_guest_stage(struct kvm_vm **vm)
 {
-       struct kvm_vm *ret_vm = vm;
+       int prev_stage = stage;
 
-       pr_debug("Stage: %d\n", stage);
+       pr_debug("Stage: %d\n", prev_stage);
 
-       switch (stage) {
+       /* Sync the stage early, the VM might be freed below. */
+       stage++;
+       sync_global_to_guest(*vm, stage);
+
+       switch (prev_stage) {
        case TEST_STAGE_REG_IFACE:
-               test_fw_regs_after_vm_start(vm);
+               test_fw_regs_after_vm_start(*vm);
                break;
        case TEST_STAGE_HVC_IFACE_FEAT_DISABLED:
                /* Start a new VM so that all the features are now enabled by default */
-               kvm_vm_free(vm);
-               ret_vm = test_vm_create();
+               kvm_vm_free(*vm);
+               *vm = test_vm_create();
                break;
        case TEST_STAGE_HVC_IFACE_FEAT_ENABLED:
        case TEST_STAGE_HVC_IFACE_FALSE_INFO:
                break;
        default:
-               TEST_FAIL("Unknown test stage: %d\n", stage);
+               TEST_FAIL("Unknown test stage: %d\n", prev_stage);
        }
-
-       stage++;
-       sync_global_to_guest(vm, stage);
-
-       return ret_vm;
 }
 
 static void test_run(void)
@@ -289,7 +288,7 @@ static void test_run(void)
 
                switch (get_ucall(vm, 0, &uc)) {
                case UCALL_SYNC:
-                       vm = test_guest_stage(vm);
+                       test_guest_stage(&vm);
                        break;
                case UCALL_DONE:
                        guest_done = true;