diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d95790307964..490db1745f31 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -349,8 +349,12 @@ pmap_pku_mask_bit(pmap_t pmap) } \ } while (0) -#define CHANGE_PV_LIST_LOCK_TO_VM_PAGE(lockp, m) \ - CHANGE_PV_LIST_LOCK_TO_PHYS(lockp, VM_PAGE_TO_PHYS(m)) +#define CHANGE_PV_LIST_LOCK_TO_VM_PAGE(lockp, m) do { \ + if ((m->flags & PG_FICTITIOUS) == 0) \ + CHANGE_PV_LIST_LOCK_TO_PHYS(lockp, VM_PAGE_TO_PHYS(m));\ + else \ + *lockp = &pv_dummy_large.pv_lock; \ +} while (0) #define RELEASE_PV_LIST_LOCK(lockp) do { \ struct rwlock **_lockp = (lockp); \ @@ -416,19 +420,20 @@ static int pmap_initialized; */ static TAILQ_HEAD(pch, pv_chunk) pv_chunks = TAILQ_HEAD_INITIALIZER(pv_chunks); static struct mtx __exclusive_cache_line pv_chunks_mutex; -#if VM_NRESERVLEVEL > 0 struct pmap_large_md_page { struct rwlock pv_lock; struct md_page pv_page; u_long pv_invl_gen; }; +static struct pmap_large_md_page pv_dummy_large; +#define pv_dummy pv_dummy_large.pv_page +#if VM_NRESERVLEVEL > 0 static struct pmap_large_md_page *pv_table; #else static struct rwlock __exclusive_cache_line pv_list_locks[NPV_LIST_LOCKS]; static u_long pv_invl_gen[NPV_LIST_LOCKS]; static struct md_page *pv_table; #endif -static struct md_page pv_dummy; /* * All those kernel PT submaps that BSD is so fond of @@ -1906,12 +1911,18 @@ pmap_init_pv_table(void) pvd++; } } - TAILQ_INIT(&pv_dummy.pv_list); + pvd = &pv_dummy_large; + rw_init_flags(&pvd->pv_lock, "pmap pv list dummy", RW_NEW); + TAILQ_INIT(&pvd->pv_page.pv_list); + pvd->pv_page.pv_gen = 0; + pvd->pv_page.pat_mode = 0; + pvd->pv_invl_gen = 0; } #else static void pmap_init_pv_table(void) { + struct pmap_large_md_page *pvd; vm_size_t s; long i, pv_npg; @@ -1934,7 +1945,13 @@ pmap_init_pv_table(void) pv_table = (struct md_page *)kmem_malloc(s, M_WAITOK | M_ZERO); for (i = 0; i < pv_npg; i++) TAILQ_INIT(&pv_table[i].pv_list); - TAILQ_INIT(&pv_dummy.pv_list); + pvd = &pv_dummy_large; + rw_init_flags(&pvd->pv_lock, "pmap pv list dummy", RW_NEW); + TAILQ_INIT(&pvd->pv_page.pv_list); + pvd->pv_page.pv_gen = 0; + pvd->pv_page.pat_mode = 0; + pvd->pv_invl_gen = 0; + } #endif