Module Name:    src
Committed By:   cherry
Date:           Wed Aug 10 11:39:46 UTC 2011

Modified Files:
        src/sys/arch/amd64/amd64: fpu.c machdep.c
        src/sys/arch/i386/isa: npx.c
        src/sys/arch/x86/x86: x86_machdep.c
        src/sys/arch/xen/conf: files.xen
        src/sys/arch/xen/include: intr.h
Added Files:
        src/sys/arch/xen/x86: xen_ipi.c

Log Message:
xen ipi infrastructure


To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/sys/arch/amd64/amd64/fpu.c
cvs rdiff -u -r1.162 -r1.163 src/sys/arch/amd64/amd64/machdep.c
cvs rdiff -u -r1.140 -r1.141 src/sys/arch/i386/isa/npx.c
cvs rdiff -u -r1.53 -r1.54 src/sys/arch/x86/x86/x86_machdep.c
cvs rdiff -u -r1.121 -r1.122 src/sys/arch/xen/conf/files.xen
cvs rdiff -u -r1.31 -r1.32 src/sys/arch/xen/include/intr.h
cvs rdiff -u -r0 -r1.2 src/sys/arch/xen/x86/xen_ipi.c

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/amd64/amd64/fpu.c
diff -u src/sys/arch/amd64/amd64/fpu.c:1.35 src/sys/arch/amd64/amd64/fpu.c:1.36
--- src/sys/arch/amd64/amd64/fpu.c:1.35	Fri Jul  1 19:24:14 2011
+++ src/sys/arch/amd64/amd64/fpu.c	Wed Aug 10 11:39:44 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: fpu.c,v 1.35 2011/07/01 19:24:14 dyoung Exp $	*/
+/*	$NetBSD: fpu.c,v 1.36 2011/08/10 11:39:44 cherry Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.  All
@@ -100,7 +100,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.35 2011/07/01 19:24:14 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.36 2011/08/10 11:39:44 cherry Exp $");
 
 #include "opt_multiprocessor.h"
 
@@ -406,7 +406,11 @@
 			break;
 		}
 		splx(s);
+#ifdef XEN
+		xen_send_ipi(oci, XEN_IPI_SYNCH_FPU);
+#else /* XEN */
 		x86_send_ipi(oci, X86_IPI_SYNCH_FPU);
+#endif
 		while (pcb->pcb_fpcpu == oci && ticks == hardclock_ticks) {
 			x86_pause();
 			spins++;

Index: src/sys/arch/amd64/amd64/machdep.c
diff -u src/sys/arch/amd64/amd64/machdep.c:1.162 src/sys/arch/amd64/amd64/machdep.c:1.163
--- src/sys/arch/amd64/amd64/machdep.c:1.162	Sun Jul 17 15:16:58 2011
+++ src/sys/arch/amd64/amd64/machdep.c	Wed Aug 10 11:39:45 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.162 2011/07/17 15:16:58 jym Exp $	*/
+/*	$NetBSD: machdep.c,v 1.163 2011/08/10 11:39:45 cherry Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008
@@ -107,7 +107,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.162 2011/07/17 15:16:58 jym Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.163 2011/08/10 11:39:45 cherry Exp $");
 
 /* #define XENDEBUG_LOW  */
 
@@ -719,7 +719,11 @@
 #endif /* XEN */
 	}
 
+#ifdef XEN
+	xen_broadcast_ipi(XEN_IPI_HALT);
+#else /* XEN */
 	x86_broadcast_ipi(X86_IPI_HALT);
