Commit 945eb01b authored by Philippe Gerum's avatar Philippe Gerum
Browse files

cobalt/blackfin: upgrade I-pipe support

parent 8c3bb4a5
......@@ -12,7 +12,7 @@ index a117652..c5d277d1 100644
comment "Processor and Board Settings"
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
index 17b5e92..90c5be8 100644
index 17b5e92..c8d1a8a 100644
--- a/arch/blackfin/include/asm/ipipe.h
+++ b/arch/blackfin/include/asm/ipipe.h
@@ -28,7 +28,7 @@
......@@ -32,7 +32,7 @@ index 17b5e92..90c5be8 100644
-#define IPIPE_MAJOR_NUMBER 1
-#define IPIPE_MINOR_NUMBER 16
-#define IPIPE_PATCH_NUMBER 1
+#define IPIPE_CORE_RELEASE 5
+#define IPIPE_CORE_RELEASE 6
#ifdef CONFIG_SMP
#error "I-pipe/blackfin: SMP not implemented"
......@@ -1982,10 +1982,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
+ *
......@@ -2392,6 +2392,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 */
......@@ -2431,10 +2437,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
+ *
......@@ -2617,9 +2623,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__; \
......@@ -2787,10 +2790,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); })
+
......@@ -2817,6 +2816,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) && \
......@@ -4968,10 +4976,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
......@@ -4992,6 +5000,9 @@ index 0000000..da17b04
+config IPIPE_WANT_CLOCKSOURCE
+ bool
+
+config IPIPE_WANT_PTE_PINNING
+ bool
+
+config IPIPE_CORE_APIREV
+ int
+ depends on IPIPE
......@@ -7767,10 +7778,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
+ *
......@@ -8518,6 +8529,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);
......@@ -8720,6 +8734,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;
......@@ -8890,6 +8909,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 */
......@@ -9139,18 +9163,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;
......@@ -9172,20 +9216,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;
......@@ -9219,7 +9251,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 @@
......@@ -9268,7 +9300,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);
......@@ -9840,7 +9872,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 @@
......@@ -10978,7 +11010,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 @@
......@@ -10997,7 +11029,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);
+ }
......@@ -11332,14 +11364,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;
}
......
......@@ -12,7 +12,7 @@ index 9ceccef..3c94fa7 100644
comment "Processor and Board Settings"
diff --git a/arch/blackfin/include/asm/ipipe.h b/arch/blackfin/include/asm/ipipe.h
index 17b5e92..8b74b1b 100644
index 17b5e92..db71a80 100644
--- a/arch/blackfin/include/asm/ipipe.h
+++ b/arch/blackfin/include/asm/ipipe.h
@@ -28,7 +28,7 @@
......@@ -32,7 +32,7 @@ index 17b5e92..8b74b1b 100644
-#define IPIPE_MAJOR_NUMBER 1
-#define IPIPE_MINOR_NUMBER 16
-#define IPIPE_PATCH_NUMBER 1
+#define IPIPE_CORE_RELEASE 7
+#define IPIPE_CORE_RELEASE 9
#ifdef CONFIG_SMP
#error "I-pipe/blackfin: SMP not implemented"
......@@ -636,7 +636,7 @@ index a017359..e6ad56f 100644
} \
} \
diff --git a/arch/blackfin/kernel/ipipe.c b/arch/blackfin/kernel/ipipe.c
index f657b38..3a7acb8 100644
index f657b38..9ee8c7c 100644
--- a/arch/blackfin/kernel/ipipe.c
+++ b/arch/blackfin/kernel/ipipe.c
@@ -32,32 +32,29 @@
......@@ -685,7 +685,7 @@ index f657b38..3a7acb8 100644
/*
* __ipipe_enable_pipeline() -- We are running on the boot CPU, hw
@@ -71,214 +68,86 @@ void __ipipe_enable_pipeline(void)
@@ -71,214 +68,76 @@ void __ipipe_enable_pipeline(void)
__ipipe_freq_scale = 1000000000UL / __ipipe_core_clock;
for (irq = 0; irq < NR_IRQS; ++irq)
......@@ -905,10 +905,9 @@ index f657b38..3a7acb8 100644
- * works for virtual interrupts.
- */
-int ipipe_trigger_irq(unsigned irq)
+void ipipe_raise_irq(unsigned int irq)
{
unsigned long flags;
-{
- unsigned long flags;
-
-#ifdef CONFIG_IPIPE_DEBUG
- if (irq >= IPIPE_NR_IRQS ||
- (ipipe_virtual_irq_p(irq)
......@@ -916,20 +915,19 @@ index f657b38..3a7acb8 100644
- return -EINVAL;
-#endif
-
flags = hard_local_irq_save();
__ipipe_handle_irq(irq, NULL);
hard_local_irq_restore(flags);
- flags = hard_local_irq_save();
- __ipipe_handle_irq(irq, NULL);
- hard_local_irq_restore(flags);
-
- return 1;
}
+EXPORT_SYMBOL_GPL(ipipe_raise_irq);
-}
-
-asmlinkage void __ipipe_sync_root(void)
+void __ipipe_sync_root(void)
{
void (*irq_tail_hook)(void) = (void (*)(void))__ipipe_irq_tail_hook;
struct ipipe_percpu_domain_data *p;
@@ -293,23 +162,14 @@ asmlinkage void __ipipe_sync_root(void)
@@ -293,23 +152,14 @@ asmlinkage void __ipipe_sync_root(void)
clear_thread_flag(TIF_IRQ_SYNC);
......@@ -956,7 +954,7 @@ index f657b38..3a7acb8 100644
{
/*
* This code is called by the ins{bwl} routines (see
@@ -320,12 +180,15 @@ void __ipipe_disable_root_irqs_hw(void)
@@ -320,12 +170,15 @@ void __ipipe_disable_root_irqs_hw(void)
* the real-time domain.
*/
bfin_sti(__ipipe_irq_lvmask);
......@@ -975,7 +973,7 @@ index f657b38..3a7acb8 100644
bfin_sti(bfin_irq_flags);
}
@@ -334,64 +197,155 @@ void __ipipe_enable_root_irqs_hw(void)
@@ -334,64 +187,155 @@ void __ipipe_enable_root_irqs_hw(void)
* manipulation routines, but let's prepare for SMP support in the
* same move, preventing CPU migration as required.
*/
......@@ -1794,6 +1792,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
......@@ -1884,7 +1901,7 @@ index 612dfc7..ffd8160 100644
.probe = serial8250_probe,
.remove = serial8250_remove,
diff --git a/fs/exec.c b/fs/exec.c
index ea4449d..aa73a12 100644
index 05f1942..836253a 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -822,6 +822,7 @@ static int exec_mmap(struct mm_struct *mm)
......@@ -2201,10 +2218,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
+ *
......@@ -2621,6 +2638,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 */
......@@ -2662,10 +2685,10 @@ index 0000000..912f689
+#endif /* !__LINUX_IPIPE_H */
diff --git a/include/linux/ipipe_base.h b/include/linux/ipipe_base.h
new file mode 100644
index 0000000..ea01dd6
index 0000000..a37358c
--- /dev/null
+++ b/include/linux/ipipe_base.h
@@ -0,0 +1,356 @@
@@ -0,0 +1,358 @@
+/* -*- linux-c -*-
+ * include/linux/ipipe_base.h
+ *
......@@ -2847,9 +2870,6 @@ index 0000000..ea01dd6
+
+void __ipipe_flush_printk(unsigned int irq, void *cookie);
+
+void __ipipe_pin_range_globally(unsigned long start,
+ unsigned long end);
+
+#define __ipipe_get_cpu(flags) ({ (flags) = hard_preempt_disable(); ipipe_processor_id(); })
+#define __ipipe_put_cpu(flags) hard_preempt_enable(flags)
+
......@@ -2982,10 +3002,6 @@ index 0000000..ea01dd6
+
+static inline void __ipipe_init_taskinfo(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); })
+
......@@ -3012,6 +3028,15 @@ index 0000000..ea01dd6
+
+#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) && \
......@@ -4529,7 +4554,7 @@ index 5b9b84b..6c8bb4d 100644
static inline void __raw_read_lock(rwlock_t *lock)
{
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 218b058..d579687 100644
index 91fe6a3..d579687 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -24,6 +24,7 @@ struct sched_param {
......@@ -4595,15 +4620,6 @@ index 218b058..d579687 100644
/*
* cache last used pipe for splice
@@ -1695,7 +1719,7 @@ static inline pid_t task_tgid_vnr(struct task_struct *tsk)
}
-static int pid_alive(const struct task_struct *p);
+static inline int pid_alive(const struct task_struct *p);
static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns)
{
pid_t pid = 0;
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index 3f2867f..336c90a 100644
--- a/include/linux/spinlock.h
......@@ -5209,10 +5225,10 @@ index e2c6853..68c5ef5a 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
......@@ -5233,6 +5249,9 @@ index 0000000..da17b04
+config IPIPE_WANT_CLOCKSOURCE
+ bool
+
+config IPIPE_WANT_PTE_PINNING
+ bool
+
+config IPIPE_CORE_APIREV
+ int
+ depends on IPIPE
......@@ -5666,10 +5685,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
+ *
......@@ -7071,6 +7090,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);
......@@ -7601,10 +7647,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
+ *
......@@ -7972,6 +8018,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;
......@@ -8099,10 +8146,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
+ *
......@@ -8850,6 +8897,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);
......@@ -9052,6 +9102,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;
......@@ -9222,6 +9277,11 @@ index 0000000..5cce0bc