From patchwork Mon Feb 15 14:25:01 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kiszka X-Patchwork-Id: 79405 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 o1FEPOkv004060 for ; Mon, 15 Feb 2010 14:25:24 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755026Ab0BOOZW (ORCPT ); Mon, 15 Feb 2010 09:25:22 -0500 Received: from goliath.siemens.de ([192.35.17.28]:20231 "EHLO goliath.siemens.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752881Ab0BOOZV (ORCPT ); Mon, 15 Feb 2010 09:25:21 -0500 Received: from mail2.siemens.de (localhost [127.0.0.1]) by goliath.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id o1FEP2Cj021507; Mon, 15 Feb 2010 15:25:02 +0100 Received: from [139.25.109.167] (mchn012c.ww002.siemens.net [139.25.109.167] (may be forged)) by mail2.siemens.de (8.12.11.20060308/8.12.11) with ESMTP id o1FEP1VF028682; Mon, 15 Feb 2010 15:25:02 +0100 Message-ID: <4B79593D.6070709@siemens.com> Date: Mon, 15 Feb 2010 15:25:01 +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: Gleb Natapov CC: Avi Kivity , Marcelo Tosatti , kvm Subject: Re: [PATCH] KVM: VMX: Update instruction length on intercepted BP References: <4B77D4DE.3030602@web.de> <20100214111544.GJ2511@redhat.com> <4B77E0E2.7030704@web.de> <20100214144501.GN2511@redhat.com> <4B7826D3.7080201@web.de> <20100214165319.GA19246@redhat.com> <4B782D97.9030304@web.de> <20100214172613.GB19246@redhat.com> <4B7837A3.4040607@web.de> <4B794A1F.7050009@siemens.com> <20100215133042.GC19478@redhat.com> In-Reply-To: <20100215133042.GC19478@redhat.com> 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]); Mon, 15 Feb 2010 14:25:24 +0000 (UTC) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 52f78dd..5f35aaf 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -46,6 +46,7 @@ MODULE_LICENSE("GPL"); #define SVM_FEATURE_NPT (1 << 0) #define SVM_FEATURE_LBRV (1 << 1) #define SVM_FEATURE_SVML (1 << 2) +#define SVM_FEATURE_NRIP (1 << 3) #define SVM_FEATURE_PAUSE_FILTER (1 << 10) #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ @@ -109,6 +110,8 @@ struct vcpu_svm { struct nested_state nested; bool nmi_singlestep; + + bool int3_injected; }; /* enable NPT for AMD64 and X86 with PAE */ @@ -234,23 +237,6 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) vcpu->arch.efer = efer; } -static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, - bool has_error_code, u32 error_code) -{ - struct vcpu_svm *svm = to_svm(vcpu); - - /* If we are within a nested VM we'd better #VMEXIT and let the - guest handle the exception */ - if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) - return; - - svm->vmcb->control.event_inj = nr - | SVM_EVTINJ_VALID - | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) - | SVM_EVTINJ_TYPE_EXEPT; - svm->vmcb->control.event_inj_err = error_code; -} - static int is_external_interrupt(u32 info) { info &= SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; @@ -296,6 +282,29 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) svm_set_interrupt_shadow(vcpu, 0); } +static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, + bool has_error_code, u32 error_code) +{ + struct vcpu_svm *svm = to_svm(vcpu); + + /* If we are within a nested VM we'd better #VMEXIT and let the + guest handle the exception */ + if (nested_svm_check_exception(svm, nr, has_error_code, error_code)) + return; + + if (nr == BP_VECTOR && !svm_has(SVM_FEATURE_NRIP)) { + svm->next_rip = kvm_rip_read(&svm->vcpu) + 1; + skip_emulated_instruction(&svm->vcpu); + svm->int3_injected = true; + } + + svm->vmcb->control.event_inj = nr + | SVM_EVTINJ_VALID + | (has_error_code ? SVM_EVTINJ_VALID_ERR : 0) + | SVM_EVTINJ_TYPE_EXEPT; + svm->vmcb->control.event_inj_err = error_code; +} + static int has_svm(void) { const char *msg; @@ -2653,6 +2662,9 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) if (is_nested(svm)) break; if (kvm_exception_is_soft(vector)) + if (vector == BP_VECTOR && svm->int3_injected) + kvm_rip_write(&svm->vcpu, + kvm_rip_read(&svm->vcpu) - 1); break; if (exitintinfo & SVM_EXITINTINFO_VALID_ERR) { u32 err = svm->vmcb->control.exit_int_info_err; @@ -2667,6 +2679,7 @@ static void svm_complete_interrupts(struct vcpu_svm *svm) default: break; } + svm->int3_injected =false; } #ifdef CONFIG_X86_64