KVM: selftest: Add proper helpers for x86-specific save/restore ioctls
authorSean Christopherson <seanjc@google.com>
Thu, 2 Jun 2022 17:30:06 +0000 (10:30 -0700)
committerPaolo Bonzini <pbonzini@redhat.com>
Sat, 11 Jun 2022 15:46:29 +0000 (11:46 -0400)
Add helpers for the various one-off helpers used by x86's vCPU state
save/restore helpers, and convert the other open coded ioctl()s to use
existing helpers.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
tools/testing/selftests/kvm/include/x86_64/processor.h
tools/testing/selftests/kvm/lib/x86_64/processor.c

index 9145da0..0bb9ba9 100644 (file)
@@ -432,6 +432,60 @@ const struct kvm_msr_list *kvm_get_feature_msr_index_list(void);
 bool kvm_msr_is_in_save_restore_list(uint32_t msr_index);
 uint64_t kvm_get_feature_msr(uint64_t msr_index);
 
+static inline void vcpu_msrs_get(struct kvm_vm *vm, uint32_t vcpuid,
+                                struct kvm_msrs *msrs)
+{
+       int r = __vcpu_ioctl(vm, vcpuid, KVM_GET_MSRS, msrs);
+
+       TEST_ASSERT(r == msrs->nmsrs,
+                   "KVM_GET_MSRS failed, r: %i (failed on MSR %x)",
+                   r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index);
+}
+static inline void vcpu_msrs_set(struct kvm_vm *vm, uint32_t vcpuid,
+                                struct kvm_msrs *msrs)
+{
+       int r = __vcpu_ioctl(vm, vcpuid, KVM_SET_MSRS, msrs);
+
+       TEST_ASSERT(r == msrs->nmsrs,
+                   "KVM_GET_MSRS failed, r: %i (failed on MSR %x)",
+                   r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index);
+}
+static inline void vcpu_debugregs_get(struct kvm_vm *vm, uint32_t vcpuid,
+                                     struct kvm_debugregs *debugregs)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_GET_DEBUGREGS, debugregs);
+}
+static inline void vcpu_debugregs_set(struct kvm_vm *vm, uint32_t vcpuid,
+                                     struct kvm_debugregs *debugregs)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_SET_DEBUGREGS, debugregs);
+}
+static inline void vcpu_xsave_get(struct kvm_vm *vm, uint32_t vcpuid,
+                                 struct kvm_xsave *xsave)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_GET_XSAVE, xsave);
+}
+static inline void vcpu_xsave2_get(struct kvm_vm *vm, uint32_t vcpuid,
+                                  struct kvm_xsave *xsave)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_GET_XSAVE2, xsave);
+}
+static inline void vcpu_xsave_set(struct kvm_vm *vm, uint32_t vcpuid,
+                                 struct kvm_xsave *xsave)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_SET_XSAVE, xsave);
+}
+static inline void vcpu_xcrs_get(struct kvm_vm *vm, uint32_t vcpuid,
+                                struct kvm_xcrs *xcrs)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_GET_XCRS, xcrs);
+}
+static inline void vcpu_xcrs_set(struct kvm_vm *vm, uint32_t vcpuid,
+                                struct kvm_xcrs *xcrs)
+{
+       vcpu_ioctl(vm, vcpuid, KVM_SET_XCRS, xcrs);
+}
+
 struct kvm_cpuid2 *kvm_get_supported_cpuid(void);
 struct kvm_cpuid2 *vcpu_get_cpuid(struct kvm_vm *vm, uint32_t vcpuid);
 
index 8dfe40e..47bc84d 100644 (file)
@@ -814,13 +814,11 @@ uint64_t vcpu_get_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index)
                struct kvm_msrs header;
                struct kvm_msr_entry entry;
        } buffer = {};
-       int r;
 
        buffer.header.nmsrs = 1;
        buffer.entry.index = msr_index;
 
