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@xxxxxxxxxx> --- .../selftests/kvm/include/x86_64/processor.h | 54 ++++++++ .../selftests/kvm/lib/x86_64/processor.c | 126 +++++------------- 2 files changed, 91 insertions(+), 89 deletions(-) diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index e4268432cfe8..1d46d60bb480 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -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); diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index 9268537f9bd7..5c92e96300c5 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -815,13 +815,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; } @@ -958,28 +956,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; + int size = vm_check_cap(vm, KVM_CAP_XSAVE2); - size = vm_check_cap(vm, KVM_CAP_XSAVE2); - if (!size) - size = sizeof(struct kvm_xsave); - - 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) { @@ -998,102 +994,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); + 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); - r = ioctl(vcpu->fd, KVM_GET_REGS, &state->regs); - TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_REGS, r: %i", - r); + if (kvm_check_cap(KVM_CAP_XCRS)) + vcpu_xcrs_get(vm, vcpuid, &state->xcrs); - 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_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; + vcpu_sregs_set(vm, vcpuid, &state->sregs); + vcpu_msrs_set(vm, vcpuid, &state->msrs); - r = ioctl(vcpu->fd, KVM_SET_SREGS, &state->sregs); - TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_SREGS, r: %i", - r); + if (kvm_check_cap(KVM_CAP_XCRS)) + vcpu_xcrs_set(vm, vcpuid, &state->xcrs); - 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); + 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); - 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); - } - - r = ioctl(vcpu->fd, KVM_SET_XSAVE, state->xsave); - TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XSAVE, r: %i", - r); - - r = ioctl(vcpu->fd, KVM_SET_VCPU_EVENTS, &state->events); - TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_VCPU_EVENTS, r: %i", - r); - - 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) -- 2.36.1.255.ge46751e96f-goog