Merge ^/head r352436 through r352536.

This commit is contained in:
Dimitry Andric 2019-09-19 19:26:12 +00:00
commit 0f80acb965
61 changed files with 1876 additions and 478 deletions

View File

@ -2773,6 +2773,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \
lib/libfigpar \
${_lib_libgssapi} \
lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \
lib/libzstd \
${_lib_casper} \
lib/ncurses/ncurses lib/ncurses/ncursesw \
lib/libopie lib/libpam/libpam ${_lib_libthr} \

View File

@ -190,8 +190,8 @@
.Ar snapshot
.Nm
.Cm send
.Op Fl Lce
.Op Fl i Ar snapshot Ns | Ns bookmark
.Op Fl LPcenv
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Nm
.Cm send
@ -2766,7 +2766,7 @@ on future versions of
.It Xo
.Nm
.Cm send
.Op Fl Lce
.Op Fl LPcenv
.Op Fl i Ar snapshot Ns | Ns Ar bookmark
.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot
.Xc
@ -2780,7 +2780,7 @@ stream generated from a filesystem or volume is received, the default snapshot
name will be
.Pq --head-- .
.Bl -tag -width indent
.It Fl i Ar snapshot Ns | Ns bookmark
.It Fl i Ar snapshot Ns | Ns Ar bookmark
Generate an incremental send stream.
The incremental source must be an earlier
snapshot in the destination's history.
@ -2792,6 +2792,23 @@ specified as the last component of the name
If the incremental target is a clone, the incremental source can
be the origin snapshot, or an earlier snapshot in the origin's filesystem,
or the origin's origin, etc.
.It Fl n, -dryrun
Do a dry-run
.Pq Qq No-op
send.
Do not generate any actual send data.
This is useful in conjunction with the
.Fl v
or
.Fl P
flags to determine what data will be sent.
In this case, the verbose output will be written to standard output
.Po contrast with a non-dry-run, where the stream is written to standard output
and the verbose output goes to standard error
.Pc .
.It Fl v, -verbose
Print verbose information about the stream package generated.
This information includes a per-second report of how much data has been sent.
.It Fl L, -large-block
Generate a stream which may contain blocks larger than 128KB.
This flag
@ -2808,6 +2825,8 @@ See
for details on ZFS feature flags and the
.Sy large_blocks
feature.
.It Fl P, -parsable
Print machine-parsable verbose information about the stream package generated.
.It Fl c, -compressed
Generate a more compact stream by using compressed WRITE records for blocks
which are compressed on disk and in memory (see the

View File

@ -290,7 +290,7 @@ get_usage(zfs_help_t idx)
case HELP_SEND:
return (gettext("\tsend [-DnPpRvLec] [-[iI] snapshot] "
"<snapshot>\n"
"\tsend [-Le] [-i snapshot|bookmark] "
"\tsend [-LPcenv] [-i snapshot|bookmark] "
"<filesystem|volume|snapshot>\n"
"\tsend [-nvPe] -t <receive_resume_token>\n"));
case HELP_SET:
@ -3928,13 +3928,11 @@ zfs_do_send(int argc, char **argv)
if (strchr(argv[0], '@') == NULL ||
(fromname && strchr(fromname, '#') != NULL)) {
char frombuf[ZFS_MAX_DATASET_NAME_LEN];
enum lzc_send_flags lzc_flags = 0;
if (flags.replicate || flags.doall || flags.props ||
flags.dedup || flags.dryrun || flags.verbose ||
flags.progress) {
(void) fprintf(stderr,
gettext("Error: "
flags.dedup || (strchr(argv[0], '@') == NULL &&
(flags.dryrun || flags.verbose || flags.progress))) {
(void) fprintf(stderr, gettext("Error: "
"Unsupported flag with filesystem or bookmark.\n"));
return (1);
}
@ -3943,13 +3941,6 @@ zfs_do_send(int argc, char **argv)
if (zhp == NULL)
return (1);
if (flags.largeblock)
lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
if (flags.embed_data)
lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
if (flags.compress)
lzc_flags |= LZC_SEND_FLAG_COMPRESS;
if (fromname != NULL &&
(fromname[0] == '#' || fromname[0] == '@')) {
/*
@ -3963,7 +3954,7 @@ zfs_do_send(int argc, char **argv)
(void) strlcat(frombuf, fromname, sizeof (frombuf));
fromname = frombuf;
}
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, lzc_flags);
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, flags);
zfs_close(zhp);
return (err != 0);
}

View File

@ -660,7 +660,7 @@ typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
extern int zfs_send(zfs_handle_t *, const char *, const char *,
sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **);
extern int zfs_send_one(zfs_handle_t *, const char *, int, enum lzc_send_flags);
extern int zfs_send_one(zfs_handle_t *, const char *, int, sendflags_t flags);
extern int zfs_send_resume(libzfs_handle_t *, sendflags_t *, int outfd,
const char *);
extern nvlist_t *zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl,

View File

@ -1190,16 +1190,14 @@ send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
}
}
if (size != 0) {
if (parsable) {
(void) fprintf(fout, "\t%llu",
(longlong_t)size);
} else {
char buf[16];
zfs_nicenum(size, buf, sizeof (buf));
(void) fprintf(fout, dgettext(TEXT_DOMAIN,
" estimated size is %s"), buf);
}
if (parsable) {
(void) fprintf(fout, "\t%llu",
(longlong_t)size);
} else if (size != 0) {
char buf[16];
zfs_nicenum(size, buf, sizeof (buf));
(void) fprintf(fout, dgettext(TEXT_DOMAIN,
" estimated size is %s"), buf);
}
(void) fprintf(fout, "\n");
}
@ -2037,17 +2035,40 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
}
int
zfs_send_one(zfs_handle_t *zhp, const char *from, int fd,
enum lzc_send_flags flags)
zfs_send_one(zfs_handle_t *zhp, const char *from, int fd, sendflags_t flags)
{
int err;
int err = 0;
libzfs_handle_t *hdl = zhp->zfs_hdl;
enum lzc_send_flags lzc_flags = 0;
FILE *fout = (flags.verbose && flags.dryrun) ? stdout : stderr;
char errbuf[1024];
if (flags.largeblock)
lzc_flags |= LZC_SEND_FLAG_LARGE_BLOCK;
if (flags.embed_data)
lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
if (flags.compress)
lzc_flags |= LZC_SEND_FLAG_COMPRESS;
if (flags.verbose) {
uint64_t size = 0;
err = lzc_send_space(zhp->zfs_name, from, lzc_flags, &size);
if (err == 0) {
send_print_verbose(fout, zhp->zfs_name, from, size,
flags.parsable);
} else {
(void) fprintf(stderr, "Cannot estimate send size: "
"%s\n", strerror(errno));
}
}
if (flags.dryrun)
return (err);
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
"warning: cannot send '%s'"), zhp->zfs_name);
err = lzc_send(zhp->zfs_name, from, fd, flags);
err = lzc_send(zhp->zfs_name, from, fd, lzc_flags);
if (err != 0) {
switch (errno) {
case EXDEV:

View File

@ -2299,21 +2299,6 @@ je_realloc(void *ptr, size_t size) {
LOG("core.realloc.entry", "ptr: %p, size: %zu\n", ptr, size);
if (unlikely(size == 0)) {
if (ptr != NULL) {
/* realloc(ptr, 0) is equivalent to free(ptr). */
UTRACE(ptr, 0, 0);
tcache_t *tcache;
tsd_t *tsd = tsd_fetch();
if (tsd_reentrancy_level_get(tsd) == 0) {
tcache = tcache_get(tsd);
} else {
tcache = NULL;
}
ifree(tsd, ptr, tcache, true);
LOG("core.realloc.exit", "result: %p", NULL);
return NULL;
}
size = 1;
}

View File

@ -332,6 +332,9 @@ ATF_TC_BODY(stat_socket, tc)
uint32_t iaddr;
int fd, flags;
if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
atf_tc_skip("https://bugs.freebsd.org/240621");
(void)memset(&st, 0, sizeof(struct stat));
(void)memset(&addr, 0, sizeof(struct sockaddr_in));

View File

@ -102,7 +102,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
# libraries, those libraries should be listed as build order dependencies here.
SUBDIR_DEPEND_geom= libufs
SUBDIR_DEPEND_libarchive= libz libbz2 libexpat liblzma libmd
SUBDIR_DEPEND_libarchive= libz libbz2 libexpat liblzma libmd libzstd
SUBDIR_DEPEND_libauditdm= libbsm
SUBDIR_DEPEND_libbsnmp= ${_libnetgraph}
SUBDIR_DEPEND_libc++:= libcxxrt

View File

@ -6,8 +6,8 @@ _LIBARCHIVEDIR= ${SRCTOP}/contrib/libarchive
LIB= archive
LIBADD= z bz2 lzma bsdxml
CFLAGS+= -DHAVE_BZLIB_H=1 -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1
LIBADD= z bz2 lzma bsdxml zstd
CFLAGS+= -DHAVE_BZLIB_H=1 -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1 -DHAVE_ZSTD_H=1 -DHAVE_LIBZSTD=1
# FreeBSD SHLIB_MAJOR value is managed as part of the FreeBSD system.
# It has no real relation to the libarchive version number.
@ -15,6 +15,7 @@ SHLIB_MAJOR= 7
CFLAGS+= -DPLATFORM_CONFIG_H=\"${.CURDIR}/config_freebsd.h\"
CFLAGS+= -I${.OBJDIR}
CFLAGS+= -I${SRCTOP}/sys/contrib/zstd/lib
.if ${MK_OPENSSL} != "no"
CFLAGS+= -DWITH_OPENSSL

View File

@ -305,6 +305,9 @@ BROKEN_TESTS+= test_read_disk_directory_traversals
# (Times out?) [and] crashes
BROKEN_TESTS+= test_fuzz_rar
# https://bugs.freebsd.org/240683
BROKEN_TESTS+= test_write_filter_zstd
# Build the test program.
SRCS.libarchive_test= \
${TESTS_SRCS} \
@ -517,12 +520,12 @@ ${PACKAGE}FILES+= test_read_format_rar5_blake2.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_compressed.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_different_window_size.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_distance_overflow.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_extra_field_version.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_extra_field_version.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_fileattr.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_hardlink.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_invalid_dict_reference.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_leftshift1.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_leftshift2.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_hardlink.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_invalid_dict_reference.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_leftshift1.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_leftshift2.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part01.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part02.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part03.rar.uu
@ -538,13 +541,13 @@ ${PACKAGE}FILES+= test_read_format_rar5_multiarchive_solid.part04.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiple_files.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_multiple_files_solid.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_nonempty_dir_stream.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_owner.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_readtables_overflow.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_owner.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_readtables_overflow.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_solid.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_stored.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_stored_manyfiles.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_symlink.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_truncated_huff.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_truncated_huff.rar.uu
${PACKAGE}FILES+= test_read_format_rar5_win32.rar.uu
${PACKAGE}FILES+= test_read_format_raw.bufr.uu
${PACKAGE}FILES+= test_read_format_raw.data.Z.uu

View File

@ -775,6 +775,7 @@ be_export(libbe_handle_t *lbh, const char *bootenv, int fd)
char snap_name[BE_MAXPATHLEN];
char buf[BE_MAXPATHLEN];
zfs_handle_t *zfs;
sendflags_t flags = { 0 };
int err;
if ((err = be_snapshot(lbh, bootenv, NULL, true, snap_name)) != 0)
@ -786,7 +787,7 @@ be_export(libbe_handle_t *lbh, const char *bootenv, int fd)
if ((zfs = zfs_open(lbh->lzh, buf, ZFS_TYPE_DATASET)) == NULL)
return (set_error(lbh, BE_ERR_ZFSOPEN));
err = zfs_send_one(zfs, NULL, fd, 0);
err = zfs_send_one(zfs, NULL, fd, flags);
zfs_close(zfs);
return (err);

View File

@ -47,8 +47,8 @@ sysctlnametomib(const char *name, int *mibp, size_t *sizep)
int oid[2];
int error;
oid[0] = 0;
oid[1] = 3;
oid[0] = CTL_SYSCTL;
oid[1] = CTL_SYSCTL_NAME2OID;
*sizep *= sizeof(int);
error = sysctl(oid, 2, mibp, sizep, name, strlen(name));

View File

@ -28,7 +28,7 @@
.\" @(#)open.2 8.2 (Berkeley) 11/16/93
.\" $FreeBSD$
.\"
.Dd June 14, 2019
.Dd September 17, 2019
.Dt OPEN 2
.Os
.Sh NAME
@ -419,6 +419,11 @@ Too many symbolic links were encountered in translating the pathname.
.It Bq Er EISDIR
The named file is a directory, and the arguments specify
it is to be modified.
.It Bq Er EISDIR
The named file is a directory, and the flags specified
.Dv O_CREAT
without
.Dv O_DIRECTORY .
.It Bq Er EROFS
The named file resides on a read-only file system,
and the file is to be modified.

View File

@ -143,6 +143,7 @@ PMC_CLASSDEP_TABLE(k8, K8);
PMC_CLASSDEP_TABLE(xscale, XSCALE);
PMC_CLASSDEP_TABLE(armv7, ARMV7);
PMC_CLASSDEP_TABLE(armv8, ARMV8);
PMC_CLASSDEP_TABLE(beri, BERI);
PMC_CLASSDEP_TABLE(mips24k, MIPS24K);
PMC_CLASSDEP_TABLE(mips74k, MIPS74K);
PMC_CLASSDEP_TABLE(octeon, OCTEON);
@ -187,6 +188,7 @@ static const struct pmc_event_descr cortex_a57_event_table[] =
PMC_MDEP_TABLE(k8, K8, PMC_CLASS_SOFT, PMC_CLASS_TSC);
PMC_MDEP_TABLE(xscale, XSCALE, PMC_CLASS_SOFT, PMC_CLASS_XSCALE);
PMC_MDEP_TABLE(beri, BERI, PMC_CLASS_SOFT, PMC_CLASS_BERI);
PMC_MDEP_TABLE(cortex_a8, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
PMC_MDEP_TABLE(cortex_a9, ARMV7, PMC_CLASS_SOFT, PMC_CLASS_ARMV7);
PMC_MDEP_TABLE(cortex_a53, ARMV8, PMC_CLASS_SOFT, PMC_CLASS_ARMV8);
@ -235,6 +237,7 @@ PMC_CLASS_TABLE_DESC(cortex_a53, ARMV8, cortex_a53, arm64);
PMC_CLASS_TABLE_DESC(cortex_a57, ARMV8, cortex_a57, arm64);
#endif
#if defined(__mips__)
PMC_CLASS_TABLE_DESC(beri, BERI, beri, mips);
PMC_CLASS_TABLE_DESC(mips24k, MIPS24K, mips24k, mips);
PMC_CLASS_TABLE_DESC(mips74k, MIPS74K, mips74k, mips);
PMC_CLASS_TABLE_DESC(octeon, OCTEON, octeon, mips);
@ -829,6 +832,11 @@ arm64_allocate_pmc(enum pmc_event pe, char *ctrspec __unused,
#if defined(__mips__)
static struct pmc_event_alias beri_aliases[] = {
EV_ALIAS("instructions", "INST"),
EV_ALIAS(NULL, NULL)
};
static struct pmc_event_alias mips24k_aliases[] = {
EV_ALIAS("instructions", "INSTR_EXECUTED"),
EV_ALIAS("branches", "BRANCH_COMPLETED"),
@ -1267,6 +1275,10 @@ pmc_event_names_of_class(enum pmc_class cl, const char ***eventnames,
break;
}
break;
case PMC_CLASS_BERI:
ev = beri_event_table;
count = PMC_EVENT_TABLE_SIZE(beri);
break;
case PMC_CLASS_MIPS24K:
ev = mips24k_event_table;
count = PMC_EVENT_TABLE_SIZE(mips24k);
@ -1508,6 +1520,10 @@ pmc_init(void)
break;
#endif
#if defined(__mips__)
case PMC_CPU_MIPS_BERI:
PMC_MDEP_INIT(beri);
pmc_class_table[n] = &beri_class_table_descr;
break;
case PMC_CPU_MIPS_24K:
PMC_MDEP_INIT(mips24k);
pmc_class_table[n] = &mips24k_class_table_descr;
@ -1645,6 +1661,9 @@ _pmc_name_of_event(enum pmc_event pe, enum pmc_cputype cpu)
default: /* Unknown CPU type. */
break;
}
} else if (pe >= PMC_EV_BERI_FIRST && pe <= PMC_EV_BERI_LAST) {
ev = beri_event_table;
evfence = beri_event_table + PMC_EVENT_TABLE_SIZE(beri);
} else if (pe >= PMC_EV_MIPS24K_FIRST && pe <= PMC_EV_MIPS24K_LAST) {
ev = mips24k_event_table;
evfence = mips24k_event_table + PMC_EVENT_TABLE_SIZE(mips24k);

View File

@ -80,6 +80,7 @@
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -110,18 +111,20 @@ static void
media_status(int s)
{
struct ifmediareq ifmr;
struct ifdownreason ifdr;
int *media_list, i;
int xmedia = 1;
bool no_carrier, xmedia;
(void) memset(&ifmr, 0, sizeof(ifmr));
(void) strlcpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
xmedia = true;
/*
* Check if interface supports extended media types.
*/
if (ioctl(s, SIOCGIFXMEDIA, (caddr_t)&ifmr) < 0)
xmedia = 0;
if (xmedia == 0 && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
xmedia = false;
if (!xmedia && ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
/*
* Interface doesn't support SIOC{G,S}IFMEDIA.
*/
@ -158,6 +161,7 @@ media_status(int s)
putchar('\n');
if (ifmr.ifm_status & IFM_AVALID) {
no_carrier = false;
printf("\tstatus: ");
switch (IFM_TYPE(ifmr.ifm_active)) {
case IFM_ETHER:
@ -165,7 +169,7 @@ media_status(int s)
if (ifmr.ifm_status & IFM_ACTIVE)
printf("active");
else
printf("no carrier");
no_carrier = true;
break;
case IFM_IEEE80211:
@ -176,9 +180,27 @@ media_status(int s)
else
printf("running");
} else
printf("no carrier");
no_carrier = true;
break;
}
if (no_carrier) {
printf("no carrier");
memset(&ifdr, 0, sizeof(ifdr));
strlcpy(ifdr.ifdr_name, name, sizeof(ifdr.ifdr_name));
if (ioctl(s, SIOCGIFDOWNREASON, (caddr_t)&ifdr) == 0) {
switch (ifdr.ifdr_reason) {
case IFDR_REASON_MSG:
printf(" (%s)", ifdr.ifdr_msg);
break;
case IFDR_REASON_VENDOR:
printf(" (vendor code %d)",
ifdr.ifdr_vendor);
break;
default:
break;
}
}
}
putchar('\n');
}

View File

@ -1,6 +1,6 @@
.\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
.\" $FreeBSD$
.Dd August 16, 2019
.Dd September 17, 2019
.Dt SRC.CONF 5
.Os
.Sh NAME
@ -831,6 +831,17 @@ Set to neither build nor install
.Lb libgmock ,
.Lb libgtest ,
and dependent tests.
.Pp
This is a default setting on
mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf and mips/mips64hf.
.It Va WITH_GOOGLETEST
Set to build and install
.Lb libgmock ,
.Lb libgtest ,
and dependent tests.
.Pp
This is a default setting on
amd64/amd64, arm/arm, arm/armv6, arm/armv7, arm64/aarch64, i386/i386, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64 and sparc64/sparc64.
.It Va WITHOUT_GPIO
Set to not build
.Xr gpioctl 8

View File

@ -230,7 +230,7 @@ LIBVERIEXEC?= ${LIBVERIEXECDIR}/libveriexec${PIE_SUFFIX}.a
# Each library's LIBADD needs to be duplicated here for static linkage of
# 2nd+ order consumers. Auto-generating this would be better.
_DP_80211= sbuf bsdxml
_DP_archive= z bz2 lzma bsdxml
_DP_archive= z bz2 lzma bsdxml zstd
_DP_zstd= pthread
.if ${MK_BLACKLIST} != "no"
_DP_blacklist+= pthread

View File

@ -108,7 +108,6 @@ __DEFAULT_YES_OPTIONS = \
GDB \
GNU_DIFF \
GNU_GREP \
GOOGLETEST \
GPIO \
HAST \
HTML \
@ -260,6 +259,15 @@ __TT=${TARGET}
__TT=${MACHINE}
.endif
# Default GOOGLETEST to off for MIPS while LLVM PR 43263 is active. Part
# of the fusefs tests trigger excessively long compile times. It does
# eventually succeed, but this shouldn't be forced on those building by default.
.if ${__TT} == "mips"
__DEFAULT_NO_OPTIONS+= GOOGLETEST
.else
__DEFAULT_YES_OPTIONS+= GOOGLETEST
.endif
# All supported backends for LLVM_TARGET_XXX
__LLVM_TARGETS= \
aarch64 \

View File

@ -64,6 +64,9 @@ static int efipart_printhd(int);
#define PNP0700 0x700
#define PNP0701 0x701
/* Bounce buffer max size */
#define BIO_BUFFER_SIZE 0x4000
struct devsw efipart_fddev = {
.dv_name = "fd",
.dv_type = DEVT_FD,
@ -266,6 +269,12 @@ efipart_inithandles(void)
continue;
}
/* Allowed values are 0, 1 and power of 2. */
if (blkio->Media->IoAlign > 1 &&
!powerof2(blkio->Media->IoAlign)) {
continue;
}
/* This is bad. */
if ((pd = calloc(1, sizeof(*pd))) == NULL) {
printf("efipart_inithandles: Out of memory.\n");
@ -979,8 +988,10 @@ efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size,
EFI_BLOCK_IO *blkio;
uint64_t off, disk_blocks, d_offset = 0;
char *blkbuf;
size_t blkoff, blksz;
int error;
size_t blkoff, blksz, bio_size;
unsigned ioalign;
bool need_buf;
int rc;
uint64_t diskend, readstart;
if (dev == NULL || blk < 0)
@ -1028,40 +1039,118 @@ efipart_realstrategy(void *devdata, int rw, daddr_t blk, size_t size,
size = size * blkio->Media->BlockSize;
}
if (rsize != NULL)
*rsize = size;
need_buf = true;
/* Do we need bounce buffer? */
if ((size % blkio->Media->BlockSize == 0) &&
(off % blkio->Media->BlockSize == 0))
return (efipart_readwrite(blkio, rw,
off / blkio->Media->BlockSize,
size / blkio->Media->BlockSize, buf));
need_buf = false;
/* Do we have IO alignment requirement? */
ioalign = blkio->Media->IoAlign;
if (ioalign == 0)
ioalign++;
if (ioalign > 1 && (uintptr_t)buf != roundup2((uintptr_t)buf, ioalign))
need_buf = true;
if (need_buf) {
for (bio_size = BIO_BUFFER_SIZE; bio_size > 0;
bio_size -= blkio->Media->BlockSize) {
blkbuf = memalign(ioalign, bio_size);
if (blkbuf != NULL)
break;
}
} else {
blkbuf = buf;
bio_size = size;
}
/*
* The buffer size is not a multiple of the media block size.
*/
blkbuf = malloc(blkio->Media->BlockSize);
if (blkbuf == NULL)
return (ENOMEM);
error = 0;
if (rsize != NULL)
*rsize = size;
rc = 0;
blk = off / blkio->Media->BlockSize;
blkoff = off % blkio->Media->BlockSize;
blksz = blkio->Media->BlockSize - blkoff;
while (size > 0) {
error = efipart_readwrite(blkio, rw, blk, 1, blkbuf);
if (error)
size_t x = min(size, bio_size);
if (x < blkio->Media->BlockSize)
x = 1;
else
x /= blkio->Media->BlockSize;
switch (rw & F_MASK) {
case F_READ:
blksz = blkio->Media->BlockSize * x - blkoff;
if (size < blksz)
blksz = size;
rc = efipart_readwrite(blkio, rw, blk, x, blkbuf);
if (rc != 0)
goto error;
if (need_buf)
bcopy(blkbuf + blkoff, buf, blksz);
break;
if (size < blksz)
blksz = size;
bcopy(blkbuf + blkoff, buf, blksz);
case F_WRITE:
rc = 0;
if (blkoff != 0) {
/*
* We got offset to sector, read 1 sector to
* blkbuf.
*/
x = 1;
blksz = blkio->Media->BlockSize - blkoff;
blksz = min(blksz, size);
rc = efipart_readwrite(blkio, F_READ, blk, x,
blkbuf);
} else if (size < blkio->Media->BlockSize) {
/*
* The remaining block is not full
* sector. Read 1 sector to blkbuf.
*/
x = 1;
blksz = size;
rc = efipart_readwrite(blkio, F_READ, blk, x,
blkbuf);
} else {
/* We can write full sector(s). */
blksz = blkio->Media->BlockSize * x;
}
if (rc != 0)
goto error;
/*
* Put your Data In, Put your Data out,
* Put your Data In, and shake it all about
*/
if (need_buf)
bcopy(buf, blkbuf + blkoff, blksz);
rc = efipart_readwrite(blkio, F_WRITE, blk, x, blkbuf);
if (rc != 0)
goto error;
break;
default:
/* DO NOTHING */
rc = EROFS;
goto error;
}
blkoff = 0;
buf += blksz;
size -= blksz;
blk++;
blkoff = 0;
blksz = blkio->Media->BlockSize;
blk += x;
}
free(blkbuf);
return (error);
error:
if (rsize != NULL)
*rsize -= size;
if (need_buf)
free(blkbuf);
return (rc);
}

View File

@ -27,6 +27,29 @@
only forth definitions
\ provide u> if needed
s" u>" sfind [if] drop [else]
drop
: u>
2dup u< if 2drop 0 exit then
swap u< if -1 exit then
0
;
[then]
\ provide xemit if needed
s" xemit" sfind [if] drop [else]
drop
: xemit
dup 0x80 u< if emit exit then
0 swap 0x3F
begin 2dup u> while
2/ >r dup 0x3F and 0x80 or swap 6 rshift r>
repeat 0x7F xor 2* or
begin dup 0x80 u< 0= while emit repeat drop
;
[then]
s" arch-i386" environment? [if] [if]
s" loader_version" environment? [if]
11 < [if]

View File

@ -264,9 +264,6 @@ static __inline int tolower(int c)
extern void setheap(void *base, void *top);
extern char *sbrk(int incr);
extern void *reallocf(void *ptr, size_t size);
extern void mallocstats(void);
extern int printf(const char *fmt, ...) __printflike(1, 2);
extern int asprintf(char **buf, const char *cfmt, ...) __printflike(2, 3);
extern int sprintf(char *buf, const char *cfmt, ...) __printflike(2, 3);
@ -430,20 +427,27 @@ extern uint16_t ntohs(uint16_t);
#endif
void *Malloc(size_t, const char *, int);
void *Memalign(size_t, size_t, const char *, int);
void *Calloc(size_t, size_t, const char *, int);
void *Realloc(void *, size_t, const char *, int);
void *Reallocf(void *, size_t, const char *, int);
void Free(void *, const char *, int);
extern void mallocstats(void);
#ifdef DEBUG_MALLOC
#define malloc(x) Malloc(x, __FILE__, __LINE__)
#define memalign(x, y) Memalign(x, y, __FILE__, __LINE__)
#define calloc(x, y) Calloc(x, y, __FILE__, __LINE__)
#define free(x) Free(x, __FILE__, __LINE__)
#define realloc(x, y) Realloc(x, y, __FILE__, __LINE__)
#define reallocf(x, y) Reallocf(x, y, __FILE__, __LINE__)
#else
#define malloc(x) Malloc(x, NULL, 0)
#define memalign(x, y) Memalign(x, y, NULL, 0)
#define calloc(x, y) Calloc(x, y, NULL, 0)
#define free(x) Free(x, NULL, 0)
#define realloc(x, y) Realloc(x, y, NULL, 0)
#define reallocf(x, y) Reallocf(x, y, NULL, 0)
#endif
#endif /* STAND_H */

View File

@ -1,5 +1,5 @@
/*
* This module derived from code donated to the FreeBSD Project by
* This module derived from code donated to the FreeBSD Project by
* Matthew Dillon <dillon@backplane.com>
*
* Copyright (c) 1998 The FreeBSD Project
@ -30,11 +30,13 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
/*
* LIB/MEMORY/ZALLOC.C - self contained low-overhead memory pool/allocation
* LIB/MEMORY/ZALLOC.C - self contained low-overhead memory pool/allocation
* subsystem
*
* This subsystem implements memory pools and memory allocation
* This subsystem implements memory pools and memory allocation
* routines.
*
* Pools are managed via a linked list of 'free' areas. Allocating
@ -43,7 +45,7 @@ __FBSDID("$FreeBSD$");
* to allocate the entire pool without incuring any structural overhead.
*
* The system works best when allocating similarly-sized chunks of
* memory. Care must be taken to avoid fragmentation when
* memory. Care must be taken to avoid fragmentation when
* allocating/deallocating dissimilar chunks.
*
* When a memory pool is first allocated, the entire pool is marked as
@ -53,7 +55,7 @@ __FBSDID("$FreeBSD$");
* available.
*
* z[n]xalloc() works like z[n]alloc() but the allocation is made from
* within the specified address range. If the segment could not be
* within the specified address range. If the segment could not be
* allocated, NULL is returned. WARNING! The address range will be
* aligned to an 8 or 16 byte boundry depending on the cpu so if you
* give an unaligned address range, unexpected results may occur.
@ -86,58 +88,82 @@ typedef char assert_align[(sizeof(struct MemNode) <= MALLOCALIGN) ? 1 : -1];
*/
void *
znalloc(MemPool *mp, uintptr_t bytes)
znalloc(MemPool *mp, uintptr_t bytes, size_t align)
{
/*
* align according to pool object size (can be 0). This is
* inclusive of the MEMNODE_SIZE_MASK minimum alignment.
*
*/
bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
if (bytes == 0)
return((void *)-1);
/*
* locate freelist entry big enough to hold the object. If all objects
* are the same size, this is a constant-time function.
*/
if (bytes <= mp->mp_Size - mp->mp_Used) {
MemNode **pmn;
MemNode *mn;
for (pmn = &mp->mp_First; (mn=*pmn) != NULL; pmn = &mn->mr_Next) {
if (bytes > mn->mr_Bytes)
continue;
/*
* align according to pool object size (can be 0). This is
* inclusive of the MEMNODE_SIZE_MASK minimum alignment.
*
*/
bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
/*
* Cut a chunk of memory out of the beginning of this
* block and fixup the link appropriately.
*/
if (bytes == 0)
return ((void *)-1);
{
/*
* locate freelist entry big enough to hold the object. If all objects
* are the same size, this is a constant-time function.
*/
if (bytes > mp->mp_Size - mp->mp_Used)
return (NULL);
for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) {
char *ptr = (char *)mn;
uintptr_t dptr;
char *aligned;
size_t extra;
dptr = (uintptr_t)(ptr + MALLOCALIGN); /* pointer to data */
aligned = (char *)(roundup2(dptr, align) - MALLOCALIGN);
extra = aligned - ptr;
if (bytes + extra > mn->mr_Bytes)
continue;
/*
* Cut extra from head and create new memory node from reminder.
*/
if (extra != 0) {
MemNode *new;
new = (MemNode *)aligned;
new->mr_Next = mn->mr_Next;
new->mr_Bytes = mn->mr_Bytes - extra;
/* And update current memory node */
mn->mr_Bytes = extra;
mn->mr_Next = new;
/* In next iteration, we will get our aligned address */
continue;
}
/*
* Cut a chunk of memory out of the beginning of this
* block and fixup the link appropriately.
*/
if (mn->mr_Bytes == bytes) {
*pmn = mn->mr_Next;
*pmn = mn->mr_Next;
} else {
mn = (MemNode *)((char *)mn + bytes);
mn->mr_Next = ((MemNode *)ptr)->mr_Next;
mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes;
*pmn = mn;
mn = (MemNode *)((char *)mn + bytes);
mn->mr_Next = ((MemNode *)ptr)->mr_Next;
mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes;
*pmn = mn;
}
mp->mp_Used += bytes;
return(ptr);
}
}
}
/*
* Memory pool is full, return NULL.
*/
/*
* Memory pool is full, return NULL.
*/
return(NULL);
return (NULL);
}
/*
@ -147,99 +173,97 @@ znalloc(MemPool *mp, uintptr_t bytes)
void
zfree(MemPool *mp, void *ptr, uintptr_t bytes)
{
/*
* align according to pool object size (can be 0). This is
* inclusive of the MEMNODE_SIZE_MASK minimum alignment.
*/
bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
if (bytes == 0)
return;
/*
* panic if illegal pointer
*/
if ((char *)ptr < (char *)mp->mp_Base ||
(char *)ptr + bytes > (char *)mp->mp_End ||
((uintptr_t)ptr & MEMNODE_SIZE_MASK) != 0)
panic("zfree(%p,%ju): wild pointer", ptr, (uintmax_t)bytes);
/*
* free the segment
*/
{
MemNode **pmn;
MemNode *mn;
/*
* align according to pool object size (can be 0). This is
* inclusive of the MEMNODE_SIZE_MASK minimum alignment.
*/
bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
if (bytes == 0)
return;
/*
* panic if illegal pointer
*/
if ((char *)ptr < (char *)mp->mp_Base ||
(char *)ptr + bytes > (char *)mp->mp_End ||
((uintptr_t)ptr & MEMNODE_SIZE_MASK) != 0)
panic("zfree(%p,%ju): wild pointer", ptr, (uintmax_t)bytes);
/*
* free the segment
*/
mp->mp_Used -= bytes;
for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) {
/*
* If area between last node and current node
* - check range
* - check merge with next area
* - check merge with previous area
*/
if ((char *)ptr <= (char *)mn) {
/*
* range check
* If area between last node and current node
* - check range
* - check merge with next area
* - check merge with previous area
*/
if ((char *)ptr + bytes > (char *)mn) {
panic("zfree(%p,%ju): corrupt memlist1", ptr,
(uintmax_t)bytes);
if ((char *)ptr <= (char *)mn) {
/*
* range check
*/
if ((char *)ptr + bytes > (char *)mn) {
panic("zfree(%p,%ju): corrupt memlist1", ptr,
(uintmax_t)bytes);
}
/*
* merge against next area or create independant area
*/
if ((char *)ptr + bytes == (char *)mn) {
((MemNode *)ptr)->mr_Next = mn->mr_Next;
((MemNode *)ptr)->mr_Bytes =
bytes + mn->mr_Bytes;
} else {
((MemNode *)ptr)->mr_Next = mn;
((MemNode *)ptr)->mr_Bytes = bytes;
}
*pmn = mn = (MemNode *)ptr;
/*
* merge against previous area (if there is a previous
* area).
*/
if (pmn != &mp->mp_First) {
if ((char *)pmn + ((MemNode*)pmn)->mr_Bytes ==
(char *)ptr) {
((MemNode *)pmn)->mr_Next = mn->mr_Next;
((MemNode *)pmn)->mr_Bytes +=
mn->mr_Bytes;
mn = (MemNode *)pmn;
}
}
return;
}
/*
* merge against next area or create independant area
*/
if ((char *)ptr + bytes == (char *)mn) {
((MemNode *)ptr)->mr_Next = mn->mr_Next;
((MemNode *)ptr)->mr_Bytes= bytes + mn->mr_Bytes;
} else {
((MemNode *)ptr)->mr_Next = mn;
((MemNode *)ptr)->mr_Bytes= bytes;
if ((char *)ptr < (char *)mn + mn->mr_Bytes) {
panic("zfree(%p,%ju): corrupt memlist2", ptr,
(uintmax_t)bytes);
}
*pmn = mn = (MemNode *)ptr;
/*
* merge against previous area (if there is a previous
* area).
*/
if (pmn != &mp->mp_First) {
if ((char*)pmn + ((MemNode*)pmn)->mr_Bytes == (char*)ptr) {
((MemNode *)pmn)->mr_Next = mn->mr_Next;
((MemNode *)pmn)->mr_Bytes += mn->mr_Bytes;
mn = (MemNode *)pmn;
}
}
return;
/* NOT REACHED */
}
if ((char *)ptr < (char *)mn + mn->mr_Bytes) {
panic("zfree(%p,%ju): corrupt memlist2", ptr,
(uintmax_t)bytes);
}
}
/*
* We are beyond the last MemNode, append new MemNode. Merge against
* previous area if possible.
*/
if (pmn == &mp->mp_First ||
(char *)pmn + ((MemNode *)pmn)->mr_Bytes != (char *)ptr
) {
((MemNode *)ptr)->mr_Next = NULL;
((MemNode *)ptr)->mr_Bytes = bytes;
*pmn = (MemNode *)ptr;
mn = (MemNode *)ptr;
if (pmn == &mp->mp_First ||
(char *)pmn + ((MemNode *)pmn)->mr_Bytes != (char *)ptr) {
((MemNode *)ptr)->mr_Next = NULL;
((MemNode *)ptr)->mr_Bytes = bytes;
*pmn = (MemNode *)ptr;
mn = (MemNode *)ptr;
} else {
((MemNode *)pmn)->mr_Bytes += bytes;
mn = (MemNode *)pmn;
((MemNode *)pmn)->mr_Bytes += bytes;
mn = (MemNode *)pmn;
}
}
}
/*
@ -256,26 +280,26 @@ zfree(MemPool *mp, void *ptr, uintptr_t bytes)
void
zextendPool(MemPool *mp, void *base, uintptr_t bytes)
{
if (mp->mp_Size == 0) {
mp->mp_Base = base;
mp->mp_Used = bytes;
mp->mp_End = (char *)base + bytes;
mp->mp_Size = bytes;
} else {
void *pend = (char *)mp->mp_Base + mp->mp_Size;
if (mp->mp_Size == 0) {
mp->mp_Base = base;
mp->mp_Used = bytes;
mp->mp_End = (char *)base + bytes;
mp->mp_Size = bytes;
} else {
void *pend = (char *)mp->mp_Base + mp->mp_Size;
if (base < mp->mp_Base) {
mp->mp_Size += (char *)mp->mp_Base - (char *)base;
mp->mp_Used += (char *)mp->mp_Base - (char *)base;
mp->mp_Base = base;
if (base < mp->mp_Base) {
mp->mp_Size += (char *)mp->mp_Base - (char *)base;
mp->mp_Used += (char *)mp->mp_Base - (char *)base;
mp->mp_Base = base;
}
base = (char *)base + bytes;
if (base > pend) {
mp->mp_Size += (char *)base - (char *)pend;
mp->mp_Used += (char *)base - (char *)pend;
mp->mp_End = (char *)base;
}
}
base = (char *)base + bytes;
if (base > pend) {
mp->mp_Size += (char *)base - (char *)pend;
mp->mp_Used += (char *)base - (char *)pend;
mp->mp_End = (char *)base;
}
}
}
#ifdef ZALLOCDEBUG
@ -283,34 +307,32 @@ zextendPool(MemPool *mp, void *base, uintptr_t bytes)
void
zallocstats(MemPool *mp)
{
int abytes = 0;
int hbytes = 0;
int fcount = 0;
MemNode *mn;
int abytes = 0;
int hbytes = 0;
int fcount = 0;
MemNode *mn;
printf("%d bytes reserved", (int) mp->mp_Size);
printf("%d bytes reserved", (int)mp->mp_Size);
mn = mp->mp_First;
mn = mp->mp_First;
if ((void *)mn != (void *)mp->mp_Base) {
abytes += (char *)mn - (char *)mp->mp_Base;
}
while (mn) {
if ((char *)mn + mn->mr_Bytes != mp->mp_End) {
hbytes += mn->mr_Bytes;
++fcount;
if ((void *)mn != (void *)mp->mp_Base) {
abytes += (char *)mn - (char *)mp->mp_Base;
}
if (mn->mr_Next)
abytes += (char *)mn->mr_Next - ((char *)mn + mn->mr_Bytes);
mn = mn->mr_Next;
}
printf(" %d bytes allocated\n%d fragments (%d bytes fragmented)\n",
abytes,
fcount,
hbytes
);
while (mn != NULL) {
if ((char *)mn + mn->mr_Bytes != mp->mp_End) {
hbytes += mn->mr_Bytes;
++fcount;
}
if (mn->mr_Next != NULL) {
abytes += (char *)mn->mr_Next -
((char *)mn + mn->mr_Bytes);
}
mn = mn->mr_Next;
}
printf(" %d bytes allocated\n%d fragments (%d bytes fragmented)\n",
abytes, fcount, hbytes);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* This module derived from code donated to the FreeBSD Project by
* This module derived from code donated to the FreeBSD Project by
* Matthew Dillon <dillon@backplane.com>
*
* Copyright (c) 1998 The FreeBSD Project
@ -33,23 +33,26 @@
* DEFS.H
*/
#define USEGUARD /* use stard/end guard bytes */
#define USEENDGUARD
#define DMALLOCDEBUG /* add debugging code to gather stats */
#define ZALLOCDEBUG
#ifndef _ZALLOC_DEFS_H
#define _ZALLOC_DEFS_H
#define USEGUARD /* use stard/end guard bytes */
#define USEENDGUARD
#define DMALLOCDEBUG /* add debugging code to gather stats */
#define ZALLOCDEBUG
#include <sys/stdint.h>
#include "stand.h"
#include "zalloc_mem.h"
#define Library extern
#define Library extern
/*
* block extension for sbrk()
*/
#define BLKEXTEND (4 * 1024)
#define BLKEXTENDMASK (BLKEXTEND - 1)
#define BLKEXTEND (4 * 1024)
#define BLKEXTENDMASK (BLKEXTEND - 1)
/*
* Required malloc alignment.
@ -68,11 +71,13 @@
#define MALLOCALIGN_MASK (MALLOCALIGN - 1)
typedef struct Guard {
size_t ga_Bytes;
size_t ga_Magic; /* must be at least 32 bits */
size_t ga_Bytes;
size_t ga_Magic; /* must be at least 32 bits */
} Guard;
#define GAMAGIC 0x55FF44FD
#define GAFREE 0x5F54F4DF
#define GAMAGIC 0x55FF44FD
#define GAFREE 0x5F54F4DF
#include "zalloc_protos.h"
#endif /* _ZALLOC_DEFS_H */

View File

@ -1,5 +1,5 @@
/*
* This module derived from code donated to the FreeBSD Project by
* This module derived from code donated to the FreeBSD Project by
* Matthew Dillon <dillon@backplane.com>
*
* Copyright (c) 1998 The FreeBSD Project
@ -50,142 +50,163 @@ void mallocstats(void);
#undef free
#endif
void *
Malloc(size_t bytes, const char *file, int line)
{
Guard *res;
static void *Malloc_align(size_t, size_t);
if (bytes == 0)
return (NULL);
void *
Malloc(size_t bytes, const char *file __unused, int line __unused)
{
return (Malloc_align(bytes, 1));
}
void *
Memalign(size_t alignment, size_t bytes, const char *file __unused,
int line __unused)
{
if (alignment == 0)
alignment = 1;
return (Malloc_align(bytes, alignment));
}
static void *
Malloc_align(size_t bytes, size_t alignment)
{
Guard *res;
#ifdef USEENDGUARD
bytes += MALLOCALIGN + 1;
bytes += MALLOCALIGN + 1;
#else
bytes += MALLOCALIGN;
bytes += MALLOCALIGN;
#endif
while ((res = znalloc(&MallocPool, bytes)) == NULL) {
int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
char *base;
while ((res = znalloc(&MallocPool, bytes, alignment)) == NULL) {
int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
char *base;
if ((base = sbrk(incr)) == (char *)-1)
return(NULL);
zextendPool(&MallocPool, base, incr);
zfree(&MallocPool, base, incr);
}
if ((base = sbrk(incr)) == (char *)-1)
return (NULL);
zextendPool(&MallocPool, base, incr);
zfree(&MallocPool, base, incr);
}
#ifdef DMALLOCDEBUG
if (++MallocCount > MallocMax)
MallocMax = MallocCount;
if (++MallocCount > MallocMax)
MallocMax = MallocCount;
#endif
#ifdef USEGUARD
res->ga_Magic = GAMAGIC;
res->ga_Magic = GAMAGIC;
#endif
res->ga_Bytes = bytes;
res->ga_Bytes = bytes;
#ifdef USEENDGUARD
*((signed char *)res + bytes - 1) = -2;
*((signed char *)res + bytes - 1) = -2;
#endif
return((char *)res + MALLOCALIGN);
return ((char *)res + MALLOCALIGN);
}
void
Free(void *ptr, const char *file, int line)
{
size_t bytes;
size_t bytes;
if (ptr != NULL) {
Guard *res = (void *)((char *)ptr - MALLOCALIGN);
if (ptr != NULL) {
Guard *res = (void *)((char *)ptr - MALLOCALIGN);
if (file == NULL)
file = "unknown";
if (file == NULL)
file = "unknown";
#ifdef USEGUARD
if (res->ga_Magic == GAFREE) {
printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line);
return;
}
if (res->ga_Magic != GAMAGIC)
panic("free: guard1 fail @ %p from %s:%d", ptr, file, line);
res->ga_Magic = GAFREE;
if (res->ga_Magic == GAFREE) {
printf("free: duplicate free @ %p from %s:%d\n",
ptr, file, line);
return;
}
if (res->ga_Magic != GAMAGIC)
panic("free: guard1 fail @ %p from %s:%d",
ptr, file, line);
res->ga_Magic = GAFREE;
#endif
#ifdef USEENDGUARD
if (*((signed char *)res + res->ga_Bytes - 1) == -1) {
printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line);
return;
}
if (*((signed char *)res + res->ga_Bytes - 1) != -2)
panic("free: guard2 fail @ %p + %zu from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line);
*((signed char *)res + res->ga_Bytes - 1) = -1;
if (*((signed char *)res + res->ga_Bytes - 1) == -1) {
printf("free: duplicate2 free @ %p from %s:%d\n",
ptr, file, line);
return;
}
if (*((signed char *)res + res->ga_Bytes - 1) != -2)
panic("free: guard2 fail @ %p + %zu from %s:%d",
ptr, res->ga_Bytes - MALLOCALIGN, file, line);
*((signed char *)res + res->ga_Bytes - 1) = -1;
#endif
bytes = res->ga_Bytes;
zfree(&MallocPool, res, bytes);
bytes = res->ga_Bytes;
zfree(&MallocPool, res, bytes);
#ifdef DMALLOCDEBUG
--MallocCount;
--MallocCount;
#endif
}
}
}
void *
Calloc(size_t n1, size_t n2, const char *file, int line)
{
uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2;
void *res;
uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2;
void *res;
if ((res = Malloc(bytes, file, line)) != NULL) {
bzero(res, bytes);
if ((res = Malloc(bytes, file, line)) != NULL) {
bzero(res, bytes);
#ifdef DMALLOCDEBUG
if (++MallocCount > MallocMax)
MallocMax = MallocCount;
if (++MallocCount > MallocMax)
MallocMax = MallocCount;
#endif
}
return(res);
}
return (res);
}
/*
* realloc() - I could be fancier here and free the old buffer before
* allocating the new one (saving potential fragmentation
* allocating the new one (saving potential fragmentation
* and potential buffer copies). But I don't bother.
*/
void *
Realloc(void *ptr, size_t size, const char *file, int line)
{
void *res;
size_t old;
void *res;
size_t old;
if ((res = Malloc(size, file, line)) != NULL) {
if (ptr) {
old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
if (old < size)
bcopy(ptr, res, old);
else
bcopy(ptr, res, size);
Free(ptr, file, line);
} else {
if ((res = Malloc(size, file, line)) != NULL) {
if (ptr != NULL) {
Guard *g = (Guard *)((char *)ptr - MALLOCALIGN);
old = g->ga_Bytes - MALLOCALIGN;
if (old < size)
bcopy(ptr, res, old);
else
bcopy(ptr, res, size);
Free(ptr, file, line);
} else {
#ifdef DMALLOCDEBUG
if (++MallocCount > MallocMax)
MallocMax = MallocCount;
if (++MallocCount > MallocMax)
MallocMax = MallocCount;
#ifdef EXITSTATS
if (DidAtExit == 0) {
DidAtExit = 1;
atexit(mallocstats);
}
if (DidAtExit == 0) {
DidAtExit = 1;
atexit(mallocstats);
}
#endif
#endif
}
}
}
return(res);
return (res);
}
void *
Reallocf(void *ptr, size_t size, const char *file, int line)
{
void *res;
void *res;
if ((res = Realloc(ptr, size, file, line)) == NULL)
Free(ptr, file, line);
return(res);
if ((res = Realloc(ptr, size, file, line)) == NULL)
Free(ptr, file, line);
return (res);
}
#ifdef DMALLOCDEBUG
@ -193,11 +214,10 @@ Reallocf(void *ptr, size_t size, const char *file, int line)
void
mallocstats(void)
{
printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
#ifdef ZALLOCDEBUG
zallocstats(&MallocPool);
zallocstats(&MallocPool);
#endif
}
#endif

View File

@ -1,5 +1,5 @@
/*
* This module derived from code donated to the FreeBSD Project by
* This module derived from code donated to the FreeBSD Project by
* Matthew Dillon <dillon@backplane.com>
*
* Copyright (c) 1998 The FreeBSD Project
@ -34,20 +34,23 @@
*
* Basic memory pool / memory node structures.
*/
#ifndef _ZALLOC_MEM_H
#define _ZALLOC_MEM_H
typedef struct MemNode {
struct MemNode *mr_Next;
uintptr_t mr_Bytes;
struct MemNode *mr_Next;
uintptr_t mr_Bytes;
} MemNode;
typedef struct MemPool {
void *mp_Base;
void *mp_End;
MemNode *mp_First;
uintptr_t mp_Size;
uintptr_t mp_Used;
void *mp_Base;
void *mp_End;
MemNode *mp_First;
uintptr_t mp_Size;
uintptr_t mp_Used;
} MemPool;
#define ZNOTE_FREE 0
#define ZNOTE_REUSE 1
#define ZNOTE_FREE 0
#define ZNOTE_REUSE 1
#endif /* _ZALLOC_MEM_H */

View File

@ -1,5 +1,5 @@
/*
* This module derived from code donated to the FreeBSD Project by
* This module derived from code donated to the FreeBSD Project by
* Matthew Dillon <dillon@backplane.com>
*
* Copyright (c) 1998 The FreeBSD Project
@ -29,7 +29,12 @@
* $FreeBSD$
*/
Library void *znalloc(struct MemPool *mpool, uintptr_t bytes);
#ifndef _ZALLOC_PROTOS_H
#define _ZALLOC_PROTOS_H
Library void *znalloc(struct MemPool *mpool, uintptr_t bytes, size_t align);
Library void zfree(struct MemPool *mpool, void *ptr, uintptr_t bytes);
Library void zextendPool(MemPool *mp, void *base, uintptr_t bytes);
Library void zallocstats(struct MemPool *mp);
#endif /* _ZALLOC_PROTOS_H */

View File

@ -19,7 +19,11 @@ INSTALLFLAGS= -b
WARNS?= 1
# Address at which ubldr will be loaded.
# This varies for different boards and SOCs.
.if ${MACHINE_ARCH:Mmips64*}
UBLDR_LOADADDR?= 0xffffffff80800000
.else
UBLDR_LOADADDR?= 0x80800000
.endif
# Architecture-specific loader code
SRCS= start.S conf.c vers.c

View File

@ -2014,16 +2014,17 @@ ds_clone_swapped_bookmark(dsl_dataset_t *ds1, dsl_dataset_t *ds2,
}
/*
* Called when a parent dataset and its clone are swapped. If we were
* Called when an origin dataset and its clone are swapped. If we were
* currently traversing the dataset, we need to switch to traversing the
* newly promoted parent.
* newly promoted clone.
*/
void
dsl_scan_ds_clone_swapped(dsl_dataset_t *ds1, dsl_dataset_t *ds2, dmu_tx_t *tx)
{
dsl_pool_t *dp = ds1->ds_dir->dd_pool;
dsl_scan_t *scn = dp->dp_scan;
uint64_t mintxg;
uint64_t mintxg1, mintxg2;
boolean_t ds1_queued, ds2_queued;
if (!dsl_scan_is_running(scn))
return;
@ -2031,44 +2032,81 @@ dsl_scan_ds_clone_swapped(dsl_dataset_t *ds1, dsl_dataset_t *ds2, dmu_tx_t *tx)
ds_clone_swapped_bookmark(ds1, ds2, &scn->scn_phys.scn_bookmark);
ds_clone_swapped_bookmark(ds1, ds2, &scn->scn_phys_cached.scn_bookmark);
if (scan_ds_queue_contains(scn, ds1->ds_object, &mintxg)) {
scan_ds_queue_remove(scn, ds1->ds_object);
scan_ds_queue_insert(scn, ds2->ds_object, mintxg);
/*
* Handle the in-memory scan queue.
*/
ds1_queued = scan_ds_queue_contains(scn, ds1->ds_object, &mintxg1);
ds2_queued = scan_ds_queue_contains(scn, ds2->ds_object, &mintxg2);
/* Sanity checking. */
if (ds1_queued) {
ASSERT3U(mintxg1, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
ASSERT3U(mintxg1, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
}
if (scan_ds_queue_contains(scn, ds2->ds_object, &mintxg)) {
scan_ds_queue_remove(scn, ds2->ds_object);
scan_ds_queue_insert(scn, ds1->ds_object, mintxg);
if (ds2_queued) {
ASSERT3U(mintxg2, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
ASSERT3U(mintxg2, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
}
if (zap_lookup_int_key(dp->dp_meta_objset, scn->scn_phys.scn_queue_obj,
ds1->ds_object, &mintxg) == 0) {
int err;
ASSERT3U(mintxg, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
ASSERT3U(mintxg, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
if (ds1_queued && ds2_queued) {
/*
* If both are queued, we don't need to do anything.
* The swapping code below would not handle this case correctly,
* since we can't insert ds2 if it is already there. That's
* because scan_ds_queue_insert() prohibits a duplicate insert
* and panics.
*/
} else if (ds1_queued) {
scan_ds_queue_remove(scn, ds1->ds_object);
scan_ds_queue_insert(scn, ds2->ds_object, mintxg1);
} else if (ds2_queued) {
scan_ds_queue_remove(scn, ds2->ds_object);
scan_ds_queue_insert(scn, ds1->ds_object, mintxg2);
}
/*
* Handle the on-disk scan queue.
* The on-disk state is an out-of-date version of the in-memory state,
* so the in-memory and on-disk values for ds1_queued and ds2_queued may
* be different. Therefore we need to apply the swap logic to the
* on-disk state independently of the in-memory state.
*/
ds1_queued = zap_lookup_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds1->ds_object, &mintxg1) == 0;
ds2_queued = zap_lookup_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds2->ds_object, &mintxg2) == 0;
/* Sanity checking. */
if (ds1_queued) {
ASSERT3U(mintxg1, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
ASSERT3U(mintxg1, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
}
if (ds2_queued) {
ASSERT3U(mintxg2, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
ASSERT3U(mintxg2, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
}
if (ds1_queued && ds2_queued) {
/*
* If both are queued, we don't need to do anything.
* Alternatively, we could check for EEXIST from
* zap_add_int_key() and back out to the original state, but
* that would be more work than checking for this case upfront.
*/
} else if (ds1_queued) {
VERIFY3S(0, ==, zap_remove_int(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds1->ds_object, tx));
err = zap_add_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds2->ds_object, mintxg, tx);
VERIFY(err == 0 || err == EEXIST);
if (err == EEXIST) {
/* Both were there to begin with */
VERIFY(0 == zap_add_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj,
ds1->ds_object, mintxg, tx));
}
VERIFY3S(0, ==, zap_add_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds2->ds_object, mintxg1, tx));
zfs_dbgmsg("clone_swap ds %llu; in queue; "
"replacing with %llu",
(u_longlong_t)ds1->ds_object,
(u_longlong_t)ds2->ds_object);
}
if (zap_lookup_int_key(dp->dp_meta_objset, scn->scn_phys.scn_queue_obj,
ds2->ds_object, &mintxg) == 0) {
ASSERT3U(mintxg, ==, dsl_dataset_phys(ds1)->ds_prev_snap_txg);
ASSERT3U(mintxg, ==, dsl_dataset_phys(ds2)->ds_prev_snap_txg);
VERIFY3U(0, ==, zap_remove_int(dp->dp_meta_objset,
} else if (ds2_queued) {
VERIFY3S(0, ==, zap_remove_int(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds2->ds_object, tx));
VERIFY(0 == zap_add_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds1->ds_object, mintxg, tx));
VERIFY3S(0, ==, zap_add_int_key(dp->dp_meta_objset,
scn->scn_phys.scn_queue_obj, ds1->ds_object, mintxg2, tx));
zfs_dbgmsg("clone_swap ds %llu; in queue; "
"replacing with %llu",
(u_longlong_t)ds2->ds_object,

View File

@ -5202,7 +5202,7 @@ zfs_freebsd_setattr(ap)
FLAG_CHANGE(UF_HIDDEN, ZFS_HIDDEN, XAT_HIDDEN,
xvap.xva_xoptattrs.xoa_hidden);
FLAG_CHANGE(UF_REPARSE, ZFS_REPARSE, XAT_REPARSE,
xvap.xva_xoptattrs.xoa_hidden);
xvap.xva_xoptattrs.xoa_reparse);
FLAG_CHANGE(UF_OFFLINE, ZFS_OFFLINE, XAT_OFFLINE,
xvap.xva_xoptattrs.xoa_offline);
FLAG_CHANGE(UF_SPARSE, ZFS_SPARSE, XAT_SPARSE,

View File

@ -91,7 +91,9 @@ dev/nvram2env/nvram2env_mips.c optional nvram2env
dev/nvram2env/nvram2env.c optional nvram2env
# hwpmc support
dev/hwpmc/hwpmc_mips.c optional hwpmc
dev/hwpmc/hwpmc_beri.c optional hwpmc_beri
dev/hwpmc/hwpmc_mips.c optional hwpmc_mips24k | \
hwpmc_mips74k
dev/hwpmc/hwpmc_mips24k.c optional hwpmc_mips24k
dev/hwpmc/hwpmc_mips74k.c optional hwpmc_mips74k

540
sys/dev/hwpmc/hwpmc_beri.c Normal file
View File

@ -0,0 +1,540 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Ruslan Bukin <br@bsdpad.com>
*
* This software was developed by SRI International and the University of
* Cambridge Computer Laboratory (Department of Computer Science and
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
* DARPA SSITH research programme.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_hwpmc_hooks.h"
#include <sys/param.h>
#include <sys/pmckern.h>
#include <dev/hwpmc/hwpmc_beri.h>
#define BERI_NCOUNTERS 56
#define BERI_PMC_CAPS (PMC_CAP_USER | PMC_CAP_SYSTEM | \
PMC_CAP_READ | PMC_CAP_WRITE )
struct beri_event_code_map {
uint32_t pe_ev; /* enum value */
uint64_t (*get_func)(void);
};
const struct beri_event_code_map beri_event_codes[BERI_NCOUNTERS] = {
{ PMC_EV_BERI_CYCLE,
statcounters_get_cycle_count },
{ PMC_EV_BERI_INST,
statcounters_get_inst_count },
{ PMC_EV_BERI_INST_USER,
statcounters_get_inst_user_count },
{ PMC_EV_BERI_INST_KERNEL,
statcounters_get_inst_kernel_count },
{ PMC_EV_BERI_IMPRECISE_SETBOUNDS,
statcounters_get_imprecise_setbounds_count },
{ PMC_EV_BERI_UNREPRESENTABLE_CAPS,
statcounters_get_unrepresentable_caps_count },
{ PMC_EV_BERI_ITLB_MISS,
statcounters_get_itlb_miss_count },
{ PMC_EV_BERI_DTLB_MISS,
statcounters_get_dtlb_miss_count },
{ PMC_EV_BERI_ICACHE_WRITE_HIT,
statcounters_get_icache_write_hit_count },
{ PMC_EV_BERI_ICACHE_WRITE_MISS,
statcounters_get_icache_write_miss_count },
{ PMC_EV_BERI_ICACHE_READ_HIT,
statcounters_get_icache_read_hit_count },
{ PMC_EV_BERI_ICACHE_READ_MISS,
statcounters_get_icache_read_miss_count },
{ PMC_EV_BERI_ICACHE_EVICT,
statcounters_get_icache_evict_count },
{ PMC_EV_BERI_DCACHE_WRITE_HIT,
statcounters_get_dcache_write_hit_count },
{ PMC_EV_BERI_DCACHE_WRITE_MISS,
statcounters_get_dcache_write_miss_count },
{ PMC_EV_BERI_DCACHE_READ_HIT,
statcounters_get_dcache_read_hit_count },
{ PMC_EV_BERI_DCACHE_READ_MISS,
statcounters_get_dcache_read_miss_count },
{ PMC_EV_BERI_DCACHE_EVICT,
statcounters_get_dcache_evict_count },
{ PMC_EV_BERI_DCACHE_SET_TAG_WRITE,
statcounters_get_dcache_set_tag_write_count },
{ PMC_EV_BERI_DCACHE_SET_TAG_READ,
statcounters_get_dcache_set_tag_read_count },
{ PMC_EV_BERI_L2CACHE_WRITE_HIT,
statcounters_get_l2cache_write_hit_count },
{ PMC_EV_BERI_L2CACHE_WRITE_MISS,
statcounters_get_l2cache_write_miss_count },
{ PMC_EV_BERI_L2CACHE_READ_HIT,
statcounters_get_l2cache_read_hit_count },
{ PMC_EV_BERI_L2CACHE_READ_MISS,
statcounters_get_l2cache_read_miss_count },
{ PMC_EV_BERI_L2CACHE_EVICT,
statcounters_get_l2cache_evict_count },
{ PMC_EV_BERI_L2CACHE_SET_TAG_WRITE,
statcounters_get_l2cache_set_tag_write_count },
{ PMC_EV_BERI_L2CACHE_SET_TAG_READ,
statcounters_get_l2cache_set_tag_read_count },
{ PMC_EV_BERI_MEM_BYTE_READ,
statcounters_get_mem_byte_read_count },
{ PMC_EV_BERI_MEM_BYTE_WRITE,
statcounters_get_mem_byte_write_count },
{ PMC_EV_BERI_MEM_HWORD_READ,
statcounters_get_mem_hword_read_count },
{ PMC_EV_BERI_MEM_HWORD_WRITE,
statcounters_get_mem_hword_write_count },
{ PMC_EV_BERI_MEM_WORD_READ,
statcounters_get_mem_word_read_count },
{ PMC_EV_BERI_MEM_WORD_WRITE,
statcounters_get_mem_word_write_count },
{ PMC_EV_BERI_MEM_DWORD_READ,
statcounters_get_mem_dword_read_count },
{ PMC_EV_BERI_MEM_DWORD_WRITE,
statcounters_get_mem_dword_write_count },
{ PMC_EV_BERI_MEM_CAP_READ,
statcounters_get_mem_cap_read_count },
{ PMC_EV_BERI_MEM_CAP_WRITE,
statcounters_get_mem_cap_write_count },
{ PMC_EV_BERI_MEM_CAP_READ_TAG_SET,
statcounters_get_mem_cap_read_tag_set_count },
{ PMC_EV_BERI_MEM_CAP_WRITE_TAG_SET,
statcounters_get_mem_cap_write_tag_set_count },
{ PMC_EV_BERI_TAGCACHE_WRITE_HIT,
statcounters_get_tagcache_write_hit_count },
{ PMC_EV_BERI_TAGCACHE_WRITE_MISS,
statcounters_get_tagcache_write_miss_count },
{ PMC_EV_BERI_TAGCACHE_READ_HIT,
statcounters_get_tagcache_read_hit_count },
{ PMC_EV_BERI_TAGCACHE_READ_MISS,
statcounters_get_tagcache_read_miss_count },
{ PMC_EV_BERI_TAGCACHE_EVICT,
statcounters_get_tagcache_evict_count },
{ PMC_EV_BERI_L2CACHEMASTER_READ_REQ,
statcounters_get_l2cachemaster_read_req_count },
{ PMC_EV_BERI_L2CACHEMASTER_WRITE_REQ,
statcounters_get_l2cachemaster_write_req_count },
{ PMC_EV_BERI_L2CACHEMASTER_WRITE_REQ_FLIT,
statcounters_get_l2cachemaster_write_req_flit_count },
{ PMC_EV_BERI_L2CACHEMASTER_READ_RSP,
statcounters_get_l2cachemaster_read_rsp_count },
{ PMC_EV_BERI_L2CACHEMASTER_READ_RSP_FLIT,
statcounters_get_l2cachemaster_read_rsp_flit_count },
{ PMC_EV_BERI_L2CACHEMASTER_WRITE_RSP,
statcounters_get_l2cachemaster_write_rsp_count },
{ PMC_EV_BERI_TAGCACHEMASTER_READ_REQ,
statcounters_get_tagcachemaster_read_req_count },
{ PMC_EV_BERI_TAGCACHEMASTER_WRITE_REQ,
statcounters_get_tagcachemaster_write_req_count },
{ PMC_EV_BERI_TAGCACHEMASTER_WRITE_REQ_FLIT,
statcounters_get_tagcachemaster_write_req_flit_count },
{ PMC_EV_BERI_TAGCACHEMASTER_READ_RSP,
statcounters_get_tagcachemaster_read_rsp_count },
{ PMC_EV_BERI_TAGCACHEMASTER_READ_RSP_FLIT,
statcounters_get_tagcachemaster_read_rsp_flit_count },
{ PMC_EV_BERI_TAGCACHEMASTER_WRITE_RSP,
statcounters_get_tagcachemaster_write_rsp_count },
};
struct mips_pmc_spec beri_pmc_spec = {
.ps_cpuclass = PMC_CLASS_BERI,
.ps_cputype = PMC_CPU_MIPS_BERI,
.ps_capabilities = BERI_PMC_CAPS,
.ps_counter_width = 64
};
/*
* Per-processor information.
*/
struct beri_cpu {
struct pmc_hw *pc_beripmcs;
uint64_t start_values[BERI_NCOUNTERS];
uint64_t stop_values[BERI_NCOUNTERS];
uint64_t saved_values[BERI_NCOUNTERS];
};
int beri_npmcs;
static struct beri_cpu **beri_pcpu;
static int
beri_allocate_pmc(int cpu, int ri, struct pmc *pm,
const struct pmc_op_pmcallocate *a)
{
uint32_t config;
int i;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d] illegal CPU value %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < beri_npmcs,
("[beri,%d] illegal row index %d", __LINE__, ri));
if (a->pm_class != beri_pmc_spec.ps_cpuclass)
return (EINVAL);
for (i = 0; i < BERI_NCOUNTERS; i++) {
if (beri_event_codes[i].pe_ev == a->pm_ev) {
config = i;
break;
}
}
if (i == BERI_NCOUNTERS)
return (EINVAL);
pm->pm_md.pm_mips_evsel = config;
PMCDBG2(MDP,ALL,2,"beri-allocate ri=%d -> config=0x%x", ri, config);
return (0);
}
static int
beri_read_pmc(int cpu, int ri, pmc_value_t *v)
{
uint32_t config;
struct pmc *pm;
pmc_value_t new;
pmc_value_t start_val;
pmc_value_t stop_val;
pmc_value_t saved_val;
pmc_value_t result;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d] illegal CPU value %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < beri_npmcs,
("[beri,%d] illegal row index %d", __LINE__, ri));
pm = beri_pcpu[cpu]->pc_beripmcs[ri].phw_pmc;
config = pm->pm_md.pm_mips_evsel;
start_val = beri_pcpu[cpu]->start_values[config];
if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm))) {
stop_val = beri_event_codes[config].get_func();
} else
stop_val = beri_pcpu[cpu]->stop_values[config];
if (start_val <= stop_val)
result = stop_val - start_val;
else {
if (config == 0) /* CYCLE counter is 48 bit */
result = 0x00ffffffffffffffUL;
else
result = 0xffffffffffffffffUL;
result -= start_val;
result += stop_val;
}
saved_val = beri_pcpu[cpu]->saved_values[config];
*v = result + saved_val;
return (0);
}
static int
beri_write_pmc(int cpu, int ri, pmc_value_t v)
{
struct pmc *pm;
uint32_t config;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d] illegal CPU value %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < beri_npmcs,
("[beri,%d] illegal row-index %d", __LINE__, ri));
pm = beri_pcpu[cpu]->pc_beripmcs[ri].phw_pmc;
config = pm->pm_md.pm_mips_evsel;
if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
v = (1UL << (beri_pmc_spec.ps_counter_width - 1)) - v;
PMCDBG3(MDP,WRI,1,"beri-write cpu=%d ri=%d v=%jx", cpu, ri, v);
if (PMC_IS_SYSTEM_MODE(PMC_TO_MODE(pm)))
beri_pcpu[cpu]->saved_values[config] = 0;
else
beri_pcpu[cpu]->saved_values[config] = v;
return (0);
}
static int
beri_config_pmc(int cpu, int ri, struct pmc *pm)
{
struct pmc_hw *phw;
PMCDBG3(MDP,CFG,1, "cpu=%d ri=%d pm=%p", cpu, ri, pm);
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d] illegal CPU value %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < beri_npmcs,
("[beri,%d] illegal row-index %d", __LINE__, ri));
phw = &beri_pcpu[cpu]->pc_beripmcs[ri];
KASSERT(pm == NULL || phw->phw_pmc == NULL,
("[beri,%d] pm=%p phw->pm=%p hwpmc not unconfigured",
__LINE__, pm, phw->phw_pmc));
phw->phw_pmc = pm;
return (0);
}
static int
beri_start_pmc(int cpu, int ri)
{
uint32_t config;
struct pmc *pm;
struct pmc_hw *phw;
pmc_value_t v;
phw = &beri_pcpu[cpu]->pc_beripmcs[ri];
pm = phw->phw_pmc;
config = pm->pm_md.pm_mips_evsel;
v = beri_event_codes[config].get_func();
beri_pcpu[cpu]->start_values[config] = v;
return (0);
}
static int
beri_stop_pmc(int cpu, int ri)
{
uint32_t config;
struct pmc *pm;
struct pmc_hw *phw;
pmc_value_t v;
phw = &beri_pcpu[cpu]->pc_beripmcs[ri];
pm = phw->phw_pmc;
config = pm->pm_md.pm_mips_evsel;
v = beri_event_codes[config].get_func();
beri_pcpu[cpu]->stop_values[config] = v;
return (0);
}
static int
beri_release_pmc(int cpu, int ri, struct pmc *pmc)
{
struct pmc_hw *phw;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d] illegal CPU value %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < beri_npmcs,
("[beri,%d] illegal row-index %d", __LINE__, ri));
phw = &beri_pcpu[cpu]->pc_beripmcs[ri];
KASSERT(phw->phw_pmc == NULL,
("[beri,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc));
return (0);
}
static int
beri_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc)
{
struct pmc_hw *phw;
char beri_name[PMC_NAME_MAX];
int error;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d], illegal CPU %d", __LINE__, cpu));
KASSERT(ri >= 0 && ri < beri_npmcs,
("[beri,%d] row-index %d out of range", __LINE__, ri));
phw = &beri_pcpu[cpu]->pc_beripmcs[ri];
snprintf(beri_name, sizeof(beri_name), "MIPS-%d", ri);
if ((error = copystr(beri_name, pi->pm_name, PMC_NAME_MAX,
NULL)) != 0)
return error;
pi->pm_class = beri_pmc_spec.ps_cpuclass;
if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) {
pi->pm_enabled = TRUE;
*ppmc = phw->phw_pmc;
} else {
pi->pm_enabled = FALSE;
*ppmc = NULL;
}
return (0);
}
static int
beri_get_config(int cpu, int ri, struct pmc **ppm)
{
*ppm = beri_pcpu[cpu]->pc_beripmcs[ri].phw_pmc;
return (0);
}
static int
beri_pmc_switch_in(struct pmc_cpu *pc, struct pmc_process *pp)
{
return (0);
}
static int
beri_pmc_switch_out(struct pmc_cpu *pc, struct pmc_process *pp)
{
return (0);
}
static int
beri_pcpu_init(struct pmc_mdep *md, int cpu)
{
int first_ri, i;
struct pmc_cpu *pc;
struct beri_cpu *pac;
struct pmc_hw *phw;
KASSERT(cpu >= 0 && cpu < pmc_cpu_max(),
("[beri,%d] wrong cpu number %d", __LINE__, cpu));
PMCDBG1(MDP,INI,1,"beri-init cpu=%d", cpu);
beri_pcpu[cpu] = pac = malloc(sizeof(struct beri_cpu), M_PMC,
M_WAITOK|M_ZERO);
pac->pc_beripmcs = malloc(sizeof(struct pmc_hw) * beri_npmcs,
M_PMC, M_WAITOK|M_ZERO);
pc = pmc_pcpu[cpu];
first_ri = md->pmd_classdep[PMC_MDEP_CLASS_INDEX_MIPS].pcd_ri;
KASSERT(pc != NULL, ("[beri,%d] NULL per-cpu pointer", __LINE__));
for (i = 0, phw = pac->pc_beripmcs; i < beri_npmcs; i++, phw++) {
phw->phw_state = PMC_PHW_FLAG_IS_ENABLED |
PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(i);
phw->phw_pmc = NULL;
pc->pc_hwpmcs[i + first_ri] = phw;
}
return (0);
}
static int
beri_pcpu_fini(struct pmc_mdep *md, int cpu)
{
return (0);
}
struct pmc_mdep *
pmc_beri_initialize()
{
struct pmc_mdep *pmc_mdep;
struct pmc_classdep *pcd;
snprintf(pmc_cpuid, sizeof(pmc_cpuid), "beri");
beri_npmcs = 2;
PMCDBG1(MDP,INI,1,"beri-init npmcs=%d", beri_npmcs);
/*
* Allocate space for pointers to PMC HW descriptors and for
* the MDEP structure used by MI code.
*/
beri_pcpu = malloc(sizeof(struct beri_cpu *) * pmc_cpu_max(), M_PMC,
M_WAITOK|M_ZERO);
/* Just one class */
pmc_mdep = pmc_mdep_alloc(1);
pmc_mdep->pmd_cputype = beri_pmc_spec.ps_cputype;
pcd = &pmc_mdep->pmd_classdep[PMC_MDEP_CLASS_INDEX_MIPS];
pcd->pcd_caps = beri_pmc_spec.ps_capabilities;
pcd->pcd_class = beri_pmc_spec.ps_cpuclass;
pcd->pcd_num = beri_npmcs;
pcd->pcd_ri = pmc_mdep->pmd_npmc;
pcd->pcd_width = beri_pmc_spec.ps_counter_width;
pcd->pcd_allocate_pmc = beri_allocate_pmc;
pcd->pcd_config_pmc = beri_config_pmc;
pcd->pcd_pcpu_fini = beri_pcpu_fini;
pcd->pcd_pcpu_init = beri_pcpu_init;
pcd->pcd_describe = beri_describe;
pcd->pcd_get_config = beri_get_config;
pcd->pcd_read_pmc = beri_read_pmc;
pcd->pcd_release_pmc = beri_release_pmc;
pcd->pcd_start_pmc = beri_start_pmc;
pcd->pcd_stop_pmc = beri_stop_pmc;
pcd->pcd_write_pmc = beri_write_pmc;
pmc_mdep->pmd_intr = NULL;
pmc_mdep->pmd_switch_in = beri_pmc_switch_in;
pmc_mdep->pmd_switch_out = beri_pmc_switch_out;
pmc_mdep->pmd_npmc += beri_npmcs;
return (pmc_mdep);
}
void
pmc_beri_finalize(struct pmc_mdep *md)
{
}
struct pmc_mdep *
pmc_md_initialize()
{
return (pmc_beri_initialize());
}
void
pmc_md_finalize(struct pmc_mdep *md)
{
return (pmc_beri_finalize(md));
}
int
pmc_save_kernel_callchain(uintptr_t *cc, int nframes,
struct trapframe *tf)
{
return (0);
}
int
pmc_save_user_callchain(uintptr_t *cc, int nframes,
struct trapframe *tf)
{
return (0);
}

107
sys/dev/hwpmc/hwpmc_beri.h Normal file
View File

@ -0,0 +1,107 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Alex Richardson
*
* This software was developed by SRI International and the University of
* Cambridge Computer Laboratory (Department of Computer Science and
* Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
* DARPA SSITH research programme.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _DEV_HWPMC_HWPMC_BERI_H_
#define _DEV_HWPMC_HWPMC_BERI_H_
#define STATCOUNTER_ITEM(name, X, Y) \
static inline uint64_t statcounters_get_##name##_count(void) \
{ \
uint64_t ret; \
__asm __volatile( \
".word (0x1f << 26) | (0x0 << 21) | \
(12 << 16) | ("#X" << 11) | \
( "#Y" << 6) | 0x3b\n\t" \
"move %0,$12" : "=r" (ret) :: "$12"); \
return (ret); \
}
STATCOUNTER_ITEM(cycle,2,0)
STATCOUNTER_ITEM(inst,4,0)
STATCOUNTER_ITEM(inst_user,4,1)
STATCOUNTER_ITEM(inst_kernel,4,2)
STATCOUNTER_ITEM(imprecise_setbounds,4,3)
STATCOUNTER_ITEM(unrepresentable_caps,4,4)
STATCOUNTER_ITEM(itlb_miss,5,0)
STATCOUNTER_ITEM(dtlb_miss,6,0)
STATCOUNTER_ITEM(icache_write_hit,8,0)
STATCOUNTER_ITEM(icache_write_miss,8,1)
STATCOUNTER_ITEM(icache_read_hit,8,2)
STATCOUNTER_ITEM(icache_read_miss,8,3)
STATCOUNTER_ITEM(icache_evict,8,6)
STATCOUNTER_ITEM(dcache_write_hit,9,0)
STATCOUNTER_ITEM(dcache_write_miss,9,1)
STATCOUNTER_ITEM(dcache_read_hit,9,2)
STATCOUNTER_ITEM(dcache_read_miss,9,3)
STATCOUNTER_ITEM(dcache_evict,9,6)
STATCOUNTER_ITEM(dcache_set_tag_write,9,8)
STATCOUNTER_ITEM(dcache_set_tag_read,9,9)
STATCOUNTER_ITEM(l2cache_write_hit,10,0)
STATCOUNTER_ITEM(l2cache_write_miss,10,1)
STATCOUNTER_ITEM(l2cache_read_hit,10,2)
STATCOUNTER_ITEM(l2cache_read_miss,10,3)
STATCOUNTER_ITEM(l2cache_evict,10,6)
STATCOUNTER_ITEM(l2cache_set_tag_write,10,8)
STATCOUNTER_ITEM(l2cache_set_tag_read,10,9)
STATCOUNTER_ITEM(mem_byte_read,11,0)
STATCOUNTER_ITEM(mem_byte_write,11,1)
STATCOUNTER_ITEM(mem_hword_read,11,2)
STATCOUNTER_ITEM(mem_hword_write,11,3)
STATCOUNTER_ITEM(mem_word_read,11,4)
STATCOUNTER_ITEM(mem_word_write,11,5)
STATCOUNTER_ITEM(mem_dword_read,11,6)
STATCOUNTER_ITEM(mem_dword_write,11,7)
STATCOUNTER_ITEM(mem_cap_read,11,8)
STATCOUNTER_ITEM(mem_cap_write,11,9)
STATCOUNTER_ITEM(mem_cap_read_tag_set,11,10)
STATCOUNTER_ITEM(mem_cap_write_tag_set,11,11)
STATCOUNTER_ITEM(tagcache_write_hit,12,0)
STATCOUNTER_ITEM(tagcache_write_miss,12,1)
STATCOUNTER_ITEM(tagcache_read_hit,12,2)
STATCOUNTER_ITEM(tagcache_read_miss,12,3)
STATCOUNTER_ITEM(tagcache_evict,12,6)
STATCOUNTER_ITEM(l2cachemaster_read_req,13,0)
STATCOUNTER_ITEM(l2cachemaster_write_req,13,1)
STATCOUNTER_ITEM(l2cachemaster_write_req_flit,13,2)
STATCOUNTER_ITEM(l2cachemaster_read_rsp,13,3)
STATCOUNTER_ITEM(l2cachemaster_read_rsp_flit,13,4)
STATCOUNTER_ITEM(l2cachemaster_write_rsp,13,5)
STATCOUNTER_ITEM(tagcachemaster_read_req,14,0)
STATCOUNTER_ITEM(tagcachemaster_write_req,14,1)
STATCOUNTER_ITEM(tagcachemaster_write_req_flit,14,2)
STATCOUNTER_ITEM(tagcachemaster_read_rsp,14,3)
STATCOUNTER_ITEM(tagcachemaster_read_rsp_flit,14,4)
STATCOUNTER_ITEM(tagcachemaster_write_rsp,14,5)
#endif /* !_DEV_HWPMC_HWPMC_BERI_H_ */

View File

@ -1246,6 +1246,67 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC)
#define PMC_EV_MIPS74K_FIRST PMC_EV_MIPS74K_CYCLES
#define PMC_EV_MIPS74K_LAST PMC_EV_MIPS74K_WBB_25_50_FULL
#define __PMC_EV_BERI() \
__PMC_EV(BERI, CYCLE) \
__PMC_EV(BERI, INST) \
__PMC_EV(BERI, INST_USER) \
__PMC_EV(BERI, INST_KERNEL) \
__PMC_EV(BERI, IMPRECISE_SETBOUNDS) \
__PMC_EV(BERI, UNREPRESENTABLE_CAPS) \
__PMC_EV(BERI, ITLB_MISS) \
__PMC_EV(BERI, DTLB_MISS) \
__PMC_EV(BERI, ICACHE_WRITE_HIT) \
__PMC_EV(BERI, ICACHE_WRITE_MISS) \
__PMC_EV(BERI, ICACHE_READ_HIT) \
__PMC_EV(BERI, ICACHE_READ_MISS) \
__PMC_EV(BERI, ICACHE_EVICT) \
__PMC_EV(BERI, DCACHE_WRITE_HIT) \
__PMC_EV(BERI, DCACHE_WRITE_MISS) \
__PMC_EV(BERI, DCACHE_READ_HIT) \
__PMC_EV(BERI, DCACHE_READ_MISS) \
__PMC_EV(BERI, DCACHE_EVICT) \
__PMC_EV(BERI, DCACHE_SET_TAG_WRITE) \
__PMC_EV(BERI, DCACHE_SET_TAG_READ) \
__PMC_EV(BERI, L2CACHE_WRITE_HIT) \
__PMC_EV(BERI, L2CACHE_WRITE_MISS) \
__PMC_EV(BERI, L2CACHE_READ_HIT) \
__PMC_EV(BERI, L2CACHE_READ_MISS) \
__PMC_EV(BERI, L2CACHE_EVICT) \
__PMC_EV(BERI, L2CACHE_SET_TAG_WRITE) \
__PMC_EV(BERI, L2CACHE_SET_TAG_READ) \
__PMC_EV(BERI, MEM_BYTE_READ) \
__PMC_EV(BERI, MEM_BYTE_WRITE) \
__PMC_EV(BERI, MEM_HWORD_READ) \
__PMC_EV(BERI, MEM_HWORD_WRITE) \
__PMC_EV(BERI, MEM_WORD_READ) \
__PMC_EV(BERI, MEM_WORD_WRITE) \
__PMC_EV(BERI, MEM_DWORD_READ) \
__PMC_EV(BERI, MEM_DWORD_WRITE) \
__PMC_EV(BERI, MEM_CAP_READ) \
__PMC_EV(BERI, MEM_CAP_WRITE) \
__PMC_EV(BERI, MEM_CAP_READ_TAG_SET) \
__PMC_EV(BERI, MEM_CAP_WRITE_TAG_SET) \
__PMC_EV(BERI, TAGCACHE_WRITE_HIT) \
__PMC_EV(BERI, TAGCACHE_WRITE_MISS) \
__PMC_EV(BERI, TAGCACHE_READ_HIT) \
__PMC_EV(BERI, TAGCACHE_READ_MISS) \
__PMC_EV(BERI, TAGCACHE_EVICT) \
__PMC_EV(BERI, L2CACHEMASTER_READ_REQ) \
__PMC_EV(BERI, L2CACHEMASTER_WRITE_REQ) \
__PMC_EV(BERI, L2CACHEMASTER_WRITE_REQ_FLIT) \
__PMC_EV(BERI, L2CACHEMASTER_READ_RSP) \
__PMC_EV(BERI, L2CACHEMASTER_READ_RSP_FLIT) \
__PMC_EV(BERI, L2CACHEMASTER_WRITE_RSP) \
__PMC_EV(BERI, TAGCACHEMASTER_READ_REQ) \
__PMC_EV(BERI, TAGCACHEMASTER_WRITE_REQ) \
__PMC_EV(BERI, TAGCACHEMASTER_WRITE_REQ_FLIT) \
__PMC_EV(BERI, TAGCACHEMASTER_READ_RSP) \
__PMC_EV(BERI, TAGCACHEMASTER_READ_RSP_FLIT) \
__PMC_EV(BERI, TAGCACHEMASTER_WRITE_RSP)
#define PMC_EV_BERI_FIRST PMC_EV_BERI_CYCLE
#define PMC_EV_BERI_LAST PMC_EV_BERI_TAGCACHEMASTER_WRITE_RSP
/*
* Cavium Octeon counters. Obtained from cvmx-core.h
*/
@ -1774,6 +1835,7 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC)
* 0x11300 0x00FF MIPS 24K events
* 0x11400 0x00FF Octeon events
* 0x11500 0x00FF MIPS 74K events
* 0x11600 0x00FF BERI statcounters
* 0x13000 0x00FF MPC7450 events
* 0x13100 0x00FF IBM PPC970 events
* 0x13300 0x00FF Freescale e500 events
@ -1798,6 +1860,8 @@ __PMC_EV_ALIAS("unhalted-core-cycles", IAP_ARCH_UNH_COR_CYC)
__PMC_EV_OCTEON() \
__PMC_EV_BLOCK(MIPS74K, 0x11500) \
__PMC_EV_MIPS74K() \
__PMC_EV_BLOCK(BERI, 0x11600) \
__PMC_EV_BERI() \
__PMC_EV_BLOCK(UCP, 0x12080) \
__PMC_EV_UCP() \
__PMC_EV_BLOCK(PPC7450, 0x13000) \

View File

@ -335,7 +335,7 @@ static void
vt_switch_timer(void *arg)
{
vt_late_window_switch((struct vt_window *)arg);
(void)vt_late_window_switch((struct vt_window *)arg);
}
static int
@ -457,13 +457,22 @@ vt_window_postswitch(struct vt_window *vw)
static int
vt_late_window_switch(struct vt_window *vw)
{
struct vt_window *curvw;
int ret;
callout_stop(&vw->vw_proc_dead_timer);
ret = vt_window_switch(vw);
if (ret)
if (ret != 0) {
/*
* If the switch hasn't happened, then return the VT
* to the current owner, if any.
*/
curvw = vw->vw_device->vd_curwindow;
if (curvw->vw_smode.mode == VT_PROCESS)
(void)vt_window_postswitch(curvw);
return (ret);
}
/* Notify owner process about terminal availability. */
if (vw->vw_smode.mode == VT_PROCESS) {
@ -509,6 +518,19 @@ vt_proc_window_switch(struct vt_window *vw)
return (0); /* success */
}
/*
* Early check for an attempt to switch to a non-functional VT.
* The same check is done in vt_window_switch(), but it's better
* to fail as early as possible to avoid needless pre-switch
* actions.
*/
VT_LOCK(vd);
if ((vw->vw_flags & (VWF_OPENED|VWF_CONSOLE)) == 0) {
VT_UNLOCK(vd);
return (EINVAL);
}
VT_UNLOCK(vd);
/* Ask current process permission to switch away. */
if (curvw->vw_smode.mode == VT_PROCESS) {
DPRINTF(30, "%s: VT_PROCESS ", __func__);
@ -1792,7 +1814,7 @@ finish_vt_rel(struct vt_window *vw, int release, int *s)
vw->vw_flags &= ~VWF_SWWAIT_REL;
if (release) {
callout_drain(&vw->vw_proc_dead_timer);
vt_late_window_switch(vw->vw_switch_to);
(void)vt_late_window_switch(vw->vw_switch_to);
}
return (0);
}

View File

@ -414,12 +414,12 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
struct nfsnode *np;
struct nfsmount *nmp;
struct timespec mtime_save;
vm_object_t object;
u_quad_t nsize;
int setnsize, error, force_fid_err;
int error, force_fid_err;
bool setnsize;
error = 0;
setnsize = 0;
nsize = 0;
/*
* If v_type == VNON it is a new node, so fill in the v_type,
@ -511,8 +511,7 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
* zero np->n_attrstamp to indicate that
* the attributes are stale.
*/
nsize = vap->va_size = np->n_size;
setnsize = 1;
vap->va_size = np->n_size;
np->n_attrstamp = 0;
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
} else if (np->n_flag & NMODIFIED) {
@ -526,22 +525,9 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
np->n_size = vap->va_size;
np->n_flag |= NSIZECHANGED;
}
nsize = np->n_size;
setnsize = 1;
} else if (vap->va_size < np->n_size) {
/*
* When shrinking the size, the call to
* vnode_pager_setsize() cannot be done
* with the mutex held, so delay it until
* after the mtx_unlock call.
*/
nsize = np->n_size = vap->va_size;
np->n_flag |= NSIZECHANGED;
setnsize = 1;
} else {
nsize = np->n_size = vap->va_size;
np->n_size = vap->va_size;
np->n_flag |= NSIZECHANGED;
setnsize = 1;
}
} else {
np->n_size = vap->va_size;
@ -579,6 +565,23 @@ nfscl_loadattrcache(struct vnode **vpp, struct nfsvattr *nap, void *nvaper,
if (np->n_attrstamp != 0)
KDTRACE_NFS_ATTRCACHE_LOAD_DONE(vp, vap, error);
#endif
nsize = vap->va_size;
object = vp->v_object;
setnsize = false;
if (object != NULL) {
if (OFF_TO_IDX(nsize + PAGE_MASK) < object->size) {
/*
* When shrinking the size, the call to
* vnode_pager_setsize() cannot be done with
* the mutex held, because we might need to
* wait for a busy page. Delay it until after
* the node is unlocked.
*/
setnsize = true;
} else {
vnode_pager_setsize(vp, nsize);
}
}
NFSUNLOCKNODE(np);
if (setnsize)
vnode_pager_setsize(vp, nsize);

View File

@ -935,13 +935,18 @@ SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_FIRST, sysctl_register_all, NULL);
* (be aware though, that the proper interface isn't as obvious as it
* may seem, there are various conflicting requirements.
*
* {0,0} printf the entire MIB-tree.
* {0,1,...} return the name of the "..." OID.
* {0,2,...} return the next OID.
* {0,3} return the OID of the name in "new"
* {0,4,...} return the kind & format info for the "..." OID.
* {0,5,...} return the description of the "..." OID.
* {0,6,...} return the aggregation label of the "..." OID.
* {CTL_SYSCTL, CTL_SYSCTL_DEBUG} printf the entire MIB-tree.
* {CTL_SYSCTL, CTL_SYSCTL_NAME, ...} return the name of the "..."
* OID.
* {CTL_SYSCTL, CTL_SYSCTL_NEXT, ...} return the next OID.
* {CTL_SYSCTL, CTL_SYSCTL_NAME2OID} return the OID of the name in
* "new"
* {CTL_SYSCTL, CTL_SYSCTL_OIDFMT, ...} return the kind & format info
* for the "..." OID.
* {CTL_SYSCTL, CTL_SYSCTL_OIDDESCR, ...} return the description of the
* "..." OID.
* {CTL_SYSCTL, CTL_SYSCTL_OIDLABEL, ...} return the aggregation label of
* the "..." OID.
*/
#ifdef SYSCTL_DEBUG
@ -1009,8 +1014,8 @@ sysctl_sysctl_debug(SYSCTL_HANDLER_ARGS)
return (ENOENT);
}
SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD|CTLFLAG_MPSAFE,
0, 0, sysctl_sysctl_debug, "-", "");
SYSCTL_PROC(_sysctl, CTL_SYSCTL_DEBUG, debug, CTLTYPE_STRING | CTLFLAG_RD |
CTLFLAG_MPSAFE, 0, 0, sysctl_sysctl_debug, "-", "");
#endif
static int
@ -1075,8 +1080,8 @@ sysctl_sysctl_name(SYSCTL_HANDLER_ARGS)
* XXXRW/JA: Shouldn't return name data for nodes that we don't permit in
* capability mode.
*/
static SYSCTL_NODE(_sysctl, 1, name, CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD,
sysctl_sysctl_name, "");
static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NAME, name, CTLFLAG_RD |
CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_name, "");
static int
sysctl_sysctl_next_ls(struct sysctl_oid_list *lsp, int *name, u_int namelen,
@ -1162,8 +1167,8 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS)
* XXXRW/JA: Shouldn't return next data for nodes that we don't permit in
* capability mode.
*/
static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD,
sysctl_sysctl_next, "");
static SYSCTL_NODE(_sysctl, CTL_SYSCTL_NEXT, next, CTLFLAG_RD |
CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_next, "");
static int
name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp)
@ -1249,9 +1254,9 @@ sysctl_sysctl_name2oid(SYSCTL_HANDLER_ARGS)
* XXXRW/JA: Shouldn't return name2oid data for nodes that we don't permit in
* capability mode.
*/
SYSCTL_PROC(_sysctl, 3, name2oid,
CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE
| CTLFLAG_CAPRW, 0, 0, sysctl_sysctl_name2oid, "I", "");
SYSCTL_PROC(_sysctl, CTL_SYSCTL_NAME2OID, name2oid, CTLTYPE_INT | CTLFLAG_RW |
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE | CTLFLAG_CAPRW, 0, 0,
sysctl_sysctl_name2oid, "I", "");
static int
sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
@ -1279,8 +1284,8 @@ sysctl_sysctl_oidfmt(SYSCTL_HANDLER_ARGS)
}
static SYSCTL_NODE(_sysctl, 4, oidfmt, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD,
sysctl_sysctl_oidfmt, "");
static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDFMT, oidfmt, CTLFLAG_RD |
CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidfmt, "");
static int
sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
@ -1304,8 +1309,8 @@ sysctl_sysctl_oiddescr(SYSCTL_HANDLER_ARGS)
return (error);
}
static SYSCTL_NODE(_sysctl, 5, oiddescr, CTLFLAG_RD|CTLFLAG_MPSAFE|CTLFLAG_CAPRD,
sysctl_sysctl_oiddescr, "");
static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDDESCR, oiddescr, CTLFLAG_RD |
CTLFLAG_MPSAFE|CTLFLAG_CAPRD, sysctl_sysctl_oiddescr, "");
static int
sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
@ -1329,8 +1334,8 @@ sysctl_sysctl_oidlabel(SYSCTL_HANDLER_ARGS)
return (error);
}
static SYSCTL_NODE(_sysctl, 6, oidlabel,
CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, "");
static SYSCTL_NODE(_sysctl, CTL_SYSCTL_OIDLABEL, oidlabel, CTLFLAG_RD |
CTLFLAG_MPSAFE | CTLFLAG_CAPRD, sysctl_sysctl_oidlabel, "");
/*
* Default "handler" functions.
@ -1857,8 +1862,8 @@ kernel_sysctlbyname(struct thread *td, char *name, void *old, size_t *oldlenp,
size_t oidlen, plen;
int error;
oid[0] = 0; /* sysctl internal magic */
oid[1] = 3; /* name2oid */
oid[0] = CTL_SYSCTL;
oid[1] = CTL_SYSCTL_NAME2OID;
oidlen = sizeof(oid);
error = kernel_sysctl(td, oid, 2, oid, &oidlen,
@ -2165,8 +2170,8 @@ kern___sysctlbyname(struct thread *td, const char *oname, size_t namelen,
if (error != 0)
goto out;
oid[0] = 0;
oid[1] = 3;
oid[0] = CTL_SYSCTL;
oid[1] = CTL_SYSCTL_NAME2OID;
oidlen = sizeof(oid);
error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen,
retval, flags);
@ -2667,8 +2672,8 @@ db_show_sysctl_all(int *oid, size_t len, int flags)
int name1[CTL_MAXNAME + 2], name2[CTL_MAXNAME + 2];
size_t l1, l2;
name1[0] = 0;
name1[1] = 2;
name1[0] = CTL_SYSCTL;
name1[1] = CTL_SYSCTL_NEXT;
l1 = 2;
if (len) {
memcpy(name1+2, oid, len * sizeof(int));

View File

@ -718,6 +718,14 @@ cluster_write(struct vnode *vp, struct buf *bp, u_quad_t filesize, int seqcount,
struct cluster_save *buflist;
buflist = cluster_collectbufs(vp, bp, gbflags);
if (buflist == NULL) {
/*
* Cluster build failed so just write
* it now.
*/
bawrite(bp);
return;
}
endbp = &buflist->bs_children
[buflist->bs_nchildren - 1];
if (VOP_REALLOCBLKS(vp, buflist)) {
@ -1056,7 +1064,7 @@ cluster_collectbufs(struct vnode *vp, struct buf *last_bp, int gbflags)
struct cluster_save *buflist;
struct buf *bp;
daddr_t lbn;
int i, len;
int i, j, len, error;
len = vp->v_lastw - vp->v_cstart + 1;
buflist = malloc(sizeof(struct buf *) * (len + 1) + sizeof(*buflist),
@ -1064,8 +1072,18 @@ cluster_collectbufs(struct vnode *vp, struct buf *last_bp, int gbflags)
buflist->bs_nchildren = 0;
buflist->bs_children = (struct buf **) (buflist + 1);
for (lbn = vp->v_cstart, i = 0; i < len; lbn++, i++) {
(void)bread_gb(vp, lbn, last_bp->b_bcount, NOCRED,
error = bread_gb(vp, lbn, last_bp->b_bcount, NOCRED,
gbflags, &bp);
if (error != 0) {
/*
* If read fails, release collected buffers
* and return failure.
*/
for (j = 0; j < i; j++)
brelse(buflist->bs_children[j]);
free(buflist, M_SEGMENT);
return (NULL);
}
buflist->bs_children[i] = bp;
if (bp->b_blkno == bp->b_lblkno)
VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno,

View File

@ -606,18 +606,22 @@ vop_stdgetwritemount(ap)
return (0);
}
if (vfs_op_thread_enter(mp)) {
if (mp == vp->v_mount)
if (mp == vp->v_mount) {
vfs_mp_count_add_pcpu(mp, ref, 1);
else
vfs_op_thread_exit(mp);
} else {
vfs_op_thread_exit(mp);
mp = NULL;
vfs_op_thread_exit(mp);
}
} else {
MNT_ILOCK(mp);
if (mp == vp->v_mount)
if (mp == vp->v_mount) {
MNT_REF(mp);
else
MNT_IUNLOCK(mp);
} else {
MNT_IUNLOCK(mp);
mp = NULL;
MNT_IUNLOCK(mp);
}
}
*(ap->a_mpp) = mp;
return (0);

View File

@ -264,6 +264,10 @@ vn_open_cred(struct nameidata *ndp, int *flagp, int cmode, u_int vn_open_flags,
error = EEXIST;
goto bad;
}
if (vp->v_type == VDIR) {
error = EISDIR;
goto bad;
}
fmode &= ~O_CREAT;
}
} else {

View File

@ -2891,6 +2891,7 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
case SIOCGIFGENERIC:
case SIOCGIFRSSKEY:
case SIOCGIFRSSHASH:
case SIOCGIFDOWNREASON:
if (ifp->if_ioctl == NULL)
return (EOPNOTSUPP);
error = (*ifp->if_ioctl)(ifp, cmd, data);

View File

@ -585,6 +585,16 @@ struct ifrsshash {
#define IFNET_PCP_NONE 0xff /* PCP disabled */
#define IFDR_MSG_SIZE 64
#define IFDR_REASON_MSG 1
#define IFDR_REASON_VENDOR 2
struct ifdownreason {
char ifdr_name[IFNAMSIZ];
uint32_t ifdr_reason;
uint32_t ifdr_vendor;
char ifdr_msg[IFDR_MSG_SIZE];
};
#endif /* __BSD_VISIBLE */
#ifdef _KERNEL

View File

@ -523,7 +523,7 @@ sctp_insert_sharedkey(struct sctp_keyhead *shared_keys,
} else if (new_skey->keyid == skey->keyid) {
/* replace the existing key */
/* verify this key *can* be replaced */
if ((skey->deactivated) && (skey->refcount > 1)) {
if ((skey->deactivated) || (skey->refcount > 1)) {
SCTPDBG(SCTP_DEBUG_AUTH1,
"can't replace shared key id %u\n",
new_skey->keyid);

View File

@ -7840,7 +7840,16 @@ rack_output(struct tcpcb *tp)
hdrlen += sizeof(struct udphdr);
}
#endif
ipoptlen = 0;
#ifdef INET6
if (isipv6)
ipoptlen = ip6_optlen(tp->t_inpcb);
else
#endif
if (tp->t_inpcb->inp_options)
ipoptlen = tp->t_inpcb->inp_options->m_len -
offsetof(struct ipoption, ipopt_list);
else
ipoptlen = 0;
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
ipoptlen += ipsec_optlen;
#endif
@ -7913,6 +7922,18 @@ rack_output(struct tcpcb *tp)
sendalot = 1;
} else {
if (optlen + ipoptlen > tp->t_maxseg) {
/*
* Since we don't have enough space to put
* the IP header chain and the TCP header in
* one packet as required by RFC 7112, don't
* send it.
*/
SOCKBUF_UNLOCK(&so->so_snd);
error = EMSGSIZE;
sack_rxmit = 0;
goto out;
}
len = tp->t_maxseg - optlen - ipoptlen;
sendalot = 1;
}
@ -8414,15 +8435,9 @@ rack_output(struct tcpcb *tp)
m->m_pkthdr.csum_flags |= CSUM_TSO;
m->m_pkthdr.tso_segsz = tp->t_maxseg - optlen;
}
#if defined(IPSEC) || defined(IPSEC_SUPPORT)
KASSERT(len + hdrlen + ipoptlen - ipsec_optlen == m_length(m, NULL),
("%s: mbuf chain shorter than expected: %d + %u + %u - %u != %u",
__func__, len, hdrlen, ipoptlen, ipsec_optlen, m_length(m, NULL)));
#else
KASSERT(len + hdrlen + ipoptlen == m_length(m, NULL),
("%s: mbuf chain shorter than expected: %d + %u + %u != %u",
__func__, len, hdrlen, ipoptlen, m_length(m, NULL)));
#endif
KASSERT(len + hdrlen == m_length(m, NULL),
("%s: mbuf chain different than expected: %d + %u != %u",
__func__, len, hdrlen, m_length(m, NULL)));
#ifdef TCP_HHOOK
/* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */

View File

@ -403,20 +403,22 @@ VNET_SYSUNINIT(inet6, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, ip6_destroy, NULL);
#endif
static int
ip6_input_hbh(struct mbuf *m, uint32_t *plen, uint32_t *rtalert, int *off,
ip6_input_hbh(struct mbuf **mp, uint32_t *plen, uint32_t *rtalert, int *off,
int *nxt, int *ours)
{
struct mbuf *m;
struct ip6_hdr *ip6;
struct ip6_hbh *hbh;
if (ip6_hopopts_input(plen, rtalert, &m, off)) {
if (ip6_hopopts_input(plen, rtalert, mp, off)) {
#if 0 /*touches NULL pointer*/
in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);
in6_ifstat_inc((*mp)->m_pkthdr.rcvif, ifs6_in_discard);
#endif
goto out; /* m have already been freed */
}
/* adjust pointer */
m = *mp;
ip6 = mtod(m, struct ip6_hdr *);
/*
@ -854,7 +856,7 @@ ip6_input(struct mbuf *m)
*/
plen = (u_int32_t)ntohs(ip6->ip6_plen);
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
if (ip6_input_hbh(m, &plen, &rtalert, &off, &nxt, &ours) != 0)
if (ip6_input_hbh(&m, &plen, &rtalert, &off, &nxt, &ours) != 0)
return;
} else
nxt = ip6->ip6_nxt;

View File

@ -114,6 +114,7 @@ extern char pmc_cpuid[PMC_CPUID_LEN];
__PMC_CPU(MIPS_24K, 0x200, "MIPS 24K") \
__PMC_CPU(MIPS_OCTEON, 0x201, "Cavium Octeon") \
__PMC_CPU(MIPS_74K, 0x202, "MIPS 74K") \
__PMC_CPU(MIPS_BERI, 0x203, "BERI") \
__PMC_CPU(PPC_7450, 0x300, "PowerPC MPC7450") \
__PMC_CPU(PPC_E500, 0x340, "PowerPC e500 Core") \
__PMC_CPU(PPC_970, 0x380, "IBM PowerPC 970") \
@ -160,7 +161,8 @@ enum pmc_cputype {
__PMC_CLASS(ARMV7, 0x10, "ARMv7") \
__PMC_CLASS(ARMV8, 0x11, "ARMv8") \
__PMC_CLASS(MIPS74K, 0x12, "MIPS 74K") \
__PMC_CLASS(E500, 0x13, "Freescale e500 class")
__PMC_CLASS(E500, 0x13, "Freescale e500 class") \
__PMC_CLASS(BERI, 0x14, "MIPS BERI")
enum pmc_class {
#undef __PMC_CLASS

View File

@ -143,4 +143,6 @@
#define SIOCGLANPCP _IOWR('i', 152, struct ifreq) /* Get (V)LAN PCP */
#define SIOCSLANPCP _IOW('i', 153, struct ifreq) /* Set (V)LAN PCP */
#define SIOCGIFDOWNREASON _IOWR('i', 154, struct ifdownreason)
#endif /* !_SYS_SOCKIO_H_ */

View File

@ -889,7 +889,7 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
/*
* Top-level identifiers
*/
#define CTL_UNSPEC 0 /* unused */
#define CTL_SYSCTL 0 /* "magic" numbers */
#define CTL_KERN 1 /* "high kernel": proc, limits */
#define CTL_VM 2 /* virtual memory */
#define CTL_VFS 3 /* filesystem, mount type is next */
@ -900,6 +900,17 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry);
#define CTL_USER 8 /* user-level */
#define CTL_P1003_1B 9 /* POSIX 1003.1B */
/*
* CTL_SYSCTL identifiers
*/
#define CTL_SYSCTL_DEBUG 0 /* printf all nodes */
#define CTL_SYSCTL_NAME 1 /* string name of OID */
#define CTL_SYSCTL_NEXT 2 /* next OID */
#define CTL_SYSCTL_NAME2OID 3 /* int array of name */
#define CTL_SYSCTL_OIDFMT 4 /* OID's kind and format */
#define CTL_SYSCTL_OIDDESCR 5 /* OID's description */
#define CTL_SYSCTL_OIDLABEL 6 /* aggregation label */
/*
* CTL_KERN identifiers
*/

View File

@ -320,7 +320,7 @@ vm_thread_stack_create(struct domainset *ds, vm_object_t *ksobjp, int pages)
ks = kva_alloc((pages + KSTACK_GUARD_PAGES) * PAGE_SIZE);
#endif
if (ks == 0) {
printf("vm_thread_new: kstack allocation failed\n");
printf("%s: kstack allocation failed\n", __func__);
vm_object_deallocate(ksobj);
return (0);
}
@ -362,7 +362,7 @@ vm_thread_stack_dispose(vm_object_t ksobj, vm_offset_t ks, int pages)
for (i = 0; i < pages; i++) {
m = vm_page_lookup(ksobj, i);
if (m == NULL)
panic("vm_thread_dispose: kstack already missing?");
panic("%s: kstack already missing?", __func__);
vm_page_unwire_noq(m);
vm_page_free(m);
}

View File

@ -40,6 +40,10 @@ v4_head()
v4_body()
{
firewall=$1
if [ "$(atf_config_get ci false)" = "true" ] && \
[ "$(uname -p)" = "i386" ] && [ "${firewall}" = "pf" ]; then
atf_skip "https://bugs.freebsd.org/240085"
fi
firewall_init $firewall
epair_send=$(vnet_mkepair)

View File

@ -40,6 +40,10 @@ tos_head()
tos_body()
{
firewall=$1
if [ "$(atf_config_get ci false)" = "true" ] && \
[ "$(uname -p)" = "i386" ] && [ "${firewall}" = "pf" ]; then
atf_skip "https://bugs.freebsd.org/240086"
fi
firewall_init $firewall
epair_send=$(vnet_mkepair)

View File

@ -5,6 +5,7 @@ PACKAGE= tests
TESTSDIR= ${TESTSBASE}/sys/vm
ATF_TESTS_C+= mlock_test \
mmap_test
mmap_test \
page_fault_signal
.include <bsd.test.mk>

View File

@ -0,0 +1,184 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2019 Jilles Tjoelker
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include <sys/mman.h>
#include <atf-c.h>
#include <fcntl.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
static sigjmp_buf sig_env;
static volatile int last_sig, last_code;
static void
sighandler(int sig, siginfo_t *info, void *context __unused)
{
last_sig = sig;
last_code = info->si_code;
siglongjmp(sig_env, 1);
}
static void
setup_signals(void)
{
struct sigaction sa;
int r;
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_RESTART | SA_RESETHAND | SA_SIGINFO;
r = sigfillset(&sa.sa_mask);
ATF_REQUIRE(r != -1);
r = sigaction(SIGILL, &sa, NULL);
ATF_REQUIRE(r != -1);
r = sigaction(SIGBUS, &sa, NULL);
ATF_REQUIRE(r != -1);
r = sigaction(SIGSEGV, &sa, NULL);
ATF_REQUIRE(r != -1);
}
ATF_TC_WITHOUT_HEAD(page_fault_signal__segv_maperr_1);
ATF_TC_BODY(page_fault_signal__segv_maperr_1, tc)
{
int *p;
int r;
int sz;
sz = getpagesize();
p = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0);
ATF_REQUIRE(p != MAP_FAILED);
r = munmap(p, sz);
ATF_REQUIRE(r != -1);
if (sigsetjmp(sig_env, 1) == 0) {
setup_signals();
*(volatile int *)p = 1;
}
ATF_CHECK_EQ(SIGSEGV, last_sig);
ATF_CHECK_EQ(SEGV_MAPERR, last_code);
}
ATF_TC_WITHOUT_HEAD(page_fault_signal__segv_accerr_1);
ATF_TC_BODY(page_fault_signal__segv_accerr_1, tc)
{
int *p;
int sz;
sz = getpagesize();
p = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0);
ATF_REQUIRE(p != MAP_FAILED);
if (sigsetjmp(sig_env, 1) == 0) {
setup_signals();
*(volatile int *)p = 1;
}
(void)munmap(p, sz);
ATF_CHECK_EQ(SIGSEGV, last_sig);
ATF_CHECK_EQ(SEGV_ACCERR, last_code);
}
ATF_TC_WITHOUT_HEAD(page_fault_signal__segv_accerr_2);
ATF_TC_BODY(page_fault_signal__segv_accerr_2, tc)
{
int *p;
volatile int dummy;
int sz;
sz = getpagesize();
p = mmap(NULL, sz, PROT_NONE, MAP_ANON, -1, 0);
ATF_REQUIRE(p != MAP_FAILED);
if (sigsetjmp(sig_env, 1) == 0) {
setup_signals();
dummy = *p;
}
(void)munmap(p, sz);
ATF_CHECK_EQ(SIGSEGV, last_sig);
ATF_CHECK_EQ(SEGV_ACCERR, last_code);
}
ATF_TC_WITHOUT_HEAD(page_fault_signal__bus_objerr_1);
ATF_TC_BODY(page_fault_signal__bus_objerr_1, tc)
{
int *p;
int fd;
int sz;
atf_tc_expect_fail("bug 211924");
sz = getpagesize();
fd = shm_open(SHM_ANON, O_RDWR | O_CREAT, 0600);
ATF_REQUIRE(fd != -1);
p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
ATF_REQUIRE(p != MAP_FAILED);
if (sigsetjmp(sig_env, 1) == 0) {
setup_signals();
*(volatile int *)p = 1;
}
(void)munmap(p, sz);
(void)close(fd);
ATF_CHECK_EQ(SIGBUS, last_sig);
ATF_CHECK_EQ(BUS_OBJERR, last_code);
}
ATF_TC_WITHOUT_HEAD(page_fault_signal__bus_objerr_2);
ATF_TC_BODY(page_fault_signal__bus_objerr_2, tc)
{
int *p;
int fd;
int r;
int sz;
atf_tc_expect_fail("bug 211924");
sz = getpagesize();
fd = shm_open(SHM_ANON, O_RDWR | O_CREAT, 0600);
ATF_REQUIRE(fd != -1);
r = ftruncate(fd, sz);
ATF_REQUIRE(r != -1);
p = mmap(NULL, sz * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
ATF_REQUIRE(p != MAP_FAILED);
if (sigsetjmp(sig_env, 1) == 0) {
setup_signals();
((volatile int *)p)[sz / sizeof(int)] = 1;
}
(void)munmap(p, sz * 2);
(void)close(fd);
ATF_CHECK_EQ(SIGBUS, last_sig);
ATF_CHECK_EQ(BUS_OBJERR, last_code);
}
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, page_fault_signal__segv_maperr_1);
ATF_TP_ADD_TC(tp, page_fault_signal__segv_accerr_1);
ATF_TP_ADD_TC(tp, page_fault_signal__segv_accerr_2);
ATF_TP_ADD_TC(tp, page_fault_signal__bus_objerr_1);
ATF_TP_ADD_TC(tp, page_fault_signal__bus_objerr_2);
return (atf_no_error());
}

View File

@ -0,0 +1,5 @@
.\" $FreeBSD$
Set to build and install
.Lb libgmock ,
.Lb libgtest ,
and dependent tests.

View File

@ -131,6 +131,7 @@ enum Argtype {
Sockprotocol,
Socktype,
Sysarch,
Sysctl,
Umtxop,
Waitoptions,
Whence,

View File

@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <sys/socket.h>
#define _WANT_FREEBSD11_STAT
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/un.h>
#include <sys/wait.h>
@ -506,6 +507,12 @@ static struct syscall decoded_syscalls[] = {
.args = { { Name, 0 }, { Atfd, 1 }, { Name, 2 } } },
{ .name = "sysarch", .ret_type = 1, .nargs = 2,
.args = { { Sysarch, 0 }, { Ptr, 1 } } },
{ .name = "__sysctl", .ret_type = 1, .nargs = 6,
.args = { { Sysctl, 0 }, { Sizet, 1 }, { Ptr, 2 }, { Ptr, 3 },
{ Ptr, 4 }, { Sizet, 5 } } },
{ .name = "__sysctlbyname", .ret_type = 1, .nargs = 6,
.args = { { Name, 0 }, { Sizet, 1 }, { Ptr, 2 }, { Ptr, 3 },
{ Ptr, 4}, { Sizet, 5 } } },
{ .name = "thr_kill", .ret_type = 1, .nargs = 2,
.args = { { Long, 0 }, { Signal, 1 } } },
{ .name = "thr_self", .ret_type = 1, .nargs = 1,
@ -1551,6 +1558,15 @@ print_cmsgs(FILE *fp, pid_t pid, bool receive, struct msghdr *msghdr)
free(cmsgbuf);
}
static void
print_sysctl_oid(FILE *fp, int *oid, int len)
{
int i;
for (i = 0; i < len; i++)
fprintf(fp, ".%d", oid[i]);
}
/*
* Converts a syscall argument into a string. Said string is
* allocated via malloc(), so needs to be free()'d. sc is
@ -2267,6 +2283,62 @@ print_arg(struct syscall_args *sc, unsigned long *args, register_t *retval,
print_integer_arg(sysdecode_sysarch_number, fp,
args[sc->offset]);
break;
case Sysctl: {
char name[BUFSIZ];
int oid[CTL_MAXNAME + 2], qoid[CTL_MAXNAME + 2];
size_t i;
int len;
memset(name, 0, sizeof(name));
len = args[sc->offset + 1];
if (get_struct(pid, (void *)args[sc->offset], oid,
len * sizeof(oid[0])) != -1) {
fprintf(fp, "\"");
if (oid[0] == CTL_SYSCTL) {
fprintf(fp, "sysctl.");
switch (oid[1]) {
case CTL_SYSCTL_DEBUG:
fprintf(fp, "debug");
break;
case CTL_SYSCTL_NAME:
fprintf(fp, "name");
print_sysctl_oid(fp, oid + 2, len - 2);
break;
case CTL_SYSCTL_NEXT:
fprintf(fp, "next");
break;
case CTL_SYSCTL_NAME2OID:
fprintf(fp, "name2oid");
break;
case CTL_SYSCTL_OIDFMT:
fprintf(fp, "oidfmt");
print_sysctl_oid(fp, oid + 2, len - 2);
break;
case CTL_SYSCTL_OIDDESCR:
fprintf(fp, "oiddescr");
print_sysctl_oid(fp, oid + 2, len - 2);
break;
case CTL_SYSCTL_OIDLABEL:
fprintf(fp, "oidlabel");
print_sysctl_oid(fp, oid + 2, len - 2);
break;
default:
print_sysctl_oid(fp, oid + 1, len - 1);
}
} else {
qoid[0] = CTL_SYSCTL;
qoid[1] = CTL_SYSCTL_NAME;
memcpy(qoid + 2, oid, len * sizeof(int));
i = sizeof(name);
if (sysctl(qoid, len + 2, name, &i, 0, 0) == -1)
print_sysctl_oid(fp, qoid + 2, len);
else
fprintf(fp, "%s", name);
}
fprintf(fp, "\"");
}
break;
}
case PipeFds:
/*
* The pipe() system call in the kernel returns its

View File

@ -95,7 +95,7 @@ Trust an RSA key with SHA256 of
.Ar KEY .
(default: read value from configuration file.)
.It Fl r Ar newrelease
Specify the new release (e.g. 11.2-RELEASE) to which
Specify the new release (e.g., 11.2-RELEASE) to which
.Nm
should upgrade (upgrade command only).
.It Fl s Ar server

View File

@ -64,7 +64,7 @@ Commands:
upgrade -- Fetch upgrades to FreeBSD version specified via -r option
install -- Install downloaded updates or upgrades
rollback -- Uninstall most recently installed updates
IDS -- Compare the system against an index of "known good" files.
IDS -- Compare the system against an index of "known good" files
EOF
exit 0
}

View File

@ -30,6 +30,7 @@
/var/log/security 600 10 1000 * JC
/var/log/utx.log 644 3 * @01T05 B
/var/log/weekly.log 640 5 * $W6D0 JN
/var/log/daemon.log 644 5 1000 @0101T JC
<include> /etc/newsyslog.conf.d/[!.]*.conf
<include> /usr/local/etc/newsyslog.conf.d/[!.]*.conf

View File

@ -83,7 +83,7 @@ CFLAGS+= -I${SRCTOP}/contrib/ntp/include \
-I${.CURDIR:H} \
-I${.CURDIR}/
CFLAGS+= -DHAVE_BSD_NICE -DHAVE_STDINT_H
CFLAGS+= -DHAVE_BSD_NICE -DHAVE_STDINT_H -DHAVE_CLOSEFROM
CLEANFILES+= .version version.c

View File

@ -1,6 +1,16 @@
# $FreeBSD$
.if ${MACHINE} != "amd64" && ${MACHINE} != "i386"
PKGCONFBRANCH?= quarterly
.else
_BRANCH!= ${MAKE} -C ${SRCTOP}/release -V BRANCH
BRANCH?= ${_BRANCH}
. if ${BRANCH:MBETA*} || ${BRANCH:MRC*} || ${BRANCH:MRELEASE*}
PKGCONFBRANCH?= quarterly
. else
PKGCONFBRANCH?= latest
. endif
.endif
CONFS= FreeBSD.conf.${PKGCONFBRANCH}
CONFSNAME= FreeBSD.conf
CONFSDIR= /etc/pkg

View File

@ -14,6 +14,7 @@ cron.* /var/log/cron
!-devd
*.=debug /var/log/debug.log
*.emerg *
daemon.info /var/log/daemon.log
# uncomment this to log all writes to /dev/console to /var/log/console.log
# touch /var/log/console.log and chmod it to mode 600 before it will work
#console.info /var/log/console.log