svn commit: r348795 - in head/sys/powerpc: aim include powerpc

Justin Hibbits jhibbits at FreeBSD.org
Sat Jun 8 03:07:10 UTC 2019


Author: jhibbits
Date: Sat Jun  8 03:07:08 2019
New Revision: 348795
URL: https://svnweb.freebsd.org/changeset/base/348795

Log:
  powerpc/pmap: Move the SLB spill handlers to a better place
  
  The SLB spill handlers are AIM-specific, and belong better with the rest of
  the SLB code anyway.  No functional change.

Modified:
  head/sys/powerpc/aim/slb.c
  head/sys/powerpc/include/slb.h
  head/sys/powerpc/powerpc/trap.c

Modified: head/sys/powerpc/aim/slb.c
==============================================================================
--- head/sys/powerpc/aim/slb.c	Sat Jun  8 02:36:07 2019	(r348794)
+++ head/sys/powerpc/aim/slb.c	Sat Jun  8 03:07:08 2019	(r348795)
@@ -47,7 +47,10 @@
 #include <machine/md_var.h>
 #include <machine/platform.h>
 #include <machine/vmparam.h>
+#include <machine/trap.h>
 
+#include "mmu_oea64.h"
+
 uintptr_t moea64_get_unique_vsid(void);
 void moea64_release_vsid(uint64_t vsid);
 static void slb_zone_init(void *);
@@ -540,3 +543,86 @@ slb_free_user_cache(struct slb **slb)
 {
 	uma_zfree(slb_cache_zone, slb);
 }
+
+#if defined(__powerpc64__)
+/* Handle kernel SLB faults -- runs in real mode, all seat belts off */
+void
+handle_kernel_slb_spill(int type, register_t dar, register_t srr0)
+{
+	struct slb *slbcache;
+	uint64_t slbe, slbv;
+	uint64_t esid, addr;
+	int i;
+
+	addr = (type == EXC_ISE) ? srr0 : dar;
+	slbcache = PCPU_GET(aim.slb);
+	esid = (uintptr_t)addr >> ADDR_SR_SHFT;
+	slbe = (esid << SLBE_ESID_SHIFT) | SLBE_VALID;
+	
+	/* See if the hardware flushed this somehow (can happen in LPARs) */
+	for (i = 0; i < n_slbs; i++)
+		if (slbcache[i].slbe == (slbe | (uint64_t)i))
+			return;
+
+	/* Not in the map, needs to actually be added */
+	slbv = kernel_va_to_slbv(addr);
+	if (slbcache[USER_SLB_SLOT].slbe == 0) {
+		for (i = 0; i < n_slbs; i++) {
+			if (i == USER_SLB_SLOT)
+				continue;
+			if (!(slbcache[i].slbe & SLBE_VALID))
+				goto fillkernslb;
+		}
+
+		if (i == n_slbs)
+			slbcache[USER_SLB_SLOT].slbe = 1;
+	}
+
+	/* Sacrifice a random SLB entry that is not the user entry */
+	i = mftb() % n_slbs;
+	if (i == USER_SLB_SLOT)
+		i = (i+1) % n_slbs;
+
+fillkernslb:
+	/* Write new entry */
+	slbcache[i].slbv = slbv;
+	slbcache[i].slbe = slbe | (uint64_t)i;
+
+	/* Trap handler will restore from cache on exit */
+}
+
+int 
+handle_user_slb_spill(pmap_t pm, vm_offset_t addr)
+{
+	struct slb *user_entry;
+	uint64_t esid;
+	int i;
+
+	if (pm->pm_slb == NULL)
+		return (-1);
+
+	esid = (uintptr_t)addr >> ADDR_SR_SHFT;
+
+	PMAP_LOCK(pm);
+	user_entry = user_va_to_slb_entry(pm, addr);
+
+	if (user_entry == NULL) {
+		/* allocate_vsid auto-spills it */
+		(void)allocate_user_vsid(pm, esid, 0);
+	} else {
+		/*
+		 * Check that another CPU has not already mapped this.
+		 * XXX: Per-thread SLB caches would be better.
+		 */
+		for (i = 0; i < pm->pm_slb_len; i++)
+			if (pm->pm_slb[i] == user_entry)
+				break;
+
+		if (i == pm->pm_slb_len)
+			slb_insert_user(pm, user_entry);
+	}
+	PMAP_UNLOCK(pm);
+
+	return (0);
+}
+#endif

Modified: head/sys/powerpc/include/slb.h
==============================================================================
--- head/sys/powerpc/include/slb.h	Sat Jun  8 02:36:07 2019	(r348794)
+++ head/sys/powerpc/include/slb.h	Sat Jun  8 03:07:08 2019	(r348795)
@@ -79,4 +79,8 @@ struct slb {
 	uint64_t	slbe;
 };
 
