svn commit: r214739 - head/sys/powerpc/aim

Nathan Whitehorn nwhitehorn at FreeBSD.org
Wed Nov 3 15:15:49 UTC 2010


Author: nwhitehorn
Date: Wed Nov  3 15:15:48 2010
New Revision: 214739
URL: http://svn.freebsd.org/changeset/base/214739

Log:
  Clean up the user segment handling code a little more. Now that
  set_user_sr() itself caches the user segment VSID, there is no need for
  cpu_switch() to do it again. This change also unifies the 32 and 64-bit
  code paths for kernel faults on user pages and remaps the user SLB slot
  on 64-bit systems when taking a syscall to avoid some unnecessary segment
  exception traps.

Modified:
  head/sys/powerpc/aim/copyinout.c
  head/sys/powerpc/aim/swtch32.S
  head/sys/powerpc/aim/swtch64.S
  head/sys/powerpc/aim/trap.c

Modified: head/sys/powerpc/aim/copyinout.c
==============================================================================
--- head/sys/powerpc/aim/copyinout.c	Wed Nov  3 13:42:59 2010	(r214738)
+++ head/sys/powerpc/aim/copyinout.c	Wed Nov  3 15:15:48 2010	(r214739)
@@ -102,11 +102,12 @@ set_user_sr(pmap_t pm, const void *addr)
 	if (curthread->td_pcb->pcb_cpu.aim.usr_vsid == slbv) 
 		return;
 
-	__asm __volatile ("isync; slbie %0; slbmte %1, %2; isync" ::
-	    "r"(USER_ADDR), "r"(slbv), "r"(USER_SLB_SLBE));
+	__asm __volatile("isync");
 	curthread->td_pcb->pcb_cpu.aim.usr_segm =
 	    (uintptr_t)addr >> ADDR_SR_SHFT;
 	curthread->td_pcb->pcb_cpu.aim.usr_vsid = slbv;
+	__asm __volatile ("slbie %0; slbmte %1, %2; isync" ::
+	    "r"(USER_ADDR), "r"(slbv), "r"(USER_SLB_SLBE));
 }
 #else
 static __inline void
@@ -124,6 +125,8 @@ set_user_sr(pmap_t pm, const void *addr)
 	vsid |= SR_N;
 
 	__asm __volatile("isync");
+	curthread->td_pcb->pcb_cpu.aim.usr_segm =
+	    (uintptr_t)addr >> ADDR_SR_SHFT;
 	curthread->td_pcb->pcb_cpu.aim.usr_vsid = vsid;
 	__asm __volatile("mtsr %0,%1; isync" :: "n"(USER_SR), "r"(vsid));
 }

Modified: head/sys/powerpc/aim/swtch32.S
==============================================================================
--- head/sys/powerpc/aim/swtch32.S	Wed Nov  3 13:42:59 2010	(r214738)
+++ head/sys/powerpc/aim/swtch32.S	Wed Nov  3 15:15:48 2010	(r214739)
@@ -88,8 +88,6 @@ ENTRY(cpu_switch)
 	stw	%r16,PCB_CR(%r6)
 	mflr	%r16			/* Save the link register */
 	stw	%r16,PCB_LR(%r6)
-	mfsr	%r16,USER_SR		/* Save USER_SR for copyin/out */
-	stw	%r16,PCB_AIM_USR_VSID(%r6)
 	stw	%r1,PCB_SP(%r6)		/* Save the stack pointer */
 	stw	%r2,PCB_TOC(%r6)	/* Save the TOC pointer */
 

Modified: head/sys/powerpc/aim/swtch64.S
==============================================================================
--- head/sys/powerpc/aim/swtch64.S	Wed Nov  3 13:42:59 2010	(r214738)
+++ head/sys/powerpc/aim/swtch64.S	Wed Nov  3 15:15:48 2010	(r214739)
@@ -110,11 +110,6 @@ ENTRY(cpu_switch)
 	std	%r1,PCB_SP(%r6)		/* Save the stack pointer */
 	std	%r2,PCB_TOC(%r6)	/* Save the TOC pointer */
 	
-	li	%r15,0			/* Save user segment for copyin/out */
-	li	%r16,USER_SLB_SLOT
-	slbmfev %r15, %r16
-	std	%r15,PCB_AIM_USR_VSID(%r6)
-
 	mr	%r14,%r3		/* Copy the old thread ptr... */
 	mr	%r15,%r4		/* and the new thread ptr in scratch */
 	mr	%r16,%r5		/* and the new lock */

Modified: head/sys/powerpc/aim/trap.c
==============================================================================
--- head/sys/powerpc/aim/trap.c	Wed Nov  3 13:42:59 2010	(r214738)
+++ head/sys/powerpc/aim/trap.c	Wed Nov  3 15:15:48 2010	(r214739)
@@ -455,6 +455,13 @@ syscall(struct trapframe *frame)
 	td = PCPU_GET(curthread);
 	td->td_frame = frame;
 
+	/*
+	 * Speculatively restore last user SLB segment, which we know is
+	 * invalid already, since we are likely to do copyin()/copyout().
+	 */
+	__asm __volatile ("slbmte %0, %1; isync" ::
+            "r"(td->td_pcb->pcb_cpu.aim.usr_vsid), "r"(USER_SLB_SLBE));
+
 	error = syscallenter(td, &sa);
 	syscallret(td, error, &sa);
 }
@@ -532,13 +539,7 @@ trap_pfault(struct trapframe *frame, int
 
 			map = &p->p_vmspace->vm_map;
 
-			#ifdef __powerpc64__
 			user_sr = td->td_pcb->pcb_cpu.aim.usr_segm;
-			#else
-			__asm ("mfsr %0, %1"
-			    : "=r"(user_sr)
-			    : "K"(USER_SR));
-			#endif
 			eva &= ADDR_PIDX | ADDR_POFF;
 			eva |= user_sr << ADDR_SR_SHFT;
 		} else {


More information about the svn-src-head mailing list