From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: [PATCH 2/2] qemu-kvm: x86: Add support for VCPU event states Date: Thu, 12 Nov 2009 01:05:49 +0100 Message-ID: <4AFB515D.1030202@web.de> References: <4AFB5123.7000301@web.de> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigE3D9AFD3791E679195D75BE7" Cc: kvm To: Avi Kivity , Marcelo Tosatti Return-path: Received: from fmmailgate01.web.de ([217.72.192.221]:60325 "EHLO fmmailgate01.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759731AbZKLAFh (ORCPT ); Wed, 11 Nov 2009 19:05:37 -0500 In-Reply-To: <4AFB5123.7000301@web.de> Sender: kvm-owner@vger.kernel.org List-ID: This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigE3D9AFD3791E679195D75BE7 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: quoted-printable This patch extends the qemu-kvm state sync logic with support for KVM_GET/SET_VCPU_EVENTS, giving access to yet missing exception, interrupt and NMI states. Signed-off-by: Jan Kiszka --- qemu-kvm-x86.c | 64 +++++++++++++++++++++++++++++++++++++++++++= ++++++ target-i386/cpu.h | 5 ++++ target-i386/machine.c | 5 ++++ 3 files changed, 74 insertions(+), 0 deletions(-) diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index e03a4ba..577c5db 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -903,6 +903,60 @@ static void get_seg(SegmentCache *lhs, const struct = kvm_segment *rhs) | (rhs->avl * DESC_AVL_MASK); } =20 +static void kvm_get_vcpu_events(CPUState *env) +{ +#ifdef KVM_CAP_VCPU_EVENTS + struct kvm_vcpu_events events; + int r; + + r =3D kvm_vcpu_ioctl(env, KVM_GET_VCPU_EVENTS, &events); + if (r =3D=3D 0) { + env->exception_index =3D + events.exception.injected ? events.exception.nr : -1; + env->has_error_code =3D events.exception.has_error_code; + env->error_code =3D events.exception.error_code; + + env->interrupt_injected =3D + events.interrupt.injected ? events.interrupt.nr : -1; + env->soft_interrupt =3D events.interrupt.soft; + + env->nmi_injected =3D events.nmi.injected; + env->nmi_pending =3D events.nmi.pending; + if (events.nmi.masked) { + env->hflags2 |=3D HF2_NMI_MASK; + } else { + env->hflags2 &=3D ~HF2_NMI_MASK; + } + + env->sipi_vector =3D events.sipi_vector; + } +#endif +} + +static void kvm_set_vcpu_events(CPUState *env) +{ +#ifdef KVM_CAP_VCPU_EVENTS + struct kvm_vcpu_events events; + + events.exception.injected =3D (env->exception_index >=3D 0); + events.exception.nr =3D env->exception_index; + events.exception.has_error_code =3D env->has_error_code; + events.exception.error_code =3D env->error_code; + + events.interrupt.injected =3D (env->interrupt_injected >=3D 0); + events.interrupt.nr =3D env->interrupt_injected; + events.interrupt.soft =3D env->soft_interrupt; + + events.nmi.injected =3D env->nmi_injected; + events.nmi.pending =3D env->nmi_pending; + events.nmi.masked =3D !!(env->hflags2 & HF2_NMI_MASK); + + events.sipi_vector =3D env->sipi_vector; + + kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, &events); +#endif +} + void kvm_arch_load_regs(CPUState *env) { struct kvm_regs regs; @@ -1019,6 +1073,8 @@ void kvm_arch_load_regs(CPUState *env) rc =3D kvm_set_msrs(env, msrs, n); if (rc =3D=3D -1) perror("kvm_set_msrs FAILED"); + + kvm_set_vcpu_events(env); } =20 void kvm_load_tsc(CPUState *env) @@ -1215,6 +1271,8 @@ void kvm_arch_save_regs(CPUState *env) return; } } + + kvm_get_vcpu_events(env); } =20 static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function, @@ -1383,7 +1441,10 @@ int kvm_arch_init_vcpu(CPUState *cenv) kvm_tpr_vcpu_start(cenv); #endif =20 + cenv->exception_index =3D -1; cenv->interrupt_injected =3D -1; + cenv->nmi_injected =3D 0; + cenv->nmi_pending =3D 0; =20 return 0; } @@ -1453,7 +1514,10 @@ void kvm_arch_push_nmi(void *opaque) =20 void kvm_arch_cpu_reset(CPUState *env) { + env->exception_index =3D -1; env->interrupt_injected =3D -1; + env->nmi_injected =3D 0; + env->nmi_pending =3D 0; 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 a638e70..31412a8 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -711,6 +711,11 @@ typedef struct CPUX86State { /* For KVM */ uint32_t mp_state; int32_t interrupt_injected; + uint8_t soft_interrupt; + uint8_t nmi_injected; + uint8_t nmi_pending; + uint8_t has_error_code; + uint32_t sipi_vector; =20 /* in order to simplify APIC support, we leave this pointer to the user */ diff --git a/target-i386/machine.c b/target-i386/machine.c index 6bd447f..1eda7c5 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -452,6 +452,11 @@ static const VMStateDescription vmstate_cpu =3D { VMSTATE_INT32_V(interrupt_injected, CPUState, 9), VMSTATE_UINT32_V(mp_state, CPUState, 9), VMSTATE_UINT64_V(tsc, CPUState, 9), + VMSTATE_UINT8_V(soft_interrupt, CPUState, 11), + VMSTATE_UINT8_V(nmi_injected, CPUState, 11), + VMSTATE_UINT8_V(nmi_pending, CPUState, 11), + VMSTATE_UINT8_V(has_error_code, CPUState, 11), + VMSTATE_UINT32_V(sipi_vector, CPUState, 11), /* MCE */ VMSTATE_UINT64_V(mcg_cap, CPUState, 10), VMSTATE_UINT64_V(mcg_status, CPUState, 10), --------------enigE3D9AFD3791E679195D75BE7 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 iEYEARECAAYFAkr7UV4ACgkQitSsb3rl5xTQSgCg30YB3qpG5VaU4GPF9fnQgkOL YokAoOvIpiObsmU6jrZyUdOALwtj6qTR =PAv6 -----END PGP SIGNATURE----- --------------enigE3D9AFD3791E679195D75BE7--