svn commit: r279042 - user/nwhitehorn/ppc64-pmap-rework/pseries

Nathan Whitehorn nwhitehorn at FreeBSD.org
Fri Feb 20 05:29:23 UTC 2015


Author: nwhitehorn
Date: Fri Feb 20 05:29:22 2015
New Revision: 279042
URL: https://svnweb.freebsd.org/changeset/base/279042

Log:
  Restore accidentally deleted broken KVM detection. This is being fixed upstream.

Modified:
  user/nwhitehorn/ppc64-pmap-rework/pseries/mmu_phyp.c

Modified: user/nwhitehorn/ppc64-pmap-rework/pseries/mmu_phyp.c
==============================================================================
--- user/nwhitehorn/ppc64-pmap-rework/pseries/mmu_phyp.c	Fri Feb 20 05:23:51 2015	(r279041)
+++ user/nwhitehorn/ppc64-pmap-rework/pseries/mmu_phyp.c	Fri Feb 20 05:29:22 2015	(r279042)
@@ -89,6 +89,23 @@ static mmu_method_t mphyp_methods[] = {
 
 MMU_DEF_INHERIT(pseries_mmu, "mmu_phyp", mphyp_methods, 0, oea64_mmu);
 
+static int brokenkvm = 0;
+
+static void
+print_kvm_bug_warning(void *data)
+{
+
+	if (brokenkvm)
+		printf("WARNING: Running on a broken hypervisor that does "
+		    "not support mandatory H_CLEAR_MOD and H_CLEAR_REF "
+		    "hypercalls. Performance will be suboptimal.\n");
+}
+
+SYSINIT(kvmbugwarn1, SI_SUB_COPYRIGHT, SI_ORDER_THIRD + 1,
+    print_kvm_bug_warning, NULL);
+SYSINIT(kvmbugwarn2, SI_SUB_LAST, SI_ORDER_THIRD + 1, print_kvm_bug_warning,
+    NULL);
+
 static void
 mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
 {
@@ -181,6 +198,10 @@ mphyp_bootstrap(mmu_t mmup, vm_offset_t 
 
 	moea64_mid_bootstrap(mmup, kernelstart, kernelend);
 	moea64_late_bootstrap(mmup, kernelstart, kernelend);
+
+	/* Test for broken versions of KVM that don't conform to the spec */
+	if (phyp_hcall(H_CLEAR_MOD, 0, 0) == H_FUNCTION)
+		brokenkvm = 1;
 }
 
 static void
@@ -229,6 +250,7 @@ mphyp_pte_clear(mmu_t mmu, struct pvo_en
 {
 	int64_t refchg;
 	uint64_t ptelo, junk;
+	int err;
 
 	/*
 	 * This involves two steps (synch and clear) so we need the entry
@@ -246,14 +268,28 @@ mphyp_pte_clear(mmu_t mmu, struct pvo_en
 		return (refchg);
 	}
 
+	if (brokenkvm) {
+		/*
+		 * No way to clear either bit, which is total madness.
+		 * Pessimistically claim that, once modified, it stays so
+		 * forever and that it is never referenced.
+		 */
+		rw_runlock(&mphyp_eviction_lock);
+		return (refchg & ~LPTE_REF);
+	}
+
 	if (ptebit & LPTE_CHG) {
-		phyp_pft_hcall(H_CLEAR_MOD, 0, pvo->pvo_pte.slot, 0, 0, &ptelo,
-		    &junk, &junk);
+		err = phyp_pft_hcall(H_CLEAR_MOD, 0, pvo->pvo_pte.slot, 0, 0,
+		    &ptelo, &junk, &junk);
+		KASSERT(err == H_SUCCESS,
+		    ("Error clearing page change bit: %d", err));
 		refchg |= (ptelo & LPTE_CHG);
 	}
 	if (ptebit & LPTE_REF) {
-		phyp_pft_hcall(H_CLEAR_REF, 0, pvo->pvo_pte.slot, 0, 0, &ptelo,
-		    &junk, &junk);
+		err = phyp_pft_hcall(H_CLEAR_REF, 0, pvo->pvo_pte.slot, 0, 0,
+		    &ptelo, &junk, &junk);
+		KASSERT(err == H_SUCCESS,
+		    ("Error clearing page reference bit: %d", err));
 		refchg |= (ptelo & LPTE_REF);
 	}
 


More information about the svn-src-user mailing list