Merge ^/head r358131 through r358178.

This commit is contained in:
Dimitry Andric 2020-02-20 19:07:29 +00:00
commit 6c140a7281
57 changed files with 788 additions and 259 deletions

View File

@ -273,6 +273,12 @@ OLD_DIRS+=usr/lib/clang/9.0.1/lib/freebsd
OLD_DIRS+=usr/lib/clang/9.0.1/lib OLD_DIRS+=usr/lib/clang/9.0.1/lib
OLD_DIRS+=usr/lib/clang/9.0.1 OLD_DIRS+=usr/lib/clang/9.0.1
# 20200220: Upgrade of ncurses, shlib bumped to version 9
OLD_LIBS+=lib/libncurses.so.8
OLD_LIBS+=lib/libncursesw.so.8
OLD_LIBS+=usr/lib32/libncurses.so.8
OLD_LIBS+=usr/lib32/libncursesw.so.8
# 20200206: Remove elf2aout # 20200206: Remove elf2aout
OLD_FILES+=usr/bin/elf2aout OLD_FILES+=usr/bin/elf2aout
OLD_FILES+=usr/share/man/man1/elf2aout.1.gz OLD_FILES+=usr/share/man/man1/elf2aout.1.gz

View File

@ -32,10 +32,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
information about prerequisites and upgrading, if you are not already information about prerequisites and upgrading, if you are not already
using clang 3.5.0 or higher. using clang 3.5.0 or higher.
20200218: 20200220:
ncurses has been updated to a newer version (6.1-20200118). After an ncurses has been updated to a newer version (6.1-20200118). Given the ABI
update some applications using ncurses may results have some rendering has changed, users will have to rebuild all the ports that are linked to
problems and would need to be rebuilt. ncurses.
20200217: 20200217:
The size of struct vnet and the magic cookie have changed. The size of struct vnet and the magic cookie have changed.

View File

@ -66,10 +66,79 @@ __FBSDID("$FreeBSD$");
#undef eflag #undef eflag
#define READ_BUFLEN 1024
struct fdctx {
int fd;
size_t off; /* offset in buf */
size_t buflen;
char *ep; /* tail pointer */
char buf[READ_BUFLEN];
};
static void fdctx_init(int, struct fdctx *);
static void fdctx_destroy(struct fdctx *);
static ssize_t fdgetc(struct fdctx *, char *);
int readcmd(int, char **); int readcmd(int, char **);
int umaskcmd(int, char **); int umaskcmd(int, char **);
int ulimitcmd(int, char **); int ulimitcmd(int, char **);
static void
fdctx_init(int fd, struct fdctx *fdc)
{
off_t cur;
/* Check if fd is seekable. */
cur = lseek(fd, 0, SEEK_CUR);
*fdc = (struct fdctx){
.fd = fd,
.buflen = (cur != -1) ? READ_BUFLEN : 1,
.ep = &fdc->buf[0], /* No data */
};
}
static ssize_t
fdgetc(struct fdctx *fdc, char *c)
{
ssize_t nread;
if (&fdc->buf[fdc->off] == fdc->ep) {
nread = read(fdc->fd, fdc->buf, fdc->buflen);
if (nread > 0) {
fdc->off = 0;
fdc->ep = fdc->buf + nread;
} else
return (nread);
}
*c = fdc->buf[fdc->off++];
return (1);
}
static void
fdctx_destroy(struct fdctx *fdc)
{
size_t residue;
if (fdc->buflen > 1) {
/*
* Reposition the file offset. Here is the layout of buf:
*
* | off
* v
* |*****************|-------|
* buf ep buf+buflen
* |<- residue ->|
*
* off: current character
* ep: offset just after read(2)
* residue: length for reposition
*/
residue = (fdc->ep - fdc->buf) - fdc->off;
if (residue > 0)
(void) lseek(fdc->fd, -residue, SEEK_CUR);
}
}
/* /*
* The read builtin. The -r option causes backslashes to be treated like * The read builtin. The -r option causes backslashes to be treated like
* ordinary characters. * ordinary characters.
@ -108,6 +177,7 @@ readcmd(int argc __unused, char **argv __unused)
fd_set ifds; fd_set ifds;
ssize_t nread; ssize_t nread;
int sig; int sig;
struct fdctx fdctx;
rflag = 0; rflag = 0;
prompt = NULL; prompt = NULL;
@ -173,8 +243,9 @@ readcmd(int argc __unused, char **argv __unused)
backslash = 0; backslash = 0;
STARTSTACKSTR(p); STARTSTACKSTR(p);
lastnonifs = lastnonifsws = -1; lastnonifs = lastnonifsws = -1;
fdctx_init(STDIN_FILENO, &fdctx);
for (;;) { for (;;) {
nread = read(STDIN_FILENO, &c, 1); nread = fdgetc(&fdctx, &c);
if (nread == -1) { if (nread == -1) {
if (errno == EINTR) { if (errno == EINTR) {
sig = pendingsig; sig = pendingsig;
@ -260,6 +331,7 @@ readcmd(int argc __unused, char **argv __unused)
STARTSTACKSTR(p); STARTSTACKSTR(p);
lastnonifs = lastnonifsws = -1; lastnonifs = lastnonifsws = -1;
} }
fdctx_destroy(&fdctx);
STACKSTRNUL(p); STACKSTRNUL(p);
/* /*

View File

@ -42,14 +42,19 @@ __FBSDID("$FreeBSD$");
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h>
#include "un-namespace.h" #include "un-namespace.h"
#include "libc_private.h"
extern int __realpathat(int fd, const char *path, char *buf, size_t size,
int flags);
/* /*
* Find the real name of path, by removing all ".", ".." and symlink * Find the real name of path, by removing all ".", ".." and symlink
* components. Returns (resolved) on success, or (NULL) on failure, * components. Returns (resolved) on success, or (NULL) on failure,
* in which case the path which caused trouble is left in (resolved). * in which case the path which caused trouble is left in (resolved).
*/ */
static char * static char * __noinline
realpath1(const char *path, char *resolved) realpath1(const char *path, char *resolved)
{ {
struct stat sb; struct stat sb;
@ -223,6 +228,10 @@ realpath(const char * __restrict path, char * __restrict resolved)
if (resolved == NULL) if (resolved == NULL)
return (NULL); return (NULL);
} }
if (__getosreldate() >= 1300080) {
if (__realpathat(AT_FDCWD, path, resolved, PATH_MAX, 0) == 0)
return (resolved);
}
res = realpath1(path, resolved); res = realpath1(path, resolved);
if (res == NULL) if (res == NULL)
free(m); free(m);

View File

@ -13,7 +13,7 @@ MK_MAN=no
.include "${.CURDIR:H}/config.mk" .include "${.CURDIR:H}/config.mk"
LIB= ncurses${LIB_SUFFIX} LIB= ncurses${LIB_SUFFIX}
SHLIB_MAJOR= 8 SHLIB_MAJOR= 9
NO_LINT= NO_LINT=
@ -292,7 +292,6 @@ CLEANFILES= ${GENSRCS} ${GENHDRS} keys.list make_hash term.h.new \
make_keys MKterm.h.awk comp_captab.c curses.head make_keys MKterm.h.awk comp_captab.c curses.head
CFLAGS+= -DFREEBSD_NATIVE -DTERMIOS CFLAGS+= -DFREEBSD_NATIVE -DTERMIOS
CFLAGS.lib_freeall.c+= -Wno-missing-prototypes
# Installed # Installed
HEADERS= curses.h term.h termcap.h unctrl.h HEADERS= curses.h term.h termcap.h unctrl.h

View File

@ -49,7 +49,7 @@ _libc_other_objects= sigsetjmp lstat stat fstat fstatat fstatfs syscall \
sysarch __sysctl issetugid __getcwd utrace \ sysarch __sysctl issetugid __getcwd utrace \
thr_self thr_kill pread mmap lseek _exit _fstat _fstatat _fstatfs \ thr_self thr_kill pread mmap lseek _exit _fstat _fstatat _fstatfs \
getdirentries _getdirentries _close _fcntl _open _openat _read \ getdirentries _getdirentries _close _fcntl _open _openat _read \
_sigprocmask _write readlink _setjmp setjmp setjmperr _sigprocmask _write readlink __realpathat _setjmp setjmp setjmperr
# Finally add additional architecture-dependent libc dependencies # Finally add additional architecture-dependent libc dependencies

View File

@ -192,6 +192,7 @@ MAN= aac.4 \
${_hv_vmbus.4} \ ${_hv_vmbus.4} \
${_hv_vss.4} \ ${_hv_vss.4} \
hwpmc.4 \ hwpmc.4 \
${_hwpstate_intel.4} \
iavf.4 \ iavf.4 \
ichsmb.4 \ ichsmb.4 \
${_ichwd.4} \ ${_ichwd.4} \
@ -787,6 +788,7 @@ _hv_storvsc.4= hv_storvsc.4
_hv_utils.4= hv_utils.4 _hv_utils.4= hv_utils.4
_hv_vmbus.4= hv_vmbus.4 _hv_vmbus.4= hv_vmbus.4
_hv_vss.4= hv_vss.4 _hv_vss.4= hv_vss.4
_hwpstate_intel.4= hwpstate_intel.4
_i8254.4= i8254.4 _i8254.4= i8254.4
_ichwd.4= ichwd.4 _ichwd.4= ichwd.4
_if_bxe.4= if_bxe.4 _if_bxe.4= if_bxe.4

View File

@ -52,6 +52,8 @@ connect_controllers(EFI_GUID *filter)
} }
handles = malloc(hsize); handles = malloc(hsize);
if (handles == NULL)
return (EFI_OUT_OF_RESOURCES);
nhandles = hsize / sizeof(EFI_HANDLE); nhandles = hsize / sizeof(EFI_HANDLE);
status = BS->LocateHandle(ByProtocol, filter, NULL, status = BS->LocateHandle(ByProtocol, filter, NULL,

View File

@ -701,6 +701,8 @@ efihttp_fs_seek(struct open_file *f, off_t offset, int where)
return (0); return (0);
if (where == SEEK_SET && fh->offset < offset) { if (where == SEEK_SET && fh->offset < offset) {
buf = malloc(1500); buf = malloc(1500);
if (buf == NULL)
return (ENOMEM);
res = offset - fh->offset; res = offset - fh->offset;
while (res > 0) { while (res > 0) {
err = _efihttp_fs_read(f, buf, min(1500, res), &res2); err = _efihttp_fs_read(f, buf, min(1500, res), &res2);

View File

@ -371,6 +371,8 @@ efinet_dev_init()
status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL); status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL);
if (status == EFI_BUFFER_TOO_SMALL) { if (status == EFI_BUFFER_TOO_SMALL) {
handles = (EFI_HANDLE *)malloc(sz); handles = (EFI_HANDLE *)malloc(sz);
if (handles == NULL)
return (ENOMEM);
status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz,
handles); handles);
if (EFI_ERROR(status)) if (EFI_ERROR(status))

View File

@ -363,6 +363,8 @@ efipart_inithandles(void)
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, hin); status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, hin);
if (status == EFI_BUFFER_TOO_SMALL) { if (status == EFI_BUFFER_TOO_SMALL) {
hin = malloc(sz); hin = malloc(sz);
if (hin == NULL)
return (ENOMEM);
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
hin); hin);
if (EFI_ERROR(status)) if (EFI_ERROR(status))

View File

@ -86,9 +86,11 @@ insert_zfs(EFI_HANDLE handle, uint64_t guid)
zfsinfo_t *zi; zfsinfo_t *zi;
zi = malloc(sizeof(zfsinfo_t)); zi = malloc(sizeof(zfsinfo_t));
zi->zi_handle = handle; if (zi != NULL) {
zi->zi_pool_guid = guid; zi->zi_handle = handle;
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link); zi->zi_pool_guid = guid;
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);
}
} }
void void

