Date: Mon, 31 Jul 2006 08:30:05 GMT From: John Birrell <jb@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 102832 for review Message-ID: <200607310830.k6V8U5Xc089099@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102832 Change 102832 by jb@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;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607310830.k6V8U5Xc089099>