From patchwork Tue Nov 3 17:36:16 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 57343 Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA3HifM2020299 for ; Tue, 3 Nov 2009 17:44:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751521AbZKCRob (ORCPT ); Tue, 3 Nov 2009 12:44:31 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751488AbZKCRob (ORCPT ); Tue, 3 Nov 2009 12:44:31 -0500 Received: from goliath.siemens.de ([192.35.17.28]:24798 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751326AbZKCRoa (ORCPT ); Tue, 3 Nov 2009 12:44:30 -0500 Received: from mail1.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id nA3HiMxt026336; Tue, 3 Nov 2009 18:44:22 +0100 Received: from [139.25.109.167] (mchn012c.mchp.siemens.de [139.25.109.167] (may be forged)) by mail1.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id nA3HiMh4028883; Tue, 3 Nov 2009 18:44:22 +0100 Message-ID: <4AF06A10.6000208@siemens.com> Date: Tue, 03 Nov 2009 18:36:16 +0100 From: Jan Kiszka User-Agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666 MIME-Version: 1.0 To: Marcelo Tosatti , Avi Kivity CC: kvm Subject: [PATCH 1/2] qemu-kvm: x86: Refactor use of interrupt_bitmap Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org 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 = env->mxcsr; kvm_set_fpu(env, &fpu); - 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]); @@ -1104,7 +1108,14 @@ void kvm_arch_save_regs(CPUState *env) kvm_get_sregs(env, &sregs); - memcpy(env->interrupt_bitmap, sregs.interrupt_bitmap, sizeof(env->interrupt_bitmap)); + env->interrupt_injected = -1; + for (i = 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) { + if (sregs.interrupt_bitmap[i]) { + n = ctz64(sregs.interrupt_bitmap[i]); + env->interrupt_injected = i * 64 + n; + break; + } + } 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 = -1; + return 0; } @@ -1439,6 +1453,7 @@ void kvm_arch_push_nmi(void *opaque) void kvm_arch_cpu_reset(CPUState *env) { + env->interrupt_injected = -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]; /* 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 */ @@ -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; 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" #ifdef KVM_UPSTREAM //#define DEBUG_KVM @@ -408,9 +409,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]); @@ -518,15 +521,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 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" #include "exec-all.h" #include "kvm.h" @@ -321,7 +320,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); kvm_save_mpstate(env); @@ -338,17 +337,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) @@ -377,14 +365,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); kvm_load_mpstate(env); @@ -469,7 +449,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 */