Mercurial > illumos > illumos-gate
changeset 12532:e0c8045b31e0
6897709 BAD TRAP: unix:page_get_mnode_freelist
6898574 incorrect pagetable handling in i86pc/vm
author | Joe Bonasera <joe.bonasera@oracle.com> |
---|---|
date | Wed, 02 Jun 2010 09:26:54 -0700 |
parents | 0cd962838fce |
children | a474309e6ba5 |
files | usr/src/uts/i86pc/vm/hat_i86.c usr/src/uts/i86pc/vm/htable.c usr/src/uts/i86pc/vm/vm_machdep.c |
diffstat | 3 files changed, 17 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/i86pc/vm/hat_i86.c Wed Jun 02 08:32:30 2010 -0400 +++ b/usr/src/uts/i86pc/vm/hat_i86.c Wed Jun 02 09:26:54 2010 -0700 @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ /* * Copyright (c) 2010, Intel Corporation. @@ -2200,22 +2199,7 @@ x86_hm_enter(pp); } - /* - * If freeing the address space, check that the PTE - * hasn't changed, as the mappings are no longer in use by - * any thread, invalidation is unnecessary. - * If not freeing, do a full invalidate. - * - * On the hypervisor we must always remove mappings, as a - * writable mapping left behind could cause a page table - * allocation to fail. - */ -#if !defined(__xpv) - if (hat->hat_flags & HAT_FREEING) - old_pte = x86pte_get(ht, entry); - else -#endif - old_pte = x86pte_inval(ht, entry, old_pte, pte_ptr); + old_pte = x86pte_inval(ht, entry, old_pte, pte_ptr); /* * If the page hadn't changed we've unmapped it and can proceed @@ -3421,6 +3405,13 @@ level_t level; XPV_DISALLOW_MIGRATE(); + + /* + * prevent recursion due to kmem_free() + */ + ++curthread->t_hatdepth; + ASSERT(curthread->t_hatdepth < 16); + #if defined(__amd64) /* * clear the vpm ref. @@ -3448,6 +3439,8 @@ * If not part of a larger page, we're done. */ if (cur_pp->p_szc <= pg_szcd) { + ASSERT(curthread->t_hatdepth > 0); + --curthread->t_hatdepth; XPV_ALLOW_MIGRATE(); return (0); }
--- a/usr/src/uts/i86pc/vm/htable.c Wed Jun 02 08:32:30 2010 -0400 +++ b/usr/src/uts/i86pc/vm/htable.c Wed Jun 02 09:26:54 2010 -0700 @@ -20,8 +20,7 @@ */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. */ #include <sys/types.h> @@ -334,18 +333,17 @@ * Get an exclusive lock, might have to wait for a kmem reader. */ if (!page_tryupgrade(pp)) { + u_offset_t off = pp->p_offset; page_unlock(pp); - /* - * RFE: we could change this to not loop forever - * For now looping works - it's just like sfmmu. - */ - while (!page_lock(pp, SE_EXCL, (kmutex_t *)NULL, P_RECLAIM)) - continue; + pp = page_lookup(&kvp, off, SE_EXCL); + if (pp == NULL) + panic("page not found"); } #ifdef __xpv if (kpm_vbase && xen_kpm_page(pfn, PT_VALID | PT_WRITABLE) < 0) panic("failure making kpm r/w pfn=0x%lx", pfn); #endif + page_hashout(pp, NULL); page_free(pp, 1); page_unresv(1); }
--- a/usr/src/uts/i86pc/vm/vm_machdep.c Wed Jun 02 08:32:30 2010 -0400 +++ b/usr/src/uts/i86pc/vm/vm_machdep.c Wed Jun 02 09:26:54 2010 -0700 @@ -3982,7 +3982,6 @@ &tmpseg, (caddr_t)(ctr += MMU_PAGESIZE)); /* changing VA usage */ if (pp != NULL) { page_io_unlock(pp); - page_hashout(pp, NULL); page_downgrade(pp); } return (pp);