Module Name: src
Committed By: maxv
Date: Sun Nov 26 14:29:48 UTC 2017
Modified Files:
src/sys/arch/amd64/stand/prekern: mm.c
Log Message:
Oh, damn. Obviously I forgot one case here: an already-mapped region could
be contained entirely in the region we're trying to create. So go through
another round. While here add mm_reenter_pa, and make sure the va given to
mm_enter_pa does not already point to something.
To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 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.19 src/sys/arch/amd64/stand/prekern/mm.c:1.20
--- src/sys/arch/amd64/stand/prekern/mm.c:1.19 Sun Nov 26 11:01:09 2017
+++ src/sys/arch/amd64/stand/prekern/mm.c Sun Nov 26 14:29:48 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: mm.c,v 1.19 2017/11/26 11:01:09 maxv Exp $ */
+/* $NetBSD: mm.c,v 1.20 2017/11/26 14:29:48 maxv Exp $ */
/*
* Copyright (c) 2017 The NetBSD Foundation, Inc. All rights reserved.
@@ -71,6 +71,15 @@ mm_init(paddr_t first_pa)
static void
mm_enter_pa(paddr_t pa, vaddr_t va, pte_prot_t prot)
{
+ if (PTE_BASE[pl1_i(va)] & PG_V) {
+ fatal("mm_enter_pa: mapping already present");
+ }
+ PTE_BASE[pl1_i(va)] = pa | PG_V | protection_codes[prot];
+}
+
+static void
+mm_reenter_pa(paddr_t pa, vaddr_t va, pte_prot_t prot)
+{
PTE_BASE[pl1_i(va)] = pa | PG_V | protection_codes[prot];
}
@@ -92,7 +101,7 @@ mm_palloc(size_t npages)
/* Zero them out */
for (i = 0; i < npages; i++) {
- mm_enter_pa(pa + i * PAGE_SIZE, tmpva,
+ mm_reenter_pa(pa + i * PAGE_SIZE, tmpva,
MM_PROT_READ|MM_PROT_WRITE);
mm_flush_va(tmpva);
memset((void *)tmpva, 0, PAGE_SIZE);
@@ -120,7 +129,7 @@ mm_mprotect(vaddr_t startva, size_t size
for (i = 0; i < npages; i++) {
va = startva + i * PAGE_SIZE;
pa = (PTE_BASE[pl1_i(va)] & PG_FRAME);
- mm_enter_pa(pa, va, prot);
+ mm_reenter_pa(pa, va, prot);
mm_flush_va(va);
}
}
@@ -227,6 +236,10 @@ mm_randva_kregion(size_t size, size_t pa
ok = false;
break;
}
+ if (randva < sva && eva < (randva + size)) {
+ ok = false;
+ break;
+ }
}
if (ok) {
break;