Module Name: src Committed By: thorpej Date: Sat Dec 30 23:07:42 UTC 2023
Modified Files: src/sys/arch/alpha/alpha: pmap.c Log Message: pmap_bootstrap(): When initializing the L2 PTEs, don't use l2pte_index(), as it is designed to wrap from 1023->0 during the normal course of use. However, when setting up the initial kernel page tables, if we have a large enough config that we end up with more than L2 PT page, we rely on being able to index > 1023 into the adjacent PT pages to initialize those entries. Fixes a MM fault panic during early boot on larger memory configs (reported by Dave McGuire with an 8GB ES40 and John Klos with a 12GB DS25). I've successfully booted at 16GB config in Qemu with this fix. To generate a diff of this commit: cvs rdiff -u -r1.307 -r1.308 src/sys/arch/alpha/alpha/pmap.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/alpha/alpha/pmap.c diff -u src/sys/arch/alpha/alpha/pmap.c:1.307 src/sys/arch/alpha/alpha/pmap.c:1.308 --- src/sys/arch/alpha/alpha/pmap.c:1.307 Sat Apr 9 23:38:31 2022 +++ src/sys/arch/alpha/alpha/pmap.c Sat Dec 30 23:07:42 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.307 2022/04/09 23:38:31 riastradh Exp $ */ +/* $NetBSD: pmap.c,v 1.308 2023/12/30 23:07:42 thorpej Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001, 2007, 2008, 2020 @@ -135,7 +135,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.307 2022/04/09 23:38:31 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.308 2023/12/30 23:07:42 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -1204,13 +1204,15 @@ static bool vtophys_internal(vaddr_t, pa l1pte_ = pmap_l1pte(kernel_lev1map, va); \ if (pmap_pte_v(l1pte_) == 0) { \ printf("kernel level 1 PTE not valid, va 0x%lx " \ - "(line %d)\n", (va), __LINE__); \ + "(line %d) pte=%p *pte=0x%016lx\n", (va), __LINE__, \ + l1pte_, *l1pte_); \ panic("PMAP_KERNEL_PTE"); \ } \ l2pte_ = pmap_l2pte(kernel_lev1map, va, l1pte_); \ if (pmap_pte_v(l2pte_) == 0) { \ printf("kernel level 2 PTE not valid, va 0x%lx " \ - "(line %d)\n", (va), __LINE__); \ + "(line %d) pte=%p *pte=0x%016lx\n", (va), __LINE__, \ + l2pte_, *l2pte_); \ panic("PMAP_KERNEL_PTE"); \ } \ pmap_l3pte(kernel_lev1map, va, l2pte_); \ @@ -1358,8 +1360,19 @@ pmap_bootstrap(paddr_t ptaddr, u_int max pte = (ALPHA_K0SEG_TO_PHYS(((vaddr_t)lev3map) + (i*PAGE_SIZE)) >> PGSHIFT) << PG_SHIFT; pte |= PG_V | PG_ASM | PG_KRE | PG_KWE | PG_WIRED; - lev2map[l2pte_index(VM_MIN_KERNEL_ADDRESS+ - (i*PAGE_SIZE*NPTEPG))] = pte; + /* + * No need to use l2pte_index() here; it's equivalent + * to just indexing with our loop variable i, but will + * fall over if we end up with more than 1 L2 PT page. + * + * In other words: + * + * l2pte_index(VM_MIN_KERNEL_ADDRESS + + * (i*PAGE_SIZE*NPTEPG)) + * + * ...is the same as 'i' so long as i stays below 1024. + */ + lev2map[i] = pte; } /* Initialize the pmap_growkernel_lock. */