+#endif
 
 	if (howto & RB_HALT) {
 #if NACPICA > 0

Index: src/sys/arch/i386/isa/npx.c
diff -u src/sys/arch/i386/isa/npx.c:1.140 src/sys/arch/i386/isa/npx.c:1.141
--- src/sys/arch/i386/isa/npx.c:1.140	Tue Jun  7 14:53:03 2011
+++ src/sys/arch/i386/isa/npx.c	Wed Aug 10 11:39:45 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: npx.c,v 1.140 2011/06/07 14:53:03 bouyer Exp $	*/
+/*	$NetBSD: npx.c,v 1.141 2011/08/10 11:39:45 cherry Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.140 2011/06/07 14:53:03 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npx.c,v 1.141 2011/08/10 11:39:45 cherry Exp $");
 
 #if 0
 #define IPRINTF(x)	printf x
@@ -719,7 +719,11 @@
 			break;
 		}
 		splx(s);
+#ifdef XEN
+		xen_send_ipi(oci, XEN_IPI_SYNCH_FPU);
+#else /* XEN */
 		x86_send_ipi(oci, X86_IPI_SYNCH_FPU);
+#endif
 		while (pcb->pcb_fpcpu == oci &&
 		    ticks == hardclock_ticks) {
 			x86_pause();

Index: src/sys/arch/x86/x86/x86_machdep.c
diff -u src/sys/arch/x86/x86/x86_machdep.c:1.53 src/sys/arch/x86/x86/x86_machdep.c:1.54
--- src/sys/arch/x86/x86/x86_machdep.c:1.53	Mon Aug  1 11:26:31 2011
+++ src/sys/arch/x86/x86/x86_machdep.c	Wed Aug 10 11:39:45 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: x86_machdep.c,v 1.53 2011/08/01 11:26:31 jmcneill Exp $	*/
+/*	$NetBSD: x86_machdep.c,v 1.54 2011/08/10 11:39:45 cherry Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi,
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.53 2011/08/01 11:26:31 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.54 2011/08/10 11:39:45 cherry Exp $");
 
 #include "opt_modular.h"
 #include "opt_physmem.h"
@@ -204,10 +204,13 @@
 	if (l == ci->ci_data.cpu_idlelwp) {
 		if (ci == cur)
 			return;
-#ifndef XEN /* XXX review when Xen gets MP support */
-		if (x86_cpu_idle_ipi != false)
+		if (x86_cpu_idle_ipi != false) {
+#ifdef XEN
+			xen_send_ipi(ci, XEN_IPI_KICK);
+#else /* XEN */
 			x86_send_ipi(ci, 0);
-#endif
+#endif /* XEN */
+		}
 		return;
 	}
 
@@ -228,7 +231,11 @@
 		return;
 	}
 	if ((flags & RESCHED_IMMED) != 0) {
+#ifdef XEN
+		xen_send_ipi(ci, XEN_IPI_KICK);
+#else /* XEN */
 		x86_send_ipi(ci, 0);
+#endif /* XEN */
 	}
 }
 
@@ -239,7 +246,11 @@
 	KASSERT(kpreempt_disabled());
 	aston(l, X86_AST_GENERIC);
 	if (l->l_cpu != curcpu())
+#ifdef XEN
+		xen_send_ipi(l->l_cpu, XEN_IPI_KICK);
+#else /* XEN */
 		x86_send_ipi(l->l_cpu, 0);
+#endif /* XEN */
 }
 
 void
@@ -363,7 +374,7 @@
 	else
 		x86_cpu_idle_set(x86_cpu_idle_mwait, "mwait", false);
 #else
-	x86_cpu_idle_set(x86_cpu_idle_xen, "xen", false);
+	x86_cpu_idle_set(x86_cpu_idle_xen, "xen", true);
 #endif
 }
 

Index: src/sys/arch/xen/conf/files.xen
diff -u src/sys/arch/xen/conf/files.xen:1.121 src/sys/arch/xen/conf/files.xen:1.122
--- src/sys/arch/xen/conf/files.xen:1.121	Mon Jun 13 00:53:15 2011
+++ src/sys/arch/xen/conf/files.xen	Wed Aug 10 11:39:45 2011
@@ -1,4 +1,4 @@
-#	$NetBSD: files.xen,v 1.121 2011/06/13 00:53:15 pgoyette Exp $
+#	$NetBSD: files.xen,v 1.122 2011/08/10 11:39:45 cherry Exp $
 #	NetBSD: files.x86,v 1.10 2003/10/08 17:30:00 bouyer Exp 
 #	NetBSD: files.i386,v 1.254 2004/03/25 23:32:10 jmc Exp 
 
