Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Sep 2013 13:11:20 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r255909 - head/sys/powerpc/pseries
Message-ID:  <201309271311.r8RDBKPH090625@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Fri Sep 27 13:11:20 2013
New Revision: 255909
URL: http://svnweb.freebsd.org/changeset/base/255909

Log:
  Make sure that ref and changed bits propagate back to the VM layer
  whenever pages are unmapped. The old code had several races that could
  allow these to become stale.
  
  Approved by:	re (kib)

Modified:
  head/sys/powerpc/pseries/mmu_phyp.c

Modified: head/sys/powerpc/pseries/mmu_phyp.c
==============================================================================
--- head/sys/powerpc/pseries/mmu_phyp.c	Fri Sep 27 11:25:37 2013	(r255908)
+++ head/sys/powerpc/pseries/mmu_phyp.c	Fri Sep 27 13:11:20 2013	(r255909)
@@ -201,6 +201,7 @@ mphyp_pte_synch(mmu_t mmu, uintptr_t slo
 	struct lpte pte;
 	uint64_t junk;
 
+	__asm __volatile("ptesync");
 	phyp_pft_hcall(H_READ, 0, slot, 0, 0, &pte.pte_hi, &pte.pte_lo,
 	    &junk);
 
@@ -221,9 +222,16 @@ mphyp_pte_clear(mmu_t mmu, uintptr_t slo
 static void
 mphyp_pte_unset(mmu_t mmu, uintptr_t slot, struct lpte *pvo_pt, uint64_t vpn)
 {
+	struct lpte pte;
+	uint64_t junk;
+	int err;
+
+	err = phyp_pft_hcall(H_REMOVE, 1UL << 31, slot,
+	    pvo_pt->pte_hi & LPTE_AVPN_MASK, 0, &pte.pte_hi, &pte.pte_lo,
+	    &junk);
+	KASSERT(err == H_SUCCESS, ("Error removing page: %d", err));
 
-	/* XXX: last argument can check the VPN -- set flag to enable */
-	phyp_hcall(H_REMOVE, 0, slot, vpn);
+	pvo_pt->pte_lo |= pte.pte_lo & (LPTE_CHG | LPTE_REF);
 }
 
 static void
@@ -242,9 +250,7 @@ mphyp_pte_change(mmu_t mmu, uintptr_t sl
 	    ("Locked pages not supported on PHYP"));
 
 	/* XXX: optimization using H_PROTECT for common case? */
-	result = phyp_hcall(H_REMOVE, 0, slot, vpn);
-	if (result != H_SUCCESS)
-		panic("mphyp_pte_change() invalidation failure: %ld\n", result);
+	mphyp_pte_unset(mmu, slot, pvo_pt, vpn);
 	result = phyp_pft_hcall(H_ENTER, H_EXACT, slot, pvo_pt->pte_hi,
 				pvo_pt->pte_lo, &index, &evicted.pte_lo, &junk);
 	if (result != H_SUCCESS)
@@ -360,7 +366,8 @@ mphyp_pte_insert(mmu_t mmu, u_int ptegid
 		if (pvo->pvo_pte.lpte.pte_hi == evicted.pte_hi) {
 			KASSERT(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID,
 			    ("Invalid PVO for valid PTE!"));
-			phyp_hcall(H_REMOVE, 0, index, 0);
+			mphyp_pte_unset(mmu, index, &pvo->pvo_pte.lpte,
+			    pvo->pvo_vpn);
 			PVO_PTEGIDX_CLR(pvo);
 			moea64_pte_overflow++;
 			break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309271311.r8RDBKPH090625>