--- /dev/null
+From: jbeulich@novell.com
+Subject: fold per-CPU VIRQs onto a single IRQ each
+Patch-mainline: obsolete
+
+--- sle11-2009-06-04.orig/arch/x86/kernel/time_32-xen.c 2009-06-04 10:47:20.000000000 +0200
++++ sle11-2009-06-04/arch/x86/kernel/time_32-xen.c 2009-06-04 10:47:28.000000000 +0200
+@@ -725,19 +725,17 @@ int xen_update_persistent_clock(void)
+ }
+
+ /* Dynamically-mapped IRQ. */
+-DEFINE_PER_CPU(int, timer_irq);
++static int __read_mostly timer_irq = -1;
++static struct irqaction timer_action = {
++ .handler = timer_interrupt,
++ .flags = IRQF_DISABLED,
++ .name = "timer"
++};
+
+ static void __init setup_cpu0_timer_irq(void)
+ {
+- per_cpu(timer_irq, 0) =
+- bind_virq_to_irqhandler(
+- VIRQ_TIMER,
+- 0,
+- timer_interrupt,
+- IRQF_DISABLED|IRQF_NOBALANCING,
+- "timer0",
+- NULL);
+- BUG_ON(per_cpu(timer_irq, 0) < 0);
++ timer_irq = bind_virq_to_irqaction(VIRQ_TIMER, 0, &timer_action);
++ BUG_ON(timer_irq < 0);
+ }
+
+ void __init time_init(void)
+@@ -864,8 +862,6 @@ void xen_halt(void)
+ EXPORT_SYMBOL(xen_halt);
+
+ #ifdef CONFIG_SMP
+-static char timer_name[NR_CPUS][15];
+-
+ int __cpuinit local_setup_timer(unsigned int cpu)
+ {
+ int seq, irq;
+@@ -891,16 +887,10 @@ int __cpuinit local_setup_timer(unsigned
+ init_missing_ticks_accounting(cpu);
+ } while (read_seqretry(&xtime_lock, seq));
+
+- sprintf(timer_name[cpu], "timer%u", cpu);
+- irq = bind_virq_to_irqhandler(VIRQ_TIMER,
+- cpu,
+- timer_interrupt,
+- IRQF_DISABLED|IRQF_NOBALANCING,
+- timer_name[cpu],
+- NULL);
++ irq = bind_virq_to_irqaction(VIRQ_TIMER, cpu, &timer_action);
+ if (irq < 0)
+ return irq;
+- per_cpu(timer_irq, cpu) = irq;
++ BUG_ON(timer_irq != irq);
+
+ return 0;
+ }
+@@ -908,7 +898,7 @@ int __cpuinit local_setup_timer(unsigned
+ void __cpuinit local_teardown_timer(unsigned int cpu)
+ {
+ BUG_ON(cpu == 0);
+- unbind_from_irqhandler(per_cpu(timer_irq, cpu), NULL);
++ unbind_from_per_cpu_irq(timer_irq, cpu, &timer_action);
+ }
+ #endif
+
+--- sle11-2009-06-04.orig/drivers/xen/core/evtchn.c 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/evtchn.c 2009-06-04 10:47:28.000000000 +0200
+@@ -58,6 +58,23 @@ static DEFINE_SPINLOCK(irq_mapping_updat
+ static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
+ [0 ... NR_EVENT_CHANNELS-1] = -1 };
+
++#if defined(CONFIG_SMP) && defined(CONFIG_X86)
++static struct per_cpu_irqaction {
++ struct irqaction action; /* must be first */
++ struct per_cpu_irqaction *next;
++ cpumask_t cpus;
++} *virq_actions[NR_VIRQS];
++/* IRQ <-> VIRQ mapping. */
++static DECLARE_BITMAP(virq_per_cpu, NR_VIRQS) __read_mostly;
++static DEFINE_PER_CPU(int[NR_VIRQS], virq_to_evtchn);
++#define BUG_IF_VIRQ_PER_CPU(irq) \
++ BUG_ON(type_from_irq(irq) == IRQT_VIRQ \
++ && test_bit(index_from_irq(irq), virq_per_cpu))
++#else
++#define BUG_IF_VIRQ_PER_CPU(irq) ((void)(irq))
++#define PER_CPU_VIRQ_IRQ
++#endif
++
+ /* IRQ <-> IPI mapping. */
+ #ifndef NR_IPIS
+ #define NR_IPIS 1
+@@ -114,13 +131,6 @@ static inline u32 mk_irq_info(u32 type,
+ * Accessors for packed IRQ information.
+ */
+
+-#ifdef PER_CPU_IPI_IRQ
+-static inline unsigned int evtchn_from_irq(int irq)
+-{
+- return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
+-}
+-#endif
+-
+ static inline unsigned int index_from_irq(int irq)
+ {
+ return (irq_info[irq] >> _EVTCHN_BITS) & ((1U << _INDEX_BITS) - 1);
+@@ -131,20 +141,35 @@ static inline unsigned int type_from_irq
+ return irq_info[irq] >> (32 - _IRQT_BITS);
+ }
+
+-#ifndef PER_CPU_IPI_IRQ
+ static inline unsigned int evtchn_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
+ {
+- BUG_ON(type_from_irq(irq) != IRQT_IPI);
+- return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
++ switch (type_from_irq(irq)) {
++#ifndef PER_CPU_VIRQ_IRQ
++ case IRQT_VIRQ:
++ return per_cpu(virq_to_evtchn, cpu)[index_from_irq(irq)];
++#endif
++#ifndef PER_CPU_IPI_IRQ
++ case IRQT_IPI:
++ return per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)];
++#endif
++ }
++ BUG();
++ return 0;
+ }
+
+ static inline unsigned int evtchn_from_irq(unsigned int irq)
+ {
+- if (type_from_irq(irq) != IRQT_IPI)
+- return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
+- return evtchn_from_per_cpu_irq(irq, smp_processor_id());
+-}
++ switch (type_from_irq(irq)) {
++#ifndef PER_CPU_VIRQ_IRQ
++ case IRQT_VIRQ:
++#endif
++#ifndef PER_CPU_IPI_IRQ
++ case IRQT_IPI:
+ #endif
++ return evtchn_from_per_cpu_irq(irq, smp_processor_id());
++ }
++ return irq_info[irq] & ((1U << _EVTCHN_BITS) - 1);
++}
+
+ /* IRQ <-> VIRQ mapping. */
+ DEFINE_PER_CPU(int, virq_to_irq[NR_VIRQS]) = {[0 ... NR_VIRQS-1] = -1};
+@@ -479,6 +504,14 @@ static int bind_virq_to_irq(unsigned int
+ evtchn = bind_virq.port;
+
+ evtchn_to_irq[evtchn] = irq;
++#ifndef PER_CPU_VIRQ_IRQ
++ {
++ unsigned int cpu;
++
++ for_each_possible_cpu(cpu)
++ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
++ }
++#endif
+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
+
+ per_cpu(virq_to_irq, cpu)[virq] = irq;
+@@ -533,7 +566,9 @@ static void unbind_from_irq(unsigned int
+ unsigned int cpu;
+ int evtchn = evtchn_from_irq(irq);
+
++ BUG_IF_VIRQ_PER_CPU(irq);
+ BUG_IF_IPI(irq);
++
+ spin_lock(&irq_mapping_update_lock);
+
+ if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
+@@ -546,6 +581,11 @@ static void unbind_from_irq(unsigned int
+ case IRQT_VIRQ:
+ per_cpu(virq_to_irq, cpu_from_evtchn(evtchn))
+ [index_from_irq(irq)] = -1;
++#ifndef PER_CPU_VIRQ_IRQ
++ for_each_possible_cpu(cpu)
++ per_cpu(virq_to_evtchn, cpu)
++ [index_from_irq(irq)] = 0;
++#endif
+ break;
+ #if defined(CONFIG_SMP) && defined(PER_CPU_IPI_IRQ)
+ case IRQT_IPI:
+@@ -571,11 +611,13 @@ static void unbind_from_irq(unsigned int
+ spin_unlock(&irq_mapping_update_lock);
+ }
+
+-#if defined(CONFIG_SMP) && !defined(PER_CPU_IPI_IRQ)
+-void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu)
++#if defined(CONFIG_SMP) && (!defined(PER_CPU_IPI_IRQ) || !defined(PER_CPU_VIRQ_IRQ))
++void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu,
++ struct irqaction *action)
+ {
+ struct evtchn_close close;
+ int evtchn = evtchn_from_per_cpu_irq(irq, cpu);
++ struct irqaction *free_action = NULL;
+
+ spin_lock(&irq_mapping_update_lock);
+
+@@ -586,6 +628,32 @@ void unbind_from_per_cpu_irq(unsigned in
+
+ BUG_ON(irq_bindcount[irq] <= 1);
+ irq_bindcount[irq]--;
++
++#ifndef PER_CPU_VIRQ_IRQ
++ if (type_from_irq(irq) == IRQT_VIRQ) {
++ unsigned int virq = index_from_irq(irq);
++ struct per_cpu_irqaction *cur, *prev = NULL;
++
++ cur = virq_actions[virq];
++ while (cur) {
++ if (cur->action.dev_id == action) {
++ cpu_clear(cpu, cur->cpus);
++ if (cpus_empty(cur->cpus)) {
++ if (prev)
++ prev->next = cur->next;
++ else
++ virq_actions[virq] = cur->next;
++ free_action = action;
++ }
++ } else if (cpu_isset(cpu, cur->cpus))
++ evtchn = 0;
++ cur = (prev = cur)->next;
++ }
++ if (!VALID_EVTCHN(evtchn))
++ goto done;
++ }
++#endif
++
+ cpu_clear(cpu, desc->affinity);
+
+ close.port = evtchn;
+@@ -593,9 +661,16 @@ void unbind_from_per_cpu_irq(unsigned in
+ BUG();
+
+ switch (type_from_irq(irq)) {
++#ifndef PER_CPU_VIRQ_IRQ
++ case IRQT_VIRQ:
++ per_cpu(virq_to_evtchn, cpu)[index_from_irq(irq)] = 0;
++ break;
++#endif
++#ifndef PER_CPU_IPI_IRQ
+ case IRQT_IPI:
+ per_cpu(ipi_to_evtchn, cpu)[index_from_irq(irq)] = 0;
+ break;
++#endif
+ default:
+ BUG();
+ break;
+@@ -607,9 +682,16 @@ void unbind_from_per_cpu_irq(unsigned in
+ evtchn_to_irq[evtchn] = -1;
+ }
+
++#ifndef PER_CPU_VIRQ_IRQ
++done:
++#endif
+ spin_unlock(&irq_mapping_update_lock);
++
++ if (free_action)
++ free_irq(irq, free_action);
+ }
+-#endif /* CONFIG_SMP && !PER_CPU_IPI_IRQ */
++EXPORT_SYMBOL_GPL(unbind_from_per_cpu_irq);
++#endif /* CONFIG_SMP && (!PER_CPU_IPI_IRQ || !PER_CPU_VIRQ_IRQ) */
+
+ int bind_caller_port_to_irqhandler(
+ unsigned int caller_port,
+@@ -691,6 +773,8 @@ int bind_virq_to_irqhandler(
+ {
+ int irq, retval;
+
++ BUG_IF_VIRQ_PER_CPU(virq);
++
+ irq = bind_virq_to_irq(virq, cpu);
+ if (irq < 0)
+ return irq;
+@@ -706,6 +790,108 @@ int bind_virq_to_irqhandler(
+ EXPORT_SYMBOL_GPL(bind_virq_to_irqhandler);
+
+ #ifdef CONFIG_SMP
++#ifndef PER_CPU_VIRQ_IRQ
++int bind_virq_to_irqaction(
++ unsigned int virq,
++ unsigned int cpu,
++ struct irqaction *action)
++{
++ struct evtchn_bind_virq bind_virq;
++ int evtchn, irq, retval = 0;
++ struct per_cpu_irqaction *cur = NULL, *new;
++
++ BUG_ON(!test_bit(virq, virq_per_cpu));
++
++ if (action->dev_id)
++ return -EINVAL;
++
++ new = kzalloc(sizeof(*new), GFP_ATOMIC);
++ if (new) {
++ new->action = *action;
++ new->action.dev_id = action;
++ }
++
++ spin_lock(&irq_mapping_update_lock);
++
++ for (cur = virq_actions[virq]; cur; cur = cur->next)
++ if (cur->action.dev_id == action)
++ break;
++ if (!cur) {
++ if (!new) {
++ spin_unlock(&irq_mapping_update_lock);
++ return -ENOMEM;
++ }
++ new->next = virq_actions[virq];
++ virq_actions[virq] = cur = new;
++ retval = 1;
++ }
++ cpu_set(cpu, cur->cpus);
++ action = &cur->action;
++
++ if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
++ unsigned int cpu;
++
++ BUG_ON(!retval);
++
++ if ((irq = find_unbound_irq(true)) < 0) {
++ if (cur)
++ virq_actions[virq] = cur->next;
++ spin_unlock(&irq_mapping_update_lock);
++ if (cur != new)
++ kfree(new);
++ return irq;
++ }
++
++ /* Extra reference so count will never drop to zero. */
++ irq_bindcount[irq]++;
++
++ for_each_possible_cpu(cpu)
++ per_cpu(virq_to_irq, cpu)[virq] = irq;
++ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, 0);
++ }
++
++ evtchn = per_cpu(virq_to_evtchn, cpu)[virq];
++ if (!VALID_EVTCHN(evtchn)) {
++ bind_virq.virq = virq;
++ bind_virq.vcpu = cpu;
++ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
++ &bind_virq) != 0)
++ BUG();
++ evtchn = bind_virq.port;
++ evtchn_to_irq[evtchn] = irq;
++ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
++
++ bind_evtchn_to_cpu(evtchn, cpu);
++ }
++
++ irq_bindcount[irq]++;
++
++ spin_unlock(&irq_mapping_update_lock);
++
++ if (cur != new)
++ kfree(new);
++
++ if (retval == 0) {
++ unsigned long flags;
++
++ local_irq_save(flags);
++ unmask_evtchn(evtchn);
++ local_irq_restore(flags);
++ } else {
++ action->flags |= IRQF_PERCPU;
++ retval = setup_irq(irq, action);
++ if (retval) {
++ unbind_from_per_cpu_irq(irq, cpu, cur->action.dev_id);
++ BUG_ON(retval > 0);
++ irq = retval;
++ }
++ }
++
++ return irq;
++}
++EXPORT_SYMBOL_GPL(bind_virq_to_irqaction);
++#endif
++
+ #ifdef PER_CPU_IPI_IRQ
+ int bind_ipi_to_irqhandler(
+ unsigned int ipi,
+@@ -784,7 +970,7 @@ int __cpuinit bind_ipi_to_irqaction(
+ action->flags |= IRQF_PERCPU;
+ retval = setup_irq(irq, action);
+ if (retval) {
+- unbind_from_per_cpu_irq(irq, cpu);
++ unbind_from_per_cpu_irq(irq, cpu, NULL);
+ BUG_ON(retval > 0);
+ irq = retval;
+ }
+@@ -819,7 +1005,9 @@ static void rebind_irq_to_cpu(unsigned i
+ {
+ int evtchn = evtchn_from_irq(irq);
+
++ BUG_IF_VIRQ_PER_CPU(irq);
+ BUG_IF_IPI(irq);
++
+ if (VALID_EVTCHN(evtchn))
+ rebind_evtchn_to_cpu(evtchn, tcpu);
+ }
+@@ -1098,7 +1286,9 @@ void notify_remote_via_irq(int irq)
+ {
+ int evtchn = evtchn_from_irq(irq);
+
++ BUG_ON(type_from_irq(irq) == IRQT_VIRQ);
+ BUG_IF_IPI(irq);
++
+ if (VALID_EVTCHN(evtchn))
+ notify_remote_via_evtchn(evtchn);
+ }
+@@ -1106,6 +1296,7 @@ EXPORT_SYMBOL_GPL(notify_remote_via_irq)
+
+ int irq_to_evtchn_port(int irq)
+ {
++ BUG_IF_VIRQ_PER_CPU(irq);
+ BUG_IF_IPI(irq);
+ return evtchn_from_irq(irq);
+ }
+@@ -1200,6 +1391,12 @@ static void restore_cpu_virqs(unsigned i
+ if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1)
+ continue;
+
++#ifndef PER_CPU_VIRQ_IRQ
++ if (test_bit(virq, virq_per_cpu)
++ && !VALID_EVTCHN(per_cpu(virq_to_evtchn, cpu)[virq]))
++ continue;
++#endif
++
+ BUG_ON(irq_info[irq] != mk_irq_info(IRQT_VIRQ, virq, 0));
+
+ /* Get a new binding from Xen. */
+@@ -1212,7 +1409,19 @@ static void restore_cpu_virqs(unsigned i
+
+ /* Record the new mapping. */
+ evtchn_to_irq[evtchn] = irq;
++#ifdef PER_CPU_VIRQ_IRQ
+ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
++#else
++ if (test_bit(virq, virq_per_cpu))
++ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
++ else {
++ unsigned int cpu;
++
++ irq_info[irq] = mk_irq_info(IRQT_VIRQ, virq, evtchn);
++ for_each_possible_cpu(cpu)
++ per_cpu(virq_to_evtchn, cpu)[virq] = evtchn;
++ }
++#endif
+ bind_evtchn_to_cpu(evtchn, cpu);
+
+ /* Ready for use. */
+@@ -1267,7 +1476,11 @@ static int evtchn_resume(struct sys_devi
+
+ /* Avoid doing anything in the 'suspend cancelled' case. */
+ status.dom = DOMID_SELF;
++#ifdef PER_CPU_VIRQ_IRQ
+ status.port = evtchn_from_irq(__get_cpu_var(virq_to_irq)[VIRQ_TIMER]);
++#else
++ status.port = __get_cpu_var(virq_to_evtchn)[VIRQ_TIMER];
++#endif
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_status, &status))
+ BUG();
+ if (status.status == EVTCHNSTAT_virq
+@@ -1407,6 +1620,15 @@ void __init xen_init_IRQ(void)
+ unsigned int i;
+ struct physdev_pirq_eoi_gmfn eoi_gmfn;
+
++#ifndef PER_CPU_VIRQ_IRQ
++ __set_bit(VIRQ_TIMER, virq_per_cpu);
++ __set_bit(VIRQ_DEBUG, virq_per_cpu);
++ __set_bit(VIRQ_XENOPROF, virq_per_cpu);
++#ifdef CONFIG_IA64
++ __set_bit(VIRQ_ITC, virq_per_cpu);
++#endif
++#endif
++
+ init_evtchn_cpu_bindings();
+
+ pirq_needs_eoi = alloc_bootmem_pages(sizeof(unsigned long)
+--- sle11-2009-06-04.orig/drivers/xen/core/smpboot.c 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/smpboot.c 2009-06-04 10:47:28.000000000 +0200
+@@ -163,11 +163,11 @@ static int __cpuinit xen_smp_intr_init(u
+ fail:
+ xen_spinlock_cleanup(cpu);
+ unbind_call1:
+- unbind_from_per_cpu_irq(call1func_irq, cpu);
++ unbind_from_per_cpu_irq(call1func_irq, cpu, NULL);
+ unbind_call:
+- unbind_from_per_cpu_irq(callfunc_irq, cpu);
++ unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL);
+ unbind_resched:
+- unbind_from_per_cpu_irq(resched_irq, cpu);
++ unbind_from_per_cpu_irq(resched_irq, cpu, NULL);
+ return rc;
+ }
+
+@@ -177,9 +177,9 @@ static void __cpuinit xen_smp_intr_exit(
+ if (cpu != 0)
+ local_teardown_timer(cpu);
+
+- unbind_from_per_cpu_irq(resched_irq, cpu);
+- unbind_from_per_cpu_irq(callfunc_irq, cpu);
+- unbind_from_per_cpu_irq(call1func_irq, cpu);
++ unbind_from_per_cpu_irq(resched_irq, cpu, NULL);
++ unbind_from_per_cpu_irq(callfunc_irq, cpu, NULL);
++ unbind_from_per_cpu_irq(call1func_irq, cpu, NULL);
+ xen_spinlock_cleanup(cpu);
+ }
+ #endif
+--- sle11-2009-06-04.orig/drivers/xen/core/spinlock.c 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/core/spinlock.c 2009-06-04 10:47:28.000000000 +0200
+@@ -57,7 +57,7 @@ int __cpuinit xen_spinlock_init(unsigned
+
+ void __cpuinit xen_spinlock_cleanup(unsigned int cpu)
+ {
+- unbind_from_per_cpu_irq(spinlock_irq, cpu);
++ unbind_from_per_cpu_irq(spinlock_irq, cpu, NULL);
+ }
+
+ int xen_spin_wait(raw_spinlock_t *lock, unsigned int token)
+--- sle11-2009-06-04.orig/drivers/xen/netback/netback.c 2009-06-04 10:20:21.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/netback/netback.c 2009-06-04 10:47:28.000000000 +0200
+@@ -1561,6 +1561,12 @@ static irqreturn_t netif_be_dbg(int irq,
+
+ return IRQ_HANDLED;
+ }
++
++static struct irqaction netif_be_dbg_action = {
++ .handler = netif_be_dbg,
++ .flags = IRQF_SHARED,
++ .name = "net-be-dbg"
++};
+ #endif
+
+ static int __init netback_init(void)
+@@ -1620,12 +1626,9 @@ static int __init netback_init(void)
+ netif_xenbus_init();
+
+ #ifdef NETBE_DEBUG_INTERRUPT
+- (void)bind_virq_to_irqhandler(VIRQ_DEBUG,
+- 0,
+- netif_be_dbg,
+- IRQF_SHARED,
+- "net-be-dbg",
+- &netif_be_dbg);
++ (void)bind_virq_to_irqaction(VIRQ_DEBUG,
++ 0,
++ &netif_be_dbg_action);
+ #endif
+
+ return 0;
+--- sle11-2009-06-04.orig/drivers/xen/xenoprof/xenoprofile.c 2009-06-04 10:20:39.000000000 +0200
++++ sle11-2009-06-04/drivers/xen/xenoprof/xenoprofile.c 2009-06-04 10:47:28.000000000 +0200
+@@ -210,6 +210,11 @@ static irqreturn_t xenoprof_ovf_interrup
+ return IRQ_HANDLED;
+ }
+
++static struct irqaction ovf_action = {
++ .handler = xenoprof_ovf_interrupt,
++ .flags = IRQF_DISABLED,
++ .name = "xenoprof"
++};
+
+ static void unbind_virq(void)
+ {
+@@ -217,7 +222,7 @@ static void unbind_virq(void)
+
+ for_each_online_cpu(i) {
+ if (ovf_irq[i] >= 0) {
+- unbind_from_irqhandler(ovf_irq[i], NULL);
++ unbind_from_per_cpu_irq(ovf_irq[i], i, &ovf_action);
+ ovf_irq[i] = -1;
+ }
+ }
+@@ -230,12 +235,7 @@ static int bind_virq(void)
+ int result;
+
+ for_each_online_cpu(i) {
+- result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
+- i,
+- xenoprof_ovf_interrupt,
+- IRQF_DISABLED|IRQF_NOBALANCING,
+- "xenoprof",
+- NULL);
++ result = bind_virq_to_irqaction(VIRQ_XENOPROF, i, &ovf_action);
+
+ if (result < 0) {
+ unbind_virq();
+--- sle11-2009-06-04.orig/include/xen/evtchn.h 2009-06-04 10:47:21.000000000 +0200
++++ sle11-2009-06-04/include/xen/evtchn.h 2009-06-04 10:47:28.000000000 +0200
+@@ -78,6 +78,17 @@ int bind_virq_to_irqhandler(
+ unsigned long irqflags,
+ const char *devname,
+ void *dev_id);
++#if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
++int bind_virq_to_irqaction(
++ unsigned int virq,
++ unsigned int cpu,
++ struct irqaction *action);
++#else
++#define bind_virq_to_irqaction(virq, cpu, action) \
++ bind_virq_to_irqhandler(virq, cpu, (action)->handler, \
++ (action)->flags | IRQF_NOBALANCING, \
++ (action)->name, action)
++#endif
+ #if defined(CONFIG_SMP) && !defined(MODULE)
+ #ifndef CONFIG_X86
+ int bind_ipi_to_irqhandler(
+@@ -102,9 +113,13 @@ int bind_ipi_to_irqaction(
+ */
+ void unbind_from_irqhandler(unsigned int irq, void *dev_id);
+
+-#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)
++#if defined(CONFIG_SMP) && defined(CONFIG_XEN) && defined(CONFIG_X86)
+ /* Specialized unbind function for per-CPU IRQs. */
+-void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu);
++void unbind_from_per_cpu_irq(unsigned int irq, unsigned int cpu,
++ struct irqaction *);
++#else
++#define unbind_from_per_cpu_irq(irq, cpu, action) \
++ unbind_from_irqhandler(irq, action)
+ #endif
+
+ #ifndef CONFIG_XEN