Subject: Patch for KVM86 support on MP kernels
To: None <port-i386@netbsd.org>
From: Pierre Pronchery <khorben@defora.org>
List: port-i386
Date: 01/05/2007 05:28:21
This is a multi-part message in MIME format.
--------------080500010805040704070603
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 7bit

	Hi,

I am probably not knowing what I am doing, but here is my humble attempt
at allowing the framebuffer code to compile (and hopefully work) on MP
machines. I got the inspiration from an earlier unanswered post by Eric
Auge [1], and the current equivalent in OpenBSD [2]. They say there are
probably still problems.

[1] http://mail-index.netbsd.org/netbsd-users/2006/12/01/0000.html
[2] http://www.openbsd.org/cgi-bin/cvsweb/src/sys/arch/i386/i386/kvm86.c

I did not test that code, nor could 100% check that the code is
otherwise equivalent to the version from OpenBSD.

HTH,
-- 
khorben

--------------080500010805040704070603
Content-Type: text/plain;
 name="kvm86-smp.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="kvm86-smp.diff"

Index: kvm86.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/kvm86.c,v
retrieving revision 1.10
diff -u -r1.10 kvm86.c
--- kvm86.c	26 Dec 2005 19:23:59 -0000	1.10
+++ kvm86.c	5 Jan 2007 04:15:03 -0000
@@ -36,6 +36,7 @@
 #include <sys/proc.h>
 #include <sys/user.h>
 #include <sys/malloc.h>
+#include <sys/lock.h>
 #include <uvm/uvm.h>
 #include <machine/pcb.h>
 #include <machine/pte.h>
@@ -70,6 +71,8 @@
 /* a virtual page to map in vm86 memory temporarily */
 vaddr_t bioscalltmpva;
 
+struct lock kvm86_mp_lock;
+
 #define KVM86_IOPL3 /* not strictly necessary, saves a lot of traps */
 
 void
@@ -119,6 +122,7 @@
 		  BIOSCALLSCRATCHPAGE_VMVA);
 	bioscallvmd = vmd;
 	bioscalltmpva = uvm_km_alloc(kernel_map, PAGE_SIZE, 0, UVM_KMF_VAONLY);
+	lockinit(&kvm86_mp_lock, 0, "KVM86 MP", 0, LK_RECURSEFAIL);
 }
 
 /*
@@ -136,10 +140,6 @@
 	extern struct trapframe *vm86frame;
 	extern pt_entry_t *vm86pgtableva;
 
-#ifdef MULTIPROCESSOR
-#error this needs a rewrite for MP
-#endif
-
 	vm86newptd = vtophys((vaddr_t)vmd) | PG_V | PG_RW | PG_U | PG_u;
 	vm86pgtableva = vmd->pgtbl;
 	vm86frame = (struct trapframe *)vmd - 1;
@@ -276,7 +276,9 @@
 	tf.tf_edi = r->EDI;
 	tf.tf_vm86_es = r->ES;
 
+	lockmgr(&kvm86_mp_lock, LK_EXCLUSIVE, NULL);
 	res = kvm86_bioscall(intno, &tf);
+	lockmgr(&kvm86_mp_lock, LK_RELEASE, NULL);
 
 	r->EAX = tf.tf_eax;
 	r->EBX = tf.tf_ebx;
Index: trap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/i386/trap.c,v
retrieving revision 1.214
diff -u -r1.214 trap.c
--- trap.c	29 Sep 2006 14:48:15 -0000	1.214
+++ trap.c	5 Jan 2007 04:15:03 -0000
@@ -135,9 +135,6 @@
 #endif
 
 #ifdef KVM86
-#ifdef MULTIPROCESSOR
-#error KVM86 needs a rewrite to support MP systems.
-#endif
 #include <machine/kvm86.h>
 #define KVM86MODE (kvm86_incall)
 #else
@@ -437,9 +434,11 @@
 		return;
 
 	case T_PROTFLT|T_USER:		/* protection fault */
+		KERNEL_PROC_LOCK(l);
 #ifdef VM86
 		if (frame->tf_eflags & PSL_VM) {
 			vm86_gpfault(l, type & ~T_USER);
+			KERNEL_PROC_UNLOCK(l);
 			goto out;
 		}
 #endif
@@ -447,12 +446,14 @@
 		/* If pmap_exec_fixup does something, let's retry the trap. */
 		if (pmap_exec_fixup(&p->p_vmspace->vm_map, frame,
 		    &l->l_addr->u_pcb)) {
+			KERNEL_PROC_UNLOCK(l);
 			goto out;
 		}
 		KSI_INIT_TRAP(&ksi);
 		ksi.ksi_signo = SIGSEGV;
 		ksi.ksi_addr = (void *)rcr2();
 		ksi.ksi_code = SEGV_ACCERR;
+		KERNEL_PROC_UNLOCK(l);
 		goto trapsignal;
 
 	case T_TSSFLT|T_USER:

--------------080500010805040704070603--