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
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
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()