qemu call kvm_get_vcpu_events, and kernel return sipi_vector always 0, never valid when reporting to user space. But qemu call kvm_put_vcpu_events will make sipi_vector in kernel be 0. This will accidently modify sipi_vector when sipi_vector in kernel is not 0. Signed-off-by: Peng Hao <peng.hao2@xxxxxxxxxx> Reviewed-by: Liu Yi <liu.yi24@xxxxxxxxxx> --- target/i386/kvm.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/target/i386/kvm.c b/target/i386/kvm.c index f84a49d..7abb533 100644 --- a/target/i386/kvm.c +++ b/target/i386/kvm.c @@ -2444,8 +2444,12 @@ static int kvm_put_vcpu_events(X86CPU *cpu, int level) } if (level >= KVM_PUT_RESET_STATE) { - events.flags |= - KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR; + if (env->mp_state == KVM_MP_STATE_SIPI_RECEIVED) { + events.flags |= + KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR; + } else { + events.flags |= KVM_VCPUEVENT_VALID_NMI_PENDING; + } } return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_VCPU_EVENTS, &events); @@ -2633,6 +2637,10 @@ int kvm_arch_put_registers(CPUState *cpu, int level) if (ret < 0) { return ret; } + ret = kvm_put_vcpu_events(x86_cpu, level); + if (ret < 0) { + return ret; + } if (level >= KVM_PUT_RESET_STATE) { ret = kvm_put_mp_state(x86_cpu); if (ret < 0) { @@ -2644,11 +2652,6 @@ int kvm_arch_put_registers(CPUState *cpu, int level) if (ret < 0) { return ret; } - - ret = kvm_put_vcpu_events(x86_cpu, level); - if (ret < 0) { - return ret; - } ret = kvm_put_debugregs(x86_cpu); if (ret < 0) { return ret; @@ -2688,15 +2691,15 @@ int kvm_arch_get_registers(CPUState *cs) if (ret < 0) { goto out; } - ret = kvm_get_mp_state(cpu); + ret = kvm_get_vcpu_events(cpu); if (ret < 0) { goto out; } - ret = kvm_get_apic(cpu); + ret = kvm_get_mp_state(cpu); if (ret < 0) { goto out; } - ret = kvm_get_vcpu_events(cpu); + ret = kvm_get_apic(cpu); if (ret < 0) { goto out; } -- 1.8.3.1