MFhead @ r304232

This commit is contained in:
Enji Cooper 2016-08-16 18:32:01 +00:00
commit 532c3cde6a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/netbsd-tests-update-12/; revision=304233
144 changed files with 3161 additions and 3173 deletions

View File

@ -1581,10 +1581,6 @@ _groff= gnu/usr.bin/groff \
_vtfontcvt= usr.bin/vtfontcvt
.endif
.if ${BOOTSTRAPPING} < 900002
_sed= usr.bin/sed
.endif
.if ${BOOTSTRAPPING} < 1000033
_libopenbsd= lib/libopenbsd
_m4= usr.bin/m4
@ -1623,10 +1619,6 @@ _crunchide= usr.sbin/crunch/crunchide
_crunchgen= usr.sbin/crunch/crunchgen
.endif
.if ${BOOTSTRAPPING} >= 900040 && ${BOOTSTRAPPING} < 900041
_awk= usr.bin/awk
.endif
# r296926 -P keymap search path, MFC to stable/10 in r298297
.if ${BOOTSTRAPPING} < 1003501 || \
(${BOOTSTRAPPING} >= 1100000 && ${BOOTSTRAPPING} < 1100103)
@ -1694,7 +1686,6 @@ bootstrap-tools: .PHONY
${_gperf} \
${_groff} \
${_dtc} \
${_awk} \
${_cat} \
${_dd} \
${_kbdcontrol} \
@ -1702,7 +1693,6 @@ bootstrap-tools: .PHONY
${_libopenbsd} \
${_makewhatis} \
usr.bin/rpcgen \
${_sed} \
${_yacc} \
${_m4} \
${_lex} \

View File

@ -38,6 +38,8 @@
# xargs -n1 | sort | uniq -d;
# done
# 20160815: Remove mcd(4)
OLD_FILES+=usr/share/man/man4/mcd.4.gz
# 20160703: POSIXify locales with variants
OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_COLLATE
OLD_FILES+=usr/share/locale/zh_Hant_TW.UTF-8/LC_CTYPE

View File

@ -25,6 +25,10 @@
# Use is subject to license terms.
#
#
# Copyright (c) 2014, 2016 by Delphix. All rights reserved.
#
require 5.8.4;
$PNAME = $0;
@ -131,7 +135,8 @@ sub dstyle
}
if (!/^enum/ && !/^\t*struct/ && !/^\t*union/ && !/^typedef/ &&
!/^translator/ && !/^provider/) {
!/^translator/ && !/^provider/ && !/\tif / &&
!/ else /) {
if (/[\w\s]+{/) {
err "left brace not on its own line";
}
@ -141,7 +146,7 @@ sub dstyle
}
}
if (!/;$/) {
if (!/;$/ && !/\t*}$/ && !/ else /) {
if (/[\w\s]+}/) {
err "right brace not on its own line";
}

View File

@ -0,0 +1,32 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2016, Joyent, Inc. All rights reserved.
*/
#pragma D option strsize=16k
char *k;
BEGIN
{
j = probeprov;
k = j;
k[0] = 'D';
k[1] = 'T';
}
BEGIN
{
trace(stringof(k));
exit(k == "DTrace" ? 0 : 1);
}

View File

@ -0,0 +1,29 @@
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
* Copyright (c) 2016, Joyent, Inc. All rights reserved.
*/
#pragma D option strsize=16k
BEGIN
{
this->j = probeprov;
this->j[0] = 'D';
this->j[1] = 'T';
}
BEGIN
{
trace(this->j);
exit(this->j == "DTrace" ? 0 : 1);
}

View File

@ -0,0 +1,33 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* "else" statement is executed
*/
BEGIN
{
if (0) {
n = 1;
} else {
n = 0;
}
exit(n)
}

View File

@ -0,0 +1,33 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* "if" statement executes the correct body.
*/
BEGIN
{
if (1) {
n = 0;
} else {
n = 1;
}
exit(n)
}

View File

@ -0,0 +1,33 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* "if" statement executes the correct body.
* parses single-statement, braceless bodies correctly.
*/
BEGIN
{
if (1)
n = 0;
else
n = 1;
exit(n)
}

View File

@ -0,0 +1,46 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* statements before and after an if statement are executed.
*/
BEGIN
{
i = 1;
if (1) {
i++;
} else {
i++;
}
i++;
}
BEGIN
/i == 3/
{
exit(0);
}
BEGIN
/i != 3/
{
exit(1);
}

View File

@ -0,0 +1,38 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* nested "if" statement executes the correct body.
*/
BEGIN
{
if (0) {
exit(1);
} else {
if (0) {
exit(1);
} else {
exit(0);
}
exit(1);
}
exit(1);
}

View File

@ -0,0 +1,30 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* "if" body without trailing semicolon parses correctly
*/
BEGIN
{
if (1) {
exit(0)
}
}

View File

@ -0,0 +1,31 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
*/
/*
* ASSERTION:
* "if" body without trailing semicolon parses correctly
*/
BEGIN
{
if (1) {
i = 1;
exit(0)
}
}

View File

@ -21,8 +21,9 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013, Joyent Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2015 Gary Mills
*/
/*
@ -119,7 +120,6 @@ static const dtrace_diftype_t dt_int_rtype = {
static void *dt_compile(dtrace_hdl_t *, int, dtrace_probespec_t, void *,
uint_t, int, char *const[], FILE *, const char *);
/*ARGSUSED*/
static int
dt_idreset(dt_idhash_t *dhp, dt_ident_t *idp, void *ignored)
@ -2435,7 +2435,7 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
dt_node_t *dnp;
dt_decl_t *ddp;
dt_pcb_t pcb;
void *rv;
void *volatile rv;
int err;
if ((fp == NULL && s == NULL) || (cflags & ~DTRACE_C_MASK) != 0) {
@ -2517,6 +2517,28 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
"not referenced)\n", yypcb->pcb_sargv[argc - 1], argc - 1);
}
/*
* Perform sugar transformations (for "if" / "else") and replace the
* existing clause chain with the new one.
*/
if (context == DT_CTX_DPROG) {
dt_node_t *dnp, *next_dnp;
dt_node_t *new_list = NULL;
for (dnp = yypcb->pcb_root->dn_list;
dnp != NULL; dnp = next_dnp) {
/* remove this node from the list */
next_dnp = dnp->dn_list;
dnp->dn_list = NULL;
if (dnp->dn_kind == DT_NODE_CLAUSE)
dnp = dt_compile_sugar(dtp, dnp);
/* append node to the new list */
new_list = dt_node_link(new_list, dnp);
}
yypcb->pcb_root->dn_list = new_list;
}
/*
* If we have successfully created a parse tree for a D program, loop
* over the clauses and actions and instantiate the corresponding
@ -2537,6 +2559,8 @@ dt_compile(dtrace_hdl_t *dtp, int context, dtrace_probespec_t pspec, void *arg,
for (; dnp != NULL; dnp = dnp->dn_list) {
switch (dnp->dn_kind) {
case DT_NODE_CLAUSE:
if (DT_TREEDUMP_PASS(dtp, 4))
dt_printd(dnp, stderr, 0);
dt_compile_clause(dtp, dnp);
break;
case DT_NODE_XLATOR:

View File

@ -23,8 +23,9 @@
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
@ -155,6 +156,8 @@
%type <l_node> probe_specifier_list
%type <l_node> probe_specifier
%type <l_node> statement_list
%type <l_node> statement_list_impl
%type <l_node> statement_or_block
%type <l_node> statement
%type <l_node> declaration
%type <l_node> init_declarator_list
@ -319,9 +322,11 @@ probe_definition:
"or actions following probe description\n");
}
$$ = dt_node_clause($1, NULL, NULL);
yybegin(YYS_CLAUSE);
}
| probe_specifiers '{' statement_list '}' {
$$ = dt_node_clause($1, NULL, $3);
yybegin(YYS_CLAUSE);
}
| probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED {
dnerror($3, D_SYNTAX, "expected actions { } following "
@ -330,6 +335,7 @@ probe_definition:
| probe_specifiers DT_TOK_DIV expression DT_TOK_EPRED
'{' statement_list '}' {
$$ = dt_node_clause($1, $3, $6);
yybegin(YYS_CLAUSE);
}
;
@ -349,12 +355,30 @@ probe_specifier:
| DT_TOK_INT { $$ = dt_node_pdesc_by_id($1); }
;
statement_list: statement { $$ = $1; }
| statement_list ';' statement { $$ = LINK($1, $3); }
statement_list_impl: /* empty */ { $$ = NULL; }
| statement_list_impl statement { $$ = LINK($1, $2); }
;
statement: /* empty */ { $$ = NULL; }
| expression { $$ = dt_node_statement($1); }
statement_list:
statement_list_impl { $$ = $1; }
| statement_list_impl expression {
$$ = LINK($1, dt_node_statement($2));
}
;
statement_or_block:
statement
| '{' statement_list '}' { $$ = $2; }
statement: ';' { $$ = NULL; }
| expression ';' { $$ = dt_node_statement($1); }
| DT_KEY_IF DT_TOK_LPAR expression DT_TOK_RPAR statement_or_block {
$$ = dt_node_if($3, $5, NULL);
}
| DT_KEY_IF DT_TOK_LPAR expression DT_TOK_RPAR
statement_or_block DT_KEY_ELSE statement_or_block {
$$ = dt_node_if($3, $5, $7);
}
;
argument_expression_list:

View File

@ -26,7 +26,7 @@
/*
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2011, 2016 by Delphix. All rights reserved.
*/
#ifndef _DT_IMPL_H
@ -362,6 +362,7 @@ struct dtrace_hdl {
int dt_indent; /* recommended flow indent */
dtrace_epid_t dt_last_epid; /* most recently consumed EPID */
uint64_t dt_last_timestamp; /* most recently consumed timestamp */
boolean_t dt_has_sugar; /* syntactic sugar used? */
};
/*

View File

@ -22,7 +22,7 @@
/*
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
#include <sys/types.h>
@ -130,8 +130,9 @@
#define DT_VERS_1_11 DT_VERSION_NUMBER(1, 11, 0)
#define DT_VERS_1_12 DT_VERSION_NUMBER(1, 12, 0)
#define DT_VERS_1_12_1 DT_VERSION_NUMBER(1, 12, 1)
#define DT_VERS_LATEST DT_VERS_1_12_1
#define DT_VERS_STRING "Sun D 1.12.1"
#define DT_VERS_1_13 DT_VERSION_NUMBER(1, 13, 0)
#define DT_VERS_LATEST DT_VERS_1_13
#define DT_VERS_STRING "Sun D 1.13"
const dt_version_t _dtrace_versions[] = {
DT_VERS_1_0, /* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@ -157,6 +158,7 @@ const dt_version_t _dtrace_versions[] = {
DT_VERS_1_11, /* D API 1.11 */
DT_VERS_1_12, /* D API 1.12 */
DT_VERS_1_12_1, /* D API 1.12.1 */
DT_VERS_1_13, /* D API 1.13 */
0
};

View File