View File

@ -52,6 +52,8 @@ efi_register_handles(struct devsw *sw, EFI_HANDLE *handles,
nentries += count; nentries += count;
sz = nentries * sizeof(struct entry); sz = nentries * sizeof(struct entry);
entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz); entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz);
if (entry == NULL)
return (ENOMEM);
for (unit = 0; idx < nentries; idx++, unit++) { for (unit = 0; idx < nentries; idx++, unit++) {
entry[idx].handle = handles[unit]; entry[idx].handle = handles[unit];
if (aliases != NULL) if (aliases != NULL)

View File

@ -22,7 +22,6 @@ SRCS= autoload.c \
framebuffer.c \ framebuffer.c \
main.c \ main.c \
self_reloc.c \ self_reloc.c \
smbios.c \
vers.c vers.c
CFLAGS+= -I${.CURDIR}/../loader CFLAGS+= -I${.CURDIR}/../loader
@ -45,8 +44,6 @@ CWARNFLAGS.main.c+= -Wno-format
.PATH: ${.CURDIR}/../loader .PATH: ${.CURDIR}/../loader
.PATH: ${.CURDIR}/../loader/arch/${MACHINE} .PATH: ${.CURDIR}/../loader/arch/${MACHINE}
# For smbios.c XXX need to abstract properly
.PATH: ${BOOTSRC}/i386/libi386
.include "${.CURDIR}/../loader/arch/${MACHINE}/Makefile.inc" .include "${.CURDIR}/../loader/arch/${MACHINE}/Makefile.inc"
CFLAGS+= -I${.CURDIR} CFLAGS+= -I${.CURDIR}
@ -57,18 +54,6 @@ CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include
CFLAGS+= -I${BOOTSRC}/i386/libi386 CFLAGS+= -I${BOOTSRC}/i386/libi386
CFLAGS+= -DEFI CFLAGS+= -DEFI
.if !defined(BOOT_HIDE_SERIAL_NUMBERS)
# Export serial numbers, UUID, and asset tag from loader.
CFLAGS+= -DSMBIOS_SERIAL_NUMBERS
.if defined(BOOT_LITTLE_ENDIAN_UUID)
# Use little-endian UUID format as defined in SMBIOS 2.6.
CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID
.elif defined(BOOT_NETWORK_ENDIAN_UUID)
# Use network-endian UUID format for backward compatibility.
CFLAGS+= -DSMBIOS_NETWORK_ENDIAN_UUID
.endif
.endif
.if defined(HAVE_FDT) && ${MK_FDT} != "no" .if defined(HAVE_FDT) && ${MK_FDT} != "no"
.include "${BOOTSRC}/fdt.mk" .include "${BOOTSRC}/fdt.mk"
LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a

View File

@ -852,7 +852,11 @@ read_loader_env(const char *name, char *def_fn, bool once)
} }
} }
caddr_t
ptov(uintptr_t x)
{
return ((caddr_t)x);
}
EFI_STATUS EFI_STATUS
main(int argc, CHAR16 *argv[]) main(int argc, CHAR16 *argv[])

View File

@ -9,7 +9,7 @@ SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c \
comconsole.c devicename.c elf32_freebsd.c \ comconsole.c devicename.c elf32_freebsd.c \
elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \ elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.S \
i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.S \ i386_copy.c i386_module.c nullconsole.c pxe.c pxetramp.S \
smbios.c time.c vidconsole.c amd64_tramp.S spinconsole.c time.c vidconsole.c amd64_tramp.S spinconsole.c
.PATH: ${ZFSSRC} .PATH: ${ZFSSRC}
SRCS+= devicename_stubs.c SRCS+= devicename_stubs.c
CFLAGS+= -I${ZFSSRC} CFLAGS+= -I${ZFSSRC}
@ -28,18 +28,6 @@ CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
CFLAGS+= -DDISK_DEBUG CFLAGS+= -DDISK_DEBUG
.endif .endif
.if !defined(BOOT_HIDE_SERIAL_NUMBERS)
# Export serial numbers, UUID, and asset tag from loader.
CFLAGS+= -DSMBIOS_SERIAL_NUMBERS
.if defined(BOOT_LITTLE_ENDIAN_UUID)
# Use little-endian UUID format as defined in SMBIOS 2.6.
CFLAGS+= -DSMBIOS_LITTLE_ENDIAN_UUID
.elif defined(BOOT_NETWORK_ENDIAN_UUID)
# Use network-endian UUID format for backward compatibility.
CFLAGS+= -DSMBIOS_NETWORK_ENDIAN_UUID
.endif
.endif
# terminal emulation # terminal emulation
CFLAGS.vidconsole.c+= -I${SRCTOP}/sys/teken CFLAGS.vidconsole.c+= -I${SRCTOP}/sys/teken
CFLAGS.teken.c+= -I${SRCTOP}/sys/teken CFLAGS.teken.c+= -I${SRCTOP}/sys/teken

View File

@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h" #include "bootstrap.h"
#include "common/bootargs.h" #include "common/bootargs.h"
#include "libi386/libi386.h" #include "libi386/libi386.h"
#include "libi386/smbios.h" #include <smbios.h>
#include "btxv86.h" #include "btxv86.h"
#ifdef LOADER_ZFS_SUPPORT #ifdef LOADER_ZFS_SUPPORT
@ -86,6 +86,12 @@ extern char end[];
static void *heap_top; static void *heap_top;
static void *heap_bottom; static void *heap_bottom;
caddr_t
ptov(uintptr_t x)
{
return (PTOV(x));
}
int int
main(void) main(void)
{ {

View File

@ -137,6 +137,20 @@ CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC}
SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \ SRCS+= closeall.c dev.c ioctl.c nullfs.c stat.c \
fstat.c close.c lseek.c open.c read.c write.c readdir.c fstat.c close.c lseek.c open.c read.c write.c readdir.c
# SMBios routines
SRCS+= smbios.c
.if !defined(BOOT_HIDE_SERIAL_NUMBERS)
# Export serial numbers, UUID, and asset tag from loader.
CFLAGS.smbios.c+= -DSMBIOS_SERIAL_NUMBERS
.if defined(BOOT_LITTLE_ENDIAN_UUID)
# Use little-endian UUID format as defined in SMBIOS 2.6.
CFLAGS.smbios.c+= -DSMBIOS_LITTLE_ENDIAN_UUID
.elif defined(BOOT_NETWORK_ENDIAN_UUID)
# Use network-endian UUID format for backward compatibility.
CFLAGS.smbios.c+= -DSMBIOS_NETWORK_ENDIAN_UUID
.endif
.endif
# network routines # network routines
SRCS+= arp.c ether.c ip.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c SRCS+= arp.c ether.c ip.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c

View File

@ -28,16 +28,9 @@
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
#include <stand.h> #include <stand.h>
#include <bootstrap.h>
#include <sys/endian.h> #include <sys/endian.h>
#ifdef EFI #define PTOV(x) ptov(x)
/* In EFI, we don't need PTOV(). */
#define PTOV(x) (caddr_t)(x)
#else
#include "btxv86.h"
#endif
#include "smbios.h"
/* /*
* Detect SMBIOS and export information about the SMBIOS into the * Detect SMBIOS and export information about the SMBIOS into the

View File

@ -452,4 +452,9 @@ const char *x86_hypervisor(void);
#define reallocf(x, y) Reallocf(x, y, NULL, 0) #define reallocf(x, y) Reallocf(x, y, NULL, 0)
#endif #endif
/*
* va <-> pa routines. MD code must supply.
*/
caddr_t ptov(uintptr_t);
#endif /* STAND_H */ #endif /* STAND_H */

View File

@ -657,6 +657,7 @@
#define AUE_LGETUUID 43261 /* CADETS. */ #define AUE_LGETUUID 43261 /* CADETS. */
#define AUE_EXECVEAT 43262 /* FreeBSD/Linux. */ #define AUE_EXECVEAT 43262 /* FreeBSD/Linux. */
#define AUE_SHMRENAME 43263 /* FreeBSD-specific. */ #define AUE_SHMRENAME 43263 /* FreeBSD-specific. */
#define AUE_REALPATHAT 43264 /* FreeBSD-specific. */
/* /*
* Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the * Darwin BSM uses a number of AUE_O_* definitions, which are aliased to the

View File

@ -500,4 +500,5 @@
#define FREEBSD32_SYS_shm_open2 571 #define FREEBSD32_SYS_shm_open2 571
#define FREEBSD32_SYS_shm_rename 572 #define FREEBSD32_SYS_shm_rename 572
#define FREEBSD32_SYS_sigfastblock 573 #define FREEBSD32_SYS_sigfastblock 573
#define FREEBSD32_SYS_MAXSYSCALL 574 #define FREEBSD32_SYS___realpathat 574
#define FREEBSD32_SYS_MAXSYSCALL 575

View File

@ -610,4 +610,5 @@ const char *freebsd32_syscallnames[] = {
"shm_open2", /* 571 = shm_open2 */ "shm_open2", /* 571 = shm_open2 */
"shm_rename", /* 572 = shm_rename */ "shm_rename", /* 572 = shm_rename */
"sigfastblock", /* 573 = sigfastblock */ "sigfastblock", /* 573 = sigfastblock */
"__realpathat", /* 574 = __realpathat */
}; };

View File

@ -663,4 +663,5 @@ struct sysent freebsd32_sysent[] = {
{ AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */ { AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */
{ AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */
{ AS(sigfastblock_args), (sy_call_t *)sys_sigfastblock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 573 = sigfastblock */ { AS(sigfastblock_args), (sy_call_t *)sys_sigfastblock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 573 = sigfastblock */
{ AS(__realpathat_args), (sy_call_t *)sys___realpathat, AUE_REALPATHAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 574 = __realpathat */
}; };

View File

@ -3363,6 +3363,17 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 2; *n_args = 2;
break; break;
} }
/* __realpathat */
case 574: {
struct __realpathat_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->path; /* const char * */
uarg[2] = (intptr_t) p->buf; /* char * */
uarg[3] = p->size; /* size_t */
iarg[4] = p->flags; /* int */
*n_args = 5;
break;
}
default: default:
*n_args = 0; *n_args = 0;
break; break;
@ -9062,6 +9073,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break; break;
}; };
break; break;
/* __realpathat */
case 574:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "userland const char *";
break;
case 2:
p = "userland char *";
break;
case 3:
p = "size_t";
break;
case 4:
p = "int";
break;
default:
break;
};
break;
default: default:
break; break;
}; };
@ -10956,6 +10989,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1) if (ndx == 0 || ndx == 1)
p = "int"; p = "int";
break; break;
/* __realpathat */
case 574:
if (ndx == 0 || ndx == 1)
p = "int";
break;
default: default:
break; break;
}; };

