From patchwork Sat Aug 14 00:19:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mohammed Gamal X-Patchwork-Id: 119534 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o7E0K7M6002780 for ; Sat, 14 Aug 2010 00:20:07 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932254Ab0HNAUE (ORCPT ); Fri, 13 Aug 2010 20:20:04 -0400 Received: from mail-wy0-f174.google.com ([74.125.82.174]:49407 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932220Ab0HNAUC (ORCPT ); Fri, 13 Aug 2010 20:20:02 -0400 Received: by mail-wy0-f174.google.com with SMTP id 32so3231606wyb.19 for ; Fri, 13 Aug 2010 17:20:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=dHk20n3dwdgHtuZCxAq6x7rqaj1MBYQtrsKe4s3Ys9U=; b=ZGcRkobA4JSbfbBNi2eJbpl/bUfsEt+WZWfpho15X5585jYtZ9ZK/OLWodf7G4grtw 5va18zUhzkDPz05qEmW1mzpFoi+KKSfs8ediexr5Wm7lzPybvrPBD2heHbjRU13ZW0IH nAlRjxSBH5prsvlocQh/U4J7H+eKXVz0alJ0o= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=WWTWkxz2lPBKug4UI4wFysi+AfTX22Cnx51EJes5l6wt3vM9eFXOiGJ8h8e//9sUAs 9fH9Demvh0G1x8yRoDmMRGirpzvjrAqYDLnWSMsPpJadOLPjmFJTicegeUO7QhFphBbs F4qDLtcLM28FPusaXzZknR6PDW0e3ulXigq0Y= Received: by 10.216.236.197 with SMTP id w47mr90275weq.114.1281745201368; Fri, 13 Aug 2010 17:20:01 -0700 (PDT) Received: from localhost.localdomain ([188.55.88.49]) by mx.google.com with ESMTPS id v44sm1915180weq.28.2010.08.13.17.19.57 (version=TLSv1/SSLv3 cipher=RC4-MD5); Fri, 13 Aug 2010 17:20:01 -0700 (PDT) From: Mohammed Gamal To: avi@redhat.com Cc: mtosatti@redhat.com, kvm@vger.kernel.org, Mohammed Gamal Subject: [RFC PATCH v2 3/4] VMX: Emulated real mode interrupt injection Date: Sat, 14 Aug 2010 03:19:40 +0300 Message-Id: <1281745181-4426-2-git-send-email-m.gamal005@gmail.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1281745181-4426-1-git-send-email-m.gamal005@gmail.com> References: <1281745181-4426-1-git-send-email-m.gamal005@gmail.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]); Sat, 14 Aug 2010 00:20:07 +0000 (UTC) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 652d317..1f4387b 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -155,11 +155,6 @@ struct vcpu_vmx { u32 limit; u32 ar; } tr, es, ds, fs, gs; - struct { - bool pending; - u8 vector; - unsigned rip; - } irq; } rmode; int vpid; bool emulation_required; @@ -1048,16 +1043,8 @@ static void vmx_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, } if (vmx->rmode.vm86_active) { - vmx->rmode.irq.pending = true; - vmx->rmode.irq.vector = nr; - vmx->rmode.irq.rip = kvm_rip_read(vcpu); - if (kvm_exception_is_soft(nr)) - vmx->rmode.irq.rip += - vmx->vcpu.arch.event_exit_inst_len; - intr_info |= INTR_TYPE_SOFT_INTR; - vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, intr_info); - vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); - kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); + if (inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE) + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); return; } @@ -2838,16 +2825,8 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu) ++vcpu->stat.irq_injections; if (vmx->rmode.vm86_active) { - vmx->rmode.irq.pending = true; - vmx->rmode.irq.vector = irq; - vmx->rmode.irq.rip = kvm_rip_read(vcpu); - if (vcpu->arch.interrupt.soft) - vmx->rmode.irq.rip += - vmx->vcpu.arch.event_exit_inst_len; - vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, - irq | INTR_TYPE_SOFT_INTR | INTR_INFO_VALID_MASK); - vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); - kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); + if (inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE) + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); return; } intr = irq | INTR_INFO_VALID_MASK; @@ -2879,14 +2858,8 @@ static void vmx_inject_nmi(struct kvm_vcpu *vcpu) ++vcpu->stat.nmi_injections; if (vmx->rmode.vm86_active) { - vmx->rmode.irq.pending = true; - vmx->rmode.irq.vector = NMI_VECTOR; - vmx->rmode.irq.rip = kvm_rip_read(vcpu); - vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, - NMI_VECTOR | INTR_TYPE_SOFT_INTR | - INTR_INFO_VALID_MASK); - vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, 1); - kvm_rip_write(vcpu, vmx->rmode.irq.rip - 1); + if (inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE) + kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu); return; } vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, @@ -3848,29 +3821,6 @@ static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time)); } -/* - * Failure to inject an interrupt should give us the information - * in IDT_VECTORING_INFO_FIELD. However, if the failure occurs - * when fetching the interrupt redirection bitmap in the real-mode - * tss, this doesn't happen. So we do it ourselves. - */ -static void fixup_rmode_irq(struct vcpu_vmx *vmx, u32 *idt_vectoring_info) -{ - vmx->rmode.irq.pending = 0; - if (kvm_rip_read(&vmx->vcpu) + 1 != vmx->rmode.irq.rip) - return; - kvm_rip_write(&vmx->vcpu, vmx->rmode.irq.rip); - if (*idt_vectoring_info & VECTORING_INFO_VALID_MASK) { - *idt_vectoring_info &= ~VECTORING_INFO_TYPE_MASK; - *idt_vectoring_info |= INTR_TYPE_EXT_INTR; - return; - } - *idt_vectoring_info = - VECTORING_INFO_VALID_MASK - | INTR_TYPE_EXT_INTR - | vmx->rmode.irq.vector; -} - static void __vmx_complete_interrupts(struct vcpu_vmx *vmx, u32 idt_vectoring_info, int instr_len_field, @@ -3880,9 +3830,6 @@ static void __vmx_complete_interrupts(struct vcpu_vmx *vmx, int type; bool idtv_info_valid; - if (vmx->rmode.irq.pending) - fixup_rmode_irq(vmx, &idt_vectoring_info); - idtv_info_valid = idt_vectoring_info & VECTORING_INFO_VALID_MASK; vmx->vcpu.arch.nmi_injected = false;