@@ -56,7 +56,6 @@
 file	arch/i386/i386/trap.c
 file	arch/i386/i386/lock_stubs.S
 
-file	arch/i386/i386/mptramp.S		multiprocessor
 
 file	arch/i386/i386/pmc.c			perfctrs
 
@@ -82,7 +81,6 @@
 file	arch/amd64/amd64/trap.c
 file	arch/amd64/amd64/fpu.c
 file	arch/amd64/amd64/lock_stubs.S
-file	arch/amd64/amd64/mptramp.S		multiprocessor
 endif
 
 file	kern/subr_disk_mbr.c		disk
@@ -129,7 +127,7 @@
 file	arch/xen/x86/consinit.c
 file	arch/x86/x86/identcpu.c
 file	arch/xen/x86/intr.c
-file	arch/x86/x86/ipi.c
+file	arch/xen/x86/xen_ipi.c		multiprocessor
 file	arch/x86/x86/pmap.c
 file	arch/x86/x86/pmap_tlb.c
 file	arch/x86/x86/procfs_machdep.c	procfs

Index: src/sys/arch/xen/include/intr.h
diff -u src/sys/arch/xen/include/intr.h:1.31 src/sys/arch/xen/include/intr.h:1.32
--- src/sys/arch/xen/include/intr.h:1.31	Wed Jul 29 12:02:06 2009
+++ src/sys/arch/xen/include/intr.h	Wed Aug 10 11:39:45 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: intr.h,v 1.31 2009/07/29 12:02:06 cegger Exp $	*/
+/*	$NetBSD: intr.h,v 1.32 2011/08/10 11:39:45 cherry Exp $	*/
 /*	NetBSD intr.h,v 1.15 2004/10/31 10:39:34 yamt Exp	*/
 
 /*-
@@ -175,9 +175,15 @@
 struct pic *intr_findpic(int);
 void intr_add_pcibus(struct pcibus_attach_args *);
 
-int x86_send_ipi(struct cpu_info *, int);
-void x86_broadcast_ipi(int);
-void x86_multicast_ipi(int, int);
+#ifdef MULTIPROCESSOR
+void xen_ipi_init(void);
+int xen_send_ipi(struct cpu_info *, uint32_t);
+void xen_broadcast_ipi(uint32_t);
+#else
+#define xen_ipi_init(_1) do {} while(0) /* nothing */
+#define xen_send_ipi(_i1, _i2) do {} while(0) /* nothing */
+#define xen_broadcast_ipi(_i1) do {} while(0) /* nothing */
+#endif /* MULTIPROCESSOR */
 
 #endif /* !_LOCORE */
 

Added files:

