Index: lib/libcasper/libcasper/libcasper.h =================================================================== --- lib/libcasper/libcasper/libcasper.h +++ lib/libcasper/libcasper/libcasper.h @@ -123,8 +123,21 @@ int cap_service_limit(const cap_channel_t *chan, const char * const *names, size_t nnames); #else -#define cap_service_open(chan, name) (cap_init()) -#define cap_service_limit(chan, names, nnames) (0) +static inline cap_channel_t * +cap_service_open(const cap_channel_t *chan __unused, + const char *name __unused) +{ + + return (cap_init()); +} + +static inline int +cap_service_limit(const cap_channel_t *chan __unused, + const char * const *names __unused, size_t nnames __unused) +{ + + return (0); +} #endif /* @@ -229,7 +242,13 @@ #ifdef WITH_CASPER int cap_limit_set(const cap_channel_t *chan, nvlist_t *limits); #else -#define cap_limit_set(chan, limits) (0) +static inline int +cap_limit_set(const cap_channel_t *chan __unused, + nvlist_t *limits __unused) +{ + + return (0); +} #endif /* Index: lib/libthr/thread/thr_malloc.c =================================================================== --- lib/libthr/thread/thr_malloc.c +++ lib/libthr/thread/thr_malloc.c @@ -41,6 +41,7 @@ size_t *pagesizes; static size_t pagesizes_d[2]; static struct umutex thr_malloc_umtx; +static u_int thr_malloc_umtx_level; void __thr_malloc_init(void) @@ -60,11 +61,16 @@ static void thr_malloc_lock(struct pthread *curthread) { + uint32_t curtid; if (curthread == NULL) return; curthread->locklevel++; - _thr_umutex_lock(&thr_malloc_umtx, TID(curthread)); + curtid = TID(curthread); + if ((uint32_t)thr_malloc_umtx.m_owner == curtid) + thr_malloc_umtx_level++; + else + _thr_umutex_lock(&thr_malloc_umtx, curtid); } static void @@ -73,7 +79,10 @@ if (curthread == NULL) return; - _thr_umutex_unlock(&thr_malloc_umtx, TID(curthread)); + if (thr_malloc_umtx_level > 0) + thr_malloc_umtx_level--; + else + _thr_umutex_unlock(&thr_malloc_umtx, TID(curthread)); curthread->locklevel--; _thr_ast(curthread); } Index: share/mk/src.opts.mk =================================================================== --- share/mk/src.opts.mk +++ share/mk/src.opts.mk @@ -438,7 +438,6 @@ MK_PKGBOOTSTRAP:= no MK_SVN:= no MK_SVNLITE:= no -MK_WIRELESS:= no .endif .if ${MK_LDNS} == "no" Index: stand/efi/libefi/Makefile =================================================================== --- stand/efi/libefi/Makefile +++ stand/efi/libefi/Makefile @@ -50,6 +50,7 @@ CFLAGS+= -I${EFIINC} CFLAGS+= -I${EFIINCMD} CFLAGS.efi_console.c+= -I${SRCTOP}/sys/teken -I${SRCTOP}/contrib/pnglite +CFLAGS.efi_console.c+= -I${.CURDIR}/../loader CFLAGS.teken.c+= -I${SRCTOP}/sys/teken .if ${MK_LOADER_ZFS} != "no" CFLAGS+= -I${ZFSSRC} Index: stand/efi/libefi/efi_console.c =================================================================== --- stand/efi/libefi/efi_console.c +++ stand/efi/libefi/efi_console.c @@ -34,10 +34,10 @@ #include #include #include +#include #include "bootstrap.h" extern EFI_GUID gop_guid; -extern int efi_find_framebuffer(struct efi_fb *efifb); static EFI_GUID simple_input_ex_guid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID; static SIMPLE_TEXT_OUTPUT_INTERFACE *conout; static SIMPLE_INPUT_INTERFACE *conin; @@ -884,52 +884,29 @@ const teken_attr_t *a; teken_attr_t attr; EFI_STATUS status; - EFI_GRAPHICS_OUTPUT *gop = NULL; - struct efi_fb efifb; char env[10], *ptr; - if (use_gfx_mode == true) { - gfx_state.tg_fb_type = FB_GOP; - if (gfx_state.tg_private == NULL) { - (void) BS->LocateProtocol(&gop_guid, NULL, - (void **)&gop); - gfx_state.tg_private = gop; - } else { - gop = gfx_state.tg_private; - } + /* + * Despite the use_gfx_mode, we want to make sure we call + * efi_find_framebuffer(). This will populate the fb data, + * which will be passed to kernel. + */ + if (efi_find_framebuffer(&gfx_state) == 0 && use_gfx_mode) { + int roff, goff, boff; + roff = ffs(gfx_state.tg_fb.fb_mask_red) - 1; + goff = ffs(gfx_state.tg_fb.fb_mask_green) - 1; + boff = ffs(gfx_state.tg_fb.fb_mask_blue) - 1; + + (void) generate_cons_palette(cmap, COLOR_FORMAT_RGB, + gfx_state.tg_fb.fb_mask_red >> roff, roff, + gfx_state.tg_fb.fb_mask_green >> goff, goff, + gfx_state.tg_fb.fb_mask_blue >> boff, boff); + } else { /* - * We have FB but no GOP - it must be UGA. + * Either text mode was asked by user or we failed to + * find frame buffer. */ - if (gop == NULL) - gfx_state.tg_fb_type = FB_UGA; - - if (efi_find_framebuffer(&efifb) == 0) { - int roff, goff, boff; - - gfx_state.tg_fb.fb_addr = efifb.fb_addr; - gfx_state.tg_fb.fb_size = efifb.fb_size; - gfx_state.tg_fb.fb_height = efifb.fb_height; - gfx_state.tg_fb.fb_width = efifb.fb_width; - gfx_state.tg_fb.fb_stride = efifb.fb_stride; - gfx_state.tg_fb.fb_mask_red = efifb.fb_mask_red; - gfx_state.tg_fb.fb_mask_green = efifb.fb_mask_green; - gfx_state.tg_fb.fb_mask_blue = efifb.fb_mask_blue; - gfx_state.tg_fb.fb_mask_reserved = - efifb.fb_mask_reserved; - roff = ffs(efifb.fb_mask_red) - 1; - goff = ffs(efifb.fb_mask_green) - 1; - boff = ffs(efifb.fb_mask_blue) - 1; - - (void) generate_cons_palette(cmap, COLOR_FORMAT_RGB, - efifb.fb_mask_red >> roff, roff, - efifb.fb_mask_green >> goff, goff, - efifb.fb_mask_blue >> boff, boff); - gfx_state.tg_fb.fb_bpp = fls( - efifb.fb_mask_red | efifb.fb_mask_green | - efifb.fb_mask_blue | efifb.fb_mask_reserved); - } - } else { gfx_state.tg_fb_type = FB_TEXT; } @@ -972,13 +949,13 @@ /* * setup_font() can adjust terminal size. - * Note, we assume 80x24 terminal first, this is - * because the font selection will attempt to achieve - * at least this terminal dimension and we do not - * end up with too small font. + * Note, we do use UEFI terminal dimensions first, + * this is because the font selection will attempt + * to achieve at least this terminal dimension and + * we do not end up with too small font. */ - gfx_state.tg_tp.tp_row = TEXT_ROWS; - gfx_state.tg_tp.tp_col = TEXT_COLS; + gfx_state.tg_tp.tp_row = rows; + gfx_state.tg_tp.tp_col = cols; setup_font(&gfx_state, fb_height, fb_width); rows = gfx_state.tg_tp.tp_row; cols = gfx_state.tg_tp.tp_col; Index: stand/efi/loader/Makefile =================================================================== --- stand/efi/loader/Makefile +++ stand/efi/loader/Makefile @@ -35,6 +35,10 @@ HAVE_ZFS= yes .endif +CFLAGS.bootinfo.c += -I$(SRCTOP)/sys/teken +CFLAGS.bootinfo.c += -I${SRCTOP}/contrib/pnglite +CFLAGS.framebuffer.c += -I$(SRCTOP)/sys/teken +CFLAGS.framebuffer.c += -I${SRCTOP}/contrib/pnglite CFLAGS.gfx_fb.c += -I$(SRCTOP)/sys/teken CFLAGS.gfx_fb.c += -I${SRCTOP}/sys/cddl/contrib/opensolaris/common/lz4 CFLAGS.gfx_fb.c += -I${SRCTOP}/contrib/pnglite Index: stand/efi/loader/bootinfo.c =================================================================== --- stand/efi/loader/bootinfo.c +++ stand/efi/loader/bootinfo.c @@ -50,7 +50,7 @@ #include #endif -#include "framebuffer.h" +#include "gfx_fb.h" #if defined(LOADER_FDT_SUPPORT) #include @@ -300,19 +300,26 @@ #if defined(__amd64__) || defined(__aarch64__) struct efi_fb efifb; - if (efi_find_framebuffer(&efifb) == 0) { - printf("EFI framebuffer information:\n"); - printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, - efifb.fb_size); - printf("dimensions %d x %d\n", efifb.fb_width, - efifb.fb_height); - printf("stride %d\n", efifb.fb_stride); - printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", - efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, - efifb.fb_mask_reserved); - + efifb.fb_addr = gfx_state.tg_fb.fb_addr; + efifb.fb_size = gfx_state.tg_fb.fb_size; + efifb.fb_height = gfx_state.tg_fb.fb_height; + efifb.fb_width = gfx_state.tg_fb.fb_width; + efifb.fb_stride = gfx_state.tg_fb.fb_stride; + efifb.fb_mask_red = gfx_state.tg_fb.fb_mask_red; + efifb.fb_mask_green = gfx_state.tg_fb.fb_mask_green; + efifb.fb_mask_blue = gfx_state.tg_fb.fb_mask_blue; + efifb.fb_mask_reserved = gfx_state.tg_fb.fb_mask_reserved; + + printf("EFI framebuffer information:\n"); + printf("addr, size 0x%jx, 0x%jx\n", efifb.fb_addr, efifb.fb_size); + printf("dimensions %d x %d\n", efifb.fb_width, efifb.fb_height); + printf("stride %d\n", efifb.fb_stride); + printf("masks 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + efifb.fb_mask_red, efifb.fb_mask_green, efifb.fb_mask_blue, + efifb.fb_mask_reserved); + + if (efifb.fb_addr != 0) file_addmetadata(kfp, MODINFOMD_EFI_FB, sizeof(efifb), &efifb); - } #endif do_vmap = true; Index: stand/efi/loader/framebuffer.h =================================================================== --- stand/efi/loader/framebuffer.h +++ stand/efi/loader/framebuffer.h @@ -28,9 +28,11 @@ * $FreeBSD$ */ +#include + #ifndef _EFIFB_H_ #define _EFIFB_H_ -int efi_find_framebuffer(struct efi_fb *efifb); +int efi_find_framebuffer(teken_gfx_t *gfx_state); #endif /* _EFIFB_H_ */ Index: stand/efi/loader/framebuffer.c =================================================================== --- stand/efi/loader/framebuffer.c +++ stand/efi/loader/framebuffer.c @@ -464,21 +464,57 @@ } int -efi_find_framebuffer(struct efi_fb *efifb) +efi_find_framebuffer(teken_gfx_t *gfx_state) { + struct efi_fb efifb; EFI_GRAPHICS_OUTPUT *gop; EFI_UGA_DRAW_PROTOCOL *uga; EFI_STATUS status; + int rv; + + gfx_state->tg_fb_type = FB_TEXT; status = BS->LocateProtocol(&gop_guid, NULL, (VOID **)&gop); - if (status == EFI_SUCCESS) - return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info)); + if (status == EFI_SUCCESS) { + gfx_state->tg_fb_type = FB_GOP; + gfx_state->tg_private = gop; + } else { + status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga); + if (status == EFI_SUCCESS) { + gfx_state->tg_fb_type = FB_UGA; + gfx_state->tg_private = uga; + } else { + return (1); + } + } - status = BS->LocateProtocol(&uga_guid, NULL, (VOID **)&uga); - if (status == EFI_SUCCESS) - return (efifb_from_uga(efifb, uga)); + switch (gfx_state->tg_fb_type) { + case FB_GOP: + rv = efifb_from_gop(&efifb, gop->Mode, gop->Mode->Info); + break; - return (1); + case FB_UGA: + rv = efifb_from_uga(&efifb, uga); + break; + + default: + return (1); + } + + gfx_state->tg_fb.fb_addr = efifb.fb_addr; + gfx_state->tg_fb.fb_size = efifb.fb_size; + gfx_state->tg_fb.fb_height = efifb.fb_height; + gfx_state->tg_fb.fb_width = efifb.fb_width; + gfx_state->tg_fb.fb_stride = efifb.fb_stride; + gfx_state->tg_fb.fb_mask_red = efifb.fb_mask_red; + gfx_state->tg_fb.fb_mask_green = efifb.fb_mask_green; + gfx_state->tg_fb.fb_mask_blue = efifb.fb_mask_blue; + gfx_state->tg_fb.fb_mask_reserved = efifb.fb_mask_reserved; + + gfx_state->tg_fb.fb_bpp = fls(efifb.fb_mask_red | efifb.fb_mask_green | + efifb.fb_mask_blue | efifb.fb_mask_reserved); + + return (0); } static void Index: sys/amd64/sgx/sgx_linux.c =================================================================== --- sys/amd64/sgx/sgx_linux.c +++ sys/amd64/sgx/sgx_linux.c @@ -63,7 +63,8 @@ int error; int len; - error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(td, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), + &fp); if (error != 0) return (error); Index: sys/arm64/include/pcpu.h =================================================================== --- sys/arm64/include/pcpu.h +++ sys/arm64/include/pcpu.h @@ -56,14 +56,9 @@ struct pcb; struct pcpu; -static inline struct pcpu * -get_pcpu(void) -{ - struct pcpu *pcpu; +register struct pcpu *pcpup __asm ("x18"); - __asm __volatile("mov %0, x18" : "=&r"(pcpu)); - return (pcpu); -} +#define get_pcpu() pcpup static inline struct thread * get_curthread(void) @@ -76,11 +71,11 @@ #define curthread get_curthread() -#define PCPU_GET(member) (get_pcpu()->pc_ ## member) -#define PCPU_ADD(member, value) (get_pcpu()->pc_ ## member += (value)) +#define PCPU_GET(member) (pcpup->pc_ ## member) +#define PCPU_ADD(member, value) (pcpup->pc_ ## member += (value)) #define PCPU_INC(member) PCPU_ADD(member, 1) -#define PCPU_PTR(member) (&get_pcpu()->pc_ ## member) -#define PCPU_SET(member,value) (get_pcpu()->pc_ ## member = (value)) +#define PCPU_PTR(member) (&pcpup->pc_ ## member) +#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value)) #endif /* _KERNEL */ Index: sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -2468,6 +2468,14 @@ #define RET_INSTR 0xd65f03c0 +#define SUB_MASK 0xffc00000 +#define SUB_INSTR 0xd1000000 +#define SUB_RD_SHIFT 0 +#define SUB_RN_SHIFT 5 +#define SUB_R_MASK 0x1f +#define SUB_IMM_SHIFT 10 +#define SUB_IMM_MASK 0xfff + #define LDP_STP_MASK 0xffc00000 #define STP_32 0x29800000 #define STP_64 0xa9800000 @@ -2479,13 +2487,16 @@ #define ARG1_MASK 0x1f #define ARG2_SHIFT 10 #define ARG2_MASK 0x1f +#define ADDR_SHIFT 5 +#define ADDR_MASK 0x1f #define OFFSET_SHIFT 15 #define OFFSET_SIZE 7 #define OFFSET_MASK ((1 << OFFSET_SIZE) - 1) -#define DTRACE_INVOP_PUSHM 1 +#define DTRACE_INVOP_STP 1 #define DTRACE_INVOP_RET 2 #define DTRACE_INVOP_B 3 +#define DTRACE_INVOP_SUB 4 #elif defined(__mips__) Index: sys/cddl/dev/dtrace/aarch64/dtrace_subr.c =================================================================== --- sys/cddl/dev/dtrace/aarch64/dtrace_subr.c +++ sys/cddl/dev/dtrace/aarch64/dtrace_subr.c @@ -305,6 +305,12 @@ return (0); } + if ((invop & SUB_MASK) == SUB_INSTR) { + frame->tf_sp -= (invop >> SUB_IMM_SHIFT) & SUB_IMM_MASK; + frame->tf_elr += INSN_SIZE; + return (0); + } + if ((invop & B_MASK) == B_INSTR) { data = (invop & B_DATA_MASK); /* The data is the number of 4-byte words to change the pc */ Index: sys/cddl/dev/fbt/aarch64/fbt_isa.c =================================================================== --- sys/cddl/dev/fbt/aarch64/fbt_isa.c +++ sys/cddl/dev/fbt/aarch64/fbt_isa.c @@ -87,6 +87,7 @@ uint32_t *instr, *limit; const char *name; char *modname; + bool found; int offs; modname = opaque; @@ -108,12 +109,33 @@ limit = (uint32_t *)(symval->value + symval->size); /* Look for stp (pre-indexed) operation */ + found = false; for (; instr < limit; instr++) { - if ((*instr & LDP_STP_MASK) == STP_64) + /* Some functions start with "stp xt1, xt2, [xn, ]!" */ + if ((*instr & LDP_STP_MASK) == STP_64) { + /* + * Assume any other store of this type means we + * are past the function prolog. + */ + if (((*instr >> ADDR_SHIFT) & ADDR_MASK) == 31) + found = true; break; + } + + /* + * Some functions start with a "sub sp, sp, " + * Sometimes the compiler will have a sub instruction that + * is not of the above type so don't stop if we see one. + */ + if ((*instr & SUB_MASK) == SUB_INSTR && + ((*instr >> SUB_RD_SHIFT) & SUB_R_MASK) == 31 && + ((*instr >> SUB_RN_SHIFT) & SUB_R_MASK) == 31) { + found = true; + break; + } } - if (instr >= limit) + if (!found) return (0); fbt = malloc(sizeof (fbt_probe_t), M_FBT, M_WAITOK | M_ZERO); @@ -125,7 +147,10 @@ fbt->fbtp_loadcnt = lf->loadcnt; fbt->fbtp_savedval = *instr; fbt->fbtp_patchval = FBT_PATCHVAL; - fbt->fbtp_rval = DTRACE_INVOP_PUSHM; + if ((*instr & SUB_MASK) == SUB_INSTR) + fbt->fbtp_rval = DTRACE_INVOP_SUB; + else + fbt->fbtp_rval = DTRACE_INVOP_STP; fbt->fbtp_symindx = symindx; fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)]; Index: sys/cddl/dev/fbt/riscv/fbt_isa.c =================================================================== --- sys/cddl/dev/fbt/riscv/fbt_isa.c +++ sys/cddl/dev/fbt/riscv/fbt_isa.c @@ -156,6 +156,19 @@ if (fbt_excluded(name)) return (0); + /* + * Some assembly-language exception handlers are not suitable for + * instrumentation. + */ + if (strcmp(name, "cpu_exception_handler") == 0) + return (0); + if (strcmp(name, "cpu_exception_handler_user") == 0) + return (0); + if (strcmp(name, "cpu_exception_handler_supervisor") == 0) + return (0); + if (strcmp(name, "do_trap_supervisor") == 0) + return (0); + instr = (uint32_t *)(symval->value); limit = (uint32_t *)(symval->value + symval->size); Index: sys/compat/freebsd32/freebsd32_ioctl.c =================================================================== --- sys/compat/freebsd32/freebsd32_ioctl.c +++ sys/compat/freebsd32/freebsd32_ioctl.c @@ -212,7 +212,7 @@ cap_rights_t rights; int error; - error = fget(td, uap->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp); if (error != 0) return (error); if ((fp->f_flag & (FREAD | FWRITE)) == 0) { Index: sys/compat/freebsd32/freebsd32_misc.c =================================================================== --- sys/compat/freebsd32/freebsd32_misc.c +++ sys/compat/freebsd32/freebsd32_misc.c @@ -2095,7 +2095,7 @@ AUDIT_ARG_FD(uap->fd); if ((error = fget_read(td, uap->fd, - cap_rights_init(&rights, CAP_PREAD), &fp)) != 0) + cap_rights_init_one(&rights, CAP_PREAD), &fp)) != 0) goto out; error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, Index: sys/compat/linux/linux_event.c =================================================================== --- sys/compat/linux/linux_event.c +++ sys/compat/linux/linux_event.c @@ -421,7 +421,7 @@ } error = fget(td, args->epfd, - cap_rights_init(&rights, CAP_KQUEUE_CHANGE), &epfp); + cap_rights_init_one(&rights, CAP_KQUEUE_CHANGE), &epfp); if (error != 0) return (error); if (epfp->f_type != DTYPE_KQUEUE) { @@ -430,7 +430,8 @@ } /* Protect user data vector from incorrectly supplied fd. */ - error = fget(td, args->fd, cap_rights_init(&rights, CAP_POLL_EVENT), &fp); + error = fget(td, args->fd, + cap_rights_init_one(&rights, CAP_POLL_EVENT), &fp); if (error != 0) goto leave1; @@ -505,7 +506,7 @@ return (EINVAL); error = fget(td, epfd, - cap_rights_init(&rights, CAP_KQUEUE_EVENT), &epfp); + cap_rights_init_one(&rights, CAP_KQUEUE_EVENT), &epfp); if (error != 0) return (error); if (epfp->f_type != DTYPE_KQUEUE) { Index: sys/compat/linux/linux_mib.h =================================================================== --- sys/compat/linux/linux_mib.h +++ sys/compat/linux/linux_mib.h @@ -47,7 +47,7 @@ int linux_kernver(struct thread *td); #define LINUX_KVERSION 3 -#define LINUX_KPATCHLEVEL 10 +#define LINUX_KPATCHLEVEL 17 #define LINUX_KSUBLEVEL 0 #define LINUX_KERNVER(a,b,c) (((a) << 16) + ((b) << 8) + (c)) Index: sys/compat/linux/linux_misc.h =================================================================== --- sys/compat/linux/linux_misc.h +++ sys/compat/linux/linux_misc.h @@ -58,6 +58,7 @@ #define LINUX_PR_GET_NAME 16 /* Get process name. */ #define LINUX_PR_GET_SECCOMP 21 #define LINUX_PR_SET_SECCOMP 22 +#define LINUX_PR_CAPBSET_READ 23 #define LINUX_PR_SET_NO_NEW_PRIVS 38 #define LINUX_PR_SET_PTRACER 1499557217 Index: sys/compat/linux/linux_misc.c =================================================================== --- sys/compat/linux/linux_misc.c +++ sys/compat/linux/linux_misc.c @@ -2041,6 +2041,16 @@ */ error = EINVAL; break; + case LINUX_PR_CAPBSET_READ: +#if 0 + /* + * This makes too much noise with Ubuntu Focal. + */ + linux_msg(td, "unsupported prctl PR_CAPBSET_READ %d", + (int)args->arg2); +#endif + error = EINVAL; + break; case LINUX_PR_SET_NO_NEW_PRIVS: linux_msg(td, "unsupported prctl PR_SET_NO_NEW_PRIVS"); error = EINVAL; Index: sys/compat/linuxkpi/common/include/asm/fpu/api.h =================================================================== --- sys/compat/linuxkpi/common/include/asm/fpu/api.h +++ sys/compat/linuxkpi/common/include/asm/fpu/api.h @@ -1,9 +1,8 @@ /*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Greg V * - * This software was developed by Benno Rice under sponsorship from - * the FreeBSD Foundation. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,11 +11,11 @@ * 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 + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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) @@ -24,13 +23,46 @@ * 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. - * - * $FreeBSD$ */ -#ifndef _EFIFB_H_ -#define _EFIFB_H_ +#ifndef _FPU_API_H_ +#define _FPU_API_H_ + +#if defined(__aarch64__) || defined(__amd64__) || defined(__i386__) + +#include + +extern struct fpu_kern_ctx *__lkpi_fpu_ctx; +extern unsigned int __lkpi_fpu_ctx_level; + +static inline void +kernel_fpu_begin() +{ + if (__lkpi_fpu_ctx_level++ == 0) { + fpu_kern_enter(curthread, __lkpi_fpu_ctx, FPU_KERN_NORMAL); + } +} + +static inline void +kernel_fpu_end() +{ + if (--__lkpi_fpu_ctx_level == 0) { + fpu_kern_leave(curthread, __lkpi_fpu_ctx); + } +} + +#else + +static inline void +kernel_fpu_begin() +{ +} + +static inline void +kernel_fpu_end() +{ +} -int efi_find_framebuffer(struct efi_fb *efifb); +#endif -#endif /* _EFIFB_H_ */ +#endif /* _FPU_API_H_ */ Index: sys/compat/linuxkpi/common/include/linux/pci.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/pci.h +++ sys/compat/linuxkpi/common/include/linux/pci.h @@ -460,6 +460,9 @@ pdev->msi_enabled = false; } +#define pci_free_irq_vectors(pdev) \ + linux_pci_disable_msi(pdev) + unsigned long pci_resource_start(struct pci_dev *pdev, int bar); unsigned long pci_resource_len(struct pci_dev *pdev, int bar); @@ -702,6 +705,23 @@ } } +static inline void +lkpi_pci_save_state(struct pci_dev *pdev) +{ + + pci_save_state(pdev->dev.bsddev); +} + +static inline void +lkpi_pci_restore_state(struct pci_dev *pdev) +{ + + pci_restore_state(pdev->dev.bsddev); +} + +#define pci_save_state(dev) lkpi_pci_save_state(dev) +#define pci_restore_state(dev) lkpi_pci_restore_state(dev) + #define DEFINE_PCI_DEVICE_TABLE(_table) \ const struct pci_device_id _table[] __devinitdata @@ -1058,4 +1078,80 @@ return (0); } +static inline bool +pci_is_root_bus(struct pci_bus *pbus) +{ + + return (pbus->self == NULL); +} + +struct pci_dev *lkpi_pci_get_domain_bus_and_slot(int domain, + unsigned int bus, unsigned int devfn); +#define pci_get_domain_bus_and_slot(domain, bus, devfn) \ + lkpi_pci_get_domain_bus_and_slot(domain, bus, devfn) + +static inline int +pci_domain_nr(struct pci_bus *pbus) +{ + + return (pci_get_domain(pbus->self->dev.bsddev)); +} + +static inline int +pci_bus_read_config(struct pci_bus *bus, unsigned int devfn, + int pos, uint32_t *val, int len) +{ + + *val = pci_read_config(bus->self->dev.bsddev, pos, len); + return (0); +} + +static inline int +pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int pos, u16 *val) +{ + uint32_t tmp; + int ret; + + ret = pci_bus_read_config(bus, devfn, pos, &tmp, 2); + *val = (u16)tmp; + return (ret); +} + +static inline int +pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, u8 *val) +{ + uint32_t tmp; + int ret; + + ret = pci_bus_read_config(bus, devfn, pos, &tmp, 1); + *val = (u8)tmp; + return (ret); +} + +static inline int +pci_bus_write_config(struct pci_bus *bus, unsigned int devfn, int pos, + uint32_t val, int size) +{ + + pci_write_config(bus->self->dev.bsddev, pos, val, size); + return (0); +} + +static inline int +pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int pos, + uint8_t val) +{ + return (pci_bus_write_config(bus, devfn, pos, val, 1)); +} + +static inline int +pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int pos, + uint16_t val) +{ + return (pci_bus_write_config(bus, devfn, pos, val, 2)); +} + +struct pci_dev *lkpi_pci_get_class(unsigned int class, struct pci_dev *from); +#define pci_get_class(class, from) lkpi_pci_get_class(class, from) + #endif /* _LINUX_PCI_H_ */ Index: sys/compat/linuxkpi/common/include/linux/shrinker.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/shrinker.h +++ sys/compat/linuxkpi/common/include/linux/shrinker.h @@ -1,9 +1,6 @@ /*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. + * Copyright (c) 2020 Emmanuel Vadot * - * This software was developed by Benno Rice under sponsorship from - * the FreeBSD Foundation. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -28,9 +25,32 @@ * $FreeBSD$ */ -#ifndef _EFIFB_H_ -#define _EFIFB_H_ +#ifndef __LINUX_SHRINKER_H__ +#define __LINUX_SHRINKER_H__ -int efi_find_framebuffer(struct efi_fb *efifb); +#include -#endif /* _EFIFB_H_ */ +struct shrink_control { + unsigned long nr_to_scan; + unsigned long nr_scanned; +}; + +struct shrinker { + unsigned long (*count_objects)(struct shrinker *, struct shrink_control *); + unsigned long (*scan_objects)(struct shrinker *, struct shrink_control *); + int seeks; + long batch; + TAILQ_ENTRY(shrinker) next; +}; + +#define SHRINK_STOP (~0UL) + +#define DEFAULT_SEEKS 2 + +int linuxkpi_register_shrinker(struct shrinker *s); +void linuxkpi_unregister_shrinker(struct shrinker *s); + +#define register_shrinker(s) linuxkpi_register_shrinker(s) +#define unregister_shrinker(s) linuxkpi_unregister_shrinker(s) + +#endif /* __LINUX_SHRINKER_H__ */ Index: sys/compat/linuxkpi/common/src/linux_fpu.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_fpu.c +++ sys/compat/linuxkpi/common/src/linux_fpu.c @@ -1,9 +1,8 @@ /*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 Greg V * - * This software was developed by Benno Rice under sponsorship from - * the FreeBSD Foundation. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -12,11 +11,11 @@ * 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 + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS 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 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS 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) @@ -24,13 +23,28 @@ * 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. - * - * $FreeBSD$ */ -#ifndef _EFIFB_H_ -#define _EFIFB_H_ +#include +#include +#include +#include + +#include + +struct fpu_kern_ctx *__lkpi_fpu_ctx; +unsigned int __lkpi_fpu_ctx_level = 0; -int efi_find_framebuffer(struct efi_fb *efifb); +static void +linux_fpu_init(void *arg __unused) +{ + __lkpi_fpu_ctx = fpu_kern_alloc_ctx(0); +} +SYSINIT(linux_fpu, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_fpu_init, NULL); -#endif /* _EFIFB_H_ */ +static void +linux_fpu_uninit(void *arg __unused) +{ + fpu_kern_free_ctx(__lkpi_fpu_ctx); +} +SYSUNINIT(linux_fpu, SI_SUB_EVENTHANDLER, SI_ORDER_SECOND, linux_fpu_uninit, NULL); Index: sys/compat/linuxkpi/common/src/linux_pci.c =================================================================== --- sys/compat/linuxkpi/common/src/linux_pci.c +++ sys/compat/linuxkpi/common/src/linux_pci.c @@ -70,6 +70,9 @@ #include "backlight_if.h" #include "pcib_if.h" +/* Undef the linux function macro defined in linux/pci.h */ +#undef pci_get_class + static device_probe_t linux_pci_probe; static device_attach_t linux_pci_attach; static device_detach_t linux_pci_detach; @@ -210,6 +213,67 @@ return (NULL); } +static void +lkpifill_pci_dev(device_t dev, struct pci_dev *pdev) +{ + + pdev->devfn = PCI_DEVFN(pci_get_slot(dev), pci_get_function(dev)); + pdev->vendor = pci_get_vendor(dev); + pdev->device = pci_get_device(dev); + pdev->class = pci_get_class(dev); + pdev->revision = pci_get_revid(dev); + pdev->dev.bsddev = dev; + pdev->bus->self = pdev; + pdev->bus->number = pci_get_bus(dev); + pdev->bus->domain = pci_get_domain(dev); +} + +static struct pci_dev * +lkpinew_pci_dev(device_t dev) +{ + struct pci_dev *pdev; + struct pci_bus *pbus; + + pdev = malloc(sizeof(*pdev), M_DEVBUF, M_WAITOK|M_ZERO); + pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK|M_ZERO); + pdev->bus = pbus; + lkpifill_pci_dev(dev, pdev); + return (pdev); +} + +struct pci_dev * +lkpi_pci_get_class(unsigned int class, struct pci_dev *from) +{ + device_t dev; + device_t devfrom = NULL; + struct pci_dev *pdev; + + if (from != NULL) + devfrom = from->dev.bsddev; + + dev = pci_find_class_from(class >> 16, (class >> 8) & 0xFF, devfrom); + if (dev == NULL) + return (NULL); + + pdev = lkpinew_pci_dev(dev); + return (pdev); +} + +struct pci_dev * +lkpi_pci_get_domain_bus_and_slot(int domain, unsigned int bus, + unsigned int devfn) +{ + device_t dev; + struct pci_dev *pdev; + + dev = pci_find_dbsf(domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + if (dev == NULL) + return (NULL); + + pdev = lkpinew_pci_dev(dev); + return (pdev); +} + static int linux_pci_probe(device_t dev) { @@ -245,7 +309,6 @@ const struct pci_device_id *id, struct pci_dev *pdev) { struct resource_list_entry *rle; - struct pci_bus *pbus; struct pci_devinfo *dinfo; device_t parent; uintptr_t rid; @@ -264,8 +327,9 @@ dinfo = device_get_ivars(dev); } + pdev->bus = malloc(sizeof(*pdev->bus), M_DEVBUF, M_WAITOK | M_ZERO); + lkpifill_pci_dev(dev, pdev); pdev->dev.parent = &linux_root_device; - pdev->dev.bsddev = dev; INIT_LIST_HEAD(&pdev->dev.irqents); if (isdrm) PCI_GET_ID(device_get_parent(parent), parent, PCI_ID_RID, &rid); @@ -276,8 +340,6 @@ pdev->vendor = dinfo->cfg.vendor; pdev->subsystem_vendor = dinfo->cfg.subvendor; pdev->subsystem_device = dinfo->cfg.subdevice; - pdev->class = pci_get_class(dev); - pdev->revision = pci_get_revid(dev); pdev->pdrv = pdrv; kobject_init(&pdev->dev.kobj, &linux_dev_ktype); kobject_set_name(&pdev->dev.kobj, device_get_nameunit(dev)); @@ -294,11 +356,6 @@ goto out_dma_init; TAILQ_INIT(&pdev->mmio); - pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK | M_ZERO); - pbus->self = pdev; - pbus->number = pci_get_bus(dev); - pbus->domain = pci_get_domain(dev); - pdev->bus = pbus; spin_lock(&pci_lock); list_add(&pdev->links, &pci_devices); Index: sys/compat/linuxkpi/common/src/linux_shrinker.c =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/src/linux_shrinker.c @@ -0,0 +1,125 @@ +/*- + * Copyright (c) 2020 Emmanuel Vadot + * + * 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. + * + * $FreeBSD$ + */ + + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +TAILQ_HEAD(, shrinker) lkpi_shrinkers = TAILQ_HEAD_INITIALIZER(lkpi_shrinkers); +static struct mtx mtx_shrinker; + +int +linuxkpi_register_shrinker(struct shrinker *s) +{ + + KASSERT(s != NULL, ("NULL shrinker")); + KASSERT(s->count_objects != NULL, ("NULL shrinker")); + KASSERT(s->scan_objects != NULL, ("NULL shrinker")); + mtx_lock(&mtx_shrinker); + TAILQ_INSERT_TAIL(&lkpi_shrinkers, s, next); + mtx_unlock(&mtx_shrinker); + return (0); +} + +void +linuxkpi_unregister_shrinker(struct shrinker *s) +{ + + mtx_lock(&mtx_shrinker); + TAILQ_REMOVE(&lkpi_shrinkers, s, next); + mtx_unlock(&mtx_shrinker); +} + +#define SHRINKER_BATCH 512 + +static void +shrinker_shrink(struct shrinker *s) +{ + struct shrink_control sc; + unsigned long can_free; + unsigned long batch; + unsigned long freeed = 0; + unsigned long ret; + + can_free = s->count_objects(s, &sc); + if (can_free <= 0) + return; + + batch = s->batch ? s->batch : SHRINKER_BATCH; + while (freeed <= can_free) { + sc.nr_to_scan = batch; + ret = s->scan_objects(s, &sc); + if (ret == SHRINK_STOP) + break; + freeed += ret; + } +} + +static void +linuxkpi_vm_lowmem(void *arg __unused) +{ + struct shrinker *s; + + mtx_lock(&mtx_shrinker); + TAILQ_FOREACH(s, &lkpi_shrinkers, next) { + shrinker_shrink(s); + } + mtx_unlock(&mtx_shrinker); +} + +static eventhandler_tag lowmem_tag; + +static void +linuxkpi_sysinit_shrinker(void *arg __unused) +{ + + mtx_init(&mtx_shrinker, "lkpi-shrinker", NULL, MTX_DEF); + lowmem_tag = EVENTHANDLER_REGISTER(vm_lowmem, linuxkpi_vm_lowmem, + NULL, EVENTHANDLER_PRI_FIRST); +} + +static void +linuxkpi_sysuninit_shrinker(void *arg __unused) +{ + + mtx_destroy(&mtx_shrinker); + EVENTHANDLER_DEREGISTER(vm_lowmem, lowmem_tag); +} + +SYSINIT(linuxkpi_shrinker, SI_SUB_DRIVERS, SI_ORDER_ANY, + linuxkpi_sysinit_shrinker, NULL); +SYSUNINIT(linuxkpi_shrinker, SI_SUB_DRIVERS, SI_ORDER_ANY, + linuxkpi_sysuninit_shrinker, NULL); Index: sys/conf/Makefile.arm64 =================================================================== --- sys/conf/Makefile.arm64 +++ sys/conf/Makefile.arm64 @@ -45,7 +45,7 @@ KERNEL_EXTRA+= ${KERNEL_KO}.bin KERNEL_EXTRA_INSTALL+= ${KERNEL_KO}.bin -.if !empty(DDB_ENABLED) +.if !empty(DDB_ENABLED) || !empty(DTR_ENABLED) || !empty(HWPMC_ENABLED) CFLAGS += -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer .endif Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -4576,6 +4576,8 @@ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_shmemfs.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" +compat/linuxkpi/common/src/linux_shrinker.c optional compat_linuxkpi \ + compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_slab.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_usb.c optional compat_linuxkpi usb \ Index: sys/conf/files.amd64 =================================================================== --- sys/conf/files.amd64 +++ sys/conf/files.amd64 @@ -462,6 +462,9 @@ x86/xen/pvcpu_enum.c optional xenhvm x86/xen/xen_pci_bus.c optional xenhvm +compat/linuxkpi/common/src/linux_fpu.c optional compat_linuxkpi \ + compile-with "${LINUXKPI_C}" + contrib/openzfs/module/zcommon/zfs_fletcher_avx512.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher_intel.c optional zfs compile-with "${ZFS_C}" contrib/openzfs/module/zcommon/zfs_fletcher_sse.c optional zfs compile-with "${ZFS_C}" Index: sys/conf/files.arm64 =================================================================== --- sys/conf/files.arm64 +++ sys/conf/files.arm64 @@ -494,3 +494,6 @@ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "tegra210_xusb.fw" + +compat/linuxkpi/common/src/linux_fpu.c optional compat_linuxkpi \ + compile-with "${LINUXKPI_C}" Index: sys/conf/files.i386 =================================================================== --- sys/conf/files.i386 +++ sys/conf/files.i386 @@ -241,3 +241,6 @@ x86/x86/mptable.c optional apic x86/x86/mptable_pci.c optional apic pci x86/x86/msi.c optional apic pci + +compat/linuxkpi/common/src/linux_fpu.c optional compat_linuxkpi \ + compile-with "${LINUXKPI_C}" Index: sys/conf/kmod.mk =================================================================== --- sys/conf/kmod.mk +++ sys/conf/kmod.mk @@ -146,7 +146,7 @@ .endif CFLAGS+= ${DEBUG_FLAGS} -.if ${MACHINE_CPUARCH} == amd64 +.if ${MACHINE_CPUARCH} == aarch64 || ${MACHINE_CPUARCH} == amd64 CFLAGS+= -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer .endif Index: sys/dev/aac/aac_linux.c =================================================================== --- sys/dev/aac/aac_linux.c +++ sys/dev/aac/aac_linux.c @@ -82,7 +82,8 @@ u_long cmd; int error; - error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(td, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), + &fp); if (error != 0) return (error); cmd = args->cmd; Index: sys/dev/aacraid/aacraid_linux.c =================================================================== --- sys/dev/aacraid/aacraid_linux.c +++ sys/dev/aacraid/aacraid_linux.c @@ -85,7 +85,7 @@ int error; if ((error = fget(td, args->fd, - cap_rights_init(&rights, CAP_IOCTL), + cap_rights_init_one(&rights, CAP_IOCTL), &fp)) != 0) { return (error); } Index: sys/dev/amr/amr_linux.c =================================================================== --- sys/dev/amr/amr_linux.c +++ sys/dev/amr/amr_linux.c @@ -78,7 +78,7 @@ struct file *fp; int error; - error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(p, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp); if (error != 0) return (error); error = fo_ioctl(fp, args->cmd, (caddr_t)args->arg, p->td_ucred, p); Index: sys/dev/cxgbe/cxgbei/icl_cxgbei.c =================================================================== --- sys/dev/cxgbe/cxgbei/icl_cxgbei.c +++ sys/dev/cxgbe/cxgbei/icl_cxgbei.c @@ -624,7 +624,7 @@ * Steal the socket from userland. */ error = fget(curthread, fd, - cap_rights_init(&rights, CAP_SOCK_CLIENT), &fp); + cap_rights_init_one(&rights, CAP_SOCK_CLIENT), &fp); if (error != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { Index: sys/dev/dwwdt/dwwdt.c =================================================================== --- /dev/null +++ sys/dev/dwwdt/dwwdt.c @@ -0,0 +1,366 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2020 BusyTech + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +/* Registers */ +#define DWWDT_CR 0x00 +#define DWWDT_CR_WDT_EN (1 << 0) +#define DWWDT_CR_RESP_MODE (1 << 1) +#define DWWDT_TORR 0x04 +#define DWWDT_CCVR 0x08 +#define DWWDT_CRR 0x0C +#define DWWDT_CRR_KICK 0x76 +#define DWWDT_STAT 0x10 +#define DWWDT_STAT_STATUS 0x01 +#define DWWDT_EOI 0x14 + +#define DWWDT_READ4(sc, reg) bus_read_4((sc)->sc_mem_res, (reg)) +#define DWWDT_WRITE4(sc, reg, val) \ + bus_write_4((sc)->sc_mem_res, (reg), (val)) + +/* + * 47 = 16 (timeout shift of dwwdt) + 30 (1s ~= 2 ** 30ns) + 1 + * (pre-restart delay) + */ +#define DWWDT_EXP_OFFSET 47 + +struct dwwdt_softc { + device_t sc_dev; + struct resource *sc_mem_res; + struct resource *sc_irq_res; + void *sc_intr_cookie; + clk_t sc_clk; + uint64_t sc_clk_freq; + eventhandler_tag sc_evtag; + int sc_mem_rid; + int sc_irq_rid; + enum { + DWWDT_STOPPED, + DWWDT_RUNNING, + } sc_status; +}; + +static devclass_t dwwdt_devclass; + +static struct ofw_compat_data compat_data[] = { + { "snps,dw-wdt", 1 }, + { NULL, 0 } +}; + +SYSCTL_NODE(_dev, OID_AUTO, dwwdt, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, + "Synopsys Designware watchdog timer"); +/* Setting this to 0 enables full restart mode. */ +static uint32_t dwwdt_prevent_restart = 1; +SYSCTL_UINT(_dev_dwwdt, OID_AUTO, prevent_restart, CTLFLAG_RW | CTLFLAG_MPSAFE, + &dwwdt_prevent_restart, 1, + "Prevent system restart (0 - Disabled; 1 - Enabled)"); + +static uint32_t dwwdt_debug_enabled = 0; +SYSCTL_UINT(_dev_dwwdt, OID_AUTO, debug, CTLFLAG_RW | CTLFLAG_MPSAFE, + &dwwdt_debug_enabled, 1, "Debug mode (0 - Disabled; 1 - Enabled)"); + +static int dwwdt_probe(device_t); +static int dwwdt_attach(device_t); +static int dwwdt_detach(device_t); +static int dwwdt_shutdown(device_t); + +static void dwwdt_intr(void *); +static void dwwdt_event(void *, unsigned int, int *); + +/* Helpers */ +static inline void dwwdt_start(struct dwwdt_softc *sc); +static inline bool dwwdt_started(const struct dwwdt_softc *sc); +static inline void dwwdt_stop(struct dwwdt_softc *sc); +static inline void dwwdt_set_timeout(const struct dwwdt_softc *sc, int val); + +static void dwwdt_debug(device_t); + +static void +dwwdt_debug(device_t dev) +{ + /* + * Reading from EOI may clear interrupt flag. + */ + const struct dwwdt_softc *sc = device_get_softc(dev); + + device_printf(dev, "Registers dump: \n"); + device_printf(dev, " CR: %08x\n", DWWDT_READ4(sc, DWWDT_CR)); + device_printf(dev, " CCVR: %08x\n", DWWDT_READ4(sc, DWWDT_CCVR)); + device_printf(dev, " CRR: %08x\n", DWWDT_READ4(sc, DWWDT_CRR)); + device_printf(dev, " STAT: %08x\n", DWWDT_READ4(sc, DWWDT_STAT)); + + device_printf(dev, "Clock: %s\n", clk_get_name(sc->sc_clk)); + device_printf(dev, " FREQ: %lu\n", sc->sc_clk_freq); +} + +static inline bool +dwwdt_started(const struct dwwdt_softc *sc) +{ + + /* CR_WDT_E bit can be clear only by full CPU reset. */ + return ((DWWDT_READ4(sc, DWWDT_CR) & DWWDT_CR_WDT_EN) != 0); +} + +static void inline +dwwdt_start(struct dwwdt_softc *sc) +{ + uint32_t val; + + /* Enable watchdog */ + val = DWWDT_READ4(sc, DWWDT_CR); + val |= DWWDT_CR_WDT_EN | DWWDT_CR_RESP_MODE; + DWWDT_WRITE4(sc, DWWDT_CR, val); + sc->sc_status = DWWDT_RUNNING; +} + +static void inline +dwwdt_stop(struct dwwdt_softc *sc) +{ + + sc->sc_status = DWWDT_STOPPED; + dwwdt_set_timeout(sc, 0x0f); +} + +static void inline +dwwdt_set_timeout(const struct dwwdt_softc *sc, int val) +{ + + DWWDT_WRITE4(sc, DWWDT_TORR, val); + DWWDT_WRITE4(sc, DWWDT_CRR, DWWDT_CRR_KICK); +} + +static void +dwwdt_intr(void *arg) +{ + struct dwwdt_softc *sc = arg; + + KASSERT((DWWDT_READ4(sc, DWWDT_STAT) & DWWDT_STAT_STATUS) != 0, + ("Missing interrupt status bit?")); + + if (dwwdt_prevent_restart != 0 || sc->sc_status == DWWDT_STOPPED) { + /* + * Confirm interrupt reception. Restart counter. + * This also emulates stopping watchdog. + */ + (void)DWWDT_READ4(sc, DWWDT_EOI); + } +} + +static void +dwwdt_event(void *arg, unsigned int cmd, int *error) +{ + struct dwwdt_softc *sc = arg; + const int exponent = flsl(sc->sc_clk_freq); + int timeout; + int val; + + timeout = cmd & WD_INTERVAL; + val = MAX(0, timeout + exponent - DWWDT_EXP_OFFSET); + + dwwdt_stop(sc); + if (cmd == 0 || val > 0x0f) { + /* + * Set maximum time between interrupts and Leave watchdog + * disabled. + */ + return; + } + + dwwdt_set_timeout(sc, val); + dwwdt_start(sc); + *error = 0; + + if (dwwdt_debug_enabled) + dwwdt_debug(sc->sc_dev); +} + +static int +dwwdt_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (!ofw_bus_search_compatible(dev, compat_data)->ocd_data) + return (ENXIO); + + device_set_desc(dev, "Synopsys Designware watchdog timer"); + return (BUS_PROBE_DEFAULT); +} + +static int +dwwdt_attach(device_t dev) +{ + struct dwwdt_softc *sc; + + sc = device_get_softc(dev); + sc->sc_dev = dev; + + sc->sc_mem_rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, + &sc->sc_mem_rid, RF_ACTIVE); + if (sc->sc_mem_res == NULL) { + device_printf(dev, "cannot allocate memory resource\n"); + goto err_no_mem; + } + + sc->sc_irq_rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + &sc->sc_irq_rid, RF_ACTIVE); + if (sc->sc_irq_res == NULL) { + device_printf(dev, "cannot allocate ireq resource\n"); + goto err_no_irq; + } + + sc->sc_intr_cookie = NULL; + if (bus_setup_intr(dev, sc->sc_irq_res, INTR_MPSAFE | INTR_TYPE_MISC, + NULL, dwwdt_intr, sc, &sc->sc_intr_cookie) != 0) { + device_printf(dev, "cannot setup interrupt routine\n"); + goto err_no_intr; + } + + if (clk_get_by_ofw_index(dev, 0, 0, &sc->sc_clk) != 0) { + device_printf(dev, "cannot find clock\n"); + goto err_no_clock; + } + + if (clk_enable(sc->sc_clk) != 0) { + device_printf(dev, "cannot enable clock\n"); + goto err_no_freq; + } + + if (clk_get_freq(sc->sc_clk, &sc->sc_clk_freq) != 0) { + device_printf(dev, "cannot get clock frequency\n"); + goto err_no_freq; + } + + if (sc->sc_clk_freq == 0UL) + goto err_no_freq; + + sc->sc_evtag = EVENTHANDLER_REGISTER(watchdog_list, dwwdt_event, sc, 0); + sc->sc_status = DWWDT_STOPPED; + + return (bus_generic_attach(dev)); + +err_no_freq: + clk_release(sc->sc_clk); +err_no_clock: + bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_cookie); +err_no_intr: + bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid, sc->sc_irq_res); +err_no_irq: + bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, + sc->sc_mem_res); +err_no_mem: + return (ENXIO); +} + +static int +dwwdt_detach(device_t dev) +{ + struct dwwdt_softc *sc = device_get_softc(dev); + + if (dwwdt_started(sc)) { + /* + * Once started it cannot be stopped. Prevent module unload + * instead. + */ + return (EBUSY); + } + + EVENTHANDLER_DEREGISTER(watchdog_list, sc->sc_evtag); + sc->sc_evtag = NULL; + + if (sc->sc_clk != NULL) + clk_release(sc->sc_clk); + + if (sc->sc_intr_cookie != NULL) + bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intr_cookie); + + if (sc->sc_irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid, + sc->sc_irq_res); + } + + if (sc->sc_mem_res) { + bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid, + sc->sc_mem_res); + } + + return (bus_generic_detach(dev)); +} + +static int +dwwdt_shutdown(device_t dev) +{ + struct dwwdt_softc *sc; + + sc = device_get_softc(dev); + + /* Prevent restarts during shutdown. */ + dwwdt_prevent_restart = 1; + dwwdt_stop(sc); + return (bus_generic_shutdown(dev)); +} + +static device_method_t dwwdt_methods[] = { + DEVMETHOD(device_probe, dwwdt_probe), + DEVMETHOD(device_attach, dwwdt_attach), + DEVMETHOD(device_detach, dwwdt_detach), + DEVMETHOD(device_shutdown, dwwdt_shutdown), + + {0, 0} +}; + +static driver_t dwwdt_driver = { + "dwwdt", + dwwdt_methods, + sizeof(struct dwwdt_softc), +}; + +DRIVER_MODULE(dwwdt, simplebus, dwwdt_driver, dwwdt_devclass, NULL, NULL); +MODULE_VERSION(dwwdt, 1); +OFWBUS_PNP_INFO(compat_data); Index: sys/dev/filemon/filemon_wrapper.c =================================================================== --- sys/dev/filemon/filemon_wrapper.c +++ sys/dev/filemon/filemon_wrapper.c @@ -185,7 +185,7 @@ * than nothing. */ if (getvnode(td, fd, - cap_rights_init(&rights, CAP_LOOKUP), &fp) == 0) { + cap_rights_init_one(&rights, CAP_LOOKUP), &fp) == 0) { vn_fullpath(fp->f_vnode, &atpath, &freepath); } } Index: sys/dev/gpio/gpioc.c =================================================================== --- sys/dev/gpio/gpioc.c +++ sys/dev/gpio/gpioc.c @@ -582,7 +582,7 @@ return (err); sc->sc_pin_intr = malloc(sizeof(struct gpioc_pin_intr) * sc->sc_npins, M_GPIOC, M_WAITOK | M_ZERO); - for (int i = 0; i <= sc->sc_npins; i++) { + for (int i = 0; i < sc->sc_npins; i++) { sc->sc_pin_intr[i].pin = malloc(sizeof(struct gpiobus_pin), M_GPIOC, M_WAITOK | M_ZERO); sc->sc_pin_intr[i].sc = sc; @@ -616,7 +616,7 @@ if (sc->sc_ctl_dev) destroy_dev(sc->sc_ctl_dev); - for (int i = 0; i <= sc->sc_npins; i++) { + for (int i = 0; i < sc->sc_npins; i++) { mtx_destroy(&sc->sc_pin_intr[i].mtx); free(&sc->sc_pin_intr[i].pin, M_GPIOC); } Index: sys/dev/if_wg/module/module.c =================================================================== --- sys/dev/if_wg/module/module.c +++ sys/dev/if_wg/module/module.c @@ -843,5 +843,8 @@ DECLARE_MODULE(wg, wg_moduledata, SI_SUB_PSEUDO, SI_ORDER_ANY); MODULE_VERSION(wg, 1); MODULE_DEPEND(wg, iflib, 1, 1, 1); +#if defined(__amd64__) || defined(__i386__) +/* Optimized blake2 implementations are only available on x86. */ MODULE_DEPEND(wg, blake2, 1, 1, 1); +#endif MODULE_DEPEND(wg, crypto, 1, 1, 1); Index: sys/dev/ipmi/ipmi_linux.c =================================================================== --- sys/dev/ipmi/ipmi_linux.c +++ sys/dev/ipmi/ipmi_linux.c @@ -96,7 +96,8 @@ u_long cmd; int error; - error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(td, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), + &fp); if (error != 0) return (error); cmd = args->cmd; Index: sys/dev/iscsi/icl_soft.c =================================================================== --- sys/dev/iscsi/icl_soft.c +++ sys/dev/iscsi/icl_soft.c @@ -1397,7 +1397,7 @@ * Steal the socket from userland. */ error = fget(curthread, fd, - cap_rights_init(&rights, CAP_SOCK_CLIENT), &fp); + cap_rights_init_one(&rights, CAP_SOCK_CLIENT), &fp); if (error != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { Index: sys/dev/iscsi_initiator/iscsi.c =================================================================== --- sys/dev/iscsi_initiator/iscsi.c +++ sys/dev/iscsi_initiator/iscsi.c @@ -392,8 +392,8 @@ if(sp->soc != NULL) isc_stop_receiver(sp); - error = getsock_cap(td, fd, cap_rights_init(&rights, CAP_SOCK_CLIENT), - &sp->fp, NULL, NULL); + error = getsock_cap(td, fd, cap_rights_init_one(&rights, CAP_SOCK_CLIENT), + &sp->fp, NULL, NULL); if(error) return error; Index: sys/dev/mfi/mfi_linux.c =================================================================== --- sys/dev/mfi/mfi_linux.c +++ sys/dev/mfi/mfi_linux.c @@ -100,7 +100,7 @@ break; } - error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(p, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp); if (error != 0) return (error); error = fo_ioctl(fp, cmd, (caddr_t)args->arg, p->td_ucred, p); Index: sys/dev/mlx4/mlx4_core/mlx4_main.c =================================================================== --- sys/dev/mlx4/mlx4_core/mlx4_main.c +++ sys/dev/mlx4/mlx4_core/mlx4_main.c @@ -3781,7 +3781,7 @@ return ret; } else { device_set_desc(pdev->dev.bsddev, mlx4_description); - pci_save_state(pdev->dev.bsddev); + pci_save_state(pdev); } snprintf(dev->fw_str, sizeof(dev->fw_str), "%d.%d.%d", Index: sys/dev/mlx5/mlx5_core/mlx5_main.c =================================================================== --- sys/dev/mlx5/mlx5_core/mlx5_main.c +++ sys/dev/mlx5/mlx5_core/mlx5_main.c @@ -1634,7 +1634,7 @@ } #endif - pci_save_state(bsddev); + pci_save_state(pdev); return 0; clean_health: @@ -1709,8 +1709,8 @@ } pci_set_master(pdev); pci_set_powerstate(pdev->dev.bsddev, PCI_POWERSTATE_D0); - pci_restore_state(pdev->dev.bsddev); - pci_save_state(pdev->dev.bsddev); + pci_restore_state(pdev); + pci_save_state(pdev); return err ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED; } Index: sys/dev/mrsas/mrsas_linux.c =================================================================== --- sys/dev/mrsas/mrsas_linux.c +++ sys/dev/mrsas/mrsas_linux.c @@ -121,7 +121,7 @@ goto END; } #if (__FreeBSD_version >= 1000000) - error = fget(p, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(p, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp); #elif (__FreeBSD_version <= 900000) error = fget(p, args->fd, &fp); #else /* For FreeBSD version greater than Index: sys/dev/pci/pci.c =================================================================== --- sys/dev/pci/pci.c +++ sys/dev/pci/pci.c @@ -493,6 +493,28 @@ return (NULL); } +device_t +pci_find_class_from(uint8_t class, uint8_t subclass, device_t from) +{ + struct pci_devinfo *dinfo; + bool found = false; + + STAILQ_FOREACH(dinfo, &pci_devq, pci_links) { + if (from != NULL && found == false) { + if (from != dinfo->cfg.dev) + continue; + found = true; + continue; + } + if (dinfo->cfg.baseclass == class && + dinfo->cfg.subclass == subclass) { + return (dinfo->cfg.dev); + } + } + + return (NULL); +} + static int pci_printf(pcicfgregs *cfg, const char *fmt, ...) { Index: sys/dev/pci/pcivar.h =================================================================== --- sys/dev/pci/pcivar.h +++ sys/dev/pci/pcivar.h @@ -666,6 +666,7 @@ device_t pci_find_dbsf(uint32_t, uint8_t, uint8_t, uint8_t); device_t pci_find_device(uint16_t, uint16_t); device_t pci_find_class(uint8_t class, uint8_t subclass); +device_t pci_find_class_from(uint8_t class, uint8_t subclass, device_t devfrom); /* Can be used by drivers to manage the MSI-X table. */ int pci_pending_msix(device_t dev, u_int index); Index: sys/dev/tdfx/tdfx_linux.c =================================================================== --- sys/dev/tdfx/tdfx_linux.c +++ sys/dev/tdfx/tdfx_linux.c @@ -57,7 +57,7 @@ struct file *fp; - error = fget(td, args->fd, cap_rights_init(&rights, CAP_IOCTL), &fp); + error = fget(td, args->fd, cap_rights_init_one(&rights, CAP_IOCTL), &fp); if (error != 0) return (error); /* We simply copy the data and send it right to ioctl */ Index: sys/dev/usb/net/if_ure.c =================================================================== --- sys/dev/usb/net/if_ure.c +++ sys/dev/usb/net/if_ure.c @@ -581,13 +581,6 @@ goto detach; } - /* Mark all TX transfers as available */ - for (int i = 0; i < URE_N_TRANSFER; i++) { - sc->sc_txavail[i] = sc->sc_tx_xfer[i]; - DEVPRINTF(dev, "sc_txavail[%d] = %p\n", i, sc->sc_txavail[i]); - } - sc->sc_txpos = 0; - ue->ue_sc = sc; ue->ue_dev = dev; ue->ue_udev = uaa->device; @@ -870,16 +863,6 @@ usbd_transfer_submit(xfer); - KASSERT(sc->sc_txpos >= 0 && sc->sc_txpos <= URE_N_TRANSFER, - ("sc_txpos invalid: %d", sc->sc_txpos)); - if (sc->sc_txpos < URE_N_TRANSFER && - !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { - xfer = sc->sc_txavail[sc->sc_txpos++]; - usbd_transfer_start(xfer); - } - - if (sc->sc_txpos == URE_N_TRANSFER) - ifp->if_drv_flags |= IFF_DRV_OACTIVE; return; default: /* Error */ @@ -900,11 +883,6 @@ goto tr_setup; } } - - KASSERT(sc->sc_txpos > 0 && sc->sc_txpos <= URE_N_TRANSFER, ("sc_txpos invalid: %d", sc->sc_txpos)); - sc->sc_txavail[(--(sc->sc_txpos))] = xfer; - if (sc->sc_txpos < URE_N_TRANSFER) - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } static void @@ -1110,10 +1088,7 @@ URE_LOCK_ASSERT(sc, MA_OWNED); - KASSERT(sc->sc_txpos >= 0 && sc->sc_txpos <= URE_N_TRANSFER, ("sc_txpos invalid: %d", sc->sc_txpos)); (void)ifp; - DEVPRINTFN(13, sc->sc_ue.ue_dev, - "sc_txpos: %d, oactive: %d\n", sc->sc_txpos, !!(ifp->if_drv_flags & IFF_DRV_OACTIVE)); for (int i = 0; i < URE_N_TRANSFER; i++) DEVPRINTFN(13, sc->sc_ue.ue_dev, "rx[%d] = %d\n", i, USB_GET_STATE(sc->sc_rx_xfer[i])); @@ -1190,34 +1165,18 @@ ure_start(struct usb_ether *ue) { struct ure_softc *sc = uether_getsc(ue); - struct usb_xfer *xfer; - struct ifnet *ifp; + unsigned i; URE_LOCK_ASSERT(sc, MA_OWNED); if (!sc->sc_rxstarted) { sc->sc_rxstarted = 1; - for (int i = 0; i < URE_N_TRANSFER; i++) + for (i = 0; i != URE_N_TRANSFER; i++) usbd_transfer_start(sc->sc_rx_xfer[i]); } - /* - * start the USB transfers, if not already started: - */ - if (sc->sc_txpos == URE_N_TRANSFER) { - ifp = uether_getifp(&sc->sc_ue); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - return; - } - - KASSERT(sc->sc_txpos >= 0 && sc->sc_txpos < URE_N_TRANSFER, ("sc_txpos invalid: %d", sc->sc_txpos)); - xfer = sc->sc_txavail[sc->sc_txpos++]; - if (sc->sc_txpos == URE_N_TRANSFER) { - ifp = uether_getifp(&sc->sc_ue); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - } - usbd_transfer_start(xfer); + for (i = 0; i != URE_N_TRANSFER; i++) + usbd_transfer_start(sc->sc_tx_xfer[i]); } static void Index: sys/dev/usb/net/if_urereg.h =================================================================== --- sys/dev/usb/net/if_urereg.h +++ sys/dev/usb/net/if_urereg.h @@ -445,15 +445,6 @@ int sc_rxstarted; - struct usb_xfer *sc_txavail[URE_N_TRANSFER]; - /* - * Position of next available xfer for TX. If - * sc_txpos == URE_N_TRANSFER, no tx xfer's are available. - * Pop xfer: sc->sc_txavail[sc->sc_txpos++] - * Push xfer: sc->sc_txavail[(--(sc->sc_txpos))] = xfer - */ - int sc_txpos; - int sc_phyno; u_int sc_flags; Index: sys/fs/fdescfs/fdesc_vnops.c =================================================================== --- sys/fs/fdescfs/fdesc_vnops.c +++ sys/fs/fdescfs/fdesc_vnops.c @@ -496,7 +496,7 @@ * Allow setattr where there is an underlying vnode. */ error = getvnode(td, fd, - cap_rights_init(&rights, CAP_EXTATTR_SET), &fp); + cap_rights_init_one(&rights, CAP_EXTATTR_SET), &fp); if (error) { /* * getvnode() returns EINVAL if the file descriptor is not Index: sys/fs/nfsclient/nfs_clport.c =================================================================== --- sys/fs/nfsclient/nfs_clport.c +++ sys/fs/nfsclient/nfs_clport.c @@ -1247,7 +1247,7 @@ * careful than too reckless. */ error = fget(td, nfscbdarg.sock, - cap_rights_init(&rights, CAP_SOCK_CLIENT), &fp); + cap_rights_init_one(&rights, CAP_SOCK_CLIENT), &fp); if (error) return (error); if (fp->f_type != DTYPE_SOCKET) { Index: sys/fs/nfsserver/nfs_nfsdport.c =================================================================== --- sys/fs/nfsserver/nfs_nfsdport.c +++ sys/fs/nfsserver/nfs_nfsdport.c @@ -3609,7 +3609,7 @@ * careful than too reckless. */ error = fget(td, sockarg.sock, - cap_rights_init(&rights, CAP_SOCK_SERVER), &fp); + cap_rights_init_one(&rights, CAP_SOCK_SERVER), &fp); if (error != 0) goto out; if (fp->f_type != DTYPE_SOCKET) { Index: sys/i386/linux/imgact_linux.c =================================================================== --- sys/i386/linux/imgact_linux.c +++ sys/i386/linux/imgact_linux.c @@ -158,7 +158,8 @@ * remove write enable on the 'text' part */ error = vm_map_protect(&vmspace->vm_map, vmaddr, - vmaddr + a_out->a_text, VM_PROT_EXECUTE|VM_PROT_READ, TRUE); + vmaddr + a_out->a_text, 0, VM_PROT_EXECUTE | VM_PROT_READ, + VM_MAP_PROTECT_SET_MAXPROT); if (error) goto fail; } else { @@ -185,7 +186,8 @@ * allow read/write of data */ error = vm_map_protect(&vmspace->vm_map, vmaddr + a_out->a_text, - vmaddr + a_out->a_text + a_out->a_data, VM_PROT_ALL, FALSE); + vmaddr + a_out->a_text + a_out->a_data, VM_PROT_ALL, 0, + VM_MAP_PROTECT_SET_PROT); if (error) goto fail; Index: sys/kern/imgact_elf.c =================================================================== --- sys/kern/imgact_elf.c +++ sys/kern/imgact_elf.c @@ -692,7 +692,7 @@ */ if ((prot & VM_PROT_WRITE) == 0) vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + - map_len), prot, FALSE); + map_len), prot, 0, VM_MAP_PROTECT_SET_PROT); return (0); } Index: sys/kern/kern_descrip.c =================================================================== --- sys/kern/kern_descrip.c +++ sys/kern/kern_descrip.c @@ -1979,13 +1979,14 @@ MPASS(resultfp != NULL); MPASS(resultfd != NULL); - error = falloc_noinstall(td, &fp); - if (error) - return (error); /* no reference held on error */ + error = _falloc_noinstall(td, &fp, 2); + if (__predict_false(error != 0)) { + return (error); + } - error = finstall(td, fp, &fd, flags, fcaps); - if (error) { - fdrop(fp, td); /* one reference (fp only) */ + error = finstall_refed(td, fp, &fd, flags, fcaps); + if (__predict_false(error != 0)) { + falloc_abort(td, fp); return (error); } @@ -1999,7 +2000,7 @@ * Create a new open file structure without allocating a file descriptor. */ int -falloc_noinstall(struct thread *td, struct file **resultfp) +_falloc_noinstall(struct thread *td, struct file **resultfp, u_int n) { struct file *fp; int maxuserfiles = maxfiles - (maxfiles / 20); @@ -2008,6 +2009,7 @@ static int curfail; KASSERT(resultfp != NULL, ("%s: resultfp == NULL", __func__)); + MPASS(n > 0); openfiles_new = atomic_fetchadd_int(&openfiles, 1) + 1; if ((openfiles_new >= maxuserfiles && @@ -2022,13 +2024,24 @@ } fp = uma_zalloc(file_zone, M_WAITOK); bzero(fp, sizeof(*fp)); - refcount_init(&fp->f_count, 1); + refcount_init(&fp->f_count, n); fp->f_cred = crhold(td->td_ucred); fp->f_ops = &badfileops; *resultfp = fp; return (0); } +void +falloc_abort(struct thread *td, struct file *fp) +{ + + /* + * For assertion purposes. + */ + refcount_init(&fp->f_count, 0); + _fdrop(fp, td); +} + /* * Install a file in a file descriptor table. */ @@ -2059,7 +2072,7 @@ } int -finstall(struct thread *td, struct file *fp, int *fd, int flags, +finstall_refed(struct thread *td, struct file *fp, int *fd, int flags, struct filecaps *fcaps) { struct filedesc *fdp = td->td_proc->p_fd; @@ -2067,18 +2080,30 @@ MPASS(fd != NULL); - if (!fhold(fp)) - return (EBADF); FILEDESC_XLOCK(fdp); error = fdalloc(td, 0, fd); + if (__predict_true(error == 0)) { + _finstall(fdp, fp, *fd, flags, fcaps); + } + FILEDESC_XUNLOCK(fdp); + return (error); +} + +int +finstall(struct thread *td, struct file *fp, int *fd, int flags, + struct filecaps *fcaps) +{ + int error; + + MPASS(fd != NULL); + + if (!fhold(fp)) + return (EBADF); + error = finstall_refed(td, fp, fd, flags, fcaps); if (__predict_false(error != 0)) { - FILEDESC_XUNLOCK(fdp); fdrop(fp, td); - return (error); } - _finstall(fdp, fp, *fd, flags, fcaps); - FILEDESC_XUNLOCK(fdp); - return (0); + return (error); } /* @@ -2737,6 +2762,8 @@ struct filedesc_to_leader *fdtol; struct filedesc *fdp; + MPASS(td != NULL); + /* * POSIX record locking dictates that any close releases ALL * locks owned by this process. This is handled by setting @@ -2749,7 +2776,7 @@ * context that might have locks, or the locks will be * leaked. */ - if (fp->f_type == DTYPE_VNODE && td != NULL) { + if (fp->f_type == DTYPE_VNODE) { vp = fp->f_vnode; if ((td->td_proc->p_leader->p_flag & P_ADVLOCK) != 0) { lf.l_whence = SEEK_SET; @@ -2797,6 +2824,16 @@ return (fdrop_close(fp, td)); } +/* + * Hack for file descriptor passing code. + */ +void +closef_nothread(struct file *fp) +{ + + fdrop(fp, NULL); +} + /* * Initialize the file pointer with the specified properties. * Index: sys/kern/kern_event.c =================================================================== --- sys/kern/kern_event.c +++ sys/kern/kern_event.c @@ -2714,7 +2714,8 @@ cap_rights_t rights; int error; - error = fget(td, fd, cap_rights_init(&rights, CAP_KQUEUE_CHANGE), &fp); + error = fget(td, fd, cap_rights_init_one(&rights, CAP_KQUEUE_CHANGE), + &fp); if (error != 0) return (error); if ((error = kqueue_acquire(fp, &kq)) != 0) Index: sys/kern/kern_resource.c =================================================================== --- sys/kern/kern_resource.c +++ sys/kern/kern_resource.c @@ -770,7 +770,8 @@ addr = trunc_page(addr); size = round_page(size); (void)vm_map_protect(&p->p_vmspace->vm_map, - addr, addr + size, prot, FALSE); + addr, addr + size, prot, 0, + VM_MAP_PROTECT_SET_PROT); } } Index: sys/kern/kern_sig.c =================================================================== --- sys/kern/kern_sig.c +++ sys/kern/kern_sig.c @@ -4213,7 +4213,7 @@ int res; uint32_t oldval; - if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) + if ((td->td_pflags & TDP_SIGFASTPENDING) == 0) return; res = fueword32((void *)td->td_sigblock_ptr, &oldval); if (res == -1) { Index: sys/kern/link_elf.c =================================================================== --- sys/kern/link_elf.c +++ sys/kern/link_elf.c @@ -1224,7 +1224,7 @@ error = vm_map_protect(kernel_map, (vm_offset_t)segbase, (vm_offset_t)segbase + round_page(segs[i]->p_memsz), - prot, FALSE); + prot, 0, VM_MAP_PROTECT_SET_PROT); if (error != KERN_SUCCESS) { error = ENOMEM; goto out; Index: sys/kern/link_elf_obj.c =================================================================== --- sys/kern/link_elf_obj.c +++ sys/kern/link_elf_obj.c @@ -219,7 +219,8 @@ #endif return; } - error = vm_map_protect(kernel_map, start, end, prot, FALSE); + error = vm_map_protect(kernel_map, start, end, prot, 0, + VM_MAP_PROTECT_SET_PROT); KASSERT(error == KERN_SUCCESS, ("link_elf_protect_range: vm_map_protect() returned %d", error)); } Index: sys/kern/subr_trap.c =================================================================== --- sys/kern/subr_trap.c +++ sys/kern/subr_trap.c @@ -204,6 +204,7 @@ struct thread *td; struct proc *p; int flags, sig; + bool resched_sigs; td = curthread; p = td->td_proc; @@ -316,27 +317,24 @@ if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || !SIGISEMPTY(p->p_siglist)) { sigfastblock_fetch(td); - if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 && - td->td_sigblock_val != 0) { - sigfastblock_setpend(td, true); - } else { - PROC_LOCK(p); - mtx_lock(&p->p_sigacts->ps_mtx); - while ((sig = cursig(td)) != 0) { - KASSERT(sig >= 0, ("sig %d", sig)); - postsig(sig); - } - mtx_unlock(&p->p_sigacts->ps_mtx); - PROC_UNLOCK(p); + PROC_LOCK(p); + mtx_lock(&p->p_sigacts->ps_mtx); + while ((sig = cursig(td)) != 0) { + KASSERT(sig >= 0, ("sig %d", sig)); + postsig(sig); } + mtx_unlock(&p->p_sigacts->ps_mtx); + PROC_UNLOCK(p); + resched_sigs = true; + } else { + resched_sigs = false; } /* * Handle deferred update of the fast sigblock value, after * the postsig() loop was performed. */ - if (td->td_pflags & TDP_SIGFASTPENDING) - sigfastblock_setpend(td, false); + sigfastblock_setpend(td, resched_sigs); #ifdef KTRACE KTRUSERRET(td); Index: sys/kern/tty.c =================================================================== --- sys/kern/tty.c +++ sys/kern/tty.c @@ -2087,7 +2087,7 @@ /* Validate the file descriptor. */ fdp = p->p_fd; - error = fget_unlocked(fdp, fd, cap_rights_init(&rights, CAP_TTYHOOK), + error = fget_unlocked(fdp, fd, cap_rights_init_one(&rights, CAP_TTYHOOK), &fp); if (error != 0) return (error); Index: sys/kern/uipc_sem.c =================================================================== --- sys/kern/uipc_sem.c +++ sys/kern/uipc_sem.c @@ -725,7 +725,7 @@ AUDIT_ARG_FD(uap->id); error = ksem_get(td, uap->id, - cap_rights_init(&rights, CAP_SEM_POST), &fp); + cap_rights_init_one(&rights, CAP_SEM_POST), &fp); if (error) return (error); ks = fp->f_data; @@ -817,7 +817,8 @@ DP((">>> kern_sem_wait entered! pid=%d\n", (int)td->td_proc->p_pid)); AUDIT_ARG_FD(id); - error = ksem_get(td, id, cap_rights_init(&rights, CAP_SEM_WAIT), &fp); + error = ksem_get(td, id, cap_rights_init_one(&rights, CAP_SEM_WAIT), + &fp); if (error) return (error); ks = fp->f_data; @@ -886,7 +887,7 @@ AUDIT_ARG_FD(uap->id); error = ksem_get(td, uap->id, - cap_rights_init(&rights, CAP_SEM_GETVALUE), &fp); + cap_rights_init_one(&rights, CAP_SEM_GETVALUE), &fp); if (error) return (error); ks = fp->f_data; Index: sys/kern/uipc_usrreq.c =================================================================== --- sys/kern/uipc_usrreq.c +++ sys/kern/uipc_usrreq.c @@ -636,7 +636,8 @@ restart: NDINIT_ATRIGHTS(&nd, CREATE, NOFOLLOW | LOCKPARENT | SAVENAME | NOCACHE, - UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_BINDAT), td); + UIO_SYSSPACE, buf, fd, cap_rights_init_one(&rights, CAP_BINDAT), + td); /* SHOULD BE ABLE TO ADOPT EXISTING AND wakeup() ALA FIFO's */ error = namei(&nd); if (error) @@ -1559,14 +1560,15 @@ else sa = NULL; NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF, - UIO_SYSSPACE, buf, fd, cap_rights_init(&rights, CAP_CONNECTAT), td); + UIO_SYSSPACE, buf, fd, cap_rights_init_one(&rights, CAP_CONNECTAT), + td); error = namei(&nd); if (error) vp = NULL; else vp = nd.ni_vp; ASSERT_VOP_LOCKED(vp, "unp_connect"); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); if (error) goto bad; @@ -2484,7 +2486,7 @@ atomic_add_int(&unp_defers_count, 1); taskqueue_enqueue(taskqueue_thread, &unp_defer_task); } else - (void) closef(fp, (struct thread *)NULL); + closef_nothread(fp); } static void @@ -2506,7 +2508,7 @@ count = 0; while ((dr = SLIST_FIRST(&drl)) != NULL) { SLIST_REMOVE_HEAD(&drl, ud_link); - closef(dr->ud_fp, NULL); + closef_nothread(dr->ud_fp); free(dr, M_TEMP); count++; } Index: sys/kern/vfs_cache.c =================================================================== --- sys/kern/vfs_cache.c +++ sys/kern/vfs_cache.c @@ -5436,7 +5436,8 @@ if (SDT_PROBES_ENABLED()) { SDT_PROBE3(vfs, fplookup, lookup, done, ndp, fpl.line, fpl.status); if (fpl.status == CACHE_FPL_STATUS_HANDLED) - SDT_PROBE3(vfs, namei, lookup, return, error, ndp->ni_vp, true); + SDT_PROBE4(vfs, namei, lookup, return, error, ndp->ni_vp, true, + ndp); } if (__predict_true(fpl.status == CACHE_FPL_STATUS_HANDLED)) { Index: sys/kern/vfs_lookup.c =================================================================== --- sys/kern/vfs_lookup.c +++ sys/kern/vfs_lookup.c @@ -76,7 +76,8 @@ SDT_PROVIDER_DEFINE(vfs); SDT_PROBE_DEFINE4(vfs, namei, lookup, entry, "struct vnode *", "char *", "unsigned long", "bool"); -SDT_PROBE_DEFINE3(vfs, namei, lookup, return, "int", "struct vnode *", "bool"); +SDT_PROBE_DEFINE4(vfs, namei, lookup, return, "int", "struct vnode *", "bool", + "struct nameidata"); /* Allocation zone for namei. */ uma_zone_t namei_zone; @@ -643,6 +644,8 @@ * If not a symbolic link, we're done. */ if ((cnp->cn_flags & ISSYMLINK) == 0) { + SDT_PROBE4(vfs, namei, lookup, return, error, + (error == 0 ? ndp->ni_vp : NULL), false, ndp); if ((cnp->cn_flags & (SAVENAME | SAVESTART)) == 0) { namei_cleanup_cnp(cnp); } else @@ -653,8 +656,6 @@ error = ENOTCAPABLE; } nameicap_cleanup(ndp, true); - SDT_PROBE3(vfs, namei, lookup, return, error, - (error == 0 ? ndp->ni_vp : NULL), false); pwd_drop(pwd); if (error == 0) NDVALIDATE(ndp); @@ -729,9 +730,9 @@ vrele(ndp->ni_dvp); out: MPASS(error != 0); + SDT_PROBE4(vfs, namei, lookup, return, error, NULL, false, ndp); namei_cleanup_cnp(cnp); nameicap_cleanup(ndp, true); - SDT_PROBE3(vfs, namei, lookup, return, error, NULL, false); pwd_drop(pwd); return (error); } @@ -1487,6 +1488,33 @@ } } +/* + * NDFREE_PNBUF replacement for callers that know there is no buffer. + * + * This is a hack. Preferably the VFS layer would not produce anything more + * than it was asked to do. Unfortunately several non-LOOKUP cases can add the + * HASBUF flag to the result. Even then an interface could be implemented where + * the caller specifies what they expected to see in the result and what they + * are going to take care of. + * + * In the meantime provide this kludge as a trivial replacement for NDFREE_PNBUF + * calls scattered throughout the kernel where we know for a fact the flag must not + * be seen. + */ +#ifdef INVARIANTS +void +NDFREE_NOTHING(struct nameidata *ndp) +{ + struct componentname *cnp; + + cnp = &ndp->ni_cnd; + KASSERT(cnp->cn_nameiop == LOOKUP, ("%s: got non-LOOKUP op %d\n", + __func__, cnp->cn_nameiop)); + KASSERT((cnp->cn_flags & (SAVENAME | HASBUF)) == 0, + ("%s: bad flags \%" PRIx64 "\n", __func__, cnp->cn_flags)); +} +#endif + void (NDFREE)(struct nameidata *ndp, const u_int flags) { Index: sys/kern/vfs_syscalls.c =================================================================== --- sys/kern/vfs_syscalls.c +++ sys/kern/vfs_syscalls.c @@ -340,7 +340,7 @@ return (error); mp = nd.ni_vp->v_mount; vfs_ref(mp); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); vput(nd.ni_vp); return (kern_do_statfs(td, mp, buf)); } @@ -949,11 +949,11 @@ return (error); if ((error = change_dir(nd.ni_vp, td)) != 0) { vput(nd.ni_vp); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); return (error); } VOP_UNLOCK(nd.ni_vp); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); pwd_chdir(td, nd.ni_vp); return (0); } @@ -991,12 +991,12 @@ VOP_UNLOCK(nd.ni_vp); error = pwd_chroot(td, nd.ni_vp); vrele(nd.ni_vp); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); return (error); e_vunlock: vput(nd.ni_vp); error: - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); return (error); } @@ -1129,15 +1129,11 @@ /* * Allocate a file structure. The descriptor to reference it - * is allocated and set by finstall() below. + * is allocated and used by finstall_refed() below. */ error = falloc_noinstall(td, &fp); if (error != 0) return (error); - /* - * An extra reference on `fp' has been held for us by - * falloc_noinstall(). - */ /* Set the flags early so the finit in devfs can pick them up. */ fp->f_flag = flags & FMASK; cmode = ((mode & ~pdp->pd_cmask) & ALLPERMS) & ~S_ISTXT; @@ -1210,26 +1206,22 @@ else #endif fcaps = NULL; - error = finstall(td, fp, &indx, flags, fcaps); - /* On success finstall() consumes fcaps. */ + error = finstall_refed(td, fp, &indx, flags, fcaps); + /* On success finstall_refed() consumes fcaps. */ if (error != 0) { filecaps_free(&nd.ni_filecaps); goto bad; } } else { filecaps_free(&nd.ni_filecaps); + falloc_abort(td, fp); } - /* - * Release our private reference, leaving the one associated with - * the descriptor table intact. - */ - fdrop(fp, td); td->td_retval[0] = indx; return (0); bad: KASSERT(indx == -1, ("indx=%d, should be -1", indx)); - fdrop_close(fp, td); + falloc_abort(td, fp); return (error); } @@ -2118,7 +2110,7 @@ vp = nd.ni_vp; error = vn_access(vp, amode, usecred, td); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); vput(vp); out: if (usecred != cred) { @@ -2417,7 +2409,7 @@ if (__predict_false(hook != NULL)) hook(nd.ni_vp, sbp); } - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); vput(nd.ni_vp); #ifdef __STAT_TIME_T_EXT sbp->st_atim_ext = 0; @@ -2557,7 +2549,7 @@ pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); error = VOP_PATHCONF(nd.ni_vp, name, valuep); vput(nd.ni_vp); @@ -2613,7 +2605,7 @@ if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); vp = nd.ni_vp; error = kern_readlink_vp(vp, buf, bufseg, count, td); @@ -2764,7 +2756,7 @@ &cap_fchflags_rights, td); if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); error = setfflags(td, nd.ni_vp, flags); vrele(nd.ni_vp); return (error); @@ -2893,7 +2885,7 @@ &cap_fchmod_rights, td); if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); error = setfmode(td, td->td_ucred, nd.ni_vp, mode); vrele(nd.ni_vp); return (error); @@ -3006,7 +2998,7 @@ if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); error = setfown(td, td->td_ucred, nd.ni_vp, uid, gid); vrele(nd.ni_vp); return (error); @@ -3219,7 +3211,7 @@ if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); return (error); @@ -3255,7 +3247,7 @@ NDINIT(&nd, LOOKUP, NOFOLLOW | AUDITVNODE1, pathseg, path, td); if ((error = namei(&nd)) != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); error = setutimes(td, nd.ni_vp, ts, 2, tptr == NULL); vrele(nd.ni_vp); return (error); @@ -3370,7 +3362,7 @@ * "If both tv_nsec fields are UTIME_OMIT... EACCESS may be detected." * "Search permission is denied by a component of the path prefix." */ - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); if ((flags & UTIMENS_EXIT) == 0) error = setutimes(td, nd.ni_vp, ts, 2, flags & UTIMENS_NULL); vrele(nd.ni_vp); @@ -4226,7 +4218,7 @@ if ((error = namei(&nd)) != 0) return (error); vp = nd.ni_vp; - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); if (vp->v_type != VCHR || vp->v_rdev == NULL) { error = EINVAL; goto out; @@ -4361,7 +4353,7 @@ error = namei(&nd); if (error != 0) return (error); - NDFREE(&nd, NDF_ONLY_PNBUF); + NDFREE_NOTHING(&nd); vp = nd.ni_vp; bzero(&fh, sizeof(fh)); fh.fh_fsid = vp->v_mount->mnt_stat.f_fsid; Index: sys/kern/vfs_vnops.c =================================================================== --- sys/kern/vfs_vnops.c +++ sys/kern/vfs_vnops.c @@ -240,8 +240,11 @@ /* * Set NOCACHE to avoid flushing the cache when * rolling in many files at once. - */ - ndp->ni_cnd.cn_flags |= LOCKPARENT | NOCACHE; + * + * Set NC_KEEPPOSENTRY to keep positive entries if they already + * exist despite NOCACHE. + */ + ndp->ni_cnd.cn_flags |= LOCKPARENT | NOCACHE | NC_KEEPPOSENTRY; if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0) ndp->ni_cnd.cn_flags |= FOLLOW; if ((vn_open_flags & VN_OPEN_INVFS) == 0) Index: sys/modules/Makefile =================================================================== --- sys/modules/Makefile +++ sys/modules/Makefile @@ -108,6 +108,7 @@ ${_dpdk_lpm6} \ ${_dpms} \ dummynet \ + ${_dwwdt} \ ${_efirt} \ ${_em} \ ${_ena} \ @@ -611,6 +612,7 @@ .if ${MACHINE_CPUARCH} == "aarch64" _allwinner= allwinner _armv8crypto= armv8crypto +_dwwdt= dwwdt _em= em _rockchip= rockchip .endif Index: sys/modules/dwwdt/Makefile =================================================================== --- /dev/null +++ sys/modules/dwwdt/Makefile @@ -0,0 +1,7 @@ +.PATH: ${SRCTOP}/sys/dev/dwwdt + +KMOD = dwwdt +SRCS = dwwdt.c \ + device_if.h bus_if.h ofw_bus_if.h + +.include Index: sys/modules/linuxkpi/Makefile =================================================================== --- sys/modules/linuxkpi/Makefile +++ sys/modules/linuxkpi/Makefile @@ -17,6 +17,7 @@ linux_seq_file.c \ linux_schedule.c \ linux_shmemfs.c \ + linux_shrinker.c \ linux_slab.c \ linux_tasklet.c \ linux_usb.c \ @@ -25,7 +26,7 @@ .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "i386" -SRCS+= opt_acpi.h acpi_if.h linux_acpi.c +SRCS+= opt_acpi.h acpi_if.h linux_acpi.c linux_fpu.c .endif SRCS+= ${LINUXKPI_GENSRCS} Index: sys/net/if_tuntap.c =================================================================== --- sys/net/if_tuntap.c +++ sys/net/if_tuntap.c @@ -123,7 +123,7 @@ #define TUN_OPEN 0x0001 #define TUN_INITED 0x0002 #define TUN_UNUSED1 0x0008 -#define TUN_DSTADDR 0x0010 +#define TUN_UNUSED2 0x0010 #define TUN_LMODE 0x0020 #define TUN_RWAIT 0x0040 #define TUN_ASYNC 0x0080 @@ -1160,19 +1160,8 @@ /* Delete all addresses and routes which reference this interface. */ if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - struct ifaddr *ifa; - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; TUN_UNLOCK(tp); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - /* deal w/IPv4 PtP destination; unlocked read */ - if (!l2tun && ifa->ifa_addr->sa_family == AF_INET) { - rtinit(ifa, (int)RTM_DELETE, - tp->tun_flags & TUN_DSTADDR ? RTF_HOST : 0); - } else { - rtinit(ifa, (int)RTM_DELETE, 0); - } - } if_purgeaddrs(ifp); TUN_LOCK(tp); } @@ -1197,10 +1186,6 @@ tuninit(struct ifnet *ifp) { struct tuntap_softc *tp = ifp->if_softc; -#ifdef INET - struct epoch_tracker et; - struct ifaddr *ifa; -#endif TUNDEBUG(ifp, "tuninit\n"); @@ -1209,21 +1194,6 @@ if ((tp->tun_flags & TUN_L2) == 0) { ifp->if_flags |= IFF_UP; getmicrotime(&ifp->if_lastchange); -#ifdef INET - NET_EPOCH_ENTER(et); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family == AF_INET) { - struct sockaddr_in *si; - - si = (struct sockaddr_in *)ifa->ifa_dstaddr; - if (si && si->sin_addr.s_addr) { - tp->tun_flags |= TUN_DSTADDR; - break; - } - } - } - NET_EPOCH_EXIT(et); -#endif TUN_UNLOCK(tp); } else { ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; Index: sys/netinet/sctp_syscalls.c =================================================================== --- sys/netinet/sctp_syscalls.c +++ sys/netinet/sctp_syscalls.c @@ -153,7 +153,7 @@ int error, fd; AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_PEELOFF), + error = getsock_cap(td, uap->sd, cap_rights_init_one(&rights, CAP_PEELOFF), &headfp, &fflag, NULL); if (error != 0) goto done2; @@ -472,7 +472,7 @@ int error, fromlen, i, msg_flags; AUDIT_ARG_FD(uap->sd); - error = getsock_cap(td, uap->sd, cap_rights_init(&rights, CAP_RECV), + error = getsock_cap(td, uap->sd, cap_rights_init_one(&rights, CAP_RECV), &fp, NULL, NULL); if (error != 0) return (error); Index: sys/netinet/tcp_input.c =================================================================== --- sys/netinet/tcp_input.c +++ sys/netinet/tcp_input.c @@ -510,6 +510,7 @@ } /* XXXLAS: EXIT_RECOVERY ? */ tp->t_bytes_acked = 0; + tp->sackhint.recover_fs = 0; } /* @@ -2580,6 +2581,9 @@ tp->sackhint.sack_bytes_rexmit; tp->sackhint.prr_delivered += del_data; if (pipe > tp->snd_ssthresh) { + if (tp->sackhint.recover_fs == 0) + tp->sackhint.recover_fs = + max(1, tp->snd_nxt - tp->snd_una); snd_cnt = (tp->sackhint.prr_delivered * tp->snd_ssthresh / tp->sackhint.recover_fs) + @@ -2667,14 +2671,14 @@ tcp_timer_activate(tp, TT_REXMT, 0); tp->t_rtttime = 0; if (V_tcp_do_prr) { - /* - * snd_ssthresh is already updated by - * cc_cong_signal. - */ - tp->sackhint.prr_delivered = 0; - tp->sackhint.sack_bytes_rexmit = 0; - if (!(tp->sackhint.recover_fs = tp->snd_nxt - tp->snd_una)) - tp->sackhint.recover_fs = 1; + /* + * snd_ssthresh is already updated by + * cc_cong_signal. + */ + tp->sackhint.prr_delivered = 0; + tp->sackhint.sack_bytes_rexmit = 0; + tp->sackhint.recover_fs = max(1, + tp->snd_nxt - tp->snd_una); } if (tp->t_flags & TF_SACK_PERMIT) { TCPSTAT_INC( Index: sys/netinet/tcp_subr.c =================================================================== --- sys/netinet/tcp_subr.c +++ sys/netinet/tcp_subr.c @@ -737,6 +737,16 @@ TCPS_HAVEESTABLISHED(tp->t_state) ? TP_KEEPIDLE(tp) : TP_KEEPINIT(tp)); + /* + * Make sure critical variables are initialized + * if transitioning while in Recovery. + */ + if IN_FASTRECOVERY(tp->t_flags) { + if (tp->sackhint.recover_fs == 0) + tp->sackhint.recover_fs = max(1, + tp->snd_nxt - tp->snd_una); + } + return (0); } Index: sys/netinet6/in6_ifattach.c =================================================================== --- sys/netinet6/in6_ifattach.c +++ sys/netinet6/in6_ifattach.c @@ -520,8 +520,11 @@ * valid with referring to the old link-local address. */ if ((pr = nd6_prefix_lookup(&pr0)) == NULL) { - if ((error = nd6_prelist_add(&pr0, NULL, NULL)) != 0) + if ((error = nd6_prelist_add(&pr0, NULL, &pr)) != 0) return (error); + /* Reference prefix */ + ia->ia6_ndpr = pr; + pr->ndpr_addrcnt++; } else nd6_prefix_rele(pr); Index: sys/riscv/riscv/pmap.c =================================================================== --- sys/riscv/riscv/pmap.c +++ sys/riscv/riscv/pmap.c @@ -3498,7 +3498,10 @@ goto restart; } } - l3 = pmap_l3(pmap, pv->pv_va); + l2 = pmap_l2(pmap, pv->pv_va); + KASSERT((pmap_load(l2) & PTE_RWX) == 0, + ("%s: found a 2mpage in page %p's pv list", __func__, m)); + l3 = pmap_l2_to_l3(l2, pv->pv_va); if ((pmap_load(l3) & PTE_SW_WIRED) != 0) count++; PMAP_UNLOCK(pmap); @@ -3745,7 +3748,10 @@ goto restart; } } - l3 = pmap_l3(pmap, pv->pv_va); + l2 = pmap_l2(pmap, pv->pv_va); + KASSERT((pmap_load(l2) & PTE_RWX) == 0, + ("%s: found a 2mpage in page %p's pv list", __func__, m)); + l3 = pmap_l2_to_l3(l2, pv->pv_va); rv = (pmap_load(l3) & mask) == mask; PMAP_UNLOCK(pmap); if (rv) @@ -3901,7 +3907,10 @@ goto retry_pv_loop; } } - l3 = pmap_l3(pmap, pv->pv_va); + l2 = pmap_l2(pmap, pv->pv_va); + KASSERT((pmap_load(l2) & PTE_RWX) == 0, + ("%s: found a 2mpage in page %p's pv list", __func__, m)); + l3 = pmap_l2_to_l3(l2, pv->pv_va); oldl3 = pmap_load(l3); retry: if ((oldl3 & PTE_W) != 0) { @@ -4172,8 +4181,7 @@ } l2 = pmap_l2(pmap, pv->pv_va); KASSERT((pmap_load(l2) & PTE_RWX) == 0, - ("pmap_clear_modify: found a 2mpage in page %p's pv list", - m)); + ("%s: found a 2mpage in page %p's pv list", __func__, m)); l3 = pmap_l2_to_l3(l2, pv->pv_va); if ((pmap_load(l3) & (PTE_D | PTE_W)) == (PTE_D | PTE_W)) { pmap_clear_bits(l3, PTE_D | PTE_W); Index: sys/rpc/rpcsec_tls/rpctls_impl.c =================================================================== --- sys/rpc/rpcsec_tls/rpctls_impl.c +++ sys/rpc/rpcsec_tls/rpctls_impl.c @@ -573,6 +573,7 @@ mtx_unlock(&rpctls_server_lock); /* Do the server upcall. */ + res.gid.gid_val = NULL; stat = rpctlssd_connect_1(NULL, &res, cl); if (stat == RPC_SUCCESS) { *flags = res.flags; @@ -598,6 +599,7 @@ soshutdown(so, SHUT_RD); } CLNT_RELEASE(cl); + mem_free(res.gid.gid_val, 0); /* Once the upcall is done, the daemon is done with the fp and so. */ mtx_lock(&rpctls_server_lock); Index: sys/security/mac/mac_syscalls.c =================================================================== --- sys/security/mac/mac_syscalls.c +++ sys/security/mac/mac_syscalls.c @@ -253,7 +253,8 @@ } buffer = malloc(mac.m_buflen, M_MACTEMP, M_WAITOK | M_ZERO); - error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_GET), &fp); + error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_MAC_GET), + &fp); if (error) goto out; @@ -411,7 +412,8 @@ return (error); } - error = fget(td, uap->fd, cap_rights_init(&rights, CAP_MAC_SET), &fp); + error = fget(td, uap->fd, cap_rights_init_one(&rights, CAP_MAC_SET), + &fp); if (error) goto out; Index: sys/security/mac_veriexec/mac_veriexec.c =================================================================== --- sys/security/mac_veriexec/mac_veriexec.c +++ sys/security/mac_veriexec/mac_veriexec.c @@ -656,8 +656,8 @@ switch (call) { case MAC_VERIEXEC_CHECK_FD_SYSCALL: /* Get the vnode associated with the file descriptor passed */ - error = getvnode(td, (uintptr_t) arg, cap_rights_init(&rights, - CAP_READ), &fp); + error = getvnode(td, (uintptr_t) arg, + cap_rights_init_one(&rights, CAP_READ), &fp); if (error) return (error); if (fp->f_type != DTYPE_VNODE) { Index: sys/sys/filedesc.h =================================================================== --- sys/sys/filedesc.h +++ sys/sys/filedesc.h @@ -224,15 +224,20 @@ void filecaps_free(struct filecaps *fcaps); int closef(struct file *fp, struct thread *td); +void closef_nothread(struct file *fp); int dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode, int openerror, int *indxp); int falloc_caps(struct thread *td, struct file **resultfp, int *resultfd, int flags, struct filecaps *fcaps); -int falloc_noinstall(struct thread *td, struct file **resultfp); +void falloc_abort(struct thread *td, struct file *fp); +int _falloc_noinstall(struct thread *td, struct file **resultfp, u_int n); +#define falloc_noinstall(td, resultfp) _falloc_noinstall(td, resultfp, 1) void _finstall(struct filedesc *fdp, struct file *fp, int fd, int flags, struct filecaps *fcaps); int finstall(struct thread *td, struct file *fp, int *resultfd, int flags, struct filecaps *fcaps); +int finstall_refed(struct thread *td, struct file *fp, int *resultfd, int flags, + struct filecaps *fcaps); int fdalloc(struct thread *td, int minfd, int *result); int fdallocn(struct thread *td, int minfd, int *fds, int n); int fdcheckstd(struct thread *td); Index: sys/sys/namei.h =================================================================== --- sys/sys/namei.h +++ sys/sys/namei.h @@ -288,8 +288,10 @@ } while (0) #ifdef INVARIANTS +void NDFREE_NOTHING(struct nameidata *); void NDVALIDATE(struct nameidata *); #else +#define NDFREE_NOTHING(ndp) do { } while (0) #define NDVALIDATE(ndp) do { } while (0) #endif Index: sys/sys/param.h =================================================================== --- sys/sys/param.h +++ sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1300134 /* Master, propagated to newvers */ +#define __FreeBSD_version 1300135 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, Index: sys/ufs/ffs/ffs_alloc.c =================================================================== --- sys/ufs/ffs/ffs_alloc.c +++ sys/ufs/ffs/ffs_alloc.c @@ -3218,7 +3218,7 @@ if (cmd.version != FFS_CMD_VERSION) return (ERPCMISMATCH); if ((error = getvnode(td, cmd.handle, - cap_rights_init(&rights, CAP_FSCK), &fp)) != 0) + cap_rights_init_one(&rights, CAP_FSCK), &fp)) != 0) return (error); vp = fp->f_vnode; if (vp->v_type != VREG && vp->v_type != VDIR) { Index: sys/vm/vm_map.h =================================================================== --- sys/vm/vm_map.h +++ sys/vm/vm_map.h @@ -510,7 +510,12 @@ for ((it) = vm_map_entry_first(map); \ (it) != &(map)->header; \ (it) = vm_map_entry_succ(it)) -int vm_map_protect (vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t); + +#define VM_MAP_PROTECT_SET_PROT 0x0001 +#define VM_MAP_PROTECT_SET_MAXPROT 0x0002 + +int vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end, + vm_prot_t new_prot, vm_prot_t new_maxprot, int flags); int vm_map_remove (vm_map_t, vm_offset_t, vm_offset_t); void vm_map_try_merge_entries(vm_map_t map, vm_map_entry_t prev, vm_map_entry_t entry); Index: sys/vm/vm_map.c =================================================================== --- sys/vm/vm_map.c +++ sys/vm/vm_map.c @@ -2733,14 +2733,12 @@ /* * vm_map_protect: * - * Sets the protection of the specified address - * region in the target map. If "set_max" is - * specified, the maximum protection is to be set; - * otherwise, only the current protection is affected. + * Sets the protection and/or the maximum protection of the + * specified address region in the target map. */ int vm_map_protect(vm_map_t map, vm_offset_t start, vm_offset_t end, - vm_prot_t new_prot, boolean_t set_max) + vm_prot_t new_prot, vm_prot_t new_maxprot, int flags) { vm_map_entry_t entry, first_entry, in_tran, prev_entry; vm_object_t obj; @@ -2751,12 +2749,18 @@ if (start == end) return (KERN_SUCCESS); + if ((flags & (VM_MAP_PROTECT_SET_PROT | VM_MAP_PROTECT_SET_MAXPROT)) == + (VM_MAP_PROTECT_SET_PROT | VM_MAP_PROTECT_SET_MAXPROT) && + (new_prot & new_maxprot) != new_prot) + return (KERN_OUT_OF_BOUNDS); + again: in_tran = NULL; vm_map_lock(map); - if ((map->flags & MAP_WXORX) != 0 && (new_prot & - (VM_PROT_WRITE | VM_PROT_EXECUTE)) == (VM_PROT_WRITE | + if ((map->flags & MAP_WXORX) != 0 && + (flags & VM_MAP_PROTECT_SET_PROT) != 0 && + (new_prot & (VM_PROT_WRITE | VM_PROT_EXECUTE)) == (VM_PROT_WRITE | VM_PROT_EXECUTE)) { vm_map_unlock(map); return (KERN_PROTECTION_FAILURE); @@ -2786,7 +2790,12 @@ vm_map_unlock(map); return (KERN_INVALID_ARGUMENT); } - if ((new_prot & entry->max_protection) != new_prot) { + if ((flags & VM_MAP_PROTECT_SET_PROT) == 0) + new_prot = entry->protection; + if ((flags & VM_MAP_PROTECT_SET_MAXPROT) == 0) + new_maxprot = entry->max_protection; + if ((new_prot & entry->max_protection) != new_prot || + (new_maxprot & entry->max_protection) != new_maxprot) { vm_map_unlock(map); return (KERN_PROTECTION_FAILURE); } @@ -2827,12 +2836,16 @@ return (rv); } - if (set_max || + if ((flags & VM_MAP_PROTECT_SET_PROT) == 0) + new_prot = entry->protection; + if ((flags & VM_MAP_PROTECT_SET_MAXPROT) == 0) + new_maxprot = entry->max_protection; + + if ((flags & VM_MAP_PROTECT_SET_PROT) == 0 || ((new_prot & ~entry->protection) & VM_PROT_WRITE) == 0 || ENTRY_CHARGED(entry) || - (entry->eflags & MAP_ENTRY_GUARD) != 0) { + (entry->eflags & MAP_ENTRY_GUARD) != 0) continue; - } cred = curthread->td_ucred; obj = entry->object.vm_object; @@ -2893,11 +2906,11 @@ old_prot = entry->protection; - if (set_max) - entry->protection = - (entry->max_protection = new_prot) & - old_prot; - else + if ((flags & VM_MAP_PROTECT_SET_MAXPROT) != 0) { + entry->max_protection = new_maxprot; + entry->protection = new_maxprot & old_prot; + } + if ((flags & VM_MAP_PROTECT_SET_PROT) != 0) entry->protection = new_prot; /* Index: sys/vm/vm_mmap.c =================================================================== --- sys/vm/vm_mmap.c +++ sys/vm/vm_mmap.c @@ -653,6 +653,7 @@ vm_offset_t addr; vm_size_t pageoff; int vm_error, max_prot; + int flags; addr = addr0; if ((prot & ~(_PROT_ALL | PROT_MAX(_PROT_ALL))) != 0) @@ -672,16 +673,11 @@ if (addr + size < addr) return (EINVAL); - vm_error = KERN_SUCCESS; - if (max_prot != 0) { - if ((max_prot & prot) != prot) - return (ENOTSUP); - vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map, - addr, addr + size, max_prot, TRUE); - } - if (vm_error == KERN_SUCCESS) - vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map, - addr, addr + size, prot, FALSE); + flags = VM_MAP_PROTECT_SET_PROT; + if (max_prot != 0) + flags |= VM_MAP_PROTECT_SET_MAXPROT; + vm_error = vm_map_protect(&td->td_proc->p_vmspace->vm_map, + addr, addr + size, prot, max_prot, flags); switch (vm_error) { case KERN_SUCCESS: @@ -690,6 +686,8 @@ return (EACCES); case KERN_RESOURCE_SHORTAGE: return (ENOMEM); + case KERN_OUT_OF_BOUNDS: + return (ENOTSUP); } return (EINVAL); } Index: sys/x86/x86/busdma_bounce.c =================================================================== --- sys/x86/x86/busdma_bounce.c +++ sys/x86/x86/busdma_bounce.c @@ -400,7 +400,7 @@ * A dmamap to for use with dmamap_load is also allocated. */ static int -bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, +bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, bus_dmamap_t *mapp) { vm_memattr_t attr; Index: tools/tools/netmap/pkt-gen.c =================================================================== --- tools/tools/netmap/pkt-gen.c +++ tools/tools/netmap/pkt-gen.c @@ -3176,17 +3176,17 @@ struct netmap_if *nifp = g.nmd->nifp; struct nmreq_register *req = &g.nmd->reg; - D("nifp at offset %"PRIu64", %d tx %d rx region %d", + D("nifp at offset %"PRIu64" ntxqs %d nrxqs %d memid %d", req->nr_offset, req->nr_tx_rings, req->nr_rx_rings, req->nr_mem_id); for (i = 0; i < req->nr_tx_rings + req->nr_host_tx_rings; i++) { struct netmap_ring *ring = NETMAP_TXRING(nifp, i); - D(" TX%d at 0x%p slots %d", i, + D(" TX%d at offset %p slots %d", i, (void *)((char *)ring - (char *)nifp), ring->num_slots); } for (i = 0; i < req->nr_rx_rings + req->nr_host_rx_rings; i++) { struct netmap_ring *ring = NETMAP_RXRING(nifp, i); - D(" RX%d at 0x%p slots %d", i, + D(" RX%d at offset %p slots %d", i, (void *)((char *)ring - (char *)nifp), ring->num_slots); } } Index: usr.bin/elfctl/elfctl.1 =================================================================== --- usr.bin/elfctl/elfctl.1 +++ usr.bin/elfctl/elfctl.1 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 1, 2020 +.Dd January 12, 2021 .Dt ELFCTL 1 .Os .Sh NAME @@ -35,6 +35,7 @@ .Sh SYNOPSIS .Nm .Op Fl h | Fl -help +.Op Fl i .Op Fl l .Op Fl e Ar featurelist .Ar @@ -47,6 +48,9 @@ .Bl -tag -width indent .It Fl h | Fl -help Print a usage message and exit. +.It Fl i +Ignore unknown feature flags in +.Ar featurelist . .It Fl l List known ELF feature flags. .It Fl e Ar featurelist Index: usr.bin/elfctl/elfctl.c =================================================================== --- usr.bin/elfctl/elfctl.c +++ usr.bin/elfctl/elfctl.c @@ -81,7 +81,9 @@ #else #define SUPPORTED_ENDIAN ELFDATA2MSB #endif - + +static bool iflag; + int main(int argc, char **argv) { @@ -100,8 +102,11 @@ if (elf_version(EV_CURRENT) == EV_NONE) errx(EXIT_FAILURE, "elf_version error"); - while ((ch = getopt_long(argc, argv, "hle:", long_opts, NULL)) != -1) { + while ((ch = getopt_long(argc, argv, "hile:", long_opts, NULL)) != -1) { switch (ch) { + case 'i': + iflag = true; + break; case 'l': print_features(); lflag = true; @@ -197,6 +202,7 @@ Set or display the control features for an ELF object.\n\n\ Supported options are:\n\ -l List known control features.\n\ + -i Ignore unknown features.\n\ -e [+-=]feature,list Edit features from a comma separated list.\n\ -h | --help Print a usage message and exit.\n" @@ -229,7 +235,8 @@ } if (i == len) { warnx("%s is not a valid feature", feature); - return (false); + if (!iflag) + return (false); } } Index: usr.sbin/wpa/Makefile.crypto =================================================================== --- usr.sbin/wpa/Makefile.crypto +++ usr.sbin/wpa/Makefile.crypto @@ -16,9 +16,13 @@ CONFIG_INTERNAL_SHA1=y NEED_SHA256=y CONFIG_INTERNAL_SHA256=y +NEED_SHA384=y +CONFIG_INTERNAL_SHA384=y +NEED_SHA512=y +CONFIG_INTERNAL_SHA512=y CONFIG_INTERNAL_TLS=y +NEED_DH_GROUPS=y CONFIG_INTERNAL_DH5=y -CONFIG_INTERNAL_DH=y NEED_AES_ENC=true NEED_AES_CBC=true .endif @@ -45,6 +49,7 @@ tlsv1_client.c \ tlsv1_client_write.c \ tlsv1_client_read.c \ + tlsv1_client_ocsp.c \ x509v3.c NEED_DES=y NEED_MD4=y @@ -123,14 +128,36 @@ .endif .endif +.if defined(NEED_SHA384) +CFLAGS+=-DCONFIG_SHA384 +SRCS+= sha384.c +.if defined(CONFIG_INTERNAL_SHA384) +SRCS+= sha384-internal.c sha384-prf.c +.endif +.endif + +.if defined(NEED_SHA512) +CFLAGS+=-DCONFIG_SHA512 +SRCS+= sha512.c +.if defined(CONFIG_INTERNAL_SHA512) +SRCS+= sha512-internal.c sha512-prf.c +.endif +.endif + .if defined(NEED_TLS_PRF) SRCS+= sha1-tlsprf.c .endif .if defined(CONFIG_INTERNAL_DH5) +.if defined(NEED_DH_GROUPS) SRCS+= dh_group5.c .endif +.endif -.if defined(CONFIG_INTERNAL_DH) +.if defined(NEED_DH_GROUPS) SRCS+= dh_groups.c .endif + +.if defined(NEED_DH_GROUPS_ALL) +CFLAGS+=-DALL_DH_GROUPS +.endif Index: usr.sbin/wpa/hostapd/Makefile =================================================================== --- usr.sbin/wpa/hostapd/Makefile +++ usr.sbin/wpa/hostapd/Makefile @@ -163,6 +163,10 @@ eapol_auth_sm.c TLS_FUNCS=y +# For WPS, EAP modes, etc +NEED_DH_GROUPS=y +NEED_DH_GROUPS_ALL=y + .if !empty(CFLAGS:M*-DCONFIG_WPS) NEED_SIM_COMMON=y .endif Index: usr.sbin/wpa/wpa_supplicant/Makefile =================================================================== --- usr.sbin/wpa/wpa_supplicant/Makefile +++ usr.sbin/wpa/wpa_supplicant/Makefile @@ -14,7 +14,7 @@ SRCS= base64.c bitfield.c blacklist.c bss.c cli.c common.c \ config.c config_file.c \ ctrl_iface.c ctrl_iface_common.c ctrl_iface_unix.c \ - dh_groups.c driver_bsd.c driver_common.c \ + driver_bsd.c driver_common.c \ driver_ndis.c driver_wired.c driver_wired_common.c drivers.c \ eap_register.c eloop.c \ events.c gas.c gas_query.c \