Xen: make events.c portable for ia64/xen support
Isaku Yamahata [Wed, 2 Apr 2008 17:53:56 +0000 (10:53 -0700)]
Remove x86 dependency in drivers/xen/events.c for ia64/xen support
introducing include/asm/xen/events.h.
Introduce xen_irqs_disabled() to hide regs->flags
Introduce xen_do_IRQ() to hide regs->orig_ax.
make enum ipi_vector definition arch specific. ia64/xen needs four vectors.
Add one rmb() because on ia64 xchg() isn't barrier.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Jeremy Fitzhardinge <jeremy.fitzhardinge@citrix.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

drivers/xen/events.c
include/asm-x86/xen/events.h [new file with mode: 0644]
include/xen/events.h

index c50d499..2396b44 100644 (file)
@@ -469,7 +469,7 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
        for_each_online_cpu(i) {
                struct vcpu_info *v = per_cpu(xen_vcpu, i);
                printk("%d: masked=%d pending=%d event_sel %08lx\n  ", i,
-                       (get_irq_regs() && i == cpu) ? !(get_irq_regs()->flags & X86_EFLAGS_IF) : v->evtchn_upcall_mask,
+                       (get_irq_regs() && i == cpu) ? xen_irqs_disabled(get_irq_regs()) : v->evtchn_upcall_mask,
                        v->evtchn_upcall_pending,
                        v->evtchn_pending_sel);
        }
@@ -527,7 +527,10 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
                if (__get_cpu_var(nesting_count)++)
                        goto out;
 
-               /* NB. No need for a barrier here -- XCHG is a barrier on x86. */
+#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
+               /* Clear master flag /before/ clearing selector flag. */
+               rmb();
+#endif
                pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
                while (pending_words != 0) {
                        unsigned long pending_bits;
@@ -539,10 +542,8 @@ void xen_evtchn_do_upcall(struct pt_regs *regs)
                                int port = (word_idx * BITS_PER_LONG) + bit_idx;
                                int irq = evtchn_to_irq[port];
 
-                               if (irq != -1) {
-                                       regs->orig_ax = ~irq;
-                                       do_IRQ(regs);
-                               }
+                               if (irq != -1)
+                                       xen_do_IRQ(irq, regs);
                        }
                }
 
diff --git a/include/asm-x86/xen/events.h b/include/asm-x86/xen/events.h
new file mode 100644 (file)
index 0000000..596312a
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef __XEN_EVENTS_H
+#define __XEN_EVENTS_H
+
+enum ipi_vector {
+       XEN_RESCHEDULE_VECTOR,
+       XEN_CALL_FUNCTION_VECTOR,
+
+       XEN_NR_IPIS,
+};
+
+static inline int xen_irqs_disabled(struct pt_regs *regs)
+{
+       return raw_irqs_disabled_flags(regs->flags);
+}
+
+static inline void xen_do_IRQ(int irq, struct pt_regs *regs)
+{
+       regs->orig_ax = ~irq;
+       do_IRQ(regs);
+}
+
+#endif /* __XEN_EVENTS_H */
index 2bde54d..d99a3e0 100644 (file)
@@ -5,13 +5,7 @@
 
 #include <xen/interface/event_channel.h>
 #include <asm/xen/hypercall.h>
-
-enum ipi_vector {
-       XEN_RESCHEDULE_VECTOR,
-       XEN_CALL_FUNCTION_VECTOR,
-
-       XEN_NR_IPIS,
-};
+#include <asm/xen/events.h>
 
 int bind_evtchn_to_irq(unsigned int evtchn);
 int bind_evtchn_to_irqhandler(unsigned int evtchn,