From 2b35d82f32a340a523ebae3def0bc3a1b21d9393 Mon Sep 17 00:00:00 2001 From: joerg Date: Wed, 26 Dec 2007 16:28:15 +0000 Subject: [PATCH] Add PHYSMEM_MAX_ADDR and PHYSMEM_MAX_SIZE options. This limit physical memory based on overall size (useful for debugging to keep core dumps small) or maximum address (when using devices with bus dma limits). Contrary to REALBASEMEM and REALEXTMEM, they still use the BIOS memory map and can therefore deal with fragmented memory. --- sys/arch/amd64/amd64/machdep.c | 30 ++++++++++++++++++++++++++---- sys/arch/amd64/conf/GENERIC | 11 +++++++++-- sys/arch/amd64/conf/files.amd64 | 5 ++++- sys/arch/i386/conf/GENERIC | 11 +++++++++-- sys/arch/i386/conf/files.i386 | 5 ++++- sys/arch/i386/i386/machdep.c | 30 +++++++++++++++++++++++++----- 6 files changed, 77 insertions(+), 15 deletions(-) diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index a2d686c9fabd..a9dcd447bfb9 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.73 2007/12/26 11:51:11 yamt Exp $ */ +/* $NetBSD: machdep.c,v 1.74 2007/12/26 16:28:16 joerg Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007 @@ -120,7 +120,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.73 2007/12/26 11:51:11 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.74 2007/12/26 16:28:16 joerg Exp $"); /* #define XENDEBUG_LOW */ @@ -134,6 +134,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.73 2007/12/26 11:51:11 yamt Exp $"); #include "opt_multiprocessor.h" #include "opt_lockdebug.h" #include "opt_mtrr.h" +#include "opt_physmem.h" #include "opt_realmem.h" #include "opt_xen.h" @@ -1108,6 +1109,7 @@ extern vector IDTVEC(oosyscall); extern vector *IDTVEC(exceptions)[]; #define KBTOB(x) ((size_t)(x) * 1024UL) +#define MBTOB(x) ((size_t)(x) * 1024UL * 1024UL) static void init_x86_64_msgbuf(void) @@ -1213,7 +1215,7 @@ init_x86_64(paddr_t first_avail) u_int64_t seg_start1, seg_end1; #if !defined(REALEXTMEM) && !defined(REALBASEMEM) struct btinfo_memmap *bim; - u_int64_t addr, size, io_end; + u_int64_t addr, size, io_end, new_physmem; #endif #else /* XEN */ __PRINTK(("init_x86_64(0x%lx)\n", first_avail)); @@ -1359,6 +1361,13 @@ init_x86_64(paddr_t first_avail) panic("init386: too many memory segments " "(increase VM_PHYSSEG_MAX)"); +#ifdef PHYSMEM_MAX_ADDR + if (seg_start >= MBTOB(PHYSMEM_MAX_ADDR)) + continue; + if (seg_end > MBTOB(PHYSMEM_MAX_ADDR)) + seg_end = MBTOB(PHYSMEM_MAX_ADDR); +#endif + seg_start = round_page(seg_start); seg_end = trunc_page(seg_end); @@ -1366,12 +1375,25 @@ init_x86_64(paddr_t first_avail) continue; mem_clusters[mem_cluster_cnt].start = seg_start; + new_physmem = physmem + + atop(seg_end - seg_start); + +#ifdef PHYSMEM_MAX_SIZE + if (physmem >= atop(MBTOB(PHYSMEM_MAX_SIZE))) + continue; + if (new_physmem > atop(MBTOB(PHYSMEM_MAX_SIZE))) { + seg_end = seg_start + + MBTOB(PHYSMEM_MAX_SIZE) - ptoa(physmem); + new_physmem = atop(MBTOB(PHYSMEM_MAX_SIZE)); + } +#endif + mem_clusters[mem_cluster_cnt].size = seg_end - seg_start; if (avail_end < seg_end) avail_end = seg_end; - physmem += atop(mem_clusters[mem_cluster_cnt].size); + physmem = new_physmem; mem_cluster_cnt++; } } diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC index 5746d30e16f3..68bf0737aa07 100644 --- a/sys/arch/amd64/conf/GENERIC +++ b/sys/arch/amd64/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.189 2007/12/24 07:54:26 kiyohara Exp $ +# $NetBSD: GENERIC,v 1.190 2007/12/26 16:28:17 joerg Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/amd64/conf/std.amd64" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.189 $" +#ident "GENERIC-$Revision: 1.190 $" maxusers 32 # estimated number of users @@ -44,6 +44,13 @@ maxusers 32 # estimated number of users #options REALBASEMEM=639 # size of base memory (in KB) #options REALEXTMEM=15360 # size of extended memory (in KB) +# The following options limit the overall size of physical memory +# and/or the maximum address used by the system. +# Contrary to REALBASEMEM and REALEXTMEM, they still use the BIOS memory map +# and can deal with holes in the memory layout. +#options PHYSMEM_MAX_SIZE=64 # max size of physical memory (in MB) +#options PHYSMEM_MAX_ADDR=2048 # don't use memory above this (in MB) + # Standard system options options INSECURE # disable kernel security levels - X needs this diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index 0a64e86b7740..9765e00f2eae 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $NetBSD: files.amd64,v 1.51 2007/12/18 07:17:10 joerg Exp $ +# $NetBSD: files.amd64,v 1.52 2007/12/26 16:28:17 joerg Exp $ # # new style config file for amd64 architecture # @@ -18,6 +18,9 @@ defparam CPURESET_DELAY # The REAL{BASE,EXT}MEM options defparam opt_realmem.h REALBASEMEM REALEXTMEM +# The PHYSMEM_MAX_{SIZE,ADDR} optionms +defparam opt_physmem.h PHYSMEM_MAX_ADDR PHYSMEM_MAX_SIZE + # # XXX these are just here at the moment so that we can share files # with the i386 (they include the opt_*.h for these) diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC index 3d24a0e64c2d..0f692f981f3e 100644 --- a/sys/arch/i386/conf/GENERIC +++ b/sys/arch/i386/conf/GENERIC @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.870 2007/12/25 01:03:32 ad Exp $ +# $NetBSD: GENERIC,v 1.871 2007/12/26 16:28:15 joerg Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.870 $" +#ident "GENERIC-$Revision: 1.871 $" maxusers 32 # estimated number of users @@ -76,6 +76,13 @@ options MULTIBOOT # Multiboot support (see multiboot(8)) #options REALBASEMEM=639 # size of base memory (in KB) #options REALEXTMEM=15360 # size of extended memory (in KB) +# The following options limit the overall size of physical memory +# and/or the maximum address used by the system. +# Contrary to REALBASEMEM and REALEXTMEM, they still use the BIOS memory map +# and can deal with holes in the memory layout. +#options PHYSMEM_MAX_SIZE=64 # max size of physical memory (in MB) +#options PHYSMEM_MAX_ADDR=2048 # don't use memory above this (in MB) + # Standard system options options INSECURE # disable kernel security levels - X needs this diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index 45ccb847ab07..370200152a84 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $NetBSD: files.i386,v 1.325 2007/12/23 17:29:27 jmcneill Exp $ +# $NetBSD: files.i386,v 1.326 2007/12/26 16:28:15 joerg Exp $ # # new style config file for i386 architecture # @@ -36,6 +36,9 @@ defflag opt_xserver.h XSERVER XSERVER_DDB # The REAL{BASE,EXT}MEM options defparam opt_realmem.h REALBASEMEM REALEXTMEM +# The PHYSMEM_MAX_{SIZE,ADDR} optionms +defparam opt_physmem.h PHYSMEM_MAX_ADDR PHYSMEM_MAX_SIZE + # understand boot device passed by pre-1.3 bootblocks defflag COMPAT_OLDBOOT diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index c0716c4338e0..0146367725b7 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.618 2007/12/26 11:51:10 yamt Exp $ */ +/* $NetBSD: machdep.c,v 1.619 2007/12/26 16:28:16 joerg Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006 The NetBSD Foundation, Inc. @@ -72,7 +72,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.618 2007/12/26 11:51:10 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.619 2007/12/26 16:28:16 joerg Exp $"); #include "opt_beep.h" #include "opt_compat_ibcs2.h" @@ -85,6 +85,7 @@ __KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.618 2007/12/26 11:51:10 yamt Exp $"); #include "opt_kgdb.h" #include "opt_mtrr.h" #include "opt_multiprocessor.h" +#include "opt_physmem.h" #include "opt_realmem.h" #include "opt_user_ldt.h" #include "opt_vm86.h" @@ -1315,6 +1316,7 @@ extern vector IDTVEC(mach_trap); #endif #define KBTOB(x) ((size_t)(x) * 1024UL) +#define MBTOB(x) ((size_t)(x) * 1024UL * 1024UL) void cpu_init_idt() { @@ -1327,6 +1329,7 @@ void add_mem_cluster(uint64_t seg_start, uint64_t seg_end, uint32_t type) { extern struct extent *iomem_ex; + uint64_t new_physmem; int i; if (seg_end > 0x100000000ULL) { @@ -1388,6 +1391,13 @@ add_mem_cluster(uint64_t seg_start, uint64_t seg_end, uint32_t type) panic("init386: too many memory segments " "(increase VM_PHYSSEG_MAX)"); +#ifdef PHYSMEM_MAX_ADDR + if (seg_start >= MBTOB(PHYSMEM_MAX_ADDR)) + return; + if (seg_end > MBTOB(PHYSMEM_MAX_ADDR)) + seg_end = MBTOB(PHYSMEM_MAX_ADDR); +#endif + seg_start = round_page(seg_start); seg_end = trunc_page(seg_end); @@ -1395,12 +1405,22 @@ add_mem_cluster(uint64_t seg_start, uint64_t seg_end, uint32_t type) return; mem_clusters[mem_cluster_cnt].start = seg_start; - mem_clusters[mem_cluster_cnt].size = - seg_end - seg_start; + new_physmem = physmem + atop(seg_end - seg_start); + +#ifdef PHYSMEM_MAX_SIZE + if (physmem >= atop(MBTOB(PHYSMEM_MAX_SIZE))) + return; + if (new_physmem > atop(MBTOB(PHYSMEM_MAX_SIZE))) { + seg_end = seg_start + MBTOB(PHYSMEM_MAX_SIZE) - ptoa(physmem); + new_physmem = atop(MBTOB(PHYSMEM_MAX_SIZE)); + } +#endif + + mem_clusters[mem_cluster_cnt].size = seg_end - seg_start; if (avail_end < seg_end) avail_end = seg_end; - physmem += atop(mem_clusters[mem_cluster_cnt].size); + physmem = new_physmem; mem_cluster_cnt++; }