Module Name:    src
Committed By:   rmind
Date:           Mon May 19 22:47:54 UTC 2014

Modified Files:
        src/sys/arch/alpha/alpha: ipifuncs.c
        src/sys/arch/alpha/include: intr.h
        src/sys/arch/arm/arm32: arm32_machdep.c
        src/sys/arch/arm/cortex: gic.c
        src/sys/arch/arm/pic: pic.c picvar.h
        src/sys/arch/hppa/hppa: ipifuncs.c
        src/sys/arch/hppa/include: intrdefs.h
        src/sys/arch/mips/include: intr.h
        src/sys/arch/mips/mips: cpu_subr.c ipifuncs.c
        src/sys/arch/powerpc/booke: e500_intr.c
        src/sys/arch/powerpc/include/booke: intr.h
        src/sys/arch/powerpc/pic: ipi.c ipivar.h
        src/sys/arch/powerpc/powerpc: powerpc_machdep.c
        src/sys/arch/sparc/sparc: cpu.c
        src/sys/arch/sparc64/sparc64: ipifuncs.c
        src/sys/arch/vax/include: cpu.h
        src/sys/arch/vax/vax: multicpu.c
        src/sys/arch/x86/include: intrdefs.h
        src/sys/arch/x86/x86: ipi.c
        src/sys/arch/xen/include: intrdefs.h
        src/sys/arch/xen/x86: xen_ipi.c
        src/sys/conf: files
        src/sys/kern: init_main.c
Added Files:
        src/sys/kern: subr_ipi.c
        src/sys/sys: ipi.h

Log Message:
Implement MI IPI interface with cross-call support.


To generate a diff of this commit:
cvs rdiff -u -r1.47 -r1.48 src/sys/arch/alpha/alpha/ipifuncs.c
cvs rdiff -u -r1.70 -r1.71 src/sys/arch/alpha/include/intr.h
cvs rdiff -u -r1.104 -r1.105 src/sys/arch/arm/arm32/arm32_machdep.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/cortex/gic.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/pic/pic.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/pic/picvar.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/hppa/hppa/ipifuncs.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/hppa/include/intrdefs.h
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/mips/include/intr.h
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/mips/mips/ipifuncs.c
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/powerpc/booke/e500_intr.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/powerpc/include/booke/intr.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/powerpc/pic/ipi.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/pic/ipivar.h
cvs rdiff -u -r1.69 -r1.70 src/sys/arch/powerpc/powerpc/powerpc_machdep.c
cvs rdiff -u -r1.244 -r1.245 src/sys/arch/sparc/sparc/cpu.c
cvs rdiff -u -r1.47 -r1.48 src/sys/arch/sparc64/sparc64/ipifuncs.c
cvs rdiff -u -r1.98 -r1.99 src/sys/arch/vax/include/cpu.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/vax/vax/multicpu.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/include/intrdefs.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/x86/x86/ipi.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/xen/include/intrdefs.h
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/xen/x86/xen_ipi.c
cvs rdiff -u -r1.1090 -r1.1091 src/sys/conf/files
cvs rdiff -u -r1.454 -r1.455 src/sys/kern/init_main.c
cvs rdiff -u -r0 -r1.1 src/sys/kern/subr_ipi.c
cvs rdiff -u -r0 -r1.1 src/sys/sys/ipi.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/alpha/alpha/ipifuncs.c
diff -u src/sys/arch/alpha/alpha/ipifuncs.c:1.47 src/sys/arch/alpha/alpha/ipifuncs.c:1.48
--- src/sys/arch/alpha/alpha/ipifuncs.c:1.47	Tue Jun 14 15:34:22 2011
+++ src/sys/arch/alpha/alpha/ipifuncs.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.47 2011/06/14 15:34:22 matt Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:53 rmind Exp $ */
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.47 2011/06/14 15:34:22 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:53 rmind Exp $");
 
 /*
  * Interprocessor interrupt handlers.
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v
 #include <sys/reboot.h>
 #include <sys/atomic.h>
 #include <sys/cpu.h>
+#include <sys/ipi.h>
 #include <sys/intr.h>
 #include <sys/xcall.h>
 #include <sys/bitops.h>
@@ -59,12 +60,13 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v
 
 typedef void (*ipifunc_t)(struct cpu_info *, struct trapframe *);
 
-void	alpha_ipi_halt(struct cpu_info *, struct trapframe *);
-void	alpha_ipi_microset(struct cpu_info *, struct trapframe *);
-void	alpha_ipi_imb(struct cpu_info *, struct trapframe *);
-void	alpha_ipi_ast(struct cpu_info *, struct trapframe *);
-void	alpha_ipi_pause(struct cpu_info *, struct trapframe *);
-void	alpha_ipi_xcall(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_halt(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_microset(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_imb(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_ast(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_pause(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_xcall(struct cpu_info *, struct trapframe *);
+static void	alpha_ipi_generic(struct cpu_info *, struct trapframe *);
 
 /*
  * NOTE: This table must be kept in order with the bit definitions
@@ -77,7 +79,8 @@ const ipifunc_t ipifuncs[ALPHA_NIPIS] = 
 	[ilog2(ALPHA_IPI_IMB)] =	alpha_ipi_imb,
 	[ilog2(ALPHA_IPI_AST)] =	alpha_ipi_ast,
 	[ilog2(ALPHA_IPI_PAUSE)] =	alpha_ipi_pause,
-	[ilog2(ALPHA_IPI_XCALL)] =	alpha_ipi_xcall
+	[ilog2(ALPHA_IPI_XCALL)] =	alpha_ipi_xcall,
+	[ilog2(ALPHA_IPI_GENERIC)] =	alpha_ipi_generic
 };
 
 const char * const ipinames[ALPHA_NIPIS] = {
@@ -87,7 +90,8 @@ const char * const ipinames[ALPHA_NIPIS]
 	[ilog2(ALPHA_IPI_IMB)] =	"imb ipi",
 	[ilog2(ALPHA_IPI_AST)] =	"ast ipi",
 	[ilog2(ALPHA_IPI_PAUSE)] =	"pause ipi",
-	[ilog2(ALPHA_IPI_XCALL)] =	"xcall ipi"
+	[ilog2(ALPHA_IPI_XCALL)] =	"xcall ipi",
+	[ilog2(ALPHA_IPI_GENERIC)] =	"generic ipi",
 };
 
 /*
@@ -208,7 +212,7 @@ alpha_multicast_ipi(u_long cpumask, u_lo
 	}
 }
 
-void
+static void
 alpha_ipi_halt(struct cpu_info *ci, struct trapframe *framep)
 {
 	u_long cpu_id = ci->ci_cpuid;
@@ -241,21 +245,21 @@ alpha_ipi_halt(struct cpu_info *ci, stru
 	/* NOTREACHED */
 }
 
