PERFORCE change 102832 for review

John Birrell jb at FreeBSD.org
Mon Jul 31 08:30:06 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=102832

Change 102832 by jb at jb_freebsd2 on 2006/07/31 08:30:03

	Add a kernel option for Hypervisor trap tracing and enable it per
	cpu, reporting the trace buffer for a rogue CPU which fails to
	respond to IPIs.

Affected files ...

.. //depot/projects/kmacy_sun4v_stable/src/sys/conf/files.sun4v#2 edit
.. //depot/projects/kmacy_sun4v_stable/src/sys/conf/options.sun4v#2 edit
.. //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/conf/GENERIC#7 edit
.. //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/include/hypervisor_api.h#2 edit
.. //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/sun4v/mp_machdep.c#3 edit
.. //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/sun4v/pmap.c#10 edit
.. //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/sun4v/trap_trace.S#1 add

Differences ...

==== //depot/projects/kmacy_sun4v_stable/src/sys/conf/files.sun4v#2 (text+ko) ====

@@ -52,6 +52,7 @@
 						eeprom sbus
 sun4v/sun4v/gdb_machdep.c	optional	gdb
 sun4v/sun4v/hv_pci.c	optional	pci
+sun4v/sun4v/trap_trace.S	optional	trap_tracing
 sparc64/pci/ofw_pci.c		optional	pci
 sparc64/pci/ofw_pcib.c		optional	pci
 sparc64/pci/ofw_pcib_subr.c	optional	pci

==== //depot/projects/kmacy_sun4v_stable/src/sys/conf/options.sun4v#2 (text+ko) ====

@@ -15,3 +15,6 @@
 SIMULATOR		opt_simulator.h
 
 DTRACE			opt_global.h
+
+TRAP_TRACING		opt_trap_trace.h
+TRAP_TRACE_ENTRIES	opt_trap_trace.h

==== //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/conf/GENERIC#7 (text+ko) ====

@@ -65,6 +65,8 @@
 options 	KDB			# Enable kernel debugger support.
 options		KDB_TRACE
 options 	DDB			# Support DDB.
+options 	TRAP_TRACING		# Enable trap tracing.
+options 	TRAP_TRACE_ENTRIES=256	# Trap trace buffer entries.
 #options 	GDB			# Support remote GDB.
 #options 	INVARIANTS		# Enable calls of extra sanity checking
 #options 	INVARIANT_SUPPORT	# Extra sanity checks of internal structures, required by INVARIANTS

==== //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/include/hypervisor_api.h#2 (text+ko) ====

@@ -62,6 +62,22 @@
 typedef uint64_t r_addr_t;
 typedef uint64_t io_addr_t;
 
+typedef struct trap_trace_entry {
+	uint8_t		tte_type;	/* Hypervisor or guest entry. */
+	uint8_t		tte_hpstat;	/* Hyper-privileged state. */
+	uint8_t		tte_tl;		/* Trap level. */
+	uint8_t		tte_gl;		/* Global register level. */
+	uint16_t	tte_tt;		/* Trap type.*/
+	uint16_t	tte_tag;	/* Extended trap identifier. */
+	uint64_t	tte_tstate;	/* Trap state. */
+	uint64_t	tte_tick;	/* Tick. */
+	uint64_t	tte_tpc;	/* Trap PC. */
+	uint64_t	tte_f1;		/* Entry specific. */
+	uint64_t	tte_f2;		/* Entry specific. */
+	uint64_t	tte_f3;		/* Entry specific. */
+	uint64_t	tte_f4;		/* Entry specific. */
+} trap_trace_entry_t;
+
 extern uint64_t hv_mmu_map_perm_addr(void *, int, uint64_t, int);
 extern uint64_t	hv_mmu_unmap_perm_addr(void *, int, int);
 extern uint64_t	hv_set_ctx0(uint64_t, uint64_t);
@@ -94,6 +110,7 @@
 extern uint64_t hv_ttrace_buf_conf(uint64_t, uint64_t, uint64_t *);
 extern uint64_t hv_ttrace_enable(uint64_t, uint64_t *);
 extern uint64_t hv_ttrace_freeze(uint64_t, uint64_t *);
+extern uint64_t hv_ttrace_addentry(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t);
 extern uint64_t hv_dump_buf_update(uint64_t, uint64_t, uint64_t *);
 
 extern int64_t hv_cnputchar(uint8_t);

==== //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/sun4v/mp_machdep.c#3 (text+ko) ====

@@ -57,6 +57,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD: src/sys/sparc64/sparc64/mp_machdep.c,v 1.31 2006/02/07 21:22:02 phk Exp $");
 
+#include "opt_trap_trace.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/lock.h>
@@ -116,6 +118,59 @@
 void cpu_mp_unleash(void *);
 SYSINIT(cpu_mp_unleash, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL);
 
