diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 6b3add7e2661..41c830e21fe4 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -1898,6 +1898,8 @@ moea64_get_unique_vsid(void) { hash &= VSID_HASHMASK & ~(VSID_NBPW - 1); hash |= i; } + if (hash == VSID_VRMA) /* also special, avoid this too */ + continue; KASSERT(!(moea64_vsid_bitmap[n] & mask), ("Allocating in-use VSID %#zx\n", hash)); moea64_vsid_bitmap[n] |= mask; diff --git a/sys/powerpc/include/slb.h b/sys/powerpc/include/slb.h index 637110c68533..32425908ed40 100644 --- a/sys/powerpc/include/slb.h +++ b/sys/powerpc/include/slb.h @@ -62,6 +62,9 @@ #define SLBE_ESID_MASK 0xfffffffff0000000UL /* Effective segment ID mask */ #define SLBE_ESID_SHIFT 28 +/* Virtual real-mode VSID in LPARs */ +#define VSID_VRMA 0x1ffffff + /* * User segment for copyin/out */ diff --git a/sys/powerpc/pseries/mmu_phyp.c b/sys/powerpc/pseries/mmu_phyp.c index 91b342446a6f..7ef7189797fb 100644 --- a/sys/powerpc/pseries/mmu_phyp.c +++ b/sys/powerpc/pseries/mmu_phyp.c @@ -114,6 +114,8 @@ mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) uint32_t prop[2]; uint32_t nptlp, shift = 0, slb_encoding = 0; uint32_t lp_size, lp_encoding; + struct lpte old; + uint64_t vsid; phandle_t dev, node, root; int idx, len, res; @@ -150,6 +152,18 @@ mphyp_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend) moea64_pteg_count = final_pteg_count / sizeof(struct lpteg); + /* Clear any old page table entries */ + for (idx = 0; idx < moea64_pteg_count*8; idx++) { + phyp_pft_hcall(H_READ, 0, idx, 0, 0, &old.pte_hi, + &old.pte_lo, &old.pte_lo); + vsid = (old.pte_hi << (ADDR_API_SHFT64 - ADDR_PIDX_SHFT)) >> 28; + if (vsid == VSID_VRMA || vsid == 0 /* Older VRMA */) + continue; + + if (old.pte_hi & LPTE_VALID) + phyp_hcall(H_REMOVE, 0, idx, 0); + } + /* * Scan the large page size property for PAPR compatible machines. * See PAPR D.5 Changes to Section 5.1.4, 'CPU Node Properties'