commit 47faf947315d8abeaf5ec90a906e47a24e0657dd
Author: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
Date:   Thu Mar 27 20:35:06 2008 +0000

    xen: fix RMW when unmasking events
    
    upstream commit: 04c44a080d2f699a3042d4e743f7ad2ffae9d538
    
    xen_irq_enable_direct and xen_sysexit were using "andw $0x00ff,
    XEN_vcpu_info_pending(vcpu)" to unmask events and test for pending ones
    in one instuction.
    
    Unfortunately, the pending flag must be modified with a locked operation
    since it can be set by another CPU, and the unlocked form of this
    operation was causing the pending flag to get lost, allowing the processor
    to return to usermode with pending events and ultimately deadlock.
    
    The simple fix would be to make it a locked operation, but that's rather
    costly and unnecessary.  The fix here is to split the mask-clearing and
    pending-testing into two instructions; the interrupt window between
    them is of no concern because either way pending or new events will
    be processed.
    
    This should fix lingering bugs in using direct vcpu structure access too.
    
    Signed-off-by: Jeremy Fitzhardinge <[EMAIL PROTECTED]>
    Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
    Signed-off-by: Chris Wright <[EMAIL PROTECTED]>

diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 79ad152..b6af3ea 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -95,7 +95,7 @@ struct shared_info *HYPERVISOR_shared_info = (void 
*)&dummy_shared_info;
  *
  * 0: not available, 1: available
  */
-static int have_vcpu_info_placement = 0;
+static int have_vcpu_info_placement = 1;
 
 static void __init xen_vcpu_setup(int cpu)
 {
diff --git a/arch/x86/xen/xen-asm.S b/arch/x86/xen/xen-asm.S
index 1a43b60..6b71904 100644
--- a/arch/x86/xen/xen-asm.S
+++ b/arch/x86/xen/xen-asm.S
@@ -33,12 +33,17 @@
        events, then enter the hypervisor to get them handled.
  */
 ENTRY(xen_irq_enable_direct)
-       /* Clear mask and test pending */
-       andw $0x00ff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending
+       /* Unmask events */
+       movb $0, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask
+
        /* Preempt here doesn't matter because that will deal with
           any pending interrupts.  The pending check may end up being
           run on the wrong CPU, but that doesn't hurt. */
+
+       /* Test for pending */
+       testb $0xff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending
        jz 1f
+
 2:     call check_events
 1:
 ENDPATCH(xen_irq_enable_direct)
_______________________________________________
unionfs-cvs mailing list: http://unionfs.filesystems.org/
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs-cvs

Reply via email to