-void
+static void
 alpha_ipi_microset(struct cpu_info *ci, struct trapframe *framep)
 {
 
 	cc_calibrate_cpu(ci);
 }
 
-void
+static void
 alpha_ipi_imb(struct cpu_info *ci, struct trapframe *framep)
 {
 
 	alpha_pal_imb();
 }
 
-void
+static void
 alpha_ipi_ast(struct cpu_info *ci, struct trapframe *framep)
 {
 
@@ -263,7 +267,7 @@ alpha_ipi_ast(struct cpu_info *ci, struc
 		aston(ci->ci_curlwp);
 }
 
-void
+static void
 alpha_ipi_pause(struct cpu_info *ci, struct trapframe *framep)
 {
 	u_long cpumask = (1UL << ci->ci_cpuid);
@@ -295,17 +299,15 @@ alpha_ipi_pause(struct cpu_info *ci, str
  * MD support for xcall(9) interface.
  */
 
-void
+static void
 alpha_ipi_xcall(struct cpu_info *ci, struct trapframe *framep)
 {
-
 	xc_ipi_handler();
 }
 
 void
 xc_send_ipi(struct cpu_info *ci)
 {
-
 	KASSERT(kpreempt_disabled());
 	KASSERT(curcpu() != ci);
 
@@ -317,3 +319,24 @@ xc_send_ipi(struct cpu_info *ci)
 		alpha_broadcast_ipi(ALPHA_IPI_XCALL);
 	}
 }
+
+static void
+alpha_ipi_generic(struct cpu_info *ci, struct trapframe *framep)
+{
+	ipi_cpu_handler();
+}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	if (ci) {
+		/* Unicast: remote CPU. */
+		alpha_send_ipi(ci->ci_cpuid, ALPHA_IPI_GENERIC);
+	} else {
+		/* Broadcast: all, but local CPU (caller will handle it). */
+		alpha_broadcast_ipi(ALPHA_IPI_GENERIC);
+	}
+}

Index: src/sys/arch/alpha/include/intr.h
diff -u src/sys/arch/alpha/include/intr.h:1.70 src/sys/arch/alpha/include/intr.h:1.71
--- src/sys/arch/alpha/include/intr.h:1.70	Mon Feb  6 02:14:13 2012
+++ src/sys/arch/alpha/include/intr.h	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.70 2012/02/06 02:14:13 matt Exp $ */
+/* $NetBSD: intr.h,v 1.71 2014/05/19 22:47:53 rmind Exp $ */
 
 /*-
  * Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -164,8 +164,9 @@ _splraise(int s)
 #define	ALPHA_IPI_AST			(1UL << 4)
 #define	ALPHA_IPI_PAUSE			(1UL << 5)
 #define	ALPHA_IPI_XCALL			(1UL << 6)
+#define	ALPHA_IPI_GENERIC		(1UL << 7)
 
-#define	ALPHA_NIPIS		7	/* must not exceed 64 */
+#define	ALPHA_NIPIS			8	/* must not exceed 64 */
 
 struct cpu_info;
 struct trapframe;

Index: src/sys/arch/arm/arm32/arm32_machdep.c
diff -u src/sys/arch/arm/arm32/arm32_machdep.c:1.104 src/sys/arch/arm/arm32/arm32_machdep.c:1.105
--- src/sys/arch/arm/arm32/arm32_machdep.c:1.104	Fri Apr 11 04:19:47 2014
+++ src/sys/arch/arm/arm32/arm32_machdep.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: arm32_machdep.c,v 1.104 2014/04/11 04:19:47 matt Exp $	*/
+/*	$NetBSD: arm32_machdep.c,v 1.105 2014/05/19 22:47:53 rmind Exp $	*/
 
 /*
  * Copyright (c) 1994-1998 Mark Brinicombe.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.104 2014/04/11 04:19:47 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.105 2014/05/19 22:47:53 rmind Exp $");
 
 #include "opt_modular.h"
 #include "opt_md.h"
@@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_machde
 #include <sys/module.h>
 #include <sys/atomic.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -706,6 +707,16 @@ xc_send_ipi(struct cpu_info *ci)
 
 	intr_ipi_send(ci != NULL ? ci->ci_kcpuset : NULL, IPI_XCALL);
 }
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	intr_ipi_send(ci != NULL ? ci->ci_kcpuset : NULL, IPI_GENERIC);
+}
+
 #endif /* MULTIPROCESSOR */
 
 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS

Index: src/sys/arch/arm/cortex/gic.c
diff -u src/sys/arch/arm/cortex/gic.c:1.9 src/sys/arch/arm/cortex/gic.c:1.10
--- src/sys/arch/arm/cortex/gic.c:1.9	Sun Apr 27 16:22:13 2014
+++ src/sys/arch/arm/cortex/gic.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: gic.c,v 1.9 2014/04/27 16:22:13 matt Exp $	*/
+/*	$NetBSD: gic.c,v 1.10 2014/05/19 22:47:53 rmind Exp $	*/
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -33,7 +33,7 @@
 #define _INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.9 2014/04/27 16:22:13 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.10 2014/05/19 22:47:53 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -42,7 +42,6 @@ __KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.9 
 #include <sys/intr.h>
 #include <sys/cpu.h>
 #include <sys/proc.h>
-#include <sys/xcall.h>		/* for xc_ipi_handler */
 
 #include <arm/armreg.h>
 #include <arm/cpufunc.h>
@@ -612,6 +611,8 @@ armgic_attach(device_t parent, device_t 
 	    pic_ipi_nop, (void *)-1);
 	intr_establish(ARMGIC_SGI_IPIBASE + IPI_XCALL, IPL_VM, IST_EDGE,
 	    pic_ipi_xcall, (void *)-1);
+	intr_establish(ARMGIC_SGI_IPIBASE + IPI_GENERIC, IPL_VM, IST_EDGE,
+	    pic_ipi_generic, (void *)-1);
 	intr_establish(ARMGIC_SGI_IPIBASE + IPI_NOP, IPL_VM, IST_EDGE,
 	    pic_ipi_nop, (void *)-1);
 	intr_establish(ARMGIC_SGI_IPIBASE + IPI_SHOOTDOWN, IPL_VM, IST_EDGE,

Index: src/sys/arch/arm/pic/pic.c
diff -u src/sys/arch/arm/pic/pic.c:1.21 src/sys/arch/arm/pic/pic.c:1.22
--- src/sys/arch/arm/pic/pic.c:1.21	Thu Mar 13 23:47:53 2014
+++ src/sys/arch/arm/pic/pic.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: pic.c,v 1.21 2014/03/13 23:47:53 matt Exp $	*/
+/*	$NetBSD: pic.c,v 1.22 2014/05/19 22:47:53 rmind Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -32,7 +32,7 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.21 2014/03/13 23:47:53 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.22 2014/05/19 22:47:53 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.21
 #include <sys/kernel.h>
 #include <sys/kmem.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <arm/armreg.h>
 #include <arm/cpufunc.h>
@@ -107,6 +108,13 @@ pic_ipi_xcall(void *arg)
 	return 1;
 }
 
+int
+pic_ipi_generic(void *arg)
+{
+	ipi_cpu_handler();
+	return 1;
+}
+
 #ifdef DDB
 int
 pic_ipi_ddb(void *arg)

Index: src/sys/arch/arm/pic/picvar.h
diff -u src/sys/arch/arm/pic/picvar.h:1.9 src/sys/arch/arm/pic/picvar.h:1.10
--- src/sys/arch/arm/pic/picvar.h:1.9	Thu Mar 13 23:47:53 2014
+++ src/sys/arch/arm/pic/picvar.h	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: picvar.h,v 1.9 2014/03/13 23:47:53 matt Exp $	*/
+/*	$NetBSD: picvar.h,v 1.10 2014/05/19 22:47:53 rmind Exp $	*/
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -49,11 +49,12 @@ struct cpu_info;
 #define	IPI_NOP			2	/* just get an interrupt (armv6) */
 #define	IPI_SHOOTDOWN		3	/* cause a tlb shootdown */
 #define	IPI_DDB			4	/* enter DDB */
+#define	IPI_GENERIC		5	/* generic IPI */
 #ifdef __HAVE_PREEMPTION
-#define	IPI_KPREEMPT		5	/* cause a preemption */
-#define	NIPI			6
+#define	IPI_KPREEMPT		6	/* cause a preemption */
+#define	NIPI			7
 #else
-#define	NIPI			5
+#define	NIPI			6
 #endif
 
 int	pic_handle_intr(void *);
@@ -160,6 +161,7 @@ void	pic_do_pending_int(void);
 #ifdef MULTIPROCESSOR
 int	pic_ipi_nop(void *);
 int	pic_ipi_xcall(void *);
+int	pic_ipi_generic(void *);
 int	pic_ipi_shootdown(void *);
 int	pic_ipi_ddb(void *);
 #endif

Index: src/sys/arch/hppa/hppa/ipifuncs.c
diff -u src/sys/arch/hppa/hppa/ipifuncs.c:1.2 src/sys/arch/hppa/hppa/ipifuncs.c:1.3
--- src/sys/arch/hppa/hppa/ipifuncs.c:1.2	Thu Apr  5 16:16:01 2012
+++ src/sys/arch/hppa/hppa/ipifuncs.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipifuncs.c,v 1.2 2012/04/05 16:16:01 skrll Exp $	*/
+/*	$NetBSD: ipifuncs.c,v 1.3 2014/05/19 22:47:53 rmind Exp $	*/
 /*	$OpenBSD: ipi.c,v 1.4 2011/01/14 13:20:06 jsing Exp $	*/
 
 /*
@@ -24,6 +24,7 @@
 #include <sys/device.h>
 #include <sys/atomic.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <machine/cpu.h>
 #include <machine/cpufunc.h>
@@ -38,21 +39,22 @@
 
 #include <hppa/hppa/cpuvar.h>
 
-void hppa_ipi_nop(void);
-void hppa_ipi_halt(void);
-void hppa_ipi_xcall(void);
+static void hppa_ipi_nop(void);
+static void hppa_ipi_halt(void);
 
 void (*ipifunc[HPPA_NIPI])(void) =
 {
 	hppa_ipi_nop,
 	hppa_ipi_halt,
-	hppa_ipi_xcall
+	xc_ipi_handler,
+	ipi_cpu_handler,
 };
 
 const char *ipinames[HPPA_NIPI] = {
 	"nop ipi",
 	"halt ipi",
 	"xcall ipi"
+	"generic ipi"
 };
 
 void
@@ -130,16 +132,16 @@ hppa_ipi_broadcast(u_long ipi)
 	return count;	
 }
 
-void
+static void
 hppa_ipi_nop(void)
 {
 }
 
-void
+static void
 hppa_ipi_halt(void)
 {
 	struct cpu_info *ci = curcpu();
-	
+
 	/* Turn off interrupts and halt CPU. */
 // 	hppa_intr_disable();
 	ci->ci_flags &= ~CPUF_RUNNING;
@@ -149,24 +151,31 @@ hppa_ipi_halt(void)
 }
 
 void
-hppa_ipi_xcall(void)
+xc_send_ipi(struct cpu_info *ci)
 {
-	
-	xc_ipi_handler();
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	if (ci) {
+		/* Unicast: remote CPU. */
+		hppa_ipi_send(ci, HPPA_IPI_XCALL);
+	} else {
+		/* Broadcast: all, but local CPU (caller will handle it). */
+		hppa_ipi_broadcast(HPPA_IPI_XCALL);
+	}
 }
 
 void
-xc_send_ipi(struct cpu_info *ci)
+cpu_ipi(struct cpu_info *)
 {
-	
 	KASSERT(kpreempt_disabled());
 	KASSERT(curcpu() != ci);
 
 	if (ci) {
 		/* Unicast: remote CPU. */
-		hppa_ipi_send(ci, HPPA_IPI_XCALL);
+		hppa_ipi_send(ci, HPPA_IPI_GENERIC);
 	} else {
 		/* Broadcast: all, but local CPU (caller will handle it). */
-		hppa_ipi_broadcast(HPPA_IPI_XCALL);
+		hppa_ipi_broadcast(HPPA_IPI_GENERIC);
 	}
 }

Index: src/sys/arch/hppa/include/intrdefs.h
diff -u src/sys/arch/hppa/include/intrdefs.h:1.1 src/sys/arch/hppa/include/intrdefs.h:1.2
--- src/sys/arch/hppa/include/intrdefs.h:1.1	Mon Feb 24 07:23:43 2014
+++ src/sys/arch/hppa/include/intrdefs.h	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: intrdefs.h,v 1.1 2014/02/24 07:23:43 skrll Exp $	*/
+/*	$NetBSD: intrdefs.h,v 1.2 2014/05/19 22:47:53 rmind Exp $	*/
 
 #ifndef _HPPA_INTRDEFS_H_
 #define _HPPA_INTRDEFS_H_
@@ -24,7 +24,8 @@
 #define	HPPA_IPI_NOP		0
 #define	HPPA_IPI_HALT		1
 #define	HPPA_IPI_XCALL		2
-#define	HPPA_NIPI		3
+#define	HPPA_IPI_GENERIC	3
+#define	HPPA_NIPI		4
 #endif
 
 #endif

Index: src/sys/arch/mips/include/intr.h
diff -u src/sys/arch/mips/include/intr.h:1.7 src/sys/arch/mips/include/intr.h:1.8
--- src/sys/arch/mips/include/intr.h:1.7	Sun Mar 11 00:02:05 2012
+++ src/sys/arch/mips/include/intr.h	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.7 2012/03/11 00:02:05 mrg Exp $ */
+/* $NetBSD: intr.h,v 1.8 2014/05/19 22:47:53 rmind Exp $ */
 
 /*-
  * Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@@ -72,7 +72,8 @@
 #define	IPI_SUSPEND	5		/* DDB suspend signaling */
 #define	IPI_HALT	6		/* halt cpu */
 #define	IPI_XCALL	7		/* xcall */
-#define	NIPIS		8
+#define	IPI_GENERIC	8		/* generic IPI */
+#define	NIPIS		9
 
 #ifdef __INTR_PRIVATE
 struct splsw {

Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.16 src/sys/arch/mips/mips/cpu_subr.c:1.17
--- src/sys/arch/mips/mips/cpu_subr.c:1.16	Mon May 21 14:15:18 2012
+++ src/sys/arch/mips/mips/cpu_subr.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu_subr.c,v 1.16 2012/05/21 14:15:18 martin Exp $	*/
+/*	$NetBSD: cpu_subr.c,v 1.17 2014/05/19 22:47:53 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.16 2012/05/21 14:15:18 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.17 2014/05/19 22:47:53 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v
 #include <sys/bitops.h>
 #include <sys/idle.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <uvm/uvm.h>
 
@@ -928,6 +929,13 @@ xc_send_ipi(struct cpu_info *ci)
 
 	(*mips_locoresw.lsw_send_ipi)(ci, IPI_XCALL);
 }
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	(*mips_locoresw.lsw_send_ipi)(ci, IPI_GENERIC);
+}
+
 #endif /* MULTIPROCESSOR */
 
 void

Index: src/sys/arch/mips/mips/ipifuncs.c
diff -u src/sys/arch/mips/mips/ipifuncs.c:1.6 src/sys/arch/mips/mips/ipifuncs.c:1.7
--- src/sys/arch/mips/mips/ipifuncs.c:1.6	Mon May  2 00:17:35 2011
+++ src/sys/arch/mips/mips/ipifuncs.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipifuncs.c,v 1.6 2011/05/02 00:17:35 matt Exp $	*/
+/*	$NetBSD: ipifuncs.c,v 1.7 2014/05/19 22:47:53 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -32,13 +32,14 @@
 #include "opt_ddb.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.6 2011/05/02 00:17:35 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.7 2014/05/19 22:47:53 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
 #include <sys/device.h>
 #include <sys/intr.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -59,6 +60,7 @@ static const char * const ipi_names[] = 
 	[IPI_SUSPEND]	= "ipi suspend",
 	[IPI_HALT]	= "ipi halt",
 	[IPI_XCALL]	= "ipi xcall",
+	[IPI_GENERIC]	= "ipi generic",
 };
 
 static void
@@ -139,6 +141,10 @@ ipi_process(struct cpu_info *ci, uint64_
 		ci->ci_evcnt_per_ipi[IPI_XCALL].ev_count++;
 		xc_ipi_handler();
 	}
+	if (ipi_mask & __BIT(IPI_GENERIC)) {
+		ci->ci_evcnt_per_ipi[IPI_GENERIC].ev_count++;
+		ipi_cpu_handler();
+	}
 }
 
 void

Index: src/sys/arch/powerpc/booke/e500_intr.c
diff -u src/sys/arch/powerpc/booke/e500_intr.c:1.23 src/sys/arch/powerpc/booke/e500_intr.c:1.24
--- src/sys/arch/powerpc/booke/e500_intr.c:1.23	Sat Mar 29 19:28:29 2014
+++ src/sys/arch/powerpc/booke/e500_intr.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: e500_intr.c,v 1.23 2014/03/29 19:28:29 christos Exp $	*/
+/*	$NetBSD: e500_intr.c,v 1.24 2014/05/19 22:47:53 rmind Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,7 +39,7 @@
 #define __INTR_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.23 2014/03/29 19:28:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.24 2014/05/19 22:47:53 rmind Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: e500_intr.c,
 #include <sys/atomic.h>
 #include <sys/bus.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 #include <sys/bitops.h>
 
 #include <uvm/uvm_extern.h>
@@ -1217,6 +1218,7 @@ e500_ipi_kpreempt(void)
 
 static const ipifunc_t e500_ipifuncs[] = {
 	[ilog2(IPI_XCALL)] =	xc_ipi_handler,
+	[ilog2(IPI_GENERIC)] =	ipi_cpu_handler,
 	[ilog2(IPI_HALT)] =	e500_ipi_halt,
 #ifdef __HAVE_PREEMPTION
 	[ilog2(IPI_KPREEMPT)] =	e500_ipi_kpreempt,

Index: src/sys/arch/powerpc/include/booke/intr.h
diff -u src/sys/arch/powerpc/include/booke/intr.h:1.7 src/sys/arch/powerpc/include/booke/intr.h:1.8
--- src/sys/arch/powerpc/include/booke/intr.h:1.7	Sat Mar 29 19:28:29 2014
+++ src/sys/arch/powerpc/include/booke/intr.h	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.h,v 1.7 2014/03/29 19:28:29 christos Exp $	*/
+/*	$NetBSD: intr.h,v 1.8 2014/05/19 22:47:53 rmind Exp $	*/
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -73,6 +73,7 @@
 #define IPI_XCALL	0x0002
 #define	IPI_KPREEMPT	0x0004
 #define IPI_TLB1SYNC	0x0008
+#define IPI_GENERIC	0x0010
 
 #define	__HAVE_FAST_SOFTINTS	1
 #define	SOFTINT_KPREEMPT	SOFTINT_COUNT

Index: src/sys/arch/powerpc/pic/ipi.c
diff -u src/sys/arch/powerpc/pic/ipi.c:1.10 src/sys/arch/powerpc/pic/ipi.c:1.11
--- src/sys/arch/powerpc/pic/ipi.c:1.10	Mon Jun 20 06:23:52 2011
+++ src/sys/arch/powerpc/pic/ipi.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipi.c,v 1.10 2011/06/20 06:23:52 matt Exp $ */
+/* $NetBSD: ipi.c,v 1.11 2014/05/19 22:47:53 rmind Exp $ */
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.10 2011/06/20 06:23:52 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.11 2014/05/19 22:47:53 rmind Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_pic.h"
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.10
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 #include <sys/atomic.h>
 #include <sys/cpu.h>
 
@@ -71,6 +72,9 @@ ipi_intr(void *v)
 	if (ipi & IPI_XCALL)
 		xc_ipi_handler();
 
+	if (ipi & IPI_GENERIC)
+		ipi_cpu_handler();
+
 	if (ipi & IPI_HALT) {
 		aprint_normal("halting CPU %d\n", cpu_id);
 		msr = (mfmsr() & ~PSL_EE) | PSL_POW;

Index: src/sys/arch/powerpc/pic/ipivar.h
diff -u src/sys/arch/powerpc/pic/ipivar.h:1.6 src/sys/arch/powerpc/pic/ipivar.h:1.7
--- src/sys/arch/powerpc/pic/ipivar.h:1.6	Thu Oct 13 19:49:50 2011
+++ src/sys/arch/powerpc/pic/ipivar.h	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipivar.h,v 1.6 2011/10/13 19:49:50 matt Exp $ */
+/* $NetBSD: ipivar.h,v 1.7 2014/05/19 22:47:53 rmind Exp $ */
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipivar.h,v 1.6 2011/10/13 19:49:50 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipivar.h,v 1.7 2014/05/19 22:47:53 rmind Exp $");
 
 #ifndef _IPI_VAR_H_
 #define _IPI_VAR_H_
@@ -54,6 +54,7 @@ struct ipi_ops {
 #define IPI_HALT		0x0001
 #define IPI_XCALL		0x0002
 #define IPI_KPREEMPT		0x0004
+#define IPI_GENERIC		0x0008
 
 /* OpenPIC */
 void setup_openpic_ipi(void);

Index: src/sys/arch/powerpc/powerpc/powerpc_machdep.c
diff -u src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.69 src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.70
--- src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.69	Mon Mar 24 19:14:31 2014
+++ src/sys/arch/powerpc/powerpc/powerpc_machdep.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: powerpc_machdep.c,v 1.69 2014/03/24 19:14:31 christos Exp $	*/
+/*	$NetBSD: powerpc_machdep.c,v 1.70 2014/05/19 22:47:53 rmind Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.69 2014/03/24 19:14:31 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.70 2014/05/19 22:47:53 rmind Exp $");
 
 #include "opt_altivec.h"
 #include "opt_modular.h"
@@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: powerpc_mach
 #include <sys/atomic.h>
 #include <sys/kmem.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <dev/mm.h>
 
@@ -488,6 +489,20 @@ xc_send_ipi(struct cpu_info *ci)
 	/* Broadcast: all, but local CPU (caller will handle it). */
 	cpu_send_ipi(target, IPI_XCALL);
 }
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	cpuid_t target = (ci != NULL ? cpu_index(ci) : IPI_DST_NOTME);
+
+	/* Unicast: remote CPU. */
+	/* Broadcast: all, but local CPU (caller will handle it). */
+	cpu_send_ipi(target, IPI_GENERIC);
+}
+
 #endif /* MULTIPROCESSOR */
 
 #ifdef MODULAR

Index: src/sys/arch/sparc/sparc/cpu.c
diff -u src/sys/arch/sparc/sparc/cpu.c:1.244 src/sys/arch/sparc/sparc/cpu.c:1.245
--- src/sys/arch/sparc/sparc/cpu.c:1.244	Tue Apr 15 10:39:44 2014
+++ src/sys/arch/sparc/sparc/cpu.c	Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: cpu.c,v 1.244 2014/04/15 10:39:44 macallan Exp $ */
+/*	$NetBSD: cpu.c,v 1.245 2014/05/19 22:47:53 rmind Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -52,7 +52,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.244 2014/04/15 10:39:44 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.245 2014/05/19 22:47:53 rmind Exp $");
 
 #include "opt_multiprocessor.h"
 #include "opt_lockdebug.h"
@@ -62,10 +62,10 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.24
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/device.h>
-#include <sys/malloc.h>
 #include <sys/kernel.h>
 #include <sys/evcnt.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 #include <sys/cpu.h>
 
 #include <uvm/uvm.h>
@@ -814,6 +814,21 @@ xc_send_ipi(struct cpu_info *target)
 	XCALL0(xc_ipi_handler, cpuset);
 }
 
+void
+cpu_ipi(struct cpu_info *target)
+{
+	u_int cpuset;
+
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != target);
+
+	if (target)
+		cpuset = 1 << target->ci_cpuid;
+	else
+		cpuset = CPUSET_ALL & ~(1 << cpuinfo.ci_cpuid);
+	XCALL0(ipi_cpu_handler, cpuset);
+}
+
 /*
  * Tell all CPUs other than the current one to enter the PROM idle loop.
  */

Index: src/sys/arch/sparc64/sparc64/ipifuncs.c
diff -u src/sys/arch/sparc64/sparc64/ipifuncs.c:1.47 src/sys/arch/sparc64/sparc64/ipifuncs.c:1.48
--- src/sys/arch/sparc64/sparc64/ipifuncs.c:1.47	Thu Nov  8 16:36:53 2012
+++ src/sys/arch/sparc64/sparc64/ipifuncs.c	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipifuncs.c,v 1.47 2012/11/08 16:36:53 nakayama Exp $ */
+/*	$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:54 rmind Exp $ */
 
 /*-
  * Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -27,14 +27,14 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.47 2012/11/08 16:36:53 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:54 rmind Exp $");
 
 #include "opt_ddb.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/malloc.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <machine/db_machdep.h>
 
@@ -507,3 +507,10 @@ xc_send_ipi(struct cpu_info *target)
 
 	sparc64_generic_xcall(target, (ipi_c_call_func_t)xc_ipi_handler, NULL);
 }
+
+void
+cpu_send_ipi(struct cpu_info *target)
+{
+
+	sparc64_generic_xcall(target, (ipi_c_call_func_t)ipi_cpu_handler, NULL);
+}

Index: src/sys/arch/vax/include/cpu.h
diff -u src/sys/arch/vax/include/cpu.h:1.98 src/sys/arch/vax/include/cpu.h:1.99
--- src/sys/arch/vax/include/cpu.h:1.98	Sun Nov 10 00:50:13 2013
+++ src/sys/arch/vax/include/cpu.h	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/*      $NetBSD: cpu.h,v 1.98 2013/11/10 00:50:13 christos Exp $      */
+/*      $NetBSD: cpu.h,v 1.99 2014/05/19 22:47:54 rmind Exp $      */
 
 /*
  * Copyright (c) 1994 Ludd, University of Lule}, Sweden
@@ -101,6 +101,7 @@ struct cpu_mp_dep {
 #define	IPI_TBIA	4	/* Flush the TLB */
 #define	IPI_DDB		5	/* Jump into the DDB loop */
 #define	IPI_XCALL	6	/* Helper for xcall(9) */
+#define	IPI_GENERIC	7	/* Generic ipi(9) call */
 
 #define	IPI_DEST_MASTER	-1	/* Destination is mastercpu */
 #define	IPI_DEST_ALL	-2	/* Broadcast */

Index: src/sys/arch/vax/vax/multicpu.c
diff -u src/sys/arch/vax/vax/multicpu.c:1.32 src/sys/arch/vax/vax/multicpu.c:1.33
--- src/sys/arch/vax/vax/multicpu.c:1.32	Sun Jun  5 16:59:21 2011
+++ src/sys/arch/vax/vax/multicpu.c	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: multicpu.c,v 1.32 2011/06/05 16:59:21 matt Exp $	*/
+/*	$NetBSD: multicpu.c,v 1.33 2014/05/19 22:47:54 rmind Exp $	*/
 
 /*
  * Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: multicpu.c,v 1.32 2011/06/05 16:59:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: multicpu.c,v 1.33 2014/05/19 22:47:54 rmind Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: multicpu.c,v
 #include <sys/malloc.h>
 #include <sys/proc.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 
 #include <uvm/uvm_extern.h>
 
@@ -198,6 +199,9 @@ cpu_handle_ipi(void)
 		case IPI_XCALL:
 			xc_ipi_handler();
 			break;
+		case IPI_GENERIC:
+			ipi_cpu_handler();
+			break;
 		default:
 			panic("cpu_handle_ipi: bad bit %x", bitno);
 		}
@@ -212,7 +216,6 @@ cpu_handle_ipi(void)
 void
 xc_send_ipi(struct cpu_info *ci)
 {
-
 	KASSERT(kpreempt_disabled());
 	KASSERT(curcpu() != ci);
 
@@ -224,3 +227,18 @@ xc_send_ipi(struct cpu_info *ci)
 		cpu_send_ipi(IPI_DEST_ALL, IPI_XCALL);
 	}
 }
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	if (ci) {
+		/* Unicast: remote CPU. */
+		cpu_send_ipi(ci->ci_cpuid, IPI_GENERIC);
+	} else {
+		/* Broadcast: all, but local CPU (caller will handle it). */
+		cpu_send_ipi(IPI_DEST_ALL, IPI_GENERIC);
+	}
+}

