Merge ^/head r358131 through r358178.
This commit is contained in:
commit
6c140a7281
@ -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
|
||||
|
||||
# 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
|
||||
OLD_FILES+=usr/bin/elf2aout
|
||||
OLD_FILES+=usr/share/man/man1/elf2aout.1.gz
|
||||
|
8
UPDATING
8
UPDATING
@ -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
|
||||
using clang 3.5.0 or higher.
|
||||
|
||||
20200218:
|
||||
ncurses has been updated to a newer version (6.1-20200118). After an
|
||||
update some applications using ncurses may results have some rendering
|
||||
problems and would need to be rebuilt.
|
||||
20200220:
|
||||
ncurses has been updated to a newer version (6.1-20200118). Given the ABI
|
||||
has changed, users will have to rebuild all the ports that are linked to
|
||||
ncurses.
|
||||
|
||||
20200217:
|
||||
The size of struct vnet and the magic cookie have changed.
|
||||
|
@ -66,10 +66,79 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#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 umaskcmd(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
|
||||
* ordinary characters.
|
||||
@ -108,6 +177,7 @@ readcmd(int argc __unused, char **argv __unused)
|
||||
fd_set ifds;
|
||||
ssize_t nread;
|
||||
int sig;
|
||||
struct fdctx fdctx;
|
||||
|
||||
rflag = 0;
|
||||
prompt = NULL;
|
||||
@ -173,8 +243,9 @@ readcmd(int argc __unused, char **argv __unused)
|
||||
backslash = 0;
|
||||
STARTSTACKSTR(p);
|
||||
lastnonifs = lastnonifsws = -1;
|
||||
fdctx_init(STDIN_FILENO, &fdctx);
|
||||
for (;;) {
|
||||
nread = read(STDIN_FILENO, &c, 1);
|
||||
nread = fdgetc(&fdctx, &c);
|
||||
if (nread == -1) {
|
||||
if (errno == EINTR) {
|
||||
sig = pendingsig;
|
||||
@ -260,6 +331,7 @@ readcmd(int argc __unused, char **argv __unused)
|
||||
STARTSTACKSTR(p);
|
||||
lastnonifs = lastnonifsws = -1;
|
||||
}
|
||||
fdctx_destroy(&fdctx);
|
||||
STACKSTRNUL(p);
|
||||
|
||||
/*
|
||||
|
@ -42,14 +42,19 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.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
|
||||
* components. Returns (resolved) on success, or (NULL) on failure,
|
||||
* in which case the path which caused trouble is left in (resolved).
|
||||
*/
|
||||
static char *
|
||||
static char * __noinline
|
||||
realpath1(const char *path, char *resolved)
|
||||
{
|
||||
struct stat sb;
|
||||
@ -223,6 +228,10 @@ realpath(const char * __restrict path, char * __restrict resolved)
|
||||
if (resolved == NULL)
|
||||
return (NULL);
|
||||
}
|
||||
if (__getosreldate() >= 1300080) {
|
||||
if (__realpathat(AT_FDCWD, path, resolved, PATH_MAX, 0) == 0)
|
||||
return (resolved);
|
||||
}
|
||||
res = realpath1(path, resolved);
|
||||
if (res == NULL)
|
||||
free(m);
|
||||
|
@ -13,7 +13,7 @@ MK_MAN=no
|
||||
.include "${.CURDIR:H}/config.mk"
|
||||
|
||||
LIB= ncurses${LIB_SUFFIX}
|
||||
SHLIB_MAJOR= 8
|
||||
SHLIB_MAJOR= 9
|
||||
|
||||
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
|
||||
|
||||
CFLAGS+= -DFREEBSD_NATIVE -DTERMIOS
|
||||
CFLAGS.lib_freeall.c+= -Wno-missing-prototypes
|
||||
|
||||
# Installed
|
||||
HEADERS= curses.h term.h termcap.h unctrl.h
|
||||
|
@ -49,7 +49,7 @@ _libc_other_objects= sigsetjmp lstat stat fstat fstatat fstatfs syscall \
|
||||
sysarch __sysctl issetugid __getcwd utrace \
|
||||
thr_self thr_kill pread mmap lseek _exit _fstat _fstatat _fstatfs \
|
||||
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
|
||||
|
@ -192,6 +192,7 @@ MAN= aac.4 \
|
||||
${_hv_vmbus.4} \
|
||||
${_hv_vss.4} \
|
||||
hwpmc.4 \
|
||||
${_hwpstate_intel.4} \
|
||||
iavf.4 \
|
||||
ichsmb.4 \
|
||||
${_ichwd.4} \
|
||||
@ -787,6 +788,7 @@ _hv_storvsc.4= hv_storvsc.4
|
||||
_hv_utils.4= hv_utils.4
|
||||
_hv_vmbus.4= hv_vmbus.4
|
||||
_hv_vss.4= hv_vss.4
|
||||
_hwpstate_intel.4= hwpstate_intel.4
|
||||
_i8254.4= i8254.4
|
||||
_ichwd.4= ichwd.4
|
||||
_if_bxe.4= if_bxe.4
|
||||
|
@ -52,6 +52,8 @@ connect_controllers(EFI_GUID *filter)
|
||||
}
|
||||
|
||||
handles = malloc(hsize);
|
||||
if (handles == NULL)
|
||||
return (EFI_OUT_OF_RESOURCES);
|
||||
nhandles = hsize / sizeof(EFI_HANDLE);
|
||||
|
||||
status = BS->LocateHandle(ByProtocol, filter, NULL,
|
||||
|
@ -701,6 +701,8 @@ efihttp_fs_seek(struct open_file *f, off_t offset, int where)
|
||||
return (0);
|
||||
if (where == SEEK_SET && fh->offset < offset) {
|
||||
buf = malloc(1500);
|
||||
if (buf == NULL)
|
||||
return (ENOMEM);
|
||||
res = offset - fh->offset;
|
||||
while (res > 0) {
|
||||
err = _efihttp_fs_read(f, buf, min(1500, res), &res2);
|
||||
|
@ -371,6 +371,8 @@ efinet_dev_init()
|
||||
status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz, NULL);
|
||||
if (status == EFI_BUFFER_TOO_SMALL) {
|
||||
handles = (EFI_HANDLE *)malloc(sz);
|
||||
if (handles == NULL)
|
||||
return (ENOMEM);
|
||||
status = BS->LocateHandle(ByProtocol, &sn_guid, NULL, &sz,
|
||||
handles);
|
||||
if (EFI_ERROR(status))
|
||||
|
@ -363,6 +363,8 @@ efipart_inithandles(void)
|
||||
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz, hin);
|
||||
if (status == EFI_BUFFER_TOO_SMALL) {
|
||||
hin = malloc(sz);
|
||||
if (hin == NULL)
|
||||
return (ENOMEM);
|
||||
status = BS->LocateHandle(ByProtocol, &blkio_guid, 0, &sz,
|
||||
hin);
|
||||
if (EFI_ERROR(status))
|
||||
|
@ -86,9 +86,11 @@ insert_zfs(EFI_HANDLE handle, uint64_t guid)
|
||||
zfsinfo_t *zi;
|
||||
|
||||
zi = malloc(sizeof(zfsinfo_t));
|
||||
zi->zi_handle = handle;
|
||||
zi->zi_pool_guid = guid;
|
||||
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);
|
||||
if (zi != NULL) {
|
||||
zi->zi_handle = handle;
|
||||
zi->zi_pool_guid = guid;
|
||||
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -52,6 +52,8 @@ efi_register_handles(struct devsw *sw, EFI_HANDLE *handles,
|
||||
nentries += count;
|
||||
sz = nentries * sizeof(struct entry);
|
||||
entry = (entry == NULL) ? malloc(sz) : realloc(entry, sz);
|
||||
if (entry == NULL)
|
||||
return (ENOMEM);
|
||||
for (unit = 0; idx < nentries; idx++, unit++) {
|
||||
entry[idx].handle = handles[unit];
|
||||
if (aliases != NULL)
|
||||
|
@ -22,7 +22,6 @@ SRCS= autoload.c \
|
||||
framebuffer.c \
|
||||
main.c \
|
||||
self_reloc.c \
|
||||
smbios.c \
|
||||
vers.c
|
||||
|
||||
CFLAGS+= -I${.CURDIR}/../loader
|
||||
@ -45,8 +44,6 @@ CWARNFLAGS.main.c+= -Wno-format
|
||||
|
||||
.PATH: ${.CURDIR}/../loader
|
||||
.PATH: ${.CURDIR}/../loader/arch/${MACHINE}
|
||||
# For smbios.c XXX need to abstract properly
|
||||
.PATH: ${BOOTSRC}/i386/libi386
|
||||
.include "${.CURDIR}/../loader/arch/${MACHINE}/Makefile.inc"
|
||||
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
@ -57,18 +54,6 @@ CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include
|
||||
CFLAGS+= -I${BOOTSRC}/i386/libi386
|
||||
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"
|
||||
.include "${BOOTSRC}/fdt.mk"
|
||||
LIBEFI_FDT= ${BOOTOBJ}/efi/fdt/libefi_fdt.a
|
||||
|
@ -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
|
||||
main(int argc, CHAR16 *argv[])
|
||||
|
@ -9,7 +9,7 @@ SRCS= bio.c biosacpi.c biosdisk.c biosmem.c biospnp.c \
|
||||
comconsole.c devicename.c elf32_freebsd.c \
|
||||
elf64_freebsd.c multiboot.c multiboot_tramp.S relocater_tramp.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}
|
||||
SRCS+= devicename_stubs.c
|
||||
CFLAGS+= -I${ZFSSRC}
|
||||
@ -28,18 +28,6 @@ CFLAGS+= -DCOMSPEED=${BOOT_COMCONSOLE_SPEED}
|
||||
CFLAGS+= -DDISK_DEBUG
|
||||
.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
|
||||
CFLAGS.vidconsole.c+= -I${SRCTOP}/sys/teken
|
||||
CFLAGS.teken.c+= -I${SRCTOP}/sys/teken
|
||||
|
@ -45,7 +45,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include "bootstrap.h"
|
||||
#include "common/bootargs.h"
|
||||
#include "libi386/libi386.h"
|
||||
#include "libi386/smbios.h"
|
||||
#include <smbios.h>
|
||||
#include "btxv86.h"
|
||||
|
||||
#ifdef LOADER_ZFS_SUPPORT
|
||||
@ -86,6 +86,12 @@ extern char end[];
|
||||
static void *heap_top;
|
||||
static void *heap_bottom;
|
||||
|
||||
caddr_t
|
||||
ptov(uintptr_t x)
|
||||
{
|
||||
return (PTOV(x));
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
|
@ -137,6 +137,20 @@ CLEANFILES+= ${SAFE_INCS} ${STAND_H_INC} ${OTHER_INC}
|
||||
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
|
||||
|
||||
# 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
|
||||
SRCS+= arp.c ether.c ip.c inet_ntoa.c in_cksum.c net.c udp.c netif.c rpc.c
|
||||
|
||||
|
@ -28,16 +28,9 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stand.h>
|
||||
#include <bootstrap.h>
|
||||
#include <sys/endian.h>
|
||||
|
||||
#ifdef EFI
|
||||
/* In EFI, we don't need PTOV(). */
|
||||
#define PTOV(x) (caddr_t)(x)
|
||||
#else
|
||||
#include "btxv86.h"
|
||||
#endif
|
||||
#include "smbios.h"
|
||||
#define PTOV(x) ptov(x)
|
||||
|
||||
/*
|
||||
* Detect SMBIOS and export information about the SMBIOS into the
|
@ -452,4 +452,9 @@ const char *x86_hypervisor(void);
|
||||
#define reallocf(x, y) Reallocf(x, y, NULL, 0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* va <-> pa routines. MD code must supply.
|
||||
*/
|
||||
caddr_t ptov(uintptr_t);
|
||||
|
||||
#endif /* STAND_H */
|
||||
|
@ -657,6 +657,7 @@
|
||||
#define AUE_LGETUUID 43261 /* CADETS. */
|
||||
#define AUE_EXECVEAT 43262 /* FreeBSD/Linux. */
|
||||
#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
|
||||
|
@ -500,4 +500,5 @@
|
||||
#define FREEBSD32_SYS_shm_open2 571
|
||||
#define FREEBSD32_SYS_shm_rename 572
|
||||
#define FREEBSD32_SYS_sigfastblock 573
|
||||
#define FREEBSD32_SYS_MAXSYSCALL 574
|
||||
#define FREEBSD32_SYS___realpathat 574
|
||||
#define FREEBSD32_SYS_MAXSYSCALL 575
|
||||
|
@ -610,4 +610,5 @@ const char *freebsd32_syscallnames[] = {
|
||||
"shm_open2", /* 571 = shm_open2 */
|
||||
"shm_rename", /* 572 = shm_rename */
|
||||
"sigfastblock", /* 573 = sigfastblock */
|
||||
"__realpathat", /* 574 = __realpathat */
|
||||
};
|
||||
|
@ -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_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(__realpathat_args), (sy_call_t *)sys___realpathat, AUE_REALPATHAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 574 = __realpathat */
|
||||
};
|
||||
|
@ -3363,6 +3363,17 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
|
||||
*n_args = 2;
|
||||
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:
|
||||
*n_args = 0;
|
||||
break;
|
||||
@ -9062,6 +9073,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
|
||||
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:
|
||||
break;
|
||||
};
|
||||
@ -10956,6 +10989,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
|
||||
if (ndx == 0 || ndx == 1)
|
||||
p = "int";
|
||||
break;
|
||||
/* __realpathat */
|
||||
case 574:
|
||||
if (ndx == 0 || ndx == 1)
|
||||
p = "int";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
@ -1160,5 +1160,7 @@
|
||||
572 AUE_SHMRENAME NOPROTO { int shm_rename(const char *path_from, \
|
||||
const char *path_to, int flags); }
|
||||
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
|
||||
|
@ -449,6 +449,13 @@ static inline void list_cut_position(struct list_head *list,
|
||||
__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,
|
||||
const struct list_head *head)
|
||||
{
|
||||
|
@ -154,4 +154,13 @@ memchr_inv(const void *start, int c, size_t length)
|
||||
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_ */
|
||||
|
@ -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",
|
||||
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_bstucktask,0, ath_bstuck_proc, sc);
|
||||
TASK_INIT(&sc->sc_resettask,0, ath_reset_proc, sc);
|
||||
|
@ -656,6 +656,8 @@ ath_rx_pkt(struct ath_softc *sc, struct ath_rx_status *rs, HAL_STATUS status,
|
||||
int is_good = 0;
|
||||
struct ath_rx_edma *re = &sc->sc_rxedma[qtype];
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
|
||||
/*
|
||||
* Calculate the correct 64 bit TSF given
|
||||
* the TSF64 register value and rs_tstamp.
|
||||
@ -1074,6 +1076,8 @@ ath_rx_proc(struct ath_softc *sc, int resched)
|
||||
int kickpcu = 0;
|
||||
int ret;
|
||||
|
||||
NET_EPOCH_ASSERT();
|
||||
|
||||
/* XXX we must not hold the ATH_LOCK here */
|
||||
ATH_UNLOCK_ASSERT(sc);
|
||||
ATH_PCU_UNLOCK_ASSERT(sc);
|
||||
@ -1293,6 +1297,7 @@ static void
|
||||
ath_legacy_rx_tasklet(void *arg, int npending)
|
||||
{
|
||||
struct ath_softc *sc = arg;
|
||||
struct epoch_tracker et;
|
||||
|
||||
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);
|
||||
@ -1305,14 +1310,18 @@ ath_legacy_rx_tasklet(void *arg, int npending)
|
||||
}
|
||||
ATH_PCU_UNLOCK(sc);
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
ath_rx_proc(sc, 1);
|
||||
NET_EPOCH_EXIT(et);
|
||||
}
|
||||
|
||||
static void
|
||||
ath_legacy_flushrecv(struct ath_softc *sc)
|
||||
{
|
||||
|
||||
struct epoch_tracker et;
|
||||
NET_EPOCH_ENTER(et);
|
||||
ath_rx_proc(sc, 0);
|
||||
NET_EPOCH_EXIT(et);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -521,6 +521,7 @@ ath_edma_recv_proc_deferred_queue(struct ath_softc *sc, HAL_RX_QUEUE qtype,
|
||||
int16_t nf;
|
||||
ath_bufhead rxlist;
|
||||
struct mbuf *m;
|
||||
struct epoch_tracker et;
|
||||
|
||||
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);
|
||||
ATH_RX_UNLOCK(sc);
|
||||
|
||||
NET_EPOCH_ENTER(et);
|
||||
|
||||
/* Handle the completed descriptors */
|
||||
/*
|
||||
* 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) {
|
||||
sc->sc_lastrx = tsf;
|
||||
}
|
||||
NET_EPOCH_EXIT(et);
|
||||
|
||||
ATH_KTR(sc, ATH_KTR_INTERRUPTS, 1,
|
||||
"ath edma rx deferred proc: ngood=%d\n",
|
||||
|
@ -151,6 +151,7 @@
|
||||
#define PCIY_SATA 0x12 /* SATA */
|
||||
#define PCIY_PCIAF 0x13 /* PCI Advanced Features */
|
||||
#define PCIY_EA 0x14 /* PCI Extended Allocation */
|
||||
#define PCIY_FPB 0x15 /* Flattening Portal Bridge */
|
||||
|
||||
/* Extended Capability Register Fields */
|
||||
|
||||
@ -194,6 +195,20 @@
|
||||
#define PCIZ_LN_REQ 0x001c /* LN Requester */
|
||||
#define PCIZ_DPC 0x001d /* Downstream Port Containment */
|
||||
#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 */
|
||||
|
||||
@ -334,6 +349,8 @@
|
||||
#define PCIS_STORAGE_NVM 0x08
|
||||
#define PCIP_STORAGE_NVM_NVMHCI_1_0 0x01
|
||||
#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 PCIC_NETWORK 0x02
|
||||
@ -344,6 +361,8 @@
|
||||
#define PCIS_NETWORK_ISDN 0x04
|
||||
#define PCIS_NETWORK_WORLDFIP 0x05
|
||||
#define PCIS_NETWORK_PICMG 0x06
|
||||
#define PCIS_NETWORK_INFINIBAND 0x07
|
||||
#define PCIS_NETWORK_HFC 0x08
|
||||
#define PCIS_NETWORK_OTHER 0x80
|
||||
|
||||
#define PCIC_DISPLAY 0x03
|
||||
@ -357,6 +376,7 @@
|
||||
#define PCIS_MULTIMEDIA_AUDIO 0x01
|
||||
#define PCIS_MULTIMEDIA_TELE 0x02
|
||||
#define PCIS_MULTIMEDIA_HDA 0x03
|
||||
#define PCIP_MULTIMEDIA_HDA_VENDOR 0x01
|
||||
#define PCIS_MULTIMEDIA_OTHER 0x80
|
||||
|
||||
#define PCIC_MEMORY 0x05
|
||||
@ -377,6 +397,8 @@
|
||||
#define PCIS_BRIDGE_RACEWAY 0x08
|
||||
#define PCIS_BRIDGE_PCI_TRANSPARENT 0x09
|
||||
#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 PCIC_SIMPLECOMM 0x07
|
||||
@ -408,6 +430,7 @@
|
||||
#define PCIS_BASEPERIPH_PCIHOT 0x04
|
||||
#define PCIS_BASEPERIPH_SDHC 0x05
|
||||
#define PCIS_BASEPERIPH_IOMMU 0x06
|
||||
#define PCIS_BASEPERIPH_RCEC 0x07
|
||||
#define PCIS_BASEPERIPH_OTHER 0x80
|
||||
|
||||
#define PCIC_INPUTDEV 0x09
|
||||
@ -450,6 +473,7 @@
|
||||
#define PCIP_SERIALBUS_IPMI_BT 0x02
|
||||
#define PCIS_SERIALBUS_SERCOS 0x08
|
||||
#define PCIS_SERIALBUS_CANBUS 0x09
|
||||
#define PCIS_SERIALBUS_MIPI_I3C 0x0a
|
||||
|
||||
#define PCIC_WIRELESS 0x0d
|
||||
#define PCIS_WIRELESS_IRDA 0x00
|
||||
@ -459,6 +483,8 @@
|
||||
#define PCIS_WIRELESS_BROADBAND 0x12
|
||||
#define PCIS_WIRELESS_80211A 0x20
|
||||
#define PCIS_WIRELESS_80211B 0x21
|
||||
#define PCIS_WIRELESS_CELL 0x40
|
||||
#define PCIS_WIRELESS_CELL_E 0x41
|
||||
#define PCIS_WIRELESS_OTHER 0x80
|
||||
|
||||
#define PCIC_INTELLIIO 0x0e
|
||||
|
@ -196,7 +196,7 @@ vtmmio_setup_intr(device_t dev, enum intr_type type)
|
||||
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)) {
|
||||
device_printf(dev, "Can't setup the interrupt\n");
|
||||
return (ENXIO);
|
||||
|
@ -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_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(__realpathat_args), (sy_call_t *)sys___realpathat, AUE_REALPATHAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 574 = __realpathat */
|
||||
};
|
||||
|
@ -1035,9 +1035,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv)
|
||||
imgp->vmspace_destroyed = 1;
|
||||
imgp->sysent = sv;
|
||||
|
||||
td->td_pflags &= ~TDP_SIGFASTBLOCK;
|
||||
td->td_sigblock_ptr = NULL;
|
||||
td->td_sigblock_val = 0;
|
||||
sigfastblock_clear(td);
|
||||
|
||||
/* May be called with Giant held */
|
||||
EVENTHANDLER_DIRECT_INVOKE(process_exec, p, imgp);
|
||||
|
@ -157,6 +157,12 @@ static int kern_lognosys = 0;
|
||||
SYSCTL_INT(_kern, OID_AUTO, lognosys, CTLFLAG_RWTUN, &kern_lognosys, 0,
|
||||
"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);
|
||||
|
||||
/*
|
||||
@ -2005,6 +2011,7 @@ trapsignal(struct thread *td, ksiginfo_t *ksi)
|
||||
code = ksi->ksi_code;
|
||||
KASSERT(_SIG_VALID(sig), ("invalid signal"));
|
||||
|
||||
sigfastblock_fetch(td);
|
||||
PROC_LOCK(p);
|
||||
ps = p->p_sigacts;
|
||||
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
|
||||
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;
|
||||
|
||||
error = 0;
|
||||
p = td->td_proc;
|
||||
switch (uap->cmd) {
|
||||
case SIGFASTBLOCK_SETPTR:
|
||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) {
|
||||
@ -3975,18 +4019,22 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
|
||||
break;
|
||||
|
||||
case SIGFASTBLOCK_UNBLOCK:
|
||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0) {
|
||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
again:
|
||||
res = casueword32(td->td_sigblock_ptr, SIGFASTBLOCK_PEND,
|
||||
&oldval, 0);
|
||||
if (res == -1) {
|
||||
error = EFAULT;
|
||||
break;
|
||||
}
|
||||
if (res == 1) {
|
||||
|
||||
for (;;) {
|
||||
res = casueword32(td->td_sigblock_ptr,
|
||||
SIGFASTBLOCK_PEND, &oldval, 0);
|
||||
if (res == -1) {
|
||||
error = EFAULT;
|
||||
sigfastblock_failed(td, false, true);
|
||||
break;
|
||||
}
|
||||
if (res == 0)
|
||||
break;
|
||||
MPASS(res == 1);
|
||||
if (oldval != SIGFASTBLOCK_PEND) {
|
||||
error = EBUSY;
|
||||
break;
|
||||
@ -3994,8 +4042,22 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
|
||||
error = thread_check_susp(td, false);
|
||||
if (error != 0)
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -4003,7 +4065,6 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
|
||||
* signals to current thread. But notify others about
|
||||
* fake unblock.
|
||||
*/
|
||||
p = td->td_proc;
|
||||
if (error == 0 && p->p_numthreads != 1) {
|
||||
PROC_LOCK(p);
|
||||
reschedule_signals(p, td->td_sigmask, 0);
|
||||
@ -4016,8 +4077,7 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
res = fueword32(td->td_sigblock_ptr, &oldval);
|
||||
if (res == -1) {
|
||||
if (!sigfastblock_fetch_sig(td, false, &oldval)) {
|
||||
error = EFAULT;
|
||||
break;
|
||||
}
|
||||
@ -4025,8 +4085,7 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
|
||||
error = EBUSY;
|
||||
break;
|
||||
}
|
||||
td->td_pflags &= ~TDP_SIGFASTBLOCK;
|
||||
td->td_sigblock_val = 0;
|
||||
sigfastblock_clear(td);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -4037,32 +4096,59 @@ sys_sigfastblock(struct thread *td, struct sigfastblock_args *uap)
|
||||
}
|
||||
|
||||
void
|
||||
fetch_sigfastblock(struct thread *td)
|
||||
sigfastblock_clear(struct thread *td)
|
||||
{
|
||||
struct proc *p;
|
||||
bool resched;
|
||||
|
||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0)
|
||||
return;
|
||||
if (fueword32(td->td_sigblock_ptr, &td->td_sigblock_val) == -1) {
|
||||
fetch_sigfastblock_failed(td, false);
|
||||
return;
|
||||
td->td_sigblock_val = 0;
|
||||
resched = (td->td_pflags & TDP_SIGFASTPENDING) != 0;
|
||||
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
|
||||
fetch_sigfastblock_failed(struct thread *td, bool write)
|
||||
sigfastblock_fetch(struct thread *td)
|
||||
{
|
||||
ksiginfo_t ksi;
|
||||
uint32_t val;
|
||||
|
||||
/*
|
||||
* Prevent further fetches and SIGSEGVs, allowing thread to
|
||||
* issue syscalls despite corruption.
|
||||
*/
|
||||
td->td_pflags &= ~TDP_SIGFASTBLOCK;
|
||||
|
||||
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);
|
||||
(void)sigfastblock_fetch_sig(td, true, &val);
|
||||
}
|
||||
|
||||
void
|
||||
sigfastblock_setpend(struct thread *td)
|
||||
{
|
||||
int res;
|
||||
uint32_t oldval;
|
||||
|
||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) == 0)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +132,11 @@ syscallenter(struct thread *td)
|
||||
}
|
||||
|
||||
/*
|
||||
* Fetch fast sigblock value at the time of syscall
|
||||
* entry because sleepqueue primitives might call
|
||||
* cursig().
|
||||
* Fetch fast sigblock value at the time of syscall entry to
|
||||
* handle sleepqueue primitives which might call cursig().
|
||||
*/
|
||||
fetch_sigfastblock(td);
|
||||
if (__predict_false(sigfastblock_fetch_always))
|
||||
(void)sigfastblock_fetch(td);
|
||||
|
||||
/* Let system calls set td_errno directly. */
|
||||
td->td_pflags &= ~TDP_NERRNO;
|
||||
|
@ -134,6 +134,7 @@ userret(struct thread *td, struct trapframe *frame)
|
||||
#ifdef KTRACE
|
||||
KTRUSERRET(td);
|
||||
#endif
|
||||
|
||||
td_softdep_cleanup(td);
|
||||
MPASS(td->td_su == NULL);
|
||||
|
||||
@ -222,8 +223,7 @@ ast(struct trapframe *framep)
|
||||
{
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
uint32_t oldval;
|
||||
int flags, sig, res;
|
||||
int flags, sig;
|
||||
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
@ -325,11 +325,12 @@ ast(struct trapframe *framep)
|
||||
*/
|
||||
if (flags & TDF_NEEDSIGCHK || p->p_pendingcnt > 0 ||
|
||||
!SIGISEMPTY(p->p_siglist)) {
|
||||
fetch_sigfastblock(td);
|
||||
sigfastblock_fetch(td);
|
||||
PROC_LOCK(p);
|
||||
mtx_lock(&p->p_sigacts->ps_mtx);
|
||||
if ((td->td_pflags & TDP_SIGFASTBLOCK) != 0 &&
|
||||
td->td_sigblock_val != 0) {
|
||||
sigfastblock_setpend(td);
|
||||
reschedule_signals(p, fastblock_mask,
|
||||
SIGPROCMASK_PS_LOCKED | SIGPROCMASK_FASTBLK);
|
||||
} else {
|
||||
@ -346,32 +347,8 @@ ast(struct trapframe *framep)
|
||||
* Handle deferred update of the fast sigblock value, after
|
||||
* the postsig() loop was performed.
|
||||
*/
|
||||
if (td->td_pflags & TDP_SIGFASTPENDING) {
|
||||
td->td_pflags &= ~TDP_SIGFASTPENDING;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (td->td_pflags & TDP_SIGFASTPENDING)
|
||||
sigfastblock_setpend(td);
|
||||
|
||||
/*
|
||||
* We need to check to see if we have to exit or wait due to a
|
||||
|
@ -580,4 +580,5 @@ const char *syscallnames[] = {
|
||||
"shm_open2", /* 571 = shm_open2 */
|
||||
"shm_rename", /* 572 = shm_rename */
|
||||
"sigfastblock", /* 573 = sigfastblock */
|
||||
"__realpathat", /* 574 = __realpathat */
|
||||
};
|
||||
|
@ -3218,6 +3218,15 @@
|
||||
_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:
|
||||
; sys/compat/freebsd32/syscalls.master
|
||||
|
@ -3355,6 +3355,17 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
|
||||
*n_args = 2;
|
||||
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:
|
||||
*n_args = 0;
|
||||
break;
|
||||
@ -8967,6 +8978,28 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
|
||||
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:
|
||||
break;
|
||||
};
|
||||
@ -10888,6 +10921,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
|
||||
if (ndx == 0 || ndx == 1)
|
||||
p = "int";
|
||||
break;
|
||||
/* __realpathat */
|
||||
case 574:
|
||||
if (ndx == 0 || ndx == 1)
|
||||
p = "int";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/capsicum.h>
|
||||
#include <sys/counter.h>
|
||||
#include <sys/filedesc.h>
|
||||
#include <sys/fnv_hash.h>
|
||||
@ -387,8 +388,12 @@ STATNODE_COUNTER(shrinking_skipped,
|
||||
"Number of times shrinking was already in progress");
|
||||
|
||||
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);
|
||||
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");
|
||||
|
||||
@ -2201,7 +2206,7 @@ vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen)
|
||||
rdir = fdp->fd_rdir;
|
||||
vrefact(rdir);
|
||||
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(cdir);
|
||||
|
||||
@ -2212,6 +2217,37 @@ vn_getcwd(struct thread *td, char *buf, char **retbuf, size_t *buflen)
|
||||
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
|
||||
* cache (if available)
|
||||
@ -2235,7 +2271,7 @@ vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf)
|
||||
rdir = fdp->fd_rdir;
|
||||
vrefact(rdir);
|
||||
FILEDESC_SUNLOCK(fdp);
|
||||
error = vn_fullpath1(td, vn, rdir, buf, retbuf, &buflen);
|
||||
error = vn_fullpath_any(td, vn, rdir, buf, retbuf, &buflen);
|
||||
vrele(rdir);
|
||||
|
||||
if (!error)
|
||||
@ -2263,7 +2299,7 @@ vn_fullpath_global(struct thread *td, struct vnode *vn,
|
||||
return (EINVAL);
|
||||
buflen = MAXPATHLEN;
|
||||
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)
|
||||
*freebuf = buf;
|
||||
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
|
||||
vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
|
||||
char *buf, char **retbuf, size_t *len)
|
||||
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)
|
||||
{
|
||||
int error, slash_prefixed;
|
||||
#ifdef KDTRACE_HOOKS
|
||||
struct vnode *startvp = vp;
|
||||
#endif
|
||||
struct vnode *vp1;
|
||||
size_t buflen;
|
||||
int error;
|
||||
|
||||
VNPASS(vp->v_type == VDIR || VN_IS_DOOMED(vp), vp);
|
||||
VNPASS(vp->v_usecount > 0, vp);
|
||||
|
||||
buflen = *len;
|
||||
|
||||
buflen--;
|
||||
buf[buflen] = '\0';
|
||||
if (!slash_prefixed) {
|
||||
MPASS(*len >= 2);
|
||||
buflen--;
|
||||
buf[buflen] = '\0';
|
||||
}
|
||||
|
||||
error = 0;
|
||||
slash_prefixed = 0;
|
||||
|
||||
SDT_PROBE1(vfs, namecache, fullpath, entry, vp);
|
||||
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) {
|
||||
/*
|
||||
* The vp vnode must be already fully constructed,
|
||||
@ -2420,7 +2456,7 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
|
||||
break;
|
||||
}
|
||||
buf[--buflen] = '/';
|
||||
slash_prefixed = 1;
|
||||
slash_prefixed = true;
|
||||
}
|
||||
if (error)
|
||||
return (error);
|
||||
@ -2437,12 +2473,128 @@ vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
|
||||
counter_u64_add(numfullpathfound, 1);
|
||||
vrele(vp);
|
||||
|
||||
SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen);
|
||||
*retbuf = buf + buflen;
|
||||
SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, *retbuf);
|
||||
*len -= buflen;
|
||||
*len += addend;
|
||||
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 *
|
||||
vn_dir_dd_ino(struct vnode *vp)
|
||||
{
|
||||
|
@ -543,14 +543,13 @@ __FBSDID("$FreeBSD$");
|
||||
#define SCTP_TIMER_TYPE_ASCONF 10
|
||||
#define SCTP_TIMER_TYPE_SHUTDOWNGUARD 11
|
||||
#define SCTP_TIMER_TYPE_AUTOCLOSE 12
|
||||
#define SCTP_TIMER_TYPE_EVENTWAKE 13
|
||||
#define SCTP_TIMER_TYPE_STRRESET 14
|
||||
#define SCTP_TIMER_TYPE_INPKILL 15
|
||||
#define SCTP_TIMER_TYPE_ASOCKILL 16
|
||||
#define SCTP_TIMER_TYPE_ADDR_WQ 17
|
||||
#define SCTP_TIMER_TYPE_PRIM_DELETED 18
|
||||
#define SCTP_TIMER_TYPE_STRRESET 13
|
||||
#define SCTP_TIMER_TYPE_INPKILL 14
|
||||
#define SCTP_TIMER_TYPE_ASOCKILL 15
|
||||
#define SCTP_TIMER_TYPE_ADDR_WQ 16
|
||||
#define SCTP_TIMER_TYPE_PRIM_DELETED 17
|
||||
/* 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) && \
|
||||
((t) < SCTP_TIMER_TYPE_LAST))
|
||||
|
@ -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
|
||||
* mp is the destination.
|
||||
* Make an extension header from option data. hp is the source,
|
||||
* mp is the destination, and _ol is the optlen.
|
||||
*/
|
||||
#define MAKE_EXTHDR(hp, mp) \
|
||||
#define MAKE_EXTHDR(hp, mp, _ol) \
|
||||
do { \
|
||||
if (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); \
|
||||
if (error) \
|
||||
goto freehdrs; \
|
||||
(_ol) += (*(mp))->m_len; \
|
||||
} \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
@ -384,22 +385,23 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
struct ip6_hdr *ip6;
|
||||
struct ifnet *ifp, *origifp;
|
||||
struct mbuf *m = m0;
|
||||
struct mbuf *mprev = NULL;
|
||||
struct mbuf *mprev;
|
||||
int hlen, tlen, len;
|
||||
struct route_in6 ip6route;
|
||||
struct rtentry *rt = NULL;
|
||||
struct sockaddr_in6 *dst, src_sa, dst_sa;
|
||||
struct in6_addr odst;
|
||||
u_char *nexthdrp;
|
||||
int error = 0;
|
||||
struct in6_ifaddr *ia = NULL;
|
||||
u_long mtu;
|
||||
int alwaysfrag, dontfrag;
|
||||
u_int32_t optlen = 0, plen = 0, unfragpartlen = 0;
|
||||
u_int32_t optlen, plen = 0, unfragpartlen;
|
||||
struct ip6_exthdrs exthdrs;
|
||||
struct in6_addr src0, dst0;
|
||||
u_int32_t zone;
|
||||
struct route_in6 *ro_pmtu = NULL;
|
||||
int hdrsplit = 0;
|
||||
bool hdrsplit;
|
||||
int sw_csum, tso;
|
||||
int needfiblookup;
|
||||
uint32_t fibnum;
|
||||
@ -436,12 +438,49 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
}
|
||||
#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));
|
||||
optlen = 0;
|
||||
unfragpartlen = 0;
|
||||
if (opt) {
|
||||
/* 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). */
|
||||
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).
|
||||
* 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
|
||||
* the kernel.
|
||||
*/
|
||||
MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1);
|
||||
MAKE_EXTHDR(opt->ip6po_dest1, &exthdrs.ip6e_dest1,
|
||||
optlen);
|
||||
}
|
||||
/* 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). */
|
||||
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,
|
||||
* separate IP6 header from the payload.
|
||||
*/
|
||||
if (optlen && !hdrsplit) {
|
||||
hdrsplit = false;
|
||||
if (optlen) {
|
||||
if ((error = ip6_splithdr(m, &exthdrs)) != 0) {
|
||||
m = NULL;
|
||||
goto freehdrs;
|
||||
}
|
||||
m = exthdrs.ip6e_ip6;
|
||||
hdrsplit++;
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
hdrsplit = true;
|
||||
}
|
||||
|
||||
ip6 = mtod(m, struct ip6_hdr *);
|
||||
|
||||
/* Adjust mbuf packet header length. */
|
||||
m->m_pkthdr.len += optlen;
|
||||
plen = m->m_pkthdr.len - sizeof(*ip6);
|
||||
@ -504,77 +535,59 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt,
|
||||
goto freehdrs;
|
||||
}
|
||||
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)
|
||||
goto freehdrs;
|
||||
ip6->ip6_plen = 0;
|
||||
} else
|
||||
ip6->ip6_plen = htons(plen);
|
||||
nexthdrp = &ip6->ip6_nxt;
|
||||
|
||||
/*
|
||||
* Concatenate headers and fill in next header fields.
|
||||
* Here we have, on "m"
|
||||
* IPv6 payload
|
||||
* and we insert headers accordingly.
|
||||
* 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.
|
||||
*/
|
||||
u_char *nexthdrp = &ip6->ip6_nxt;
|
||||
mprev = m;
|
||||
if (optlen) {
|
||||
/*
|
||||
* Concatenate headers and fill in next header fields.
|
||||
* Here we have, on "m"
|
||||
* IPv6 payload
|
||||
* and we insert headers accordingly.
|
||||
* 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.
|
||||
*/
|
||||
mprev = m;
|
||||
|
||||
/*
|
||||
* We treat dest2 specially. This makes IPsec processing
|
||||
* much easier. The goal here is to make mprev point the
|
||||
* mbuf prior to dest2.
|
||||
*
|
||||
* Result: IPv6 dest2 payload.
|
||||
* m and mprev will point to IPv6 header.
|
||||
*/
|
||||
if (exthdrs.ip6e_dest2) {
|
||||
if (!hdrsplit)
|
||||
panic("%s:%d: assumption failed: "
|
||||
"hdr not split: hdrsplit %d exthdrs %p",
|
||||
__func__, __LINE__, hdrsplit, &exthdrs);
|
||||
exthdrs.ip6e_dest2->m_next = m->m_next;
|
||||
m->m_next = exthdrs.ip6e_dest2;
|
||||
*mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
|
||||
ip6->ip6_nxt = IPPROTO_DSTOPTS;
|
||||
}
|
||||
/*
|
||||
* We treat dest2 specially. This makes IPsec processing
|
||||
* much easier. The goal here is to make mprev point the
|
||||
* mbuf prior to dest2.
|
||||
*
|
||||
* Result: IPv6 dest2 payload.
|
||||
* m and mprev will point to IPv6 header.
|
||||
*/
|
||||
if (exthdrs.ip6e_dest2) {
|
||||
if (!hdrsplit)
|
||||
panic("%s:%d: assumption failed: "
|
||||
"hdr not split: hdrsplit %d exthdrs %p",
|
||||
__func__, __LINE__, hdrsplit, &exthdrs);
|
||||
exthdrs.ip6e_dest2->m_next = m->m_next;
|
||||
m->m_next = exthdrs.ip6e_dest2;
|
||||
*mtod(exthdrs.ip6e_dest2, u_char *) = ip6->ip6_nxt;
|
||||
ip6->ip6_nxt = IPPROTO_DSTOPTS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Result: IPv6 hbh dest1 rthdr dest2 payload.
|
||||
* m will point to IPv6 header. mprev will point to the
|
||||
* extension header prior to dest2 (rthdr in the above case).
|
||||
*/
|
||||
MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
|
||||
MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
|
||||
IPPROTO_DSTOPTS);
|
||||
MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
|
||||
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;
|
||||
/*
|
||||
* Result: IPv6 hbh dest1 rthdr dest2 payload.
|
||||
* m will point to IPv6 header. mprev will point to the
|
||||
* extension header prior to dest2 (rthdr in the above case).
|
||||
*/
|
||||
MAKE_CHAIN(exthdrs.ip6e_hbh, mprev, nexthdrp, IPPROTO_HOPOPTS);
|
||||
MAKE_CHAIN(exthdrs.ip6e_dest1, mprev, nexthdrp,
|
||||
IPPROTO_DSTOPTS);
|
||||
MAKE_CHAIN(exthdrs.ip6e_rthdr, mprev, nexthdrp,
|
||||
IPPROTO_ROUTING);
|
||||
}
|
||||
|
||||
IP6STAT_INC(ip6s_localout);
|
||||
|
@ -830,6 +830,7 @@ kaudit_to_bsm(struct kaudit_record *kar, struct au_record **pau)
|
||||
case AUE_UNLINK:
|
||||
case AUE_UNLINKAT:
|
||||
case AUE_UTIMES:
|
||||
case AUE_REALPATHAT:
|
||||
ATFD1_TOKENS(1);
|
||||
UPATH1_VNODE1_TOKENS;
|
||||
break;
|
||||
|
@ -60,7 +60,7 @@
|
||||
* in the range 5 to 9.
|
||||
*/
|
||||
#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,
|
||||
|
@ -273,6 +273,7 @@ int __sys_sigfastblock(int cmd, void *ptr);
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern sigset_t fastblock_mask;
|
||||
extern bool sigfastblock_fetch_always;
|
||||
|
||||
/* Return nonzero if process p has an unmasked pending signal. */
|
||||
#define SIGPENDING(td) \
|
||||
@ -382,8 +383,6 @@ sigallowstop(int prev)
|
||||
|
||||
int cursig(struct thread *td);
|
||||
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 killproc(struct proc *p, char *why);
|
||||
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;
|
||||
int sigev_findtd(struct proc *p, struct sigevent *sigev, struct thread **);
|
||||
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 signotify(struct thread *td);
|
||||
void sigqueue_delete(struct sigqueue *queue, int sig);
|
||||
|
@ -509,4 +509,5 @@
|
||||
#define SYS_shm_open2 571
|
||||
#define SYS_shm_rename 572
|
||||
#define SYS_sigfastblock 573
|
||||
#define SYS_MAXSYSCALL 574
|
||||
#define SYS___realpathat 574
|
||||
#define SYS_MAXSYSCALL 575
|
||||
|
@ -414,4 +414,5 @@ MIASM = \
|
||||
__sysctlbyname.o \
|
||||
shm_open2.o \
|
||||
shm_rename.o \
|
||||
sigfastblock.o
|
||||
sigfastblock.o \
|
||||
__realpathat.o
|
||||
|
@ -1823,6 +1823,13 @@ struct sigfastblock_args {
|
||||
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 *)];
|
||||
};
|
||||
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 *);
|
||||
void sys_sys_exit(struct thread *, struct sys_exit_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_rename(struct thread *, struct shm_rename_args *);
|
||||
int sys_sigfastblock(struct thread *, struct sigfastblock_args *);
|
||||
int sys___realpathat(struct thread *, struct __realpathat_args *);
|
||||
|
||||
#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_rename AUE_SHMRENAME
|
||||
#define SYS_AUE_sigfastblock AUE_NULL
|
||||
#define SYS_AUE___realpathat AUE_REALPATHAT
|
||||
|
||||
#undef PAD_
|
||||
#undef PADL_
|
||||
|
@ -208,6 +208,8 @@ vm_radix_node_load(smrnode_t *p, enum vm_radix_access access)
|
||||
case 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
|
||||
|
@ -628,8 +628,11 @@ vnode_pager_input_smlfs(vm_object_t object, vm_page_t m)
|
||||
|
||||
bwait(bp, PVM, "vnsrd");
|
||||
|
||||
if ((bp->b_ioflags & BIO_ERROR) != 0)
|
||||
error = EIO;
|
||||
if ((bp->b_ioflags & BIO_ERROR) != 0) {
|
||||
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
|
||||
@ -1113,7 +1116,9 @@ vnode_pager_generic_getpages_done(struct buf *bp)
|
||||
off_t tfoff, nextoff;
|
||||
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;
|
||||
|
||||
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_OBJECT_RUNLOCK(object);
|
||||
if (error != 0)
|
||||
printf("%s: I/O read error %d\n", __func__, error);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -115,6 +115,9 @@ static struct syscall decoded_syscalls[] = {
|
||||
.args = { { Int, 0 }, { Int, 1 }, { CapRights | OUT, 2 } } },
|
||||
{ .name = "__getcwd", .ret_type = 1, .nargs = 2,
|
||||
.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,
|
||||
.args = { { Ptr, 0 }, { Umtxop, 1 }, { LongHex, 2 }, { Ptr, 3 },
|
||||
{ Ptr, 4 } } },
|
||||
|
@ -1015,6 +1015,20 @@ static struct {
|
||||
{ PCIZ_LN_REQ, "LN Requester" },
|
||||
{ PCIZ_DPC, "Downstream Port Containment" },
|
||||
{ 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 }
|
||||
};
|
||||
|
||||
|
@ -665,12 +665,17 @@ static struct
|
||||
{PCIC_STORAGE, PCIS_STORAGE_SATA, "SATA"},
|
||||
{PCIC_STORAGE, PCIS_STORAGE_SAS, "SAS"},
|
||||
{PCIC_STORAGE, PCIS_STORAGE_NVM, "NVM"},
|
||||
{PCIC_STORAGE, PCIS_STORAGE_UFS, "UFS"},
|
||||
{PCIC_NETWORK, -1, "network"},
|
||||
{PCIC_NETWORK, PCIS_NETWORK_ETHERNET, "ethernet"},
|
||||
{PCIC_NETWORK, PCIS_NETWORK_TOKENRING, "token ring"},
|
||||
{PCIC_NETWORK, PCIS_NETWORK_FDDI, "fddi"},
|
||||
{PCIC_NETWORK, PCIS_NETWORK_ATM, "ATM"},
|
||||
{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, PCIS_DISPLAY_VGA, "VGA"},
|
||||
{PCIC_DISPLAY, PCIS_DISPLAY_XGA, "XGA"},
|
||||
@ -693,6 +698,11 @@ static struct
|
||||
{PCIC_BRIDGE, PCIS_BRIDGE_NUBUS, "PCI-NuBus"},
|
||||
{PCIC_BRIDGE, PCIS_BRIDGE_CARDBUS, "PCI-CardBus"},
|
||||
{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, PCIS_SIMPLECOMM_UART, "UART"}, /* could detect 16550 */
|
||||
{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_SDHC, "SD host controller"},
|
||||
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_IOMMU, "IOMMU"},
|
||||
{PCIC_BASEPERIPH, PCIS_BASEPERIPH_RCEC,
|
||||
"Root Complex Event Collector"},
|
||||
{PCIC_INPUTDEV, -1, "input device"},
|
||||
{PCIC_INPUTDEV, PCIS_INPUTDEV_KEYBOARD, "keyboard"},
|
||||
{PCIC_INPUTDEV, PCIS_INPUTDEV_DIGITIZER,"digitizer"},
|
||||
@ -721,10 +733,23 @@ static struct
|
||||
{PCIC_SERIALBUS, PCIS_SERIALBUS_USB, "USB"},
|
||||
{PCIC_SERIALBUS, PCIS_SERIALBUS_FC, "Fibre Channel"},
|
||||
{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, PCIS_WIRELESS_IRDA, "iRDA"},
|
||||
{PCIC_WIRELESS, PCIS_WIRELESS_IR, "IR"},
|
||||
{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, PCIS_INTELLIIO_I2O, "I2O"},
|
||||
{PCIC_SATCOM, -1, "satellite communication"},
|
||||
|
@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$");
|
||||
static char tname[MAXPATHLEN];
|
||||
|
||||
#define PMASK 0xffff
|
||||
#define PROTOMAX 5
|
||||
#define PROTOMAX 6
|
||||
|
||||
static void add(DB *, StringList *, size_t, const char *, size_t *, int);
|
||||
static StringList ***parseservices(const char *, StringList *);
|
||||
|
Loading…
Reference in New Issue
Block a user