View File

@ -1160,5 +1160,7 @@
572 AUE_SHMRENAME NOPROTO { int shm_rename(const char *path_from, \ 572 AUE_SHMRENAME NOPROTO { int shm_rename(const char *path_from, \
const char *path_to, int flags); } const char *path_to, int flags); }
573 AUE_NULL NOPROTO { int sigfastblock(int cmd, uint32_t *ptr); } 573 AUE_NULL NOPROTO { int sigfastblock(int cmd, uint32_t *ptr); }
574 AUE_REALPATHAT NOPROTO { int __realpathat(int fd, const char *path, \
char *buf, size_t size, int flags); }
; vim: syntax=off ; vim: syntax=off

View File

@ -449,6 +449,13 @@ static inline void list_cut_position(struct list_head *list,
__list_cut_position(list, head, entry); __list_cut_position(list, head, entry);
} }
static inline int list_is_first(const struct list_head *list,
const struct list_head *head)
{
return (list->prev == head);
}
static inline int list_is_last(const struct list_head *list, static inline int list_is_last(const struct list_head *list,
const struct list_head *head) const struct list_head *head)
{ {

View File

@ -154,4 +154,13 @@ memchr_inv(const void *start, int c, size_t length)
return (NULL); return (NULL);
} }
static inline size_t
str_has_prefix(const char *str, const char *prefix)
{
size_t len;
len = strlen(prefix);
return (strncmp(str, prefix, len) == 0 ? len : 0);
}
#endif /* _LINUX_STRING_H_ */ #endif /* _LINUX_STRING_H_ */

View File

@ -760,7 +760,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc)
taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
device_get_nameunit(sc->sc_dev)); device_get_nameunit(sc->sc_dev));
NET_TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc); TASK_INIT(&sc->sc_rxtask, 0, sc->sc_rx.recv_tasklet, sc);
TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc); TASK_INIT(&sc->sc_bmisstask, 0, ath_bmiss_proc, sc);
TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc); TASK_INIT(&sc->sc_bstucktask,0, ath_bstuck_proc, sc);
TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc); TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc);

View File

@ -656,6 +656,8 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
int is_good = 0; int is_good = 0;
struct ath_rx_edma *re = &sc->sc_rxedma[qtype]; struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
NET_EPOCH_ASSERT();
/* /*
* Calculate the correct 64 bit TSF given * Calculate the correct 64 bit TSF given
* the TSF64 register value and rs_tstamp. * the TSF64 register value and rs_tstamp.
@ -1074,6 +1076,8 @@ ath_rx_proc(struct ath_softc *sc, int resched)
int kickpcu = 0; int kickpcu = 0;
int ret; int ret;
NET_EPOCH_ASSERT();
/* XXX we must not hold the ATH_LOCK here */ /* XXX we must not hold the ATH_LOCK here */
ATH_UNLOCK_ASSERT(sc); ATH_UNLOCK_ASSERT(sc);
ATH_PCU_UNLOCK_ASSERT(sc); ATH_PCU_UNLOCK_ASSERT(sc);
@ -1293,6 +1297,7 @@ static void
ath_legacy_rx_tasklet(void *arg, int npending) ath_legacy_rx_tasklet(void *arg, int npending)
{ {
struct ath_softc *sc = arg; struct ath_softc *sc = arg;
struct epoch_tracker et;
ATH_KTR(sc, ATH_KTR_RXPROC, 1, "ath_rx_proc: pending=%d", npending); ATH_KTR(sc, ATH_KTR_RXPROC, 1, "ath_rx_proc: pending=%d", npending);
DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending);
@ -1305,14 +1310,18 @@ ath_legacy_rx_tasklet(void *arg, int npending)
} }
ATH_PCU_UNLOCK(sc); ATH_PCU_UNLOCK(sc);
NET_EPOCH_ENTER(et);
ath_rx_proc(sc, 1); ath_rx_proc(sc, 1);
NET_EPOCH_EXIT(et);
} }
static void static void
ath_legacy_flushrecv(struct ath_softc *sc) ath_legacy_flushrecv(struct ath_softc *sc)
{ {
struct epoch_tracker et;
NET_EPOCH_ENTER(et);
ath_rx_proc(sc, 0); ath_rx_proc(sc, 0);
NET_EPOCH_EXIT(et);
} }
static void static void

View File

@ -521,6 +521,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
int16_t nf; int16_t nf;
ath_bufhead rxlist; ath_bufhead rxlist;
struct mbuf *m; struct mbuf *m;
struct epoch_tracker et;
TAILQ_INIT(&rxlist); TAILQ_INIT(&rxlist);
@ -537,6 +538,8 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
TAILQ_CONCAT(&rxlist, &sc->sc_rx_rxlist[qtype], bf_list); TAILQ_CONCAT(&rxlist, &sc->sc_rx_rxlist[qtype], bf_list);
ATH_RX_UNLOCK(sc); ATH_RX_UNLOCK(sc);
NET_EPOCH_ENTER(et);
/* Handle the completed descriptors */ /* Handle the completed descriptors */
/* /*
* XXX is this SAFE call needed? The ath_buf entries * XXX is this SAFE call needed? The ath_buf entries
@ -560,6 +563,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
if (ngood) { if (ngood) {
sc->sc_lastrx = tsf; sc->sc_lastrx = tsf;
} }
NET_EPOCH_EXIT(et);
ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1, ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1,
"ath edma rx deferred proc: ngood=%d\n", "ath edma rx deferred proc: ngood=%d\n",

View File

@ -151,6 +151,7 @@
#define PCIY_SATA 0x12 /* SATA */ #define PCIY_SATA 0x12 /* SATA */
#define PCIY_PCIAF 0x13 /* PCI Advanced Features */ #define PCIY_PCIAF 0x13 /* PCI Advanced Features */
#define PCIY_EA 0x14 /* PCI Extended Allocation */ #define PCIY_EA 0x14 /* PCI Extended Allocation */
#define PCIY_FPB 0x15 /* Flattening Portal Bridge */
/* Extended Capability Register Fields */ /* Extended Capability Register Fields */
@ -194,6 +195,20 @@
#define PCIZ_LN_REQ 0x001c /* LN Requester */ #define PCIZ_LN_REQ 0x001c /* LN Requester */
#define PCIZ_DPC 0x001d /* Downstream Port Containment */ #define PCIZ_DPC 0x001d /* Downstream Port Containment */
#define PCIZ_L1PM 0x001e /* L1 PM Substates */ #define PCIZ_L1PM 0x001e /* L1 PM Substates */
#define PCIZ_PTM 0x001f /* Precision Time Measurement */
#define PCIZ_M_PCIE 0x0020 /* PCIe over M-PHY */
#define PCIZ_FRS 0x0021 /* FRS Queuing */
#define PCIZ_RTR 0x0022 /* Readiness Time Reporting */
#define PCIZ_DVSEC 0x0023 /* Designated Vendor-Specific */
#define PCIZ_VF_REBAR 0x0024 /* VF Resizable BAR */
#define PCIZ_DLNK 0x0025 /* Data Link Feature */
#define PCIZ_16GT 0x0026 /* Physical Layer 16.0 GT/s */
#define PCIZ_LMR 0x0027 /* Lane Margining at Receiver */
#define PCIZ_HIER_ID 0x0028 /* Hierarchy ID */
#define PCIZ_NPEM 0x0029 /* Native PCIe Enclosure Management */
#define PCIZ_PL32 0x002a /* Physical Layer 32.0 GT/s */
#define PCIZ_AP 0x002b /* Alternate Protocol */
#define PCIZ_SFI 0x002c /* System Firmware Intermediary */
/* config registers for header type 0 devices */ /* config registers for header type 0 devices */
@ -334,6 +349,8 @@
#define PCIS_STORAGE_NVM 0x08 #define PCIS_STORAGE_NVM 0x08
#define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01 #define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01
#define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02 #define PCIP_STORAGE_NVM_ENTERPRISE_NVMHCI_1_0 0x02
#define PCIS_STORAGE_UFS 0x09
#define PCIP_STORAGE_UFS_UFSHCI_1_0 0x01
#define PCIS_STORAGE_OTHER 0x80 #define PCIS_STORAGE_OTHER 0x80
#define PCIC_NETWORK 0x02 #define PCIC_NETWORK 0x02
@ -344,6 +361,8 @@
#define PCIS_NETWORK_ISDN 0x04 #define PCIS_NETWORK_ISDN 0x04
#define PCIS_NETWORK_WORLDFIP 0x05 #define PCIS_NETWORK_WORLDFIP 0x05
#define PCIS_NETWORK_PICMG 0x06 #define PCIS_NETWORK_PICMG 0x06
#define PCIS_NETWORK_INFINIBAND 0x07
#define PCIS_NETWORK_HFC 0x08
#define PCIS_NETWORK_OTHER 0x80 #define PCIS_NETWORK_OTHER 0x80
#define PCIC_DISPLAY 0x03 #define PCIC_DISPLAY 0x03
@ -357,6 +376,7 @@
#define PCIS_MULTIMEDIA_AUDIO 0x01 #define PCIS_MULTIMEDIA_AUDIO 0x01
#define PCIS_MULTIMEDIA_TELE 0x02 #define PCIS_MULTIMEDIA_TELE 0x02
#define PCIS_MULTIMEDIA_HDA 0x03 #define PCIS_MULTIMEDIA_HDA 0x03
#define PCIP_MULTIMEDIA_HDA_VENDOR 0x01
#define PCIS_MULTIMEDIA_OTHER 0x80 #define PCIS_MULTIMEDIA_OTHER 0x80
#define PCIC_MEMORY 0x05 #define PCIC_MEMORY 0x05
@ -377,6 +397,8 @@
#define PCIS_BRIDGE_RACEWAY 0x08 #define PCIS_BRIDGE_RACEWAY 0x08
#define PCIS_BRIDGE_PCI_TRANSPARENT 0x09 #define PCIS_BRIDGE_PCI_TRANSPARENT 0x09
#define PCIS_BRIDGE_INFINIBAND 0x0a #define PCIS_BRIDGE_INFINIBAND 0x0a
#define PCIS_BRIDGE_AS_PCI 0x0b
#define PCIS_BRIDGE_AS_PCI_ASI_SIG 0x01
#define PCIS_BRIDGE_OTHER 0x80 #define PCIS_BRIDGE_OTHER 0x80
#define PCIC_SIMPLECOMM 0x07 #define PCIC_SIMPLECOMM 0x07
@ -408,6 +430,7 @@
#define PCIS_BASEPERIPH_PCIHOT 0x04 #define PCIS_BASEPERIPH_PCIHOT 0x04
#define PCIS_BASEPERIPH_SDHC 0x05 #define PCIS_BASEPERIPH_SDHC 0x05
#define PCIS_BASEPERIPH_IOMMU 0x06 #define PCIS_BASEPERIPH_IOMMU 0x06
#define PCIS_BASEPERIPH_RCEC 0x07
#define PCIS_BASEPERIPH_OTHER 0x80 #define PCIS_BASEPERIPH_OTHER 0x80
#define PCIC_INPUTDEV 0x09 #define PCIC_INPUTDEV 0x09
@ -450,6 +473,7 @@
#define PCIP_SERIALBUS_IPMI_BT 0x02 #define PCIP_SERIALBUS_IPMI_BT 0x02
#define PCIS_SERIALBUS_SERCOS 0x08 #define PCIS_SERIALBUS_SERCOS 0x08
#define PCIS_SERIALBUS_CANBUS 0x09 #define PCIS_SERIALBUS_CANBUS 0x09
#define PCIS_SERIALBUS_MIPI_I3C 0x0a
#define PCIC_WIRELESS 0x0d #define PCIC_WIRELESS 0x0d
#define PCIS_WIRELESS_IRDA 0x00 #define PCIS_WIRELESS_IRDA 0x00
@ -459,6 +483,8 @@
#define PCIS_WIRELESS_BROADBAND 0x12 #define PCIS_WIRELESS_BROADBAND 0x12
#define PCIS_WIRELESS_80211A 0x20 #define PCIS_WIRELESS_80211A 0x20
#define PCIS_WIRELESS_80211B 0x21 #define PCIS_WIRELESS_80211B 0x21
#define PCIS_WIRELESS_CELL 0x40
#define PCIS_WIRELESS_CELL_E 0x41
#define PCIS_WIRELESS_OTHER 0x80 #define PCIS_WIRELESS_OTHER 0x80
#define PCIC_INTELLIIO 0x0e #define PCIC_INTELLIIO 0x0e

