git: 8c99dfed5412 - main - Port subr_physmem to userspace and add tests
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 06 Apr 2022 13:24:02 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=8c99dfed541263bd51cae943684bcc13768c2a36 commit 8c99dfed541263bd51cae943684bcc13768c2a36 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2022-03-28 10:20:29 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2022-04-06 13:13:05 +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 --- sys/kern/subr_physmem.c | 25 ++++++++ tests/sys/kern/Makefile | 4 ++ tests/sys/kern/subr_physmem_test.c | 122 +++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+) diff --git a/sys/kern/subr_physmem.c b/sys/kern/subr_physmem.c index e3b85f387b55..c149edaf0281 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 @@ -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 @@ -469,6 +492,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. * @@ -495,6 +519,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 dbf88dd89a9a..ff147730b21d 100644 --- a/tests/sys/kern/Makefile +++ b/tests/sys/kern/Makefile @@ -23,6 +23,7 @@ ATF_TESTS_C+= ptrace_test TEST_METADATA.ptrace_test+= timeout="15" ATF_TESTS_C+= reaper ATF_TESTS_C+= sigaltstack +ATF_TESTS_C+= subr_physmem_test PLAIN_TESTS_C+= subr_unit_test ATF_TESTS_C+= sysctl_kern_proc ATF_TESTS_C+= sys_getrandom @@ -78,6 +79,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()); +}