Split the {text+rodata} chunk in two separate chunks on x86. The

rodata segment now loses the large page optimization, gets mapped inside
the data segment, and therefore becomes RWX. It may break the build on
Xen.
This commit is contained in:
maxv 2016-05-12 06:45:16 +00:00
parent e4c74434a0
commit 09b37bb062
7 changed files with 37 additions and 32 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.86 2016/05/11 19:35:08 maxv Exp $ */
/* $NetBSD: locore.S,v 1.87 2016/05/12 06:45:16 maxv Exp $ */
/*
* Copyright-o-rama!
@ -617,11 +617,11 @@ no_NOX:
addl %ecx,%ebx
/*
* Compute &__data_start - KERNBASE. This can't be > 4G, or we can't
* Compute &__rodata_start - KERNBASE. This can't be > 4G, or we can't
* deal with it anyway, since we can't load it in 32 bit mode. So use
* the bottom 32 bits.
*/
movl $RELOC(__data_start),%edx
movl $RELOC(__rodata_start),%edx
andl $~PGOFSET,%edx
/* Map the kernel text read-only. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.215 2016/02/15 20:35:59 riastradh Exp $ */
/* $NetBSD: machdep.c,v 1.216 2016/05/12 06:45:16 maxv Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011
@ -111,7 +111,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.215 2016/02/15 20:35:59 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.216 2016/05/12 06:45:16 maxv Exp $");
/* #define XENDEBUG_LOW */
@ -2102,6 +2102,7 @@ mm_md_kernacc(void *ptr, vm_prot_t prot, bool *handled)
if (v >= (vaddr_t)&start && v < (vaddr_t)kern_end) {
*handled = true;
/* Either the text or rodata segment */
if (v < (vaddr_t)&__data_start && (prot & VM_PROT_WRITE))
return EFAULT;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern.ldscript,v 1.18 2016/05/08 08:30:41 maxv Exp $ */
/* $NetBSD: kern.ldscript,v 1.19 2016/05/12 06:45:16 maxv Exp $ */
#include "assym.h"
@ -23,6 +23,12 @@ SECTIONS
_etext = . ;
PROVIDE (etext = .) ;
/*
* Push the rodata segment up to the next large page boundary so that we
* can map the text segment with large pages.
*/
. = ALIGN(__LARGE_PAGE_SIZE);
__rodata_start = . ;
.rodata :
{
@ -30,12 +36,6 @@ SECTIONS
*(.rodata.*)
}
/*
* Push the data segment up to the next large page boundary so that we
* can map the text+rodata segments with large pages.
*/
. = ALIGN(__LARGE_PAGE_SIZE);
__data_start = . ;
.data :
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern.ldscript,v 1.16 2015/11/28 18:08:40 maxv Exp $ */
/* $NetBSD: kern.ldscript,v 1.17 2016/05/12 06:45:16 maxv Exp $ */
#include "assym.h"
@ -15,17 +15,19 @@ SECTIONS
_etext = . ;
PROVIDE (etext = .) ;
/*
* Adjust the address for the rodata segment. We want to adjust up to
* the same address within the page on the next page up.
*/
. = ALIGN(0x1000) + (. & (0x1000 - 1));
__rodata_start = . ;
.rodata :
{
*(.rodata)
*(.rodata.*)
}
/*
* Adjust the address for the data segment. We want to adjust up to
* the same address within the page on the next page up.
*/
. = ALIGN(0x1000) + (. & (0x1000 - 1));
__data_start = . ;
.data :
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: locore.S,v 1.115 2016/05/11 17:48:05 maxv Exp $ */
/* $NetBSD: locore.S,v 1.116 2016/05/12 06:45:16 maxv Exp $ */
/*
* Copyright-o-rama!
@ -128,7 +128,7 @@
*/
#include <machine/asm.h>
__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.115 2016/05/11 17:48:05 maxv Exp $");
__KERNEL_RCSID(0, "$NetBSD: locore.S,v 1.116 2016/05/12 06:45:16 maxv Exp $");
#include "opt_compat_oldboot.h"
#include "opt_copy_symtab.h"
@ -613,11 +613,11 @@ try586: /* Use the `cpuid' instruction. */
* Build initial page tables.
*/
/*
* Compute &__data_start - KERNBASE. This can't be > 4G,
* Compute &__rodata_start - KERNBASE. This can't be > 4G,
* or we can't deal with it anyway, since we can't load it in
* 32 bit mode. So use the bottom 32 bits.
*/
movl $RELOC(__data_start),%edx
movl $RELOC(__rodata_start),%edx
andl $~PGOFSET,%edx
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: db_memrw.c,v 1.1 2012/05/07 17:45:29 jym Exp $ */
/* $NetBSD: db_memrw.c,v 1.2 2016/05/12 06:45:16 maxv Exp $ */
/*-
* Copyright (c) 1996, 2000 The NetBSD Foundation, Inc.
@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: db_memrw.c,v 1.1 2012/05/07 17:45:29 jym Exp $");
__KERNEL_RCSID(0, "$NetBSD: db_memrw.c,v 1.2 2016/05/12 06:45:16 maxv Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@ -174,13 +174,15 @@ db_write_text(vaddr_t addr, size_t size, const char *data)
void
db_write_bytes(vaddr_t addr, size_t size, const char *data)
{
extern int __rodata_start;
extern int __data_start;
char *dst;
dst = (char *)addr;
/* If any part is in kernel text, use db_write_text() */
if (addr >= KERNBASE && addr < (vaddr_t)&__data_start) {
/* If any part is in kernel text or rodata, use db_write_text() */
if ((addr >= KERNBASE && addr < (vaddr_t)&__rodata_start) ||
(addr >= (vaddr_t)&__rodata_start && addr < (vaddr_t)&__data_start)) {
db_write_text(addr, size, data);
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.c,v 1.190 2016/01/26 14:34:50 hannken Exp $ */
/* $NetBSD: pmap.c,v 1.191 2016/05/12 06:45:16 maxv Exp $ */
/*-
* Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
@ -171,7 +171,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.190 2016/01/26 14:34:50 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.191 2016/05/12 06:45:16 maxv Exp $");
#include "opt_user_ldt.h"
#include "opt_lockdebug.h"
@ -1301,7 +1301,7 @@ pmap_bootstrap(vaddr_t kva_start)
if (cpu_feature[0] & CPUID_PSE) {
paddr_t pa;
extern char __data_start;
extern char __rodata_start;
lcr4(rcr4() | CR4_PSE); /* enable hardware (via %cr4) */
pmap_largepages = 1; /* enable software */
@ -1317,9 +1317,9 @@ pmap_bootstrap(vaddr_t kva_start)
/*
* now, remap the kernel text using large pages. we
* assume that the linker has properly aligned the
* .data segment to a NBPD_L2 boundary.
* .rodata segment to a NBPD_L2 boundary.
*/
kva_end = rounddown((vaddr_t)&__data_start, NBPD_L1);
kva_end = rounddown((vaddr_t)&__rodata_start, NBPD_L1);
for (pa = 0, kva = KERNBASE; kva + NBPD_L2 <= kva_end;
kva += NBPD_L2, pa += NBPD_L2) {
pde = &L2_BASE[pl2_i(kva)];
@ -1331,7 +1331,7 @@ pmap_bootstrap(vaddr_t kva_start)
aprint_normal("kernel text is mapped with %" PRIuPSIZE " large "
"pages and %" PRIuPSIZE " normal pages\n",
howmany(kva - KERNBASE, NBPD_L2),
howmany((vaddr_t)&__data_start - kva, NBPD_L1));
howmany((vaddr_t)&__rodata_start - kva, NBPD_L1));
#endif /* defined(DEBUG) */
}
#endif /* !XEN */