View File

@ -196,7 +196,7 @@ vtmmio_setup_intr(device_t dev, enum intr_type type)
return (ENXIO); return (ENXIO);
} }
if (bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC | INTR_MPSAFE, if (bus_setup_intr(dev, sc->res[1], type | INTR_MPSAFE,
NULL, vtmmio_vq_intr, sc, &sc->ih)) { NULL, vtmmio_vq_intr, sc, &sc->ih)) {
device_printf(dev, "Can't setup the interrupt\n"); device_printf(dev, "Can't setup the interrupt\n");
return (ENXIO); return (ENXIO);

View File

@ -629,4 +629,5 @@ struct sysent sysent[] = {
{ AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */ { AS(shm_open2_args), (sy_call_t *)sys_shm_open2, AUE_SHMOPEN, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 571 = shm_open2 */
{ AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */ { AS(shm_rename_args), (sy_call_t *)sys_shm_rename, AUE_SHMRENAME, NULL, 0, 0, 0, SY_THR_STATIC }, /* 572 = shm_rename */
{ AS(sigfastblock_args), (sy_call_t *)sys_sigfastblock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 573 = sigfastblock */ { AS(sigfastblock_args), (sy_call_t *)sys_sigfastblock, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 573 = sigfastblock */
{ AS(__realpathat_args), (sy_call_t *)sys___realpathat, AUE_REALPATHAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 574 = __realpathat */
}; };

View File

@ -1035,9 +1035,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
imgp->vmspace_destroyed = 1; imgp->vmspace_destroyed = 1;
imgp->sysent = sv; imgp->sysent = sv;
td->td_pflags &= ~TDP_SIGFASTBLOCK; sigfastblock_clear(td);
td->td_sigblock_ptr = NULL;
td->td_sigblock_val = 0;
/* May be called with Giant held */ /* May be called with Giant held */
EVENTHANDLER_DIRECT_INVOKE(process_exec, p, imgp); EVENTHANDLER_DIRECT_INVOKE(process_exec, p, imgp);

View File

@ -157,6 +157,12 @@ static int kern_lognosys = 0;
SYSCTL_INT(_kern, OID_AUTO, lognosys, CTLFLAG_RWTUN, &kern_lognosys, 0, SYSCTL_INT(_kern, OID_AUTO, lognosys, CTLFLAG_RWTUN, &kern_lognosys, 0,
"Log invalid syscalls"); "Log invalid syscalls");
__read_frequently bool sigfastblock_fetch_always = false;
SYSCTL_BOOL(_kern, OID_AUTO, sigfastblock_fetch_always, CTLFLAG_RWTUN,
&sigfastblock_fetch_always, 0,
"Fetch sigfastblock word on each syscall entry for proper "
"blocking semantic");
SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL); SYSINIT(signal, SI_SUB_P1003_1B, SI_ORDER_FIRST+3, sigqueue_start, NULL);
/* /*
@ -2005,6 +2011,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
code = ksi->ksi_code; code = ksi->ksi_code;
KASSERT(_SIG_VALID(sig), ("invalid signal")); KASSERT(_SIG_VALID(sig), ("invalid signal"));
sigfastblock_fetch(td);
PROC_LOCK(p); PROC_LOCK(p);
ps = p->p_sigacts; ps = p->p_sigacts;
mtx_lock(&ps->ps_mtx); mtx_lock(&ps->ps_mtx);
@ -3952,6 +3959,42 @@ sig_drop_caught(struct proc *p)
} }
} }
static void
sigfastblock_failed(struct thread *td, bool sendsig, bool write)
{
ksiginfo_t ksi;
/*
* Prevent further fetches and SIGSEGVs, allowing thread to
* issue syscalls despite corruption.
*/
sigfastblock_clear(td);
if (!sendsig)
return;
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = SIGSEGV;
ksi.ksi_code = write ? SEGV_ACCERR : SEGV_MAPERR;
ksi.ksi_addr = td->td_sigblock_ptr;
trapsignal(td, &ksi);
}
static bool
sigfastblock_fetch_sig(struct thread *td, bool sendsig, uint32_t *valp)
{
uint32_t res;
if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0)
return (true);
if (fueword32((void *)td->td_sigblock_ptr, &res) == -1) {
sigfastblock_failed(td, sendsig, false);
return (false);
}
*valp = res;
td->td_sigblock_val = res & ~SIGFASTBLOCK_FLAGS;
return (true);
}
int int
sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap) sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
{ {
@ -3960,6 +4003,7 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
uint32_t oldval; uint32_t oldval;
error = 0; error = 0;
p = td->td_proc;
switch (uap->cmd) { switch (uap->cmd) {
case SIGFASTBLOCK_SETPTR: case SIGFASTBLOCK_SETPTR:
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) { if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) {
@ -3975,18 +4019,22 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
break; break;
case SIGFASTBLOCK_UNBLOCK: case SIGFASTBLOCK_UNBLOCK:
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) { if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) {
error = EINVAL; error = EINVAL;
break; break;
} }
again:
res = casueword32(td->td_sigblock_ptr, SIGFASTBLOCK_PEND, for (;;) {
&oldval, 0); res = casueword32(td->td_sigblock_ptr,
if (res == -1) { SIGFASTBLOCK_PEND, &oldval, 0);
error = EFAULT; if (res == -1) {
break; error = EFAULT;
} sigfastblock_failed(td, false, true);
if (res == 1) { break;
}
if (res == 0)
break;
MPASS(res == 1);
if (oldval != SIGFASTBLOCK_PEND) { if (oldval != SIGFASTBLOCK_PEND) {
error = EBUSY; error = EBUSY;
break; break;
@ -3994,8 +4042,22 @@ again:
error = thread_check_susp(td, false); error = thread_check_susp(td, false);
if (error != 0) if (error != 0)
break; break;
goto again;
} }
if (error != 0)
break;
/*
* td_sigblock_val is cleared there, but not on a
* syscall exit. The end effect is that a single
* interruptible sleep, while user sigblock word is
* set, might return EINTR or ERESTART to usermode
* without delivering signal. All further sleeps,
* until userspace clears the word and does
* sigfastblock(UNBLOCK), observe current word and no
* longer get interrupted. It is slight
* non-conformance, with alternative to have read the
* sigblock word on each syscall entry.
*/
td->td_sigblock_val = 0; td->td_sigblock_val = 0;
/* /*
@ -4003,7 +4065,6 @@ again:
* signals to current thread. But notify others about * signals to current thread. But notify others about
* fake unblock. * fake unblock.
*/ */
p = td->td_proc;
if (error == 0 && p->p_numthreads != 1) { if (error == 0 && p->p_numthreads != 1) {
PROC_LOCK(p); PROC_LOCK(p);
reschedule_signals(p, td->td_sigmask, 0); reschedule_signals(p, td->td_sigmask, 0);
@ -4016,8 +4077,7 @@ again:
error = EINVAL; error = EINVAL;
break; break;
} }
res = fueword32(td->td_sigblock_ptr, &oldval); if (!sigfastblock_fetch_sig(td, false, &oldval)) {
if (res == -1) {
error = EFAULT; error = EFAULT;
break; break;
} }
@ -4025,8 +4085,7 @@ again:
error = EBUSY; error = EBUSY;
break; break;
} }
td->td_pflags &= ~TDP_SIGFASTBLOCK; sigfastblock_clear(td);
td->td_sigblock_val = 0;
break; break;
default: default:
@ -4037,32 +4096,59 @@ again:
} }
void void
fetch_sigfastblock(struct thread *td) sigfastblock_clear(struct thread *td)
{ {
struct proc *p;
bool resched;
if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0)
return; return;
if (fueword32(td->td_sigblock_ptr, &td->td_sigblock_val) == -1) { td->td_sigblock_val = 0;
fetch_sigfastblock_failed(td, false); resched = (td->td_pflags & TDP_SIGFASTPENDING) != 0;
return; td->td_pflags &= ~(TDP_SIGFASTBLOCK | TDP_SIGFASTPENDING);
if (resched) {
p = td->td_proc;
PROC_LOCK(p);
reschedule_signals(p, td->td_sigmask, 0);
PROC_UNLOCK(p);
} }
td->td_sigblock_val &= ~SIGFASTBLOCK_FLAGS;
} }
void void
fetch_sigfastblock_failed(struct thread *td, bool write) sigfastblock_fetch(struct thread *td)
{ {
ksiginfo_t ksi; uint32_t val;
/* (void)sigfastblock_fetch_sig(td, true, &val);
* Prevent further fetches and SIGSEGVs, allowing thread to }
* issue syscalls despite corruption.
*/ void
td->td_pflags &= ~TDP_SIGFASTBLOCK; sigfastblock_setpend(struct thread *td)
{
ksiginfo_init_trap(&ksi); int res;
ksi.ksi_signo = SIGSEGV; uint32_t oldval;
ksi.ksi_code = write ? SEGV_ACCERR : SEGV_MAPERR;
ksi.ksi_addr = td->td_sigblock_ptr; if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0)
trapsignal(td, &ksi); return;
res = fueword32((void *)td->td_sigblock_ptr, &oldval);
if (res == -1) {
sigfastblock_failed(td, true, false);
return;
}
for (;;) {
res = casueword32(td->td_sigblock_ptr, oldval, &oldval,
oldval | SIGFASTBLOCK_PEND);
if (res == -1) {
sigfastblock_failed(td, true, true);
return;
}
if (res == 0) {
td->td_sigblock_val = oldval & ~SIGFASTBLOCK_FLAGS;
td->td_pflags &= ~TDP_SIGFASTPENDING;
break;
}
MPASS(res == 1);
if (thread_check_susp(td, false) != 0)
break;
}
} }

View File

@ -132,11 +132,11 @@ syscallenter(struct thread *td)
} }
/* /*
* Fetch fast sigblock value at the time of syscall * Fetch fast sigblock value at the time of syscall entry to
* entry because sleepqueue primitives might call * handle sleepqueue primitives which might call cursig().
* cursig().
*/ */
fetch_sigfastblock(td); if (__predict_false(sigfastblock_fetch_always))
(void)sigfastblock_fetch(td);
/* Let system calls set td_errno directly. */ /* Let system calls set td_errno directly. */
td->td_pflags &= ~TDP_NERRNO; td->td_pflags &= ~TDP_NERRNO;

