ia64/xen-unstable

changeset 1234:bf4b11f253d4

bitkeeper revision 1.828 (40640df3HBWjpgwaIGWq-p3zFq0m5g)

Merge tetris.cl.cam.ac.uk:/auto/groups/xeno/BK/xeno.bk
into tetris.cl.cam.ac.uk:/auto/groups/xeno/users/iap10/xeno-clone/xeno.bk
author iap10@tetris.cl.cam.ac.uk
date Fri Mar 26 11:03:15 2004 +0000 (2004-03-26)
parents 53a93ee1224d 01aaaa1d5d17
children 8b5451a42056
files .rootkeys docs/Console-HOWTO.txt xen/arch/i386/entry.S xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c xenolinux-2.4.25-sparse/arch/xen/kernel/entry.S xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c xenolinux-2.4.25-sparse/arch/xen/kernel/time.c xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h xenolinux-2.4.25-sparse/include/asm-xen/synch_bitops.h xenolinux-2.4.25-sparse/include/asm-xen/system.h
line diff
     1.1 --- a/.rootkeys	Thu Mar 25 15:02:26 2004 +0000
     1.2 +++ b/.rootkeys	Fri Mar 26 11:03:15 2004 +0000
     1.3 @@ -684,6 +684,7 @@ 3e5a4e67AJPjW-zL7p-xWuA6IVeH1g xenolinux
     1.4  3e5a4e68uJz-xI0IBVMD7xRLQKJDFg xenolinux-2.4.25-sparse/include/asm-xen/segment.h
     1.5  3e5a4e68Nfdh6QcOKUTGCaYkf2LmYA xenolinux-2.4.25-sparse/include/asm-xen/smp.h
     1.6  3fa8e3f0kBLeE4To2vpdi3cpJbIkbQ xenolinux-2.4.25-sparse/include/asm-xen/suspend.h
     1.7 +4062f7e2PzFOUGT0PaE7A0VprTU3JQ xenolinux-2.4.25-sparse/include/asm-xen/synch_bitops.h
     1.8  3e5a4e68mTr0zcp9SXDbnd-XLrrfxw xenolinux-2.4.25-sparse/include/asm-xen/system.h
     1.9  3f1056a9L_kqHcFheV00KbKBzv9j5w xenolinux-2.4.25-sparse/include/asm-xen/vga.h
    1.10  3f689063nhrIRsMMZjZxMFk7iEINqQ xenolinux-2.4.25-sparse/include/asm-xen/xen_proc.h
     2.1 --- a/docs/Console-HOWTO.txt	Thu Mar 25 15:02:26 2004 +0000
     2.2 +++ b/docs/Console-HOWTO.txt	Fri Mar 26 11:03:15 2004 +0000
     2.3 @@ -60,8 +60,8 @@ Virtual console for other domains
     2.4   the provided init.d script. To integrate startup and shutdown of xend
     2.5   in such a system, you will need to run a few configuration commands:
     2.6    # chkconfig --add xend
     2.7 -  # chkconfig --level 35 on
     2.8 -  # chkconfig --level 01246 off
     2.9 +  # chkconfig --level 35 xend on
    2.10 +  # chkconfig --level 01246 xend off
    2.11   This will avoid the need to run xend manually from rc.local, for example.
    2.12  
    2.13   Note that, when a domain is created using xc_dom_create.py, xend MUST
     3.1 --- a/xen/arch/i386/entry.S	Thu Mar 25 15:02:26 2004 +0000
     3.2 +++ b/xen/arch/i386/entry.S	Fri Mar 26 11:03:15 2004 +0000
     3.3 @@ -373,7 +373,7 @@ test_all_events:
     3.4          andl UPCALL_PENDING(%eax),%ecx  # ECX = pending & ~mask
     3.5          andl $1,%ecx                    # Is bit 0 pending and not masked?
     3.6          jz   restore_all_guest
     3.7 -        orl  %ecx,UPCALL_MASK(%eax)     # Upcalls are masked during delivery
     3.8 +        lock btsl $0,UPCALL_MASK(%eax)  # Upcalls are masked during delivery
     3.9  /*process_guest_events:*/
    3.10          movzwl PROCESSOR(%ebx),%edx
    3.11          shl  $4,%edx                    # sizeof(guest_trap_bounce) == 16
     4.1 --- a/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c	Thu Mar 25 15:02:26 2004 +0000
     4.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/drivers/console/console.c	Fri Mar 26 11:03:15 2004 +0000
     4.3 @@ -144,12 +144,7 @@ void xen_console_init(void)
     4.4  
     4.5      register_console(&kcons_info);
     4.6  
     4.7 -    /*
     4.8 -     * XXX This prevents a bogus 'VIRQ_ERROR' when interrupts are enabled
     4.9 -     * for the first time. This works because by this point all important
    4.10 -     * VIRQs (eg. timer) have been properly bound.
    4.11 -     */
    4.12 -    clear_bit(0, &HYPERVISOR_shared_info->evtchn_pending[0]);
    4.13 +    evtchn_clear_error_virq();
    4.14  }
    4.15  
    4.16  
     5.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/entry.S	Thu Mar 25 15:02:26 2004 +0000
     5.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/entry.S	Fri Mar 26 11:03:15 2004 +0000
     5.3 @@ -210,14 +210,14 @@ ENTRY(system_call)
     5.4  	movl %eax,EAX(%esp)		# save the return value
     5.5  ENTRY(ret_from_sys_call)
     5.6          movl SYMBOL_NAME(HYPERVISOR_shared_info),%esi
     5.7 -        btsl $0,evtchn_upcall_mask(%esi) # make tests atomic
     5.8 +        lock btsl $0,evtchn_upcall_mask(%esi) # make tests atomic
     5.9  ret_syscall_tests:
    5.10  	cmpl $0,need_resched(%ebx)
    5.11  	jne reschedule
    5.12  	cmpl $0,sigpending(%ebx)
    5.13  	je   safesti                    # ensure need_resched updates are seen
    5.14  signal_return:
    5.15 -	btrl $0,evtchn_upcall_mask(%esi) # reenable event callbacks
    5.16 +	lock btrl $0,evtchn_upcall_mask(%esi) # reenable event callbacks
    5.17  	movl %esp,%eax
    5.18  	xorl %edx,%edx
    5.19  	call SYMBOL_NAME(do_signal)
    5.20 @@ -254,7 +254,7 @@ ret_from_exception:
    5.21  
    5.22  	ALIGN
    5.23  reschedule:
    5.24 -        btrl $0,evtchn_upcall_mask(%esi)       # reenable event callbacks
    5.25 +        lock btrl $0,evtchn_upcall_mask(%esi)  # reenable event callbacks
    5.26  	call SYMBOL_NAME(schedule)             # test
    5.27  	jmp ret_from_sys_call
    5.28  
    5.29 @@ -317,12 +317,12 @@ 11:     push %esp
    5.30          movb CS(%esp),%cl
    5.31  	test $2,%cl          # slow return to ring 2 or 3
    5.32  	jne  ret_syscall_tests
    5.33 -safesti:btrl $0,evtchn_upcall_mask(%esi) # reenable event callbacks
    5.34 +safesti:lock btrl $0,evtchn_upcall_mask(%esi) # reenable event callbacks
    5.35  scrit:  /**** START OF CRITICAL REGION ****/
    5.36          testb $1,evtchn_upcall_pending(%esi)
    5.37          jnz  14f              # process more events if necessary...
    5.38          RESTORE_ALL
    5.39 -14:     btsl $0,evtchn_upcall_mask(%esi)
    5.40 +14:     lock btsl $0,evtchn_upcall_mask(%esi)
    5.41          jmp  11b
    5.42  ecrit:  /**** END OF CRITICAL REGION ****/
    5.43  # [How we do the fixup]. We want to merge the current stack frame with the
    5.44 @@ -364,7 +364,7 @@ critical_fixup_table:
    5.45          .byte 0x20                            # pop  %es
    5.46          .byte 0x24,0x24,0x24                  # add  $4,%esp
    5.47          .byte 0x28                            # iret
    5.48 -        .byte 0x00,0x00,0x00,0x00,0x00        # btsl $0,4(%esi)
    5.49 +        .byte 0x00,0x00,0x00,0x00,0x00,0x00   # lock btsl $0,4(%esi)
    5.50          .byte 0x00,0x00                       # jmp  11b
    5.51  
    5.52  # Hypervisor uses this for application faults while it executes.
     6.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c	Thu Mar 25 15:02:26 2004 +0000
     6.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/evtchn.c	Fri Mar 26 11:03:15 2004 +0000
     6.3 @@ -14,6 +14,7 @@
     6.4  #include <asm/atomic.h>
     6.5  #include <asm/system.h>
     6.6  #include <asm/ptrace.h>
     6.7 +#include <asm/synch_bitops.h>
     6.8  #include <asm/hypervisor.h>
     6.9  #include <asm/hypervisor-ifs/event_channel.h>
    6.10  
    6.11 @@ -84,7 +85,7 @@ static void evtchn_handle_exceptions(sha
    6.12              {
    6.13                  printk(KERN_ALERT "Error on IRQ line %d!\n", 
    6.14                         dynirq + DYNIRQ_BASE);
    6.15 -                clear_bit(port, &s->evtchn_exception[0]);
    6.16 +                synch_clear_bit(port, &s->evtchn_exception[0]);
    6.17              }
    6.18              else
    6.19                  evtchn_device_upcall(port, 1);
    6.20 @@ -99,7 +100,7 @@ void evtchn_do_upcall(struct pt_regs *re
    6.21  
    6.22      local_irq_save(flags);
    6.23      
    6.24 -    while ( test_and_clear_bit(0, &s->evtchn_upcall_pending) )
    6.25 +    while ( synch_test_and_clear_bit(0, &s->evtchn_upcall_pending) )
    6.26      {
    6.27          if ( s->evtchn_pending_sel != 0 )
    6.28              evtchn_handle_normal(s, regs);
     7.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c	Thu Mar 25 15:02:26 2004 +0000
     7.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/setup.c	Fri Mar 26 11:03:15 2004 +0000
     7.3 @@ -1151,6 +1151,9 @@ static void stop_task(void *unused)
     7.4      extern void blkdev_suspend(void);
     7.5      extern void blkdev_resume(void);
     7.6      
     7.7 +    extern void time_suspend(void);
     7.8 +    extern void time_resume(void);
     7.9 +
    7.10      unsigned long *pfn_to_mfn_frame_list = NULL;
    7.11      suspend_record_t *suspend_record     = NULL;
    7.12      struct net_device *dev;
    7.13 @@ -1198,6 +1201,8 @@ static void stop_task(void *unused)
    7.14  
    7.15      __cli();
    7.16  
    7.17 +    time_suspend();
    7.18 +
    7.19      HYPERVISOR_shared_info = (shared_info_t *)empty_zero_page;
    7.20      clear_fixmap(FIX_SHARED_INFO);
    7.21  
    7.22 @@ -1211,6 +1216,8 @@ static void stop_task(void *unused)
    7.23      HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
    7.24      memset(empty_zero_page, 0, PAGE_SIZE);
    7.25  
    7.26 +    time_resume();
    7.27 +
    7.28      __sti();
    7.29  
    7.30      blkdev_resume();
     8.1 --- a/xenolinux-2.4.25-sparse/arch/xen/kernel/time.c	Thu Mar 25 15:02:26 2004 +0000
     8.2 +++ b/xenolinux-2.4.25-sparse/arch/xen/kernel/time.c	Fri Mar 26 11:03:15 2004 +0000
     8.3 @@ -634,6 +634,24 @@ void __init time_init(void)
     8.4      rdtscll(alarm);
     8.5  }
     8.6  
     8.7 +void time_suspend(void)
     8.8 +{
     8.9 +}
    8.10 +
    8.11 +void time_resume(void)
    8.12 +{
    8.13 +    unsigned long flags;
    8.14 +    write_lock_irqsave(&xtime_lock, flags);
    8.15 +    /* Get timebases for new environment. */ 
    8.16 +    __get_time_values_from_xen();
    8.17 +    /* Reset our own concept of passage of system time. */
    8.18 +    processed_system_time = shadow_system_time;
    8.19 +    /* Accept a warp in UTC (wall-clock) time. */
    8.20 +    last_seen_tv.tv_sec = 0;
    8.21 +    /* Make sure we resync UTC time with Xen on next timer interrupt. */
    8.22 +    last_update_from_xen = 0;
    8.23 +    write_unlock_irqrestore(&xtime_lock, flags);
    8.24 +}
    8.25  
    8.26  /*
    8.27   * /proc/sys/xen: This really belongs in another file. It can stay here for
     9.1 --- a/xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h	Thu Mar 25 15:02:26 2004 +0000
     9.2 +++ b/xenolinux-2.4.25-sparse/include/asm-xen/evtchn.h	Fri Mar 26 11:03:15 2004 +0000
     9.3 @@ -13,6 +13,7 @@
     9.4  #include <linux/config.h>
     9.5  #include <asm/hypervisor.h>
     9.6  #include <asm/ptrace.h>
     9.7 +#include <asm/synch_bitops.h>
     9.8  
     9.9  /*
    9.10   * LOW-LEVEL DEFINITIONS
    9.11 @@ -27,21 +28,15 @@ void evtchn_device_upcall(int port, int 
    9.12  static inline void mask_evtchn(int port)
    9.13  {
    9.14      shared_info_t *s = HYPERVISOR_shared_info;
    9.15 -    set_bit(port, &s->evtchn_mask[0]);
    9.16 +    synch_set_bit(port, &s->evtchn_mask[0]);
    9.17  }
    9.18  
    9.19 -/*
    9.20 - * I haven't thought too much about the synchronisation in here against
    9.21 - * other CPUs, but all the bit-update operations are reorder barriers on
    9.22 - * x86 so reordering concerns aren't a problem for now. Some mb() calls
    9.23 - * would be required on weaker architectures I think. -- KAF (24/3/2004)
    9.24 - */
    9.25  static inline void unmask_evtchn(int port)
    9.26  {
    9.27      shared_info_t *s = HYPERVISOR_shared_info;
    9.28      int need_upcall = 0;
    9.29  
    9.30 -    clear_bit(port, &s->evtchn_mask[0]);
    9.31 +    synch_clear_bit(port, &s->evtchn_mask[0]);
    9.32  
    9.33      /*
    9.34       * The following is basically the equivalent of 'hw_resend_irq'. Just like
    9.35 @@ -49,34 +44,43 @@ static inline void unmask_evtchn(int por
    9.36       */
    9.37  
    9.38      /* Asserted a standard notification? */
    9.39 -    if (  test_bit        (port,    &s->evtchn_pending[0]) && 
    9.40 -         !test_and_set_bit(port>>5, &s->evtchn_pending_sel) )
    9.41 +    if (  synch_test_bit        (port,    &s->evtchn_pending[0]) && 
    9.42 +         !synch_test_and_set_bit(port>>5, &s->evtchn_pending_sel) )
    9.43          need_upcall = 1;
    9.44  
    9.45      /* Asserted an exceptional notification? */
    9.46 -    if (  test_bit        (port,    &s->evtchn_exception[0]) && 
    9.47 -         !test_and_set_bit(port>>5, &s->evtchn_exception_sel) )
    9.48 +    if (  synch_test_bit        (port,    &s->evtchn_exception[0]) && 
    9.49 +         !synch_test_and_set_bit(port>>5, &s->evtchn_exception_sel) )
    9.50          need_upcall = 1;
    9.51  
    9.52      /* If asserted either type of notification, check the master flags. */
    9.53      if ( need_upcall &&
    9.54 -         !test_and_set_bit(0,       &s->evtchn_upcall_pending) &&
    9.55 -         !test_bit        (0,       &s->evtchn_upcall_mask) )
    9.56 +         !synch_test_and_set_bit(0,       &s->evtchn_upcall_pending) &&
    9.57 +         !synch_test_bit        (0,       &s->evtchn_upcall_mask) )
    9.58          evtchn_do_upcall(NULL);
    9.59  }
    9.60  
    9.61  static inline void clear_evtchn(int port)
    9.62  {
    9.63      shared_info_t *s = HYPERVISOR_shared_info;
    9.64 -    clear_bit(port, &s->evtchn_pending[0]);
    9.65 +    synch_clear_bit(port, &s->evtchn_pending[0]);
    9.66  }
    9.67  
    9.68  static inline void clear_evtchn_exception(int port)
    9.69  {
    9.70      shared_info_t *s = HYPERVISOR_shared_info;
    9.71 -    clear_bit(port, &s->evtchn_exception[0]);
    9.72 +    synch_clear_bit(port, &s->evtchn_exception[0]);
    9.73  }
    9.74  
    9.75 +static inline void evtchn_clear_error_virq(void)
    9.76 +{
    9.77 +    /*
    9.78 +     * XXX This prevents a bogus 'VIRQ_ERROR' when interrupts are enabled
    9.79 +     * for the first time. This works because by this point all important
    9.80 +     * VIRQs (eg. timer) have been properly bound.
    9.81 +     */
    9.82 +    synch_clear_bit(0, &HYPERVISOR_shared_info->evtchn_pending[0]);
    9.83 +}
    9.84  
    9.85  /*
    9.86   * CHARACTER-DEVICE DEFINITIONS
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/xenolinux-2.4.25-sparse/include/asm-xen/synch_bitops.h	Fri Mar 26 11:03:15 2004 +0000
    10.3 @@ -0,0 +1,83 @@
    10.4 +#ifndef __XEN_SYNCH_BITOPS_H__
    10.5 +#define __XEN_SYNCH_BITOPS_H__
    10.6 +
    10.7 +/*
    10.8 + * Copyright 1992, Linus Torvalds.
    10.9 + * Heavily modified to provide guaranteed strong synchronisation
   10.10 + * when communicating with Xen or other guest OSes running on other CPUs.
   10.11 + */
   10.12 +
   10.13 +#include <linux/config.h>
   10.14 +
   10.15 +#define ADDR (*(volatile long *) addr)
   10.16 +
   10.17 +static __inline__ void synch_set_bit(int nr, volatile void * addr)
   10.18 +{
   10.19 +    __asm__ __volatile__ ( 
   10.20 +        "lock btsl %1,%0"
   10.21 +        : "=m" (ADDR) : "Ir" (nr) : "memory" );
   10.22 +}
   10.23 +
   10.24 +static __inline__ void synch_clear_bit(int nr, volatile void * addr)
   10.25 +{
   10.26 +    __asm__ __volatile__ (
   10.27 +        "lock btrl %1,%0"
   10.28 +        : "=m" (ADDR) : "Ir" (nr) : "memory" );
   10.29 +}
   10.30 +
   10.31 +static __inline__ void synch_change_bit(int nr, volatile void * addr)
   10.32 +{
   10.33 +    __asm__ __volatile__ (
   10.34 +        "lock btcl %1,%0"
   10.35 +        : "=m" (ADDR) : "Ir" (nr) : "memory" );
   10.36 +}
   10.37 +
   10.38 +static __inline__ int synch_test_and_set_bit(int nr, volatile void * addr)
   10.39 +{
   10.40 +    int oldbit;
   10.41 +    __asm__ __volatile__ (
   10.42 +        "lock btsl %2,%1\n\tsbbl %0,%0"
   10.43 +        : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
   10.44 +    return oldbit;
   10.45 +}
   10.46 +
   10.47 +static __inline__ int synch_test_and_clear_bit(int nr, volatile void * addr)
   10.48 +{
   10.49 +    int oldbit;
   10.50 +    __asm__ __volatile__ (
   10.51 +        "lock btrl %2,%1\n\tsbbl %0,%0"
   10.52 +        : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
   10.53 +    return oldbit;
   10.54 +}
   10.55 +
   10.56 +static __inline__ int synch_test_and_change_bit(int nr, volatile void * addr)
   10.57 +{
   10.58 +    int oldbit;
   10.59 +
   10.60 +    __asm__ __volatile__ (
   10.61 +        "lock btcl %2,%1\n\tsbbl %0,%0"
   10.62 +        : "=r" (oldbit), "=m" (ADDR) : "Ir" (nr) : "memory");
   10.63 +    return oldbit;
   10.64 +}
   10.65 +
   10.66 +static __inline__ int synch_const_test_bit(int nr, const volatile void * addr)
   10.67 +{
   10.68 +    return ((1UL << (nr & 31)) & 
   10.69 +            (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
   10.70 +}
   10.71 +
   10.72 +static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
   10.73 +{
   10.74 +    int oldbit;
   10.75 +    __asm__ __volatile__ (
   10.76 +        "btl %2,%1\n\tsbbl %0,%0"
   10.77 +        : "=r" (oldbit) : "m" (ADDR), "Ir" (nr) );
   10.78 +    return oldbit;
   10.79 +}
   10.80 +
   10.81 +#define synch_test_bit(nr,addr) \
   10.82 +(__builtin_constant_p(nr) ? \
   10.83 + synch_const_test_bit((nr),(addr)) : \
   10.84 + synch_var_test_bit((nr),(addr)))
   10.85 +
   10.86 +#endif /* __XEN_SYNCH_BITOPS_H__ */
    11.1 --- a/xenolinux-2.4.25-sparse/include/asm-xen/system.h	Thu Mar 25 15:02:26 2004 +0000
    11.2 +++ b/xenolinux-2.4.25-sparse/include/asm-xen/system.h	Fri Mar 26 11:03:15 2004 +0000
    11.3 @@ -4,9 +4,10 @@
    11.4  #include <linux/config.h>
    11.5  #include <linux/kernel.h>
    11.6  #include <linux/init.h>
    11.7 +#include <linux/bitops.h>
    11.8 +#include <asm/synch_bitops.h>
    11.9  #include <asm/segment.h>
   11.10  #include <asm/hypervisor.h>
   11.11 -#include <linux/bitops.h> /* for LOCK_PREFIX */
   11.12  #include <asm/evtchn.h>
   11.13  
   11.14  #ifdef __KERNEL__
   11.15 @@ -250,19 +251,19 @@ static inline unsigned long __cmpxchg(vo
   11.16  	unsigned long prev;
   11.17  	switch (size) {
   11.18  	case 1:
   11.19 -		__asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
   11.20 +		__asm__ __volatile__("lock cmpxchgb %b1,%2"
   11.21  				     : "=a"(prev)
   11.22  				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
   11.23  				     : "memory");
   11.24  		return prev;
   11.25  	case 2:
   11.26 -		__asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
   11.27 +		__asm__ __volatile__("lock cmpxchgw %w1,%2"
   11.28  				     : "=a"(prev)
   11.29  				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
   11.30  				     : "memory");
   11.31  		return prev;
   11.32  	case 4:
   11.33 -		__asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
   11.34 +		__asm__ __volatile__("lock cmpxchgl %1,%2"
   11.35  				     : "=a"(prev)
   11.36  				     : "q"(new), "m"(*__xg(ptr)), "0"(old)
   11.37  				     : "memory");
   11.38 @@ -320,49 +321,47 @@ static inline unsigned long __cmpxchg(vo
   11.39  
   11.40  #define set_wmb(var, value) do { var = value; wmb(); } while (0)
   11.41  
   11.42 +#define safe_halt()             ((void)0)
   11.43 +
   11.44  /*
   11.45 - * NB. ALl the following routines are SMP-safe on x86, even where they look
   11.46 - * possibly racy. For example, we must ensure that we clear the mask bit and
   11.47 - * /then/ check teh pending bit. But this will happen because the bit-update
   11.48 - * operations are ordering barriers.
   11.49 - * 
   11.50 - * For this reason also, many uses of 'barrier' here are rather anal. But
   11.51 - * they do no harm.
   11.52 + * Note the use of synch_*_bit() operations in the following. These operations
   11.53 + * ensure correct serialisation of checks and updates w.r.t. Xen executing on
   11.54 + * a different CPU.
   11.55   */
   11.56  
   11.57  #define __cli()                                                               \
   11.58  do {                                                                          \
   11.59 -    set_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask);                  \
   11.60 -    barrier();                                                                \
   11.61 +    synch_set_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask);            \
   11.62  } while (0)
   11.63  
   11.64  #define __sti()                                                               \
   11.65  do {                                                                          \
   11.66      shared_info_t *_shared = HYPERVISOR_shared_info;                          \
   11.67 -    clear_bit(0, &_shared->evtchn_upcall_mask);                               \
   11.68 -    barrier();                                                                \
   11.69 -    if ( unlikely(test_bit(0, &_shared->evtchn_upcall_pending)) )             \
   11.70 +    synch_clear_bit(0, &_shared->evtchn_upcall_mask);                         \
   11.71 +    if ( unlikely(synch_test_bit(0, &_shared->evtchn_upcall_pending)) )       \
   11.72          evtchn_do_upcall(NULL);                                               \
   11.73  } while (0)
   11.74  
   11.75  #define __save_flags(x)                                                       \
   11.76  do {                                                                          \
   11.77 -    (x) = test_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask);           \
   11.78 -    barrier();                                                                \
   11.79 +    (x) = synch_test_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask);     \
   11.80  } while (0)
   11.81  
   11.82 -#define __restore_flags(x)      do { if (x) __cli(); else __sti(); } while (0)
   11.83 +#define __restore_flags(x) do { if (x) __cli(); else __sti(); } while (0)
   11.84  
   11.85 -#define safe_halt()             ((void)0)
   11.86 +#define __save_and_cli(x)                                                     \
   11.87 +do {                                                                          \
   11.88 +    (x) = synch_test_and_set_bit(                                             \
   11.89 +        0, &HYPERVISOR_shared_info->evtchn_upcall_mask);                      \
   11.90 +} while (0)
   11.91  
   11.92 -#define __save_and_cli(x)	do { __save_flags(x); __cli(); } while(0);
   11.93 -#define __save_and_sti(x)	do { __save_flags(x); __sti(); } while(0);
   11.94 +#define __save_and_sti(x)                                                     \
   11.95 +do {                                                                          \
   11.96 +    (x) = synch_test_and_clear_bit(                                           \
   11.97 +        0, &HYPERVISOR_shared_info->evtchn_upcall_mask);                      \
   11.98 +} while (0)
   11.99  
  11.100 -#define local_irq_save(x)                                                     \
  11.101 -do {                                                                          \
  11.102 -    (x) = test_and_set_bit(0, &HYPERVISOR_shared_info->evtchn_upcall_mask);   \
  11.103 -    barrier();                                                                \
  11.104 -} while (0)
  11.105 +#define local_irq_save(x)       __save_and_cli(x)
  11.106  #define local_irq_restore(x)    __restore_flags(x)
  11.107  #define local_irq_disable()     __cli()
  11.108  #define local_irq_enable()      __sti()