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
# 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

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
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.

View File

@ -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);
/*

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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);

View File

@ -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))

View File

@ -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))

View File

@ -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

View File

@ -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)

View File

@ -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

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
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 \
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

View File

@ -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)
{

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 \
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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -610,4 +610,5 @@ const char *freebsd32_syscallnames[] = {
"shm_open2", /* 571 = shm_open2 */
"shm_rename", /* 572 = shm_rename */
"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_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 */
};

View File

@ -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;
};

View File

@ -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

View File

@ -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)
{

View File

@ -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_ */

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",
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);

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;
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

View File

@ -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",

View File

@ -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

View File

@ -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);

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_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 */
};

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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

View File

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

View File

@ -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

View File

@ -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;
};

View File

@ -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)
{

View File

@ -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))

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
* 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);

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -414,4 +414,5 @@ MIASM = \
__sysctlbyname.o \
shm_open2.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 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_

View File

@ -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

View File

@ -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);
}

View File

@ -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 } } },

View File

@ -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 }
};

View File

@ -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"},

View File

@ -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 *);