? arch/x86/x86/new
Index: arch/xen/include/evtchn.h
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/include/evtchn.h,v
retrieving revision 1.25
diff -u -p -r1.25 evtchn.h
--- arch/xen/include/evtchn.h	4 Nov 2017 14:56:48 -0000	1.25
+++ arch/xen/include/evtchn.h	24 Jun 2018 11:53:10 -0000
@@ -41,7 +41,8 @@ bool events_resume(void);
 unsigned int evtchn_do_event(int, struct intrframe *);
 void call_evtchn_do_event(int, struct intrframe *);
 void call_xenevt_event(int);
-int event_set_handler(int, int (*func)(void *), void *, int, const char *);
+int event_set_handler(int, int (*func)(void *), void *, int, const char *,
+    const char *);
 int event_remove_handler(int, int (*func)(void *), void *);
 
 struct cpu_info;
@@ -69,7 +70,7 @@ struct pintrhand {
 };
 
 struct pintrhand *pirq_establish(int, int, int (*)(void *), void *, int,
-     const char *);
+     const char *, const char *);
 void pirq_disestablish(struct pintrhand *);
 
 #endif /*  _XEN_EVENTS_H_ */
Index: arch/xen/include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/include/intr.h,v
retrieving revision 1.45
diff -u -p -r1.45 intr.h
--- arch/xen/include/intr.h	13 Dec 2017 16:30:18 -0000	1.45
+++ arch/xen/include/intr.h	24 Jun 2018 11:53:10 -0000
@@ -57,7 +57,8 @@ struct evtsource {
 	struct intrhand *ev_handlers;	/* handler chain */
 	struct evcnt ev_evcnt;		/* interrupt counter */
 	struct cpu_info *ev_cpu;        /* cpu on which this event is bound */
-	char ev_evname[32];		/* event counter name */
+	char ev_intrname[32];		/* interrupt string */
+	char ev_xname[64];		/* handler device list */
 };
 
 extern struct intrstub xenev_stubs[];
Index: arch/xen/x86/xen_ipi.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/x86/xen_ipi.c,v
retrieving revision 1.24
diff -u -p -r1.24 xen_ipi.c
--- arch/xen/x86/xen_ipi.c	23 Jun 2018 15:53:14 -0000	1.24
+++ arch/xen/x86/xen_ipi.c	24 Jun 2018 11:53:10 -0000
@@ -122,6 +122,7 @@ xen_ipi_init(void)
 	cpuid_t vcpu;
 	evtchn_port_t evtchn;
 	struct cpu_info *ci;
+	char intr_xname[INTRDEVNAMEBUF];
 
 	ci = curcpu();
 
@@ -133,8 +134,11 @@ xen_ipi_init(void)
 
 	KASSERT(evtchn != -1 && evtchn < NR_EVENT_CHANNELS);
 
-	if(intr_establish_xname(0, &xen_pic, evtchn, IST_LEVEL, IPL_HIGH,
-		xen_ipi_handler, ci, true, "ipi") == NULL) {
+	snprintf(intr_xname, sizeof(intr_xname), "%s ipi",
+	    device_xname(ci->ci_dev));
+
+	if (intr_establish_xname(0, &xen_pic, evtchn, IST_LEVEL, IPL_HIGH,
+		xen_ipi_handler, ci, true, intr_xname) == NULL) {
 		panic("%s: unable to register ipi handler\n", __func__);
 		/* NOTREACHED */
 	}
@@ -215,7 +219,6 @@ xen_broadcast_ipi(uint32_t ipimask)
 }
 
 /* MD wrapper for the xcall(9) callback. */
-#define PRIuCPUID	"lu" /* XXX: move this somewhere more appropriate */
 
 static void
 xen_ipi_halt(struct cpu_info *ci, struct intrframe *intrf)
@@ -223,7 +226,7 @@ xen_ipi_halt(struct cpu_info *ci, struct
 	KASSERT(ci == curcpu());
 	KASSERT(ci != NULL);
 	if (HYPERVISOR_vcpu_op(VCPUOP_down, ci->ci_cpuid, NULL)) {
-		panic("vcpu%" PRIuCPUID "shutdown failed.\n", ci->ci_cpuid);
+		panic("%s shutdown failed.\n", device_xname(ci->ci_dev));
 	}
 
 }