View File

@ -134,6 +134,7 @@ userret(struct thread *td, struct trapframe *frame)
#ifdef KTRACE #ifdef KTRACE
KTRUSERRET(td); KTRUSERRET(td);
#endif #endif
td_softdep_cleanup(td); td_softdep_cleanup(td);
MPASS(td->td_su == NULL); MPASS(td->td_su == NULL);
@ -222,8 +223,7 @@ ast(struct trapframe *framep)
{ {
struct thread *td; struct thread *td;
struct proc *p; struct proc *p;
uint32_t oldval; int flags, sig;
int flags, sig, res;
td = curthread; td = curthread;
p = td->td_proc; p = td->td_proc;
@ -325,11 +325,12 @@ ast(struct trapframe *framep)
*/ */
if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 || if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 ||
!SIGISEMPTY(p->p_siglist)) { !SIGISEMPTY(p->p_siglist)) {
fetch_sigfastblock(td); sigfastblock_fetch(td);
PROC_LOCK(p); PROC_LOCK(p);
mtx_lock(&p->p_sigacts->ps_mtx); mtx_lock(&p->p_sigacts->ps_mtx);
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 && if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 &&
td->td_sigblock_val != 0) { td->td_sigblock_val != 0) {
sigfastblock_setpend(td);
reschedule_signals(p, fastblock_mask, reschedule_signals(p, fastblock_mask,
SIGPROCMASK_PS_LOCKED | SIGPROCMASK_FASTBLK); SIGPROCMASK_PS_LOCKED | SIGPROCMASK_FASTBLK);
} else { } else {
@ -346,32 +347,8 @@ ast(struct trapframe *framep)
* Handle deferred update of the fast sigblock value, after * Handle deferred update of the fast sigblock value, after
* the postsig() loop was performed. * the postsig() loop was performed.
*/ */
if (td->td_pflags & TDP_SIGFASTPENDING) { if (td->td_pflags & TDP_SIGFASTPENDING)
td->td_pflags &= ~TDP_SIGFASTPENDING; sigfastblock_setpend(td);
res = fueword32(td->td_sigblock_ptr, &oldval);
if (res == -1) {
fetch_sigfastblock_failed(td, false);
} else {
for (;;) {
oldval |= SIGFASTBLOCK_PEND;
res = casueword32(td->td_sigblock_ptr, oldval,
&oldval, oldval | SIGFASTBLOCK_PEND);
if (res == -1) {
fetch_sigfastblock_failed(td, true);
break;
}
if (res == 0) {
td->td_sigblock_val = oldval &
~SIGFASTBLOCK_FLAGS;
break;
}
MPASS(res == 1);
res = thread_check_susp(td, false);
if (res != 0)
break;
}
}
}
/* /*
* We need to check to see if we have to exit or wait due to a * We need to check to see if we have to exit or wait due to a

View File

@ -580,4 +580,5 @@ const char *syscallnames[] = {
"shm_open2", /* 571 = shm_open2 */ "shm_open2", /* 571 = shm_open2 */
"shm_rename", /* 572 = shm_rename */ "shm_rename", /* 572 = shm_rename */
"sigfastblock", /* 573 = sigfastblock */ "sigfastblock", /* 573 = sigfastblock */
"__realpathat", /* 574 = __realpathat */
}; };

View File

@ -3218,6 +3218,15 @@
_Inout_opt_ uint32_t *ptr _Inout_opt_ uint32_t *ptr
); );
} }
574 AUE_REALPATHAT STD {
int __realpathat(
int fd,
_In_z_ const char *path,
_Out_writes_z_(size) char *buf,
size_t size,
int flags
);
}
; Please copy any additions and changes to the following compatability tables: ; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master ; sys/compat/freebsd32/syscalls.master

View File

@ -3355,6 +3355,17 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 2; *n_args = 2;
break; break;
} }
/* __realpathat */
case 574: {
struct __realpathat_args *p = params;
iarg[0] = p->fd; /* int */
uarg[1] = (intptr_t) p->path; /* const char * */
uarg[2] = (intptr_t) p->buf; /* char * */
uarg[3] = p->size; /* size_t */
iarg[4] = p->flags; /* int */
*n_args = 5;
break;
}
default: default:
*n_args = 0; *n_args = 0;
break; break;
@ -8967,6 +8978,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break; break;
}; };
break; break;
/* __realpathat */
case 574:
switch(ndx) {
case 0:
p = "int";
break;
case 1:
p = "userland const char *";
break;
case 2:
p = "userland char *";
break;
case 3:
p = "size_t";
break;
case 4:
p = "int";
break;
default:
break;
};
break;
default: default:
break; break;
}; };
@ -10888,6 +10921,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1) if (ndx == 0 || ndx == 1)
p = "int"; p = "int";
break; break;
/* __realpathat */
case 574:
if (ndx == 0 || ndx == 1)
p = "int";
break;
default: default:
break; break;
}; };

View File