Index: src/sys/arch/xen/x86/xen_ipi.c
diff -u /dev/null src/sys/arch/xen/x86/xen_ipi.c:1.2
--- /dev/null	Wed Aug 10 11:39:46 2011
+++ src/sys/arch/xen/x86/xen_ipi.c	Wed Aug 10 11:39:46 2011
@@ -0,0 +1,311 @@
+/* $NetBSD: xen_ipi.c,v 1.2 2011/08/10 11:39:46 cherry Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Cherry G. Mathew <che...@zyx.in>
+ *
+ * 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.
+ */
+
+#include <sys/cdefs.h>			/* RCS ID macro */
+
+/* 
+ * Based on: x86/ipi.c
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.2 2011/08/10 11:39:46 cherry Exp $"); 
+ */
+
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.2 2011/08/10 11:39:46 cherry Exp $");
+
+#include <sys/types.h>
+
+#include <sys/atomic.h>
+#include <sys/mutex.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+#include <sys/xcall.h>
+#include <sys/errno.h>
+#include <sys/systm.h>
+
+#include <machine/cpu.h>
+#ifdef __x86_64__
+#include <machine/fpu.h>
+#else
+#include <machine/npx.h>
+#endif /* __x86_64__ */
+#include <machine/frame.h>
+#include <machine/segments.h>
+
+#include <xen/intr.h>
+#include <xen/intrdefs.h>
+#include <xen/hypervisor.h>
+#include <xen/xen3-public/vcpu.h>
+
+#ifdef __x86_64__
+extern void ddb_ipi(struct trapframe);
+#else
+extern void ddb_ipi(int, struct trapframe);
+#endif /* __x86_64__ */
+
+static void xen_ipi_halt(struct cpu_info *, struct intrframe *);
+static void xen_ipi_synch_fpu(struct cpu_info *, struct intrframe *);
+static void xen_ipi_ddb(struct cpu_info *, struct intrframe *);
+static void xen_ipi_xcall(struct cpu_info *, struct intrframe *);
+
+static void (*ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) =
+{	/* In order of priority (see: xen/include/intrdefs.h */
+	xen_ipi_halt,
+	xen_ipi_synch_fpu,
+	xen_ipi_ddb,
+	xen_ipi_xcall
+};
+
+static void
+xen_ipi_handler(struct cpu_info *ci, struct intrframe *regs)
+{
+	uint32_t pending;
+	int bit;
+
+	pending = atomic_swap_32(&ci->ci_ipis, 0);
+
+	KDASSERT((pending >> XEN_NIPIS) == 0);
+	while ((bit = ffs(pending)) != 0) {
+		bit--;
+		pending &= ~(1 << bit);
+		ci->ci_ipi_events[bit].ev_count++;
+		if (ipifunc[bit] != NULL) {
+			(*ipifunc[bit])(ci, regs);
+		}
+		else {
+			panic("ipifunc[%d] unsupported!\n", bit);
+			/* NOTREACHED */
+		}
+	}
+
+	return;
+}
+
+/* Must be called once for every cpu that expects to send/recv ipis */
+void
+xen_ipi_init(void)
+{
+	cpuid_t vcpu;
+	evtchn_port_t evtchn;
+	struct cpu_info *ci;
+
+	ci = curcpu();
+
+	vcpu = ci->ci_cpuid;
+	KASSERT(vcpu < MAX_VIRT_CPUS);
+
+	evtchn = ci->ci_ipi_evtchn = bind_vcpu_to_evtch(vcpu);
+
+	KASSERT(evtchn != -1 && evtchn < NR_EVENT_CHANNELS);
+
+	if (0 != event_set_handler(evtchn, (int (*)(void *))xen_ipi_handler,
+				   ci, IPL_HIGH, "ipi")) {
+		panic("event_set_handler(...) KPI violation\n");
+		/* NOTREACHED */
+	}
+
+	hypervisor_enable_event(evtchn);
+	return;
+}
+
+/* prefer this to global variable */
+static inline u_int max_cpus(void)
+{
+	return maxcpus;
+}
+
+static inline bool /* helper */
+valid_ipimask(uint32_t ipimask)
+{
+	uint32_t masks =  XEN_IPI_XCALL | XEN_IPI_DDB | 
+		XEN_IPI_SYNCH_FPU | XEN_IPI_HALT | 
+		XEN_IPI_KICK;
+
+	if (ipimask & ~masks) {
+		return false;
+	}
+	else {
+		return true;
+	}
+
+}
+
+int
+xen_send_ipi(struct cpu_info *ci, uint32_t ipimask)
+{
+	evtchn_port_t evtchn;
+
+	KASSERT(ci != NULL || ci != curcpu());
+
+	if (!(ci->ci_flags & CPUF_RUNNING)) {
+		return ENOENT;
+	}
+
+	evtchn = ci->ci_ipi_evtchn;
+	if (false == valid_ipimask(ipimask)) {
+		panic("xen_send_ipi() called with invalid ipimask\n");
+		/* NOTREACHED */
+	}
+
+	atomic_or_32(&ci->ci_ipis, ipimask);
+	hypervisor_notify_via_evtchn(evtchn);
+
+	return 0;
+}
+
+void
+xen_broadcast_ipi(uint32_t ipimask)
+{
+	struct cpu_info *ci, *self = curcpu();
+	CPU_INFO_ITERATOR cii;
+
+	if (false == valid_ipimask(ipimask)) {
+		panic("xen_broadcast_ipi() called with invalid ipimask\n");
+		/* NOTREACHED */
+	}
+
+	/* 
+	 * XXX-cherry: there's an implicit broadcast sending order
+	 * which I dislike. Randomise this ? :-)
+	 */
+
+	for (CPU_INFO_FOREACH(cii, ci)) {
+		if (ci == NULL)
+			continue;
+		if (ci == self)
+			continue;
+		if (ci->ci_data.cpu_idlelwp == NULL)
+			continue;
+		if ((ci->ci_flags & CPUF_PRESENT) == 0)
+			continue;
+		if (ci->ci_flags & (CPUF_RUNNING)) {
+			if (0 != xen_send_ipi(ci, ipimask)) {
+				panic("xen_ipi of %x from %s to %s failed\n",
+				      ipimask, cpu_name(curcpu()),
+				      cpu_name(ci));
+			}
+		}
+	}
+
+	return;
+	/* NOTREACHED */
+}
+
+/* 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)
+{
+	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);
+	}
+
+	return;
+}
+
+static void
+xen_ipi_synch_fpu(struct cpu_info *ci, struct intrframe *intrf)
+{
+	KASSERT(ci != NULL);
+	KASSERT(intrf != NULL);
+
+#ifdef __x86_64__
+	fpusave_cpu(true);
+#else
+	npxsave_cpu(true);
+#endif /* __x86_64__ */
+	return;
+}
+
+static void
+xen_ipi_ddb(struct cpu_info *ci, struct intrframe *intrf)
+{
+	KASSERT(ci != NULL);
+	KASSERT(intrf != NULL);
+
+#ifdef __x86_64__
+	ddb_ipi(intrf->if_tf);
+#else
+	struct trapframe tf;
+	tf.tf_gs = intrf->if_gs;
+	tf.tf_fs = intrf->if_fs;
+	tf.tf_es = intrf->if_es;
+	tf.tf_ds = intrf->if_ds;
+	tf.tf_edi = intrf->if_edi;
+	tf.tf_esi = intrf->if_esi;
+	tf.tf_ebp = intrf->if_ebp;
+	tf.tf_ebx = intrf->if_ebx;
+	tf.tf_ecx = intrf->if_ecx;
+	tf.tf_eax = intrf->if_eax;
+	tf.tf_trapno = intrf->__if_trapno;
+	tf.tf_err = intrf->__if_err;
+	tf.tf_eip = intrf->if_eip;
+	tf.tf_cs = intrf->if_cs;
+	tf.tf_eflags = intrf->if_eflags;
+	tf.tf_esp = intrf->if_esp;
+	tf.tf_ss = intrf->if_ss;
+
+	/* XXX: does i386/Xen have vm86 support ?
+	tf.tf_vm86_es;
+	tf.tf_vm86_ds;
+	tf.tf_vm86_fs;
+	tf.tf_vm86_gs;
+	   :XXX */
+
+	ddb_ipi(SEL_KPL, tf);
+#endif
+}
+
+static void
+xen_ipi_xcall(struct cpu_info *ci, struct intrframe *intrf)
+{
+	KASSERT(ci != NULL);
+	KASSERT(intrf != NULL);
+
+	xc_ipi_handler();
+	return;
+}
+
+void
+xc_send_ipi(struct cpu_info *ci)
+{
+
+	KASSERT(kpreempt_disabled());
+	KASSERT(curcpu() != ci);
+	printf("xc_send_ipi called \n");
+	if (ci) {
+		if (0 != xen_send_ipi(ci, XEN_IPI_XCALL)) {
+			panic("xen_send_ipi(XEN_IPI_XCALL) failed\n");
+		};
+	} else {
+		xen_broadcast_ipi(XEN_IPI_XCALL);
+	}
+}

Reply via email to