@ -23,7 +23,7 @@
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2013, Joyent Inc. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@ -2142,6 +2142,17 @@ dt_node_statement(dt_node_t *expr)
return (dnp);
}
dt_node_t *
dt_node_if(dt_node_t *pred, dt_node_t *acts, dt_node_t *else_acts)
{
dt_node_t *dnp = dt_node_alloc(DT_NODE_IF);
dnp->dn_conditional = pred;
dnp->dn_body = acts;
dnp->dn_alternate_body = else_acts;
return (dnp);
}
dt_node_t *
dt_node_pdesc_by_name(char *spec)
{
@ -2211,7 +2222,6 @@ dt_node_clause(dt_node_t *pdescs, dt_node_t *pred, dt_node_t *acts)
dnp->dn_pred = pred;
dnp->dn_acts = acts;
yybegin(YYS_CLAUSE);
return (dnp);
}
@ -3203,8 +3213,9 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
dt_xcook_ident(lp, dhp, idkind, B_TRUE);
else
dt_xcook_ident(lp, dhp, idp->di_kind, B_FALSE);
} else
} else {
lp = dnp->dn_left = dt_node_cook(lp, 0);
}
/*
* Switch op to '+' for *(E1 + E2) array mode in these cases:
@ -3218,10 +3229,12 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
if (lp->dn_ident->di_kind == DT_IDENT_ARRAY) {
if (lp->dn_args != NULL)
op = DT_TOK_ADD;
} else if (!dt_ident_unref(lp->dn_ident))
} else if (!dt_ident_unref(lp->dn_ident)) {
op = DT_TOK_ADD;
} else if (lp->dn_kind != DT_NODE_AGG)
}
} else if (lp->dn_kind != DT_NODE_AGG) {
op = DT_TOK_ADD;
}
}
switch (op) {
@ -3645,45 +3658,34 @@ dt_cook_op2(dt_node_t *dnp, uint_t idflags)
case DT_TOK_PTR:
/*
* If the left-hand side of operator -> is the name "self",
* then we permit a TLS variable to be created or referenced.
* If the left-hand side of operator -> is one of the scoping
* keywords, permit a local or thread variable to be created or
* referenced.
*/
if (lp->dn_kind == DT_NODE_IDENT &&
strcmp(lp->dn_string, "self") == 0) {
if (rp->dn_kind != DT_NODE_VAR) {
dt_xcook_ident(rp, dtp->dt_tls,
DT_IDENT_SCALAR, B_TRUE);
if (lp->dn_kind == DT_NODE_IDENT) {
dt_idhash_t *dhp = NULL;
if (strcmp(lp->dn_string, "self") == 0) {
dhp = dtp->dt_tls;
} else if (strcmp(lp->dn_string, "this") == 0) {
dhp = yypcb->pcb_locals;
}
if (dhp != NULL) {
if (rp->dn_kind != DT_NODE_VAR) {
dt_xcook_ident(rp, dhp,
DT_IDENT_SCALAR, B_TRUE);
}
if (idflags != 0)
rp = dt_node_cook(rp, idflags);
if (idflags != 0)
rp = dt_node_cook(rp, idflags);
dnp->dn_right = dnp->dn_left; /* avoid freeing rp */
dt_node_free(dnp);
return (rp);
}
/*
* If the left-hand side of operator -> is the name "this",
* then we permit a local variable to be created or referenced.
*/
if (lp->dn_kind == DT_NODE_IDENT &&
strcmp(lp->dn_string, "this") == 0) {
if (rp->dn_kind != DT_NODE_VAR) {
dt_xcook_ident(rp, yypcb->pcb_locals,
DT_IDENT_SCALAR, B_TRUE);
/* avoid freeing rp */
dnp->dn_right = dnp->dn_left;
dt_node_free(dnp);
return (rp);
}
if (idflags != 0)
rp = dt_node_cook(rp, idflags);
dnp->dn_right = dnp->dn_left; /* avoid freeing rp */
dt_node_free(dnp);
return (rp);
}
/*FALLTHRU*/
case DT_TOK_DOT:
lp = dnp->dn_left = dt_node_cook(lp, DT_IDFLG_REF);
@ -4502,7 +4504,8 @@ static dt_node_t *(*dt_cook_funcs[])(dt_node_t *, uint_t) = {
dt_cook_xlator, /* DT_NODE_XLATOR */
dt_cook_none, /* DT_NODE_PROBE */
dt_cook_provider, /* DT_NODE_PROVIDER */
dt_cook_none /* DT_NODE_PROG */
dt_cook_none, /* DT_NODE_PROG */
dt_cook_none, /* DT_NODE_IF */
};
/*
@ -4517,6 +4520,8 @@ dt_node_cook(dt_node_t *dnp, uint_t idflags)
yylineno = dnp->dn_line;
assert(dnp->dn_kind <
sizeof (dt_cook_funcs) / sizeof (dt_cook_funcs[0]));
dnp = dt_cook_funcs[dnp->dn_kind](dnp, idflags);
dnp->dn_flags |= DT_NF_COOKED;
@ -4619,6 +4624,181 @@ dt_node_diftype(dtrace_hdl_t *dtp, const dt_node_t *dnp, dtrace_diftype_t *tp)
tp->dtdt_size = ctf_type_size(dnp->dn_ctfp, dnp->dn_type);
}
/*
* Output the parse tree as D. The "-xtree=8" argument will call this
* function to print out the program after any syntactic sugar
* transformations have been applied (e.g. to implement "if"). The
* resulting output can be used to understand the transformations
* applied by these features, or to run such a script on a system that
* does not support these features
*
* Note that the output does not express precisely the same program as
* the input. In particular:
* - Only the clauses are output. #pragma options, variable
* declarations, etc. are excluded.
* - Command argument substitution has already been done, so the output
* will not contain e.g. $$1, but rather the substituted string.
*/
void
dt_printd(dt_node_t *dnp, FILE *fp, int depth)
{
dt_node_t *arg;
switch (dnp->dn_kind) {
case DT_NODE_INT:
(void) fprintf(fp, "0x%llx", (u_longlong_t)dnp->dn_value);
if (!(dnp->dn_flags & DT_NF_SIGNED))
(void) fprintf(fp, "u");
break;
case DT_NODE_STRING: {
char *escd = strchr2esc(dnp->dn_string, strlen(dnp->dn_string));
(void) fprintf(fp, "\"%s\"", escd);
free(escd);
break;
}
case DT_NODE_IDENT:
(void) fprintf(fp, "%s", dnp->dn_string);
break;
case DT_NODE_VAR:
(void) fprintf(fp, "%s%s",
(dnp->dn_ident->di_flags & DT_IDFLG_LOCAL) ? "this->" :
(dnp->dn_ident->di_flags & DT_IDFLG_TLS) ? "self->" : "",
dnp->dn_ident->di_name);
if (dnp->dn_args != NULL) {
(void) fprintf(fp, "[");
for (arg = dnp->dn_args; arg != NULL;
arg = arg->dn_list) {
dt_printd(arg, fp, 0);
if (arg->dn_list != NULL)
(void) fprintf(fp, ", ");
}
(void) fprintf(fp, "]");
}
break;
case DT_NODE_SYM: {
const dtrace_syminfo_t *dts = dnp->dn_ident->di_data;
(void) fprintf(fp, "%s`%s", dts->dts_object, dts->dts_name);
break;
}
case DT_NODE_FUNC:
(void) fprintf(fp, "%s(", dnp->dn_ident->di_name);
for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list) {
dt_printd(arg, fp, 0);
if (arg->dn_list != NULL)
(void) fprintf(fp, ", ");
}
(void) fprintf(fp, ")");
break;
case DT_NODE_OP1:
(void) fprintf(fp, "%s(", opstr(dnp->dn_op));
dt_printd(dnp->dn_child, fp, 0);
(void) fprintf(fp, ")");
break;
case DT_NODE_OP2:
(void) fprintf(fp, "(");
dt_printd(dnp->dn_left, fp, 0);
if (dnp->dn_op == DT_TOK_LPAR) {
(void) fprintf(fp, ")");
dt_printd(dnp->dn_right, fp, 0);
break;
}
if (dnp->dn_op == DT_TOK_PTR || dnp->dn_op == DT_TOK_DOT ||
dnp->dn_op == DT_TOK_LBRAC)
(void) fprintf(fp, "%s", opstr(dnp->dn_op));
else
(void) fprintf(fp, " %s ", opstr(dnp->dn_op));
dt_printd(dnp->dn_right, fp, 0);
if (dnp->dn_op == DT_TOK_LBRAC) {
dt_node_t *ln = dnp->dn_right;
while (ln->dn_list != NULL) {
(void) fprintf(fp, ", ");
dt_printd(ln->dn_list, fp, depth);
ln = ln->dn_list;
}
(void) fprintf(fp, "]");
}
(void) fprintf(fp, ")");
break;
case DT_NODE_OP3:
(void) fprintf(fp, "(");
dt_printd(dnp->dn_expr, fp, 0);
(void) fprintf(fp, " ? ");
dt_printd(dnp->dn_left, fp, 0);
(void) fprintf(fp, " : ");
dt_printd(dnp->dn_right, fp, 0);
(void) fprintf(fp, ")");
break;
case DT_NODE_DEXPR:
case DT_NODE_DFUNC:
(void) fprintf(fp, "%*s", depth * 8, "");
dt_printd(dnp->dn_expr, fp, depth + 1);
(void) fprintf(fp, ";\n");
break;
case DT_NODE_PDESC:
(void) fprintf(fp, "%s:%s:%s:%s",
dnp->dn_desc->dtpd_provider, dnp->dn_desc->dtpd_mod,
dnp->dn_desc->dtpd_func, dnp->dn_desc->dtpd_name);
break;
case DT_NODE_CLAUSE:
for (arg = dnp->dn_pdescs; arg != NULL; arg = arg->dn_list) {
dt_printd(arg, fp, 0);
if (arg->dn_list != NULL)
(void) fprintf(fp, ",");
(void) fprintf(fp, "\n");
}
if (dnp->dn_pred != NULL) {
(void) fprintf(fp, "/");
dt_printd(dnp->dn_pred, fp, 0);
(void) fprintf(fp, "/\n");
}
(void) fprintf(fp, "{\n");
for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
dt_printd(arg, fp, depth + 1);
(void) fprintf(fp, "}\n");
(void) fprintf(fp, "\n");
break;
case DT_NODE_IF:
(void) fprintf(fp, "%*sif (", depth * 8, "");
dt_printd(dnp->dn_conditional, fp, 0);
(void) fprintf(fp, ") {\n");
for (arg = dnp->dn_body; arg != NULL; arg = arg->dn_list)
dt_printd(arg, fp, depth + 1);
if (dnp->dn_alternate_body == NULL) {
(void) fprintf(fp, "%*s}\n", depth * 8, "");
} else {
(void) fprintf(fp, "%*s} else {\n", depth * 8, "");
for (arg = dnp->dn_alternate_body; arg != NULL;
arg = arg->dn_list)
dt_printd(arg, fp, depth + 1);
(void) fprintf(fp, "%*s}\n", depth * 8, "");
}
break;
default:
(void) fprintf(fp, "/* bad node %p, kind %d */\n",
(void *)dnp, dnp->dn_kind);
}
}
void
dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
{
@ -4729,6 +4909,13 @@ dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
(void) fprintf(fp, "OP2 %s (%s)\n", opstr(dnp->dn_op), buf);
dt_node_printr(dnp->dn_left, fp, depth + 1);
dt_node_printr(dnp->dn_right, fp, depth + 1);
if (dnp->dn_op == DT_TOK_LBRAC) {
dt_node_t *ln = dnp->dn_right;
while (ln->dn_list != NULL) {
dt_node_printr(ln->dn_list, fp, depth + 1);
ln = ln->dn_list;
}
}
break;
case DT_NODE_OP3:
@ -4790,6 +4977,7 @@ dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
dt_node_printr(arg, fp, depth + 1);
(void) fprintf(fp, "\n");
break;
case DT_NODE_INLINE:
@ -4840,6 +5028,24 @@ dt_node_printr(dt_node_t *dnp, FILE *fp, int depth)
dt_node_printr(arg, fp, depth + 1);
break;
case DT_NODE_IF:
(void) fprintf(fp, "IF attr=%s CONDITION:\n", a);
dt_node_printr(dnp->dn_conditional, fp, depth + 1);
(void) fprintf(fp, "%*sIF BODY: \n", depth * 2, "");
for (arg = dnp->dn_body; arg != NULL; arg = arg->dn_list)
dt_node_printr(arg, fp, depth + 1);
if (dnp->dn_alternate_body != NULL) {
(void) fprintf(fp, "%*sIF ELSE: \n", depth * 2, "");
for (arg = dnp->dn_alternate_body; arg != NULL;
arg = arg->dn_list)
dt_node_printr(arg, fp, depth + 1);
}
break;
default:
(void) fprintf(fp, "<bad node %p, kind %d>\n",
(void *)dnp, dnp->dn_kind);

View File

@ -23,7 +23,7 @@
* Use is subject to license terms.
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2013, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013 Joyent, Inc. All rights reserved.
*/
@ -105,6 +105,12 @@ typedef struct dt_node {
struct dt_node *_probes; /* list of probe nodes */
int _redecl; /* provider redeclared */
} _provider;
struct {
struct dt_node *_conditional;
struct dt_node *_body;
struct dt_node *_alternate_body;
} _conditional;
} dn_u;
struct dt_node *dn_list; /* parse tree list link */
@ -140,6 +146,11 @@ typedef struct dt_node {
#define dn_provred dn_u._provider._redecl /* DT_NODE_PROVIDER */
#define dn_probes dn_u._provider._probes /* DT_NODE_PROVIDER */
/* DT_NODE_IF: */
#define dn_conditional dn_u._conditional._conditional
#define dn_body dn_u._conditional._body
#define dn_alternate_body dn_u._conditional._alternate_body
#define DT_NODE_FREE 0 /* unused node (waiting to be freed) */
#define DT_NODE_INT 1 /* integer value */
#define DT_NODE_STRING 2 /* string value */
@ -162,6 +173,7 @@ typedef struct dt_node {
#define DT_NODE_PROBE 19 /* probe definition */
#define DT_NODE_PROVIDER 20 /* provider definition */
#define DT_NODE_PROG 21 /* program translation unit */
#define DT_NODE_IF 22 /* if statement */
#define DT_NF_SIGNED 0x01 /* data is a signed quantity (else unsigned) */
#define DT_NF_COOKED 0x02 /* data is a known type (else still cooking) */
@ -213,6 +225,7 @@ extern dt_node_t *dt_node_xlator(dt_decl_t *, dt_decl_t *, char *, dt_node_t *);
extern dt_node_t *dt_node_probe(char *, int, dt_node_t *, dt_node_t *);
extern dt_node_t *dt_node_provider(char *, dt_node_t *);
extern dt_node_t *dt_node_program(dt_node_t *);
extern dt_node_t *dt_node_if(dt_node_t *, dt_node_t *, dt_node_t *);
extern dt_node_t *dt_node_link(dt_node_t *, dt_node_t *);
extern dt_node_t *dt_node_cook(dt_node_t *, uint_t);
@ -237,6 +250,7 @@ extern void dt_node_promote(dt_node_t *, dt_node_t *, dt_node_t *);
extern void dt_node_diftype(dtrace_hdl_t *,
const dt_node_t *, dtrace_diftype_t *);
extern void dt_node_printr(dt_node_t *, FILE *, int);
extern void dt_printd(dt_node_t *, FILE *, int);
extern const char *dt_node_name(const dt_node_t *, char *, size_t);
extern int dt_node_root(dt_node_t *);

View File

@ -0,0 +1,516 @@
/*
* CDDL HEADER START
*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms of version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2012, 2016 by Delphix. All rights reserved.
*/
/*
* Syntactic sugar features are implemented by transforming the D parse tree
* such that it only uses the subset of D that is supported by the rest of the
* compiler / the kernel. A clause containing these language features is
* referred to as a "super-clause", and its transformation typically entails
* creating several "sub-clauses" to implement it. For diagnosability, the
* sub-clauses will be printed if the "-xtree=8" flag is specified.
*
* Currently, the only syntactic sugar feature is "if/else" statements. Each
* basic block (e.g. the body of the "if" and "else" statements, and the
* statements before and after) is turned into its own sub-clause, with a
* predicate that causes it to be executed only if the code flows to this point.
* Nested if/else statements are supported.
*
* This infrastructure is designed to accommodate other syntactic sugar features
* in the future.
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/sysmacros.h>
#include <assert.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <dt_module.h>
#include <dt_program.h>
#include <dt_provider.h>
#include <dt_printf.h>
#include <dt_pid.h>
#include <dt_grammar.h>
#include <dt_ident.h>
#include <dt_string.h>
#include <dt_impl.h>
typedef struct dt_sugar_parse {
dtrace_hdl_t *dtsp_dtp; /* dtrace handle */
dt_node_t *dtsp_pdescs; /* probe descriptions */
int dtsp_num_conditions; /* number of condition variables */
int dtsp_num_ifs; /* number of "if" statements */
dt_node_t *dtsp_clause_list; /* list of clauses */
} dt_sugar_parse_t;
static void dt_sugar_visit_stmts(dt_sugar_parse_t *, dt_node_t *, int);
/*
* Return a node for "self->%error".
*
* Note that the "%" is part of the variable name, and is included so that
* this variable name can not collide with any user-specified variable.
*
* This error variable is used to keep track of if there has been an error
* in any of the sub-clauses, and is used to prevent execution of subsequent
* sub-clauses following an error.
*/
static dt_node_t *
dt_sugar_new_error_var(void)
{
return (dt_node_op2(DT_TOK_PTR, dt_node_ident(strdup("self")),
dt_node_ident(strdup("%error"))));
}
/*
* Append this clause to the clause list.
*/
static void
dt_sugar_append_clause(dt_sugar_parse_t *dp, dt_node_t *clause)
{
dp->dtsp_clause_list = dt_node_link(dp->dtsp_clause_list, clause);
}
/*
* Prepend this clause to the clause list.
*/
static void
dt_sugar_prepend_clause(dt_sugar_parse_t *dp, dt_node_t *clause)
{
dp->dtsp_clause_list = dt_node_link(clause, dp->dtsp_clause_list);
}
/*
* Return a node for "this->%condition_<condid>", or NULL if condid==0.
*
* Note that the "%" is part of the variable name, and is included so that
* this variable name can not collide with any user-specified variable.
*/
static dt_node_t *
dt_sugar_new_condition_var(int condid)
{
char *str;
if (condid == 0)
return (NULL);
assert(condid > 0);
(void) asprintf(&str, "%%condition_%d", ABS(condid));
return (dt_node_op2(DT_TOK_PTR, dt_node_ident(strdup("this")),
dt_node_ident(str)));
}
/*
* Return new clause to evaluate predicate and set newcond. condid is
* the condition that we are already under, or 0 if none.
* The new clause will be of the form:
*
* dp_pdescs
* /!self->%error/
* {
* this->%condition_<newcond> =
* (this->%condition_<condid> && pred);
* }
*
* Note: if condid==0, we will instead do "... = (1 && pred)", to effectively
* convert the pred to a boolean.
*
* Note: Unless an error has been encountered, we always set the condition
* variable (either to 0 or 1). This lets us avoid resetting the condition
* variables back to 0 when the super-clause completes.
*/
static dt_node_t *
dt_sugar_new_condition_impl(dt_sugar_parse_t *dp,
dt_node_t *pred, int condid, int newcond)
{
dt_node_t *value, *body, *newpred;
/* predicate is !self->%error */
newpred = dt_node_op1(DT_TOK_LNEG, dt_sugar_new_error_var());
if (condid == 0) {
/*
* value is (1 && pred)
*
* Note, D doesn't allow a probe-local "this" variable to
* be reused as a different type, even from a different probe.
* Therefore, value can't simply be <pred>, because then
* its type could be different when we reuse this condid
* in a different meta-clause.
*/
value = dt_node_op2(DT_TOK_LAND, dt_node_int(1), pred);
} else {
/* value is (this->%condition_<condid> && pred) */
value = dt_node_op2(DT_TOK_LAND,
dt_sugar_new_condition_var(condid), pred);
}
/* body is "this->%condition_<retval> = <value>;" */
body = dt_node_statement(dt_node_op2(DT_TOK_ASGN,
dt_sugar_new_condition_var(newcond), value));
return (dt_node_clause(dp->dtsp_pdescs, newpred, body));
}
/*
* Generate a new clause to evaluate predicate and set a new condition variable,
* whose ID will be returned. The new clause will be appended to
* dp_first_new_clause.
*/
static int
dt_sugar_new_condition(dt_sugar_parse_t *dp, dt_node_t *pred, int condid)
{
dp->dtsp_num_conditions++;
dt_sugar_append_clause(dp, dt_sugar_new_condition_impl(dp,
pred, condid, dp->dtsp_num_conditions));
return (dp->dtsp_num_conditions);
}
/*
* Visit the specified node and all of its descendants. Currently this is only
* used to count the number of "if" statements (dtsp_num_ifs).
*/
static void
dt_sugar_visit_all(dt_sugar_parse_t *dp, dt_node_t *dnp)
{
dt_node_t *arg;
switch (dnp->dn_kind) {
case DT_NODE_FREE:
case DT_NODE_INT:
case DT_NODE_STRING:
case DT_NODE_SYM:
case DT_NODE_TYPE:
case DT_NODE_PROBE:
case DT_NODE_PDESC:
case DT_NODE_IDENT:
break;
case DT_NODE_FUNC:
for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
break;
case DT_NODE_OP1:
dt_sugar_visit_all(dp, dnp->dn_child);
break;
case DT_NODE_OP2:
dt_sugar_visit_all(dp, dnp->dn_left);
dt_sugar_visit_all(dp, dnp->dn_right);
if (dnp->dn_op == DT_TOK_LBRAC) {
dt_node_t *ln = dnp->dn_right;
while (ln->dn_list != NULL) {
dt_sugar_visit_all(dp, ln->dn_list);
ln = ln->dn_list;
}
}
break;
case DT_NODE_OP3:
dt_sugar_visit_all(dp, dnp->dn_expr);
dt_sugar_visit_all(dp, dnp->dn_left);
dt_sugar_visit_all(dp, dnp->dn_right);
break;
case DT_NODE_DEXPR:
case DT_NODE_DFUNC:
dt_sugar_visit_all(dp, dnp->dn_expr);
break;
case DT_NODE_AGG:
for (arg = dnp->dn_aggtup; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
if (dnp->dn_aggfun)
dt_sugar_visit_all(dp, dnp->dn_aggfun);
break;
case DT_NODE_CLAUSE:
for (arg = dnp->dn_pdescs; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
if (dnp->dn_pred != NULL)
dt_sugar_visit_all(dp, dnp->dn_pred);
for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
break;
case DT_NODE_INLINE: {
const dt_idnode_t *inp = dnp->dn_ident->di_iarg;
dt_sugar_visit_all(dp, inp->din_root);
break;
}
case DT_NODE_MEMBER:
if (dnp->dn_membexpr)
dt_sugar_visit_all(dp, dnp->dn_membexpr);
break;
case DT_NODE_XLATOR:
for (arg = dnp->dn_members; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
break;
case DT_NODE_PROVIDER:
for (arg = dnp->dn_probes; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
break;
case DT_NODE_PROG:
for (arg = dnp->dn_list; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
break;
case DT_NODE_IF:
dp->dtsp_num_ifs++;
dt_sugar_visit_all(dp, dnp->dn_conditional);
for (arg = dnp->dn_body; arg != NULL; arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
for (arg = dnp->dn_alternate_body; arg != NULL;
arg = arg->dn_list)
dt_sugar_visit_all(dp, arg);
break;
default:
(void) dnerror(dnp, D_UNKNOWN, "bad node %p, kind %d\n",
(void *)dnp, dnp->dn_kind);
}
}
/*
* Return a new clause which resets the error variable to zero:
*
* dp_pdescs{ self->%error = 0; }
*
* This clause will be executed at the beginning of each meta-clause, to
* ensure the error variable is unset (in case the previous meta-clause
* failed).
*/
static dt_node_t *
dt_sugar_new_clearerror_clause(dt_sugar_parse_t *dp)
{
dt_node_t *stmt = dt_node_statement(dt_node_op2(DT_TOK_ASGN,
dt_sugar_new_error_var(), dt_node_int(0)));
return (dt_node_clause(dp->dtsp_pdescs, NULL, stmt));
}
/*
* Evaluate the conditional, and recursively visit the body of the "if"
* statement (and the "else", if present).
*/
static void
dt_sugar_do_if(dt_sugar_parse_t *dp, dt_node_t *if_stmt, int precondition)
{
int newid;
assert(if_stmt->dn_kind == DT_NODE_IF);
/* condition */
newid = dt_sugar_new_condition(dp,
if_stmt->dn_conditional, precondition);
/* body of if */
dt_sugar_visit_stmts(dp, if_stmt->dn_body, newid);
/*
* Visit the body of the "else" statement, if present. Note that we
* generate a new condition which is the inverse of the previous
* condition.
*/
if (if_stmt->dn_alternate_body != NULL) {
dt_node_t *pred =
dt_node_op1(DT_TOK_LNEG, dt_sugar_new_condition_var(newid));
dt_sugar_visit_stmts(dp, if_stmt->dn_alternate_body,
dt_sugar_new_condition(dp, pred, precondition));
}
}
/*
* Generate a new clause to evaluate the statements based on the condition.
* The new clause will be appended to dp_first_new_clause.
*
* dp_pdescs
* /!self->%error && this->%condition_<condid>/
* {
* stmts
* }
*/
static void
dt_sugar_new_basic_block(dt_sugar_parse_t *dp, int condid, dt_node_t *stmts)
{
dt_node_t *pred = NULL;
if (condid == 0) {
/*
* Don't bother with !error on the first clause, because if
* there is only one clause, we don't add the prelude to
* zero out %error.
*/
if (dp->dtsp_num_conditions != 0) {
pred = dt_node_op1(DT_TOK_LNEG,
dt_sugar_new_error_var());
}
} else {
pred = dt_node_op2(DT_TOK_LAND,
dt_node_op1(DT_TOK_LNEG, dt_sugar_new_error_var()),
dt_sugar_new_condition_var(condid));
}
dt_sugar_append_clause(dp,
dt_node_clause(dp->dtsp_pdescs, pred, stmts));
}
/*
* Visit all the statements in this list, and break them into basic blocks,
* generating new clauses for "if" and "else" statements.
*/
static void
dt_sugar_visit_stmts(dt_sugar_parse_t *dp, dt_node_t *stmts, int precondition)
{
dt_node_t *stmt;
dt_node_t *prev_stmt = NULL;
dt_node_t *next_stmt;
dt_node_t *first_stmt_in_basic_block = NULL;
for (stmt = stmts; stmt != NULL; stmt = next_stmt) {
next_stmt = stmt->dn_list;
if (stmt->dn_kind != DT_NODE_IF) {
if (first_stmt_in_basic_block == NULL)
first_stmt_in_basic_block = stmt;
prev_stmt = stmt;
continue;
}
/*
* Remove this and following statements from the previous
* clause.
*/
if (prev_stmt != NULL)
prev_stmt->dn_list = NULL;
/*
* Generate clause for statements preceding the "if"
*/
if (first_stmt_in_basic_block != NULL) {
dt_sugar_new_basic_block(dp, precondition,
first_stmt_in_basic_block);
}
dt_sugar_do_if(dp, stmt, precondition);
first_stmt_in_basic_block = NULL;
prev_stmt = stmt;
}
/* generate clause for statements after last "if". */
if (first_stmt_in_basic_block != NULL) {
dt_sugar_new_basic_block(dp, precondition,
first_stmt_in_basic_block);
}
}
/*
* Generate a new clause which will set the error variable when an error occurs.
* Only one of these clauses is created per program (e.g. script file).
* The clause is:
*
* dtrace:::ERROR{ self->%error = 1; }
*/
static dt_node_t *
dt_sugar_makeerrorclause(void)
{
dt_node_t *acts, *pdesc;
pdesc = dt_node_pdesc_by_name(strdup("dtrace:::ERROR"));
acts = dt_node_statement(dt_node_op2(DT_TOK_ASGN,
dt_sugar_new_error_var(), dt_node_int(1)));
return (dt_node_clause(pdesc, NULL, acts));
}
/*
* Transform the super-clause into straight-D, returning the new list of
* sub-clauses.
*/
dt_node_t *
dt_compile_sugar(dtrace_hdl_t *dtp, dt_node_t *clause)
{
dt_sugar_parse_t dp = { 0 };
int condid = 0;
dp.dtsp_dtp = dtp;
dp.dtsp_pdescs = clause->dn_pdescs;
/* make dt_node_int() generate an "int"-typed integer */
yyintdecimal = B_TRUE;
yyintsuffix[0] = '\0';
yyintprefix = 0;
dt_sugar_visit_all(&dp, clause);
if (dp.dtsp_num_ifs == 0 && dp.dtsp_num_conditions == 0) {
/*
* There is nothing that modifies the number of clauses. Use
* the existing clause as-is, with its predicate intact. This
* ensures that in the absence of D sugar, the body of the
* clause can create a variable that is referenced in the
* predicate.
*/
dt_sugar_append_clause(&dp, dt_node_clause(clause->dn_pdescs,
clause->dn_pred, clause->dn_acts));
} else {
if (clause->dn_pred != NULL) {
condid = dt_sugar_new_condition(&dp,
clause->dn_pred, condid);
}
if (clause->dn_acts == NULL) {
/*
* dt_sugar_visit_stmts() does not emit a clause with
* an empty body (e.g. if there's an empty "if" body),
* but we need the empty body here so that we
* continue to get the default tracing action.
*/
dt_sugar_new_basic_block(&dp, condid, NULL);
} else {
dt_sugar_visit_stmts(&dp, clause->dn_acts, condid);
}
}
if (dp.dtsp_num_conditions != 0) {
dt_sugar_prepend_clause(&dp,
dt_sugar_new_clearerror_clause(&dp));
}
if (dp.dtsp_clause_list != NULL &&
dp.dtsp_clause_list->dn_list != NULL && !dtp->dt_has_sugar) {
dtp->dt_has_sugar = B_TRUE;
dt_sugar_prepend_clause(&dp, dt_sugar_makeerrorclause());
}
return (dp.dtsp_clause_list);
}

View File

@ -25,7 +25,7 @@
*/
/*
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2014, 2016 by Delphix. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/
@ -59,6 +59,7 @@ extern "C" {
#define DTRACE_VERSION 3 /* library ABI interface version */
struct ps_prochandle;
struct dt_node;
typedef struct dtrace_hdl dtrace_hdl_t;
typedef struct dtrace_prog dtrace_prog_t;
typedef struct dtrace_vector dtrace_vector_t;
@ -115,7 +116,7 @@ typedef struct dtrace_proginfo {
#define DTRACE_C_CPP 0x0010 /* Preprocess input file with cpp(1) utility */
#define DTRACE_C_KNODEF 0x0020 /* Permit unresolved kernel symbols in DIFO */
#define DTRACE_C_UNODEF 0x0040 /* Permit unresolved user symbols in DIFO */
#define DTRACE_C_PSPEC 0x0080 /* Intepret ambiguous specifiers as probes */
#define DTRACE_C_PSPEC 0x0080 /* Interpret ambiguous specifiers as probes */
#define DTRACE_C_ETAGS 0x0100 /* Prefix error messages with error tags */
#define DTRACE_C_ARGREF 0x0200 /* Do not require all macro args to be used */
#define DTRACE_C_DEFARG 0x0800 /* Use 0/"" as value for unspecified args */
@ -523,6 +524,10 @@ extern int dtrace_type_strcompile(dtrace_hdl_t *,
extern int dtrace_type_fcompile(dtrace_hdl_t *,
FILE *, dtrace_typeinfo_t *);
extern struct dt_node *dt_compile_sugar(dtrace_hdl_t *,
struct dt_node *);
/*
* DTrace Probe Interface
*

View File

@ -42,6 +42,7 @@ SRCS= dt_aggregate.c \
dt_string.c \
dt_strtab.c \
dt_subr.c \
dt_sugar.c \
dt_work.c \
dt_xlator.c \
gmatch.c

View File

@ -69,6 +69,7 @@ TESTS_SUBDIRS+= aggs \
strlen \
strtoll \
struct \
sugar \
syscall \
tick-n \
trace \

View File

@ -18,6 +18,8 @@ ${PACKAGE}FILES= \
err.D_SYNTAX.declare.d \
err.bigglobal.d \
err.biglocal.d \
tst.16kglobal.d \
tst.16klocal.d \
tst.basicvar.d \
tst.basicvar.d.out \
tst.localvar.d \

View File

@ -0,0 +1,25 @@
# $FreeBSD$
#
# This Makefile was generated by $srcdir/cddl/usr.sbin/dtrace/tests/tools/genmakefiles.sh.
#
PACKAGE= tests
${PACKAGE}FILES= \
tst.else.d \
tst.if.d \
tst.if2.d \
tst.if_before_after.d \
tst.if_nested.d \
tst.if_trailing_semicolon.d \
tst.if_trailing_semicolon2.d \
TESTEXES= \
CFILES= \
.include "../../dtrace.test.mk"

View File

@ -27,7 +27,6 @@ exclude()
}
exclude EXFAIL common/aggs/tst.subr.d
exclude EXFAIL common/dtraceUtil/tst.DataModel32.d.ksh
exclude EXFAIL common/dtraceUtil/tst.ELFGenerationOut.d.ksh
exclude EXFAIL common/dtraceUtil/tst.ELFGenerationWithO.d.ksh
exclude EXFAIL common/funcs/tst.copyin.d

View File

@ -251,6 +251,7 @@ create_elf_from_srec(struct elfcopy *ecp, int ifd)
sec_index = 1;
sec_addr = entry = 0;
while (fgets(line, _LINE_BUFSZ, ifp) != NULL) {
sz = 0; /* Silence GCC 5.3 uninitialized variable warning */
if (line[0] == '\r' || line[0] == '\n')
continue;
if (line[0] == '$' && line[1] == '$') {

View File

@ -89,6 +89,7 @@ Known descriptor names and their properties include:
.It Li elf64-ia64-big Ta ELF Ta MSB Ta 64
.It Li elf64-ia64-little Ta ELF Ta LSB Ta 64
.It Li elf64-little Ta ELF Ta LSB Ta 64
.It Li elf64-littleaarch64 Ta ELF Ta LSB Ta 64
.It Li elf64-littlemips Ta ELF Ta LSB Ta 64
.It Li elf64-powerpc Ta ELF Ta MSB Ta 64
.It Li elf64-powerpcle Ta ELF Ta LSB Ta 64

View File

@ -249,6 +249,14 @@ struct _Elftc_Bfd_Target _libelftc_targets[] = {
.bt_elfclass = ELFCLASS64,
},
{
.bt_name = "elf64-littleaarch64",
.bt_type = ETF_ELF,
.bt_byteorder = ELFDATA2LSB,
.bt_elfclass = ELFCLASS64,
.bt_machine = EM_AARCH64,
},
{
.bt_name = "elf64-littlemips",
.bt_type = ETF_ELF,

View File

@ -111,6 +111,7 @@ ATF_TC_BODY(basename_posix, tc)
} else
base = basename(NULL);
#ifdef __NetBSD__
/*
* basename(3) is allowed to modify the input buffer.
* However, that is considered hostile by some programs,
@ -127,6 +128,7 @@ ATF_TC_BODY(basename_posix, tc)
test_basename_table[i].input);
atf_tc_fail("Input buffer was modified.");
}
#endif
/* Make sure the result is correct. */
if (strcmp(test_basename_table[i].output, base) != 0) {
@ -162,6 +164,7 @@ ATF_TC_BODY(dirname_posix, tc)
} else
base = dirname(NULL);
#ifdef __NetBSD__
/*
* dirname(3) is allowed to modify the input buffer.
* However, that is considered hostile by some programs,
@ -178,6 +181,7 @@ ATF_TC_BODY(dirname_posix, tc)
test_dirname_table[i].input);
atf_tc_fail("Input buffer was modified.");
}
#endif
/* Make sure the result is correct. */
if (strcmp(test_dirname_table[i].output, base) != 0) {

View File

@ -183,6 +183,8 @@
..
struct
..
sugar
..
syscall
..
sysevent

View File

@ -16,7 +16,7 @@ case "$daily_ntpd_leapfile_enable" in
case "$daily_ntpd_avoid_congestion" in
[Yy][Ee][Ss])
# Avoid dogpiling
(sleep $(jot -r 1 0 86400); service ntpd onefetch) &
(sleep $(jot -r 1 0 3600); service ntpd onefetch) &
;;
*)
service ntpd onefetch

View File

@ -134,6 +134,8 @@ typedef __ssize_t ssize_t;
void swab(const void * __restrict, void * __restrict, ssize_t);
#endif /* _SWAB_DECLARED */
int timingsafe_bcmp(const void *, const void *, size_t);
int timingsafe_memcmp(const void *, const void *, size_t);
#endif /* __BSD_VISIBLE */
#if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_)

View File

@ -384,6 +384,7 @@ extern int optind, opterr, optopt;
/* ISO/IEC 9945-1: 1996 */
#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
int fsync(int);
int fdatasync(int);
/*
* ftruncate() was in the POSIX Realtime Extension (it's used for shared

View File

@ -228,6 +228,7 @@ enum {
INTERPOS_wait6,
INTERPOS_ppoll,
INTERPOS_map_stacks_exec,
INTERPOS_fdatasync,
INTERPOS_MAX
};
@ -318,6 +319,7 @@ int __sys_clock_gettime(__clockid_t, struct timespec *ts);
int __sys_close(int);
int __sys_connect(int, const struct sockaddr *, __socklen_t);
int __sys_fcntl(int, int, ...);
int __sys_fdatasync(int);
int __sys_fsync(int);
__pid_t __sys_fork(void);
int __sys_ftruncate(int, __off_t);

View File

@ -97,9 +97,9 @@ __nss_compat_getgrnam_r(void *retval, void *mdata, va_list ap)
const char *name;
struct group *grp;
char *buffer;
int *errnop;
int *errnop, ns_status;
size_t bufsize;
enum nss_status status;
enum nss_status nss_status;
fn = mdata;
name = va_arg(ap, const char *);
@ -107,11 +107,11 @@ __nss_compat_getgrnam_r(void *retval, void *mdata, va_list ap)
buffer = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
status = fn(name, grp, buffer, bufsize, errnop);
status = __nss_compat_result(status, *errnop);
if (status == NS_SUCCESS)
nss_status = fn(name, grp, buffer, bufsize, errnop);
ns_status = __nss_compat_result(nss_status, *errnop);
if (ns_status == NS_SUCCESS)
*(struct group **)retval = grp;
return (status);
return (ns_status);
}
@ -122,9 +122,9 @@ __nss_compat_getgrgid_r(void *retval, void *mdata, va_list ap)
gid_t gid;
struct group *grp;
char *buffer;
int *errnop;
int *errnop, ns_status;
size_t bufsize;
enum nss_status status;
enum nss_status nss_status;
fn = mdata;
gid = va_arg(ap, gid_t);
@ -132,11 +132,11 @@ __nss_compat_getgrgid_r(void *retval, void *mdata, va_list ap)
buffer = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
status = fn(gid, grp, buffer, bufsize, errnop);
status = __nss_compat_result(status, *errnop);
if (status == NS_SUCCESS)
nss_status = fn(gid, grp, buffer, bufsize, errnop);
ns_status = __nss_compat_result(nss_status, *errnop);
if (ns_status == NS_SUCCESS)
*(struct group **)retval = grp;
return (status);
return (ns_status);
}
@ -146,9 +146,9 @@ __nss_compat_getgrent_r(void *retval, void *mdata, va_list ap)
int (*fn)(struct group *, char *, size_t, int *);
struct group *grp;
char *buffer;
int *errnop;
int *errnop, ns_status;
size_t bufsize;
enum nss_status status;
enum nss_status nss_status;
if (CHECK_TERMINATOR(group))
return (NS_NOTFOUND);
@ -157,13 +157,13 @@ __nss_compat_getgrent_r(void *retval, void *mdata, va_list ap)
buffer = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
status = fn(grp, buffer, bufsize, errnop);
status = __nss_compat_result(status, *errnop);
if (status == NS_SUCCESS)
nss_status = fn(grp, buffer, bufsize, errnop);
ns_status = __nss_compat_result(nss_status, *errnop);
if (ns_status == NS_SUCCESS)
*(struct group **)retval = grp;
else if (status != NS_RETURN)
else if (ns_status != NS_RETURN)
SET_TERMINATOR(group, &terminator);
return (status);
return (ns_status);
}
@ -198,9 +198,9 @@ __nss_compat_getpwnam_r(void *retval, void *mdata, va_list ap)
const char *name;
struct passwd *pwd;
char *buffer;
int *errnop;
int *errnop, ns_status;
size_t bufsize;
enum nss_status status;
enum nss_status nss_status;
fn = mdata;
name = va_arg(ap, const char *);
@ -208,11 +208,11 @@ __nss_compat_getpwnam_r(void *retval, void *mdata, va_list ap)
buffer = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
status = fn(name, pwd, buffer, bufsize, errnop);
status = __nss_compat_result(status, *errnop);
if (status == NS_SUCCESS)
nss_status = fn(name, pwd, buffer, bufsize, errnop);
ns_status = __nss_compat_result(nss_status, *errnop);
if (ns_status == NS_SUCCESS)
*(struct passwd **)retval = pwd;
return (status);
return (ns_status);
}
@ -223,9 +223,9 @@ __nss_compat_getpwuid_r(void *retval, void *mdata, va_list ap)
uid_t uid;
struct passwd *pwd;
char *buffer;
int *errnop;
int *errnop, ns_status;
size_t bufsize;
enum nss_status status;
enum nss_status nss_status;
fn = mdata;
uid = va_arg(ap, uid_t);
@ -233,11 +233,11 @@ __nss_compat_getpwuid_r(void *retval, void *mdata, va_list ap)
buffer = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
status = fn(uid, pwd, buffer, bufsize, errnop);
status = __nss_compat_result(status, *errnop);
if (status == NS_SUCCESS)
nss_status = fn(uid, pwd, buffer, bufsize, errnop);
ns_status = __nss_compat_result(nss_status, *errnop);
if (ns_status == NS_SUCCESS)
*(struct passwd **)retval = pwd;
return (status);
return (ns_status);
}
@ -247,9 +247,9 @@ __nss_compat_getpwent_r(void *retval, void *mdata, va_list ap)
int (*fn)(struct passwd *, char *, size_t, int *);
struct passwd *pwd;
char *buffer;
int *errnop;
int *errnop, ns_status;
size_t bufsize;
enum nss_status status;
enum nss_status nss_status;
if (CHECK_TERMINATOR(passwd))
return (NS_NOTFOUND);
@ -258,13 +258,13 @@ __nss_compat_getpwent_r(void *retval, void *mdata, va_list ap)
buffer = va_arg(ap, char *);
bufsize = va_arg(ap, size_t);
errnop = va_arg(ap, int *);
status = fn(pwd, buffer, bufsize, errnop);
status = __nss_compat_result(status, *errnop);
if (status == NS_SUCCESS)
nss_status = fn(pwd, buffer, bufsize, errnop);
ns_status = __nss_compat_result(nss_status, *errnop);
if (ns_status == NS_SUCCESS)
*(struct passwd **)retval = pwd;
else if (status != NS_RETURN)
else if (ns_status != NS_RETURN)
SET_TERMINATOR(passwd, &terminator);
return (status);
return (ns_status);
}

View File

@ -16,7 +16,10 @@ MISRCS+=bcmp.c bcopy.c bzero.c explicit_bzero.c \
strcspn.c strdup.c strerror.c strlcat.c strlcpy.c strlen.c strmode.c \
strncat.c strncmp.c strncpy.c strndup.c strnlen.c strnstr.c \
strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \
strxfrm.c swab.c wcpcpy.c wcpncpy.c wcscasecmp.c wcscat.c \
strxfrm.c swab.c \
timingsafe_bcmp.c \
timingsafe_memcmp.c \
wcpcpy.c wcpncpy.c wcscasecmp.c wcscat.c \
wcschr.c wcscmp.c wcscoll.c wcscpy.c wcscspn.c wcsdup.c \
wcslcat.c wcslcpy.c wcslen.c wcsncasecmp.c wcsncat.c wcsncmp.c \
wcsncpy.c wcsnlen.c wcspbrk.c \
@ -34,7 +37,9 @@ MAN+= bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \
memcmp.3 memcpy.3 memmem.3 memmove.3 memset.3 strcasecmp.3 strcat.3 \
strchr.3 strcmp.3 strcoll.3 strcpy.3 strdup.3 strerror.3 \
string.3 strlcpy.3 strlen.3 strmode.3 strpbrk.3 strsep.3 \
strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 wcscoll.3 wcstok.3 \
strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 \
timingsafe_bcmp.3 \
wcscoll.3 wcstok.3 \
wcswidth.3 wcsxfrm.3 wmemchr.3
MLINKS+=bzero.3 explicit_bzero.3
@ -69,6 +74,7 @@ MLINKS+=strstr.3 strcasestr.3 \
strstr.3 strcasestr_l.3
MLINKS+=strtok.3 strtok_r.3
MLINKS+=strxfrm.3 strxfrm_l.3
MLINKS+=timingsafe_bcmp.3 timingsafe_memcmp.3
MLINKS+=wmemchr.3 wcpcpy.3 \
wmemchr.3 wcpncpy.3 \
wmemchr.3 wcscasecmp.3 \

View File

@ -104,6 +104,11 @@ FBSD_1.4 {
explicit_bzero;
};
FBSD_1.5 {
timingsafe_bcmp;
timingsafe_memcmp;
};
FBSDprivate_1.0 {
__strtok_r;
};

View File

@ -30,7 +30,7 @@
.\" @(#)bcmp.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd June 4, 1993
.Dd August 15, 2016
.Dt BCMP 3
.Os
.Sh NAME
@ -62,7 +62,8 @@ The strings may overlap.
.Xr strcasecmp 3 ,
.Xr strcmp 3 ,
.Xr strcoll 3 ,
.Xr strxfrm 3
.Xr strxfrm 3 ,
.Xr timingsafe_bcmp 3
.Sh HISTORY
A
.Fn bcmp

View File

@ -32,7 +32,7 @@
.\" @(#)memcmp.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
.Dd June 4, 1993
.Dd August 15, 2016
.Dt MEMCMP 3
.Os
.Sh NAME
@ -75,6 +75,7 @@ Zero-length strings are always identical.
.Xr strcmp 3 ,
.Xr strcoll 3 ,
.Xr strxfrm 3 ,
.Xr timingsafe_memcmp 3 ,
.Xr wmemcmp 3
.Sh STANDARDS
The

View File

@ -0,0 +1,92 @@
.\" $OpenBSD: timingsafe_bcmp.3,v 1.2 2014/06/21 20:22:15 tedu Exp $
.\"
.\" Copyright (c) 2014 Google Inc.
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.\" $FreeBSD$
.Dd August 15, 2016
.Dt TIMINGSAFE_BCMP 3
.Os
.Sh NAME
.Nm timingsafe_bcmp ,
.Nm timingsafe_memcmp
.Nd timing-safe byte sequence comparisons
.Sh SYNOPSIS
.In string.h
.Ft int
.Fn timingsafe_bcmp "const void *b1" "const void *b2" "size_t len"
.Ft int
.Fn timingsafe_memcmp "const void *b1" "const void *b2" "size_t len"
.Sh DESCRIPTION
The
.Fn timingsafe_bcmp
and
.Fn timingsafe_memcmp
functions lexicographically compare the first
.Fa len
bytes (each interpreted as an
.Vt unsigned char )
pointed to by
.Fa b1
and
.Fa b2 .
.Pp
Additionally, their running times are independent of the byte sequences compared,
making them safe to use for comparing secret values such as cryptographic MACs.
In contrast,
.Xr bcmp 3
and
.Xr memcmp 3
may short-circuit after finding the first differing byte.
.Sh RETURN VALUES
The
.Fn timingsafe_bcmp
function returns 0 or not zero if the byte sequence pointed to by
.Fa b1
compares equal to or not equal to (respectively)
the byte sequence pointed to by
.Fa b2 .
.Pp
The
.Fn timingsafe_memcmp
function returns a negative value, 0, or positive value if the byte sequence
pointed to by
.Fa b1
compares less than, equal to, or greater than (respectively)
the byte sequence pointed to by
.Fa b2 .
.Sh SEE ALSO
.Xr bcmp 3 ,
.Xr memcmp 3
.Sh STANDARDS
The
.Fn timingsafe_bcmp
and
.Fn timingsafe_memcmp
functions are
.Fx
extensions.
.Sh HISTORY
The
.Fn timingsafe_bcmp
function first appeared in
.Ox 4.9 .
.Pp
The
.Fn timingsafe_memcmp
function first appeared in
.Ox 5.6 .
.Pp
Both functions first appeared in
.Fx 12.0 .

View File

@ -0,0 +1,36 @@
/* $OpenBSD: timingsafe_bcmp.c,v 1.3 2015/08/31 02:53:57 guenther Exp $ */
/*
* Copyright (c) 2010 Damien Miller. All rights reserved.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <string.h>
int __timingsafe_bcmp(const void *, const void *, size_t);
int
__timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for (; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}
__weak_reference(__timingsafe_bcmp, timingsafe_bcmp);

View File

@ -0,0 +1,53 @@
/* $OpenBSD: timingsafe_memcmp.c,v 1.2 2015/08/31 02:53:57 guenther Exp $ */
/*
* Copyright (c) 2014 Google Inc.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <limits.h>
#include <string.h>
int __timingsafe_memcmp(const void *, const void *, size_t);
int
__timingsafe_memcmp(const void *b1, const void *b2, size_t len)
{
const unsigned char *p1 = b1, *p2 = b2;
size_t i;
int res = 0, done = 0;
for (i = 0; i < len; i++) {
/* lt is -1 if p1[i] < p2[i]; else 0. */
int lt = (p1[i] - p2[i]) >> CHAR_BIT;
/* gt is -1 if p1[i] > p2[i]; else 0. */
int gt = (p2[i] - p1[i]) >> CHAR_BIT;
/* cmp is 1 if p1[i] > p2[i]; -1 if p1[i] < p2[i]; else 0. */
int cmp = lt - gt;
/* set res = cmp if !done. */
res |= cmp & ~done;
/* set done if p1[i] != p2[i]. */
done |= lt | gt;
}
return (res);
}
__weak_reference(__timingsafe_memcmp, timingsafe_memcmp);

View File

@ -37,6 +37,7 @@ INTERPOSED = \
close \
connect \
fcntl \
fdatasync \
fsync \
fork \
kevent \

View File

@ -400,6 +400,10 @@ FBSD_1.4 {
recvmmsg;
};
FBSD_1.5 {
fdatasync;
};
FBSDprivate_1.0 {
___acl_aclcheck_fd;
__sys___acl_aclcheck_fd;
@ -594,6 +598,8 @@ FBSDprivate_1.0 {
__sys_fstatfs;
_fsync;
__sys_fsync;
_fdatasync;
__sys_fdatasync;
_futimes;
__sys_futimes;
_getaudit;

46
lib/libc/sys/fdatasync.c Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2016 The FreeBSD Foundation.
* All rights reserved.
*
* Portions of this software were developed by Konstantin Belousov
* under sponsorship from the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice(s), this list of conditions and the following disclaimer as
* the first lines of this file unmodified other than the possible
* addition of one or more copyright notices.
* 2. Redistributions in binary form must reproduce the above copyright
* notice(s), 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 COPYRIGHT HOLDER(S) ``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 COPYRIGHT HOLDER(S) 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/fcntl.h>
#include <unistd.h>
#include "libc_private.h"
int
fdatasync(int fd)
{
return (((int (*)(int))__libc_interposing[INTERPOS_fdatasync])(fd));
}

View File

@ -79,6 +79,7 @@ interpos_func_t __libc_interposing[INTERPOS_MAX] = {
SLOT(wait6, __sys_wait6),
SLOT(ppoll, __sys_ppoll),
SLOT(map_stacks_exec, __libc_map_stacks_exec),
SLOT(fdatasync, __sys_fdatasync),
};
#undef SLOT

View File

@ -84,7 +84,7 @@ _tcb_get(void)
".set\tmips64r2\n\t"
"rdhwr\t%0, $29\n\t"
".set\tpop"
: "=v" (_rv));
: "=r" (_rv));
/*
* XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'
@ -106,7 +106,7 @@ _tcb_get(void)
".set\tmips32r2\n\t"
"rdhwr\t%0, $29\n\t"
".set\tpop"
: "=v" (_rv));
: "=r" (_rv));
/*
* XXXSS See 'git show c6be4f4d2d1b71c04de5d3bbb6933ce2dbcdb317'

View File

@ -227,6 +227,20 @@ __thr_fsync(int fd)
return (ret);
}
static int
__thr_fdatasync(int fd)
{
struct pthread *curthread;
int ret;
curthread = _get_curthread();
_thr_cancel_enter2(curthread, 0);
ret = __sys_fdatasync(fd);
_thr_cancel_leave(curthread, 1);
return (ret);
}
/*
* Cancellation behavior:
* Thread may be canceled after system call.
@ -653,6 +667,7 @@ __thr_interpose_libc(void)
SLOT(wait6);
SLOT(ppoll);
SLOT(map_stacks_exec);
SLOT(fdatasync);
#undef SLOT
*(__libc_interposing_slot(
INTERPOS__pthread_mutex_init_calloc_cb)) =

View File

@ -1,5 +1,5 @@
.\" $FreeBSD$
.Dd April 16, 2015
.Dd August 16, 2016
.Dt PTHREAD_TESTCANCEL 3
.Os
.Sh NAME
@ -114,6 +114,7 @@ function is a cancellation point if
.Fa cmd
is
.Dv F_SETLKW .
.It Fn fdatasync
.It Fn fsync
.It Fn kevent
The

View File

@ -28,12 +28,13 @@
.\" @(#)queue.3 8.2 (Berkeley) 1/24/94
.\" $FreeBSD$
.\"
.Dd June 24, 2015
.Dd August 15, 2016
.Dt QUEUE 3
.Os
.Sh NAME
.Nm SLIST_CLASS_ENTRY ,
.Nm SLIST_CLASS_HEAD ,
.Nm SLIST_CONCAT ,
.Nm SLIST_EMPTY ,
.Nm SLIST_ENTRY ,
.Nm SLIST_FIRST ,
@ -75,6 +76,7 @@
.Nm STAILQ_SWAP ,
.Nm LIST_CLASS_ENTRY ,
.Nm LIST_CLASS_HEAD ,
.Nm LIST_CONCAT ,
.Nm LIST_EMPTY ,
.Nm LIST_ENTRY ,
.Nm LIST_FIRST ,
@ -125,6 +127,7 @@ lists and tail queues
.\"
.Fn SLIST_CLASS_ENTRY "CLASSTYPE"
.Fn SLIST_CLASS_HEAD "HEADNAME" "CLASSTYPE"
.Fn SLIST_CONCAT "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE" "SLIST_ENTRY NAME"
.Fn SLIST_EMPTY "SLIST_HEAD *head"
.Fn SLIST_ENTRY "TYPE"
.Fn SLIST_FIRST "SLIST_HEAD *head"
@ -168,6 +171,7 @@ lists and tail queues
.\"
.Fn LIST_CLASS_ENTRY "CLASSTYPE"
.Fn LIST_CLASS_HEAD "HEADNAME" "CLASSTYPE"
.Fn LIST_CONCAT "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
.Fn LIST_EMPTY "LIST_HEAD *head"
.Fn LIST_ENTRY "TYPE"
.Fn LIST_FIRST "LIST_HEAD *head"
@ -249,6 +253,8 @@ Singly-linked lists add the following functionality:
.Bl -enum -compact -offset indent
.It
O(n) removal of any entry in the list.
.It
O(n) concatenation of two lists.
.El
.Pp
Singly-linked tail queues add the following functionality:
@ -296,6 +302,8 @@ Linked lists are the simplest of the doubly linked data structures.
They add the following functionality over the above:
.Bl -enum -compact -offset indent
.It
O(n) concatenation of two lists.
.It
They may be traversed backwards.
.El
However:
@ -401,6 +409,19 @@ evaluates to an initializer for the list
.Fa head .
.Pp
The macro
.Nm SLIST_CONCAT
concatenates the list headed by
.Fa head2
onto the end of the one headed by
.Fa head1
removing all entries from the former.
Use of this macro should be avoided as it traverses the entirety of the
.Fa head1
list.
A singly-linked tail queue should be used if this macro is needed in
high-usage code paths or to operate on long lists.
.Pp
The macro
.Nm SLIST_EMPTY
evaluates to true if there are no elements in the list.
.Pp
@ -508,6 +529,9 @@ The macro
removes the element
.Fa elm
from the list.
Use of this macro should be avoided as it traverses the entire list.
A doubly-linked list should be used if this macro is needed in
high-usage code paths or to operate on long lists.
.Pp
The macro
.Nm SLIST_SWAP
@ -724,6 +748,9 @@ The macro
removes the element
.Fa elm
from the tail queue.
Use of this macro should be avoided as it traverses the entire list.
A doubly-linked tail queue should be used if this macro is needed in
high-usage code paths or to operate on long tail queues.
.Pp
The macro
.Nm STAILQ_SWAP
@ -823,6 +850,19 @@ evaluates to an initializer for the list
.Fa head .
.Pp
The macro
.Nm LIST_CONCAT
concatenates the list headed by
.Fa head2
onto the end of the one headed by
.Fa head1
removing all entries from the former.
Use of this macro should be avoided as it traverses the entirety of the
.Fa head1
list.
A tail queue should be used if this macro is needed in
high-usage code paths or to operate on long lists.
.Pp
The macro
.Nm LIST_EMPTY
evaluates to true if there are no elements in the list.
.Pp

View File

@ -269,7 +269,6 @@ MAN= aac.4 \
mac_stub.4 \
mac_test.4 \
malo.4 \
mcd.4 \
md.4 \
mdio.4 \
me.4 \

View File

@ -1,165 +0,0 @@
.\"
.\" Copyright (c) 1994 Keith E. Walker
.\" 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.
.\" 3. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission
.\"
.\" 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.
.\"
.\" $FreeBSD$
.\"
.Dd December 8, 1994
.Dt MCD 4
.Os
.Sh NAME
.Nm mcd
.Nd Mitsumi CD-ROM driver
.Sh SYNOPSIS
.Cd "device mcd"
.Pp
In
.Pa /boot/device.hints :
.Cd hint.mcd.0.at="isa"
.Cd hint.mcd.0.port="0x300"
.Cd hint.mcd.0.irq="10"
.Sh DESCRIPTION
The
.Nm
driver provides a data and audio interface to the Mitsumi-brand CD-ROM
player.
The CD-ROM player must be interfaced to the ISA bus through
one of the Mitsumi proprietary controller boards.
The controller
boards supported are the LU002S, LU005S, the FX001 and the quite
common FX001D.
.Pp
The
.Nm
driver responds to disk-specific
.Fn ioctl
commands, namely the
.Dv DIOCGPART
command.
Other disk-specific
.Fn ioctl
commands will return an error.
.Pp
The
.Nm
driver also responds to special CD-ROM
.Fn ioctl
commands.
These commands
control the CD-ROM player's audio features.
The commands are:
.Pp
.Bl -tag -width CDIOCREADSUBCHANNEL -compact -offset indent
.It CDIOCREADSUBCHANNEL
get sub-channel information on current status of disc playing
.It CDIOCREADTOCHEADER
get table of contents header
.It CDIOCREADTOCENTRYS
gets all of the table of contents
.It CDIOCPLAYTRACKS
begins audio playing at location specified
.It CDIOCPLAYBLOCKS
fails with error
.Er EINVAL
.It CDIOCPLAYMSF
begins audio playing at location specified
.It CDIOCRESUME
resumes playing a previously paused disc
.It CDIOCPAUSE
pauses a playing disc
.It CDIOCSTART
begins playing a disc
.It CDIOCSTOP
stops a previously playing disc
.It CDIOCEJECT
opens the disc tray (there is no support for a corresponding un-eject
command).
.It CDIOCRESET
stops any play and resets the Mitsumi controller board
.It CDIOCSETDEBUG
cause the kernel to print debug messages to the console about the
.Nm
driver
.It CDIOCCLRDEBUG
cause the kernel to quit printing debug messages about the
.Nm
driver
.El
.Pp
The
.Fn ioctl
commands defined above are the only ones that the
.Nm
driver supports.
There are other CD-ROM related
.Fn ioctl
commands (such as
.Dv CDIOCSETVOL
and
.Dv CDIOCSETSTERIO )
which are available
and may be supported by future versions of the driver.
.Sh FILES
.Bl -tag -width /dev/(r)mcd0a -compact
.It Pa /dev/(r)mcd0a
accesses
.Bx
partition on the disc.
Normally, there is only
one file system on a CD-ROM disc.
.It Pa /dev/(r)mcd0c
accesses raw device.
.El
.Sh NOTES
The character-mode devices for the
.Nm
driver should only be used for accessing the audio features of the
CD-ROM player as the performance on data is abysmal.
.Pp
The current version of the driver uses neither the DMA or IRQ
features of the interface board, although it has an interrupt handler
for any IRQ requests that are generated.
Until the DMA features are
supported, the only interrupts that the board generates are those that
are not supported by the driver anyway.
.Sh SEE ALSO
.In sys/cdio.h
.Sh HISTORY
An
.Nm
driver appeared in
.Fx 1.0 .
.Sh AUTHORS
.An -nosplit
The driver was written by
.An Holger Veit
(data part) and
.An Brian Moore
(audio part).
Changes were provided by
.An Gary Clark II ,
.An Andrew A. Chernov ,
and
.An Jordan K. Hubbard .

View File

@ -633,7 +633,8 @@ when trying to use a TCP function block that is not available;
.Xr mod_cc 4 ,
.Xr siftr 4 ,
.Xr syncache 4 ,
.Xr setkey 8
.Xr setkey 8 ,
.Xr tcp_functions 9
.Rs
.%A "V. Jacobson"
.%A "R. Braden"

View File

@ -114,14 +114,17 @@ struct tcp_function_block {
struct inpcb *inp, struct tcpcb *tp);
/* Optional memory allocation/free routine */
void (*tfb_tcp_fb_init)(struct tcpcb *);
void (*tfb_tcp_fb_fini)(struct tcpcb *);
void (*tfb_tcp_fb_fini)(struct tcpcb *, int);
/* Optional timers, must define all if you define one */
int (*tfb_tcp_timer_stop_all)(struct tcpcb *);
void (*tfb_tcp_timer_activate)(struct tcpcb *,
uint32_t, u_int);
int (*tfb_tcp_timer_active)(struct tcpcb *, uint32_t);
void (*tfb_tcp_timer_stop)(struct tcpcb *, uint32_t);
/* Optional functions */
void (*tfb_tcp_rexmit_tmr)(struct tcpcb *);
void (*tfb_tcp_handoff_ok)(struct tcpcb *);
/* System use */
volatile uint32_t tfb_refcnt;
uint32_t tfb_flags;
};
@ -157,6 +160,16 @@ in the
.Va tfb_tcp_fb_fini
field.
.Pp
If the
.Va tfb_tcp_fb_fini
argument is non-NULL, the function to which it points is called when the
kernel is destroying the TCP control block or when the socket is transitioning
to use a different TCP stack.
The function is called with arguments of the TCP control block and an integer
flag.
The flag will be zero if the socket is transitioning to use another TCP stack
or one if the TCP control block is being destroyed.
.Pp
If the TCP stack implements additional timers, the TCP stack should set a
non-NULL pointer in the
.Va tfb_tcp_timer_stop_all ,
@ -193,6 +206,37 @@ However, care must be taken to ensure the retransmit timer leaves the
TCP control block in a valid state for the remainder of the retransmit
timer logic.
.Pp
A user may select a new TCP stack before calling
.Xr connect 2
or
.Xr listen 2 .
Optionally, a TCP stack may also allow a user to begin using the TCP stack for
a connection that is in a later state by setting a non-NULL function pointer in
the
.Va tfb_tcp_handoff_ok
field.
If this field is non-NULL and a user attempts to select that TCP stack after
calling
.Xr connect 2
or
.Xr listen 2
for that socket, the kernel will call the function pointed to by the
.Va tfb_tcp_handoff_ok
field.
The function should return 0 if the user is allowed to switch the socket to use
the TCP stack. Otherwise, the function should return an error code, which will
be returned to the user.
If the
.Va tfb_tcp_handoff_ok
field is
.Dv NULL
and a user attempts to select the TCP stack after calling
.Xr connect 2
or
.Xr listen 2
for that socket, the operation will fail and the kernel will return
.Er EINVAL .
.Pp
The
.Va tfb_refcnt
and
@ -269,8 +313,10 @@ The
.Fa blk
argument references a function block that is not currently registered.
.Sh SEE ALSO
.Xr malloc 9 ,
.Xr tcp 4
.Xr connect 2 ,
.Xr listen 2 ,
.Xr tcp 4 ,
.Xr malloc 9
.Sh HISTORY
This framework first appeared in
.Fx 11.0 .

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
1월

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
1岿
2岿
3岿
4岿
5岿
6岿
7岿
8岿
9岿
10岿
11岿
12岿
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
1¿ù

View File

@ -4,53 +4,53 @@
# -----------------------------------------------------------------------------
#
# Short month names
!!#1TB
!!#2TB
!!#3TB
!!#4TB
!!#5TB
!!#6TB
!!#7TB
!!#8TB
!!#9TB
#1#0TB
#1#1TB
#1#2TB
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
R;TB
6~TB
H}TB
KDTB
NeTB
AyTB
F_TB
0KTB
>ETB
J.TB
J.R;TB
J.6~TB
一月
二月
三月
四月
五月
六月
七月
八月
九月
十月
十一月
十二月
#
# Short weekday names
V\HU
V\R;
V\6~
V\H}
V\KD
V\Ne
V\Ay
周日
周一
周二
周三
周四
周五
周六
#
# Long weekday names
PGFZHU
PGFZR;
PGFZ6~
PGFZH}
PGFZKD
PGFZNe
PGFZAy
星期日
星期一
星期二
星期三
星期四
星期五
星期六
#
# X_fmt
%Hʱ%M·Ö%SÃë
%H时%M分%S秒
#
# x_fmt
%Y/%m/%d
@ -59,25 +59,25 @@ PGFZAy
%a %b/%e %T %Y
#
# AM/PM
IONg
OBNg
上午
下午
#
# date_fmt
%YÄê%bÔÂ%eÈÕ %A %X %Z
%Y年%b月%e日 %A %X %Z
#
# Long month names (without case ending)
R;TB
6~TB
H}TB
KDTB
NeTB
AyTB
F_TB
0KTB
>ETB
J.TB
J.R;TB
J.6~TB
一月
二月
三月
四月
五月
六月
七月
八月
九月
十月
十一月
十二月
#
# md_order
md

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
一月

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
一月

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
 1月
 2月
 3月
 4月
 5月
 6月
 7月
 8月
 9月
10月
11月
12月
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
一月

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
1月

View File

@ -4,32 +4,32 @@
# -----------------------------------------------------------------------------
#
# Short month names
 1月
 2月
 3月
 4月
 5月
 6月
 7月
 8月
 9月
10月
11月
12月
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
1月
2月
3月
4月
5月
6月
7月
8月
9月
10月
11月
12月
1る
2る
3る
4る
5る
6る
7る
8る
9る
10る
11る
12る
#
# Short weekday names
週日
@ -62,21 +62,22 @@
上午
下午
#
# date_fmt
%Y年%b月%e日 %A %X %Z
#
# Long month names (without case ending)
1月
2月
3月
4月
5月
6月
7月
8月
9月
10月
11月
12月
1る
2る
3る
4る
5る
6る
7る
8る
9る
10る
11る
12る
#
# md_order
md

View File

@ -4,18 +4,18 @@
# -----------------------------------------------------------------------------
#
# Short month names
1
2
3
4
5
6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
#
# Long month names (as in a date)
1月

View File

@ -188,6 +188,27 @@ print_cpu_features(u_int cpu)
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR0) != 0) {
printed = 0;
printf(" Instruction Set Attributes 0 = <");
switch (ID_AA64ISAR0_RDM(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_RDM_NONE:
break;
case ID_AA64ISAR0_RDM_IMPL:
printf("%sRDM", SEP_STR);
break;
default:
printf("%sUnknown RDM", SEP_STR);
}
switch (ID_AA64ISAR0_ATOMIC(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_ATOMIC_NONE:
break;
case ID_AA64ISAR0_ATOMIC_IMPL:
printf("%sAtomic", SEP_STR);
break;
default:
printf("%sUnknown Atomic", SEP_STR);
}
switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) {
case ID_AA64ISAR0_AES_NONE:
break;
@ -466,8 +487,82 @@ print_cpu_features(u_int cpu)
/* AArch64 Memory Model Feature Register 1 */
if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR1) != 0) {
printf(" Memory Model Features 1 = <%#lx>\n",
cpu_desc[cpu].id_aa64mmfr1);
printed = 0;
printf(" Memory Model Features 1 = <");
switch (ID_AA64MMFR1_PAN(cpu_desc[cpu].id_aa64mmfr1)) {
case ID_AA64MMFR1_PAN_NONE:
break;
case ID_AA64MMFR1_PAN_IMPL:
printf("%sPAN", SEP_STR);
break;
default:
printf("%sUnknown PAN", SEP_STR);
break;
}
switch (ID_AA64MMFR1_LO(cpu_desc[cpu].id_aa64mmfr1)) {
case ID_AA64MMFR1_LO_NONE:
break;
case ID_AA64MMFR1_LO_IMPL:
printf("%sLO", SEP_STR);
break;
default:
printf("%sUnknown LO", SEP_STR);
break;
}
switch (ID_AA64MMFR1_HPDS(cpu_desc[cpu].id_aa64mmfr1)) {
case ID_AA64MMFR1_HPDS_NONE:
break;
case ID_AA64MMFR1_HPDS_IMPL:
printf("%sHPDS", SEP_STR);
break;
default:
printf("%sUnknown HPDS", SEP_STR);
break;
}
switch (ID_AA64MMFR1_VH(cpu_desc[cpu].id_aa64mmfr1)) {
case ID_AA64MMFR1_VH_NONE:
break;
case ID_AA64MMFR1_VH_IMPL:
printf("%sVHE", SEP_STR);
break;
default:
printf("%sUnknown VHE", SEP_STR);
break;
}
switch (ID_AA64MMFR1_VMIDBITS(cpu_desc[cpu].id_aa64mmfr1)) {
case ID_AA64MMFR1_VMIDBITS_8:
break;
case ID_AA64MMFR1_VMIDBITS_16:
printf("%s16 VMID bits", SEP_STR);
break;
default:
printf("%sUnknown VMID bits", SEP_STR);
break;
}
switch (ID_AA64MMFR1_HAFDBS(cpu_desc[cpu].id_aa64mmfr1)) {
case ID_AA64MMFR1_HAFDBS_NONE:
break;
case ID_AA64MMFR1_HAFDBS_AF:
printf("%sAF", SEP_STR);
break;
case ID_AA64MMFR1_HAFDBS_AF_DBS:
printf("%sAF+DBS", SEP_STR);
break;
default:
printf("%sUnknown Hardware update AF/DBS", SEP_STR);
break;
}
if ((cpu_desc[cpu].id_aa64mmfr1 & ~ID_AA64MMFR1_MASK) != 0)
printf("%s%#lx", SEP_STR,
cpu_desc[cpu].id_aa64mmfr1 & ~ID_AA64MMFR1_MASK);
printf(">\n");
}
/* AArch64 Debug Feature Register 0 */
@ -489,6 +584,9 @@ print_cpu_features(u_int cpu)
case ID_AA64DFR0_PMU_VER_3:
printf("%sPMUv3", SEP_STR);
break;
case ID_AA64DFR0_PMU_VER_3_1:
printf("%sPMUv3+16 bit evtCount", SEP_STR);
break;
case ID_AA64DFR0_PMU_VER_IMPL:
printf("%sImplementation defined PMU", SEP_STR);
break;
@ -512,6 +610,9 @@ print_cpu_features(u_int cpu)
case ID_AA64DFR0_DEBUG_VER_8:
printf("%sDebug v8", SEP_STR);
break;
case ID_AA64DFR0_DEBUG_VER_8_VHE:
printf("%sDebug v8+VHE", SEP_STR);
break;
default:
printf("%sUnknown Debug", SEP_STR);
break;

View File

@ -172,6 +172,7 @@
#define ID_AA64DFR0_DEBUG_VER_MASK (0xf << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_DEBUG_VER(x) ((x) & ID_AA64DFR0_DEBUG_VER_MASK)
#define ID_AA64DFR0_DEBUG_VER_8 (0x6 << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_DEBUG_VER_8_VHE (0x7 << ID_AA64DFR0_DEBUG_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER_SHIFT 4
#define ID_AA64DFR0_TRACE_VER_MASK (0xf << ID_AA64DFR0_TRACE_VER_SHIFT)
#define ID_AA64DFR0_TRACE_VER(x) ((x) & ID_AA64DFR0_TRACE_VER_MASK)
@ -182,6 +183,7 @@
#define ID_AA64DFR0_PMU_VER(x) ((x) & ID_AA64DFR0_PMU_VER_MASK)
#define ID_AA64DFR0_PMU_VER_NONE (0x0 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_3 (0x1 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_3_1 (0x4 << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_PMU_VER_IMPL (0xf << ID_AA64DFR0_PMU_VER_SHIFT)
#define ID_AA64DFR0_BRPS_SHIFT 12
#define ID_AA64DFR0_BRPS_MASK (0xf << ID_AA64DFR0_BRPS_SHIFT)
@ -197,7 +199,7 @@
((((x) >> ID_AA64DFR0_CTX_CMPS_SHIFT) & 0xf) + 1)
/* ID_AA64ISAR0_EL1 */
#define ID_AA64ISAR0_MASK 0x000ffff0
#define ID_AA64ISAR0_MASK 0xf0fffff0
#define ID_AA64ISAR0_AES_SHIFT 4
#define ID_AA64ISAR0_AES_MASK (0xf << ID_AA64ISAR0_AES_SHIFT)
#define ID_AA64ISAR0_AES(x) ((x) & ID_AA64ISAR0_AES_MASK)
@ -219,6 +221,16 @@
#define ID_AA64ISAR0_CRC32(x) ((x) & ID_AA64ISAR0_CRC32_MASK)
#define ID_AA64ISAR0_CRC32_NONE (0x0 << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_CRC32_BASE (0x1 << ID_AA64ISAR0_CRC32_SHIFT)
#define ID_AA64ISAR0_ATOMIC_SHIFT 20
#define ID_AA64ISAR0_ATOMIC_MASK (0xf << ID_AA64ISAR0_ATOMIC_SHIFT)
#define ID_AA64ISAR0_ATOMIC(x) ((x) & ID_AA64ISAR0_ATOMIC_MASK)
#define ID_AA64ISAR0_ATOMIC_NONE (0x0 << ID_AA64ISAR0_ATOMIC_SHIFT)
#define ID_AA64ISAR0_ATOMIC_IMPL (0x2 << ID_AA64ISAR0_ATOMIC_SHIFT)
#define ID_AA64ISAR0_RDM_SHIFT 28
#define ID_AA64ISAR0_RDM_MASK (0xf << ID_AA64ISAR0_RDM_SHIFT)
#define ID_AA64ISAR0_RDM(x) ((x) & ID_AA64ISAR0_RDM_MASK)
#define ID_AA64ISAR0_RDM_NONE (0x0 << ID_AA64ISAR0_RDM_SHIFT)
#define ID_AA64ISAR0_RDM_IMPL (0x1 << ID_AA64ISAR0_RDM_SHIFT)
/* ID_AA64MMFR0_EL1 */
#define ID_AA64MMFR0_MASK 0xffffffff
@ -267,6 +279,40 @@
#define ID_AA64MMFR0_TGRAN4_IMPL (0x0 << ID_AA64MMFR0_TGRAN4_SHIFT)
#define ID_AA64MMFR0_TGRAN4_NONE (0xf << ID_AA64MMFR0_TGRAN4_SHIFT)
/* ID_AA64MMFR1_EL1 */
#define ID_AA64MMFR1_MASK 0x00ffffff
#define ID_AA64MMFR1_HAFDBS_SHIFT 0
#define ID_AA64MMFR1_HAFDBS_MASK (0xf << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_HAFDBS(x) ((x) & ID_AA64MMFR1_HAFDBS_MASK)
#define ID_AA64MMFR1_HAFDBS_NONE (0x0 << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_HAFDBS_AF (0x1 << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_HAFDBS_AF_DBS (0x2 << ID_AA64MMFR1_HAFDBS_SHIFT)
#define ID_AA64MMFR1_VMIDBITS_SHIFT 4
#define ID_AA64MMFR1_VMIDBITS_MASK (0xf << ID_AA64MMFR1_VMIDBITS_SHIFT)
#define ID_AA64MMFR1_VMIDBITS(x) ((x) & ID_AA64MMFR1_VMIDBITS_MASK)
#define ID_AA64MMFR1_VMIDBITS_8 (0x0 << ID_AA64MMFR1_VMIDBITS_SHIFT)
#define ID_AA64MMFR1_VMIDBITS_16 (0x2 << ID_AA64MMFR1_VMIDBITS_SHIFT)
#define ID_AA64MMFR1_VH_SHIFT 8
#define ID_AA64MMFR1_VH_MASK (0xf << ID_AA64MMFR1_VH_SHIFT)
#define ID_AA64MMFR1_VH(x) ((x) & ID_AA64MMFR1_VH_MASK)
#define ID_AA64MMFR1_VH_NONE (0x0 << ID_AA64MMFR1_VH_SHIFT)
#define ID_AA64MMFR1_VH_IMPL (0x1 << ID_AA64MMFR1_VH_SHIFT)
#define ID_AA64MMFR1_HPDS_SHIFT 12
#define ID_AA64MMFR1_HPDS_MASK (0xf << ID_AA64MMFR1_HPDS_SHIFT)
#define ID_AA64MMFR1_HPDS(x) ((x) & ID_AA64MMFR1_HPDS_MASK)
#define ID_AA64MMFR1_HPDS_NONE (0x0 << ID_AA64MMFR1_HPDS_SHIFT)
#define ID_AA64MMFR1_HPDS_IMPL (0x1 << ID_AA64MMFR1_HPDS_SHIFT)
#define ID_AA64MMFR1_LO_SHIFT 16
#define ID_AA64MMFR1_LO_MASK (0xf << ID_AA64MMFR1_LO_SHIFT)
#define ID_AA64MMFR1_LO(x) ((x) & ID_AA64MMFR1_LO_MASK)
#define ID_AA64MMFR1_LO_NONE (0x0 << ID_AA64MMFR1_LO_SHIFT)
#define ID_AA64MMFR1_LO_IMPL (0x1 << ID_AA64MMFR1_LO_SHIFT)
#define ID_AA64MMFR1_PAN_SHIFT 20
#define ID_AA64MMFR1_PAN_MASK (0xf << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_PAN(x) ((x) & ID_AA64MMFR1_PAN_MASK)
#define ID_AA64MMFR1_PAN_NONE (0x0 << ID_AA64MMFR1_PAN_SHIFT)
#define ID_AA64MMFR1_PAN_IMPL (0x1 << ID_AA64MMFR1_PAN_SHIFT)
/* ID_AA64PFR0_EL1 */
#define ID_AA64PFR0_MASK 0x0fffffff
#define ID_AA64PFR0_EL0_SHIFT 0

View File

@ -56,7 +56,7 @@ dskread(void *buf, u_int64_t lba, int nblk)
devinfo->dev->Media->MediaId, lba, size, buf);
if (status != EFI_SUCCESS) {
DPRINTF("dskread: failed dev: %p, id: %u, lba: %lu, size: %d, "
DPRINTF("dskread: failed dev: %p, id: %u, lba: %zu, size: %d, "
"status: %lu\n", devinfo->dev,
devinfo->dev->Media->MediaId, lba, size,
EFI_ERROR_CODE(status));

View File

@ -53,7 +53,7 @@ vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes)
status = devinfo->dev->ReadBlocks(devinfo->dev,
devinfo->dev->Media->MediaId, lba, bytes, buf);
if (status != EFI_SUCCESS) {
DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %zu, size: %zu,"
DPRINTF("vdev_read: failed dev: %p, id: %u, lba: %jd, size: %zu,"
" status: %lu\n", devinfo->dev,
devinfo->dev->Media->MediaId, lba, bytes,
EFI_ERROR_CODE(status));

View File

@ -438,8 +438,10 @@ efi_cons_getchar()
/* Try to read a key stroke. We wait for one if none is pending. */
status = conin->ReadKeyStroke(conin, &key);
if (status == EFI_NOT_READY) {
BS->WaitForEvent(1, &conin->WaitForKey, &junk);
while (status == EFI_NOT_READY) {
/* Some EFI implementation (u-boot for example) do not support WaitForKey */
if (conin->WaitForKey != NULL)
BS->WaitForEvent(1, &conin->WaitForKey, &junk);
status = conin->ReadKeyStroke(conin, &key);
}
switch (key.ScanCode) {
@ -454,6 +456,9 @@ efi_cons_getchar()
int
efi_cons_poll()
{
if (conin->WaitForKey == NULL)
return (1);
/* This can clear the signaled state. */
return (BS->CheckEvent(conin->WaitForKey) == EFI_SUCCESS);
}

View File

@ -480,6 +480,14 @@ static kmutex_t dtrace_errlock;
(testaddr) + (testsz) - (uintptr_t)(baseaddr) <= (basesz) && \
(testaddr) + (testsz) >= (testaddr))
#define DTRACE_RANGE_REMAIN(remp, addr, baseaddr, basesz) \
do { \
if ((remp) != NULL) { \
*(remp) = (uintptr_t)(baseaddr) + (basesz) - (addr); \
} \
_NOTE(CONSTCOND) } while (0)
/*
* Test whether alloc_sz bytes will fit in the scratch region. We isolate
* alloc_sz on the righthand side of the comparison in order to avoid overflow
@ -588,6 +596,10 @@ dtrace_dynvar_t *dtrace_dynvar(dtrace_dstate_t *, uint_t, dtrace_key_t *,
uintptr_t dtrace_dif_varstr(uintptr_t, dtrace_state_t *, dtrace_mstate_t *);
static int dtrace_priv_proc(dtrace_state_t *);
static void dtrace_getf_barrier(void);
static int dtrace_canload_remains(uint64_t, size_t, size_t *,
dtrace_mstate_t *, dtrace_vstate_t *);
static int dtrace_canstore_remains(uint64_t, size_t, size_t *,
dtrace_mstate_t *, dtrace_vstate_t *);
/*
* DTrace Probe Context Functions
@ -698,7 +710,7 @@ dtrace_inscratch(uintptr_t dest, size_t size, dtrace_mstate_t *mstate)
}
static int
dtrace_canstore_statvar(uint64_t addr, size_t sz,
dtrace_canstore_statvar(uint64_t addr, size_t sz, size_t *remain,
dtrace_statvar_t **svars, int nsvars)
{
int i;
@ -707,8 +719,8 @@ dtrace_canstore_statvar(uint64_t addr, size_t sz,
if (nsvars == 0)
return (0);
maxglobalsize = dtrace_statvar_maxsize;
maxlocalsize = (maxglobalsize + sizeof (uint64_t)) * NCPU;
maxglobalsize = dtrace_statvar_maxsize + sizeof (uint64_t);
maxlocalsize = maxglobalsize * NCPU;
for (i = 0; i < nsvars; i++) {
dtrace_statvar_t *svar = svars[i];
@ -726,11 +738,15 @@ dtrace_canstore_statvar(uint64_t addr, size_t sz,
* DTrace to escalate an orthogonal kernel heap corruption bug
* into the ability to store to arbitrary locations in memory.
*/
VERIFY((scope == DIFV_SCOPE_GLOBAL && size < maxglobalsize) ||
(scope == DIFV_SCOPE_LOCAL && size < maxlocalsize));
VERIFY((scope == DIFV_SCOPE_GLOBAL && size <= maxglobalsize) ||
(scope == DIFV_SCOPE_LOCAL && size <= maxlocalsize));
if (DTRACE_INRANGE(addr, sz, svar->dtsv_data, svar->dtsv_size))
if (DTRACE_INRANGE(addr, sz, svar->dtsv_data,
svar->dtsv_size)) {
DTRACE_RANGE_REMAIN(remain, addr, svar->dtsv_data,
svar->dtsv_size);
return (1);
}
}
return (0);
@ -745,13 +761,27 @@ dtrace_canstore_statvar(uint64_t addr, size_t sz,
static int
dtrace_canstore(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
dtrace_vstate_t *vstate)
{
return (dtrace_canstore_remains(addr, sz, NULL, mstate, vstate));
}
/*
* Implementation of dtrace_canstore which communicates the upper bound of the
* allowed memory region.
*/
static int
dtrace_canstore_remains(uint64_t addr, size_t sz, size_t *remain,
dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
{
/*
* First, check to see if the address is in scratch space...
*/
if (DTRACE_INRANGE(addr, sz, mstate->dtms_scratch_base,
mstate->dtms_scratch_size))
mstate->dtms_scratch_size)) {
DTRACE_RANGE_REMAIN(remain, addr, mstate->dtms_scratch_base,
mstate->dtms_scratch_size);
return (1);
}
/*
* Now check to see if it's a dynamic variable. This check will pick
@ -804,6 +834,7 @@ dtrace_canstore(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
((dvar->dtdv_tuple.dtt_nkeys - 1) * sizeof (dtrace_key_t)))
return (0);
DTRACE_RANGE_REMAIN(remain, addr, dvar, dstate->dtds_chunksize);
return (1);
}
@ -811,11 +842,11 @@ dtrace_canstore(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
* Finally, check the static local and global variables. These checks
* take the longest, so we perform them last.
*/
if (dtrace_canstore_statvar(addr, sz,
if (dtrace_canstore_statvar(addr, sz, remain,
vstate->dtvs_locals, vstate->dtvs_nlocals))
return (1);
if (dtrace_canstore_statvar(addr, sz,
if (dtrace_canstore_statvar(addr, sz, remain,
vstate->dtvs_globals, vstate->dtvs_nglobals))
return (1);
@ -835,6 +866,17 @@ dtrace_canstore(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
static int
dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
dtrace_vstate_t *vstate)
{
return (dtrace_canload_remains(addr, sz, NULL, mstate, vstate));
}
/*
* Implementation of dtrace_canload which communicates the uppoer bound of the
* allowed memory region.
*/
static int
dtrace_canload_remains(uint64_t addr, size_t sz, size_t *remain,
dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
{
volatile uintptr_t *illval = &cpu_core[curcpu].cpuc_dtrace_illval;
file_t *fp;
@ -843,21 +885,27 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
* If we hold the privilege to read from kernel memory, then
* everything is readable.
*/
if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0) {
DTRACE_RANGE_REMAIN(remain, addr, addr, sz);
return (1);
}
/*
* You can obviously read that which you can store.
*/
if (dtrace_canstore(addr, sz, mstate, vstate))
if (dtrace_canstore_remains(addr, sz, remain, mstate, vstate))
return (1);
/*
* We're allowed to read from our own string table.
*/
if (DTRACE_INRANGE(addr, sz, mstate->dtms_difo->dtdo_strtab,
mstate->dtms_difo->dtdo_strlen))
mstate->dtms_difo->dtdo_strlen)) {
DTRACE_RANGE_REMAIN(remain, addr,
mstate->dtms_difo->dtdo_strtab,
mstate->dtms_difo->dtdo_strlen);
return (1);
}
if (vstate->dtvs_state != NULL &&
dtrace_priv_proc(vstate->dtvs_state)) {
@ -879,27 +927,38 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
* deallocated and reallocated as something else while it's
* being operated upon.
*/
if (DTRACE_INRANGE(addr, sz, curthread, sizeof (kthread_t)))
if (DTRACE_INRANGE(addr, sz, curthread, sizeof (kthread_t))) {
DTRACE_RANGE_REMAIN(remain, addr, curthread,
sizeof (kthread_t));
return (1);
}
if ((p = curthread->t_procp) != NULL && DTRACE_INRANGE(addr,
sz, curthread->t_procp, sizeof (proc_t))) {
DTRACE_RANGE_REMAIN(remain, addr, curthread->t_procp,
sizeof (proc_t));
return (1);
}
if (curthread->t_cred != NULL && DTRACE_INRANGE(addr, sz,
curthread->t_cred, sizeof (cred_t))) {
DTRACE_RANGE_REMAIN(remain, addr, curthread->t_cred,
sizeof (cred_t));
return (1);
}
#ifdef illumos
if (p != NULL && p->p_pidp != NULL && DTRACE_INRANGE(addr, sz,
&(p->p_pidp->pid_id), sizeof (pid_t))) {
DTRACE_RANGE_REMAIN(remain, addr, &(p->p_pidp->pid_id),
sizeof (pid_t));
return (1);
}
if (curthread->t_cpu != NULL && DTRACE_INRANGE(addr, sz,
curthread->t_cpu, offsetof(cpu_t, cpu_pause_thread))) {
DTRACE_RANGE_REMAIN(remain, addr, curthread->t_cpu,
offsetof(cpu_t, cpu_pause_thread));
return (1);
}
#endif
@ -922,31 +981,46 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
* either dtms_getf itself or its f_vnode member to reference
* freed memory).
*/
if (DTRACE_INRANGE(addr, sz, fp, sizeof (file_t)))
if (DTRACE_INRANGE(addr, sz, fp, sizeof (file_t))) {
DTRACE_RANGE_REMAIN(remain, addr, fp, sizeof (file_t));
return (1);
}
if ((vp = fp->f_vnode) != NULL) {
size_t slen;
#ifdef illumos
if (DTRACE_INRANGE(addr, sz, &vp->v_path, psz))
if (DTRACE_INRANGE(addr, sz, &vp->v_path, psz)) {
DTRACE_RANGE_REMAIN(remain, addr, &vp->v_path,
psz);
return (1);
if (vp->v_path != NULL && DTRACE_INRANGE(addr, sz,
vp->v_path, strlen(vp->v_path) + 1)) {
}
slen = strlen(vp->v_path) + 1;
if (DTRACE_INRANGE(addr, sz, vp->v_path, slen)) {
DTRACE_RANGE_REMAIN(remain, addr, vp->v_path,
slen);
return (1);
}
#endif
if (DTRACE_INRANGE(addr, sz, &vp->v_op, psz))
if (DTRACE_INRANGE(addr, sz, &vp->v_op, psz)) {
DTRACE_RANGE_REMAIN(remain, addr, &vp->v_op,
psz);
return (1);
}
#ifdef illumos
if ((op = vp->v_op) != NULL &&
DTRACE_INRANGE(addr, sz, &op->vnop_name, psz)) {
DTRACE_RANGE_REMAIN(remain, addr,
&op->vnop_name, psz);
return (1);
}
if (op != NULL && op->vnop_name != NULL &&
DTRACE_INRANGE(addr, sz, op->vnop_name,
strlen(op->vnop_name) + 1)) {
(slen = strlen(op->vnop_name) + 1))) {
DTRACE_RANGE_REMAIN(remain, addr,
op->vnop_name, slen);
return (1);
}
#endif
@ -965,21 +1039,41 @@ dtrace_canload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
* calls in the event that the user has all privileges.
*/
static int
dtrace_strcanload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
dtrace_vstate_t *vstate)
dtrace_strcanload(uint64_t addr, size_t sz, size_t *remain,
dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
{
size_t strsz;
size_t rsize;
/*
* If we hold the privilege to read from kernel memory, then
* everything is readable.
*/
if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0) {
DTRACE_RANGE_REMAIN(remain, addr, addr, sz);
return (1);
}
strsz = 1 + dtrace_strlen((char *)(uintptr_t)addr, sz);
if (dtrace_canload(addr, strsz, mstate, vstate))
return (1);
/*
* Even if the caller is uninterested in querying the remaining valid
* range, it is required to ensure that the access is allowed.
*/
if (remain == NULL) {
remain = &rsize;
}
if (dtrace_canload_remains(addr, 0, remain, mstate, vstate)) {
size_t strsz;
/*
* Perform the strlen after determining the length of the
* memory region which is accessible. This prevents timing
* information from being used to find NULs in memory which is
* not accessible to the caller.
*/
strsz = 1 + dtrace_strlen((char *)(uintptr_t)addr,
MIN(sz, *remain));
if (strsz <= *remain) {
return (1);
}
}
return (0);
}
@ -989,26 +1083,49 @@ dtrace_strcanload(uint64_t addr, size_t sz, dtrace_mstate_t *mstate,
* region in which a load may be issued given the user's privilege level.
*/
static int
dtrace_vcanload(void *src, dtrace_diftype_t *type, dtrace_mstate_t *mstate,
dtrace_vstate_t *vstate)
dtrace_vcanload(void *src, dtrace_diftype_t *type, size_t *remain,
dtrace_mstate_t *mstate, dtrace_vstate_t *vstate)
{
size_t sz;
ASSERT(type->dtdt_flags & DIF_TF_BYREF);
/*
* Calculate the max size before performing any checks since even
* DTRACE_ACCESS_KERNEL-credentialed callers expect that this function
* return the max length via 'remain'.
*/
if (type->dtdt_kind == DIF_TYPE_STRING) {
dtrace_state_t *state = vstate->dtvs_state;
if (state != NULL) {
sz = state->dts_options[DTRACEOPT_STRSIZE];
} else {
/*
* In helper context, we have a NULL state; fall back
* to using the system-wide default for the string size
* in this case.
*/
sz = dtrace_strsize_default;
}
} else {
sz = type->dtdt_size;
}
/*
* If we hold the privilege to read from kernel memory, then
* everything is readable.
*/
if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0)
if ((mstate->dtms_access & DTRACE_ACCESS_KERNEL) != 0) {
DTRACE_RANGE_REMAIN(remain, (uintptr_t)src, src, sz);
return (1);
}
if (type->dtdt_kind == DIF_TYPE_STRING)
sz = dtrace_strlen(src,
vstate->dtvs_state->dts_options[DTRACEOPT_STRSIZE]) + 1;
else
sz = type->dtdt_size;
return (dtrace_canload((uintptr_t)src, sz, mstate, vstate));
if (type->dtdt_kind == DIF_TYPE_STRING) {
return (dtrace_strcanload((uintptr_t)src, sz, remain, mstate,
vstate));
}
return (dtrace_canload_remains((uintptr_t)src, sz, remain, mstate,
vstate));
}
/*
@ -1198,14 +1315,14 @@ dtrace_strcpy(const void *src, void *dst, size_t len)
* specified type; we assume that we can store to directly.
*/
static void
dtrace_vcopy(void *src, void *dst, dtrace_diftype_t *type)
dtrace_vcopy(void *src, void *dst, dtrace_diftype_t *type, size_t limit)
{
ASSERT(type->dtdt_flags & DIF_TF_BYREF);
if (type->dtdt_kind == DIF_TYPE_STRING) {
dtrace_strcpy(src, dst, type->dtdt_size);
dtrace_strcpy(src, dst, MIN(type->dtdt_size, limit));
} else {
dtrace_bcopy(src, dst, type->dtdt_size);
dtrace_bcopy(src, dst, MIN(type->dtdt_size, limit));
}
}
@ -4503,31 +4620,30 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
uintptr_t kaddr = tupregs[0].dttk_value;
uintptr_t uaddr = tupregs[1].dttk_value;
uint64_t size = tupregs[2].dttk_value;
size_t lim;
if (!dtrace_destructive_disallow &&
dtrace_priv_proc_control(state) &&
!dtrace_istoxic(kaddr, size) &&
dtrace_strcanload(kaddr, size, mstate, vstate)) {
dtrace_strcanload(kaddr, size, &lim, mstate, vstate)) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
dtrace_copyoutstr(kaddr, uaddr, size, flags);
dtrace_copyoutstr(kaddr, uaddr, lim, flags);
DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
}
break;
}
case DIF_SUBR_STRLEN: {
size_t sz;
size_t size = state->dts_options[DTRACEOPT_STRSIZE];
uintptr_t addr = (uintptr_t)tupregs[0].dttk_value;
sz = dtrace_strlen((char *)addr,
state->dts_options[DTRACEOPT_STRSIZE]);
size_t lim;
if (!dtrace_canload(addr, sz + 1, mstate, vstate)) {
if (!dtrace_strcanload(addr, size, &lim, mstate, vstate)) {
regs[rd] = 0;
break;
}
regs[rd] = sz;
regs[rd] = dtrace_strlen((char *)addr, lim);
break;
}
@ -4540,12 +4656,19 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
* is DIF_SUBR_STRRCHR, we will look for the last occurrence
* of the specified character instead of the first.
*/
uintptr_t saddr = tupregs[0].dttk_value;
uintptr_t addr = tupregs[0].dttk_value;
uintptr_t limit = addr + state->dts_options[DTRACEOPT_STRSIZE];
uintptr_t addr_limit;
uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
size_t lim;
char c, target = (char)tupregs[1].dttk_value;
for (regs[rd] = 0; addr < limit; addr++) {
if (!dtrace_strcanload(addr, size, &lim, mstate, vstate)) {
regs[rd] = 0;
break;
}
addr_limit = addr + lim;
for (regs[rd] = 0; addr < addr_limit; addr++) {
if ((c = dtrace_load8(addr)) == target) {
regs[rd] = addr;
@ -4556,12 +4679,6 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
if (c == '\0')
break;
}
if (!dtrace_canload(saddr, addr - saddr, mstate, vstate)) {
regs[rd] = 0;
break;
}
break;
}
@ -4719,7 +4836,8 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
uintptr_t addr = tupregs[0].dttk_value;
uintptr_t tokaddr = tupregs[1].dttk_value;
uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
uintptr_t limit, toklimit = tokaddr + size;
uintptr_t limit, toklimit;
size_t clim;
uint8_t c = 0, tokmap[32]; /* 256 / 8 */
char *dest = (char *)mstate->dtms_scratch_ptr;
int i;
@ -4728,10 +4846,11 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
* Check both the token buffer and (later) the input buffer,
* since both could be non-scratch addresses.
*/
if (!dtrace_strcanload(tokaddr, size, mstate, vstate)) {
if (!dtrace_strcanload(tokaddr, size, &clim, mstate, vstate)) {
regs[rd] = 0;
break;
}
toklimit = tokaddr + clim;
if (!DTRACE_INSCRATCH(mstate, size)) {
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOSCRATCH);
@ -4748,6 +4867,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
* it behaves like an implicit clause-local variable.
*/
addr = mstate->dtms_strtok;
limit = mstate->dtms_strtok_limit;
} else {
/*
* If the user-specified address is non-NULL we must
@ -4757,10 +4877,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
* (when we fetch addr from mstate->dtms_strtok)
* would fail this access check.
*/
if (!dtrace_strcanload(addr, size, mstate, vstate)) {
if (!dtrace_strcanload(addr, size, &clim, mstate,
vstate)) {
regs[rd] = 0;
break;
}
limit = addr + clim;
}
/*
@ -4779,10 +4901,10 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
tokmap[c >> 3] |= (1 << (c & 0x7));
}
for (limit = addr + size; addr < limit; addr++) {
for (; addr < limit; addr++) {
/*
* We're looking for a character that is _not_ contained
* in the token string.
* We're looking for a character that is _not_
* contained in the token string.
*/
if ((c = dtrace_load8(addr)) == '\0')
break;
@ -4800,6 +4922,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
*/
regs[rd] = 0;
mstate->dtms_strtok = 0;
mstate->dtms_strtok_limit = 0;
break;
}
@ -4822,6 +4945,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
regs[rd] = (uintptr_t)dest;
mstate->dtms_scratch_ptr += size;
mstate->dtms_strtok = addr;
mstate->dtms_strtok_limit = limit;
break;
}
@ -5199,10 +5323,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
uintptr_t s1 = tupregs[0].dttk_value;
uintptr_t s2 = tupregs[1].dttk_value;
int i = 0;
int i = 0, j = 0;
size_t lim1, lim2;
char c;
if (!dtrace_strcanload(s1, size, mstate, vstate) ||
!dtrace_strcanload(s2, size, mstate, vstate)) {
if (!dtrace_strcanload(s1, size, &lim1, mstate, vstate) ||
!dtrace_strcanload(s2, size, &lim2, mstate, vstate)) {
regs[rd] = 0;
break;
}
@ -5219,8 +5345,8 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
regs[rd] = 0;
break;
}
if ((d[i++] = dtrace_load8(s1++)) == '\0') {
c = (i >= lim1) ? '\0' : dtrace_load8(s1++);
if ((d[i++] = c) == '\0') {
i--;
break;
}
@ -5233,7 +5359,8 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
break;
}
if ((d[i++] = dtrace_load8(s2++)) == '\0')
c = (j++ >= lim2) ? '\0' : dtrace_load8(s2++);
if ((d[i++] = c) == '\0')
break;
}
@ -5248,6 +5375,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
case DIF_SUBR_STRTOLL: {
uintptr_t s = tupregs[0].dttk_value;
uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
size_t lim;
int base = 10;
if (nargs > 1) {
@ -5258,12 +5386,12 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
}
}
if (!dtrace_strcanload(s, size, mstate, vstate)) {
if (!dtrace_strcanload(s, size, &lim, mstate, vstate)) {
regs[rd] = INT64_MIN;
break;
}
regs[rd] = dtrace_strtoll((char *)s, base, size);
regs[rd] = dtrace_strtoll((char *)s, base, lim);
break;
}
@ -5498,12 +5626,13 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
char *dest = (char *)mstate->dtms_scratch_ptr, c;
uint64_t size = state->dts_options[DTRACEOPT_STRSIZE];
uintptr_t src = tupregs[0].dttk_value;
size_t lim;
int i = 0, j = 0;
#ifdef illumos
zone_t *z;
#endif
if (!dtrace_strcanload(src, size, mstate, vstate)) {
if (!dtrace_strcanload(src, size, &lim, mstate, vstate)) {
regs[rd] = 0;
break;
}
@ -5518,7 +5647,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
* Move forward, loading each character.
*/
do {
c = dtrace_load8(src + i++);
c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
next:
if (j + 5 >= size) /* 5 = strlen("/..c\0") */
break;
@ -5528,7 +5657,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
continue;
}
c = dtrace_load8(src + i++);
c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
if (c == '/') {
/*
@ -5549,7 +5678,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
continue;
}
c = dtrace_load8(src + i++);
c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
if (c == '/') {
/*
@ -5572,7 +5701,7 @@ dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
continue;
}
c = dtrace_load8(src + i++);
c = (i >= lim) ? '\0' : dtrace_load8(src + i++);
if (c != '/' && c != '\0') {
/*
@ -6211,15 +6340,17 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
size_t sz = state->dts_options[DTRACEOPT_STRSIZE];
uintptr_t s1 = regs[r1];
uintptr_t s2 = regs[r2];
size_t lim1, lim2;
if (s1 != 0 &&
!dtrace_strcanload(s1, sz, mstate, vstate))
!dtrace_strcanload(s1, sz, &lim1, mstate, vstate))
break;
if (s2 != 0 &&
!dtrace_strcanload(s2, sz, mstate, vstate))
!dtrace_strcanload(s2, sz, &lim2, mstate, vstate))
break;
cc_r = dtrace_strncmp((char *)s1, (char *)s2, sz);
cc_r = dtrace_strncmp((char *)s1, (char *)s2,
MIN(lim1, lim2));
cc_n = cc_r < 0;
cc_z = cc_r == 0;
@ -6278,6 +6409,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
uintptr_t a = (uintptr_t)svar->dtsv_data;
size_t lim;
ASSERT(a != 0);
ASSERT(svar->dtsv_size != 0);
@ -6291,11 +6423,11 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
}
if (!dtrace_vcanload(
(void *)(uintptr_t)regs[rd], &v->dtdv_type,
mstate, vstate))
&lim, mstate, vstate))
break;
dtrace_vcopy((void *)(uintptr_t)regs[rd],
(void *)a, &v->dtdv_type);
(void *)a, &v->dtdv_type, lim);
break;
}
@ -6334,6 +6466,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
uintptr_t a = (uintptr_t)svar->dtsv_data;
size_t sz = v->dtdv_type.dtdt_size;
size_t lim;
sz += sizeof (uint64_t);
ASSERT(svar->dtsv_size == NCPU * sz);
@ -6373,6 +6506,7 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
uintptr_t a = (uintptr_t)svar->dtsv_data;
size_t sz = v->dtdv_type.dtdt_size;
size_t lim;
sz += sizeof (uint64_t);
ASSERT(svar->dtsv_size == NCPU * sz);
@ -6388,11 +6522,11 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
if (!dtrace_vcanload(
(void *)(uintptr_t)regs[rd], &v->dtdv_type,
mstate, vstate))
&lim, mstate, vstate))
break;
dtrace_vcopy((void *)(uintptr_t)regs[rd],
(void *)a, &v->dtdv_type);
(void *)a, &v->dtdv_type, lim);
break;
}
@ -6466,13 +6600,15 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
break;
if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
size_t lim;
if (!dtrace_vcanload(
(void *)(uintptr_t)regs[rd],
&v->dtdv_type, mstate, vstate))
&v->dtdv_type, &lim, mstate, vstate))
break;
dtrace_vcopy((void *)(uintptr_t)regs[rd],
dvar->dtdv_data, &v->dtdv_type);
dvar->dtdv_data, &v->dtdv_type, lim);
} else {
*((uint64_t *)dvar->dtdv_data) = regs[rd];
}
@ -6614,13 +6750,15 @@ dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
break;
if (v->dtdv_type.dtdt_flags & DIF_TF_BYREF) {
size_t lim;
if (!dtrace_vcanload(
(void *)(uintptr_t)regs[rd], &v->dtdv_type,
mstate, vstate))
&lim, mstate, vstate))
break;
dtrace_vcopy((void *)(uintptr_t)regs[rd],
dvar->dtdv_data, &v->dtdv_type);
dvar->dtdv_data, &v->dtdv_type, lim);
} else {
*((uint64_t *)dvar->dtdv_data) = regs[rd];
}
@ -6929,6 +7067,7 @@ dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state,
uint64_t *pcs = &buf[1], *fps;
char *str = (char *)&pcs[nframes];
int size, offs = 0, i, j;
size_t rem;
uintptr_t old = mstate->dtms_scratch_ptr, saved;
uint16_t *flags = &cpu_core[curcpu].cpuc_dtrace_flags;
char *sym;
@ -7000,12 +7139,18 @@ dtrace_action_ustack(dtrace_mstate_t *mstate, dtrace_state_t *state,
continue;
}
if (!dtrace_strcanload((uintptr_t)sym, strsize, &rem, mstate,
&(state->dts_vstate))) {
str[offs++] = '\0';
continue;
}
DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
/*
* Now copy in the string that the helper returned to us.
*/
for (j = 0; offs + j < strsize; j++) {
for (j = 0; offs + j < strsize && j < rem; j++) {
if ((str[offs + j] = sym[j]) == '\0')
break;
}
@ -7740,7 +7885,7 @@ dtrace_probe(dtrace_id_t id, uintptr_t arg0, uintptr_t arg1,
if (dp->dtdo_rtype.dtdt_flags & DIF_TF_BYREF &&
!dtrace_vcanload((void *)(uintptr_t)val,
&dp->dtdo_rtype, &mstate, vstate))
&dp->dtdo_rtype, NULL, &mstate, vstate))
continue;
dtrace_store_by_ref(dp, tomax, size, &valoffs,
@ -11017,7 +11162,7 @@ dtrace_ecb_enable(dtrace_ecb_t *ecb)
}
}
static void
static int
dtrace_ecb_resize(dtrace_ecb_t *ecb)
{
dtrace_action_t *act;
@ -11051,6 +11196,8 @@ dtrace_ecb_resize(dtrace_ecb_t *ecb)
curneeded = P2ROUNDUP(curneeded, rec->dtrd_alignment);
rec->dtrd_offset = curneeded;
if (curneeded + rec->dtrd_size < curneeded)
return (EINVAL);
curneeded += rec->dtrd_size;
ecb->dte_needed = MAX(ecb->dte_needed, curneeded);
@ -11075,6 +11222,8 @@ dtrace_ecb_resize(dtrace_ecb_t *ecb)
}
curneeded = P2ROUNDUP(curneeded, rec->dtrd_alignment);
rec->dtrd_offset = curneeded;
if (curneeded + rec->dtrd_size < curneeded)
return (EINVAL);
curneeded += rec->dtrd_size;
} else {
/* tuples must be followed by an aggregation */
@ -11084,6 +11233,8 @@ dtrace_ecb_resize(dtrace_ecb_t *ecb)
ecb->dte_size = P2ROUNDUP(ecb->dte_size,
rec->dtrd_alignment);
rec->dtrd_offset = ecb->dte_size;
if (ecb->dte_size + rec->dtrd_size < ecb->dte_size)
return (EINVAL);
ecb->dte_size += rec->dtrd_size;
ecb->dte_needed = MAX(ecb->dte_needed, ecb->dte_size);
}
@ -11103,6 +11254,7 @@ dtrace_ecb_resize(dtrace_ecb_t *ecb)
ecb->dte_needed = P2ROUNDUP(ecb->dte_needed, (sizeof (dtrace_epid_t)));
ecb->dte_state->dts_needed = MAX(ecb->dte_state->dts_needed,
ecb->dte_needed);
return (0);
}
static dtrace_action_t *
@ -11788,7 +11940,10 @@ dtrace_ecb_create(dtrace_state_t *state, dtrace_probe_t *probe,
}
}
dtrace_ecb_resize(ecb);
if ((enab->dten_error = dtrace_ecb_resize(ecb)) != 0) {
dtrace_ecb_destroy(ecb);
return (NULL);
}
return (dtrace_ecb_create_cache = ecb);
}

View File

@ -23,12 +23,12 @@
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright (c) 2011, Joyent, Inc. All rights reserved.
* Copyright 2016 Joyent, Inc.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/
#ifndef _SYS_DTRACE_IMPL_H
@ -932,6 +932,7 @@ typedef struct dtrace_mstate {
int dtms_ipl; /* cached interrupt pri lev */
int dtms_fltoffs; /* faulting DIFO offset */
uintptr_t dtms_strtok; /* saved strtok() pointer */
uintptr_t dtms_strtok_limit; /* upper bound of strtok ptr */
uint32_t dtms_access; /* memory access rights */
dtrace_difo_t *dtms_difo; /* current dif object */
file_t *dtms_getf; /* cached rval of getf() */

View File

@ -172,12 +172,8 @@ int
cloudabi_sys_fd_datasync(struct thread *td,
struct cloudabi_sys_fd_datasync_args *uap)
{
struct fsync_args fsync_args = {
.fd = uap->fd
};
/* Call into fsync(), as FreeBSD lacks fdatasync(). */
return (sys_fsync(td, &fsync_args));
return (kern_fsync(td, uap->fd, false));
}
int
@ -557,9 +553,6 @@ cloudabi_sys_fd_stat_put(struct thread *td,
int
cloudabi_sys_fd_sync(struct thread *td, struct cloudabi_sys_fd_sync_args *uap)
{
struct fsync_args fsync_args = {
.fd = uap->fd
};
return (sys_fsync(td, &fsync_args));
return (kern_fsync(td, uap->fd, true));
}

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 303699 2016-08-03 06:33:04Z ed
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 304176 2016-08-15 19:08:51Z kib
*/
#ifndef _FREEBSD32_SYSPROTO_H_

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 303699 2016-08-03 06:33:04Z ed
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 304176 2016-08-15 19:08:51Z kib
*/
#define FREEBSD32_SYS_syscall 0
@ -457,4 +457,5 @@
#define FREEBSD32_SYS_freebsd32_utimensat 547
#define FREEBSD32_SYS_numa_getaffinity 548
#define FREEBSD32_SYS_numa_setaffinity 549
#define FREEBSD32_SYS_MAXSYSCALL 550
#define FREEBSD32_SYS_fdatasync 550
#define FREEBSD32_SYS_MAXSYSCALL 551

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 303699 2016-08-03 06:33:04Z ed
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 304176 2016-08-15 19:08:51Z kib
*/
const char *freebsd32_syscallnames[] = {
@ -583,4 +583,5 @@ const char *freebsd32_syscallnames[] = {
"freebsd32_utimensat", /* 547 = freebsd32_utimensat */
"numa_getaffinity", /* 548 = numa_getaffinity */
"numa_setaffinity", /* 549 = numa_setaffinity */
"fdatasync", /* 550 = fdatasync */
};

View File

@ -3,7 +3,7 @@
*
* DO NOT EDIT-- this file is automatically generated.
* $FreeBSD$
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 303699 2016-08-03 06:33:04Z ed
* created from FreeBSD: head/sys/compat/freebsd32/syscalls.master 304176 2016-08-15 19:08:51Z kib
*/
#include "opt_compat.h"
@ -626,4 +626,5 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_utimensat_args), (sy_call_t *)freebsd32_utimensat, AUE_FUTIMESAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 547 = freebsd32_utimensat */
{ AS(numa_getaffinity_args), (sy_call_t *)sys_numa_getaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 548 = numa_getaffinity */
{ AS(numa_setaffinity_args), (sy_call_t *)sys_numa_setaffinity, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 549 = numa_setaffinity */
{ AS(fdatasync_args), (sy_call_t *)sys_fdatasync, AUE_FSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 550 = fdatasync */
};

View File

@ -3316,6 +3316,13 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args)
*n_args = 3;
break;
}
/* fdatasync */
case 550: {
struct fdatasync_args *p = params;
iarg[0] = p->fd; /* int */
*n_args = 1;
break;
}
default:
*n_args = 0;
break;
@ -8902,6 +8909,16 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
break;
};
break;
/* fdatasync */
case 550:
switch(ndx) {
case 0:
p = "int";
break;
default:
break;
};
break;
default:
break;
};
@ -10783,6 +10800,11 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz)
if (ndx == 0 || ndx == 1)
p = "int";
break;
/* fdatasync */
case 550:
if (ndx == 0 || ndx == 1)
p = "int";
break;
default:
break;
};

View File

@ -1081,3 +1081,4 @@
549 AUE_NULL NOPROTO { int numa_setaffinity(cpuwhich_t which, \
id_t id, \
const struct vm_domain_policy *policy); }
550 AUE_FSYNC NOPROTO { int fdatasync(int fd); }

View File

@ -1013,10 +1013,8 @@ linux_fdatasync(td, uap)
struct thread *td;
struct linux_fdatasync_args *uap;
{
struct fsync_args bsd;
bsd.fd = uap->fd;
return (sys_fsync(td, &bsd));
return (kern_fsync(td, uap->fd, false));
}
int

View File

@ -2412,15 +2412,10 @@ options SND_OLDSTEREO
# Miscellaneous hardware:
#
# scd: Sony CD-ROM using proprietary (non-ATAPI) interface
# mcd: Mitsumi CD-ROM using proprietary (non-ATAPI) interface
# bktr: Brooktree bt848/848a/849a/878/879 video capture and TV Tuner board
# joy: joystick (including IO DATA PCJOY PC Card joystick)
# cmx: OmniKey CardMan 4040 pccard smartcard reader
# Mitsumi CD-ROM
device mcd
hint.mcd.0.at="isa"
hint.mcd.0.port="0x300"
# for the Sony CDU31/33A CDROM
device scd
hint.scd.0.at="isa"

View File

@ -2018,8 +2018,6 @@ dev/malo/if_malohal.c optional malo
dev/malo/if_malo_pci.c optional malo pci
dev/mc146818/mc146818.c optional mc146818
dev/mca/mca_bus.c optional mca
dev/mcd/mcd.c optional mcd isa nowerror
dev/mcd/mcd_isa.c optional mcd isa nowerror
dev/md/md.c optional md
dev/mdio/mdio_if.m optional miiproxy | mdio
dev/mdio/mdio.c optional miiproxy | mdio

View File

@ -418,6 +418,7 @@ IPFILTER_LOOKUP opt_ipfilter.h
IPFIREWALL opt_ipfw.h
IPFIREWALL_DEFAULT_TO_ACCEPT opt_ipfw.h
IPFIREWALL_NAT opt_ipfw.h
IPFIREWALL_NAT64 opt_ipfw.h
IPFIREWALL_NAT64_DIRECT_OUTPUT opt_ipfw.h
IPFIREWALL_NPTV6 opt_ipfw.h
IPFIREWALL_VERBOSE opt_ipfw.h

View File

@ -215,6 +215,8 @@ struct sge_params {
int pad_boundary;
int pack_boundary;
int fl_pktshift;
u32 sge_control;
u32 sge_fl_buffer_size[SGE_FLBUF_SIZES];
};
struct tp_params {

View File

@ -289,6 +289,14 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
if ((size & 15) || size > MBOX_LEN)
return -EINVAL;
if (adap->flags & IS_VF) {
if (is_t6(adap))
data_reg = FW_T6VF_MBDATA_BASE_ADDR;
else
data_reg = FW_T4VF_MBDATA_BASE_ADDR;
ctl_reg = VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL);
}
/*
* If we have a negative timeout, that implies that we can't sleep.
*/
@ -343,6 +351,22 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
for (i = 0; i < size; i += 8, p++)
t4_write_reg64(adap, data_reg + i, be64_to_cpu(*p));
if (adap->flags & IS_VF) {
/*
* For the VFs, the Mailbox Data "registers" are
* actually backed by T4's "MA" interface rather than
* PL Registers (as is the case for the PFs). Because
* these are in different coherency domains, the write
* to the VF's PL-register-backed Mailbox Control can
* race in front of the writes to the MA-backed VF
* Mailbox Data "registers". So we need to do a
* read-back on at least one byte of the VF Mailbox
* Data registers before doing the write to the VF
* Mailbox Control register.
*/
t4_read_reg(adap, data_reg);
}
CH_DUMP_MBOX(adap, mbox, data_reg);
t4_write_reg(adap, ctl_reg, F_MBMSGVALID | V_MBOWNER(X_MBOWNER_FW));
@ -355,10 +379,13 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd,
* Loop waiting for the reply; bail out if we time out or the firmware
* reports an error.
*/
for (i = 0;
!((pcie_fw = t4_read_reg(adap, A_PCIE_FW)) & F_PCIE_FW_ERR) &&
i < timeout;
i += ms) {
pcie_fw = 0;
for (i = 0; i < timeout; i += ms) {
if (!(adap->flags & IS_VF)) {
pcie_fw = t4_read_reg(adap, A_PCIE_FW);
if (pcie_fw & F_PCIE_FW_ERR)
break;
}
if (sleep_ok) {
ms = delay[delay_idx]; /* last element may repeat */
if (delay_idx < ARRAY_SIZE(delay) - 1)
@ -698,10 +725,14 @@ unsigned int t4_get_regs_len(struct adapter *adapter)
switch (chip_version) {
case CHELSIO_T4:
if (adapter->flags & IS_VF)
return FW_T4VF_REGMAP_SIZE;
return T4_REGMAP_SIZE;
case CHELSIO_T5:
case CHELSIO_T6:
if (adapter->flags & IS_VF)
return FW_T4VF_REGMAP_SIZE;
return T5_REGMAP_SIZE;
}
@ -1180,6 +1211,18 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size)
0x27e00, 0x27e04,
};
static const unsigned int t4vf_reg_ranges[] = {
VF_SGE_REG(A_SGE_VF_KDOORBELL), VF_SGE_REG(A_SGE_VF_GTS),
VF_MPS_REG(A_MPS_VF_CTL),
VF_MPS_REG(A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H),
VF_PL_REG(A_PL_VF_WHOAMI), VF_PL_REG(A_PL_VF_WHOAMI),
VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL),
VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_STATUS),
FW_T4VF_MBDATA_BASE_ADDR,
FW_T4VF_MBDATA_BASE_ADDR +
((NUM_CIM_PF_MAILBOX_DATA_INSTANCES - 1) * 4),
};
static const unsigned int t5_reg_ranges[] = {
0x1008, 0x10c0,
0x10cc, 0x10f8,
@ -1955,6 +1998,18 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size)
0x51300, 0x51308,
};
static const unsigned int t5vf_reg_ranges[] = {
VF_SGE_REG(A_SGE_VF_KDOORBELL), VF_SGE_REG(A_SGE_VF_GTS),
VF_MPS_REG(A_MPS_VF_CTL),
VF_MPS_REG(A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H),
VF_PL_REG(A_PL_VF_WHOAMI), VF_PL_REG(A_PL_VF_REVISION),
VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL),
VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_STATUS),
FW_T4VF_MBDATA_BASE_ADDR,
FW_T4VF_MBDATA_BASE_ADDR +
((NUM_CIM_PF_MAILBOX_DATA_INSTANCES - 1) * 4),
};
static const unsigned int t6_reg_ranges[] = {
0x1008, 0x101c,
0x1024, 0x10a8,
@ -2532,6 +2587,18 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size)
0x51300, 0x51324,
};
static const unsigned int t6vf_reg_ranges[] = {
VF_SGE_REG(A_SGE_VF_KDOORBELL), VF_SGE_REG(A_SGE_VF_GTS),
VF_MPS_REG(A_MPS_VF_CTL),
VF_MPS_REG(A_MPS_VF_STAT_RX_VF_ERR_FRAMES_H),
VF_PL_REG(A_PL_VF_WHOAMI), VF_PL_REG(A_PL_VF_REVISION),
VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_CTRL),
VF_CIM_REG(A_CIM_VF_EXT_MAILBOX_STATUS),
FW_T6VF_MBDATA_BASE_ADDR,
FW_T6VF_MBDATA_BASE_ADDR +
((NUM_CIM_PF_MAILBOX_DATA_INSTANCES - 1) * 4),
};
u32 *buf_end = (u32 *)(buf + buf_size);
const unsigned int *reg_ranges;
int reg_ranges_size, range;
@ -2543,18 +2610,33 @@ void t4_get_regs(struct adapter *adap, u8 *buf, size_t buf_size)
*/
switch (chip_version) {
case CHELSIO_T4:
reg_ranges = t4_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t4_reg_ranges);
if (adap->flags & IS_VF) {
reg_ranges = t4vf_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t4vf_reg_ranges);
} else {
reg_ranges = t4_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t4_reg_ranges);
}
break;
case CHELSIO_T5:
reg_ranges = t5_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t5_reg_ranges);
if (adap->flags & IS_VF) {
reg_ranges = t5vf_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t5vf_reg_ranges);
} else {
reg_ranges = t5_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t5_reg_ranges);
}
break;
case CHELSIO_T6:
reg_ranges = t6_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t6_reg_ranges);
if (adap->flags & IS_VF) {
reg_ranges = t6vf_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t6vf_reg_ranges);
} else {
reg_ranges = t6_reg_ranges;
reg_ranges_size = ARRAY_SIZE(t6_reg_ranges);
}
break;
default:
@ -7644,6 +7726,7 @@ int t4_init_sge_params(struct adapter *adapter)
{
u32 r;
struct sge_params *sp = &adapter->params.sge;
unsigned i;
r = t4_read_reg(adapter, A_SGE_INGRESS_RX_THRESHOLD);
sp->counter_val[0] = G_THRESHOLD_0(r);
@ -7686,6 +7769,7 @@ int t4_init_sge_params(struct adapter *adapter)
sp->page_shift = (r & M_HOSTPAGESIZEPF0) + 10;
r = t4_read_reg(adapter, A_SGE_CONTROL);
sp->sge_control = r;
sp->spg_len = r & F_EGRSTATUSPAGESIZE ? 128 : 64;
sp->fl_pktshift = G_PKTSHIFT(r);
sp->pad_boundary = 1 << (G_INGPADBOUNDARY(r) + 5);
@ -7698,6 +7782,9 @@ int t4_init_sge_params(struct adapter *adapter)
else
sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(r) + 5);
}
for (i = 0; i < SGE_FLBUF_SIZES; i++)
sp->sge_fl_buffer_size[i] = t4_read_reg(adapter,
A_SGE_FL_BUFFER_SIZE0 + (4 * i));
return 0;
}

