Fix vcpu_{save,load}_state() by adding APIC state into kvm_x86_state and properly save/restore it in vcpu_{save,load}_state(). When vcpu resets, APIC state become software disabled in kernel and thus the corresponding vCPU is not able to receive posted interrupts [1]. So, add APIC save/restore in userspace in selftest library code. [1] commit 97222cc83163 ("KVM: Emulate local APIC in kernel"). Cc: Jim Mattson <jmattson@xxxxxxxxxx> Signed-off-by: Mingwei Zhang <mizhang@xxxxxxxxxx> --- tools/testing/selftests/kvm/include/kvm_util_base.h | 10 ++++++++++ tools/testing/selftests/kvm/include/x86_64/processor.h | 1 + tools/testing/selftests/kvm/lib/x86_64/processor.c | 2 ++ 3 files changed, 13 insertions(+) diff --git a/tools/testing/selftests/kvm/include/kvm_util_base.h b/tools/testing/selftests/kvm/include/kvm_util_base.h index 24fde97f6121..ac883b8eab57 100644 --- a/tools/testing/selftests/kvm/include/kvm_util_base.h +++ b/tools/testing/selftests/kvm/include/kvm_util_base.h @@ -457,6 +457,16 @@ static inline void vcpu_fpu_set(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu) vcpu_ioctl(vcpu, KVM_SET_FPU, fpu); } +static inline void vcpu_apic_get(struct kvm_vcpu *vcpu, struct kvm_lapic_state *apic) +{ + vcpu_ioctl(vcpu, KVM_GET_LAPIC, apic); +} + +static inline void vcpu_apic_set(struct kvm_vcpu *vcpu, struct kvm_lapic_state *apic) +{ + vcpu_ioctl(vcpu, KVM_SET_LAPIC, apic); +} + static inline int __vcpu_get_reg(struct kvm_vcpu *vcpu, uint64_t id, void *addr) { struct kvm_one_reg reg = { .id = id, .addr = (uint64_t)addr }; diff --git a/tools/testing/selftests/kvm/include/x86_64/processor.h b/tools/testing/selftests/kvm/include/x86_64/processor.h index 45edf45821d0..bf5f874709a4 100644 --- a/tools/testing/selftests/kvm/include/x86_64/processor.h +++ b/tools/testing/selftests/kvm/include/x86_64/processor.h @@ -225,6 +225,7 @@ struct kvm_x86_state { struct kvm_nested_state nested; char nested_[16384]; }; + struct kvm_lapic_state apic; struct kvm_msrs msrs; }; diff --git a/tools/testing/selftests/kvm/lib/x86_64/processor.c b/tools/testing/selftests/kvm/lib/x86_64/processor.c index f35626df1dea..d18da71654b6 100644 --- a/tools/testing/selftests/kvm/lib/x86_64/processor.c +++ b/tools/testing/selftests/kvm/lib/x86_64/processor.c @@ -980,6 +980,7 @@ struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu) vcpu_msrs_get(vcpu, &state->msrs); vcpu_debugregs_get(vcpu, &state->debugregs); + vcpu_apic_get(vcpu, &state->apic); return state; } @@ -997,6 +998,7 @@ void vcpu_load_state(struct kvm_vcpu *vcpu, struct kvm_x86_state *state) vcpu_mp_state_set(vcpu, &state->mp_state); vcpu_debugregs_set(vcpu, &state->debugregs); vcpu_regs_set(vcpu, &state->regs); + vcpu_apic_set(vcpu, &state->apic); if (state->nested.size) vcpu_nested_state_set(vcpu, &state->nested); -- 2.37.1.455.g008518b4e5-goog