diff options
Diffstat (limited to 'sys/kern')
| -rw-r--r-- | sys/kern/init_main.c | 2 | ||||
| -rw-r--r-- | sys/kern/init_sysent.c | 1 | ||||
| -rw-r--r-- | sys/kern/kern_conf.c | 5 | ||||
| -rw-r--r-- | sys/kern/kern_kexec.c | 350 | ||||
| -rw-r--r-- | sys/kern/md4c.c | 298 | ||||
| -rw-r--r-- | sys/kern/md5c.c | 341 | ||||
| -rw-r--r-- | sys/kern/subr_bus.c | 2 | ||||
| -rw-r--r-- | sys/kern/subr_kdb.c | 2 | ||||
| -rw-r--r-- | sys/kern/subr_smp.c | 15 | ||||
| -rw-r--r-- | sys/kern/syscalls.c | 1 | ||||
| -rw-r--r-- | sys/kern/syscalls.master | 8 | ||||
| -rw-r--r-- | sys/kern/systrace_args.c | 34 | ||||
| -rw-r--r-- | sys/kern/vfs_cluster.c | 4 | ||||
| -rw-r--r-- | sys/kern/vfs_default.c | 1 | ||||
| -rw-r--r-- | sys/kern/vfs_syscalls.c | 2 | 
15 files changed, 417 insertions, 649 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_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_bus.c b/sys/kern/subr_bus.c index bf5bda7e058d..b84f69cfd03e 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -4633,7 +4633,7 @@ bus_release_resources(device_t dev, const struct resource_spec *rs,   * parent of @p dev.   */  struct resource * -bus_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, +(bus_alloc_resource)(device_t dev, int type, int *rid, rman_res_t start,      rman_res_t end, rman_res_t count, u_int flags)  {  	struct resource *res; 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)) | 
