MFhead@r344527
This commit is contained in:
commit
d497ec8996
5
UPDATING
5
UPDATING
@ -31,6 +31,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
disable the most expensive debugging functionality run
|
||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
||||
|
||||
20190219:
|
||||
drm and drm2 have been removed from the tree. Please see
|
||||
https://wiki.freebsd.org/Graphics for the latest information on
|
||||
migrating to the drm ports.
|
||||
|
||||
20190131:
|
||||
Iflib is no longer unconditionally compiled into the kernel. Drivers
|
||||
using iflib and statically compiled into the kernel, now require
|
||||
|
@ -472,10 +472,31 @@ str_to_event(const char *str, int last)
|
||||
int
|
||||
bindcmd(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
FILE *old;
|
||||
FILE *out;
|
||||
|
||||
if (el == NULL)
|
||||
error("line editing is disabled");
|
||||
return (el_parse(el, argc, __DECONST(const char **, argv)));
|
||||
|
||||
INTOFF;
|
||||
|
||||
out = out1fp();
|
||||
if (out == NULL)
|
||||
error("Out of space");
|
||||
|
||||
el_get(el, EL_GETFP, 1, &old);
|
||||
el_set(el, EL_SETFP, 1, out);
|
||||
|
||||
ret = el_parse(el, argc, __DECONST(const char **, argv));
|
||||
|
||||
el_set(el, EL_SETFP, 1, old);
|
||||
|
||||
fclose(out);
|
||||
|
||||
INTON;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -105,6 +105,7 @@ struct job {
|
||||
char changed; /* true if status has changed */
|
||||
char foreground; /* true if running in the foreground */
|
||||
char remembered; /* true if $! referenced */
|
||||
char pipefail; /* pass any non-zero status */
|
||||
#if JOBS
|
||||
char jobctl; /* job running under job control */
|
||||
struct job *next; /* job used after this one */
|
||||
@ -144,6 +145,7 @@ static void setcurjob(struct job *);
|
||||
static void deljob(struct job *);
|
||||
static struct job *getcurjob(struct job *);
|
||||
#endif
|
||||
static int getjobstatus(const struct job *);
|
||||
static void printjobcmd(struct job *);
|
||||
static void showjob(struct job *, int);
|
||||
|
||||
@ -341,6 +343,20 @@ jobscmd(int argc __unused, char *argv[] __unused)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int getjobstatus(const struct job *jp)
|
||||
{
|
||||
int i, status;
|
||||
|
||||
if (!jp->pipefail)
|
||||
return (jp->ps[jp->nprocs - 1].status);
|
||||
for (i = jp->nprocs - 1; i >= 0; i--) {
|
||||
status = jp->ps[i].status;
|
||||
if (status != 0)
|
||||
return (status);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
printjobcmd(struct job *jp)
|
||||
{
|
||||
@ -377,7 +393,7 @@ showjob(struct job *jp, int mode)
|
||||
}
|
||||
#endif
|
||||
coredump = "";
|
||||
status = jp->ps[jp->nprocs - 1].status;
|
||||
status = getjobstatus(jp);
|
||||
if (jp->state == 0) {
|
||||
statestr = "Running";
|
||||
#if JOBS
|
||||
@ -556,7 +572,7 @@ waitcmdloop(struct job *job)
|
||||
do {
|
||||
if (job != NULL) {
|
||||
if (job->state == JOBDONE) {
|
||||
status = job->ps[job->nprocs - 1].status;
|
||||
status = getjobstatus(job);
|
||||
if (WIFEXITED(status))
|
||||
retval = WEXITSTATUS(status);
|
||||
else
|
||||
@ -781,6 +797,7 @@ makejob(union node *node __unused, int nprocs)
|
||||
jp->nprocs = 0;
|
||||
jp->foreground = 0;
|
||||
jp->remembered = 0;
|
||||
jp->pipefail = pipefailflag;
|
||||
#if JOBS
|
||||
jp->jobctl = jobctl;
|
||||
jp->next = NULL;
|
||||
@ -1076,7 +1093,7 @@ waitforjob(struct job *jp, int *signaled)
|
||||
if (jp->state == JOBSTOPPED)
|
||||
setcurjob(jp);
|
||||
#endif
|
||||
status = jp->ps[jp->nprocs - 1].status;
|
||||
status = getjobstatus(jp);
|
||||
if (signaled != NULL)
|
||||
*signaled = WIFSIGNALED(status);
|
||||
/* convert to 8 bits */
|
||||
|
@ -67,9 +67,10 @@ struct shparam {
|
||||
#define Pflag optval[17]
|
||||
#define hflag optval[18]
|
||||
#define nologflag optval[19]
|
||||
#define pipefailflag optval[20]
|
||||
|
||||
#define NSHORTOPTS 19
|
||||
#define NOPTS 20
|
||||
#define NOPTS 21
|
||||
|
||||
extern char optval[NOPTS];
|
||||
extern const char optletter[NSHORTOPTS];
|
||||
@ -97,6 +98,7 @@ static const unsigned char optname[] =
|
||||
"\010physical"
|
||||
"\010trackall"
|
||||
"\005nolog"
|
||||
"\010pipefail"
|
||||
;
|
||||
#endif
|
||||
|
||||
|
@ -340,6 +340,12 @@ doformat(struct output *dest, const char *f, va_list ap)
|
||||
}
|
||||
}
|
||||
|
||||
FILE *
|
||||
out1fp(void)
|
||||
{
|
||||
return fwopen(out1, doformat_wr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Version of write which resumes after a signal is caught.
|
||||
*/
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct output {
|
||||
char *nextc;
|
||||
@ -75,6 +76,7 @@ void out1fmt(const char *, ...) __printflike(1, 2);
|
||||
void out2fmt_flush(const char *, ...) __printflike(1, 2);
|
||||
void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
|
||||
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
|
||||
FILE *out1fp(void);
|
||||
int xwrite(int, const char *, int);
|
||||
|
||||
#define outc(c, file) ((file)->nextc == (file)->bufend ? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
|
||||
|
25
bin/sh/sh.1
25
bin/sh/sh.1
@ -32,7 +32,7 @@
|
||||
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 24, 2019
|
||||
.Dd February 24, 2019
|
||||
.Dt SH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -343,6 +343,18 @@ Useful for debugging.
|
||||
.It Li nolog
|
||||
Another do-nothing option for POSIX compliance.
|
||||
It only has a long name.
|
||||
.It Li pipefail
|
||||
Change the exit status of a pipeline to the last non-zero exit status of
|
||||
any command in the pipeline, if any.
|
||||
Since an exit due to
|
||||
.Dv SIGPIPE
|
||||
counts as a non-zero exit status,
|
||||
this option may cause non-zero exit status for successful pipelines
|
||||
if a command such as
|
||||
.Xr head 1
|
||||
in the pipeline terminates with status 0 without reading its
|
||||
input completely.
|
||||
This option only has a long name.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
@ -856,12 +868,15 @@ If the keyword
|
||||
.Ic !\&
|
||||
does not precede the pipeline, the
|
||||
exit status is the exit status of the last command specified
|
||||
in the pipeline.
|
||||
in the pipeline if the
|
||||
.Cm pipefail
|
||||
option is not set or all commands returned zero,
|
||||
or the last non-zero exit status of any command in the pipeline otherwise.
|
||||
Otherwise, the exit status is the logical
|
||||
NOT of the exit status of the last command.
|
||||
NOT of that exit status.
|
||||
That is, if
|
||||
the last command returns zero, the exit status is 1; if
|
||||
the last command returns greater than zero, the exit status
|
||||
that status is zero, the exit status is 1; if
|
||||
that status is greater than zero, the exit status
|
||||
is zero.
|
||||
.Pp
|
||||
Because pipeline assignment of standard input or standard
|
||||
|
@ -31,6 +31,13 @@ ${PACKAGE}FILES+= killed2.0
|
||||
${PACKAGE}FILES+= not1.0
|
||||
${PACKAGE}FILES+= not2.0
|
||||
${PACKAGE}FILES+= path1.0
|
||||
${PACKAGE}FILES+= pipefail1.0
|
||||
${PACKAGE}FILES+= pipefail2.42
|
||||
${PACKAGE}FILES+= pipefail3.42
|
||||
${PACKAGE}FILES+= pipefail4.42
|
||||
${PACKAGE}FILES+= pipefail5.42
|
||||
${PACKAGE}FILES+= pipefail6.42
|
||||
${PACKAGE}FILES+= pipefail7.0
|
||||
${PACKAGE}FILES+= redir1.0
|
||||
${PACKAGE}FILES+= redir2.0
|
||||
${PACKAGE}FILES+= redir3.0
|
||||
|
4
bin/sh/tests/execution/pipefail1.0
Normal file
4
bin/sh/tests/execution/pipefail1.0
Normal file
@ -0,0 +1,4 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -o pipefail
|
||||
: && : | : && : | : | : && : | : | : | :
|
4
bin/sh/tests/execution/pipefail2.42
Normal file
4
bin/sh/tests/execution/pipefail2.42
Normal file
@ -0,0 +1,4 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -o pipefail
|
||||
(exit 42) | :
|
4
bin/sh/tests/execution/pipefail3.42
Normal file
4
bin/sh/tests/execution/pipefail3.42
Normal file
@ -0,0 +1,4 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -o pipefail
|
||||
: | (exit 42)
|
4
bin/sh/tests/execution/pipefail4.42
Normal file
4
bin/sh/tests/execution/pipefail4.42
Normal file
@ -0,0 +1,4 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -o pipefail
|
||||
(exit 43) | (exit 42)
|
5
bin/sh/tests/execution/pipefail5.42
Normal file
5
bin/sh/tests/execution/pipefail5.42
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -o pipefail
|
||||
(exit 42) | : &
|
||||
wait %+
|
6
bin/sh/tests/execution/pipefail6.42
Normal file
6
bin/sh/tests/execution/pipefail6.42
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
set -o pipefail
|
||||
(exit 42) | : &
|
||||
set +o pipefail
|
||||
wait %+
|
5
bin/sh/tests/execution/pipefail7.0
Normal file
5
bin/sh/tests/execution/pipefail7.0
Normal file
@ -0,0 +1,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
(exit 42) | : &
|
||||
set -o pipefail
|
||||
wait %+
|
@ -27,7 +27,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 27, 2018
|
||||
.Dd February 20, 2019
|
||||
.Dt ZPOOL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -187,7 +187,7 @@
|
||||
.Op Ar device ...
|
||||
.Nm
|
||||
.Cm status
|
||||
.Op Fl vx
|
||||
.Op Fl Dvx
|
||||
.Op Fl T Cm d Ns | Ns Cm u
|
||||
.Op Ar pool
|
||||
.Ar ...
|
||||
@ -1862,7 +1862,7 @@ section, above, for more information on the available pool properties.
|
||||
.It Xo
|
||||
.Nm
|
||||
.Cm status
|
||||
.Op Fl vx
|
||||
.Op Fl Dvx
|
||||
.Op Fl T Cm d Ns | Ns Cm u
|
||||
.Op Ar pool
|
||||
.Ar ...
|
||||
@ -1891,14 +1891,12 @@ done and the estimated time to completion. Both of these are only approximate,
|
||||
because the amount of data in the pool and the other workloads on the system
|
||||
can change.
|
||||
.Bl -tag -width indent
|
||||
.It Fl x
|
||||
Only display status for pools that are exhibiting errors or are otherwise
|
||||
unavailable.
|
||||
Warnings about pools not using the latest on-disk format, having non-native
|
||||
block size or disabled features will not be included.
|
||||
.It Fl v
|
||||
Displays verbose data error information, printing out a complete list of all
|
||||
data errors since the last complete pool scrub.
|
||||
.It Fl D
|
||||
Display a histogram of deduplication statistics, showing the allocated
|
||||
.Pq physically present on disk
|
||||
and referenced
|
||||
.Pq logically referenced in the pool
|
||||
block counts and sizes by reference count.
|
||||
.It Fl T Cm d Ns | Ns Cm u
|
||||
Print a timestamp.
|
||||
.Pp
|
||||
@ -1910,6 +1908,14 @@ Use modifier
|
||||
.Cm u
|
||||
for unixtime
|
||||
.Pq equals Qq Ic date +%s .
|
||||
.It Fl v
|
||||
Displays verbose data error information, printing out a complete list of all
|
||||
data errors since the last complete pool scrub.
|
||||
.It Fl x
|
||||
Only display status for pools that are exhibiting errors or are otherwise
|
||||
unavailable.
|
||||
Warnings about pools not using the latest on-disk format, having non-native
|
||||
block size or disabled features will not be included.
|
||||
.El
|
||||
.It Xo
|
||||
.Nm
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2017, Joyent, Inc. All rights reserved.
|
||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||
*/
|
||||
|
||||
@ -3040,9 +3040,6 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
|
||||
break;
|
||||
|
||||
timestamp = dt_buf_oldest(buf, dtp);
|
||||
assert(timestamp >= dtp->dt_last_timestamp);
|
||||
dtp->dt_last_timestamp = timestamp;
|
||||
|
||||
if (timestamp == buf->dtbd_timestamp) {
|
||||
/*
|
||||
* We've reached the end of the time covered
|
||||
@ -3056,6 +3053,8 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
assert(timestamp >= dtp->dt_last_timestamp);
|
||||
dtp->dt_last_timestamp = timestamp;
|
||||
|
||||
if ((rval = dt_consume_cpu(dtp, fp,
|
||||
buf->dtbd_cpu, buf, B_TRUE, pf, rf, arg)) != 0)
|
||||
|
@ -79,8 +79,13 @@ again: if ((t = tq->tq_freelist) != NULL && tq->tq_nalloc >= tq->tq_minalloc) {
|
||||
* immediately retry the allocation.
|
||||
*/
|
||||
tq->tq_maxalloc_wait++;
|
||||
#ifdef __FreeBSD__
|
||||
rv = cv_timedwait(&tq->tq_maxalloc_cv,
|
||||
&tq->tq_lock, hz);
|
||||
#else
|
||||
rv = cv_timedwait(&tq->tq_maxalloc_cv,
|
||||
&tq->tq_lock, ddi_get_lbolt() + hz);
|
||||
#endif
|
||||
tq->tq_maxalloc_wait--;
|
||||
if (rv > 0)
|
||||
goto again; /* signaled */
|
||||
|
@ -1230,8 +1230,6 @@ _LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<w
|
||||
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char16_t, char, mbstate_t>)
|
||||
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_t, char, mbstate_t>)
|
||||
|
||||
_LIBCPP_NORETURN _LIBCPP_FUNC_VIS void __throw_runtime_error(const char*);
|
||||
|
||||
template <size_t _Np>
|
||||
struct __narrow_to_utf8
|
||||
{
|
||||
|
@ -989,15 +989,23 @@ bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) {
|
||||
if (AM.hasSymbolicDisplacement())
|
||||
return true;
|
||||
|
||||
bool IsRIPRelTLS = false;
|
||||
bool IsRIPRel = N.getOpcode() == X86ISD::WrapperRIP;
|
||||
if (IsRIPRel) {
|
||||
SDValue Val = N.getOperand(0);
|
||||
if (Val.getOpcode() == ISD::TargetGlobalTLSAddress)
|
||||
IsRIPRelTLS = true;
|
||||
}
|
||||
|
||||
// We can't use an addressing mode in the 64-bit large code model. In the
|
||||
// medium code model, we use can use an mode when RIP wrappers are present.
|
||||
// That signifies access to globals that are known to be "near", such as the
|
||||
// GOT itself.
|
||||
// We can't use an addressing mode in the 64-bit large code model.
|
||||
// Global TLS addressing is an exception. In the medium code model,
|
||||
// we use can use a mode when RIP wrappers are present.
|
||||
// That signifies access to globals that are known to be "near",
|
||||
// such as the GOT itself.
|
||||
CodeModel::Model M = TM.getCodeModel();
|
||||
if (Subtarget->is64Bit() &&
|
||||
(M == CodeModel::Large || (M == CodeModel::Medium && !IsRIPRel)))
|
||||
((M == CodeModel::Large && !IsRIPRelTLS) ||
|
||||
(M == CodeModel::Medium && !IsRIPRel)))
|
||||
return true;
|
||||
|
||||
// Base and index reg must be 0 in order to use %rip as base.
|
||||
|
@ -70,6 +70,14 @@ static bool hasBaseReg(uint8_t ModRM) { return (ModRM & 0xc7) != 0x5; }
|
||||
|
||||
RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
|
||||
const uint8_t *Loc) const {
|
||||
// There are 4 different TLS variable models with varying degrees of
|
||||
// flexibility and performance. LocalExec and InitialExec models are fast but
|
||||
// less-flexible models. If they are in use, we set DF_STATIC_TLS flag in the
|
||||
// dynamic section to let runtime know about that.
|
||||
if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 || Type == R_386_TLS_IE ||
|
||||
Type == R_386_TLS_GOTIE)
|
||||
Config->HasStaticTlsModel = true;
|
||||
|
||||
switch (Type) {
|
||||
case R_386_8:
|
||||
case R_386_16:
|
||||
|
@ -76,6 +76,9 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
|
||||
template <class ELFT>
|
||||
RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
|
||||
const uint8_t *Loc) const {
|
||||
if (Type == R_X86_64_GOTTPOFF)
|
||||
Config->HasStaticTlsModel = true;
|
||||
|
||||
switch (Type) {
|
||||
case R_X86_64_8:
|
||||
case R_X86_64_16:
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "llvm/Support/CachePruning.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
namespace lld {
|
||||
@ -81,6 +82,7 @@ struct VersionDefinition {
|
||||
// and such fields have the same name as the corresponding options.
|
||||
// Most fields are initialized by the driver.
|
||||
struct Configuration {
|
||||
std::atomic<bool> HasStaticTlsModel{false};
|
||||
uint8_t OSABI = 0;
|
||||
llvm::CachePruningPolicy ThinLTOCachePolicy;
|
||||
llvm::StringMap<uint64_t> SectionStartMap;
|
||||
|
@ -1282,6 +1282,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
|
||||
}
|
||||
if (!Config->ZText)
|
||||
DtFlags |= DF_TEXTREL;
|
||||
if (Config->HasStaticTlsModel)
|
||||
DtFlags |= DF_STATIC_TLS;
|
||||
|
||||
if (DtFlags)
|
||||
addInt(DT_FLAGS, DtFlags);
|
||||
|
@ -18,7 +18,7 @@
|
||||
.Nd secure copy (remote file copy program)
|
||||
.Sh SYNOPSIS
|
||||
.Nm scp
|
||||
.Op Fl 346BCpqrv
|
||||
.Op Fl 346BCpqrTv
|
||||
.Op Fl c Ar cipher
|
||||
.Op Fl F Ar ssh_config
|
||||
.Op Fl i Ar identity_file
|
||||
@ -207,6 +207,16 @@ to use for the encrypted connection.
|
||||
The program must understand
|
||||
.Xr ssh 1
|
||||
options.
|
||||
.It Fl T
|
||||
Disable strict filename checking.
|
||||
By default when copying files from a remote host to a local directory
|
||||
.Nm
|
||||
checks that the received filenames match those requested on the command-line
|
||||
to prevent the remote end from sending unexpected or unwanted files.
|
||||
Because of differences in how various operating systems and shells interpret
|
||||
filename wildcards, these checks may cause wanted files to be rejected.
|
||||
This option disables these checks at the expense of fully trusting that
|
||||
the server will not send unexpected filenames.
|
||||
.It Fl v
|
||||
Verbose mode.
|
||||
Causes
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: scp.c,v 1.197 2018/06/01 04:31:48 dtucker Exp $ */
|
||||
/* $OpenBSD: scp.c,v 1.203 2019/01/27 07:14:11 jmc Exp $ */
|
||||
/*
|
||||
* scp - secure remote copy. This is basically patched BSD rcp which
|
||||
* uses ssh to do the data transfer (instead of using rcmd).
|
||||
@ -94,6 +94,7 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fnmatch.h>
|
||||
#include <limits.h>
|
||||
#include <locale.h>
|
||||
#include <pwd.h>
|
||||
@ -375,14 +376,14 @@ void verifydir(char *);
|
||||
struct passwd *pwd;
|
||||
uid_t userid;
|
||||
int errs, remin, remout;
|
||||
int pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
||||
int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
||||
|
||||
#define CMDNEEDS 64
|
||||
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
|
||||
|
||||
int response(void);
|
||||
void rsource(char *, struct stat *);
|
||||
void sink(int, char *[]);
|
||||
void sink(int, char *[], const char *);
|
||||
void source(int, char *[]);
|
||||
void tolocal(int, char *[]);
|
||||
void toremote(int, char *[]);
|
||||
@ -421,8 +422,9 @@ main(int argc, char **argv)
|
||||
addargs(&args, "-oRemoteCommand=none");
|
||||
addargs(&args, "-oRequestTTY=no");
|
||||
|
||||
fflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1)
|
||||
fflag = Tflag = tflag = 0;
|
||||
while ((ch = getopt(argc, argv,
|
||||
"dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) {
|
||||
switch (ch) {
|
||||
/* User-visible flags. */
|
||||
case '1':
|
||||
@ -501,9 +503,13 @@ main(int argc, char **argv)
|
||||
setmode(0, O_BINARY);
|
||||
#endif
|
||||
break;
|
||||
case 'T':
|
||||
Tflag = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
@ -534,7 +540,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
if (tflag) {
|
||||
/* Receive data. */
|
||||
sink(argc, argv);
|
||||
sink(argc, argv, NULL);
|
||||
exit(errs != 0);
|
||||
}
|
||||
if (argc < 2)
|
||||
@ -791,7 +797,7 @@ tolocal(int argc, char **argv)
|
||||
continue;
|
||||
}
|
||||
free(bp);
|
||||
sink(1, argv + argc - 1);
|
||||
sink(1, argv + argc - 1, src);
|
||||
(void) close(remin);
|
||||
remin = remout = -1;
|
||||
}
|
||||
@ -967,7 +973,7 @@ rsource(char *name, struct stat *statp)
|
||||
(sizeof(type) != 4 && sizeof(type) != 8))
|
||||
|
||||
void
|
||||
sink(int argc, char **argv)
|
||||
sink(int argc, char **argv, const char *src)
|
||||
{
|
||||
static BUF buffer;
|
||||
struct stat stb;
|
||||
@ -983,6 +989,7 @@ sink(int argc, char **argv)
|
||||
unsigned long long ull;
|
||||
int setimes, targisdir, wrerrno = 0;
|
||||
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
|
||||
char *src_copy = NULL, *restrict_pattern = NULL;
|
||||
struct timeval tv[2];
|
||||
|
||||
#define atime tv[0]
|
||||
@ -1007,6 +1014,17 @@ sink(int argc, char **argv)
|
||||
(void) atomicio(vwrite, remout, "", 1);
|
||||
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
||||
targisdir = 1;
|
||||
if (src != NULL && !iamrecursive && !Tflag) {
|
||||
/*
|
||||
* Prepare to try to restrict incoming filenames to match
|
||||
* the requested destination file glob.
|
||||
*/
|
||||
if ((src_copy = strdup(src)) == NULL)
|
||||
fatal("strdup failed");
|
||||
if ((restrict_pattern = strrchr(src_copy, '/')) != NULL) {
|
||||
*restrict_pattern++ = '\0';
|
||||
}
|
||||
}
|
||||
for (first = 1;; first = 0) {
|
||||
cp = buf;
|
||||
if (atomicio(read, remin, cp, 1) != 1)
|
||||
@ -1111,6 +1129,9 @@ sink(int argc, char **argv)
|
||||
run_err("error: unexpected filename: %s", cp);
|
||||
exit(1);
|
||||
}
|
||||
if (restrict_pattern != NULL &&
|
||||
fnmatch(restrict_pattern, cp, 0) != 0)
|
||||
SCREWUP("filename does not match request");
|
||||
if (targisdir) {
|
||||
static char *namebuf;
|
||||
static size_t cursize;
|
||||
@ -1148,7 +1169,7 @@ sink(int argc, char **argv)
|
||||
goto bad;
|
||||
}
|
||||
vect[0] = xstrdup(np);
|
||||
sink(1, vect);
|
||||
sink(1, vect, src);
|
||||
if (setimes) {
|
||||
setimes = 0;
|
||||
if (utimes(vect[0], tv) < 0)
|
||||
@ -1316,7 +1337,7 @@ void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr,
|
||||
"usage: scp [-346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
"usage: scp [-346BCpqrTv] [-c cipher] [-F ssh_config] [-i identity_file]\n"
|
||||
" [-l limit] [-o ssh_option] [-P port] [-S program] source ... target\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -44,6 +44,13 @@ FBSD_1.0 {
|
||||
vfork;
|
||||
};
|
||||
|
||||
FBSD_1.6 {
|
||||
x86_pkru_get_perm;
|
||||
x86_pkru_set_perm;
|
||||
x86_pkru_protect_range;
|
||||
x86_pkru_unprotect_range;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* FreeBSD private ABI
|
||||
|
@ -46,6 +46,13 @@ FBSD_1.0 {
|
||||
___tls_get_addr;
|
||||
};
|
||||
|
||||
FBSD_1.6 {
|
||||
x86_pkru_get_perm;
|
||||
x86_pkru_set_perm;
|
||||
x86_pkru_protect_range;
|
||||
x86_pkru_unprotect_range;
|
||||
};
|
||||
|
||||
FBSDprivate_1.0 {
|
||||
/* PSEUDO syscalls */
|
||||
_getlogin;
|
||||
|
@ -70,7 +70,6 @@ _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask)
|
||||
{
|
||||
acl_t acl_new, acl_old;
|
||||
acl_entry_t entry, entry_new;
|
||||
acl_permset_t perm;
|
||||
acl_tag_t tag;
|
||||
int entry_id, have_mask_entry;
|
||||
|
||||
@ -104,16 +103,8 @@ _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask)
|
||||
case ACL_USER_OBJ:
|
||||
case ACL_GROUP_OBJ:
|
||||
case ACL_OTHER:
|
||||
if (acl_get_tag_type(entry, &tag) == -1)
|
||||
goto fail;
|
||||
if (acl_get_permset(entry, &perm) == -1)
|
||||
goto fail;
|
||||
if (acl_create_entry(&acl_new, &entry_new) == -1)
|
||||
goto fail;
|
||||
if (acl_set_tag_type(entry_new, tag) == -1)
|
||||
goto fail;
|
||||
if (acl_set_permset(entry_new, perm) == -1)
|
||||
goto fail;
|
||||
if (acl_copy_entry(entry_new, entry) == -1)
|
||||
goto fail;
|
||||
assert(_entry_brand(entry_new) == ACL_BRAND_POSIX);
|
||||
|
@ -156,6 +156,8 @@ setup_client(int domain, int type, int port)
|
||||
"Will try to connect to host='%s', address_family=%d, "
|
||||
"socket_type=%d\n",
|
||||
host, res->ai_family, res->ai_socktype);
|
||||
/* Avoid a double print when forked by flushing. */
|
||||
fflush(stdout);
|
||||
sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
@ -187,6 +189,8 @@ setup_server(int domain, int type, int port)
|
||||
"Will try to bind socket to host='%s', address_family=%d, "
|
||||
"socket_type=%d\n",
|
||||
host, res->ai_family, res->ai_socktype);
|
||||
/* Avoid a double print when forked by flushing. */
|
||||
fflush(stdout);
|
||||
error = bind(sock, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno));
|
||||
@ -204,11 +208,17 @@ setup_server(int domain, int type, int port)
|
||||
static void
|
||||
server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||
{
|
||||
char *buffer;
|
||||
char *buffer, *buf_window_ptr;
|
||||
int recv_sock;
|
||||
ssize_t received_bytes;
|
||||
size_t buffer_size;
|
||||
ssize_t received_bytes, recv_ret;
|
||||
|
||||
buffer = calloc(len + 1, sizeof(char));
|
||||
/*
|
||||
* Ensure that there isn't excess data sent across the wire by
|
||||
* capturing 10 extra bytes (plus 1 for nul).
|
||||
*/
|
||||
buffer_size = len + 10 + 1;
|
||||
buffer = calloc(buffer_size, sizeof(char));
|
||||
if (buffer == NULL)
|
||||
err(1, "malloc failed");
|
||||
|
||||
@ -216,32 +226,26 @@ server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||
if (recv_sock == -1)
|
||||
err(1, "accept failed");
|
||||
|
||||
/*
|
||||
* XXX: this assumes the simplest case where all data is received in a
|
||||
* single recv(2) call.
|
||||
*/
|
||||
if (recv(recv_sock, buffer, len, 0) == -1)
|
||||
err(1, "recv failed");
|
||||
buf_window_ptr = buffer;
|
||||
received_bytes = 0;
|
||||
do {
|
||||
recv_ret = recv(recv_sock, buf_window_ptr,
|
||||
buffer_size - received_bytes, 0);
|
||||
if (recv_ret <= 0)
|
||||
break;
|
||||
buf_window_ptr += recv_ret;
|
||||
received_bytes += recv_ret;
|
||||
} while (received_bytes < buffer_size);
|
||||
|
||||
atf_utils_create_file(dest_filename, "%s", buffer);
|
||||
|
||||
/*
|
||||
* This recv(2) call helps ensure the amount of sent data is exactly
|
||||
* what was specified by `len`.
|
||||
*/
|
||||
received_bytes = recv(recv_sock, buffer, len, 0);
|
||||
switch (received_bytes) {
|
||||
case -1:
|
||||
err(1, "recv failed");
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
errx(1, "received unexpected data: %s", buffer);
|
||||
}
|
||||
|
||||
(void)close(recv_sock);
|
||||
(void)close(server_sock);
|
||||
free(buffer);
|
||||
|
||||
if (received_bytes != len)
|
||||
errx(1, "received unexpected data: %zd != %zd", received_bytes,
|
||||
len);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -667,10 +671,6 @@ hdtr_positive_test(int domain)
|
||||
offset = 0;
|
||||
nbytes = 0;
|
||||
|
||||
atf_tc_expect_fail(
|
||||
"The header/trailer testcases fail today with a data mismatch; "
|
||||
"bug # 234809");
|
||||
|
||||
for (i = 0; i < nitems(testcases); i++) {
|
||||
struct sf_hdtr hdtr;
|
||||
char *pattern;
|
||||
|
@ -3,7 +3,11 @@
|
||||
.PATH: ${LIBC_SRCTOP}/x86/sys
|
||||
|
||||
SRCS+= \
|
||||
__vdso_gettc.c
|
||||
__vdso_gettc.c \
|
||||
pkru.c
|
||||
|
||||
MAN+= \
|
||||
pkru.3
|
||||
|
||||
.if ${MACHINE_CPUARCH} == "amd64" && ${MK_HYPERV} != "no"
|
||||
CFLAGS+= -DWANT_HYPERV
|
||||
|
206
lib/libc/x86/sys/pkru.3
Normal file
206
lib/libc/x86/sys/pkru.3
Normal file
@ -0,0 +1,206 @@
|
||||
.\" Copyright (c) 2019 The FreeBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This documentation was written by
|
||||
.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
|
||||
.\" from the FreeBSD Foundation.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 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 AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" 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$
|
||||
.\"
|
||||
.Dd February 16, 2019
|
||||
.Dt PKRU 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm Protection Key Rights for User pages
|
||||
.Nd provide fast user-managed key-based access control for pages
|
||||
.Sh LIBRARY
|
||||
.Lb libc
|
||||
.Sh SYNOPSIS
|
||||
.In machine/sysarch.h
|
||||
.Ft int
|
||||
.Fn x86_pkru_get_perm "unsigned int keyidx" "int *access" "int *modify"
|
||||
.Ft int
|
||||
.Fn x86_pkru_set_perm "unsigned int keyidx" "int access" "int modify"
|
||||
.Ft int
|
||||
.Fo x86_pkru_protect_range
|
||||
.Fa "void *addr"
|
||||
.Fa "unsigned long len"
|
||||
.Fa "unsigned int keyidx"
|
||||
.Fa "int flag"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn x86_pkru_unprotect_range "void *addr" "unsigned long len"
|
||||
.Sh DESCRIPTION
|
||||
The protection keys feature provides an additional mechanism, besides the
|
||||
normal page permissions as established by
|
||||
.Xr mmap 2
|
||||
and
|
||||
.Xr mprotect 2 ,
|
||||
to control access to user-mode addresses.
|
||||
The mechanism gives safety measures which can be used to avoid
|
||||
incidental read or modification of sensitive memory,
|
||||
or as a debugging feature.
|
||||
It cannot guard against conscious accesses since permissions
|
||||
are user-controllable.
|
||||
.Pp
|
||||
If supported by hardware, each mapped user linear address
|
||||
has an associated 4-bit protection key.
|
||||
A new per-thread PKRU hardware register determines, for each protection
|
||||
key, whether user-mode addresses with that protection key may be
|
||||
read or written.
|
||||
.Pp
|
||||
Only one key may apply to a given range at a time.
|
||||
The default protection key index is zero, it is used even if no key
|
||||
was explicitly assigned to the address, or if the key was removed.
|
||||
.Pp
|
||||
The protection prevents the system from accessing user addresses as well
|
||||
as the user applications.
|
||||
When a system call was unable to read or write user memory due to key
|
||||
protection, it returns the
|
||||
.Er EFAULT
|
||||
error code.
|
||||
Note that some side effects may have occurred if this error is reported.
|
||||
.Pp
|
||||
Protection keys require that the system uses 4-level paging
|
||||
(also called long mode),
|
||||
which means that it is only available on amd64 system.
|
||||
Both 64-bit and 32-bit applications can use protection keys.
|
||||
More information about the hardware feature is provided in the IA32 Software
|
||||
Developer's Manual published by Intel Corp.
|
||||
.Pp
|
||||
The key indexes written into the page table entries are managed by the
|
||||
.Fn sysarch
|
||||
syscall.
|
||||
Per-key permissions are managed using the user-mode instructions
|
||||
.Em RDPKRU
|
||||
and
|
||||
.Em WRPKRU.
|
||||
The system provides convenient library helpers for both the syscall and
|
||||
the instructions, described below.
|
||||
.Pp
|
||||
The
|
||||
.Fn x86_pkru_protect_range
|
||||
function assigns key
|
||||
.Fa keyidx
|
||||
to the range starting at
|
||||
.Fa addr
|
||||
and having length
|
||||
.Fa len .
|
||||
Starting address is truncated to the page start,
|
||||
and the end is rounded up to the end of the page.
|
||||
After a successfull call, the range has the specified key assigned,
|
||||
even if the key is zero and it did not change the page table entries.
|
||||
.Pp
|
||||
The
|
||||
.Fa flags
|
||||
argument takes the logical OR of the following values:
|
||||
.Bl -tag -width
|
||||
.It Bq Va AMD64_PKRU_EXCL
|
||||
Only assign the key if the range does not have any other keys assigned
|
||||
(including the zero key).
|
||||
You must first remove any existing key with
|
||||
.Fn x86_pkru_unprotect_range
|
||||
in order for this request to succeed.
|
||||
If the
|
||||
.Va AMD64_PKRU_EXCL
|
||||
flag is not specified,
|
||||
.Fn x86_pkru_protect_range
|
||||
replaces any existing key.
|
||||
.It Bq Va AMD64_PKRU_PERSIST
|
||||
The keys assigned to the range are persistent.
|
||||
They are re-established when the current mapping is destroyed
|
||||
and a new mapping is created in any sub-range of the specified range.
|
||||
You must use a
|
||||
.Fn x86_pkru_unprotect_range
|
||||
call to forget the key.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn x86_pkru_unprotect_range
|
||||
function removes any keys assigned to the specified range.
|
||||
Existing mappings are changed to use key index zero in page table entries.
|
||||
Keys are no longer considered installed for all mappings in the range,
|
||||
for the purposes of
|
||||
.Fn x86_pkru_protect_range
|
||||
with the
|
||||
.Va AMD64_PKRU_EXCL
|
||||
flag.
|
||||
.Pp
|
||||
The
|
||||
.Fn x86_pkru_get_perm
|
||||
function returns access rights for the key specified by the
|
||||
.Fn keyidx
|
||||
argument.
|
||||
If the value pointed to by
|
||||
.Fa access
|
||||
is zero after the call, no read or write permissions is granted for
|
||||
mappings which are assigned the key
|
||||
.Fn keyidx .
|
||||
If
|
||||
.Fa access
|
||||
is not zero, read access is permitted.
|
||||
The non-zero value of the variable pointed to by the
|
||||
.Fa modify
|
||||
argument indicates that write access is permitted.
|
||||
.Pp
|
||||
Conversely, the
|
||||
.Fn x86_pkru_set_perm
|
||||
establishes the access and modify permissions for the given key index
|
||||
as specified by its arguments.
|
||||
.Sh RETURN VALUES
|
||||
.Rv -std
|
||||
.Sh ERRORS
|
||||
.Bl -tag -width Er
|
||||
.It Bq Er EOPNOTSUPP
|
||||
The hardware does not support protection keys.
|
||||
.It Bq Er EINVAL
|
||||
The supplied key index is invalid (greater than 15).
|
||||
.It Bq Er EINVAL
|
||||
The supplied
|
||||
.Fa flags
|
||||
argument for
|
||||
.Fn x86_pkru_protect_range
|
||||
has reserved bits set.
|
||||
.It Bq Er EFAULT
|
||||
The supplied address range does not completely fit into the user-managed
|
||||
address range.
|
||||
.It Bq Er ENOMEM
|
||||
The memory shortage prevents the completion of the operation.
|
||||
.It Bq Er EBUSY
|
||||
The
|
||||
.Va AMD64_PKRU_EXCL
|
||||
flag was specified for
|
||||
.Fn x86_pkru_protect_range
|
||||
and the range already has defined protection keys.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mmap 2 ,
|
||||
.Xr mprotect 2 ,
|
||||
.Xr munmap 2 ,
|
||||
.Xr sysarch 2 .
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
functions are non-standard and first appeared in
|
||||
.Fx 13.0 .
|
138
lib/libc/x86/sys/pkru.c
Normal file
138
lib/libc/x86/sys/pkru.c
Normal file
@ -0,0 +1,138 @@
|
||||
/*-
|
||||
* Copyright (c) 2019 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Portions of this software were developed by Konstantin Belousov
|
||||
* under sponsorship from the FreeBSD Foundation.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 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 <sys/param.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/sysarch.h>
|
||||
#include <x86/ifunc.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAX_PKRU_IDX 0xf
|
||||
#ifdef __i386__
|
||||
#define X86_SET_PKRU I386_SET_PKRU
|
||||
#define X86_CLEAR_PKRU I386_CLEAR_PKRU
|
||||
#else
|
||||
#define X86_SET_PKRU AMD64_SET_PKRU
|
||||
#define X86_CLEAR_PKRU AMD64_CLEAR_PKRU
|
||||
#endif
|
||||
|
||||
static int
|
||||
x86_pkru_get_perm_unsup(u_int keyidx, int *access, int *modify)
|
||||
{
|
||||
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
x86_pkru_get_perm_hw(u_int keyidx, int *access, int *modify)
|
||||
{
|
||||
uint32_t pkru;
|
||||
|
||||
if (keyidx > MAX_PKRU_IDX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
keyidx *= 2;
|
||||
pkru = rdpkru();
|
||||
*access = (pkru & (1 << keyidx)) == 0;
|
||||
*modify = (pkru & (2 << keyidx)) == 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEFINE_UIFUNC(, int, x86_pkru_get_perm, (u_int, int *, int *), static)
|
||||
{
|
||||
|
||||
return ((cpu_stdext_feature2 & CPUID_STDEXT2_OSPKE) == 0 ?
|
||||
x86_pkru_get_perm_unsup : x86_pkru_get_perm_hw);
|
||||
}
|
||||
|
||||
static int
|
||||
x86_pkru_set_perm_unsup(u_int keyidx, int access, int modify)
|
||||
{
|
||||
|
||||
errno = EOPNOTSUPP;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
x86_pkru_set_perm_hw(u_int keyidx, int access, int modify)
|
||||
{
|
||||
uint32_t pkru;
|
||||
|
||||
if (keyidx > MAX_PKRU_IDX) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
keyidx *= 2;
|
||||
pkru = rdpkru();
|
||||
pkru &= ~(3 << keyidx);
|
||||
if (!access)
|
||||
pkru |= 1 << keyidx;
|
||||
if (!modify)
|
||||
pkru |= 2 << keyidx;
|
||||
wrpkru(pkru);
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEFINE_UIFUNC(, int, x86_pkru_set_perm, (u_int, int, int), static)
|
||||
{
|
||||
|
||||
return ((cpu_stdext_feature2 & CPUID_STDEXT2_OSPKE) == 0 ?
|
||||
x86_pkru_set_perm_unsup : x86_pkru_set_perm_hw);
|
||||
}
|
||||
|
||||
int
|
||||
x86_pkru_protect_range(void *addr, unsigned long len, u_int keyidx, int flags)
|
||||
{
|
||||
struct amd64_set_pkru a64pkru;
|
||||
|
||||
memset(&a64pkru, 0, sizeof(a64pkru));
|
||||
a64pkru.addr = addr;
|
||||
a64pkru.len = len;
|
||||
a64pkru.keyidx = keyidx;
|
||||
a64pkru.flags = flags;
|
||||
return (sysarch(X86_SET_PKRU, &a64pkru));
|
||||
}
|
||||
|
||||
int
|
||||
x86_pkru_unprotect_range(void *addr, unsigned long len)
|
||||
{
|
||||
struct amd64_set_pkru a64pkru;
|
||||
|
||||
memset(&a64pkru, 0, sizeof(a64pkru));
|
||||
a64pkru.addr = addr;
|
||||
a64pkru.len = len;
|
||||
return (sysarch(X86_CLEAR_PKRU, &a64pkru));
|
||||
}
|
@ -96,7 +96,7 @@ vm_extra_pre_umount() {
|
||||
|
||||
# Use the NTP service provided by Amazon
|
||||
sed -i '' -e 's/^pool/#pool/' \
|
||||
-e 's/^#server.*/server 169.254.169.123 iburst/' \
|
||||
-e '1,/^#server/s/^#server.*/server 169.254.169.123 iburst/' \
|
||||
${DESTDIR}/etc/ntp.conf
|
||||
|
||||
# The first time the AMI boots, the installed "first boot" scripts
|
||||
|
@ -863,6 +863,7 @@ bind_lease(struct interface_info *ip)
|
||||
opt = &ip->client->new->options[DHO_INTERFACE_MTU];
|
||||
if (opt->len == sizeof(u_int16_t)) {
|
||||
u_int16_t mtu = 0;
|
||||
u_int16_t old_mtu = 0;
|
||||
bool supersede = (ip->client->config->default_actions[DHO_INTERFACE_MTU] ==
|
||||
ACTION_SUPERSEDE);
|
||||
|
||||
@ -871,12 +872,19 @@ bind_lease(struct interface_info *ip)
|
||||
else
|
||||
mtu = be16dec(opt->data);
|
||||
|
||||
if (ip->client->active) {
|
||||
opt = &ip->client->active->options[DHO_INTERFACE_MTU];
|
||||
if (opt->len == sizeof(u_int16_t)) {
|
||||
old_mtu = be16dec(opt->data);
|
||||
}
|
||||
}
|
||||
|
||||
if (mtu < MIN_MTU) {
|
||||
/* Treat 0 like a user intentionally doesn't want to change MTU and,
|
||||
* therefore, warning is not needed */
|
||||
if (!supersede || mtu != 0)
|
||||
warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
|
||||
} else {
|
||||
} else if (ip->client->state != S_RENEWING || mtu != old_mtu) {
|
||||
interface_set_mtu_unpriv(privfd, mtu);
|
||||
}
|
||||
}
|
||||
|
@ -349,9 +349,11 @@ getnextinode(ino_t inumber, int rebuildcg)
|
||||
lastinum += fullcnt;
|
||||
}
|
||||
/*
|
||||
* Flush old contents in case they have been updated.
|
||||
* If getblk encounters an error, it will already have zeroed
|
||||
* out the buffer, so we do not need to do so here.
|
||||
*/
|
||||
flush(fswritefd, &inobuf);
|
||||
getblk(&inobuf, blk, size);
|
||||
nextinop = inobuf.b_un.b_buf;
|
||||
}
|
||||
@ -461,6 +463,10 @@ void
|
||||
freeinodebuf(void)
|
||||
{
|
||||
|
||||
/*
|
||||
* Flush old contents in case they have been updated.
|
||||
*/
|
||||
flush(fswritefd, &inobuf);
|
||||
if (inobuf.b_un.b_buf != NULL)
|
||||
free((char *)inobuf.b_un.b_buf);
|
||||
inobuf.b_un.b_buf = NULL;
|
||||
|
@ -53,7 +53,14 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define MAX_FW_SLOTS (7)
|
||||
|
||||
SET_CONCAT_DEF(logpage, struct logpage_function);
|
||||
static SLIST_HEAD(,logpage_function) logpages;
|
||||
|
||||
void
|
||||
logpage_register(struct logpage_function *p)
|
||||
{
|
||||
|
||||
SLIST_INSERT_HEAD(&logpages, p, link);
|
||||
}
|
||||
|
||||
const char *
|
||||
kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key)
|
||||
@ -326,15 +333,15 @@ NVME_LOGPAGE(fw,
|
||||
static void
|
||||
logpage_help(void)
|
||||
{
|
||||
const struct logpage_function * const *f;
|
||||
const struct logpage_function *f;
|
||||
const char *v;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "%-8s %-10s %s\n", "Page", "Vendor","Page Name");
|
||||
fprintf(stderr, "-------- ---------- ----------\n");
|
||||
for (f = logpage_begin(); f < logpage_limit(); f++) {
|
||||
v = (*f)->vendor == NULL ? "-" : (*f)->vendor;
|
||||
fprintf(stderr, "0x%02x %-10s %s\n", (*f)->log_page, v, (*f)->name);
|
||||
SLIST_FOREACH(f, &logpages, link) {
|
||||
v = f->vendor == NULL ? "-" : f->vendor;
|
||||
fprintf(stderr, "0x%02x %-10s %s\n", f->log_page, v, f->name);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
@ -352,7 +359,7 @@ logpage(const struct nvme_function *nf, int argc, char *argv[])
|
||||
uint32_t nsid, size;
|
||||
void *buf;
|
||||
const char *vendor = NULL;
|
||||
const struct logpage_function * const *f;
|
||||
const struct logpage_function *f;
|
||||
struct nvme_controller_data cdata;
|
||||
print_fn_t print_fn;
|
||||
uint8_t ns_smart;
|
||||
@ -438,14 +445,14 @@ logpage(const struct nvme_function *nf, int argc, char *argv[])
|
||||
* the page is vendor specific, don't match the print function
|
||||
* unless the vendors match.
|
||||
*/
|
||||
for (f = logpage_begin(); f < logpage_limit(); f++) {
|
||||
if ((*f)->vendor != NULL && vendor != NULL &&
|
||||
strcmp((*f)->vendor, vendor) != 0)
|
||||
SLIST_FOREACH(f, &logpages, link) {
|
||||
if (f->vendor != NULL && vendor != NULL &&
|
||||
strcmp(f->vendor, vendor) != 0)
|
||||
continue;
|
||||
if (log_page != (*f)->log_page)
|
||||
if (log_page != f->log_page)
|
||||
continue;
|
||||
print_fn = (*f)->print_fn;
|
||||
size = (*f)->size;
|
||||
print_fn = f->print_fn;
|
||||
size = f->size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -312,19 +312,17 @@ load_dir(const char *dir)
|
||||
warnx("Can't load %s: %s", path, dlerror());
|
||||
else {
|
||||
/*
|
||||
* Add in the top (for cli commands) and logpage (for
|
||||
* logpage parsing) linker sets. We have to do this by
|
||||
* hand because linker sets aren't automatically merged.
|
||||
* Add in the top (for cli commands)linker sets. We have
|
||||
* to do this by hand because linker sets aren't
|
||||
* automatically merged.
|
||||
*/
|
||||
void *begin, *limit;
|
||||
|
||||
begin = dlsym(h, "__start_set_top");
|
||||
limit = dlsym(h, "__stop_set_top");
|
||||
if (begin)
|
||||
add_to_top(begin, limit);
|
||||
begin = dlsym(h, "__start_set_logpage");
|
||||
limit = dlsym(h, "__stop_set_logpage");
|
||||
if (begin)
|
||||
add_to_logpage(begin, limit);
|
||||
/* log pages use constructors so are done on load */
|
||||
}
|
||||
free(path);
|
||||
path = NULL;
|
||||
@ -337,7 +335,6 @@ main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
add_to_top(NVME_CMD_BEGIN(top), NVME_CMD_LIMIT(top));
|
||||
add_to_logpage(NVME_LOGPAGE_BEGIN, NVME_LOGPAGE_LIMIT);
|
||||
|
||||
load_dir("/lib/nvmecontrol");
|
||||
load_dir("/usr/local/lib/nvmecontrol");
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define __NVMECONTROL_H__
|
||||
|
||||
#include <sys/linker_set.h>
|
||||
#include <sys/queue.h>
|
||||
#include <dev/nvme/nvme.h>
|
||||
|
||||
struct nvme_function;
|
||||
@ -56,6 +57,7 @@ struct nvme_function {
|
||||
typedef void (*print_fn_t)(const struct nvme_controller_data *cdata, void *buf, uint32_t size);
|
||||
|
||||
struct logpage_function {
|
||||
SLIST_ENTRY(logpage_function) link;
|
||||
uint8_t log_page;
|
||||
const char *vendor;
|
||||
const char *name;
|
||||
@ -64,7 +66,6 @@ struct logpage_function {
|
||||
};
|
||||
|
||||
|
||||
#define NVME_LOGPAGESET(sym) DATA_SET(NVME_SETNAME(logpage), sym)
|
||||
#define NVME_LOGPAGE(unique, lp, vend, nam, fn, sz) \
|
||||
static struct logpage_function unique ## _lpf = { \
|
||||
.log_page = lp, \
|
||||
@ -73,10 +74,8 @@ struct logpage_function {
|
||||
.print_fn = fn, \
|
||||
.size = sz, \
|
||||
} ; \
|
||||
NVME_LOGPAGESET(unique ## _lpf)
|
||||
#define NVME_LOGPAGE_BEGIN SET_BEGIN(NVME_SETNAME(logpage))
|
||||
#define NVME_LOGPAGE_LIMIT SET_LIMIT(NVME_SETNAME(logpage))
|
||||
#define NVME_LOGPAGE_DECLARE(t) SET_DECLARE(NVME_SETNAME(logpage), t)
|
||||
static void logpage_reg_##unique(void) __attribute__((constructor)); \
|
||||
static void logpage_reg_##unique(void) { logpage_register(&unique##_lpf); }
|
||||
|
||||
#define DEFAULT_SIZE (4096)
|
||||
struct kv_name {
|
||||
@ -87,7 +86,7 @@ struct kv_name {
|
||||
const char *kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key);
|
||||
|
||||
NVME_CMD_DECLARE(top, struct nvme_function);
|
||||
NVME_LOGPAGE_DECLARE(struct logpage_function);
|
||||
void logpage_register(struct logpage_function *p);
|
||||
|
||||
struct set_concat {
|
||||
void **begin;
|
||||
@ -105,7 +104,6 @@ void add_to_ ## set(t **b, t **e) \
|
||||
#define SET_CONCAT_DECL(set, t) \
|
||||
void add_to_ ## set(t **b, t **e)
|
||||
SET_CONCAT_DECL(top, struct nvme_function);
|
||||
SET_CONCAT_DECL(logpage, struct logpage_function);
|
||||
|
||||
#define NVME_CTRLR_PREFIX "nvme"
|
||||
#define NVME_NS_PREFIX "ns"
|
||||
|
@ -49,6 +49,7 @@ static const char rcsid[] =
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <dev/evdev/input.h>
|
||||
|
||||
#ifdef __amd64__
|
||||
#include <sys/efi.h>
|
||||
@ -680,6 +681,22 @@ S_vmtotal(size_t l2, void *p)
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
S_input_id(size_t l2, void *p)
|
||||
{
|
||||
struct input_id *id = p;
|
||||
|
||||
if (l2 != sizeof(*id)) {
|
||||
warnx("S_input_id %zu != %zu", l2, sizeof(*id));
|
||||
return (1);
|
||||
}
|
||||
|
||||
printf("{ bustype = 0x%04x, vendor = 0x%04x, "
|
||||
"product = 0x%04x, version = 0x%04x }",
|
||||
id->bustype, id->vendor, id->product, id->version);
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef __amd64__
|
||||
static int
|
||||
S_efi_map(size_t l2, void *p)
|
||||
@ -983,6 +1000,8 @@ show_var(int *oid, int nlen)
|
||||
func = S_loadavg;
|
||||
else if (strcmp(fmt, "S,vmtotal") == 0)
|
||||
func = S_vmtotal;
|
||||
else if (strcmp(fmt, "S,input_id") == 0)
|
||||
func = S_input_id;
|
||||
#ifdef __amd64__
|
||||
else if (strcmp(fmt, "S,efi_map_header") == 0)
|
||||
func = S_efi_map;
|
||||
|
@ -75,6 +75,7 @@ the congestion window in response to an ECN congestion signal when
|
||||
.Va net.inet.tcp.cc.abe=1
|
||||
per: cwnd = (cwnd * CC_NEWRENO_BETA_ECN) / 100.
|
||||
Default is 80.
|
||||
.El
|
||||
.Sh MIB Variables
|
||||
The algorithm exposes these variables in the
|
||||
.Va net.inet.tcp.cc.newreno
|
||||
@ -93,6 +94,7 @@ the congestion window in response to an ECN congestion signal when
|
||||
.Va net.inet.tcp.cc.abe=1
|
||||
per: cwnd = (cwnd * beta_ecn) / 100.
|
||||
Default is 80.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr cc_chd 4 ,
|
||||
.Xr cc_cubic 4 ,
|
||||
|
@ -202,6 +202,7 @@ The default value is 1024.
|
||||
.It Va kern.cam.ctl.max_ports
|
||||
Specifies the maximum number of ports we support, must be a power of 2.
|
||||
The default value is 256.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr cfiscsi 4 ,
|
||||
.Xr cfumass 4 ,
|
||||
|
@ -88,6 +88,7 @@ The default value is 0 (off).
|
||||
.It Va hw.usb.ehci.no_hs
|
||||
This tunable disables USB devices to attach like HIGH-speed ones and will force all attached devices to attach to the FULL- or LOW-speed companion controller.
|
||||
The default value is 0 (off).
|
||||
.El
|
||||
.Sh SYSCTL VARIABLES
|
||||
The following variables are available as both
|
||||
.Xr sysctl 8
|
||||
|
@ -264,6 +264,7 @@ If
|
||||
.Va hw.em.tx_int_delay
|
||||
is non-zero, this tunable limits the maximum delay in which a transmit
|
||||
interrupt is generated.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/led/em*
|
||||
.It Pa /dev/led/em*
|
||||
|
@ -239,6 +239,7 @@ for more details.
|
||||
.Pp
|
||||
Packet with unsupported number of segments was queued for sending to the
|
||||
device; packet will be dropped.
|
||||
.El
|
||||
.Sh SUPPORT
|
||||
If an issue is identified with the released source code with a supported adapter
|
||||
email the specific information related to the issue to
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" @(#)ip.4 8.2 (Berkeley) 11/30/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd August 19, 2018
|
||||
.Dd February 22, 2019
|
||||
.Dt IP 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -571,32 +571,55 @@ To join a multicast group, use the
|
||||
.Dv IP_ADD_MEMBERSHIP
|
||||
option:
|
||||
.Bd -literal
|
||||
struct ip_mreq mreq;
|
||||
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
||||
struct ip_mreqn mreqn;
|
||||
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, sizeof(mreqn));
|
||||
.Ed
|
||||
.Pp
|
||||
where
|
||||
.Fa mreq
|
||||
.Fa mreqn
|
||||
is the following structure:
|
||||
.Bd -literal
|
||||
struct ip_mreq {
|
||||
struct ip_mreqn {
|
||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||
struct in_addr imr_interface; /* local IP address of interface */
|
||||
int imr_ifindex; /* interface index */
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
.Va imr_interface
|
||||
should be set to the
|
||||
.Tn IP
|
||||
address of a particular multicast-capable interface if
|
||||
.Va imr_ifindex
|
||||
should be set to the index of a particular multicast-capable interface if
|
||||
the host is multihomed.
|
||||
It may be set to
|
||||
.Dv INADDR_ANY
|
||||
to choose the default interface, although this is not recommended;
|
||||
this is considered to be the first interface corresponding
|
||||
to the default route.
|
||||
Otherwise, the first multicast-capable interface
|
||||
configured in the system will be used.
|
||||
If
|
||||
.Va imr_ifindex
|
||||
is non-zero, value of
|
||||
.Va imr_interface
|
||||
is ignored.
|
||||
Otherwise, if
|
||||
.Va imr_ifindex
|
||||
is 0, kernel will use IP address from
|
||||
.Va imr_interface
|
||||
to lookup the interface.
|
||||
Value of
|
||||
.Va imr_interface
|
||||
may be set to
|
||||
.Va INADDR_ANY
|
||||
to choose the default interface, although this is not recommended; this is
|
||||
considered to be the first interface corresponding to the default route.
|
||||
Otherwise, the first multicast-capable interface configured in the system
|
||||
will be used.
|
||||
.Pp
|
||||
Legacy
|
||||
.Vt "struct ip_mreq" ,
|
||||
that lacks
|
||||
.Va imr_ifindex
|
||||
field is also supported by
|
||||
.Dv IP_ADD_MEMBERSHIP
|
||||
setsockopt.
|
||||
In this case kernel would behave as if
|
||||
.Va imr_ifindex
|
||||
was set to zero:
|
||||
.Va imr_interface
|
||||
will be used to lookup interface.
|
||||
.Pp
|
||||
Prior to
|
||||
.Fx 7.0 ,
|
||||
|
@ -114,7 +114,7 @@ Unable to obtain adapter or drive configuration.
|
||||
A buffer input/output error has occurred.
|
||||
.Bq Er ENXIO
|
||||
.El
|
||||
.Ss General adapter errors:
|
||||
.Ss General adapter errors :
|
||||
.Bl -diag
|
||||
.It Attaching bus failed
|
||||
.Pp
|
||||
@ -146,7 +146,7 @@ The adapter is disabled.
|
||||
.Pp
|
||||
The driver was unable to allocate resources for the device.
|
||||
.El
|
||||
.Ss Error messages due to DMA:
|
||||
.Ss Error messages due to DMA :
|
||||
.Bl -diag
|
||||
.It can't alloc command dma tag
|
||||
.It can't alloc SG dma tag
|
||||
@ -155,7 +155,7 @@ The driver was unable to allocate resources for the device.
|
||||
.Pp
|
||||
Failure to map or allocate DMA resources.
|
||||
.El
|
||||
.Ss Cache, buffer, and command errors:
|
||||
.Ss Cache, buffer, and command errors :
|
||||
.Bl -diag
|
||||
.It failed to initialize command buffers
|
||||
.It no mem for command slots!
|
||||
|
@ -110,6 +110,7 @@ To enable/disable driver RSS support
|
||||
.It Va hw.lio.hwlro
|
||||
.Pp
|
||||
To enable/disable hardware LRO
|
||||
.El
|
||||
.Sh SUPPORT
|
||||
For general information and support,
|
||||
go to the Cavium support website at:
|
||||
|
@ -70,14 +70,15 @@ It's value is hard coded to 0 indicating flash.
|
||||
This variable reports whether the
|
||||
.Nm
|
||||
driver accepts unmapped I/O for this unit.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".Pa /dev/nda*" -compact
|
||||
.It Pa /dev/nda*
|
||||
NVMe storage device nodes
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr nvme 4 ,
|
||||
.Xr nvd 4
|
||||
.Xr nvd 4 ,
|
||||
.Xr nvme 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -387,6 +387,7 @@ route add default x.y.0.1
|
||||
msg igb0_NAT: setdlt 1
|
||||
msg igb0_NAT: setaliasaddr x.y.8.35
|
||||
SEQ
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr libalias 3 ,
|
||||
.Xr ng_ipfw 4 ,
|
||||
|
@ -70,6 +70,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ehci 4 ,
|
||||
.Xr uhci 4 ,
|
||||
|
@ -386,7 +386,7 @@ specified by the
|
||||
member, otherwise fail.
|
||||
.It PCIIO_BAR_MMAP_EXCL
|
||||
Must be used together with
|
||||
.Vd PCIIO_BAR_MMAP_FIXED
|
||||
.Dv PCIIO_BAR_MMAP_FIXED
|
||||
If the specified base contains already established mappings, the
|
||||
operation fails instead of implicitly unmapping them.
|
||||
.It PCIIO_BAR_MMAP_RW
|
||||
|
@ -176,7 +176,7 @@ and tested with
|
||||
.Xr getsockopt 2
|
||||
or
|
||||
.Xr sctp_opt_info 3 :
|
||||
.Bl -tag -indent
|
||||
.Bl -tag -width indent
|
||||
.It Dv SCTP_NODELAY
|
||||
Under most circumstances,
|
||||
.Tn SCTP
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 05, 2015
|
||||
.Dd September 5, 2015
|
||||
.Dt SES 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -399,11 +399,15 @@ The summation of num_inbound_tcp_pkts and num_outbound_tcp_pkts.
|
||||
.El
|
||||
.Bl -tag -offset indent -width Va
|
||||
.It Va num_inbound_skipped_pkts_malloc
|
||||
Number of inbound packets that were not processed because of failed malloc() calls.
|
||||
Number of inbound packets that were not processed because of failed
|
||||
.Fn malloc
|
||||
calls.
|
||||
.El
|
||||
.Bl -tag -offset indent -width Va
|
||||
.It Va num_outbound_skipped_pkts_malloc
|
||||
Number of outbound packets that were not processed because of failed malloc() calls.
|
||||
Number of outbound packets that were not processed because of failed
|
||||
.Fn malloc
|
||||
calls.
|
||||
.El
|
||||
.Bl -tag -offset indent -width Va
|
||||
.It Va num_inbound_skipped_pkts_mtx
|
||||
@ -759,8 +763,10 @@ Ideally,
|
||||
.Nm
|
||||
should intercept packets after they have been processed by the TCP layer i.e.
|
||||
intercept packets coming up the stack after they have been processed by
|
||||
tcp_input(), and intercept packets coming down the stack after they have been
|
||||
processed by tcp_output().
|
||||
.Fn tcp_input ,
|
||||
and intercept packets coming down the stack after they have been
|
||||
processed by
|
||||
.Fn tcp_output .
|
||||
The current code still gives satisfactory granularity though, as inbound events
|
||||
tend to trigger outbound events, allowing the cause-and-effect to be observed
|
||||
indirectly by capturing the state on outbound events as well.
|
||||
|
@ -23,7 +23,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $FreeBSD$ stable/10/share/man/man4/smartpqi.4 195614 2017-01-11 08:10:18Z jkim $
|
||||
.Dd April 06, 2018
|
||||
.Dd April 6, 2018
|
||||
.Dt SMARTPQI 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -37,6 +37,7 @@ kernel configuration file:
|
||||
.Cd device pci
|
||||
.Cd device scbus
|
||||
.Cd device smartpqi
|
||||
.Ed
|
||||
.Pp
|
||||
Alternatively, to load the driver as a
|
||||
module at boot time, place the following line in
|
||||
@ -81,10 +82,10 @@ smartpqi management interface
|
||||
.Xr kld 4 ,
|
||||
.Xr linux 4 ,
|
||||
.Xr scsi 4 ,
|
||||
.Xr kldload 8
|
||||
.Xr pass 4
|
||||
.Xr xpt 4
|
||||
.Xr loader.conf 5
|
||||
.Xr kldload 8 ,
|
||||
.Xr pass 4 ,
|
||||
.Xr xpt 4 ,
|
||||
.Xr loader.conf 5 ,
|
||||
.Xr camcontrol 8
|
||||
.Rs
|
||||
.%T "Microsemi Website"
|
||||
@ -95,7 +96,7 @@ The
|
||||
.Nm
|
||||
driver first appeared in
|
||||
.Fx 11.1 .
|
||||
.Sh AUTHOR
|
||||
.Sh AUTHORS
|
||||
.An Murthy Bhat
|
||||
.Aq murthy.bhat@microsemi.com
|
||||
.Sh BUGS
|
||||
|
@ -38,6 +38,7 @@
|
||||
.Cd "options SC_ALT_MOUSE_IMAGE"
|
||||
.Cd "options SC_CUT_SEPCHARS=_characters_"
|
||||
.Cd "options SC_CUT_SPACES2TABS"
|
||||
.Cd "options SC_DFLT_TERM"
|
||||
.Cd "options SC_DISABLE_KDBKEY"
|
||||
.Cd "options SC_DISABLE_REBOOT"
|
||||
.Cd "options SC_HISTORY_SIZE=N"
|
||||
@ -48,6 +49,9 @@
|
||||
.Cd "options SC_NO_PALETTE_LOADING"
|
||||
.Cd "options SC_NO_SUSPEND_VTYSWITCH"
|
||||
.Cd "options SC_NO_SYSMOUSE"
|
||||
.Cd "options SC_NO_TERM_DUMB"
|
||||
.Cd "options SC_NO_TERM_SC"
|
||||
.Cd "options SC_NO_TERM_SCTEKEN"
|
||||
.Cd "options SC_PIXEL_MODE"
|
||||
.Cd "options SC_TWOBUTTON_MOUSE"
|
||||
.Cd "options SC_NORM_ATTR=_attribute_"
|
||||
@ -285,6 +289,8 @@ This options instructs the driver to convert leading spaces into tabs
|
||||
when copying data into cut buffer.
|
||||
This might be useful to preserve
|
||||
indentation when copying tab-indented text.
|
||||
.It Dv SC_DFLT_TERM=_name_
|
||||
This option specifies the name of the preferred terminal emulator.
|
||||
.It Dv SC_DISABLE_KDBKEY
|
||||
This option disables the ``debug'' key combination (by default, it is
|
||||
.Dv Alt-Esc ,
|
||||
@ -409,6 +415,15 @@ will fail if this option is defined.
|
||||
This option implies the
|
||||
.Dv SC_NO_CUTPASTE
|
||||
option too.
|
||||
.It Dv SC_NO_TERM_DUMB
|
||||
.It Dv SC_NO_TERM_SC
|
||||
.It Dv SC_NO_TERM_SCTEKEN
|
||||
These options remove the
|
||||
.Qq dumb ,
|
||||
.Qq sc ,
|
||||
and
|
||||
.Qq scteken
|
||||
terminal emulators, respectively.
|
||||
.El
|
||||
.Ss Driver Flags
|
||||
The following driver flags can be used to control the
|
||||
|
@ -55,7 +55,6 @@ Make sure that
|
||||
.Xr moused 8
|
||||
is running, otherwise the user process will not see any data coming from
|
||||
the mouse.
|
||||
.Pp
|
||||
.Ss Operation Levels
|
||||
The
|
||||
.Nm
|
||||
|
@ -597,8 +597,7 @@ The default TCP function block (TCP stack).
|
||||
.It Va functions_inherit_listen_socket_stack
|
||||
Determines whether to inherit listen socket's tcp stack or use the current
|
||||
system default tcp stack, as defined by
|
||||
.Va functions_default
|
||||
.Pc .
|
||||
.Va functions_default .
|
||||
Default is true.
|
||||
.It Va insecure_rst
|
||||
Use criteria defined in RFC793 instead of RFC5961 for accepting RST segments.
|
||||
|
@ -76,7 +76,7 @@ This is normally done by the
|
||||
utility that is launched by
|
||||
.Xr devd 8
|
||||
when the device is inserted.
|
||||
.Xr uathload
|
||||
.Xr uathload 8
|
||||
includes the firmware in the binary program.
|
||||
This firmware is licensed for general use and is included in the base system.
|
||||
.Sh HARDWARE
|
||||
|
@ -81,6 +81,7 @@ driver will mark terminals as console devices when operating in device mode.
|
||||
Default is 1.
|
||||
.It Va hw.usb.ucom.pps_mode
|
||||
Enables and configure PPS capture mode as described below.
|
||||
.El
|
||||
.Sh Pulse Per Second (PPS) Timing Interface
|
||||
The
|
||||
.Nm
|
||||
|
@ -302,6 +302,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".Pa /dev/ugen Ns Ar N Ns Pa \&. Ns Ar E" -compact
|
||||
.It Pa /dev/ugen Ns Ar N Ns Pa \&. Ns Ar E
|
||||
|
@ -60,6 +60,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ehci 4 ,
|
||||
.Xr ohci 4 ,
|
||||
|
@ -155,6 +155,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".Pa /dev/uhid?"
|
||||
.It Pa /dev/uhid?
|
||||
|
@ -147,6 +147,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width ".Pa /dev/kbd*" -compact
|
||||
.It Pa /dev/kbd*
|
||||
|
@ -77,4 +77,7 @@ corresponding callout initial-state and lock-state devices
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
driver appeared in OpenBSD and was ported to FreeBSD.
|
||||
driver appeared in
|
||||
.Ox
|
||||
and was ported to
|
||||
.Fx .
|
||||
|
@ -75,6 +75,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /dev/ums0 -compact
|
||||
.It Pa /dev/ums0
|
||||
|
@ -191,6 +191,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width "/dev/ttyU*.init" -compact
|
||||
.It Pa /dev/ttyU*
|
||||
|
@ -142,6 +142,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
The
|
||||
.Tn USB
|
||||
@ -173,7 +174,7 @@ specifications can be found at:
|
||||
.Xr uvscom 4 ,
|
||||
.Xr xhci 4
|
||||
.Xr usbconfig 8 ,
|
||||
.Xr usbdi 9 ,
|
||||
.Xr usbdi 9
|
||||
.Sh STANDARDS
|
||||
The
|
||||
.Nm
|
||||
|
@ -90,6 +90,7 @@ for callout ports
|
||||
.It Pa /dev/cuaU*.init
|
||||
.It Pa /dev/cuaU*.lock
|
||||
corresponding callout initial-state and lock-state devices
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr tty 4 ,
|
||||
.Xr ucom 4 ,
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\" $FreeBSD$
|
||||
.\" $Id: $
|
||||
.\"
|
||||
.Dd Jan 9, 2019
|
||||
.Dd January 9, 2019
|
||||
.Dt VALE 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -59,6 +59,7 @@ virtual machine itself.
|
||||
.Rs
|
||||
.%T "VMware vSockets Documentation"
|
||||
.%U https://www.vmware.com/support/developer/vmci-sdk/
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
|
@ -31,7 +31,6 @@
|
||||
.Nm vmm.ko
|
||||
.Nd "bhyve virtual machine monitor"
|
||||
.Sh SYNOPSIS
|
||||
.Pp
|
||||
To load the driver as a module at boot, add this line to
|
||||
.Xr loader.conf 5 :
|
||||
.Bd -literal -offset indent
|
||||
@ -47,7 +46,7 @@ kldload vmm
|
||||
.Nm
|
||||
provides the kernel portion of the
|
||||
.Xr bhyve 4
|
||||
hypervisor.
|
||||
hypervisor.
|
||||
.Pp
|
||||
An Intel CPU with VT-x/EPT or AMD CPU with SVM support is required.
|
||||
.Pp
|
||||
|
@ -316,7 +316,7 @@ command.
|
||||
.Xr wlan_xauth 4 ,
|
||||
.Xr hostapd 8 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr wpa_supplicant 8 .
|
||||
.Xr wpa_supplicant 8
|
||||
.Rs
|
||||
.%T HCF Light programming specification
|
||||
.%U http://web.archive.org/web/20040130141721/http://wavelan.com/
|
||||
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd October 24 2018
|
||||
.Dd October 24, 2018
|
||||
.Dt XE 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -67,6 +67,7 @@ tunables:
|
||||
Debug output level, where 0 is debugging disabled and larger values increase
|
||||
debug message verbosity.
|
||||
Default is 0.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr ehci 4 ,
|
||||
.Xr ohci 4 ,
|
||||
|
@ -203,7 +203,7 @@ macro is usually not necessary.
|
||||
.It
|
||||
Use
|
||||
.Sy \&Va
|
||||
instead of:
|
||||
instead of
|
||||
.Sy \&Dv
|
||||
for
|
||||
.Xr sysctl 8
|
||||
|
@ -25,11 +25,14 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd June 1, 2018
|
||||
.Dd February 25, 2019
|
||||
.Dt SYSCTL 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm SYSCTL_DECL ,
|
||||
.Nm SYSCTL_ADD_BOOL ,
|
||||
.Nm SYSCTL_ADD_COUNTER_U64 ,
|
||||
.Nm SYSCTL_ADD_COUNTER_U64_ARRAY ,
|
||||
.Nm SYSCTL_ADD_INT ,
|
||||
.Nm SYSCTL_ADD_LONG ,
|
||||
.Nm SYSCTL_ADD_NODE ,
|
||||
@ -42,6 +45,8 @@
|
||||
.Nm SYSCTL_ADD_S16 ,
|
||||
.Nm SYSCTL_ADD_S32 ,
|
||||
.Nm SYSCTL_ADD_S64 ,
|
||||
.Nm SYSCTL_ADD_SBINTIME_MSEC ,
|
||||
.Nm SYSCTL_ADD_SBINTIME_USEC ,
|
||||
.Nm SYSCTL_ADD_STRING ,
|
||||
.Nm SYSCTL_ADD_STRUCT ,
|
||||
.Nm SYSCTL_ADD_U8 ,
|
||||
@ -52,10 +57,15 @@
|
||||
.Nm SYSCTL_ADD_UINT ,
|
||||
.Nm SYSCTL_ADD_ULONG ,
|
||||
.Nm SYSCTL_ADD_UQUAD ,
|
||||
.Nm SYSCTL_ADD_UMA_CUR ,
|
||||
.Nm SYSCTL_ADD_UMA_MAX ,
|
||||
.Nm SYSCTL_CHILDREN ,
|
||||
.Nm SYSCTL_STATIC_CHILDREN ,
|
||||
.Nm SYSCTL_NODE_CHILDREN ,
|
||||
.Nm SYSCTL_PARENT ,
|
||||
.Nm SYSCTL_BOOL ,
|
||||
.Nm SYSCTL_COUNTER_U64 ,
|
||||
.Nm SYSCTL_COUNTER_U64_ARRAY ,
|
||||
.Nm SYSCTL_INT ,
|
||||
.Nm SYSCTL_INT_WITH_LABEL ,
|
||||
.Nm SYSCTL_LONG ,
|
||||
@ -69,6 +79,8 @@
|
||||
.Nm SYSCTL_S16 ,
|
||||
.Nm SYSCTL_S32 ,
|
||||
.Nm SYSCTL_S64 ,
|
||||
.Nm SYSCTL_SBINTIME_MSEC ,
|
||||
.Nm SYSCTL_SBINTIME_USEC ,
|
||||
.Nm SYSCTL_STRING ,
|
||||
.Nm SYSCTL_STRUCT ,
|
||||
.Nm SYSCTL_U8 ,
|
||||
@ -77,13 +89,47 @@
|
||||
.Nm SYSCTL_U64 ,
|
||||
.Nm SYSCTL_UINT ,
|
||||
.Nm SYSCTL_ULONG ,
|
||||
.Nm SYSCTL_UQUAD
|
||||
.Nm SYSCTL_UQUAD ,
|
||||
.Nm SYSCTL_UMA_CUR ,
|
||||
.Nm SYSCTL_UMA_MAX
|
||||
.Nd Dynamic and static sysctl MIB creation functions
|
||||
.Sh SYNOPSIS
|
||||
.In sys/param.h
|
||||
.In sys/sysctl.h
|
||||
.Fn SYSCTL_DECL name
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_BOOL
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "bool *ptr"
|
||||
.Fa "uint8_t val"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_COUNTER_U64
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "counter_u64_t *ptr"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_COUNTER_U64_ARRAY
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "counter_u64_t *ptr"
|
||||
.Fa "intmax_t len"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_INT
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
@ -214,6 +260,26 @@
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_SBINTIME_MSEC
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "sbintime_t *ptr"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_SBINTIME_USEC
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "sbintime_t *ptr"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_STRING
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
@ -311,6 +377,27 @@
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_UMA_CUR
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "uma_zone_t ptr"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_UMA_MAX
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
.Fa "int number"
|
||||
.Fa "const char *name"
|
||||
.Fa "int ctlflags"
|
||||
.Fa "uma_zone_t ptr"
|
||||
.Fa "const char *descr"
|
||||
.Fc
|
||||
.Fa "const char *descr"
|
||||
.Ft struct sysctl_oid *
|
||||
.Fo SYSCTL_ADD_UAUTO
|
||||
.Fa "struct sysctl_ctx_list *ctx"
|
||||
.Fa "struct sysctl_oid_list *parent"
|
||||
@ -337,6 +424,9 @@
|
||||
.Fo SYSCTL_PARENT
|
||||
.Fa "struct sysctl_oid *oid"
|
||||
.Fc
|
||||
.Fn SYSCTL_BOOL parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_COUNTER_U64 parent number name ctlflags ptr descr
|
||||
.Fn SYSCTL_COUNTER_U64_ARRAY parent number name ctlflags ptr len descr
|
||||
.Fn SYSCTL_INT parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_INT_WITH_LABEL parent number name ctlflags ptr val descr label
|
||||
.Fn SYSCTL_LONG parent number name ctlflags ptr val descr
|
||||
@ -350,6 +440,8 @@
|
||||
.Fn SYSCTL_S16 parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_S32 parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_S64 parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_SBINTIME_MSEC parent number name ctlflags ptr descr
|
||||
.Fn SYSCTL_SBINTIME_USEC parent number name ctlflags ptr descr
|
||||
.Fn SYSCTL_STRING parent number name ctlflags arg len descr
|
||||
.Fn SYSCTL_STRUCT parent number name ctlflags ptr struct_type descr
|
||||
.Fn SYSCTL_U8 parent number name ctlflags ptr val descr
|
||||
@ -359,6 +451,8 @@
|
||||
.Fn SYSCTL_UINT parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_ULONG parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_UQUAD parent number name ctlflags ptr val descr
|
||||
.Fn SYSCTL_UMA_MAX parent number name ctlflags ptr descr
|
||||
.Fn SYSCTL_UMA_CUR parent number name ctlflags ptr descr
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm SYSCTL
|
||||
@ -416,6 +510,7 @@ argument.
|
||||
For string type OIDs a length of zero means that
|
||||
.Xr strlen 3
|
||||
will be used to get the length of the string at each access to the OID.
|
||||
For array type OIDs the length must be greater than zero.
|
||||
.It Fa ptr
|
||||
Pointer to sysctl variable or string data.
|
||||
For sysctl values the pointer can be SYSCTL_NULL_XXX_PTR which means the OID is read-only and the returned value should be taken from the
|
||||
@ -544,6 +639,9 @@ This OID type is especially useful if the kernel data is not easily
|
||||
accessible, or needs to be processed before exporting.
|
||||
.Sh CREATING A STATIC SYSCTL
|
||||
Static sysctls are declared using one of the
|
||||
.Fn SYSCTL_BOOL ,
|
||||
.Fn SYSCTL_COUNTER_U64 ,
|
||||
.Fn SYSCTL_COUNTER_U64_ARRAY ,
|
||||
.Fn SYSCTL_INT ,
|
||||
.Fn SYSCTL_INT_WITH_LABEL ,
|
||||
.Fn SYSCTL_LONG ,
|
||||
@ -557,6 +655,8 @@ Static sysctls are declared using one of the
|
||||
.Fn SYSCTL_S16 ,
|
||||
.Fn SYSCTL_S32 ,
|
||||
.Fn SYSCTL_S64 ,
|
||||
.Fn SYSCTL_SBINTIME_MSEC ,
|
||||
.Fn SYSCTL_SBINTIME_USEC ,
|
||||
.Fn SYSCTL_STRING ,
|
||||
.Fn SYSCTL_STRUCT ,
|
||||
.Fn SYSCTL_U8 ,
|
||||
@ -564,12 +664,17 @@ Static sysctls are declared using one of the
|
||||
.Fn SYSCTL_U32 ,
|
||||
.Fn SYSCTL_U64 ,
|
||||
.Fn SYSCTL_UINT ,
|
||||
.Fn SYSCTL_ULONG
|
||||
.Fn SYSCTL_ULONG ,
|
||||
.Fn SYSCTL_UQUAD ,
|
||||
.Fn SYSCTL_UMA_CUR
|
||||
or
|
||||
.Fn SYSCTL_UQUAD
|
||||
.Fn SYSCTL_UMA_MAX
|
||||
macros.
|
||||
.Sh CREATING A DYNAMIC SYSCTL
|
||||
Dynamic nodes are created using one of the
|
||||
.Fn SYSCTL_ADD_BOOL ,
|
||||
.Fn SYSCTL_ADD_COUNTER_U64 ,
|
||||
.Fn SYSCTL_ADD_COUNTER_U64_ARRAY ,
|
||||
.Fn SYSCTL_ADD_INT ,
|
||||
.Fn SYSCTL_ADD_LONG ,
|
||||
.Fn SYSCTL_ADD_NODE ,
|
||||
@ -582,6 +687,8 @@ Dynamic nodes are created using one of the
|
||||
.Fn SYSCTL_ADD_S16 ,
|
||||
.Fn SYSCTL_ADD_S32 ,
|
||||
.Fn SYSCTL_ADD_S64 ,
|
||||
.Fn SYSCTL_ADD_SBINTIME_MSEC ,
|
||||
.Fn SYSCTL_ADD_SBINTIME_USEC ,
|
||||
.Fn SYSCTL_ADD_STRING ,
|
||||
.Fn SYSCTL_ADD_STRUCT ,
|
||||
.Fn SYSCTL_ADD_U8 ,
|
||||
@ -591,8 +698,10 @@ Dynamic nodes are created using one of the
|
||||
.Fn SYSCTL_ADD_UAUTO ,
|
||||
.Fn SYSCTL_ADD_UINT ,
|
||||
.Fn SYSCTL_ADD_ULONG ,
|
||||
.Fn SYSCTL_ADD_UQUAD ,
|
||||
.Fn SYSCTL_ADD_UMA_CUR
|
||||
or
|
||||
.Fn SYSCTL_UQUAD
|
||||
.Fn SYSCTL_ADD_UMA_MAX
|
||||
functions.
|
||||
See
|
||||
.Xr sysctl_remove_oid 9
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <fs/cd9660/iso.h>
|
||||
#include <fs/cd9660/cd9660_rrip.h>
|
||||
@ -227,8 +228,8 @@ static int
|
||||
dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||
int use_rrip, int lenskip)
|
||||
{
|
||||
size_t len;
|
||||
char *cp;
|
||||
size_t len, plen;
|
||||
char *cp, *sep;
|
||||
int i, icase;
|
||||
|
||||
if (use_rrip)
|
||||
@ -242,7 +243,14 @@ dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||
} else
|
||||
icase = 0;
|
||||
|
||||
if (strlen(path) != len)
|
||||
sep = strchr(path, '/');
|
||||
if (sep != NULL) {
|
||||
plen = sep - path;
|
||||
} else {
|
||||
plen = strlen(path);
|
||||
}
|
||||
|
||||
if (plen != len)
|
||||
return (0);
|
||||
|
||||
for (i = len; --i >= 0; path++, cp++) {
|
||||
@ -283,6 +291,7 @@ cd9660_open(const char *path, struct open_file *f)
|
||||
struct iso_directory_record rec;
|
||||
struct iso_directory_record *dp = NULL;
|
||||
int rc, first, use_rrip, lenskip;
|
||||
bool isdir = false;
|
||||
|
||||
/* First find the volume descriptor */
|
||||
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
|
||||
@ -372,7 +381,24 @@ cd9660_open(const char *path, struct open_file *f)
|
||||
rec = *dp;
|
||||
while (*path && *path != '/') /* look for next component */
|
||||
path++;
|
||||
if (*path) path++; /* skip '/' */
|
||||
|
||||
if (*path) /* this component was directory */
|
||||
isdir = true;
|
||||
|
||||
while (*path == '/')
|
||||
path++; /* skip '/' */
|
||||
|
||||
if (*path) /* We do have next component. */
|
||||
isdir = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the path had trailing / but the path does point to file,
|
||||
* report the error ENOTDIR.
|
||||
*/
|
||||
if (isdir == true && (isonum_711(rec.flags) & 2) == 0) {
|
||||
rc = ENOTDIR;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* allocate file system specific data structure */
|
||||
|
@ -226,16 +226,23 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
p = get_device_type(devstr, type);
|
||||
|
||||
/*
|
||||
* If type is DEV_TYP_STOR we have a disk-like device. If we can parse
|
||||
* the remainder of the string as a standard unit+slice+partition (e.g.,
|
||||
* 0s2a or 1p12), return those results. Otherwise we'll fall through to
|
||||
* the code that parses the legacy format.
|
||||
* If type is DEV_TYP_STOR we have a disk-like device. If the remainder
|
||||
* of the string contains spaces, dots, or a colon in any location other
|
||||
* than the last char, it's legacy format. Otherwise it might be
|
||||
* standard loader(8) format (e.g., disk0s2a or mmc1p12), so try to
|
||||
* parse the remainder of the string as such, and if it works, return
|
||||
* those results. Otherwise we'll fall through to the code that parses
|
||||
* the legacy format.
|
||||
*/
|
||||
if ((*type & DEV_TYP_STOR) && disk_parsedev(&dev, p, NULL) == 0) {
|
||||
*unit = dev.dd.d_unit;
|
||||
*slice = dev.d_slice;
|
||||
*partition = dev.d_partition;
|
||||
return;
|
||||
if (*type & DEV_TYP_STOR) {
|
||||
size_t len = strlen(p);
|
||||
if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 &&
|
||||
disk_parsedev(&dev, p, NULL) == 0) {
|
||||
*unit = dev.dd.d_unit;
|
||||
*slice = dev.d_slice;
|
||||
*partition = dev.d_partition;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore optional spaces after the device name. */
|
||||
|
@ -233,6 +233,9 @@ initializecpu(void)
|
||||
if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE)
|
||||
cr4 |= CR4_FSGSBASE;
|
||||
|
||||
if (cpu_stdext_feature2 & CPUID_STDEXT2_PKU)
|
||||
cr4 |= CR4_PKE;
|
||||
|
||||
/*
|
||||
* Postpone enabling the SMEP on the boot CPU until the page
|
||||
* tables are switched from the boot loader identity mapping
|
||||
|
@ -48,7 +48,7 @@
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 2003 Networks Associates Technology, Inc.
|
||||
* Copyright (c) 2014-2018 The FreeBSD Foundation
|
||||
* Copyright (c) 2014-2019 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by Jake Burkholder,
|
||||
@ -121,6 +121,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/mman.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/rangeset.h>
|
||||
#include <sys/rwlock.h>
|
||||
#include <sys/sx.h>
|
||||
#include <sys/turnstile.h>
|
||||
@ -155,6 +156,7 @@ __FBSDID("$FreeBSD$");
|
||||
#ifdef SMP
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
#include <machine/sysarch.h>
|
||||
#include <machine/tss.h>
|
||||
|
||||
static __inline boolean_t
|
||||
@ -285,6 +287,13 @@ pmap_modified_bit(pmap_t pmap)
|
||||
return (mask);
|
||||
}
|
||||
|
||||
static __inline pt_entry_t
|
||||
pmap_pku_mask_bit(pmap_t pmap)
|
||||
{
|
||||
|
||||
return (pmap->pm_type == PT_X86 ? X86_PG_PKU_MASK : 0);
|
||||
}
|
||||
|
||||
#if !defined(DIAGNOSTIC)
|
||||
#ifdef __GNUC_GNU_INLINE__
|
||||
#define PMAP_INLINE __attribute__((__gnu_inline__)) inline
|
||||
@ -424,6 +433,22 @@ static pml4_entry_t *pti_pml4;
|
||||
static vm_pindex_t pti_pg_idx;
|
||||
static bool pti_finalized;
|
||||
|
||||
struct pmap_pkru_range {
|
||||
struct rs_el pkru_rs_el;
|
||||
u_int pkru_keyidx;
|
||||
int pkru_flags;
|
||||
};
|
||||
|
||||
static uma_zone_t pmap_pkru_ranges_zone;
|
||||
static bool pmap_pkru_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
static pt_entry_t pmap_pkru_get(pmap_t pmap, vm_offset_t va);
|
||||
static void pmap_pkru_on_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
static void *pkru_dup_range(void *ctx, void *data);
|
||||
static void pkru_free_range(void *ctx, void *node);
|
||||
static int pmap_pkru_copy(pmap_t dst_pmap, pmap_t src_pmap);
|
||||
static int pmap_pkru_deassign(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
static void pmap_pkru_deassign_all(pmap_t pmap);
|
||||
|
||||
static int
|
||||
pmap_pcid_save_cnt_proc(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
@ -2846,6 +2871,12 @@ pmap_pinit0(pmap_t pmap)
|
||||
pmap->pm_pcids[i].pm_gen = 1;
|
||||
}
|
||||
pmap_activate_boot(pmap);
|
||||
|
||||
if ((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0) {
|
||||
pmap_pkru_ranges_zone = uma_zcreate("pkru ranges",
|
||||
sizeof(struct pmap_pkru_range), NULL, NULL, NULL, NULL,
|
||||
UMA_ALIGN_PTR, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2934,6 +2965,10 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
|
||||
pmap_pinit_pml4_pti(pml4pgu);
|
||||
pmap->pm_ucr3 = VM_PAGE_TO_PHYS(pml4pgu);
|
||||
}
|
||||
if ((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0) {
|
||||
rangeset_init(&pmap->pm_pkru, pkru_dup_range,
|
||||
pkru_free_range, pmap, M_NOWAIT);
|
||||
}
|
||||
}
|
||||
|
||||
pmap->pm_root.rt_root = 0;
|
||||
@ -3230,6 +3265,9 @@ pmap_release(pmap_t pmap)
|
||||
vm_page_unwire_noq(m);
|
||||
vm_page_free(m);
|
||||
}
|
||||
if (pmap->pm_type == PT_X86 &&
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0)
|
||||
rangeset_fini(&pmap->pm_pkru);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4060,7 +4098,7 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
{
|
||||
pd_entry_t newpde, oldpde;
|
||||
pt_entry_t *firstpte, newpte;
|
||||
pt_entry_t PG_A, PG_G, PG_M, PG_RW, PG_V;
|
||||
pt_entry_t PG_A, PG_G, PG_M, PG_PKU_MASK, PG_RW, PG_V;
|
||||
vm_paddr_t mptepa;
|
||||
vm_page_t mpte;
|
||||
struct spglist free;
|
||||
@ -4073,6 +4111,7 @@ pmap_demote_pde_locked(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
PG_RW = pmap_rw_bit(pmap);
|
||||
PG_V = pmap_valid_bit(pmap);
|
||||
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
||||
PG_PKU_MASK = pmap_pku_mask_bit(pmap);
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
oldpde = *pde;
|
||||
@ -4505,6 +4544,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
out:
|
||||
if (anyvalid)
|
||||
pmap_invalidate_all(pmap);
|
||||
pmap_pkru_on_remove(pmap, sva, eva);
|
||||
PMAP_UNLOCK(pmap);
|
||||
pmap_delayed_invl_finished();
|
||||
vm_page_free_pages_toq(&free, true);
|
||||
@ -4816,7 +4856,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
{
|
||||
pd_entry_t newpde;
|
||||
pt_entry_t *firstpte, oldpte, pa, *pte;
|
||||
pt_entry_t PG_G, PG_A, PG_M, PG_RW, PG_V;
|
||||
pt_entry_t PG_G, PG_A, PG_M, PG_RW, PG_V, PG_PKU_MASK;
|
||||
vm_page_t mpte;
|
||||
int PG_PTE_CACHE;
|
||||
|
||||
@ -4825,6 +4865,7 @@ pmap_promote_pde(pmap_t pmap, pd_entry_t *pde, vm_offset_t va,
|
||||
PG_M = pmap_modified_bit(pmap);
|
||||
PG_V = pmap_valid_bit(pmap);
|
||||
PG_RW = pmap_rw_bit(pmap);
|
||||
PG_PKU_MASK = pmap_pku_mask_bit(pmap);
|
||||
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
@ -5052,6 +5093,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
|
||||
|
||||
origpte = *pte;
|
||||
pv = NULL;
|
||||
if (va < VM_MAXUSER_ADDRESS && pmap->pm_type == PT_X86)
|
||||
newpte |= pmap_pkru_get(pmap, va);
|
||||
|
||||
/*
|
||||
* Is the specified virtual address already mapped?
|
||||
@ -5271,6 +5314,25 @@ pmap_enter_pde(pmap_t pmap, vm_offset_t va, pd_entry_t newpde, u_int flags,
|
||||
" in pmap %p", va, pmap);
|
||||
return (KERN_RESOURCE_SHORTAGE);
|
||||
}
|
||||
|
||||
/*
|
||||
* If pkru is not same for the whole pde range, return failure
|
||||
* and let vm_fault() cope. Check after pde allocation, since
|
||||
* it could sleep.
|
||||
*/
|
||||
if (!pmap_pkru_same(pmap, va, va + NBPDR)) {
|
||||
SLIST_INIT(&free);
|
||||
if (pmap_unwire_ptp(pmap, va, pdpg, &free)) {
|
||||
pmap_invalidate_page(pmap, va);
|
||||
vm_page_free_pages_toq(&free, true);
|
||||
}
|
||||
return (KERN_FAILURE);
|
||||
}
|
||||
if (va < VM_MAXUSER_ADDRESS && pmap->pm_type == PT_X86) {
|
||||
newpde &= ~X86_PG_PKU_MASK;
|
||||
newpde |= pmap_pkru_get(pmap, va);
|
||||
}
|
||||
|
||||
pde = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pdpg));
|
||||
pde = &pde[pmap_pde_index(va)];
|
||||
oldpde = *pde;
|
||||
@ -5530,7 +5592,7 @@ pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m,
|
||||
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||
newpte |= pg_nx;
|
||||
if (va < VM_MAXUSER_ADDRESS)
|
||||
newpte |= PG_U;
|
||||
newpte |= PG_U | pmap_pkru_get(pmap, va);
|
||||
pte_store(pte, newpte);
|
||||
return (mpte);
|
||||
}
|
||||
@ -5906,6 +5968,36 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
PMAP_UNLOCK(dst_pmap);
|
||||
}
|
||||
|
||||
int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap, pmap_t src_pmap)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (dst_pmap->pm_type != src_pmap->pm_type ||
|
||||
dst_pmap->pm_type != PT_X86 ||
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0)
|
||||
return (0);
|
||||
for (;;) {
|
||||
if (dst_pmap < src_pmap) {
|
||||
PMAP_LOCK(dst_pmap);
|
||||
PMAP_LOCK(src_pmap);
|
||||
} else {
|
||||
PMAP_LOCK(src_pmap);
|
||||
PMAP_LOCK(dst_pmap);
|
||||
}
|
||||
error = pmap_pkru_copy(dst_pmap, src_pmap);
|
||||
/* Clean up partial copy on failure due to no memory. */
|
||||
if (error == ENOMEM)
|
||||
pmap_pkru_deassign_all(dst_pmap);
|
||||
PMAP_UNLOCK(src_pmap);
|
||||
PMAP_UNLOCK(dst_pmap);
|
||||
if (error != ENOMEM)
|
||||
break;
|
||||
vm_wait(NULL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero the specified hardware page.
|
||||
*/
|
||||
@ -6305,6 +6397,7 @@ pmap_remove_pages(pmap_t pmap)
|
||||
if (lock != NULL)
|
||||
rw_wunlock(lock);
|
||||
pmap_invalidate_all(pmap);
|
||||
pmap_pkru_deassign_all(pmap);
|
||||
PMAP_UNLOCK(pmap);
|
||||
vm_page_free_pages_toq(&free, true);
|
||||
}
|
||||
@ -8941,6 +9034,285 @@ pmap_pti_remove_kva(vm_offset_t sva, vm_offset_t eva)
|
||||
VM_OBJECT_WUNLOCK(pti_obj);
|
||||
}
|
||||
|
||||
static void *
|
||||
pkru_dup_range(void *ctx __unused, void *data)
|
||||
{
|
||||
struct pmap_pkru_range *node, *new_node;
|
||||
|
||||
new_node = uma_zalloc(pmap_pkru_ranges_zone, M_NOWAIT);
|
||||
if (new_node == NULL)
|
||||
return (NULL);
|
||||
node = data;
|
||||
memcpy(new_node, node, sizeof(*node));
|
||||
return (new_node);
|
||||
}
|
||||
|
||||
static void
|
||||
pkru_free_range(void *ctx __unused, void *node)
|
||||
{
|
||||
|
||||
uma_zfree(pmap_pkru_ranges_zone, node);
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_assign(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, u_int keyidx,
|
||||
int flags)
|
||||
{
|
||||
struct pmap_pkru_range *ppr;
|
||||
int error;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
MPASS(pmap->pm_type == PT_X86);
|
||||
MPASS((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0);
|
||||
if ((flags & AMD64_PKRU_EXCL) != 0 &&
|
||||
!rangeset_check_empty(&pmap->pm_pkru, sva, eva))
|
||||
return (EBUSY);
|
||||
ppr = uma_zalloc(pmap_pkru_ranges_zone, M_NOWAIT);
|
||||
if (ppr == NULL)
|
||||
return (ENOMEM);
|
||||
ppr->pkru_keyidx = keyidx;
|
||||
ppr->pkru_flags = flags & AMD64_PKRU_PERSIST;
|
||||
error = rangeset_insert(&pmap->pm_pkru, sva, eva, ppr);
|
||||
if (error != 0)
|
||||
uma_zfree(pmap_pkru_ranges_zone, ppr);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_deassign(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
MPASS(pmap->pm_type == PT_X86);
|
||||
MPASS((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0);
|
||||
return (rangeset_remove(&pmap->pm_pkru, sva, eva));
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_pkru_deassign_all(pmap_t pmap)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type == PT_X86 &&
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0)
|
||||
rangeset_remove_all(&pmap->pm_pkru);
|
||||
}
|
||||
|
||||
static bool
|
||||
pmap_pkru_same(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
struct pmap_pkru_range *ppr, *prev_ppr;
|
||||
vm_offset_t va;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type != PT_X86 ||
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0 ||
|
||||
sva >= VM_MAXUSER_ADDRESS)
|
||||
return (true);
|
||||
MPASS(eva <= VM_MAXUSER_ADDRESS);
|
||||
for (va = sva, prev_ppr = NULL; va < eva;) {
|
||||
ppr = rangeset_lookup(&pmap->pm_pkru, va);
|
||||
if ((ppr == NULL) ^ (prev_ppr == NULL))
|
||||
return (false);
|
||||
if (ppr == NULL) {
|
||||
va += PAGE_SIZE;
|
||||
continue;
|
||||
}
|
||||
if (prev_ppr->pkru_keyidx != ppr->pkru_keyidx)
|
||||
return (false);
|
||||
va = ppr->pkru_rs_el.re_end;
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
static pt_entry_t
|
||||
pmap_pkru_get(pmap_t pmap, vm_offset_t va)
|
||||
{
|
||||
struct pmap_pkru_range *ppr;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type != PT_X86 ||
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0 ||
|
||||
va >= VM_MAXUSER_ADDRESS)
|
||||
return (0);
|
||||
ppr = rangeset_lookup(&pmap->pm_pkru, va);
|
||||
if (ppr != NULL)
|
||||
return (X86_PG_PKU(ppr->pkru_keyidx));
|
||||
return (0);
|
||||
}
|
||||
|
||||
static bool
|
||||
pred_pkru_on_remove(void *ctx __unused, void *r)
|
||||
{
|
||||
struct pmap_pkru_range *ppr;
|
||||
|
||||
ppr = r;
|
||||
return ((ppr->pkru_flags & AMD64_PKRU_PERSIST) == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_pkru_on_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
if (pmap->pm_type == PT_X86 &&
|
||||
(cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0) {
|
||||
rangeset_remove_pred(&pmap->pm_pkru, sva, eva,
|
||||
pred_pkru_on_remove);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_copy(pmap_t dst_pmap, pmap_t src_pmap)
|
||||
{
|
||||
|
||||
PMAP_LOCK_ASSERT(dst_pmap, MA_OWNED);
|
||||
PMAP_LOCK_ASSERT(src_pmap, MA_OWNED);
|
||||
MPASS(dst_pmap->pm_type == PT_X86);
|
||||
MPASS(src_pmap->pm_type == PT_X86);
|
||||
MPASS((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) != 0);
|
||||
if (src_pmap->pm_pkru.rs_data_ctx == NULL)
|
||||
return (0);
|
||||
return (rangeset_copy(&dst_pmap->pm_pkru, &src_pmap->pm_pkru));
|
||||
}
|
||||
|
||||
static void
|
||||
pmap_pkru_update_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
|
||||
u_int keyidx)
|
||||
{
|
||||
pml4_entry_t *pml4e;
|
||||
pdp_entry_t *pdpe;
|
||||
pd_entry_t newpde, ptpaddr, *pde;
|
||||
pt_entry_t newpte, *ptep, pte;
|
||||
vm_offset_t va, va_next;
|
||||
bool changed;
|
||||
|
||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||
MPASS(pmap->pm_type == PT_X86);
|
||||
MPASS(keyidx <= PMAP_MAX_PKRU_IDX);
|
||||
|
||||
for (changed = false, va = sva; va < eva; va = va_next) {
|
||||
pml4e = pmap_pml4e(pmap, va);
|
||||
if ((*pml4e & X86_PG_V) == 0) {
|
||||
va_next = (va + NBPML4) & ~PML4MASK;
|
||||
if (va_next < va)
|
||||
va_next = eva;
|
||||
continue;
|
||||
}
|
||||
|
||||
pdpe = pmap_pml4e_to_pdpe(pml4e, va);
|
||||
if ((*pdpe & X86_PG_V) == 0) {
|
||||
va_next = (va + NBPDP) & ~PDPMASK;
|
||||
if (va_next < va)
|
||||
va_next = eva;
|
||||
continue;
|
||||
}
|
||||
|
||||
va_next = (va + NBPDR) & ~PDRMASK;
|
||||
if (va_next < va)
|
||||
va_next = eva;
|
||||
|
||||
pde = pmap_pdpe_to_pde(pdpe, va);
|
||||
ptpaddr = *pde;
|
||||
if (ptpaddr == 0)
|
||||
continue;
|
||||
|
||||
MPASS((ptpaddr & X86_PG_V) != 0);
|
||||
if ((ptpaddr & PG_PS) != 0) {
|
||||
if (va + NBPDR == va_next && eva >= va_next) {
|
||||
newpde = (ptpaddr & ~X86_PG_PKU_MASK) |
|
||||
X86_PG_PKU(keyidx);
|
||||
if (newpde != ptpaddr) {
|
||||
*pde = newpde;
|
||||
changed = true;
|
||||
}
|
||||
continue;
|
||||
} else if (!pmap_demote_pde(pmap, pde, va)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (va_next > eva)
|
||||
va_next = eva;
|
||||
|
||||
for (ptep = pmap_pde_to_pte(pde, va); va != va_next;
|
||||
ptep++, va += PAGE_SIZE) {
|
||||
pte = *ptep;
|
||||
if ((pte & X86_PG_V) == 0)
|
||||
continue;
|
||||
newpte = (pte & ~X86_PG_PKU_MASK) | X86_PG_PKU(keyidx);
|
||||
if (newpte != pte) {
|
||||
*ptep = newpte;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
pmap_invalidate_range(pmap, sva, eva);
|
||||
}
|
||||
|
||||
static int
|
||||
pmap_pkru_check_uargs(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
|
||||
u_int keyidx, int flags)
|
||||
{
|
||||
|
||||
if (pmap->pm_type != PT_X86 || keyidx > PMAP_MAX_PKRU_IDX ||
|
||||
(flags & ~(AMD64_PKRU_PERSIST | AMD64_PKRU_EXCL)) != 0)
|
||||
return (EINVAL);
|
||||
if (eva <= sva || eva > VM_MAXUSER_ADDRESS)
|
||||
return (EFAULT);
|
||||
if ((cpu_stdext_feature2 & CPUID_STDEXT2_PKU) == 0)
|
||||
return (ENOTSUP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
pmap_pkru_set(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, u_int keyidx,
|
||||
int flags)
|
||||
{
|
||||
int error;
|
||||
|
||||
sva = trunc_page(sva);
|
||||
eva = round_page(eva);
|
||||
error = pmap_pkru_check_uargs(pmap, sva, eva, keyidx, flags);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
for (;;) {
|
||||
PMAP_LOCK(pmap);
|
||||
error = pmap_pkru_assign(pmap, sva, eva, keyidx, flags);
|
||||
if (error == 0)
|
||||
pmap_pkru_update_range(pmap, sva, eva, keyidx);
|
||||
PMAP_UNLOCK(pmap);
|
||||
if (error != ENOMEM)
|
||||
break;
|
||||
vm_wait(NULL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
pmap_pkru_clear(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
||||
{
|
||||
int error;
|
||||
|
||||
sva = trunc_page(sva);
|
||||
eva = round_page(eva);
|
||||
error = pmap_pkru_check_uargs(pmap, sva, eva, 0, 0);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
for (;;) {
|
||||
PMAP_LOCK(pmap);
|
||||
error = pmap_pkru_deassign(pmap, sva, eva);
|
||||
if (error == 0)
|
||||
pmap_pkru_update_range(pmap, sva, eva, 0);
|
||||
PMAP_UNLOCK(pmap);
|
||||
if (error != ENOMEM)
|
||||
break;
|
||||
vm_wait(NULL);
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
|
||||
#include "opt_ddb.h"
|
||||
#ifdef DDB
|
||||
#include <sys/kdb.h>
|
||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/priv.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/smp.h>
|
||||
@ -53,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <vm/vm_kern.h> /* for kernel_map */
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
@ -170,13 +172,16 @@ update_gdt_fsbase(struct thread *td, uint32_t base)
|
||||
int
|
||||
sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
{
|
||||
int error = 0;
|
||||
struct pcb *pcb = curthread->td_pcb;
|
||||
struct pcb *pcb;
|
||||
struct vm_map *map;
|
||||
uint32_t i386base;
|
||||
uint64_t a64base;
|
||||
struct i386_ioperm_args iargs;
|
||||
struct i386_get_xfpustate i386xfpu;
|
||||
struct i386_set_pkru i386pkru;
|
||||
struct amd64_get_xfpustate a64xfpu;
|
||||
struct amd64_set_pkru a64pkru;
|
||||
int error;
|
||||
|
||||
#ifdef CAPABILITY_MODE
|
||||
/*
|
||||
@ -194,11 +199,15 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
case I386_GET_GSBASE:
|
||||
case I386_SET_GSBASE:
|
||||
case I386_GET_XFPUSTATE:
|
||||
case I386_SET_PKRU:
|
||||
case I386_CLEAR_PKRU:
|
||||
case AMD64_GET_FSBASE:
|
||||
case AMD64_SET_FSBASE:
|
||||
case AMD64_GET_GSBASE:
|
||||
case AMD64_SET_GSBASE:
|
||||
case AMD64_GET_XFPUSTATE:
|
||||
case AMD64_SET_PKRU:
|
||||
case AMD64_CLEAR_PKRU:
|
||||
break;
|
||||
|
||||
case I386_SET_IOPERM:
|
||||
@ -214,6 +223,10 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
|
||||
if (uap->op == I386_GET_LDT || uap->op == I386_SET_LDT)
|
||||
return (sysarch_ldt(td, uap, UIO_USERSPACE));
|
||||
|
||||
error = 0;
|
||||
pcb = td->td_pcb;
|
||||
|
||||
/*
|
||||
* XXXKIB check that the BSM generation code knows to encode
|
||||
* the op argument.
|
||||
@ -233,11 +246,27 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
a64xfpu.addr = (void *)(uintptr_t)i386xfpu.addr;
|
||||
a64xfpu.len = i386xfpu.len;
|
||||
break;
|
||||
case I386_SET_PKRU:
|
||||
case I386_CLEAR_PKRU:
|
||||
if ((error = copyin(uap->parms, &i386pkru,
|
||||
sizeof(struct i386_set_pkru))) != 0)
|
||||
return (error);
|
||||
a64pkru.addr = (void *)(uintptr_t)i386pkru.addr;
|
||||
a64pkru.len = i386pkru.len;
|
||||
a64pkru.keyidx = i386pkru.keyidx;
|
||||
a64pkru.flags = i386pkru.flags;
|
||||
break;
|
||||
case AMD64_GET_XFPUSTATE:
|
||||
if ((error = copyin(uap->parms, &a64xfpu,
|
||||
sizeof(struct amd64_get_xfpustate))) != 0)
|
||||
return (error);
|
||||
break;
|
||||
case AMD64_SET_PKRU:
|
||||
case AMD64_CLEAR_PKRU:
|
||||
if ((error = copyin(uap->parms, &a64pkru,
|
||||
sizeof(struct amd64_set_pkru))) != 0)
|
||||
return (error);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -326,6 +355,34 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
||||
a64xfpu.addr, a64xfpu.len);
|
||||
break;
|
||||
|
||||
case I386_SET_PKRU:
|
||||
case AMD64_SET_PKRU:
|
||||
/*
|
||||
* Read-lock the map to synchronize with parallel
|
||||
* pmap_vmspace_copy() on fork.
|
||||
*/
|
||||
map = &td->td_proc->p_vmspace->vm_map;
|
||||
vm_map_lock_read(map);
|
||||
error = pmap_pkru_set(PCPU_GET(curpmap),
|
||||
(vm_offset_t)a64pkru.addr, (vm_offset_t)a64pkru.addr +
|
||||
a64pkru.len, a64pkru.keyidx, a64pkru.flags);
|
||||
vm_map_unlock_read(map);
|
||||
break;
|
||||
|
||||
case I386_CLEAR_PKRU:
|
||||
case AMD64_CLEAR_PKRU:
|
||||
if (a64pkru.flags != 0 || a64pkru.keyidx != 0) {
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
map = &td->td_proc->p_vmspace->vm_map;
|
||||
vm_map_lock_read(map);
|
||||
error = pmap_pkru_clear(PCPU_GET(curpmap),
|
||||
(vm_offset_t)a64pkru.addr,
|
||||
(vm_offset_t)a64pkru.addr + a64pkru.len);
|
||||
vm_map_unlock(map);
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
|
@ -807,6 +807,20 @@ trap_pfault(struct trapframe *frame, int usermode)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* User-mode protection key violation (PKU). May happen
|
||||
* either from usermode or from kernel if copyin accessed
|
||||
* key-protected mapping.
|
||||
*/
|
||||
if ((frame->tf_err & PGEX_PK) != 0) {
|
||||
if (eva > VM_MAXUSER_ADDRESS) {
|
||||
trap_fatal(frame, eva);
|
||||
return (-1);
|
||||
}
|
||||
rv = KERN_PROTECTION_FAILURE;
|
||||
goto after_vmfault;
|
||||
}
|
||||
|
||||
/*
|
||||
* If nx protection of the usermode portion of kernel page
|
||||
* tables caused trap, panic.
|
||||
@ -842,6 +856,7 @@ trap_pfault(struct trapframe *frame, int usermode)
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
after_vmfault:
|
||||
if (!usermode) {
|
||||
if (td->td_intr_nesting_level == 0 &&
|
||||
curpcb->pcb_onfault != NULL) {
|
||||
@ -885,10 +900,12 @@ trap_fatal(frame, eva)
|
||||
#endif
|
||||
if (type == T_PAGEFLT) {
|
||||
printf("fault virtual address = 0x%lx\n", eva);
|
||||
printf("fault code = %s %s %s, %s\n",
|
||||
printf("fault code = %s %s %s%s%s, %s\n",
|
||||
code & PGEX_U ? "user" : "supervisor",
|
||||
code & PGEX_W ? "write" : "read",
|
||||
code & PGEX_I ? "instruction" : "data",
|
||||
code & PGEX_PK ? " prot key" : " ",
|
||||
code & PGEX_SGX ? " SGX" : " ",
|
||||
code & PGEX_RSV ? "reserved bits in PTE" :
|
||||
code & PGEX_P ? "protection violation" : "page not present");
|
||||
}
|
||||
|
@ -286,17 +286,6 @@ options ACPI_DEBUG
|
||||
# The cpufreq(4) driver provides support for non-ACPI CPU frequency control
|
||||
device cpufreq
|
||||
|
||||
# Direct Rendering modules for 3D acceleration.
|
||||
device drm # DRM core module required by DRM drivers
|
||||
device mach64drm # ATI Rage Pro, Rage Mobility P/M, Rage XL
|
||||
device mgadrm # AGP Matrox G200, G400, G450, G550
|
||||
device r128drm # ATI Rage 128
|
||||
device savagedrm # S3 Savage3D, Savage4
|
||||
device sisdrm # SiS 300/305, 540, 630
|
||||
device tdfxdrm # 3dfx Voodoo 3/4/5 and Banshee
|
||||
device viadrm # VIA
|
||||
options DRM_DEBUG # Include debug printfs (slow)
|
||||
|
||||
#
|
||||
# Network interfaces:
|
||||
#
|
||||
|
@ -627,6 +627,22 @@ cpu_mwait(u_long extensions, u_int hints)
|
||||
__asm __volatile("mwait" : : "a" (hints), "c" (extensions));
|
||||
}
|
||||
|
||||
static __inline uint32_t
|
||||
rdpkru(void)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
__asm __volatile("rdpkru" : "=a" (res) : "c" (0) : "edx");
|
||||
return (res);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
wrpkru(uint32_t mask)
|
||||
{
|
||||
|
||||
__asm __volatile("wrpkru" : : "a" (mask), "c" (0), "d" (0));
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
/* This is defined in <machine/specialreg.h> but is too painful to get to */
|
||||
#ifndef MSR_FSBASE
|
||||
|
@ -66,6 +66,7 @@
|
||||
#define X86_PG_AVAIL2 0x400 /* < programmers use */
|
||||
#define X86_PG_AVAIL3 0x800 /* \ */
|
||||
#define X86_PG_PDE_PAT 0x1000 /* PAT PAT index */
|
||||
#define X86_PG_PKU(idx) ((pt_entry_t)idx << 59)
|
||||
#define X86_PG_NX (1ul<<63) /* No-execute */
|
||||
#define X86_PG_AVAIL(x) (1ul << (x))
|
||||
|
||||
@ -73,6 +74,10 @@
|
||||
#define X86_PG_PDE_CACHE (X86_PG_PDE_PAT | X86_PG_NC_PWT | X86_PG_NC_PCD)
|
||||
#define X86_PG_PTE_CACHE (X86_PG_PTE_PAT | X86_PG_NC_PWT | X86_PG_NC_PCD)
|
||||
|
||||
/* Protection keys indexes */
|
||||
#define PMAP_MAX_PKRU_IDX 0xf
|
||||
#define X86_PG_PKU_MASK X86_PG_PKU(PMAP_MAX_PKRU_IDX)
|
||||
|
||||
/*
|
||||
* Intel extended page table (EPT) bit definitions.
|
||||
*/
|
||||
@ -120,7 +125,7 @@
|
||||
* (PTE) page mappings have identical settings for the following fields:
|
||||
*/
|
||||
#define PG_PTE_PROMOTE (PG_NX | PG_MANAGED | PG_W | PG_G | PG_PTE_CACHE | \
|
||||
PG_M | PG_A | PG_U | PG_RW | PG_V)
|
||||
PG_M | PG_A | PG_U | PG_RW | PG_V | PG_PKU_MASK)
|
||||
|
||||
/*
|
||||
* Page Protection Exception bits
|
||||
@ -131,6 +136,8 @@
|
||||
#define PGEX_U 0x04 /* access from User mode (UPL) */
|
||||
#define PGEX_RSV 0x08 /* reserved PTE field is non-zero */
|
||||
#define PGEX_I 0x10 /* during an instruction fetch */
|
||||
#define PGEX_PK 0x20 /* protection key violation */
|
||||
#define PGEX_SGX 0x40 /* SGX-related */
|
||||
|
||||
/*
|
||||
* undef the PG_xx macros that define bits in the regular x86 PTEs that
|
||||
@ -240,6 +247,8 @@
|
||||
#include <sys/_cpuset.h>
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
#include <sys/_pctrie.h>
|
||||
#include <sys/_rangeset.h>
|
||||
|
||||
#include <vm/_vm_radix.h>
|
||||
|
||||
@ -334,6 +343,7 @@ struct pmap {
|
||||
long pm_eptgen; /* EPT pmap generation id */
|
||||
int pm_flags;
|
||||
struct pmap_pcids pm_pcids[MAXCPU];
|
||||
struct rangeset pm_pkru;
|
||||
};
|
||||
|
||||
/* flags */
|
||||
@ -452,6 +462,10 @@ void pmap_pti_pcid_invalidate(uint64_t ucr3, uint64_t kcr3);
|
||||
void pmap_pti_pcid_invlpg(uint64_t ucr3, uint64_t kcr3, vm_offset_t va);
|
||||
void pmap_pti_pcid_invlrng(uint64_t ucr3, uint64_t kcr3, vm_offset_t sva,
|
||||
vm_offset_t eva);
|
||||
int pmap_pkru_clear(pmap_t pmap, vm_offset_t sva, vm_offset_t eva);
|
||||
int pmap_pkru_set(pmap_t pmap, vm_offset_t sva, vm_offset_t eva,
|
||||
u_int keyidx, int flags);
|
||||
int pmap_vmspace_copy(pmap_t dst_pmap, pmap_t src_pmap);
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/* Return various clipped indexes for a given VA */
|
||||
|
@ -195,8 +195,9 @@ MALLOC_DEFINE(M_AXP8XX_REG, "AXP8xx regulator", "AXP8xx power regulator");
|
||||
#define AXP_BAT_COULOMB_LO 0xe3
|
||||
|
||||
#define AXP_BAT_CAP_WARN 0xe6
|
||||
#define AXP_BAT_CAP_WARN_LV1 0xf0 /* Bits 4, 5, 6, 7 */
|
||||
#define AXP_BAT_CAP_WARN_LV2 0xf /* Bits 0, 1, 2, 3 */
|
||||
#define AXP_BAT_CAP_WARN_LV1 0xf0 /* Bits 4, 5, 6, 7 */
|
||||
#define AXP_BAP_CAP_WARN_LV1BASE 5 /* 5-20%, 1% per step */
|
||||
#define AXP_BAT_CAP_WARN_LV2 0xf /* Bits 0, 1, 2, 3 */
|
||||
|
||||
/* Sensor conversion macros */
|
||||
#define AXP_SENSOR_BAT_H(hi) ((hi) << 4)
|
||||
@ -1088,9 +1089,9 @@ axp8xx_intr(void *arg)
|
||||
if (bootverbose)
|
||||
device_printf(dev, "AXP_IRQSTAT4 val: %x\n", val);
|
||||
if (val & AXP_IRQSTAT4_BATLVL_LO0)
|
||||
devctl_notify("PMU", "Battery", "lower than level 2", NULL);
|
||||
devctl_notify("PMU", "Battery", "shutdown threshold", NULL);
|
||||
if (val & AXP_IRQSTAT4_BATLVL_LO1)
|
||||
devctl_notify("PMU", "Battery", "lower than level 1", NULL);
|
||||
devctl_notify("PMU", "Battery", "warning threshold", NULL);
|
||||
/* Acknowledge */
|
||||
axp8xx_write(dev, AXP_IRQSTAT4, val);
|
||||
}
|
||||
@ -1527,6 +1528,7 @@ axp8xx_attach(device_t dev)
|
||||
/* Get thresholds */
|
||||
if (axp8xx_read(dev, AXP_BAT_CAP_WARN, &val, 1) == 0) {
|
||||
sc->warn_thres = (val & AXP_BAT_CAP_WARN_LV1) >> 4;
|
||||
sc->warn_thres += AXP_BAP_CAP_WARN_LV1BASE;
|
||||
sc->shut_thres = (val & AXP_BAT_CAP_WARN_LV2);
|
||||
if (bootverbose) {
|
||||
device_printf(dev,
|
||||
|
@ -71,5 +71,12 @@ void pmap_kremove_device(vm_offset_t, vm_size_t);
|
||||
vm_paddr_t pmap_kextract(vm_offset_t);
|
||||
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
|
||||
|
||||
static inline int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* !_MACHINE_PMAP_H_ */
|
||||
|
@ -171,6 +171,13 @@ struct pcb *pmap_switch(struct thread *, struct thread *);
|
||||
|
||||
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
|
||||
|
||||
static inline int
|
||||
pmap_vmspace_copy(pmap_t dst_pmap __unused, pmap_t src_pmap __unused)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !LOCORE */
|
||||
|
@ -128,7 +128,7 @@ rk_clk_composite_set_mux(struct clknode *clk, int index)
|
||||
READ4(clk, sc->muxdiv_offset, &val);
|
||||
val &= ~sc->mux_mask;
|
||||
val |= index << sc->mux_shift;
|
||||
WRITE4(clk, sc->muxdiv_offset, val);
|
||||
WRITE4(clk, sc->muxdiv_offset, val | RK_CLK_COMPOSITE_MASK);
|
||||
DEVICE_UNLOCK(clk);
|
||||
|
||||
return (0);
|
||||
@ -222,6 +222,7 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
|
||||
return (0);
|
||||
}
|
||||
|
||||
p_idx = clknode_get_parent_idx(clk);
|
||||
if (p_idx != best_parent)
|
||||
clknode_set_parent_by_idx(clk, best_parent);
|
||||
|
||||
|
@ -651,7 +651,7 @@ ctl_ha_datamove(union ctl_io *io)
|
||||
|
||||
memset(&msg.dt, 0, sizeof(msg.dt));
|
||||
msg.hdr.msg_type = CTL_MSG_DATAMOVE;
|
||||
msg.hdr.original_sc = io->io_hdr.original_sc;
|
||||
msg.hdr.original_sc = io->io_hdr.remote_io;
|
||||
msg.hdr.serializing_sc = io;
|
||||
msg.hdr.nexus = io->io_hdr.nexus;
|
||||
msg.hdr.status = io->io_hdr.status;
|
||||
@ -766,7 +766,7 @@ ctl_ha_done(union ctl_io *io)
|
||||
if (io->io_hdr.io_type == CTL_IO_SCSI) {
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.msg_type = CTL_MSG_FINISH_IO;
|
||||
msg.hdr.original_sc = io->io_hdr.original_sc;
|
||||
msg.hdr.original_sc = io->io_hdr.remote_io;
|
||||
msg.hdr.nexus = io->io_hdr.nexus;
|
||||
msg.hdr.status = io->io_hdr.status;
|
||||
msg.scsi.scsi_status = io->scsiio.scsi_status;
|
||||
@ -1439,7 +1439,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
|
||||
// populate ctsio from msg
|
||||
io->io_hdr.io_type = CTL_IO_SCSI;
|
||||
io->io_hdr.msg_type = CTL_MSG_SERIALIZE;
|
||||
io->io_hdr.original_sc = msg->hdr.original_sc;
|
||||
io->io_hdr.remote_io = msg->hdr.original_sc;
|
||||
io->io_hdr.flags |= CTL_FLAG_FROM_OTHER_SC |
|
||||
CTL_FLAG_IO_ACTIVE;
|
||||
/*
|
||||
@ -1495,7 +1495,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
|
||||
* Keep track of this, we need to send it back over
|
||||
* when the datamove is complete.
|
||||
*/
|
||||
io->io_hdr.serializing_sc = msg->hdr.serializing_sc;
|
||||
io->io_hdr.remote_io = msg->hdr.serializing_sc;
|
||||
if (msg->hdr.status == CTL_SUCCESS)
|
||||
io->io_hdr.status = msg->hdr.status;
|
||||
|
||||
@ -1508,9 +1508,8 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
|
||||
CTL_HA_DATAMOVE_SEGMENT + 1;
|
||||
sgl = malloc(sizeof(*sgl) * i, M_CTL,
|
||||
M_WAITOK | M_ZERO);
|
||||
io->io_hdr.remote_sglist = sgl;
|
||||
io->io_hdr.local_sglist =
|
||||
&sgl[msg->dt.kern_sg_entries];
|
||||
CTL_RSGL(io) = sgl;
|
||||
CTL_LSGL(io) = &sgl[msg->dt.kern_sg_entries];
|
||||
|
||||
io->scsiio.kern_data_ptr = (uint8_t *)sgl;
|
||||
|
||||
@ -1597,7 +1596,7 @@ ctl_isc_event_handler(ctl_ha_channel channel, ctl_ha_event event, int param)
|
||||
}
|
||||
io->io_hdr.flags |= CTL_FLAG_IO_ACTIVE;
|
||||
io->io_hdr.msg_type = CTL_MSG_R2R;
|
||||
io->io_hdr.serializing_sc = msg->hdr.serializing_sc;
|
||||
io->io_hdr.remote_io = msg->hdr.serializing_sc;
|
||||
ctl_enqueue_isc(io);
|
||||
break;
|
||||
|
||||
@ -2369,7 +2368,7 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
|
||||
mtx_unlock(&lun->lun_lock);
|
||||
|
||||
/* send msg back to other side */
|
||||
msg_info.hdr.original_sc = ctsio->io_hdr.original_sc;
|
||||
msg_info.hdr.original_sc = ctsio->io_hdr.remote_io;
|
||||
msg_info.hdr.serializing_sc = (union ctl_io *)ctsio;
|
||||
msg_info.hdr.msg_type = CTL_MSG_R2R;
|
||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
|
||||
@ -2395,7 +2394,7 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
|
||||
/*retry_count*/ 0);
|
||||
badjuju:
|
||||
ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
|
||||
msg_info.hdr.original_sc = ctsio->io_hdr.original_sc;
|
||||
msg_info.hdr.original_sc = ctsio->io_hdr.remote_io;
|
||||
msg_info.hdr.serializing_sc = NULL;
|
||||
msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU;
|
||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
|
||||
@ -2743,39 +2742,6 @@ ctl_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
|
||||
#endif /* CTL_IO_DELAY */
|
||||
break;
|
||||
}
|
||||
#ifdef CTL_LEGACY_STATS
|
||||
case CTL_GETSTATS: {
|
||||
struct ctl_stats *stats = (struct ctl_stats *)addr;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* XXX KDM no locking here. If the LUN list changes,
|
||||
* things can blow up.
|
||||
*/
|
||||
i = 0;
|
||||
stats->status = CTL_SS_OK;
|
||||
stats->fill_len = 0;
|
||||
STAILQ_FOREACH(lun, &softc->lun_list, links) {
|
||||
if (stats->fill_len + sizeof(lun->legacy_stats) >
|
||||
stats->alloc_len) {
|
||||
stats->status = CTL_SS_NEED_MORE_SPACE;
|
||||
break;
|
||||
}
|
||||
retval = copyout(&lun->legacy_stats, &stats->lun_stats[i++],
|
||||
sizeof(lun->legacy_stats));
|
||||
if (retval != 0)
|
||||
break;
|
||||
stats->fill_len += sizeof(lun->legacy_stats);
|
||||
}
|
||||
stats->num_luns = softc->num_luns;
|
||||
stats->flags = CTL_STATS_FLAG_NONE;
|
||||
#ifdef CTL_TIME_IO
|
||||
stats->flags |= CTL_STATS_FLAG_TIME_VALID;
|
||||
#endif
|
||||
getnanouptime(&stats->timestamp);
|
||||
break;
|
||||
}
|
||||
#endif /* CTL_LEGACY_STATS */
|
||||
case CTL_ERROR_INJECT: {
|
||||
struct ctl_error_desc *err_desc, *new_err_desc;
|
||||
|
||||
@ -4758,17 +4724,6 @@ ctl_alloc_lun(struct ctl_softc *ctl_softc, struct ctl_lun *ctl_lun,
|
||||
ctl_init_log_page_index(lun);
|
||||
|
||||
/* Setup statistics gathering */
|
||||
#ifdef CTL_LEGACY_STATS
|
||||
lun->legacy_stats.device_type = be_lun->lun_type;
|
||||
lun->legacy_stats.lun_number = lun_number;
|
||||
lun->legacy_stats.blocksize = be_lun->blocksize;
|
||||
if (be_lun->blocksize == 0)
|
||||
lun->legacy_stats.flags = CTL_LUN_STATS_NO_BLOCKSIZE;
|
||||
lun->legacy_stats.ports = malloc(sizeof(struct ctl_lun_io_port_stats) *
|
||||
ctl_max_ports, M_DEVBUF, M_WAITOK | M_ZERO);
|
||||
for (len = 0; len < ctl_max_ports; len++)
|
||||
lun->legacy_stats.ports[len].targ_port = len;
|
||||
#endif /* CTL_LEGACY_STATS */
|
||||
lun->stats.item = lun_number;
|
||||
|
||||
/*
|
||||
@ -11087,7 +11042,7 @@ ctl_check_blocked(struct ctl_lun *lun)
|
||||
|
||||
cur_blocked->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
|
||||
msg_info.hdr.original_sc =
|
||||
cur_blocked->io_hdr.original_sc;
|
||||
cur_blocked->io_hdr.remote_io;
|
||||
msg_info.hdr.serializing_sc = cur_blocked;
|
||||
msg_info.hdr.msg_type = CTL_MSG_R2R;
|
||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
|
||||
@ -12524,7 +12479,7 @@ ctl_send_datamove_done(union ctl_io *io, int have_lock)
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.msg_type = CTL_MSG_DATAMOVE_DONE;
|
||||
msg.hdr.original_sc = io;
|
||||
msg.hdr.serializing_sc = io->io_hdr.serializing_sc;
|
||||
msg.hdr.serializing_sc = io->io_hdr.remote_io;
|
||||
msg.hdr.nexus = io->io_hdr.nexus;
|
||||
msg.hdr.status = io->io_hdr.status;
|
||||
msg.scsi.kern_data_resid = io->scsiio.kern_data_resid;
|
||||
@ -12575,10 +12530,10 @@ ctl_datamove_remote_write_cb(struct ctl_ha_dt_req *rq)
|
||||
ctl_dt_req_free(rq);
|
||||
|
||||
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
||||
free(io->io_hdr.local_sglist[i].addr, M_CTL);
|
||||
free(io->io_hdr.remote_sglist, M_CTL);
|
||||
io->io_hdr.remote_sglist = NULL;
|
||||
io->io_hdr.local_sglist = NULL;
|
||||
free(CTL_LSGLT(io)[i].addr, M_CTL);
|
||||
free(CTL_RSGL(io), M_CTL);
|
||||
CTL_RSGL(io) = NULL;
|
||||
CTL_LSGL(io) = NULL;
|
||||
|
||||
/*
|
||||
* The data is in local and remote memory, so now we need to send
|
||||
@ -12618,7 +12573,7 @@ ctl_datamove_remote_write(union ctl_io *io)
|
||||
return;
|
||||
|
||||
/* Switch the pointer over so the FETD knows what to do */
|
||||
io->scsiio.kern_data_ptr = (uint8_t *)io->io_hdr.local_sglist;
|
||||
io->scsiio.kern_data_ptr = (uint8_t *)CTL_LSGL(io);
|
||||
|
||||
/*
|
||||
* Use a custom move done callback, since we need to send completion
|
||||
@ -12641,10 +12596,10 @@ ctl_datamove_remote_dm_read_cb(union ctl_io *io)
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
||||
free(io->io_hdr.local_sglist[i].addr, M_CTL);
|
||||
free(io->io_hdr.remote_sglist, M_CTL);
|
||||
io->io_hdr.remote_sglist = NULL;
|
||||
io->io_hdr.local_sglist = NULL;
|
||||
free(CTL_LSGLT(io)[i].addr, M_CTL);
|
||||
free(CTL_RSGL(io), M_CTL);
|
||||
CTL_RSGL(io) = NULL;
|
||||
CTL_LSGL(io) = NULL;
|
||||
|
||||
#if 0
|
||||
scsi_path_string(io, path_str, sizeof(path_str));
|
||||
@ -12691,7 +12646,7 @@ ctl_datamove_remote_read_cb(struct ctl_ha_dt_req *rq)
|
||||
ctl_dt_req_free(rq);
|
||||
|
||||
/* Switch the pointer over so the FETD knows what to do */
|
||||
io->scsiio.kern_data_ptr = (uint8_t *)io->io_hdr.local_sglist;
|
||||
io->scsiio.kern_data_ptr = (uint8_t *)CTL_LSGL(io);
|
||||
|
||||
/*
|
||||
* Use a custom move done callback, since we need to send completion
|
||||
@ -12714,7 +12669,7 @@ ctl_datamove_remote_sgl_setup(union ctl_io *io)
|
||||
int i;
|
||||
|
||||
retval = 0;
|
||||
local_sglist = io->io_hdr.local_sglist;
|
||||
local_sglist = CTL_LSGL(io);
|
||||
len_to_go = io->scsiio.kern_data_len;
|
||||
|
||||
/*
|
||||
@ -12785,8 +12740,8 @@ ctl_datamove_remote_xfer(union ctl_io *io, unsigned command,
|
||||
return (1);
|
||||
}
|
||||
|
||||
local_sglist = io->io_hdr.local_sglist;
|
||||
remote_sglist = io->io_hdr.remote_sglist;
|
||||
local_sglist = CTL_LSGL(io);
|
||||
remote_sglist = CTL_RSGL(io);
|
||||
local_used = 0;
|
||||
remote_used = 0;
|
||||
total_used = 0;
|
||||
@ -12899,10 +12854,10 @@ ctl_datamove_remote_read(union ctl_io *io)
|
||||
* error if there is a problem.
|
||||
*/
|
||||
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
||||
free(io->io_hdr.local_sglist[i].addr, M_CTL);
|
||||
free(io->io_hdr.remote_sglist, M_CTL);
|
||||
io->io_hdr.remote_sglist = NULL;
|
||||
io->io_hdr.local_sglist = NULL;
|
||||
free(CTL_LSGLT(io)[i].addr, M_CTL);
|
||||
free(CTL_RSGL(io), M_CTL);
|
||||
CTL_RSGL(io) = NULL;
|
||||
CTL_LSGL(io) = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -13079,21 +13034,6 @@ ctl_process_done(union ctl_io *io)
|
||||
else
|
||||
type = CTL_STATS_NO_IO;
|
||||
|
||||
#ifdef CTL_LEGACY_STATS
|
||||
uint32_t targ_port = port->targ_port;
|
||||
lun->legacy_stats.ports[targ_port].bytes[type] +=
|
||||
io->scsiio.kern_total_len;
|
||||
lun->legacy_stats.ports[targ_port].operations[type] ++;
|
||||
lun->legacy_stats.ports[targ_port].num_dmas[type] +=
|
||||
io->io_hdr.num_dmas;
|
||||
#ifdef CTL_TIME_IO
|
||||
bintime_add(&lun->legacy_stats.ports[targ_port].dma_time[type],
|
||||
&io->io_hdr.dma_bt);
|
||||
bintime_add(&lun->legacy_stats.ports[targ_port].time[type],
|
||||
&bt);
|
||||
#endif
|
||||
#endif /* CTL_LEGACY_STATS */
|
||||
|
||||
lun->stats.bytes[type] += io->scsiio.kern_total_len;
|
||||
lun->stats.operations[type] ++;
|
||||
lun->stats.dmas[type] += io->io_hdr.num_dmas;
|
||||
@ -13165,7 +13105,7 @@ ctl_process_done(union ctl_io *io)
|
||||
(io->io_hdr.flags & CTL_FLAG_SENT_2OTHER_SC)) {
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
msg.hdr.msg_type = CTL_MSG_FINISH_IO;
|
||||
msg.hdr.serializing_sc = io->io_hdr.serializing_sc;
|
||||
msg.hdr.serializing_sc = io->io_hdr.remote_io;
|
||||
msg.hdr.nexus = io->io_hdr.nexus;
|
||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
|
||||
sizeof(msg.scsi) - sizeof(msg.scsi.sense_data),
|
||||
|
@ -167,6 +167,15 @@ union ctl_priv {
|
||||
#define CTL_PORT(io) (((struct ctl_softc *)CTL_SOFTC(io))-> \
|
||||
ctl_ports[(io)->io_hdr.nexus.targ_port])
|
||||
|
||||
/*
|
||||
* These are used only on Originating SC in XFER mode, where requests don't
|
||||
* ever reach backends, so we can reuse backend's private storage.
|
||||
*/
|
||||
#define CTL_RSGL(io) ((io)->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptrs[0])
|
||||
#define CTL_LSGL(io) ((io)->io_hdr.ctl_private[CTL_PRIV_BACKEND].ptrs[1])
|
||||
#define CTL_RSGLT(io) ((struct ctl_sg_entry *)CTL_RSGL(io))
|
||||
#define CTL_LSGLT(io) ((struct ctl_sg_entry *)CTL_LSGL(io))
|
||||
|
||||
#define CTL_INVALID_PORTNAME 0xFF
|
||||
#define CTL_UNMAPPED_IID 0xFF
|
||||
|
||||
@ -229,12 +238,12 @@ struct ctl_io_hdr {
|
||||
struct bintime dma_bt; /* DMA total ticks */
|
||||
#endif /* CTL_TIME_IO */
|
||||
uint32_t num_dmas; /* Number of DMAs */
|
||||
union ctl_io *original_sc;
|
||||
union ctl_io *serializing_sc;
|
||||
union ctl_io *remote_io; /* I/O counterpart on remote HA side */
|
||||
void *pad1;
|
||||
void *pool; /* I/O pool */
|
||||
union ctl_priv ctl_private[CTL_NUM_PRIV];/* CTL private area */
|
||||
struct ctl_sg_entry *remote_sglist;
|
||||
struct ctl_sg_entry *local_sglist;
|
||||
void *pad2;
|
||||
void *pad3;
|
||||
STAILQ_ENTRY(ctl_io_hdr) links; /* linked list pointer */
|
||||
TAILQ_ENTRY(ctl_io_hdr) ooa_links;
|
||||
TAILQ_ENTRY(ctl_io_hdr) blocked_links;
|
||||
|
@ -69,9 +69,6 @@
|
||||
/* Hopefully this won't conflict with new misc devices that pop up */
|
||||
#define CTL_MINOR 225
|
||||
|
||||
/* Legacy statistics accumulated for every port for every LU. */
|
||||
//#define CTL_LEGACY_STATS 1
|
||||
|
||||
typedef enum {
|
||||
CTL_DELAY_TYPE_NONE,
|
||||
CTL_DELAY_TYPE_CONT,
|
||||
@ -119,39 +116,6 @@ typedef enum {
|
||||
CTL_STATS_FLAG_TIME_VALID = 0x01
|
||||
} ctl_stats_flags;
|
||||
|
||||
#ifdef CTL_LEGACY_STATS
|
||||
typedef enum {
|
||||
CTL_LUN_STATS_NO_BLOCKSIZE = 0x01
|
||||
} ctl_lun_stats_flags;
|
||||
|
||||
struct ctl_lun_io_port_stats {
|
||||
uint32_t targ_port;
|
||||
uint64_t bytes[CTL_STATS_NUM_TYPES];
|
||||
uint64_t operations[CTL_STATS_NUM_TYPES];
|
||||
struct bintime time[CTL_STATS_NUM_TYPES];
|
||||
uint64_t num_dmas[CTL_STATS_NUM_TYPES];
|
||||
struct bintime dma_time[CTL_STATS_NUM_TYPES];
|
||||
};
|
||||
|
||||
struct ctl_lun_io_stats {
|
||||
uint8_t device_type;
|
||||
uint64_t lun_number;
|
||||
uint32_t blocksize;
|
||||
ctl_lun_stats_flags flags;
|
||||
struct ctl_lun_io_port_stats *ports;
|
||||
};
|
||||
|
||||
struct ctl_stats {
|
||||
int alloc_len; /* passed to kernel */
|
||||
struct ctl_lun_io_stats *lun_stats; /* passed to/from kernel */
|
||||
int fill_len; /* passed to userland */
|
||||
int num_luns; /* passed to userland */
|
||||
ctl_stats_status status; /* passed to userland */
|
||||
ctl_stats_flags flags; /* passed to userland */
|
||||
struct timespec timestamp; /* passed to userland */
|
||||
};
|
||||
#endif /* CTL_LEGACY_STATS */
|
||||
|
||||
struct ctl_io_stats {
|
||||
uint32_t item;
|
||||
uint64_t bytes[CTL_STATS_NUM_TYPES];
|
||||
@ -795,7 +759,6 @@ struct ctl_lun_map {
|
||||
#define CTL_ENABLE_PORT _IOW(CTL_MINOR, 0x04, struct ctl_port_entry)
|
||||
#define CTL_DISABLE_PORT _IOW(CTL_MINOR, 0x05, struct ctl_port_entry)
|
||||
#define CTL_DELAY_IO _IOWR(CTL_MINOR, 0x10, struct ctl_io_delay_info)
|
||||
#define CTL_GETSTATS _IOWR(CTL_MINOR, 0x15, struct ctl_stats)
|
||||
#define CTL_ERROR_INJECT _IOWR(CTL_MINOR, 0x16, struct ctl_error_desc)
|
||||
#define CTL_GET_OOA _IOWR(CTL_MINOR, 0x18, struct ctl_ooa)
|
||||
#define CTL_DUMP_STRUCTS _IO(CTL_MINOR, 0x19)
|
||||
|
@ -403,9 +403,6 @@ struct ctl_lun {
|
||||
struct callout ie_callout; /* INTERVAL TIMER */
|
||||
struct ctl_mode_pages mode_pages;
|
||||
struct ctl_log_pages log_pages;
|
||||
#ifdef CTL_LEGACY_STATS
|
||||
struct ctl_lun_io_stats legacy_stats;
|
||||
#endif /* CTL_LEGACY_STATS */
|
||||
struct ctl_io_stats stats;
|
||||
uint32_t res_idx;
|
||||
uint32_t pr_generation;
|
||||
|
@ -1089,6 +1089,8 @@ fasttrap_tracepoint_disable(proc_t *p, fasttrap_probe_t *probe, uint_t index)
|
||||
ASSERT(p->p_proc_flag & P_PR_LOCK);
|
||||
#endif
|
||||
p->p_dtrace_count--;
|
||||
|
||||
atomic_add_rel_64(&p->p_fasttrap_tp_gen, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -360,16 +360,13 @@ trim_map_write_start(zio_t *zio)
|
||||
return (B_FALSE);
|
||||
}
|
||||
|
||||
ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL);
|
||||
if (ts != NULL) {
|
||||
/*
|
||||
* Loop until all overlapping segments are removed.
|
||||
*/
|
||||
do {
|
||||
trim_map_segment_remove(tm, ts, start, end);
|
||||
ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL);
|
||||
} while (ts != NULL);
|
||||
/*
|
||||
* Loop until all overlapping segments are removed.
|
||||
*/
|
||||
while ((ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL)) != NULL) {
|
||||
trim_map_segment_remove(tm, ts, start, end);
|
||||
}
|
||||
|
||||
avl_add(&tm->tm_inflight_writes, zio);
|
||||
|
||||
mutex_exit(&tm->tm_lock);
|
||||
|
@ -692,10 +692,12 @@ vdev_geom_attach_by_guids(vdev_t *vd)
|
||||
struct g_geom *gp;
|
||||
struct g_provider *pp, *best_pp;
|
||||
struct g_consumer *cp;
|
||||
const char *vdpath;
|
||||
enum match match, best_match;
|
||||
|
||||
g_topology_assert();
|
||||
|
||||
vdpath = vd->vdev_path + sizeof("/dev/") - 1;
|
||||
cp = NULL;
|
||||
best_pp = NULL;
|
||||
best_match = NO_MATCH;
|
||||
@ -710,6 +712,10 @@ vdev_geom_attach_by_guids(vdev_t *vd)
|
||||
if (match > best_match) {
|
||||
best_match = match;
|
||||
best_pp = pp;
|
||||
} else if (match == best_match) {
|
||||
if (strcmp(pp->name, vdpath) == 0) {
|
||||
best_pp = pp;
|
||||
}
|
||||
}
|
||||
if (match == FULL_MATCH)
|
||||
goto out;
|
||||
@ -794,7 +800,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
|
||||
/*
|
||||
* We must have a pathname, and it must be absolute.
|
||||
*/
|
||||
if (vd->vdev_path == NULL || vd->vdev_path[0] != '/') {
|
||||
if (vd->vdev_path == NULL || strncmp(vd->vdev_path, "/dev/", 5) != 0) {
|
||||
vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
|
||||
return (EINVAL);
|
||||
}
|
||||
|
@ -270,7 +270,6 @@ static void
|
||||
vdev_raidz_map_free(raidz_map_t *rm)
|
||||
{
|
||||
int c;
|
||||
size_t size;
|
||||
|
||||
for (c = 0; c < rm->rm_firstdatacol; c++) {
|
||||
if (rm->rm_col[c].rc_abd != NULL)
|
||||
@ -281,11 +280,9 @@ vdev_raidz_map_free(raidz_map_t *rm)
|
||||
rm->rm_col[c].rc_size);
|
||||
}
|
||||
|
||||
size = 0;
|
||||
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
|
||||
if (rm->rm_col[c].rc_abd != NULL)
|
||||
abd_put(rm->rm_col[c].rc_abd);
|
||||
size += rm->rm_col[c].rc_size;
|
||||
}
|
||||
|
||||
if (rm->rm_abd_copy != NULL)
|
||||
@ -571,10 +568,7 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset, boolean_t dofre
|
||||
abd_alloc_linear(rm->rm_col[c].rc_size, B_TRUE);
|
||||
}
|
||||
|
||||
rm->rm_col[c].rc_abd = abd_get_offset(abd, 0);
|
||||
off = rm->rm_col[c].rc_size;
|
||||
|
||||
for (c = c + 1; c < acols; c++) {
|
||||
for (off = 0; c < acols; c++) {
|
||||
rm->rm_col[c].rc_abd = abd_get_offset(abd, off);
|
||||
off += rm->rm_col[c].rc_size;
|
||||
}
|
||||
@ -2023,7 +2017,7 @@ vdev_raidz_io_start(zio_t *zio)
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(zio->io_type == ZIO_TYPE_READ);
|
||||
ASSERT3U(zio->io_type, ==, ZIO_TYPE_READ);
|
||||
|
||||
/*
|
||||
* Iterate over the columns in reverse order so that we hit the parity
|
||||
@ -2561,7 +2555,7 @@ vdev_raidz_io_done(zio_t *zio)
|
||||
/*
|
||||
* We're here because either:
|
||||
*
|
||||
* total_errors == rm_first_datacol, or
|
||||
* total_errors == rm_firstdatacol, or
|
||||
* vdev_raidz_combrec() failed
|
||||
*
|
||||
* In either case, there is enough bad data to prevent
|
||||
|
@ -967,6 +967,7 @@ fasttrap_pid_probe(struct trapframe *tf)
|
||||
struct reg reg, *rp;
|
||||
proc_t *p = curproc, *pp;
|
||||
struct rm_priotracker tracker;
|
||||
uint64_t gen;
|
||||
uintptr_t pc;
|
||||
uintptr_t new_pc = 0;
|
||||
fasttrap_bucket_t *bucket;
|
||||
@ -1026,8 +1027,22 @@ fasttrap_pid_probe(struct trapframe *tf)
|
||||
while (pp->p_vmspace == pp->p_pptr->p_vmspace)
|
||||
pp = pp->p_pptr;
|
||||
pid = pp->p_pid;
|
||||
if (pp != p) {
|
||||
PROC_LOCK(pp);
|
||||
if ((pp->p_flag & P_WEXIT) != 0) {
|
||||
/*
|
||||
* This can happen if the child was created with
|
||||
* rfork(2). Userspace tracing cannot work reliably in
|
||||
* such a scenario, but we can at least try.
|
||||
*/
|
||||
PROC_UNLOCK(pp);
|
||||
sx_sunlock(&proctree_lock);
|
||||
return (-1);
|
||||
}
|
||||
_PHOLD_LITE(pp);
|
||||
PROC_UNLOCK(pp);
|
||||
}
|
||||
sx_sunlock(&proctree_lock);
|
||||
pp = NULL;
|
||||
|
||||
rm_rlock(&fasttrap_tp_lock, &tracker);
|
||||
#endif
|
||||
@ -1051,11 +1066,32 @@ fasttrap_pid_probe(struct trapframe *tf)
|
||||
if (tp == NULL) {
|
||||
#ifdef illumos
|
||||
mutex_exit(pid_mtx);
|
||||
return (-1);
|
||||
#else
|
||||
rm_runlock(&fasttrap_tp_lock, &tracker);
|
||||
gen = atomic_load_acq_64(&pp->p_fasttrap_tp_gen);
|
||||
if (pp != p)
|
||||
PRELE(pp);
|
||||
if (curthread->t_fasttrap_tp_gen != gen) {
|
||||
/*
|
||||
* At least one tracepoint associated with this PID has
|
||||
* been removed from the table since #BP was raised.
|
||||
* Speculate that we hit a tracepoint that has since
|
||||
* been removed, and retry the instruction.
|
||||
*/
|
||||
curthread->t_fasttrap_tp_gen = gen;
|
||||
#ifdef __amd64
|
||||
tf->tf_rip = pc;
|
||||
#else
|
||||
tf->tf_eip = pc;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
#endif
|
||||
}
|
||||
if (pp != p)
|
||||
PRELE(pp);
|
||||
|
||||
/*
|
||||
* Set the program counter to the address of the traced instruction
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user