summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroyger <royger@FreeBSD.org>2014-08-04 08:52:10 +0000
committerroyger <royger@FreeBSD.org>2014-08-04 08:52:10 +0000
commit3c669f2b534115df96d4390ab31ad578ef7f831e (patch)
treef70b98e2b30cd0da2e92b478e680f8776b5d99d3
parent8d27fa514fc678424ba2a314b7db3623c20b5488 (diff)
downloadFreeBSD-src-3c669f2b534115df96d4390ab31ad578ef7f831e.zip
FreeBSD-src-3c669f2b534115df96d4390ab31ad578ef7f831e.tar.gz
xen: add a DDB command to print event channel information
Add a new DDB command to dump all registered event channels. Sponsored by: Citrix Systems R&D x86/xen/xen_intr.c: - Add a new xen_evtchn command to DDB in order to dump all information related to event channels.
-rw-r--r--sys/x86/xen/xen_intr.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c
index a3f7f41..b285894 100644
--- a/sys/x86/xen/xen_intr.c
+++ b/sys/x86/xen/xen_intr.c
@@ -32,6 +32,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_ddb.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
@@ -62,6 +64,10 @@ __FBSDID("$FreeBSD$");
#include <dev/xen/xenpci/xenpcivar.h>
+#ifdef DDB
+#include <ddb/ddb.h>
+#endif
+
static MALLOC_DEFINE(M_XENINTR, "xen_intr", "Xen Interrupt Services");
/**
@@ -1427,3 +1433,74 @@ xen_intr_port(xen_intr_handle_t handle)
return (isrc->xi_port);
}
+
+#ifdef DDB
+static const char *
+xen_intr_print_type(enum evtchn_type type)
+{
+ static const char *evtchn_type_to_string[EVTCHN_TYPE_COUNT] = {
+ [EVTCHN_TYPE_UNBOUND] = "UNBOUND",
+ [EVTCHN_TYPE_PIRQ] = "PIRQ",
+ [EVTCHN_TYPE_VIRQ] = "VIRQ",
+ [EVTCHN_TYPE_IPI] = "IPI",
+ [EVTCHN_TYPE_PORT] = "PORT",
+ };
+
+ if (type >= EVTCHN_TYPE_COUNT)
+ return ("UNKNOWN");
+
+ return (evtchn_type_to_string[type]);
+}
+
+static void
+xen_intr_dump_port(struct xenisrc *isrc)
+{
+ struct xen_intr_pcpu_data *pcpu;
+ shared_info_t *s = HYPERVISOR_shared_info;
+ int i;
+
+ db_printf("Port %d Type: %s\n",
+ isrc->xi_port, xen_intr_print_type(isrc->xi_type));
+ if (isrc->xi_type == EVTCHN_TYPE_PIRQ) {
+ db_printf("\tPirq: %d ActiveHi: %d EdgeTrigger: %d "
+ "NeedsEOI: %d Shared: %d\n",
+ isrc->xi_pirq, isrc->xi_activehi, isrc->xi_edgetrigger,
+ !!test_bit(isrc->xi_pirq, xen_intr_pirq_eoi_map),
+ isrc->xi_shared);
+ }
+ if (isrc->xi_type == EVTCHN_TYPE_VIRQ)
+ db_printf("\tVirq: %d\n", isrc->xi_virq);
+
+ db_printf("\tMasked: %d Pending: %d\n",
+ !!test_bit(isrc->xi_port, &s->evtchn_mask[0]),
+ !!test_bit(isrc->xi_port, &s->evtchn_pending[0]));
+
+ db_printf("\tPer-CPU Masks: ");
+ CPU_FOREACH(i) {
+ pcpu = DPCPU_ID_PTR(i, xen_intr_pcpu);
+ db_printf("cpu#%d: %d ", i,
+ !!test_bit(isrc->xi_port, pcpu->evtchn_enabled));
+ }
+ db_printf("\n");
+}
+
+DB_SHOW_COMMAND(xen_evtchn, db_show_xen_evtchn)
+{
+ int i;
+
+ if (!xen_domain()) {
+ db_printf("Only available on Xen guests\n");
+ return;
+ }
+
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+ struct xenisrc *isrc;
+
+ isrc = xen_intr_port_to_isrc[i];
+ if (isrc == NULL)
+ continue;
+
+ xen_intr_dump_port(isrc);
+ }
+}
+#endif /* DDB */
OpenPOWER on IntegriCloud