There is an issue in the way the fillkpt macro sets up pages on both
amd64 and i386. The fillkpt loop is equivalent to the following: do { /* fill in the slot */ /* increment %ebx to the next slot */ /* increment %eax to the next pa */ } while (%ecx > 0) The issue here is that if %ecx = 0 (i.e., the chunk we are trying to map is zero-sized), there is still one entry created in the page table. The kernel expects the va<->pa translation to be linear in low memory. If there is a zero-sized chunk, the dead entry creates a +4096 offset in the virtual space, with two consecutive entries that point to the same physical address. In other words, the mappings are not linear anymore, which causes the kernel to die. Before my recent changes, there were only two big chunks that were mapped, and neither of these could be zero-sized. Now, with multiple, fine-grained chunks, it is possible that the [SYMS]+[PRELOADED_MODULES] chunk could be zero-sized. [PRELOADED_MODULES] is almost never here, and [SYMS] is always here on default kernels. Except for floppies, where the bootloader does not load [SYMS]. Should fix PR 51148.
This commit is contained in:
parent
6bbd2477a9
commit
a56d0ceb2a
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.S,v 1.93 2016/05/22 10:11:55 maxv Exp $ */
|
||||
/* $NetBSD: locore.S,v 1.94 2016/05/26 07:24:55 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright-o-rama!
|
||||
@ -220,16 +220,21 @@
|
||||
* Each entry is 8 (PDE_SIZE) bytes long: we must set the 4 upper bytes to 0.
|
||||
*/
|
||||
#define fillkpt \
|
||||
cmpl $0,%ecx ; /* zero-sized? */ \
|
||||
je 2f ; \
|
||||
1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \
|
||||
movl %eax,(%ebx) ; /* store phys addr */ \
|
||||
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \
|
||||
addl $PAGE_SIZE,%eax ; /* next phys page */ \
|
||||
loop 1b ;
|
||||
loop 1b ; \
|
||||
2: ;
|
||||
|
||||
/*
|
||||
* fillkpt_nox - Same as fillkpt, but sets the NX/XD bit.
|
||||
*/
|
||||
#define fillkpt_nox \
|
||||
cmpl $0,%ecx ; /* zero-sized? */ \
|
||||
je 2f ; \
|
||||
pushl %ebp ; \
|
||||
movl RELOC(nox_flag),%ebp ; \
|
||||
1: movl %ebp,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: NX */ \
|
||||
@ -237,7 +242,8 @@
|
||||
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \
|
||||
addl $PAGE_SIZE,%eax ; /* next phys page */ \
|
||||
loop 1b ; \
|
||||
popl %ebp ;
|
||||
popl %ebp ; \
|
||||
2: ;
|
||||
|
||||
/*
|
||||
* killkpt - Destroy a kernel page table (long mode)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.S,v 1.124 2016/05/15 07:17:53 maxv Exp $ */
|
||||
/* $NetBSD: locore.S,v 1.125 2016/05/26 07:24:55 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright-o-rama!
|
||||
@ -128,7 +128,7 @@
|
||||
*/
|
||||
|
||||
#include <machine/asm.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.124 2016/05/15 07:17:53 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.125 2016/05/26 07:24:55 maxv Exp $");
|
||||
|
||||
#include "opt_compat_oldboot.h"
|
||||
#include "opt_copy_symtab.h"
|
||||
@ -192,16 +192,21 @@ __KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.124 2016/05/15 07:17:53 maxv Exp $");
|
||||
* instruction just clears the page table entry.
|
||||
*/
|
||||
#define fillkpt \
|
||||
cmpl $0,%ecx ; /* zero-sized? */ \
|
||||
je 2f ; \
|
||||
1: movl $0,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: 0 */ \
|
||||
movl %eax,(%ebx) ; /* store phys addr */ \
|
||||
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \
|
||||
addl $PAGE_SIZE,%eax ; /* next phys page */ \
|
||||
loop 1b ;
|
||||
loop 1b ; \
|
||||
2: ;
|
||||
|
||||
/*
|
||||
* fillkpt_nox - Same as fillkpt, but sets the NX/XD bit.
|
||||
*/
|
||||
#define fillkpt_nox \
|
||||
cmpl $0,%ecx ; /* zero-sized? */ \
|
||||
je 2f ; \
|
||||
pushl %ebp ; \
|
||||
movl RELOC(nox_flag),%ebp ; \
|
||||
1: movl %ebp,(PDE_SIZE-4)(%ebx) ; /* upper 32 bits: NX */ \
|
||||
@ -209,7 +214,8 @@ __KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.124 2016/05/15 07:17:53 maxv Exp $");
|
||||
addl $PDE_SIZE,%ebx ; /* next PTE/PDE */ \
|
||||
addl $PAGE_SIZE,%eax ; /* next phys page */ \
|
||||
loop 1b ; \
|
||||
popl %ebp ;
|
||||
popl %ebp ; \
|
||||
2: ;
|
||||
|
||||
/*
|
||||
* killkpt - Destroy a kernel page table
|
||||
|
Loading…
Reference in New Issue
Block a user