diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 5929d2813911d234e2c99f8c4e0d2008a48214dc..eb9532aef334a82afd337b4b118094b1fbf27de5 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -691,8 +691,8 @@ typedef struct CPUX86State { MTRRVar mtrr_var[8]; /* For KVM */ - uint64_t interrupt_bitmap[256 / 64]; uint32_t mp_state; + int32_t interrupt_injected; /* in order to simplify APIC support, we leave this pointer to the user */ @@ -709,7 +709,6 @@ typedef struct CPUX86State { uint16_t fpus_vmstate; uint16_t fptag_vmstate; uint16_t fpregs_format_vmstate; - int32_t pending_irq_vmstate; } CPUX86State; CPUX86State *cpu_x86_init(const char *cpu_model); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ea6a510ce29ab3de0b3e51083656e6863ffe08fd..d6bc23ae26dcd64d4d133e7b2e754cf45cec4b7b 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -23,6 +23,7 @@ #include "kvm.h" #include "cpu.h" #include "gdbstub.h" +#include "host-utils.h" //#define DEBUG_KVM @@ -223,6 +224,7 @@ int kvm_arch_init_vcpu(CPUState *env) void kvm_arch_reset_vcpu(CPUState *env) { + env->interrupt_injected = -1; } static int kvm_has_msr_star(CPUState *env) @@ -411,9 +413,11 @@ static int kvm_put_sregs(CPUState *env) { struct kvm_sregs sregs; - memcpy(sregs.interrupt_bitmap, - env->interrupt_bitmap, - sizeof(sregs.interrupt_bitmap)); + memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); + if (env->interrupt_injected >= 0) { + sregs.interrupt_bitmap[env->interrupt_injected / 64] |= + (uint64_t)1 << (env->interrupt_injected % 64); + } if ((env->eflags & VM_MASK)) { set_v8086_seg(&sregs.cs, &env->segs[R_CS]); @@ -520,15 +524,22 @@ static int kvm_get_sregs(CPUState *env) { struct kvm_sregs sregs; uint32_t hflags; - int ret; + int bit, i, ret; ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); if (ret < 0) return ret; - memcpy(env->interrupt_bitmap, - sregs.interrupt_bitmap, - sizeof(sregs.interrupt_bitmap)); + /* There can only be one pending IRQ set in the bitmap at a time, so try + to find it and save its number instead (-1 for none). */ + env->interrupt_injected = -1; + for (i = 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) { + if (sregs.interrupt_bitmap[i]) { + bit = ctz64(sregs.interrupt_bitmap[i]); + env->interrupt_injected = i * 64 + bit; + break; + } + } get_seg(&env->segs[R_CS], &sregs.cs); get_seg(&env->segs[R_DS], &sregs.ds); diff --git a/target-i386/machine.c b/target-i386/machine.c index 869c681f4d8e6b68ec2fa6689dc7a9b814e33ce2..c09b049d90f898d4734a1423cde2dad4e8e50979 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -2,7 +2,6 @@ #include "hw/boards.h" #include "hw/pc.h" #include "hw/isa.h" -#include "host-utils.h" #include "exec-all.h" #include "kvm.h" @@ -320,7 +319,7 @@ static const VMStateInfo vmstate_hack_uint64_as_uint32 = { static void cpu_pre_save(void *opaque) { CPUState *env = opaque; - int i, bit; + int i; cpu_synchronize_state(env); @@ -336,17 +335,6 @@ static void cpu_pre_save(void *opaque) #else env->fpregs_format_vmstate = 1; #endif - - /* There can only be one pending IRQ set in the bitmap at a time, so try - to find it and save its number instead (-1 for none). */ - env->pending_irq_vmstate = -1; - for (i = 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) { - if (env->interrupt_bitmap[i]) { - bit = ctz64(env->interrupt_bitmap[i]); - env->pending_irq_vmstate = i * 64 + bit; - break; - } - } } static int cpu_pre_load(void *opaque) @@ -375,14 +363,6 @@ static int cpu_post_load(void *opaque, int version_id) for (i = 0; i < 4; i++) hw_breakpoint_insert(env, i); - if (version_id >= 9) { - memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap)); - if (env->pending_irq_vmstate >= 0) { - env->interrupt_bitmap[env->pending_irq_vmstate / 64] |= - (uint64_t)1 << (env->pending_irq_vmstate % 64); - } - } - tlb_flush(env, 1); return 0; } @@ -465,7 +445,7 @@ static const VMStateDescription vmstate_cpu = { VMSTATE_UINT64_V(mtrr_deftype, CPUState, 8), VMSTATE_MTRR_VARS(mtrr_var, CPUState, 8, 8), /* KVM-related states */ - VMSTATE_INT32_V(pending_irq_vmstate, CPUState, 9), + VMSTATE_INT32_V(interrupt_injected, CPUState, 9), VMSTATE_UINT32_V(mp_state, CPUState, 9), VMSTATE_UINT64_V(tsc, CPUState, 9), /* MCE */