From patchwork Sun Feb 14 12:39:41 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 79279 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1ECdpw2003122 for ; Sun, 14 Feb 2010 12:39:51 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758459Ab0BNMjt (ORCPT ); Sun, 14 Feb 2010 07:39:49 -0500 Received: from fmmailgate03.web.de ([217.72.192.234]:43480 "EHLO fmmailgate03.web.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753872Ab0BNMjs (ORCPT ); Sun, 14 Feb 2010 07:39:48 -0500 Received: from smtp06.web.de (fmsmtp06.dlan.cinetic.de [172.20.5.172]) by fmmailgate03.web.de (Postfix) with ESMTP id AA88013E0E6F7; Sun, 14 Feb 2010 13:39:47 +0100 (CET) Received: from [88.65.42.158] (helo=[192.168.1.10]) by smtp06.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #314) id 1NgdlL-0005AB-00; Sun, 14 Feb 2010 13:39:47 +0100 Message-ID: <4B77EF0D.4050303@web.de> Date: Sun, 14 Feb 2010 13:39:41 +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: Avi Kivity CC: Gleb Natapov , Marcelo Tosatti , kvm Subject: Re: [PATCH] KVM: VMX: Update instruction length on intercepted BP References: <4B767160.4070609@web.de> <20100214075303.GF2511@redhat.com> <4B77CFD7.9080504@web.de> <20100214103445.GH2511@redhat.com> <4B77EC14.4000302@redhat.com> In-Reply-To: <4B77EC14.4000302@redhat.com> X-Enigmail-Version: 0.95.7 X-Sender: jan.kiszka@web.de X-Provags-ID: V01U2FsdGVkX19qBVZhnmRJUSwIWrE/4TXmr8f0NwGSzPOPX7S9 etGua/lKCIScpzkceODJIpi110tss+xg5itmqo4xocrI9Wf72W ODBqH08eY= Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Sun, 14 Feb 2010 12:39:51 +0000 (UTC) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 52f78dd..450c1e7 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -109,6 +109,7 @@ struct vcpu_svm { struct nested_state nested; bool nmi_singlestep; + bool bp_singlestep; }; /* enable NPT for AMD64 and X86 with PAE */ @@ -244,6 +245,19 @@ static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) return; + if (nr == BP_VECTOR && vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) { + /* + * Temporarily disable BP interception so that the trap is + * properly delivered to the guest (if we left it on, SVM + * would push the wrong IP on the stack). + * We single-step into theexception handler in order to + * reenble interception ASAP. + */ + svm->vmcb->control.intercept_exceptions &= ~(1 << BP_VECTOR); + svm->bp_singlestep = true; + svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF); + } + svm->vmcb->control.event_inj = nr | SVM_EVTINJ_VALID | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) @@ -1083,7 +1097,8 @@ static void update_db_intercept(struct kvm_vcpu *vcpu) (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) svm->vmcb->control.intercept_exceptions |= 1 << DB_VECTOR; - if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP) + if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP && + !svm->bp_singlestep) svm->vmcb->control.intercept_exceptions |= 1 << BP_VECTOR; } else @@ -1214,7 +1229,7 @@ static int db_interception(struct vcpu_svm *svm) if (!(svm->vcpu.guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)) && - !svm->nmi_singlestep) { + !svm->nmi_singlestep && !svm->bp_singlestep) { kvm_queue_exception(&svm->vcpu, DB_VECTOR); return 1; } @@ -1227,6 +1242,14 @@ static int db_interception(struct vcpu_svm *svm) update_db_intercept(&svm->vcpu); } + if (svm->bp_singlestep) { + svm->bp_singlestep = false; + if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP)) + svm->vmcb->save.rflags &= + ~(X86_EFLAGS_TF | X86_EFLAGS_RF); + update_db_intercept(&svm->vcpu); + } + if (svm->vcpu.guest_debug & (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP)){ kvm_run->exit_reason = KVM_EXIT_DEBUG;