Index: src/sys/arch/x86/include/intrdefs.h
diff -u src/sys/arch/x86/include/intrdefs.h:1.19 src/sys/arch/x86/include/intrdefs.h:1.20
--- src/sys/arch/x86/include/intrdefs.h:1.19	Sun Dec  1 01:05:16 2013
+++ src/sys/arch/x86/include/intrdefs.h	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: intrdefs.h,v 1.19 2013/12/01 01:05:16 christos Exp $	*/
+/*	$NetBSD: intrdefs.h,v 1.20 2014/05/19 22:47:54 rmind Exp $	*/
 
 #ifndef _X86_INTRDEFS_H_
 #define _X86_INTRDEFS_H_
@@ -60,7 +60,7 @@
 
 #define X86_IPI_HALT			0x00000001
 #define X86_IPI_MICROSET		0x00000002
-#define X86_IPI__UNUSED1		0x00000004
+#define X86_IPI_GENERIC			0x00000004
 #define X86_IPI_SYNCH_FPU		0x00000008
 #define X86_IPI_MTRR			0x00000010
 #define X86_IPI_GDT			0x00000020
@@ -70,7 +70,7 @@
 
 #define X86_NIPI		9
 
-#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "unused", \
+#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "generic IPI", \
 			 "FPU synch IPI", "MTRR update IPI", \
 			 "GDT update IPI", "xcall IPI", \
 			 "ACPI CPU sleep IPI", "kpreempt IPI" }

