From nobody Wed Jan 03 04:48:17 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T4cfp0fT1z54cJ2; Wed, 3 Jan 2024 04:48:18 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T4cfn62S3z3C5t; Wed, 3 Jan 2024 04:48:17 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704257297; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=DKLmfaa4+1BTgkWpVnNobGRNsL7an4cfmXKd/GcPUac=; b=g0X3z2WYY0qauNx9vZ3NOKhpjhNnVhmCwyiNNIxaWSk49ymBRqneAU4PdJn1pSIx2Pj2YN ccxSnIsG4Z+tTA5EzLmJjJn9s60fOIwmkdY7UjHA1fXxWpBJpu41xXmjY7nRFsB5dzrQBn WwgYYzBnr+swcIpc7AM0FXYe8Ui2Tx5xcUFRGM2+FrQXD1xaKyh2Fs9BsPZseQ4YB7HpKs EjyQkLh8zBmAWf8V6f3CjLXBpgMKo5mgyTBQiyM0MPak4KGlDye1/8yyFHpqY9RfnQ+APX eR9jXZeZd9e5CeVco46lGlrgAkqa732Wintk/7Oe/49h9LQulnr7s6qbll8Dzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704257297; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=DKLmfaa4+1BTgkWpVnNobGRNsL7an4cfmXKd/GcPUac=; b=jp7hQbHpfRU1Uhm0fvBDW1DUtO2it4jLpXxrLPDiMFTKhRPo1/cawxKhK6g02UpbJELLBq cGVb5e3qnnTghFee/goxycmUf1TrtbWgkQRtZsaIMPUabyzn7ZZ2jvY9S0+GMeg1cKrAji yo8U2yV5UQWDhYWYDjJKUW/wVyzEvxEJMicSttI7zZuHvF+HdgR9bswcLojbqJiyn3HG6e ZRndiGa/2tvVACfI1G+ptRmMkyTy+8RgdF5sisvbeMpjGs1xzH7aFX9+M17ABIP6mKPdJh PbW6+SxsuXrKwa7PjLDT5fRG16TjPkNh0TOWjjx85slk9BTsRNH2k5V+hhkNVQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704257297; a=rsa-sha256; cv=none; b=pLydBmdsUQ5tDuOoO/6dXH5uWgYXNnTF9u7j99oRamNpxxor7Pfyr5Y4K/nOTcHwkoBABu ql6tIGJTAPWcwkTjMFkfp1RWPhZpuID1WUjogCM3gIpA3n2VrsrRy6+KxAMXO1VM0B8G8B immxN0A3M1LifjQWgMaPme+a+JtbYZ9CVx3b5BI6dIPHaH7Vc8gyQrYcWXDspCpVg90CHQ 4QRNSnKiAIDo90nm5Xq7Db6e3bAPTHqWTceadwGECrcOpAATvQnZSomXgi9d/IpB15pCfT Z1DGB8K9VFeSL041gCyRoTwmff3XKWcJtl7NDMIMU5rU7wKNEs3WGD64+51igg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T4cfn55QmzWj4; Wed, 3 Jan 2024 04:48:17 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 4034mH2f025973; Wed, 3 Jan 2024 04:48:17 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 4034mHCL025970; Wed, 3 Jan 2024 04:48:17 GMT (envelope-from git) Date: Wed, 3 Jan 2024 04:48:17 GMT Message-Id: <202401030448.4034mHCL025970@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Kyle Evans Subject: git: bafbd6445e5d - stable/13 - loader: provide a features table for binary compatibility advertisement List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: bafbd6445e5d434b4d99e9e6e550f169e033c24f Auto-Submitted: auto-generated The branch stable/13 has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=bafbd6445e5d434b4d99e9e6e550f169e033c24f commit bafbd6445e5d434b4d99e9e6e550f169e033c24f Author: Kyle Evans AuthorDate: 2023-12-08 21:36:06 +0000 Commit: Kyle Evans CommitDate: 2024-01-03 04:47:26 +0000 loader: provide a features table for binary compatibility advertisement liblua now provides a loader.has_feature() function to probe the loader binary for features advertised. name => desc mappings are provided in loader.features to get a list of all of the features loader *can* support. core.hasFeature is provided as a shim to loader.has_feature so that individual consumers don't need to think about the logic of the loader module not providing has_feature; we know that means the feature isn't enabled. The first consumer of this will be EARLY_ACPI to advertise that the loader binary probes for ACPI presence before the interpreter has started, so that we know whether we can trust the presence of acpi.rsdp as relatively authoritative. In general, it's intended to be used to avoid breaking new scripts on older loaders within reason. This will be used in lua as `core.hasFeature("EARLY_ACPI")`, while the C bits of loader will `feature_enable(FEATURE_EARLY_ACPI)`. Reviewed by: imp (cherry picked from commit 1631382cf2820245cc72965498ff174bb548dd63) --- stand/liblua/lutils.c | 48 ++++++++++++++++++++++++++++++++++++++++ stand/libsa/Makefile | 2 +- stand/libsa/features.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ stand/libsa/libsa.3 | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++ stand/libsa/stand.h | 15 +++++++++++++ stand/lua/core.lua | 9 ++++++++ stand/lua/core.lua.8 | 9 +++++++- 7 files changed, 197 insertions(+), 2 deletions(-) diff --git a/stand/liblua/lutils.c b/stand/liblua/lutils.c index db0a8cc73e7f..6c2cceeff3c3 100644 --- a/stand/liblua/lutils.c +++ b/stand/liblua/lutils.c @@ -76,6 +76,25 @@ lua_has_command(lua_State *L) return 1; } +static int +lua_has_feature(lua_State *L) +{ + const char *feature; + char *msg; + + feature = luaL_checkstring(L, 1); + + if (feature_name_is_enabled(feature)) { + lua_pushboolean(L, 1); + return 1; + } + + lua_pushnil(L); + lua_pushstring(L, "Feature not enabled"); + return 2; +} + + static int lua_perform(lua_State *L) { @@ -553,6 +572,7 @@ static const struct luaL_Reg loaderlib[] = { REG_SIMPLE(parse), REG_SIMPLE(getenv), REG_SIMPLE(has_command), + REG_SIMPLE(has_feature), REG_SIMPLE(perform), REG_SIMPLE(printc), /* Also registered as the global 'printc' */ REG_SIMPLE(setenv), @@ -580,6 +600,33 @@ static const struct luaL_Reg iolib[] = { }; #undef REG_SIMPLE +static void +lua_add_feature(void *cookie, const char *name, const char *desc, bool enabled) +{ + lua_State *L = cookie; + + /* + * The feature table consists solely of features that are enabled, and + * their associated descriptions for debugging purposes. + */ + lua_pushstring(L, desc); + lua_setfield(L, -2, name); +} + +static void +lua_add_features(lua_State *L) +{ + + lua_newtable(L); + feature_iter(&lua_add_feature, L); + + /* + * We should still have just the table on the stack after we're done + * iterating. + */ + lua_setfield(L, -2, "features"); +} + int luaopen_loader(lua_State *L) { @@ -591,6 +638,7 @@ luaopen_loader(lua_State *L) lua_setfield(L, -2, "machine_arch"); lua_pushstring(L, LUA_PATH); lua_setfield(L, -2, "lua_path"); + lua_add_features(L); /* Set global printc to loader.printc */ lua_register(L, "printc", lua_printc); return 1; diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index 6af49cdbdfd1..89e7a67f7e41 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -13,7 +13,7 @@ LIB?= sa # standalone components and stuff we have modified locally SRCS+= gzguts.h zutil.h __main.c abort.c assert.c bcd.c environment.c \ - getopt.c gets.c globals.c \ + features.c getopt.c gets.c globals.c \ hexdump.c nvstore.c pager.c panic.c printf.c strdup.c strerror.c \ random.c sbrk.c tslog.c twiddle.c zalloc.c zalloc_malloc.c diff --git a/stand/libsa/features.c b/stand/libsa/features.c new file mode 100644 index 000000000000..23dce2b13b60 --- /dev/null +++ b/stand/libsa/features.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2023 Kyle Evans + * + * SPDX-License-Identifier: BSD-2-Clause + * + */ + +#include + +#include "stand.h" + +static uint32_t loader_features; + +#define FEATURE_ENTRY(name, desc) { FEATURE_##name, #name, desc } +static const struct feature_entry { + uint32_t value; + const char *name; + const char *desc; +} feature_map[] = { + FEATURE_ENTRY(EARLY_ACPI, "Loader probes ACPI in early startup"), +}; + +void +feature_enable(uint32_t mask) +{ + + loader_features |= mask; +} + +bool +feature_name_is_enabled(const char *name) +{ + const struct feature_entry *entry; + + for (size_t i = 0; i < nitems(feature_map); i++) { + entry = &feature_map[i]; + + if (strcmp(entry->name, name) == 0) + return ((loader_features & entry->value) != 0); + } + + return (false); +} + +void +feature_iter(feature_iter_fn *iter_fn, void *cookie) +{ + const struct feature_entry *entry; + + for (size_t i = 0; i < nitems(feature_map); i++) { + entry = &feature_map[i]; + + (*iter_fn)(cookie, entry->name, entry->desc, + (loader_features & entry->value) != 0); + } +} diff --git a/stand/libsa/libsa.3 b/stand/libsa/libsa.3 index a6f30051c8df..7643423b342a 100644 --- a/stand/libsa/libsa.3 +++ b/stand/libsa/libsa.3 @@ -497,6 +497,66 @@ Attempts to open and display the file .Fa fname . Returns -1 on error, 0 at EOF, or 1 if the user elects to quit while reading. .El +.Sh FEATURE SUPPORT +A set of functions are provided to communicate support of features from the +loader binary to the interpreter. +These are used to do something sensible if we are still operating with a loader +binary that behaves differently than expected. +.Bl -hang -width 10n +.It Xo +.Ft void +.Fn feature_enable "uint32_t mask" +.Xc +.Pp +Enable the referenced +.Fa mask +feature, which should be one of the +.Li FEATURE_* +macros defined in +.In stand.h . +.It Xo +.Ft bool +.Fn feature_name_is_enabled "const char *name" +.Xc +.Pp +Check if the referenced +.Fa name +feature is enabled. +The +.Fa name +is usually the same name as the +.Li FEATURE_* +macro, but with the FEATURE_ prefix stripped off. +The authoritative source of feature names is the mapping table near the top in +.Pa stand/libsa/features.c . +.It Xo +.Ft void +.Fn "(feature_iter_fn)" "void *cookie" "const char *name" "const char *desc" "bool enabled" +.Xc +.Pp +The +.Fa cookie +argument is passed as-is from the argument of the same name to +.Fn feature_iter . +The +.Fa name +and +.Fa desc +arguments are defined in the mapping table in +.Pa stand/libsa/features.c . +The +.Fa enabled +argument indicates the current status of the feature, though one could +theoretically turn a feature off in later execution. +As such, this should likely not be trusted if it is needed after the iteration +has finished. +.It Xo +.Ft void +.Fn "feature_iter" "feature_iter_fn *iter_fn" "void *cookie" +.Xc +.Pp +Iterate over the current set of features. +.El .Sh MISC .Bl -hang -width 10n .It Xo diff --git a/stand/libsa/stand.h b/stand/libsa/stand.h index d19d42d37f10..e4e7c76fea7a 100644 --- a/stand/libsa/stand.h +++ b/stand/libsa/stand.h @@ -498,6 +498,21 @@ extern void *reallocf(void *, size_t); */ caddr_t ptov(uintptr_t); +/* features.c */ +typedef void (feature_iter_fn)(void *, const char *, const char *, bool); + +extern void feature_enable(uint32_t); +extern bool feature_name_is_enabled(const char *); +extern void feature_iter(feature_iter_fn *, void *); + +/* + * Note that these should also be added to the mapping table in features.c, + * which the interpreter may query to provide details from. The name with + * FEATURE_ removed is assumed to be the name we'll provide in the loader + * features table, just to simplify reasoning about these. + */ +#define FEATURE_EARLY_ACPI 0x0001 + /* hexdump.c */ void hexdump(caddr_t region, size_t len); diff --git a/stand/lua/core.lua b/stand/lua/core.lua index 8a481ee0b782..358705ac7ace 100644 --- a/stand/lua/core.lua +++ b/stand/lua/core.lua @@ -382,6 +382,15 @@ function core.boot(argstr) loader.perform(composeLoaderCmd("boot", argstr)) end +function core.hasFeature(name) + if not loader.has_feature then + -- Loader too old, no feature support + return nil, "No feature support in loaded loader" + end + + return loader.has_feature(name) +end + function core.isSingleUserBoot() local single_user = loader.getenv("boot_single") return single_user ~= nil and single_user:lower() == "yes" diff --git a/stand/lua/core.lua.8 b/stand/lua/core.lua.8 index 39ae2166d442..e1752475f942 100644 --- a/stand/lua/core.lua.8 +++ b/stand/lua/core.lua.8 @@ -24,7 +24,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 21, 2018 +.Dd December 28, 2023 .Dt CORE.LUA 8 .Os .Sh NAME @@ -145,6 +145,13 @@ due to a boot environment change or a potential change in either .Ic kernel or .Ic kernels . +.It Fn core.hasFeature featureName +Checks whether the named +.Fa featureName +is enabled in the current loader. +This is specifically used for detecting capabilities of the loaded loader +binary, so that one can reasonably implement backwards compatibility shims if +needed. .It Fn core.kernelList Returns a table of kernels to display on the boot menu. This will combine