View File

@ -3332,6 +3332,8 @@ get_params__post_init(struct adapter *sc)
sc->vres.iscsi.size = val[1] - val[0] + 1;
}
t4_init_sge_params(sc);
/*
* We've got the params we wanted to query via the firmware. Now grab
* some others directly from the chip.
@ -8763,7 +8765,7 @@ t4_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data, int fflag,
}
case CHELSIO_T4_REGDUMP: {
struct t4_regdump *regs = (struct t4_regdump *)data;
int reglen = is_t4(sc) ? T4_REGDUMP_SIZE : T5_REGDUMP_SIZE;
int reglen = t4_get_regs_len(sc);
uint8_t *buf;
if (regs->len < reglen) {

View File

@ -625,11 +625,9 @@ t4_read_chip_settings(struct adapter *sc)
struct sw_zone_info *swz, *safe_swz;
struct hw_buf_info *hwb;
t4_init_sge_params(sc);
m = F_RXPKTCPLMODE;
v = F_RXPKTCPLMODE;
r = t4_read_reg(sc, A_SGE_CONTROL);
r = sc->params.sge.sge_control;
if ((r & m) != v) {
device_printf(sc->dev, "invalid SGE_CONTROL(0x%x)\n", r);
rc = EINVAL;
@ -647,7 +645,7 @@ t4_read_chip_settings(struct adapter *sc)
/* Filter out unusable hw buffer sizes entirely (mark with -2). */
hwb = &s->hw_buf_info[0];
for (i = 0; i < nitems(s->hw_buf_info); i++, hwb++) {
r = t4_read_reg(sc, A_SGE_FL_BUFFER_SIZE0 + (4 * i));
r = sc->params.sge.sge_fl_buffer_size[i];
hwb->size = r;
hwb->zidx = hwsz_ok(sc, r) ? -1 : -2;
hwb->next = -1;

View File

@ -304,6 +304,10 @@ s32 e1000_set_mac_type(struct e1000_hw *hw)
case E1000_DEV_ID_PCH_SPT_I219_LM2:
case E1000_DEV_ID_PCH_SPT_I219_V2:
case E1000_DEV_ID_PCH_LBG_I219_LM3:
case E1000_DEV_ID_PCH_SPT_I219_LM4:
case E1000_DEV_ID_PCH_SPT_I219_V4:
case E1000_DEV_ID_PCH_SPT_I219_LM5:
case E1000_DEV_ID_PCH_SPT_I219_V5:
mac->type = e1000_pch_spt;
break;
case E1000_DEV_ID_82575EB_COPPER:

View File

@ -142,6 +142,10 @@ struct e1000_hw;
#define E1000_DEV_ID_PCH_SPT_I219_LM2 0x15B7 /* Sunrise Point-H PCH */
#define E1000_DEV_ID_PCH_SPT_I219_V2 0x15B8 /* Sunrise Point-H PCH */
#define E1000_DEV_ID_PCH_LBG_I219_LM3 0x15B9 /* LEWISBURG PCH */
#define E1000_DEV_ID_PCH_SPT_I219_LM4 0x15D7
#define E1000_DEV_ID_PCH_SPT_I219_V4 0x15D8
#define E1000_DEV_ID_PCH_SPT_I219_LM5 0x15E3
#define E1000_DEV_ID_PCH_SPT_I219_V5 0x15D6
#define E1000_DEV_ID_82576 0x10C9
#define E1000_DEV_ID_82576_FIBER 0x10E6
#define E1000_DEV_ID_82576_SERDES 0x10E7
@ -957,9 +961,13 @@ struct e1000_dev_spec_ich8lan {
E1000_MUTEX nvm_mutex;
E1000_MUTEX swflag_mutex;
bool nvm_k1_enabled;
bool disable_k1_off;
bool eee_disable;
u16 eee_lp_ability;
enum e1000_ulp_state ulp_state;
bool ulp_capability_disabled;
bool during_suspend_flow;
bool during_dpg_exit;
};
struct e1000_dev_spec_82575 {

View File

@ -288,7 +288,7 @@ static void e1000_toggle_lanphypc_pch_lpt(struct e1000_hw *hw)
mac_reg &= ~E1000_CTRL_LANPHYPC_VALUE;
E1000_WRITE_REG(hw, E1000_CTRL, mac_reg);
E1000_WRITE_FLUSH(hw);
usec_delay(10);
msec_delay(1);
mac_reg &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
E1000_WRITE_REG(hw, E1000_CTRL, mac_reg);
E1000_WRITE_FLUSH(hw);
@ -1625,7 +1625,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
hw->phy.ops.write_reg_locked(hw,
I217_PLL_CLOCK_GATE_REG,
phy_reg);
}
if (speed == SPEED_1000) {
hw->phy.ops.read_reg_locked(hw, HV_PM_CTRL,
&phy_reg);
phy_reg |= HV_PM_CTRL_K1_CLK_REQ;
hw->phy.ops.write_reg_locked(hw, HV_PM_CTRL,
phy_reg);
}
}
hw->phy.ops.release(hw);
if (ret_val)
@ -1718,7 +1728,8 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
u32 pcieanacfg = E1000_READ_REG(hw, E1000_PCIEANACFG);
u32 fextnvm6 = E1000_READ_REG(hw, E1000_FEXTNVM6);
if (pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE)
if ((pcieanacfg & E1000_FEXTNVM6_K1_OFF_ENABLE) &&
(hw->dev_spec.ich8lan.disable_k1_off == FALSE))
fextnvm6 |= E1000_FEXTNVM6_K1_OFF_ENABLE;
else
fextnvm6 &= ~E1000_FEXTNVM6_K1_OFF_ENABLE;

