From owner-svn-src-user@FreeBSD.ORG  Fri Feb 20 05:29:23 2015
Return-Path: <owner-svn-src-user@FreeBSD.ORG>
Delivered-To: svn-src-user@freebsd.org
Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115])
 (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))
 (No client certificate requested)
 by hub.freebsd.org (Postfix) with ESMTPS id 298EA234;
 Fri, 20 Feb 2015 05:29:23 +0000 (UTC)
Received: from svn.freebsd.org (svn.freebsd.org
 [IPv6:2001:1900:2254:2068::e6a:0])
 (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
 (Client did not present a certificate)
 by mx1.freebsd.org (Postfix) with ESMTPS id 0C5E6C8;
 Fri, 20 Feb 2015 05:29:23 +0000 (UTC)
Received: from svn.freebsd.org ([127.0.1.70])
 by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1K5TMHK039532;
 Fri, 20 Feb 2015 05:29:22 GMT (envelope-from nwhitehorn@FreeBSD.org)
Received: (from nwhitehorn@localhost)
 by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1K5TMNo039531;
 Fri, 20 Feb 2015 05:29:22 GMT (envelope-from nwhitehorn@FreeBSD.org)
Message-Id: <201502200529.t1K5TMNo039531@svn.freebsd.org>
X-Authentication-Warning: svn.freebsd.org: nwhitehorn set sender to
 nwhitehorn@FreeBSD.org using -f
From: Nathan Whitehorn <nwhitehorn@FreeBSD.org>
Date: Fri, 20 Feb 2015 05:29:22 +0000 (UTC)
To: src-committers@freebsd.org, svn-src-user@freebsd.org
Subject: svn commit: r279042 - user/nwhitehorn/ppc64-pmap-rework/pseries
X-SVN-Group: user
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: svn-src-user@freebsd.org
X-Mailman-Version: 2.1.18-1
Precedence: list
List-Id: "SVN commit messages for the experimental &quot; user&quot;
 src tree" <svn-src-user.freebsd.org>
List-Unsubscribe: <http://lists.freebsd.org/mailman/options/svn-src-user>,
 <mailto:svn-src-user-request@freebsd.org?subject=unsubscribe>
List-Archive: <http://lists.freebsd.org/pipermail/svn-src-user/>
List-Post: <mailto:svn-src-user@freebsd.org>
List-Help: <mailto:svn-src-user-request@freebsd.org?subject=help>
List-Subscribe: <http://lists.freebsd.org/mailman/listinfo/svn-src-user>,
 <mailto:svn-src-user-request@freebsd.org?subject=subscribe>
X-List-Received-Date: Fri, 20 Feb 2015 05:29:23 -0000

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);
 	}