-       r = __vcpu_ioctl(vm, vcpuid, KVM_GET_MSRS, &buffer.header);
-       TEST_ASSERT(r == 1, KVM_IOCTL_ERROR(KVM_GET_MSRS, r));
+       vcpu_msrs_get(vm, vcpuid, &buffer.header);
 
        return buffer.entry.data;
 }
@@ -957,28 +955,26 @@ bool kvm_msr_is_in_save_restore_list(uint32_t msr_index)
        return false;
 }
 
-static int vcpu_save_xsave_state(struct kvm_vm *vm, struct vcpu *vcpu,
-                                struct kvm_x86_state *state)
+static void vcpu_save_xsave_state(struct kvm_vm *vm, uint32_t vcpuid,
+                                 struct kvm_x86_state *state)
 {
-       int size;
-
-       size = vm_check_cap(vm, KVM_CAP_XSAVE2);
-       if (!size)
-               size = sizeof(struct kvm_xsave);
+       int size = vm_check_cap(vm, KVM_CAP_XSAVE2);
 
-       state->xsave = malloc(size);
-       if (size == sizeof(struct kvm_xsave))
-               return ioctl(vcpu->fd, KVM_GET_XSAVE, state->xsave);
-       else
-               return ioctl(vcpu->fd, KVM_GET_XSAVE2, state->xsave);
+       if (size) {
+               state->xsave = malloc(size);
+               vcpu_xsave2_get(vm, vcpuid, state->xsave);
+       } else {
+               state->xsave = malloc(sizeof(struct kvm_xsave));
+               vcpu_xsave_get(vm, vcpuid, state->xsave);
+       }
 }
 
 struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid)
 {
        const struct kvm_msr_list *msr_list = kvm_get_msr_index_list();
-       struct vcpu *vcpu = vcpu_get(vm, vcpuid);
        struct kvm_x86_state *state;
-       int r, i;
+       int i;
+
        static int nested_size = -1;
 
        if (nested_size == -1) {
@@ -997,102 +993,54 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid)
        vcpu_run_complete_io(vm, vcpuid);
 
        state = malloc(sizeof(*state) + msr_list->nmsrs * sizeof(state->msrs.entries[0]));
-       r = ioctl(vcpu->fd, KVM_GET_VCPU_EVENTS, &state->events);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_VCPU_EVENTS, r: %i",
-                   r);
-
-       r = ioctl(vcpu->fd, KVM_GET_MP_STATE, &state->mp_state);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_MP_STATE, r: %i",
-                   r);
-
-       r = ioctl(vcpu->fd, KVM_GET_REGS, &state->regs);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_REGS, r: %i",
-                   r);
-
-       r = vcpu_save_xsave_state(vm, vcpu, state);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XSAVE, r: %i",
-                   r);
-
-       if (kvm_check_cap(KVM_CAP_XCRS)) {
-               r = ioctl(vcpu->fd, KVM_GET_XCRS, &state->xcrs);
-               TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XCRS, r: %i",
-                           r);
-       }
 
-       r = ioctl(vcpu->fd, KVM_GET_SREGS, &state->sregs);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_SREGS, r: %i",
-                   r);
+       vcpu_events_get(vm, vcpuid, &state->events);
+       vcpu_mp_state_get(vm, vcpuid, &state->mp_state);
+       vcpu_regs_get(vm, vcpuid, &state->regs);
+       vcpu_save_xsave_state(vm, vcpuid, state);
+
+       if (kvm_check_cap(KVM_CAP_XCRS))
+               vcpu_xcrs_get(vm, vcpuid, &state->xcrs);
+
+       vcpu_sregs_get(vm, vcpuid, &state->sregs);
 
        if (nested_size) {
                state->nested.size = sizeof(state->nested_);
-               r = ioctl(vcpu->fd, KVM_GET_NESTED_STATE, &state->nested);
-               TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_NESTED_STATE, r: %i",
-                           r);
+
+               vcpu_nested_state_get(vm, vcpuid, &state->nested);
                TEST_ASSERT(state->nested.size <= nested_size,
                            "Nested state size too big, %i (KVM_CHECK_CAP gave %i)",
                            state->nested.size, nested_size);