Index: src/sys/arch/x86/x86/ipi.c
diff -u src/sys/arch/x86/x86/ipi.c:1.23 src/sys/arch/x86/x86/ipi.c:1.24
--- src/sys/arch/x86/x86/ipi.c:1.23	Wed Feb 19 21:23:02 2014
+++ src/sys/arch/x86/x86/ipi.c	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ipi.c,v 1.23 2014/02/19 21:23:02 dsl Exp $	*/
+/*	$NetBSD: ipi.c,v 1.24 2014/05/19 22:47:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2000, 2008, 2009 The NetBSD Foundation, Inc.
@@ -32,18 +32,19 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.23 2014/02/19 21:23:02 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.24 2014/05/19 22:47:54 rmind Exp $");
 
 #include "opt_mtrr.h"
 
-#include <sys/param.h> 
+#include <sys/param.h>
 #include <sys/device.h>
 #include <sys/systm.h>
 #include <sys/atomic.h>
 #include <sys/intr.h>
+#include <sys/ipi.h>
 #include <sys/cpu.h>
 #include <sys/xcall.h>
- 
+
 #ifdef MULTIPROCESSOR
 
 #include <machine/cpufunc.h>
@@ -61,6 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.23
 static void	x86_ipi_halt(struct cpu_info *);
 static void	x86_ipi_kpreempt(struct cpu_info *);
 static void	x86_ipi_xcall(struct cpu_info *);
+static void	x86_ipi_generic(struct cpu_info *);
 
 #ifdef MTRR
 static void	x86_ipi_reload_mtrr(struct cpu_info *);
@@ -80,7 +82,7 @@ void (*ipifunc[X86_NIPI])(struct cpu_inf
 {
 	x86_ipi_halt,
 	NULL,
-	NULL,
+	x86_ipi_generic,
 	x86_ipi_synch_fpu,
 	x86_ipi_reload_mtrr,
 	gdt_reload_cpu,
@@ -206,10 +208,15 @@ x86_ipi_kpreempt(struct cpu_info *ci)
 static void
 x86_ipi_xcall(struct cpu_info *ci)
 {
-
 	xc_ipi_handler();
 }
 
+static void
+x86_ipi_generic(struct cpu_info *ci)
+{
+	ipi_cpu_handler();
+}
+
 void
 xc_send_ipi(struct cpu_info *ci)
 {
@@ -226,6 +233,21 @@ xc_send_ipi(struct cpu_info *ci)
 	}
 }
 
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	if (ci) {
+		/* Unicast: remote CPU. */
+		x86_send_ipi(ci, X86_IPI_GENERIC);
+	} else {
+		/* Broadcast: all, but local CPU (caller will handle it). */
+		x86_broadcast_ipi(X86_IPI_GENERIC);
+	}
+}
+
 #else
 
 int
