lkml.org 
[lkml]   [2008]   [Apr]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subjectxen: fix RMW when unmasking events
    -stable review patch.  If anyone has any objections, please let us know.
    ---------------------

    From: Jeremy Fitzhardinge <jeremy@goop.org>

    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 <jeremy.fitzhardinge@citrix.com>
    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    Signed-off-by: Chris Wright <chrisw@sous-sol.org>
    ---
    arch/x86/xen/enlighten.c | 2 +-
    arch/x86/xen/xen-asm.S | 9 +++++++--
    2 files changed, 8 insertions(+), 3 deletions(-)

    --- a/arch/x86/xen/enlighten.c
    +++ b/arch/x86/xen/enlighten.c
    @@ -95,7 +95,7 @@ struct shared_info *HYPERVISOR_shared_in
    *
    * 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)
    {
    --- 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)
    --


    \
     
     \ /
      Last update: 2008-04-17 03:31    [W:4.817 / U:0.316 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site