From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: [PATCH 1/2] qemu-kvm: x86: Refactor use of interrupt_bitmap Date: Thu, 12 Nov 2009 01:04:51 +0100 Message-ID: <4AFB5123.7000301@web.de> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigCCE2A3D93E2AA6CE0DA66E29" Cc: kvm To: Avi Kivity , Marcelo Tosatti Return-path: Received: from fmmailgate01.web.de ([217.72.192.221]:59719 "EHLO fmmailgate01.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752526AbZKLAEi (ORCPT ); Wed, 11 Nov 2009 19:04:38 -0500 Sender: kvm-owner@vger.kernel.org List-ID: This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigCCE2A3D93E2AA6CE0DA66E29 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable Drop interrupt_bitmap from the cpustate and solely rely on the integer interrupt_injected. This prepares us for the new injected-interrupt interface, which will deprecate the bitmap, while preserving compatibility. Signed-off-by: Jan Kiszka --- qemu-kvm-x86.c | 19 +++++++++++++++++-- target-i386/cpu.h | 3 +-- target-i386/kvm.c | 24 +++++++++++++++++------- target-i386/machine.c | 24 ++---------------------- 4 files changed, 37 insertions(+), 33 deletions(-) diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index 9df0d83..e03a4ba 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -946,7 +946,11 @@ void kvm_arch_load_regs(CPUState *env) fpu.mxcsr =3D env->mxcsr; kvm_set_fpu(env, &fpu); =20 - memcpy(sregs.interrupt_bitmap, env->interrupt_bitmap, sizeof(sregs.i= nterrupt_bitmap)); + memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); + if (env->interrupt_injected >=3D 0) { + sregs.interrupt_bitmap[env->interrupt_injected / 64] |=3D + (uint64_t)1 << (env->interrupt_injected % 64); + } =20 if ((env->eflags & VM_MASK)) { set_v8086_seg(&sregs.cs, &env->segs[R_CS]); @@ -1104,7 +1108,14 @@ void kvm_arch_save_regs(CPUState *env) =20 kvm_get_sregs(env, &sregs); =20 - memcpy(env->interrupt_bitmap, sregs.interrupt_bitmap, sizeof(env->in= terrupt_bitmap)); + env->interrupt_injected =3D -1; + for (i =3D 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) { + if (sregs.interrupt_bitmap[i]) { + n =3D ctz64(sregs.interrupt_bitmap[i]); + env->interrupt_injected =3D i * 64 + n; + break; + } + } =20 get_seg(&env->segs[R_CS], &sregs.cs); get_seg(&env->segs[R_DS], &sregs.ds); @@ -1371,6 +1382,9 @@ int kvm_arch_init_vcpu(CPUState *cenv) #ifdef KVM_EXIT_TPR_ACCESS kvm_tpr_vcpu_start(cenv); #endif + + cenv->interrupt_injected =3D -1; + return 0; } =20 @@ -1439,6 +1453,7 @@ void kvm_arch_push_nmi(void *opaque) =20 void kvm_arch_cpu_reset(CPUState *env) { + env->interrupt_injected =3D -1; kvm_arch_load_regs(env); if (!cpu_is_bsp(env)) { if (kvm_irqchip_in_kernel()) { diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 4605fd2..a638e70 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -709,8 +709,8 @@ typedef struct CPUX86State { MTRRVar mtrr_var[8]; =20 /* For KVM */ - uint64_t interrupt_bitmap[256 / 64]; uint32_t mp_state; + int32_t interrupt_injected; =20 /* in order to simplify APIC support, we leave this pointer to the user */ @@ -727,7 +727,6 @@ typedef struct CPUX86State { uint16_t fpus_vmstate; uint16_t fptag_vmstate; uint16_t fpregs_format_vmstate; - int32_t pending_irq_vmstate; } CPUX86State; =20 CPUX86State *cpu_x86_init(const char *cpu_model); diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 24c9903..33f7d65 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" =20 #ifdef KVM_UPSTREAM //#define DEBUG_KVM @@ -408,9 +409,11 @@ static int kvm_put_sregs(CPUState *env) { struct kvm_sregs sregs; =20 - memcpy(sregs.interrupt_bitmap, - env->interrupt_bitmap, - sizeof(sregs.interrupt_bitmap)); + memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap)); + if (env->interrupt_injected >=3D 0) { + sregs.interrupt_bitmap[env->interrupt_injected / 64] |=3D + (uint64_t)1 << (env->interrupt_injected % 64); + } =20 if ((env->eflags & VM_MASK)) { set_v8086_seg(&sregs.cs, &env->segs[R_CS]); @@ -518,15 +521,22 @@ static int kvm_get_sregs(CPUState *env) { struct kvm_sregs sregs; uint32_t hflags; - int ret; + int bit, i, ret; =20 ret =3D kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs); if (ret < 0) return ret; =20 - memcpy(env->interrupt_bitmap,=20 - 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 =3D -1; + for (i =3D 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) { + if (sregs.interrupt_bitmap[i]) { + bit =3D ctz64(sregs.interrupt_bitmap[i]); + env->interrupt_injected =3D i * 64 + bit; + break; + } + } =20 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 2b88fea..6bd447f 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" =20 #include "exec-all.h" #include "kvm.h" @@ -321,7 +320,7 @@ static const VMStateInfo vmstate_hack_uint64_as_uint3= 2 =3D { static void cpu_pre_save(void *opaque) { CPUState *env =3D opaque; - int i, bit; + int i; =20 cpu_synchronize_state(env); kvm_save_mpstate(env); @@ -338,17 +337,6 @@ static void cpu_pre_save(void *opaque) #else env->fpregs_format_vmstate =3D 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 =3D -1; - for (i =3D 0; i < ARRAY_SIZE(env->interrupt_bitmap); i++) { - if (env->interrupt_bitmap[i]) { - bit =3D ctz64(env->interrupt_bitmap[i]); - env->pending_irq_vmstate =3D i * 64 + bit; - break; - } - } } =20 static int cpu_pre_load(void *opaque) @@ -377,14 +365,6 @@ static int cpu_post_load(void *opaque, int version_i= d) for (i =3D 0; i < 4; i++) hw_breakpoint_insert(env, i); =20 - if (version_id >=3D 9) { - memset(&env->interrupt_bitmap, 0, sizeof(env->interrupt_bitmap))= ; - if (env->pending_irq_vmstate >=3D 0) { - env->interrupt_bitmap[env->pending_irq_vmstate / 64] |=3D - (uint64_t)1 << (env->pending_irq_vmstate % 64); - } - } - tlb_flush(env, 1); kvm_load_mpstate(env); =20 @@ -469,7 +449,7 @@ static const VMStateDescription vmstate_cpu =3D { 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 */ --------------enigCCE2A3D93E2AA6CE0DA66E29 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.9 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iEYEARECAAYFAkr7USMACgkQitSsb3rl5xQugACgsbeFW8RYzinaAmdCY3tVwOs6 cWoAoOdxWi26+2C7PAO08U0aeCr7p2Fd =nT9t -----END PGP SIGNATURE----- --------------enigCCE2A3D93E2AA6CE0DA66E29--