From owner-svn-src-all@freebsd.org Sun Jan 24 21:04:08 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C88157F21; Sun, 24 Jan 2016 21:04:08 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8A4E4667; Sun, 24 Jan 2016 21:04:08 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0OL47X7008822; Sun, 24 Jan 2016 21:04:07 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0OL47UM008815; Sun, 24 Jan 2016 21:04:07 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201601242104.u0OL47UM008815@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Sun, 24 Jan 2016 21:04:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r294683 - in stable/10/sys: amd64/amd64 arm/arm arm/xscale/ixp425 i386/i386 kern sparc64/sparc64 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 24 Jan 2016 21:04:09 -0000 Author: ian Date: Sun Jan 24 21:04:06 2016 New Revision: 294683 URL: https://svnweb.freebsd.org/changeset/base/294683 Log: MFC r293045, r293046: Make the 'env' directive described in config(5) work on all architectures, providing compiled-in static environment data that is used instead of any data passed in from a boot loader. Previously 'env' worked only on i386 and arm xscale systems, because it required the MD startup code to examine the global envmode variable and decide whether to use static_env or an environment obtained from the boot loader, and set the global kern_envp accordingly. Most startup code wasn't doing so. Making things even more complex, some mips startup code uses an alternate scheme that involves calling init_static_kenv() to pass an empty buffer and its size, then uses a series of kern_setenv() calls to populate that buffer. Now all MD startup code calls init_static_kenv(), and that routine provides a single point where envmode is checked and the decision is made whether to use the compiled-in static_kenv or the values provided by the MD code. The routine also continues to serve its original purpose for mips; if a non-zero buffer size is passed the routine installs the empty buffer ready to accept kern_setenv() values. Now if the size is zero, the provided buffer full of existing env data is installed. A NULL pointer can be passed if the boot loader provides no env data; this allows the static env to be installed if envmode is set to do so. Most of the work here is a near-mechanical change to call the init function instead of directly setting kern_envp. A notable exception is in xen/pv.c; that code was originally installing a buffer full of preformatted env data along with its non-zero size (like mips code does), which would have allowed kern_setenv() calls to wipe out the preformatted data. Now it passes a zero for the size so that the buffer of data it installs is treated as non-writeable. Also, revert accidental change that snuck into r293045. Modified: stable/10/sys/amd64/amd64/machdep.c stable/10/sys/arm/arm/machdep.c stable/10/sys/arm/xscale/ixp425/avila_machdep.c stable/10/sys/i386/i386/machdep.c stable/10/sys/kern/kern_environment.c stable/10/sys/sparc64/sparc64/machdep.c Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/amd64/machdep.c ============================================================================== --- stable/10/sys/amd64/amd64/machdep.c Sun Jan 24 20:15:52 2016 (r294682) +++ stable/10/sys/amd64/amd64/machdep.c Sun Jan 24 21:04:06 2016 (r294683) @@ -1847,7 +1847,7 @@ hammer_time(u_int64_t modulep, u_int64_t if (kmdp == NULL) kmdp = preload_search_by_type("elf64 kernel"); boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); - kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *) + KERNBASE; + init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *) + KERNBASE, 0); #ifdef DDB ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); Modified: stable/10/sys/arm/arm/machdep.c ============================================================================== --- stable/10/sys/arm/arm/machdep.c Sun Jan 24 20:15:52 2016 (r294682) +++ stable/10/sys/arm/arm/machdep.c Sun Jan 24 21:04:06 2016 (r294683) @@ -826,6 +826,8 @@ fake_preload_metadata(struct arm_boot_pa fake_preload[i] = 0; preload_metadata = (void *)fake_preload; + init_static_kenv(NULL, 0); + return (lastaddr); } @@ -901,6 +903,8 @@ linux_parse_boot_param(struct arm_boot_p bcopy(atag_list, atags, (char *)walker - (char *)atag_list + ATAG_SIZE(walker)); + init_static_kenv(NULL, 0); + return fake_preload_metadata(abp); } #endif @@ -929,7 +933,7 @@ freebsd_parse_boot_param(struct arm_boot return 0; boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); - kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); + init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0); lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); #ifdef DDB ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); Modified: stable/10/sys/arm/xscale/ixp425/avila_machdep.c ============================================================================== --- stable/10/sys/arm/xscale/ixp425/avila_machdep.c Sun Jan 24 20:15:52 2016 (r294682) +++ stable/10/sys/arm/xscale/ixp425/avila_machdep.c Sun Jan 24 21:04:06 2016 (r294683) @@ -223,8 +223,8 @@ initarm(struct arm_boot_params *abp) pcpu_init(pcpup, 0, sizeof(struct pcpu)); PCPU_SET(curthread, &thread0); - if (envmode == 1) - kern_envp = static_env; + init_static_kenv(NULL, 0); + /* Do basic tuning, hz etc */ init_param1(); @@ -420,10 +420,6 @@ initarm(struct arm_boot_params *abp) init_param2(physmem); kdb_init(); - /* use static kernel environment if so configured */ - if (envmode == 1) - kern_envp = static_env; - return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP - sizeof(struct pcb))); #undef next_page Modified: stable/10/sys/i386/i386/machdep.c ============================================================================== --- stable/10/sys/i386/i386/machdep.c Sun Jan 24 20:15:52 2016 (r294682) +++ stable/10/sys/i386/i386/machdep.c Sun Jan 24 21:04:06 2016 (r294683) @@ -3190,10 +3190,11 @@ init386(first) } else { metadata_missing = 1; } - if (envmode == 1) - kern_envp = static_env; - else if (bootinfo.bi_envp) - kern_envp = (caddr_t)bootinfo.bi_envp + KERNBASE; + + if (bootinfo.bi_envp) + init_static_kenv((caddr_t)bootinfo.bi_envp + KERNBASE, 0); + else + init_static_kenv(NULL, 0); /* Init basic tunables, hz etc */ init_param1(); Modified: stable/10/sys/kern/kern_environment.c ============================================================================== --- stable/10/sys/kern/kern_environment.c Sun Jan 24 20:15:52 2016 (r294682) +++ stable/10/sys/kern/kern_environment.c Sun Jan 24 21:04:06 2016 (r294683) @@ -210,12 +210,44 @@ done: return (error); } +/* + * Populate the initial kernel environment. + * + * This is called very early in MD startup, either to provide a copy of the + * environment obtained from a boot loader, or to provide an empty buffer into + * which MD code can store an initial environment using kern_setenv() calls. + * + * If the global envmode is 1, the environment is initialized from the global + * static_env[], regardless of the arguments passed. This implements the env + * keyword described in config(5). In this case env_pos is set to env_len, + * causing kern_setenv() to return -1 (if len > 0) or panic (if len == 0) until + * the dynamic environment is available. The envmode and static_env variables + * are defined in env.c which is generated by config(8). + * + * If len is non-zero, the caller is providing an empty buffer. The caller will + * subsequently use kern_setenv() to add up to len bytes of initial environment + * before the dynamic environment is available. + * + * If len is zero, the caller is providing a pre-loaded buffer containing + * environment strings. Additional strings cannot be added until the dynamic + * environment is available. The memory pointed to must remain stable at least + * until sysinit runs init_dynamic_kenv(). If no initial environment is + * available from the boot loader, passing a NULL pointer allows the static_env + * to be installed if it is configured. + */ void init_static_kenv(char *buf, size_t len) { - kern_envp = buf; - env_len = len; - env_pos = 0; + + if (envmode == 1) { + kern_envp = static_env; + env_len = len; + env_pos = len; + } else { + kern_envp = buf; + env_len = len; + env_pos = 0; + } } /* Modified: stable/10/sys/sparc64/sparc64/machdep.c ============================================================================== --- stable/10/sys/sparc64/sparc64/machdep.c Sun Jan 24 20:15:52 2016 (r294682) +++ stable/10/sys/sparc64/sparc64/machdep.c Sun Jan 24 21:04:06 2016 (r294683) @@ -383,7 +383,8 @@ sparc64_init(caddr_t mdp, u_long o1, u_l kmdp = preload_search_by_type("elf kernel"); if (kmdp != NULL) { boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int); - kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *); + init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), + 0); end = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t); kernel_tlb_slots = MD_FETCH(kmdp, MODINFOMD_DTLB_SLOTS, int);