MFhead@r344527
This commit is contained in:
commit
18b18078f2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/import-googletest-1.8.1/; revision=344528
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
|
disable the most expensive debugging functionality run
|
||||||
"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
|
"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:
|
20190131:
|
||||||
Iflib is no longer unconditionally compiled into the kernel. Drivers
|
Iflib is no longer unconditionally compiled into the kernel. Drivers
|
||||||
using iflib and statically compiled into the kernel, now require
|
using iflib and statically compiled into the kernel, now require
|
||||||
|
@ -472,10 +472,31 @@ str_to_event(const char *str, int last)
|
|||||||
int
|
int
|
||||||
bindcmd(int argc, char **argv)
|
bindcmd(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
FILE *old;
|
||||||
|
FILE *out;
|
||||||
|
|
||||||
if (el == NULL)
|
if (el == NULL)
|
||||||
error("line editing is disabled");
|
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
|
#else
|
||||||
|
@ -105,6 +105,7 @@ struct job {
|
|||||||
char changed; /* true if status has changed */
|
char changed; /* true if status has changed */
|
||||||
char foreground; /* true if running in the foreground */
|
char foreground; /* true if running in the foreground */
|
||||||
char remembered; /* true if $! referenced */
|
char remembered; /* true if $! referenced */
|
||||||
|
char pipefail; /* pass any non-zero status */
|
||||||
#if JOBS
|
#if JOBS
|
||||||
char jobctl; /* job running under job control */
|
char jobctl; /* job running under job control */
|
||||||
struct job *next; /* job used after this one */
|
struct job *next; /* job used after this one */
|
||||||
@ -144,6 +145,7 @@ static void setcurjob(struct job *);
|
|||||||
static void deljob(struct job *);
|
static void deljob(struct job *);
|
||||||
static struct job *getcurjob(struct job *);
|
static struct job *getcurjob(struct job *);
|
||||||
#endif
|
#endif
|
||||||
|
static int getjobstatus(const struct job *);
|
||||||
static void printjobcmd(struct job *);
|
static void printjobcmd(struct job *);
|
||||||
static void showjob(struct job *, int);
|
static void showjob(struct job *, int);
|
||||||
|
|
||||||
@ -341,6 +343,20 @@ jobscmd(int argc __unused, char *argv[] __unused)
|
|||||||
return (0);
|
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
|
static void
|
||||||
printjobcmd(struct job *jp)
|
printjobcmd(struct job *jp)
|
||||||
{
|
{
|
||||||
@ -377,7 +393,7 @@ showjob(struct job *jp, int mode)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
coredump = "";
|
coredump = "";
|
||||||
status = jp->ps[jp->nprocs - 1].status;
|
status = getjobstatus(jp);
|
||||||
if (jp->state == 0) {
|
if (jp->state == 0) {
|
||||||
statestr = "Running";
|
statestr = "Running";
|
||||||
#if JOBS
|
#if JOBS
|
||||||
@ -556,7 +572,7 @@ waitcmdloop(struct job *job)
|
|||||||
do {
|
do {
|
||||||
if (job != NULL) {
|
if (job != NULL) {
|
||||||
if (job->state == JOBDONE) {
|
if (job->state == JOBDONE) {
|
||||||
status = job->ps[job->nprocs - 1].status;
|
status = getjobstatus(job);
|
||||||
if (WIFEXITED(status))
|
if (WIFEXITED(status))
|
||||||
retval = WEXITSTATUS(status);
|
retval = WEXITSTATUS(status);
|
||||||
else
|
else
|
||||||
@ -781,6 +797,7 @@ makejob(union node *node __unused, int nprocs)
|
|||||||
jp->nprocs = 0;
|
jp->nprocs = 0;
|
||||||
jp->foreground = 0;
|
jp->foreground = 0;
|
||||||
jp->remembered = 0;
|
jp->remembered = 0;
|
||||||
|
jp->pipefail = pipefailflag;
|
||||||
#if JOBS
|
#if JOBS
|
||||||
jp->jobctl = jobctl;
|
jp->jobctl = jobctl;
|
||||||
jp->next = NULL;
|
jp->next = NULL;
|
||||||
@ -1076,7 +1093,7 @@ waitforjob(struct job *jp, int *signaled)
|
|||||||
if (jp->state == JOBSTOPPED)
|
if (jp->state == JOBSTOPPED)
|
||||||
setcurjob(jp);
|
setcurjob(jp);
|
||||||
#endif
|
#endif
|
||||||
status = jp->ps[jp->nprocs - 1].status;
|
status = getjobstatus(jp);
|
||||||
if (signaled != NULL)
|
if (signaled != NULL)
|
||||||
*signaled = WIFSIGNALED(status);
|
*signaled = WIFSIGNALED(status);
|
||||||
/* convert to 8 bits */
|
/* convert to 8 bits */
|
||||||
|
@ -67,9 +67,10 @@ struct shparam {
|
|||||||
#define Pflag optval[17]
|
#define Pflag optval[17]
|
||||||
#define hflag optval[18]
|
#define hflag optval[18]
|
||||||
#define nologflag optval[19]
|
#define nologflag optval[19]
|
||||||
|
#define pipefailflag optval[20]
|
||||||
|
|
||||||
#define NSHORTOPTS 19
|
#define NSHORTOPTS 19
|
||||||
#define NOPTS 20
|
#define NOPTS 21
|
||||||
|
|
||||||
extern char optval[NOPTS];
|
extern char optval[NOPTS];
|
||||||
extern const char optletter[NSHORTOPTS];
|
extern const char optletter[NSHORTOPTS];
|
||||||
@ -97,6 +98,7 @@ static const unsigned char optname[] =
|
|||||||
"\010physical"
|
"\010physical"
|
||||||
"\010trackall"
|
"\010trackall"
|
||||||
"\005nolog"
|
"\005nolog"
|
||||||
|
"\010pipefail"
|
||||||
;
|
;
|
||||||
#endif
|
#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.
|
* Version of write which resumes after a signal is caught.
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
struct output {
|
struct output {
|
||||||
char *nextc;
|
char *nextc;
|
||||||
@ -75,6 +76,7 @@ void out1fmt(const char *, ...) __printflike(1, 2);
|
|||||||
void out2fmt_flush(const char *, ...) __printflike(1, 2);
|
void out2fmt_flush(const char *, ...) __printflike(1, 2);
|
||||||
void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
|
void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
|
||||||
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
|
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
|
||||||
|
FILE *out1fp(void);
|
||||||
int xwrite(int, const char *, int);
|
int xwrite(int, const char *, int);
|
||||||
|
|
||||||
#define outc(c, file) ((file)->nextc == (file)->bufend ? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
|
#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
|
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd January 24, 2019
|
.Dd February 24, 2019
|
||||||
.Dt SH 1
|
.Dt SH 1
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -343,6 +343,18 @@ Useful for debugging.
|
|||||||
.It Li nolog
|
.It Li nolog
|
||||||
Another do-nothing option for POSIX compliance.
|
Another do-nothing option for POSIX compliance.
|
||||||
It only has a long name.
|
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
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
@ -856,12 +868,15 @@ If the keyword
|
|||||||
.Ic !\&
|
.Ic !\&
|
||||||
does not precede the pipeline, the
|
does not precede the pipeline, the
|
||||||
exit status is the exit status of the last command specified
|
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
|
Otherwise, the exit status is the logical
|
||||||
NOT of the exit status of the last command.
|
NOT of that exit status.
|
||||||
That is, if
|
That is, if
|
||||||
the last command returns zero, the exit status is 1; if
|
that status is zero, the exit status is 1; if
|
||||||
the last command returns greater than zero, the exit status
|
that status is greater than zero, the exit status
|
||||||
is zero.
|
is zero.
|
||||||
.Pp
|
.Pp
|
||||||
Because pipeline assignment of standard input or standard
|
Because pipeline assignment of standard input or standard
|
||||||
|
@ -31,6 +31,13 @@ ${PACKAGE}FILES+= killed2.0
|
|||||||
${PACKAGE}FILES+= not1.0
|
${PACKAGE}FILES+= not1.0
|
||||||
${PACKAGE}FILES+= not2.0
|
${PACKAGE}FILES+= not2.0
|
||||||
${PACKAGE}FILES+= path1.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+= redir1.0
|
||||||
${PACKAGE}FILES+= redir2.0
|
${PACKAGE}FILES+= redir2.0
|
||||||
${PACKAGE}FILES+= redir3.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$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd April 27, 2018
|
.Dd February 20, 2019
|
||||||
.Dt ZPOOL 8
|
.Dt ZPOOL 8
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -187,7 +187,7 @@
|
|||||||
.Op Ar device ...
|
.Op Ar device ...
|
||||||
.Nm
|
.Nm
|
||||||
.Cm status
|
.Cm status
|
||||||
.Op Fl vx
|
.Op Fl Dvx
|
||||||
.Op Fl T Cm d Ns | Ns Cm u
|
.Op Fl T Cm d Ns | Ns Cm u
|
||||||
.Op Ar pool
|
.Op Ar pool
|
||||||
.Ar ...
|
.Ar ...
|
||||||
@ -1862,7 +1862,7 @@ section, above, for more information on the available pool properties.
|
|||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.Nm
|
||||||
.Cm status
|
.Cm status
|
||||||
.Op Fl vx
|
.Op Fl Dvx
|
||||||
.Op Fl T Cm d Ns | Ns Cm u
|
.Op Fl T Cm d Ns | Ns Cm u
|
||||||
.Op Ar pool
|
.Op Ar pool
|
||||||
.Ar ...
|
.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
|
because the amount of data in the pool and the other workloads on the system
|
||||||
can change.
|
can change.
|
||||||
.Bl -tag -width indent
|
.Bl -tag -width indent
|
||||||
.It Fl x
|
.It Fl D
|
||||||
Only display status for pools that are exhibiting errors or are otherwise
|
Display a histogram of deduplication statistics, showing the allocated
|
||||||
unavailable.
|
.Pq physically present on disk
|
||||||
Warnings about pools not using the latest on-disk format, having non-native
|
and referenced
|
||||||
block size or disabled features will not be included.
|
.Pq logically referenced in the pool
|
||||||
.It Fl v
|
block counts and sizes by reference count.
|
||||||
Displays verbose data error information, printing out a complete list of all
|
|
||||||
data errors since the last complete pool scrub.
|
|
||||||
.It Fl T Cm d Ns | Ns Cm u
|
.It Fl T Cm d Ns | Ns Cm u
|
||||||
Print a timestamp.
|
Print a timestamp.
|
||||||
.Pp
|
.Pp
|
||||||
@ -1910,6 +1908,14 @@ Use modifier
|
|||||||
.Cm u
|
.Cm u
|
||||||
for unixtime
|
for unixtime
|
||||||
.Pq equals Qq Ic date +%s .
|
.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
|
.El
|
||||||
.It Xo
|
.It Xo
|
||||||
.Nm
|
.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.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3040,9 +3040,6 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
timestamp = dt_buf_oldest(buf, dtp);
|
timestamp = dt_buf_oldest(buf, dtp);
|
||||||
assert(timestamp >= dtp->dt_last_timestamp);
|
|
||||||
dtp->dt_last_timestamp = timestamp;
|
|
||||||
|
|
||||||
if (timestamp == buf->dtbd_timestamp) {
|
if (timestamp == buf->dtbd_timestamp) {
|
||||||
/*
|
/*
|
||||||
* We've reached the end of the time covered
|
* We've reached the end of the time covered
|
||||||
@ -3056,6 +3053,8 @@ dtrace_consume(dtrace_hdl_t *dtp, FILE *fp,
|
|||||||
break;
|
break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
assert(timestamp >= dtp->dt_last_timestamp);
|
||||||
|
dtp->dt_last_timestamp = timestamp;
|
||||||
|
|
||||||
if ((rval = dt_consume_cpu(dtp, fp,
|
if ((rval = dt_consume_cpu(dtp, fp,
|
||||||
buf->dtbd_cpu, buf, B_TRUE, pf, rf, arg)) != 0)
|
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.
|
* immediately retry the allocation.
|
||||||
*/
|
*/
|
||||||
tq->tq_maxalloc_wait++;
|
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,
|
rv = cv_timedwait(&tq->tq_maxalloc_cv,
|
||||||
&tq->tq_lock, ddi_get_lbolt() + hz);
|
&tq->tq_lock, ddi_get_lbolt() + hz);
|
||||||
|
#endif
|
||||||
tq->tq_maxalloc_wait--;
|
tq->tq_maxalloc_wait--;
|
||||||
if (rv > 0)
|
if (rv > 0)
|
||||||
goto again; /* signaled */
|
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<char16_t, char, mbstate_t>)
|
||||||
_LIBCPP_EXTERN_TEMPLATE2(class _LIBCPP_EXTERN_TEMPLATE_TYPE_VIS codecvt_byname<char32_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>
|
template <size_t _Np>
|
||||||
struct __narrow_to_utf8
|
struct __narrow_to_utf8
|
||||||
{
|
{
|
||||||
|
@ -989,15 +989,23 @@ bool X86DAGToDAGISel::matchWrapper(SDValue N, X86ISelAddressMode &AM) {
|
|||||||
if (AM.hasSymbolicDisplacement())
|
if (AM.hasSymbolicDisplacement())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
bool IsRIPRelTLS = false;
|
||||||
bool IsRIPRel = N.getOpcode() == X86ISD::WrapperRIP;
|
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
|
// We can't use an addressing mode in the 64-bit large code model.
|
||||||
// medium code model, we use can use an mode when RIP wrappers are present.
|
// Global TLS addressing is an exception. In the medium code model,
|
||||||
// That signifies access to globals that are known to be "near", such as the
|
// we use can use a mode when RIP wrappers are present.
|
||||||
// GOT itself.
|
// That signifies access to globals that are known to be "near",
|
||||||
|
// such as the GOT itself.
|
||||||
CodeModel::Model M = TM.getCodeModel();
|
CodeModel::Model M = TM.getCodeModel();
|
||||||
if (Subtarget->is64Bit() &&
|
if (Subtarget->is64Bit() &&
|
||||||
(M == CodeModel::Large || (M == CodeModel::Medium && !IsRIPRel)))
|
((M == CodeModel::Large && !IsRIPRelTLS) ||
|
||||||
|
(M == CodeModel::Medium && !IsRIPRel)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Base and index reg must be 0 in order to use %rip as base.
|
// 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,
|
RelExpr X86::getRelExpr(RelType Type, const Symbol &S,
|
||||||
const uint8_t *Loc) const {
|
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) {
|
switch (Type) {
|
||||||
case R_386_8:
|
case R_386_8:
|
||||||
case R_386_16:
|
case R_386_16:
|
||||||
|
@ -76,6 +76,9 @@ template <class ELFT> X86_64<ELFT>::X86_64() {
|
|||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
|
RelExpr X86_64<ELFT>::getRelExpr(RelType Type, const Symbol &S,
|
||||||
const uint8_t *Loc) const {
|
const uint8_t *Loc) const {
|
||||||
|
if (Type == R_X86_64_GOTTPOFF)
|
||||||
|
Config->HasStaticTlsModel = true;
|
||||||
|
|
||||||
switch (Type) {
|
switch (Type) {
|
||||||
case R_X86_64_8:
|
case R_X86_64_8:
|
||||||
case R_X86_64_16:
|
case R_X86_64_16:
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm/Support/CachePruning.h"
|
#include "llvm/Support/CachePruning.h"
|
||||||
#include "llvm/Support/CodeGen.h"
|
#include "llvm/Support/CodeGen.h"
|
||||||
#include "llvm/Support/Endian.h"
|
#include "llvm/Support/Endian.h"
|
||||||
|
#include <atomic>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace lld {
|
namespace lld {
|
||||||
@ -81,6 +82,7 @@ struct VersionDefinition {
|
|||||||
// and such fields have the same name as the corresponding options.
|
// and such fields have the same name as the corresponding options.
|
||||||
// Most fields are initialized by the driver.
|
// Most fields are initialized by the driver.
|
||||||
struct Configuration {
|
struct Configuration {
|
||||||
|
std::atomic<bool> HasStaticTlsModel{false};
|
||||||
uint8_t OSABI = 0;
|
uint8_t OSABI = 0;
|
||||||
llvm::CachePruningPolicy ThinLTOCachePolicy;
|
llvm::CachePruningPolicy ThinLTOCachePolicy;
|
||||||
llvm::StringMap<uint64_t> SectionStartMap;
|
llvm::StringMap<uint64_t> SectionStartMap;
|
||||||
|
@ -1282,6 +1282,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
|
|||||||
}
|
}
|
||||||
if (!Config->ZText)
|
if (!Config->ZText)
|
||||||
DtFlags |= DF_TEXTREL;
|
DtFlags |= DF_TEXTREL;
|
||||||
|
if (Config->HasStaticTlsModel)
|
||||||
|
DtFlags |= DF_STATIC_TLS;
|
||||||
|
|
||||||
if (DtFlags)
|
if (DtFlags)
|
||||||
addInt(DT_FLAGS, DtFlags);
|
addInt(DT_FLAGS, DtFlags);
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
.Nd secure copy (remote file copy program)
|
.Nd secure copy (remote file copy program)
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm scp
|
.Nm scp
|
||||||
.Op Fl 346BCpqrv
|
.Op Fl 346BCpqrTv
|
||||||
.Op Fl c Ar cipher
|
.Op Fl c Ar cipher
|
||||||
.Op Fl F Ar ssh_config
|
.Op Fl F Ar ssh_config
|
||||||
.Op Fl i Ar identity_file
|
.Op Fl i Ar identity_file
|
||||||
@ -207,6 +207,16 @@ to use for the encrypted connection.
|
|||||||
The program must understand
|
The program must understand
|
||||||
.Xr ssh 1
|
.Xr ssh 1
|
||||||
options.
|
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
|
.It Fl v
|
||||||
Verbose mode.
|
Verbose mode.
|
||||||
Causes
|
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
|
* scp - secure remote copy. This is basically patched BSD rcp which
|
||||||
* uses ssh to do the data transfer (instead of using rcmd).
|
* uses ssh to do the data transfer (instead of using rcmd).
|
||||||
@ -94,6 +94,7 @@
|
|||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
@ -375,14 +376,14 @@ void verifydir(char *);
|
|||||||
struct passwd *pwd;
|
struct passwd *pwd;
|
||||||
uid_t userid;
|
uid_t userid;
|
||||||
int errs, remin, remout;
|
int errs, remin, remout;
|
||||||
int pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
int Tflag, pflag, iamremote, iamrecursive, targetshouldbedirectory;
|
||||||
|
|
||||||
#define CMDNEEDS 64
|
#define CMDNEEDS 64
|
||||||
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
|
char cmd[CMDNEEDS]; /* must hold "rcp -r -p -d\0" */
|
||||||
|
|
||||||
int response(void);
|
int response(void);
|
||||||
void rsource(char *, struct stat *);
|
void rsource(char *, struct stat *);
|
||||||
void sink(int, char *[]);
|
void sink(int, char *[], const char *);
|
||||||
void source(int, char *[]);
|
void source(int, char *[]);
|
||||||
void tolocal(int, char *[]);
|
void tolocal(int, char *[]);
|
||||||
void toremote(int, char *[]);
|
void toremote(int, char *[]);
|
||||||
@ -421,8 +422,9 @@ main(int argc, char **argv)
|
|||||||
addargs(&args, "-oRemoteCommand=none");
|
addargs(&args, "-oRemoteCommand=none");
|
||||||
addargs(&args, "-oRequestTTY=no");
|
addargs(&args, "-oRequestTTY=no");
|
||||||
|
|
||||||
fflag = tflag = 0;
|
fflag = Tflag = tflag = 0;
|
||||||
while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q12346S:o:F:")) != -1)
|
while ((ch = getopt(argc, argv,
|
||||||
|
"dfl:prtTvBCc:i:P:q12346S:o:F:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
/* User-visible flags. */
|
/* User-visible flags. */
|
||||||
case '1':
|
case '1':
|
||||||
@ -501,9 +503,13 @@ main(int argc, char **argv)
|
|||||||
setmode(0, O_BINARY);
|
setmode(0, O_BINARY);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case 'T':
|
||||||
|
Tflag = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
@ -534,7 +540,7 @@ main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (tflag) {
|
if (tflag) {
|
||||||
/* Receive data. */
|
/* Receive data. */
|
||||||
sink(argc, argv);
|
sink(argc, argv, NULL);
|
||||||
exit(errs != 0);
|
exit(errs != 0);
|
||||||
}
|
}
|
||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
@ -791,7 +797,7 @@ tolocal(int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
free(bp);
|
free(bp);
|
||||||
sink(1, argv + argc - 1);
|
sink(1, argv + argc - 1, src);
|
||||||
(void) close(remin);
|
(void) close(remin);
|
||||||
remin = remout = -1;
|
remin = remout = -1;
|
||||||
}
|
}
|
||||||
@ -967,7 +973,7 @@ rsource(char *name, struct stat *statp)
|
|||||||
(sizeof(type) != 4 && sizeof(type) != 8))
|
(sizeof(type) != 4 && sizeof(type) != 8))
|
||||||
|
|
||||||
void
|
void
|
||||||
sink(int argc, char **argv)
|
sink(int argc, char **argv, const char *src)
|
||||||
{
|
{
|
||||||
static BUF buffer;
|
static BUF buffer;
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
@ -983,6 +989,7 @@ sink(int argc, char **argv)
|
|||||||
unsigned long long ull;
|
unsigned long long ull;
|
||||||
int setimes, targisdir, wrerrno = 0;
|
int setimes, targisdir, wrerrno = 0;
|
||||||
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
|
char ch, *cp, *np, *targ, *why, *vect[1], buf[2048], visbuf[2048];
|
||||||
|
char *src_copy = NULL, *restrict_pattern = NULL;
|
||||||
struct timeval tv[2];
|
struct timeval tv[2];
|
||||||
|
|
||||||
#define atime tv[0]
|
#define atime tv[0]
|
||||||
@ -1007,6 +1014,17 @@ sink(int argc, char **argv)
|
|||||||
(void) atomicio(vwrite, remout, "", 1);
|
(void) atomicio(vwrite, remout, "", 1);
|
||||||
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode))
|
||||||
targisdir = 1;
|
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) {
|
for (first = 1;; first = 0) {
|
||||||
cp = buf;
|
cp = buf;
|
||||||
if (atomicio(read, remin, cp, 1) != 1)
|
if (atomicio(read, remin, cp, 1) != 1)
|
||||||
@ -1111,6 +1129,9 @@ sink(int argc, char **argv)
|
|||||||
run_err("error: unexpected filename: %s", cp);
|
run_err("error: unexpected filename: %s", cp);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
if (restrict_pattern != NULL &&
|
||||||
|
fnmatch(restrict_pattern, cp, 0) != 0)
|
||||||
|
SCREWUP("filename does not match request");
|
||||||
if (targisdir) {
|
if (targisdir) {
|
||||||
static char *namebuf;
|
static char *namebuf;
|
||||||
static size_t cursize;
|
static size_t cursize;
|
||||||
@ -1148,7 +1169,7 @@ sink(int argc, char **argv)
|
|||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
vect[0] = xstrdup(np);
|
vect[0] = xstrdup(np);
|
||||||
sink(1, vect);
|
sink(1, vect, src);
|
||||||
if (setimes) {
|
if (setimes) {
|
||||||
setimes = 0;
|
setimes = 0;
|
||||||
if (utimes(vect[0], tv) < 0)
|
if (utimes(vect[0], tv) < 0)
|
||||||
@ -1316,7 +1337,7 @@ void
|
|||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
(void) fprintf(stderr,
|
(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");
|
" [-l limit] [-o ssh_option] [-P port] [-S program] source ... target\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,13 @@ FBSD_1.0 {
|
|||||||
vfork;
|
vfork;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FBSD_1.6 {
|
||||||
|
x86_pkru_get_perm;
|
||||||
|
x86_pkru_set_perm;
|
||||||
|
x86_pkru_protect_range;
|
||||||
|
x86_pkru_unprotect_range;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* FreeBSD private ABI
|
* FreeBSD private ABI
|
||||||
|
@ -46,6 +46,13 @@ FBSD_1.0 {
|
|||||||
___tls_get_addr;
|
___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 {
|
FBSDprivate_1.0 {
|
||||||
/* PSEUDO syscalls */
|
/* PSEUDO syscalls */
|
||||||
_getlogin;
|
_getlogin;
|
||||||
|
@ -70,7 +70,6 @@ _posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask)
|
|||||||
{
|
{
|
||||||
acl_t acl_new, acl_old;
|
acl_t acl_new, acl_old;
|
||||||
acl_entry_t entry, entry_new;
|
acl_entry_t entry, entry_new;
|
||||||
acl_permset_t perm;
|
|
||||||
acl_tag_t tag;
|
acl_tag_t tag;
|
||||||
int entry_id, have_mask_entry;
|
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_USER_OBJ:
|
||||||
case ACL_GROUP_OBJ:
|
case ACL_GROUP_OBJ:
|
||||||
case ACL_OTHER:
|
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)
|
if (acl_create_entry(&acl_new, &entry_new) == -1)
|
||||||
goto fail;
|
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)
|
if (acl_copy_entry(entry_new, entry) == -1)
|
||||||
goto fail;
|
goto fail;
|
||||||
assert(_entry_brand(entry_new) == ACL_BRAND_POSIX);
|
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, "
|
"Will try to connect to host='%s', address_family=%d, "
|
||||||
"socket_type=%d\n",
|
"socket_type=%d\n",
|
||||||
host, res->ai_family, res->ai_socktype);
|
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);
|
sock = make_socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||||
error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen);
|
error = connect(sock, (struct sockaddr*)res->ai_addr, res->ai_addrlen);
|
||||||
freeaddrinfo(res);
|
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, "
|
"Will try to bind socket to host='%s', address_family=%d, "
|
||||||
"socket_type=%d\n",
|
"socket_type=%d\n",
|
||||||
host, res->ai_family, res->ai_socktype);
|
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);
|
error = bind(sock, res->ai_addr, res->ai_addrlen);
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
ATF_REQUIRE_EQ_MSG(error, 0, "bind failed: %s", strerror(errno));
|
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
|
static void
|
||||||
server_cat(const char *dest_filename, int server_sock, size_t len)
|
server_cat(const char *dest_filename, int server_sock, size_t len)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer, *buf_window_ptr;
|
||||||
int recv_sock;
|
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)
|
if (buffer == NULL)
|
||||||
err(1, "malloc failed");
|
err(1, "malloc failed");
|
||||||
|
|
||||||
@ -216,32 +226,26 @@ server_cat(const char *dest_filename, int server_sock, size_t len)
|
|||||||
if (recv_sock == -1)
|
if (recv_sock == -1)
|
||||||
err(1, "accept failed");
|
err(1, "accept failed");
|
||||||
|
|
||||||
/*
|
buf_window_ptr = buffer;
|
||||||
* XXX: this assumes the simplest case where all data is received in a
|
received_bytes = 0;
|
||||||
* single recv(2) call.
|
do {
|
||||||
*/
|
recv_ret = recv(recv_sock, buf_window_ptr,
|
||||||
if (recv(recv_sock, buffer, len, 0) == -1)
|
buffer_size - received_bytes, 0);
|
||||||
err(1, "recv failed");
|
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);
|
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(recv_sock);
|
||||||
(void)close(server_sock);
|
(void)close(server_sock);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
|
if (received_bytes != len)
|
||||||
|
errx(1, "received unexpected data: %zd != %zd", received_bytes,
|
||||||
|
len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -667,10 +671,6 @@ hdtr_positive_test(int domain)
|
|||||||
offset = 0;
|
offset = 0;
|
||||||
nbytes = 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++) {
|
for (i = 0; i < nitems(testcases); i++) {
|
||||||
struct sf_hdtr hdtr;
|
struct sf_hdtr hdtr;
|
||||||
char *pattern;
|
char *pattern;
|
||||||
|
@ -3,7 +3,11 @@
|
|||||||
.PATH: ${LIBC_SRCTOP}/x86/sys
|
.PATH: ${LIBC_SRCTOP}/x86/sys
|
||||||
|
|
||||||
SRCS+= \
|
SRCS+= \
|
||||||
__vdso_gettc.c
|
__vdso_gettc.c \
|
||||||
|
pkru.c
|
||||||
|
|
||||||
|
MAN+= \
|
||||||
|
pkru.3
|
||||||
|
|
||||||
.if ${MACHINE_CPUARCH} == "amd64" && ${MK_HYPERV} != "no"
|
.if ${MACHINE_CPUARCH} == "amd64" && ${MK_HYPERV} != "no"
|
||||||
CFLAGS+= -DWANT_HYPERV
|
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
|
# Use the NTP service provided by Amazon
|
||||||
sed -i '' -e 's/^pool/#pool/' \
|
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
|
${DESTDIR}/etc/ntp.conf
|
||||||
|
|
||||||
# The first time the AMI boots, the installed "first boot" scripts
|
# 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];
|
opt = &ip->client->new->options[DHO_INTERFACE_MTU];
|
||||||
if (opt->len == sizeof(u_int16_t)) {
|
if (opt->len == sizeof(u_int16_t)) {
|
||||||
u_int16_t mtu = 0;
|
u_int16_t mtu = 0;
|
||||||
|
u_int16_t old_mtu = 0;
|
||||||
bool supersede = (ip->client->config->default_actions[DHO_INTERFACE_MTU] ==
|
bool supersede = (ip->client->config->default_actions[DHO_INTERFACE_MTU] ==
|
||||||
ACTION_SUPERSEDE);
|
ACTION_SUPERSEDE);
|
||||||
|
|
||||||
@ -871,12 +872,19 @@ bind_lease(struct interface_info *ip)
|
|||||||
else
|
else
|
||||||
mtu = be16dec(opt->data);
|
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) {
|
if (mtu < MIN_MTU) {
|
||||||
/* Treat 0 like a user intentionally doesn't want to change MTU and,
|
/* Treat 0 like a user intentionally doesn't want to change MTU and,
|
||||||
* therefore, warning is not needed */
|
* therefore, warning is not needed */
|
||||||
if (!supersede || mtu != 0)
|
if (!supersede || mtu != 0)
|
||||||
warning("mtu size %u < %d: ignored", (unsigned)mtu, MIN_MTU);
|
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);
|
interface_set_mtu_unpriv(privfd, mtu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -349,9 +349,11 @@ getnextinode(ino_t inumber, int rebuildcg)
|
|||||||
lastinum += fullcnt;
|
lastinum += fullcnt;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
* Flush old contents in case they have been updated.
|
||||||
* If getblk encounters an error, it will already have zeroed
|
* If getblk encounters an error, it will already have zeroed
|
||||||
* out the buffer, so we do not need to do so here.
|
* out the buffer, so we do not need to do so here.
|
||||||
*/
|
*/
|
||||||
|
flush(fswritefd, &inobuf);
|
||||||
getblk(&inobuf, blk, size);
|
getblk(&inobuf, blk, size);
|
||||||
nextinop = inobuf.b_un.b_buf;
|
nextinop = inobuf.b_un.b_buf;
|
||||||
}
|
}
|
||||||
@ -461,6 +463,10 @@ void
|
|||||||
freeinodebuf(void)
|
freeinodebuf(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush old contents in case they have been updated.
|
||||||
|
*/
|
||||||
|
flush(fswritefd, &inobuf);
|
||||||
if (inobuf.b_un.b_buf != NULL)
|
if (inobuf.b_un.b_buf != NULL)
|
||||||
free((char *)inobuf.b_un.b_buf);
|
free((char *)inobuf.b_un.b_buf);
|
||||||
inobuf.b_un.b_buf = NULL;
|
inobuf.b_un.b_buf = NULL;
|
||||||
|
@ -53,7 +53,14 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
#define MAX_FW_SLOTS (7)
|
#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 *
|
const char *
|
||||||
kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key)
|
kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key)
|
||||||
@ -326,15 +333,15 @@ NVME_LOGPAGE(fw,
|
|||||||
static void
|
static void
|
||||||
logpage_help(void)
|
logpage_help(void)
|
||||||
{
|
{
|
||||||
const struct logpage_function * const *f;
|
const struct logpage_function *f;
|
||||||
const char *v;
|
const char *v;
|
||||||
|
|
||||||
fprintf(stderr, "\n");
|
fprintf(stderr, "\n");
|
||||||
fprintf(stderr, "%-8s %-10s %s\n", "Page", "Vendor","Page Name");
|
fprintf(stderr, "%-8s %-10s %s\n", "Page", "Vendor","Page Name");
|
||||||
fprintf(stderr, "-------- ---------- ----------\n");
|
fprintf(stderr, "-------- ---------- ----------\n");
|
||||||
for (f = logpage_begin(); f < logpage_limit(); f++) {
|
SLIST_FOREACH(f, &logpages, link) {
|
||||||
v = (*f)->vendor == NULL ? "-" : (*f)->vendor;
|
v = f->vendor == NULL ? "-" : f->vendor;
|
||||||
fprintf(stderr, "0x%02x %-10s %s\n", (*f)->log_page, v, (*f)->name);
|
fprintf(stderr, "0x%02x %-10s %s\n", f->log_page, v, f->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -352,7 +359,7 @@ logpage(const struct nvme_function *nf, int argc, char *argv[])
|
|||||||
uint32_t nsid, size;
|
uint32_t nsid, size;
|
||||||
void *buf;
|
void *buf;
|
||||||
const char *vendor = NULL;
|
const char *vendor = NULL;
|
||||||
const struct logpage_function * const *f;
|
const struct logpage_function *f;
|
||||||
struct nvme_controller_data cdata;
|
struct nvme_controller_data cdata;
|
||||||
print_fn_t print_fn;
|
print_fn_t print_fn;
|
||||||
uint8_t ns_smart;
|
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
|
* the page is vendor specific, don't match the print function
|
||||||
* unless the vendors match.
|
* unless the vendors match.
|
||||||
*/
|
*/
|
||||||
for (f = logpage_begin(); f < logpage_limit(); f++) {
|
SLIST_FOREACH(f, &logpages, link) {
|
||||||
if ((*f)->vendor != NULL && vendor != NULL &&
|
if (f->vendor != NULL && vendor != NULL &&
|
||||||
strcmp((*f)->vendor, vendor) != 0)
|
strcmp(f->vendor, vendor) != 0)
|
||||||
continue;
|
continue;
|
||||||
if (log_page != (*f)->log_page)
|
if (log_page != f->log_page)
|
||||||
continue;
|
continue;
|
||||||
print_fn = (*f)->print_fn;
|
print_fn = f->print_fn;
|
||||||
size = (*f)->size;
|
size = f->size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -312,19 +312,17 @@ load_dir(const char *dir)
|
|||||||
warnx("Can't load %s: %s", path, dlerror());
|
warnx("Can't load %s: %s", path, dlerror());
|
||||||
else {
|
else {
|
||||||
/*
|
/*
|
||||||
* Add in the top (for cli commands) and logpage (for
|
* Add in the top (for cli commands)linker sets. We have
|
||||||
* logpage parsing) linker sets. We have to do this by
|
* to do this by hand because linker sets aren't
|
||||||
* hand because linker sets aren't automatically merged.
|
* automatically merged.
|
||||||
*/
|
*/
|
||||||
void *begin, *limit;
|
void *begin, *limit;
|
||||||
|
|
||||||
begin = dlsym(h, "__start_set_top");
|
begin = dlsym(h, "__start_set_top");
|
||||||
limit = dlsym(h, "__stop_set_top");
|
limit = dlsym(h, "__stop_set_top");
|
||||||
if (begin)
|
if (begin)
|
||||||
add_to_top(begin, limit);
|
add_to_top(begin, limit);
|
||||||
begin = dlsym(h, "__start_set_logpage");
|
/* log pages use constructors so are done on load */
|
||||||
limit = dlsym(h, "__stop_set_logpage");
|
|
||||||
if (begin)
|
|
||||||
add_to_logpage(begin, limit);
|
|
||||||
}
|
}
|
||||||
free(path);
|
free(path);
|
||||||
path = NULL;
|
path = NULL;
|
||||||
@ -337,7 +335,6 @@ main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
|
|
||||||
add_to_top(NVME_CMD_BEGIN(top), NVME_CMD_LIMIT(top));
|
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("/lib/nvmecontrol");
|
||||||
load_dir("/usr/local/lib/nvmecontrol");
|
load_dir("/usr/local/lib/nvmecontrol");
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#define __NVMECONTROL_H__
|
#define __NVMECONTROL_H__
|
||||||
|
|
||||||
#include <sys/linker_set.h>
|
#include <sys/linker_set.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
#include <dev/nvme/nvme.h>
|
#include <dev/nvme/nvme.h>
|
||||||
|
|
||||||
struct nvme_function;
|
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);
|
typedef void (*print_fn_t)(const struct nvme_controller_data *cdata, void *buf, uint32_t size);
|
||||||
|
|
||||||
struct logpage_function {
|
struct logpage_function {
|
||||||
|
SLIST_ENTRY(logpage_function) link;
|
||||||
uint8_t log_page;
|
uint8_t log_page;
|
||||||
const char *vendor;
|
const char *vendor;
|
||||||
const char *name;
|
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) \
|
#define NVME_LOGPAGE(unique, lp, vend, nam, fn, sz) \
|
||||||
static struct logpage_function unique ## _lpf = { \
|
static struct logpage_function unique ## _lpf = { \
|
||||||
.log_page = lp, \
|
.log_page = lp, \
|
||||||
@ -73,10 +74,8 @@ struct logpage_function {
|
|||||||
.print_fn = fn, \
|
.print_fn = fn, \
|
||||||
.size = sz, \
|
.size = sz, \
|
||||||
} ; \
|
} ; \
|
||||||
NVME_LOGPAGESET(unique ## _lpf)
|
static void logpage_reg_##unique(void) __attribute__((constructor)); \
|
||||||
#define NVME_LOGPAGE_BEGIN SET_BEGIN(NVME_SETNAME(logpage))
|
static void logpage_reg_##unique(void) { logpage_register(&unique##_lpf); }
|
||||||
#define NVME_LOGPAGE_LIMIT SET_LIMIT(NVME_SETNAME(logpage))
|
|
||||||
#define NVME_LOGPAGE_DECLARE(t) SET_DECLARE(NVME_SETNAME(logpage), t)
|
|
||||||
|
|
||||||
#define DEFAULT_SIZE (4096)
|
#define DEFAULT_SIZE (4096)
|
||||||
struct kv_name {
|
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);
|
const char *kv_lookup(const struct kv_name *kv, size_t kv_count, uint32_t key);
|
||||||
|
|
||||||
NVME_CMD_DECLARE(top, struct nvme_function);
|
NVME_CMD_DECLARE(top, struct nvme_function);
|
||||||
NVME_LOGPAGE_DECLARE(struct logpage_function);
|
void logpage_register(struct logpage_function *p);
|
||||||
|
|
||||||
struct set_concat {
|
struct set_concat {
|
||||||
void **begin;
|
void **begin;
|
||||||
@ -105,7 +104,6 @@ void add_to_ ## set(t **b, t **e) \
|
|||||||
#define SET_CONCAT_DECL(set, t) \
|
#define SET_CONCAT_DECL(set, t) \
|
||||||
void add_to_ ## set(t **b, t **e)
|
void add_to_ ## set(t **b, t **e)
|
||||||
SET_CONCAT_DECL(top, struct nvme_function);
|
SET_CONCAT_DECL(top, struct nvme_function);
|
||||||
SET_CONCAT_DECL(logpage, struct logpage_function);
|
|
||||||
|
|
||||||
#define NVME_CTRLR_PREFIX "nvme"
|
#define NVME_CTRLR_PREFIX "nvme"
|
||||||
#define NVME_NS_PREFIX "ns"
|
#define NVME_NS_PREFIX "ns"
|
||||||
|
@ -49,6 +49,7 @@ static const char rcsid[] =
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <sys/vmmeter.h>
|
#include <sys/vmmeter.h>
|
||||||
|
#include <dev/evdev/input.h>
|
||||||
|
|
||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
#include <sys/efi.h>
|
#include <sys/efi.h>
|
||||||
@ -680,6 +681,22 @@ S_vmtotal(size_t l2, void *p)
|
|||||||
return (0);
|
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__
|
#ifdef __amd64__
|
||||||
static int
|
static int
|
||||||
S_efi_map(size_t l2, void *p)
|
S_efi_map(size_t l2, void *p)
|
||||||
@ -983,6 +1000,8 @@ show_var(int *oid, int nlen)
|
|||||||
func = S_loadavg;
|
func = S_loadavg;
|
||||||
else if (strcmp(fmt, "S,vmtotal") == 0)
|
else if (strcmp(fmt, "S,vmtotal") == 0)
|
||||||
func = S_vmtotal;
|
func = S_vmtotal;
|
||||||
|
else if (strcmp(fmt, "S,input_id") == 0)
|
||||||
|
func = S_input_id;
|
||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
else if (strcmp(fmt, "S,efi_map_header") == 0)
|
else if (strcmp(fmt, "S,efi_map_header") == 0)
|
||||||
func = S_efi_map;
|
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
|
.Va net.inet.tcp.cc.abe=1
|
||||||
per: cwnd = (cwnd * CC_NEWRENO_BETA_ECN) / 100.
|
per: cwnd = (cwnd * CC_NEWRENO_BETA_ECN) / 100.
|
||||||
Default is 80.
|
Default is 80.
|
||||||
|
.El
|
||||||
.Sh MIB Variables
|
.Sh MIB Variables
|
||||||
The algorithm exposes these variables in the
|
The algorithm exposes these variables in the
|
||||||
.Va net.inet.tcp.cc.newreno
|
.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
|
.Va net.inet.tcp.cc.abe=1
|
||||||
per: cwnd = (cwnd * beta_ecn) / 100.
|
per: cwnd = (cwnd * beta_ecn) / 100.
|
||||||
Default is 80.
|
Default is 80.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr cc_chd 4 ,
|
.Xr cc_chd 4 ,
|
||||||
.Xr cc_cubic 4 ,
|
.Xr cc_cubic 4 ,
|
||||||
|
@ -202,6 +202,7 @@ The default value is 1024.
|
|||||||
.It Va kern.cam.ctl.max_ports
|
.It Va kern.cam.ctl.max_ports
|
||||||
Specifies the maximum number of ports we support, must be a power of 2.
|
Specifies the maximum number of ports we support, must be a power of 2.
|
||||||
The default value is 256.
|
The default value is 256.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr cfiscsi 4 ,
|
.Xr cfiscsi 4 ,
|
||||||
.Xr cfumass 4 ,
|
.Xr cfumass 4 ,
|
||||||
|
@ -88,6 +88,7 @@ The default value is 0 (off).
|
|||||||
.It Va hw.usb.ehci.no_hs
|
.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.
|
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).
|
The default value is 0 (off).
|
||||||
|
.El
|
||||||
.Sh SYSCTL VARIABLES
|
.Sh SYSCTL VARIABLES
|
||||||
The following variables are available as both
|
The following variables are available as both
|
||||||
.Xr sysctl 8
|
.Xr sysctl 8
|
||||||
|
@ -264,6 +264,7 @@ If
|
|||||||
.Va hw.em.tx_int_delay
|
.Va hw.em.tx_int_delay
|
||||||
is non-zero, this tunable limits the maximum delay in which a transmit
|
is non-zero, this tunable limits the maximum delay in which a transmit
|
||||||
interrupt is generated.
|
interrupt is generated.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width /dev/led/em*
|
.Bl -tag -width /dev/led/em*
|
||||||
.It Pa /dev/led/em*
|
.It Pa /dev/led/em*
|
||||||
|
@ -239,6 +239,7 @@ for more details.
|
|||||||
.Pp
|
.Pp
|
||||||
Packet with unsupported number of segments was queued for sending to the
|
Packet with unsupported number of segments was queued for sending to the
|
||||||
device; packet will be dropped.
|
device; packet will be dropped.
|
||||||
|
.El
|
||||||
.Sh SUPPORT
|
.Sh SUPPORT
|
||||||
If an issue is identified with the released source code with a supported adapter
|
If an issue is identified with the released source code with a supported adapter
|
||||||
email the specific information related to the issue to
|
email the specific information related to the issue to
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
.\" @(#)ip.4 8.2 (Berkeley) 11/30/93
|
.\" @(#)ip.4 8.2 (Berkeley) 11/30/93
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd August 19, 2018
|
.Dd February 22, 2019
|
||||||
.Dt IP 4
|
.Dt IP 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -571,32 +571,55 @@ To join a multicast group, use the
|
|||||||
.Dv IP_ADD_MEMBERSHIP
|
.Dv IP_ADD_MEMBERSHIP
|
||||||
option:
|
option:
|
||||||
.Bd -literal
|
.Bd -literal
|
||||||
struct ip_mreq mreq;
|
struct ip_mreqn mreqn;
|
||||||
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
|
setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, sizeof(mreqn));
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
where
|
where
|
||||||
.Fa mreq
|
.Fa mreqn
|
||||||
is the following structure:
|
is the following structure:
|
||||||
.Bd -literal
|
.Bd -literal
|
||||||
struct ip_mreq {
|
struct ip_mreqn {
|
||||||
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
struct in_addr imr_multiaddr; /* IP multicast address of group */
|
||||||
struct in_addr imr_interface; /* local IP address of interface */
|
struct in_addr imr_interface; /* local IP address of interface */
|
||||||
|
int imr_ifindex; /* interface index */
|
||||||
}
|
}
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
.Va imr_interface
|
.Va imr_ifindex
|
||||||
should be set to the
|
should be set to the index of a particular multicast-capable interface if
|
||||||
.Tn IP
|
|
||||||
address of a particular multicast-capable interface if
|
|
||||||
the host is multihomed.
|
the host is multihomed.
|
||||||
It may be set to
|
If
|
||||||
.Dv INADDR_ANY
|
.Va imr_ifindex
|
||||||
to choose the default interface, although this is not recommended;
|
is non-zero, value of
|
||||||
this is considered to be the first interface corresponding
|
.Va imr_interface
|
||||||
to the default route.
|
is ignored.
|
||||||
Otherwise, the first multicast-capable interface
|
Otherwise, if
|
||||||
configured in the system will be used.
|
.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
|
.Pp
|
||||||
Prior to
|
Prior to
|
||||||
.Fx 7.0 ,
|
.Fx 7.0 ,
|
||||||
|
@ -114,7 +114,7 @@ Unable to obtain adapter or drive configuration.
|
|||||||
A buffer input/output error has occurred.
|
A buffer input/output error has occurred.
|
||||||
.Bq Er ENXIO
|
.Bq Er ENXIO
|
||||||
.El
|
.El
|
||||||
.Ss General adapter errors:
|
.Ss General adapter errors :
|
||||||
.Bl -diag
|
.Bl -diag
|
||||||
.It Attaching bus failed
|
.It Attaching bus failed
|
||||||
.Pp
|
.Pp
|
||||||
@ -146,7 +146,7 @@ The adapter is disabled.
|
|||||||
.Pp
|
.Pp
|
||||||
The driver was unable to allocate resources for the device.
|
The driver was unable to allocate resources for the device.
|
||||||
.El
|
.El
|
||||||
.Ss Error messages due to DMA:
|
.Ss Error messages due to DMA :
|
||||||
.Bl -diag
|
.Bl -diag
|
||||||
.It can't alloc command dma tag
|
.It can't alloc command dma tag
|
||||||
.It can't alloc SG dma tag
|
.It can't alloc SG dma tag
|
||||||
@ -155,7 +155,7 @@ The driver was unable to allocate resources for the device.
|
|||||||
.Pp
|
.Pp
|
||||||
Failure to map or allocate DMA resources.
|
Failure to map or allocate DMA resources.
|
||||||
.El
|
.El
|
||||||
.Ss Cache, buffer, and command errors:
|
.Ss Cache, buffer, and command errors :
|
||||||
.Bl -diag
|
.Bl -diag
|
||||||
.It failed to initialize command buffers
|
.It failed to initialize command buffers
|
||||||
.It no mem for command slots!
|
.It no mem for command slots!
|
||||||
|
@ -110,6 +110,7 @@ To enable/disable driver RSS support
|
|||||||
.It Va hw.lio.hwlro
|
.It Va hw.lio.hwlro
|
||||||
.Pp
|
.Pp
|
||||||
To enable/disable hardware LRO
|
To enable/disable hardware LRO
|
||||||
|
.El
|
||||||
.Sh SUPPORT
|
.Sh SUPPORT
|
||||||
For general information and support,
|
For general information and support,
|
||||||
go to the Cavium support website at:
|
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
|
This variable reports whether the
|
||||||
.Nm
|
.Nm
|
||||||
driver accepts unmapped I/O for this unit.
|
driver accepts unmapped I/O for this unit.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width ".Pa /dev/nda*" -compact
|
.Bl -tag -width ".Pa /dev/nda*" -compact
|
||||||
.It Pa /dev/nda*
|
.It Pa /dev/nda*
|
||||||
NVMe storage device nodes
|
NVMe storage device nodes
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr nvme 4 ,
|
.Xr nvd 4 ,
|
||||||
.Xr nvd 4
|
.Xr nvme 4
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -387,6 +387,7 @@ route add default x.y.0.1
|
|||||||
msg igb0_NAT: setdlt 1
|
msg igb0_NAT: setdlt 1
|
||||||
msg igb0_NAT: setaliasaddr x.y.8.35
|
msg igb0_NAT: setaliasaddr x.y.8.35
|
||||||
SEQ
|
SEQ
|
||||||
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr libalias 3 ,
|
.Xr libalias 3 ,
|
||||||
.Xr ng_ipfw 4 ,
|
.Xr ng_ipfw 4 ,
|
||||||
|
@ -70,6 +70,7 @@ tunables:
|
|||||||
Debug output level, where 0 is debugging disabled and larger values increase
|
Debug output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr ehci 4 ,
|
.Xr ehci 4 ,
|
||||||
.Xr uhci 4 ,
|
.Xr uhci 4 ,
|
||||||
|
@ -386,7 +386,7 @@ specified by the
|
|||||||
member, otherwise fail.
|
member, otherwise fail.
|
||||||
.It PCIIO_BAR_MMAP_EXCL
|
.It PCIIO_BAR_MMAP_EXCL
|
||||||
Must be used together with
|
Must be used together with
|
||||||
.Vd PCIIO_BAR_MMAP_FIXED
|
.Dv PCIIO_BAR_MMAP_FIXED
|
||||||
If the specified base contains already established mappings, the
|
If the specified base contains already established mappings, the
|
||||||
operation fails instead of implicitly unmapping them.
|
operation fails instead of implicitly unmapping them.
|
||||||
.It PCIIO_BAR_MMAP_RW
|
.It PCIIO_BAR_MMAP_RW
|
||||||
|
@ -176,7 +176,7 @@ and tested with
|
|||||||
.Xr getsockopt 2
|
.Xr getsockopt 2
|
||||||
or
|
or
|
||||||
.Xr sctp_opt_info 3 :
|
.Xr sctp_opt_info 3 :
|
||||||
.Bl -tag -indent
|
.Bl -tag -width indent
|
||||||
.It Dv SCTP_NODELAY
|
.It Dv SCTP_NODELAY
|
||||||
Under most circumstances,
|
Under most circumstances,
|
||||||
.Tn SCTP
|
.Tn SCTP
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd September 05, 2015
|
.Dd September 5, 2015
|
||||||
.Dt SES 4
|
.Dt SES 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -399,11 +399,15 @@ The summation of num_inbound_tcp_pkts and num_outbound_tcp_pkts.
|
|||||||
.El
|
.El
|
||||||
.Bl -tag -offset indent -width Va
|
.Bl -tag -offset indent -width Va
|
||||||
.It Va num_inbound_skipped_pkts_malloc
|
.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
|
.El
|
||||||
.Bl -tag -offset indent -width Va
|
.Bl -tag -offset indent -width Va
|
||||||
.It Va num_outbound_skipped_pkts_malloc
|
.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
|
.El
|
||||||
.Bl -tag -offset indent -width Va
|
.Bl -tag -offset indent -width Va
|
||||||
.It Va num_inbound_skipped_pkts_mtx
|
.It Va num_inbound_skipped_pkts_mtx
|
||||||
@ -759,8 +763,10 @@ Ideally,
|
|||||||
.Nm
|
.Nm
|
||||||
should intercept packets after they have been processed by the TCP layer i.e.
|
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
|
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
|
.Fn tcp_input ,
|
||||||
processed by tcp_output().
|
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
|
The current code still gives satisfactory granularity though, as inbound events
|
||||||
tend to trigger outbound events, allowing the cause-and-effect to be observed
|
tend to trigger outbound events, allowing the cause-and-effect to be observed
|
||||||
indirectly by capturing the state on outbound events as well.
|
indirectly by capturing the state on outbound events as well.
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
.\" SUCH DAMAGE.
|
.\" SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$ stable/10/share/man/man4/smartpqi.4 195614 2017-01-11 08:10:18Z jkim $
|
.\" $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
|
.Dt SMARTPQI 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -37,6 +37,7 @@ kernel configuration file:
|
|||||||
.Cd device pci
|
.Cd device pci
|
||||||
.Cd device scbus
|
.Cd device scbus
|
||||||
.Cd device smartpqi
|
.Cd device smartpqi
|
||||||
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
Alternatively, to load the driver as a
|
Alternatively, to load the driver as a
|
||||||
module at boot time, place the following line in
|
module at boot time, place the following line in
|
||||||
@ -81,10 +82,10 @@ smartpqi management interface
|
|||||||
.Xr kld 4 ,
|
.Xr kld 4 ,
|
||||||
.Xr linux 4 ,
|
.Xr linux 4 ,
|
||||||
.Xr scsi 4 ,
|
.Xr scsi 4 ,
|
||||||
.Xr kldload 8
|
.Xr kldload 8 ,
|
||||||
.Xr pass 4
|
.Xr pass 4 ,
|
||||||
.Xr xpt 4
|
.Xr xpt 4 ,
|
||||||
.Xr loader.conf 5
|
.Xr loader.conf 5 ,
|
||||||
.Xr camcontrol 8
|
.Xr camcontrol 8
|
||||||
.Rs
|
.Rs
|
||||||
.%T "Microsemi Website"
|
.%T "Microsemi Website"
|
||||||
@ -95,7 +96,7 @@ The
|
|||||||
.Nm
|
.Nm
|
||||||
driver first appeared in
|
driver first appeared in
|
||||||
.Fx 11.1 .
|
.Fx 11.1 .
|
||||||
.Sh AUTHOR
|
.Sh AUTHORS
|
||||||
.An Murthy Bhat
|
.An Murthy Bhat
|
||||||
.Aq murthy.bhat@microsemi.com
|
.Aq murthy.bhat@microsemi.com
|
||||||
.Sh BUGS
|
.Sh BUGS
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
.Cd "options SC_ALT_MOUSE_IMAGE"
|
.Cd "options SC_ALT_MOUSE_IMAGE"
|
||||||
.Cd "options SC_CUT_SEPCHARS=_characters_"
|
.Cd "options SC_CUT_SEPCHARS=_characters_"
|
||||||
.Cd "options SC_CUT_SPACES2TABS"
|
.Cd "options SC_CUT_SPACES2TABS"
|
||||||
|
.Cd "options SC_DFLT_TERM"
|
||||||
.Cd "options SC_DISABLE_KDBKEY"
|
.Cd "options SC_DISABLE_KDBKEY"
|
||||||
.Cd "options SC_DISABLE_REBOOT"
|
.Cd "options SC_DISABLE_REBOOT"
|
||||||
.Cd "options SC_HISTORY_SIZE=N"
|
.Cd "options SC_HISTORY_SIZE=N"
|
||||||
@ -48,6 +49,9 @@
|
|||||||
.Cd "options SC_NO_PALETTE_LOADING"
|
.Cd "options SC_NO_PALETTE_LOADING"
|
||||||
.Cd "options SC_NO_SUSPEND_VTYSWITCH"
|
.Cd "options SC_NO_SUSPEND_VTYSWITCH"
|
||||||
.Cd "options SC_NO_SYSMOUSE"
|
.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_PIXEL_MODE"
|
||||||
.Cd "options SC_TWOBUTTON_MOUSE"
|
.Cd "options SC_TWOBUTTON_MOUSE"
|
||||||
.Cd "options SC_NORM_ATTR=_attribute_"
|
.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.
|
when copying data into cut buffer.
|
||||||
This might be useful to preserve
|
This might be useful to preserve
|
||||||
indentation when copying tab-indented text.
|
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
|
.It Dv SC_DISABLE_KDBKEY
|
||||||
This option disables the ``debug'' key combination (by default, it is
|
This option disables the ``debug'' key combination (by default, it is
|
||||||
.Dv Alt-Esc ,
|
.Dv Alt-Esc ,
|
||||||
@ -409,6 +415,15 @@ will fail if this option is defined.
|
|||||||
This option implies the
|
This option implies the
|
||||||
.Dv SC_NO_CUTPASTE
|
.Dv SC_NO_CUTPASTE
|
||||||
option too.
|
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
|
.El
|
||||||
.Ss Driver Flags
|
.Ss Driver Flags
|
||||||
The following driver flags can be used to control the
|
The following driver flags can be used to control the
|
||||||
|
@ -55,7 +55,6 @@ Make sure that
|
|||||||
.Xr moused 8
|
.Xr moused 8
|
||||||
is running, otherwise the user process will not see any data coming from
|
is running, otherwise the user process will not see any data coming from
|
||||||
the mouse.
|
the mouse.
|
||||||
.Pp
|
|
||||||
.Ss Operation Levels
|
.Ss Operation Levels
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -597,8 +597,7 @@ The default TCP function block (TCP stack).
|
|||||||
.It Va functions_inherit_listen_socket_stack
|
.It Va functions_inherit_listen_socket_stack
|
||||||
Determines whether to inherit listen socket's tcp stack or use the current
|
Determines whether to inherit listen socket's tcp stack or use the current
|
||||||
system default tcp stack, as defined by
|
system default tcp stack, as defined by
|
||||||
.Va functions_default
|
.Va functions_default .
|
||||||
.Pc .
|
|
||||||
Default is true.
|
Default is true.
|
||||||
.It Va insecure_rst
|
.It Va insecure_rst
|
||||||
Use criteria defined in RFC793 instead of RFC5961 for accepting RST segments.
|
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
|
utility that is launched by
|
||||||
.Xr devd 8
|
.Xr devd 8
|
||||||
when the device is inserted.
|
when the device is inserted.
|
||||||
.Xr uathload
|
.Xr uathload 8
|
||||||
includes the firmware in the binary program.
|
includes the firmware in the binary program.
|
||||||
This firmware is licensed for general use and is included in the base system.
|
This firmware is licensed for general use and is included in the base system.
|
||||||
.Sh HARDWARE
|
.Sh HARDWARE
|
||||||
|
@ -81,6 +81,7 @@ driver will mark terminals as console devices when operating in device mode.
|
|||||||
Default is 1.
|
Default is 1.
|
||||||
.It Va hw.usb.ucom.pps_mode
|
.It Va hw.usb.ucom.pps_mode
|
||||||
Enables and configure PPS capture mode as described below.
|
Enables and configure PPS capture mode as described below.
|
||||||
|
.El
|
||||||
.Sh Pulse Per Second (PPS) Timing Interface
|
.Sh Pulse Per Second (PPS) Timing Interface
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -302,6 +302,7 @@ tunables:
|
|||||||
Debug output level, where 0 is debugging disabled and larger values increase
|
Debug output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width ".Pa /dev/ugen Ns Ar N Ns Pa \&. Ns Ar E" -compact
|
.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
|
.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 output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr ehci 4 ,
|
.Xr ehci 4 ,
|
||||||
.Xr ohci 4 ,
|
.Xr ohci 4 ,
|
||||||
|
@ -155,6 +155,7 @@ tunables:
|
|||||||
Debug output level, where 0 is debugging disabled and larger values increase
|
Debug output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width ".Pa /dev/uhid?"
|
.Bl -tag -width ".Pa /dev/uhid?"
|
||||||
.It 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 output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width ".Pa /dev/kbd*" -compact
|
.Bl -tag -width ".Pa /dev/kbd*" -compact
|
||||||
.It Pa /dev/kbd*
|
.It Pa /dev/kbd*
|
||||||
|
@ -77,4 +77,7 @@ corresponding callout initial-state and lock-state devices
|
|||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm
|
.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 output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width /dev/ums0 -compact
|
.Bl -tag -width /dev/ums0 -compact
|
||||||
.It Pa /dev/ums0
|
.It Pa /dev/ums0
|
||||||
|
@ -191,6 +191,7 @@ tunables:
|
|||||||
Debug output level, where 0 is debugging disabled and larger values increase
|
Debug output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width "/dev/ttyU*.init" -compact
|
.Bl -tag -width "/dev/ttyU*.init" -compact
|
||||||
.It Pa /dev/ttyU*
|
.It Pa /dev/ttyU*
|
||||||
|
@ -142,6 +142,7 @@ tunables:
|
|||||||
Debug output level, where 0 is debugging disabled and larger values increase
|
Debug output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
The
|
The
|
||||||
.Tn USB
|
.Tn USB
|
||||||
@ -173,7 +174,7 @@ specifications can be found at:
|
|||||||
.Xr uvscom 4 ,
|
.Xr uvscom 4 ,
|
||||||
.Xr xhci 4
|
.Xr xhci 4
|
||||||
.Xr usbconfig 8 ,
|
.Xr usbconfig 8 ,
|
||||||
.Xr usbdi 9 ,
|
.Xr usbdi 9
|
||||||
.Sh STANDARDS
|
.Sh STANDARDS
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -90,6 +90,7 @@ for callout ports
|
|||||||
.It Pa /dev/cuaU*.init
|
.It Pa /dev/cuaU*.init
|
||||||
.It Pa /dev/cuaU*.lock
|
.It Pa /dev/cuaU*.lock
|
||||||
corresponding callout initial-state and lock-state devices
|
corresponding callout initial-state and lock-state devices
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr tty 4 ,
|
.Xr tty 4 ,
|
||||||
.Xr ucom 4 ,
|
.Xr ucom 4 ,
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\" $Id: $
|
.\" $Id: $
|
||||||
.\"
|
.\"
|
||||||
.Dd Jan 9, 2019
|
.Dd January 9, 2019
|
||||||
.Dt VALE 4
|
.Dt VALE 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -59,6 +59,7 @@ virtual machine itself.
|
|||||||
.Rs
|
.Rs
|
||||||
.%T "VMware vSockets Documentation"
|
.%T "VMware vSockets Documentation"
|
||||||
.%U https://www.vmware.com/support/developer/vmci-sdk/
|
.%U https://www.vmware.com/support/developer/vmci-sdk/
|
||||||
|
.Re
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
The
|
The
|
||||||
.Nm
|
.Nm
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
.Nm vmm.ko
|
.Nm vmm.ko
|
||||||
.Nd "bhyve virtual machine monitor"
|
.Nd "bhyve virtual machine monitor"
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Pp
|
|
||||||
To load the driver as a module at boot, add this line to
|
To load the driver as a module at boot, add this line to
|
||||||
.Xr loader.conf 5 :
|
.Xr loader.conf 5 :
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
@ -47,7 +46,7 @@ kldload vmm
|
|||||||
.Nm
|
.Nm
|
||||||
provides the kernel portion of the
|
provides the kernel portion of the
|
||||||
.Xr bhyve 4
|
.Xr bhyve 4
|
||||||
hypervisor.
|
hypervisor.
|
||||||
.Pp
|
.Pp
|
||||||
An Intel CPU with VT-x/EPT or AMD CPU with SVM support is required.
|
An Intel CPU with VT-x/EPT or AMD CPU with SVM support is required.
|
||||||
.Pp
|
.Pp
|
||||||
|
@ -316,7 +316,7 @@ command.
|
|||||||
.Xr wlan_xauth 4 ,
|
.Xr wlan_xauth 4 ,
|
||||||
.Xr hostapd 8 ,
|
.Xr hostapd 8 ,
|
||||||
.Xr ifconfig 8 ,
|
.Xr ifconfig 8 ,
|
||||||
.Xr wpa_supplicant 8 .
|
.Xr wpa_supplicant 8
|
||||||
.Rs
|
.Rs
|
||||||
.%T HCF Light programming specification
|
.%T HCF Light programming specification
|
||||||
.%U http://web.archive.org/web/20040130141721/http://wavelan.com/
|
.%U http://web.archive.org/web/20040130141721/http://wavelan.com/
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd October 24 2018
|
.Dd October 24, 2018
|
||||||
.Dt XE 4
|
.Dt XE 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -67,6 +67,7 @@ tunables:
|
|||||||
Debug output level, where 0 is debugging disabled and larger values increase
|
Debug output level, where 0 is debugging disabled and larger values increase
|
||||||
debug message verbosity.
|
debug message verbosity.
|
||||||
Default is 0.
|
Default is 0.
|
||||||
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr ehci 4 ,
|
.Xr ehci 4 ,
|
||||||
.Xr ohci 4 ,
|
.Xr ohci 4 ,
|
||||||
|
@ -203,7 +203,7 @@ macro is usually not necessary.
|
|||||||
.It
|
.It
|
||||||
Use
|
Use
|
||||||
.Sy \&Va
|
.Sy \&Va
|
||||||
instead of:
|
instead of
|
||||||
.Sy \&Dv
|
.Sy \&Dv
|
||||||
for
|
for
|
||||||
.Xr sysctl 8
|
.Xr sysctl 8
|
||||||
|
@ -25,11 +25,14 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd June 1, 2018
|
.Dd February 25, 2019
|
||||||
.Dt SYSCTL 9
|
.Dt SYSCTL 9
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm SYSCTL_DECL ,
|
.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_INT ,
|
||||||
.Nm SYSCTL_ADD_LONG ,
|
.Nm SYSCTL_ADD_LONG ,
|
||||||
.Nm SYSCTL_ADD_NODE ,
|
.Nm SYSCTL_ADD_NODE ,
|
||||||
@ -42,6 +45,8 @@
|
|||||||
.Nm SYSCTL_ADD_S16 ,
|
.Nm SYSCTL_ADD_S16 ,
|
||||||
.Nm SYSCTL_ADD_S32 ,
|
.Nm SYSCTL_ADD_S32 ,
|
||||||
.Nm SYSCTL_ADD_S64 ,
|
.Nm SYSCTL_ADD_S64 ,
|
||||||
|
.Nm SYSCTL_ADD_SBINTIME_MSEC ,
|
||||||
|
.Nm SYSCTL_ADD_SBINTIME_USEC ,
|
||||||
.Nm SYSCTL_ADD_STRING ,
|
.Nm SYSCTL_ADD_STRING ,
|
||||||
.Nm SYSCTL_ADD_STRUCT ,
|
.Nm SYSCTL_ADD_STRUCT ,
|
||||||
.Nm SYSCTL_ADD_U8 ,
|
.Nm SYSCTL_ADD_U8 ,
|
||||||
@ -52,10 +57,15 @@
|
|||||||
.Nm SYSCTL_ADD_UINT ,
|
.Nm SYSCTL_ADD_UINT ,
|
||||||
.Nm SYSCTL_ADD_ULONG ,
|
.Nm SYSCTL_ADD_ULONG ,
|
||||||
.Nm SYSCTL_ADD_UQUAD ,
|
.Nm SYSCTL_ADD_UQUAD ,
|
||||||
|
.Nm SYSCTL_ADD_UMA_CUR ,
|
||||||
|
.Nm SYSCTL_ADD_UMA_MAX ,
|
||||||
.Nm SYSCTL_CHILDREN ,
|
.Nm SYSCTL_CHILDREN ,
|
||||||
.Nm SYSCTL_STATIC_CHILDREN ,
|
.Nm SYSCTL_STATIC_CHILDREN ,
|
||||||
.Nm SYSCTL_NODE_CHILDREN ,
|
.Nm SYSCTL_NODE_CHILDREN ,
|
||||||
.Nm SYSCTL_PARENT ,
|
.Nm SYSCTL_PARENT ,
|
||||||
|
.Nm SYSCTL_BOOL ,
|
||||||
|
.Nm SYSCTL_COUNTER_U64 ,
|
||||||
|
.Nm SYSCTL_COUNTER_U64_ARRAY ,
|
||||||
.Nm SYSCTL_INT ,
|
.Nm SYSCTL_INT ,
|
||||||
.Nm SYSCTL_INT_WITH_LABEL ,
|
.Nm SYSCTL_INT_WITH_LABEL ,
|
||||||
.Nm SYSCTL_LONG ,
|
.Nm SYSCTL_LONG ,
|
||||||
@ -69,6 +79,8 @@
|
|||||||
.Nm SYSCTL_S16 ,
|
.Nm SYSCTL_S16 ,
|
||||||
.Nm SYSCTL_S32 ,
|
.Nm SYSCTL_S32 ,
|
||||||
.Nm SYSCTL_S64 ,
|
.Nm SYSCTL_S64 ,
|
||||||
|
.Nm SYSCTL_SBINTIME_MSEC ,
|
||||||
|
.Nm SYSCTL_SBINTIME_USEC ,
|
||||||
.Nm SYSCTL_STRING ,
|
.Nm SYSCTL_STRING ,
|
||||||
.Nm SYSCTL_STRUCT ,
|
.Nm SYSCTL_STRUCT ,
|
||||||
.Nm SYSCTL_U8 ,
|
.Nm SYSCTL_U8 ,
|
||||||
@ -77,13 +89,47 @@
|
|||||||
.Nm SYSCTL_U64 ,
|
.Nm SYSCTL_U64 ,
|
||||||
.Nm SYSCTL_UINT ,
|
.Nm SYSCTL_UINT ,
|
||||||
.Nm SYSCTL_ULONG ,
|
.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
|
.Nd Dynamic and static sysctl MIB creation functions
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.In sys/param.h
|
.In sys/param.h
|
||||||
.In sys/sysctl.h
|
.In sys/sysctl.h
|
||||||
.Fn SYSCTL_DECL name
|
.Fn SYSCTL_DECL name
|
||||||
.Ft struct sysctl_oid *
|
.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
|
.Fo SYSCTL_ADD_INT
|
||||||
.Fa "struct sysctl_ctx_list *ctx"
|
.Fa "struct sysctl_ctx_list *ctx"
|
||||||
.Fa "struct sysctl_oid_list *parent"
|
.Fa "struct sysctl_oid_list *parent"
|
||||||
@ -214,6 +260,26 @@
|
|||||||
.Fa "const char *descr"
|
.Fa "const char *descr"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft struct sysctl_oid *
|
.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
|
.Fo SYSCTL_ADD_STRING
|
||||||
.Fa "struct sysctl_ctx_list *ctx"
|
.Fa "struct sysctl_ctx_list *ctx"
|
||||||
.Fa "struct sysctl_oid_list *parent"
|
.Fa "struct sysctl_oid_list *parent"
|
||||||
@ -311,6 +377,27 @@
|
|||||||
.Fa "const char *descr"
|
.Fa "const char *descr"
|
||||||
.Fc
|
.Fc
|
||||||
.Ft struct sysctl_oid *
|
.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
|
.Fo SYSCTL_ADD_UAUTO
|
||||||
.Fa "struct sysctl_ctx_list *ctx"
|
.Fa "struct sysctl_ctx_list *ctx"
|
||||||
.Fa "struct sysctl_oid_list *parent"
|
.Fa "struct sysctl_oid_list *parent"
|
||||||
@ -337,6 +424,9 @@
|
|||||||
.Fo SYSCTL_PARENT
|
.Fo SYSCTL_PARENT
|
||||||
.Fa "struct sysctl_oid *oid"
|
.Fa "struct sysctl_oid *oid"
|
||||||
.Fc
|
.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 parent number name ctlflags ptr val descr
|
||||||
.Fn SYSCTL_INT_WITH_LABEL parent number name ctlflags ptr val descr label
|
.Fn SYSCTL_INT_WITH_LABEL parent number name ctlflags ptr val descr label
|
||||||
.Fn SYSCTL_LONG parent number name ctlflags ptr val descr
|
.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_S16 parent number name ctlflags ptr val descr
|
||||||
.Fn SYSCTL_S32 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_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_STRING parent number name ctlflags arg len descr
|
||||||
.Fn SYSCTL_STRUCT parent number name ctlflags ptr struct_type descr
|
.Fn SYSCTL_STRUCT parent number name ctlflags ptr struct_type descr
|
||||||
.Fn SYSCTL_U8 parent number name ctlflags ptr val 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_UINT parent number name ctlflags ptr val descr
|
||||||
.Fn SYSCTL_ULONG 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_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
|
.Sh DESCRIPTION
|
||||||
The
|
The
|
||||||
.Nm SYSCTL
|
.Nm SYSCTL
|
||||||
@ -416,6 +510,7 @@ argument.
|
|||||||
For string type OIDs a length of zero means that
|
For string type OIDs a length of zero means that
|
||||||
.Xr strlen 3
|
.Xr strlen 3
|
||||||
will be used to get the length of the string at each access to the OID.
|
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
|
.It Fa ptr
|
||||||
Pointer to sysctl variable or string data.
|
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
|
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.
|
accessible, or needs to be processed before exporting.
|
||||||
.Sh CREATING A STATIC SYSCTL
|
.Sh CREATING A STATIC SYSCTL
|
||||||
Static sysctls are declared using one of the
|
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 ,
|
||||||
.Fn SYSCTL_INT_WITH_LABEL ,
|
.Fn SYSCTL_INT_WITH_LABEL ,
|
||||||
.Fn SYSCTL_LONG ,
|
.Fn SYSCTL_LONG ,
|
||||||
@ -557,6 +655,8 @@ Static sysctls are declared using one of the
|
|||||||
.Fn SYSCTL_S16 ,
|
.Fn SYSCTL_S16 ,
|
||||||
.Fn SYSCTL_S32 ,
|
.Fn SYSCTL_S32 ,
|
||||||
.Fn SYSCTL_S64 ,
|
.Fn SYSCTL_S64 ,
|
||||||
|
.Fn SYSCTL_SBINTIME_MSEC ,
|
||||||
|
.Fn SYSCTL_SBINTIME_USEC ,
|
||||||
.Fn SYSCTL_STRING ,
|
.Fn SYSCTL_STRING ,
|
||||||
.Fn SYSCTL_STRUCT ,
|
.Fn SYSCTL_STRUCT ,
|
||||||
.Fn SYSCTL_U8 ,
|
.Fn SYSCTL_U8 ,
|
||||||
@ -564,12 +664,17 @@ Static sysctls are declared using one of the
|
|||||||
.Fn SYSCTL_U32 ,
|
.Fn SYSCTL_U32 ,
|
||||||
.Fn SYSCTL_U64 ,
|
.Fn SYSCTL_U64 ,
|
||||||
.Fn SYSCTL_UINT ,
|
.Fn SYSCTL_UINT ,
|
||||||
.Fn SYSCTL_ULONG
|
.Fn SYSCTL_ULONG ,
|
||||||
|
.Fn SYSCTL_UQUAD ,
|
||||||
|
.Fn SYSCTL_UMA_CUR
|
||||||
or
|
or
|
||||||
.Fn SYSCTL_UQUAD
|
.Fn SYSCTL_UMA_MAX
|
||||||
macros.
|
macros.
|
||||||
.Sh CREATING A DYNAMIC SYSCTL
|
.Sh CREATING A DYNAMIC SYSCTL
|
||||||
Dynamic nodes are created using one of the
|
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_INT ,
|
||||||
.Fn SYSCTL_ADD_LONG ,
|
.Fn SYSCTL_ADD_LONG ,
|
||||||
.Fn SYSCTL_ADD_NODE ,
|
.Fn SYSCTL_ADD_NODE ,
|
||||||
@ -582,6 +687,8 @@ Dynamic nodes are created using one of the
|
|||||||
.Fn SYSCTL_ADD_S16 ,
|
.Fn SYSCTL_ADD_S16 ,
|
||||||
.Fn SYSCTL_ADD_S32 ,
|
.Fn SYSCTL_ADD_S32 ,
|
||||||
.Fn SYSCTL_ADD_S64 ,
|
.Fn SYSCTL_ADD_S64 ,
|
||||||
|
.Fn SYSCTL_ADD_SBINTIME_MSEC ,
|
||||||
|
.Fn SYSCTL_ADD_SBINTIME_USEC ,
|
||||||
.Fn SYSCTL_ADD_STRING ,
|
.Fn SYSCTL_ADD_STRING ,
|
||||||
.Fn SYSCTL_ADD_STRUCT ,
|
.Fn SYSCTL_ADD_STRUCT ,
|
||||||
.Fn SYSCTL_ADD_U8 ,
|
.Fn SYSCTL_ADD_U8 ,
|
||||||
@ -591,8 +698,10 @@ Dynamic nodes are created using one of the
|
|||||||
.Fn SYSCTL_ADD_UAUTO ,
|
.Fn SYSCTL_ADD_UAUTO ,
|
||||||
.Fn SYSCTL_ADD_UINT ,
|
.Fn SYSCTL_ADD_UINT ,
|
||||||
.Fn SYSCTL_ADD_ULONG ,
|
.Fn SYSCTL_ADD_ULONG ,
|
||||||
|
.Fn SYSCTL_ADD_UQUAD ,
|
||||||
|
.Fn SYSCTL_ADD_UMA_CUR
|
||||||
or
|
or
|
||||||
.Fn SYSCTL_UQUAD
|
.Fn SYSCTL_ADD_UMA_MAX
|
||||||
functions.
|
functions.
|
||||||
See
|
See
|
||||||
.Xr sysctl_remove_oid 9
|
.Xr sysctl_remove_oid 9
|
||||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
*/
|
*/
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <sys/dirent.h>
|
#include <sys/dirent.h>
|
||||||
#include <fs/cd9660/iso.h>
|
#include <fs/cd9660/iso.h>
|
||||||
#include <fs/cd9660/cd9660_rrip.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,
|
dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||||
int use_rrip, int lenskip)
|
int use_rrip, int lenskip)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len, plen;
|
||||||
char *cp;
|
char *cp, *sep;
|
||||||
int i, icase;
|
int i, icase;
|
||||||
|
|
||||||
if (use_rrip)
|
if (use_rrip)
|
||||||
@ -242,7 +243,14 @@ dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
|||||||
} else
|
} else
|
||||||
icase = 0;
|
icase = 0;
|
||||||
|
|
||||||
if (strlen(path) != len)
|
sep = strchr(path, '/');
|
||||||
|
if (sep != NULL) {
|
||||||
|
plen = sep - path;
|
||||||
|
} else {
|
||||||
|
plen = strlen(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plen != len)
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
for (i = len; --i >= 0; path++, cp++) {
|
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 rec;
|
||||||
struct iso_directory_record *dp = NULL;
|
struct iso_directory_record *dp = NULL;
|
||||||
int rc, first, use_rrip, lenskip;
|
int rc, first, use_rrip, lenskip;
|
||||||
|
bool isdir = false;
|
||||||
|
|
||||||
/* First find the volume descriptor */
|
/* First find the volume descriptor */
|
||||||
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
|
buf = malloc(buf_size = ISO_DEFAULT_BLOCK_SIZE);
|
||||||
@ -372,7 +381,24 @@ cd9660_open(const char *path, struct open_file *f)
|
|||||||
rec = *dp;
|
rec = *dp;
|
||||||
while (*path && *path != '/') /* look for next component */
|
while (*path && *path != '/') /* look for next component */
|
||||||
path++;
|
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 */
|
/* 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);
|
p = get_device_type(devstr, type);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If type is DEV_TYP_STOR we have a disk-like device. If we can parse
|
* If type is DEV_TYP_STOR we have a disk-like device. If the remainder
|
||||||
* the remainder of the string as a standard unit+slice+partition (e.g.,
|
* of the string contains spaces, dots, or a colon in any location other
|
||||||
* 0s2a or 1p12), return those results. Otherwise we'll fall through to
|
* than the last char, it's legacy format. Otherwise it might be
|
||||||
* the code that parses the legacy format.
|
* 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) {
|
if (*type & DEV_TYP_STOR) {
|
||||||
*unit = dev.dd.d_unit;
|
size_t len = strlen(p);
|
||||||
*slice = dev.d_slice;
|
if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 &&
|
||||||
*partition = dev.d_partition;
|
disk_parsedev(&dev, p, NULL) == 0) {
|
||||||
return;
|
*unit = dev.dd.d_unit;
|
||||||
|
*slice = dev.d_slice;
|
||||||
|
*partition = dev.d_partition;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ignore optional spaces after the device name. */
|
/* Ignore optional spaces after the device name. */
|
||||||
|
@ -233,6 +233,9 @@ initializecpu(void)
|
|||||||
if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE)
|
if (cpu_stdext_feature & CPUID_STDEXT_FSGSBASE)
|
||||||
cr4 |= CR4_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
|
* Postpone enabling the SMEP on the boot CPU until the page
|
||||||
* tables are switched from the boot loader identity mapping
|
* tables are switched from the boot loader identity mapping
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
*/
|
*/
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003 Networks Associates Technology, Inc.
|
* Copyright (c) 2003 Networks Associates Technology, Inc.
|
||||||
* Copyright (c) 2014-2018 The FreeBSD Foundation
|
* Copyright (c) 2014-2019 The FreeBSD Foundation
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* This software was developed for the FreeBSD Project by Jake Burkholder,
|
* This software was developed for the FreeBSD Project by Jake Burkholder,
|
||||||
@ -121,6 +121,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
|
#include <sys/rangeset.h>
|
||||||
#include <sys/rwlock.h>
|
#include <sys/rwlock.h>
|
||||||
#include <sys/sx.h>
|
#include <sys/sx.h>
|
||||||
#include <sys/turnstile.h>
|
#include <sys/turnstile.h>
|
||||||
@ -155,6 +156,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#ifdef SMP
|
#ifdef SMP
|
||||||
#include <machine/smp.h>
|
#include <machine/smp.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <machine/sysarch.h>
|
||||||
#include <machine/tss.h>
|
#include <machine/tss.h>
|
||||||
|
|
||||||
static __inline boolean_t
|
static __inline boolean_t
|
||||||
@ -285,6 +287,13 @@ pmap_modified_bit(pmap_t pmap)
|
|||||||
return (mask);
|
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)
|
#if !defined(DIAGNOSTIC)
|
||||||
#ifdef __GNUC_GNU_INLINE__
|
#ifdef __GNUC_GNU_INLINE__
|
||||||
#define PMAP_INLINE __attribute__((__gnu_inline__)) 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 vm_pindex_t pti_pg_idx;
|
||||||
static bool pti_finalized;
|
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
|
static int
|
||||||
pmap_pcid_save_cnt_proc(SYSCTL_HANDLER_ARGS)
|
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->pm_pcids[i].pm_gen = 1;
|
||||||
}
|
}
|
||||||
pmap_activate_boot(pmap);
|
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
|
void
|
||||||
@ -2934,6 +2965,10 @@ pmap_pinit_type(pmap_t pmap, enum pmap_type pm_type, int flags)
|
|||||||
pmap_pinit_pml4_pti(pml4pgu);
|
pmap_pinit_pml4_pti(pml4pgu);
|
||||||
pmap->pm_ucr3 = VM_PAGE_TO_PHYS(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;
|
pmap->pm_root.rt_root = 0;
|
||||||
@ -3230,6 +3265,9 @@ pmap_release(pmap_t pmap)
|
|||||||
vm_page_unwire_noq(m);
|
vm_page_unwire_noq(m);
|
||||||
vm_page_free(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
|
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;
|
pd_entry_t newpde, oldpde;
|
||||||
pt_entry_t *firstpte, newpte;
|
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_paddr_t mptepa;
|
||||||
vm_page_t mpte;
|
vm_page_t mpte;
|
||||||
struct spglist free;
|
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_RW = pmap_rw_bit(pmap);
|
||||||
PG_V = pmap_valid_bit(pmap);
|
PG_V = pmap_valid_bit(pmap);
|
||||||
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
||||||
|
PG_PKU_MASK = pmap_pku_mask_bit(pmap);
|
||||||
|
|
||||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
||||||
oldpde = *pde;
|
oldpde = *pde;
|
||||||
@ -4505,6 +4544,7 @@ pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
|
|||||||
out:
|
out:
|
||||||
if (anyvalid)
|
if (anyvalid)
|
||||||
pmap_invalidate_all(pmap);
|
pmap_invalidate_all(pmap);
|
||||||
|
pmap_pkru_on_remove(pmap, sva, eva);
|
||||||
PMAP_UNLOCK(pmap);
|
PMAP_UNLOCK(pmap);
|
||||||
pmap_delayed_invl_finished();
|
pmap_delayed_invl_finished();
|
||||||
vm_page_free_pages_toq(&free, true);
|
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;
|
pd_entry_t newpde;
|
||||||
pt_entry_t *firstpte, oldpte, pa, *pte;
|
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;
|
vm_page_t mpte;
|
||||||
int PG_PTE_CACHE;
|
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_M = pmap_modified_bit(pmap);
|
||||||
PG_V = pmap_valid_bit(pmap);
|
PG_V = pmap_valid_bit(pmap);
|
||||||
PG_RW = pmap_rw_bit(pmap);
|
PG_RW = pmap_rw_bit(pmap);
|
||||||
|
PG_PKU_MASK = pmap_pku_mask_bit(pmap);
|
||||||
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
PG_PTE_CACHE = pmap_cache_mask(pmap, 0);
|
||||||
|
|
||||||
PMAP_LOCK_ASSERT(pmap, MA_OWNED);
|
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;
|
origpte = *pte;
|
||||||
pv = NULL;
|
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?
|
* 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);
|
" in pmap %p", va, pmap);
|
||||||
return (KERN_RESOURCE_SHORTAGE);
|
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 = (pd_entry_t *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pdpg));
|
||||||
pde = &pde[pmap_pde_index(va)];
|
pde = &pde[pmap_pde_index(va)];
|
||||||
oldpde = *pde;
|
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)
|
if ((prot & VM_PROT_EXECUTE) == 0)
|
||||||
newpte |= pg_nx;
|
newpte |= pg_nx;
|
||||||
if (va < VM_MAXUSER_ADDRESS)
|
if (va < VM_MAXUSER_ADDRESS)
|
||||||
newpte |= PG_U;
|
newpte |= PG_U | pmap_pkru_get(pmap, va);
|
||||||
pte_store(pte, newpte);
|
pte_store(pte, newpte);
|
||||||
return (mpte);
|
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);
|
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.
|
* Zero the specified hardware page.
|
||||||
*/
|
*/
|
||||||
@ -6305,6 +6397,7 @@ pmap_remove_pages(pmap_t pmap)
|
|||||||
if (lock != NULL)
|
if (lock != NULL)
|
||||||
rw_wunlock(lock);
|
rw_wunlock(lock);
|
||||||
pmap_invalidate_all(pmap);
|
pmap_invalidate_all(pmap);
|
||||||
|
pmap_pkru_deassign_all(pmap);
|
||||||
PMAP_UNLOCK(pmap);
|
PMAP_UNLOCK(pmap);
|
||||||
vm_page_free_pages_toq(&free, true);
|
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);
|
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"
|
#include "opt_ddb.h"
|
||||||
#ifdef DDB
|
#ifdef DDB
|
||||||
#include <sys/kdb.h>
|
#include <sys/kdb.h>
|
||||||
|
@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/malloc.h>
|
#include <sys/malloc.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/pcpu.h>
|
||||||
#include <sys/priv.h>
|
#include <sys/priv.h>
|
||||||
#include <sys/proc.h>
|
#include <sys/proc.h>
|
||||||
#include <sys/smp.h>
|
#include <sys/smp.h>
|
||||||
@ -53,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/pmap.h>
|
#include <vm/pmap.h>
|
||||||
#include <vm/vm_kern.h> /* for kernel_map */
|
#include <vm/vm_kern.h> /* for kernel_map */
|
||||||
|
#include <vm/vm_map.h>
|
||||||
#include <vm/vm_extern.h>
|
#include <vm/vm_extern.h>
|
||||||
|
|
||||||
#include <machine/frame.h>
|
#include <machine/frame.h>
|
||||||
@ -170,13 +172,16 @@ update_gdt_fsbase(struct thread *td, uint32_t base)
|
|||||||
int
|
int
|
||||||
sysarch(struct thread *td, struct sysarch_args *uap)
|
sysarch(struct thread *td, struct sysarch_args *uap)
|
||||||
{
|
{
|
||||||
int error = 0;
|
struct pcb *pcb;
|
||||||
struct pcb *pcb = curthread->td_pcb;
|
struct vm_map *map;
|
||||||
uint32_t i386base;
|
uint32_t i386base;
|
||||||
uint64_t a64base;
|
uint64_t a64base;
|
||||||
struct i386_ioperm_args iargs;
|
struct i386_ioperm_args iargs;
|
||||||
struct i386_get_xfpustate i386xfpu;
|
struct i386_get_xfpustate i386xfpu;
|
||||||
|
struct i386_set_pkru i386pkru;
|
||||||
struct amd64_get_xfpustate a64xfpu;
|
struct amd64_get_xfpustate a64xfpu;
|
||||||
|
struct amd64_set_pkru a64pkru;
|
||||||
|
int error;
|
||||||
|
|
||||||
#ifdef CAPABILITY_MODE
|
#ifdef CAPABILITY_MODE
|
||||||
/*
|
/*
|
||||||
@ -194,11 +199,15 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
|||||||
case I386_GET_GSBASE:
|
case I386_GET_GSBASE:
|
||||||
case I386_SET_GSBASE:
|
case I386_SET_GSBASE:
|
||||||
case I386_GET_XFPUSTATE:
|
case I386_GET_XFPUSTATE:
|
||||||
|
case I386_SET_PKRU:
|
||||||
|
case I386_CLEAR_PKRU:
|
||||||
case AMD64_GET_FSBASE:
|
case AMD64_GET_FSBASE:
|
||||||
case AMD64_SET_FSBASE:
|
case AMD64_SET_FSBASE:
|
||||||
case AMD64_GET_GSBASE:
|
case AMD64_GET_GSBASE:
|
||||||
case AMD64_SET_GSBASE:
|
case AMD64_SET_GSBASE:
|
||||||
case AMD64_GET_XFPUSTATE:
|
case AMD64_GET_XFPUSTATE:
|
||||||
|
case AMD64_SET_PKRU:
|
||||||
|
case AMD64_CLEAR_PKRU:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case I386_SET_IOPERM:
|
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)
|
if (uap->op == I386_GET_LDT || uap->op == I386_SET_LDT)
|
||||||
return (sysarch_ldt(td, uap, UIO_USERSPACE));
|
return (sysarch_ldt(td, uap, UIO_USERSPACE));
|
||||||
|
|
||||||
|
error = 0;
|
||||||
|
pcb = td->td_pcb;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XXXKIB check that the BSM generation code knows to encode
|
* XXXKIB check that the BSM generation code knows to encode
|
||||||
* the op argument.
|
* the op argument.
|
||||||
@ -233,11 +246,27 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
|||||||
a64xfpu.addr = (void *)(uintptr_t)i386xfpu.addr;
|
a64xfpu.addr = (void *)(uintptr_t)i386xfpu.addr;
|
||||||
a64xfpu.len = i386xfpu.len;
|
a64xfpu.len = i386xfpu.len;
|
||||||
break;
|
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:
|
case AMD64_GET_XFPUSTATE:
|
||||||
if ((error = copyin(uap->parms, &a64xfpu,
|
if ((error = copyin(uap->parms, &a64xfpu,
|
||||||
sizeof(struct amd64_get_xfpustate))) != 0)
|
sizeof(struct amd64_get_xfpustate))) != 0)
|
||||||
return (error);
|
return (error);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -326,6 +355,34 @@ sysarch(struct thread *td, struct sysarch_args *uap)
|
|||||||
a64xfpu.addr, a64xfpu.len);
|
a64xfpu.addr, a64xfpu.len);
|
||||||
break;
|
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:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
|
@ -807,6 +807,20 @@ trap_pfault(struct trapframe *frame, int usermode)
|
|||||||
return (-1);
|
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
|
* If nx protection of the usermode portion of kernel page
|
||||||
* tables caused trap, panic.
|
* tables caused trap, panic.
|
||||||
@ -842,6 +856,7 @@ trap_pfault(struct trapframe *frame, int usermode)
|
|||||||
#endif
|
#endif
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
after_vmfault:
|
||||||
if (!usermode) {
|
if (!usermode) {
|
||||||
if (td->td_intr_nesting_level == 0 &&
|
if (td->td_intr_nesting_level == 0 &&
|
||||||
curpcb->pcb_onfault != NULL) {
|
curpcb->pcb_onfault != NULL) {
|
||||||
@ -885,10 +900,12 @@ trap_fatal(frame, eva)
|
|||||||
#endif
|
#endif
|
||||||
if (type == T_PAGEFLT) {
|
if (type == T_PAGEFLT) {
|
||||||
printf("fault virtual address = 0x%lx\n", eva);
|
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_U ? "user" : "supervisor",
|
||||||
code & PGEX_W ? "write" : "read",
|
code & PGEX_W ? "write" : "read",
|
||||||
code & PGEX_I ? "instruction" : "data",
|
code & PGEX_I ? "instruction" : "data",
|
||||||
|
code & PGEX_PK ? " prot key" : " ",
|
||||||
|
code & PGEX_SGX ? " SGX" : " ",
|
||||||
code & PGEX_RSV ? "reserved bits in PTE" :
|
code & PGEX_RSV ? "reserved bits in PTE" :
|
||||||
code & PGEX_P ? "protection violation" : "page not present");
|
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
|
# The cpufreq(4) driver provides support for non-ACPI CPU frequency control
|
||||||
device cpufreq
|
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:
|
# Network interfaces:
|
||||||
#
|
#
|
||||||
|
@ -627,6 +627,22 @@ cpu_mwait(u_long extensions, u_int hints)
|
|||||||
__asm __volatile("mwait" : : "a" (hints), "c" (extensions));
|
__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
|
#ifdef _KERNEL
|
||||||
/* This is defined in <machine/specialreg.h> but is too painful to get to */
|
/* This is defined in <machine/specialreg.h> but is too painful to get to */
|
||||||
#ifndef MSR_FSBASE
|
#ifndef MSR_FSBASE
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
#define X86_PG_AVAIL2 0x400 /* < programmers use */
|
#define X86_PG_AVAIL2 0x400 /* < programmers use */
|
||||||
#define X86_PG_AVAIL3 0x800 /* \ */
|
#define X86_PG_AVAIL3 0x800 /* \ */
|
||||||
#define X86_PG_PDE_PAT 0x1000 /* PAT PAT index */
|
#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_NX (1ul<<63) /* No-execute */
|
||||||
#define X86_PG_AVAIL(x) (1ul << (x))
|
#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_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)
|
#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.
|
* Intel extended page table (EPT) bit definitions.
|
||||||
*/
|
*/
|
||||||
@ -120,7 +125,7 @@
|
|||||||
* (PTE) page mappings have identical settings for the following fields:
|
* (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 | \
|
#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
|
* Page Protection Exception bits
|
||||||
@ -131,6 +136,8 @@
|
|||||||
#define PGEX_U 0x04 /* access from User mode (UPL) */
|
#define PGEX_U 0x04 /* access from User mode (UPL) */
|
||||||
#define PGEX_RSV 0x08 /* reserved PTE field is non-zero */
|
#define PGEX_RSV 0x08 /* reserved PTE field is non-zero */
|
||||||
#define PGEX_I 0x10 /* during an instruction fetch */
|
#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
|
* undef the PG_xx macros that define bits in the regular x86 PTEs that
|
||||||
@ -240,6 +247,8 @@
|
|||||||
#include <sys/_cpuset.h>
|
#include <sys/_cpuset.h>
|
||||||
#include <sys/_lock.h>
|
#include <sys/_lock.h>
|
||||||
#include <sys/_mutex.h>
|
#include <sys/_mutex.h>
|
||||||
|
#include <sys/_pctrie.h>
|
||||||
|
#include <sys/_rangeset.h>
|
||||||
|
|
||||||
#include <vm/_vm_radix.h>
|
#include <vm/_vm_radix.h>
|
||||||
|
|
||||||
@ -334,6 +343,7 @@ struct pmap {
|
|||||||
long pm_eptgen; /* EPT pmap generation id */
|
long pm_eptgen; /* EPT pmap generation id */
|
||||||
int pm_flags;
|
int pm_flags;
|
||||||
struct pmap_pcids pm_pcids[MAXCPU];
|
struct pmap_pcids pm_pcids[MAXCPU];
|
||||||
|
struct rangeset pm_pkru;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* flags */
|
/* 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_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,
|
void pmap_pti_pcid_invlrng(uint64_t ucr3, uint64_t kcr3, vm_offset_t sva,
|
||||||
vm_offset_t eva);
|
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 */
|
#endif /* _KERNEL */
|
||||||
|
|
||||||
/* Return various clipped indexes for a given VA */
|
/* 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_COULOMB_LO 0xe3
|
||||||
|
|
||||||
#define AXP_BAT_CAP_WARN 0xe6
|
#define AXP_BAT_CAP_WARN 0xe6
|
||||||
#define AXP_BAT_CAP_WARN_LV1 0xf0 /* Bits 4, 5, 6, 7 */
|
#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_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 */
|
/* Sensor conversion macros */
|
||||||
#define AXP_SENSOR_BAT_H(hi) ((hi) << 4)
|
#define AXP_SENSOR_BAT_H(hi) ((hi) << 4)
|
||||||
@ -1088,9 +1089,9 @@ axp8xx_intr(void *arg)
|
|||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
device_printf(dev, "AXP_IRQSTAT4 val: %x\n", val);
|
device_printf(dev, "AXP_IRQSTAT4 val: %x\n", val);
|
||||||
if (val & AXP_IRQSTAT4_BATLVL_LO0)
|
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)
|
if (val & AXP_IRQSTAT4_BATLVL_LO1)
|
||||||
devctl_notify("PMU", "Battery", "lower than level 1", NULL);
|
devctl_notify("PMU", "Battery", "warning threshold", NULL);
|
||||||
/* Acknowledge */
|
/* Acknowledge */
|
||||||
axp8xx_write(dev, AXP_IRQSTAT4, val);
|
axp8xx_write(dev, AXP_IRQSTAT4, val);
|
||||||
}
|
}
|
||||||
@ -1527,6 +1528,7 @@ axp8xx_attach(device_t dev)
|
|||||||
/* Get thresholds */
|
/* Get thresholds */
|
||||||
if (axp8xx_read(dev, AXP_BAT_CAP_WARN, &val, 1) == 0) {
|
if (axp8xx_read(dev, AXP_BAT_CAP_WARN, &val, 1) == 0) {
|
||||||
sc->warn_thres = (val & AXP_BAT_CAP_WARN_LV1) >> 4;
|
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);
|
sc->shut_thres = (val & AXP_BAT_CAP_WARN_LV2);
|
||||||
if (bootverbose) {
|
if (bootverbose) {
|
||||||
device_printf(dev,
|
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);
|
vm_paddr_t pmap_kextract(vm_offset_t);
|
||||||
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
|
#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 /* _KERNEL */
|
||||||
#endif /* !_MACHINE_PMAP_H_ */
|
#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))
|
#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 /* _KERNEL */
|
||||||
|
|
||||||
#endif /* !LOCORE */
|
#endif /* !LOCORE */
|
||||||
|
@ -128,7 +128,7 @@ rk_clk_composite_set_mux(struct clknode *clk, int index)
|
|||||||
READ4(clk, sc->muxdiv_offset, &val);
|
READ4(clk, sc->muxdiv_offset, &val);
|
||||||
val &= ~sc->mux_mask;
|
val &= ~sc->mux_mask;
|
||||||
val |= index << sc->mux_shift;
|
val |= index << sc->mux_shift;
|
||||||
WRITE4(clk, sc->muxdiv_offset, val);
|
WRITE4(clk, sc->muxdiv_offset, val | RK_CLK_COMPOSITE_MASK);
|
||||||
DEVICE_UNLOCK(clk);
|
DEVICE_UNLOCK(clk);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -222,6 +222,7 @@ rk_clk_composite_set_freq(struct clknode *clk, uint64_t fparent, uint64_t *fout,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_idx = clknode_get_parent_idx(clk);
|
||||||
if (p_idx != best_parent)
|
if (p_idx != best_parent)
|
||||||
clknode_set_parent_by_idx(clk, 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));
|
memset(&msg.dt, 0, sizeof(msg.dt));
|
||||||
msg.hdr.msg_type = CTL_MSG_DATAMOVE;
|
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.serializing_sc = io;
|
||||||
msg.hdr.nexus = io->io_hdr.nexus;
|
msg.hdr.nexus = io->io_hdr.nexus;
|
||||||
msg.hdr.status = io->io_hdr.status;
|
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) {
|
if (io->io_hdr.io_type == CTL_IO_SCSI) {
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.hdr.msg_type = CTL_MSG_FINISH_IO;
|
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.nexus = io->io_hdr.nexus;
|
||||||
msg.hdr.status = io->io_hdr.status;
|
msg.hdr.status = io->io_hdr.status;
|
||||||
msg.scsi.scsi_status = io->scsiio.scsi_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
|
// populate ctsio from msg
|
||||||
io->io_hdr.io_type = CTL_IO_SCSI;
|
io->io_hdr.io_type = CTL_IO_SCSI;
|
||||||
io->io_hdr.msg_type = CTL_MSG_SERIALIZE;
|
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 |
|
io->io_hdr.flags |= CTL_FLAG_FROM_OTHER_SC |
|
||||||
CTL_FLAG_IO_ACTIVE;
|
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
|
* Keep track of this, we need to send it back over
|
||||||
* when the datamove is complete.
|
* 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)
|
if (msg->hdr.status == CTL_SUCCESS)
|
||||||
io->io_hdr.status = msg->hdr.status;
|
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;
|
CTL_HA_DATAMOVE_SEGMENT + 1;
|
||||||
sgl = malloc(sizeof(*sgl) * i, M_CTL,
|
sgl = malloc(sizeof(*sgl) * i, M_CTL,
|
||||||
M_WAITOK | M_ZERO);
|
M_WAITOK | M_ZERO);
|
||||||
io->io_hdr.remote_sglist = sgl;
|
CTL_RSGL(io) = sgl;
|
||||||
io->io_hdr.local_sglist =
|
CTL_LSGL(io) = &sgl[msg->dt.kern_sg_entries];
|
||||||
&sgl[msg->dt.kern_sg_entries];
|
|
||||||
|
|
||||||
io->scsiio.kern_data_ptr = (uint8_t *)sgl;
|
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.flags |= CTL_FLAG_IO_ACTIVE;
|
||||||
io->io_hdr.msg_type = CTL_MSG_R2R;
|
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);
|
ctl_enqueue_isc(io);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2369,7 +2368,7 @@ ctl_serialize_other_sc_cmd(struct ctl_scsiio *ctsio)
|
|||||||
mtx_unlock(&lun->lun_lock);
|
mtx_unlock(&lun->lun_lock);
|
||||||
|
|
||||||
/* send msg back to other side */
|
/* 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.serializing_sc = (union ctl_io *)ctsio;
|
||||||
msg_info.hdr.msg_type = CTL_MSG_R2R;
|
msg_info.hdr.msg_type = CTL_MSG_R2R;
|
||||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
|
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);
|
/*retry_count*/ 0);
|
||||||
badjuju:
|
badjuju:
|
||||||
ctl_copy_sense_data_back((union ctl_io *)ctsio, &msg_info);
|
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.serializing_sc = NULL;
|
||||||
msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU;
|
msg_info.hdr.msg_type = CTL_MSG_BAD_JUJU;
|
||||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
|
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 */
|
#endif /* CTL_IO_DELAY */
|
||||||
break;
|
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: {
|
case CTL_ERROR_INJECT: {
|
||||||
struct ctl_error_desc *err_desc, *new_err_desc;
|
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);
|
ctl_init_log_page_index(lun);
|
||||||
|
|
||||||
/* Setup statistics gathering */
|
/* 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;
|
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;
|
cur_blocked->io_hdr.flags &= ~CTL_FLAG_IO_ACTIVE;
|
||||||
msg_info.hdr.original_sc =
|
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.serializing_sc = cur_blocked;
|
||||||
msg_info.hdr.msg_type = CTL_MSG_R2R;
|
msg_info.hdr.msg_type = CTL_MSG_R2R;
|
||||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg_info,
|
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));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.hdr.msg_type = CTL_MSG_DATAMOVE_DONE;
|
msg.hdr.msg_type = CTL_MSG_DATAMOVE_DONE;
|
||||||
msg.hdr.original_sc = io;
|
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.nexus = io->io_hdr.nexus;
|
||||||
msg.hdr.status = io->io_hdr.status;
|
msg.hdr.status = io->io_hdr.status;
|
||||||
msg.scsi.kern_data_resid = io->scsiio.kern_data_resid;
|
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);
|
ctl_dt_req_free(rq);
|
||||||
|
|
||||||
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
||||||
free(io->io_hdr.local_sglist[i].addr, M_CTL);
|
free(CTL_LSGLT(io)[i].addr, M_CTL);
|
||||||
free(io->io_hdr.remote_sglist, M_CTL);
|
free(CTL_RSGL(io), M_CTL);
|
||||||
io->io_hdr.remote_sglist = NULL;
|
CTL_RSGL(io) = NULL;
|
||||||
io->io_hdr.local_sglist = NULL;
|
CTL_LSGL(io) = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The data is in local and remote memory, so now we need to send
|
* 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;
|
return;
|
||||||
|
|
||||||
/* Switch the pointer over so the FETD knows what to do */
|
/* 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
|
* 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;
|
uint32_t i;
|
||||||
|
|
||||||
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
||||||
free(io->io_hdr.local_sglist[i].addr, M_CTL);
|
free(CTL_LSGLT(io)[i].addr, M_CTL);
|
||||||
free(io->io_hdr.remote_sglist, M_CTL);
|
free(CTL_RSGL(io), M_CTL);
|
||||||
io->io_hdr.remote_sglist = NULL;
|
CTL_RSGL(io) = NULL;
|
||||||
io->io_hdr.local_sglist = NULL;
|
CTL_LSGL(io) = NULL;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
scsi_path_string(io, path_str, sizeof(path_str));
|
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);
|
ctl_dt_req_free(rq);
|
||||||
|
|
||||||
/* Switch the pointer over so the FETD knows what to do */
|
/* 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
|
* 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;
|
int i;
|
||||||
|
|
||||||
retval = 0;
|
retval = 0;
|
||||||
local_sglist = io->io_hdr.local_sglist;
|
local_sglist = CTL_LSGL(io);
|
||||||
len_to_go = io->scsiio.kern_data_len;
|
len_to_go = io->scsiio.kern_data_len;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -12785,8 +12740,8 @@ ctl_datamove_remote_xfer(union ctl_io *io, unsigned command,
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
local_sglist = io->io_hdr.local_sglist;
|
local_sglist = CTL_LSGL(io);
|
||||||
remote_sglist = io->io_hdr.remote_sglist;
|
remote_sglist = CTL_RSGL(io);
|
||||||
local_used = 0;
|
local_used = 0;
|
||||||
remote_used = 0;
|
remote_used = 0;
|
||||||
total_used = 0;
|
total_used = 0;
|
||||||
@ -12899,10 +12854,10 @@ ctl_datamove_remote_read(union ctl_io *io)
|
|||||||
* error if there is a problem.
|
* error if there is a problem.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
for (i = 0; i < io->scsiio.kern_sg_entries; i++)
|
||||||
free(io->io_hdr.local_sglist[i].addr, M_CTL);
|
free(CTL_LSGLT(io)[i].addr, M_CTL);
|
||||||
free(io->io_hdr.remote_sglist, M_CTL);
|
free(CTL_RSGL(io), M_CTL);
|
||||||
io->io_hdr.remote_sglist = NULL;
|
CTL_RSGL(io) = NULL;
|
||||||
io->io_hdr.local_sglist = NULL;
|
CTL_LSGL(io) = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13079,21 +13034,6 @@ ctl_process_done(union ctl_io *io)
|
|||||||
else
|
else
|
||||||
type = CTL_STATS_NO_IO;
|
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.bytes[type] += io->scsiio.kern_total_len;
|
||||||
lun->stats.operations[type] ++;
|
lun->stats.operations[type] ++;
|
||||||
lun->stats.dmas[type] += io->io_hdr.num_dmas;
|
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)) {
|
(io->io_hdr.flags & CTL_FLAG_SENT_2OTHER_SC)) {
|
||||||
memset(&msg, 0, sizeof(msg));
|
memset(&msg, 0, sizeof(msg));
|
||||||
msg.hdr.msg_type = CTL_MSG_FINISH_IO;
|
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;
|
msg.hdr.nexus = io->io_hdr.nexus;
|
||||||
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
|
ctl_ha_msg_send(CTL_HA_CHAN_CTL, &msg,
|
||||||
sizeof(msg.scsi) - sizeof(msg.scsi.sense_data),
|
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))-> \
|
#define CTL_PORT(io) (((struct ctl_softc *)CTL_SOFTC(io))-> \
|
||||||
ctl_ports[(io)->io_hdr.nexus.targ_port])
|
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_INVALID_PORTNAME 0xFF
|
||||||
#define CTL_UNMAPPED_IID 0xFF
|
#define CTL_UNMAPPED_IID 0xFF
|
||||||
|
|
||||||
@ -229,12 +238,12 @@ struct ctl_io_hdr {
|
|||||||
struct bintime dma_bt; /* DMA total ticks */
|
struct bintime dma_bt; /* DMA total ticks */
|
||||||
#endif /* CTL_TIME_IO */
|
#endif /* CTL_TIME_IO */
|
||||||
uint32_t num_dmas; /* Number of DMAs */
|
uint32_t num_dmas; /* Number of DMAs */
|
||||||
union ctl_io *original_sc;
|
union ctl_io *remote_io; /* I/O counterpart on remote HA side */
|
||||||
union ctl_io *serializing_sc;
|
void *pad1;
|
||||||
void *pool; /* I/O pool */
|
void *pool; /* I/O pool */
|
||||||
union ctl_priv ctl_private[CTL_NUM_PRIV];/* CTL private area */
|
union ctl_priv ctl_private[CTL_NUM_PRIV];/* CTL private area */
|
||||||
struct ctl_sg_entry *remote_sglist;
|
void *pad2;
|
||||||
struct ctl_sg_entry *local_sglist;
|
void *pad3;
|
||||||
STAILQ_ENTRY(ctl_io_hdr) links; /* linked list pointer */
|
STAILQ_ENTRY(ctl_io_hdr) links; /* linked list pointer */
|
||||||
TAILQ_ENTRY(ctl_io_hdr) ooa_links;
|
TAILQ_ENTRY(ctl_io_hdr) ooa_links;
|
||||||
TAILQ_ENTRY(ctl_io_hdr) blocked_links;
|
TAILQ_ENTRY(ctl_io_hdr) blocked_links;
|
||||||
|
@ -69,9 +69,6 @@
|
|||||||
/* Hopefully this won't conflict with new misc devices that pop up */
|
/* Hopefully this won't conflict with new misc devices that pop up */
|
||||||
#define CTL_MINOR 225
|
#define CTL_MINOR 225
|
||||||
|
|
||||||
/* Legacy statistics accumulated for every port for every LU. */
|
|
||||||
//#define CTL_LEGACY_STATS 1
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CTL_DELAY_TYPE_NONE,
|
CTL_DELAY_TYPE_NONE,
|
||||||
CTL_DELAY_TYPE_CONT,
|
CTL_DELAY_TYPE_CONT,
|
||||||
@ -119,39 +116,6 @@ typedef enum {
|
|||||||
CTL_STATS_FLAG_TIME_VALID = 0x01
|
CTL_STATS_FLAG_TIME_VALID = 0x01
|
||||||
} ctl_stats_flags;
|
} 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 {
|
struct ctl_io_stats {
|
||||||
uint32_t item;
|
uint32_t item;
|
||||||
uint64_t bytes[CTL_STATS_NUM_TYPES];
|
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_ENABLE_PORT _IOW(CTL_MINOR, 0x04, struct ctl_port_entry)
|
||||||
#define CTL_DISABLE_PORT _IOW(CTL_MINOR, 0x05, 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_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_ERROR_INJECT _IOWR(CTL_MINOR, 0x16, struct ctl_error_desc)
|
||||||
#define CTL_GET_OOA _IOWR(CTL_MINOR, 0x18, struct ctl_ooa)
|
#define CTL_GET_OOA _IOWR(CTL_MINOR, 0x18, struct ctl_ooa)
|
||||||
#define CTL_DUMP_STRUCTS _IO(CTL_MINOR, 0x19)
|
#define CTL_DUMP_STRUCTS _IO(CTL_MINOR, 0x19)
|
||||||
|
@ -403,9 +403,6 @@ struct ctl_lun {
|
|||||||
struct callout ie_callout; /* INTERVAL TIMER */
|
struct callout ie_callout; /* INTERVAL TIMER */
|
||||||
struct ctl_mode_pages mode_pages;
|
struct ctl_mode_pages mode_pages;
|
||||||
struct ctl_log_pages log_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;
|
struct ctl_io_stats stats;
|
||||||
uint32_t res_idx;
|
uint32_t res_idx;
|
||||||
uint32_t pr_generation;
|
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);
|
ASSERT(p->p_proc_flag & P_PR_LOCK);
|
||||||
#endif
|
#endif
|
||||||
p->p_dtrace_count--;
|
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);
|
return (B_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL);
|
/*
|
||||||
if (ts != NULL) {
|
* Loop until all overlapping segments are removed.
|
||||||
/*
|
*/
|
||||||
* 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);
|
||||||
do {
|
|
||||||
trim_map_segment_remove(tm, ts, start, end);
|
|
||||||
ts = avl_find(&tm->tm_queued_frees, &tsearch, NULL);
|
|
||||||
} while (ts != NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
avl_add(&tm->tm_inflight_writes, zio);
|
avl_add(&tm->tm_inflight_writes, zio);
|
||||||
|
|
||||||
mutex_exit(&tm->tm_lock);
|
mutex_exit(&tm->tm_lock);
|
||||||
|
@ -692,10 +692,12 @@ vdev_geom_attach_by_guids(vdev_t *vd)
|
|||||||
struct g_geom *gp;
|
struct g_geom *gp;
|
||||||
struct g_provider *pp, *best_pp;
|
struct g_provider *pp, *best_pp;
|
||||||
struct g_consumer *cp;
|
struct g_consumer *cp;
|
||||||
|
const char *vdpath;
|
||||||
enum match match, best_match;
|
enum match match, best_match;
|
||||||
|
|
||||||
g_topology_assert();
|
g_topology_assert();
|
||||||
|
|
||||||
|
vdpath = vd->vdev_path + sizeof("/dev/") - 1;
|
||||||
cp = NULL;
|
cp = NULL;
|
||||||
best_pp = NULL;
|
best_pp = NULL;
|
||||||
best_match = NO_MATCH;
|
best_match = NO_MATCH;
|
||||||
@ -710,6 +712,10 @@ vdev_geom_attach_by_guids(vdev_t *vd)
|
|||||||
if (match > best_match) {
|
if (match > best_match) {
|
||||||
best_match = match;
|
best_match = match;
|
||||||
best_pp = pp;
|
best_pp = pp;
|
||||||
|
} else if (match == best_match) {
|
||||||
|
if (strcmp(pp->name, vdpath) == 0) {
|
||||||
|
best_pp = pp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (match == FULL_MATCH)
|
if (match == FULL_MATCH)
|
||||||
goto out;
|
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.
|
* 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;
|
vd->vdev_stat.vs_aux = VDEV_AUX_BAD_LABEL;
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
}
|
}
|
||||||
|
@ -270,7 +270,6 @@ static void
|
|||||||
vdev_raidz_map_free(raidz_map_t *rm)
|
vdev_raidz_map_free(raidz_map_t *rm)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
size_t size;
|
|
||||||
|
|
||||||
for (c = 0; c < rm->rm_firstdatacol; c++) {
|
for (c = 0; c < rm->rm_firstdatacol; c++) {
|
||||||
if (rm->rm_col[c].rc_abd != NULL)
|
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);
|
rm->rm_col[c].rc_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = 0;
|
|
||||||
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
|
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++) {
|
||||||
if (rm->rm_col[c].rc_abd != NULL)
|
if (rm->rm_col[c].rc_abd != NULL)
|
||||||
abd_put(rm->rm_col[c].rc_abd);
|
abd_put(rm->rm_col[c].rc_abd);
|
||||||
size += rm->rm_col[c].rc_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rm->rm_abd_copy != NULL)
|
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);
|
abd_alloc_linear(rm->rm_col[c].rc_size, B_TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
rm->rm_col[c].rc_abd = abd_get_offset(abd, 0);
|
for (off = 0; c < acols; c++) {
|
||||||
off = rm->rm_col[c].rc_size;
|
|
||||||
|
|
||||||
for (c = c + 1; c < acols; c++) {
|
|
||||||
rm->rm_col[c].rc_abd = abd_get_offset(abd, off);
|
rm->rm_col[c].rc_abd = abd_get_offset(abd, off);
|
||||||
off += rm->rm_col[c].rc_size;
|
off += rm->rm_col[c].rc_size;
|
||||||
}
|
}
|
||||||
@ -2023,7 +2017,7 @@ vdev_raidz_io_start(zio_t *zio)
|
|||||||
return;
|
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
|
* 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:
|
* We're here because either:
|
||||||
*
|
*
|
||||||
* total_errors == rm_first_datacol, or
|
* total_errors == rm_firstdatacol, or
|
||||||
* vdev_raidz_combrec() failed
|
* vdev_raidz_combrec() failed
|
||||||
*
|
*
|
||||||
* In either case, there is enough bad data to prevent
|
* In either case, there is enough bad data to prevent
|
||||||
|
@ -967,6 +967,7 @@ fasttrap_pid_probe(struct trapframe *tf)
|
|||||||
struct reg reg, *rp;
|
struct reg reg, *rp;
|
||||||
proc_t *p = curproc, *pp;
|
proc_t *p = curproc, *pp;
|
||||||
struct rm_priotracker tracker;
|
struct rm_priotracker tracker;
|
||||||
|
uint64_t gen;
|
||||||
uintptr_t pc;
|
uintptr_t pc;
|
||||||
uintptr_t new_pc = 0;
|
uintptr_t new_pc = 0;
|
||||||
fasttrap_bucket_t *bucket;
|
fasttrap_bucket_t *bucket;
|
||||||
@ -1026,8 +1027,22 @@ fasttrap_pid_probe(struct trapframe *tf)
|
|||||||
while (pp->p_vmspace == pp->p_pptr->p_vmspace)
|
while (pp->p_vmspace == pp->p_pptr->p_vmspace)
|
||||||
pp = pp->p_pptr;
|
pp = pp->p_pptr;
|
||||||
pid = pp->p_pid;
|
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);
|
sx_sunlock(&proctree_lock);
|
||||||
pp = NULL;
|
|
||||||
|
|
||||||
rm_rlock(&fasttrap_tp_lock, &tracker);
|
rm_rlock(&fasttrap_tp_lock, &tracker);
|
||||||
#endif
|
#endif
|
||||||
@ -1051,11 +1066,32 @@ fasttrap_pid_probe(struct trapframe *tf)
|
|||||||
if (tp == NULL) {
|
if (tp == NULL) {
|
||||||
#ifdef illumos
|
#ifdef illumos
|
||||||
mutex_exit(pid_mtx);
|
mutex_exit(pid_mtx);
|
||||||
|
return (-1);
|
||||||
#else
|
#else
|
||||||
rm_runlock(&fasttrap_tp_lock, &tracker);
|
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
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
return (-1);
|
return (-1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
if (pp != p)
|
||||||
|
PRELE(pp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the program counter to the address of the traced instruction
|
* 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