Module Name:    src
Committed By:   maxv
Date:           Sat Oct 28 19:28:11 UTC 2017

Modified Files:
        src/sys/arch/amd64/stand/prekern: mm.c

Log Message:
Fix a mistake I made in the very first revision. The calculation of the
number of slots was incorrect in some cases, and it could cause the
prekern to fault right away at boot time, or the kernel to fault when
loading kernel modules near the end of the module map.

The variables are divided by PAGE_SIZE to prevent integer overflows.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/amd64/stand/prekern/mm.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/amd64/stand/prekern/mm.c
diff -u src/sys/arch/amd64/stand/prekern/mm.c:1.4 src/sys/arch/amd64/stand/prekern/mm.c:1.5
--- src/sys/arch/amd64/stand/prekern/mm.c:1.4	Mon Oct 23 06:00:59 2017
+++ src/sys/arch/amd64/stand/prekern/mm.c	Sat Oct 28 19:28:11 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: mm.c,v 1.4 2017/10/23 06:00:59 maxv Exp $	*/
+/*	$NetBSD: mm.c,v 1.5 2017/10/28 19:28:11 maxv Exp $	*/
 
 /*
  * Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -112,20 +112,28 @@ mm_mprotect(vaddr_t startva, size_t size
 	}
 }
 
+static size_t
+mm_nentries_range(vaddr_t startva, vaddr_t endva, size_t pgsz)
+{
+	size_t npages;
+
+	npages = roundup((endva / PAGE_SIZE), (pgsz / PAGE_SIZE)) -
+	    rounddown((startva / PAGE_SIZE), (pgsz / PAGE_SIZE));
+	return (npages / (pgsz / PAGE_SIZE));
+}
+
 static void
 mm_map_tree(vaddr_t startva, vaddr_t endva)
 {
-	size_t i, size, nL4e, nL3e, nL2e;
+	size_t i, nL4e, nL3e, nL2e;
 	size_t L4e_idx, L3e_idx, L2e_idx;
 	paddr_t pa;
 
-	size = endva - startva;
-
 	/*
 	 * Build L4.
 	 */
 	L4e_idx = pl4_i(startva);
-	nL4e = roundup(size, NBPD_L4) / NBPD_L4;
+	nL4e = mm_nentries_range(startva, endva, NBPD_L4);
 	ASSERT(L4e_idx == 511);
 	ASSERT(nL4e == 1);
 	if (!mm_pte_is_valid(L4_BASE[L4e_idx])) {
@@ -137,7 +145,7 @@ mm_map_tree(vaddr_t startva, vaddr_t end
 	 * Build L3.
 	 */
 	L3e_idx = pl3_i(startva);
-	nL3e = roundup(size, NBPD_L3) / NBPD_L3;
+	nL3e = mm_nentries_range(startva, endva, NBPD_L3);
 	for (i = 0; i < nL3e; i++) {
 		if (mm_pte_is_valid(L3_BASE[L3e_idx+i])) {
 			continue;
@@ -150,7 +158,7 @@ mm_map_tree(vaddr_t startva, vaddr_t end
 	 * Build L2.
 	 */
 	L2e_idx = pl2_i(startva);
-	nL2e = roundup(size, NBPD_L2) / NBPD_L2;
+	nL2e = mm_nentries_range(startva, endva, NBPD_L2);
 	for (i = 0; i < nL2e; i++) {
 		if (mm_pte_is_valid(L2_BASE[L2e_idx+i])) {
 			continue;

Reply via email to