git: 0edb26c3bad0 - stable/13 - Port subr_physmem to userspace and add tests
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 03 May 2022 14:04:40 UTC
The branch stable/13 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=0edb26c3bad0419d1107f78cab834e165daa39fa commit 0edb26c3bad0419d1107f78cab834e165daa39fa Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2022-03-28 10:20:29 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2022-05-03 14:04:04 +0000 Port subr_physmem to userspace and add tests These give us some confidience we haven't broken anything in early boot code that may be running before the console. Reviewed by: emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34691 (cherry picked from commit 8c99dfed541263bd51cae943684bcc13768c2a36) Disable the physmem test for now It fails to build on at least i386 (cherry picked from commit d8819d88af529974bac1fe49b713dacf1f3d7239) Enable subr_physmem_test on supported architectures Only build where it's supported. While here add support for amd64 to help with testing. Sponsored by: The FreeBSD Foundation (cherry picked from commit 41e6d2091ce5653d4ace3f0b9cbde1375d458c67) --- sys/kern/subr_physmem.c | 27 +++++++- tests/sys/kern/Makefile | 6 ++ tests/sys/kern/subr_physmem_test.c | 122 +++++++++++++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 1 deletion(-) diff --git a/sys/kern/subr_physmem.c b/sys/kern/subr_physmem.c index a4b865bed56d..106200dd814e 100644 --- a/sys/kern/subr_physmem.c +++ b/sys/kern/subr_physmem.c @@ -29,8 +29,10 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#ifdef _KERNEL #include "opt_acpi.h" #include "opt_ddb.h" +#endif /* * Routines for describing and initializing anything related to physical memory. @@ -40,12 +42,19 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/kernel.h> #include <sys/physmem.h> + +#ifdef _KERNEL #include <vm/vm.h> #include <vm/vm_param.h> #include <vm/vm_page.h> #include <vm/vm_phys.h> #include <vm/vm_dumpset.h> #include <machine/md_var.h> +#else +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#endif /* * These structures are used internally to keep track of regions of physical @@ -64,7 +73,7 @@ __FBSDID("$FreeBSD$"); #if defined(__arm__) #define MAX_PHYS_ADDR 0xFFFFFFFFull -#elif defined(__aarch64__) || defined(__riscv) +#elif defined(__aarch64__) || defined(__amd64__) || defined(__riscv) #define MAX_PHYS_ADDR 0xFFFFFFFFFFFFFFFFull #endif @@ -87,6 +96,20 @@ static size_t excnt; long realmem; long Maxmem; +#ifndef _KERNEL +static void +panic(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + vfprintf(stderr, fmt, va); + fprintf(stderr, "\n"); + va_end(va); + __builtin_trap(); +} +#endif + /* * Print the contents of the physical and excluded region tables using the * provided printf-like output function (which will be either printf or @@ -389,6 +412,7 @@ physmem_avail(vm_paddr_t *avail, size_t maxavail) return (regions_to_avail(avail, EXFLAG_NOALLOC, maxavail, 0, NULL, NULL)); } +#ifdef _KERNEL /* * Process all the regions added earlier into the global avail lists. * @@ -415,6 +439,7 @@ physmem_init_kernel_globals(void) panic("No memory entries in phys_avail"); Maxmem = atop(phys_avail[nextidx - 1]); } +#endif #ifdef DDB #include <ddb/ddb.h> diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile index fe23803c2267..77e514e9e747 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -22,6 +22,9 @@ ATF_TESTS_C+= ptrace_test TEST_METADATA.ptrace_test+= timeout="15" ATF_TESTS_C+= reaper ATF_TESTS_C+= sigaltstack +.if ${MACHINE_ARCH} != "i386" && ${MACHINE_ARCH:Mpowerpc*} == "" +ATF_TESTS_C+= subr_physmem_test +.endif PLAIN_TESTS_C+= subr_unit_test ATF_TESTS_C+= sysctl_kern_proc ATF_TESTS_C+= sys_getrandom @@ -77,6 +80,9 @@ SRCS.libkern_crc32+= crc32_sse42.c SRCS.libkern_crc32+= crc32c_armv8.S .endif +CFLAGS.subr_physmem.c+= -D_WANT_FREEBSD_BITSET +SRCS.subr_physmem_test+= subr_physmem_test.c subr_physmem.c + # subr_unit.c contains functions whose prototypes lie in headers that cannot be # included in userland. But as far as subr_unit_test goes, they're effectively # static. So it's ok to disable -Wmissing-prototypes for this program. diff --git a/tests/sys/kern/subr_physmem_test.c b/tests/sys/kern/subr_physmem_test.c new file mode 100644 index 000000000000..a562bacec65c --- /dev/null +++ b/tests/sys/kern/subr_physmem_test.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2021 The FreeBSD Foundation + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/physmem.h> + +#include <atf-c.h> + +ATF_TC_WITHOUT_HEAD(hwregion); +ATF_TC_BODY(hwregion, tc) +{ + vm_paddr_t avail[4]; + size_t len; + + physmem_hardware_region(2 * PAGE_SIZE, PAGE_SIZE); + + len = physmem_avail(avail, 4); + ATF_CHECK_EQ(len, 2); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 3 * PAGE_SIZE); + + /* Add an overlap */ + physmem_hardware_region(2 * PAGE_SIZE, 2 * PAGE_SIZE); + len = physmem_avail(avail, 4); + ATF_CHECK_EQ(len, 2); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 4 * PAGE_SIZE); + + /* Add a touching region */ + physmem_hardware_region(4 * PAGE_SIZE, PAGE_SIZE); + len = physmem_avail(avail, 4); + ATF_CHECK_EQ(len, 2); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 5 * PAGE_SIZE); + + /* Add a partial overlap */ + physmem_hardware_region(4 * PAGE_SIZE, 2 * PAGE_SIZE); + len = physmem_avail(avail, 4); + ATF_CHECK_EQ(len, 2); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 6 * PAGE_SIZE); + + /* Add a non-page aligned section */ + physmem_hardware_region(6 * PAGE_SIZE, PAGE_SIZE / 2); + len = physmem_avail(avail, 4); + ATF_CHECK_EQ(len, 2); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 6 * PAGE_SIZE); + +#ifdef notyet /* This doesn't currently work */ + /* Add the remaining part of the page */ + physmem_hardware_region(6 * PAGE_SIZE + PAGE_SIZE / 2, PAGE_SIZE / 2); + len = physmem_avail(avail, 4); + ATF_CHECK_EQ(len, 2); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 7 * PAGE_SIZE); +#endif +} + +ATF_TC_WITHOUT_HEAD(hwregion_exclude); +ATF_TC_BODY(hwregion_exclude, tc) +{ + vm_paddr_t avail[6]; + size_t len; + + physmem_hardware_region(2 * PAGE_SIZE, 5 * PAGE_SIZE); + physmem_exclude_region(4 * PAGE_SIZE, PAGE_SIZE, EXFLAG_NOALLOC); + + len = physmem_avail(avail, 6); + ATF_CHECK_EQ(len, 4); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 4 * PAGE_SIZE); + ATF_CHECK_EQ(avail[2], 5 * PAGE_SIZE); + ATF_CHECK_EQ(avail[3], 7 * PAGE_SIZE); + + /* Check mis-aligned/sized excluded regions work */ + physmem_exclude_region(4 * PAGE_SIZE - 1, PAGE_SIZE + 2, + EXFLAG_NOALLOC); + len = physmem_avail(avail, 6); + ATF_CHECK_EQ(len, 4); + ATF_CHECK_EQ(avail[0], 2 * PAGE_SIZE); + ATF_CHECK_EQ(avail[1], 3 * PAGE_SIZE); + ATF_CHECK_EQ(avail[2], 6 * PAGE_SIZE); + ATF_CHECK_EQ(avail[3], 7 * PAGE_SIZE); +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, hwregion); + ATF_TP_ADD_TC(tp, hwregion_exclude); + return (atf_no_error()); +}