From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jan Kiszka Subject: Re: [PATCH] KVM: x86: Add instruction length to VCPU event state Date: Sat, 13 Feb 2010 18:49:44 +0100 Message-ID: <4B76E638.5010100@web.de> References: <4B76762C.10107@web.de> <20100213152635.GA2511@redhat.com> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enig2BA78BDB1D75592438AE3B38" Cc: Avi Kivity , Marcelo Tosatti , kvm To: Gleb Natapov Return-path: Received: from fmmailgate02.web.de ([217.72.192.227]:40658 "EHLO fmmailgate02.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751671Ab0BMRty (ORCPT ); Sat, 13 Feb 2010 12:49:54 -0500 In-Reply-To: <20100213152635.GA2511@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig2BA78BDB1D75592438AE3B38 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Gleb Natapov wrote: > On Sat, Feb 13, 2010 at 10:51:40AM +0100, Jan Kiszka wrote: >> From: Jan Kiszka >> >> VMX requires a properly set instruction length VM entry field when >> trying to inject soft exception and interrupts. We have to preserve th= is >> state across VM save/restore to avoid breaking the re-injection of suc= h >> events on Intel. So add it to the new VCPU event state. >> > We shouldn't re-inject soft exceptions/interrupts after migration, but > re-execute instruction instead. Instruction length field doesn't exist > on SVM and migration shouldn't expose implementation details. >=20 Hmm, then I guess this totally untested patch should fly: diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_h= ost.h index f9a2f66..f87c3a5 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -315,8 +315,6 @@ struct kvm_vcpu_arch { struct kvm_pio_request pio; void *pio_data; =20 - u8 event_exit_inst_len; - struct kvm_queued_exception { bool pending; bool has_error_code; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f82b072..a7111da 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -889,8 +889,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu= , unsigned nr, vmx->rmode.irq.vector =3D nr; vmx->rmode.irq.rip =3D kvm_rip_read(vcpu); if (kvm_exception_is_soft(nr)) - vmx->rmode.irq.rip +=3D - vmx->vcpu.arch.event_exit_inst_len; + vmx->rmode.irq.rip++; intr_info |=3D INTR_TYPE_SOFT_INTR; vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); @@ -899,8 +898,7 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu= , unsigned nr, } =20 if (kvm_exception_is_soft(nr)) { - vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, - vmx->vcpu.arch.event_exit_inst_len); + vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); intr_info |=3D INTR_TYPE_SOFT_EXCEPTION; } else intr_info |=3D INTR_TYPE_HARD_EXCEPTION; @@ -2639,8 +2637,7 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) vmx->rmode.irq.vector =3D irq; vmx->rmode.irq.rip =3D kvm_rip_read(vcpu); if (vcpu->arch.interrupt.soft) - vmx->rmode.irq.rip +=3D - vmx->vcpu.arch.event_exit_inst_len; + vmx->rmode.irq.rip +=3D 2; vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); @@ -2650,8 +2647,7 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) intr =3D irq | INTR_INFO_VALID_MASK; if (vcpu->arch.interrupt.soft) { intr |=3D INTR_TYPE_SOFT_INTR; - vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, - vmx->vcpu.arch.event_exit_inst_len); + vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 2); } else intr |=3D INTR_TYPE_EXT_INTR; vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr); @@ -3688,9 +3684,6 @@ static void vmx_complete_interrupts(struct vcpu_vmx= *vmx) GUEST_INTR_STATE_NMI); break; case INTR_TYPE_SOFT_EXCEPTION: - vmx->vcpu.arch.event_exit_inst_len =3D - vmcs_read32(VM_EXIT_INSTRUCTION_LEN); - /* fall through */ case INTR_TYPE_HARD_EXCEPTION: if (idt_vectoring_info & VECTORING_INFO_DELIVER_CODE_MASK) { u32 err =3D vmcs_read32(IDT_VECTORING_ERROR_CODE); @@ -3699,9 +3692,6 @@ static void vmx_complete_interrupts(struct vcpu_vmx= *vmx) kvm_queue_exception(&vmx->vcpu, vector); break; case INTR_TYPE_SOFT_INTR: - vmx->vcpu.arch.event_exit_inst_len =3D - vmcs_read32(VM_EXIT_INSTRUCTION_LEN); - /* fall through */ case INTR_TYPE_EXT_INTR: kvm_queue_interrupt(&vmx->vcpu, vector, type =3D=3D INTR_TYPE_SOFT_INTR); As we actually do not support privileged soft exceptions, we are left with int3 and into as single-byte instructions triggering soft exceptions and int N as a two-byte instruction a the reason for soft interrupts. Am I missing something? Jan --------------enig2BA78BDB1D75592438AE3B38 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 iEYEARECAAYFAkt25kAACgkQitSsb3rl5xScSwCgoC4zH/uaLUSbd+gjEQZiewOR rjoAnjUK/XfZ2hhuTvtePQpMSUkSSD5U =DZce -----END PGP SIGNATURE----- --------------enig2BA78BDB1D75592438AE3B38--