+#ifdef TRAP_TRACING
+#ifndef TRAP_TRACE_ENTRIES
+#define TRAP_TRACE_ENTRIES	64
+#endif
+extern trap_trace_entry_t trap_trace_entry[MAXCPU][TRAP_TRACE_ENTRIES];
+
+static void
+mp_trap_trace_init(void)
+{
+	uint64_t ret, ret1;
+
+	printf("curcpu %d trap_trace_entry %p TRAP_TRACE_ENTRIES %d\n", curcpu, &trap_trace_entry[curcpu][0], TRAP_TRACE_ENTRIES);
+
+	/* Configure the trap trace buffer for the current CPU. */
+	if ((ret = hv_ttrace_buf_conf((uint64_t) vtophys(&trap_trace_entry[curcpu][0]),
+	    (uint64_t) TRAP_TRACE_ENTRIES, &ret1)) != 0)
+		printf("%s: hv_ttrace_buf_conf error %lu\n", __FUNCTION__, ret);
+
+	/* Enable trap tracing for the current CPU. */
+	else if ((ret = hv_ttrace_enable((uint64_t) -1, &ret1)) != 0)
+		printf("%s: hv_ttrace_enable error %lu\n", __FUNCTION__, ret);
+}
+
+void trap_trace_report(int);
+
+static int	trace_trap_lock;
+
+void
+trap_trace_report(int cpuid)
+{
+	int i, j;
+
+	while (!atomic_cmpset_acq_int(&trace_trap_lock, 0, 1))
+		DELAY(10000);
+
+	for (i = 0; i < MAXCPU; i++) {
+		if (cpuid != -1 && cpuid != i)
+			continue;
+
+		for (j = 0; j < TRAP_TRACE_ENTRIES; j++) {
+			trap_trace_entry_t *p = &trap_trace_entry[i][j];
+
+			printf("0x%08jx [%02d][%04d] tpc 0x%jx type 0x%x hpstat 0x%x tl %u gl %u tt 0x%hx tag 0x%hx tstate 0x%jx f1 0x%jx f2 0x%jx f3 0x%jx f4 0x%jx\n",
+			    p->tte_tick, i, j, p->tte_tpc,p->tte_type,p->tte_hpstat,
+			    p->tte_tl,p->tte_gl,p->tte_tt,p->tte_tag,p->tte_tstate,
+			    p->tte_f1,p->tte_f2,p->tte_f3,p->tte_f4);
+		}
+	}
+
+	atomic_store_rel_int(&trace_trap_lock, 0);
+}
+#endif
+
 vm_offset_t
 mp_tramp_alloc(void)
 {
@@ -327,6 +382,11 @@
 	trap_init();
 	cpu_intrq_init();
 	tick_start();
+
+#ifdef TRAP_TRACING
+	mp_trap_trace_init();
+#endif
+
 	/* 
 	 * enable interrupts now that we have our trap table set
 	 */

==== //depot/projects/kmacy_sun4v_stable/src/sys/sun4v/sun4v/pmap.c#10 (text+ko) ====

@@ -28,6 +28,7 @@
 #include "opt_kstack_pages.h"
 #include "opt_msgbuf.h"
 #include "opt_pmap.h"
+#include "opt_trap_trace.h"
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -74,6 +75,10 @@
 
 #include <machine/hypervisor_api.h>
 
+#ifdef TRAP_TRACING
+void trap_trace_report(int);
+#endif
+
 #if 1
 #define	PMAP_DEBUG
 #endif
@@ -384,7 +389,7 @@
 {
 	pmap_t pmap, oldpmap;
 	int err;
-
+	
 	critical_enter();
 	pmap = vmspace_pmap(td->td_proc->p_vmspace);
 	oldpmap = PCPU_GET(curpmap);
@@ -1275,10 +1280,19 @@
 		membar(Sync);
 		i++;
 		if (i > 10000000) {
+#ifdef TRAP_TRACING
+			int j;
+#endif
 			uint64_t cpu_state;
 			printf("cpu with cpumask=0x%x appears to not be responding to ipis\n",
 			       curactive & ~ackmask);
 
+#ifdef TRAP_TRACING
+			for (j = 0; j < MAXCPU; j++)
+				if (((1 << j) & curactive & ~ackmask) != 0)
+					trap_trace_report(j);
+#endif
+
 			hv_cpu_state((uint64_t)ffs64(curactive & ~ackmask), &cpu_state);
 			printf("cpu_state of %ld is %ld\n", ffs64(curactive & ~ackmask), cpu_state);
 			if (!retried) {
@@ -1289,7 +1303,7 @@
 				goto retry;
 			}
 
-				panic(" ackmask=0x%x active=0x%x\n", ackmask, curactive);
+			panic(" ackmask=0x%x active=0x%x\n", ackmask, curactive);
 		}
 	}
 
@@ -1327,7 +1341,6 @@
 	char *func;
 	cpumask_t active;
 #endif
-
 	if ((eva - sva) == PAGE_SIZE) {
 		pmap_invalidate_page(pmap, sva, cleartsb);
 		return;


More information about the p4-projects mailing list