This is not a real tracing facility, but it is good enough to find bugs.
It supports symbolic lookup and tracepoint insertion, as well as hooking
the three main entry points to the hypervisor.
Signed-off-by: Amos Waterland <apw@xxxxxxxxxx>
---
arch/powerpc/exceptions.c | 79 +++++++++++++++++++++++++++++++++++++++++++
arch/powerpc/external.c | 20 ++++++++++
arch/powerpc/hcalls.c | 20 ++++++++++
include/asm-powerpc/config.h | 11 +++++
4 files changed, 130 insertions(+)
diff -r c94df1e4e62c xen/arch/powerpc/exceptions.c
--- a/xen/arch/powerpc/exceptions.c Thu Sep 14 15:43:38 2006 -0500
+++ b/xen/arch/powerpc/exceptions.c Thu Sep 14 18:33:35 2006 -0400
@@ -29,6 +29,40 @@
#undef DEBUG
+#ifdef TRACE_DOMAINS
+long iars[MAX_IARS][2];
+long last_dump_time = 0;
+int cpu_to_trace = 3;
+
+void trace_function(void *addr)
+{
+ long iar = ((long *)(addr))[0];
+
+ return trace_address(iar);
+}
+
+void trace_address(long iar)
+{
+ int i;
+
+ if (smp_processor_id() != cpu_to_trace)
+ return;
+
+ for (i = 0; iars[i][0] != 0 && i < MAX_IARS; i++) {
+ if (iars[i][0] == iar) {
+ iars[i][1]++;
+ i = MAX_IARS;
+ break;
+ }
+ }
+
+ if (i < MAX_IARS) {
+ iars[i][0] = iar;
+ iars[i][1] = 1;
+ }
+}
+#endif
+
extern ulong ppc_do_softirq(ulong orig_msr);
extern void do_timer(struct cpu_user_regs *regs);
extern void do_dec(struct cpu_user_regs *regs);
@@ -41,6 +75,51 @@ void do_timer(struct cpu_user_regs *regs
/* Set HDEC high so it stops firing and can be reprogrammed by
* set_preempt() */
mthdec(INT_MAX);
+
+#ifdef TRACE_DOMAINS
+ if (smp_processor_id() == cpu_to_trace) {
+ int i;
+ long iar = regs->pc;
+
+ for (i = 0; iars[i][0] != 0 && i < MAX_IARS; i++) {
+ if (iars[i][0] == iar) {
+ iars[i][1]++;
+ i = MAX_IARS;
+ break;
+ }
+ }
+
+ if (i < MAX_IARS) {
+ iars[i][0] = iar;
+ iars[i][1] = 1;
+ }
+ }
+
+ extern const char *symbols_lookup(unsigned long addr,
+ unsigned long *symbolsize,
+ unsigned long *offset,
+ char *namebuf);
+
+ if (smp_processor_id() == 0) {
+ int i;
+ long now = mftb();
+ long dump_interval = 3 * timebase_freq;
+
+ if (now > last_dump_time + dump_interval) {
+ last_dump_time = now;
+
+ for (i = 0; iars[i][0] != 0 && i < MAX_IARS; i++) {
+ char buff[128];
+
+ if (symbols_lookup(iars[i][0], NULL, NULL, buff))
+ printk("%4d %22s: %ld\n", i, buff, iars[i][1]);
+ else
+ printk("%4d %22lx: %ld\n", i, iars[i][0], iars[i][1]);
+ }
+ }
+ }
+#endif
+
raise_softirq(TIMER_SOFTIRQ);
}
diff -r c94df1e4e62c xen/arch/powerpc/external.c
--- a/xen/arch/powerpc/external.c Thu Sep 14 15:43:38 2006 -0500
+++ b/xen/arch/powerpc/external.c Thu Sep 14 18:33:35 2006 -0400
@@ -80,6 +80,26 @@ void do_external(struct cpu_user_regs *r
BUG_ON(!(regs->msr & MSR_EE));
BUG_ON(mfmsr() & MSR_EE);
+#ifdef TRACE_DOMAINS
+ if (smp_processor_id() == cpu_to_trace) {
+ int i;
+ long iar = regs->pc;
+
+ for (i = 0; iars[i][0] != 0 && i < MAX_IARS; i++) {
+ if (iars[i][0] == iar) {
+ iars[i][1]++;
+ i = MAX_IARS;
+ break;
+ }
+ }
+
+ if (i < MAX_IARS) {
+ iars[i][0] = iar;
+ iars[i][1] = 1;
+ }
+ }
+#endif
+
vec = xen_mpic_get_irq(regs);
if (vec != -1) {
diff -r c94df1e4e62c xen/arch/powerpc/hcalls.c
--- a/xen/arch/powerpc/hcalls.c Thu Sep 14 15:43:38 2006 -0500
+++ b/xen/arch/powerpc/hcalls.c Thu Sep 14 18:33:35 2006 -0400
@@ -96,6 +96,26 @@ void do_hcall(struct cpu_user_regs *regs
{
ulong num = regs->gprs[3];
+#ifdef TRACE_DOMAINS
+ if (smp_processor_id() == cpu_to_trace) {
+ int i;
+ long iar = regs->pc;
+
+ for (i = 0; iars[i][0] != 0 && i < MAX_IARS; i++) {
+ if (iars[i][0] == iar) {
+ iars[i][1]++;
+ i = MAX_IARS;
+ break;
+ }
+ }
+
+ if (i < MAX_IARS) {
+ iars[i][0] = iar;
+ iars[i][1] = 1;
+ }
+ }
+#endif
+
local_irq_enable();
if ((num & XEN_MARK(0)) == XEN_MARK(0)) {
diff -r c94df1e4e62c xen/include/asm-powerpc/config.h
--- a/xen/include/asm-powerpc/config.h Thu Sep 14 15:43:38 2006 -0500
+++ b/xen/include/asm-powerpc/config.h Thu Sep 14 18:33:35 2006 -0400
@@ -38,6 +38,17 @@ extern char _end[];
extern char _end[];
extern char _etext[];
extern char __bss_start[];
+
+#define TRACE_DOMAINS
+#ifdef TRACE_DOMAINS
+#define MAX_IARS 1000
+extern long iars[MAX_IARS][2];
+extern long last_dump_time;
+extern int cpu_to_trace;
+void trace_function(void *addr);
+void trace_address(long addr);
+#endif /* TRACE_DOMAINS */
+
#endif
/* align addr on a size boundary - adjust address up/down if needed */
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ppc-devel
|