View File

@ -239,7 +239,7 @@
/* PHY Power Management Control */
#define HV_PM_CTRL PHY_REG(770, 17)
#define HV_PM_CTRL_PLL_STOP_IN_K1_GIGA 0x100
#define HV_PM_CTRL_K1_CLK_REQ 0x200
#define HV_PM_CTRL_K1_ENABLE 0x4000
#define I217_PLL_CLOCK_GATE_REG PHY_REG(772, 28)

View File

@ -4146,12 +4146,13 @@ s32 e1000_read_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 *data)
*data = E1000_READ_REG(hw, E1000_MPHY_DATA);
/* Disable access to mPHY if it was originally disabled */
if (locked) {
if (locked)
ready = e1000_is_mphy_ready(hw);
if (!ready)
return -E1000_ERR_PHY;
}
E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, E1000_MPHY_DIS_ACCESS);
if (!ready)
return -E1000_ERR_PHY;
E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
E1000_MPHY_DIS_ACCESS);
return E1000_SUCCESS;
}
@ -4210,12 +4211,13 @@ s32 e1000_write_phy_reg_mphy(struct e1000_hw *hw, u32 address, u32 data,
E1000_WRITE_REG(hw, E1000_MPHY_DATA, data);
/* Disable access to mPHY if it was originally disabled */
if (locked) {
if (locked)
ready = e1000_is_mphy_ready(hw);
if (!ready)
return -E1000_ERR_PHY;
}
E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL, E1000_MPHY_DIS_ACCESS);
if (!ready)
return -E1000_ERR_PHY;
E1000_WRITE_REG(hw, E1000_MPHY_ADDR_CTRL,
E1000_MPHY_DIS_ACCESS);
return E1000_SUCCESS;
}

