Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F141076816
D49962.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
52 KB
Referenced Files
None
Subscribers
None
D49962.diff
View Options
diff --git a/include/fts.h b/include/fts.h
--- a/include/fts.h
+++ b/include/fts.h
@@ -34,17 +34,27 @@
#include <sys/_types.h>
+typedef struct _ftsent FTSENT;
+
typedef struct {
- struct _ftsent *fts_cur; /* current node */
- struct _ftsent *fts_child; /* linked list of children */
- struct _ftsent **fts_array; /* sort array */
+ FTSENT *fts_cur; /* current node */
+ FTSENT *fts_child; /* linked list of children */
+ FTSENT **fts_array; /* sort array */
__dev_t fts_dev; /* starting device # */
char *fts_path; /* path for this descent */
int fts_rfd; /* fd for root */
__size_t fts_pathlen; /* sizeof(path) */
__size_t fts_nitems; /* elements in the sort array */
- int (*fts_compar) /* compare function */
- (const struct _ftsent * const *, const struct _ftsent * const *);
+ union {
+ int (*fts_compar) /* compare function */
+ (const FTSENT * const *, const FTSENT * const *);
+#ifdef __BLOCKS__
+ int (^fts_compar_b)
+ (const FTSENT * const *, const FTSENT * const *);
+#else
+ void *fts_compar_b;
+#endif /* __BLOCKS__ */
+ };
/* valid for fts_open() */
#define FTS_COMFOLLOW 0x000001 /* follow command line symlinks */
@@ -62,11 +72,12 @@
/* internal use only */
#define FTS_STOP 0x010000 /* unrecoverable error */
+#define FTS_COMPAR_B 0x020000 /* compare function is a block */
int fts_options; /* fts_open options, global flags */
void *fts_clientptr; /* thunk for sort function */
} FTS;
-typedef struct _ftsent {
+struct _ftsent {
struct _ftsent *fts_cycle; /* cycle node */
struct _ftsent *fts_parent; /* parent directory */
struct _ftsent *fts_link; /* next file in directory */
@@ -118,7 +129,7 @@
struct stat *fts_statp; /* stat(2) information */
char *fts_name; /* file name */
FTS *fts_fts; /* back pointer to main FTS */
-} FTSENT;
+};
#include <sys/cdefs.h>
@@ -131,6 +142,10 @@
#define fts_get_stream(ftsent) ((ftsent)->fts_fts)
FTS *fts_open(char * const *, int,
int (*)(const FTSENT * const *, const FTSENT * const *));
+#ifdef __BLOCKS__
+FTS *fts_open_b(char * const *, int,
+ int (^)(const FTSENT * const *, const FTSENT * const *));
+#endif /* __BLOCKS__ */
FTSENT *fts_read(FTS *);
int fts_set(FTS *, FTSENT *, int);
void fts_set_clientptr(FTS *, void *);
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -168,6 +168,10 @@
valloc.c \
wordexp.c
+.if ${COMPILER_FEATURES:Mblocks}
+CFLAGS.fts.c= -fblocks
+.endif
+
CFLAGS.arc4random.c= -I${SRCTOP}/sys -I${SRCTOP}/sys/crypto/chacha20
CFLAGS.sysconf.c= -I${SRCTOP}/contrib/tzcode
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -458,6 +458,7 @@
aio_read2;
aio_write2;
execvpe;
+ fts_open_b;
psiginfo;
rtld_get_var;
rtld_set_var;
diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c
--- a/lib/libc/gen/exec.c
+++ b/lib/libc/gen/exec.c
@@ -136,7 +136,7 @@
int
execvp(const char *name, char * const *argv)
{
- return (execvpe(name, argv, environ));
+ return (__libc_execvpe(name, argv, environ));
}
static int
@@ -288,7 +288,7 @@
}
int
-execvpe(const char *name, char * const argv[], char * const envp[])
+__libc_execvpe(const char *name, char * const argv[], char * const envp[])
{
const char *path;
@@ -298,3 +298,5 @@
return (execvPe(name, path, argv, envp));
}
+
+__weak_reference(__libc_execvpe, execvpe);
diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3
--- a/lib/libc/gen/fts.3
+++ b/lib/libc/gen/fts.3
@@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd January 12, 2014
+.Dd April 17, 2025
.Dt FTS 3
.Os
.Sh NAME
@@ -37,6 +37,8 @@
.In fts.h
.Ft FTS *
.Fn fts_open "char * const *path_argv" "int options" "int (*compar)(const FTSENT * const *, const FTSENT * const *)"
+.Ft FTS *
+.Fn fts_open_b "char * const *path_argv" "int options" "int (^compar)(const FTSENT * const *, const FTSENT * const *)"
.Ft FTSENT *
.Fn fts_read "FTS *ftsp"
.Ft FTSENT *
@@ -59,7 +61,9 @@
file hierarchies.
A simple overview is that the
.Fn fts_open
-function returns a
+and
+.Fn fts_open_b
+functions return a
.Dq handle
on a file hierarchy, which is then supplied to
the other
@@ -186,6 +190,8 @@
.Ql ..\&
which was not specified as a file name to
.Fn fts_open
+or
+.Fn fts_open_b
(see
.Dv FTS_SEEDOT ) .
.It Dv FTS_DP
@@ -234,6 +240,8 @@
The path for the file relative to the root of the traversal.
This path contains the path specified to
.Fn fts_open
+or
+.Fn fts_open_b
as a prefix.
.It Fa fts_pathlen
The length of the string referenced by
@@ -518,6 +526,15 @@
.Fa path_argv
for the root paths, and in the order listed in the directory for
everything else.
+.Sh FTS_OPEN_B
+The
+.Fn fts_open_b
+function is identical to
+.Fn fts_open
+except that it takes a block pointer instead of a function pointer.
+The block is copied before
+.Fn fts_open_b
+returns, so the original can safely go out of scope or be released.
.Sh FTS_READ
The
.Fn fts_read
@@ -593,9 +610,13 @@
has not yet been called for a hierarchy,
.Fn fts_children
will return a pointer to the files in the logical directory specified to
-.Fn fts_open ,
+.Fn fts_open
+or
+.Fn fts_open_b ,
i.e., the arguments specified to
-.Fn fts_open .
+.Fn fts_open
+or
+.Fn fts_open_b .
Otherwise, if the
.Vt FTSENT
structure most recently returned by
@@ -716,6 +737,8 @@
.Fa ftsp
and restores the current directory to the directory from which
.Fn fts_open
+or
+.Fn fts_open_b
was called to open
.Fa ftsp .
The
@@ -723,29 +746,38 @@
function
returns 0 on success, and \-1 if an error occurs.
.Sh ERRORS
-The function
+The
.Fn fts_open
-may fail and set
+and
+.Fn fts_open_b
+functions may fail and set
.Va errno
for any of the errors specified for the library functions
.Xr open 2
and
.Xr malloc 3 .
+The
+.Fn fts_open_b
+function may also fail and set
+.Va errno
+to
+.Dv ENOSYS
+if the blocks runtime is missing.
.Pp
-The function
+The
.Fn fts_close
-may fail and set
+function may fail and set
.Va errno
for any of the errors specified for the library functions
.Xr chdir 2
and
.Xr close 2 .
.Pp
-The functions
+The
.Fn fts_read
and
.Fn fts_children
-may fail and set
+functions may fail and set
.Va errno
for any of the errors specified for the library functions
.Xr chdir 2 ,
@@ -755,12 +787,12 @@
and
.Xr stat 2 .
.Pp
-In addition,
+In addition, the
.Fn fts_children ,
-.Fn fts_open
+.Fn fts_open ,
and
.Fn fts_set
-may fail and set
+functions may fail and set
.Va errno
as follows:
.Bl -tag -width Er
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -48,6 +48,19 @@
#include "gen-private.h"
+#ifdef __BLOCKS__
+#include <Block.h>
+#else
+#include "block_abi.h"
+typedef DECLARE_BLOCK(int, fts_block,
+ const FTSENT * const *, const FTSENT * const *);
+void qsort_b(void *, size_t, size_t, fts_block);
+#endif /* __BLOCKS__ */
+/* only present if linked with blocks runtime */
+void *_Block_copy(const void *) __weak_symbol;
+void _Block_release(const void *) __weak_symbol;
+extern void *_NSConcreteGlobalBlock[] __weak_symbol;
+
static FTSENT *fts_alloc(FTS *, char *, size_t);
static FTSENT *fts_build(FTS *, int);
static void fts_lfree(FTSENT *);
@@ -102,35 +115,13 @@
0
};
-FTS *
-fts_open(char * const *argv, int options,
- int (*compar)(const FTSENT * const *, const FTSENT * const *))
+static FTS *
+__fts_open(FTS *sp, char * const *argv)
{
- struct _fts_private *priv;
- FTS *sp;
FTSENT *p, *root;
FTSENT *parent, *tmp;
size_t len, nitems;
- /* Options check. */
- if (options & ~FTS_OPTIONMASK) {
- errno = EINVAL;
- return (NULL);
- }
-
- /* fts_open() requires at least one path */
- if (*argv == NULL) {
- errno = EINVAL;
- return (NULL);
- }
-
- /* Allocate/initialize the stream. */
- if ((priv = calloc(1, sizeof(*priv))) == NULL)
- return (NULL);
- sp = &priv->ftsp_fts;
- sp->fts_compar = compar;
- sp->fts_options = options;
-
/* Logical walks turn on NOCHDIR; symbolic links are too hard. */
if (ISSET(FTS_LOGICAL))
SET(FTS_NOCHDIR);
@@ -168,7 +159,7 @@
* If comparison routine supplied, traverse in sorted
* order; otherwise traverse in the order specified.
*/
- if (compar) {
+ if (sp->fts_compar) {
p->fts_link = root;
root = p;
} else {
@@ -181,7 +172,7 @@
}
}
}
- if (compar && nitems > 1)
+ if (sp->fts_compar && nitems > 1)
root = fts_sort(sp, root, nitems);
/*
@@ -214,6 +205,97 @@
return (NULL);
}
+FTS *
+fts_open(char * const *argv, int options,
+ int (*compar)(const FTSENT * const *, const FTSENT * const *))
+{
+ struct _fts_private *priv;
+ FTS *sp;
+
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* fts_open() requires at least one path */
+ if (*argv == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream. */
+ if ((priv = calloc(1, sizeof(*priv))) == NULL)
+ return (NULL);
+ sp = &priv->ftsp_fts;
+ sp->fts_compar = compar;
+ sp->fts_options = options;
+
+ return (__fts_open(sp, argv));
+}
+
+#ifdef __BLOCKS__
+FTS *
+fts_open_b(char * const *argv, int options,
+ int (^compar)(const FTSENT * const *, const FTSENT * const *))
+#else
+FTS *
+fts_open_b(char * const *argv, int options, fts_block compar)
+#endif /* __BLOCKS__ */
+{
+ struct _fts_private *priv;
+ FTS *sp;
+
+ /* No blocks, no problems. */
+ if (compar == NULL)
+ return (fts_open(argv, options, NULL));
+
+ /* Avoid segfault if blocks runtime is missing. */
+ if (_Block_copy == NULL) {
+ errno = ENOSYS;
+ return (NULL);
+ }
+
+ /* Options check. */
+ if (options & ~FTS_OPTIONMASK) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* fts_open() requires at least one path */
+ if (*argv == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ /* Allocate/initialize the stream. */
+ if ((priv = calloc(1, sizeof(*priv))) == NULL)
+ return (NULL);
+ sp = &priv->ftsp_fts;
+#ifdef __BLOCKS__
+ compar = Block_copy(compar);
+#else
+ if (compar->isa != &_NSConcreteGlobalBlock)
+ compar = _Block_copy(compar);
+#endif /* __BLOCKS__ */
+ if (compar == NULL) {
+ free(priv);
+ return (NULL);
+ }
+ sp->fts_compar_b = compar;
+ sp->fts_options = options | FTS_COMPAR_B;
+
+ if ((sp = __fts_open(sp, argv)) == NULL) {
+#ifdef __BLOCKS__
+ Block_release(compar);
+#else
+ if (compar->isa != &_NSConcreteGlobalBlock)
+ _Block_release(compar);
+#endif /* __BLOCKS__ */
+ }
+ return (sp);
+}
+
static void
fts_load(FTS *sp, FTSENT *p)
{
@@ -265,6 +347,16 @@
free(sp->fts_array);
free(sp->fts_path);
+ /* Free up any block pointer. */
+ if (ISSET(FTS_COMPAR_B) && sp->fts_compar_b != NULL) {
+#ifdef __BLOCKS__
+ Block_release(sp->fts_compar_b);
+#else
+ if (sp->fts_compar_b->isa != &_NSConcreteGlobalBlock)
+ _Block_release(sp->fts_compar_b);
+#endif /* __BLOCKS__ */
+ }
+
/* Return to original directory, save errno if necessary. */
if (!ISSET(FTS_NOCHDIR)) {
saved_errno = fchdir(sp->fts_rfd) ? errno : 0;
@@ -979,21 +1071,6 @@
return (FTS_DEFAULT);
}
-/*
- * The comparison function takes pointers to pointers to FTSENT structures.
- * Qsort wants a comparison function that takes pointers to void.
- * (Both with appropriate levels of const-poisoning, of course!)
- * Use a trampoline function to deal with the difference.
- */
-static int
-fts_compar(const void *a, const void *b)
-{
- FTS *parent;
-
- parent = (*(const FTSENT * const *)a)->fts_fts;
- return (*parent->fts_compar)(a, b);
-}
-
static FTSENT *
fts_sort(FTS *sp, FTSENT *head, size_t nitems)
{
@@ -1016,7 +1093,18 @@
}
for (ap = sp->fts_array, p = head; p; p = p->fts_link)
*ap++ = p;
- qsort(sp->fts_array, nitems, sizeof(FTSENT *), fts_compar);
+ if (ISSET(FTS_COMPAR_B)) {
+#ifdef __BLOCKS__
+ qsort_b(sp->fts_array, nitems, sizeof(FTSENT *),
+ (int (^)(const void *, const void *))sp->fts_compar_b);
+#else
+ qsort_b(sp->fts_array, nitems, sizeof(FTSENT *),
+ sp->fts_compar_b);
+#endif /* __BLOCKS__ */
+ } else {
+ qsort(sp->fts_array, nitems, sizeof(FTSENT *),
+ (int (*)(const void *, const void *))sp->fts_compar);
+ }
for (head = *(ap = sp->fts_array); --nitems; ++ap)
ap[0]->fts_link = ap[1];
ap[0]->fts_link = NULL;
diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c
--- a/lib/libc/gen/posix_spawn.c
+++ b/lib/libc/gen/posix_spawn.c
@@ -261,7 +261,7 @@
}
envp = psa->envp != NULL ? psa->envp : environ;
if (psa->use_env_path)
- execvpe(psa->path, psa->argv, envp);
+ __libc_execvpe(psa->path, psa->argv, envp);
else
_execve(psa->path, psa->argv, envp);
psa->error = errno;
diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h
--- a/lib/libc/include/libc_private.h
+++ b/lib/libc/include/libc_private.h
@@ -345,6 +345,7 @@
struct __wrusage;
enum idtype;
+int __libc_execvpe(const char *, char * const *, char * const *);
int __libc_sigaction(int, const struct sigaction *,
struct sigaction *) __hidden;
int __libc_sigprocmask(int, const __sigset_t *, __sigset_t *)
diff --git a/lib/libc/tests/gen/Makefile b/lib/libc/tests/gen/Makefile
--- a/lib/libc/tests/gen/Makefile
+++ b/lib/libc/tests/gen/Makefile
@@ -7,6 +7,9 @@
ATF_TESTS_C+= fmtmsg_test
ATF_TESTS_C+= fnmatch2_test
ATF_TESTS_C+= fpclassify2_test
+.if ${COMPILER_FEATURES:Mblocks}
+ATF_TESTS_C+= fts_blocks_test
+.endif
ATF_TESTS_C+= ftw_test
ATF_TESTS_C+= getentropy_test
ATF_TESTS_C+= getmntinfo_test
@@ -92,6 +95,12 @@
TESTS_SUBDIRS= execve
TESTS_SUBDIRS+= posix_spawn
+# Tests that require blocks support
+.for t in fts_blocks_test
+CFLAGS.${t}.c+= -fblocks
+LIBADD.${t}+= BlocksRuntime
+.endfor
+
# The old testcase name
TEST_FNMATCH= test-fnmatch
CLEANFILES+= ${GEN_SH_CASE_TESTCASES}
diff --git a/lib/libc/tests/gen/fts_blocks_test.c b/lib/libc/tests/gen/fts_blocks_test.c
new file mode 100644
--- /dev/null
+++ b/lib/libc/tests/gen/fts_blocks_test.c
@@ -0,0 +1,63 @@
+/*-
+ * Copyright (c) 2025 Klara, Inc.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <fts.h>
+
+#include <atf-c.h>
+
+/*
+ * Create two directories with three files each in lexicographical order,
+ * then call FTS with a sort block that sorts in reverse lexicographical
+ * order. This has the least chance of getting a false positive due to
+ * differing file system semantics. UFS will return the files in the
+ * order they were created while ZFS will sort them lexicographically; in
+ * both cases, the order we expect is the reverse.
+ */
+ATF_TC_WITHOUT_HEAD(fts_blocks_test);
+ATF_TC_BODY(fts_blocks_test, tc)
+{
+ char *args[] = {
+ "bar", "foo", NULL
+ };
+ char *paths[] = {
+ "foo", "z", "y", "x", "foo",
+ "bar", "c", "b", "a", "bar",
+ NULL
+ };
+ char **expect = paths;
+ FTS *fts;
+ FTSENT *ftse;
+
+ ATF_REQUIRE_EQ(0, mkdir("bar", 0755));
+ ATF_REQUIRE_EQ(0, close(creat("bar/a", 0644)));
+ ATF_REQUIRE_EQ(0, close(creat("bar/b", 0644)));
+ ATF_REQUIRE_EQ(0, close(creat("bar/c", 0644)));
+ ATF_REQUIRE_EQ(0, mkdir("foo", 0755));
+ ATF_REQUIRE_EQ(0, close(creat("foo/x", 0644)));
+ ATF_REQUIRE_EQ(0, close(creat("foo/y", 0644)));
+ ATF_REQUIRE_EQ(0, close(creat("foo/z", 0644)));
+ fts = fts_open_b(args, 0,
+ ^(const FTSENT * const *a, const FTSENT * const *b) {
+ return (strcmp((*b)->fts_name, (*a)->fts_name));
+ });
+ ATF_REQUIRE_MSG(fts != NULL, "fts_open_b(): %m");
+ while ((ftse = fts_read(fts)) != NULL && *expect != NULL) {
+ ATF_CHECK_STREQ(*expect, ftse->fts_name);
+ expect++;
+ }
+ ATF_CHECK_EQ(NULL, ftse);
+ ATF_CHECK_EQ(NULL, *expect);
+ ATF_REQUIRE_EQ_MSG(0, fts_close(fts), "fts_close(): %m");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, fts_blocks_test);
+ return (atf_no_error());
+}
diff --git a/lib/libc/tests/stdlib/Makefile b/lib/libc/tests/stdlib/Makefile
--- a/lib/libc/tests/stdlib/Makefile
+++ b/lib/libc/tests/stdlib/Makefile
@@ -7,7 +7,7 @@
ATF_TESTS_C+= libc_exit_test
ATF_TESTS_C+= mergesort_test
ATF_TESTS_C+= qsort_test
-.if ${COMPILER_TYPE} == "clang"
+.if ${COMPILER_FEATURES:Mblocks}
ATF_TESTS_C+= qsort_b_test
.endif
ATF_TESTS_C+= qsort_r_compat_test
@@ -61,7 +61,7 @@
LIBADD.cxa_thread_atexit_test+= pthread
-# Tests that requires Blocks feature
+# Tests that require blocks support
.for t in qsort_b_test
CFLAGS.${t}.c+= -fblocks
LIBADD.${t}+= BlocksRuntime
diff --git a/share/mk/Makefile b/share/mk/Makefile
--- a/share/mk/Makefile
+++ b/share/mk/Makefile
@@ -50,6 +50,7 @@
bsd.progs.mk \
bsd.snmpmod.mk \
bsd.subdir.mk \
+ bsd.suffixes-extra.mk \
bsd.suffixes-posix.mk \
bsd.suffixes.mk \
bsd.symver.mk \
diff --git a/share/mk/bsd.compiler.mk b/share/mk/bsd.compiler.mk
--- a/share/mk/bsd.compiler.mk
+++ b/share/mk/bsd.compiler.mk
@@ -245,6 +245,7 @@
${X_}COMPILER_FEATURES+= init-all
.endif
.if ${${X_}COMPILER_TYPE} == "clang"
+${X_}COMPILER_FEATURES+= blocks
${X_}COMPILER_FEATURES+= retpoline
# PR257638 lld fails with BE compressed debug. Fixed in main but external tool
# chains will initially not have the fix. For now limit the feature to LE
diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk
--- a/share/mk/bsd.lib.mk
+++ b/share/mk/bsd.lib.mk
@@ -148,79 +148,7 @@
.include <bsd.libnames.mk>
-# prefer .s to a .c, remove stuff not used in the BSD libraries
-# .pico used for PIC object files
-# .nossppico used for NOSSP PIC object files
-# .pieo used for PIE object files
-.SUFFIXES: .out .o .bc .ll .pico .nossppico .pieo .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
-
-.if !defined(PICFLAG)
-PICFLAG=-fpic
-PIEFLAG=-fpie
-.endif
-
-.c.pico:
- ${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.c.nossppico:
- ${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} ${CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.c.pieo:
- ${CC} ${PIEFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.cc.pico .C.pico .cpp.pico .cxx.pico:
- ${CXX} ${PICFLAG} -DPIC ${SHARED_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-
-.cc.nossppico .C.nossppico .cpp.nossppico .cxx.nossppico:
- ${CXX} ${PICFLAG} -DPIC ${SHARED_CXXFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} ${CXXFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} -c ${.IMPSRC} -o ${.TARGET}
-
-.cc.pieo .C.pieo .cpp.pieo .cxx.pieo:
- ${CXX} ${PIEFLAG} ${SHARED_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
-
-.f.pico:
- ${FC} ${PICFLAG} -DPIC ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
- ${CTFCONVERT_CMD}
-
-.f.nossppico:
- ${FC} ${PICFLAG} -DPIC ${FFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//} -o ${.TARGET} -c ${.IMPSRC}
- ${CTFCONVERT_CMD}
-
-.s.pico .s.nossppico .s.pieo:
- ${CC:N${CCACHE_BIN}} -x assembler ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.asm.pico:
- ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PICFLAG} -DPIC \
- ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.asm.nossppico:
- ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PICFLAG} -DPIC \
- ${CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.asm.pieo:
- ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PIEFLAG} -DPIC \
- ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.S.pico:
- ${CC:N${CCACHE_BIN}} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
- -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.S.nossppico:
- ${CC:N${CCACHE_BIN}} ${PICFLAG} -DPIC ${CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//} ${ACFLAGS} \
- -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
-
-.S.pieo:
- ${CC:N${CCACHE_BIN}} ${PIEFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
- -c ${.IMPSRC} -o ${.TARGET}
- ${CTFCONVERT_CMD}
+.include <bsd.suffixes-extra.mk>
_LIBDIR:=${LIBDIR}
_SHLIBDIR:=${SHLIBDIR}
diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk
--- a/share/mk/bsd.prog.mk
+++ b/share/mk/bsd.prog.mk
@@ -4,7 +4,7 @@
.include <bsd.compiler.mk>
.include <bsd.linker.mk>
-.SUFFIXES: .out .o .bc .c .cc .cpp .cxx .C .m .y .l .ll .ln .s .S .asm
+.include <bsd.suffixes-extra.mk>
# XXX The use of COPTS in modern makefiles is discouraged.
.if defined(COPTS)
@@ -47,13 +47,14 @@
LDFLAGS+= -Wl,-zrelro
.endif
.endif
-.if ${MK_PIE} != "no"
# Static PIE is not yet supported/tested.
-.if !defined(NO_SHARED) || ${NO_SHARED:tl} == "no"
+.if ${MK_PIE} != "no" && (!defined(NO_SHARED) || ${NO_SHARED:tl} == "no")
CFLAGS+= -fPIE
CXXFLAGS+= -fPIE
LDFLAGS+= -pie
-.endif
+OBJ_EXT=pieo
+.else
+OBJ_EXT=o
.endif
.if ${MK_RETPOLINE} != "no"
.if ${COMPILER_FEATURES:Mretpoline} && ${LINKER_FEATURES:Mretpoline}
@@ -161,7 +162,7 @@
.if defined(SRCS)
-OBJS+= ${SRCS:N*.h:${OBJS_SRCS_FILTER:ts:}:S/$/.o/g}
+OBJS+= ${SRCS:N*.h:${OBJS_SRCS_FILTER:ts:}:S/$/.${OBJ_EXT}/g}
# LLVM bitcode / textual IR representations of the program
BCOBJS+=${SRCS:N*.[hsS]:N*.asm:${OBJS_SRCS_FILTER:ts:}:S/$/.bco/g}
@@ -197,10 +198,10 @@
# - the name of the object gets put into the executable symbol table instead of
# the name of a variable temporary object.
# - it's useful to keep objects around for crunching.
-OBJS+= ${PROG}.o
+OBJS+= ${PROG}.${OBJ_EXT}
BCOBJS+= ${PROG}.bc
LLOBJS+= ${PROG}.ll
-CLEANFILES+= ${PROG}.o ${PROG}.bc ${PROG}.ll
+CLEANFILES+= ${PROG}.${OBJ_EXT} ${PROG}.bc ${PROG}.ll
.if target(beforelinking)
beforelinking: ${OBJS}
diff --git a/share/mk/bsd.progs.mk b/share/mk/bsd.progs.mk
--- a/share/mk/bsd.progs.mk
+++ b/share/mk/bsd.progs.mk
@@ -110,7 +110,7 @@
.if !empty(_PROGS_COMMON_SRCS)
_PROGS_COMMON_OBJS= ${_PROGS_COMMON_SRCS:M*.[dhly]}
.if !empty(_PROGS_COMMON_SRCS:N*.[dhly])
-_PROGS_COMMON_OBJS+= ${_PROGS_COMMON_SRCS:N*.[dhly]:${OBJS_SRCS_FILTER:ts:}:S/$/.o/g}
+_PROGS_COMMON_OBJS+= ${_PROGS_COMMON_SRCS:N*.[dhly]:${OBJS_SRCS_FILTER:ts:}:S/$/.${OBJ_EXT}/g}
.endif
.endif
diff --git a/share/mk/bsd.suffixes-extra.mk b/share/mk/bsd.suffixes-extra.mk
new file mode 100644
--- /dev/null
+++ b/share/mk/bsd.suffixes-extra.mk
@@ -0,0 +1,76 @@
+.if !target(__<bsd.suffixes-extra.mk>__)
+__<bsd.suffixes-extra.mk>__: .NOTMAIN
+
+# prefer .s to a .c, remove stuff not used in the BSD libraries
+# .pico used for PIC object files
+# .nossppico used for NOSSP PIC object files
+# .pieo used for PIE object files
+.SUFFIXES: .out .o .bc .ll .pico .nossppico .pieo .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
+
+PICFLAG?=-fpic
+PIEFLAG?=-fpie
+
+.c.pico:
+ ${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.c.nossppico:
+ ${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} ${CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.c.pieo:
+ ${CC} ${PIEFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.cc.pico .C.pico .cpp.pico .cxx.pico:
+ ${CXX} ${PICFLAG} -DPIC ${SHARED_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+
+.cc.nossppico .C.nossppico .cpp.nossppico .cxx.nossppico:
+ ${CXX} ${PICFLAG} -DPIC ${SHARED_CXXFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} ${CXXFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//:C/^-fsanitize.*$//} -c ${.IMPSRC} -o ${.TARGET}
+
+.cc.pieo .C.pieo .cpp.pieo .cxx.pieo:
+ ${CXX} ${PIEFLAG} ${SHARED_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+
+.f.pico:
+ ${FC} ${PICFLAG} -DPIC ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
+ ${CTFCONVERT_CMD}
+
+.f.nossppico:
+ ${FC} ${PICFLAG} -DPIC ${FFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//} -o ${.TARGET} -c ${.IMPSRC}
+ ${CTFCONVERT_CMD}
+
+.s.pico .s.nossppico .s.pieo:
+ ${CC:N${CCACHE_BIN}} -x assembler ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.asm.pico:
+ ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PICFLAG} -DPIC \
+ ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.asm.nossppico:
+ ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PICFLAG} -DPIC \
+ ${CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.asm.pieo:
+ ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PIEFLAG} -DPIC \
+ ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.S.pico:
+ ${CC:N${CCACHE_BIN}} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
+ -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.S.nossppico:
+ ${CC:N${CCACHE_BIN}} ${PICFLAG} -DPIC ${CFLAGS:C/^-fstack-protector.*$//:C/^-fstack-clash-protection.*$//} ${ACFLAGS} \
+ -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.S.pieo:
+ ${CC:N${CCACHE_BIN}} ${PIEFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
+ -c ${.IMPSRC} -o ${.TARGET}
+ ${CTFCONVERT_CMD}
+
+.endif # !target(__<bsd.suffixes-extra.mk>__)
diff --git a/share/vt/keymaps/INDEX.keymaps b/share/vt/keymaps/INDEX.keymaps
--- a/share/vt/keymaps/INDEX.keymaps
+++ b/share/vt/keymaps/INDEX.keymaps
@@ -547,6 +547,13 @@
us.acc.kbd:pt:Estados Unidos da América (com acentos)
us.acc.kbd:es:Estadounidense (con acentos)
+us.intl.acc.kbd:en:United States of America International (accent keys)
+us.intl.acc.kbd:da:USA international (accenttaster)
+us.intl.acc.kbd:de:US-amerikanisch international (mit Akzenten)
+us.intl.acc.kbd:fr:États Unis d'Amérique International (avec accents)
+us.intl.acc.kbd:pt:Estados Unidos da América Internacional (com acentos)
+us.intl.acc.kbd:es:Estadounidense Internacional (con acentos)
+
us.dvorak.kbd:en:United States of America dvorak
us.dvorak.kbd:da:USA dvorak
us.dvorak.kbd:de:US-amerikanisch dvorak
diff --git a/share/vt/keymaps/us.intl.acc.kbd b/share/vt/keymaps/us.intl.acc.kbd
new file mode 100644
index 0000000000000000000000000000000000000000..5ae189da845d63ce1db54dc27f38f4322f426f4b
GIT binary patch
literal 8902
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
al<#ySab|4b%vic=#v*6Nl=E;+SN{h>LDVb&
literal 0
Hc$@<O00001
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -815,14 +815,29 @@
cache_setup();
- /* Bootstrap enough of pmap to enter the kernel proper */
- pmap_bootstrap(lastaddr - KERNBASE);
- /* Exclude entries needed in the DMAP region, but not phys_avail */
+ /*
+ * Perform a staged bootstrap of virtual memory.
+ *
+ * - First we create the DMAP region. This allows it to be used in
+ * later bootstrapping.
+ * - Next exclude memory that is needed in the DMAP region, but must
+ * not be used by FreeBSD.
+ * - Lastly complete the bootstrapping. It may use the physical
+ * memory map so any excluded memory must be marked as such before
+ * pmap_bootstrap() is called.
+ */
+ pmap_bootstrap_dmap(lastaddr - KERNBASE);
+ /*
+ * Exclude EFI entries needed in the DMAP, e.g. EFI_MD_TYPE_RECLAIM
+ * may contain the ACPI tables but shouldn't be used by the kernel
+ */
if (efihdr != NULL)
efi_map_exclude_entries(efihdr);
/* Do the same for reserve entries in the EFI MEMRESERVE table */
if (efi_systbl_phys != 0)
exclude_efi_memreserve(efi_systbl_phys);
+ /* Continue bootstrapping pmap */
+ pmap_bootstrap();
/*
* We carefully bootstrap the sanitizer map after we've excluded
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -1211,11 +1211,28 @@
MPASS(state->va == (state->pa - dmap_phys_base + DMAP_MIN_ADDRESS));
}
-static void
-pmap_bootstrap_dmap(void)
+void
+pmap_bootstrap_dmap(vm_size_t kernlen)
{
+ vm_paddr_t start_pa, pa;
+ uint64_t tcr;
int i;
+ tcr = READ_SPECIALREG(tcr_el1);
+
+ /* Verify that the ASID is set through TTBR0. */
+ KASSERT((tcr & TCR_A1) == 0, ("pmap_bootstrap: TCR_EL1.A1 != 0"));
+
+ if ((tcr & TCR_DS) != 0)
+ pmap_lpa_enabled = true;
+
+ pmap_l1_supported = L1_BLOCKS_SUPPORTED;
+
+ start_pa = pmap_early_vtophys(KERNBASE);
+
+ bs_state.freemempos = KERNBASE + kernlen;
+ bs_state.freemempos = roundup2(bs_state.freemempos, PAGE_SIZE);
+
/* Fill in physmap array. */
physmap_idx = physmem_avail(physmap, nitems(physmap));
@@ -1275,6 +1292,12 @@
}
cpu_tlb_flushID();
+
+ bs_state.dmap_valid = true;
+
+ /* Exclude the kernel and DMAP region */
+ pa = pmap_early_vtophys(bs_state.freemempos);
+ physmem_exclude_region(start_pa, pa - start_pa, EXFLAG_NOALLOC);
}
static void
@@ -1305,21 +1328,11 @@
* Bootstrap the system enough to run with virtual memory.
*/
void
-pmap_bootstrap(vm_size_t kernlen)
+pmap_bootstrap(void)
{
vm_offset_t dpcpu, msgbufpv;
vm_paddr_t start_pa, pa;
- uint64_t tcr;
-
- tcr = READ_SPECIALREG(tcr_el1);
-
- /* Verify that the ASID is set through TTBR0. */
- KASSERT((tcr & TCR_A1) == 0, ("pmap_bootstrap: TCR_EL1.A1 != 0"));
-
- if ((tcr & TCR_DS) != 0)
- pmap_lpa_enabled = true;
-
- pmap_l1_supported = L1_BLOCKS_SUPPORTED;
+ size_t largest_phys_size;
/* Set this early so we can use the pagetable walking functions */
kernel_pmap_store.pm_l0 = pagetable_l0_ttbr1;
@@ -1334,12 +1347,13 @@
kernel_pmap->pm_ttbr = kernel_pmap->pm_l0_paddr;
kernel_pmap->pm_asid_set = &asids;
- bs_state.freemempos = KERNBASE + kernlen;
- bs_state.freemempos = roundup2(bs_state.freemempos, PAGE_SIZE);
+ /* Reserve some VA space for early BIOS/ACPI mapping */
+ preinit_map_va = roundup2(bs_state.freemempos, L2_SIZE);
- /* Create a direct map region early so we can use it for pa -> va */
- pmap_bootstrap_dmap();
- bs_state.dmap_valid = true;
+ virtual_avail = preinit_map_va + PMAP_PREINIT_MAPPING_SIZE;
+ virtual_avail = roundup2(virtual_avail, L1_SIZE);
+ virtual_end = VM_MAX_KERNEL_ADDRESS - PMAP_MAPDEV_EARLY_SIZE;
+ kernel_vm_end = virtual_avail;
/*
* We only use PXN when we know nothing will be executed from it, e.g.
@@ -1347,7 +1361,28 @@
*/
bs_state.table_attrs &= ~TATTR_PXN_TABLE;
- start_pa = pa = pmap_early_vtophys(KERNBASE);
+ /*
+ * Find the physical memory we could use. This needs to be after we
+ * exclude any memory that is mapped into the DMAP region but should
+ * not be used by the kernel, e.g. some UEFI memory types.
+ */
+ physmap_idx = physmem_avail(physmap, nitems(physmap));
+
+ /*
+ * Find space for early allocations. We search for the largest
+ * region. This is because the user may choose a large msgbuf.
+ * This could be smarter, e.g. to allow multiple regions to be
+ * used & switch to the next when one is full.
+ */
+ largest_phys_size = 0;
+ for (int i = 0; i < physmap_idx; i += 2) {
+ if ((physmap[i + 1] - physmap[i]) > largest_phys_size) {
+ largest_phys_size = physmap[i + 1] - physmap[i];
+ bs_state.freemempos = PHYS_TO_DMAP(physmap[i]);
+ }
+ }
+
+ start_pa = pmap_early_vtophys(bs_state.freemempos);
/*
* Create the l2 tables up to VM_MAX_KERNEL_ADDRESS. We assume that the
@@ -1373,19 +1408,9 @@
alloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE);
msgbufp = (void *)msgbufpv;
- /* Reserve some VA space for early BIOS/ACPI mapping */
- preinit_map_va = roundup2(bs_state.freemempos, L2_SIZE);
-
- virtual_avail = preinit_map_va + PMAP_PREINIT_MAPPING_SIZE;
- virtual_avail = roundup2(virtual_avail, L1_SIZE);
- virtual_end = VM_MAX_KERNEL_ADDRESS - (PMAP_MAPDEV_EARLY_SIZE);
- kernel_vm_end = virtual_avail;
-
pa = pmap_early_vtophys(bs_state.freemempos);
physmem_exclude_region(start_pa, pa - start_pa, EXFLAG_NOALLOC);
-
- cpu_tlb_flushID();
}
#if defined(KASAN) || defined(KMSAN)
diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h
--- a/sys/arm64/include/pmap.h
+++ b/sys/arm64/include/pmap.h
@@ -141,7 +141,8 @@
#define pmap_vm_page_alloc_check(m)
void pmap_activate_vm(pmap_t);
-void pmap_bootstrap(vm_size_t);
+void pmap_bootstrap_dmap(vm_size_t);
+void pmap_bootstrap(void);
int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode);
int pmap_change_prot(vm_offset_t va, vm_size_t size, vm_prot_t prot);
void pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode);
diff --git a/sys/conf/files.riscv b/sys/conf/files.riscv
--- a/sys/conf/files.riscv
+++ b/sys/conf/files.riscv
@@ -46,6 +46,7 @@
riscv/riscv/busdma_bounce.c standard
riscv/riscv/busdma_machdep.c standard
riscv/riscv/cache.c standard
+riscv/riscv/cbo.c standard
riscv/riscv/clock.c standard
riscv/riscv/copyinout.S standard
riscv/riscv/cpufunc_asm.S standard
diff --git a/sys/contrib/edk2/Include/Library/BaseLib.h b/sys/contrib/edk2/Include/Library/BaseLib.h
--- a/sys/contrib/edk2/Include/Library/BaseLib.h
+++ b/sys/contrib/edk2/Include/Library/BaseLib.h
@@ -152,6 +152,29 @@
#endif // defined (MDE_CPU_RISCV64)
+#if defined (MDE_CPU_LOONGARCH64)
+///
+/// The LoongArch architecture context buffer used by SetJump() and LongJump()
+///
+typedef struct {
+ UINT64 S0;
+ UINT64 S1;
+ UINT64 S2;
+ UINT64 S3;
+ UINT64 S4;
+ UINT64 S5;
+ UINT64 S6;
+ UINT64 S7;
+ UINT64 S8;
+ UINT64 SP;
+ UINT64 FP;
+ UINT64 RA;
+} BASE_LIBRARY_JUMP_BUFFER;
+
+#define BASE_LIBRARY_JUMP_BUFFER_ALIGNMENT 8
+
+#endif // defined (MDE_CPU_LOONGARCH64)
+
//
// String Services
//
diff --git a/sys/contrib/edk2/Include/Uefi/UefiBaseType.h b/sys/contrib/edk2/Include/Uefi/UefiBaseType.h
--- a/sys/contrib/edk2/Include/Uefi/UefiBaseType.h
+++ b/sys/contrib/edk2/Include/Uefi/UefiBaseType.h
@@ -248,6 +248,13 @@
#define EFI_IMAGE_MACHINE_RISCV64 0x5064
#define EFI_IMAGE_MACHINE_RISCV128 0x5128
+///
+/// PE32+ Machine type for LoongArch 32/64 images.
+///
+#define EFI_IMAGE_MACHINE_LOONGARCH32 0x6232
+#define EFI_IMAGE_MACHINE_LOONGARCH64 0x6264
+
+
#if defined (MDE_CPU_IA32)
#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
@@ -281,6 +288,13 @@
#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+ #elif defined (MDE_CPU_LOONGARCH64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ ((Machine) == EFI_IMAGE_MACHINE_LOONGARCH64)
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
#elif defined (MDE_CPU_EBC)
///
diff --git a/sys/contrib/edk2/Include/Uefi/UefiSpec.h b/sys/contrib/edk2/Include/Uefi/UefiSpec.h
--- a/sys/contrib/edk2/Include/Uefi/UefiSpec.h
+++ b/sys/contrib/edk2/Include/Uefi/UefiSpec.h
@@ -2203,6 +2203,7 @@
#define EFI_REMOVABLE_MEDIA_FILE_NAME_ARM L"\\EFI\\BOOT\\BOOTARM.EFI"
#define EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64 L"\\EFI\\BOOT\\BOOTAA64.EFI"
#define EFI_REMOVABLE_MEDIA_FILE_NAME_RISCV64 L"\\EFI\\BOOT\\BOOTRISCV64.EFI"
+#define EFI_REMOVABLE_MEDIA_FILE_NAME_LOONGARCH64 L"\\EFI\\BOOT\\BOOTLOONGARCH64.EFI"
#if defined (MDE_CPU_IA32)
#define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_IA32
@@ -2215,7 +2216,9 @@
#define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_AARCH64
#elif defined (MDE_CPU_RISCV64)
#define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_RISCV64
-#else
+ #elif defined (MDE_CPU_LOONGARCH64)
+#define EFI_REMOVABLE_MEDIA_FILE_NAME EFI_REMOVABLE_MEDIA_FILE_NAME_LOONGARCH64
+ #else
#error Unknown Processor Type
#endif
diff --git a/sys/dev/xilinx/axidma.c b/sys/dev/xilinx/axidma.c
--- a/sys/dev/xilinx/axidma.c
+++ b/sys/dev/xilinx/axidma.c
@@ -169,6 +169,9 @@
while (chan->idx_tail != chan->idx_head) {
desc = chan->descs[chan->idx_tail];
+ cpu_dcache_wbinv_range((vm_offset_t)desc,
+ sizeof(struct axidma_desc));
+
if ((desc->status & BD_STATUS_CMPLT) == 0)
break;
@@ -357,7 +360,8 @@
return (-1);
}
chan->mem_vaddr = kva_alloc(chan->mem_size);
- pmap_kenter_device(chan->mem_vaddr, chan->mem_size, chan->mem_paddr);
+ pmap_kenter(chan->mem_vaddr, chan->mem_size, chan->mem_paddr,
+ VM_MEMATTR_DEFAULT);
device_printf(sc->dev, "Allocated chunk %lx %lu\n",
chan->mem_paddr, chan->mem_size);
@@ -493,6 +497,9 @@
if (sg[i].last == 1)
desc->control |= BD_CONTROL_TXEOF;
+ cpu_dcache_wbinv_range((vm_offset_t)desc,
+ sizeof(struct axidma_desc));
+
tmp = chan->idx_head;
atomic_add_int(&chan->descs_used_count, 1);
diff --git a/sys/kern/uipc_ktls.c b/sys/kern/uipc_ktls.c
--- a/sys/kern/uipc_ktls.c
+++ b/sys/kern/uipc_ktls.c
@@ -1332,7 +1332,11 @@
/* Mark the socket as using TLS offload. */
SOCK_RECVBUF_LOCK(so);
- if (__predict_false(so->so_rcv.sb_tls_info != NULL)) {
+ if (__predict_false(so->so_rcv.sb_tls_info != NULL))
+ error = EALREADY;
+ else if ((so->so_rcv.sb_flags & SB_SPLICED) != 0)
+ error = EINVAL;
+ if (error != 0) {
SOCK_RECVBUF_UNLOCK(so);
SOCK_IO_RECV_UNLOCK(so);
ktls_free(tls);
@@ -1432,12 +1436,16 @@
inp = so->so_pcb;
INP_WLOCK(inp);
SOCK_SENDBUF_LOCK(so);
- if (__predict_false(so->so_snd.sb_tls_info != NULL)) {
+ if (__predict_false(so->so_snd.sb_tls_info != NULL))
+ error = EALREADY;
+ else if ((so->so_snd.sb_flags & SB_SPLICED) != 0)
+ error = EINVAL;
+ if (error != 0) {
SOCK_SENDBUF_UNLOCK(so);
INP_WUNLOCK(inp);
SOCK_IO_SEND_UNLOCK(so);
ktls_free(tls);
- return (EALREADY);
+ return (error);
}
so->so_snd.sb_tls_seqno = be64dec(en->rec_seq);
so->so_snd.sb_tls_info = tls;
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1699,10 +1699,16 @@
uma_zfree(splice_zone, sp);
return (error);
}
- soref(so);
- so->so_splice = sp;
SOCK_RECVBUF_LOCK(so);
+ if (so->so_rcv.sb_tls_info != NULL) {
+ SOCK_RECVBUF_UNLOCK(so);
+ SOCK_UNLOCK(so);
+ uma_zfree(splice_zone, sp);
+ return (EINVAL);
+ }
so->so_rcv.sb_flags |= SB_SPLICED;
+ so->so_splice = sp;
+ soref(so);
SOCK_RECVBUF_UNLOCK(so);
SOCK_UNLOCK(so);
@@ -1716,20 +1722,19 @@
error = EBUSY;
if (error != 0) {
SOCK_UNLOCK(so2);
- SOCK_LOCK(so);
- so->so_splice = NULL;
- SOCK_RECVBUF_LOCK(so);
- so->so_rcv.sb_flags &= ~SB_SPLICED;
- SOCK_RECVBUF_UNLOCK(so);
- SOCK_UNLOCK(so);
- sorele(so);
- uma_zfree(splice_zone, sp);
+ so_unsplice(so, false);
return (error);
}
- soref(so2);
- so2->so_splice_back = sp;
SOCK_SENDBUF_LOCK(so2);
+ if (so->so_snd.sb_tls_info != NULL) {
+ SOCK_SENDBUF_UNLOCK(so2);
+ SOCK_UNLOCK(so2);
+ so_unsplice(so, false);
+ return (EINVAL);
+ }
so2->so_snd.sb_flags |= SB_SPLICED;
+ so2->so_splice_back = sp;
+ soref(so2);
mtx_lock(&sp->mtx);
SOCK_SENDBUF_UNLOCK(so2);
SOCK_UNLOCK(so2);
@@ -1754,7 +1759,7 @@
{
struct socket *so2;
struct so_splice *sp;
- bool drain;
+ bool drain, so2rele;
/*
* First unset SB_SPLICED and hide the splice structure so that
@@ -1793,11 +1798,14 @@
SOCK_LOCK(so2);
KASSERT(!SOLISTENING(so2), ("%s: so2 is listening", __func__));
SOCK_SENDBUF_LOCK(so2);
- KASSERT((so2->so_snd.sb_flags & SB_SPLICED) != 0,
+ KASSERT(sp->state == SPLICE_INIT ||
+ (so2->so_snd.sb_flags & SB_SPLICED) != 0,
("%s: so2 is not spliced", __func__));
- KASSERT(so2->so_splice_back == sp,
+ KASSERT(sp->state == SPLICE_INIT ||
+ so2->so_splice_back == sp,
("%s: so_splice_back != sp", __func__));
so2->so_snd.sb_flags &= ~SB_SPLICED;
+ so2rele = so2->so_splice_back != NULL;
so2->so_splice_back = NULL;
SOCK_SENDBUF_UNLOCK(so2);
SOCK_UNLOCK(so2);
@@ -1815,6 +1823,7 @@
while (sp->state == SPLICE_CLOSING)
msleep(sp, &sp->mtx, PSOCK, "unsplice", 0);
break;
+ case SPLICE_INIT:
case SPLICE_IDLE:
case SPLICE_EXCEPTION:
sp->state = SPLICE_CLOSED;
@@ -1840,7 +1849,8 @@
CURVNET_SET(so->so_vnet);
sorele(so);
sowwakeup(so2);
- sorele(so2);
+ if (so2rele)
+ sorele(so2);
CURVNET_RESTORE();
so_splice_free(sp);
return (0);
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c
+++ b/sys/netinet6/icmp6.c
@@ -2087,6 +2087,12 @@
hlim = 0;
srcp = NULL;
+ if (__predict_false(IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src))) {
+ nd6log((LOG_DEBUG,
+ "icmp6_reflect: source address is unspecified\n"));
+ goto bad;
+ }
+
/*
* If the incoming packet was addressed directly to us (i.e. unicast),
* use dst as the src for the reply.
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -109,7 +109,8 @@
*/
if ((m->m_flags & (M_BCAST|M_MCAST)) != 0 ||
IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||
- IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
+ IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) ||
+ IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_dst)) {
IP6STAT_INC(ip6s_cantforward);
/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
if (V_ip6_log_cannot_forward && ip6_log_ratelimit()) {
diff --git a/sys/riscv/include/cbo.h b/sys/riscv/include/cbo.h
new file mode 100644
--- /dev/null
+++ b/sys/riscv/include/cbo.h
@@ -0,0 +1,33 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Ruslan Bukin <br@bsdpad.com>
+ *
+ * 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.
+ */
+
+#ifndef _RISCV_CBO_H_
+#define _RISCV_CBO_H_
+
+void cbo_zicbom_setup_cache(int cbom_block_size);
+
+#endif /* _RISCV_CBO_H_ */
diff --git a/sys/riscv/include/cpu.h b/sys/riscv/include/cpu.h
--- a/sys/riscv/include/cpu.h
+++ b/sys/riscv/include/cpu.h
@@ -80,6 +80,7 @@
/* SiFive marchid values */
#define MARCHID_SIFIVE_U7 MARCHID_COMMERCIAL(7)
+#define MARCHID_SIFIVE_P5 MARCHID_COMMERCIAL(8)
/*
* MMU virtual-addressing modes. Support for each level implies the previous,
diff --git a/sys/riscv/riscv/cbo.c b/sys/riscv/riscv/cbo.c
new file mode 100644
--- /dev/null
+++ b/sys/riscv/riscv/cbo.c
@@ -0,0 +1,104 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Ruslan Bukin <br@bsdpad.com>
+ *
+ * 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.
+ */
+
+/* Cache Block Operations. */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <machine/cbo.h>
+
+static void
+cbo_zicbom_cpu_dcache_wbinv_range(vm_offset_t va, vm_size_t len)
+{
+ vm_offset_t addr;
+
+ /*
+ * A flush operation atomically performs a clean operation followed by
+ * an invalidate operation.
+ */
+
+ va &= ~(dcache_line_size - 1);
+ for (addr = va; addr < va + len; addr += dcache_line_size)
+ __asm __volatile(".option push; .option arch, +zicbom\n"
+ "cbo.flush (%0); .option pop\n" :: "r"(addr));
+}
+
+static void
+cbo_zicbom_cpu_dcache_inv_range(vm_offset_t va, vm_size_t len)
+{
+ vm_offset_t addr;
+
+ /*
+ * An invalidate operation makes data from store operations performed by
+ * a set of non-coherent agents visible to the set of coherent agents at
+ * a point common to both sets by deallocating all copies of a cache
+ * block from the set of coherent caches up to that point.
+ */
+
+ va &= ~(dcache_line_size - 1);
+ for (addr = va; addr < va + len; addr += dcache_line_size)
+ __asm __volatile(".option push; .option arch, +zicbom\n"
+ "cbo.inval (%0); .option pop\n" :: "r"(addr));
+}
+
+static void
+cbo_zicbom_cpu_dcache_wb_range(vm_offset_t va, vm_size_t len)
+{
+ vm_offset_t addr;
+
+ /*
+ * A clean operation makes data from store operations performed by the
+ * set of coherent agents visible to a set of non-coherent agents at a
+ * point common to both sets by performing a write transfer of a copy of
+ * a cache block to that point provided a coherent agent performed a
+ * store operation that modified the data in the cache block since the
+ * previous invalidate, clean, or flush operation on the cache block.
+ */
+
+ va &= ~(dcache_line_size - 1);
+ for (addr = va; addr < va + len; addr += dcache_line_size)
+ __asm __volatile(".option push; .option arch, +zicbom\n"
+ "cbo.clean (%0); .option pop\n" :: "r"(addr));
+}
+
+void
+cbo_zicbom_setup_cache(int cbom_block_size)
+{
+ struct riscv_cache_ops zicbom_ops;
+
+ if (cbom_block_size <= 0 || !powerof2(cbom_block_size)) {
+ printf("Zicbom: could not initialise (invalid cache line %d)\n",
+ cbom_block_size);
+ return;
+ }
+
+ zicbom_ops.dcache_wbinv_range = cbo_zicbom_cpu_dcache_wbinv_range;
+ zicbom_ops.dcache_inv_range = cbo_zicbom_cpu_dcache_inv_range;
+ zicbom_ops.dcache_wb_range = cbo_zicbom_cpu_dcache_wb_range;
+ riscv_cache_install_hooks(&zicbom_ops, cbom_block_size);
+}
diff --git a/sys/riscv/riscv/identcpu.c b/sys/riscv/riscv/identcpu.c
--- a/sys/riscv/riscv/identcpu.c
+++ b/sys/riscv/riscv/identcpu.c
@@ -53,6 +53,7 @@
#include <machine/elf.h>
#include <machine/md_var.h>
#include <machine/thead.h>
+#include <machine/cbo.h>
#ifdef FDT
#include <dev/fdt/fdt_common.h>
@@ -78,6 +79,11 @@
bool __read_frequently has_sscofpmf;
bool has_svpbmt;
+/* Z-extensions support. */
+bool has_zicbom;
+bool has_zicboz;
+bool has_zicbop;
+
struct cpu_desc {
const char *cpu_mvendor_name;
const char *cpu_march_name;
@@ -89,6 +95,12 @@
#define SV_SVPBMT (1 << 2)
#define SV_SVINVAL (1 << 3)
#define SV_SSCOFPMF (1 << 4)
+ u_int z_extensions; /* Multi-letter extensions. */
+#define Z_ZICBOM (1 << 0)
+#define Z_ZICBOZ (1 << 1)
+#define Z_ZICBOP (1 << 2)
+ int cbom_block_size;
+ int cboz_block_size;
};
struct cpu_desc cpu_desc[MAXCPU];
@@ -114,6 +126,7 @@
static const struct marchid_entry sifive_marchids[] = {
{ MARCHID_SIFIVE_U7, "6/7/P200/X200-Series Processor" },
+ { MARCHID_SIFIVE_P5, "P550/P650 Processor" },
MARCHID_END
};
@@ -196,11 +209,24 @@
static __inline int
parse_ext_z(struct cpu_desc *desc __unused, char *isa, int idx, int len)
{
+#define CHECK_Z_EXT(str, flag) \
+ do { \
+ if (strncmp(&isa[idx], (str), \
+ MIN(strlen(str), len - idx)) == 0) { \
+ desc->z_extensions |= flag; \
+ return (idx + strlen(str)); \
+ } \
+ } while (0)
+
+ /* Check for known/supported extensions. */
+ CHECK_Z_EXT("zicbom", Z_ZICBOM);
+ CHECK_Z_EXT("zicboz", Z_ZICBOZ);
+ CHECK_Z_EXT("zicbop", Z_ZICBOP);
+
+#undef CHECK_Z_EXT
/*
* Proceed to the next multi-letter extension or the end of the
* string.
- *
- * TODO: parse some of these.
*/
while (isa[idx] != '_' && idx < len) {
idx++;
@@ -321,6 +347,22 @@
}
}
+static void
+parse_cbo_fdt(struct cpu_desc *desc, phandle_t node)
+{
+ int error;
+
+ error = OF_getencprop(node, "riscv,cbom-block-size",
+ &desc->cbom_block_size, sizeof(desc->cbom_block_size));
+ if (error == -1)
+ desc->cbom_block_size = 0;
+
+ error = OF_getencprop(node, "riscv,cboz-block-size",
+ &desc->cboz_block_size, sizeof(desc->cboz_block_size));
+ if (error == -1)
+ desc->cboz_block_size = 0;
+}
+
static void
identify_cpu_features_fdt(u_int cpu, struct cpu_desc *desc)
{
@@ -372,6 +414,9 @@
/* Check MMU features. */
parse_mmu_fdt(desc, node);
+ /* Cache-block operations (CBO). */
+ parse_cbo_fdt(desc, node);
+
/* We are done. */
break;
}
@@ -422,6 +467,11 @@
UPDATE_CAP(has_sscofpmf, (desc->smode_extensions & SV_SSCOFPMF) != 0);
UPDATE_CAP(has_svpbmt, (desc->smode_extensions & SV_SVPBMT) != 0);
+ /* Z extension support. */
+ UPDATE_CAP(has_zicbom, (desc->z_extensions & Z_ZICBOM) != 0);
+ UPDATE_CAP(has_zicboz, (desc->z_extensions & Z_ZICBOZ) != 0);
+ UPDATE_CAP(has_zicbop, (desc->z_extensions & Z_ZICBOP) != 0);
+
#undef UPDATE_CAP
}
@@ -506,6 +556,9 @@
update_global_capabilities(cpu, desc);
handle_cpu_quirks(cpu, desc);
+
+ if (has_zicbom && cpu == 0)
+ cbo_zicbom_setup_cache(desc->cbom_block_size);
}
void
diff --git a/tools/tools/git/ghpr/ghpr-init.sh b/tools/tools/git/ghpr/ghpr-init.sh
--- a/tools/tools/git/ghpr/ghpr-init.sh
+++ b/tools/tools/git/ghpr/ghpr-init.sh
@@ -16,12 +16,14 @@
# Bail if the branch already exists
else
if git rev-parse --verify ${BRANCH} > /dev/null 2>&1; then
- echo "Branch ${BRANCH} already exists, skipping creation"
+ echo "Branch ${BRANCH} already exists, skipping creation, but rebasing to ${base}"
+ git rebase ${base} ${BRANCH}
else
# Create the branch and tag it as the one we're using for opabinia merging.
+ echo "Creating ${BRANCH} from ${base} to land changes"
git checkout -b ${BRANCH} ${base} || die "Can't create ${BRANCH}"
fi
fi
-git config --add --type bool branch.${BRANCH}.opabinia true || die "Can't annotate"
-git config --add branch.${BRANCH}.opabinia.base ${base} || die "Can't annotate"
+git config set --type bool --all branch.${BRANCH}.opabinia true || die "Can't annotate"
+git config set --all branch.${BRANCH}.opabinia.base "${base}" || die "Can't annotate"
diff --git a/tools/tools/git/ghpr/ghpr-push.sh b/tools/tools/git/ghpr/ghpr-push.sh
--- a/tools/tools/git/ghpr/ghpr-push.sh
+++ b/tools/tools/git/ghpr/ghpr-push.sh
@@ -42,6 +42,7 @@
for pr in $(git config --get-all branch.${staging}.opabinia.prs); do
if ! $do_pr_branch_push; then
gh pr edit $pr --add-label merged
+ gh pr close $pr --comment "ghpr helper script closed this after push to source of truth."
fi
git branch -D PR-${pr}
git config --remove-section branch.${staging}.opabinia.${pr}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jan 1, 1:54 PM (6 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27437730
Default Alt Text
D49962.diff (52 KB)
Attached To
Mode
D49962: Use .pieo extension for WITH_PIE bsd.prog.mk output
Attached
Detach File
Event Timeline
Log In to Comment