* [Adeos-main] [PATCH 5/5] consolidate common 32/64-bit code
@ 2007-12-29 23:13 Jan Kiszka
2007-12-30 11:01 ` Philippe Gerum
0 siblings, 1 reply; 2+ messages in thread
From: Jan Kiszka @ 2007-12-29 23:13 UTC (permalink / raw)
To: adeos-main; +Cc: Philippe Gerum
[-- Attachment #1.1: Type: text/plain, Size: 166 bytes --]
Long patch, short summary: removes more than 700 LOC by pushing common
code in commonly used files. Specifically, there is now only
arch/x86/ipipe.c again.
Jan
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: consolidate-common-code.patch --]
[-- Type: text/x-patch; name="consolidate-common-code.patch", Size: 105415 bytes --]
---
arch/x86/kernel/Makefile_32 | 2
arch/x86/kernel/Makefile_64 | 2
arch/x86/kernel/entry_64.S | 30 -
arch/x86/kernel/ipipe.c | 1003 ++++++++++++++++++++++++++++++++++++++++
arch/x86/kernel/ipipe_32.c | 838 ---------------------------------
arch/x86/kernel/ipipe_64.c | 803 --------------------------------
include/asm-x86/ipipe.h | 116 ++++
include/asm-x86/ipipe_32.h | 85 ---
include/asm-x86/ipipe_64.h | 85 ---
include/asm-x86/ipipe_base.h | 93 +++
include/asm-x86/ipipe_base_32.h | 63 --
include/asm-x86/ipipe_base_64.h | 63 --
include/asm-x86/unistd_64.h | 2
13 files changed, 1229 insertions(+), 1956 deletions(-)
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_base.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/ipipe_base.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_base.h
@@ -1,5 +1,98 @@
+/* -*- linux-c -*-
+ * include/asm-x86/ipipe_base.h
+ *
+ * Copyright (C) 2007 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __X86_IPIPE_BASE_H
+#define __X86_IPIPE_BASE_H
+
#ifdef CONFIG_X86_32
# include "ipipe_base_32.h"
#else
# include "ipipe_base_64.h"
#endif
+
+#define ex_do_divide_error 0
+#define ex_do_debug 1
+/* NMI not pipelined. */
+#define ex_do_int3 3
+#define ex_do_overflow 4
+#define ex_do_bounds 5
+#define ex_do_invalid_op 6
+#define ex_device_not_available 7 /* x86_32 */
+#define ex_math_state_restore 7 /* x86_64 */
+/* Double fault not pipelined. */
+#define ex_do_coprocessor_segment_overrun 9
+#define ex_do_invalid_TSS 10
+#define ex_do_segment_not_present 11
+#define ex_do_stack_segment 12
+#define ex_do_general_protection 13
+#define ex_do_page_fault 14
+#define ex_do_spurious_interrupt_bug 15
+#define ex_do_coprocessor_error 16
+#define ex_do_alignment_check 17
+#define ex_machine_check_vector 18
+#define ex_reserved ex_machine_check_vector
+#define ex_do_simd_coprocessor_error 19
+#define ex_do_iret_error 32
+
+#if !defined(__ASSEMBLY__) && !defined(CONFIG_SMP)
+
+#if __GNUC__ >= 4
+/* Alias to ipipe_root_cpudom_var(status) */
+extern unsigned long __ipipe_root_status;
+#else
+extern unsigned long *const __ipipe_root_status_addr;
+#define __ipipe_root_status (*__ipipe_root_status_addr)
+#endif
+
+static inline void __ipipe_stall_root(void)
+{
+ volatile unsigned long *p = &__ipipe_root_status;
+ __asm__ __volatile__("btsl $0,%0;"
+ :"+m" (*p) : : "memory");
+}
+
+static inline unsigned long __ipipe_test_and_stall_root(void)
+{
+ volatile unsigned long *p = &__ipipe_root_status;
+ int oldbit;
+
+ __asm__ __volatile__("btsl $0,%1;"
+ "sbbl %0,%0;"
+ :"=r" (oldbit), "+m" (*p)
+ : : "memory");
+ return oldbit;
+}
+
+static inline unsigned long __ipipe_test_root(void)
+{
+ volatile unsigned long *p = &__ipipe_root_status;
+ int oldbit;
+
+ __asm__ __volatile__("btl $0,%1;"
+ "sbbl %0,%0;"
+ :"=r" (oldbit)
+ :"m" (*p));
+ return oldbit;
+}
+
+#endif /* !__ASSEMBLY__ && !CONFIG_SMP */
+
+#endif /* !__X86_IPIPE_BASE_H */
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_base_32.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/ipipe_base_32.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_base_32.h
@@ -50,28 +50,6 @@
#define IPIPE_IRQ_ISHIFT 5 /* 2^5 for 32bits arch. */
-#define ex_do_divide_error 0
-#define ex_do_debug 1
-/* NMI not pipelined. */
-#define ex_do_int3 3
-#define ex_do_overflow 4
-#define ex_do_bounds 5
-#define ex_do_invalid_op 6
-#define ex_device_not_available 7
-/* Double fault not pipelined. */
-#define ex_do_coprocessor_segment_overrun 9
-#define ex_do_invalid_TSS 10
-#define ex_do_segment_not_present 11
-#define ex_do_stack_segment 12
-#define ex_do_general_protection 13
-#define ex_do_page_fault 14
-#define ex_do_spurious_interrupt_bug 15
-#define ex_do_coprocessor_error 16
-#define ex_do_alignment_check 17
-#define ex_machine_check_vector 18
-#define ex_do_simd_coprocessor_error 19
-#define ex_do_iret_error 32
-
/* IDT fault vectors */
#define IPIPE_NR_FAULTS 33 /* 32 from IDT + iret_error */
/* Pseudo-vectors used for kernel events */
@@ -134,47 +112,6 @@ static inline unsigned long __ipipe_test
return oldbit;
}
-#else /* ! CONFIG_SMP */
-
-#if __GNUC__ >= 4
-/* Alias to ipipe_root_cpudom_var(status) */
-extern unsigned long __ipipe_root_status;
-#else
-extern unsigned long *const __ipipe_root_status_addr;
-#define __ipipe_root_status (*__ipipe_root_status_addr)
-#endif
-
-static inline void __ipipe_stall_root(void)
-{
- volatile unsigned long *p = &__ipipe_root_status;
- __asm__ __volatile__("btsl $0,%0;"
- :"+m" (*p) : : "memory");
-}
-
-static inline unsigned long __ipipe_test_and_stall_root(void)
-{
- volatile unsigned long *p = &__ipipe_root_status;
- int oldbit;
-
- __asm__ __volatile__("btsl $0,%1;"
- "sbbl %0,%0;"
- :"=r" (oldbit), "+m" (*p)
- : : "memory");
- return oldbit;
-}
-
-static inline unsigned long __ipipe_test_root(void)
-{
- volatile unsigned long *p = &__ipipe_root_status;
- int oldbit;
-
- __asm__ __volatile__("btl $0,%1;"
- "sbbl %0,%0;"
- :"=r" (oldbit)
- :"m" (*p));
- return oldbit;
-}
-
#endif /* CONFIG_SMP */
#endif /* !__ASSEMBLY__ */
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_base_64.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/ipipe_base_64.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_base_64.h
@@ -50,28 +50,6 @@
#define IPIPE_IRQ_ISHIFT 6 /* 2^6 for 64bits arch. */
-#define ex_divide_error 0
-#define ex_debug 1
-/* NMI not pipelined. */
-#define ex_int3 3
-#define ex_overflow 4
-#define ex_bounds 5
-#define ex_invalid_op 6
-#define ex_math_state_restore 7
-/* Double fault not pipelined. */
-#define ex_coprocessor_segment_overrun 9
-#define ex_invalid_TSS 10
-#define ex_segment_not_present 11
-#define ex_stack_segment 12
-#define ex_general_protection 13
-#define ex_page_fault 14
-#define ex_spurious_interrupt_bug 15
-#define ex_coprocessor_error 16
-#define ex_alignment_check 17
-#define ex_reserved 18
-#define ex_machine_check_vector ex_reserved
-#define ex_simd_coprocessor_error 19
-
/* IDT fault vectors */
#define IPIPE_NR_FAULTS 32
/* Pseudo-vectors used for kernel events */
@@ -137,47 +115,6 @@ static inline unsigned long __ipipe_test
return oldbit;
}
-#else /* !CONFIG_SMP */
-
-#if __GNUC__ >= 4
-/* Alias to ipipe_root_cpudom_var(status) */
-extern unsigned long __ipipe_root_status;
-#else
-extern unsigned long *const __ipipe_root_status_addr;
-#define __ipipe_root_status (*__ipipe_root_status_addr)
-#endif
-
-static inline void __ipipe_stall_root(void)
-{
- volatile unsigned long *p = &__ipipe_root_status;
- __asm__ __volatile__("btsl $0,%0;"
- :"+m" (*p) : : "memory");
-}
-
-static inline unsigned long __ipipe_test_and_stall_root(void)
-{
- volatile unsigned long *p = &__ipipe_root_status;
- int oldbit;
-
- __asm__ __volatile__("btsl $0,%1;"
- "sbbl %0,%0;"
- :"=r" (oldbit), "+m" (*p)
- : : "memory");
- return oldbit;
-}
-
-static inline unsigned long __ipipe_test_root(void)
-{
- volatile unsigned long *p = &__ipipe_root_status;
- int oldbit;
-
- __asm__ __volatile__("btl $0,%1;"
- "sbbl %0,%0;"
- :"=r" (oldbit)
- :"m" (*p));
- return oldbit;
-}
-
#endif /* CONFIG_SMP */
#endif /* !__ASSEMBLY__ */
Index: linux-2.6.24-rc6-xeno_64/arch/x86/kernel/Makefile_32
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/arch/x86/kernel/Makefile_32
+++ linux-2.6.24-rc6-xeno_64/arch/x86/kernel/Makefile_32
@@ -34,7 +34,7 @@ obj-$(CONFIG_X86_SUMMIT_NUMA) += summit_
obj-$(CONFIG_KPROBES) += kprobes_32.o
obj-$(CONFIG_MODULES) += module_32.o
obj-y += sysenter_32.o vsyscall_32.o
-obj-$(CONFIG_IPIPE) += ipipe_32.o
+obj-$(CONFIG_IPIPE) += ipipe.o
obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount_32.o
obj-$(CONFIG_ACPI_SRAT) += srat_32.o
obj-$(CONFIG_EFI) += efi_32.o efi_stub_32.o
Index: linux-2.6.24-rc6-xeno_64/arch/x86/kernel/Makefile_64
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/arch/x86/kernel/Makefile_64
+++ linux-2.6.24-rc6-xeno_64/arch/x86/kernel/Makefile_64
@@ -35,7 +35,7 @@ obj-$(CONFIG_X86_PM_TIMER) += pmtimer_64
obj-$(CONFIG_X86_VSMP) += vsmp_64.o
obj-$(CONFIG_K8_NB) += k8.o
obj-$(CONFIG_AUDIT) += audit_64.o
-obj-$(CONFIG_IPIPE) += ipipe_64.o
+obj-$(CONFIG_IPIPE) += ipipe.o
obj-$(CONFIG_IPIPE_TRACE_MCOUNT) += mcount_64.o
obj-$(CONFIG_MODULES) += module_64.o
Index: linux-2.6.24-rc6-xeno_64/arch/x86/kernel/ipipe.c
===================================================================
--- /dev/null
+++ linux-2.6.24-rc6-xeno_64/arch/x86/kernel/ipipe.c
@@ -0,0 +1,1003 @@
+/* -*- linux-c -*-
+ * linux/arch/x86/kernel/ipipe.c
+ *
+ * Copyright (C) 2002-2007 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Architecture-dependent I-PIPE support for x86.
+ */
+
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <asm/unistd.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/hw_irq.h>
+#include <asm/irq.h>
+#include <asm/desc.h>
+#include <asm/io.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/tlbflush.h>
+#include <asm/fixmap.h>
+#include <asm/bitops.h>
+#include <asm/mpspec.h>
+#ifdef CONFIG_X86_IO_APIC
+#include <asm/io_apic.h>
+#endif /* CONFIG_X86_IO_APIC */
+#ifdef CONFIG_X86_32
+#include <asm/apic.h>
+#include <mach_ipi.h>
+#else /* !CONFIG_X86_32 */
+#include <asm/ipi.h>
+#include <asm/mach_apic.h>
+#endif /* !CONFIG_X86_32 */
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+int __ipipe_tick_irq = TIMER_IRQ;
+
+DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
+
+#ifdef CONFIG_SMP
+
+static cpumask_t __ipipe_cpu_sync_map;
+
+static cpumask_t __ipipe_cpu_lock_map;
+
+static IPIPE_DEFINE_SPINLOCK(__ipipe_cpu_barrier);
+
+static atomic_t __ipipe_critical_count = ATOMIC_INIT(0);
+
+static void (*__ipipe_cpu_sync) (void);
+
+#endif /* CONFIG_SMP */
+
+/* ipipe_trigger_irq() -- Push the interrupt at front of the pipeline
+ just like if it has been actually received from a hw source. Also
+ works for virtual interrupts. */
+
+int ipipe_trigger_irq(unsigned irq)
+{
+ struct pt_regs regs;
+ unsigned long flags;
+
+ if (irq >= IPIPE_NR_IRQS ||
+ (ipipe_virtual_irq_p(irq) &&
+ !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map)))
+ return -EINVAL;
+
+ local_irq_save_hw(flags);
+
+ regs.eflags = flags;
+#ifdef CONFIG_X86_32
+ regs.orig_eax = irq; /* Positive value - IRQ won't be acked */
+ regs.xcs = __KERNEL_CS;
+
+ __ipipe_handle_irq(regs);
+
+#else /* !CONFIG_X86_32 */
+ regs.orig_rax = irq; /* Positive value - IRQ won't be acked */
+ regs.cs = __KERNEL_CS;
+
+ __ipipe_handle_irq(®s);
+#endif /* !CONFIG_X86_32 */
+
+ local_irq_restore_hw(flags);
+
+ return 1;
+}
+
+int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
+{
+ info->ncpus = num_online_cpus();
+ info->cpufreq = ipipe_cpu_freq();
+ info->archdep.tmirq = __ipipe_tick_irq;
+#ifdef CONFIG_X86_TSC
+ info->archdep.tmfreq = ipipe_cpu_freq();
+#else /* !CONFIG_X86_TSC */
+ info->archdep.tmfreq = CLOCK_TICK_RATE;
+#endif /* CONFIG_X86_TSC */
+
+ return 0;
+}
+
+unsigned int do_IRQ(struct pt_regs *regs);
+void smp_apic_timer_interrupt(struct pt_regs *regs);
+void smp_spurious_interrupt(struct pt_regs *regs);
+void smp_error_interrupt(struct pt_regs *regs);
+void smp_thermal_interrupt(struct pt_regs *regs);
+void smp_reschedule_interrupt(struct pt_regs *regs);
+void smp_invalidate_interrupt(struct pt_regs *regs);
+void smp_call_function_interrupt(struct pt_regs *regs);
+void mce_threshold_interrupt(struct pt_regs *regs);
+
+static int __ipipe_ack_irq(unsigned irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ desc->ipipe_ack(irq, desc);
+ return 1;
+}
+
+void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
+{
+ irq_desc[irq].status &= ~IRQ_DISABLED;
+}
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+static int __ipipe_noack_apic(unsigned irq)
+{
+ return 1;
+}
+
+int __ipipe_ack_apic(unsigned irq)
+{
+ __ack_APIC_irq();
+ return 1;
+}
+
+static void __ipipe_null_handler(unsigned irq, void *cookie)
+{
+}
+
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+/* __ipipe_enable_pipeline() -- We are running on the boot CPU, hw
+ interrupts are off, and secondary CPUs are still lost in space. */
+
+void __init __ipipe_enable_pipeline(void)
+{
+ unsigned irq;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+
+ /* Map the APIC system vectors. */
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(LOCAL_TIMER_VECTOR),
+ (ipipe_irq_handler_t)&smp_apic_timer_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(SPURIOUS_APIC_VECTOR),
+ (ipipe_irq_handler_t)&smp_spurious_interrupt,
+ NULL,
+ &__ipipe_noack_apic,
+ IPIPE_STDROOT_MASK);
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(ERROR_APIC_VECTOR),
+ (ipipe_irq_handler_t)&smp_error_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR0),
+ &__ipipe_null_handler,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR1),
+ &__ipipe_null_handler,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR2),
+ &__ipipe_null_handler,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR3),
+ &__ipipe_null_handler,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+#if defined(CONFIG_X86_MCE_P4THERMAL) || defined(CONFIG_X86_64)
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(THERMAL_APIC_VECTOR),
+ (ipipe_irq_handler_t)&smp_thermal_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+#endif /* CONFIG_X86_MCE_P4THERMAL || CONFIG_X86_64 */
+
+#ifdef CONFIG_X86_64
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(THRESHOLD_APIC_VECTOR),
+ (ipipe_irq_handler_t)&mce_threshold_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+#endif /* CONFIG_X86_64 */
+
+#endif /* CONFIG_X86_LOCAL_APIC */
+
+#ifdef CONFIG_SMP
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(RESCHEDULE_VECTOR),
+ (ipipe_irq_handler_t)&smp_reschedule_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+#ifdef CONFIG_X86_32
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(INVALIDATE_TLB_VECTOR),
+ (ipipe_irq_handler_t)&smp_invalidate_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+#else /* !CONFIG_X86_32 */
+ {
+ unsigned vector;
+
+ for (vector = INVALIDATE_TLB_VECTOR_START;
+ vector <= INVALIDATE_TLB_VECTOR_END; ++vector)
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(vector),
+ (ipipe_irq_handler_t)&smp_invalidate_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+ }
+#endif /* !CONFIG_X86_32 */
+
+ ipipe_virtualize_irq(ipipe_root_domain,
+ ipipe_apic_vector_irq(CALL_FUNCTION_VECTOR),
+ (ipipe_irq_handler_t)&smp_call_function_interrupt,
+ NULL,
+ &__ipipe_ack_apic,
+ IPIPE_STDROOT_MASK);
+
+#endif /* CONFIG_SMP */
+
+ /* Finally, virtualize the remaining ISA and IO-APIC
+ * interrupts. Interrupts which have already been virtualized
+ * will just beget a silent -EPERM error since
+ * IPIPE_SYSTEM_MASK has been passed for them, that's ok. */
+
+ for (irq = 0; irq < NR_IRQS; irq++)
+ /* Fails for IPIPE_CRITICAL_IPI but that's ok. */
+ ipipe_virtualize_irq(ipipe_root_domain,
+ irq,
+ (ipipe_irq_handler_t)&do_IRQ,
+ NULL,
+ &__ipipe_ack_irq,
+ IPIPE_STDROOT_MASK);
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ /* Eventually allow these vectors to be reprogrammed. */
+ ipipe_root_domain->irqs[IPIPE_SERVICE_IPI0].control &= ~IPIPE_SYSTEM_MASK;
+ ipipe_root_domain->irqs[IPIPE_SERVICE_IPI1].control &= ~IPIPE_SYSTEM_MASK;
+ ipipe_root_domain->irqs[IPIPE_SERVICE_IPI2].control &= ~IPIPE_SYSTEM_MASK;
+ ipipe_root_domain->irqs[IPIPE_SERVICE_IPI3].control &= ~IPIPE_SYSTEM_MASK;
+#endif /* CONFIG_X86_LOCAL_APIC */
+}
+
+#ifdef CONFIG_SMP
+
+cpumask_t __ipipe_set_irq_affinity(unsigned irq, cpumask_t cpumask)
+{
+ cpumask_t oldmask = irq_desc[irq].affinity;
+
+ if (irq_desc[irq].chip->set_affinity == NULL)
+ return CPU_MASK_NONE;
+
+ if (cpus_empty(cpumask))
+ return oldmask; /* Return mask value -- no change. */
+
+ cpus_and(cpumask,cpumask,cpu_online_map);
+
+ if (cpus_empty(cpumask))
+ return CPU_MASK_NONE; /* Error -- bad mask value or non-routable IRQ. */
+
+ irq_desc[irq].chip->set_affinity(irq,cpumask);
+
+ return oldmask;
+}
+
+int __ipipe_send_ipi(unsigned ipi, cpumask_t cpumask)
+{
+ unsigned long flags;
+ int self;
+
+ if (ipi != IPIPE_SERVICE_IPI0 &&
+ ipi != IPIPE_SERVICE_IPI1 &&
+ ipi != IPIPE_SERVICE_IPI2 &&
+ ipi != IPIPE_SERVICE_IPI3)
+ return -EINVAL;
+
+ local_irq_save_hw(flags);
+
+ self = cpu_isset(ipipe_processor_id(),cpumask);
+ cpu_clear(ipipe_processor_id(), cpumask);
+
+ if (!cpus_empty(cpumask))
+ send_IPI_mask(cpumask, ipipe_apic_irq_vector(ipi));
+
+ if (self)
+ ipipe_trigger_irq(ipi);
+
+ local_irq_restore_hw(flags);
+
+ return 0;
+}
+
+/* Always called with hw interrupts off. */
+
+void __ipipe_do_critical_sync(unsigned irq, void *cookie)
+{
+ int cpu = ipipe_processor_id();
+
+ cpu_set(cpu, __ipipe_cpu_sync_map);
+
+ /* Now we are in sync with the lock requestor running on another
+ CPU. Enter a spinning wait until he releases the global
+ lock. */
+ spin_lock(&__ipipe_cpu_barrier);
+
+ /* Got it. Now get out. */
+
+ if (__ipipe_cpu_sync)
+ /* Call the sync routine if any. */
+ __ipipe_cpu_sync();
+
+ spin_unlock(&__ipipe_cpu_barrier);
+
+ cpu_clear(cpu, __ipipe_cpu_sync_map);
+}
+
+void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd)
+{
+ ipd->irqs[IPIPE_CRITICAL_IPI].acknowledge = &__ipipe_ack_apic;
+ ipd->irqs[IPIPE_CRITICAL_IPI].handler = &__ipipe_do_critical_sync;
+ ipd->irqs[IPIPE_CRITICAL_IPI].cookie = NULL;
+ /* Immediately handle in the current domain but *never* pass */
+ ipd->irqs[IPIPE_CRITICAL_IPI].control =
+ IPIPE_HANDLE_MASK|IPIPE_STICKY_MASK|IPIPE_SYSTEM_MASK;
+}
+
+#endif /* CONFIG_SMP */
+
+/* ipipe_critical_enter() -- Grab the superlock excluding all CPUs
+ but the current one from a critical section. This lock is used when
+ we must enforce a global critical section for a single CPU in a
+ possibly SMP system whichever context the CPUs are running. */
+
+unsigned long ipipe_critical_enter(void (*syncfn) (void))
+{
+ unsigned long flags;
+
+ local_irq_save_hw(flags);
+
+#ifdef CONFIG_SMP
+ if (unlikely(num_online_cpus() == 1)) /* We might be running a SMP-kernel on a UP box... */
+ return flags;
+
+ {
+ int cpu = ipipe_processor_id();
+ cpumask_t lock_map;
+
+ if (!cpu_test_and_set(cpu, __ipipe_cpu_lock_map)) {
+ while (cpu_test_and_set(BITS_PER_LONG - 1, __ipipe_cpu_lock_map)) {
+ int n = 0;
+ do {
+ cpu_relax();
+ } while (++n < cpu);
+ }
+
+ spin_lock(&__ipipe_cpu_barrier);
+
+ __ipipe_cpu_sync = syncfn;
+
+ /* Send the sync IPI to all processors but the current one. */
+ send_IPI_allbutself(IPIPE_CRITICAL_VECTOR);
+
+ cpus_andnot(lock_map, cpu_online_map, __ipipe_cpu_lock_map);
+
+ while (!cpus_equal(__ipipe_cpu_sync_map, lock_map))
+ cpu_relax();
+ }
+
+ atomic_inc(&__ipipe_critical_count);
+ }
+#endif /* CONFIG_SMP */
+
+ return flags;
+}
+
+/* ipipe_critical_exit() -- Release the superlock. */
+
+void ipipe_critical_exit(unsigned long flags)
+{
+#ifdef CONFIG_SMP
+ if (num_online_cpus() == 1)
+ goto out;
+
+ if (atomic_dec_and_test(&__ipipe_critical_count)) {
+ spin_unlock(&__ipipe_cpu_barrier);
+
+ while (!cpus_empty(__ipipe_cpu_sync_map))
+ cpu_relax();
+
+ cpu_clear(ipipe_processor_id(), __ipipe_cpu_lock_map);
+ cpu_clear(BITS_PER_LONG - 1, __ipipe_cpu_lock_map);
+ }
+out:
+#endif /* CONFIG_SMP */
+
+ local_irq_restore_hw(flags);
+}
+
+static inline void __fixup_if(struct pt_regs *regs)
+{
+ if (!ipipe_root_domain_p)
+ return;
+
+ /*
+ * Have the saved hw state look like the domain stall bit, so
+ * that __ipipe_unstall_iret_root() restores the proper
+ * pipeline state for the root stage upon exit.
+ */
+
+ if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
+ regs->eflags &= ~X86_EFLAGS_IF;
+ else
+ regs->eflags |= X86_EFLAGS_IF;
+}
+
+#ifdef CONFIG_X86_32
+
+/*
+ * Check the stall bit of the root domain to make sure the existing
+ * preemption opportunity upon in-kernel resumption could be
+ * exploited. In case a rescheduling could take place, the root stage
+ * is stalled before the hw interrupts are re-enabled. This routine
+ * must be called with hw interrupts off.
+ */
+
+asmlinkage int __ipipe_kpreempt_root(struct pt_regs regs)
+{
+ if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
+ /* Root stage is stalled: rescheduling denied. */
+ return 0;
+
+ __ipipe_stall_root();
+ local_irq_enable_hw_notrace();
+
+ return 1; /* Ok, may reschedule now. */
+}
+
+asmlinkage void __ipipe_unstall_iret_root(struct pt_regs regs)
+{
+ /* Emulate IRET's handling of the interrupt flag. */
+
+ local_irq_disable_hw();
+
+ /* Restore the software state as it used to be on kernel
+ entry. CAUTION: NMIs must *not* return through this
+ emulation. */
+
+ if (!(regs.eflags & X86_EFLAGS_IF)) {
+ if (!__test_and_set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
+ trace_hardirqs_off();
+ regs.eflags |= X86_EFLAGS_IF;
+ } else {
+ if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status))) {
+ trace_hardirqs_on();
+ __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+ }
+
+ /* Only sync virtual IRQs here, so that we don't recurse
+ indefinitely in case of an external interrupt flood. */
+
+ if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
+ __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+ }
+#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
+ ipipe_trace_end(0x8000000D);
+#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
+}
+
+asmlinkage int __ipipe_syscall_root(struct pt_regs regs)
+{
+ unsigned long flags;
+
+ __fixup_if(®s);
+
+ /* This routine either returns:
+ 0 -- if the syscall is to be passed to Linux;
+ >0 -- if the syscall should not be passed to Linux, and no
+ tail work should be performed;
+ <0 -- if the syscall should not be passed to Linux but the
+ tail work has to be performed (for handling signals etc). */
+
+ if (__ipipe_syscall_watched_p(current, regs.orig_eax) &&
+ __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
+ __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,®s) > 0) {
+ /* We might enter here over a non-root domain and exit
+ * over the root one as a result of the syscall
+ * (i.e. by recycling the register set of the current
+ * context across the migration), so we need to fixup
+ * the interrupt flag upon return too, so that
+ * __ipipe_unstall_iret_root() resets the correct
+ * stall bit on exit. */
+ __fixup_if(®s);
+
+ if (ipipe_root_domain_p && !in_atomic()) {
+ /* Sync pending VIRQs before _TIF_NEED_RESCHED is tested. */
+ local_irq_save_hw(flags);
+ if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
+ __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+ local_irq_restore_hw(flags);
+ return -1;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+#else /* !CONFIG_X86_32 */
+
+#ifdef CONFIG_PREEMPT
+/*
+ * Check the stall bit of the root domain to make sure the existing
+ * preemption opportunity upon in-kernel resumption could be
+ * exploited. In case a rescheduling could take place, the root stage
+ * is stalled before the hw interrupts are re-enabled. This routine
+ * must be called with hw interrupts off.
+ */
+asmlinkage int __ipipe_preempt_schedule_irq(void)
+{
+ if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
+ /* Root stage is stalled: rescheduling denied. */
+ return 0;
+
+ __set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+ local_irq_enable_hw();
+ preempt_schedule_irq(); /* Ok, may reschedule now. */
+ local_irq_disable_hw();
+ __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+
+ return 1;
+}
+#endif
+
+asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
+{
+ unsigned long flags;
+
+ __fixup_if(regs);
+
+ /* This routine either returns:
+ 0 -- if the syscall is to be passed to Linux;
+ >0 -- if the syscall should not be passed to Linux, and no
+ tail work should be performed;
+ <0 -- if the syscall should not be passed to Linux but the
+ tail work has to be performed (for handling signals etc). */
+
+ if (__ipipe_syscall_watched_p(current, regs->orig_rax) &&
+ __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
+ __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) {
+ /* We might enter here over a non-root domain and exit
+ * over the root one as a result of the syscall
+ * (i.e. by recycling the register set of the current
+ * context across the migration), so we need to fixup
+ * the interrupt flag upon return too, so that
+ * __ipipe_unstall_iret_root() resets the correct
+ * stall bit on exit. */
+ __fixup_if(regs);
+
+ if (ipipe_root_domain_p && !in_atomic()) {
+ /* Sync pending VIRQs before _TIF_NEED_RESCHED is tested. */
+ local_irq_save_hw(flags);
+ if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
+ __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
+ local_irq_restore_hw(flags);
+ return -1;
+ }
+ /*
+ * We are about to run the atomic syscall epilogue;
+ * switch interrupts off before branching to it.
+ */
+ local_irq_disable_hw();
+ return 1;
+ }
+
+ return 0;
+}
+
+#endif /* !CONFIG_X86_32 */
+
+static void do_machine_check_vector(struct pt_regs *regs, long error_code)
+{
+#ifdef CONFIG_X86_MCE
+ void do_machine_check(struct pt_regs *, long);
+ do_machine_check(regs,error_code);
+#endif /* CONFIG_X86_MCE */
+}
+
+void do_divide_error(struct pt_regs *regs, long error_code);
+void do_overflow(struct pt_regs *regs, long error_code);
+void do_bounds(struct pt_regs *regs, long error_code);
+void do_invalid_op(struct pt_regs *regs, long error_code);
+void math_state_restore(struct pt_regs *regs, long error_code);
+void do_coprocessor_segment_overrun(struct pt_regs *regs, long error_code);
+void do_invalid_TSS(struct pt_regs *regs, long error_code);
+void do_segment_not_present(struct pt_regs *regs, long error_code);
+void do_stack_segment(struct pt_regs *regs, long error_code);
+void do_general_protection(struct pt_regs *regs, long error_code);
+void do_page_fault(struct pt_regs *regs, long error_code);
+void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code);
+void do_coprocessor_error(struct pt_regs *regs, long error_code);
+void do_alignment_check(struct pt_regs *regs, long error_code);
+void do_simd_coprocessor_error(struct pt_regs *regs, long error_code);
+void do_iret_error(struct pt_regs *regs, long error_code);
+
+/* Work around genksyms's issue with over-qualification in decls. */
+
+typedef void __ipipe_exhandler(struct pt_regs *, long);
+
+typedef __ipipe_exhandler *__ipipe_exptr;
+
+static __ipipe_exptr __ipipe_std_extable[] = {
+
+ [ex_do_divide_error] = &do_divide_error,
+ [ex_do_overflow] = &do_overflow,
+ [ex_do_bounds] = &do_bounds,
+ [ex_do_invalid_op] = &do_invalid_op,
+ [ex_do_coprocessor_segment_overrun] = &do_coprocessor_segment_overrun,
+ [ex_do_invalid_TSS] = &do_invalid_TSS,
+ [ex_do_segment_not_present] = &do_segment_not_present,
+ [ex_do_stack_segment] = &do_stack_segment,
+ [ex_do_general_protection] = do_general_protection,
+ [ex_do_page_fault] = &do_page_fault,
+ [ex_do_spurious_interrupt_bug] = &do_spurious_interrupt_bug,
+ [ex_do_coprocessor_error] = &do_coprocessor_error,
+ [ex_do_alignment_check] = &do_alignment_check,
+ [ex_machine_check_vector] = &do_machine_check_vector,
+ [ex_do_simd_coprocessor_error] = &do_simd_coprocessor_error,
+#ifdef CONFIG_X86_32
+ [ex_do_iret_error] = &do_iret_error,
+#else
+ [ex_math_state_restore] = &math_state_restore,
+#endif
+};
+
+#ifdef CONFIG_KGDB
+#include <linux/kgdb.h>
+
+static int __ipipe_xlate_signo[] = {
+
+ [ex_do_divide_error] = SIGFPE,
+ [ex_do_debug] = SIGTRAP,
+ [2] = -1,
+ [ex_do_int3] = SIGTRAP,
+ [ex_do_overflow] = SIGSEGV,
+ [ex_do_bounds] = SIGSEGV,
+ [ex_do_invalid_op] = SIGILL,
+ [ex_device_not_available] = -1, /* == ex_math_state_restore on x86_64 */
+ [8] = -1,
+ [ex_do_coprocessor_segment_overrun] = SIGFPE,
+ [ex_do_invalid_TSS] = SIGSEGV,
+ [ex_do_segment_not_present] = SIGBUS,
+ [ex_do_stack_segment] = SIGBUS,
+ [ex_do_general_protection] = SIGSEGV,
+ [ex_do_page_fault] = SIGSEGV,
+ [ex_do_spurious_interrupt_bug] = -1,
+ [ex_do_coprocessor_error] = -1,
+ [ex_do_alignment_check] = SIGBUS,
+ [ex_machine_check_vector] = -1,
+ [ex_do_simd_coprocessor_error] = -1,
+ [20 ... 31] = -1,
+#ifndef CONFIG_X86_64
+ [ex_do_iret_error] = SIGSEGV,
+#endif
+};
+#endif /* CONFIG_KGDB */
+
+int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector)
+{
+ unsigned long flags;
+
+ local_save_flags(flags);
+
+ /* Track the hw interrupt state before calling the Linux
+ * exception handler, replicating it into the virtual mask. */
+
+ if (irqs_disabled_hw()) {
+ /* Do not trigger the alarm in ipipe_check_context() by using
+ * plain local_irq_disable(). */
+ __ipipe_stall_root();
+ trace_hardirqs_off();
+ barrier();
+ }
+
+#ifdef CONFIG_KGDB
+ /* catch exception KGDB is interested in over non-root domains */
+ if (!ipipe_root_domain_p &&
+ __ipipe_xlate_signo[vector] >= 0 &&
+ !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs)) {
+ local_irq_restore(flags);
+ return 1;
+ }
+#endif /* CONFIG_KGDB */
+
+ if (unlikely(ipipe_trap_notify(vector, regs))) {
+ local_irq_restore(flags);
+ return 1;
+ }
+
+ /* Detect unhandled faults over non-root domains. */
+
+ if (unlikely(!ipipe_root_domain_p)) {
+ struct ipipe_domain *ipd = ipipe_current_domain;
+
+ /* Switch to root so that Linux can handle the fault cleanly. */
+ ipipe_current_domain = ipipe_root_domain;
+
+ ipipe_trace_panic_freeze();
+
+ /* Always warn about user land and unfixable faults. */
+ if ((error_code & 4) || !search_exception_tables(instruction_pointer(regs)))
+ printk(KERN_ERR "BUG: Unhandled exception over domain"
+ " %s at 0x%lx - switching to ROOT\n",
+ ipd->name, instruction_pointer(regs));
+#ifdef CONFIG_IPIPE_DEBUG
+ /* Also report fixable ones when debugging is enabled. */
+ else
+ printk(KERN_WARNING "WARNING: Fixable exception over "
+ "domain %s at 0x%lx - switching to ROOT\n",
+ ipd->name, instruction_pointer(regs));
+#endif /* CONFIG_IPIPE_DEBUG */
+
+ dump_stack();
+ }
+
+ __ipipe_std_extable[vector](regs, error_code);
+ local_irq_restore(flags);
+ __fixup_if(regs);
+
+ return 0;
+}
+
+int __ipipe_divert_exception(struct pt_regs *regs, int vector)
+{
+#ifdef CONFIG_KGDB
+ /* catch int1 and int3 over non-root domains */
+#ifdef CONFIG_X86_32
+ if (!ipipe_root_domain_p && vector != ex_do_device_not_available) {
+#else
+ if (!ipipe_root_domain_p) {
+#endif
+ unsigned int condition = 0;
+
+ if (vector == 1)
+ get_debugreg(condition, 6);
+ if (!kgdb_handle_exception(vector, SIGTRAP, condition, regs))
+ return 1;
+ }
+#endif /* CONFIG_KGDB */
+
+ if (ipipe_trap_notify(vector, regs))
+ return 1;
+
+ __fixup_if(regs);
+
+ return 0;
+}
+
+/* __ipipe_handle_irq() -- IPIPE's generic IRQ handler. An optimistic
+ interrupt protection log is maintained here for each domain. Hw
+ interrupts are off on entry. */
+
+#ifdef CONFIG_X86_32
+int __ipipe_handle_irq(struct pt_regs regs)
+{
+ struct ipipe_domain *this_domain, *next_domain;
+ unsigned irq = regs.orig_eax;
+ struct list_head *head, *pos;
+ int m_ack;
+
+ if ((long)regs.orig_eax < 0) {
+ irq = ~irq;
+ m_ack = 0;
+ } else /* This is a self-triggered interrupt. */
+ m_ack = 1;
+
+#else /* !CONFIG_X86_32 */
+int __ipipe_handle_irq(struct pt_regs *regs)
+{
+ struct ipipe_domain *this_domain, *next_domain;
+ unsigned vector = regs->orig_rax, irq;
+ struct list_head *head, *pos;
+ int m_ack;
+
+ if ((long)regs->orig_rax < 0) {
+ vector = ~vector;
+ if (vector >= FIRST_SYSTEM_VECTOR)
+ irq = ipipe_apic_vector_irq(vector);
+ else
+ irq = __get_cpu_var(vector_irq)[vector];
+ m_ack = 0;
+ } else { /* This is a self-triggered one. */
+ irq = vector;
+ m_ack = 1;
+ }
+
+#endif /* !CONFIG_X86_32 */
+ head = __ipipe_pipeline.next;
+ next_domain = list_entry(head, struct ipipe_domain, p_link);
+ if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
+ if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
+ next_domain->irqs[irq].acknowledge(irq);
+ if (likely(__ipipe_dispatch_wired(next_domain, irq))) {
+ goto finalize;
+ } else
+ goto finalize_nosync;
+ }
+
+ this_domain = ipipe_current_domain;
+
+ if (test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))
+ head = &this_domain->p_link;
+
+ /* Ack the interrupt. */
+
+ pos = head;
+
+ while (pos != &__ipipe_pipeline) {
+ next_domain = list_entry(pos, struct ipipe_domain, p_link);
+
+ /*
+ * For each domain handling the incoming IRQ, mark it
+ * as pending in its log.
+ */
+ if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
+ /*
+ * Domains that handle this IRQ are polled for
+ * acknowledging it by decreasing priority
+ * order. The interrupt must be made pending
+ * _first_ in the domain's status flags before
+ * the PIC is unlocked.
+ */
+ __ipipe_set_irq_pending(next_domain, irq);
+
+ if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
+ m_ack = next_domain->irqs[irq].acknowledge(irq);
+ }
+
+ /*
+ * If the domain does not want the IRQ to be passed
+ * down the interrupt pipe, exit the loop now.
+ */
+
+ if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
+ break;
+
+ pos = next_domain->p_link.next;
+ }
+
+finalize:
+
+ /* Given our deferred dispatching model for regular IRQs, we
+ * only record CPU regs for the last timer interrupt, so that
+ * the timer handler charges CPU times properly. It is assumed
+ * that other interrupt handlers don't actually care for such
+ * information. */
+
+ if (irq == __ipipe_tick_irq) {
+ struct pt_regs *tick_regs = &__raw_get_cpu_var(__ipipe_tick_regs);
+#ifdef CONFIG_X86_32
+ tick_regs->eflags = regs.eflags;
+ tick_regs->xcs = regs.xcs;
+ tick_regs->eip = regs.eip;
+ tick_regs->ebp = regs.ebp;
+#else /* !CONFIG_X86_32 */
+ tick_regs->ss = regs->ss;
+ tick_regs->rsp = regs->rsp;
+ tick_regs->eflags = regs->eflags;
+ tick_regs->cs = regs->cs;
+ tick_regs->rip = regs->rip;
+ tick_regs->rbp = regs->rbp;
+#endif /* !CONFIG_X86_32 */
+ }
+
+ /*
+ * Now walk the pipeline, yielding control to the highest
+ * priority domain that has pending interrupt(s) or
+ * immediately to the current domain if the interrupt has been
+ * marked as 'sticky'. This search does not go beyond the
+ * current domain in the pipeline.
+ */
+
+ __ipipe_walk_pipeline(head);
+
+finalize_nosync:
+
+ if (!ipipe_root_domain_p ||
+ test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
+ return 0;
+
+#if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
+ /*
+ * Prevent a spurious rescheduling from being triggered on
+ * preemptible kernels along the way out through
+ * ret_from_intr.
+ */
+ if ((long)regs.orig_eax < 0)
+ __set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
+#endif /* CONFIG_SMP */
+
+ return 1;
+}
+
+int __ipipe_check_tickdev(const char *devname)
+{
+#ifdef CONFIG_X86_LOCAL_APIC
+ if (!strcmp(devname, "lapic"))
+ return __ipipe_check_lapic();
+#endif
+
+ return 1;
+}
+
+EXPORT_SYMBOL(__ipipe_tick_irq);
+EXPORT_SYMBOL(ipipe_critical_enter);
+EXPORT_SYMBOL(ipipe_critical_exit);
+EXPORT_SYMBOL(ipipe_trigger_irq);
+EXPORT_SYMBOL(ipipe_get_sysinfo);
+
+EXPORT_SYMBOL_GPL(irq_desc);
+struct task_struct *__switch_to(struct task_struct *prev_p,
+ struct task_struct *next_p);
+EXPORT_SYMBOL_GPL(__switch_to);
+EXPORT_SYMBOL_GPL(show_stack);
+
+#ifdef CONFIG_X86_32
+EXPORT_PER_CPU_SYMBOL_GPL(init_tss);
+#ifdef CONFIG_SMP
+EXPORT_PER_CPU_SYMBOL_GPL(cpu_tlbstate);
+#endif /* CONFIG_SMP */
+#else /* !CONFIG_X86_32 */
+EXPORT_SYMBOL_GPL(cpu_gdt_descr);
+#endif /* !CONFIG_X86_32 */
+
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+EXPORT_SYMBOL(tasklist_lock);
+#endif /* CONFIG_SMP || CONFIG_DEBUG_SPINLOCK */
+
+#ifdef CONFIG_IPIPE_TRACE_MCOUNT
+void notrace mcount(void);
+EXPORT_SYMBOL(mcount);
+#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
Index: linux-2.6.24-rc6-xeno_64/arch/x86/kernel/ipipe_32.c
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/arch/x86/kernel/ipipe_32.c
+++ /dev/null
@@ -1,838 +0,0 @@
-/* -*- linux-c -*-
- * linux/arch/x86/kernel/ipipe_32.c
- *
- * Copyright (C) 2002-2007 Philippe Gerum.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
- * USA; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Architecture-dependent I-PIPE support for x86_32.
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <linux/clockchips.h>
-#include <asm/unistd.h>
-#include <asm/system.h>
-#include <asm/atomic.h>
-#include <asm/hw_irq.h>
-#include <asm/irq.h>
-#include <asm/desc.h>
-#include <asm/io.h>
-#ifdef CONFIG_X86_LOCAL_APIC
-#include <asm/tlbflush.h>
-#include <asm/fixmap.h>
-#include <asm/bitops.h>
-#include <asm/mpspec.h>
-#ifdef CONFIG_X86_IO_APIC
-#include <asm/io_apic.h>
-#endif /* CONFIG_X86_IO_APIC */
-#include <asm/apic.h>
-#include <mach_ipi.h>
-#endif /* CONFIG_X86_LOCAL_APIC */
-
-int __ipipe_tick_irq = TIMER_IRQ;
-
-DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
-
-#ifdef CONFIG_SMP
-
-static cpumask_t __ipipe_cpu_sync_map;
-
-static cpumask_t __ipipe_cpu_lock_map;
-
-static IPIPE_DEFINE_SPINLOCK(__ipipe_cpu_barrier);
-
-static atomic_t __ipipe_critical_count = ATOMIC_INIT(0);
-
-static void (*__ipipe_cpu_sync) (void);
-
-#endif /* CONFIG_SMP */
-
-/* ipipe_trigger_irq() -- Push the interrupt at front of the pipeline
- just like if it has been actually received from a hw source. Also
- works for virtual interrupts. */
-
-int fastcall ipipe_trigger_irq(unsigned irq)
-{
- struct pt_regs regs;
- unsigned long flags;
-
- if (irq >= IPIPE_NR_IRQS ||
- (ipipe_virtual_irq_p(irq) &&
- !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map)))
- return -EINVAL;
-
- local_irq_save_hw(flags);
-
- regs.orig_eax = irq; /* Won't be acked */
- regs.xcs = __KERNEL_CS;
- regs.eflags = flags;
-
- __ipipe_handle_irq(regs);
-
- local_irq_restore_hw(flags);
-
- return 1;
-}
-
-int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
-{
- info->ncpus = num_online_cpus();
- info->cpufreq = ipipe_cpu_freq();
- info->archdep.tmirq = __ipipe_tick_irq;
-#ifdef CONFIG_X86_TSC
- info->archdep.tmfreq = ipipe_cpu_freq();
-#else /* !CONFIG_X86_TSC */
- info->archdep.tmfreq = CLOCK_TICK_RATE;
-#endif /* CONFIG_X86_TSC */
-
- return 0;
-}
-
-fastcall unsigned int do_IRQ(struct pt_regs *regs);
-fastcall void smp_apic_timer_interrupt(struct pt_regs *regs);
-fastcall void smp_spurious_interrupt(struct pt_regs *regs);
-fastcall void smp_error_interrupt(struct pt_regs *regs);
-fastcall void smp_thermal_interrupt(struct pt_regs *regs);
-fastcall void smp_reschedule_interrupt(struct pt_regs *regs);
-fastcall void smp_invalidate_interrupt(struct pt_regs *regs);
-fastcall void smp_call_function_interrupt(struct pt_regs *regs);
-
-static int __ipipe_ack_irq(unsigned irq)
-{
- irq_desc_t *desc = irq_desc + irq;
- desc->ipipe_ack(irq, desc);
- return 1;
-}
-
-void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
-{
- irq_desc[irq].status &= ~IRQ_DISABLED;
-}
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
-static int __ipipe_noack_apic(unsigned irq)
-{
- return 1;
-}
-
-int __ipipe_ack_apic(unsigned irq)
-{
- __ack_APIC_irq();
- return 1;
-}
-
-static void __ipipe_null_handler(unsigned irq, void *cookie)
-{
-}
-
-#endif /* CONFIG_X86_LOCAL_APIC */
-
-/* __ipipe_enable_pipeline() -- We are running on the boot CPU, hw
- interrupts are off, and secondary CPUs are still lost in space. */
-
-void __init __ipipe_enable_pipeline(void)
-{
- unsigned irq;
-
-#ifdef CONFIG_X86_LOCAL_APIC
-
- /* Map the APIC system vectors. */
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(LOCAL_TIMER_VECTOR),
- (ipipe_irq_handler_t)&smp_apic_timer_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(SPURIOUS_APIC_VECTOR),
- (ipipe_irq_handler_t)&smp_spurious_interrupt,
- NULL,
- &__ipipe_noack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(ERROR_APIC_VECTOR),
- (ipipe_irq_handler_t)&smp_error_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR0),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR1),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR2),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR3),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
-#ifdef CONFIG_X86_MCE_P4THERMAL
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(THERMAL_APIC_VECTOR),
- (ipipe_irq_handler_t)&smp_thermal_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-#endif /* CONFIG_X86_MCE_P4THERMAL */
-
-#endif /* CONFIG_X86_LOCAL_APIC */
-
-#ifdef CONFIG_SMP
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(RESCHEDULE_VECTOR),
- (ipipe_irq_handler_t)&smp_reschedule_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(INVALIDATE_TLB_VECTOR),
- (ipipe_irq_handler_t)&smp_invalidate_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(CALL_FUNCTION_VECTOR),
- (ipipe_irq_handler_t)&smp_call_function_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
-#endif /* CONFIG_SMP */
-
- /* Finally, virtualize the remaining ISA and IO-APIC
- * interrupts. Interrupts which have already been virtualized
- * will just beget a silent -EPERM error since
- * IPIPE_SYSTEM_MASK has been passed for them, that's ok. */
-
- for (irq = 0; irq < NR_IRQS; irq++)
- /* Fails for IPIPE_CRITICAL_IPI but that's ok. */
- ipipe_virtualize_irq(ipipe_root_domain,
- irq,
- (ipipe_irq_handler_t)&do_IRQ,
- NULL,
- &__ipipe_ack_irq,
- IPIPE_STDROOT_MASK);
-
-#ifdef CONFIG_X86_LOCAL_APIC
- /* Eventually allow these vectors to be reprogrammed. */
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI0].control &= ~IPIPE_SYSTEM_MASK;
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI1].control &= ~IPIPE_SYSTEM_MASK;
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI2].control &= ~IPIPE_SYSTEM_MASK;
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI3].control &= ~IPIPE_SYSTEM_MASK;
-#endif /* CONFIG_X86_LOCAL_APIC */
-}
-
-#ifdef CONFIG_SMP
-
-cpumask_t __ipipe_set_irq_affinity (unsigned irq, cpumask_t cpumask)
-{
- cpumask_t oldmask = irq_desc[irq].affinity;
-
- if (irq_desc[irq].chip->set_affinity == NULL)
- return CPU_MASK_NONE;
-
- if (cpus_empty(cpumask))
- return oldmask; /* Return mask value -- no change. */
-
- cpus_and(cpumask,cpumask,cpu_online_map);
-
- if (cpus_empty(cpumask))
- return CPU_MASK_NONE; /* Error -- bad mask value or non-routable IRQ. */
-
- irq_desc[irq].chip->set_affinity(irq,cpumask);
-
- return oldmask;
-}
-
-int fastcall __ipipe_send_ipi (unsigned ipi, cpumask_t cpumask)
-{
- unsigned long flags;
- int self;
-
- if (ipi != IPIPE_SERVICE_IPI0 &&
- ipi != IPIPE_SERVICE_IPI1 &&
- ipi != IPIPE_SERVICE_IPI2 &&
- ipi != IPIPE_SERVICE_IPI3)
- return -EINVAL;
-
- local_irq_save_hw(flags);
-
- self = cpu_isset(ipipe_processor_id(),cpumask);
- cpu_clear(ipipe_processor_id(), cpumask);
-
- if (!cpus_empty(cpumask))
- send_IPI_mask(cpumask,ipipe_apic_irq_vector(ipi));
-
- if (self)
- ipipe_trigger_irq(ipi);
-
- local_irq_restore_hw(flags);
-
- return 0;
-}
-
-/* Always called with hw interrupts off. */
-
-void __ipipe_do_critical_sync(unsigned irq, void *cookie)
-{
- int cpu = ipipe_processor_id();
-
- cpu_set(cpu, __ipipe_cpu_sync_map);
-
- /* Now we are in sync with the lock requestor running on another
- CPU. Enter a spinning wait until he releases the global
- lock. */
- spin_lock(&__ipipe_cpu_barrier);
-
- /* Got it. Now get out. */
-
- if (__ipipe_cpu_sync)
- /* Call the sync routine if any. */
- __ipipe_cpu_sync();
-
- spin_unlock(&__ipipe_cpu_barrier);
-
- cpu_clear(cpu, __ipipe_cpu_sync_map);
-}
-
-void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd)
-{
- ipd->irqs[IPIPE_CRITICAL_IPI].acknowledge = &__ipipe_ack_apic;
- ipd->irqs[IPIPE_CRITICAL_IPI].handler = &__ipipe_do_critical_sync;
- ipd->irqs[IPIPE_CRITICAL_IPI].cookie = NULL;
- /* Immediately handle in the current domain but *never* pass */
- ipd->irqs[IPIPE_CRITICAL_IPI].control =
- IPIPE_HANDLE_MASK|IPIPE_STICKY_MASK|IPIPE_SYSTEM_MASK;
-}
-
-#endif /* CONFIG_SMP */
-
-/* ipipe_critical_enter() -- Grab the superlock excluding all CPUs
- but the current one from a critical section. This lock is used when
- we must enforce a global critical section for a single CPU in a
- possibly SMP system whichever context the CPUs are running. */
-
-unsigned long ipipe_critical_enter(void (*syncfn) (void))
-{
- unsigned long flags;
-
- local_irq_save_hw(flags);
-
-#ifdef CONFIG_SMP
- if (unlikely(num_online_cpus() == 1)) /* We might be running a SMP-kernel on a UP box... */
- return flags;
-
- {
- int cpu = ipipe_processor_id();
- cpumask_t lock_map;
-
- if (!cpu_test_and_set(cpu, __ipipe_cpu_lock_map)) {
- while (cpu_test_and_set(BITS_PER_LONG - 1, __ipipe_cpu_lock_map)) {
- int n = 0;
- do {
- cpu_relax();
- } while (++n < cpu);
- }
-
- spin_lock(&__ipipe_cpu_barrier);
-
- __ipipe_cpu_sync = syncfn;
-
- /* Send the sync IPI to all processors but the current one. */
- send_IPI_allbutself(IPIPE_CRITICAL_VECTOR);
-
- cpus_andnot(lock_map, cpu_online_map, __ipipe_cpu_lock_map);
-
- while (!cpus_equal(__ipipe_cpu_sync_map, lock_map))
- cpu_relax();
- }
-
- atomic_inc(&__ipipe_critical_count);
- }
-#endif /* CONFIG_SMP */
-
- return flags;
-}
-
-/* ipipe_critical_exit() -- Release the superlock. */
-
-void ipipe_critical_exit(unsigned long flags)
-{
-#ifdef CONFIG_SMP
- if (num_online_cpus() == 1)
- goto out;
-
- if (atomic_dec_and_test(&__ipipe_critical_count)) {
- spin_unlock(&__ipipe_cpu_barrier);
-
- while (!cpus_empty(__ipipe_cpu_sync_map))
- cpu_relax();
-
- cpu_clear(ipipe_processor_id(), __ipipe_cpu_lock_map);
- cpu_clear(BITS_PER_LONG - 1, __ipipe_cpu_lock_map);
- }
-out:
-#endif /* CONFIG_SMP */
-
- local_irq_restore_hw(flags);
-}
-
-static inline void __fixup_if(struct pt_regs *regs)
-{
- if (!ipipe_root_domain_p)
- return;
-
- /*
- * Have the saved hw state look like the domain stall bit, so
- * that __ipipe_unstall_iret_root() restores the proper
- * pipeline state for the root stage upon exit.
- */
-
- if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- regs->eflags &= ~X86_EFLAGS_IF;
- else
- regs->eflags |= X86_EFLAGS_IF;
-}
-
-/* Check the stall bit of the root domain to make sure the existing
- preemption opportunity upon in-kernel resumption could be
- exploited. In case a rescheduling could take place, the root stage
- is stalled before the hw interrupts are re-enabled. This routine
- must be called with hw interrupts off. */
-
-asmlinkage int __ipipe_kpreempt_root(struct pt_regs regs)
-{
- if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- /* Root stage is stalled: rescheduling denied. */
- return 0;
-
- __ipipe_stall_root();
- local_irq_enable_hw_notrace();
-
- return 1; /* Ok, may reschedule now. */
-}
-
-asmlinkage void __ipipe_unstall_iret_root(struct pt_regs regs)
-{
- /* Emulate IRET's handling of the interrupt flag. */
-
- local_irq_disable_hw();
-
- /* Restore the software state as it used to be on kernel
- entry. CAUTION: NMIs must *not* return through this
- emulation. */
-
- if (!(regs.eflags & X86_EFLAGS_IF)) {
- if (!__test_and_set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- trace_hardirqs_off();
- regs.eflags |= X86_EFLAGS_IF;
- } else {
- if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status))) {
- trace_hardirqs_on();
- __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
- }
-
- /* Only sync virtual IRQs here, so that we don't recurse
- indefinitely in case of an external interrupt flood. */
-
- if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
- __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
- }
-#ifdef CONFIG_IPIPE_TRACE_IRQSOFF
- ipipe_trace_end(0x8000000D);
-#endif /* CONFIG_IPIPE_TRACE_IRQSOFF */
-}
-
-asmlinkage int __ipipe_syscall_root(struct pt_regs regs)
-{
- unsigned long flags;
-
- __fixup_if(®s);
-
- /* This routine either returns:
- 0 -- if the syscall is to be passed to Linux;
- >0 -- if the syscall should not be passed to Linux, and no
- tail work should be performed;
- <0 -- if the syscall should not be passed to Linux but the
- tail work has to be performed (for handling signals etc). */
-
- if (__ipipe_syscall_watched_p(current, regs.orig_eax) &&
- __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
- __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,®s) > 0) {
- /* We might enter here over a non-root domain and exit
- * over the root one as a result of the syscall
- * (i.e. by recycling the register set of the current
- * context across the migration), so we need to fixup
- * the interrupt flag upon return too, so that
- * __ipipe_unstall_iret_root() resets the correct
- * stall bit on exit. */
- __fixup_if(®s);
-
- if (ipipe_root_domain_p && !in_atomic()) {
- /* Sync pending VIRQs before _TIF_NEED_RESCHED is tested. */
- local_irq_save_hw(flags);
- if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
- __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
- local_irq_restore_hw(flags);
- return -1;
- }
- return 1;
- }
-
- return 0;
-}
-
-static fastcall void do_machine_check_vector(struct pt_regs *regs, long error_code)
-{
-#ifdef CONFIG_X86_MCE
- extern fastcall void (*machine_check_vector)(struct pt_regs *, long);
- machine_check_vector(regs,error_code);
-#endif /* CONFIG_X86_MCE */
-}
-
-fastcall void do_divide_error(struct pt_regs *regs, long error_code);
-fastcall void do_overflow(struct pt_regs *regs, long error_code);
-fastcall void do_bounds(struct pt_regs *regs, long error_code);
-fastcall void do_invalid_op(struct pt_regs *regs, long error_code);
-fastcall void do_coprocessor_segment_overrun(struct pt_regs *regs, long error_code);
-fastcall void do_invalid_TSS(struct pt_regs *regs, long error_code);
-fastcall void do_segment_not_present(struct pt_regs *regs, long error_code);
-fastcall void do_stack_segment(struct pt_regs *regs, long error_code);
-fastcall void do_general_protection(struct pt_regs *regs, long error_code);
-fastcall void do_page_fault(struct pt_regs *regs, long error_code);
-fastcall void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code);
-fastcall void do_coprocessor_error(struct pt_regs *regs, long error_code);
-fastcall void do_alignment_check(struct pt_regs *regs, long error_code);
-fastcall void do_simd_coprocessor_error(struct pt_regs *regs, long error_code);
-fastcall void do_iret_error(struct pt_regs *regs, long error_code);
-
-/* Work around genksyms's issue with over-qualification in decls. */
-
-typedef fastcall void __ipipe_exhandler(struct pt_regs *, long);
-
-typedef __ipipe_exhandler *__ipipe_exptr;
-
-static __ipipe_exptr __ipipe_std_extable[] = {
-
- [ex_do_divide_error] = &do_divide_error,
- [ex_do_overflow] = &do_overflow,
- [ex_do_bounds] = &do_bounds,
- [ex_do_invalid_op] = &do_invalid_op,
- [ex_do_coprocessor_segment_overrun] = &do_coprocessor_segment_overrun,
- [ex_do_invalid_TSS] = &do_invalid_TSS,
- [ex_do_segment_not_present] = &do_segment_not_present,
- [ex_do_stack_segment] = &do_stack_segment,
- [ex_do_general_protection] = do_general_protection,
- [ex_do_page_fault] = &do_page_fault,
- [ex_do_spurious_interrupt_bug] = &do_spurious_interrupt_bug,
- [ex_do_coprocessor_error] = &do_coprocessor_error,
- [ex_do_alignment_check] = &do_alignment_check,
- [ex_machine_check_vector] = &do_machine_check_vector,
- [ex_do_simd_coprocessor_error] = &do_simd_coprocessor_error,
- [ex_do_iret_error] = &do_iret_error,
-};
-
-#ifdef CONFIG_KGDB
-#include <linux/kgdb.h>
-
-static int __ipipe_xlate_signo[] = {
-
- [ex_do_divide_error] = SIGFPE,
- [ex_do_debug] = SIGTRAP,
- [2] = -1,
- [ex_do_int3] = SIGTRAP,
- [ex_do_overflow] = SIGSEGV,
- [ex_do_bounds] = SIGSEGV,
- [ex_do_invalid_op] = SIGILL,
- [ex_device_not_available] = -1,
- [8] = -1,
- [ex_do_coprocessor_segment_overrun] = SIGFPE,
- [ex_do_invalid_TSS] = SIGSEGV,
- [ex_do_segment_not_present] = SIGBUS,
- [ex_do_stack_segment] = SIGBUS,
- [ex_do_general_protection] = SIGSEGV,
- [ex_do_page_fault] = SIGSEGV,
- [ex_do_spurious_interrupt_bug] = -1,
- [ex_do_coprocessor_error] = -1,
- [ex_do_alignment_check] = SIGBUS,
- [ex_machine_check_vector] = -1,
- [ex_do_simd_coprocessor_error] = -1,
- [20 ... 31] = -1,
- [ex_do_iret_error] = SIGSEGV,
-};
-#endif /* CONFIG_KGDB */
-
-fastcall int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector)
-{
- unsigned long flags;
-
- local_save_flags(flags);
-
- /* Track the hw interrupt state before calling the Linux
- * exception handler, replicating it into the virtual mask. */
-
- if (irqs_disabled_hw()) {
- /* Do not trigger the alarm in ipipe_check_context() by using
- * plain local_irq_disable(). */
- __ipipe_stall_root();
- trace_hardirqs_off();
- barrier();
- }
-
-#ifdef CONFIG_KGDB
- /* catch exception KGDB is interested in over non-root domains */
- if (!ipipe_root_domain_p &&
- __ipipe_xlate_signo[vector] >= 0 &&
- !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs)) {
- local_irq_restore(flags);
- return 1;
- }
-#endif /* CONFIG_KGDB */
-
- if (unlikely(ipipe_trap_notify(vector, regs))) {
- local_irq_restore(flags);
- return 1;
- }
-
- /* Detect unhandled faults over non-root domains. */
-
- if (unlikely(!ipipe_root_domain_p)) {
- struct ipipe_domain *ipd = ipipe_current_domain;
-
- /* Switch to root so that Linux can handle the fault cleanly. */
- ipipe_current_domain = ipipe_root_domain;
-
- ipipe_trace_panic_freeze();
-
- /* Always warn about user land and unfixable faults. */
- if ((error_code & 4) || !search_exception_tables(regs->eip))
- printk(KERN_ERR "BUG: Unhandled exception over domain"
- " %s at 0x%lx - switching to ROOT\n",
- ipd->name, regs->eip);
-#ifdef CONFIG_IPIPE_DEBUG
- /* Also report fixable ones when debugging is enabled. */
- else
- printk(KERN_WARNING "WARNING: Fixable exception over "
- "domain %s at 0x%lx - switching to ROOT\n",
- ipd->name, regs->eip);
-#endif /* CONFIG_IPIPE_DEBUG */
-
- dump_stack();
- }
-
- __ipipe_std_extable[vector](regs, error_code);
- local_irq_restore(flags);
- __fixup_if(regs);
-
- return 0;
-}
-
-fastcall int __ipipe_divert_exception(struct pt_regs *regs, int vector)
-{
-#ifdef CONFIG_KGDB
- /* catch int1 and int3 over non-root domains */
- if (!ipipe_root_domain_p && vector != ex_device_not_available) {
- unsigned int condition = 0;
- if (vector == 1)
- get_debugreg(condition, 6);
- if (!kgdb_handle_exception(vector, SIGTRAP, condition, regs))
- return 1;
- }
-#endif /* CONFIG_KGDB */
-
- if (ipipe_trap_notify(vector, regs))
- return 1;
-
- __fixup_if(regs);
-
- return 0;
-}
-
-/* __ipipe_handle_irq() -- IPIPE's generic IRQ handler. An optimistic
- interrupt protection log is maintained here for each domain. Hw
- interrupts are off on entry. */
-
-int __ipipe_handle_irq(struct pt_regs regs)
-{
- struct ipipe_domain *this_domain, *next_domain;
- unsigned irq = regs.orig_eax;
- struct list_head *head, *pos;
- int m_ack;
-
- if ((long)regs.orig_eax < 0) {
- irq = ~irq;
- m_ack = 0;
- } else /* This is a self-triggered interrupt. */
- m_ack = 1;
-
- head = __ipipe_pipeline.next;
- next_domain = list_entry(head, struct ipipe_domain, p_link);
- if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
- if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
- next_domain->irqs[irq].acknowledge(irq);
- if (likely(__ipipe_dispatch_wired(next_domain, irq))) {
- goto finalize;
- } else
- goto finalize_nosync;
- }
-
- this_domain = ipipe_current_domain;
-
- if (test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))
- head = &this_domain->p_link;
-
- /* Ack the interrupt. */
-
- pos = head;
-
- while (pos != &__ipipe_pipeline) {
- next_domain = list_entry(pos, struct ipipe_domain, p_link);
-
- /*
- * For each domain handling the incoming IRQ, mark it
- * as pending in its log.
- */
- if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
- /*
- * Domains that handle this IRQ are polled for
- * acknowledging it by decreasing priority
- * order. The interrupt must be made pending
- * _first_ in the domain's status flags before
- * the PIC is unlocked.
- */
- __ipipe_set_irq_pending(next_domain, irq);
-
- if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
- m_ack = next_domain->irqs[irq].acknowledge(irq);
- }
-
- /*
- * If the domain does not want the IRQ to be passed
- * down the interrupt pipe, exit the loop now.
- */
-
- if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
- break;
-
- pos = next_domain->p_link.next;
- }
-
-finalize:
-
- /* Given our deferred dispatching model for regular IRQs, we
- * only record CPU regs for the last timer interrupt, so that
- * the timer handler charges CPU times properly. It is assumed
- * that other interrupt handlers don't actually care for such
- * information. */
-
- if (irq == __ipipe_tick_irq) {
- struct pt_regs *tick_regs = &__raw_get_cpu_var(__ipipe_tick_regs);
- tick_regs->eflags = regs.eflags;
- tick_regs->xcs = regs.xcs;
- tick_regs->eip = regs.eip;
- tick_regs->ebp = regs.ebp;
- }
-
- /*
- * Now walk the pipeline, yielding control to the highest
- * priority domain that has pending interrupt(s) or
- * immediately to the current domain if the interrupt has been
- * marked as 'sticky'. This search does not go beyond the
- * current domain in the pipeline.
- */
-
- __ipipe_walk_pipeline(head);
-
-finalize_nosync:
-
- if (!ipipe_root_domain_p ||
- test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- return 0;
-
-#ifdef CONFIG_SMP
- /*
- * Prevent a spurious rescheduling from being triggered on
- * preemptible kernels along the way out through
- * ret_from_intr.
- */
- if ((long)regs.orig_eax < 0)
- __set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
-#endif /* CONFIG_SMP */
-
- return 1;
-}
-
-int __ipipe_check_tickdev(const char *devname)
-{
-#ifdef CONFIG_X86_LOCAL_APIC
- if (!strcmp(devname, "lapic"))
- return __ipipe_check_lapic();
-#endif
-
- return 1;
-}
-
-EXPORT_SYMBOL(__ipipe_tick_irq);
-EXPORT_SYMBOL(ipipe_critical_enter);
-EXPORT_SYMBOL(ipipe_critical_exit);
-EXPORT_SYMBOL(ipipe_trigger_irq);
-EXPORT_SYMBOL(ipipe_get_sysinfo);
-
-EXPORT_SYMBOL_GPL(irq_desc);
-EXPORT_SYMBOL_GPL(__switch_to);
-EXPORT_SYMBOL_GPL(show_stack);
-EXPORT_PER_CPU_SYMBOL_GPL(init_tss);
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-EXPORT_SYMBOL(tasklist_lock);
-#endif /* CONFIG_SMP || CONFIG_DEBUG_SPINLOCK */
-#ifdef CONFIG_SMP
-EXPORT_PER_CPU_SYMBOL_GPL(cpu_tlbstate);
-#endif /* CONFIG_SMP */
-
-#ifdef CONFIG_IPIPE_TRACE_MCOUNT
-void notrace mcount(void);
-EXPORT_SYMBOL(mcount);
-#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
Index: linux-2.6.24-rc6-xeno_64/arch/x86/kernel/ipipe_64.c
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/arch/x86/kernel/ipipe_64.c
+++ /dev/null
@@ -1,803 +0,0 @@
-/* -*- linux-c -*-
- * linux/arch/x86/kernel/ipipe_64.c
- *
- * Copyright (C) 2007 Philippe Gerum.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
- * USA; either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Architecture-dependent I-PIPE support for x86_64.
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/irq.h>
-#include <asm/unistd.h>
-#include <asm/system.h>
-#include <asm/atomic.h>
-#include <asm/hw_irq.h>
-#include <asm/irq.h>
-#include <asm/desc.h>
-#include <asm/io.h>
-#include <asm/tlbflush.h>
-#include <asm/fixmap.h>
-#include <asm/bitops.h>
-#include <asm/mpspec.h>
-#include <asm/io_apic.h>
-#include <asm/smp.h>
-#include <asm/ipi.h>
-#include <asm/mach_apic.h>
-
-asmlinkage void preempt_schedule_irq(void);
-
-int __ipipe_tick_irq = TIMER_IRQ;
-
-DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
-
-#ifdef CONFIG_SMP
-
-static cpumask_t __ipipe_cpu_sync_map;
-
-static cpumask_t __ipipe_cpu_lock_map;
-
-static IPIPE_DEFINE_SPINLOCK(__ipipe_cpu_barrier);
-
-static atomic_t __ipipe_critical_count = ATOMIC_INIT(0);
-
-static void (*__ipipe_cpu_sync) (void);
-
-#endif /* CONFIG_SMP */
-
-/* ipipe_trigger_irq() -- Push the interrupt at front of the pipeline
- just like if it has been actually received from a hw source. Also
- works for virtual interrupts. */
-
-int ipipe_trigger_irq(unsigned irq)
-{
- struct pt_regs regs;
- unsigned long flags;
-
- if (irq >= IPIPE_NR_IRQS ||
- (ipipe_virtual_irq_p(irq) &&
- !test_bit(irq - IPIPE_VIRQ_BASE, &__ipipe_virtual_irq_map)))
- return -EINVAL;
-
- local_irq_save_hw(flags);
-
- regs.orig_rax = irq; /* Positive value - IRQ won't be acked */
- regs.cs = __KERNEL_CS;
- regs.eflags = flags;
-
- __ipipe_handle_irq(®s);
-
- local_irq_restore_hw(flags);
-
- return 1;
-}
-
-int ipipe_get_sysinfo(struct ipipe_sysinfo *info)
-{
- info->ncpus = num_online_cpus();
- info->cpufreq = ipipe_cpu_freq();
- info->archdep.tmirq = __ipipe_tick_irq;
- info->archdep.tmfreq = ipipe_cpu_freq();
-
- return 0;
-}
-
-asmlinkage unsigned int do_IRQ(struct pt_regs *regs);
-asmlinkage void smp_apic_timer_interrupt(struct pt_regs *regs);
-asmlinkage void smp_spurious_interrupt(struct pt_regs *regs);
-asmlinkage void smp_error_interrupt(struct pt_regs *regs);
-asmlinkage void smp_thermal_interrupt(struct pt_regs *regs);
-asmlinkage void smp_reschedule_interrupt(struct pt_regs *regs);
-asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs);
-asmlinkage void smp_call_function_interrupt(struct pt_regs *regs);
-asmlinkage void mce_threshold_interrupt(struct pt_regs *regs);
-
-static int __ipipe_ack_irq(unsigned irq)
-{
- irq_desc_t *desc = irq_desc + irq;
- desc->ipipe_ack(irq, desc);
- return 1;
-}
-
-void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq)
-{
- irq_desc[irq].status &= ~IRQ_DISABLED;
-}
-
-static int __ipipe_noack_apic(unsigned irq)
-{
- return 1;
-}
-
-int __ipipe_ack_apic(unsigned irq)
-{
- __ack_APIC_irq();
- return 1;
-}
-
-static void __ipipe_null_handler(unsigned irq, void *cookie)
-{
-}
-
-/* __ipipe_enable_pipeline() -- We are running on the boot CPU, hw
- interrupts are off, and secondary CPUs are still lost in space. */
-
-void __init __ipipe_enable_pipeline(void)
-{
- unsigned irq;
-
- /* Map the APIC system vectors. */
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(LOCAL_TIMER_VECTOR),
- (ipipe_irq_handler_t)&smp_apic_timer_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(SPURIOUS_APIC_VECTOR),
- (ipipe_irq_handler_t)&smp_spurious_interrupt,
- NULL,
- &__ipipe_noack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(ERROR_APIC_VECTOR),
- (ipipe_irq_handler_t)&smp_error_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR0),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR1),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR2),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(IPIPE_SERVICE_VECTOR3),
- &__ipipe_null_handler,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(THRESHOLD_APIC_VECTOR),
- (ipipe_irq_handler_t)&mce_threshold_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(THERMAL_APIC_VECTOR),
- (ipipe_irq_handler_t)&smp_thermal_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
-#ifdef CONFIG_SMP
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(RESCHEDULE_VECTOR),
- (ipipe_irq_handler_t)&smp_reschedule_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-
- {
- unsigned vector;
-
- for (vector = INVALIDATE_TLB_VECTOR_START;
- vector <= INVALIDATE_TLB_VECTOR_END; ++vector)
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(vector),
- (ipipe_irq_handler_t)&smp_invalidate_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
- }
-
- ipipe_virtualize_irq(ipipe_root_domain,
- ipipe_apic_vector_irq(CALL_FUNCTION_VECTOR),
- (ipipe_irq_handler_t)&smp_call_function_interrupt,
- NULL,
- &__ipipe_ack_apic,
- IPIPE_STDROOT_MASK);
-#endif /* CONFIG_SMP */
-
- /* Finally, virtualize the remaining ISA and IO-APIC
- * interrupts. Interrupts which have already been virtualized
- * will just beget a silent -EPERM error since
- * IPIPE_SYSTEM_MASK has been passed for them, that's ok. */
-
- for (irq = 0; irq < NR_IRQS; irq++)
- /* Fails for IPIPE_CRITICAL_IPI but that's ok. */
- ipipe_virtualize_irq(ipipe_root_domain,
- irq,
- (ipipe_irq_handler_t)&do_IRQ, /* Via thunk. */
- NULL,
- &__ipipe_ack_irq,
- IPIPE_STDROOT_MASK);
-
- /* Eventually allow these vectors to be reprogrammed. */
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI0].control &= ~IPIPE_SYSTEM_MASK;
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI1].control &= ~IPIPE_SYSTEM_MASK;
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI2].control &= ~IPIPE_SYSTEM_MASK;
- ipipe_root_domain->irqs[IPIPE_SERVICE_IPI3].control &= ~IPIPE_SYSTEM_MASK;
-}
-
-#ifdef CONFIG_SMP
-
-cpumask_t __ipipe_set_irq_affinity(unsigned irq, cpumask_t cpumask)
-
-{
- cpumask_t oldmask = irq_desc[irq].affinity;
-
- if (irq_desc[irq].chip->set_affinity == NULL)
- return CPU_MASK_NONE;
-
- if (cpus_empty(cpumask))
- return oldmask; /* Return mask value -- no change. */
-
- cpus_and(cpumask,cpumask,cpu_online_map);
-
- if (cpus_empty(cpumask))
- return CPU_MASK_NONE; /* Error -- bad mask value or non-routable IRQ. */
-
- irq_desc[irq].chip->set_affinity(irq,cpumask);
-
- return oldmask;
-}
-
-int asmlinkage __ipipe_send_ipi(unsigned ipi, cpumask_t cpumask)
-
-{
- unsigned long flags;
- int self;
-
- if (ipi != IPIPE_SERVICE_IPI0 &&
- ipi != IPIPE_SERVICE_IPI1 &&
- ipi != IPIPE_SERVICE_IPI2 &&
- ipi != IPIPE_SERVICE_IPI3)
- return -EINVAL;
-
- local_irq_save_hw(flags);
-
- self = cpu_isset(ipipe_processor_id(),cpumask);
- cpu_clear(ipipe_processor_id(), cpumask);
-
- if (!cpus_empty(cpumask))
- send_IPI_mask(cpumask, ipipe_apic_irq_vector(ipi));
-
- if (self)
- ipipe_trigger_irq(ipi);
-
- local_irq_restore_hw(flags);
-
- return 0;
-}
-
-/* Always called with hw interrupts off. */
-
-void __ipipe_do_critical_sync(unsigned irq, void *cookie)
-{
- int cpu = ipipe_processor_id();
-
- cpu_set(cpu, __ipipe_cpu_sync_map);
-
- /* Now we are in sync with the lock requestor running on another
- CPU. Enter a spinning wait until he releases the global
- lock. */
- spin_lock(&__ipipe_cpu_barrier);
-
- /* Got it. Now get out. */
-
- if (__ipipe_cpu_sync)
- /* Call the sync routine if any. */
- __ipipe_cpu_sync();
-
- spin_unlock(&__ipipe_cpu_barrier);
-
- cpu_clear(cpu, __ipipe_cpu_sync_map);
-}
-
-void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd)
-{
- ipd->irqs[IPIPE_CRITICAL_IPI].acknowledge = &__ipipe_ack_apic;
- ipd->irqs[IPIPE_CRITICAL_IPI].handler = &__ipipe_do_critical_sync;
- ipd->irqs[IPIPE_CRITICAL_IPI].cookie = NULL;
- /* Immediately handle in the current domain but *never* pass */
- ipd->irqs[IPIPE_CRITICAL_IPI].control =
- IPIPE_HANDLE_MASK|IPIPE_STICKY_MASK|IPIPE_SYSTEM_MASK;
-}
-
-#endif /* CONFIG_SMP */
-
-/* ipipe_critical_enter() -- Grab the superlock excluding all CPUs
- but the current one from a critical section. This lock is used when
- we must enforce a global critical section for a single CPU in a
- possibly SMP system whichever context the CPUs are running. */
-
-unsigned long ipipe_critical_enter(void (*syncfn) (void))
-{
- unsigned long flags;
-
- local_irq_save_hw(flags);
-
-#ifdef CONFIG_SMP
- if (unlikely(num_online_cpus() == 1)) /* We might be running a SMP-kernel on a UP box... */
- return flags;
-
- {
- int cpu = ipipe_processor_id();
- cpumask_t lock_map;
-
- if (!cpu_test_and_set(cpu, __ipipe_cpu_lock_map)) {
- while (cpu_test_and_set(BITS_PER_LONG - 1, __ipipe_cpu_lock_map)) {
- int n = 0;
- do {
- cpu_relax();
- } while (++n < cpu);
- }
-
- spin_lock(&__ipipe_cpu_barrier);
-
- __ipipe_cpu_sync = syncfn;
-
- /* Send the sync IPI to all processors but the current one. */
- send_IPI_allbutself(IPIPE_CRITICAL_VECTOR);
-
- cpus_andnot(lock_map, cpu_online_map, __ipipe_cpu_lock_map);
-
- while (!cpus_equal(__ipipe_cpu_sync_map, lock_map))
- cpu_relax();
- }
-
- atomic_inc(&__ipipe_critical_count);
- }
-#endif /* CONFIG_SMP */
-
- return flags;
-}
-
-/* ipipe_critical_exit() -- Release the superlock. */
-
-void ipipe_critical_exit(unsigned long flags)
-{
-#ifdef CONFIG_SMP
- if (num_online_cpus() == 1)
- goto out;
-
- if (atomic_dec_and_test(&__ipipe_critical_count)) {
- spin_unlock(&__ipipe_cpu_barrier);
-
- while (!cpus_empty(__ipipe_cpu_sync_map))
- cpu_relax();
-
- cpu_clear(ipipe_processor_id(), __ipipe_cpu_lock_map);
- cpu_clear(BITS_PER_LONG - 1, __ipipe_cpu_lock_map);
- }
-out:
-#endif /* CONFIG_SMP */
-
- local_irq_restore_hw(flags);
-}
-
-static inline void __fixup_if(struct pt_regs *regs)
-{
- if (!ipipe_root_domain_p)
- return;
-
- /* Have the saved hw state look like the domain stall bit. */
-
- if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- regs->eflags &= ~X86_EFLAGS_IF;
- else
- regs->eflags |= X86_EFLAGS_IF;
-}
-
-#ifdef CONFIG_PREEMPT
-
-/*
- * Check the stall bit of the root domain to make sure the existing
- * preemption opportunity upon in-kernel resumption could be
- * exploited. In case a rescheduling could take place, the root stage
- * is stalled before the hw interrupts are re-enabled. This routine
- * must be called with hw interrupts off.
- */
-asmlinkage int __ipipe_preempt_schedule_irq(void)
-{
- if (test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- /* Root stage is stalled: rescheduling denied. */
- return 0;
-
- __set_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
- local_irq_enable_hw();
- preempt_schedule_irq(); /* Ok, may reschedule now. */
- local_irq_disable_hw();
- __clear_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status));
-
- return 1;
-}
-
-#endif
-
-asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
-{
- unsigned long flags;
-
- __fixup_if(regs);
-
- /* This routine either returns:
- 0 -- if the syscall is to be passed to Linux;
- >0 -- if the syscall should not be passed to Linux, and no
- tail work should be performed;
- <0 -- if the syscall should not be passed to Linux but the
- tail work has to be performed (for handling signals etc). */
-
- if (__ipipe_syscall_watched_p(current, regs->orig_rax) &&
- __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
- __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) {
- /* We might enter here over a non-root domain and exit
- * over the root one as a result of the syscall
- * (i.e. by recycling the register set of the current
- * context across the migration), so we need to fixup
- * the interrupt flag upon return too, so that
- * __ipipe_unstall_iret_root() resets the correct
- * stall bit on exit. */
- __fixup_if(regs);
-
- if (ipipe_root_domain_p && !in_atomic()) {
- /* Sync pending VIRQs before _TIF_NEED_RESCHED is tested. */
- local_irq_save_hw(flags);
- if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
- __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
- local_irq_restore_hw(flags);
- return -1;
- }
- /*
- * We are about to run the atomic syscall epilogue;
- * switch interrupts off before branching to it.
- */
- local_irq_disable_hw();
- return 1;
- }
-
- return 0;
-}
-
-static asmlinkage void do_machine_check_vector(struct pt_regs *regs, long error_code)
-{
-#ifdef CONFIG_X86_MCE
- void do_machine_check(struct pt_regs * regs, long error_code);
- do_machine_check(regs,error_code);
-#endif /* CONFIG_X86_MCE */
-}
-
-asmlinkage void do_divide_error(struct pt_regs *regs, long error_code);
-asmlinkage void do_overflow(struct pt_regs *regs, long error_code);
-asmlinkage void do_bounds(struct pt_regs *regs, long error_code);
-asmlinkage void do_invalid_op(struct pt_regs *regs, long error_code);
-asmlinkage void math_state_restore(struct pt_regs *regs, long error_code);
-asmlinkage void do_coprocessor_segment_overrun(struct pt_regs *regs, long error_code);
-asmlinkage void do_invalid_TSS(struct pt_regs *regs, long error_code);
-asmlinkage void do_segment_not_present(struct pt_regs *regs, long error_code);
-asmlinkage void do_stack_segment(struct pt_regs *regs, long error_code);
-asmlinkage void do_general_protection(struct pt_regs *regs, long error_code);
-asmlinkage void do_page_fault(struct pt_regs *regs, long error_code);
-asmlinkage void do_spurious_interrupt_bug(struct pt_regs *regs, long error_code);
-asmlinkage void do_coprocessor_error(struct pt_regs *regs, long error_code);
-asmlinkage void do_alignment_check(struct pt_regs *regs, long error_code);
-asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs, long error_code);
-
-/* Work around genksyms's issue with over-qualification in decls. */
-
-typedef asmlinkage void __ipipe_exhandler(struct pt_regs *, long);
-
-typedef __ipipe_exhandler *__ipipe_exptr;
-
-static __ipipe_exptr __ipipe_std_extable[] = {
-
- [ex_divide_error] = &do_divide_error,
- [ex_overflow] = &do_overflow,
- [ex_bounds] = &do_bounds,
- [ex_invalid_op] = &do_invalid_op,
- [ex_math_state_restore] = &math_state_restore,
- [ex_coprocessor_segment_overrun] = &do_coprocessor_segment_overrun,
- [ex_invalid_TSS] = &do_invalid_TSS,
- [ex_segment_not_present] = &do_segment_not_present,
- [ex_stack_segment] = &do_stack_segment,
- [ex_general_protection] = do_general_protection,
- [ex_page_fault] = &do_page_fault,
- [ex_spurious_interrupt_bug] = &do_spurious_interrupt_bug,
- [ex_coprocessor_error] = &do_coprocessor_error,
- [ex_alignment_check] = &do_alignment_check,
- [ex_machine_check_vector] = &do_machine_check_vector,
- [ex_simd_coprocessor_error] = &do_simd_coprocessor_error,
-};
-
-#ifdef CONFIG_KGDB
-#include <linux/kgdb.h>
-
-static int __ipipe_xlate_signo[] = {
-
- [ex_divide_error] = SIGFPE,
- [ex_debug] = SIGTRAP,
- [2] = -1,
- [ex_int3] = SIGTRAP,
- [ex_overflow] = SIGSEGV,
- [ex_bounds] = SIGSEGV,
- [ex_invalid_op] = SIGILL,
- [ex_math_state_restore] = -1,
- [8] = -1,
- [ex_coprocessor_segment_overrun] = SIGFPE,
- [ex_invalid_TSS] = SIGSEGV,
- [ex_segment_not_present] = SIGBUS,
- [ex_stack_segment] = SIGBUS,
- [ex_general_protection] = SIGSEGV,
- [ex_page_fault] = SIGSEGV,
- [ex_spurious_interrupt_bug] = -1,
- [ex_coprocessor_error] = -1,
- [ex_alignment_check] = SIGBUS,
- [ex_machine_check_vector] = -1,
- [ex_simd_coprocessor_error] = -1,
- [20 ... 31] = -1,
-};
-#endif /* CONFIG_KGDB */
-
-asmlinkage int __ipipe_handle_exception(struct pt_regs *regs, long error_code, int vector)
-{
- unsigned long flags;
-
- local_save_flags(flags);
-
- /* Track the hw interrupt state before calling the Linux
- * exception handler, replicating it into the virtual mask. */
-
- if (irqs_disabled_hw()) {
- /* Do not trigger the alarm in ipipe_check_context() by using
- * plain local_irq_disable(). */
- __ipipe_stall_root();
- trace_hardirqs_off();
- barrier();
- }
-
-#ifdef CONFIG_KGDB
- /* catch exception KGDB is interested in over non-root domains */
- if (ipipe_current_domain != ipipe_root_domain &&
- __ipipe_xlate_signo[vector] >= 0 &&
- !kgdb_handle_exception(vector, __ipipe_xlate_signo[vector], error_code, regs)) {
- local_irq_restore(flags);
- return 1;
- }
-#endif /* CONFIG_KGDB */
-
- if (unlikely(ipipe_trap_notify(vector, regs))) {
- local_irq_restore(flags);
- return 1;
- }
-
- /* Detect unhandled faults over non-root domains. */
-
- if (unlikely(!ipipe_root_domain_p)) {
- struct ipipe_domain *ipd = ipipe_current_domain;
-
- /* Switch to root so that Linux can handle the fault cleanly. */
- ipipe_current_domain = ipipe_root_domain;
-
- ipipe_trace_panic_freeze();
-
- /* Always warn about user land and unfixable faults. */
- if ((error_code & 4) || !search_exception_tables(regs->rip))
- printk(KERN_ERR "BUG: Unhandled exception over domain"
- " %s at 0x%lx - switching to ROOT\n",
- ipd->name, regs->rip);
-#ifdef CONFIG_IPIPE_DEBUG
- /* Also report fixable ones when debugging is enabled. */
- else
- printk(KERN_WARNING "WARNING: Fixable exception over "
- "domain %s at 0x%lx - switching to ROOT\n",
- ipd->name, regs->rip);
-#endif /* CONFIG_IPIPE_DEBUG */
-
- dump_stack();
- }
-
- __ipipe_std_extable[vector](regs, error_code);
- local_irq_restore(flags);
- __fixup_if(regs);
-
- return 0;
-}
-
-asmlinkage int __ipipe_divert_exception(struct pt_regs *regs, int vector)
-{
-#ifdef CONFIG_KGDB
- /* catch int1 and int3 over non-root domains */
- if (ipipe_current_domain != ipipe_root_domain) {
- unsigned int condition = 0;
-
- if (vector == 1)
- get_debugreg(condition, 6);
- if (!kgdb_handle_exception(vector, SIGTRAP, condition, regs))
- return 1;
- }
-#endif /* CONFIG_KGDB */
-
- if (ipipe_trap_notify(vector, regs))
- return 1;
-
- __fixup_if(regs);
-
- return 0;
-}
-
-/* __ipipe_handle_irq() -- IPIPE's generic IRQ handler. An optimistic
- interrupt protection log is maintained here for each domain. Hw
- interrupts are off on entry. */
-
-int __ipipe_handle_irq(struct pt_regs *regs)
-{
- struct ipipe_domain *this_domain, *next_domain;
- unsigned vector = regs->orig_rax, irq;
- struct list_head *head, *pos;
- int m_ack;
-
- if ((long)regs->orig_rax < 0) {
- vector = ~vector;
- if (vector >= FIRST_SYSTEM_VECTOR)
- irq = ipipe_apic_vector_irq(vector);
- else
- irq = __get_cpu_var(vector_irq)[vector];
- m_ack = 0;
- } else { /* This is a self-triggered one. */
- irq = vector;
- m_ack = 1;
- }
-
- head = __ipipe_pipeline.next;
- next_domain = list_entry(head, struct ipipe_domain, p_link);
- if (likely(test_bit(IPIPE_WIRED_FLAG, &next_domain->irqs[irq].control))) {
- if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
- next_domain->irqs[irq].acknowledge(irq);
- if (likely(__ipipe_dispatch_wired(next_domain, irq))) {
- goto finalize;
- } else
- goto finalize_nosync;
- }
-
- this_domain = ipipe_current_domain;
-
- if (test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))
- head = &this_domain->p_link;
-
- /* Ack the interrupt. */
-
- pos = head;
-
- while (pos != &__ipipe_pipeline) {
- next_domain = list_entry(pos, struct ipipe_domain, p_link);
-
- /*
- * For each domain handling the incoming IRQ, mark it
- * as pending in its log.
- */
- if (test_bit(IPIPE_HANDLE_FLAG, &next_domain->irqs[irq].control)) {
- /*
- * Domains that handle this IRQ are polled for
- * acknowledging it by decreasing priority
- * order. The interrupt must be made pending
- * _first_ in the domain's status flags before
- * the PIC is unlocked.
- */
- __ipipe_set_irq_pending(next_domain, irq);
-
- if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
- m_ack = next_domain->irqs[irq].acknowledge(irq);
- }
-
- /*
- * If the domain does not want the IRQ to be passed
- * down the interrupt pipe, exit the loop now.
- */
-
- if (!test_bit(IPIPE_PASS_FLAG, &next_domain->irqs[irq].control))
- break;
-
- pos = next_domain->p_link.next;
- }
-
-finalize:
-
- if (irq == __ipipe_tick_irq) {
- struct pt_regs *tick_regs = &__raw_get_cpu_var(__ipipe_tick_regs);
- tick_regs->ss = regs->ss;
- tick_regs->rsp = regs->rsp;
- tick_regs->eflags = regs->eflags;
- tick_regs->cs = regs->cs;
- tick_regs->rip = regs->rip;
- tick_regs->rbp = regs->rbp;
- }
-
- /*
- * Now walk the pipeline, yielding control to the highest
- * priority domain that has pending interrupt(s) or
- * immediately to the current domain if the interrupt has been
- * marked as 'sticky'. This search does not go beyond the
- * current domain in the pipeline.
- */
-
- __ipipe_walk_pipeline(head);
-
-finalize_nosync:
-
- if (!ipipe_root_domain_p ||
- test_bit(IPIPE_STALL_FLAG, &ipipe_root_cpudom_var(status)))
- return 0;
-
- return 1;
-}
-
-int __ipipe_check_tickdev(const char *devname)
-{
- if (!strcmp(devname, "lapic"))
- return __ipipe_check_lapic();
-
- return 1;
-}
-
-EXPORT_SYMBOL(__ipipe_tick_irq);
-EXPORT_SYMBOL(ipipe_critical_enter);
-EXPORT_SYMBOL(ipipe_critical_exit);
-EXPORT_SYMBOL(ipipe_trigger_irq);
-EXPORT_SYMBOL(ipipe_get_sysinfo);
-
-EXPORT_SYMBOL_GPL(irq_desc);
-struct task_struct *__switch_to(struct task_struct *prev_p,
- struct task_struct *next_p);
-EXPORT_SYMBOL_GPL(__switch_to);
-EXPORT_SYMBOL_GPL(show_stack);
-EXPORT_SYMBOL_GPL(cpu_gdt_descr);
-
-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
-EXPORT_SYMBOL(tasklist_lock);
-#endif /* CONFIG_SMP || CONFIG_DEBUG_SPINLOCK */
-
-#ifdef CONFIG_IPIPE_TRACE_MCOUNT
-void notrace mcount(void);
-EXPORT_SYMBOL(mcount);
-#endif /* CONFIG_IPIPE_TRACE_MCOUNT */
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/ipipe.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe.h
@@ -1,11 +1,125 @@
-#if defined(CONFIG_IPIPE) && !defined(IPIPE_ARCH_STRING)
+/* -*- linux-c -*-
+ * include/asm-x86/ipipe.h
+ *
+ * Copyright (C) 2007 Philippe Gerum.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
+ * USA; either version 2 of the License, or (at your option) any later
+ * version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __X86_IPIPE_H
+#define __X86_IPIPE_H
+
+#ifdef CONFIG_IPIPE
+
+#ifndef IPIPE_ARCH_STRING
#define IPIPE_ARCH_STRING "2.0-00"
#define IPIPE_MAJOR_NUMBER 2
#define IPIPE_MINOR_NUMBER 0
#define IPIPE_PATCH_NUMBER 0
#endif
+
+DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
+
#ifdef CONFIG_X86_32
# include "ipipe_32.h"
#else
# include "ipipe_64.h"
#endif
+
+/*
+ * The logical processor id is read from the PDA, so this is always
+ * safe, regardless of the underlying stack.
+ */
+#define ipipe_processor_id() raw_smp_processor_id()
+
+#define prepare_arch_switch(next) \
+do { \
+ ipipe_schedule_notify(current, next); \
+ local_irq_disable_hw(); \
+} while(0)
+
+#define task_hijacked(p) \
+ ({ int x = !ipipe_root_domain_p; \
+ __clear_bit(IPIPE_SYNC_FLAG, &ipipe_root_cpudom_var(status)); \
+ local_irq_enable_hw(); x; })
+
+struct ipipe_domain;
+
+struct ipipe_sysinfo {
+
+ int ncpus; /* Number of CPUs on board */
+ u64 cpufreq; /* CPU frequency (in Hz) */
+
+ /* Arch-dependent block */
+
+ struct {
+ unsigned tmirq; /* Timer tick IRQ */
+ u64 tmfreq; /* Timer frequency */
+ } archdep;
+};
+
+/* Private interface -- Internal use only */
+
+#define __ipipe_check_platform() do { } while(0)
+#define __ipipe_init_platform() do { } while(0)
+#define __ipipe_enable_irq(irq) irq_desc[irq].chip->enable(irq)
+#define __ipipe_disable_irq(irq) irq_desc[irq].chip->disable(irq)
+
+#ifdef CONFIG_SMP
+void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd);
+#else
+#define __ipipe_hook_critical_ipi(ipd) do { } while(0)
+#endif
+
+#define __ipipe_disable_irqdesc(ipd, irq) do { } while(0)
+
+void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq);
+
+void __ipipe_enable_pipeline(void);
+
+void __ipipe_do_critical_sync(unsigned irq, void *cookie);
+
+extern int __ipipe_tick_irq;
+
+#ifdef CONFIG_X86_LOCAL_APIC
+#define ipipe_update_tick_evtdev(evtdev) \
+ do { \
+ if (strcmp((evtdev)->name, "lapic") == 0) \
+ __ipipe_tick_irq = \
+ ipipe_apic_vector_irq(LOCAL_TIMER_VECTOR); \
+ else \
+ __ipipe_tick_irq = TIMER_IRQ; \
+ } while (0)
+#else
+#define ipipe_update_tick_evtdev(evtdev) \
+ __ipipe_tick_irq = TIMER_IRQ
+#endif
+
+int __ipipe_check_lapic(void);
+
+int __ipipe_check_tickdev(const char *devname);
+
+#define __ipipe_syscall_watched_p(p, sc) \
+ (((p)->flags & PF_EVNOTIFY) || (unsigned long)sc >= NR_syscalls)
+
+#else /* !CONFIG_IPIPE */
+
+#define ipipe_update_tick_evtdev(evtdev) do { } while (0)
+#define task_hijacked(p) 0
+
+#endif /* CONFIG_IPIPE */
+
+#endif /* !__X86_IPIPE_H */
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_32.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/ipipe_32.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_32.h
@@ -22,44 +22,12 @@
#ifndef __X86_IPIPE_32_H
#define __X86_IPIPE_32_H
-#ifdef CONFIG_IPIPE
-
-#ifndef __ASSEMBLY__
-
#include <linux/cpumask.h>
#include <linux/list.h>
#include <linux/threads.h>
#include <linux/ipipe_percpu.h>
#include <asm/ptrace.h>
-#define ipipe_processor_id() raw_smp_processor_id()
-
-#define prepare_arch_switch(next) \
-do { \
- ipipe_schedule_notify(current, next); \
- local_irq_disable_hw(); \
-} while(0)
-
-#define task_hijacked(p) \
- ({ int x = !ipipe_root_domain_p; \
- __clear_bit(IPIPE_SYNC_FLAG, &ipipe_root_cpudom_var(status)); \
- local_irq_enable_hw(); x; })
-
-struct ipipe_domain;
-
-struct ipipe_sysinfo {
-
- int ncpus; /* Number of CPUs on board */
- u64 cpufreq; /* CPU frequency (in Hz) */
-
- /* Arch-dependent block */
-
- struct {
- unsigned tmirq; /* Timer tick IRQ */
- u64 tmfreq; /* Timer frequency */
- } archdep;
-};
-
#define ipipe_read_tsc(t) __asm__ __volatile__("rdtsc" : "=A" (t))
#define ipipe_cpu_freq() ({ unsigned long long __freq = cpu_has_tsc?(1000LL * cpu_khz):CLOCK_TICK_RATE; __freq; })
@@ -79,29 +47,8 @@ struct ipipe_sysinfo {
/* Private interface -- Internal use only */
-#define __ipipe_check_platform() do { } while(0)
-#define __ipipe_init_platform() do { } while(0)
-#define __ipipe_enable_irq(irq) irq_desc[irq].chip->enable(irq)
-#define __ipipe_disable_irq(irq) irq_desc[irq].chip->disable(irq)
-
-#ifdef CONFIG_SMP
-void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd);
-#else
-#define __ipipe_hook_critical_ipi(ipd) do { } while(0)
-#endif
-
-#define __ipipe_disable_irqdesc(ipd, irq) do { } while(0)
-
-void __ipipe_enable_irqdesc(struct ipipe_domain *ipd, unsigned irq);
-
-void __ipipe_enable_pipeline(void);
-
int __ipipe_handle_irq(struct pt_regs regs);
-void __ipipe_do_critical_sync(unsigned irq, void *cookie);
-
-extern int __ipipe_tick_irq;
-
static inline unsigned long __ipipe_ffnz(unsigned long ul)
{
__asm__("bsrl %1, %0":"=r"(ul)
@@ -109,22 +56,6 @@ static inline unsigned long __ipipe_ffnz
return ul;
}
-#ifdef CONFIG_X86_LOCAL_APIC
-#define ipipe_update_tick_evtdev(evtdev) \
- do { \
- if (strcmp((evtdev)->name, "lapic") == 0) \
- __ipipe_tick_irq = \
- ipipe_apic_vector_irq(LOCAL_TIMER_VECTOR); \
- else \
- __ipipe_tick_irq = TIMER_IRQ; \
- } while (0)
-#else
-#define ipipe_update_tick_evtdev(evtdev) \
- __ipipe_tick_irq = TIMER_IRQ
-#endif
-
-DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
-
static inline void __ipipe_call_root_xirq_handler(unsigned irq,
void (*handler)(unsigned, void *))
{
@@ -210,20 +141,4 @@ do { \
local_irq_disable_nohead(ipd); \
} while(0)
-#endif /* __ASSEMBLY__ */
-
-#define __ipipe_syscall_watched_p(p, sc) \
- (((p)->flags & PF_EVNOTIFY) || (unsigned long)sc >= NR_syscalls)
-
-int __ipipe_check_lapic(void);
-
-int __ipipe_check_tickdev(const char *devname);
-
-#else /* !CONFIG_IPIPE */
-
-#define ipipe_update_tick_evtdev(evtdev) do { } while (0)
-#define task_hijacked(p) 0
-
-#endif /* CONFIG_IPIPE */
-
#endif /* !__X86_IPIPE_32_H */
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_64.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/ipipe_64.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/ipipe_64.h
@@ -22,10 +22,6 @@
#ifndef __X86_IPIPE_64_H
#define __X86_IPIPE_64_H
-#ifdef CONFIG_IPIPE
-
-#ifndef __ASSEMBLY__
-
#include <asm/ptrace.h>
#include <asm/irq.h>
#include <linux/cpumask.h>
@@ -36,38 +32,6 @@
#include <linux/thread_info.h>
#endif
-/*
- * The logical processor id is read from the PDA, so this is always
- * safe, regardless of the underlying stack.
- */
-#define ipipe_processor_id() raw_smp_processor_id()
-
-#define prepare_arch_switch(next) \
-do { \
- ipipe_schedule_notify(current, next); \
- local_irq_disable_hw(); \
-} while(0)
-
-#define task_hijacked(p) \
- ({ int x = !ipipe_root_domain_p; \
- __clear_bit(IPIPE_SYNC_FLAG, &ipipe_root_cpudom_var(status)); \
- local_irq_enable_hw(); x; })
-
-struct ipipe_domain;
-
-struct ipipe_sysinfo {
-
- int ncpus; /* Number of CPUs on board */
- u64 cpufreq; /* CPU frequency (in Hz) */
-
- /* Arch-dependent block */
-
- struct {
- unsigned tmirq; /* Timer tick IRQ */
- u64 tmfreq; /* Timer frequency */
- } archdep;
-};
-
#define ipipe_read_tsc(t) do { \
unsigned int __a,__d; \
asm volatile("rdtsc" : "=a" (__a), "=d" (__d)); \
@@ -81,34 +45,10 @@ extern unsigned cpu_khz;
/* Private interface -- Internal use only */
-#define __ipipe_check_platform() do { } while(0)
-#define __ipipe_init_platform() do { } while(0)
-#define __ipipe_enable_irq(irq) irq_desc[irq].chip->enable(irq)
-#define __ipipe_disable_irq(irq) irq_desc[irq].chip->disable(irq)
-
-#ifdef CONFIG_SMP
-void __ipipe_hook_critical_ipi(struct ipipe_domain *ipd);
-#else
-#define __ipipe_hook_critical_ipi(ipd) do { } while(0)
-#endif
-
-#define __ipipe_disable_irqdesc(ipd, irq) do { } while(0)
-
-void __ipipe_enable_irqdesc(struct ipipe_domain *ipd,
- unsigned irq);
-
-void __ipipe_enable_pipeline(void);
-
int __ipipe_handle_irq(struct pt_regs *regs);
-void __ipipe_do_critical_sync(unsigned irq, void *cookie);
-
void __ipipe_serial_debug(const char *fmt, ...);
-extern int __ipipe_tick_irq;
-
-DECLARE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
-
unsigned __ipipe_get_irq_vector(int irq);
static inline unsigned long __ipipe_ffnz(unsigned long ul)
@@ -118,15 +58,6 @@ static inline unsigned long __ipipe_ffnz
return ul;
}
-#define ipipe_update_tick_evtdev(evtdev) \
- do { \
- if (strcmp((evtdev)->name, "lapic") == 0) \
- __ipipe_tick_irq = \
- ipipe_apic_vector_irq(LOCAL_TIMER_VECTOR); \
- else \
- __ipipe_tick_irq = TIMER_IRQ; \
- } while (0)
-
struct irq_desc;
void __ipipe_ack_edge_irq(unsigned irq, struct irq_desc *desc);
@@ -227,20 +158,4 @@ static inline void __ipipe_call_root_vir
local_irq_disable_nohead(ipd); \
} while(0)
-#endif /* __ASSEMBLY__ */
-
-#define __ipipe_syscall_watched_p(p, sc) \
- (((p)->flags & PF_EVNOTIFY) || (unsigned long)sc >= __NR_syscalls)
-
-int __ipipe_check_lapic(void);
-
-int __ipipe_check_tickdev(const char *devname);
-
-#else /* !CONFIG_IPIPE */
-
-#define ipipe_update_tick_evtdev(evtdev) do { } while (0)
-#define task_hijacked(p) 0
-
-#endif /* CONFIG_IPIPE */
-
#endif /* !__X86_IPIPE_64_H */
Index: linux-2.6.24-rc6-xeno_64/include/asm-x86/unistd_64.h
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/include/asm-x86/unistd_64.h
+++ linux-2.6.24-rc6-xeno_64/include/asm-x86/unistd_64.h
@@ -636,7 +636,7 @@ __SYSCALL(__NR_eventfd, sys_eventfd)
#define __NR_fallocate 285
__SYSCALL(__NR_fallocate, sys_fallocate)
-#define __NR_syscalls 286
+#define NR_syscalls 286
#ifndef __NO_STUBS
#define __ARCH_WANT_OLD_READDIR
Index: linux-2.6.24-rc6-xeno_64/arch/x86/kernel/entry_64.S
===================================================================
--- linux-2.6.24-rc6-xeno_64.orig/arch/x86/kernel/entry_64.S
+++ linux-2.6.24-rc6-xeno_64/arch/x86/kernel/entry_64.S
@@ -1161,15 +1161,15 @@ ENTRY(kernel_execve)
ENDPROC(kernel_execve)
KPROBE_ENTRY(page_fault)
- errorentry do_page_fault ex_page_fault
+ errorentry do_page_fault ex_do_page_fault
KPROBE_END(page_fault)
ENTRY(coprocessor_error)
- zeroentry do_coprocessor_error ex_coprocessor_error
+ zeroentry do_coprocessor_error ex_do_coprocessor_error
END(coprocessor_error)
ENTRY(simd_coprocessor_error)
- zeroentry do_simd_coprocessor_error ex_simd_coprocessor_error
+ zeroentry do_simd_coprocessor_error ex_do_simd_coprocessor_error
END(simd_coprocessor_error)
ENTRY(device_not_available)
@@ -1181,7 +1181,7 @@ KPROBE_ENTRY(debug)
INTR_FRAME
pushq $0
CFI_ADJUST_CFA_OFFSET 8
- paranoidentry do_debug, DEBUG_STACK, 1, ex_debug
+ paranoidentry do_debug, DEBUG_STACK, 1, ex_do_debug
paranoidexit
KPROBE_END(debug)
@@ -1203,25 +1203,25 @@ KPROBE_ENTRY(int3)
INTR_FRAME
pushq $0
CFI_ADJUST_CFA_OFFSET 8
- paranoidentry do_int3, DEBUG_STACK, 1, ex_int3
+ paranoidentry do_int3, DEBUG_STACK, 1, ex_do_int3
jmp paranoid_exit1
CFI_ENDPROC
KPROBE_END(int3)
ENTRY(overflow)
- zeroentry do_overflow ex_overflow
+ zeroentry do_overflow ex_do_overflow
END(overflow)
ENTRY(bounds)
- zeroentry do_bounds ex_bounds
+ zeroentry do_bounds ex_do_bounds
END(bounds)
ENTRY(invalid_op)
- zeroentry do_invalid_op ex_invalid_op
+ zeroentry do_invalid_op ex_do_invalid_op
END(invalid_op)
ENTRY(coprocessor_segment_overrun)
- zeroentry do_coprocessor_segment_overrun ex_coprocessor_segment_overrun
+ zeroentry do_coprocessor_segment_overrun ex_do_coprocessor_segment_overrun
END(coprocessor_segment_overrun)
ENTRY(reserved)
@@ -1237,11 +1237,11 @@ ENTRY(double_fault)
END(double_fault)
ENTRY(invalid_TSS)
- errorentry do_invalid_TSS ex_invalid_TSS
+ errorentry do_invalid_TSS ex_do_invalid_TSS
END(invalid_TSS)
ENTRY(segment_not_present)
- errorentry do_segment_not_present ex_segment_not_present
+ errorentry do_segment_not_present ex_do_segment_not_present
END(segment_not_present)
/* runs on exception stack */
@@ -1253,19 +1253,19 @@ ENTRY(stack_segment)
END(stack_segment)
KPROBE_ENTRY(general_protection)
- errorentry do_general_protection ex_general_protection
+ errorentry do_general_protection ex_do_general_protection
KPROBE_END(general_protection)
ENTRY(alignment_check)
- errorentry do_alignment_check ex_alignment_check
+ errorentry do_alignment_check ex_do_alignment_check
END(alignment_check)
ENTRY(divide_error)
- zeroentry do_divide_error ex_divide_error
+ zeroentry do_divide_error ex_do_divide_error
END(divide_error)
ENTRY(spurious_interrupt_bug)
- zeroentry do_spurious_interrupt_bug ex_spurious_interrupt_bug
+ zeroentry do_spurious_interrupt_bug ex_do_spurious_interrupt_bug
END(spurious_interrupt_bug)
#ifdef CONFIG_X86_MCE
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2007-12-30 11:01 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-29 23:13 [Adeos-main] [PATCH 5/5] consolidate common 32/64-bit code Jan Kiszka
2007-12-30 11:01 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.