Commit 8c3bb4a5 authored by Philippe Gerum's avatar Philippe Gerum
Browse files

cobalt/powerpc: upgrade I-pipe support

parent 31c62a9e
......@@ -239,7 +239,7 @@ index ba713f1..ed1b099 100644
* or should we not care like we do now ? --BenH.
diff --git a/arch/powerpc/include/asm/ipipe.h b/arch/powerpc/include/asm/ipipe.h
new file mode 100644
index 0000000..4806477
index 0000000..2b71932
--- /dev/null
+++ b/arch/powerpc/include/asm/ipipe.h
@@ -0,0 +1,164 @@
......@@ -284,7 +284,7 @@ index 0000000..4806477
+#include <linux/cache.h>
+#include <linux/threads.h>
+
+#define IPIPE_CORE_RELEASE 6
+#define IPIPE_CORE_RELEASE 7
+
+struct ipipe_domain;
+
......@@ -1150,7 +1150,7 @@ index ba7b197..0246507 100644
_TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT | \
_TIF_NOHZ)
diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h
index 4db4959..9d4627a 100644
index 4db49590..9d4627a 100644
--- a/arch/powerpc/include/asm/uaccess.h
+++ b/arch/powerpc/include/asm/uaccess.h
@@ -117,6 +117,21 @@ struct exception_table_entry {
......@@ -1776,7 +1776,7 @@ index 8a9b6f5..9b6d8e2 100644
/* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
FITException:
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index 97e2671..c0e0e62 100644
index 97e2671..207bca1 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -262,8 +262,13 @@ interrupt_base:
......@@ -1785,7 +1785,7 @@ index 97e2671..c0e0e62 100644
/* External Input Interrupt */
+#ifdef CONFIG_IPIPE
+ EXCEPTION(0x0500, BOOKE_INTERRUPT_EXTERNAL, ExternalInput, \
+ __ipipe_grab_irq, EXC_XFER_LITE)
+ __ipipe_grab_irq, EXC_XFER_IPIPE)
+#else /* !CONFIG_IPIPE */
EXCEPTION(0x0500, BOOKE_INTERRUPT_EXTERNAL, ExternalInput, \
do_IRQ, EXC_XFER_LITE)
......@@ -1979,10 +1979,10 @@ index 939ea7e..75479f9 100644
* Go into low thread priority and possibly
diff --git a/arch/powerpc/kernel/ipipe.c b/arch/powerpc/kernel/ipipe.c
new file mode 100644
index 0000000..1d08533
index 0000000..0e30a84
--- /dev/null
+++ b/arch/powerpc/kernel/ipipe.c
@@ -0,0 +1,471 @@
@@ -0,0 +1,466 @@
+/* -*- linux-c -*-
+ * linux/arch/powerpc/kernel/ipipe.c
+ *
......@@ -2423,11 +2423,6 @@ index 0000000..1d08533
+ return -ret;
+}
+
+void __ipipe_pin_range_globally(unsigned long start, unsigned long end)
+{
+ /* We don't support this. */
+}
+
+#ifndef CONFIG_SMP
+EXPORT_SYMBOL_GPL(last_task_used_math);
+#endif
......@@ -5300,10 +5295,10 @@ index e6bb36a..898a91a 100644
diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
new file mode 100644
index 0000000..525f3cf
index 0000000..4ef7e3d
--- /dev/null
+++ b/include/linux/ipipe.h
@@ -0,0 +1,443 @@
@@ -0,0 +1,449 @@
+/* -*- linux-c -*-
+ * include/linux/ipipe.h
+ *
......@@ -5710,6 +5705,12 @@ index 0000000..525f3cf
+#define __ipipe_uaccess_might_fault() might_fault()
+#endif
+
+#ifdef CONFIG_IPIPE_TRACE
+void __ipipe_tracer_hrclock_initialized(void);
+#else /* !CONFIG_IPIPE_TRACE */
+#define __ipipe_tracer_hrclock_initialized() do { } while(0)
+#endif /* !CONFIG_IPIPE_TRACE */
+
+#include <linux/ipipe_compat.h>
+
+#else /* !CONFIG_IPIPE */
......@@ -5749,10 +5750,10 @@ index 0000000..525f3cf
+#endif /* !__LINUX_IPIPE_H */
diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
new file mode 100644
index 0000000..fc88b2e
index 0000000..c8fed98
--- /dev/null
+++ b/include/linux/ipipe_base.h
@@ -0,0 +1,392 @@
@@ -0,0 +1,394 @@
+/* -*- linux-c -*-
+ * include/linux/ipipe_base.h
+ *
......@@ -5935,9 +5936,6 @@ index 0000000..fc88b2e
+
+void __ipipe_flush_printk(unsigned int irq, void *cookie);
+
+void __ipipe_pin_range_globally(unsigned long start,
+ unsigned long end);
+
+#define hard_preempt_disable() \
+ ({ \
+ unsigned long __flags__; \
......@@ -6105,10 +6103,6 @@ index 0000000..fc88b2e
+
+static inline void __ipipe_clear_taskflags(struct task_struct *p) { }
+
+static inline void __ipipe_pin_range_globally(unsigned long start,
+ unsigned long end)
+{ }
+
+#define hard_preempt_disable() ({ preempt_disable(); 0; })
+#define hard_preempt_enable(flags) ({ preempt_enable(); (void)(flags); })
+
......@@ -6135,6 +6129,15 @@ index 0000000..fc88b2e
+
+#endif /* !CONFIG_IPIPE */
+
+#ifdef CONFIG_IPIPE_WANT_PTE_PINNING
+void __ipipe_pin_mapping_globally(unsigned long start,
+ unsigned long end);
+#else
+static inline void __ipipe_pin_mapping_globally(unsigned long start,
+ unsigned long end)
+{ }
+#endif
+
+static inline void ipipe_preempt_root_only(void)
+{
+#if defined(CONFIG_IPIPE_DEBUG_CONTEXT) && \
......@@ -8286,10 +8289,10 @@ index ff7be9d..1e80528 100644
trace_task_newtask(p, clone_flags);
diff --git a/kernel/ipipe/Kconfig b/kernel/ipipe/Kconfig
new file mode 100644
index 0000000..da17b04
index 0000000..218f51da
--- /dev/null
+++ b/kernel/ipipe/Kconfig
@@ -0,0 +1,62 @@
@@ -0,0 +1,65 @@
+config IPIPE
+ bool "Interrupt pipeline"
+ default y
......@@ -8310,6 +8313,9 @@ index 0000000..da17b04
+config IPIPE_WANT_CLOCKSOURCE
+ bool
+
+config IPIPE_WANT_PTE_PINNING
+ bool
+
+config IPIPE_CORE_APIREV
+ int
+ depends on IPIPE
......@@ -11085,10 +11091,10 @@ index 0000000..0c9b908
+#endif /* CONFIG_IPIPE_HAVE_HOSTRT */
diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
new file mode 100644
index 0000000..5cce0bc
index 0000000..8388671
--- /dev/null
+++ b/kernel/ipipe/tracer.c
@@ -0,0 +1,1447 @@
@@ -0,0 +1,1468 @@
+/* -*- linux-c -*-
+ * kernel/ipipe/tracer.c
+ *
......@@ -11836,6 +11842,9 @@ index 0000000..5cce0bc
+ unsigned long long abs_tsc;
+ long us;
+
+ if (!__ipipe_hrclock_ok())
+ return 0;
+
+ /* ipipe_tsc2us works on unsigned => handle sign separately */
+ abs_tsc = (tsc >= 0) ? tsc : -tsc;
+ us = ipipe_tsc2us(abs_tsc);
......@@ -12038,6 +12047,11 @@ index 0000000..5cce0bc
+
+ __ipipe_global_path_unlock(flags);
+
+ if (!__ipipe_hrclock_ok()) {
+ seq_printf(m, "No hrclock available, dumping traces disabled\n");
+ return NULL;
+ }
+
+ /* does this path actually contain data? */
+ if (print_path->end == print_path->begin)
+ return NULL;
......@@ -12208,6 +12222,11 @@ index 0000000..5cce0bc
+ if (!print_path)
+ return NULL;
+
+ if (!__ipipe_hrclock_ok()) {
+ seq_printf(m, "No hrclock available, dumping traces disabled\n");
+ return NULL;
+ }
+
+ /* back- and post-tracing length, post-trace length was frozen
+ in __ipipe_trace, back-trace may have to be reduced due to
+ buffer overrun */
......@@ -12457,18 +12476,38 @@ index 0000000..5cce0bc
+
+extern struct proc_dir_entry *ipipe_proc_root;
+
+void __init __ipipe_init_tracer(void)
+void __init __ipipe_tracer_hrclock_initialized(void)
+{
+ struct proc_dir_entry *trace_dir;
+ unsigned long long start, end, min = ULLONG_MAX;
+ int i;
+
+#ifdef CONFIG_IPIPE_TRACE_VMALLOC
+ if (!per_cpu(trace_path, 0))
+ return;
+#endif
+ /* Calculate minimum overhead of __ipipe_trace() */
+ hard_local_irq_disable();
+ for (i = 0; i < 100; i++) {
+ ipipe_read_tsc(start);
+ __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
+ __BUILTIN_RETURN_ADDRESS1, 0);
+ ipipe_read_tsc(end);
+
+ end -= start;
+ if (end < min)
+ min = end;
+ }
+ hard_local_irq_enable();
+ trace_overhead = ipipe_tsc2ns(min);
+}
+
+void __init __ipipe_init_tracer(void)
+{
+ struct proc_dir_entry *trace_dir;
+#ifdef CONFIG_IPIPE_TRACE_VMALLOC
+ int cpu, path;
+#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
+
+ if (!__ipipe_hrclock_ok())
+ return;
+
+#ifdef CONFIG_IPIPE_TRACE_VMALLOC
+ for_each_possible_cpu(cpu) {
+ struct ipipe_trace_path *tp_buf;
......@@ -12490,20 +12529,8 @@ index 0000000..5cce0bc
+ }
+#endif /* CONFIG_IPIPE_TRACE_VMALLOC */
+
+ /* Calculate minimum overhead of __ipipe_trace() */
+ hard_local_irq_disable();
+ for (i = 0; i < 100; i++) {
+ ipipe_read_tsc(start);
+ __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
+ __BUILTIN_RETURN_ADDRESS1, 0);
+ ipipe_read_tsc(end);
+
+ end -= start;
+ if (end < min)
+ min = end;
+ }
+ hard_local_irq_enable();
+ trace_overhead = ipipe_tsc2ns(min);
+ if (__ipipe_hrclock_ok() && !trace_overhead)
+ __ipipe_tracer_hrclock_initialized();
+
+#ifdef CONFIG_IPIPE_TRACE_ENABLE
+ ipipe_trace_enable = 1;
......@@ -12537,7 +12564,7 @@ index 0000000..5cce0bc
+#endif /* !CONFIG_IPIPE_TRACE_MCOUNT */
+}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index cbd97ce..0faa00b 100644
index cbd97ce..16ab280e 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -15,6 +15,7 @@
......@@ -12586,7 +12613,7 @@ index cbd97ce..0faa00b 100644
desc->irq_data.chip->irq_shutdown(&desc->irq_data);
- else if (desc->irq_data.chip->irq_disable)
+#ifdef CONFIG_IPIPE
+ desc->istate |= ~IPIPE_IRQS_NEEDS_STARTUP;
+ desc->istate |= IPIPE_IRQS_NEEDS_STARTUP;
+#endif
+ } else if (desc->irq_data.chip->irq_disable)
desc->irq_data.chip->irq_disable(&desc->irq_data);
......@@ -13158,7 +13185,7 @@ index 1f3186b..5b710c8 100644
if (curr->softirqs_enabled) {
diff --git a/kernel/panic.c b/kernel/panic.c
index 167ec09..cd078a7 100644
index 167ec097..cd078a7 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -22,6 +22,7 @@
......@@ -14296,7 +14323,7 @@ index f8e0e53..02175aa3 100644
wake_up_klogd();
}
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 0c9216c..1575d3e 100644
index 0c9216c..00a9a30 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -10,6 +10,7 @@
......@@ -14315,7 +14342,7 @@ index 0c9216c..1575d3e 100644
+ /* APEI may invoke this for temporarily remapping pages in interrupt
+ * context - nothing we can and need to propagate globally. */
+ if (!in_interrupt()) {
+ __ipipe_pin_range_globally(start, end);
+ __ipipe_pin_mapping_globally(start, end);
+ flush_cache_vmap(start, end);
+ }
......@@ -14650,14 +14677,14 @@ index e9f65aa..d9a21ad 100644
return pages;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index d456560..b50a41d 100644
index d456560..4083177 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -191,6 +191,8 @@ static int vmap_page_range_noflush(unsigned long start, unsigned long end,
return err;
} while (pgd++, addr = next, addr != end);
+ __ipipe_pin_range_globally(start, end);
+ __ipipe_pin_mapping_globally(start, end);
+
return nr;
}
......
......@@ -341,7 +341,7 @@ index 10be1dd..cfad863 100644
* or should we not care like we do now ? --BenH.
diff --git a/arch/powerpc/include/asm/ipipe.h b/arch/powerpc/include/asm/ipipe.h
new file mode 100644
index 0000000..1533d8b
index 0000000..6a5f109
--- /dev/null
+++ b/arch/powerpc/include/asm/ipipe.h
@@ -0,0 +1,157 @@
......@@ -386,7 +386,7 @@ index 0000000..1533d8b
+#include <linux/cache.h>
+#include <linux/threads.h>
+
+#define IPIPE_CORE_RELEASE 9
+#define IPIPE_CORE_RELEASE 12
+
+struct ipipe_domain;
+
......@@ -1997,7 +1997,7 @@ index 5193116..ab85bde 100644
#ifdef CONFIG_PPC_DOORBELL
STD_EXCEPTION_COMMON_ASYNC(0xa00, doorbell_super, .doorbell_exception)
diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S
index 9ad236e..65b8f7c 100644
index 9ad236e..3f38333 100644
--- a/arch/powerpc/kernel/fpu.S
+++ b/arch/powerpc/kernel/fpu.S
@@ -195,7 +195,17 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
......@@ -2005,12 +2005,12 @@ index 9ad236e..65b8f7c 100644
*/
_GLOBAL(giveup_fpu)
+#ifdef CONFIG_IPIPE
+ mfmsr r6
+ mfmsr r10
+#ifdef CONFIG_PPC64
+ rldicl r5,r6,48,1 /* clear MSR_EE */
+ rldicl r5,r10,48,1 /* clear MSR_EE */
+ rotldi r5,r5,16
+#else
+ rlwinm r5,r6,0,17,15 /* clear MSR_EE */
+ rlwinm r5,r10,0,17,15 /* clear MSR_EE */
+#endif
+#else
mfmsr r5
......@@ -2023,7 +2023,7 @@ index 9ad236e..65b8f7c 100644
isync
PPC_LCMPI 0,r3,0
- beqlr- /* if no previous owner, done */
+ beq- 2f /* if no previous owner, done */
+ beq- 3f /* if no previous owner, done */
addi r3,r3,THREAD /* want THREAD of task */
PPC_LL r6,THREAD_FPSAVEAREA(r3)
PPC_LL r5,PT_REGS(r3)
......@@ -2031,9 +2031,9 @@ index 9ad236e..65b8f7c 100644
LOAD_REG_ADDRBASE(r4,last_task_used_math)
PPC_STL r5,ADDROFF(last_task_used_math)(r4)
#endif /* CONFIG_SMP */
+2:
+3:
+#ifdef CONFIG_IPIPE /* restore interrupt state */
+ andi. r6,r6,MSR_EE
+ andi. r10,r10,MSR_EE
+ beqlr
+ mfmsr r5
+ ori r5,r5,MSR_EE
......@@ -2152,7 +2152,7 @@ index 67ee0d6..867f855 100644
/* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
FITException:
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S
index c334f53..06b4f42 100644
index c334f53..8fe9c44 100644
--- a/arch/powerpc/kernel/head_44x.S
+++ b/arch/powerpc/kernel/head_44x.S
@@ -262,8 +262,13 @@ interrupt_base:
......@@ -2161,7 +2161,7 @@ index c334f53..06b4f42 100644
/* External Input Interrupt */
+#ifdef CONFIG_IPIPE
+ EXCEPTION(0x0500, BOOKE_INTERRUPT_EXTERNAL, ExternalInput, \
+ __ipipe_grab_irq, EXC_XFER_LITE)
+ __ipipe_grab_irq, EXC_XFER_IPIPE)
+#else /* !CONFIG_IPIPE */
EXCEPTION(0x0500, BOOKE_INTERRUPT_EXTERNAL, ExternalInput, \
do_IRQ, EXC_XFER_LITE)
......@@ -2463,10 +2463,10 @@ index 3fdef0f..72c186e 100644
li r0,0
diff --git a/arch/powerpc/kernel/ipipe.c b/arch/powerpc/kernel/ipipe.c
new file mode 100644
index 0000000..d47e1b4
index 0000000..9995b4f
--- /dev/null
+++ b/arch/powerpc/kernel/ipipe.c
@@ -0,0 +1,391 @@
@@ -0,0 +1,381 @@
+/* -*- linux-c -*-
+ * linux/arch/powerpc/kernel/ipipe.c
+ *
......@@ -2722,16 +2722,6 @@ index 0000000..d47e1b4
+}
+EXPORT_SYMBOL_GPL(ipipe_get_sysinfo);
+
+void ipipe_raise_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ flags = hard_local_irq_save();
+ __ipipe_handle_irq(irq, NULL);
+ hard_local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ipipe_raise_irq);
+
+static int __ipipe_exit_irq(struct pt_regs *regs)
+{
+ int root = __ipipe_root_p;
......@@ -5566,6 +5556,25 @@ index f04e25f..5fa6be6 100644
select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
help
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 228632c9..3da4d6d 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -361,12 +361,12 @@ void panic_if_irq_remap(const char *msg)
static void ir_ack_apic_edge(struct irq_data *data)
{
- ack_APIC_irq();
+ __ack_APIC_irq();
}
static void ir_ack_apic_level(struct irq_data *data)
{
- ack_APIC_irq();
+ __ack_APIC_irq();
eoi_ioapic_irq(data->irq, data->chip_data);
}
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 612dfc7..ffd8160 100644
--- a/drivers/tty/serial/8250/8250_core.c
......@@ -5973,10 +5982,10 @@ index e6bb36a..898a91a 100644
diff --git a/include/linux/ipipe.h b/include/linux/ipipe.h
new file mode 100644
index 0000000..912f689
index 0000000..fc31c97
--- /dev/null
+++ b/include/linux/ipipe.h
@@ -0,0 +1,455 @@
@@ -0,0 +1,461 @@
+/* -*- linux-c -*-
+ * include/linux/ipipe.h
+ *
......@@ -6393,6 +6402,12 @@ index 0000000..912f689
+#define __ipipe_uaccess_might_fault() might_fault()
+#endif
+
+#ifdef CONFIG_IPIPE_TRACE
+void __ipipe_tracer_hrclock_initialized(void);
+#else /* !CONFIG_IPIPE_TRACE */
+#define __ipipe_tracer_hrclock_initialized() do { } while(0)
+#endif /* !CONFIG_IPIPE_TRACE */
+
+#include <linux/ipipe_compat.h>
+
+#else /* !CONFIG_IPIPE */
......@@ -9434,10 +9449,10 @@ index 0000000..797a849
+}
diff --git a/kernel/ipipe/core.c b/kernel/ipipe/core.c
new file mode 100644
index 0000000..c5b022b
index 0000000..026f6d9
--- /dev/null
+++ b/kernel/ipipe/core.c
@@ -0,0 +1,1929 @@
@@ -0,0 +1,1956 @@
+/* -*- linux-c -*-
+ * linux/kernel/ipipe/core.c
+ *
......@@ -10839,6 +10854,33 @@ index 0000000..c5b022b
+ __ipipe_sync_pipeline(ipipe_head_domain);
+}
+
+void ipipe_raise_irq(unsigned int irq)
+{
+ struct ipipe_domain *ipd = ipipe_head_domain;
+ unsigned long flags, control;
+
+ flags = hard_local_irq_save();
+
+ /*
+ * Fast path: raising a virtual IRQ handled by the head
+ * domain.
+ */
+ if (likely(ipipe_virtual_irq_p(irq) && ipd != ipipe_root_domain)) {
+ control = ipd->irqs[irq].control;
+ if (likely(control & IPIPE_HANDLE_MASK)) {
+ dispatch_irq_head(irq);
+ goto out;
+ }
+ }
+
+ /* Emulate regular device IRQ receipt. */
+ __ipipe_dispatch_irq(irq, IPIPE_IRQF_NOACK);
+out:
+ hard_local_irq_restore(flags);
+
+}
+EXPORT_SYMBOL_GPL(ipipe_raise_irq);
+
+#ifdef CONFIG_PREEMPT
+
+void preempt_schedule_irq(void);
......@@ -11369,10 +11411,10 @@ index 0000000..c5b022b
+#endif
diff --git a/kernel/ipipe/timer.c b/kernel/ipipe/timer.c
new file mode 100644
index 0000000..0c9b908
index 0000000..f32a7ff
--- /dev/null
+++ b/kernel/ipipe/timer.c
@@ -0,0 +1,492 @@
@@ -0,0 +1,493 @@
+/* -*- linux-c -*-
+ * linux/kernel/ipipe/timer.c
+ *
......@@ -11740,6 +11782,7 @@ index 0000000..0c9b908
+ timer->real_set_next_event = evtdev->set_next_event;
+ evtdev->mult = 1;
+ evtdev->shift = 0;
+ evtdev->max_delta_ns = UINT_MAX;
+ evtdev->set_mode = emumode;
+ evtdev->set_next_event = emutick;
+ evtdev->ipipe_stolen = 1;
......@@ -11867,10 +11910,10 @@ index 0000000..0c9b908
+#endif /* CONFIG_IPIPE_HAVE_HOSTRT */
diff --git a/kernel/ipipe/tracer.c b/kernel/ipipe/tracer.c
new file mode 100644
index 0000000..5cce0bc
index 0000000..8388671
--- /dev/null
+++ b/kernel/ipipe/tracer.c
@@ -0,0 +1,1447 @@
@@ -0,0 +1,1468 @@
+/* -*- linux-c -*-
+ * kernel/ipipe/tracer.c
+ *
......@@ -12618,6 +12661,9 @@ index 0000000..5cce0bc
+ unsigned long long abs_tsc;
+ long us;
+
+ if (!__ipipe_hrclock_ok())
+ return 0;
+
+ /* ipipe_tsc2us works on unsigned => handle sign separately */
+ abs_tsc = (tsc >= 0) ? tsc : -tsc;
+ us = ipipe_tsc2us(abs_tsc);
......@@ -12820,6 +12866,11 @@ index 0000000..5cce0bc
+
+ __ipipe_global_path_unlock(flags);
+
+ if (!__ipipe_hrclock_ok()) {
+ seq_printf(m, "No hrclock available, dumping traces disabled\n");
+ return NULL;
+ }
+
+ /* does this path actually contain data? */
+ if (print_path->end == print_path->begin)
+ return NULL;
......@@ -12990,6 +13041,11 @@ index 0000000..5cce0bc
+ if (!print_path)
+ return NULL;
+
+ if (!__ipipe_hrclock_ok()) {
+ seq_printf(m, "No hrclock available, dumping traces disabled\n");
+ return NULL;
+ }
+
+ /* back- and post-tracing length, post-trace length was frozen
+ in __ipipe_trace, back-trace may have to be reduced due to
+ buffer overrun */
......@@ -13239,18 +13295,38 @@ index 0000000..5cce0bc
+
+extern struct proc_dir_entry *ipipe_proc_root;
+
+void __init __ipipe_init_tracer(void)
+void __init __ipipe_tracer_hrclock_initialized(void)
+{
+ struct proc_dir_entry *trace_dir;
+ unsigned long long start, end, min = ULLONG_MAX;
+ int i;
+
+#ifdef CONFIG_IPIPE_TRACE_VMALLOC
+ if (!per_cpu(trace_path, 0))
+ return;
+#endif
+ /* Calculate minimum overhead of __ipipe_trace() */
+ hard_local_irq_disable();
+ for (i = 0; i < 100; i++) {
+ ipipe_read_tsc(start);
+ __ipipe_trace(IPIPE_TRACE_FUNC, __BUILTIN_RETURN_ADDRESS0,
+ __BUILTIN_RETURN_ADDRESS1, 0);
+ ipipe_read_tsc(end);
+
+ end -= start;