# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 0915074c356e37017562298ded188c5c354ed463
# Parent 37ad91483bd3dc65475bbe35c15f7c547c3cacea
Rationalise the kernel event-channel binding interfaces. The
new interfaces are simpler and should be implementable by any
architecture.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c
--- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c Tue Nov 8
14:58:31 2005
@@ -30,12 +30,6 @@
return op.u.bind_virq.port;
}
-int bind_virq_to_irq(int virq, int cpu)
-{
- printk("bind_virq_to_irq called... FIXME??\n");
- while(1);
-}
-
#if 0
void notify_remote_via_irq(int virq)
{
@@ -43,19 +37,6 @@
while(1);
}
#endif
-
-void unbind_virq_from_evtchn(int virq)
-{
- evtchn_op_t op;
-
- op.cmd = EVTCHNOP_close;
-// op.u.close.dom = DOMID_SELF;
- op.u.close.port = virq_to_evtchn[virq];
- if ( HYPERVISOR_event_channel_op(&op) != 0 )
- BUG();
-
- virq_to_evtchn[virq] = -1;
-}
int bind_evtchn_to_irqhandler(unsigned int evtchn,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c Tue Nov 8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smp.c Tue Nov 8 14:58:31 2005
@@ -127,13 +127,13 @@
return SET_APIC_DEST_FIELD(mask);
}
-DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
static inline void __send_IPI_one(unsigned int cpu, int vector)
{
- int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
- BUG_ON(evtchn < 0);
- notify_remote_via_evtchn(evtchn);
+ int irq = per_cpu(ipi_to_irq, cpu)[vector];
+ BUG_ON(irq < 0);
+ notify_remote_via_irq(irq);
}
void __send_IPI_shortcut(unsigned int shortcut, int vector)
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Tue Nov 8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c Tue Nov 8 14:58:31 2005
@@ -748,10 +748,19 @@
/* Dynamically-mapped IRQ. */
DEFINE_PER_CPU(int, timer_irq);
-static struct irqaction irq_timer = {
- timer_interrupt, SA_INTERRUPT, CPU_MASK_NONE, "timer0",
- NULL, NULL
-};
+extern void (*late_time_init)(void);
+static void setup_cpu0_timer_irq(void)
+{
+ per_cpu(timer_irq, 0) =
+ bind_virq_to_irqhandler(
+ VIRQ_TIMER,
+ 0,
+ timer_interrupt,
+ SA_INTERRUPT,
+ "timer0",
+ NULL);
+ BUG_ON(per_cpu(timer_irq, 0) < 0);
+}
void __init time_init(void)
{
@@ -785,8 +794,8 @@
rdtscll(vxtime.last_tsc);
#endif
- per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER, 0);
- (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer);
+ /* Cannot request_irq() until kmem is initialised. */
+ late_time_init = setup_cpu0_timer_irq;
}
/* Convert jiffies to system time. */
@@ -865,17 +874,22 @@
per_cpu(shadow_time, cpu).system_timestamp;
} while (read_seqretry(&xtime_lock, seq));
- per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER, cpu);
sprintf(timer_name[cpu], "timer%d", cpu);
- BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt,
- SA_INTERRUPT, timer_name[cpu], NULL));
+ per_cpu(timer_irq, cpu) =
+ bind_virq_to_irqhandler(
+ VIRQ_TIMER,
+ cpu,
+ timer_interrupt,
+ SA_INTERRUPT,
+ timer_name[cpu],
+ NULL);
+ BUG_ON(per_cpu(timer_irq, cpu) < 0);
}
void local_teardown_timer(unsigned int cpu)
{
BUG_ON(cpu == 0);
- free_irq(per_cpu(timer_irq, cpu), NULL);
- unbind_virq_from_irq(VIRQ_TIMER, cpu);
+ unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
}
#endif
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Nov 8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Tue Nov 8 14:58:31 2005
@@ -52,16 +52,29 @@
/* IRQ <-> event-channel mappings. */
static int evtchn_to_irq[NR_EVENT_CHANNELS];
-static int irq_to_evtchn[NR_IRQS];
+
+/* Packed IRQ information: binding type, sub-type index, and event channel. */
+static u32 irq_info[NR_IRQS];
+/* Binding types. */
+enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
+/* Constructor for packed IRQ information. */
+#define mk_irq_info(type, index, evtchn) \
+ (((u32)(type) << 24) | ((u32)(index) << 16) | (u32)(evtchn))
+/* Convenient shorthand for packed representation of an unbound IRQ. */
+#define IRQ_UNBOUND mk_irq_info(IRQT_UNBOUND, 0, 0)
+/* Accessor macros for packed IRQ information. */
+#define evtchn_from_irq(irq) ((u16)(irq_info[irq]))
+#define index_from_irq(irq) ((u8)(irq_info[irq] >> 16))
+#define type_from_irq(irq) ((u8)(irq_info[irq] >> 24))
/* IRQ <-> VIRQ mapping. */
DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]);
-/* evtchn <-> IPI mapping. */
+/* IRQ <-> IPI mapping. */
#ifndef NR_IPIS
#define NR_IPIS 1
#endif
-DEFINE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
/* Reference counts for bindings to IRQs. */
static int irq_bindcount[NR_IRQS];
@@ -92,6 +105,8 @@
memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
}
+
+#define cpu_from_evtchn(evtchn) (cpu_evtchn[evtchn])
#else
@@ -100,6 +115,7 @@
~(sh)->evtchn_mask[idx])
#define bind_evtchn_to_cpu(chn,cpu) ((void)0)
#define init_evtchn_cpu_bindings() ((void)0)
+#define cpu_from_evtchn(evtchn) (0)
#endif
@@ -121,7 +137,8 @@
} while (0)
#endif
-#define VALID_EVTCHN(_chn) ((_chn) >= 0)
+/* Xen will never allocate port zero for any purpose. */
+#define VALID_EVTCHN(chn) ((chn) != 0)
/*
* Force a proper event-channel callback from Xen after clearing the
@@ -179,7 +196,26 @@
return irq;
}
-int bind_virq_to_irq(int virq, int cpu)
+static int bind_evtchn_to_irq(unsigned int evtchn)
+{
+ int irq;
+
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((irq = evtchn_to_irq[evtchn]) == -1) {
+ irq = find_unbound_irq();
+ evtchn_to_irq[evtchn] = irq;
+ irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
+ }
+
+ irq_bindcount[irq]++;
+
+ spin_unlock(&irq_mapping_update_lock);
+
+ return irq;
+}
+
+static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq };
int evtchn, irq;
@@ -194,7 +230,7 @@
irq = find_unbound_irq();
evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
per_cpu(virq_to_irq, cpu)[virq] = irq;
@@ -207,59 +243,26 @@
return irq;
}
-EXPORT_SYMBOL(bind_virq_to_irq);
-
-void unbind_virq_from_irq(int virq, int cpu)
-{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
- int irq = per_cpu(virq_to_irq, cpu)[virq];
- int evtchn = irq_to_evtchn[irq];
-
- spin_lock(&irq_mapping_update_lock);
-
- if (--irq_bindcount[irq] == 0) {
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-
- /*
- * This is a slight hack. Interdomain ports can be allocated
- * directly by userspace, and at that point they get bound by
- * Xen to vcpu 0. We therefore need to make sure that if we get
- * an event on an event channel we don't know about vcpu 0
- * handles it. Binding channels to vcpu 0 when closing them
- * achieves this.
- */
- bind_evtchn_to_cpu(evtchn, 0);
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- per_cpu(virq_to_irq, cpu)[virq] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
-}
-EXPORT_SYMBOL(unbind_virq_from_irq);
-
-int bind_ipi_to_irq(int ipi, int cpu)
+
+static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
{
evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi };
int evtchn, irq;
spin_lock(&irq_mapping_update_lock);
- if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
+ if ((irq = per_cpu(ipi_to_irq, cpu)[ipi]) == -1) {
op.u.bind_ipi.vcpu = cpu;
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
evtchn = op.u.bind_ipi.port;
irq = find_unbound_irq();
evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
-
- per_cpu(ipi_to_evtchn, cpu)[ipi] = evtchn;
+ irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
+
+ per_cpu(ipi_to_irq, cpu)[ipi] = irq;
bind_evtchn_to_cpu(evtchn, cpu);
- } else {
- irq = evtchn_to_irq[evtchn];
}
irq_bindcount[irq]++;
@@ -268,63 +271,36 @@
return irq;
}
-EXPORT_SYMBOL(bind_ipi_to_irq);
-
-void unbind_ipi_from_irq(int ipi, int cpu)
+
+static void unbind_from_irq(unsigned int irq)
{
evtchn_op_t op = { .cmd = EVTCHNOP_close };
- int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi];
- int irq = evtchn_to_irq[evtchn];
+ int evtchn = evtchn_from_irq(irq);
spin_lock(&irq_mapping_update_lock);
- if (--irq_bindcount[irq] == 0) {
+ if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
op.u.close.port = evtchn;
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
- /* See comments in unbind_virq_from_irq */
+ switch (type_from_irq(irq)) {
+ case IRQT_VIRQ:
+ per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
+ [index_from_irq(irq)] = -1;
+ break;
+ case IRQT_IPI:
+ per_cpu(ipi_to_irq, cpu_from_evtchn(evtchn))
+ [index_from_irq(irq)] = -1;
+ break;
+ default:
+ break;
+ }
+
+ /* Closed ports are implicitly re-bound to VCPU0. */
bind_evtchn_to_cpu(evtchn, 0);
+
evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
- per_cpu(ipi_to_evtchn, cpu)[ipi] = -1;
- }
-
- spin_unlock(&irq_mapping_update_lock);
-}
-EXPORT_SYMBOL(unbind_ipi_from_irq);
-
-static int bind_evtchn_to_irq(unsigned int evtchn)
-{
- int irq;
-
- spin_lock(&irq_mapping_update_lock);
-
- if ((irq = evtchn_to_irq[evtchn]) == -1) {
- irq = find_unbound_irq();
- evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
- }
-
- irq_bindcount[irq]++;
-
- spin_unlock(&irq_mapping_update_lock);
-
- return irq;
-}
-
-static void unbind_evtchn_from_irq(unsigned int irq)
-{
- evtchn_op_t op = { .cmd = EVTCHNOP_close };
- int evtchn = irq_to_evtchn[irq];
-
- spin_lock(&irq_mapping_update_lock);
-
- if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
- op.u.close.port = evtchn;
- BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
-
- evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
+ irq_info[irq] = IRQ_UNBOUND;
}
spin_unlock(&irq_mapping_update_lock);
@@ -343,7 +319,7 @@
irq = bind_evtchn_to_irq(evtchn);
retval = request_irq(irq, handler, irqflags, devname, dev_id);
if (retval != 0) {
- unbind_evtchn_from_irq(irq);
+ unbind_from_irq(irq);
return retval;
}
@@ -351,12 +327,56 @@
}
EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
-void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id)
+int bind_virq_to_irqhandler(
+ unsigned int virq,
+ unsigned int cpu,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id)
+{
+ unsigned int irq;
+ int retval;
+
+ irq = bind_virq_to_irq(virq, cpu);
+ retval = request_irq(irq, handler, irqflags, devname, dev_id);
+ if (retval != 0) {
+ unbind_from_irq(irq);
+ return retval;
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL(bind_virq_to_irqhandler);
+
+int bind_ipi_to_irqhandler(
+ unsigned int ipi,
+ unsigned int cpu,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id)
+{
+ unsigned int irq;
+ int retval;
+
+ irq = bind_ipi_to_irq(ipi, cpu);
+ retval = request_irq(irq, handler, irqflags, devname, dev_id);
+ if (retval != 0) {
+ unbind_from_irq(irq);
+ return retval;
+ }
+
+ return irq;
+}
+EXPORT_SYMBOL(bind_ipi_to_irqhandler);
+
+void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
free_irq(irq, dev_id);
- unbind_evtchn_from_irq(irq);
-}
-EXPORT_SYMBOL(unbind_evtchn_from_irqhandler);
+ unbind_from_irq(irq);
+}
+EXPORT_SYMBOL(unbind_from_irqhandler);
#ifdef CONFIG_SMP
static void do_nothing_function(void *ign)
@@ -371,7 +391,8 @@
int evtchn;
spin_lock(&irq_mapping_update_lock);
- evtchn = irq_to_evtchn[irq];
+
+ evtchn = evtchn_from_irq(irq);
if (!VALID_EVTCHN(evtchn)) {
spin_unlock(&irq_mapping_update_lock);
return;
@@ -418,7 +439,7 @@
static unsigned int startup_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
unmask_evtchn(evtchn);
@@ -427,7 +448,7 @@
static void shutdown_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
mask_evtchn(evtchn);
@@ -435,7 +456,7 @@
static void enable_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
unmask_evtchn(evtchn);
@@ -443,7 +464,7 @@
static void disable_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
mask_evtchn(evtchn);
@@ -451,7 +472,7 @@
static void ack_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn)) {
mask_evtchn(evtchn);
@@ -461,7 +482,7 @@
static void end_dynirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED))
unmask_evtchn(evtchn);
@@ -507,7 +528,7 @@
static unsigned int startup_pirq(unsigned int irq)
{
evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
goto out;
@@ -527,7 +548,7 @@
bind_evtchn_to_cpu(evtchn, 0);
evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
+ irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);
out:
unmask_evtchn(evtchn);
@@ -539,7 +560,7 @@
static void shutdown_pirq(unsigned int irq)
{
evtchn_op_t op = { .cmd = EVTCHNOP_close };
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (!VALID_EVTCHN(evtchn))
return;
@@ -551,12 +572,12 @@
bind_evtchn_to_cpu(evtchn, 0);
evtchn_to_irq[evtchn] = -1;
- irq_to_evtchn[irq] = -1;
+ irq_info[irq] = IRQ_UNBOUND;
}
static void enable_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn)) {
unmask_evtchn(evtchn);
@@ -566,7 +587,7 @@
static void disable_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
mask_evtchn(evtchn);
@@ -574,7 +595,7 @@
static void ack_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn)) {
mask_evtchn(evtchn);
@@ -584,7 +605,7 @@
static void end_pirq(unsigned int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
unmask_evtchn(evtchn);
@@ -605,7 +626,7 @@
void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i)
{
- int evtchn = irq_to_evtchn[i];
+ int evtchn = evtchn_from_irq(i);
shared_info_t *s = HYPERVISOR_shared_info;
if (!VALID_EVTCHN(evtchn))
return;
@@ -615,7 +636,7 @@
void notify_remote_via_irq(int irq)
{
- int evtchn = irq_to_evtchn[irq];
+ int evtchn = evtchn_from_irq(irq);
if (VALID_EVTCHN(evtchn))
notify_remote_via_evtchn(evtchn);
@@ -635,24 +656,28 @@
/* Check that no PIRQs are still bound. */
for (pirq = 0; pirq < NR_PIRQS; pirq++)
- BUG_ON(irq_to_evtchn[pirq_to_irq(pirq)] != -1);
+ BUG_ON(irq_info[pirq_to_irq(pirq)] != IRQ_UNBOUND);
/* Secondary CPUs must have no VIRQ or IPI bindings. */
for (cpu = 1; cpu < NR_CPUS; cpu++) {
for (virq = 0; virq < NR_VIRQS; virq++)
BUG_ON(per_cpu(virq_to_irq, cpu)[virq] != -1);
for (ipi = 0; ipi < NR_IPIS; ipi++)
- BUG_ON(per_cpu(ipi_to_evtchn, cpu)[ipi] != -1);
- }
-
- /* No IRQ -> event-channel mappings. */
+ BUG_ON(per_cpu(ipi_to_irq, cpu)[ipi] != -1);
+ }
+
+ /* No IRQ <-> event-channel mappings. */
for (irq = 0; irq < NR_IRQS; irq++)
- irq_to_evtchn[irq] = -1;
+ irq_info[irq] &= ~0xFFFF; /* zap event-channel binding */
+ for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++)
+ evtchn_to_irq[evtchn] = -1;
/* Primary CPU: rebind VIRQs automatically. */
for (virq = 0; virq < NR_VIRQS; virq++) {
if ((irq = per_cpu(virq_to_irq, 0)[virq]) == -1)
continue;
+
+ BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
/* Get a new binding from Xen. */
memset(&op, 0, sizeof(op));
@@ -664,7 +689,7 @@
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
/* Ready for use. */
unmask_evtchn(evtchn);
@@ -672,11 +697,10 @@
/* Primary CPU: rebind IPIs automatically. */
for (ipi = 0; ipi < NR_IPIS; ipi++) {
- if ((evtchn = per_cpu(ipi_to_evtchn, 0)[ipi]) == -1)
+ if ((irq = per_cpu(ipi_to_irq, 0)[ipi]) == -1)
continue;
- irq = evtchn_to_irq[evtchn];
- evtchn_to_irq[evtchn] = -1;
+ BUG_ON(irq_info[irq] != mk_irq_info(IRQT_IPI, ipi, 0));
/* Get a new binding from Xen. */
memset(&op, 0, sizeof(op));
@@ -687,17 +711,10 @@
/* Record the new mapping. */
evtchn_to_irq[evtchn] = irq;
- irq_to_evtchn[irq] = evtchn;
+ irq_info[irq] = mk_irq_info(IRQT_IPI, ipi, evtchn);
/* Ready for use. */
unmask_evtchn(evtchn);
- }
-
- /* Remove defunct event-channel -> IRQ mappings. */
- for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) {
- if ((evtchn_to_irq[evtchn] != -1) &&
- (irq_to_evtchn[evtchn_to_irq[evtchn]] == -1))
- evtchn_to_irq[evtchn] = -1;
}
}
@@ -717,7 +734,7 @@
for (i = 0; i < NR_VIRQS; i++)
per_cpu(virq_to_irq, cpu)[i] = -1;
for (i = 0; i < NR_IPIS; i++)
- per_cpu(ipi_to_evtchn, cpu)[i] = -1;
+ per_cpu(ipi_to_irq, cpu)[i] = -1;
}
/* No event-channel -> IRQ mappings. */
@@ -728,7 +745,7 @@
/* No IRQ -> event-channel mappings. */
for (i = 0; i < NR_IRQS; i++)
- irq_to_evtchn[i] = -1;
+ irq_info[i] = IRQ_UNBOUND;
/* Dynamic IRQ space is currently unbound. Zero the refcnts. */
for (i = 0; i < NR_DYNIRQS; i++) {
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c
--- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c Tue Nov 8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c Tue Nov 8 14:58:31 2005
@@ -87,18 +87,27 @@
static void xen_smp_intr_init(unsigned int cpu)
{
+ sprintf(resched_name[cpu], "resched%d", cpu);
per_cpu(resched_irq, cpu) =
- bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu);
- sprintf(resched_name[cpu], "resched%d", cpu);
- BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt,
- SA_INTERRUPT, resched_name[cpu], NULL));
-
+ bind_ipi_to_irqhandler(
+ RESCHEDULE_VECTOR,
+ cpu,
+ smp_reschedule_interrupt,
+ SA_INTERRUPT,
+ resched_name[cpu],
+ NULL);
+ BUG_ON(per_cpu(resched_irq, cpu) < 0);
+
+ sprintf(callfunc_name[cpu], "callfunc%d", cpu);
per_cpu(callfunc_irq, cpu) =
- bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu);
- sprintf(callfunc_name[cpu], "callfunc%d", cpu);
- BUG_ON(request_irq(per_cpu(callfunc_irq, cpu),
- smp_call_function_interrupt,
- SA_INTERRUPT, callfunc_name[cpu], NULL));
+ bind_ipi_to_irqhandler(
+ CALL_FUNCTION_VECTOR,
+ cpu,
+ smp_call_function_interrupt,
+ SA_INTERRUPT,
+ callfunc_name[cpu],
+ NULL);
+ BUG_ON(per_cpu(callfunc_irq, cpu) < 0);
if (cpu != 0)
local_setup_timer(cpu);
@@ -110,11 +119,8 @@
if (cpu != 0)
local_teardown_timer(cpu);
- free_irq(per_cpu(resched_irq, cpu), NULL);
- unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu);
-
- free_irq(per_cpu(callfunc_irq, cpu), NULL);
- unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu);
+ unbind_from_irqhandler(per_cpu(resched_irq, cpu), NULL);
+ unbind_from_irqhandler(per_cpu(callfunc_irq, cpu), NULL);
}
#endif
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/genapic_xen.c Tue Nov 8
14:58:31 2005
@@ -27,13 +27,13 @@
#endif
#include <asm-xen/evtchn.h>
-DECLARE_PER_CPU(int, ipi_to_evtchn[NR_IPIS]);
+DECLARE_PER_CPU(int, ipi_to_irq[NR_IPIS]);
static inline void __send_IPI_one(unsigned int cpu, int vector)
{
- int evtchn = per_cpu(ipi_to_evtchn, cpu)[vector];
- BUG_ON(evtchn < 0);
- notify_remote_via_evtchn(evtchn);
+ int irq = per_cpu(ipi_to_irq, cpu)[vector];
+ BUG_ON(irq < 0);
+ notify_remote_via_irq(irq);
}
void xen_send_IPI_shortcut(unsigned int shortcut, int vector, unsigned int
dest)
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Tue Nov 8
14:58:31 2005
@@ -119,7 +119,7 @@
if (!blkif->irq)
return;
- unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+ unbind_from_irqhandler(blkif->irq, blkif);
blkif->irq = 0;
vbd_free(&blkif->vbd);
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Tue Nov 8
14:58:31 2005
@@ -358,7 +358,7 @@
info->ring.sring = NULL;
}
if (info->irq)
- unbind_evtchn_from_irqhandler(info->irq, info);
+ unbind_from_irqhandler(info->irq, info);
info->evtchn = info->irq = 0;
}
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Tue Nov 8
14:58:31 2005
@@ -113,7 +113,7 @@
blkif_t *blkif = (blkif_t *)arg;
if (blkif->irq)
- unbind_evtchn_from_irqhandler(blkif->irq, blkif);
+ unbind_from_irqhandler(blkif->irq, blkif);
if (blkif->blk_ring.sring) {
unmap_frontend_page(blkif);
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Tue Nov 8
14:58:31 2005
@@ -771,15 +771,14 @@
#endif
if (xen_start_info->flags & SIF_INITDOMAIN) {
-#ifdef __ia64__
- xencons_priv_irq = bind_virq_to_evtchn(VIRQ_CONSOLE);
- bind_evtchn_to_irqhandler(xencons_priv_irq,
- xencons_priv_interrupt, 0, "console", NULL);
-#else
- xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
- (void)request_irq(xencons_priv_irq,
- xencons_priv_interrupt, 0, "console", NULL);
-#endif
+ xencons_priv_irq = bind_virq_to_irqhandler(
+ VIRQ_CONSOLE,
+ 0,
+ xencons_priv_interrupt,
+ 0,
+ "console",
+ NULL);
+ BUG_ON(xencons_priv_irq < 0);
} else {
xencons_ring_register_receiver(xencons_rx);
}
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Tue Nov 8
14:58:31 2005
@@ -86,7 +86,7 @@
int err;
if (xencons_irq)
- unbind_evtchn_from_irqhandler(xencons_irq, NULL);
+ unbind_from_irqhandler(xencons_irq, NULL);
xencons_irq = 0;
if (!xen_start_info->console_evtchn)
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Tue Nov 8
14:58:31 2005
@@ -241,7 +241,7 @@
if (!netif->irq)
return;
- unbind_evtchn_from_irqhandler(netif->irq, netif);
+ unbind_from_irqhandler(netif->irq, netif);
netif->irq = 0;
unregister_netdev(netif->dev);
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Tue Nov 8
14:58:31 2005
@@ -822,9 +822,13 @@
netif_xenbus_init();
- (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG, 0),
- netif_be_dbg, SA_SHIRQ,
- "net-be-dbg", &netif_be_dbg);
+ (void)bind_virq_to_irqhandler(
+ VIRQ_DEBUG,
+ 0,
+ netif_be_dbg,
+ SA_SHIRQ,
+ "net-be-dbg",
+ &netif_be_dbg);
return 0;
}
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Tue Nov 8
14:58:31 2005
@@ -1049,7 +1049,7 @@
info->rx = NULL;
if (info->irq)
- unbind_evtchn_from_irqhandler(info->irq, info->netdev);
+ unbind_from_irqhandler(info->irq, info->netdev);
info->evtchn = info->irq = 0;
}
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Tue Nov 8
14:58:31 2005
@@ -162,7 +162,7 @@
tpmif_t *tpmif = (tpmif_t *) arg;
if (tpmif->irq)
- unbind_evtchn_from_irqhandler(tpmif->irq, tpmif);
+ unbind_from_irqhandler(tpmif->irq, tpmif);
if (tpmif->tx) {
unmap_frontend_page(tpmif);
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Tue Nov 8
14:58:31 2005
@@ -300,7 +300,7 @@
}
if (tp->irq)
- unbind_evtchn_from_irqhandler(tp->irq, NULL);
+ unbind_from_irqhandler(tp->irq, NULL);
tp->evtchn = tp->irq = 0;
}
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Nov 8
14:15:02 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Tue Nov 8
14:58:31 2005
@@ -177,7 +177,7 @@
int err;
if (xenbus_irq)
- unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq);
+ unbind_from_irqhandler(xenbus_irq, &xb_waitq);
err = bind_evtchn_to_irqhandler(
xen_start_info->store_evtchn, wake_waiting,
diff -r 37ad91483bd3 -r 0915074c356e
linux-2.6-xen-sparse/include/asm-xen/evtchn.h
--- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Tue Nov 8 14:15:02 2005
+++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Tue Nov 8 14:58:31 2005
@@ -43,29 +43,41 @@
* LOW-LEVEL DEFINITIONS
*/
-/* Dynamically bind a VIRQ source to Linux IRQ space. */
-extern int bind_virq_to_irq(int virq, int cpu);
-extern void unbind_virq_from_irq(int virq, int cpu);
-
-/* Dynamically bind an IPI source to Linux IRQ space. */
-extern int bind_ipi_to_irq(int ipi, int cpu);
-extern void unbind_ipi_from_irq(int ipi, int cpu);
-
/*
- * Dynamically bind an event-channel port to an IRQ-like callback handler.
+ * Dynamically bind an event source to an IRQ-like callback handler.
* On some platforms this may not be implemented via the Linux IRQ subsystem.
* The IRQ argument passed to the callback handler is the same as returned
* from the bind call. It may not correspond to a Linux IRQ number.
- * BIND: Returns IRQ or error.
+ * Returns IRQ or negative errno.
* UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
*/
-extern int bind_evtchn_to_irqhandler(
+extern int bind_evtchn_to_irqhandler(
unsigned int evtchn,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags,
const char *devname,
void *dev_id);
-extern void unbind_evtchn_from_irqhandler(unsigned int irq, void *dev_id);
+extern int bind_virq_to_irqhandler(
+ unsigned int virq,
+ unsigned int cpu,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id);
+extern int bind_ipi_to_irqhandler(
+ unsigned int ipi,
+ unsigned int cpu,
+ irqreturn_t (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id);
+
+/*
+ * Common unbind function for all event sources. Takes IRQ to unbind from.
+ * Automatically closes the underlying event channel (even for bindings
+ * made with bind_evtchn_to_irqhandler()).
+ */
+extern void unbind_from_irqhandler(unsigned int irq, void *dev_id);
/*
* Unlike notify_remote_via_evtchn(), this is safe to use across
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|