Index: arch/xen/xen/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/clock.c,v
retrieving revision 1.66
diff -u -p -r1.66 clock.c
--- arch/xen/xen/clock.c	11 May 2018 13:24:46 -0000	1.66
+++ arch/xen/xen/clock.c	24 Jun 2018 11:53:10 -0000
@@ -519,19 +519,24 @@ xen_suspendclocks(struct cpu_info *ci)
 void
 xen_resumeclocks(struct cpu_info *ci)
 {
+	char intr_xname[INTRDEVNAMEBUF];
 	int evtch;
        
 	evtch = bind_virq_to_evtch(VIRQ_TIMER);
 	KASSERT(evtch != -1);
 
+	snprintf(intr_xname, sizeof(intr_xname), "%s clock",
+	    device_xname(ci->ci_dev));
+
 	ih = intr_establish_xname(0, &xen_pic, evtch, IST_LEVEL, IPL_CLOCK,
-	    xen_timer_handler_stub, ci, true, "clock");
+	    xen_timer_handler_stub, ci, true, intr_xname);
 
 	KASSERT(ih != NULL);
 
 	hypervisor_enable_event(evtch);
 
-	aprint_verbose("Xen clock: using event channel %d\n", evtch);
+	aprint_verbose("Xen %s: using event channel %d\n",
+	    intr_xname, evtch);
 }
 
 /* ARGSUSED */
