aboutsummaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c2
-rw-r--r--sys/kern/init_sysent.c1
-rw-r--r--sys/kern/kern_conf.c5
-rw-r--r--sys/kern/kern_jail.c23
-rw-r--r--sys/kern/kern_kexec.c350
-rw-r--r--sys/kern/md4c.c298
-rw-r--r--sys/kern/md5c.c341
-rw-r--r--sys/kern/subr_kdb.c2
-rw-r--r--sys/kern/subr_smp.c15
-rw-r--r--sys/kern/syscalls.c1
-rw-r--r--sys/kern/syscalls.master8
-rw-r--r--sys/kern/systrace_args.c34
-rw-r--r--sys/kern/vfs_cluster.c4
-rw-r--r--sys/kern/vfs_default.c1
-rw-r--r--sys/kern/vfs_syscalls.c2
15 files changed, 428 insertions, 659 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 87ffdb8dbf07..6612ac685936 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -384,7 +384,7 @@ C_SYSINIT(diagwarn2, SI_SUB_LAST, SI_ORDER_FIFTH,
#if __SIZEOF_LONG__ == 4
static const char ilp32_warn[] =
- "WARNING: 32-bit kernels are deprecated and may be removed in FreeBSD 15.0.\n";
+ "WARNING: 32-bit kernels are deprecated and may be removed in FreeBSD 16.0.\n";
C_SYSINIT(ilp32warn, SI_SUB_COPYRIGHT, SI_ORDER_FIFTH,
print_caddr_t, ilp32_warn);
C_SYSINIT(ilp32warn2, SI_SUB_LAST, SI_ORDER_FIFTH,
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index e42e7dcf8b44..cd305de1ed44 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -665,4 +665,5 @@ struct sysent sysent[] = {
{ .sy_narg = AS(setgroups_args), .sy_call = (sy_call_t *)sys_setgroups, .sy_auevent = AUE_SETGROUPS, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 596 = setgroups */
{ .sy_narg = AS(jail_attach_jd_args), .sy_call = (sy_call_t *)sys_jail_attach_jd, .sy_auevent = AUE_JAIL_ATTACH, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 597 = jail_attach_jd */
{ .sy_narg = AS(jail_remove_jd_args), .sy_call = (sy_call_t *)sys_jail_remove_jd, .sy_auevent = AUE_JAIL_REMOVE, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 598 = jail_remove_jd */
+ { .sy_narg = AS(kexec_load_args), .sy_call = (sy_call_t *)sys_kexec_load, .sy_auevent = AUE_NULL, .sy_flags = 0, .sy_thrcnt = SY_THR_STATIC }, /* 599 = kexec_load */
};
diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c
index b891ed84957a..2da51d84ff60 100644
--- a/sys/kern/kern_conf.c
+++ b/sys/kern/kern_conf.c
@@ -664,7 +664,7 @@ prep_cdevsw(struct cdevsw *devsw, int flags)
if ((devsw->d_flags & D_GIANTOK) == 0) {
printf(
"WARNING: Device \"%s\" is Giant locked and may be "
- "deleted before FreeBSD 15.0.\n",
+ "deleted before FreeBSD 16.0.\n",
devsw->d_name == NULL ? "???" : devsw->d_name);
}
if (devsw->d_gianttrick == NULL) {
@@ -1163,6 +1163,9 @@ destroy_devl(struct cdev *dev)
devfs_destroy_cdevpriv(p);
mtx_lock(&cdevpriv_mtx);
}
+ while (cdp->cdp_fdpriv_dtrc != 0) {
+ msleep(&cdp->cdp_fdpriv_dtrc, &cdevpriv_mtx, 0, "cdfdpc", 0);
+ }
mtx_unlock(&cdevpriv_mtx);
dev_lock();
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 3697d95fe0e5..267b60ffb5bc 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -1088,6 +1088,7 @@ kern_jail_set(struct thread *td, struct uio *optuio, int flags)
else {
if (!(flags & (JAIL_USE_DESC | JAIL_AT_DESC | JAIL_GET_DESC |
JAIL_OWN_DESC))) {
+ error = EINVAL;
vfs_opterror(opts, "unexpected desc");
goto done_errmsg;
}
@@ -2518,6 +2519,7 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags)
} else if (error == 0) {
if (!(flags & (JAIL_USE_DESC | JAIL_AT_DESC | JAIL_GET_DESC |
JAIL_OWN_DESC))) {
+ error = EINVAL;
vfs_opterror(opts, "unexpected desc");
goto done;
}
@@ -2909,12 +2911,6 @@ prison_remove(struct prison *pr)
{
sx_assert(&allprison_lock, SA_XLOCKED);
mtx_assert(&pr->pr_mtx, MA_OWNED);
- if (!prison_isalive(pr)) {
- /* Silently ignore already-dying prisons. */
- mtx_unlock(&pr->pr_mtx);
- sx_xunlock(&allprison_lock);
- return;
- }
prison_deref(pr, PD_KILL | PD_DEREF | PD_LOCKED | PD_LIST_XLOCKED);
}
@@ -3461,12 +3457,17 @@ prison_deref(struct prison *pr, int flags)
/* Kill the prison and its descendents. */
KASSERT(pr != &prison0,
("prison_deref trying to kill prison0"));
- if (!(flags & PD_DEREF)) {
- prison_hold(pr);
- flags |= PD_DEREF;
+ if (!prison_isalive(pr)) {
+ /* Silently ignore already-dying prisons. */
+ flags &= ~PD_KILL;
+ } else {
+ if (!(flags & PD_DEREF)) {
+ prison_hold(pr);
+ flags |= PD_DEREF;
+ }
+ flags = prison_lock_xlock(pr, flags);
+ prison_deref_kill(pr, &freeprison);
}
- flags = prison_lock_xlock(pr, flags);
- prison_deref_kill(pr, &freeprison);
}
if (flags & PD_DEUREF) {
/* Drop a user reference. */
diff --git a/sys/kern/kern_kexec.c b/sys/kern/kern_kexec.c
new file mode 100644
index 000000000000..2efea7dcf9a7
--- /dev/null
+++ b/sys/kern/kern_kexec.c
@@ -0,0 +1,350 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2025 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/eventhandler.h>
+#include <sys/kernel.h>
+#ifdef INTRNG
+#include <sys/intr.h>
+#endif
+#include <sys/kexec.h>
+#include <sys/malloc.h>
+#include <sys/proc.h>
+#include <sys/priv.h>
+#include <sys/reboot.h>
+#include <sys/rman.h>
+#include <sys/rwlock.h>
+#include <sys/smp.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysproto.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pagequeue.h>
+#include <vm/vm_phys.h>
+#include <vm/vm_radix.h>
+
+#include <machine/kexec.h>
+
+#ifndef KEXEC_MD_PAGES
+/*
+ * Number of MD pages for extra bookkeeping.
+ * This is a macro because it can be a constant (some architectures make it 0).
+ * It accepts an argument, which is an array of
+ * kexec_segment[KEXEC_SEGMENT_MAX].
+ */
+#define KEXEC_MD_PAGES(x) 0
+#endif
+
+/*
+ * Basic design:
+ *
+ * Given an array of "segment descriptors" stage an image to be loaded and
+ * jumped to at reboot, instead of rebooting via firmware.
+ *
+ * Constraints:
+ * - The segment descriptors' "mem" and "memsz" must each fit within a
+ * vm_phys_seg segment, which can be obtained via the `vm.phys_segs` sysctl.
+ * A single segment cannot span multiple vm_phys_seg segments, even if the
+ * vm_phys_seg segments are adjacent.
+ *
+ * Technical details:
+ *
+ * Take advantage of the VM subsystem and create a vm_object to hold the staged
+ * image. When grabbing pages for the object, sort the pages so that if a page
+ * in the object is located in the physical range of any of the kexec segment
+ * targets then it gets placed at the pindex corresponding to that physical
+ * address. This avoids the chance of corruption by writing over the page in
+ * the final copy, or the need for a copy buffer page.
+ */
+
+static struct kexec_image staged_image;
+static vm_offset_t stage_addr;
+static vm_object_t kexec_obj;
+
+static eventhandler_tag kexec_reboot_handler;
+static struct mtx kexec_mutex;
+
+static MALLOC_DEFINE(M_KEXEC, "kexec", "Kexec segments");
+
+
+static void
+kexec_reboot(void *junk __unused, int howto)
+{
+ if ((howto & RB_KEXEC) == 0 || kexec_obj == NULL)
+ return;
+
+#ifdef SMP
+ cpu_mp_stop();
+#endif /* SMP */
+ intr_disable();
+ printf("Starting kexec reboot\n");
+
+ scheduler_stopped = true;
+ kexec_reboot_md(&staged_image);
+}
+
+MTX_SYSINIT(kexec_mutex, &kexec_mutex, "kexec", MTX_DEF);
+
+/* Sort the segment list once copied in */
+static int
+seg_cmp(const void *seg1, const void *seg2)
+{
+ const struct kexec_segment *s1, *s2;
+
+ s1 = seg1;
+ s2 = seg2;
+
+ return ((uintptr_t)s1->mem - (uintptr_t)s2->mem);
+}
+
+static bool
+segment_fits(struct kexec_segment *seg)
+{
+ vm_paddr_t v = (vm_paddr_t)(uintptr_t)seg->mem;
+
+ for (int i = 0; i < vm_phys_nsegs; i++) {
+ if (v >= vm_phys_segs[i].start &&
+ (v + seg->memsz - 1) <= vm_phys_segs[i].end)
+ return (true);
+ }
+
+ return (false);
+}
+
+static vm_paddr_t
+pa_for_pindex(struct kexec_segment_stage *segs, int count, vm_pindex_t pind)
+{
+ for (int i = count; i > 0; --i) {
+ if (pind >= segs[i - 1].pindex)
+ return (ptoa(pind - segs[i-1].pindex) + segs[i - 1].target);
+ }
+
+ panic("No segment for pindex %ju\n", (uintmax_t)pind);
+}
+
+/*
+ * For now still tied to the system call, so assumes all memory is userspace.
+ */
+int
+kern_kexec_load(struct thread *td, u_long entry, u_long nseg,
+ struct kexec_segment *seg, u_long flags)
+{
+ static int kexec_loading;
+ struct kexec_segment segtmp[KEXEC_SEGMENT_MAX];
+ struct kexec_image *new_image_stage = 0;
+ vm_object_t new_segments = NULL;
+ uint8_t *buf;
+ int err = 0;
+ int i;
+ const size_t segsize = nseg * sizeof(struct kexec_segment);
+ vm_page_t *page_list = 0;
+ vm_size_t image_count, md_pages, page_count, tmpsize;
+ vm_offset_t segment_va = 0;
+ /*
+ * - Do any sanity checking
+ * - Load the new segments to temporary
+ * - Remove the old segments
+ * - Install the new segments
+ */
+
+ if (nseg > KEXEC_SEGMENT_MAX)
+ return (EINVAL);
+
+ if (atomic_cmpset_acq_int(&kexec_loading, false, true) == 0)
+ return (EBUSY);
+
+ /* Only do error checking if we're installing new segments. */
+ if (nseg > 0) {
+ /* Create the new kexec object before destroying the old one. */
+ bzero(&segtmp, sizeof(segtmp));
+ err = copyin(seg, segtmp, segsize);
+ if (err != 0)
+ goto out;
+ qsort(segtmp, nseg, sizeof(*segtmp), seg_cmp);
+ new_image_stage = malloc(sizeof(*new_image_stage), M_TEMP, M_WAITOK | M_ZERO);
+ /*
+ * Sanity checking:
+ * - All segments must not overlap the kernel, so must be fully enclosed
+ * in a vm_phys_seg (each kexec segment must be in a single
+ * vm_phys_seg segment, cannot cross even adjacent segments).
+ */
+ image_count = 0;
+ for (i = 0; i < nseg; i++) {
+ if (!segment_fits(&segtmp[i]) ||
+ segtmp[i].bufsz > segtmp[i].memsz) {
+ err = EINVAL;
+ goto out;
+ }
+ new_image_stage->segments[i].pindex = image_count;
+ new_image_stage->segments[i].target = (vm_offset_t)segtmp[i].mem;
+ new_image_stage->segments[i].size = segtmp[i].memsz;
+ image_count += atop(segtmp[i].memsz);
+ }
+ md_pages = KEXEC_MD_PAGES(segtmp);
+ page_count = image_count + md_pages;
+ new_segments = vm_object_allocate(OBJT_PHYS, page_count);
+ page_list = malloc(page_count * sizeof(vm_page_t), M_TEMP, M_WAITOK);
+
+ /*
+ * - Grab all pages for all segments (use pindex to slice it)
+ * - Walk the list (once)
+ * - At each pindex, check if the target PA that corresponds
+ * to that index is in the object. If so, swap the pages.
+ * - At the end of this the list will be "best" sorted.
+ */
+ vm_page_grab_pages_unlocked(new_segments, 0,
+ VM_ALLOC_NORMAL | VM_ALLOC_WAITOK | VM_ALLOC_WIRED | VM_ALLOC_NOBUSY | VM_ALLOC_ZERO,
+ page_list, page_count);
+
+ /* Sort the pages to best match the PA */
+ VM_OBJECT_WLOCK(new_segments);
+ for (i = 0; i < image_count; i++) {
+ vm_page_t curpg, otherpg, tmp;
+ vm_pindex_t otheridx;
+
+ curpg = page_list[i];
+ otherpg = PHYS_TO_VM_PAGE(pa_for_pindex(new_image_stage->segments,
+ nseg, curpg->pindex));
+ otheridx = otherpg->pindex;
+
+ if (otherpg->object == new_segments) {
+ /*
+ * Swap 'curpg' and 'otherpg', since 'otherpg'
+ * is at the PA 'curpg' covers.
+ */
+ vm_radix_remove(&new_segments->rtree, otheridx);
+ vm_radix_remove(&new_segments->rtree, i);
+ otherpg->pindex = i;
+ curpg->pindex = otheridx;
+ vm_radix_insert(&new_segments->rtree, curpg);
+ vm_radix_insert(&new_segments->rtree, otherpg);
+ tmp = curpg;
+ page_list[i] = otherpg;
+ page_list[otheridx] = tmp;
+ }
+ }
+ for (i = 0; i < nseg; i++) {
+ new_image_stage->segments[i].first_page =
+ vm_radix_lookup(&new_segments->rtree,
+ new_image_stage->segments[i].pindex);
+ }
+ if (md_pages > 0)
+ new_image_stage->first_md_page =
+ vm_radix_lookup(&new_segments->rtree,
+ page_count - md_pages);
+ else
+ new_image_stage->first_md_page = NULL;
+ VM_OBJECT_WUNLOCK(new_segments);
+
+ /* Map the object to do the copies */
+ err = vm_map_find(kernel_map, new_segments, 0, &segment_va,
+ ptoa(page_count), 0, VMFS_ANY_SPACE,
+ VM_PROT_RW, VM_PROT_RW, MAP_PREFAULT);
+ if (err != 0)
+ goto out;
+ buf = (void *)segment_va;
+ new_image_stage->map_addr = segment_va;
+ new_image_stage->map_size = ptoa(new_segments->size);
+ new_image_stage->entry = entry;
+ new_image_stage->map_obj = new_segments;
+ for (i = 0; i < nseg; i++) {
+ err = copyin(segtmp[i].buf, buf, segtmp[i].bufsz);
+ if (err != 0) {
+ goto out;
+ }
+ new_image_stage->segments[i].map_buf = buf;
+ buf += segtmp[i].bufsz;
+ tmpsize = segtmp[i].memsz - segtmp[i].bufsz;
+ if (tmpsize > 0)
+ memset(buf, 0, tmpsize);
+ buf += tmpsize;
+ }
+ /* What's left are the MD pages, so zero them all out. */
+ if (md_pages > 0)
+ bzero(buf, ptoa(md_pages));
+
+ cpu_flush_dcache((void *)segment_va, ptoa(page_count));
+ if ((err = kexec_load_md(new_image_stage)) != 0)
+ goto out;
+ }
+ if (kexec_obj != NULL) {
+ vm_object_unwire(kexec_obj, 0, kexec_obj->size, 0);
+ KASSERT(stage_addr != 0, ("Mapped kexec_obj without address"));
+ vm_map_remove(kernel_map, stage_addr, stage_addr + kexec_obj->size);
+ }
+ kexec_obj = new_segments;
+ bzero(&staged_image, sizeof(staged_image));
+ if (nseg > 0)
+ memcpy(&staged_image, new_image_stage, sizeof(*new_image_stage));
+
+ printf("trampoline at %#jx\n", (uintmax_t)staged_image.entry);
+ if (nseg > 0) {
+ if (kexec_reboot_handler == NULL)
+ kexec_reboot_handler =
+ EVENTHANDLER_REGISTER(shutdown_final, kexec_reboot, NULL,
+ SHUTDOWN_PRI_DEFAULT - 150);
+ } else {
+ if (kexec_reboot_handler != NULL)
+ EVENTHANDLER_DEREGISTER(shutdown_final, kexec_reboot_handler);
+ }
+out:
+ /* Clean up the mess if we've gotten far. */
+ if (err != 0 && new_segments != NULL) {
+ vm_object_unwire(new_segments, 0, new_segments->size, 0);
+ if (segment_va != 0)
+ vm_map_remove(kernel_map, segment_va, segment_va + kexec_obj->size);
+ else
+ vm_object_deallocate(new_segments);
+ }
+ atomic_store_rel_int(&kexec_loading, false);
+ if (new_image_stage != NULL)
+ free(new_image_stage, M_TEMP);
+ if (page_list != 0)
+ free(page_list, M_TEMP);
+
+ return (err);
+}
+
+int
+sys_kexec_load(struct thread *td, struct kexec_load_args *uap)
+{
+ int error;
+
+ // FIXME: Do w need a better privilege check than PRIV_REBOOT here?
+ error = priv_check(td, PRIV_REBOOT);
+ if (error != 0)
+ return (error);
+ return (kern_kexec_load(td, uap->entry, uap->nseg, uap->segments, uap->flags));
+}
diff --git a/sys/kern/md4c.c b/sys/kern/md4c.c
deleted file mode 100644
index e173e17e3387..000000000000
--- a/sys/kern/md4c.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm
- */
-
-/*-
- SPDX-License-Identifier: RSA-MD
-
- Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
-
- License to copy and use this software is granted provided that it
- is identified as the "RSA Data Security, Inc. MD4 Message-Digest
- Algorithm" in all material mentioning or referencing this software
- or this function.
-
- License is also granted to make and use derivative works provided
- that such works are identified as "derived from the RSA Data
- Security, Inc. MD4 Message-Digest Algorithm" in all material
- mentioning or referencing the derived work.
-
- RSA Data Security, Inc. makes no representations concerning either
- the merchantability of this software or the suitability of this
- software for any particular purpose. It is provided "as is"
- without express or implied warranty of any kind.
-
- These notices must be retained in any copies of any part of this
- documentation and/or software.
- */
-
-#include <sys/param.h>
-#ifdef _KERNEL
-#include <sys/systm.h>
-#else
-#include <string.h>
-#endif
-#include <sys/md4.h>
-
-typedef unsigned char *POINTER;
-typedef uint16_t UINT2;
-typedef uint32_t UINT4;
-
-#define PROTO_LIST(list) list
-
-/* Constants for MD4Transform routine.
- */
-#define S11 3
-#define S12 7
-#define S13 11
-#define S14 19
-#define S21 3
-#define S22 5
-#define S23 9
-#define S24 13
-#define S31 3
-#define S32 9
-#define S33 11
-#define S34 15
-
-static void MD4Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
-static void Encode PROTO_LIST
- ((unsigned char *, UINT4 *, unsigned int));
-static void Decode PROTO_LIST
- ((UINT4 *, const unsigned char *, unsigned int));
-
-static unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G and H are basic MD4 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
-/* Rotation is separate from addition to prevent recomputation */
-#define FF(a, b, c, d, x, s) { \
- (a) += F ((b), (c), (d)) + (x); \
- (a) = ROTATE_LEFT ((a), (s)); \
- }
-#define GG(a, b, c, d, x, s) { \
- (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
- (a) = ROTATE_LEFT ((a), (s)); \
- }
-#define HH(a, b, c, d, x, s) { \
- (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
- (a) = ROTATE_LEFT ((a), (s)); \
- }
-
-/* MD4 initialization. Begins an MD4 operation, writing a new context.
- */
-void
-MD4Init(MD4_CTX *context)
-{
- context->count[0] = context->count[1] = 0;
-
- /* Load magic initialization constants.
- */
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/* MD4 block update operation. Continues an MD4 message-digest
- operation, processing another message block, and updating the
- context.
- */
-void
-MD4Update(MD4_CTX *context, const unsigned char *input,
- unsigned int inputLen)
-{
- unsigned int i, index, partLen;
-
- /* Compute number of bytes mod 64 */
- index = (unsigned int)((context->count[0] >> 3) & 0x3F);
- /* Update number of bits */
- if ((context->count[0] += ((UINT4)inputLen << 3))
- < ((UINT4)inputLen << 3))
- context->count[1]++;
- context->count[1] += ((UINT4)inputLen >> 29);
-
- partLen = 64 - index;
- /* Transform as many times as possible.
- */
- if (inputLen >= partLen) {
- bcopy(input, &context->buffer[index], partLen);
- MD4Transform (context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD4Transform (context->state, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- bcopy(&input[i], &context->buffer[index], inputLen-i);
-}
-
-/* MD4 padding. */
-void
-MD4Pad(MD4_CTX *context)
-{
- unsigned char bits[8];
- unsigned int index, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64.
- */
- index = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- MD4Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD4Update (context, bits, 8);
-}
-
-/* MD4 finalization. Ends an MD4 message-digest operation, writing the
- the message digest and zeroizing the context.
- */
-void
-MD4Final(unsigned char digest[static 16], MD4_CTX *context)
-{
- /* Do padding */
- MD4Pad (context);
-
- /* Store state in digest */
- Encode (digest, context->state, 16);
-
- /* Zeroize sensitive information.
- */
- bzero(context, sizeof (*context));
-}
-
-/* MD4 basic transformation. Transforms state based on block.
- */
-static void
-MD4Transform(UINT4 state[4], const unsigned char block[64])
-{
- UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11); /* 1 */
- FF (d, a, b, c, x[ 1], S12); /* 2 */
- FF (c, d, a, b, x[ 2], S13); /* 3 */
- FF (b, c, d, a, x[ 3], S14); /* 4 */
- FF (a, b, c, d, x[ 4], S11); /* 5 */
- FF (d, a, b, c, x[ 5], S12); /* 6 */
- FF (c, d, a, b, x[ 6], S13); /* 7 */
- FF (b, c, d, a, x[ 7], S14); /* 8 */
- FF (a, b, c, d, x[ 8], S11); /* 9 */
- FF (d, a, b, c, x[ 9], S12); /* 10 */
- FF (c, d, a, b, x[10], S13); /* 11 */
- FF (b, c, d, a, x[11], S14); /* 12 */
- FF (a, b, c, d, x[12], S11); /* 13 */
- FF (d, a, b, c, x[13], S12); /* 14 */
- FF (c, d, a, b, x[14], S13); /* 15 */
- FF (b, c, d, a, x[15], S14); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 0], S21); /* 17 */
- GG (d, a, b, c, x[ 4], S22); /* 18 */
- GG (c, d, a, b, x[ 8], S23); /* 19 */
- GG (b, c, d, a, x[12], S24); /* 20 */
- GG (a, b, c, d, x[ 1], S21); /* 21 */
- GG (d, a, b, c, x[ 5], S22); /* 22 */
- GG (c, d, a, b, x[ 9], S23); /* 23 */
- GG (b, c, d, a, x[13], S24); /* 24 */
- GG (a, b, c, d, x[ 2], S21); /* 25 */
- GG (d, a, b, c, x[ 6], S22); /* 26 */
- GG (c, d, a, b, x[10], S23); /* 27 */
- GG (b, c, d, a, x[14], S24); /* 28 */
- GG (a, b, c, d, x[ 3], S21); /* 29 */
- GG (d, a, b, c, x[ 7], S22); /* 30 */
- GG (c, d, a, b, x[11], S23); /* 31 */
- GG (b, c, d, a, x[15], S24); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 0], S31); /* 33 */
- HH (d, a, b, c, x[ 8], S32); /* 34 */
- HH (c, d, a, b, x[ 4], S33); /* 35 */
- HH (b, c, d, a, x[12], S34); /* 36 */
- HH (a, b, c, d, x[ 2], S31); /* 37 */
- HH (d, a, b, c, x[10], S32); /* 38 */
- HH (c, d, a, b, x[ 6], S33); /* 39 */
- HH (b, c, d, a, x[14], S34); /* 40 */
- HH (a, b, c, d, x[ 1], S31); /* 41 */
- HH (d, a, b, c, x[ 9], S32); /* 42 */
- HH (c, d, a, b, x[ 5], S33); /* 43 */
- HH (b, c, d, a, x[13], S34); /* 44 */
- HH (a, b, c, d, x[ 3], S31); /* 45 */
- HH (d, a, b, c, x[11], S32); /* 46 */
- HH (c, d, a, b, x[ 7], S33); /* 47 */
- HH (b, c, d, a, x[15], S34); /* 48 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information.
- */
- bzero((POINTER)x, sizeof (x));
-}
-
-/* Encodes input (UINT4) into output (unsigned char). Assumes len is
- a multiple of 4.
- */
-static void
-Encode(unsigned char *output, UINT4 *input, unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4) {
- output[j] = (unsigned char)(input[i] & 0xff);
- output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
- output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
- output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
- }
-}
-
-/* Decodes input (unsigned char) into output (UINT4). Assumes len is
- a multiple of 4.
- */
-static void
-Decode(UINT4 *output, const unsigned char *input, unsigned int len)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
- (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-}
-
-#ifdef WEAK_REFS
-/* When building libmd, provide weak references. Note: this is not
- activated in the context of compiling these sources for internal
- use in libcrypt.
- */
-#undef MD4Init
-__weak_reference(_libmd_MD4Init, MD4Init);
-#undef MD4Update
-__weak_reference(_libmd_MD4Update, MD4Update);
-#undef MD4Pad
-__weak_reference(_libmd_MD4Pad, MD4Pad);
-#undef MD4Final
-__weak_reference(_libmd_MD4Final, MD4Final);
-#endif
diff --git a/sys/kern/md5c.c b/sys/kern/md5c.c
deleted file mode 100644
index 0922d0f8cc61..000000000000
--- a/sys/kern/md5c.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*-
- * SPDX-License-Identifier: RSA-MD
- *
- * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
- *
- * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
- * rights reserved.
- *
- * License to copy and use this software is granted provided that it
- * is identified as the "RSA Data Security, Inc. MD5 Message-Digest
- * Algorithm" in all material mentioning or referencing this software
- * or this function.
- *
- * License is also granted to make and use derivative works provided
- * that such works are identified as "derived from the RSA Data
- * Security, Inc. MD5 Message-Digest Algorithm" in all material
- * mentioning or referencing the derived work.
- *
- * RSA Data Security, Inc. makes no representations concerning either
- * the merchantability of this software or the suitability of this
- * software for any particular purpose. It is provided "as is"
- * without express or implied warranty of any kind.
- *
- * These notices must be retained in any copies of any part of this
- * documentation and/or software.
- *
- * This code is the same as the code published by RSA Inc. It has been
- * edited for clarity and style only.
- */
-
-#include <sys/types.h>
-
-#ifdef _KERNEL
-#include <sys/systm.h>
-#else
-#include <string.h>
-#endif
-
-#include <machine/endian.h>
-#include <sys/endian.h>
-#include <sys/md5.h>
-
-static void MD5Transform(uint32_t [4], const unsigned char [64]);
-
-#if (BYTE_ORDER == LITTLE_ENDIAN)
-#define Encode memcpy
-#define Decode memcpy
-#else
-
-/*
- * Encodes input (uint32_t) into output (unsigned char). Assumes len is
- * a multiple of 4.
- */
-
-static void
-Encode (unsigned char *output, uint32_t *input, unsigned int len)
-{
- unsigned int i;
- uint32_t ip;
-
- for (i = 0; i < len / 4; i++) {
- ip = input[i];
- *output++ = ip;
- *output++ = ip >> 8;
- *output++ = ip >> 16;
- *output++ = ip >> 24;
- }
-}
-
-/*
- * Decodes input (unsigned char) into output (uint32_t). Assumes len is
- * a multiple of 4.
- */
-
-static void
-Decode (uint32_t *output, const unsigned char *input, unsigned int len)
-{
- unsigned int i;
-
- for (i = 0; i < len; i += 4) {
- *output++ = input[i] | (input[i+1] << 8) | (input[i+2] << 16) |
- (input[i+3] << 24);
- }
-}
-#endif
-
-static unsigned char PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/* F, G, H and I are basic MD5 functions. */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits. */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/*
- * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
- * Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-/* MD5 initialization. Begins an MD5 operation, writing a new context. */
-
-void
-MD5Init(MD5_CTX *context)
-{
-
- context->count[0] = context->count[1] = 0;
-
- /* Load magic initialization constants. */
- context->state[0] = 0x67452301;
- context->state[1] = 0xefcdab89;
- context->state[2] = 0x98badcfe;
- context->state[3] = 0x10325476;
-}
-
-/*
- * MD5 block update operation. Continues an MD5 message-digest
- * operation, processing another message block, and updating the
- * context.
- */
-
-void
-MD5Update(MD5_CTX *context, const void *in, unsigned int inputLen)
-{
- unsigned int i, index, partLen;
- const unsigned char *input = in;
-
- /* Compute number of bytes mod 64 */
- index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-
- /* Update number of bits */
- if ((context->count[0] += ((uint32_t)inputLen << 3))
- < ((uint32_t)inputLen << 3))
- context->count[1]++;
- context->count[1] += ((uint32_t)inputLen >> 29);
-
- partLen = 64 - index;
-
- /* Transform as many times as possible. */
- if (inputLen >= partLen) {
- memcpy((void *)&context->buffer[index], (const void *)input,
- partLen);
- MD5Transform (context->state, context->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- MD5Transform (context->state, &input[i]);
-
- index = 0;
- }
- else
- i = 0;
-
- /* Buffer remaining input */
- memcpy ((void *)&context->buffer[index], (const void *)&input[i],
- inputLen-i);
-}
-
-/*
- * MD5 padding. Adds padding followed by original length.
- */
-
-static void
-MD5Pad(MD5_CTX *context)
-{
- unsigned char bits[8];
- unsigned int index, padLen;
-
- /* Save number of bits */
- Encode (bits, context->count, 8);
-
- /* Pad out to 56 mod 64. */
- index = (unsigned int)((context->count[0] >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- MD5Update (context, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update (context, bits, 8);
-}
-
-/*
- * MD5 finalization. Ends an MD5 message-digest operation, writing the
- * the message digest and zeroizing the context.
- */
-
-void
-MD5Final(unsigned char digest[static MD5_DIGEST_LENGTH], MD5_CTX *context)
-{
- /* Do padding. */
- MD5Pad (context);
-
- /* Store state in digest */
- Encode (digest, context->state, MD5_DIGEST_LENGTH);
-
- /* Zeroize sensitive information. */
- explicit_bzero (context, sizeof (*context));
-}
-
-/* MD5 basic transformation. Transforms state based on block. */
-
-static void
-MD5Transform(uint32_t state[4], const unsigned char block[64])
-{
- uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode (x, block, 64);
-
- /* Round 1 */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-
- /* Zeroize sensitive information. */
- memset ((void *)x, 0, sizeof (x));
-}
-
-#ifdef WEAK_REFS
-/* When building libmd, provide weak references. Note: this is not
- activated in the context of compiling these sources for internal
- use in libcrypt.
- */
-#undef MD5Init
-__weak_reference(_libmd_MD5Init, MD5Init);
-#undef MD5Update
-__weak_reference(_libmd_MD5Update, MD5Update);
-#undef MD5Final
-__weak_reference(_libmd_MD5Final, MD5Final);
-#endif
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c
index 56264a96c9fa..909dd10a6e69 100644
--- a/sys/kern/subr_kdb.c
+++ b/sys/kern/subr_kdb.c
@@ -330,7 +330,7 @@ kdb_reboot(void)
#define KEY_CRTLP 16 /* ^P */
#define KEY_CRTLR 18 /* ^R */
-/* States of th KDB "alternate break sequence" detecting state machine. */
+/* States of the KDB "alternate break sequence" detecting state machine. */
enum {
KDB_ALT_BREAK_SEEN_NONE,
KDB_ALT_BREAK_SEEN_CR,
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index 1f9577fddf9c..9f5106316018 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -242,7 +242,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
KASSERT(
type == IPI_STOP || type == IPI_STOP_HARD
#if X86
- || type == IPI_SUSPEND
+ || type == IPI_SUSPEND || type == IPI_OFF
#endif
, ("%s: invalid stop type", __func__));
@@ -260,7 +260,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
* will be lost, violating FreeBSD's assumption of reliable
* IPI delivery.
*/
- if (type == IPI_SUSPEND)
+ if (type == IPI_SUSPEND || type == IPI_OFF)
mtx_lock_spin(&smp_ipi_mtx);
#endif
@@ -280,7 +280,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
#endif
#if X86
- if (type == IPI_SUSPEND)
+ if (type == IPI_SUSPEND || type == IPI_OFF)
cpus = &suspended_cpus;
else
#endif
@@ -298,7 +298,7 @@ generic_stop_cpus(cpuset_t map, u_int type)
}
#if X86
- if (type == IPI_SUSPEND)
+ if (type == IPI_SUSPEND || type == IPI_OFF)
mtx_unlock_spin(&smp_ipi_mtx);
#endif
@@ -327,6 +327,13 @@ suspend_cpus(cpuset_t map)
return (generic_stop_cpus(map, IPI_SUSPEND));
}
+
+int
+offline_cpus(cpuset_t map)
+{
+
+ return (generic_stop_cpus(map, IPI_OFF));
+}
#endif
/*
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 4cef89cd5219..06a4adc3d8cb 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -604,4 +604,5 @@ const char *syscallnames[] = {
"setgroups", /* 596 = setgroups */
"jail_attach_jd", /* 597 = jail_attach_jd */
"jail_remove_jd", /* 598 = jail_remove_jd */
+ "kexec_load", /* 599 = kexec_load */
};
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 967af1f5313c..ea6d2b5aa1ef 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -3394,4 +3394,12 @@
);
}
+599 AUE_NULL STD {
+ int kexec_load(
+ uint64_t entry,
+ u_long nseg,
+ _In_reads_(nseg) _Contains_long_ptr_ struct kexec_segment *segments,
+ u_long flags
+ );
+ }
; vim: syntax=off
diff --git a/sys/kern/systrace_args.c b/sys/kern/systrace_args.c
index e28fef931ea8..5951cebbe74a 100644
--- a/sys/kern/systrace_args.c
+++ b/sys/kern/systrace_args.c
@@ -3514,6 +3514,16 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 1;
break;
}
+ /* kexec_load */
+ case 599: {
+ struct kexec_load_args *p = params;
+ uarg[a++] = p->entry; /* uint64_t */
+ uarg[a++] = p->nseg; /* u_long */
+ uarg[a++] = (intptr_t)p->segments; /* struct kexec_segment * */
+ uarg[a++] = p->flags; /* u_long */
+ *n_args = 4;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -9401,6 +9411,25 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
+ /* kexec_load */
+ case 599:
+ switch (ndx) {
+ case 0:
+ p = "uint64_t";
+ break;
+ case 1:
+ p = "u_long";
+ break;
+ case 2:
+ p = "userland struct kexec_segment *";
+ break;
+ case 3:
+ p = "u_long";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -11409,6 +11438,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* kexec_load */
+ case 599:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
diff --git a/sys/kern/vfs_cluster.c b/sys/kern/vfs_cluster.c
index 2e397b8e9e8f..b674313993c4 100644
--- a/sys/kern/vfs_cluster.c
+++ b/sys/kern/vfs_cluster.c
@@ -260,8 +260,10 @@ cluster_read(struct vnode *vp, u_quad_t filesize, daddr_t lblkno, long size,
*/
while (lblkno < (origblkno + maxra)) {
error = VOP_BMAP(vp, lblkno, NULL, &blkno, &ncontig, NULL);
- if (error)
+ if (error) {
+ error = 0;
break;
+ }
if (blkno == -1)
break;
diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 05d1120030f3..4eca09aef145 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -458,6 +458,7 @@ vop_stdpathconf(struct vop_pathconf_args *ap)
case _PC_HAS_NAMEDATTR:
case _PC_HAS_HIDDENSYSTEM:
case _PC_CLONE_BLKSIZE:
+ case _PC_CASE_INSENSITIVE:
*ap->a_retval = 0;
return (0);
default:
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 9e1275359715..1a739d354f1f 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1119,7 +1119,7 @@ flags_to_rights(int flags, cap_rights_t *rightsp)
if (flags & O_TRUNC)
cap_rights_set_one(rightsp, CAP_FTRUNCATE);
- if (flags & (O_SYNC | O_FSYNC))
+ if (flags & (O_SYNC | O_FSYNC | O_DSYNC))
cap_rights_set_one(rightsp, CAP_FSYNC);
if (flags & (O_EXLOCK | O_SHLOCK))