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:
maxv 2016-07-25 12:11:40 +00:00
parent 3a0f73376f
commit b606a278f5
3 changed files with 11 additions and 6 deletions

View File

@ -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];
/*

View File

@ -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

View File

@ -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 */