Index: arch/xen/xen/evtchn.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/evtchn.c,v
retrieving revision 1.79
diff -u -p -r1.79 evtchn.c
--- arch/xen/xen/evtchn.c	13 Dec 2017 16:30:18 -0000	1.79
+++ arch/xen/xen/evtchn.c	24 Jun 2018 11:53:10 -0000
@@ -69,6 +69,7 @@ __KERNEL_RCSID(0, "$NetBSD: evtchn.c,v 1
 #include <sys/kmem.h>
 #include <sys/reboot.h>
 #include <sys/mutex.h>
+#include <sys/interrupt.h>
 
 #include <uvm/uvm.h>
 
@@ -733,7 +734,7 @@ unbind_pirq_from_evtch(int pirq)
 
 struct pintrhand *
 pirq_establish(int pirq, int evtch, int (*func)(void *), void *arg, int level,
-    const char *evname)
+    const char *intrname, const char *xname)
 {
 	struct pintrhand *ih;
 	physdev_op_t physdev_op;
@@ -752,7 +753,8 @@ pirq_establish(int pirq, int evtch, int 
 	ih->func = func;
 	ih->arg = arg;
 
-	if (event_set_handler(evtch, pirq_interrupt, ih, level, evname) != 0) {
+	if (event_set_handler(evtch, pirq_interrupt, ih, level, intrname,
+	    xname) != 0) {
 		kmem_free(ih, sizeof(struct pintrhand));
 		return NULL;
 	}
@@ -789,7 +791,6 @@ pirq_interrupt(void *arg)
 	struct pintrhand *ih = arg;
 	int ret;
 
-
 	ret = ih->func(ih->arg);
 #ifdef IRQ_DEBUG
 	if (ih->evtch == IRQ_DEBUG)
@@ -832,7 +833,7 @@ intr_calculatemasks(struct evtsource *ev
 
 int
 event_set_handler(int evtch, int (*func)(void *), void *arg, int level,
-    const char *evname)
+    const char *intrname, const char *xname)
 {
 	struct cpu_info *ci = curcpu(); /* XXX: pass in ci ? */
 	struct evtsource *evts;
@@ -849,6 +850,7 @@ event_set_handler(int evtch, int (*func)
 	KASSERTMSG(evtch >= 0, "negative evtch: %d", evtch);
 	KASSERTMSG(evtch < NR_EVENT_CHANNELS,
 	    "evtch number %d > NR_EVENT_CHANNELS", evtch);
+	KASSERT(intrname != NULL && xname != NULL);
 
 #if 0
 	printf("event_set_handler evtch %d handler %p level %d\n", evtch,
@@ -894,14 +896,10 @@ event_set_handler(int evtch, int (*func)
 		evts->ev_cpu = ci;
 		mutex_init(&evtlock[evtch], MUTEX_DEFAULT, IPL_HIGH);
 		evtsource[evtch] = evts;
-		if (evname)
-			strncpy(evts->ev_evname, evname,
-			    sizeof(evts->ev_evname));
-		else
-			snprintf(evts->ev_evname, sizeof(evts->ev_evname),
-			    "evt%d", evtch);
+		strncpy(evts->ev_intrname, intrname, sizeof(evts->ev_intrname));
+
 		evcnt_attach_dynamic(&evts->ev_evcnt, EVCNT_TYPE_INTR, NULL,
-		    device_xname(ci->ci_dev), evts->ev_evname);
+		    device_xname(ci->ci_dev), evts->ev_intrname);
 	} else {
 		evts = evtsource[evtch];
 		/* sort by IPL order, higher first */
@@ -921,6 +919,11 @@ event_set_handler(int evtch, int (*func)
 		mutex_spin_exit(&evtlock[evtch]);
 	}
 
+	// add device name
+	if (evts->ev_xname[0] != '\0')
+        	strlcat(evts->ev_xname, ", ", sizeof(evts->ev_xname));
+	strlcat(evts->ev_xname, xname, sizeof(evts->ev_xname));
+
 	intr_calculatemasks(evts, evtch, ci);
 	splx(s);
 
@@ -1059,3 +1062,130 @@ xen_debug_handler(void *arg)
 	printf("\n");
 	return 0;
 }
+
+static struct evtsource *
+event_get_handler(const char *intrid)
+{
+        for (int i = 0; i < NR_EVENT_CHANNELS; i++) {
+		if (evtsource[i] == NULL || i == debug_port)
+			continue;
+
+		struct evtsource *evp = evtsource[i];
+
+		if (strcmp(evp->ev_intrname, intrid) == 0)
+			return evp;
+	}
+
+	return NULL;
+}
+
+/*
+ * MI interface for subr_interrupt.c
+ */
+uint64_t
+interrupt_get_count(const char *intrid, u_int cpu_idx)
+{
+	int count = 0;
+	struct evtsource *evp;
+
+	mutex_spin_enter(&evtchn_lock);
+
+	evp = event_get_handler(intrid);
+	if (evp != NULL && cpu_idx == cpu_index(evp->ev_cpu))
+		count = evp->ev_evcnt.ev_count;
+
+	mutex_spin_exit(&evtchn_lock);
+
+	return count;
+}
+
+/*
+ * MI interface for subr_interrupt.c
+ */
+void
+interrupt_get_assigned(const char *intrid, kcpuset_t *cpuset)
+{
+	struct evtsource *evp;
+
+	kcpuset_zero(cpuset);
+
+	mutex_spin_enter(&evtchn_lock);
+
+	evp = event_get_handler(intrid);
+	if (evp != NULL)
+		kcpuset_set(cpuset, cpu_index(evp->ev_cpu));
+
+	mutex_spin_exit(&evtchn_lock);
+}
+
+/*
+ * MI interface for subr_interrupt.c
+ */
+void
+interrupt_get_devname(const char *intrid, char *buf, size_t len)
+{
+	struct evtsource *evp;
+
+	mutex_spin_enter(&evtchn_lock);
+
+	evp = event_get_handler(intrid);
+	strlcpy(buf, evp ? evp->ev_xname : "unknown", len);
+
+	mutex_spin_exit(&evtchn_lock);
+}
+
+/*
+ * MI interface for subr_interrupt.
+ */
+struct intrids_handler *
+interrupt_construct_intrids(const kcpuset_t *cpuset)
+{
+	struct intrids_handler *ii_handler;
+	intrid_t *ids;
+	int i, count, off;
+	struct evtsource *evp;
+
+	if (kcpuset_iszero(cpuset))
+		return 0;
+
+	/*
+	 * Count the number of interrupts which affinity to any cpu of "cpuset".
+	 */
+	count = 0;
+        for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+		evp = evtsource[i];
+
+		if (evp == NULL || i == debug_port)
+			continue;
+
+		if (!kcpuset_isset(cpuset, cpu_index(evp->ev_cpu)))
+			continue;
+
+		count++;
+        }
+
+	ii_handler = kmem_zalloc(sizeof(int) + sizeof(intrid_t) * count,
+	    KM_SLEEP);
+	if (ii_handler == NULL)
+		return NULL;
+	ii_handler->iih_nids = count;
+	if (count == 0)
+		return ii_handler;
+
+	ids = ii_handler->iih_intrids;
+	mutex_spin_enter(&evtchn_lock);
+        for (i = 0, off = 0; i < NR_EVENT_CHANNELS && off < count; i++) {
+		evp = evtsource[i];
+
+		if (evp == NULL || i == debug_port)
+			continue;
+
+		if (!kcpuset_isset(cpuset, cpu_index(evp->ev_cpu)))
+			continue;
+
+		snprintf(ids[off++], sizeof(intrid_t), "%s", evp->ev_intrname);
+	}
+	mutex_spin_exit(&evtchn_lock);
+
+	return ii_handler;
+}
Index: arch/xen/xen/pciback.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/pciback.c,v
retrieving revision 1.12
diff -u -p -r1.12 pciback.c
--- arch/xen/xen/pciback.c	16 Jul 2017 06:14:24 -0000	1.12
+++ arch/xen/xen/pciback.c	24 Jun 2018 11:53:10 -0000
@@ -619,7 +619,7 @@ pciback_xenbus_frontend_changed(void *ar
 		xenbus_switch_state(xbusd, NULL, XenbusStateConnected);
 		x86_sfence();
 		event_set_handler(pbxi->pbx_evtchn, pciback_xenbus_evthandler,
-		    pbxi, IPL_BIO, "pciback");
+		    pbxi, IPL_BIO, "pciback", "pciback");
 		hypervisor_enable_event(pbxi->pbx_evtchn);
 		hypervisor_notify_via_evtchn(pbxi->pbx_evtchn);
 		break;
Index: arch/xen/xen/xencons.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/xencons.c,v
retrieving revision 1.43
diff -u -p -r1.43 xencons.c
--- arch/xen/xen/xencons.c	11 Nov 2017 21:03:01 -0000	1.43
+++ arch/xen/xen/xencons.c	24 Jun 2018 11:53:10 -0000
@@ -230,19 +230,20 @@ xencons_resume(device_t dev, const pmf_q
 	int evtch = -1;
 
 	if (xendomain_is_dom0()) {
-	/* dom0 console resume is required only during first start-up */
+		/* dom0 console resume is required only during first start-up */
 		if (cold) {
 			evtch = bind_virq_to_evtch(VIRQ_CONSOLE);
 			ih = intr_establish_xname(0, &xen_pic, evtch,
 			    IST_LEVEL, IPL_TTY, xencons_intr,
-			    xencons_console_device, false, "xencons");
+			    xencons_console_device, false,
+			    device_xname(dev));
 			KASSERT(ih != NULL);
 		}
 	} else {
 		evtch = xen_start_info.console_evtchn;
 		ih = intr_establish_xname(0, &xen_pic, evtch,
 		    IST_LEVEL, IPL_TTY, xencons_handler,
-		    xencons_console_device, false, "xencons");
+		    xencons_console_device, false, device_xname(dev));
 		KASSERT(ih != NULL);
 	}
 
Index: arch/x86/include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/intr.h,v
retrieving revision 1.55
diff -u -p -r1.55 intr.h
--- arch/x86/include/intr.h	4 Apr 2018 22:52:58 -0000	1.55
+++ arch/x86/include/intr.h	24 Jun 2018 11:53:10 -0000
@@ -222,9 +222,7 @@ int intr_find_mpmapping(int, int, intr_h
 struct pic *intr_findpic(int);
 void intr_printconfig(void);
 
-#if !defined(XEN)
 const char *intr_create_intrid(int, struct pic *, int, char *, size_t);
-#endif /* XEN */
 struct intrsource *intr_allocate_io_intrsource(const char *);
 void intr_free_io_intrsource(const char *);
 
Index: arch/x86/isa/isa_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/isa/isa_machdep.c,v
retrieving revision 1.38
diff -u -p -r1.38 isa_machdep.c
--- arch/x86/isa/isa_machdep.c	13 Dec 2017 16:30:18 -0000	1.38
+++ arch/x86/isa/isa_machdep.c	24 Jun 2018 11:53:10 -0000
@@ -241,25 +241,22 @@ isa_intr_establish_xname(isa_chipset_tag
 	KASSERT(APIC_IRQ_ISLEGACY(irq));
 
 	int evtch;
-	char evname[16];
+	const char *intrstr;
+	char intrstr_buf[INTRIDBUF];
 
 	mpih |= APIC_IRQ_LEGACY_IRQ(irq);
 
 	evtch = xen_pirq_alloc(&mpih, type); /* XXX: legacy - xen just tosses irq back at us */
 	if (evtch == -1)
 		return NULL;
-#if NIOAPIC > 0
-	if (ioapic)
-		snprintf(evname, sizeof(evname), "%s pin %d",
-		    device_xname(ioapic->sc_dev), pin);
-	else
-#endif
-		snprintf(evname, sizeof(evname), "irq%d", irq);
+
+	intrstr = intr_create_intrid(irq, pic, pin, intrstr_buf,
+	    sizeof(intrstr_buf));
 
 	aprint_debug("irq: %d requested on pic: %s.\n", irq, pic->pic_name);
 
 	return (void *)pirq_establish(irq, evtch, ih_fun, ih_arg, level,
-	    evname);
+	    intrstr, xname);
 #else /* defined(XEN) */
 	return intr_establish_xname(irq, pic, pin, type, level, ih_fun, ih_arg,
 	    false, xname);
Index: arch/x86/x86/intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/intr.c,v
retrieving revision 1.125
diff -u -p -r1.125 intr.c
--- arch/x86/x86/intr.c	4 Apr 2018 22:52:59 -0000	1.125
+++ arch/x86/x86/intr.c	24 Jun 2018 11:53:10 -0000
@@ -238,12 +238,13 @@ static void intr_source_free(struct cpu_
 
 static void intr_establish_xcall(void *, void *);
 static void intr_disestablish_xcall(void *, void *);
+#endif
 
 static const char *legacy_intr_string(int, char *, size_t, struct pic *);
+
 #if defined(XEN) /* XXX: nuke conditional after integration */
 static const char *xen_intr_string(int, char *, size_t, struct pic *);
 #endif /* XXX: XEN */
-#endif
 
 #if defined(INTRSTACKSIZE)
 static inline bool redzone_const_or_false(bool);
@@ -489,7 +490,6 @@ intr_scan_bus(int bus, int pin, intr_han
 }
 #endif
 
-#if !defined(XEN)
 /*
  * Create an interrupt id such as "ioapic0 pin 9". This interrupt id is used
  * by MI code and intrctl(8).
@@ -551,8 +551,6 @@ intr_create_intrid(int legacy_irq, struc
 	return NULL; /* No pic found! */
 }
 
-#endif /* XEN */
-
 /*
  * Find intrsource from io_interrupt_sources list.
  */
@@ -869,6 +867,7 @@ intr_findpic(int num)
 	return NULL;
 }
 #endif
+
 #if !defined(XEN)
 /*
  * Append device name to intrsource. If device A and device B share IRQ number,
@@ -1222,6 +1221,9 @@ intr_establish_xname(int legacy_irq, str
     int type, int level, int (*handler)(void *), void *arg,
     bool known_mpsafe, const char *xname)
 {
+	const char *intrstr;
+	char intrstr_buf[INTRIDBUF];
+
 	if (pic->pic_type == PIC_XEN) {
 		struct intrhand *rih;
 
@@ -1232,7 +1234,10 @@ intr_establish_xname(int legacy_irq, str
 		 */
 		KASSERT(known_mpsafe == (level != IPL_VM));
 
-		event_set_handler(pin, handler, arg, level, xname);
+		intrstr = intr_create_intrid(legacy_irq, pic, pin, intrstr_buf,
+		    sizeof(intrstr_buf));
+
+		event_set_handler(pin, handler, arg, level, intrstr, xname);
 
 		rih = kmem_zalloc(sizeof(*rih), cold ? KM_NOSLEEP : KM_SLEEP);
 		if (rih == NULL) {
@@ -1260,7 +1265,6 @@ intr_establish_xname(int legacy_irq, str
 	struct pintrhand *pih;
 	intr_handle_t irq;
 	int evtchn;
-	char evname[16];
 
 	KASSERTMSG(legacy_irq == -1 || (0 <= legacy_irq && legacy_irq < 16),
 	    "bad legacy IRQ value: %d", legacy_irq);
@@ -1273,19 +1277,19 @@ intr_establish_xname(int legacy_irq, str
 		irq = APIC_INT_VIA_APIC;
 		irq |= pic->pic_apicid << APIC_INT_APIC_SHIFT;
 		irq |= pin << APIC_INT_PIN_SHIFT;
-		snprintf(evname, sizeof(evname), "%s pin %d",
-		    pic->pic_name, pin);
 #else /* NIOAPIC */
 		return NULL;
 #endif /* NIOAPIC */
 	} else {
-		snprintf(evname, sizeof(evname), "irq%d", legacy_irq);
 		irq = legacy_irq;
 	}
 
+	intrstr = intr_create_intrid(legacy_irq, pic, pin, intrstr_buf,
+	    sizeof(intrstr_buf));
+
 	evtchn = xen_pirq_alloc(&irq, type);
 	pih = pirq_establish(irq & 0xff, evtchn, handler, arg, level,
-	    evname);
+	    intrstr, xname);
 	pih->pic_type = pic->pic_type;
 	return pih;
 #endif /* NPCI > 0 || NISA > 0 */
@@ -1342,7 +1346,6 @@ intr_disestablish(struct intrhand *ih)
 #endif /* XEN */
 }
 
-#if !defined(XEN)
 #if defined(XEN) /* nuke conditional post integration */
 static const char *
 xen_intr_string(int port, char *buf, size_t len, struct pic *pic)
@@ -1356,7 +1359,7 @@ xen_intr_string(int port, char *buf, siz
 
 	return buf;
 }
-#endif /* XXX: XEN */
+#endif /* XEN */
 
 static const char *
 legacy_intr_string(int ih, char *buf, size_t len, struct pic *pic)
@@ -1377,7 +1380,6 @@ legacy_intr_string(int ih, char *buf, si
 
 	return buf;
 }
-#endif
 
 const char *
 intr_string(intr_handle_t ih, char *buf, size_t len)
@@ -2128,7 +2130,7 @@ intr_set_affinity(struct intrsource *isp
 
 	return err;
 }
-#endif /* XEN */
+
 static bool
 intr_is_affinity_intrsource(struct intrsource *isp, const kcpuset_t *cpuset)
 {
@@ -2163,7 +2165,6 @@ intr_get_handler(const char *intrid)
 	return isp->is_handlers;
 }
 
-#if !defined(XEN)
 /*
  * MI interface for subr_interrupt.c
  */
@@ -2209,8 +2210,6 @@ interrupt_get_count(const char *intrid, 
 	return count;
 }
 
-#endif /* XEN */
-
 /*
  * MI interface for subr_interrupt.c
  */
@@ -2235,7 +2234,7 @@ interrupt_get_assigned(const char *intri
 	mutex_exit(&cpu_lock);
 }
 
-#if !defined(XEN)
+#endif /* XEN */
 
 /*
  * MI interface for subr_interrupt.c
@@ -2257,6 +2256,8 @@ interrupt_get_available(kcpuset_t *cpuse
 	mutex_exit(&cpu_lock);
 }
 
+#if !defined(XEN)
+
 /*
  * MI interface for subr_interrupt.c
  */
@@ -2348,7 +2349,6 @@ interrupt_distribute_handler(const char 
 	mutex_exit(&intr_distribute_lock);
 	return error;
 }
-#endif
 
 /*
  * MI interface for subr_interrupt.c
@@ -2403,6 +2403,7 @@ interrupt_construct_intrids(const kcpuse
 
 	return ii_handler;
 }
+#endif /* !XEN */
 
 /*
  * MI interface for subr_interrupt.c