-       } else
+       } else {
                state->nested.size = 0;
+       }
 
        state->msrs.nmsrs = msr_list->nmsrs;
        for (i = 0; i < msr_list->nmsrs; i++)
                state->msrs.entries[i].index = msr_list->indices[i];
-       r = ioctl(vcpu->fd, KVM_GET_MSRS, &state->msrs);
-       TEST_ASSERT(r == msr_list->nmsrs, "Unexpected result from KVM_GET_MSRS, r: %i (failed MSR was 0x%x)",
-                   r, r == msr_list->nmsrs ? -1 : msr_list->indices[r]);
+       vcpu_msrs_get(vm, vcpuid, &state->msrs);
 
-       r = ioctl(vcpu->fd, KVM_GET_DEBUGREGS, &state->debugregs);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_DEBUGREGS, r: %i",
-                   r);
+       vcpu_debugregs_get(vm, vcpuid, &state->debugregs);
 
        return state;
 }
 
 void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_x86_state *state)
 {
-       struct vcpu *vcpu = vcpu_get(vm, vcpuid);
-       int r;
-
-       r = ioctl(vcpu->fd, KVM_SET_SREGS, &state->sregs);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_SREGS, r: %i",
-                   r);
-
-       r = ioctl(vcpu->fd, KVM_SET_MSRS, &state->msrs);
-       TEST_ASSERT(r == state->msrs.nmsrs,
-               "Unexpected result from KVM_SET_MSRS, r: %i (failed at %x)",
-               r, r == state->msrs.nmsrs ? -1 : state->msrs.entries[r].index);
-
-       if (kvm_check_cap(KVM_CAP_XCRS)) {
-               r = ioctl(vcpu->fd, KVM_SET_XCRS, &state->xcrs);
-               TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XCRS, r: %i",
-                           r);
-       }
+       vcpu_sregs_set(vm, vcpuid, &state->sregs);
+       vcpu_msrs_set(vm, vcpuid, &state->msrs);
 
-       r = ioctl(vcpu->fd, KVM_SET_XSAVE, state->xsave);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XSAVE, r: %i",
-                   r);
+       if (kvm_check_cap(KVM_CAP_XCRS))
+               vcpu_xcrs_set(vm, vcpuid, &state->xcrs);
 
-       r = ioctl(vcpu->fd, KVM_SET_VCPU_EVENTS, &state->events);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_VCPU_EVENTS, r: %i",
-                   r);
+       vcpu_xsave_set(vm, vcpuid,  state->xsave);
+       vcpu_events_set(vm, vcpuid, &state->events);
+       vcpu_mp_state_set(vm, vcpuid, &state->mp_state);
+       vcpu_debugregs_set(vm, vcpuid, &state->debugregs);
+       vcpu_regs_set(vm, vcpuid, &state->regs);
 
-       r = ioctl(vcpu->fd, KVM_SET_MP_STATE, &state->mp_state);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_MP_STATE, r: %i",
-                   r);
-
-       r = ioctl(vcpu->fd, KVM_SET_DEBUGREGS, &state->debugregs);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_DEBUGREGS, r: %i",
-                   r);
-
-       r = ioctl(vcpu->fd, KVM_SET_REGS, &state->regs);
-       TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_REGS, r: %i",
-                   r);
-
-       if (state->nested.size) {
-               r = ioctl(vcpu->fd, KVM_SET_NESTED_STATE, &state->nested);
-               TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_NESTED_STATE, r: %i",
-                           r);
-       }
+       if (state->nested.size)
+               vcpu_nested_state_set(vm, vcpuid, &state->nested);
 }
 
 void kvm_x86_state_cleanup(struct kvm_x86_state *state)