@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h> #include <sys/param.h>
#include <sys/systm.h> #include <sys/systm.h>
#include <sys/capsicum.h>
#include <sys/counter.h> #include <sys/counter.h>
#include <sys/filedesc.h> #include <sys/filedesc.h>
#include <sys/fnv_hash.h> #include <sys/fnv_hash.h>
@ -387,8 +388,12 @@ STATNODE_COUNTER(shrinking_skipped,
"Number of times shrinking was already in progress"); "Number of times shrinking was already in progress");
static void cache_zap_locked(struct namecache *ncp, bool neg_locked); static void cache_zap_locked(struct namecache *ncp, bool neg_locked);
static int vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, static int vn_fullpath_hardlink(struct thread *td, struct nameidata *ndp, char **retbuf,
char **freebuf, size_t *buflen);
static int vn_fullpath_any(struct thread *td, struct vnode *vp, struct vnode *rdir,
char *buf, char **retbuf, size_t *buflen); char *buf, char **retbuf, size_t *buflen);
static int vn_fullpath_dir(struct thread *td, struct vnode *vp, struct vnode *rdir,
char *buf, char **retbuf, size_t *len, bool slash_prefixed, size_t addend);
static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries"); static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries");
@ -2201,7 +2206,7 @@ vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen)
rdir = fdp->fd_rdir; rdir = fdp->fd_rdir;
vrefact(rdir); vrefact(rdir);
FILEDESC_SUNLOCK(fdp); FILEDESC_SUNLOCK(fdp);
error = vn_fullpath1(td, cdir, rdir, buf, retbuf, buflen); error = vn_fullpath_any(td, cdir, rdir, buf, retbuf, buflen);
vrele(rdir); vrele(rdir);
vrele(cdir); vrele(cdir);
@ -2212,6 +2217,37 @@ vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen)
return (error); return (error);
} }
static int
kern___realpathat(struct thread *td, int fd, const char *path, char *buf,
size_t size, int flags, enum uio_seg pathseg)
{
struct nameidata nd;
char *retbuf, *freebuf;
int error;
if (flags != 0)
return (EINVAL);
NDINIT_ATRIGHTS(&nd, LOOKUP, FOLLOW | SAVENAME | WANTPARENT | AUDITVNODE1,
pathseg, path, fd, &cap_fstat_rights, td);
if ((error = namei(&nd)) != 0)
return (error);
error = vn_fullpath_hardlink(td, &nd, &retbuf, &freebuf, &size);
if (error == 0) {
error = copyout(retbuf, buf, size);
free(freebuf, M_TEMP);
}
NDFREE(&nd, 0);
return (error);
}
int
sys___realpathat(struct thread *td, struct __realpathat_args *uap)
{
return (kern___realpathat(td, uap->fd, uap->path, uap->buf, uap->size,
uap->flags, UIO_USERSPACE));
}
/* /*
* Retrieve the full filesystem path that correspond to a vnode from the name * Retrieve the full filesystem path that correspond to a vnode from the name
* cache (if available) * cache (if available)
@ -2235,7 +2271,7 @@ vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
rdir = fdp->fd_rdir; rdir = fdp->fd_rdir;
vrefact(rdir); vrefact(rdir);
FILEDESC_SUNLOCK(fdp); FILEDESC_SUNLOCK(fdp);
error = vn_fullpath1(td, vn, rdir, buf, retbuf, &buflen); error = vn_fullpath_any(td, vn, rdir, buf, retbuf, &buflen);
vrele(rdir); vrele(rdir);
if (!error) if (!error)
@ -2263,7 +2299,7 @@ vn_fullpath_global(struct thread *td, struct vnode *vn,
return (EINVAL); return (EINVAL);
buflen = MAXPATHLEN; buflen = MAXPATHLEN;
buf = malloc(buflen, M_TEMP, M_WAITOK); buf = malloc(buflen, M_TEMP, M_WAITOK);
error = vn_fullpath1(td, vn, rootvnode, buf, retbuf, &buflen); error = vn_fullpath_any(td, vn, rootvnode, buf, retbuf, &buflen);
if (!error) if (!error)
*freebuf = buf; *freebuf = buf;
else else
@ -2334,40 +2370,40 @@ vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, size_t *buflen)
} }
/* /*
* The magic behind vn_getcwd() and vn_fullpath(). * Resolve a directory to a pathname.
*
* The name of the directory can always be found in the namecache or fetched
* from the filesystem. There is also guaranteed to be only one parent, meaning
* we can just follow vnodes up until we find the root.
*
* The vnode must be referenced.
*/ */
static int static int
vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, vn_fullpath_dir(struct thread *td, struct vnode *vp, struct vnode *rdir,
char *buf, char **retbuf, size_t *len) char *buf, char **retbuf, size_t *len, bool slash_prefixed, size_t addend)
{ {
int error, slash_prefixed;
#ifdef KDTRACE_HOOKS #ifdef KDTRACE_HOOKS
struct vnode *startvp = vp; struct vnode *startvp = vp;
#endif #endif
struct vnode *vp1; struct vnode *vp1;
size_t buflen; size_t buflen;
int error;
VNPASS(vp->v_type == VDIR || VN_IS_DOOMED(vp), vp);
VNPASS(vp->v_usecount > 0, vp);
buflen = *len; buflen = *len;
buflen--; if (!slash_prefixed) {
buf[buflen] = '\0'; MPASS(*len >= 2);
buflen--;
buf[buflen] = '\0';
}
error = 0; error = 0;
slash_prefixed = 0;
SDT_PROBE1(vfs, namecache, fullpath, entry, vp); SDT_PROBE1(vfs, namecache, fullpath, entry, vp);
counter_u64_add(numfullpathcalls, 1); counter_u64_add(numfullpathcalls, 1);
vref(vp);
if (vp->v_type != VDIR) {
error = vn_vptocnp(&vp, td->td_ucred, buf, &buflen);
if (error)
return (error);
if (buflen == 0) {
vrele(vp);
return (ENOMEM);
}
buf[--buflen] = '/';
slash_prefixed = 1;
}
while (vp != rdir && vp != rootvnode) { while (vp != rdir && vp != rootvnode) {
/* /*
* The vp vnode must be already fully constructed, * The vp vnode must be already fully constructed,
@ -2420,7 +2456,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
break; break;
} }
buf[--buflen] = '/'; buf[--buflen] = '/';
slash_prefixed = 1; slash_prefixed = true;
} }
if (error) if (error)
return (error); return (error);
@ -2437,12 +2473,128 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
counter_u64_add(numfullpathfound, 1); counter_u64_add(numfullpathfound, 1);
vrele(vp); vrele(vp);
SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen);
*retbuf = buf + buflen; *retbuf = buf + buflen;
SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, *retbuf);
*len -= buflen; *len -= buflen;
*len += addend;
return (0); return (0);
} }
/*
* Resolve an arbitrary vnode to a pathname.
*
* Note 2 caveats:
* - hardlinks are not tracked, thus if the vnode is not a directory this can
* resolve to a different path than the one used to find it
* - namecache is not mandatory, meaning names are not guaranteed to be added
* (in which case resolving fails)
*/
static int
vn_fullpath_any(struct thread *td, struct vnode *vp, struct vnode *rdir,
char *buf, char **retbuf, size_t *buflen)
{
size_t orig_buflen;
bool slash_prefixed;
int error;
if (*buflen < 2)
return (EINVAL);
orig_buflen = *buflen;
vref(vp);
slash_prefixed = false;
if (vp->v_type != VDIR) {
*buflen -= 1;
buf[*buflen] = '\0';
error = vn_vptocnp(&vp, td->td_ucred, buf, buflen);
if (error)
return (error);
if (*buflen == 0) {
vrele(vp);
return (ENOMEM);
}
*buflen -= 1;
buf[*buflen] = '/';
slash_prefixed = true;
}
return (vn_fullpath_dir(td, vp, rdir, buf, retbuf, buflen, slash_prefixed,
orig_buflen - *buflen));
}
/*
* Resolve an arbitrary vnode to a pathname (taking care of hardlinks).
*
* Since the namecache does not track handlings, the caller is expected to first
* look up the target vnode with SAVENAME | WANTPARENT flags passed to namei.
*
* Then we have 2 cases:
* - if the found vnode is a directory, the path can be constructed just by
* fullowing names up the chain
* - otherwise we populate the buffer with the saved name and start resolving
* from the parent
*/
static int
vn_fullpath_hardlink(struct thread *td, struct nameidata *ndp, char **retbuf,
char **freebuf, size_t *buflen)
{
char *buf, *tmpbuf;
struct filedesc *fdp;
struct vnode *rdir;
struct componentname *cnp;
struct vnode *vp;
size_t addend;
int error;
bool slash_prefixed;
if (*buflen < 2)
return (EINVAL);
if (*buflen > MAXPATHLEN)
*buflen = MAXPATHLEN;
slash_prefixed = false;
buf = malloc(*buflen, M_TEMP, M_WAITOK);
fdp = td->td_proc->p_fd;
FILEDESC_SLOCK(fdp);
rdir = fdp->fd_rdir;
vrefact(rdir);
FILEDESC_SUNLOCK(fdp);
addend = 0;
vp = ndp->ni_vp;
if (vp->v_type != VDIR) {
cnp = &ndp->ni_cnd;
addend = cnp->cn_namelen + 2;
if (*buflen < addend) {
error = ENOMEM;
goto out_bad;
}
*buflen -= addend;
tmpbuf = buf + *buflen;
tmpbuf[0] = '/';
memcpy(&tmpbuf[1], cnp->cn_nameptr, cnp->cn_namelen);
tmpbuf[addend - 1] = '\0';
slash_prefixed = true;
vp = ndp->ni_dvp;
}
vref(vp);
error = vn_fullpath_dir(td, vp, rdir, buf, retbuf, buflen, slash_prefixed, addend);
if (error != 0)
goto out_bad;
vrele(rdir);
*freebuf = buf;
return (0);
out_bad:
vrele(rdir);
free(buf, M_TEMP);
return (error);
}
struct vnode * struct vnode *
vn_dir_dd_ino(struct vnode *vp) vn_dir_dd_ino(struct vnode *vp)
{ {

View File

@ -543,14 +543,13 @@ __FBSDID("$FreeBSD$");
#define SCTP_TIMER_TYPE_ASCONF 10 #define SCTP_TIMER_TYPE_ASCONF 10
#define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11 #define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11
#define SCTP_TIMER_TYPE_AUTOCLOSE 12 #define SCTP_TIMER_TYPE_AUTOCLOSE 12
#define SCTP_TIMER_TYPE_EVENTWAKE 13 #define SCTP_TIMER_TYPE_STRRESET 13
#define SCTP_TIMER_TYPE_STRRESET 14 #define SCTP_TIMER_TYPE_INPKILL 14
#define SCTP_TIMER_TYPE_INPKILL 15 #define SCTP_TIMER_TYPE_ASOCKILL 15
#define SCTP_TIMER_TYPE_ASOCKILL 16 #define SCTP_TIMER_TYPE_ADDR_WQ 16
#define SCTP_TIMER_TYPE_ADDR_WQ 17 #define SCTP_TIMER_TYPE_PRIM_DELETED 17
#define SCTP_TIMER_TYPE_PRIM_DELETED 18
/* add new timers here - and increment LAST */ /* add new timers here - and increment LAST */
#define SCTP_TIMER_TYPE_LAST 19 #define SCTP_TIMER_TYPE_LAST 18
#define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \ #define SCTP_IS_TIMER_TYPE_VALID(t) (((t) > SCTP_TIMER_TYPE_NONE) && \
((t) < SCTP_TIMER_TYPE_LAST)) ((t) < SCTP_TIMER_TYPE_LAST))

View File

@ -156,10 +156,10 @@ static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
/* /*
* Make an extension header from option data. hp is the source, and * Make an extension header from option data. hp is the source,
* mp is the destination. * mp is the destination, and _ol is the optlen.
*/ */
#define MAKE_EXTHDR(hp, mp) \ #define MAKE_EXTHDR(hp, mp, _ol) \
do { \ do { \
if (hp) { \ if (hp) { \
struct ip6_ext *eh = (struct ip6_ext *)(hp); \ struct ip6_ext *eh = (struct ip6_ext *)(hp); \
@ -167,6 +167,7 @@ static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int);
((eh)->ip6e_len + 1) << 3); \ ((eh)->ip6e_len + 1) << 3); \
if (error) \ if (error) \
goto freehdrs; \ goto freehdrs; \
(_ol) += (*(mp))->m_len; \
} \ } \
} while (/*CONSTCOND*/ 0) } while (/*CONSTCOND*/ 0)
@ -384,22 +385,23 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
struct ip6_hdr *ip6; struct ip6_hdr *ip6;
struct ifnet *ifp, *origifp; struct ifnet *ifp, *origifp;
struct mbuf *m = m0; struct mbuf *m = m0;
struct mbuf *mprev = NULL; struct mbuf *mprev;
int hlen, tlen, len; int hlen, tlen, len;
struct route_in6 ip6route; struct route_in6 ip6route;
struct rtentry *rt = NULL; struct rtentry *rt = NULL;
struct sockaddr_in6 *dst, src_sa, dst_sa; struct sockaddr_in6 *dst, src_sa, dst_sa;
struct in6_addr odst; struct in6_addr odst;
u_char *nexthdrp;
int error = 0; int error = 0;
struct in6_ifaddr *ia = NULL; struct in6_ifaddr *ia = NULL;
u_long mtu; u_long mtu;
int alwaysfrag, dontfrag; int alwaysfrag, dontfrag;
u_int32_t optlen = 0, plen = 0, unfragpartlen = 0; u_int32_t optlen, plen = 0, unfragpartlen;
struct ip6_exthdrs exthdrs; struct ip6_exthdrs exthdrs;
struct in6_addr src0, dst0; struct in6_addr src0, dst0;
u_int32_t zone; u_int32_t zone;
struct route_in6 *ro_pmtu = NULL; struct route_in6 *ro_pmtu = NULL;
int hdrsplit = 0; bool hdrsplit;
int sw_csum, tso; int sw_csum, tso;
int needfiblookup; int needfiblookup;
uint32_t fibnum; uint32_t fibnum;
@ -436,12 +438,49 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
} }
#endif /* IPSEC */ #endif /* IPSEC */
/* Source address validation. */
ip6 = mtod(m, struct ip6_hdr *);
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) &&
(flags & IPV6_UNSPECSRC) == 0) {
error = EOPNOTSUPP;
IP6STAT_INC(ip6s_badscope);
goto bad;
}
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
error = EOPNOTSUPP;
IP6STAT_INC(ip6s_badscope);
goto bad;
}
/*
* If we are given packet options to add extension headers prepare them.
* Calculate the total length of the extension header chain.
* Keep the length of the unfragmentable part for fragmentation.
*/
bzero(&exthdrs, sizeof(exthdrs)); bzero(&exthdrs, sizeof(exthdrs));
optlen = 0;
unfragpartlen = 0;
if (opt) { if (opt) {
/* Hop-by-Hop options header. */ /* Hop-by-Hop options header. */
MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh); MAKE_EXTHDR(opt->ip6po_hbh, &exthdrs.ip6e_hbh, optlen);
/* Destination options header (1st part). */ /* Destination options header (1st part). */
if (opt->ip6po_rthdr) { if (opt->ip6po_rthdr) {
#ifndef RTHDR_SUPPORT_IMPLEMENTED
/*
* If there is a routing header, discard the packet
* right away here. RH0/1 are obsolete and we do not
* currently support RH2/3/4.
* People trying to use RH253/254 may want to disable
* this check.
* The moment we do support any routing header (again)
* this block should check the routing type more
* selectively.
*/
error = EINVAL;
goto bad;
#endif
/* /*
* Destination options header (1st part). * Destination options header (1st part).
* This only makes sense with a routing header. * This only makes sense with a routing header.
@ -452,46 +491,38 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
* options, which might automatically be inserted in * options, which might automatically be inserted in
* the kernel. * the kernel.
*/ */
MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1); MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1,
optlen);
} }
/* Routing header. */ /* Routing header. */
MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr); MAKE_EXTHDR(opt->ip6po_rthdr, &exthdrs.ip6e_rthdr, optlen);
unfragpartlen = optlen + sizeof(struct ip6_hdr);
/*
* NOTE: we don't add AH/ESP length here (done in
* ip6_ipsec_output()).
*/
/* Destination options header (2nd part). */ /* Destination options header (2nd part). */
MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2); MAKE_EXTHDR(opt->ip6po_dest2, &exthdrs.ip6e_dest2, optlen);
} }
/*
* Calculate the total length of the extension header chain.
* Keep the length of the unfragmentable part for fragmentation.
*/
optlen = 0;
if (exthdrs.ip6e_hbh)
optlen += exthdrs.ip6e_hbh->m_len;
if (exthdrs.ip6e_dest1)
optlen += exthdrs.ip6e_dest1->m_len;
if (exthdrs.ip6e_rthdr)
optlen += exthdrs.ip6e_rthdr->m_len;
unfragpartlen = optlen + sizeof(struct ip6_hdr);
/* NOTE: we don't add AH/ESP length here (done in ip6_ipsec_output). */
if (exthdrs.ip6e_dest2)
optlen += exthdrs.ip6e_dest2->m_len;
/* /*
* If there is at least one extension header, * If there is at least one extension header,
* separate IP6 header from the payload. * separate IP6 header from the payload.
*/ */
if (optlen && !hdrsplit) { hdrsplit = false;
if (optlen) {
if ((error = ip6_splithdr(m, &exthdrs)) != 0) { if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
m = NULL; m = NULL;
goto freehdrs; goto freehdrs;
} }
m = exthdrs.ip6e_ip6; m = exthdrs.ip6e_ip6;
hdrsplit++; ip6 = mtod(m, struct ip6_hdr *);
hdrsplit = true;
} }
ip6 = mtod(m, struct ip6_hdr *);
/* Adjust mbuf packet header length. */ /* Adjust mbuf packet header length. */
m->m_pkthdr.len += optlen; m->m_pkthdr.len += optlen;
plen = m->m_pkthdr.len - sizeof(*ip6); plen = m->m_pkthdr.len - sizeof(*ip6);
@ -504,77 +535,59 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
goto freehdrs; goto freehdrs;
} }
m = exthdrs.ip6e_ip6; m = exthdrs.ip6e_ip6;
hdrsplit++; ip6 = mtod(m, struct ip6_hdr *);
hdrsplit = true;
} }
/* Adjust pointer. */
ip6 = mtod(m, struct ip6_hdr *);
if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0) if ((error = ip6_insert_jumboopt(&exthdrs, plen)) != 0)
goto freehdrs; goto freehdrs;
ip6->ip6_plen = 0; ip6->ip6_plen = 0;
} else } else
ip6->ip6_plen = htons(plen); ip6->ip6_plen = htons(plen);
nexthdrp = &ip6->ip6_nxt;
/* if (optlen) {
* Concatenate headers and fill in next header fields. /*
* Here we have, on "m" * Concatenate headers and fill in next header fields.
* IPv6 payload * Here we have, on "m"
* and we insert headers accordingly. * IPv6 payload
* Finally, we should be getting: * and we insert headers accordingly.
* IPv6 hbh dest1 rthdr ah* [esp* dest2 payload]. * Finally, we should be getting:
* * IPv6 hbh dest1 rthdr ah* [esp* dest2 payload].
* During the header composing process "m" points to IPv6 *
* header. "mprev" points to an extension header prior to esp. * During the header composing process "m" points to IPv6
*/ * header. "mprev" points to an extension header prior to esp.
u_char *nexthdrp = &ip6->ip6_nxt; */
mprev = m; mprev = m;
/* /*
* We treat dest2 specially. This makes IPsec processing * We treat dest2 specially. This makes IPsec processing
* much easier. The goal here is to make mprev point the * much easier. The goal here is to make mprev point the
* mbuf prior to dest2. * mbuf prior to dest2.
* *
* Result: IPv6 dest2 payload. * Result: IPv6 dest2 payload.
* m and mprev will point to IPv6 header. * m and mprev will point to IPv6 header.
*/ */
if (exthdrs.ip6e_dest2) { if (exthdrs.ip6e_dest2) {
if (!hdrsplit) if (!hdrsplit)
panic("%s:%d: assumption failed: " panic("%s:%d: assumption failed: "
"hdr not split: hdrsplit %d exthdrs %p", "hdr not split: hdrsplit %d exthdrs %p",
__func__, __LINE__, hdrsplit, &exthdrs); __func__, __LINE__, hdrsplit, &exthdrs);
exthdrs.ip6e_dest2->m_next = m->m_next; exthdrs.ip6e_dest2->m_next = m->m_next;
m->m_next = exthdrs.ip6e_dest2; m->m_next = exthdrs.ip6e_dest2;
*mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt; *mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
ip6->ip6_nxt = IPPROTO_DSTOPTS; ip6->ip6_nxt = IPPROTO_DSTOPTS;
} }
/* /*
* Result: IPv6 hbh dest1 rthdr dest2 payload. * Result: IPv6 hbh dest1 rthdr dest2 payload.
* m will point to IPv6 header. mprev will point to the * m will point to IPv6 header. mprev will point to the
* extension header prior to dest2 (rthdr in the above case). * extension header prior to dest2 (rthdr in the above case).
*/ */
MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS); MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp, MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
IPPROTO_DSTOPTS); IPPROTO_DSTOPTS);
MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp, MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
IPPROTO_ROUTING); IPPROTO_ROUTING);
/* If there is a routing header, discard the packet. */
if (exthdrs.ip6e_rthdr) {
error = EINVAL;
goto bad;
}
/* Source address validation. */
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) &&
(flags & IPV6_UNSPECSRC) == 0) {
error = EOPNOTSUPP;
IP6STAT_INC(ip6s_badscope);
goto bad;
}
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
error = EOPNOTSUPP;
IP6STAT_INC(ip6s_badscope);
goto bad;
} }
IP6STAT_INC(ip6s_localout); IP6STAT_INC(ip6s_localout);

