Page MenuHomeFreeBSD

D49962.diff
No OneTemporary

D49962.diff

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

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)

Event Timeline