From b606a278f5f947132930a667c89dd46c81cdf1e8 Mon Sep 17 00:00:00 2001 From: maxv Date: Mon, 25 Jul 2016 12:11:40 +0000 Subject: [PATCH] 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. --- sys/arch/x86/include/pmap.h | 3 ++- sys/arch/x86/x86/lapic.c | 6 +++--- sys/arch/x86/x86/pmap.c | 8 ++++++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/sys/arch/x86/include/pmap.h b/sys/arch/x86/include/pmap.h index 08c6b6f326da..529df633d6f1 100644 --- a/sys/arch/x86/include/pmap.h +++ b/sys/arch/x86/include/pmap.h @@ -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]; /* diff --git a/sys/arch/x86/x86/lapic.c b/sys/arch/x86/x86/lapic.c index 593832946aab..b76a1d52e66d 100644 --- a/sys/arch/x86/x86/lapic.c +++ b/sys/arch/x86/x86/lapic.c @@ -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 -__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 diff --git a/sys/arch/x86/x86/pmap.c b/sys/arch/x86/x86/pmap.c index e73f1c384c19..c01956cbcace 100644 --- a/sys/arch/x86/x86/pmap.c +++ b/sys/arch/x86/x86/pmap.c @@ -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 -__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 */