View File

@ -830,6 +830,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
case AUE_UNLINK: case AUE_UNLINK:
case AUE_UNLINKAT: case AUE_UNLINKAT:
case AUE_UTIMES: case AUE_UTIMES:
case AUE_REALPATHAT:
ATFD1_TOKENS(1); ATFD1_TOKENS(1);
UPATH1_VNODE1_TOKENS; UPATH1_VNODE1_TOKENS;
break; break;

View File

@ -60,7 +60,7 @@
* in the range 5 to 9. * in the range 5 to 9.
*/ */
#undef __FreeBSD_version #undef __FreeBSD_version
#define __FreeBSD_version 1300078 /* Master, propagated to newvers */ #define __FreeBSD_version 1300080 /* Master, propagated to newvers */
/* /*
* __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

View File

@ -273,6 +273,7 @@ int __sys_sigfastblock(int cmd, void *ptr);
#ifdef _KERNEL #ifdef _KERNEL
extern sigset_t fastblock_mask; extern sigset_t fastblock_mask;
extern bool sigfastblock_fetch_always;
/* Return nonzero if process p has an unmasked pending signal. */ /* Return nonzero if process p has an unmasked pending signal. */
#define SIGPENDING(td) \ #define SIGPENDING(td) \
@ -382,8 +383,6 @@ sigallowstop(int prev)
int cursig(struct thread *td); int cursig(struct thread *td);
void execsigs(struct proc *p); void execsigs(struct proc *p);
void fetch_sigfastblock(struct thread *td);
void fetch_sigfastblock_failed(struct thread *td, bool write);
void gsignal(int pgid, int sig, ksiginfo_t *ksi); void gsignal(int pgid, int sig, ksiginfo_t *ksi);
void killproc(struct proc *p, char *why); void killproc(struct proc *p, char *why);
ksiginfo_t * ksiginfo_alloc(int wait); ksiginfo_t * ksiginfo_alloc(int wait);
@ -405,6 +404,9 @@ void sig_drop_caught(struct proc *p);
void sigexit(struct thread *td, int sig) __dead2; void sigexit(struct thread *td, int sig) __dead2;
int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **); int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **);
int sig_ffs(sigset_t *set); int sig_ffs(sigset_t *set);
void sigfastblock_clear(struct thread *td);
void sigfastblock_fetch(struct thread *td);
void sigfastblock_setpend(struct thread *td);
void siginit(struct proc *p); void siginit(struct proc *p);
void signotify(struct thread *td); void signotify(struct thread *td);
void sigqueue_delete(struct sigqueue *queue, int sig); void sigqueue_delete(struct sigqueue *queue, int sig);

View File

@ -509,4 +509,5 @@
#define SYS_shm_open2 571 #define SYS_shm_open2 571
#define SYS_shm_rename 572 #define SYS_shm_rename 572
#define SYS_sigfastblock 573 #define SYS_sigfastblock 573
#define SYS_MAXSYSCALL 574 #define SYS___realpathat 574
#define SYS_MAXSYSCALL 575

View File

@ -414,4 +414,5 @@ MIASM = \
__sysctlbyname.o \ __sysctlbyname.o \
shm_open2.o \ shm_open2.o \
shm_rename.o \ shm_rename.o \
sigfastblock.o sigfastblock.o \
__realpathat.o

View File

@ -1823,6 +1823,13 @@ struct sigfastblock_args {
char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)]; char cmd_l_[PADL_(int)]; int cmd; char cmd_r_[PADR_(int)];
char ptr_l_[PADL_(uint32_t *)]; uint32_t * ptr; char ptr_r_[PADR_(uint32_t *)]; char ptr_l_[PADL_(uint32_t *)]; uint32_t * ptr; char ptr_r_[PADR_(uint32_t *)];
}; };
struct __realpathat_args {
char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
char path_l_[PADL_(const char *)]; const char * path; char path_r_[PADR_(const char *)];
char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
char size_l_[PADL_(size_t)]; size_t size; char size_r_[PADR_(size_t)];
char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)];
};
int nosys(struct thread *, struct nosys_args *); int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *); void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *); int sys_fork(struct thread *, struct fork_args *);
@ -2212,6 +2219,7 @@ int sys___sysctlbyname(struct thread *, struct __sysctlbyname_args *);
int sys_shm_open2(struct thread *, struct shm_open2_args *); int sys_shm_open2(struct thread *, struct shm_open2_args *);
int sys_shm_rename(struct thread *, struct shm_rename_args *); int sys_shm_rename(struct thread *, struct shm_rename_args *);
int sys_sigfastblock(struct thread *, struct sigfastblock_args *); int sys_sigfastblock(struct thread *, struct sigfastblock_args *);
int sys___realpathat(struct thread *, struct __realpathat_args *);
#ifdef COMPAT_43 #ifdef COMPAT_43
@ -3136,6 +3144,7 @@ int freebsd12_shm_open(struct thread *, struct freebsd12_shm_open_args *);
#define SYS_AUE_shm_open2 AUE_SHMOPEN #define SYS_AUE_shm_open2 AUE_SHMOPEN
#define SYS_AUE_shm_rename AUE_SHMRENAME #define SYS_AUE_shm_rename AUE_SHMRENAME
#define SYS_AUE_sigfastblock AUE_NULL #define SYS_AUE_sigfastblock AUE_NULL
#define SYS_AUE___realpathat AUE_REALPATHAT
#undef PAD_ #undef PAD_
#undef PADL_ #undef PADL_

View File

@ -208,6 +208,8 @@ vm_radix_node_load(smrnode_t *p, enum vm_radix_access access)
case SMR: case SMR:
return (smr_entered_load(p, vm_radix_smr)); return (smr_entered_load(p, vm_radix_smr));
} }
/* This is unreachable, silence gcc. */
panic("vm_radix_node_get: Unknown access type");
} }
static __inline void static __inline void

View File

