Patchwork [3/5] kvm: x86: Refactor use of interrupt_bitmap

login
register
mail settings
Submitter Jan Kiszka
Date Nov. 6, 2009, 6:39 p.m.
Message ID <20091106183924.11700.82556.stgit@mchn012c.ww002.siemens.net>
Download mbox | patch
Permalink /patch/37887/
State New
Headers show

Comments

Jan Kiszka - Nov. 6, 2009, 6:39 p.m.
Drop interrupt_bitmap from the cpustate and solely rely on the integer
interupt_injected. This prepares us for the new injected-interrupt
interface, which will deprecate the bitmap, while preserving
compatibility.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

 target-i386/cpu.h     |    3 +--
 target-i386/kvm.c     |   25 ++++++++++++++++++-------
 target-i386/machine.c |   24 ++----------------------
 3 files changed, 21 insertions(+), 31 deletions(-)

Patch

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 5929d28..eb9532a 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 ca99cc7..c769d70 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 869c681..c09b049 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 */