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