@@ -241,4 +263,9 @@ x86_broadcast_ipi(int ipimask)
 
 }
 
+void
+cpu_ipi(struct cpu_info *ci)
+{
+}
+
 #endif

Index: src/sys/arch/xen/include/intrdefs.h
diff -u src/sys/arch/xen/include/intrdefs.h:1.11 src/sys/arch/xen/include/intrdefs.h:1.12
--- src/sys/arch/xen/include/intrdefs.h:1.11	Mon Nov  7 15:51:31 2011
+++ src/sys/arch/xen/include/intrdefs.h	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intrdefs.h,v 1.11 2011/11/07 15:51:31 cherry Exp $ */
+/* $NetBSD: intrdefs.h,v 1.12 2014/05/19 22:47:54 rmind Exp $ */
 
 /* This file co-exists, and is included via machine/intrdefs.h */
 
@@ -12,7 +12,9 @@
 #define XEN_IPI_DDB		0x00000004
 #define XEN_IPI_XCALL		0x00000008
 #define XEN_IPI_HVCB		0x00000010
+#define XEN_IPI_GENERIC		0x00000020
 
-#define XEN_NIPIS 5 /* IPI_KICK doesn't have a handler */
+/* Note: IPI_KICK does not have a handler. */
+#define XEN_NIPIS		6
 
 #endif /* _XEN_INTRDEFS_H_ */

