WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix the "hda lost interrupt" issue when creating a VMX g

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix the "hda lost interrupt" issue when creating a VMX guest on a PAE
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 21 Apr 2006 16:42:19 +0000
Delivery-date: Fri, 21 Apr 2006 09:48:17 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 29e9a0313c090e64cce0c97bd13f142f603e8817
# Parent  9c313ff7a0ed53b25ce3ae75686bdb26dd20227c
Fix the "hda lost interrupt" issue when creating a VMX guest on a PAE
host.

Occasionally when injecting an IDE DMA interrupt into the guest, a
page fault occurs (e.g., because the IDT mapping is not present in
shadow pagetables).  This causes an immediate vmexit and, because it
occurred during event delivery, the original VM_ENTRY_INTR_INFO_FIELD
is kept in IDT_VECTORING_INFO_FIELD.

The current code copies IDT_VECTORING_INFO_FIELD back to
VM_ENTRY_INTR_INFO_FIELD, intending that the interrupt will be
injected again on next vmresume.

However, there is a corner case: if, before the next vmresume, a timer
interrupt happened then vmx_intr_assist may overwrite the information
on VM_ENTRY_INTR_INFO_FIELD, and the IDE DMA interrupt is effectively
lost.

This patch checks the IDT_VECTORING_INFO_FIELD in vmx_intr_assist and,
if it is set, copies it to VM_ENTRY_INTR_INFO_FIELD and returns.

Signed-off-by: Yunhong Jiang <Yunhong.jiang@xxxxxxxxx>
Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx>

diff -r 9c313ff7a0ed -r 29e9a0313c09 xen/arch/x86/hvm/vmx/io.c
--- a/xen/arch/x86/hvm/vmx/io.c Fri Apr 21 09:56:50 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/io.c Fri Apr 21 10:11:00 2006 +0100
@@ -153,6 +153,9 @@ asmlinkage void vmx_intr_assist(void)
     struct hvm_domain *plat=&v->domain->arch.hvm_domain;
     struct hvm_time_info *time_info = &plat->vpit.time_info;
     struct hvm_virpic *pic= &plat->vpic;
+    unsigned int idtv_info_field;
+    unsigned long inst_len;
+    int    has_ext_irq;
 
     if ( v->vcpu_id == 0 )
         hvm_pic_assist(v);
@@ -162,8 +165,29 @@ asmlinkage void vmx_intr_assist(void)
         pic_set_irq(pic, 0, 1);
     }
 
-    if ( !cpu_has_pending_irq(v) ) return;
-
+    has_ext_irq = cpu_has_pending_irq(v);
+    __vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
+    if (idtv_info_field & INTR_INFO_VALID_MASK) {
+        __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
+
+        __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
+        if (inst_len >= 1 && inst_len <= 15)
+            __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
+
+        if (idtv_info_field & 0x800) { /* valid error code */
+            unsigned long error_code;
+            __vmread(IDT_VECTORING_ERROR_CODE, &error_code);
+            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
+        }
+        if ( has_ext_irq )
+            enable_irq_window(v);
+
+        HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
+
+        return;
+    }
+
+    if ( !has_ext_irq ) return;
     if ( is_interruptibility_state() ) {    /* pre-cleared for emulated 
instruction */
         enable_irq_window(v);
         HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
diff -r 9c313ff7a0ed -r 29e9a0313c09 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Fri Apr 21 09:56:50 2006 +0100
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Fri Apr 21 10:11:00 2006 +0100
@@ -2046,7 +2046,7 @@ void restore_cpu_user_regs(struct cpu_us
 
 asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs)
 {
-    unsigned int exit_reason, idtv_info_field;
+    unsigned int exit_reason;
     unsigned long exit_qualification, eip, inst_len = 0;
     struct vcpu *v = current;
     int error;
@@ -2055,23 +2055,6 @@ asmlinkage void vmx_vmexit_handler(struc
         __hvm_bug(&regs);
 
     perfc_incra(vmexits, exit_reason);
-
-    __vmread(IDT_VECTORING_INFO_FIELD, &idtv_info_field);
-    if (idtv_info_field & INTR_INFO_VALID_MASK) {
-        __vmwrite(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field);
-
-        __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
-        if (inst_len >= 1 && inst_len <= 15)
-            __vmwrite(VM_ENTRY_INSTRUCTION_LEN, inst_len);
-
-        if (idtv_info_field & 0x800) { /* valid error code */
-            unsigned long error_code;
-            __vmread(IDT_VECTORING_ERROR_CODE, &error_code);
-            __vmwrite(VM_ENTRY_EXCEPTION_ERROR_CODE, error_code);
-        }
-
-        HVM_DBG_LOG(DBG_LEVEL_1, "idtv_info_field=%x", idtv_info_field);
-    }
 
     /* don't bother H/W interrutps */
     if (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT &&

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>