The L1 entry of the first page of the data segment is overwritten for the
LAPIC page, and set as RWX+PG_N. The LAPIC pa is fixed, and its va resides in the data segment. Because of this error-prone design, the kernel image map is not linear, and I first thought it was a bug (as I vaguely said in PR/51148). Using large pages for the data segment is therefore wrong, since the first page does not actually belong to the data segment (even if its va is in the range). This bug is not triggered currently, since local_apic is not large-page-aligned. We will certainly have to allocate a va dynamically instead of using the first page of data; but for now, disable large pages on the data segment, and map the LAPIC as RW. This is the last x86-specific RWX page.
This commit is contained in:
parent
3a0f73376f
commit
b606a278f5
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.h,v 1.58 2016/07/01 11:10:48 maxv Exp $ */
|
||||
/* $NetBSD: pmap.h,v 1.59 2016/07/25 12:11:40 maxv Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Charles D. Cranor and Washington University.
|
||||
|
@ -209,6 +209,7 @@ struct pmap {
|
|||
extern u_long PDPpaddr;
|
||||
|
||||
extern pd_entry_t pmap_pg_g; /* do we support PG_G? */
|
||||
extern pd_entry_t pmap_pg_nx; /* do we support PG_NX? */
|
||||
extern long nkptp[PTP_LEVELS];
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lapic.c,v 1.51 2015/07/27 15:45:20 msaitoh Exp $ */
|
||||
/* $NetBSD: lapic.c,v 1.52 2016/07/25 12:11:40 maxv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000, 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -32,7 +32,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.51 2015/07/27 15:45:20 msaitoh Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: lapic.c,v 1.52 2016/07/25 12:11:40 maxv Exp $");
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#include "opt_mpbios.h" /* for MPDEBUG */
|
||||
|
@ -125,7 +125,7 @@ lapic_map(paddr_t lapic_base)
|
|||
*/
|
||||
|
||||
pte = kvtopte(va);
|
||||
*pte = lapic_base | PG_RW | PG_V | PG_N | pmap_pg_g;
|
||||
*pte = lapic_base | PG_RW | PG_V | PG_N | pmap_pg_g | pmap_pg_nx;
|
||||
invlpg(va);
|
||||
|
||||
#ifdef MULTIPROCESSOR
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pmap.c,v 1.216 2016/07/22 14:08:33 maxv Exp $ */
|
||||
/* $NetBSD: pmap.c,v 1.217 2016/07/25 12:11:40 maxv Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008, 2010, 2016 The NetBSD Foundation, Inc.
|
||||
|
@ -171,7 +171,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.216 2016/07/22 14:08:33 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.217 2016/07/25 12:11:40 maxv Exp $");
|
||||
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_lockdebug.h"
|
||||
|
@ -1573,7 +1573,9 @@ pmap_remap_largepages(void)
|
|||
{
|
||||
extern char __rodata_start;
|
||||
extern char __data_start;
|
||||
#if 0
|
||||
extern char __kernel_end;
|
||||
#endif
|
||||
pd_entry_t *pde;
|
||||
vaddr_t kva, kva_end;
|
||||
paddr_t pa;
|
||||
|
@ -1604,6 +1606,7 @@ pmap_remap_largepages(void)
|
|||
tlbflushg();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Remap the kernel data+bss using large pages. */
|
||||
kva = roundup((vaddr_t)&__data_start, NBPD_L2);
|
||||
kva_end = rounddown((vaddr_t)&__kernel_end, NBPD_L1);
|
||||
|
@ -1613,6 +1616,7 @@ pmap_remap_largepages(void)
|
|||
*pde = pa | pmap_pg_g | PG_PS | pmap_pg_nx | PG_KW | PG_V;
|
||||
tlbflushg();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif /* !XEN */
|
||||
|
||||
|
|
Loading…
Reference in New Issue