Index: src/sys/arch/xen/x86/xen_ipi.c
diff -u src/sys/arch/xen/x86/xen_ipi.c:1.17 src/sys/arch/xen/x86/xen_ipi.c:1.18
--- src/sys/arch/xen/x86/xen_ipi.c:1.17	Wed Feb 12 23:24:09 2014
+++ src/sys/arch/xen/x86/xen_ipi.c	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $ */
+/* $NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -33,10 +33,10 @@
 
 /* 
  * Based on: x86/ipi.c
- * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $"); 
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $"); 
  */
 
-__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $");
 
 #include <sys/types.h>
 
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 
 #include <sys/mutex.h>
 #include <sys/device.h>
 #include <sys/xcall.h>
+#include <sys/ipi.h>
 #include <sys/errno.h>
 #include <sys/systm.h>
 
@@ -69,6 +70,7 @@ static void xen_ipi_synch_fpu(struct cpu
 static void xen_ipi_ddb(struct cpu_info *, struct intrframe *);
 static void xen_ipi_xcall(struct cpu_info *, struct intrframe *);
 static void xen_ipi_hvcb(struct cpu_info *, struct intrframe *);
+static void xen_ipi_generic(struct cpu_info *, struct intrframe *);
 
 static void (*ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) =
 {	/* In order of priority (see: xen/include/intrdefs.h */
@@ -76,7 +78,8 @@ static void (*ipifunc[XEN_NIPIS])(struct
 	xen_ipi_synch_fpu,
 	xen_ipi_ddb,
 	xen_ipi_xcall,
-	xen_ipi_hvcb
+	xen_ipi_hvcb,
+	xen_ipi_generic,
 };
 
 static void
@@ -131,7 +134,7 @@ xen_ipi_init(void)
 static inline bool /* helper */
 valid_ipimask(uint32_t ipimask)
 {
-	uint32_t masks =  XEN_IPI_HVCB | XEN_IPI_XCALL |
+	uint32_t masks = XEN_IPI_GENERIC | XEN_IPI_HVCB | XEN_IPI_XCALL |
 		 XEN_IPI_DDB | XEN_IPI_SYNCH_FPU |
 		 XEN_IPI_HALT | XEN_IPI_KICK;
 
@@ -285,6 +288,29 @@ xc_send_ipi(struct cpu_info *ci)
 }
 
 static void
+xen_ipi_generic(struct cpu_info *ci, struct intrframe *intrf)
+{
+	KASSERT(ci != NULL);
+	KASSERT(intrf != NULL);
+
+	ipi_cpu_handler();
+}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+	if (ci) {
+		if (0 != xen_send_ipi(ci, XEN_IPI_GENERIC)) {
+			panic("xen_send_ipi(XEN_IPI_GENERIC) failed\n");
+		}
+	} else {
+		xen_broadcast_ipi(XEN_IPI_GENERIC);
+	}
+}
+
+static void
 xen_ipi_hvcb(struct cpu_info *ci, struct intrframe *intrf)
 {
 	KASSERT(ci != NULL);

Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1090 src/sys/conf/files:1.1091
--- src/sys/conf/files:1.1090	Tue Apr  1 17:49:30 2014
+++ src/sys/conf/files	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-#	$NetBSD: files,v 1.1090 2014/04/01 17:49:30 riastradh Exp $
+#	$NetBSD: files,v 1.1091 2014/05/19 22:47:54 rmind Exp $
 #	@(#)files.newconf	7.5 (Berkeley) 5/10/93
 
 version 	20100430
@@ -1598,6 +1598,7 @@ file	kern/subr_extent.c
 file	kern/subr_hash.c
 file	kern/subr_humanize.c
 file	kern/subr_iostat.c
+file	kern/subr_ipi.c
 file	kern/subr_kcpuset.c
 file	kern/subr_kmem.c
 file	kern/subr_kobj.c

Index: src/sys/kern/init_main.c
diff -u src/sys/kern/init_main.c:1.454 src/sys/kern/init_main.c:1.455
--- src/sys/kern/init_main.c:1.454	Wed Oct  2 21:38:55 2013
+++ src/sys/kern/init_main.c	Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $	*/
+/*	$NetBSD: init_main.c,v 1.455 2014/05/19 22:47:54 rmind Exp $	*/
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.455 2014/05/19 22:47:54 rmind Exp $");
 
 #include "opt_ddb.h"
 #include "opt_ipsec.h"
@@ -157,6 +157,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,
 #include <sys/mbuf.h>
 #include <sys/sched.h>
 #include <sys/sleepq.h>
+#include <sys/ipi.h>
 #include <sys/iostat.h>
 #include <sys/vmem.h>
 #include <sys/uuid.h>
@@ -307,6 +308,7 @@ main(void)
 
 	uvm_init();
 	kcpuset_sysinit();
+	ipi_sysinit();
 
 	prop_kern_init();
 

Added files:

Index: src/sys/kern/subr_ipi.c
diff -u /dev/null src/sys/kern/subr_ipi.c:1.1
--- /dev/null	Mon May 19 22:47:54 2014
+++ src/sys/kern/subr_ipi.c	Mon May 19 22:47:54 2014
@@ -0,0 +1,238 @@
+/*	$NetBSD: subr_ipi.c,v 1.1 2014/05/19 22:47:54 rmind Exp $	*/
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Inter-processor interrupt (IPI) interface with cross-call support.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: subr_ipi.c,v 1.1 2014/05/19 22:47:54 rmind Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sys/atomic.h>
+#include <sys/evcnt.h>
+#include <sys/cpu.h>
+#include <sys/ipi.h>
+#include <sys/kcpuset.h>
+#include <sys/kmem.h>
+#include <sys/lock.h>
+
+/*
+ * Per-CPU mailbox for IPI messages: it is a single cache line storing
+ * up to IPI_MSG_MAX messages.
+ */
+
+#define	IPI_MSG_SLOTS	(CACHE_LINE_SIZE / sizeof(ipi_msg_t *))
+#define	IPI_MSG_MAX	IPI_MSG_SLOTS
+
+typedef struct {
+	ipi_msg_t *	msg[IPI_MSG_SLOTS];
+} ipi_mbox_t;
+
+static ipi_mbox_t *	ipi_mboxes	__read_mostly;
+static struct evcnt	ipi_mboxfull_ev	__cacheline_aligned;
+
+#ifndef MULTIPROCESSOR
+#define	cpu_ipi(ci)	KASSERT(ci == NULL)
+#endif
+
+void
+ipi_sysinit(void)
+{
+	const size_t len = ncpu * sizeof(ipi_mbox_t);
+
+	/* Allocate per-CPU IPI mailboxes. */
+	ipi_mboxes = kmem_zalloc(len, KM_SLEEP);
+	KASSERT(ipi_mboxes != NULL);
+
+	evcnt_attach_dynamic(&ipi_mboxfull_ev, EVCNT_TYPE_MISC, NULL,
+	   "ipi", "full");
+}
+
+/*
+ * put_msg: insert message into the mailbox.
+ */
+static inline void
+put_msg(ipi_mbox_t *mbox, ipi_msg_t *msg)
+{
+	int count = SPINLOCK_BACKOFF_MIN;
+again:
+	for (u_int i = 0; i < IPI_MSG_MAX; i++) {
+		if (__predict_true(mbox->msg[i] == NULL) &&
+		    atomic_cas_ptr(&mbox->msg[i], NULL, msg) == NULL) {
+			return;
+		}
+	}
+
+	/* All slots are full: we have to spin-wait. */
+	ipi_mboxfull_ev.ev_count++;
+	SPINLOCK_BACKOFF(count);
+	goto again;
+}
+
+/*
+ * ipi_cpu_handler: the IPI handler.
+ */
+void
+ipi_cpu_handler(void)
+{
+	const struct cpu_info * const ci = curcpu();
+	ipi_mbox_t *mbox = &ipi_mboxes[cpu_index(ci)];
+
+	KASSERT(curcpu() == ci);
+
+	for (u_int i = 0; i < IPI_MSG_MAX; i++) {
+		ipi_msg_t *msg;
+
+		/* Get the message. */
+		if ((msg = mbox->msg[i]) == NULL) {
+			continue;
+		}
+		mbox->msg[i] = NULL;
+
+		/* Execute the handler. */
+		KASSERT(msg->func);
+		msg->func(msg->arg);
+
+		/* Ack the request. */
+		atomic_dec_uint(&msg->_pending);
+	}
+}
+
+/*
+ * ipi_unicast: send an IPI to a single CPU.
+ *
+ * => The CPU must be remote; must not be local.
+ * => The caller must ipi_wait() on the message for completion.
+ */
+void
+ipi_unicast(ipi_msg_t *msg, struct cpu_info *ci)
+{
+	const cpuid_t id = cpu_index(ci);
+
+	KASSERT(msg->func != NULL);
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+
+	msg->_pending = 1;
+	membar_producer();
+
+	put_msg(&ipi_mboxes[id], msg);
+	cpu_ipi(ci);
+}
+
+/*
+ * ipi_multicast: send an IPI to each CPU in the specified set.
+ *
+ * => The caller must ipi_wait() on the message for completion.
+ */
+void
+ipi_multicast(ipi_msg_t *msg, const kcpuset_t *target)
+{
+	const struct cpu_info * const self = curcpu();
+	CPU_INFO_ITERATOR cii;
+	struct cpu_info *ci;
+	u_int local;
+
+	KASSERT(msg->func != NULL);
+	KASSERT(kpreempt_disabled());
+
+	local = !!kcpuset_isset(target, cpu_index(self));
+	msg->_pending = kcpuset_countset(target) - local;
+	membar_producer();
+
+	for (CPU_INFO_FOREACH(cii, ci)) {
+		cpuid_t id;
+
+		if (__predict_false(ci == self)) {
+			continue;
+		}
+		id = cpu_index(ci);
+		if (!kcpuset_isset(target, id)) {
+			continue;
+		}
+		put_msg(&ipi_mboxes[id], msg);
+		cpu_ipi(ci);
+	}
+	if (local) {
+		msg->func(msg->arg);
+	}
+}
+
+/*
+ * ipi_broadcast: send an IPI to all CPUs.
+ *
+ * => The caller must ipi_wait() on the message for completion.
+ */
+void
+ipi_broadcast(ipi_msg_t *msg)
+{
+	const struct cpu_info * const self = curcpu();
+	CPU_INFO_ITERATOR cii;
+	struct cpu_info *ci;
+
+	KASSERT(msg->func != NULL);
+	KASSERT(kpreempt_disabled());
+
+	msg->_pending = ncpu - 1;
+	membar_producer();
+
+	/* Broadcast IPIs for remote CPUs. */
+	for (CPU_INFO_FOREACH(cii, ci)) {
+		cpuid_t id;
+
+		if (__predict_false(ci == self)) {
+			continue;
+		}
+		id = cpu_index(ci);
+		put_msg(&ipi_mboxes[id], msg);
+	}
+	cpu_ipi(NULL);
+
+	/* Finally, execute locally. */
+	msg->func(msg->arg);
+}
+
+/*
+ * ipi_wait: spin-wait until the message is processed.
+ */
+void
+ipi_wait(ipi_msg_t *msg)
+{
+	int count = SPINLOCK_BACKOFF_MIN;
+
+	while (msg->_pending) {
+		KASSERT(msg->_pending < ncpu);
+		SPINLOCK_BACKOFF(count);
+	}
+}

Index: src/sys/sys/ipi.h
diff -u /dev/null src/sys/sys/ipi.h:1.1
--- /dev/null	Mon May 19 22:47:54 2014
+++ src/sys/sys/ipi.h	Mon May 19 22:47:54 2014
@@ -0,0 +1,62 @@
+/*	$NetBSD: ipi.h,v 1.1 2014/05/19 22:47:54 rmind Exp $	*/
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_IPI_H_
+#define _SYS_IPI_H_
+
+#if !defined(_KERNEL) && !defined(_KMEMUSER)
+#error "not supposed to be exposed to userland"
+#endif
+
+typedef void (*ipi_func_t)(void *);
+
+typedef struct {
+	/* Public: function handler and an argument. */
+	ipi_func_t	func;
+	void *		arg;
+
+	/* Private (internal) elements. */
+	volatile u_int	_pending;
+} ipi_msg_t;
+
+void	ipi_sysinit(void);
+void	ipi_cpu_handler(void);
+void	cpu_ipi(struct cpu_info *);
+
+/*
+ * Public ipi(9) API.
+ */
+void	ipi_unicast(ipi_msg_t *, struct cpu_info *);
+void	ipi_multicast(ipi_msg_t *, const kcpuset_t *);
+void	ipi_broadcast(ipi_msg_t *);
+void	ipi_wait(ipi_msg_t *);
+
+#endif

Reply via email to