+struct pmap;
+void	handle_kernel_slb_spill(int, register_t, register_t);
+int	handle_user_slb_spill(struct pmap *pm, vm_offset_t addr);
+
 #endif /* !_MACHINE_SLB_H_ */

Modified: head/sys/powerpc/powerpc/trap.c
==============================================================================
--- head/sys/powerpc/powerpc/trap.c	Sat Jun  8 02:36:07 2019	(r348794)
+++ head/sys/powerpc/powerpc/trap.c	Sat Jun  8 03:07:08 2019	(r348795)
@@ -69,9 +69,10 @@ __FBSDID("$FreeBSD$");
 #include <machine/frame.h>
 #include <machine/pcb.h>
 #include <machine/psl.h>
-#include <machine/trap.h>
+#include <machine/slb.h>
 #include <machine/spr.h>
 #include <machine/sr.h>
+#include <machine/trap.h>
 
 /* Below matches setjmp.S */
 #define	FAULTBUF_LR	21
@@ -92,9 +93,6 @@ static int	handle_onfault(struct trapframe *frame);
 static void	syscall(struct trapframe *frame);
 
 #if defined(__powerpc64__) && defined(AIM)
-       void	handle_kernel_slb_spill(int, register_t, register_t);
-static int	handle_user_slb_spill(pmap_t pm, vm_offset_t addr);
-extern int	n_slbs;
 static void	normalize_inputs(void);
 #endif
 
@@ -720,89 +718,6 @@ syscall(struct trapframe *frame)
 	error = syscallenter(td);
 	syscallret(td, error);
 }
-
-#if defined(__powerpc64__) && defined(AIM)
-/* Handle kernel SLB faults -- runs in real mode, all seat belts off */
-void
-handle_kernel_slb_spill(int type, register_t dar, register_t srr0)
-{
-	struct slb *slbcache;
-	uint64_t slbe, slbv;
-	uint64_t esid, addr;
-	int i;
-
-	addr = (type == EXC_ISE) ? srr0 : dar;
-	slbcache = PCPU_GET(aim.slb);
-	esid = (uintptr_t)addr >> ADDR_SR_SHFT;
-	slbe = (esid << SLBE_ESID_SHIFT) | SLBE_VALID;
-	
-	/* See if the hardware flushed this somehow (can happen in LPARs) */
-	for (i = 0; i < n_slbs; i++)
-		if (slbcache[i].slbe == (slbe | (uint64_t)i))
-			return;
-
-	/* Not in the map, needs to actually be added */
-	slbv = kernel_va_to_slbv(addr);
-	if (slbcache[USER_SLB_SLOT].slbe == 0) {
-		for (i = 0; i < n_slbs; i++) {
-			if (i == USER_SLB_SLOT)
-				continue;
-			if (!(slbcache[i].slbe & SLBE_VALID))
-				goto fillkernslb;
-		}
-
-		if (i == n_slbs)
-			slbcache[USER_SLB_SLOT].slbe = 1;
-	}
-
-	/* Sacrifice a random SLB entry that is not the user entry */
-	i = mftb() % n_slbs;
-	if (i == USER_SLB_SLOT)
-		i = (i+1) % n_slbs;
-
-fillkernslb:
-	/* Write new entry */
-	slbcache[i].slbv = slbv;
-	slbcache[i].slbe = slbe | (uint64_t)i;
-
-	/* Trap handler will restore from cache on exit */
-}
-
-static int 
-handle_user_slb_spill(pmap_t pm, vm_offset_t addr)
-{
-	struct slb *user_entry;
-	uint64_t esid;
-	int i;
-
-	if (pm->pm_slb == NULL)
-		return (-1);
-
-	esid = (uintptr_t)addr >> ADDR_SR_SHFT;
-
-	PMAP_LOCK(pm);
-	user_entry = user_va_to_slb_entry(pm, addr);
-
-	if (user_entry == NULL) {
-		/* allocate_vsid auto-spills it */
-		(void)allocate_user_vsid(pm, esid, 0);
-	} else {
-		/*
-		 * Check that another CPU has not already mapped this.
-		 * XXX: Per-thread SLB caches would be better.
-		 */
-		for (i = 0; i < pm->pm_slb_len; i++)
-			if (pm->pm_slb[i] == user_entry)
-				break;
-
-		if (i == pm->pm_slb_len)
-			slb_insert_user(pm, user_entry);
-	}
-	PMAP_UNLOCK(pm);
-
-	return (0);
-}
-#endif
 
 static int
 trap_pfault(struct trapframe *frame, int user)


More information about the svn-src-head mailing list