@ -628,8 +628,11 @@ vnode_pager_input_smlfs(vm_object_t object, vm_page_t m)
bwait(bp, PVM, "vnsrd"); bwait(bp, PVM, "vnsrd");
if ((bp->b_ioflags & BIO_ERROR) != 0) if ((bp->b_ioflags & BIO_ERROR) != 0) {
error = EIO; KASSERT(bp->b_error != 0,
("%s: buf error but b_error == 0\n", __func__));
error = bp->b_error;
}
/* /*
* free the buffer header back to the swap buffer pool * free the buffer header back to the swap buffer pool
@ -1113,7 +1116,9 @@ vnode_pager_generic_getpages_done(struct buf *bp)
off_t tfoff, nextoff; off_t tfoff, nextoff;
int i, error; int i, error;
error = (bp->b_ioflags & BIO_ERROR) != 0 ? EIO : 0; KASSERT((bp->b_ioflags & BIO_ERROR) == 0 || bp->b_error != 0,
("%s: buf error but b_error == 0\n", __func__));
error = (bp->b_ioflags & BIO_ERROR) != 0 ? bp->b_error : 0;
object = bp->b_vp->v_object; object = bp->b_vp->v_object;
if (error == 0 && bp->b_bcount != bp->b_npages * PAGE_SIZE) { if (error == 0 && bp->b_bcount != bp->b_npages * PAGE_SIZE) {
@ -1169,8 +1174,6 @@ vnode_pager_generic_getpages_done(struct buf *bp)
vm_page_readahead_finish(mt); vm_page_readahead_finish(mt);
} }
VM_OBJECT_RUNLOCK(object); VM_OBJECT_RUNLOCK(object);
if (error != 0)
printf("%s: I/O read error %d\n", __func__, error);
return (error); return (error);
} }

View File

@ -115,6 +115,9 @@ static struct syscall decoded_syscalls[] = {
.args = { { Int, 0 }, { Int, 1 }, { CapRights | OUT, 2 } } }, .args = { { Int, 0 }, { Int, 1 }, { CapRights | OUT, 2 } } },
{ .name = "__getcwd", .ret_type = 1, .nargs = 2, { .name = "__getcwd", .ret_type = 1, .nargs = 2,
.args = { { Name | OUT, 0 }, { Int, 1 } } }, .args = { { Name | OUT, 0 }, { Int, 1 } } },
{ .name = "__realpathat", .ret_type = 1, .nargs = 5,
.args = { { Atfd, 0 }, { Name | IN, 1 }, { Name | OUT, 2 },
{ Sizet, 3 }, { Int, 4} } },
{ .name = "_umtx_op", .ret_type = 1, .nargs = 5, { .name = "_umtx_op", .ret_type = 1, .nargs = 5,
.args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 }, .args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 },
{ Ptr, 4 } } }, { Ptr, 4 } } },

View File

@ -1015,6 +1015,20 @@ static struct {
{ PCIZ_LN_REQ, "LN Requester" }, { PCIZ_LN_REQ, "LN Requester" },
{ PCIZ_DPC, "Downstream Port Containment" }, { PCIZ_DPC, "Downstream Port Containment" },
{ PCIZ_L1PM, "L1 PM Substates" }, { PCIZ_L1PM, "L1 PM Substates" },
{ PCIZ_PTM, "Precision Time Measurement" },
{ PCIZ_M_PCIE, "PCIe over M-PHY" },
{ PCIZ_FRS, "FRS Queuing" },
{ PCIZ_RTR, "Readiness Time Reporting" },
{ PCIZ_DVSEC, "Designated Vendor-Specific" },
{ PCIZ_VF_REBAR, "VF Resizable BAR" },
{ PCIZ_DLNK, "Data Link Feature" },
{ PCIZ_16GT, "Physical Layer 16.0 GT/s" },
{ PCIZ_LMR, "Lane Margining at Receiver" },
{ PCIZ_HIER_ID, "Hierarchy ID" },
{ PCIZ_NPEM, "Native PCIe Enclosure Management" },
{ PCIZ_PL32, "Physical Layer 32.0 GT/s" },
{ PCIZ_AP, "Alternate Protocol" },
{ PCIZ_SFI, "System Firmware Intermediary" },
{ 0, NULL } { 0, NULL }
}; };

View File

@ -665,12 +665,17 @@ static struct
{PCIC_STORAGE, PCIS_STORAGE_SATA, "SATA"}, {PCIC_STORAGE, PCIS_STORAGE_SATA, "SATA"},
{PCIC_STORAGE, PCIS_STORAGE_SAS, "SAS"}, {PCIC_STORAGE, PCIS_STORAGE_SAS, "SAS"},
{PCIC_STORAGE, PCIS_STORAGE_NVM, "NVM"}, {PCIC_STORAGE, PCIS_STORAGE_NVM, "NVM"},
{PCIC_STORAGE, PCIS_STORAGE_UFS, "UFS"},
{PCIC_NETWORK, -1, "network"}, {PCIC_NETWORK, -1, "network"},
{PCIC_NETWORK, PCIS_NETWORK_ETHERNET, "ethernet"}, {PCIC_NETWORK, PCIS_NETWORK_ETHERNET, "ethernet"},
{PCIC_NETWORK, PCIS_NETWORK_TOKENRING, "token ring"}, {PCIC_NETWORK, PCIS_NETWORK_TOKENRING, "token ring"},
{PCIC_NETWORK, PCIS_NETWORK_FDDI, "fddi"}, {PCIC_NETWORK, PCIS_NETWORK_FDDI, "fddi"},
{PCIC_NETWORK, PCIS_NETWORK_ATM, "ATM"}, {PCIC_NETWORK, PCIS_NETWORK_ATM, "ATM"},
{PCIC_NETWORK, PCIS_NETWORK_ISDN, "ISDN"}, {PCIC_NETWORK, PCIS_NETWORK_ISDN, "ISDN"},
{PCIC_NETWORK, PCIS_NETWORK_WORLDFIP, "WorldFip"},
{PCIC_NETWORK, PCIS_NETWORK_PICMG, "PICMG"},
{PCIC_NETWORK, PCIS_NETWORK_INFINIBAND, "InfiniBand"},
{PCIC_NETWORK, PCIS_NETWORK_HFC, "host fabric"},
{PCIC_DISPLAY, -1, "display"}, {PCIC_DISPLAY, -1, "display"},
{PCIC_DISPLAY, PCIS_DISPLAY_VGA, "VGA"}, {PCIC_DISPLAY, PCIS_DISPLAY_VGA, "VGA"},
{PCIC_DISPLAY, PCIS_DISPLAY_XGA, "XGA"}, {PCIC_DISPLAY, PCIS_DISPLAY_XGA, "XGA"},
@ -693,6 +698,11 @@ static struct
{PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, "PCI-NuBus"}, {PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, "PCI-NuBus"},
{PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, "PCI-CardBus"}, {PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, "PCI-CardBus"},
{PCIC_BRIDGE, PCIS_BRIDGE_RACEWAY, "PCI-RACEway"}, {PCIC_BRIDGE, PCIS_BRIDGE_RACEWAY, "PCI-RACEway"},
{PCIC_BRIDGE, PCIS_BRIDGE_PCI_TRANSPARENT,
"Semi-transparent PCI-to-PCI"},
{PCIC_BRIDGE, PCIS_BRIDGE_INFINIBAND, "InfiniBand-PCI"},
{PCIC_BRIDGE, PCIS_BRIDGE_AS_PCI,
"AdvancedSwitching-PCI"},
{PCIC_SIMPLECOMM, -1, "simple comms"}, {PCIC_SIMPLECOMM, -1, "simple comms"},
{PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_UART, "UART"}, /* could detect 16550 */ {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_UART, "UART"}, /* could detect 16550 */
{PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_PAR, "parallel port"}, {PCIC_SIMPLECOMM, PCIS_SIMPLECOMM_PAR, "parallel port"},
@ -706,6 +716,8 @@ static struct
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_PCIHOT, "PCI hot-plug controller"}, {PCIC_BASEPERIPH, PCIS_BASEPERIPH_PCIHOT, "PCI hot-plug controller"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_SDHC, "SD host controller"}, {PCIC_BASEPERIPH, PCIS_BASEPERIPH_SDHC, "SD host controller"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_IOMMU, "IOMMU"}, {PCIC_BASEPERIPH, PCIS_BASEPERIPH_IOMMU, "IOMMU"},
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_RCEC,
"Root Complex Event Collector"},
{PCIC_INPUTDEV, -1, "input device"}, {PCIC_INPUTDEV, -1, "input device"},
{PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, "keyboard"}, {PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, "keyboard"},
{PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,"digitizer"}, {PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,"digitizer"},
@ -721,10 +733,23 @@ static struct
{PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"}, {PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"}, {PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"}, {PCIC_SERIALBUS, PCIS_SERIALBUS_SMBUS, "SMBus"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_INFINIBAND, "InfiniBand"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_IPMI, "IPMI"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_SERCOS, "SERCOS"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_CANBUS, "CANbus"},
{PCIC_SERIALBUS, PCIS_SERIALBUS_MIPI_I3C, "MIPI I3C"},
{PCIC_WIRELESS, -1, "wireless controller"}, {PCIC_WIRELESS, -1, "wireless controller"},
{PCIC_WIRELESS, PCIS_WIRELESS_IRDA, "iRDA"}, {PCIC_WIRELESS, PCIS_WIRELESS_IRDA, "iRDA"},
{PCIC_WIRELESS, PCIS_WIRELESS_IR, "IR"}, {PCIC_WIRELESS, PCIS_WIRELESS_IR, "IR"},
{PCIC_WIRELESS, PCIS_WIRELESS_RF, "RF"}, {PCIC_WIRELESS, PCIS_WIRELESS_RF, "RF"},
{PCIC_WIRELESS, PCIS_WIRELESS_BLUETOOTH, "bluetooth"},
{PCIC_WIRELESS, PCIS_WIRELESS_BROADBAND, "broadband"},
{PCIC_WIRELESS, PCIS_WIRELESS_80211A, "ethernet 802.11a"},
{PCIC_WIRELESS, PCIS_WIRELESS_80211B, "ethernet 802.11b"},
{PCIC_WIRELESS, PCIS_WIRELESS_CELL,
"cellular controller/modem"},
{PCIC_WIRELESS, PCIS_WIRELESS_CELL_E,
"cellular controller/modem plus ethernet"},
{PCIC_INTELLIIO, -1, "intelligent I/O controller"}, {PCIC_INTELLIIO, -1, "intelligent I/O controller"},
{PCIC_INTELLIIO, PCIS_INTELLIIO_I2O, "I2O"}, {PCIC_INTELLIIO, PCIS_INTELLIIO_I2O, "I2O"},
{PCIC_SATCOM, -1, "satellite communication"}, {PCIC_SATCOM, -1, "satellite communication"},

View File

@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$");
static char tname[MAXPATHLEN]; static char tname[MAXPATHLEN];
#define PMASK 0xffff #define PMASK 0xffff
#define PROTOMAX 5 #define PROTOMAX 6
static void add(DB *, StringList *, size_t, const char *, size_t *, int); static void add(DB *, StringList *, size_t, const char *, size_t *, int);
static StringList ***parseservices(const char *, StringList *); static StringList ***parseservices(const char *, StringList *);