MFhead@r344270
This commit is contained in:
commit
30e009fc3a
8
UPDATING
8
UPDATING
@ -38,6 +38,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
modules on kernels not having 'device iflib', the iflib.ko module
|
||||
is loaded automatically.
|
||||
|
||||
20190125:
|
||||
The IEEE80211_AMPDU_AGE and AH_SUPPORT_AR5416 kernel configuration
|
||||
options no longer exist since r343219 and r343427 respectively;
|
||||
nothing uses them, so they should be just removed from custom
|
||||
kernel config files.
|
||||
|
||||
20181230:
|
||||
r342635 changes the way efibootmgr(8) works by requiring users to add
|
||||
the -b (bootnum) parameter for commands where the bootnum was previously
|
||||
@ -231,7 +237,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
|
||||
20180719:
|
||||
ARM64 now have efifb support, if you want to have serial console
|
||||
on your arm64 board when an screen is connected and the bootloader
|
||||
setup a frambuffer for us to use, just add :
|
||||
setup a framebuffer for us to use, just add :
|
||||
boot_serial=YES
|
||||
boot_multicons=YES
|
||||
in /boot/loader.conf
|
||||
|
@ -860,6 +860,7 @@ next_entry(struct archive_read_disk *a, struct tree *t,
|
||||
struct archive_string delayed_str;
|
||||
|
||||
delayed = ARCHIVE_OK;
|
||||
delayed_errno = 0;
|
||||
archive_string_init(&delayed_str);
|
||||
|
||||
st = NULL;
|
||||
|
@ -733,12 +733,6 @@ _LIBCPP_INLINE_VAR _LIBCPP_CONSTEXPR bool is_integral_v
|
||||
// is_floating_point
|
||||
|
||||
template <class _Tp> struct __libcpp_is_floating_point : public false_type {};
|
||||
#ifdef __clang__
|
||||
template <> struct __libcpp_is_floating_point<__fp16> : public true_type {};
|
||||
#endif
|
||||
#ifdef __FLT16_MANT_DIG__
|
||||
template <> struct __libcpp_is_floating_point<_Float16> : public true_type {};
|
||||
#endif
|
||||
template <> struct __libcpp_is_floating_point<float> : public true_type {};
|
||||
template <> struct __libcpp_is_floating_point<double> : public true_type {};
|
||||
template <> struct __libcpp_is_floating_point<long double> : public true_type {};
|
||||
|
@ -1258,14 +1258,20 @@ void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
|
||||
if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
|
||||
continue;
|
||||
|
||||
// FIXME: produce a better error message.
|
||||
// FIXME: Get source locations for these errors or diagnose them earlier.
|
||||
if (Symbol.isUndefined() && Rest.startswith("@@") &&
|
||||
!Rest.startswith("@@@"))
|
||||
report_fatal_error("A @@ version cannot be undefined");
|
||||
!Rest.startswith("@@@")) {
|
||||
Asm.getContext().reportError(SMLoc(), "versioned symbol " + AliasName +
|
||||
" must be defined");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Renames.count(&Symbol) && Renames[&Symbol] != Alias)
|
||||
report_fatal_error(llvm::Twine("Multiple symbol versions defined for ") +
|
||||
Symbol.getName());
|
||||
if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
|
||||
Asm.getContext().reportError(
|
||||
SMLoc(), llvm::Twine("multiple symbol versions defined for ") +
|
||||
Symbol.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
Renames.insert(std::make_pair(&Symbol, Alias));
|
||||
}
|
||||
|
@ -26,6 +26,8 @@
|
||||
..
|
||||
modules
|
||||
..
|
||||
uboot
|
||||
..
|
||||
zfs
|
||||
..
|
||||
..
|
||||
|
@ -6,6 +6,7 @@ LIBROKEN_A= ${.OBJDIR:H:H}/lib/libroken/libroken.a
|
||||
LIBADD= vers
|
||||
LDADD= ${LIBROKEN_A}
|
||||
DPADD= ${LIBROKEN_A}
|
||||
MK_PIE:= no
|
||||
|
||||
SRCS= \
|
||||
asn1parse.y \
|
||||
|
@ -6,6 +6,7 @@ LIBADD= vers
|
||||
LDADD= ${LIBROKEN_A}
|
||||
DPADD= ${LIBROKEN_A}
|
||||
MAN=
|
||||
MK_PIE:= no
|
||||
|
||||
SRCS= roken.h \
|
||||
slc-gram.y \
|
||||
|
@ -2,6 +2,8 @@
|
||||
|
||||
.include <bsd.compiler.mk>
|
||||
|
||||
MK_PIE:= no # Explicit libXXX.a references
|
||||
|
||||
.if ${COMPILER_TYPE} == "clang"
|
||||
DEBUG_FILES_CFLAGS= -gline-tables-only
|
||||
.else
|
||||
|
@ -18,6 +18,7 @@ SRCS+= Support/Errno.cpp
|
||||
SRCS+= Support/Error.cpp
|
||||
SRCS+= Support/ErrorHandling.cpp
|
||||
SRCS+= Support/FoldingSet.cpp
|
||||
SRCS+= Support/FormatVariadic.cpp
|
||||
SRCS+= Support/FormattedStream.cpp
|
||||
SRCS+= Support/Hashing.cpp
|
||||
SRCS+= Support/Host.cpp
|
||||
|
100
lib/libbe/be.c
100
lib/libbe/be.c
@ -45,6 +45,11 @@ __FBSDID("$FreeBSD$");
|
||||
#include "be.h"
|
||||
#include "be_impl.h"
|
||||
|
||||
struct be_destroy_data {
|
||||
libbe_handle_t *lbh;
|
||||
char *snapname;
|
||||
};
|
||||
|
||||
#if SOON
|
||||
static int be_create_child_noent(libbe_handle_t *lbh, const char *active,
|
||||
const char *child_path);
|
||||
@ -186,12 +191,38 @@ be_nicenum(uint64_t num, char *buf, size_t buflen)
|
||||
static int
|
||||
be_destroy_cb(zfs_handle_t *zfs_hdl, void *data)
|
||||
{
|
||||
char path[BE_MAXPATHLEN];
|
||||
struct be_destroy_data *bdd;
|
||||
zfs_handle_t *snap;
|
||||
int err;
|
||||
|
||||
if ((err = zfs_iter_children(zfs_hdl, be_destroy_cb, data)) != 0)
|
||||
return (err);
|
||||
if ((err = zfs_destroy(zfs_hdl, false)) != 0)
|
||||
bdd = (struct be_destroy_data *)data;
|
||||
if (bdd->snapname == NULL) {
|
||||
err = zfs_iter_children(zfs_hdl, be_destroy_cb, data);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
return (zfs_destroy(zfs_hdl, false));
|
||||
}
|
||||
/* If we're dealing with snapshots instead, delete that one alone */
|
||||
err = zfs_iter_filesystems(zfs_hdl, be_destroy_cb, data);
|
||||
if (err != 0)
|
||||
return (err);
|
||||
/*
|
||||
* This part is intentionally glossing over any potential errors,
|
||||
* because there's a lot less potential for errors when we're cleaning
|
||||
* up snapshots rather than a full deep BE. The primary error case
|
||||
* here being if the snapshot doesn't exist in the first place, which
|
||||
* the caller will likely deem insignificant as long as it doesn't
|
||||
* exist after the call. Thus, such a missing snapshot shouldn't jam
|
||||
* up the destruction.
|
||||
*/
|
||||
snprintf(path, sizeof(path), "%s@%s", zfs_get_name(zfs_hdl),
|
||||
bdd->snapname);
|
||||
if (!zfs_dataset_exists(bdd->lbh->lzh, path, ZFS_TYPE_SNAPSHOT))
|
||||
return (0);
|
||||
snap = zfs_open(bdd->lbh->lzh, path, ZFS_TYPE_SNAPSHOT);
|
||||
if (snap != NULL)
|
||||
zfs_destroy(snap, false);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -199,22 +230,26 @@ be_destroy_cb(zfs_handle_t *zfs_hdl, void *data)
|
||||
* Destroy the boot environment or snapshot specified by the name
|
||||
* parameter. Options are or'd together with the possible values:
|
||||
* BE_DESTROY_FORCE : forces operation on mounted datasets
|
||||
* BE_DESTROY_ORIGIN: destroy the origin snapshot as well
|
||||
*/
|
||||
int
|
||||
be_destroy(libbe_handle_t *lbh, const char *name, int options)
|
||||
{
|
||||
struct be_destroy_data bdd;
|
||||
char origin[BE_MAXPATHLEN], path[BE_MAXPATHLEN];
|
||||
zfs_handle_t *fs;
|
||||
char *p;
|
||||
char *snapdelim;
|
||||
int err, force, mounted;
|
||||
size_t rootlen;
|
||||
|
||||
p = path;
|
||||
bdd.lbh = lbh;
|
||||
bdd.snapname = NULL;
|
||||
force = options & BE_DESTROY_FORCE;
|
||||
*origin = '\0';
|
||||
|
||||
be_root_concat(lbh, name, path);
|
||||
|
||||
if (strchr(name, '@') == NULL) {
|
||||
if ((snapdelim = strchr(path, '@')) == NULL) {
|
||||
if (!zfs_dataset_exists(lbh->lzh, path, ZFS_TYPE_FILESYSTEM))
|
||||
return (set_error(lbh, BE_ERR_NOENT));
|
||||
|
||||
@ -222,9 +257,10 @@ be_destroy(libbe_handle_t *lbh, const char *name, int options)
|
||||
strcmp(path, lbh->bootfs) == 0)
|
||||
return (set_error(lbh, BE_ERR_DESTROYACT));
|
||||
|
||||
fs = zfs_open(lbh->lzh, p, ZFS_TYPE_FILESYSTEM);
|
||||
fs = zfs_open(lbh->lzh, path, ZFS_TYPE_FILESYSTEM);
|
||||
if (fs == NULL)
|
||||
return (set_error(lbh, BE_ERR_ZFSOPEN));
|
||||
|
||||
if ((options & BE_DESTROY_ORIGIN) != 0 &&
|
||||
zfs_prop_get(fs, ZFS_PROP_ORIGIN, origin, sizeof(origin),
|
||||
NULL, NULL, 0, 1) != 0)
|
||||
@ -233,41 +269,57 @@ be_destroy(libbe_handle_t *lbh, const char *name, int options)
|
||||
if (!zfs_dataset_exists(lbh->lzh, path, ZFS_TYPE_SNAPSHOT))
|
||||
return (set_error(lbh, BE_ERR_NOENT));
|
||||
|
||||
fs = zfs_open(lbh->lzh, p, ZFS_TYPE_SNAPSHOT);
|
||||
if (fs == NULL)
|
||||
bdd.snapname = strdup(snapdelim + 1);
|
||||
if (bdd.snapname == NULL)
|
||||
return (set_error(lbh, BE_ERR_NOMEM));
|
||||
*snapdelim = '\0';
|
||||
fs = zfs_open(lbh->lzh, path, ZFS_TYPE_DATASET);
|
||||
if (fs == NULL) {
|
||||
free(bdd.snapname);
|
||||
return (set_error(lbh, BE_ERR_ZFSOPEN));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if mounted, unmount if force is specified */
|
||||
if ((mounted = zfs_is_mounted(fs, NULL)) != 0) {
|
||||
if (force)
|
||||
if (force) {
|
||||
zfs_unmount(fs, NULL, 0);
|
||||
else
|
||||
} else {
|
||||
free(bdd.snapname);
|
||||
return (set_error(lbh, BE_ERR_DESTROYMNT));
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = be_destroy_cb(fs, NULL)) != 0) {
|
||||
err = be_destroy_cb(fs, &bdd);
|
||||
zfs_close(fs);
|
||||
free(bdd.snapname);
|
||||
if (err != 0) {
|
||||
/* Children are still present or the mount is referenced */
|
||||
if (err == EBUSY)
|
||||
return (set_error(lbh, BE_ERR_DESTROYMNT));
|
||||
return (set_error(lbh, BE_ERR_UNKNOWN));
|
||||
}
|
||||
|
||||
if (*origin != '\0') {
|
||||
fs = zfs_open(lbh->lzh, origin, ZFS_TYPE_SNAPSHOT);
|
||||
if (fs == NULL)
|
||||
return (set_error(lbh, BE_ERR_ZFSOPEN));
|
||||
err = zfs_destroy(fs, false);
|
||||
if (err == EBUSY)
|
||||
return (set_error(lbh, BE_ERR_DESTROYMNT));
|
||||
else if (err != 0)
|
||||
return (set_error(lbh, BE_ERR_UNKNOWN));
|
||||
}
|
||||
if ((options & BE_DESTROY_ORIGIN) == 0)
|
||||
return (0);
|
||||
|
||||
return (0);
|
||||
/* The origin can't possibly be shorter than the BE root */
|
||||
rootlen = strlen(lbh->root);
|
||||
if (*origin == '\0' || strlen(origin) <= rootlen + 1)
|
||||
return (set_error(lbh, BE_ERR_INVORIGIN));
|
||||
|
||||
/*
|
||||
* We'll be chopping off the BE root and running this back through
|
||||
* be_destroy, so that we properly handle the origin snapshot whether
|
||||
* it be that of a deep BE or not.
|
||||
*/
|
||||
if (strncmp(origin, lbh->root, rootlen) != 0 || origin[rootlen] != '/')
|
||||
return (0);
|
||||
|
||||
return (be_destroy(lbh, origin + rootlen + 1,
|
||||
options & ~BE_DESTROY_ORIGIN));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
be_snapshot(libbe_handle_t *lbh, const char *source, const char *snap_name,
|
||||
bool recursive, char *result)
|
||||
|
@ -59,6 +59,7 @@ typedef enum be_error {
|
||||
BE_ERR_NOPOOL, /* operation not supported on this pool */
|
||||
BE_ERR_NOMEM, /* insufficient memory */
|
||||
BE_ERR_UNKNOWN, /* unknown error */
|
||||
BE_ERR_INVORIGIN, /* invalid origin */
|
||||
} be_error_t;
|
||||
|
||||
|
||||
|
@ -105,6 +105,9 @@ libbe_error_description(libbe_handle_t *lbh)
|
||||
case BE_ERR_UNKNOWN:
|
||||
return ("unknown error");
|
||||
|
||||
case BE_ERR_INVORIGIN:
|
||||
return ("invalid origin");
|
||||
|
||||
default:
|
||||
assert(lbh->error == BE_ERR_SUCCESS);
|
||||
return ("no error");
|
||||
|
@ -28,7 +28,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd February 11, 2019
|
||||
.Dd February 12, 2019
|
||||
.Dt LIBBE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -489,6 +489,8 @@ BE_ERR_NOPOOL
|
||||
BE_ERR_NOMEM
|
||||
.It
|
||||
BE_ERR_UNKNOWN
|
||||
.It
|
||||
BE_ERR_INVORIGIN
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr bectl 8
|
||||
|
@ -122,6 +122,7 @@ NOASM=
|
||||
.endif
|
||||
.if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64"
|
||||
.include "${LIBC_SRCTOP}/x86/sys/Makefile.inc"
|
||||
.include "${LIBC_SRCTOP}/x86/gen/Makefile.inc"
|
||||
.endif
|
||||
.if ${MK_NIS} != "no"
|
||||
CFLAGS+= -DYP
|
||||
|
@ -2,7 +2,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= _setjmp.S _set_tp.c rfork_thread.S setjmp.S sigsetjmp.S \
|
||||
fabs.S getcontextx.c \
|
||||
fabs.S \
|
||||
infinity.c ldexp.c makecontext.c signalcontext.c \
|
||||
flt_rounds.c fpgetmask.c fpsetmask.c fpgetprec.c fpsetprec.c \
|
||||
fpgetround.c fpsetround.c fpgetsticky.c
|
||||
|
@ -178,4 +178,6 @@ extension and should not be used if portability is desired.
|
||||
The
|
||||
.Fn readpassphrase
|
||||
function first appeared in
|
||||
.Fx 4.6
|
||||
and
|
||||
.Ox 2.9 .
|
||||
|
@ -2,5 +2,5 @@
|
||||
# $FreeBSD$
|
||||
|
||||
SRCS+= _ctx_start.S _setjmp.S _set_tp.c fabs.S \
|
||||
flt_rounds.c getcontextx.c infinity.c ldexp.c makecontext.c \
|
||||
flt_rounds.c infinity.c ldexp.c makecontext.c \
|
||||
rfork_thread.S setjmp.S signalcontext.c sigsetjmp.S
|
||||
|
@ -1,145 +0,0 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
||||
*
|
||||
* Copyright (c) 2011 Konstantin Belousov <kib@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 ``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 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/types.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <machine/npx.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/sysarch.h>
|
||||
|
||||
static int xstate_sz = -1;
|
||||
|
||||
int
|
||||
__getcontextx_size(void)
|
||||
{
|
||||
u_int p[4];
|
||||
int cpuid_supported;
|
||||
|
||||
if (xstate_sz == -1) {
|
||||
__asm __volatile(
|
||||
" pushfl\n"
|
||||
" popl %%eax\n"
|
||||
" movl %%eax,%%ecx\n"
|
||||
" xorl $0x200000,%%eax\n"
|
||||
" pushl %%eax\n"
|
||||
" popfl\n"
|
||||
" pushfl\n"
|
||||
" popl %%eax\n"
|
||||
" xorl %%eax,%%ecx\n"
|
||||
" je 1f\n"
|
||||
" movl $1,%0\n"
|
||||
" jmp 2f\n"
|
||||
"1: movl $0,%0\n"
|
||||
"2:\n"
|
||||
: "=r" (cpuid_supported) : : "eax", "ecx");
|
||||
if (cpuid_supported) {
|
||||
__asm __volatile(
|
||||
" pushl %%ebx\n"
|
||||
" cpuid\n"
|
||||
" movl %%ebx,%1\n"
|
||||
" popl %%ebx\n"
|
||||
: "=a" (p[0]), "=r" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (0x1));
|
||||
if ((p[2] & CPUID2_OSXSAVE) != 0) {
|
||||
__asm __volatile(
|
||||
" pushl %%ebx\n"
|
||||
" cpuid\n"
|
||||
" movl %%ebx,%1\n"
|
||||
" popl %%ebx\n"
|
||||
: "=a" (p[0]), "=r" (p[1]), "=c" (p[2]),
|
||||
"=d" (p[3])
|
||||
: "0" (0xd), "2" (0x0));
|
||||
xstate_sz = p[1] - sizeof(struct savexmm);
|
||||
} else
|
||||
xstate_sz = 0;
|
||||
} else
|
||||
xstate_sz = 0;
|
||||
}
|
||||
|
||||
return (sizeof(ucontext_t) + xstate_sz);
|
||||
}
|
||||
|
||||
int
|
||||
__fillcontextx2(char *ctx)
|
||||
{
|
||||
struct i386_get_xfpustate xfpu;
|
||||
ucontext_t *ucp;
|
||||
|
||||
ucp = (ucontext_t *)ctx;
|
||||
if (xstate_sz != 0) {
|
||||
xfpu.addr = (char *)(ucp + 1);
|
||||
xfpu.len = xstate_sz;
|
||||
if (sysarch(I386_GET_XFPUSTATE, &xfpu) == -1)
|
||||
return (-1);
|
||||
ucp->uc_mcontext.mc_xfpustate = (__register_t)xfpu.addr;
|
||||
ucp->uc_mcontext.mc_xfpustate_len = xstate_sz;
|
||||
ucp->uc_mcontext.mc_flags |= _MC_HASFPXSTATE;
|
||||
} else {
|
||||
ucp->uc_mcontext.mc_xfpustate = 0;
|
||||
ucp->uc_mcontext.mc_xfpustate_len = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
__fillcontextx(char *ctx)
|
||||
{
|
||||
ucontext_t *ucp;
|
||||
|
||||
ucp = (ucontext_t *)ctx;
|
||||
if (getcontext(ucp) == -1)
|
||||
return (-1);
|
||||
__fillcontextx2(ctx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
__weak_reference(__getcontextx, getcontextx);
|
||||
|
||||
ucontext_t *
|
||||
__getcontextx(void)
|
||||
{
|
||||
char *ctx;
|
||||
int error;
|
||||
|
||||
ctx = malloc(__getcontextx_size());
|
||||
if (ctx == NULL)
|
||||
return (NULL);
|
||||
if (__fillcontextx(ctx) == -1) {
|
||||
error = errno;
|
||||
free(ctx);
|
||||
errno = error;
|
||||
return (NULL);
|
||||
}
|
||||
return ((ucontext_t *)ctx);
|
||||
}
|
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 25, 2019
|
||||
.Dd February 15, 2019
|
||||
.Dt SENDFILE 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -224,6 +224,19 @@ implementation of
|
||||
.Fn sendfile
|
||||
is "zero-copy", meaning that it has been optimized so that copying of the file data is avoided.
|
||||
.Sh TUNING
|
||||
.Ss physical paging buffers
|
||||
.Fn sendfile
|
||||
uses vnode pager to read file pages into memory.
|
||||
The pager uses a pool of physical buffers to run its I/O operations.
|
||||
When system runs out of pbufs, sendfile will block and report state
|
||||
.Dq Li zonelimit .
|
||||
Size of the pool can be tuned with
|
||||
.Va vm.vnode_pbufs
|
||||
.Xr loader.conf 5
|
||||
tunable and can be checked with
|
||||
.Xr sysctl 8
|
||||
OID of the same name at runtime.
|
||||
.Ss sendfile(2) buffers
|
||||
On some architectures, this system call internally uses a special
|
||||
.Fn sendfile
|
||||
buffer
|
||||
@ -279,9 +292,11 @@ buffers usage respectively.
|
||||
These values may also be viewed through
|
||||
.Nm netstat Fl m .
|
||||
.Pp
|
||||
If a value of zero is reported for
|
||||
.Va kern.ipc.nsfbufs ,
|
||||
your architecture does not need to use
|
||||
If
|
||||
.Xr sysctl 8
|
||||
OID
|
||||
.Va kern.ipc.nsfbufs
|
||||
doesn't exist, your architecture does not need to use
|
||||
.Fn sendfile
|
||||
buffers because their task can be efficiently performed
|
||||
by the generic virtual memory structures.
|
||||
@ -363,11 +378,13 @@ does not support
|
||||
The socket peer has closed the connection.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr loader.conf 5 ,
|
||||
.Xr netstat 1 ,
|
||||
.Xr open 2 ,
|
||||
.Xr send 2 ,
|
||||
.Xr socket 2 ,
|
||||
.Xr writev 2 ,
|
||||
.Xr sysctl 8 ,
|
||||
.Xr tuning 7
|
||||
.Rs
|
||||
.%A K. Elmeleegy
|
||||
|
6
lib/libc/x86/gen/Makefile.inc
Normal file
6
lib/libc/x86/gen/Makefile.inc
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${LIBC_SRCTOP}/x86/gen
|
||||
|
||||
SRCS+= \
|
||||
getcontextx.c
|
@ -35,51 +35,78 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/sysarch.h>
|
||||
#include <x86/ifunc.h>
|
||||
#include <x86/fpu.h>
|
||||
|
||||
static int xstate_sz = -1;
|
||||
#if defined __i386__
|
||||
#define X86_GET_XFPUSTATE I386_GET_XFPUSTATE
|
||||
typedef struct savexmm savex86_t ;
|
||||
typedef struct i386_get_xfpustate x86_get_xfpustate_t;
|
||||
#elif defined __amd64__
|
||||
#define X86_GET_XFPUSTATE AMD64_GET_XFPUSTATE
|
||||
typedef struct savefpu savex86_t;
|
||||
typedef struct amd64_get_xfpustate x86_get_xfpustate_t;
|
||||
#else
|
||||
#error "Wrong arch"
|
||||
#endif
|
||||
|
||||
int
|
||||
__getcontextx_size(void)
|
||||
static int xstate_sz = 0;
|
||||
|
||||
static int
|
||||
__getcontextx_size_xfpu(void)
|
||||
{
|
||||
u_int p[4];
|
||||
|
||||
if (xstate_sz == -1) {
|
||||
do_cpuid(1, p);
|
||||
if ((p[2] & CPUID2_OSXSAVE) != 0) {
|
||||
cpuid_count(0xd, 0x0, p);
|
||||
xstate_sz = p[1] - sizeof(struct savefpu);
|
||||
} else
|
||||
xstate_sz = 0;
|
||||
}
|
||||
|
||||
return (sizeof(ucontext_t) + xstate_sz);
|
||||
}
|
||||
|
||||
int
|
||||
__fillcontextx2(char *ctx)
|
||||
DEFINE_UIFUNC(, int, __getcontextx_size, (void), static)
|
||||
{
|
||||
struct amd64_get_xfpustate xfpu;
|
||||
u_int p[4];
|
||||
|
||||
if ((cpu_feature2 & CPUID2_OSXSAVE) != 0) {
|
||||
cpuid_count(0xd, 0x0, p);
|
||||
xstate_sz = p[1] - sizeof(savex86_t);
|
||||
}
|
||||
return (__getcontextx_size_xfpu);
|
||||
}
|
||||
|
||||
static int
|
||||
__fillcontextx2_xfpu(char *ctx)
|
||||
{
|
||||
x86_get_xfpustate_t xfpu;
|
||||
ucontext_t *ucp;
|
||||
|
||||
ucp = (ucontext_t *)ctx;
|
||||
if (xstate_sz != 0) {
|
||||
xfpu.addr = (char *)(ucp + 1);
|
||||
xfpu.len = xstate_sz;
|
||||
if (sysarch(AMD64_GET_XFPUSTATE, &xfpu) == -1)
|
||||
return (-1);
|
||||
ucp->uc_mcontext.mc_xfpustate = (__register_t)xfpu.addr;
|
||||
ucp->uc_mcontext.mc_xfpustate_len = xstate_sz;
|
||||
ucp->uc_mcontext.mc_flags |= _MC_HASFPXSTATE;
|
||||
} else {
|
||||
ucp->uc_mcontext.mc_xfpustate = 0;
|
||||
ucp->uc_mcontext.mc_xfpustate_len = 0;
|
||||
}
|
||||
xfpu.addr = (char *)(ucp + 1);
|
||||
xfpu.len = xstate_sz;
|
||||
if (sysarch(X86_GET_XFPUSTATE, &xfpu) == -1)
|
||||
return (-1);
|
||||
ucp->uc_mcontext.mc_xfpustate = (__register_t)xfpu.addr;
|
||||
ucp->uc_mcontext.mc_xfpustate_len = xstate_sz;
|
||||
ucp->uc_mcontext.mc_flags |= _MC_HASFPXSTATE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
__fillcontextx2_noxfpu(char *ctx)
|
||||
{
|
||||
ucontext_t *ucp;
|
||||
|
||||
ucp = (ucontext_t *)ctx;
|
||||
ucp->uc_mcontext.mc_xfpustate = 0;
|
||||
ucp->uc_mcontext.mc_xfpustate_len = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
DEFINE_UIFUNC(, int, __fillcontextx2, (char *), static)
|
||||
{
|
||||
|
||||
return ((cpu_feature2 & CPUID2_OSXSAVE) != 0 ? __fillcontextx2_xfpu :
|
||||
__fillcontextx2_noxfpu);
|
||||
}
|
||||
|
||||
int
|
||||
__fillcontextx(char *ctx)
|
||||
{
|
@ -53,31 +53,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <x86/ifunc.h>
|
||||
#include "libc_private.h"
|
||||
|
||||
static void
|
||||
cpuidp(u_int leaf, u_int p[4])
|
||||
{
|
||||
|
||||
__asm __volatile(
|
||||
#if defined(__i386__)
|
||||
" pushl %%ebx\n"
|
||||
#endif
|
||||
" cpuid\n"
|
||||
#if defined(__i386__)
|
||||
" movl %%ebx,%1\n"
|
||||
" popl %%ebx"
|
||||
#endif
|
||||
: "=a" (p[0]),
|
||||
#if defined(__i386__)
|
||||
"=r" (p[1]),
|
||||
#elif defined(__amd64__)
|
||||
"=b" (p[1]),
|
||||
#else
|
||||
#error "Arch"
|
||||
#endif
|
||||
"=c" (p[2]), "=d" (p[3])
|
||||
: "0" (leaf));
|
||||
}
|
||||
|
||||
static void
|
||||
rdtsc_mb_lfence(void)
|
||||
{
|
||||
@ -100,12 +75,12 @@ rdtsc_mb_none(void)
|
||||
DEFINE_UIFUNC(static, void, rdtsc_mb, (void), static)
|
||||
{
|
||||
u_int p[4];
|
||||
/* Not a typo, string matches our cpuidp() registers use. */
|
||||
/* Not a typo, string matches our do_cpuid() registers use. */
|
||||
static const char intel_id[] = "GenuntelineI";
|
||||
|
||||
if ((cpu_feature & CPUID_SSE2) == 0)
|
||||
return (rdtsc_mb_none);
|
||||
cpuidp(0, p);
|
||||
do_cpuid(0, p);
|
||||
return (memcmp(p + 1, intel_id, sizeof(intel_id) - 1) == 0 ?
|
||||
rdtsc_mb_lfence : rdtsc_mb_mfence);
|
||||
}
|
||||
|
@ -213,6 +213,15 @@ memstat_sysctl_uma(struct memory_type_list *list, int flags)
|
||||
mtp->mt_numfrees += upsp->ups_frees;
|
||||
}
|
||||
|
||||
/*
|
||||
* Values for uth_allocs and uth_frees frees are snap.
|
||||
* It may happen that kernel reports that number of frees
|
||||
* is greater than number of allocs. See counter(9) for
|
||||
* details.
|
||||
*/
|
||||
if (mtp->mt_numallocs < mtp->mt_numfrees)
|
||||
mtp->mt_numallocs = mtp->mt_numfrees;
|
||||
|
||||
mtp->mt_size = uthp->uth_size;
|
||||
mtp->mt_rsize = uthp->uth_rsize;
|
||||
mtp->mt_memalloced = mtp->mt_numallocs * uthp->uth_size;
|
||||
|
@ -72,14 +72,15 @@ _tcb_set(struct tcb *tcb)
|
||||
static __inline struct tcb *
|
||||
_tcb_get(void)
|
||||
{
|
||||
register uint8_t *_tp;
|
||||
register struct tcb *tcb;
|
||||
|
||||
#ifdef __powerpc64__
|
||||
__asm __volatile("mr %0,13" : "=r"(_tp));
|
||||
__asm __volatile("addi %0,13,%1" : "=r"(tcb) : "i"(-TP_OFFSET));
|
||||
#else
|
||||
__asm __volatile("mr %0,2" : "=r"(_tp));
|
||||
__asm __volatile("addi %0,2,%1" : "=r"(tcb) : "i"(-TP_OFFSET));
|
||||
#endif
|
||||
|
||||
return ((struct tcb *)(_tp - TP_OFFSET));
|
||||
return (tcb);
|
||||
}
|
||||
|
||||
static __inline struct pthread *
|
||||
|
@ -13,6 +13,7 @@ name="nfsd"
|
||||
desc="Remote NFS server"
|
||||
rcvar="nfs_server_enable"
|
||||
command="/usr/sbin/${name}"
|
||||
nfs_server_vhost=""
|
||||
|
||||
load_rc_config $name
|
||||
start_precmd="nfsd_precmd"
|
||||
@ -20,6 +21,7 @@ sig_stop="USR1"
|
||||
|
||||
nfsd_precmd()
|
||||
{
|
||||
local _vhost
|
||||
rc_flags="${nfs_server_flags}"
|
||||
|
||||
# Load the modules now, so that the vfs.nfsd sysctl
|
||||
@ -46,6 +48,9 @@ nfsd_precmd()
|
||||
|
||||
force_depend rpcbind || return 1
|
||||
force_depend mountd || return 1
|
||||
if [ -n "${nfs_server_vhost}" ]; then
|
||||
command_args="-V \"${nfs_server_vhost}\""
|
||||
fi
|
||||
}
|
||||
|
||||
run_rc_command "$1"
|
||||
|
@ -7,6 +7,7 @@
|
||||
.include <src.opts.mk>
|
||||
PACKAGE= clibs
|
||||
MK_BIND_NOW= no
|
||||
MK_PIE= no # Always position independent using local rules
|
||||
MK_SSP= no
|
||||
|
||||
CONFS= libmap.conf
|
||||
|
@ -196,6 +196,7 @@ main(int argc, char **argv)
|
||||
usage();
|
||||
mdtype = MD_MALLOC;
|
||||
have_mdtype = true;
|
||||
argappend(&mdconfig_arg, "-o reserve");
|
||||
break;
|
||||
case 'm':
|
||||
argappend(&newfs_arg, "-m %s", optarg);
|
||||
|
@ -177,7 +177,7 @@ static void
|
||||
firmware(const struct nvme_function *nf, int argc, char *argv[])
|
||||
{
|
||||
int fd = -1, slot = 0;
|
||||
int a_flag, s_flag, f_flag;
|
||||
int a_flag, f_flag;
|
||||
int activate_action, reboot_required;
|
||||
int opt;
|
||||
char *p, *image = NULL;
|
||||
@ -188,7 +188,7 @@ firmware(const struct nvme_function *nf, int argc, char *argv[])
|
||||
uint8_t fw_slot1_ro, fw_num_slots;
|
||||
struct nvme_controller_data cdata;
|
||||
|
||||
a_flag = s_flag = f_flag = false;
|
||||
a_flag = f_flag = false;
|
||||
|
||||
while ((opt = getopt(argc, argv, "af:s:")) != -1) {
|
||||
switch (opt) {
|
||||
@ -214,7 +214,6 @@ firmware(const struct nvme_function *nf, int argc, char *argv[])
|
||||
"7.\n", optarg);
|
||||
usage(nf);
|
||||
}
|
||||
s_flag = true;
|
||||
break;
|
||||
case 'f':
|
||||
image = optarg;
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
|
||||
.\" $FreeBSD$
|
||||
.Dd January 31, 2019
|
||||
.Dd February 15, 2019
|
||||
.Dt SRC.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -406,7 +406,8 @@ Set to build the Clang C/C++ compiler during the bootstrap phase of the build.
|
||||
This is a default setting on
|
||||
amd64/amd64, arm/arm, arm/armv6, arm/armv7, arm64/aarch64 and i386/i386.
|
||||
.It Va WITH_CLANG_EXTRAS
|
||||
Set to build additional clang and llvm tools, such as bugpoint.
|
||||
Set to build additional clang and llvm tools, such as bugpoint and
|
||||
clang-format.
|
||||
.It Va WITHOUT_CLANG_FULL
|
||||
Set to avoid building the ARCMigrate, Rewriter and StaticAnalyzer components of
|
||||
the Clang C/C++ compiler.
|
||||
@ -1542,6 +1543,9 @@ When set, it enforces these options:
|
||||
.It
|
||||
.Va WITHOUT_AUTHPF
|
||||
.El
|
||||
.It Va WITH_PIE
|
||||
Build dynamically linked binaries as
|
||||
Position-Independent Executable (PIE).
|
||||
.It Va WITHOUT_PKGBOOTSTRAP
|
||||
Set to not build
|
||||
.Xr pkg 7
|
||||
|
@ -91,13 +91,16 @@ CTFFLAGS+= -g
|
||||
# prefer .s to a .c, add .po, remove stuff not used in the BSD libraries
|
||||
# .pico used for PIC object files
|
||||
# .nossppico used for NOSSP PIC object files
|
||||
.SUFFIXES: .out .o .bc .ll .po .pico .nossppico .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
|
||||
# .pieo used for PIE object files
|
||||
.SUFFIXES: .out .o .bc .ll .po .pico .nossppico .pieo .S .asm .s .c .cc .cpp .cxx .C .f .y .l .ln
|
||||
|
||||
.if !defined(PICFLAG)
|
||||
.if ${MACHINE_CPUARCH} == "sparc64"
|
||||
PICFLAG=-fPIC
|
||||
PIEFLAG=-fPIE
|
||||
.else
|
||||
PICFLAG=-fpic
|
||||
PIEFLAG=-fpie
|
||||
.endif
|
||||
.endif
|
||||
|
||||
@ -115,6 +118,10 @@ PO_FLAG=-pg
|
||||
${CC} ${PICFLAG} -DPIC ${SHARED_CFLAGS:C/^-fstack-protector.*$//} ${CFLAGS:C/^-fstack-protector.*$//} -c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.c.pieo:
|
||||
${CC} ${PIEFLAG} -DPIC ${SHARED_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.cc.po .C.po .cpp.po .cxx.po:
|
||||
${CXX} ${PO_FLAG} ${STATIC_CXXFLAGS} ${PO_CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
@ -124,6 +131,9 @@ PO_FLAG=-pg
|
||||
.cc.nossppico .C.nossppico .cpp.nossppico .cxx.nossppico:
|
||||
${CXX} ${PICFLAG} -DPIC ${SHARED_CXXFLAGS:C/^-fstack-protector.*$//} ${CXXFLAGS:C/^-fstack-protector.*$//} -c ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
.cc.pieo .C.pieo .cpp.pieo .cxx.pieo:
|
||||
${CXX} ${PIEFLAG} ${SHARED_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
|
||||
.f.po:
|
||||
${FC} -pg ${FFLAGS} -o ${.TARGET} -c ${.IMPSRC}
|
||||
${CTFCONVERT_CMD}
|
||||
@ -136,7 +146,7 @@ PO_FLAG=-pg
|
||||
${FC} ${PICFLAG} -DPIC ${FFLAGS:C/^-fstack-protector.*$//} -o ${.TARGET} -c ${.IMPSRC}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.s.po .s.pico .s.nossppico:
|
||||
.s.po .s.pico .s.nossppico .s.pieo:
|
||||
${AS} ${AFLAGS} -o ${.TARGET} ${.IMPSRC}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
@ -155,6 +165,11 @@ PO_FLAG=-pg
|
||||
${CFLAGS:C/^-fstack-protector.*$//} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.asm.pieo:
|
||||
${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PIEFLAG} -DPIC \
|
||||
${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.S.po:
|
||||
${CC:N${CCACHE_BIN}} -DPROF ${PO_CFLAGS} ${ACFLAGS} -c ${.IMPSRC} \
|
||||
-o ${.TARGET}
|
||||
@ -170,6 +185,11 @@ PO_FLAG=-pg
|
||||
-c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
.S.pieo:
|
||||
${CC:N${CCACHE_BIN}} ${PIEFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
|
||||
-c ${.IMPSRC} -o ${.TARGET}
|
||||
${CTFCONVERT_CMD}
|
||||
|
||||
_LIBDIR:=${LIBDIR}
|
||||
_SHLIBDIR:=${SHLIBDIR}
|
||||
|
||||
@ -334,6 +354,20 @@ lib${LIB_PRIVATE}${LIB}_nossp_pic.a: ${NOSSPSOBJS}
|
||||
|
||||
.endif # !defined(INTERNALLIB)
|
||||
|
||||
.if defined(INTERNALLIB) && ${MK_PIE} != "no"
|
||||
PIEOBJS+= ${OBJS:.o=.pieo}
|
||||
DEPENDOBJS+= ${PIEOBJS}
|
||||
CLEANFILES+= ${PIEOBJS}
|
||||
|
||||
_LIBS+= lib${LIB_PRIVATE}${LIB}_pie.a
|
||||
|
||||
lib${LIB_PRIVATE}${LIB}_pie.a: ${PIEOBJS}
|
||||
@${ECHO} building pie ${LIB} library
|
||||
@rm -f ${.TARGET}
|
||||
${AR} ${ARFLAGS} ${.TARGET} ${PIEOBJS} ${ARADD}
|
||||
${RANLIB} ${RANLIBFLAGS} ${.TARGET}
|
||||
.endif
|
||||
|
||||
.if defined(_SKIP_BUILD)
|
||||
all:
|
||||
.else
|
||||
|
@ -73,6 +73,7 @@ __DEFAULT_NO_OPTIONS = \
|
||||
CCACHE_BUILD \
|
||||
CTF \
|
||||
INSTALL_AS_USER \
|
||||
PIE \
|
||||
RETPOLINE \
|
||||
STALE_STAGED
|
||||
|
||||
|
@ -38,11 +38,16 @@ MK_DEBUG_FILES= no
|
||||
.if ${MK_BIND_NOW} != "no"
|
||||
LDFLAGS+= -Wl,-znow
|
||||
.endif
|
||||
.if ${MK_PIE} != "no" && (!defined(NO_SHARED) || ${NO_SHARED:tl} == "no")
|
||||
CFLAGS+= -fPIE
|
||||
CXXFLAGS+= -fPIE
|
||||
LDFLAGS+= -pie
|
||||
.endif
|
||||
.if ${MK_RETPOLINE} != "no"
|
||||
CFLAGS+= -mretpoline
|
||||
CXXFLAGS+= -mretpoline
|
||||
# retpolineplt is broken with static linking (PR 233336)
|
||||
.if !defined(NO_SHARED) || ${NO_SHARED} == "no" || ${NO_SHARED} == "NO"
|
||||
.if !defined(NO_SHARED) || ${NO_SHARED:tl} == "no"
|
||||
LDFLAGS+= -Wl,-zretpolineplt
|
||||
.endif
|
||||
.endif
|
||||
@ -68,7 +73,7 @@ TAGS+= package=${PACKAGE:Uruntime}
|
||||
TAG_ARGS= -T ${TAGS:[*]:S/ /,/g}
|
||||
.endif
|
||||
|
||||
.if defined(NO_SHARED) && (${NO_SHARED} != "no" && ${NO_SHARED} != "NO")
|
||||
.if defined(NO_SHARED) && ${NO_SHARED:tl} != "no"
|
||||
LDFLAGS+= -static
|
||||
.endif
|
||||
|
||||
|
@ -385,6 +385,10 @@ LDADD_gtest_main= -lprivategtest_main
|
||||
LIB${_l:tu}?= ${LIBDESTDIR}${LIBDIR_BASE}/libprivate${_l}.a
|
||||
.endfor
|
||||
|
||||
.if ${MK_PIE} != "no"
|
||||
PIE_SUFFIX= _pie
|
||||
.endif
|
||||
|
||||
.for _l in ${_LIBRARIES}
|
||||
.if ${_INTERNALLIBS:M${_l}} || !defined(SYSROOT)
|
||||
LDADD_${_l}_L+= -L${LIB${_l:tu}DIR}
|
||||
@ -392,12 +396,14 @@ LDADD_${_l}_L+= -L${LIB${_l:tu}DIR}
|
||||
DPADD_${_l}?= ${LIB${_l:tu}}
|
||||
.if ${_PRIVATELIBS:M${_l}}
|
||||
LDADD_${_l}?= -lprivate${_l}
|
||||
.elif ${_INTERNALLIBS:M${_l}}
|
||||
LDADD_${_l}?= ${LDADD_${_l}_L} -l${_l:S/${PIE_SUFFIX}//}${PIE_SUFFIX}
|
||||
.else
|
||||
LDADD_${_l}?= ${LDADD_${_l}_L} -l${_l}
|
||||
.endif
|
||||
# Add in all dependencies for static linkage.
|
||||
.if defined(_DP_${_l}) && (${_INTERNALLIBS:M${_l}} || \
|
||||
(defined(NO_SHARED) && (${NO_SHARED} != "no" && ${NO_SHARED} != "NO")))
|
||||
(defined(NO_SHARED) && ${NO_SHARED:tl} != "no"))
|
||||
.for _d in ${_DP_${_l}}
|
||||
DPADD_${_l}+= ${DPADD_${_d}}
|
||||
LDADD_${_l}+= ${LDADD_${_d}}
|
||||
@ -444,69 +450,69 @@ LDADD+= ${LDADD_${_l}}
|
||||
|
||||
# INTERNALLIB definitions.
|
||||
LIBELFTCDIR= ${OBJTOP}/lib/libelftc
|
||||
LIBELFTC?= ${LIBELFTCDIR}/libelftc.a
|
||||
LIBELFTC?= ${LIBELFTCDIR}/libelftc${PIE_SUFFIX}.a
|
||||
|
||||
LIBPEDIR= ${OBJTOP}/lib/libpe
|
||||
LIBPE?= ${LIBPEDIR}/libpe.a
|
||||
LIBPE?= ${LIBPEDIR}/libpe${PIE_SUFFIX}.a
|
||||
|
||||
LIBOPENBSDDIR= ${OBJTOP}/lib/libopenbsd
|
||||
LIBOPENBSD?= ${LIBOPENBSDDIR}/libopenbsd.a
|
||||
LIBOPENBSD?= ${LIBOPENBSDDIR}/libopenbsd${PIE_SUFFIX}.a
|
||||
|
||||
LIBSMDIR= ${OBJTOP}/lib/libsm
|
||||
LIBSM?= ${LIBSMDIR}/libsm.a
|
||||
LIBSM?= ${LIBSMDIR}/libsm${PIE_SUFFIX}.a
|
||||
|
||||
LIBSMDBDIR= ${OBJTOP}/lib/libsmdb
|
||||
LIBSMDB?= ${LIBSMDBDIR}/libsmdb.a
|
||||
LIBSMDB?= ${LIBSMDBDIR}/libsmdb${PIE_SUFFIX}.a
|
||||
|
||||
LIBSMUTILDIR= ${OBJTOP}/lib/libsmutil
|
||||
LIBSMUTIL?= ${LIBSMUTILDIR}/libsmutil.a
|
||||
LIBSMUTIL?= ${LIBSMUTILDIR}/libsmutil${PIE_SUFFIX}.a
|
||||
|
||||
LIBNETBSDDIR?= ${OBJTOP}/lib/libnetbsd
|
||||
LIBNETBSD?= ${LIBNETBSDDIR}/libnetbsd.a
|
||||
LIBNETBSD?= ${LIBNETBSDDIR}/libnetbsd${PIE_SUFFIX}.a
|
||||
|
||||
LIBVERSDIR?= ${OBJTOP}/kerberos5/lib/libvers
|
||||
LIBVERS?= ${LIBVERSDIR}/libvers.a
|
||||
LIBVERS?= ${LIBVERSDIR}/libvers${PIE_SUFFIX}.a
|
||||
|
||||
LIBSLDIR= ${OBJTOP}/kerberos5/lib/libsl
|
||||
LIBSL?= ${LIBSLDIR}/libsl.a
|
||||
LIBSL?= ${LIBSLDIR}/libsl${PIE_SUFFIX}.a
|
||||
|
||||
LIBIPFDIR= ${OBJTOP}/sbin/ipf/libipf
|
||||
LIBIPF?= ${LIBIPFDIR}/libipf.a
|
||||
LIBIPF?= ${LIBIPFDIR}/libipf${PIE_SUFFIX}.a
|
||||
|
||||
LIBTELNETDIR= ${OBJTOP}/lib/libtelnet
|
||||
LIBTELNET?= ${LIBTELNETDIR}/libtelnet.a
|
||||
LIBTELNET?= ${LIBTELNETDIR}/libtelnet${PIE_SUFFIX}.a
|
||||
|
||||
LIBCRONDIR= ${OBJTOP}/usr.sbin/cron/lib
|
||||
LIBCRON?= ${LIBCRONDIR}/libcron.a
|
||||
LIBCRON?= ${LIBCRONDIR}/libcron${PIE_SUFFIX}.a
|
||||
|
||||
LIBNTPDIR= ${OBJTOP}/usr.sbin/ntp/libntp
|
||||
LIBNTP?= ${LIBNTPDIR}/libntp.a
|
||||
LIBNTP?= ${LIBNTPDIR}/libntp${PIE_SUFFIX}.a
|
||||
|
||||
LIBNTPEVENTDIR= ${OBJTOP}/usr.sbin/ntp/libntpevent
|
||||
LIBNTPEVENT?= ${LIBNTPEVENTDIR}/libntpevent.a
|
||||
LIBNTPEVENT?= ${LIBNTPEVENTDIR}/libntpevent${PIE_SUFFIX}.a
|
||||
|
||||
LIBOPTSDIR= ${OBJTOP}/usr.sbin/ntp/libopts
|
||||
LIBOPTS?= ${LIBOPTSDIR}/libopts.a
|
||||
LIBOPTS?= ${LIBOPTSDIR}/libopts${PIE_SUFFIX}.a
|
||||
|
||||
LIBPARSEDIR= ${OBJTOP}/usr.sbin/ntp/libparse
|
||||
LIBPARSE?= ${LIBPARSEDIR}/libparse.a
|
||||
LIBPARSE?= ${LIBPARSEDIR}/libparse${PIE_SUFFIX}.a
|
||||
|
||||
LIBLPRDIR= ${OBJTOP}/usr.sbin/lpr/common_source
|
||||
LIBLPR?= ${LIBLPRDIR}/liblpr.a
|
||||
LIBLPR?= ${LIBLPRDIR}/liblpr${PIE_SUFFIX}.a
|
||||
|
||||
LIBFIFOLOGDIR= ${OBJTOP}/usr.sbin/fifolog/lib
|
||||
LIBFIFOLOG?= ${LIBFIFOLOGDIR}/libfifolog.a
|
||||
LIBFIFOLOG?= ${LIBFIFOLOGDIR}/libfifolog${PIE_SUFFIX}.a
|
||||
|
||||
LIBBSNMPTOOLSDIR= ${OBJTOP}/usr.sbin/bsnmpd/tools/libbsnmptools
|
||||
LIBBSNMPTOOLS?= ${LIBBSNMPTOOLSDIR}/libbsnmptools.a
|
||||
LIBBSNMPTOOLS?= ${LIBBSNMPTOOLSDIR}/libbsnmptools${PIE_SUFFIX}.a
|
||||
|
||||
LIBAMUDIR= ${OBJTOP}/usr.sbin/amd/libamu
|
||||
LIBAMU?= ${LIBAMUDIR}/libamu.a
|
||||
LIBAMU?= ${LIBAMUDIR}/libamu${PIE_SUFFIX}.a
|
||||
|
||||
LIBBE?= ${LIBBEDIR}/libbe.a
|
||||
LIBBE?= ${LIBBEDIR}/libbe${PIE_SUFFIX}.a
|
||||
|
||||
LIBPMCSTATDIR= ${OBJTOP}/lib/libpmcstat
|
||||
LIBPMCSTAT?= ${LIBPMCSTATDIR}/libpmcstat.a
|
||||
LIBPMCSTAT?= ${LIBPMCSTATDIR}/libpmcstat${PIE_SUFFIX}.a
|
||||
|
||||
LIBC_NOSSP_PICDIR= ${OBJTOP}/lib/libc
|
||||
LIBC_NOSSP_PIC?= ${LIBC_NOSSP_PICDIR}/libc_nossp_pic.a
|
||||
|
@ -122,13 +122,15 @@ net_open(struct open_file *f, ...)
|
||||
{
|
||||
struct iodesc *d;
|
||||
va_list args;
|
||||
char *devname; /* Device part of file name (or NULL). */
|
||||
struct devdesc *dev;
|
||||
const char *devname; /* Device part of file name (or NULL). */
|
||||
int error = 0;
|
||||
|
||||
va_start(args, f);
|
||||
devname = va_arg(args, char*);
|
||||
dev = va_arg(args, struct devdesc *);
|
||||
va_end(args);
|
||||
|
||||
devname = dev->d_dev->dv_name;
|
||||
/* Before opening another interface, close the previous one first. */
|
||||
if (netdev_sock >= 0 && strcmp(devname, netdev_name) != 0)
|
||||
net_cleanup();
|
||||
@ -137,7 +139,7 @@ net_open(struct open_file *f, ...)
|
||||
if (netdev_opens == 0) {
|
||||
/* Find network interface. */
|
||||
if (netdev_sock < 0) {
|
||||
netdev_sock = netif_open(devname);
|
||||
netdev_sock = netif_open(dev);
|
||||
if (netdev_sock < 0) {
|
||||
printf("net_open: netif_open() failed\n");
|
||||
return (ENXIO);
|
||||
|
@ -75,7 +75,7 @@ display_size(uint64_t size, u_int sectorsize)
|
||||
size /= 1024;
|
||||
unit = 'M';
|
||||
}
|
||||
sprintf(buf, "%ld%cB", (long)size, unit);
|
||||
sprintf(buf, "%4ld%cB", (long)size, unit);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
@ -102,7 +102,6 @@ ptblread(void *d, void *buf, size_t blocks, uint64_t offset)
|
||||
blocks * od->sectorsize, (char *)buf, NULL));
|
||||
}
|
||||
|
||||
#define PWIDTH 35
|
||||
static int
|
||||
ptable_print(void *arg, const char *pname, const struct ptable_entry *part)
|
||||
{
|
||||
@ -112,16 +111,16 @@ ptable_print(void *arg, const char *pname, const struct ptable_entry *part)
|
||||
struct ptable *table;
|
||||
char line[80];
|
||||
int res;
|
||||
u_int sectsize;
|
||||
uint64_t partsize;
|
||||
|
||||
pa = (struct print_args *)arg;
|
||||
od = (struct open_disk *)pa->dev->dd.d_opendata;
|
||||
sprintf(line, " %s%s: %s", pa->prefix, pname,
|
||||
parttype2str(part->type));
|
||||
if (pa->verbose)
|
||||
sprintf(line, "%-*s%s", PWIDTH, line,
|
||||
display_size(part->end - part->start + 1,
|
||||
od->sectorsize));
|
||||
strcat(line, "\n");
|
||||
sectsize = od->sectorsize;
|
||||
partsize = part->end - part->start + 1;
|
||||
sprintf(line, " %s%s: %s\t%s\n", pa->prefix, pname,
|
||||
parttype2str(part->type),
|
||||
pa->verbose ? display_size(partsize, sectsize) : "");
|
||||
if (pager_output(line))
|
||||
return 1;
|
||||
res = 0;
|
||||
@ -131,10 +130,15 @@ ptable_print(void *arg, const char *pname, const struct ptable_entry *part)
|
||||
dev.dd.d_unit = pa->dev->dd.d_unit;
|
||||
dev.d_slice = part->index;
|
||||
dev.d_partition = -1;
|
||||
if (disk_open(&dev, part->end - part->start + 1,
|
||||
od->sectorsize) == 0) {
|
||||
table = ptable_open(&dev, part->end - part->start + 1,
|
||||
od->sectorsize, ptblread);
|
||||
if (disk_open(&dev, partsize, sectsize) == 0) {
|
||||
/*
|
||||
* disk_open() for partition -1 on a bsd slice assumes
|
||||
* you want the first bsd partition. Reset things so
|
||||
* that we're looking at the start of the raw slice.
|
||||
*/
|
||||
dev.d_partition = -1;
|
||||
dev.d_offset = part->start;
|
||||
table = ptable_open(&dev, partsize, sectsize, ptblread);
|
||||
if (table != NULL) {
|
||||
sprintf(line, " %s%s", pa->prefix, pname);
|
||||
bsd.dev = pa->dev;
|
||||
@ -149,7 +153,6 @@ ptable_print(void *arg, const char *pname, const struct ptable_entry *part)
|
||||
|
||||
return (res);
|
||||
}
|
||||
#undef PWIDTH
|
||||
|
||||
int
|
||||
disk_print(struct disk_devdesc *dev, char *prefix, int verbose)
|
||||
|
@ -788,6 +788,9 @@ ptable_close(struct ptable *table)
|
||||
{
|
||||
struct pentry *entry;
|
||||
|
||||
if (table == NULL)
|
||||
return;
|
||||
|
||||
while (!STAILQ_EMPTY(&table->entries)) {
|
||||
entry = STAILQ_FIRST(&table->entries);
|
||||
STAILQ_REMOVE_HEAD(&table->entries, entry);
|
||||
|
@ -7,6 +7,7 @@
|
||||
LOADER_ADDRESS?=0x200000
|
||||
LDFLAGS+= -nostdlib
|
||||
LDFLAGS.lld+= -Wl,--no-rosegment
|
||||
MK_PIE:= no
|
||||
|
||||
# BTX components
|
||||
BTXDIR= ${BOOTOBJ}/i386/btx
|
||||
|
@ -545,32 +545,19 @@ probe_drive(struct zfsdsk *zdsk)
|
||||
char *sec;
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* If we find a vdev on the whole disk, stop here.
|
||||
*/
|
||||
if (vdev_probe(vdev_read2, zdsk, NULL) == 0)
|
||||
return;
|
||||
|
||||
#ifdef LOADER_GELI_SUPPORT
|
||||
/*
|
||||
* Taste the disk, if it is GELI encrypted, decrypt it and check to see if
|
||||
* it is a usable vdev then. Otherwise dig
|
||||
* out the partition table and probe each slice/partition
|
||||
* in turn for a vdev or GELI encrypted vdev.
|
||||
* Taste the disk, if it is GELI encrypted, decrypt it then dig out the
|
||||
* partition table and probe each slice/partition in turn for a vdev or
|
||||
* GELI encrypted vdev.
|
||||
*/
|
||||
elba = drvsize_ext(zdsk);
|
||||
if (elba > 0) {
|
||||
elba--;
|
||||
}
|
||||
zdsk->gdev = geli_taste(vdev_read, zdsk, elba, "disk%u:0:");
|
||||
if (zdsk->gdev != NULL) {
|
||||
if (geli_havekey(zdsk->gdev) == 0 ||
|
||||
geli_passphrase(zdsk->gdev, gelipw) == 0) {
|
||||
if (vdev_probe(vdev_read2, zdsk, NULL) == 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((zdsk->gdev != NULL) && (geli_havekey(zdsk->gdev) == 0))
|
||||
geli_passphrase(zdsk->gdev, gelipw);
|
||||
#endif /* LOADER_GELI_SUPPORT */
|
||||
|
||||
sec = dmadat->secbuf;
|
||||
|
@ -241,6 +241,10 @@ dirmatch(struct open_file *f, const char *path, struct iso_directory_record *dp,
|
||||
icase = 1;
|
||||
} else
|
||||
icase = 0;
|
||||
|
||||
if (strlen(path) != len)
|
||||
return (0);
|
||||
|
||||
for (i = len; --i >= 0; path++, cp++) {
|
||||
if (!*path || *path == '/')
|
||||
break;
|
||||
|
@ -363,51 +363,100 @@ static int
|
||||
vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes)
|
||||
{
|
||||
int fd, ret;
|
||||
size_t res, size, remainder, rb_size, blksz;
|
||||
unsigned secsz;
|
||||
off_t off;
|
||||
char *bouncebuf, *rb_buf;
|
||||
size_t res, head, tail, total_size, full_sec_size;
|
||||
unsigned secsz, do_tail_read;
|
||||
off_t start_sec;
|
||||
char *outbuf, *bouncebuf;
|
||||
|
||||
fd = (uintptr_t) priv;
|
||||
outbuf = (char *) buf;
|
||||
bouncebuf = NULL;
|
||||
|
||||
ret = ioctl(fd, DIOCGSECTORSIZE, &secsz);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
|
||||
off = offset / secsz;
|
||||
remainder = offset % secsz;
|
||||
if (lseek(fd, off * secsz, SEEK_SET) == -1)
|
||||
return (errno);
|
||||
/*
|
||||
* Handling reads of arbitrary offset and size - multi-sector case
|
||||
* and single-sector case.
|
||||
*
|
||||
* Multi-sector Case
|
||||
* (do_tail_read = true if tail > 0)
|
||||
*
|
||||
* |<----------------------total_size--------------------->|
|
||||
* | |
|
||||
* |<--head-->|<--------------bytes------------>|<--tail-->|
|
||||
* | | | |
|
||||
* | | |<~full_sec_size~>| | |
|
||||
* +------------------+ +------------------+
|
||||
* | |0101010| . . . |0101011| |
|
||||
* +------------------+ +------------------+
|
||||
* start_sec start_sec + n
|
||||
*
|
||||
*
|
||||
* Single-sector Case
|
||||
* (do_tail_read = false)
|
||||
*
|
||||
* |<------total_size = secsz----->|
|
||||
* | |
|
||||
* |<-head->|<---bytes--->|<-tail->|
|
||||
* +-------------------------------+
|
||||
* | |0101010101010| |
|
||||
* +-------------------------------+
|
||||
* start_sec
|
||||
*/
|
||||
start_sec = offset / secsz;
|
||||
head = offset % secsz;
|
||||
total_size = roundup2(head + bytes, secsz);
|
||||
tail = total_size - (head + bytes);
|
||||
do_tail_read = ((tail > 0) && (head + bytes > secsz));
|
||||
full_sec_size = total_size;
|
||||
if (head > 0)
|
||||
full_sec_size -= secsz;
|
||||
if (do_tail_read)
|
||||
full_sec_size -= secsz;
|
||||
|
||||
rb_buf = buf;
|
||||
rb_size = bytes;
|
||||
size = roundup2(bytes + remainder, secsz);
|
||||
blksz = size;
|
||||
if (remainder != 0 || size != bytes) {
|
||||
/* Return of partial sector data requires a bounce buffer. */
|
||||
if ((head > 0) || do_tail_read) {
|
||||
bouncebuf = zfs_alloc(secsz);
|
||||
if (bouncebuf == NULL) {
|
||||
printf("vdev_read: out of memory\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
rb_buf = bouncebuf;
|
||||
blksz = rb_size - remainder;
|
||||
}
|
||||
|
||||
while (bytes > 0) {
|
||||
res = read(fd, rb_buf, rb_size);
|
||||
if (res != rb_size) {
|
||||
if (lseek(fd, start_sec * secsz, SEEK_SET) == -1)
|
||||
return (errno);
|
||||
|
||||
/* Partial data return from first sector */
|
||||
if (head > 0) {
|
||||
res = read(fd, bouncebuf, secsz);
|
||||
if (res != secsz) {
|
||||
ret = EIO;
|
||||
goto error;
|
||||
}
|
||||
if (bytes < blksz)
|
||||
blksz = bytes;
|
||||
if (bouncebuf != NULL)
|
||||
memcpy(buf, rb_buf + remainder, blksz);
|
||||
buf = (void *)((uintptr_t)buf + blksz);
|
||||
bytes -= blksz;
|
||||
remainder = 0;
|
||||
blksz = rb_size;
|
||||
memcpy(outbuf, bouncebuf + head, min(secsz - head, bytes));
|
||||
outbuf += min(secsz - head, bytes);
|
||||
}
|
||||
|
||||
/* Full data return from read sectors */
|
||||
if (full_sec_size > 0) {
|
||||
res = read(fd, outbuf, full_sec_size);
|
||||
if (res != full_sec_size) {
|
||||
ret = EIO;
|
||||
goto error;
|
||||
}
|
||||
outbuf += full_sec_size;
|
||||
}
|
||||
|
||||
/* Partial data return from last sector */
|
||||
if (do_tail_read) {
|
||||
res = read(fd, bouncebuf, secsz);
|
||||
if (res != secsz) {
|
||||
ret = EIO;
|
||||
goto error;
|
||||
}
|
||||
memcpy(outbuf, bouncebuf, secsz - tail);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
@ -38,6 +38,7 @@ local INCORRECT_PASSWORD = "loader: incorrect password"
|
||||
-- Asterisks as a password mask
|
||||
local show_password_mask = false
|
||||
local twiddle_chars = {"/", "-", "\\", "|"}
|
||||
local screen_setup = false
|
||||
|
||||
-- Module exports
|
||||
function password.read(prompt_length)
|
||||
@ -80,8 +81,6 @@ function password.read(prompt_length)
|
||||
end
|
||||
|
||||
function password.check()
|
||||
screen.clear()
|
||||
screen.defcursor()
|
||||
-- pwd is optionally supplied if we want to check it
|
||||
local function doPrompt(prompt, pwd)
|
||||
local attempts = 1
|
||||
@ -90,6 +89,12 @@ function password.check()
|
||||
printc("\r" .. string.rep(" ", #INCORRECT_PASSWORD))
|
||||
end
|
||||
|
||||
if not screen_setup then
|
||||
screen.clear()
|
||||
screen.defcursor()
|
||||
screen_setup = true
|
||||
end
|
||||
|
||||
while true do
|
||||
if attempts > 1 then
|
||||
clear_incorrect_text_prompt()
|
||||
|
@ -11,6 +11,7 @@ LOADER_BZIP2_SUPPORT?= no
|
||||
|
||||
.include <bsd.init.mk>
|
||||
|
||||
BINDIR= /boot/uboot
|
||||
PROG= ubldr
|
||||
NEWVERSWHAT= "U-Boot loader" ${MACHINE_ARCH}
|
||||
INSTALLFLAGS= -b
|
||||
|
@ -156,7 +156,7 @@ get_device_type(const char *devstr, int *devtype)
|
||||
printf("Unknown device type '%s'\n", devstr);
|
||||
}
|
||||
|
||||
*devtype = -1;
|
||||
*devtype = DEV_TYP_NONE;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -182,6 +182,14 @@ device_typename(int type)
|
||||
* The returned values for slice and partition are interpreted by
|
||||
* disk_open().
|
||||
*
|
||||
* The device string can be a standard loader(8) disk specifier:
|
||||
*
|
||||
* disk<unit>s<slice> disk0s1
|
||||
* disk<unit>s<slice><partition> disk1s2a
|
||||
* disk<unit>p<partition> disk0p4
|
||||
*
|
||||
* or one of the following formats:
|
||||
*
|
||||
* Valid device strings: For device types:
|
||||
*
|
||||
* <type_name> DEV_TYP_STOR, DEV_TYP_NET
|
||||
@ -198,11 +206,12 @@ device_typename(int type)
|
||||
static void
|
||||
get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
{
|
||||
struct disk_devdesc dev;
|
||||
char *devstr;
|
||||
const char *p;
|
||||
char *endp;
|
||||
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
*unit = -1;
|
||||
*slice = 0;
|
||||
*partition = -1;
|
||||
@ -216,18 +225,31 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
|
||||
p = get_device_type(devstr, type);
|
||||
|
||||
/*
|
||||
* If type is DEV_TYP_STOR we have a disk-like device. If we can parse
|
||||
* the remainder of the string as a standard unit+slice+partition (e.g.,
|
||||
* 0s2a or 1p12), return those results. Otherwise we'll fall through to
|
||||
* the code that parses the legacy format.
|
||||
*/
|
||||
if ((*type & DEV_TYP_STOR) && disk_parsedev(&dev, p, NULL) == 0) {
|
||||
*unit = dev.dd.d_unit;
|
||||
*slice = dev.d_slice;
|
||||
*partition = dev.d_partition;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ignore optional spaces after the device name. */
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
|
||||
/* Unknown device name, or a known name without unit number. */
|
||||
if ((*type == -1) || (*p == '\0')) {
|
||||
if ((*type == DEV_TYP_NONE) || (*p == '\0')) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Malformed unit number. */
|
||||
if (!isdigit(*p)) {
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -242,7 +264,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
|
||||
/* Device string is malformed beyond unit number. */
|
||||
if (*p != ':') {
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
*unit = -1;
|
||||
return;
|
||||
}
|
||||
@ -255,7 +277,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
|
||||
/* Only DEV_TYP_STOR devices can have a slice specification. */
|
||||
if (!(*type & DEV_TYP_STOR)) {
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
*unit = -1;
|
||||
return;
|
||||
}
|
||||
@ -264,7 +286,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
|
||||
/* Malformed slice number. */
|
||||
if (p == endp) {
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
*unit = -1;
|
||||
*slice = 0;
|
||||
return;
|
||||
@ -278,7 +300,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
|
||||
/* Device string is malformed beyond slice number. */
|
||||
if (*p != '.') {
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
*unit = -1;
|
||||
*slice = 0;
|
||||
return;
|
||||
@ -298,7 +320,7 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
|
||||
return;
|
||||
|
||||
/* Junk beyond partition number. */
|
||||
*type = -1;
|
||||
*type = DEV_TYP_NONE;
|
||||
*unit = -1;
|
||||
*slice = 0;
|
||||
*partition = -1;
|
||||
@ -310,13 +332,13 @@ print_disk_probe_info()
|
||||
char slice[32];
|
||||
char partition[32];
|
||||
|
||||
if (currdev.d_disk.slice > 0)
|
||||
sprintf(slice, "%d", currdev.d_disk.slice);
|
||||
if (currdev.d_disk.d_slice > 0)
|
||||
sprintf(slice, "%d", currdev.d_disk.d_slice);
|
||||
else
|
||||
strcpy(slice, "<auto>");
|
||||
|
||||
if (currdev.d_disk.partition >= 0)
|
||||
sprintf(partition, "%d", currdev.d_disk.partition);
|
||||
if (currdev.d_disk.d_partition >= 0)
|
||||
sprintf(partition, "%d", currdev.d_disk.d_partition);
|
||||
else
|
||||
strcpy(partition, "<auto>");
|
||||
|
||||
@ -332,8 +354,8 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice,
|
||||
int open_result, unit;
|
||||
struct open_file f;
|
||||
|
||||
currdev.d_disk.slice = load_slice;
|
||||
currdev.d_disk.partition = load_partition;
|
||||
currdev.d_disk.d_slice = load_slice;
|
||||
currdev.d_disk.d_partition = load_partition;
|
||||
|
||||
f.f_devdata = &currdev;
|
||||
open_result = -1;
|
||||
@ -467,14 +489,14 @@ main(int argc, char **argv)
|
||||
currdev.dd.d_dev = devsw[i];
|
||||
currdev.dd.d_unit = 0;
|
||||
|
||||
if ((load_type == -1 || (load_type & DEV_TYP_STOR)) &&
|
||||
if ((load_type == DEV_TYP_NONE || (load_type & DEV_TYP_STOR)) &&
|
||||
strcmp(devsw[i]->dv_name, "disk") == 0) {
|
||||
if (probe_disks(i, load_type, load_unit, load_slice,
|
||||
load_partition) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((load_type == -1 || (load_type & DEV_TYP_NET)) &&
|
||||
if ((load_type == DEV_TYP_NONE || (load_type & DEV_TYP_NET)) &&
|
||||
strcmp(devsw[i]->dv_name, "net") == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -27,18 +27,14 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
struct uboot_devdesc {
|
||||
struct devdesc dd; /* Must be first. */
|
||||
union {
|
||||
struct {
|
||||
int slice;
|
||||
int partition;
|
||||
off_t offset;
|
||||
} disk;
|
||||
} d_kind;
|
||||
};
|
||||
#include <disk.h>
|
||||
|
||||
#define d_disk d_kind.disk
|
||||
struct uboot_devdesc {
|
||||
union {
|
||||
struct devdesc dd;
|
||||
struct disk_devdesc d_disk;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* Default network packet alignment in memory. On arm arches packets must be
|
||||
|
@ -353,10 +353,6 @@ pt_entry_t pg_nx;
|
||||
|
||||
static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD, 0, "VM/pmap parameters");
|
||||
|
||||
static int pat_works = 1;
|
||||
SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RD, &pat_works, 1,
|
||||
"Is page attribute table fully functional?");
|
||||
|
||||
static int pg_ps_enabled = 1;
|
||||
SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
|
||||
&pg_ps_enabled, 0, "Are large page mappings enabled?");
|
||||
@ -1222,7 +1218,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
|
||||
void
|
||||
pmap_init_pat(void)
|
||||
{
|
||||
int pat_table[PAT_INDEX_SIZE];
|
||||
uint64_t pat_msr;
|
||||
u_long cr0, cr4;
|
||||
int i;
|
||||
@ -1233,45 +1228,32 @@ pmap_init_pat(void)
|
||||
|
||||
/* Set default PAT index table. */
|
||||
for (i = 0; i < PAT_INDEX_SIZE; i++)
|
||||
pat_table[i] = -1;
|
||||
pat_table[PAT_WRITE_BACK] = 0;
|
||||
pat_table[PAT_WRITE_THROUGH] = 1;
|
||||
pat_table[PAT_UNCACHEABLE] = 3;
|
||||
pat_table[PAT_WRITE_COMBINING] = 3;
|
||||
pat_table[PAT_WRITE_PROTECTED] = 3;
|
||||
pat_table[PAT_UNCACHED] = 3;
|
||||
pat_index[i] = -1;
|
||||
pat_index[PAT_WRITE_BACK] = 0;
|
||||
pat_index[PAT_WRITE_THROUGH] = 1;
|
||||
pat_index[PAT_UNCACHEABLE] = 3;
|
||||
pat_index[PAT_WRITE_COMBINING] = 6;
|
||||
pat_index[PAT_WRITE_PROTECTED] = 5;
|
||||
pat_index[PAT_UNCACHED] = 2;
|
||||
|
||||
/* Initialize default PAT entries. */
|
||||
/*
|
||||
* Initialize default PAT entries.
|
||||
* Leave the indices 0-3 at the default of WB, WT, UC-, and UC.
|
||||
* Program 5 and 6 as WP and WC.
|
||||
*
|
||||
* Leave 4 and 7 as WB and UC. Note that a recursive page table
|
||||
* mapping for a 2M page uses a PAT value with the bit 3 set due
|
||||
* to its overload with PG_PS.
|
||||
*/
|
||||
pat_msr = PAT_VALUE(0, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(1, PAT_WRITE_THROUGH) |
|
||||
PAT_VALUE(2, PAT_UNCACHED) |
|
||||
PAT_VALUE(3, PAT_UNCACHEABLE) |
|
||||
PAT_VALUE(4, PAT_WRITE_BACK) |
|
||||
PAT_VALUE(5, PAT_WRITE_THROUGH) |
|
||||
PAT_VALUE(6, PAT_UNCACHED) |
|
||||
PAT_VALUE(5, PAT_WRITE_PROTECTED) |
|
||||
PAT_VALUE(6, PAT_WRITE_COMBINING) |
|
||||
PAT_VALUE(7, PAT_UNCACHEABLE);
|
||||
|
||||
if (pat_works) {
|
||||
/*
|
||||
* Leave the indices 0-3 at the default of WB, WT, UC-, and UC.
|
||||
* Program 5 and 6 as WP and WC.
|
||||
* Leave 4 and 7 as WB and UC.
|
||||
*/
|
||||
pat_msr &= ~(PAT_MASK(5) | PAT_MASK(6));
|
||||
pat_msr |= PAT_VALUE(5, PAT_WRITE_PROTECTED) |
|
||||
PAT_VALUE(6, PAT_WRITE_COMBINING);
|
||||
pat_table[PAT_UNCACHED] = 2;
|
||||
pat_table[PAT_WRITE_PROTECTED] = 5;
|
||||
pat_table[PAT_WRITE_COMBINING] = 6;
|
||||
} else {
|
||||
/*
|
||||
* Just replace PAT Index 2 with WC instead of UC-.
|
||||
*/
|
||||
pat_msr &= ~PAT_MASK(2);
|
||||
pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
|
||||
pat_table[PAT_WRITE_COMBINING] = 2;
|
||||
}
|
||||
|
||||
/* Disable PGE. */
|
||||
cr4 = rcr4();
|
||||
load_cr4(cr4 & ~CR4_PGE);
|
||||
@ -1286,8 +1268,6 @@ pmap_init_pat(void)
|
||||
|
||||
/* Update PAT and index table. */
|
||||
wrmsr(MSR_PAT, pat_msr);
|
||||
for (i = 0; i < PAT_INDEX_SIZE; i++)
|
||||
pat_index[i] = pat_table[i];
|
||||
|
||||
/* Flush caches and TLBs again. */
|
||||
wbinvd();
|
||||
|
@ -70,30 +70,26 @@ sgx_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
|
||||
cmd = args->cmd;
|
||||
|
||||
args->cmd &= ~(LINUX_IOC_IN | LINUX_IOC_OUT);
|
||||
if (cmd & LINUX_IOC_IN)
|
||||
if ((cmd & LINUX_IOC_IN) != 0)
|
||||
args->cmd |= IOC_IN;
|
||||
if (cmd & LINUX_IOC_OUT)
|
||||
if ((cmd & LINUX_IOC_OUT) != 0)
|
||||
args->cmd |= IOC_OUT;
|
||||
|
||||
len = IOCPARM_LEN(cmd);
|
||||
if (len > SGX_IOCTL_MAX_DATA_LEN) {
|
||||
printf("%s: Can't copy data: cmd len is too big %d\n",
|
||||
__func__, len);
|
||||
return (EINVAL);
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd & LINUX_IOC_IN) {
|
||||
if ((cmd & LINUX_IOC_IN) != 0) {
|
||||
error = copyin((void *)args->arg, data, len);
|
||||
if (error) {
|
||||
printf("%s: Can't copy data, error %d\n",
|
||||
__func__, error);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (error != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = (fo_ioctl(fp, args->cmd, (caddr_t)data, td->td_ucred, td));
|
||||
error = fo_ioctl(fp, args->cmd, (caddr_t)data, td->td_ucred, td);
|
||||
out:
|
||||
fdrop(fp, td);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -120,6 +120,10 @@ MALLOC_DEFINE(M_AXP8XX_REG, "AXP8xx regulator", "AXP8xx power regulator");
|
||||
#define AXP_VOLTCTL_MASK 0x7f
|
||||
#define AXP_POWERBAT 0x32
|
||||
#define AXP_POWERBAT_SHUTDOWN (1 << 7)
|
||||
#define AXP_CHARGERCTL1 0x33
|
||||
#define AXP_CHARGERCTL1_MIN 0
|
||||
#define AXP_CHARGERCTL1_MAX 13
|
||||
#define AXP_CHARGERCTL1_CMASK 0xf
|
||||
#define AXP_IRQEN1 0x40
|
||||
#define AXP_IRQEN1_ACIN_HI (1 << 6)
|
||||
#define AXP_IRQEN1_ACIN_LO (1 << 5)
|
||||
@ -614,13 +618,13 @@ static const struct axp8xx_sensors axp8xx_common_sensors[] = {
|
||||
.id = AXP_SENSOR_BATT_CHARGE_CURRENT,
|
||||
.name = "batchargecurrent",
|
||||
.format = "I",
|
||||
.desc = "Battery Charging Current",
|
||||
.desc = "Average Battery Charging Current",
|
||||
},
|
||||
{
|
||||
.id = AXP_SENSOR_BATT_DISCHARGE_CURRENT,
|
||||
.name = "batdischargecurrent",
|
||||
.format = "I",
|
||||
.desc = "Battery Discharging Current",
|
||||
.desc = "Average Battery Discharging Current",
|
||||
},
|
||||
{
|
||||
.id = AXP_SENSOR_BATT_CAPACITY_PERCENT,
|
||||
@ -889,6 +893,33 @@ axp8xx_shutdown(void *devp, int howto)
|
||||
axp8xx_write(dev, AXP_POWERBAT, AXP_POWERBAT_SHUTDOWN);
|
||||
}
|
||||
|
||||
static int
|
||||
axp8xx_sysctl_chargecurrent(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
device_t dev = arg1;
|
||||
uint8_t data;
|
||||
int val, error;
|
||||
|
||||
error = axp8xx_read(dev, AXP_CHARGERCTL1, &data, 1);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
if (bootverbose)
|
||||
device_printf(dev, "Raw CHARGECTL1 val: 0x%0x\n", data);
|
||||
val = (data & AXP_CHARGERCTL1_CMASK);
|
||||
error = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (error || !req->newptr) /* error || read request */
|
||||
return (error);
|
||||
|
||||
if ((val < AXP_CHARGERCTL1_MIN) || (val > AXP_CHARGERCTL1_MAX))
|
||||
return (EINVAL);
|
||||
|
||||
val |= (data & (AXP_CHARGERCTL1_CMASK << 4));
|
||||
axp8xx_write(dev, AXP_CHARGERCTL1, val);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
axp8xx_sysctl(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
@ -1482,6 +1513,16 @@ axp8xx_attach(device_t dev)
|
||||
sc->sensors[i].format,
|
||||
sc->sensors[i].desc);
|
||||
}
|
||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "batchargecurrentstep",
|
||||
CTLTYPE_INT | CTLFLAG_RW,
|
||||
dev, 0, axp8xx_sysctl_chargecurrent,
|
||||
"I", "Battery Charging Current Step, "
|
||||
"0: 200mA, 1: 400mA, 2: 600mA, 3: 800mA, "
|
||||
"4: 1000mA, 5: 1200mA, 6: 1400mA, 7: 1600mA, "
|
||||
"8: 1800mA, 9: 2000mA, 10: 2200mA, 11: 2400mA, "
|
||||
"12: 2600mA, 13: 2800mA");
|
||||
|
||||
/* Get thresholds */
|
||||
if (axp8xx_read(dev, AXP_BAT_CAP_WARN, &val, 1) == 0) {
|
||||
|
@ -84,7 +84,7 @@ struct sysentvec elf32_freebsd_sysvec = {
|
||||
#if __ARM_ARCH >= 6
|
||||
SV_ASLR | SV_SHP | SV_TIMEKEEP |
|
||||
#endif
|
||||
SV_ABI_FREEBSD | SV_ILP32,
|
||||
SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_syscallnames = syscallnames,
|
||||
|
@ -73,6 +73,7 @@ struct snvs_softc {
|
||||
};
|
||||
|
||||
static struct ofw_compat_data compat_data[] = {
|
||||
{"fsl,sec-v4.0-mon-rtc-lp", true},
|
||||
{"fsl,sec-v4.0-mon", true},
|
||||
{NULL, false}
|
||||
};
|
||||
|
@ -79,7 +79,8 @@ static struct sysentvec elf64_freebsd_sysvec = {
|
||||
.sv_setregs = exec_setregs,
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_SHP | SV_TIMEKEEP | SV_ABI_FREEBSD | SV_LP64,
|
||||
.sv_flags = SV_SHP | SV_TIMEKEEP | SV_ABI_FREEBSD | SV_LP64 |
|
||||
SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_syscallnames = syscallnames,
|
||||
|
@ -1759,14 +1759,6 @@ hint.ata.1.at="isa"
|
||||
hint.ata.1.port="0x170"
|
||||
hint.ata.1.irq="15"
|
||||
|
||||
#
|
||||
# The following options are valid on the ATA driver:
|
||||
#
|
||||
# ATA_REQUEST_TIMEOUT: the number of seconds to wait for an ATA request
|
||||
# before timing out.
|
||||
|
||||
#options ATA_REQUEST_TIMEOUT=10
|
||||
|
||||
#
|
||||
# Standard floppy disk controllers and floppy tapes, supports
|
||||
# the Y-E DATA External FDD (PC Card)
|
||||
|
@ -4847,6 +4847,8 @@ crypto/libsodium/randombytes.c optional crypto \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium"
|
||||
crypto/libsodium/utils.c optional crypto \
|
||||
compile-with "${NORMAL_C} -I$S/contrib/libsodium/src/libsodium/include -I$S/crypto/libsodium"
|
||||
opencrypto/cbc_mac.c optional crypto
|
||||
opencrypto/xform_cbc_mac.c optional crypto
|
||||
rpc/auth_none.c optional krpc | nfslockd | nfscl | nfsd
|
||||
rpc/auth_unix.c optional krpc | nfslockd | nfscl | nfsd
|
||||
rpc/authunix_prot.c optional krpc | nfslockd | nfscl | nfsd
|
||||
|
@ -87,6 +87,10 @@ SECTIONS
|
||||
.sdata : { *(.sdata) }
|
||||
_edata = .;
|
||||
PROVIDE (edata = .);
|
||||
/* Ensure __bss_start is associated with the next section in case orphan
|
||||
sections are placed directly after .sdata, as has been seen to happen with
|
||||
LLD. */
|
||||
. = .;
|
||||
__bss_start = .;
|
||||
.sbss : { *(.sbss) *(.scommon) }
|
||||
.bss :
|
||||
|
@ -229,16 +229,8 @@ nvpair_remove_nvlist_array(nvpair_t *nvp)
|
||||
nvlarray = __DECONST(nvlist_t **,
|
||||
nvpair_get_nvlist_array(nvp, &count));
|
||||
for (i = 0; i < count; i++) {
|
||||
nvlist_t *nvl;
|
||||
nvpair_t *nnvp;
|
||||
|
||||
nvl = nvlarray[i];
|
||||
nnvp = nvlist_get_array_next_nvpair(nvl);
|
||||
if (nnvp != NULL) {
|
||||
nvpair_free_structure(nnvp);
|
||||
}
|
||||
nvlist_set_array_next(nvl, NULL);
|
||||
nvlist_set_parent(nvl, NULL);
|
||||
nvlist_set_array_next(nvlarray[i], NULL);
|
||||
nvlist_set_parent(nvlarray[i], NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,10 +203,6 @@
|
||||
#define ATA_OP_FINISHED 1
|
||||
#define ATA_MAX_28BIT_LBA 268435455UL
|
||||
|
||||
#ifndef ATA_REQUEST_TIMEOUT
|
||||
#define ATA_REQUEST_TIMEOUT 10
|
||||
#endif
|
||||
|
||||
/* structure used for composite atomic operations */
|
||||
#define MAX_COMPOSITES 32 /* u_int32_t bits */
|
||||
struct ata_composite {
|
||||
|
@ -1046,10 +1046,6 @@ ena_refill_rx_bufs(struct ena_ring *rx_ring, uint32_t num)
|
||||
"RX buffer - next to use: %d", next_to_use);
|
||||
|
||||
req_id = rx_ring->free_rx_ids[next_to_use];
|
||||
rc = validate_rx_req_id(rx_ring, req_id);
|
||||
if (unlikely(rc != 0))
|
||||
break;
|
||||
|
||||
rx_info = &rx_ring->rx_buffer_info[req_id];
|
||||
|
||||
rc = ena_alloc_rx_mbuf(adapter, rx_ring, rx_info);
|
||||
@ -1472,21 +1468,24 @@ ena_rx_mbuf(struct ena_ring *rx_ring, struct ena_com_rx_buf_info *ena_bufs,
|
||||
struct ena_rx_buffer *rx_info;
|
||||
struct ena_adapter *adapter;
|
||||
unsigned int descs = ena_rx_ctx->descs;
|
||||
int rc;
|
||||
uint16_t ntc, len, req_id, buf = 0;
|
||||
|
||||
ntc = *next_to_clean;
|
||||
adapter = rx_ring->adapter;
|
||||
rx_info = &rx_ring->rx_buffer_info[ntc];
|
||||
|
||||
len = ena_bufs[buf].len;
|
||||
req_id = ena_bufs[buf].req_id;
|
||||
rc = validate_rx_req_id(rx_ring, req_id);
|
||||
if (unlikely(rc != 0))
|
||||
return (NULL);
|
||||
|
||||
rx_info = &rx_ring->rx_buffer_info[req_id];
|
||||
if (unlikely(rx_info->mbuf == NULL)) {
|
||||
device_printf(adapter->pdev, "NULL mbuf in rx_info");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
len = ena_bufs[buf].len;
|
||||
req_id = ena_bufs[buf].req_id;
|
||||
rx_info = &rx_ring->rx_buffer_info[req_id];
|
||||
|
||||
ena_trace(ENA_DBG | ENA_RXPTH, "rx_info %p, mbuf %p, paddr %jx",
|
||||
rx_info, rx_info->mbuf, (uintmax_t)rx_info->ena_buf.paddr);
|
||||
|
||||
@ -1517,6 +1516,16 @@ ena_rx_mbuf(struct ena_ring *rx_ring, struct ena_com_rx_buf_info *ena_bufs,
|
||||
++buf;
|
||||
len = ena_bufs[buf].len;
|
||||
req_id = ena_bufs[buf].req_id;
|
||||
rc = validate_rx_req_id(rx_ring, req_id);
|
||||
if (unlikely(rc != 0)) {
|
||||
/*
|
||||
* If the req_id is invalid, then the device will be
|
||||
* reset. In that case we must free all mbufs that
|
||||
* were already gathered.
|
||||
*/
|
||||
m_freem(mbuf);
|
||||
return (NULL);
|
||||
}
|
||||
rx_info = &rx_ring->rx_buffer_info[req_id];
|
||||
|
||||
if (unlikely(rx_info->mbuf == NULL)) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
#define DRV_MODULE_VER_MAJOR 0
|
||||
#define DRV_MODULE_VER_MINOR 8
|
||||
#define DRV_MODULE_VER_SUBMINOR 2
|
||||
#define DRV_MODULE_VER_SUBMINOR 3
|
||||
|
||||
#define DRV_MODULE_NAME "ena"
|
||||
|
||||
|
@ -932,7 +932,7 @@ ixl_if_msix_intr_assign(if_ctx_t ctx, int msix)
|
||||
return (err);
|
||||
}
|
||||
/* Create soft IRQ for handling VFLRs */
|
||||
iflib_softirq_alloc_generic(ctx, &pf->iov_irq, IFLIB_INTR_IOV, pf, 0, "iov");
|
||||
iflib_softirq_alloc_generic(ctx, NULL, IFLIB_INTR_IOV, pf, 0, "iov");
|
||||
|
||||
/* Now set up the stations */
|
||||
for (i = 0, vector = 1; i < vsi->shared->isc_nrxqsets; i++, vector++, rx_que++) {
|
||||
|
@ -138,7 +138,6 @@ struct ixl_pf {
|
||||
struct ixl_vf *vfs;
|
||||
int num_vfs;
|
||||
uint16_t veb_seid;
|
||||
struct if_irq iov_irq;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -105,6 +105,7 @@ int nm_os_selinfo_init(NM_SELINFO_T *si, const char *name) {
|
||||
snprintf(si->mtxname, sizeof(si->mtxname), "nmkl%s", name);
|
||||
mtx_init(&si->m, si->mtxname, NULL, MTX_DEF);
|
||||
knlist_init_mtx(&si->si.si_note, &si->m);
|
||||
si->kqueue_users = 0;
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -1351,7 +1352,9 @@ void
|
||||
nm_os_selwakeup(struct nm_selinfo *si)
|
||||
{
|
||||
selwakeuppri(&si->si, PI_NET);
|
||||
taskqueue_enqueue(si->ntfytq, &si->ntfytask);
|
||||
if (si->kqueue_users > 0) {
|
||||
taskqueue_enqueue(si->ntfytq, &si->ntfytask);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -1364,20 +1367,28 @@ static void
|
||||
netmap_knrdetach(struct knote *kn)
|
||||
{
|
||||
struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook;
|
||||
struct selinfo *si = &priv->np_si[NR_RX]->si;
|
||||
struct nm_selinfo *si = priv->np_si[NR_RX];
|
||||
|
||||
nm_prinf("remove selinfo %p", si);
|
||||
knlist_remove(&si->si_note, kn, /*islocked=*/0);
|
||||
knlist_remove(&si->si.si_note, kn, /*islocked=*/0);
|
||||
NMG_LOCK();
|
||||
KASSERT(si->kqueue_users > 0, ("kqueue_user underflow on %s",
|
||||
si->mtxname));
|
||||
si->kqueue_users--;
|
||||
nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users);
|
||||
NMG_UNLOCK();
|
||||
}
|
||||
|
||||
static void
|
||||
netmap_knwdetach(struct knote *kn)
|
||||
{
|
||||
struct netmap_priv_d *priv = (struct netmap_priv_d *)kn->kn_hook;
|
||||
struct selinfo *si = &priv->np_si[NR_TX]->si;
|
||||
struct nm_selinfo *si = priv->np_si[NR_TX];
|
||||
|
||||
nm_prinf("remove selinfo %p", si);
|
||||
knlist_remove(&si->si_note, kn, /*islocked=*/0);
|
||||
knlist_remove(&si->si.si_note, kn, /*islocked=*/0);
|
||||
NMG_LOCK();
|
||||
si->kqueue_users--;
|
||||
nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users);
|
||||
NMG_UNLOCK();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1465,6 +1476,10 @@ netmap_kqfilter(struct cdev *dev, struct knote *kn)
|
||||
kn->kn_fop = (ev == EVFILT_WRITE) ?
|
||||
&netmap_wfiltops : &netmap_rfiltops;
|
||||
kn->kn_hook = priv;
|
||||
NMG_LOCK();
|
||||
si->kqueue_users++;
|
||||
nm_prinf("kqueue users for %s: %d", si->mtxname, si->kqueue_users);
|
||||
NMG_UNLOCK();
|
||||
knlist_add(&si->si.si_note, kn, /*islocked=*/0);
|
||||
|
||||
return 0;
|
||||
|
@ -132,11 +132,14 @@ struct netmap_adapter *netmap_getna(if_t ifp);
|
||||
#define MBUF_QUEUED(m) 1
|
||||
|
||||
struct nm_selinfo {
|
||||
/* Support for select(2) and poll(2). */
|
||||
struct selinfo si;
|
||||
/* Support for kqueue(9). See comments in netmap_freebsd.c */
|
||||
struct taskqueue *ntfytq;
|
||||
struct task ntfytask;
|
||||
struct mtx m;
|
||||
char mtxname[32];
|
||||
int kqueue_users;
|
||||
};
|
||||
|
||||
|
||||
|
@ -373,7 +373,6 @@ fuse_internal_readdir_processdata(struct uio *uio,
|
||||
|
||||
/* remove */
|
||||
|
||||
#define INVALIDATE_CACHED_VATTRS_UPON_UNLINK 1
|
||||
int
|
||||
fuse_internal_remove(struct vnode *dvp,
|
||||
struct vnode *vp,
|
||||
@ -381,15 +380,11 @@ fuse_internal_remove(struct vnode *dvp,
|
||||
enum fuse_opcode op)
|
||||
{
|
||||
struct fuse_dispatcher fdi;
|
||||
struct fuse_vnode_data *fvdat;
|
||||
int err;
|
||||
|
||||
struct vattr *vap = VTOVA(vp);
|
||||
|
||||
#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
|
||||
int need_invalidate = 0;
|
||||
uint64_t target_nlink = 0;
|
||||
|
||||
#endif
|
||||
int err = 0;
|
||||
err = 0;
|
||||
fvdat = VTOFUD(vp);
|
||||
|
||||
debug_printf("dvp=%p, cnp=%p, op=%d\n", vp, cnp, op);
|
||||
|
||||
@ -399,13 +394,6 @@ fuse_internal_remove(struct vnode *dvp,
|
||||
memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen);
|
||||
((char *)fdi.indata)[cnp->cn_namelen] = '\0';
|
||||
|
||||
#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
|
||||
if (vap->va_nlink > 1) {
|
||||
need_invalidate = 1;
|
||||
target_nlink = vap->va_nlink;
|
||||
}
|
||||
#endif
|
||||
|
||||
err = fdisp_wait_answ(&fdi);
|
||||
fdisp_destroy(&fdi);
|
||||
return err;
|
||||
@ -483,13 +471,13 @@ fuse_internal_newentry_core(struct vnode *dvp,
|
||||
if ((err = fuse_internal_checkentry(feo, vtyp))) {
|
||||
return err;
|
||||
}
|
||||
err = fuse_vnode_get(mp, feo->nodeid, dvp, vpp, cnp, vtyp);
|
||||
err = fuse_vnode_get(mp, feo, feo->nodeid, dvp, vpp, cnp, vtyp);
|
||||
if (err) {
|
||||
fuse_internal_forget_send(mp, cnp->cn_thread, cnp->cn_cred,
|
||||
feo->nodeid, 1);
|
||||
return err;
|
||||
}
|
||||
cache_attrs(*vpp, feo);
|
||||
cache_attrs(*vpp, feo, NULL);
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -563,6 +551,7 @@ fuse_internal_vnode_disappear(struct vnode *vp)
|
||||
|
||||
ASSERT_VOP_ELOCKED(vp, "fuse_internal_vnode_disappear");
|
||||
fvdat->flag |= FN_REVOKED;
|
||||
fvdat->valid_attr_cache = false;
|
||||
cache_purge(vp);
|
||||
}
|
||||
|
||||
|
@ -200,15 +200,47 @@ fuse_internal_access(struct vnode *vp,
|
||||
|
||||
/* attributes */
|
||||
|
||||
/*
|
||||
* Cache FUSE attributes 'fat', with nominal expiration
|
||||
* 'attr_valid'.'attr_valid_nsec', in attr cache associated with vnode 'vp'.
|
||||
* Optionally, if argument 'vap' is not NULL, store a copy of the converted
|
||||
* attributes there as well.
|
||||
*
|
||||
* If the nominal attribute cache TTL is zero, do not cache on the 'vp' (but do
|
||||
* return the result to the caller).
|
||||
*/
|
||||
static __inline
|
||||
void
|
||||
fuse_internal_attr_fat2vat(struct mount *mp,
|
||||
fuse_internal_attr_fat2vat(struct vnode *vp,
|
||||
struct fuse_attr *fat,
|
||||
uint64_t attr_valid,
|
||||
uint32_t attr_valid_nsec,
|
||||
struct vattr *vap)
|
||||
{
|
||||
struct mount *mp;
|
||||
struct fuse_vnode_data *fvdat;
|
||||
struct vattr *vp_cache_at;
|
||||
|
||||
mp = vnode_mount(vp);
|
||||
fvdat = VTOFUD(vp);
|
||||
|
||||
DEBUGX(FUSE_DEBUG_INTERNAL,
|
||||
"node #%ju, mode 0%o\n", (uintmax_t)fat->ino, fat->mode);
|
||||
|
||||
/* Honor explicit do-not-cache requests from user filesystems. */
|
||||
if (attr_valid == 0 && attr_valid_nsec == 0)
|
||||
fvdat->valid_attr_cache = false;
|
||||
else
|
||||
fvdat->valid_attr_cache = true;
|
||||
|
||||
vp_cache_at = VTOVA(vp);
|
||||
|
||||
if (vap == NULL && vp_cache_at == NULL)
|
||||
return;
|
||||
|
||||
if (vap == NULL)
|
||||
vap = vp_cache_at;
|
||||
|
||||
vattr_null(vap);
|
||||
|
||||
vap->va_fsid = mp->mnt_stat.f_fsid.val[0];
|
||||
@ -227,21 +259,17 @@ fuse_internal_attr_fat2vat(struct mount *mp,
|
||||
vap->va_ctime.tv_nsec = fat->ctimensec;
|
||||
vap->va_blocksize = PAGE_SIZE;
|
||||
vap->va_type = IFTOVT(fat->mode);
|
||||
|
||||
#if (S_BLKSIZE == 512)
|
||||
/* Optimize this case */
|
||||
vap->va_bytes = fat->blocks << 9;
|
||||
#else
|
||||
vap->va_bytes = fat->blocks * S_BLKSIZE;
|
||||
#endif
|
||||
|
||||
vap->va_flags = 0;
|
||||
|
||||
if (vap != vp_cache_at && vp_cache_at != NULL)
|
||||
memcpy(vp_cache_at, vap, sizeof(*vap));
|
||||
}
|
||||
|
||||
|
||||
#define cache_attrs(vp, fuse_out) \
|
||||
fuse_internal_attr_fat2vat(vnode_mount(vp), &(fuse_out)->attr, \
|
||||
VTOVA(vp));
|
||||
#define cache_attrs(vp, fuse_out, vap_out) \
|
||||
fuse_internal_attr_fat2vat((vp), &(fuse_out)->attr, \
|
||||
(fuse_out)->attr_valid, (fuse_out)->attr_valid_nsec, (vap_out))
|
||||
|
||||
/* fsync */
|
||||
|
||||
|
@ -155,7 +155,13 @@ fuse_io_dispatch(struct vnode *vp, struct uio *uio, int ioflag,
|
||||
}
|
||||
break;
|
||||
case UIO_WRITE:
|
||||
if (directio) {
|
||||
/*
|
||||
* Kludge: simulate write-through caching via write-around
|
||||
* caching. Same effect, as far as never caching dirty data,
|
||||
* but slightly pessimal in that newly written data is not
|
||||
* cached.
|
||||
*/
|
||||
if (directio || fuse_data_cache_mode == FUSE_CACHE_WT) {
|
||||
FS_DEBUG("direct write of vnode %ju via file handle %ju\n",
|
||||
(uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);
|
||||
err = fuse_write_directbackend(vp, uio, cred, fufh, ioflag);
|
||||
@ -362,8 +368,11 @@ fuse_write_directbackend(struct vnode *vp, struct uio *uio,
|
||||
}
|
||||
uio->uio_resid += diff;
|
||||
uio->uio_offset -= diff;
|
||||
if (uio->uio_offset > fvdat->filesize)
|
||||
if (uio->uio_offset > fvdat->filesize &&
|
||||
fuse_data_cache_mode != FUSE_CACHE_UC) {
|
||||
fuse_vnode_setsize(vp, cred, uio->uio_offset);
|
||||
fvdat->flag &= ~FN_SIZECHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
fdisp_destroy(&fdi);
|
||||
@ -655,6 +664,7 @@ fuse_io_strategy(struct vnode *vp, struct buf *bp)
|
||||
uiop->uio_offset = ((off_t)bp->b_blkno) * biosize;
|
||||
error = fuse_read_directbackend(vp, uiop, cred, fufh);
|
||||
|
||||
/* XXXCEM: Potentially invalid access to cached_attrs here */
|
||||
if ((!error && uiop->uio_resid) ||
|
||||
(fsess_opt_brokenio(vnode_mount(vp)) && error == EIO &&
|
||||
uiop->uio_offset < fvdat->filesize && fvdat->filesize > 0 &&
|
||||
|
@ -214,7 +214,13 @@ struct fuse_data {
|
||||
#define FSESS_NO_MMAP 0x0800 /* disable mmap */
|
||||
#define FSESS_BROKENIO 0x1000 /* fix broken io */
|
||||
|
||||
extern int fuse_data_cache_enable;
|
||||
enum fuse_data_cache_mode {
|
||||
FUSE_CACHE_UC,
|
||||
FUSE_CACHE_WT,
|
||||
FUSE_CACHE_WB,
|
||||
};
|
||||
|
||||
extern int fuse_data_cache_mode;
|
||||
extern int fuse_data_cache_invalidate;
|
||||
extern int fuse_mmap_enable;
|
||||
extern int fuse_sync_resize;
|
||||
@ -248,7 +254,7 @@ fsess_opt_datacache(struct mount *mp)
|
||||
{
|
||||
struct fuse_data *data = fuse_get_mpdata(mp);
|
||||
|
||||
return (fuse_data_cache_enable ||
|
||||
return (fuse_data_cache_mode != FUSE_CACHE_UC &&
|
||||
(data->dataflags & FSESS_NO_DATACACHE) == 0);
|
||||
}
|
||||
|
||||
@ -257,7 +263,7 @@ fsess_opt_mmap(struct mount *mp)
|
||||
{
|
||||
struct fuse_data *data = fuse_get_mpdata(mp);
|
||||
|
||||
if (!(fuse_mmap_enable && fuse_data_cache_enable))
|
||||
if (!fuse_mmap_enable || fuse_data_cache_mode == FUSE_CACHE_UC)
|
||||
return 0;
|
||||
return ((data->dataflags & (FSESS_NO_DATACACHE | FSESS_NO_MMAP)) == 0);
|
||||
}
|
||||
|
@ -94,16 +94,19 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
MALLOC_DEFINE(M_FUSEVN, "fuse_vnode", "fuse vnode private data");
|
||||
|
||||
static int sysctl_fuse_cache_mode(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
static int fuse_node_count = 0;
|
||||
|
||||
SYSCTL_INT(_vfs_fuse, OID_AUTO, node_count, CTLFLAG_RD,
|
||||
&fuse_node_count, 0, "Count of FUSE vnodes");
|
||||
|
||||
int fuse_data_cache_enable = 1;
|
||||
int fuse_data_cache_mode = FUSE_CACHE_WT;
|
||||
|
||||
SYSCTL_INT(_vfs_fuse, OID_AUTO, data_cache_enable, CTLFLAG_RW,
|
||||
&fuse_data_cache_enable, 0,
|
||||
"enable caching of FUSE file data (including dirty data)");
|
||||
SYSCTL_PROC(_vfs_fuse, OID_AUTO, data_cache_mode, CTLTYPE_INT|CTLFLAG_RW,
|
||||
&fuse_data_cache_mode, 0, sysctl_fuse_cache_mode, "I",
|
||||
"Zero: disable caching of FUSE file data; One: write-through caching "
|
||||
"(default); Two: write-back caching (generally unsafe)");
|
||||
|
||||
int fuse_data_cache_invalidate = 0;
|
||||
|
||||
@ -116,7 +119,7 @@ int fuse_mmap_enable = 1;
|
||||
|
||||
SYSCTL_INT(_vfs_fuse, OID_AUTO, mmap_enable, CTLFLAG_RW,
|
||||
&fuse_mmap_enable, 0,
|
||||
"If non-zero, and data_cache_enable is also non-zero, enable mmap(2) of "
|
||||
"If non-zero, and data_cache_mode is also non-zero, enable mmap(2) of "
|
||||
"FUSE files");
|
||||
|
||||
int fuse_refresh_size = 0;
|
||||
@ -140,6 +143,28 @@ SYSCTL_INT(_vfs_fuse, OID_AUTO, fix_broken_io, CTLFLAG_RW,
|
||||
"If non-zero, print a diagnostic warning if a userspace filesystem returns"
|
||||
" EIO on reads of recently extended portions of files");
|
||||
|
||||
static int
|
||||
sysctl_fuse_cache_mode(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int val, error;
|
||||
|
||||
val = *(int *)arg1;
|
||||
error = sysctl_handle_int(oidp, &val, 0, req);
|
||||
if (error || !req->newptr)
|
||||
return (error);
|
||||
|
||||
switch (val) {
|
||||
case FUSE_CACHE_UC:
|
||||
case FUSE_CACHE_WT:
|
||||
case FUSE_CACHE_WB:
|
||||
*(int *)arg1 = val;
|
||||
break;
|
||||
default:
|
||||
return (EDOM);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat,
|
||||
uint64_t nodeid, enum vtype vtyp)
|
||||
@ -147,6 +172,7 @@ fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat,
|
||||
int i;
|
||||
|
||||
fvdat->nid = nodeid;
|
||||
vattr_null(&fvdat->cached_attrs);
|
||||
if (nodeid == FUSE_ROOT_ID) {
|
||||
vp->v_vflag |= VV_ROOT;
|
||||
}
|
||||
@ -240,6 +266,7 @@ fuse_vnode_alloc(struct mount *mp,
|
||||
|
||||
int
|
||||
fuse_vnode_get(struct mount *mp,
|
||||
struct fuse_entry_out *feo,
|
||||
uint64_t nodeid,
|
||||
struct vnode *dvp,
|
||||
struct vnode **vpp,
|
||||
@ -260,7 +287,9 @@ fuse_vnode_get(struct mount *mp,
|
||||
MPASS(!(cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.'));
|
||||
fuse_vnode_setparent(*vpp, dvp);
|
||||
}
|
||||
if (dvp != NULL && cnp != NULL && (cnp->cn_flags & MAKEENTRY) != 0) {
|
||||
if (dvp != NULL && cnp != NULL && (cnp->cn_flags & MAKEENTRY) != 0 &&
|
||||
feo != NULL &&
|
||||
(feo->entry_valid != 0 || feo->entry_valid_nsec != 0)) {
|
||||
ASSERT_VOP_LOCKED(*vpp, "fuse_vnode_get");
|
||||
ASSERT_VOP_LOCKED(dvp, "fuse_vnode_get");
|
||||
cache_enter(dvp, *vpp, cnp);
|
||||
@ -371,6 +400,7 @@ fuse_vnode_refreshsize(struct vnode *vp, struct ucred *cred)
|
||||
struct vattr va;
|
||||
|
||||
if ((fvdat->flag & FN_SIZECHANGE) != 0 ||
|
||||
fuse_data_cache_mode == FUSE_CACHE_UC ||
|
||||
(fuse_refresh_size == 0 && fvdat->filesize != 0))
|
||||
return;
|
||||
|
||||
|
@ -86,6 +86,7 @@ struct fuse_vnode_data {
|
||||
uint32_t flag;
|
||||
|
||||
/** meta **/
|
||||
bool valid_attr_cache;
|
||||
struct vattr cached_attrs;
|
||||
off_t filesize;
|
||||
uint64_t nlookup;
|
||||
@ -95,7 +96,9 @@ struct fuse_vnode_data {
|
||||
#define VTOFUD(vp) \
|
||||
((struct fuse_vnode_data *)((vp)->v_data))
|
||||
#define VTOI(vp) (VTOFUD(vp)->nid)
|
||||
#define VTOVA(vp) (&(VTOFUD(vp)->cached_attrs))
|
||||
#define VTOVA(vp) \
|
||||
(VTOFUD(vp)->valid_attr_cache ? \
|
||||
&(VTOFUD(vp)->cached_attrs) : NULL)
|
||||
#define VTOILLU(vp) ((uint64_t)(VTOFUD(vp) ? VTOI(vp) : 0))
|
||||
|
||||
#define FUSE_NULL_ID 0
|
||||
@ -114,6 +117,7 @@ fuse_vnode_setparent(struct vnode *vp, struct vnode *dvp)
|
||||
void fuse_vnode_destroy(struct vnode *vp);
|
||||
|
||||
int fuse_vnode_get(struct mount *mp,
|
||||
struct fuse_entry_out *feo,
|
||||
uint64_t nodeid,
|
||||
struct vnode *dvp,
|
||||
struct vnode **vpp,
|
||||
|
@ -444,7 +444,8 @@ fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp)
|
||||
if (err == 0)
|
||||
*vpp = data->vroot;
|
||||
} else {
|
||||
err = fuse_vnode_get(mp, FUSE_ROOT_ID, NULL, vpp, NULL, VDIR);
|
||||
err = fuse_vnode_get(mp, NULL, FUSE_ROOT_ID, NULL, vpp, NULL,
|
||||
VDIR);
|
||||
if (err == 0) {
|
||||
FUSE_LOCK();
|
||||
MPASS(data->vroot == NULL || data->vroot == *vpp);
|
||||
|
@ -384,7 +384,7 @@ fuse_vnop_create(struct vop_create_args *ap)
|
||||
if ((err = fuse_internal_checkentry(feo, VREG))) {
|
||||
goto out;
|
||||
}
|
||||
err = fuse_vnode_get(mp, feo->nodeid, dvp, vpp, cnp, VREG);
|
||||
err = fuse_vnode_get(mp, feo, feo->nodeid, dvp, vpp, cnp, VREG);
|
||||
if (err) {
|
||||
struct fuse_release_in *fri;
|
||||
uint64_t nodeid = feo->nodeid;
|
||||
@ -518,10 +518,8 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
cache_attrs(vp, (struct fuse_attr_out *)fdi.answ);
|
||||
if (vap != VTOVA(vp)) {
|
||||
memcpy(vap, VTOVA(vp), sizeof(*vap));
|
||||
}
|
||||
|
||||
cache_attrs(vp, (struct fuse_attr_out *)fdi.answ, vap);
|
||||
if (vap->va_type != vnode_vtype(vp)) {
|
||||
fuse_internal_vnode_disappear(vp);
|
||||
err = ENOENT;
|
||||
@ -540,6 +538,7 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
|
||||
|
||||
if (fvdat->filesize != new_filesize) {
|
||||
fuse_vnode_setsize(vp, cred, new_filesize);
|
||||
fvdat->flag &= ~FN_SIZECHANGE;
|
||||
}
|
||||
}
|
||||
debug_printf("fuse_getattr e: returning 0\n");
|
||||
@ -628,9 +627,15 @@ fuse_vnop_link(struct vop_link_args *ap)
|
||||
if (vnode_mount(tdvp) != vnode_mount(vp)) {
|
||||
return EXDEV;
|
||||
}
|
||||
if (vap->va_nlink >= FUSE_LINK_MAX) {
|
||||
|
||||
/*
|
||||
* This is a seatbelt check to protect naive userspace filesystems from
|
||||
* themselves and the limitations of the FUSE IPC protocol. If a
|
||||
* filesystem does not allow attribute caching, assume it is capable of
|
||||
* validating that nlink does not overflow.
|
||||
*/
|
||||
if (vap != NULL && vap->va_nlink >= FUSE_LINK_MAX)
|
||||
return EMLINK;
|
||||
}
|
||||
fli.oldnodeid = VTOI(vp);
|
||||
|
||||
fdisp_init(&fdi, 0);
|
||||
@ -853,8 +858,8 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
|
||||
vref(dvp);
|
||||
*vpp = dvp;
|
||||
} else {
|
||||
err = fuse_vnode_get(dvp->v_mount, nid, dvp,
|
||||
&vp, cnp, IFTOVT(fattr->mode));
|
||||
err = fuse_vnode_get(dvp->v_mount, feo, nid,
|
||||
dvp, &vp, cnp, IFTOVT(fattr->mode));
|
||||
if (err)
|
||||
goto out;
|
||||
*vpp = vp;
|
||||
@ -889,12 +894,8 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
|
||||
err = EISDIR;
|
||||
goto out;
|
||||
}
|
||||
err = fuse_vnode_get(vnode_mount(dvp),
|
||||
nid,
|
||||
dvp,
|
||||
&vp,
|
||||
cnp,
|
||||
IFTOVT(fattr->mode));
|
||||
err = fuse_vnode_get(vnode_mount(dvp), feo, nid, dvp,
|
||||
&vp, cnp, IFTOVT(fattr->mode));
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
@ -932,12 +933,8 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
|
||||
}
|
||||
}
|
||||
VOP_UNLOCK(dvp, 0);
|
||||
err = fuse_vnode_get(vnode_mount(dvp),
|
||||
nid,
|
||||
NULL,
|
||||
&vp,
|
||||
cnp,
|
||||
IFTOVT(fattr->mode));
|
||||
err = fuse_vnode_get(vnode_mount(dvp), feo, nid, NULL,
|
||||
&vp, cnp, IFTOVT(fattr->mode));
|
||||
vfs_unbusy(mp);
|
||||
vn_lock(dvp, ltype | LK_RETRY);
|
||||
if ((dvp->v_iflag & VI_DOOMED) != 0) {
|
||||
@ -952,23 +949,54 @@ fuse_vnop_lookup(struct vop_lookup_args *ap)
|
||||
vref(dvp);
|
||||
*vpp = dvp;
|
||||
} else {
|
||||
err = fuse_vnode_get(vnode_mount(dvp),
|
||||
nid,
|
||||
dvp,
|
||||
&vp,
|
||||
cnp,
|
||||
IFTOVT(fattr->mode));
|
||||
struct fuse_vnode_data *fvdat;
|
||||
|
||||
err = fuse_vnode_get(vnode_mount(dvp), feo, nid, dvp,
|
||||
&vp, cnp, IFTOVT(fattr->mode));
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
fuse_vnode_setparent(vp, dvp);
|
||||
|
||||
/*
|
||||
* In the case where we are looking up a FUSE node
|
||||
* represented by an existing cached vnode, and the
|
||||
* true size reported by FUSE_LOOKUP doesn't match
|
||||
* the vnode's cached size, fix the vnode cache to
|
||||
* match the real object size.
|
||||
*
|
||||
* This can occur via FUSE distributed filesystems,
|
||||
* irregular files, etc.
|
||||
*/
|
||||
fvdat = VTOFUD(vp);
|
||||
if (vnode_isreg(vp) &&
|
||||
fattr->size != fvdat->filesize) {
|
||||
/*
|
||||
* The FN_SIZECHANGE flag reflects a dirty
|
||||
* append. If userspace lets us know our cache
|
||||
* is invalid, that write was lost. (Dirty
|
||||
* writes that do not cause append are also
|
||||
* lost, but we don't detect them here.)
|
||||
*
|
||||
* XXX: Maybe disable WB caching on this mount.
|
||||
*/
|
||||
if (fvdat->flag & FN_SIZECHANGE)
|
||||
printf("%s: WB cache incoherent on "
|
||||
"%s!\n", __func__,
|
||||
vnode_mount(vp)->mnt_stat.f_mntonname);
|
||||
|
||||
(void)fuse_vnode_setsize(vp, cred, fattr->size);
|
||||
fvdat->flag &= ~FN_SIZECHANGE;
|
||||
}
|
||||
*vpp = vp;
|
||||
}
|
||||
|
||||
if (op == FUSE_GETATTR) {
|
||||
cache_attrs(*vpp, (struct fuse_attr_out *)fdi.answ);
|
||||
cache_attrs(*vpp, (struct fuse_attr_out *)fdi.answ,
|
||||
NULL);
|
||||
} else {
|
||||
cache_attrs(*vpp, (struct fuse_entry_out *)fdi.answ);
|
||||
cache_attrs(*vpp, (struct fuse_entry_out *)fdi.answ,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Insert name into cache if appropriate. */
|
||||
@ -1643,9 +1671,9 @@ fuse_vnop_setattr(struct vop_setattr_args *ap)
|
||||
err = EAGAIN;
|
||||
}
|
||||
}
|
||||
if (!err && !sizechanged) {
|
||||
cache_attrs(vp, (struct fuse_attr_out *)fdi.answ);
|
||||
}
|
||||
if (err == 0)
|
||||
cache_attrs(vp, (struct fuse_attr_out *)fdi.answ, NULL);
|
||||
|
||||
out:
|
||||
fdisp_destroy(&fdi);
|
||||
if (!err && sizechanged) {
|
||||
|
@ -108,21 +108,47 @@ disable_intr(void)
|
||||
__asm __volatile("cli" : : : "memory");
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
static __inline void
|
||||
do_cpuid(u_int ax, u_int *p)
|
||||
{
|
||||
__asm __volatile("cpuid"
|
||||
: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax));
|
||||
: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cpuid_count(u_int ax, u_int cx, u_int *p)
|
||||
{
|
||||
__asm __volatile("cpuid"
|
||||
: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax), "c" (cx));
|
||||
: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax), "c" (cx));
|
||||
}
|
||||
#else
|
||||
static __inline void
|
||||
do_cpuid(u_int ax, u_int *p)
|
||||
{
|
||||
__asm __volatile(
|
||||
"pushl\t%%ebx\n\t"
|
||||
"cpuid\n\t"
|
||||
"movl\t%%ebx,%1\n\t"
|
||||
"popl\t%%ebx"
|
||||
: "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax));
|
||||
}
|
||||
|
||||
static __inline void
|
||||
cpuid_count(u_int ax, u_int cx, u_int *p)
|
||||
{
|
||||
__asm __volatile(
|
||||
"pushl\t%%ebx\n\t"
|
||||
"cpuid\n\t"
|
||||
"movl\t%%ebx,%1\n\t"
|
||||
"popl\t%%ebx"
|
||||
: "=a" (p[0]), "=DS" (p[1]), "=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax), "c" (cx));
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline void
|
||||
enable_intr(void)
|
||||
|
@ -863,13 +863,88 @@ rufetchtd(struct thread *td, struct rusage *ru)
|
||||
calcru1(p, &td->td_rux, &ru->ru_utime, &ru->ru_stime);
|
||||
}
|
||||
|
||||
/* XXX: the MI version is too slow to use: */
|
||||
#ifndef __HAVE_INLINE_FLSLL
|
||||
#define flsll(x) (fls((x) >> 32) != 0 ? fls((x) >> 32) + 32 : fls(x))
|
||||
#endif
|
||||
|
||||
static uint64_t
|
||||
mul64_by_fraction(uint64_t a, uint64_t b, uint64_t c)
|
||||
{
|
||||
uint64_t acc, bh, bl;
|
||||
int i, s, sa, sb;
|
||||
|
||||
/*
|
||||
* Compute floor(a * (b / c)) without overflowing, (b / c) <= 1.0.
|
||||
* Calculate (a * b) / c accurately enough without overflowing. c
|
||||
* must be nonzero, and its top bit must be 0. a or b must be
|
||||
* <= c, and the implementation is tuned for b <= c.
|
||||
*
|
||||
* The comments about times are for use in calcru1() with units of
|
||||
* microseconds for 'a' and stathz ticks at 128 Hz for b and c.
|
||||
*
|
||||
* Let n be the number of top zero bits in c. Each iteration
|
||||
* either returns, or reduces b by right shifting it by at least n.
|
||||
* The number of iterations is at most 1 + 64 / n, and the error is
|
||||
* at most the number of iterations.
|
||||
*
|
||||
* It is very unusual to need even 2 iterations. Previous
|
||||
* implementations overflowed essentially by returning early in the
|
||||
* first iteration, with n = 38 giving overflow at 105+ hours and
|
||||
* n = 32 giving overlow at at 388+ days despite a more careful
|
||||
* calculation. 388 days is a reasonable uptime, and the calculation
|
||||
* needs to work for the uptime times the number of CPUs since 'a'
|
||||
* is per-process.
|
||||
*/
|
||||
return ((a / c) * b + (a % c) * (b / c) + (a % c) * (b % c) / c);
|
||||
if (a >= (uint64_t)1 << 63)
|
||||
return (0); /* Unsupported arg -- can't happen. */
|
||||
acc = 0;
|
||||
for (i = 0; i < 128; i++) {
|
||||
sa = flsll(a);
|
||||
sb = flsll(b);
|
||||
if (sa + sb <= 64)
|
||||
/* Up to 105 hours on first iteration. */
|
||||
return (acc + (a * b) / c);
|
||||
if (a >= c) {
|
||||
/*
|
||||
* This reduction is based on a = q * c + r, with the
|
||||
* remainder r < c. 'a' may be large to start, and
|
||||
* moving bits from b into 'a' at the end of the loop
|
||||
* sets the top bit of 'a', so the reduction makes
|
||||
* significant progress.
|
||||
*/
|
||||
acc += (a / c) * b;
|
||||
a %= c;
|
||||
sa = flsll(a);
|
||||
if (sa + sb <= 64)
|
||||
/* Up to 388 days on first iteration. */
|
||||
return (acc + (a * b) / c);
|
||||
}
|
||||
|
||||
/*
|
||||
* This step writes a * b as a * ((bh << s) + bl) =
|
||||
* a * (bh << s) + a * bl = (a << s) * bh + a * bl. The 2
|
||||
* additive terms are handled separately. Splitting in
|
||||
* this way is linear except for rounding errors.
|
||||
*
|
||||
* s = 64 - sa is the maximum such that a << s fits in 64
|
||||
* bits. Since a < c and c has at least 1 zero top bit,
|
||||
* sa < 64 and s > 0. Thus this step makes progress by
|
||||
* reducing b (it increases 'a', but taking remainders on
|
||||
* the next iteration completes the reduction).
|
||||
*
|
||||
* Finally, the choice for s is just what is needed to keep
|
||||
* a * bl from overflowing, so we don't need complications
|
||||
* like a recursive call mul64_by_fraction(a, bl, c) to
|
||||
* handle the second additive term.
|
||||
*/
|
||||
s = 64 - sa;
|
||||
bh = b >> s;
|
||||
bl = b - (bh << s);
|
||||
acc += (a * bl) / c;
|
||||
a <<= s;
|
||||
b = bh;
|
||||
}
|
||||
return (0); /* Algorithm failure -- can't happen. */
|
||||
}
|
||||
|
||||
static void
|
||||
@ -896,15 +971,23 @@ calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up,
|
||||
tu = ruxp->rux_tu;
|
||||
}
|
||||
|
||||
/* Subdivide tu. Avoid overflow in the multiplications. */
|
||||
if (__predict_true(tu <= ((uint64_t)1 << 38) && tt <= (1 << 26))) {
|
||||
/* Up to 76 hours when stathz is 128. */
|
||||
uu = (tu * ut) / tt;
|
||||
su = (tu * st) / tt;
|
||||
} else {
|
||||
uu = mul64_by_fraction(tu, ut, tt);
|
||||
su = mul64_by_fraction(tu, ut, st);
|
||||
}
|
||||
|
||||
if (tu >= ruxp->rux_tu) {
|
||||
/*
|
||||
* The normal case, time increased.
|
||||
* Enforce monotonicity of bucketed numbers.
|
||||
*/
|
||||
uu = mul64_by_fraction(tu, ut, tt);
|
||||
if (uu < ruxp->rux_uu)
|
||||
uu = ruxp->rux_uu;
|
||||
su = mul64_by_fraction(tu, st, tt);
|
||||
if (su < ruxp->rux_su)
|
||||
su = ruxp->rux_su;
|
||||
} else if (tu + 3 > ruxp->rux_tu || 101 * tu > 100 * ruxp->rux_tu) {
|
||||
@ -933,8 +1016,6 @@ calcru1(struct proc *p, struct rusage_ext *ruxp, struct timeval *up,
|
||||
"to %ju usec for pid %d (%s)\n",
|
||||
(uintmax_t)ruxp->rux_tu, (uintmax_t)tu,
|
||||
p->p_pid, p->p_comm);
|
||||
uu = mul64_by_fraction(tu, ut, tt);
|
||||
su = mul64_by_fraction(tu, st, tt);
|
||||
}
|
||||
|
||||
ruxp->rux_uu = uu;
|
||||
|
@ -379,9 +379,7 @@ void
|
||||
pipe_dtor(struct pipe *dpipe)
|
||||
{
|
||||
struct pipe *peer;
|
||||
ino_t ino;
|
||||
|
||||
ino = dpipe->pipe_ino;
|
||||
peer = (dpipe->pipe_state & PIPE_NAMED) != 0 ? dpipe->pipe_peer : NULL;
|
||||
funsetown(&dpipe->pipe_sigio);
|
||||
pipeclose(dpipe);
|
||||
|
@ -76,7 +76,7 @@ struct sysentvec elf64_freebsd_sysvec = {
|
||||
.sv_setregs = exec_setregs,
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_syscallnames = syscallnames,
|
||||
@ -131,7 +131,7 @@ struct sysentvec elf32_freebsd_sysvec = {
|
||||
.sv_setregs = exec_setregs,
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_ILP32,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_syscallnames = syscallnames,
|
||||
|
@ -68,5 +68,7 @@ CFLAGS.utils.c += -I${LIBSODIUM_INC} -I${LIBSODIUM_COMPAT}
|
||||
|
||||
SRCS += opt_param.h cryptodev_if.h bus_if.h device_if.h
|
||||
SRCS += opt_ddb.h
|
||||
SRCS += cbc_mac.c
|
||||
SRCS += xform_cbc_mac.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
@ -133,6 +133,7 @@ static int lagg_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
static int lagg_snd_tag_alloc(struct ifnet *,
|
||||
union if_snd_tag_alloc_params *,
|
||||
struct m_snd_tag **);
|
||||
static void lagg_snd_tag_free(struct m_snd_tag *);
|
||||
#endif
|
||||
static int lagg_setmulti(struct lagg_port *);
|
||||
static int lagg_clrmulti(struct lagg_port *);
|
||||
@ -514,6 +515,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST;
|
||||
#ifdef RATELIMIT
|
||||
ifp->if_snd_tag_alloc = lagg_snd_tag_alloc;
|
||||
ifp->if_snd_tag_free = lagg_snd_tag_free;
|
||||
#endif
|
||||
ifp->if_capenable = ifp->if_capabilities = IFCAP_HWSTATS;
|
||||
|
||||
@ -1568,6 +1570,13 @@ lagg_snd_tag_alloc(struct ifnet *ifp,
|
||||
/* forward allocation request */
|
||||
return (ifp->if_snd_tag_alloc(ifp, params, ppmt));
|
||||
}
|
||||
|
||||
static void
|
||||
lagg_snd_tag_free(struct m_snd_tag *tag)
|
||||
{
|
||||
tag->ifp->if_snd_tag_free(tag);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int
|
||||
|
@ -267,6 +267,7 @@ static int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
|
||||
#ifdef RATELIMIT
|
||||
static int vlan_snd_tag_alloc(struct ifnet *,
|
||||
union if_snd_tag_alloc_params *, struct m_snd_tag **);
|
||||
static void vlan_snd_tag_free(struct m_snd_tag *);
|
||||
#endif
|
||||
static void vlan_qflush(struct ifnet *ifp);
|
||||
static int vlan_setflag(struct ifnet *ifp, int flag, int status,
|
||||
@ -1047,6 +1048,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params)
|
||||
ifp->if_ioctl = vlan_ioctl;
|
||||
#ifdef RATELIMIT
|
||||
ifp->if_snd_tag_alloc = vlan_snd_tag_alloc;
|
||||
ifp->if_snd_tag_free = vlan_snd_tag_free;
|
||||
#endif
|
||||
ifp->if_flags = VLAN_IFFLAGS;
|
||||
ether_ifattach(ifp, eaddr);
|
||||
@ -1934,4 +1936,10 @@ vlan_snd_tag_alloc(struct ifnet *ifp,
|
||||
/* forward allocation request */
|
||||
return (ifp->if_snd_tag_alloc(ifp, params, ppmt));
|
||||
}
|
||||
|
||||
static void
|
||||
vlan_snd_tag_free(struct m_snd_tag *tag)
|
||||
{
|
||||
tag->ifp->if_snd_tag_free(tag);
|
||||
}
|
||||
#endif
|
||||
|
@ -1468,12 +1468,17 @@ iflib_fast_intr(void *arg)
|
||||
{
|
||||
iflib_filter_info_t info = arg;
|
||||
struct grouptask *gtask = info->ifi_task;
|
||||
int result;
|
||||
|
||||
if (!iflib_started)
|
||||
return (FILTER_HANDLED);
|
||||
return (FILTER_STRAY);
|
||||
|
||||
DBG_COUNTER_INC(fast_intrs);
|
||||
if (info->ifi_filter != NULL && info->ifi_filter(info->ifi_filter_arg) == FILTER_HANDLED)
|
||||
return (FILTER_HANDLED);
|
||||
if (info->ifi_filter != NULL) {
|
||||
result = info->ifi_filter(info->ifi_filter_arg);
|
||||
if ((result & FILTER_SCHEDULE_THREAD) == 0)
|
||||
return (result);
|
||||
}
|
||||
|
||||
GROUPTASK_ENQUEUE(gtask);
|
||||
return (FILTER_HANDLED);
|
||||
@ -1488,15 +1493,18 @@ iflib_fast_intr_rxtx(void *arg)
|
||||
iflib_rxq_t rxq = (iflib_rxq_t)info->ifi_ctx;
|
||||
iflib_txq_t txq;
|
||||
void *sc;
|
||||
int i, cidx;
|
||||
int i, cidx, result;
|
||||
qidx_t txqid;
|
||||
|
||||
if (!iflib_started)
|
||||
return (FILTER_HANDLED);
|
||||
return (FILTER_STRAY);
|
||||
|
||||
DBG_COUNTER_INC(fast_intrs);
|
||||
if (info->ifi_filter != NULL && info->ifi_filter(info->ifi_filter_arg) == FILTER_HANDLED)
|
||||
return (FILTER_HANDLED);
|
||||
if (info->ifi_filter != NULL) {
|
||||
result = info->ifi_filter(info->ifi_filter_arg);
|
||||
if ((result & FILTER_SCHEDULE_THREAD) == 0)
|
||||
return (result);
|
||||
}
|
||||
|
||||
ctx = rxq->ifr_ctx;
|
||||
sc = ctx->ifc_softc;
|
||||
@ -1531,13 +1539,17 @@ iflib_fast_intr_ctx(void *arg)
|
||||
{
|
||||
iflib_filter_info_t info = arg;
|
||||
struct grouptask *gtask = info->ifi_task;
|
||||
int result;
|
||||
|
||||
if (!iflib_started)
|
||||
return (FILTER_HANDLED);
|
||||
return (FILTER_STRAY);
|
||||
|
||||
DBG_COUNTER_INC(fast_intrs);
|
||||
if (info->ifi_filter != NULL && info->ifi_filter(info->ifi_filter_arg) == FILTER_HANDLED)
|
||||
return (FILTER_HANDLED);
|
||||
if (info->ifi_filter != NULL) {
|
||||
result = info->ifi_filter(info->ifi_filter_arg);
|
||||
if ((result & FILTER_SCHEDULE_THREAD) == 0)
|
||||
return (result);
|
||||
}
|
||||
|
||||
GROUPTASK_ENQUEUE(gtask);
|
||||
return (FILTER_HANDLED);
|
||||
|
@ -1565,6 +1565,7 @@ in_pcbfree_deferred(epoch_context_t ctx)
|
||||
inp = __containerof(ctx, struct inpcb, inp_epoch_ctx);
|
||||
|
||||
INP_WLOCK(inp);
|
||||
CURVNET_SET(inp->inp_vnet);
|
||||
#ifdef INET
|
||||
struct ip_moptions *imo = inp->inp_moptions;
|
||||
inp->inp_moptions = NULL;
|
||||
@ -1597,6 +1598,7 @@ in_pcbfree_deferred(epoch_context_t ctx)
|
||||
#ifdef INET
|
||||
inp_freemoptions(imo);
|
||||
#endif
|
||||
CURVNET_RESTORE();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -302,7 +302,7 @@ tcp_twstart(struct tcpcb *tp)
|
||||
if (SEQ_GT(tp->rcv_adv, tp->rcv_nxt) &&
|
||||
recwin < (tp->rcv_adv - tp->rcv_nxt))
|
||||
recwin = (tp->rcv_adv - tp->rcv_nxt);
|
||||
tw->last_win = htons((u_short)(recwin >> tp->rcv_scale));
|
||||
tw->last_win = (u_short)(recwin >> tp->rcv_scale);
|
||||
|
||||
/*
|
||||
* Set t_recent if timestamps are used on the connection.
|
||||
|
252
sys/opencrypto/cbc_mac.c
Normal file
252
sys/opencrypto/cbc_mac.c
Normal file
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2019 iXsystems Inc. All rights reserved.
|
||||
*
|
||||
* 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 ``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 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/types.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/endian.h>
|
||||
#include <opencrypto/cbc_mac.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
/*
|
||||
* Given two CCM_CBC_BLOCK_LEN blocks, xor
|
||||
* them into dst, and then encrypt dst.
|
||||
*/
|
||||
static void
|
||||
xor_and_encrypt(struct aes_cbc_mac_ctx *ctx,
|
||||
const uint8_t *src, uint8_t *dst)
|
||||
{
|
||||
const uint64_t *b1;
|
||||
uint64_t *b2;
|
||||
uint64_t temp_block[CCM_CBC_BLOCK_LEN/sizeof(uint64_t)];
|
||||
|
||||
b1 = (const uint64_t*)src;
|
||||
b2 = (uint64_t*)dst;
|
||||
|
||||
for (size_t count = 0;
|
||||
count < CCM_CBC_BLOCK_LEN/sizeof(uint64_t);
|
||||
count++) {
|
||||
temp_block[count] = b1[count] ^ b2[count];
|
||||
}
|
||||
rijndaelEncrypt(ctx->keysched, ctx->rounds, (void*)temp_block, dst);
|
||||
}
|
||||
|
||||
void
|
||||
AES_CBC_MAC_Init(struct aes_cbc_mac_ctx *ctx)
|
||||
{
|
||||
bzero(ctx, sizeof(*ctx));
|
||||
}
|
||||
|
||||
void
|
||||
AES_CBC_MAC_Setkey(struct aes_cbc_mac_ctx *ctx, const uint8_t *key, uint16_t klen)
|
||||
{
|
||||
ctx->rounds = rijndaelKeySetupEnc(ctx->keysched, key, klen * 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called to set the nonce, aka IV.
|
||||
* Before this call, the authDataLength and cryptDataLength fields
|
||||
* MUST have been set. Sadly, there's no way to return an error.
|
||||
*
|
||||
* The CBC-MAC algorithm requires that the first block contain the
|
||||
* nonce, as well as information about the sizes and lengths involved.
|
||||
*/
|
||||
void
|
||||
AES_CBC_MAC_Reinit(struct aes_cbc_mac_ctx *ctx, const uint8_t *nonce, uint16_t nonceLen)
|
||||
{
|
||||
uint8_t b0[CCM_CBC_BLOCK_LEN];
|
||||
uint8_t *bp = b0, flags = 0;
|
||||
uint8_t L = 0;
|
||||
uint64_t dataLength = ctx->cryptDataLength;
|
||||
|
||||
KASSERT(ctx->authDataLength != 0 || ctx->cryptDataLength != 0,
|
||||
("Auth Data and Data lengths cannot both be 0"));
|
||||
|
||||
KASSERT(nonceLen >= 7 && nonceLen <= 13,
|
||||
("nonceLen must be between 7 and 13 bytes"));
|
||||
|
||||
ctx->nonce = nonce;
|
||||
ctx->nonceLength = nonceLen;
|
||||
|
||||
ctx->authDataCount = 0;
|
||||
ctx->blockIndex = 0;
|
||||
explicit_bzero(ctx->staging_block, sizeof(ctx->staging_block));
|
||||
|
||||
/*
|
||||
* Need to determine the L field value. This is the number of
|
||||
* bytes needed to specify the length of the message; the length
|
||||
* is whatever is left in the 16 bytes after specifying flags and
|
||||
* the nonce.
|
||||
*/
|
||||
L = 15 - nonceLen;
|
||||
|
||||
flags = ((ctx->authDataLength > 0) << 6) +
|
||||
(((AES_CBC_MAC_HASH_LEN - 2) / 2) << 3) +
|
||||
L - 1;
|
||||
/*
|
||||
* Now we need to set up the first block, which has flags, nonce,
|
||||
* and the message length.
|
||||
*/
|
||||
b0[0] = flags;
|
||||
bcopy(nonce, b0 + 1, nonceLen);
|
||||
bp = b0 + 1 + nonceLen;
|
||||
|
||||
/* Need to copy L' [aka L-1] bytes of cryptDataLength */
|
||||
for (uint8_t *dst = b0 + sizeof(b0) - 1; dst >= bp; dst--) {
|
||||
*dst = dataLength;
|
||||
dataLength >>= 8;
|
||||
}
|
||||
/* Now need to encrypt b0 */
|
||||
rijndaelEncrypt(ctx->keysched, ctx->rounds, b0, ctx->block);
|
||||
/* If there is auth data, we need to set up the staging block */
|
||||
if (ctx->authDataLength) {
|
||||
if (ctx->authDataLength < ((1<<16) - (1<<8))) {
|
||||
uint16_t sizeVal = htobe16(ctx->authDataLength);
|
||||
bcopy(&sizeVal, ctx->staging_block, sizeof(sizeVal));
|
||||
ctx->blockIndex = sizeof(sizeVal);
|
||||
} else if (ctx->authDataLength < (1ULL<<32)) {
|
||||
uint32_t sizeVal = htobe32(ctx->authDataLength);
|
||||
ctx->staging_block[0] = 0xff;
|
||||
ctx->staging_block[1] = 0xfe;
|
||||
bcopy(&sizeVal, ctx->staging_block+2, sizeof(sizeVal));
|
||||
ctx->blockIndex = 2 + sizeof(sizeVal);
|
||||
} else {
|
||||
uint64_t sizeVal = htobe64(ctx->authDataLength);
|
||||
ctx->staging_block[0] = 0xff;
|
||||
ctx->staging_block[1] = 0xff;
|
||||
bcopy(&sizeVal, ctx->staging_block+2, sizeof(sizeVal));
|
||||
ctx->blockIndex = 2 + sizeof(sizeVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
AES_CBC_MAC_Update(struct aes_cbc_mac_ctx *ctx, const uint8_t *data,
|
||||
uint16_t length)
|
||||
{
|
||||
size_t copy_amt;
|
||||
|
||||
/*
|
||||
* This will be called in one of two phases:
|
||||
* (1) Applying authentication data, or
|
||||
* (2) Applying the payload data.
|
||||
*
|
||||
* Because CBC-MAC puts the authentication data size before the
|
||||
* data, subsequent calls won't be block-size-aligned. Which
|
||||
* complicates things a fair bit.
|
||||
*
|
||||
* The payload data doesn't have that problem.
|
||||
*/
|
||||
|
||||
if (ctx->authDataCount < ctx->authDataLength) {
|
||||
/*
|
||||
* We need to process data as authentication data.
|
||||
* Since we may be out of sync, we may also need
|
||||
* to pad out the staging block.
|
||||
*/
|
||||
const uint8_t *ptr = data;
|
||||
while (length > 0) {
|
||||
|
||||
copy_amt = MIN(length,
|
||||
sizeof(ctx->staging_block) - ctx->blockIndex);
|
||||
|
||||
bcopy(ptr, ctx->staging_block + ctx->blockIndex,
|
||||
copy_amt);
|
||||
ptr += copy_amt;
|
||||
length -= copy_amt;
|
||||
ctx->authDataCount += copy_amt;
|
||||
ctx->blockIndex += copy_amt;
|
||||
ctx->blockIndex %= sizeof(ctx->staging_block);
|
||||
if (ctx->authDataCount == ctx->authDataLength)
|
||||
length = 0;
|
||||
if (ctx->blockIndex == 0 ||
|
||||
ctx->authDataCount >= ctx->authDataLength) {
|
||||
/*
|
||||
* We're done with this block, so we
|
||||
* xor staging_block with block, and then
|
||||
* encrypt it.
|
||||
*/
|
||||
xor_and_encrypt(ctx, ctx->staging_block, ctx->block);
|
||||
bzero(ctx->staging_block, sizeof(ctx->staging_block));
|
||||
ctx->blockIndex = 0;
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* If we're here, then we're encoding payload data.
|
||||
* This is marginally easier, except that _Update can
|
||||
* be called with non-aligned update lengths. As a result,
|
||||
* we still need to use the staging block.
|
||||
*/
|
||||
KASSERT((length + ctx->cryptDataCount) <= ctx->cryptDataLength,
|
||||
("More encryption data than allowed"));
|
||||
|
||||
while (length) {
|
||||
uint8_t *ptr;
|
||||
|
||||
copy_amt = MIN(sizeof(ctx->staging_block) - ctx->blockIndex,
|
||||
length);
|
||||
ptr = ctx->staging_block + ctx->blockIndex;
|
||||
bcopy(data, ptr, copy_amt);
|
||||
data += copy_amt;
|
||||
ctx->blockIndex += copy_amt;
|
||||
ctx->cryptDataCount += copy_amt;
|
||||
length -= copy_amt;
|
||||
if (ctx->blockIndex == sizeof(ctx->staging_block)) {
|
||||
/* We've got a full block */
|
||||
xor_and_encrypt(ctx, ctx->staging_block, ctx->block);
|
||||
ctx->blockIndex = 0;
|
||||
bzero(ctx->staging_block, sizeof(ctx->staging_block));
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
AES_CBC_MAC_Final(uint8_t *buf, struct aes_cbc_mac_ctx *ctx)
|
||||
{
|
||||
uint8_t s0[CCM_CBC_BLOCK_LEN];
|
||||
|
||||
/*
|
||||
* We first need to check to see if we've got any data
|
||||
* left over to encrypt.
|
||||
*/
|
||||
if (ctx->blockIndex != 0) {
|
||||
xor_and_encrypt(ctx, ctx->staging_block, ctx->block);
|
||||
ctx->cryptDataCount += ctx->blockIndex;
|
||||
ctx->blockIndex = 0;
|
||||
explicit_bzero(ctx->staging_block, sizeof(ctx->staging_block));
|
||||
}
|
||||
bzero(s0, sizeof(s0));
|
||||
s0[0] = (15 - ctx->nonceLength) - 1;
|
||||
bcopy(ctx->nonce, s0 + 1, ctx->nonceLength);
|
||||
rijndaelEncrypt(ctx->keysched, ctx->rounds, s0, s0);
|
||||
for (size_t indx = 0; indx < AES_CBC_MAC_HASH_LEN; indx++)
|
||||
buf[indx] = ctx->block[indx] ^ s0[indx];
|
||||
explicit_bzero(s0, sizeof(s0));
|
||||
}
|
67
sys/opencrypto/cbc_mac.h
Normal file
67
sys/opencrypto/cbc_mac.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2014 The FreeBSD Foundation
|
||||
* Copyright (c) 2018, iXsystems Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed by Sean Eric Fagan, with lots of references
|
||||
* to existing AES-CCM (gmac) code.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CBC_CCM_H
|
||||
# define _CBC_CCM_H
|
||||
|
||||
# include <sys/types.h>
|
||||
# include <crypto/rijndael/rijndael.h>
|
||||
|
||||
# define CCM_CBC_BLOCK_LEN 16 /* 128 bits */
|
||||
# define CCM_CBC_MAX_DIGEST_LEN 16
|
||||
# define CCM_CBC_MIN_DIGEST_LEN 4
|
||||
|
||||
/*
|
||||
* This is the authentication context structure;
|
||||
* the encryption one is similar.
|
||||
*/
|
||||
struct aes_cbc_mac_ctx {
|
||||
uint64_t authDataLength, authDataCount;
|
||||
uint64_t cryptDataLength, cryptDataCount;
|
||||
int blockIndex;
|
||||
uint8_t staging_block[CCM_CBC_BLOCK_LEN];
|
||||
uint8_t block[CCM_CBC_BLOCK_LEN];
|
||||
const uint8_t *nonce;
|
||||
int nonceLength; /* This one is in bytes, not bits! */
|
||||
/* AES state data */
|
||||
int rounds;
|
||||
uint32_t keysched[4*(RIJNDAEL_MAXNR+1)];
|
||||
};
|
||||
|
||||
void AES_CBC_MAC_Init(struct aes_cbc_mac_ctx *);
|
||||
void AES_CBC_MAC_Setkey(struct aes_cbc_mac_ctx *, const uint8_t *, uint16_t);
|
||||
void AES_CBC_MAC_Reinit(struct aes_cbc_mac_ctx *, const uint8_t *, uint16_t);
|
||||
int AES_CBC_MAC_Update(struct aes_cbc_mac_ctx *, const uint8_t *, uint16_t);
|
||||
void AES_CBC_MAC_Final(uint8_t *, struct aes_cbc_mac_ctx *);
|
||||
|
||||
#endif /* _CBC_CCM_H */
|
@ -444,6 +444,9 @@ cryptof_ioctl(
|
||||
case CRYPTO_CHACHA20:
|
||||
txform = &enc_xform_chacha20;
|
||||
break;
|
||||
case CRYPTO_AES_CCM_16:
|
||||
txform = &enc_xform_ccm;
|
||||
break;
|
||||
|
||||
default:
|
||||
CRYPTDEB("invalid cipher");
|
||||
@ -488,6 +491,25 @@ cryptof_ioctl(
|
||||
thash = &auth_hash_nist_gmac_aes_256;
|
||||
break;
|
||||
|
||||
case CRYPTO_AES_CCM_CBC_MAC:
|
||||
switch (sop->keylen) {
|
||||
case 16:
|
||||
thash = &auth_hash_ccm_cbc_mac_128;
|
||||
break;
|
||||
case 24:
|
||||
thash = &auth_hash_ccm_cbc_mac_192;
|
||||
break;
|
||||
case 32:
|
||||
thash = &auth_hash_ccm_cbc_mac_256;
|
||||
break;
|
||||
default:
|
||||
CRYPTDEB("Invalid CBC MAC key size %d",
|
||||
sop->keylen);
|
||||
SDT_PROBE1(opencrypto, dev, ioctl,
|
||||
error, __LINE__);
|
||||
return (EINVAL);
|
||||
}
|
||||
break;
|
||||
#ifdef notdef
|
||||
case CRYPTO_MD5:
|
||||
thash = &auth_hash_md5;
|
||||
@ -1003,12 +1025,13 @@ cryptodev_aead(
|
||||
}
|
||||
|
||||
/*
|
||||
* For GCM, crd_len covers only the AAD. For other ciphers
|
||||
* For GCM/CCM, crd_len covers only the AAD. For other ciphers
|
||||
* chained with an HMAC, crd_len covers both the AAD and the
|
||||
* cipher text.
|
||||
*/
|
||||
crda->crd_skip = 0;
|
||||
if (cse->cipher == CRYPTO_AES_NIST_GCM_16)
|
||||
if (cse->cipher == CRYPTO_AES_NIST_GCM_16 ||
|
||||
cse->cipher == CRYPTO_AES_CCM_16)
|
||||
crda->crd_len = caead->aadlen;
|
||||
else
|
||||
crda->crd_len = caead->aadlen + caead->len;
|
||||
|
@ -86,6 +86,7 @@
|
||||
#define SHA1_KPDK_HASH_LEN 20
|
||||
#define AES_GMAC_HASH_LEN 16
|
||||
#define POLY1305_HASH_LEN 16
|
||||
#define AES_CBC_MAC_HASH_LEN 16
|
||||
/* Maximum hash algorithm result length */
|
||||
#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
|
||||
|
||||
@ -107,6 +108,9 @@
|
||||
#define AES_128_GMAC_KEY_LEN 16
|
||||
#define AES_192_GMAC_KEY_LEN 24
|
||||
#define AES_256_GMAC_KEY_LEN 32
|
||||
#define AES_128_CBC_MAC_KEY_LEN 16
|
||||
#define AES_192_CBC_MAC_KEY_LEN 24
|
||||
#define AES_256_CBC_MAC_KEY_LEN 32
|
||||
|
||||
#define POLY1305_KEY_LEN 32
|
||||
|
||||
@ -129,6 +133,7 @@
|
||||
|
||||
#define ARC4_IV_LEN 1
|
||||
#define AES_GCM_IV_LEN 12
|
||||
#define AES_CCM_IV_LEN 12
|
||||
#define AES_XTS_IV_LEN 8
|
||||
#define AES_XTS_ALPHA 0x87 /* GF(2^128) generator polynomial */
|
||||
|
||||
@ -199,7 +204,9 @@
|
||||
#define CRYPTO_SHA2_384 36
|
||||
#define CRYPTO_SHA2_512 37
|
||||
#define CRYPTO_POLY1305 38
|
||||
#define CRYPTO_ALGORITHM_MAX 38 /* Keep updated - see below */
|
||||
#define CRYPTO_AES_CCM_CBC_MAC 39 /* auth side */
|
||||
#define CRYPTO_AES_CCM_16 40 /* cipher side */
|
||||
#define CRYPTO_ALGORITHM_MAX 40 /* Keep updated - see below */
|
||||
|
||||
#define CRYPTO_ALGO_VALID(x) ((x) >= CRYPTO_ALGORITHM_MIN && \
|
||||
(x) <= CRYPTO_ALGORITHM_MAX)
|
||||
|
@ -62,6 +62,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/bus.h>
|
||||
#include "cryptodev_if.h"
|
||||
|
||||
_Static_assert(AES_CCM_IV_LEN == AES_GCM_IV_LEN,
|
||||
"AES_GCM_IV_LEN must currently be the same as AES_CCM_IV_LEN");
|
||||
|
||||
static int32_t swcr_id;
|
||||
|
||||
u_int8_t hmac_ipad_buffer[HMAC_MAX_BLOCK_LEN];
|
||||
@ -506,6 +509,7 @@ swcr_authenc(struct cryptop *crp)
|
||||
caddr_t buf = (caddr_t)crp->crp_buf;
|
||||
uint32_t *blkp;
|
||||
int aadlen, blksz, i, ivlen, len, iskip, oskip, r;
|
||||
int isccm = 0;
|
||||
|
||||
ivlen = blksz = iskip = oskip = 0;
|
||||
|
||||
@ -520,13 +524,18 @@ swcr_authenc(struct cryptop *crp)
|
||||
|
||||
sw = &ses->swcr_algorithms[i];
|
||||
switch (sw->sw_alg) {
|
||||
case CRYPTO_AES_CCM_16:
|
||||
case CRYPTO_AES_NIST_GCM_16:
|
||||
case CRYPTO_AES_NIST_GMAC:
|
||||
swe = sw;
|
||||
crde = crd;
|
||||
exf = swe->sw_exf;
|
||||
ivlen = 12;
|
||||
/* AES_CCM_IV_LEN and AES_GCM_IV_LEN are both 12 */
|
||||
ivlen = AES_CCM_IV_LEN;
|
||||
break;
|
||||
case CRYPTO_AES_CCM_CBC_MAC:
|
||||
isccm = 1;
|
||||
/* FALLTHROUGH */
|
||||
case CRYPTO_AES_128_NIST_GMAC:
|
||||
case CRYPTO_AES_192_NIST_GMAC:
|
||||
case CRYPTO_AES_256_NIST_GMAC:
|
||||
@ -544,8 +553,26 @@ swcr_authenc(struct cryptop *crp)
|
||||
}
|
||||
if (crde == NULL || crda == NULL)
|
||||
return (EINVAL);
|
||||
/*
|
||||
* We need to make sure that the auth algorithm matches the
|
||||
* encr algorithm. Specifically, for AES-GCM must go with
|
||||
* AES NIST GMAC, and AES-CCM must go with CBC-MAC.
|
||||
*/
|
||||
if (crde->crd_alg == CRYPTO_AES_NIST_GCM_16) {
|
||||
switch (crda->crd_alg) {
|
||||
case CRYPTO_AES_128_NIST_GMAC:
|
||||
case CRYPTO_AES_192_NIST_GMAC:
|
||||
case CRYPTO_AES_256_NIST_GMAC:
|
||||
break; /* Good! */
|
||||
default:
|
||||
return (EINVAL); /* Not good! */
|
||||
}
|
||||
} else if (crde->crd_alg == CRYPTO_AES_CCM_16 &&
|
||||
crda->crd_alg != CRYPTO_AES_CCM_CBC_MAC)
|
||||
return (EINVAL);
|
||||
|
||||
if (crde->crd_alg == CRYPTO_AES_NIST_GCM_16 &&
|
||||
if ((crde->crd_alg == CRYPTO_AES_NIST_GCM_16 ||
|
||||
crde->crd_alg == CRYPTO_AES_CCM_16) &&
|
||||
(crde->crd_flags & CRD_F_IV_EXPLICIT) == 0)
|
||||
return (EINVAL);
|
||||
|
||||
@ -576,6 +603,15 @@ swcr_authenc(struct cryptop *crp)
|
||||
}
|
||||
}
|
||||
|
||||
if (swa->sw_alg == CRYPTO_AES_CCM_CBC_MAC) {
|
||||
/*
|
||||
* AES CCM-CBC needs to know the length of
|
||||
* both the auth data, and payload data, before
|
||||
* doing the auth computation.
|
||||
*/
|
||||
ctx.aes_cbc_mac_ctx.authDataLength = crda->crd_len;
|
||||
ctx.aes_cbc_mac_ctx.cryptDataLength = crde->crd_len;
|
||||
}
|
||||
/* Supply MAC with IV */
|
||||
if (axf->Reinit)
|
||||
axf->Reinit(&ctx, iv, ivlen);
|
||||
@ -610,16 +646,30 @@ swcr_authenc(struct cryptop *crp)
|
||||
bzero(blk, blksz);
|
||||
crypto_copydata(crp->crp_flags, buf, crde->crd_skip + i, len,
|
||||
blk);
|
||||
/*
|
||||
* One of the problems with CCM+CBC is that the authentication
|
||||
* is done on the unecncrypted data. As a result, we have
|
||||
* to do the authentication update at different times,
|
||||
* depending on whether it's CCM or not.
|
||||
*/
|
||||
if (crde->crd_flags & CRD_F_ENCRYPT) {
|
||||
if (isccm)
|
||||
axf->Update(&ctx, blk, len);
|
||||
if (exf->encrypt_multi != NULL)
|
||||
exf->encrypt_multi(swe->sw_kschedule, blk,
|
||||
len);
|
||||
else
|
||||
exf->encrypt(swe->sw_kschedule, blk);
|
||||
axf->Update(&ctx, blk, len);
|
||||
if (!isccm)
|
||||
axf->Update(&ctx, blk, len);
|
||||
crypto_copyback(crp->crp_flags, buf,
|
||||
crde->crd_skip + i, len, blk);
|
||||
} else {
|
||||
if (isccm) {
|
||||
KASSERT(exf->encrypt_multi == NULL,
|
||||
("assume CCM is single-block only"));
|
||||
exf->decrypt(swe->sw_kschedule, blk);
|
||||
}
|
||||
axf->Update(&ctx, blk, len);
|
||||
}
|
||||
}
|
||||
@ -650,6 +700,11 @@ swcr_authenc(struct cryptop *crp)
|
||||
r = timingsafe_bcmp(aalg, uaalg, axf->hashsize);
|
||||
if (r == 0) {
|
||||
/* tag matches, decrypt data */
|
||||
if (isccm) {
|
||||
KASSERT(exf->reinit != NULL,
|
||||
("AES-CCM reinit function must be set"));
|
||||
exf->reinit(swe->sw_kschedule, iv);
|
||||
}
|
||||
for (i = 0; i < crde->crd_len; i += blksz) {
|
||||
len = MIN(crde->crd_len - i, blksz);
|
||||
if (len < blksz)
|
||||
@ -799,6 +854,9 @@ swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri)
|
||||
case CRYPTO_AES_NIST_GCM_16:
|
||||
txf = &enc_xform_aes_nist_gcm;
|
||||
goto enccommon;
|
||||
case CRYPTO_AES_CCM_16:
|
||||
txf = &enc_xform_ccm;
|
||||
goto enccommon;
|
||||
case CRYPTO_AES_NIST_GMAC:
|
||||
txf = &enc_xform_aes_nist_gmac;
|
||||
swd->sw_exf = txf;
|
||||
@ -943,6 +1001,22 @@ swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri)
|
||||
swd->sw_axf = axf;
|
||||
break;
|
||||
|
||||
case CRYPTO_AES_CCM_CBC_MAC:
|
||||
switch (cri->cri_klen) {
|
||||
case 128:
|
||||
axf = &auth_hash_ccm_cbc_mac_128;
|
||||
break;
|
||||
case 192:
|
||||
axf = &auth_hash_ccm_cbc_mac_192;
|
||||
break;
|
||||
case 256:
|
||||
axf = &auth_hash_ccm_cbc_mac_256;
|
||||
break;
|
||||
default:
|
||||
swcr_freesession(dev, cses);
|
||||
return EINVAL;
|
||||
}
|
||||
goto auth4common;
|
||||
case CRYPTO_AES_128_NIST_GMAC:
|
||||
axf = &auth_hash_nist_gmac_aes_128;
|
||||
goto auth4common;
|
||||
@ -1042,6 +1116,7 @@ swcr_freesession(device_t dev, crypto_session_t cses)
|
||||
case CRYPTO_CAMELLIA_CBC:
|
||||
case CRYPTO_NULL_CBC:
|
||||
case CRYPTO_CHACHA20:
|
||||
case CRYPTO_AES_CCM_16:
|
||||
txf = swd->sw_exf;
|
||||
|
||||
if (swd->sw_kschedule)
|
||||
@ -1056,6 +1131,7 @@ swcr_freesession(device_t dev, crypto_session_t cses)
|
||||
case CRYPTO_SHA2_512_HMAC:
|
||||
case CRYPTO_RIPEMD160_HMAC:
|
||||
case CRYPTO_NULL_HMAC:
|
||||
case CRYPTO_AES_CCM_CBC_MAC:
|
||||
axf = swd->sw_axf;
|
||||
|
||||
if (swd->sw_ictx) {
|
||||
@ -1201,6 +1277,8 @@ swcr_process(device_t dev, struct cryptop *crp, int hint)
|
||||
case CRYPTO_AES_128_NIST_GMAC:
|
||||
case CRYPTO_AES_192_NIST_GMAC:
|
||||
case CRYPTO_AES_256_NIST_GMAC:
|
||||
case CRYPTO_AES_CCM_16:
|
||||
case CRYPTO_AES_CCM_CBC_MAC:
|
||||
crp->crp_etype = swcr_authenc(crp);
|
||||
goto done;
|
||||
|
||||
@ -1291,6 +1369,8 @@ swcr_attach(device_t dev)
|
||||
REGISTER(CRYPTO_BLAKE2B);
|
||||
REGISTER(CRYPTO_BLAKE2S);
|
||||
REGISTER(CRYPTO_CHACHA20);
|
||||
REGISTER(CRYPTO_AES_CCM_16);
|
||||
REGISTER(CRYPTO_AES_CCM_CBC_MAC);
|
||||
REGISTER(CRYPTO_POLY1305);
|
||||
#undef REGISTER
|
||||
|
||||
|
@ -57,6 +57,7 @@ static void aes_icm_crypt(caddr_t, u_int8_t *);
|
||||
static void aes_icm_zerokey(u_int8_t **);
|
||||
static void aes_icm_reinit(caddr_t, u_int8_t *);
|
||||
static void aes_gcm_reinit(caddr_t, u_int8_t *);
|
||||
static void aes_ccm_reinit(caddr_t, u_int8_t *);
|
||||
|
||||
/* Encryption instances */
|
||||
struct enc_xform enc_xform_aes_icm = {
|
||||
@ -79,6 +80,18 @@ struct enc_xform enc_xform_aes_nist_gcm = {
|
||||
aes_gcm_reinit,
|
||||
};
|
||||
|
||||
struct enc_xform enc_xform_ccm = {
|
||||
.type = CRYPTO_AES_CCM_16,
|
||||
.name = "AES-CCM",
|
||||
.blocksize = AES_ICM_BLOCK_LEN, .ivsize = AES_CCM_IV_LEN,
|
||||
.minkey = AES_MIN_KEY, .maxkey = AES_MAX_KEY,
|
||||
.encrypt = aes_icm_crypt,
|
||||
.decrypt = aes_icm_crypt,
|
||||
.setkey = aes_icm_setkey,
|
||||
.zerokey = aes_icm_zerokey,
|
||||
.reinit = aes_ccm_reinit,
|
||||
};
|
||||
|
||||
/*
|
||||
* Encryption wrapper routines.
|
||||
*/
|
||||
@ -104,6 +117,21 @@ aes_gcm_reinit(caddr_t key, u_int8_t *iv)
|
||||
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 2;
|
||||
}
|
||||
|
||||
static void
|
||||
aes_ccm_reinit(caddr_t key, u_int8_t *iv)
|
||||
{
|
||||
struct aes_icm_ctx *ctx;
|
||||
|
||||
ctx = (struct aes_icm_ctx*)key;
|
||||
|
||||
/* CCM has flags, then the IV, then the counter, which starts at 1 */
|
||||
bzero(ctx->ac_block, sizeof(ctx->ac_block));
|
||||
/* 3 bytes for length field; this gives a nonce of 12 bytes */
|
||||
ctx->ac_block[0] = (15 - AES_CCM_IV_LEN) - 1;
|
||||
bcopy(iv, ctx->ac_block+1, AES_CCM_IV_LEN);
|
||||
ctx->ac_block[AESICM_BLOCKSIZE - 1] = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
aes_icm_crypt(caddr_t key, u_int8_t *data)
|
||||
{
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <crypto/sha2/sha512.h>
|
||||
#include <opencrypto/rmd160.h>
|
||||
#include <opencrypto/gmac.h>
|
||||
#include <opencrypto/cbc_mac.h>
|
||||
|
||||
#include <opencrypto/cryptodev.h>
|
||||
#include <opencrypto/xform_userland.h>
|
||||
@ -85,6 +86,9 @@ extern struct auth_hash auth_hash_nist_gmac_aes_256;
|
||||
extern struct auth_hash auth_hash_blake2b;
|
||||
extern struct auth_hash auth_hash_blake2s;
|
||||
extern struct auth_hash auth_hash_poly1305;
|
||||
extern struct auth_hash auth_hash_ccm_cbc_mac_128;
|
||||
extern struct auth_hash auth_hash_ccm_cbc_mac_192;
|
||||
extern struct auth_hash auth_hash_ccm_cbc_mac_256;
|
||||
|
||||
union authctx {
|
||||
MD5_CTX md5ctx;
|
||||
@ -95,6 +99,7 @@ union authctx {
|
||||
SHA384_CTX sha384ctx;
|
||||
SHA512_CTX sha512ctx;
|
||||
struct aes_gmac_ctx aes_gmac_ctx;
|
||||
struct aes_cbc_mac_ctx aes_cbc_mac_ctx;
|
||||
};
|
||||
|
||||
#endif /* _CRYPTO_XFORM_AUTH_H_ */
|
||||
|
55
sys/opencrypto/xform_cbc_mac.c
Normal file
55
sys/opencrypto/xform_cbc_mac.c
Normal file
@ -0,0 +1,55 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <opencrypto/cbc_mac.h>
|
||||
#include <opencrypto/xform_auth.h>
|
||||
|
||||
/* Authentication instances */
|
||||
struct auth_hash auth_hash_ccm_cbc_mac_128 = {
|
||||
.type = CRYPTO_AES_CCM_CBC_MAC,
|
||||
.name = "CBC-CCM-AES-128",
|
||||
.keysize = AES_128_CBC_MAC_KEY_LEN,
|
||||
.hashsize = AES_CBC_MAC_HASH_LEN,
|
||||
.ctxsize = sizeof(struct aes_cbc_mac_ctx),
|
||||
.blocksize = CCM_CBC_BLOCK_LEN,
|
||||
.Init = (void (*)(void *)) AES_CBC_MAC_Init,
|
||||
.Setkey =
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t))AES_CBC_MAC_Setkey,
|
||||
.Reinit =
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Reinit,
|
||||
.Update =
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Update,
|
||||
.Final = (void (*)(u_int8_t *, void *)) AES_CBC_MAC_Final,
|
||||
};
|
||||
struct auth_hash auth_hash_ccm_cbc_mac_192 = {
|
||||
.type = CRYPTO_AES_CCM_CBC_MAC,
|
||||
.name = "CBC-CCM-AES-192",
|
||||
.keysize = AES_192_CBC_MAC_KEY_LEN,
|
||||
.hashsize = AES_CBC_MAC_HASH_LEN,
|
||||
.ctxsize = sizeof(struct aes_cbc_mac_ctx),
|
||||
.blocksize = CCM_CBC_BLOCK_LEN,
|
||||
.Init = (void (*)(void *)) AES_CBC_MAC_Init,
|
||||
.Setkey =
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Setkey,
|
||||
.Reinit =
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Reinit,
|
||||
.Update =
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Update,
|
||||
.Final = (void (*)(u_int8_t *, void *)) AES_CBC_MAC_Final,
|
||||
};
|
||||
struct auth_hash auth_hash_ccm_cbc_mac_256 = {
|
||||
.type = CRYPTO_AES_CCM_CBC_MAC,
|
||||
.name = "CBC-CCM-AES-256",
|
||||
.keysize = AES_256_CBC_MAC_KEY_LEN,
|
||||
.hashsize = AES_CBC_MAC_HASH_LEN,
|
||||
.ctxsize = sizeof(struct aes_cbc_mac_ctx),
|
||||
.blocksize = CCM_CBC_BLOCK_LEN,
|
||||
.Init = (void (*)(void *)) AES_CBC_MAC_Init,
|
||||
.Setkey =
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Setkey,
|
||||
.Reinit =
|
||||
(void (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Reinit,
|
||||
.Update =
|
||||
(int (*)(void *, const u_int8_t *, u_int16_t)) AES_CBC_MAC_Update,
|
||||
.Final = (void (*)(u_int8_t *, void *)) AES_CBC_MAC_Final,
|
||||
};
|
@ -84,6 +84,7 @@ extern struct enc_xform enc_xform_aes_xts;
|
||||
extern struct enc_xform enc_xform_arc4;
|
||||
extern struct enc_xform enc_xform_camellia;
|
||||
extern struct enc_xform enc_xform_chacha20;
|
||||
extern struct enc_xform enc_xform_ccm;
|
||||
|
||||
struct aes_icm_ctx {
|
||||
u_int32_t ac_ek[4*(RIJNDAEL_MAXNR + 1)];
|
||||
|
@ -2973,14 +2973,19 @@ mmu_booke_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
|
||||
|
||||
/* XXX KASSERT off and size are within a single page? */
|
||||
|
||||
mtx_lock(&zero_page_mutex);
|
||||
va = zero_page_va;
|
||||
if (hw_direct_map) {
|
||||
va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
|
||||
bzero((caddr_t)va + off, size);
|
||||
} else {
|
||||
mtx_lock(&zero_page_mutex);
|
||||
va = zero_page_va;
|
||||
|
||||
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m));
|
||||
bzero((caddr_t)va + off, size);
|
||||
mmu_booke_kremove(mmu, va);
|
||||
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m));
|
||||
bzero((caddr_t)va + off, size);
|
||||
mmu_booke_kremove(mmu, va);
|
||||
|
||||
mtx_unlock(&zero_page_mutex);
|
||||
mtx_unlock(&zero_page_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2991,15 +2996,23 @@ mmu_booke_zero_page(mmu_t mmu, vm_page_t m)
|
||||
{
|
||||
vm_offset_t off, va;
|
||||
|
||||
mtx_lock(&zero_page_mutex);
|
||||
va = zero_page_va;
|
||||
if (hw_direct_map) {
|
||||
va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
|
||||
} else {
|
||||
va = zero_page_va;
|
||||
mtx_lock(&zero_page_mutex);
|
||||
|
||||
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m));
|
||||
}
|
||||
|
||||
mmu_booke_kenter(mmu, va, VM_PAGE_TO_PHYS(m));
|
||||
for (off = 0; off < PAGE_SIZE; off += cacheline_size)
|
||||
__asm __volatile("dcbz 0,%0" :: "r"(va + off));
|
||||
mmu_booke_kremove(mmu, va);
|
||||
|
||||
mtx_unlock(&zero_page_mutex);
|
||||
if (!hw_direct_map) {
|
||||
mmu_booke_kremove(mmu, va);
|
||||
|
||||
mtx_unlock(&zero_page_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3015,13 +3028,20 @@ mmu_booke_copy_page(mmu_t mmu, vm_page_t sm, vm_page_t dm)
|
||||
sva = copy_page_src_va;
|
||||
dva = copy_page_dst_va;
|
||||
|
||||
mtx_lock(©_page_mutex);
|
||||
mmu_booke_kenter(mmu, sva, VM_PAGE_TO_PHYS(sm));
|
||||
mmu_booke_kenter(mmu, dva, VM_PAGE_TO_PHYS(dm));
|
||||
if (hw_direct_map) {
|
||||
sva = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(sm));
|
||||
dva = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dm));
|
||||
} else {
|
||||
mtx_lock(©_page_mutex);
|
||||
mmu_booke_kenter(mmu, sva, VM_PAGE_TO_PHYS(sm));
|
||||
mmu_booke_kenter(mmu, dva, VM_PAGE_TO_PHYS(dm));
|
||||
}
|
||||
memcpy((caddr_t)dva, (caddr_t)sva, PAGE_SIZE);
|
||||
mmu_booke_kremove(mmu, dva);
|
||||
mmu_booke_kremove(mmu, sva);
|
||||
mtx_unlock(©_page_mutex);
|
||||
if (!hw_direct_map) {
|
||||
mmu_booke_kremove(mmu, dva);
|
||||
mmu_booke_kremove(mmu, sva);
|
||||
mtx_unlock(©_page_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
@ -3032,26 +3052,34 @@ mmu_booke_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset,
|
||||
vm_offset_t a_pg_offset, b_pg_offset;
|
||||
int cnt;
|
||||
|
||||
mtx_lock(©_page_mutex);
|
||||
while (xfersize > 0) {
|
||||
a_pg_offset = a_offset & PAGE_MASK;
|
||||
cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
|
||||
mmu_booke_kenter(mmu, copy_page_src_va,
|
||||
VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT]));
|
||||
a_cp = (char *)copy_page_src_va + a_pg_offset;
|
||||
b_pg_offset = b_offset & PAGE_MASK;
|
||||
cnt = min(cnt, PAGE_SIZE - b_pg_offset);
|
||||
mmu_booke_kenter(mmu, copy_page_dst_va,
|
||||
VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT]));
|
||||
b_cp = (char *)copy_page_dst_va + b_pg_offset;
|
||||
bcopy(a_cp, b_cp, cnt);
|
||||
mmu_booke_kremove(mmu, copy_page_dst_va);
|
||||
mmu_booke_kremove(mmu, copy_page_src_va);
|
||||
a_offset += cnt;
|
||||
b_offset += cnt;
|
||||
xfersize -= cnt;
|
||||
if (hw_direct_map) {
|
||||
a_cp = (caddr_t)((uintptr_t)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(*ma)) +
|
||||
a_offset);
|
||||
b_cp = (caddr_t)((uintptr_t)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(*mb)) +
|
||||
b_offset);
|
||||
bcopy(a_cp, b_cp, xfersize);
|
||||
} else {
|
||||
mtx_lock(©_page_mutex);
|
||||
while (xfersize > 0) {
|
||||
a_pg_offset = a_offset & PAGE_MASK;
|
||||
cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
|
||||
mmu_booke_kenter(mmu, copy_page_src_va,
|
||||
VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT]));
|
||||
a_cp = (char *)copy_page_src_va + a_pg_offset;
|
||||
b_pg_offset = b_offset & PAGE_MASK;
|
||||
cnt = min(cnt, PAGE_SIZE - b_pg_offset);
|
||||
mmu_booke_kenter(mmu, copy_page_dst_va,
|
||||
VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT]));
|
||||
b_cp = (char *)copy_page_dst_va + b_pg_offset;
|
||||
bcopy(a_cp, b_cp, cnt);
|
||||
mmu_booke_kremove(mmu, copy_page_dst_va);
|
||||
mmu_booke_kremove(mmu, copy_page_src_va);
|
||||
a_offset += cnt;
|
||||
b_offset += cnt;
|
||||
xfersize -= cnt;
|
||||
}
|
||||
mtx_unlock(©_page_mutex);
|
||||
}
|
||||
mtx_unlock(©_page_mutex);
|
||||
}
|
||||
|
||||
static vm_offset_t
|
||||
@ -3064,6 +3092,9 @@ mmu_booke_quick_enter_page(mmu_t mmu, vm_page_t m)
|
||||
|
||||
paddr = VM_PAGE_TO_PHYS(m);
|
||||
|
||||
if (hw_direct_map)
|
||||
return (PHYS_TO_DMAP(paddr));
|
||||
|
||||
flags = PTE_SR | PTE_SW | PTE_SX | PTE_WIRED | PTE_VALID;
|
||||
flags |= tlb_calc_wimg(paddr, pmap_page_get_memattr(m)) << PTE_MAS2_SHIFT;
|
||||
flags |= PTE_PS_4KB;
|
||||
@ -3097,6 +3128,9 @@ mmu_booke_quick_remove_page(mmu_t mmu, vm_offset_t addr)
|
||||
{
|
||||
pte_t *pte;
|
||||
|
||||
if (hw_direct_map)
|
||||
return;
|
||||
|
||||
pte = pte_find(mmu, kernel_pmap, addr);
|
||||
|
||||
KASSERT(PCPU_GET(qmap_addr) == addr,
|
||||
@ -3880,29 +3914,23 @@ tlb1_write_entry_int(void *arg)
|
||||
mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(args->idx);
|
||||
|
||||
mtspr(SPR_MAS0, mas0);
|
||||
__asm __volatile("isync");
|
||||
mtspr(SPR_MAS1, args->e->mas1);
|
||||
__asm __volatile("isync");
|
||||
mtspr(SPR_MAS2, args->e->mas2);
|
||||
__asm __volatile("isync");
|
||||
mtspr(SPR_MAS3, args->e->mas3);
|
||||
__asm __volatile("isync");
|
||||
switch ((mfpvr() >> 16) & 0xFFFF) {
|
||||
case FSL_E500mc:
|
||||
case FSL_E5500:
|
||||
case FSL_E6500:
|
||||
mtspr(SPR_MAS8, 0);
|
||||
__asm __volatile("isync");
|
||||
/* FALLTHROUGH */
|
||||
case FSL_E500v2:
|
||||
mtspr(SPR_MAS7, args->e->mas7);
|
||||
__asm __volatile("isync");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
__asm __volatile("tlbwe; isync; msync");
|
||||
__asm __volatile("isync; tlbwe; isync; msync");
|
||||
|
||||
}
|
||||
|
||||
@ -4325,12 +4353,26 @@ tid_flush(tlbtid_t tid)
|
||||
msr = mfmsr();
|
||||
__asm __volatile("wrteei 0");
|
||||
|
||||
/*
|
||||
* Newer (e500mc and later) have tlbilx, which doesn't broadcast, so use
|
||||
* it for PID invalidation.
|
||||
*/
|
||||
switch ((mfpvr() >> 16) & 0xffff) {
|
||||
case FSL_E500mc:
|
||||
case FSL_E5500:
|
||||
case FSL_E6500:
|
||||
mtspr(SPR_MAS6, tid << MAS6_SPID0_SHIFT);
|
||||
/* tlbilxpid */
|
||||
__asm __volatile("isync; .long 0x7c000024; isync; msync");
|
||||
mtmsr(msr);
|
||||
return;
|
||||
}
|
||||
|
||||
for (way = 0; way < TLB0_WAYS; way++)
|
||||
for (entry = 0; entry < TLB0_ENTRIES_PER_WAY; entry++) {
|
||||
|
||||
mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way);
|
||||
mtspr(SPR_MAS0, mas0);
|
||||
__asm __volatile("isync");
|
||||
|
||||
mas2 = entry << MAS2_TLB0_ENTRY_IDX_SHIFT;
|
||||
mtspr(SPR_MAS2, mas2);
|
||||
@ -4407,7 +4449,6 @@ DB_SHOW_COMMAND(tlb0, tlb0_print_tlbentries)
|
||||
|
||||
mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(way);
|
||||
mtspr(SPR_MAS0, mas0);
|
||||
__asm __volatile("isync");
|
||||
|
||||
mas2 = entryidx << MAS2_TLB0_ENTRY_IDX_SHIFT;
|
||||
mtspr(SPR_MAS2, mas2);
|
||||
|
@ -115,7 +115,7 @@ struct sysentvec elf32_freebsd_sysvec = {
|
||||
.sv_fixlimit = NULL,
|
||||
#endif
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_ILP32 | SV_SHP,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_shared_page_base = FREEBSD32_SHAREDPAGE,
|
||||
|
@ -79,7 +79,7 @@ struct sysentvec elf64_freebsd_sysvec_v1 = {
|
||||
.sv_setregs = exec_setregs_funcdesc,
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_SHP,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_syscallnames = syscallnames,
|
||||
|
@ -474,6 +474,10 @@ set_mcontext(struct thread *td, mcontext_t *mcp)
|
||||
else
|
||||
tf->fixreg[2] = tls;
|
||||
|
||||
/* Disable FPU */
|
||||
tf->srr1 &= ~PSL_FP;
|
||||
pcb->pcb_flags &= ~PCB_FPU;
|
||||
|
||||
if (mcp->mc_flags & _MC_FP_VALID) {
|
||||
/* enable_fpu() will happen lazily on a fault */
|
||||
pcb->pcb_flags |= PCB_FPREGS;
|
||||
|
@ -82,7 +82,7 @@
|
||||
#define PAGE_SIZE (1 << PAGE_SHIFT) /* Page size */
|
||||
#define PAGE_MASK (PAGE_SIZE - 1)
|
||||
|
||||
#define MAXPAGESIZES 1 /* maximum number of supported page sizes */
|
||||
#define MAXPAGESIZES 3 /* maximum number of supported page sizes */
|
||||
|
||||
#ifndef KSTACK_PAGES
|
||||
#define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */
|
||||
|
@ -55,7 +55,6 @@ struct pcb {
|
||||
#define PCB_FP_STARTED 0x1
|
||||
#define PCB_FP_USERMASK 0x1
|
||||
uint64_t pcb_sepc; /* Supervisor exception pc */
|
||||
vm_offset_t pcb_l1addr; /* L1 page tables base address */
|
||||
vm_offset_t pcb_onfault; /* Copyinout fault handler */
|
||||
};
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define ALT_STACK_SIZE 128
|
||||
|
||||
#define PCPU_MD_FIELDS \
|
||||
struct pmap *pc_curpmap; /* Currently active pmap */ \
|
||||
uint32_t pc_pending_ipis; /* IPIs pending to this CPU */ \
|
||||
char __pad[61]
|
||||
|
||||
|
@ -41,9 +41,12 @@
|
||||
#ifndef LOCORE
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include <sys/_cpuset.h>
|
||||
#include <sys/_lock.h>
|
||||
#include <sys/_mutex.h>
|
||||
|
||||
#include <vm/_vm_radix.h>
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#define vtophys(va) pmap_kextract((vm_offset_t)(va))
|
||||
@ -78,8 +81,11 @@ struct pmap {
|
||||
struct mtx pm_mtx;
|
||||
struct pmap_statistics pm_stats; /* pmap statictics */
|
||||
pd_entry_t *pm_l1;
|
||||
u_long pm_satp; /* value for SATP register */
|
||||
cpuset_t pm_active; /* active on cpus */
|
||||
TAILQ_HEAD(,pv_chunk) pm_pvchunk; /* list of mappings in pmap */
|
||||
LIST_ENTRY(pmap) pm_list; /* List of all pmaps */
|
||||
struct vm_radix pm_root;
|
||||
};
|
||||
|
||||
typedef struct pv_entry {
|
||||
@ -134,11 +140,16 @@ extern vm_offset_t virtual_end;
|
||||
#define L1_MAPPABLE_P(va, pa, size) \
|
||||
((((va) | (pa)) & L1_OFFSET) == 0 && (size) >= L1_SIZE)
|
||||
|
||||
struct thread;
|
||||
|
||||
void pmap_activate_boot(pmap_t);
|
||||
void pmap_activate_sw(struct thread *);
|
||||
void pmap_bootstrap(vm_offset_t, vm_paddr_t, vm_size_t);
|
||||
void pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
|
||||
vm_paddr_t pmap_kextract(vm_offset_t va);
|
||||
void pmap_kremove(vm_offset_t);
|
||||
void pmap_kremove_device(vm_offset_t, vm_size_t);
|
||||
bool pmap_ps_enabled(pmap_t);
|
||||
|
||||
void *pmap_mapdev(vm_offset_t, vm_size_t);
|
||||
void *pmap_mapbios(vm_paddr_t, vm_size_t);
|
||||
|
@ -62,7 +62,8 @@ typedef uint64_t pn_t; /* page number */
|
||||
#define L3_SIZE (1 << L3_SHIFT)
|
||||
#define L3_OFFSET (L3_SIZE - 1)
|
||||
|
||||
#define Ln_ENTRIES (1 << 9)
|
||||
#define Ln_ENTRIES_SHIFT 9
|
||||
#define Ln_ENTRIES (1 << Ln_ENTRIES_SHIFT)
|
||||
#define Ln_ADDR_MASK (Ln_ENTRIES - 1)
|
||||
|
||||
/* Bits 9:8 are reserved for software */
|
||||
@ -79,6 +80,8 @@ typedef uint64_t pn_t; /* page number */
|
||||
#define PTE_RWX (PTE_R | PTE_W | PTE_X)
|
||||
#define PTE_RX (PTE_R | PTE_X)
|
||||
#define PTE_KERN (PTE_V | PTE_R | PTE_W | PTE_A | PTE_D)
|
||||
#define PTE_PROMOTE (PTE_V | PTE_RWX | PTE_D | PTE_A | PTE_G | PTE_U | \
|
||||
PTE_SW_MANAGED | PTE_SW_WIRED)
|
||||
|
||||
#define PTE_PPN0_S 10
|
||||
#define PTE_PPN1_S 19
|
||||
|
@ -99,10 +99,10 @@
|
||||
#define VM_NFREEORDER 12
|
||||
|
||||
/*
|
||||
* Disable superpage reservations.
|
||||
* Enable superpage reservations: 1 level.
|
||||
*/
|
||||
#ifndef VM_NRESERVLEVEL
|
||||
#define VM_NRESERVLEVEL 0
|
||||
#define VM_NRESERVLEVEL 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -82,7 +82,7 @@ struct sysentvec elf64_freebsd_sysvec = {
|
||||
.sv_setregs = exec_setregs,
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_SHP,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64 | SV_SHP | SV_ASLR,
|
||||
.sv_set_syscall_retval = cpu_set_syscall_retval,
|
||||
.sv_fetch_syscall_args = cpu_fetch_syscall_args,
|
||||
.sv_syscallnames = syscallnames,
|
||||
|
@ -63,7 +63,6 @@ ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
|
||||
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
|
||||
|
||||
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
||||
ASSYM(PCB_L1ADDR, offsetof(struct pcb, pcb_l1addr));
|
||||
ASSYM(PCB_SIZE, sizeof(struct pcb));
|
||||
ASSYM(PCB_RA, offsetof(struct pcb, pcb_ra));
|
||||
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user