View File

@ -193,6 +193,12 @@ static em_vendor_info_t em_vendor_info_array[] =
{ 0x8086, E1000_DEV_ID_PCH_SPT_I219_V2, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_LBG_I219_LM3,
PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_SPT_I219_LM4,
PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_SPT_I219_V4, PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_SPT_I219_LM5,
PCI_ANY_ID, PCI_ANY_ID, 0},
{ 0x8086, E1000_DEV_ID_PCH_SPT_I219_V5, PCI_ANY_ID, PCI_ANY_ID, 0},
/* required last entry */
{ 0, 0, 0, 0, 0}
};

View File

@ -83,6 +83,7 @@ struct vmbus_chanpkt_hdr {
#define VMBUS_CHANPKT_TYPE_GPA 0x0009
#define VMBUS_CHANPKT_TYPE_COMP 0x000b
#define VMBUS_CHANPKT_FLAG_NONE 0
#define VMBUS_CHANPKT_FLAG_RC 0x0001 /* report completion */
#define VMBUS_CHANPKT_CONST_DATA(pkt) \

View File

@ -73,9 +73,6 @@ static void hv_nv_on_receive(netvsc_dev *net_dev,
static void hn_nvs_sent_none(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
const struct nvsp_msg_ *msg, int);
static void hn_nvs_sent_xact(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
const struct nvsp_msg_ *msg, int dlen);
static struct hn_send_ctx hn_send_ctx_none =
HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL);
@ -121,7 +118,7 @@ hv_nv_get_next_send_section(netvsc_dev *net_dev)
unsigned long bitsmap_words = net_dev->bitsmap_words;
unsigned long *bitsmap = net_dev->send_section_bitsmap;
unsigned long idx;
int ret = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
int ret = HN_NVS_CHIM_IDX_INVALID;
int i;
for (i = 0; i < bitsmap_words; i++) {
@ -209,9 +206,8 @@ hv_nv_init_rx_buffer_with_net_vsp(struct hn_softc *sc)
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
error = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
conn, sizeof(*conn), (uint64_t)(uintptr_t)&sndc);
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
conn, sizeof(*conn), &sndc);
if (error != 0) {
if_printf(sc->hn_ifp, "send nvs rxbuf conn failed: %d\n",
error);
@ -316,9 +312,8 @@ hv_nv_init_send_buffer_with_net_vsp(struct hn_softc *sc)
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
error = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
chim, sizeof(*chim), (uint64_t)(uintptr_t)&sndc);
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
chim, sizeof(*chim), &sndc);
if (error) {
if_printf(sc->hn_ifp, "send nvs chim conn failed: %d\n",
error);
@ -396,9 +391,10 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
disconn.nvs_type = HN_NVS_TYPE_RXBUF_DISCONN;
disconn.nvs_sig = HN_NVS_RXBUF_SIG;
ret = vmbus_chan_send(net_dev->sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, 0, &disconn, sizeof(disconn),
(uint64_t)(uintptr_t)&hn_send_ctx_none);
/* NOTE: No response. */
ret = hn_nvs_send(net_dev->sc->hn_prichan,
VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn),
&hn_send_ctx_none);
if (ret != 0) {
if_printf(net_dev->sc->hn_ifp,
"send rxbuf disconn failed: %d\n", ret);
@ -436,33 +432,25 @@ hv_nv_destroy_rx_buffer(netvsc_dev *net_dev)
static int
hv_nv_destroy_send_buffer(netvsc_dev *net_dev)
{
nvsp_msg *revoke_pkt;
int ret = 0;
/*
* If we got a section count, it means we received a
* send_rx_buf_complete msg
* (ie sent nvsp_msg_1_type_send_rx_buf msg) therefore,
* we need to send a revoke msg here
*/
if (net_dev->send_section_size) {
/* Send the revoke send buffer */
revoke_pkt = &net_dev->revoke_packet;
memset(revoke_pkt, 0, sizeof(nvsp_msg));
struct hn_nvs_chim_disconn disconn;
revoke_pkt->hdr.msg_type =
nvsp_msg_1_type_revoke_send_buf;
revoke_pkt->msgs.vers_1_msgs.revoke_send_buf.id =
NETVSC_SEND_BUFFER_ID;
ret = vmbus_chan_send(net_dev->sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, 0, revoke_pkt, sizeof(nvsp_msg),
(uint64_t)(uintptr_t)&hn_send_ctx_none);
/*
* If we failed here, we might as well return and have a leak
* rather than continue and a bugchk
* Disconnect chimney sending buffer from NVS.
*/
memset(&disconn, 0, sizeof(disconn));
disconn.nvs_type = HN_NVS_TYPE_CHIM_DISCONN;
disconn.nvs_sig = HN_NVS_CHIM_SIG;
/* NOTE: No response. */
ret = hn_nvs_send(net_dev->sc->hn_prichan,
VMBUS_CHANPKT_FLAG_NONE, &disconn, sizeof(disconn),
&hn_send_ctx_none);
if (ret != 0) {
if_printf(net_dev->sc->hn_ifp,
"send chim disconn failed: %d\n", ret);
return (ret);
}
}
@ -521,9 +509,8 @@ hv_nv_negotiate_nvsp_protocol(struct hn_softc *sc, netvsc_dev *net_dev,
vmbus_xact_activate(xact);
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
error = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
init, sizeof(*init), (uint64_t)(uintptr_t)&sndc);
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
init, sizeof(*init), &sndc);
if (error) {
if_printf(sc->hn_ifp, "send nvs init failed: %d\n", error);
vmbus_xact_deactivate(xact);
@ -572,8 +559,9 @@ hv_nv_send_ndis_config(struct hn_softc *sc, uint32_t mtu)
conf.nvs_mtu = mtu;
conf.nvs_caps = HN_NVS_NDIS_CONF_VLAN;
error = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
&conf, sizeof(conf), (uint64_t)(uintptr_t)&hn_send_ctx_none);
/* NOTE: No response. */
error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
&conf, sizeof(conf), &hn_send_ctx_none);
if (error)
if_printf(sc->hn_ifp, "send nvs ndis conf failed: %d\n", error);
return (error);
@ -639,8 +627,9 @@ hv_nv_connect_to_vsp(struct hn_softc *sc)
else
ndis.nvs_ndis_minor = NDIS_VERSION_MINOR_30;
ret = vmbus_chan_send(sc->hn_prichan, VMBUS_CHANPKT_TYPE_INBAND, 0,
&ndis, sizeof(ndis), (uint64_t)(uintptr_t)&hn_send_ctx_none);
/* NOTE: No response. */
ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE,
&ndis, sizeof(ndis), &hn_send_ctx_none);
if (ret != 0) {
if_printf(sc->hn_ifp, "send nvs ndis init failed: %d\n", ret);
goto cleanup;
@ -765,16 +754,6 @@ hv_nv_on_device_remove(struct hn_softc *sc, boolean_t destroy_channel)
}
void
hn_nvs_sent_wakeup(struct hn_send_ctx *sndc __unused,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan __unused,
const struct nvsp_msg_ *msg, int dlen __unused)
{
/* Copy the response back */
memcpy(&net_dev->channel_init_packet, msg, sizeof(nvsp_msg));
sema_post(&net_dev->channel_init_sema);
}
static void
hn_nvs_sent_xact(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev __unused, struct vmbus_channel *chan __unused,
const struct nvsp_msg_ *msg, int dlen)
@ -835,33 +814,23 @@ hv_nv_on_send_completion(netvsc_dev *net_dev, struct vmbus_channel *chan,
* Returns 0 on success, non-zero on failure.
*/
int
hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt)
{
nvsp_msg send_msg;
struct hn_nvs_rndis rndis;
int ret;
send_msg.hdr.msg_type = nvsp_msg_1_type_send_rndis_pkt;
if (is_data_pkt) {
/* 0 is RMC_DATA */
send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 0;
} else {
/* 1 is RMC_CONTROL */
send_msg.msgs.vers_1_msgs.send_rndis_pkt.chan_type = 1;
}
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_idx =
sndc->hn_chim_idx;
send_msg.msgs.vers_1_msgs.send_rndis_pkt.send_buf_section_size =
sndc->hn_chim_sz;
rndis.nvs_type = HN_NVS_TYPE_RNDIS;
rndis.nvs_rndis_mtype = rndis_mtype;
rndis.nvs_chim_idx = sndc->hn_chim_idx;
rndis.nvs_chim_sz = sndc->hn_chim_sz;
if (gpa_cnt) {
ret = vmbus_chan_send_sglist(chan, gpa, gpa_cnt,
&send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt,
&rndis, sizeof(rndis), sndc);
} else {
ret = vmbus_chan_send(chan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
&send_msg, sizeof(nvsp_msg), (uint64_t)(uintptr_t)sndc);
ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC,
&rndis, sizeof(rndis), sndc);
}
return (ret);
@ -878,19 +847,18 @@ hv_nv_on_receive(netvsc_dev *net_dev, struct hn_rx_ring *rxr,
struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr)
{
const struct vmbus_chanpkt_rxbuf *pkt;
const nvsp_msg *nvsp_msg_pkt;
const struct hn_nvs_hdr *nvs_hdr;
netvsc_packet vsc_pkt;
netvsc_packet *net_vsc_pkt = &vsc_pkt;
int count = 0;
int i = 0;
int status = nvsp_status_success;
nvsp_msg_pkt = VMBUS_CHANPKT_CONST_DATA(pkthdr);
/* Make sure this is a valid nvsp packet */
if (nvsp_msg_pkt->hdr.msg_type != nvsp_msg_1_type_send_rndis_pkt) {
if_printf(rxr->hn_ifp, "packet hdr type %u is invalid!\n",
nvsp_msg_pkt->hdr.msg_type);
/* Make sure that this is a RNDIS message. */
nvs_hdr = VMBUS_CHANPKT_CONST_DATA(pkthdr);
if (__predict_false(nvs_hdr->nvs_type != HN_NVS_TYPE_RNDIS)) {
if_printf(rxr->hn_ifp, "nvs type %u, not RNDIS\n",
nvs_hdr->nvs_type);
return;
}

View File

@ -1256,7 +1256,7 @@ netvsc_dev *hv_nv_on_device_add(struct hn_softc *sc,
void *additional_info, struct hn_rx_ring *rxr);
int hv_nv_on_device_remove(struct hn_softc *sc,
boolean_t destroy_channel);
int hv_nv_on_send(struct vmbus_channel *chan, bool is_data_pkt,
int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype,
struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt);
int hv_nv_get_next_send_section(netvsc_dev *net_dev);
void hv_nv_subchan_attach(struct vmbus_channel *chan,

View File

@ -798,7 +798,7 @@ hn_tx_done(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
struct hn_txdesc *txd = sndc->hn_cbarg;
struct hn_tx_ring *txr;
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
txr = txd->txr;
@ -988,8 +988,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
txr->hn_tx_chimney_tried++;
send_buf_section_idx =
hv_nv_get_next_send_section(net_dev);
if (send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
uint8_t *dest = ((uint8_t *)net_dev->send_buf +
(send_buf_section_idx *
net_dev->send_section_size));
@ -1045,7 +1044,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0)
gpa->gpa_len = segs[i].ds_len;
}
send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
done:
txd->m = m_head;
@ -1072,8 +1071,8 @@ hn_send_pkt(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd)
* Make sure that txd is not freed before ETHER_BPF_MTAP.
*/
hn_txdesc_hold(txd);
error = hv_nv_on_send(txr->hn_chan, true, &txd->send_ctx,
txr->hn_gpa, txr->hn_gpa_cnt);
error = hv_nv_on_send(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA,
&txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt);
if (!error) {
ETHER_BPF_MTAP(ifp, txd->m);
if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);

View File

@ -46,9 +46,11 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <dev/hyperv/include/hyperv.h>
#include "hv_net_vsc.h"
#include "hv_rndis.h"
#include "hv_rndis_filter.h"
#include <dev/hyperv/include/vmbus_xact.h>
#include <dev/hyperv/netvsc/hv_net_vsc.h>
#include <dev/hyperv/netvsc/hv_rndis.h>
#include <dev/hyperv/netvsc/hv_rndis_filter.h>
#include <dev/hyperv/netvsc/if_hnreg.h>
struct hv_rf_recvinfo {
const ndis_8021q_info *vlan_info;
@ -275,8 +277,7 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
if (tot_data_buf_len < net_dev->send_section_size) {
send_buf_section_idx = hv_nv_get_next_send_section(net_dev);
if (send_buf_section_idx !=
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX) {
if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) {
char *dest = ((char *)net_dev->send_buf +
send_buf_section_idx * net_dev->send_section_size);
@ -287,14 +288,14 @@ hv_rf_send_request(rndis_device *device, rndis_request *request,
}
/* Failed to allocate chimney send buffer; move on */
}
send_buf_section_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX;
send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID;
send_buf_section_size = 0;
sendit:
hn_send_ctx_init(&request->send_ctx, cb, request,
send_buf_section_idx, send_buf_section_size);
return hv_nv_on_send(device->net_dev->sc->hn_prichan, false,
&request->send_ctx, gpa, gpa_cnt);
return hv_nv_on_send(device->net_dev->sc->hn_prichan,
HN_NVS_RNDIS_MTYPE_CTRL, &request->send_ctx, gpa, gpa_cnt);
}
/*
@ -1060,12 +1061,16 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
int ret;
netvsc_dev *net_dev;
rndis_device *rndis_dev;
nvsp_msg *init_pkt;
rndis_offload_params offloads;
struct rndis_recv_scale_cap rsscaps;
uint32_t rsscaps_size = sizeof(struct rndis_recv_scale_cap);
netvsc_device_info *dev_info = (netvsc_device_info *)additl_info;
device_t dev = sc->hn_dev;
struct hn_nvs_subch_req *req;
const struct hn_nvs_subch_resp *resp;
size_t resp_len;
struct vmbus_xact *xact;
uint32_t status, nsubch;
rndis_dev = hv_get_rndis_device();
if (rndis_dev == NULL) {
@ -1153,36 +1158,64 @@ hv_rf_on_device_add(struct hn_softc *sc, void *additl_info,
goto out;
}
/* request host to create sub channels */
init_pkt = &net_dev->channel_init_packet;
memset(init_pkt, 0, sizeof(nvsp_msg));
/*
* Ask NVS to allocate sub-channels.
*/
xact = vmbus_xact_get(sc->hn_xact, sizeof(*req));
if (xact == NULL) {
if_printf(sc->hn_ifp, "no xact for nvs subch req\n");
ret = ENXIO;
goto out;
}
init_pkt->hdr.msg_type = nvsp_msg5_type_subchannel;
init_pkt->msgs.vers_5_msgs.subchannel_request.op =
NVSP_SUBCHANNE_ALLOCATE;
init_pkt->msgs.vers_5_msgs.subchannel_request.num_subchannels =
net_dev->num_channel - 1;
req = vmbus_xact_req_data(xact);
req->nvs_type = HN_NVS_TYPE_SUBCH_REQ;
req->nvs_op = HN_NVS_SUBCH_OP_ALLOC;
req->nvs_nsubch = net_dev->num_channel - 1;
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_wakeup, NULL);
ret = vmbus_chan_send(sc->hn_prichan,
VMBUS_CHANPKT_TYPE_INBAND, VMBUS_CHANPKT_FLAG_RC,
init_pkt, sizeof(nvsp_msg), (uint64_t)(uintptr_t)&sndc);
hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact);
vmbus_xact_activate(xact);
ret = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC,
req, sizeof(*req), &sndc);
if (ret != 0) {
device_printf(dev, "Fail to allocate subchannel\n");
if_printf(sc->hn_ifp, "send nvs subch req failed: %d\n", ret);
vmbus_xact_deactivate(xact);
vmbus_xact_put(xact);
goto out;
}
sema_wait(&net_dev->channel_init_sema);
if (init_pkt->msgs.vers_5_msgs.subchn_complete.status !=
nvsp_status_success) {
ret = ENODEV;
device_printf(dev, "sub channel complete error\n");
resp = vmbus_xact_wait(xact, &resp_len);
if (resp_len < sizeof(*resp)) {
if_printf(sc->hn_ifp, "invalid subch resp length %zu\n",
resp_len);
vmbus_xact_put(xact);
ret = EINVAL;
goto out;
}
if (resp->nvs_type != HN_NVS_TYPE_SUBCH_RESP) {
if_printf(sc->hn_ifp, "not subch resp, type %u\n",
resp->nvs_type);
vmbus_xact_put(xact);
ret = EINVAL;
goto out;
}
net_dev->num_channel = 1 +
init_pkt->msgs.vers_5_msgs.subchn_complete.num_subchannels;
status = resp->nvs_status;
nsubch = resp->nvs_nsubch;
vmbus_xact_put(xact);
if (status != HN_NVS_STATUS_OK) {
if_printf(sc->hn_ifp, "subch req failed: %x\n", status);
ret = EIO;
goto out;
}
if (nsubch > net_dev->num_channel - 1) {
if_printf(sc->hn_ifp, "%u subchans are allocated, requested %u\n",
nsubch, net_dev->num_channel - 1);
nsubch = net_dev->num_channel - 1;
}
net_dev->num_channel = nsubch + 1;
ret = hv_rf_set_rss_param(rndis_dev, net_dev->num_channel);
@ -1242,7 +1275,7 @@ hn_rndis_sent_cb(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
struct vmbus_channel *chan __unused, const struct nvsp_msg_ *msg __unused,
int dlen __unused)
{
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
}
@ -1253,7 +1286,7 @@ hn_rndis_sent_halt(struct hn_send_ctx *sndc, struct netvsc_dev_ *net_dev,
{
rndis_request *request = sndc->hn_cbarg;
if (sndc->hn_chim_idx != NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX)
if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID)
hn_chim_free(net_dev, sndc->hn_chim_idx);
/*

View File

@ -35,8 +35,19 @@
#define HN_NVS_RXBUF_SIG 0xcafe
#define HN_NVS_CHIM_SIG 0xface
#define HN_NVS_CHIM_IDX_INVALID 0xffffffff
#define HN_NVS_RNDIS_MTYPE_DATA 0
#define HN_NVS_RNDIS_MTYPE_CTRL 1
/*
* NVS message transacion status codes.
*/
#define HN_NVS_STATUS_OK 1
/*
* NVS request/response message types.
*/
#define HN_NVS_TYPE_INIT 1
#define HN_NVS_TYPE_INIT_RESP 2
#define HN_NVS_TYPE_NDIS_INIT 100
@ -45,7 +56,11 @@
#define HN_NVS_TYPE_RXBUF_DISCONN 103
#define HN_NVS_TYPE_CHIM_CONN 104
#define HN_NVS_TYPE_CHIM_CONNRESP 105
#define HN_NVS_TYPE_CHIM_DISCONN 106
#define HN_NVS_TYPE_RNDIS 107
#define HN_NVS_TYPE_NDIS_CONF 125
#define HN_NVS_TYPE_SUBCH_REQ 133
#define HN_NVS_TYPE_SUBCH_RESP 133 /* same as SUBCH_REQ */
/*
* Any size less than this one will _not_ work, e.g. hn_nvs_init
@ -54,6 +69,11 @@
*/
#define HN_NVS_REQSIZE_MIN 32
/* NVS message common header */
struct hn_nvs_hdr {
uint32_t nvs_type;
} __packed;
struct hn_nvs_init {
uint32_t nvs_type; /* HN_NVS_TYPE_INIT */
uint32_t nvs_ver_min;
@ -135,4 +155,45 @@ struct hn_nvs_chim_connresp {
uint32_t nvs_sectsz; /* section size */
} __packed;
/* No response */
struct hn_nvs_chim_disconn {
uint32_t nvs_type; /* HN_NVS_TYPE_CHIM_DISCONN */
uint16_t nvs_sig; /* HN_NVS_CHIM_SIG */
uint8_t nvs_rsvd[26];
} __packed;
CTASSERT(sizeof(struct hn_nvs_chim_disconn) >= HN_NVS_REQSIZE_MIN);
#define HN_NVS_SUBCH_OP_ALLOC 1
struct hn_nvs_subch_req {
uint32_t nvs_type; /* HN_NVS_TYPE_SUBCH_REQ */
uint32_t nvs_op; /* HN_NVS_SUBCH_OP_ */
uint32_t nvs_nsubch;
uint8_t nvs_rsvd[20];
} __packed;
CTASSERT(sizeof(struct hn_nvs_subch_req) >= HN_NVS_REQSIZE_MIN);
struct hn_nvs_subch_resp {
uint32_t nvs_type; /* HN_NVS_TYPE_SUBCH_RESP */
uint32_t nvs_status; /* HN_NVS_STATUS_ */
uint32_t nvs_nsubch;
} __packed;
struct hn_nvs_rndis {
uint32_t nvs_type; /* HN_NVS_TYPE_RNDIS */
uint32_t nvs_rndis_mtype;/* HN_NVS_RNDIS_MTYPE_ */
/*
* Chimney sending buffer index and size.
*
* NOTE:
* If nvs_chim_idx is set to HN_NVS_CHIM_IDX_INVALID
* and nvs_chim_sz is set to 0, then chimney sending
* buffer is _not_ used by this RNDIS message.
*/
uint32_t nvs_chim_idx;
uint32_t nvs_chim_sz;
uint8_t nvs_rsvd[16];
} __packed;
CTASSERT(sizeof(struct hn_nvs_rndis) >= HN_NVS_REQSIZE_MIN);
#endif /* !_IF_HNREG_H_ */

View File

@ -30,7 +30,9 @@
#define _IF_HNVAR_H_
#include <sys/param.h>
#include <dev/hyperv/netvsc/hv_net_vsc.h>
#include <dev/hyperv/include/vmbus.h>
#include <dev/hyperv/netvsc/if_hnreg.h>
struct netvsc_dev_;
struct nvsp_msg_;
@ -49,18 +51,19 @@ struct hn_send_ctx {
int hn_chim_sz;
};
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
{ \
.hn_cb = cb, \
.hn_cbarg = cbarg, \
.hn_chim_idx = NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, \
.hn_chim_sz = 0 \
#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \
{ \
.hn_cb = cb, \
.hn_cbarg = cbarg, \
.hn_chim_idx = HN_NVS_CHIM_IDX_INVALID, \
.hn_chim_sz = 0 \
}
static __inline void
hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
void *cbarg, uint32_t chim_idx, int chim_sz)
{
sndc->hn_cb = cb;
sndc->hn_cbarg = cbarg;
sndc->hn_chim_idx = chim_idx;
@ -71,11 +74,29 @@ static __inline void
hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb,
void *cbarg)
{
hn_send_ctx_init(sndc, cb, cbarg,
NVSP_1_CHIMNEY_SEND_INVALID_SECTION_INDEX, 0);
hn_send_ctx_init(sndc, cb, cbarg, HN_NVS_CHIM_IDX_INVALID, 0);
}
void hn_nvs_sent_wakeup(struct hn_send_ctx *sndc,
static __inline int
hn_nvs_send(struct vmbus_channel *chan, uint16_t flags,
void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
{
return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags,
nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc));
}
static __inline int
hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen,
void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc)
{
return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen,
(uint64_t)(uintptr_t)sndc));
}
void hn_nvs_sent_xact(struct hn_send_ctx *sndc,
struct netvsc_dev_ *net_dev, struct vmbus_channel *chan,
const struct nvsp_msg_ *msg, int dlen);
void hn_chim_free(struct netvsc_dev_ *net_dev, uint32_t chim_idx);

File diff suppressed because it is too large Load Diff

View File

@ -1,202 +0,0 @@
/*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/bio.h>
#include <sys/cdio.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/rman.h>
#include <isa/isavar.h>
#include <dev/mcd/mcdreg.h>
#include <dev/mcd/mcdvar.h>
static int mcd_isa_probe (device_t);
static int mcd_isa_attach (device_t);
static int mcd_isa_detach (device_t);
static int mcd_alloc_resources (device_t);
static void mcd_release_resources (device_t);
static int
mcd_isa_probe (device_t dev)
{
struct mcd_softc * sc;
int error;
/* No pnp support */
if (isa_get_vendorid(dev))
return (ENXIO);
/* IO port must be configured. */
if (bus_get_resource_start(dev, SYS_RES_IOPORT, 0) == 0)
return (ENXIO);
sc = device_get_softc(dev);
sc->dev = dev;
sc->port_rid = 0;
sc->port_type = SYS_RES_IOPORT;
error = mcd_alloc_resources(dev);
if (error)
goto fail;
error = mcd_probe(sc);
if (error) {
device_printf(dev, "Probe failed.\n");
goto fail;
}
device_set_desc(dev, sc->data.name);
fail:
mcd_release_resources(dev);
return (error);
}
static int
mcd_isa_attach (device_t dev)
{
struct mcd_softc * sc;
int error;
sc = device_get_softc(dev);
error = 0;
sc->dev = dev;
sc->port_rid = 0;
sc->port_type = SYS_RES_IOPORT;
error = mcd_alloc_resources(dev);
if (error)
goto fail;
error = mcd_probe(sc);
if (error) {
device_printf(dev, "Re-Probe failed.\n");
goto fail;
}
error = mcd_attach(sc);
if (error) {
device_printf(dev, "Attach failed.\n");
goto fail;
}
return (0);
fail:
mcd_release_resources(dev);
return (error);
}
static int
mcd_isa_detach (device_t dev)
{
struct mcd_softc * sc;
int error;
sc = device_get_softc(dev);
error = 0;
destroy_dev(sc->mcd_dev_t);
mcd_release_resources(dev);
return (error);
}
static int
mcd_alloc_resources (device_t dev)
{
struct mcd_softc * sc;
int error;
sc = device_get_softc(dev);
error = 0;
mtx_init(&sc->mtx, "mcd", NULL, MTX_DEF);
if (sc->port_type) {
sc->port = bus_alloc_resource_any(dev, sc->port_type,
&sc->port_rid, RF_ACTIVE);
if (sc->port == NULL) {
device_printf(dev, "Unable to allocate PORT resource.\n");
error = ENOMEM;
goto bad;
}
}
if (sc->irq_type) {
sc->irq = bus_alloc_resource_any(dev, sc->irq_type,
&sc->irq_rid, RF_ACTIVE);
if (sc->irq == NULL) {
device_printf(dev, "Unable to allocate IRQ resource.\n");
error = ENOMEM;
goto bad;
}
}
if (sc->drq_type) {
sc->drq = bus_alloc_resource_any(dev, sc->drq_type,
&sc->drq_rid, RF_ACTIVE);
if (sc->drq == NULL) {
device_printf(dev, "Unable to allocate DRQ resource.\n");
error = ENOMEM;
goto bad;
}
}
bad:
return (error);
}
static void
mcd_release_resources (device_t dev)
{
struct mcd_softc * sc;
sc = device_get_softc(dev);
if (sc->irq_ih)
bus_teardown_intr(dev, sc->irq, sc->irq_ih);
if (sc->port)
bus_release_resource(dev, sc->port_type, sc->port_rid, sc->port);
if (sc->irq)
bus_release_resource(dev, sc->irq_type, sc->irq_rid, sc->irq);
if (sc->drq)
bus_release_resource(dev, sc->drq_type, sc->drq_rid, sc->drq);
mtx_destroy(&sc->mtx);
return;
}
static device_method_t mcd_isa_methods[] = {
DEVMETHOD(device_probe, mcd_isa_probe),
DEVMETHOD(device_attach, mcd_isa_attach),
DEVMETHOD(device_detach, mcd_isa_detach),
{ 0, 0 }
};
static driver_t mcd_isa_driver = {
"mcd",
mcd_isa_methods,
sizeof(struct mcd_softc)
};
static devclass_t mcd_devclass;
DRIVER_MODULE(mcd, isa, mcd_isa_driver, mcd_devclass, NULL, 0);

Some files were not shown because too many files have changed in this diff Show More