diff --git a/UPDATING b/UPDATING index 122b0600e827..ce79b09f0c6c 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20180913: + Reproducible build mode is now on by default, in preparation for + FreeBSD 12.0. This eliminates build metadata such as the user, + host, and time from the kernel (and uname), unless the working tree + corresponds to a modified checkout from a version control system. + The previous behavior can be obtained by setting the /etc/src.conf + knob WITHOUT_REPRODUCIBLE_BUILD. + 20180826: The Yarrow CSPRNG has been removed from the kernel as it has not been supported by its designers since at least 2003. Fortuna has been the @@ -169,6 +177,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: r334930 changed the interface between the NFS modules, so they all need to be rebuilt. r335018 did a __FreeBSD_version bump for this. +20180530: + As of r334391 lld is the default amd64 system linker; it is installed + as /usr/bin/ld. Kernel build workarounds (see 20180510 entry) are no + longer necessary. + 20180530: The kernel / userland interface for devinfo changed, so you'll need a new kernel and userland as a pair for it to work (rebuilding @@ -196,6 +209,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: binutils port/package). lld will soon be default, and this requirement will go away. + NOTE: As of r334391 lld is the default system linker on amd64, and no + workaround is necessary. + 20180508: The nxge(4) driver has been removed. This driver was for PCI-X 10g cards made by s2io/Neterion. The company was aquired by Exar and diff --git a/contrib/bmake/make.1 b/contrib/bmake/make.1 index c4479f1b845e..631b17c46f5b 100644 --- a/contrib/bmake/make.1 +++ b/contrib/bmake/make.1 @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd June 22, 2017 +.Dd September 27, 2018 .Dt MAKE 1 .Os .Sh NAME @@ -796,7 +796,7 @@ Tells whether to pass the descriptors of the job token queue even if the target is not tagged with .Ic .MAKE -The default is +The default is .Ql Pa yes for backwards compatability with .Fx 9.0 @@ -2385,7 +2385,8 @@ Basic use of suffix rules (for files only in the current directory, not trying to chain transformations together, etc.) is also reasonably portable. .Sh SEE ALSO -.Xr mkdep 1 +.Xr mkdep 1 , +.Xr style.Makefile 5 .Sh HISTORY A .Nm diff --git a/contrib/libarchive/README.md b/contrib/libarchive/README.md index b48142191f2f..1a127bbb2653 100644 --- a/contrib/libarchive/README.md +++ b/contrib/libarchive/README.md @@ -78,7 +78,6 @@ Currently, the library automatically detects and reads the following fomats: * POSIX pax interchange format * POSIX octet-oriented cpio * SVR4 ASCII cpio - * POSIX octet-oriented cpio * Binary cpio (big-endian or little-endian) * ISO9660 CD-ROM images (with optional Rockridge or Joliet extensions) * ZIP archives (with uncompressed or "deflate" compressed entries, including support for encrypted Zip archives) diff --git a/contrib/libarchive/libarchive/archive_acl.c b/contrib/libarchive/libarchive/archive_acl.c index 4736531afa1d..9941d2f6fdb2 100644 --- a/contrib/libarchive/libarchive/archive_acl.c +++ b/contrib/libarchive/libarchive/archive_acl.c @@ -2058,6 +2058,12 @@ next_field(const char **p, const char **start, } *sep = **p; + /* If the field is only whitespace, bail out now. */ + if (**p == '\0') { + *end = *p; + return; + } + /* Trim trailing whitespace to locate end of field. */ *end = *p - 1; while (**end == ' ' || **end == '\t' || **end == '\n') { diff --git a/contrib/libarchive/libarchive/archive_cryptor.c b/contrib/libarchive/libarchive/archive_cryptor.c index 71967c9d46f0..74df5c405b08 100644 --- a/contrib/libarchive/libarchive/archive_cryptor.c +++ b/contrib/libarchive/libarchive/archive_cryptor.c @@ -316,7 +316,14 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len) memcpy(ctx->key, key, key_len); memset(ctx->nonce, 0, sizeof(ctx->nonce)); ctx->encr_pos = AES_BLOCK_SIZE; +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) + if (!EVP_CIPHER_CTX_reset(ctx->ctx)) { + EVP_CIPHER_CTX_free(ctx->ctx); + ctx->ctx = NULL; + } +#else EVP_CIPHER_CTX_init(ctx->ctx); +#endif return 0; } diff --git a/contrib/libarchive/libarchive/archive_read_support_format_ar.c b/contrib/libarchive/libarchive/archive_read_support_format_ar.c index 22e64bf4d6bf..3818fa8ac187 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_ar.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_ar.c @@ -459,6 +459,7 @@ ar_parse_common_header(struct ar *ar, struct archive_entry *entry, uint64_t n; /* Copy remaining header */ + archive_entry_set_filetype(entry, AE_IFREG); archive_entry_set_mtime(entry, (time_t)ar_atol10(h + AR_date_offset, AR_date_size), 0L); archive_entry_set_uid(entry, diff --git a/contrib/libarchive/libarchive/archive_read_support_format_zip.c b/contrib/libarchive/libarchive/archive_read_support_format_zip.c index 1a5402792428..ac658f155934 100644 --- a/contrib/libarchive/libarchive/archive_read_support_format_zip.c +++ b/contrib/libarchive/libarchive/archive_read_support_format_zip.c @@ -2708,6 +2708,11 @@ slurp_central_directory(struct archive_read *a, struct zip *zip) return ARCHIVE_FATAL; zip_entry = calloc(1, sizeof(struct zip_entry)); + if (zip_entry == NULL) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate zip entry"); + return ARCHIVE_FATAL; + } zip_entry->next = zip->zip_entries; zip_entry->flags |= LA_FROM_CENTRAL_DIRECTORY; zip->zip_entries = zip_entry; diff --git a/contrib/libarchive/libarchive/test/test_sparse_basic.c b/contrib/libarchive/libarchive/test/test_sparse_basic.c index 58d53a94e072..0df0f1d321ac 100644 --- a/contrib/libarchive/libarchive/test/test_sparse_basic.c +++ b/contrib/libarchive/libarchive/test/test_sparse_basic.c @@ -422,6 +422,7 @@ verify_sparse_file(struct archive *a, const char *path, assert(sparse->type == END); assertEqualInt(expected_offset, archive_entry_size(ae)); + failure(path); assertEqualInt(holes_seen, expected_holes); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); @@ -457,6 +458,7 @@ verify_sparse_file2(struct archive *a, const char *path, /* Verify the number of holes only, not its offset nor its * length because those alignments are deeply dependence on * its filesystem. */ + failure(path); assertEqualInt(blocks, archive_entry_sparse_count(ae)); archive_entry_free(ae); } diff --git a/contrib/libarchive/test_utils/test_main.c b/contrib/libarchive/test_utils/test_main.c index 20ce551828ca..2ff942c84a44 100644 --- a/contrib/libarchive/test_utils/test_main.c +++ b/contrib/libarchive/test_utils/test_main.c @@ -2166,7 +2166,7 @@ void assertVersion(const char *prog, const char *base) /* Skip arbitrary third-party version numbers. */ while (s > 0 && (*q == ' ' || *q == '-' || *q == '/' || *q == '.' || - isalnum(*q))) { + isalnum((unsigned char)*q))) { ++q; --s; } diff --git a/contrib/mdocml/INSTALL b/contrib/mandoc/INSTALL similarity index 91% rename from contrib/mdocml/INSTALL rename to contrib/mandoc/INSTALL index d80e8e319251..558574b903de 100644 --- a/contrib/mdocml/INSTALL +++ b/contrib/mandoc/INSTALL @@ -1,4 +1,4 @@ -$Id: INSTALL,v 1.20 2017/07/28 14:57:56 schwarze Exp $ +$Id: INSTALL,v 1.22 2018/07/31 15:34:00 schwarze Exp $ About the portable mandoc distribution -------------------------------------- @@ -18,7 +18,7 @@ tech@ mailing list, too. Enjoy using the mandoc toolset! -Ingo Schwarze, Karlsruhe, July 2017 +Ingo Schwarze, Karlsruhe, August 2018 Installation @@ -54,8 +54,6 @@ generates. If anything looks wrong or different from what you wish, read the file "configure.local.example", create and edit a file "configure.local", and re-run "./configure" until the result seems right to you. -On Solaris 10 and earlier, you may have to run "ksh ./configure" -because the native /bin/sh lacks some POSIX features. 5. Run "make". Any POSIX-compatible make, in particular both BSD make and GNU make, @@ -83,12 +81,14 @@ apropos(1) will not find the new pages. 10. To set up a man.cgi(8) server, read its manual page. -Note that some man(7) pages may contain low-level roff(7) markup -that mandoc does not yet understand. On some BSD systems using -mandoc, third-party software is vetted on whether it may be formatted -with mandoc. If not, groff(1) is pulled in as a dependency and -used to install a pre-formatted "catpage" instead of directly as -manual page source. +Note that a very small number of man(7) pages contain low-level +roff(7) markup that mandoc does not yet understand. On some BSD +systems using mandoc, third-party software is vetted on whether it +may be formatted with mandoc. If not, groff(1) is pulled in as a +dependency and used to install pre-formatted "catpages" instead of +manual page sources. This mechanism is used much less frequently +than in the past. On OpenBSD, only 25 out of about 10000 ports +still require formatting with groff(1). Understanding mandoc dependencies diff --git a/contrib/mdocml/LICENSE b/contrib/mandoc/LICENSE similarity index 92% rename from contrib/mdocml/LICENSE rename to contrib/mandoc/LICENSE index aca7ee7a6c7e..ec7fc029d82c 100644 --- a/contrib/mdocml/LICENSE +++ b/contrib/mandoc/LICENSE @@ -1,17 +1,17 @@ -$Id: LICENSE,v 1.17 2017/06/23 15:58:14 schwarze Exp $ +$Id: LICENSE,v 1.19 2018/07/31 10:18:15 schwarze Exp $ With the exceptions noted below, all code and documentation contained in the mandoc toolkit is protected by the Copyright of the following developers: Copyright (c) 2008-2012, 2014 Kristaps Dzonsons -Copyright (c) 2010-2017 Ingo Schwarze +Copyright (c) 2010-2018 Ingo Schwarze +Copyright (c) 1999, 2004, 2017 Marc Espie Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger Copyright (c) 2013 Franco Fichtner Copyright (c) 2014 Baptiste Daroussin Copyright (c) 2016 Ed Maste Copyright (c) 2017 Michael Stapelberg -Copyright (c) 1999, 2004 Marc Espie Copyright (c) 1998, 2004, 2010 Todd C. Miller Copyright (c) 2008, 2017 Otto Moerbeek Copyright (c) 2004 Ted Unangst diff --git a/contrib/mdocml/Makefile b/contrib/mandoc/Makefile similarity index 97% rename from contrib/mdocml/Makefile rename to contrib/mandoc/Makefile index 9855c9f8f1e8..09738579f0d2 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mandoc/Makefile @@ -1,7 +1,7 @@ -# $Id: Makefile,v 1.516 2017/07/20 16:24:53 schwarze Exp $ +# $Id: Makefile,v 1.519 2018/07/31 15:34:00 schwarze Exp $ # # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons -# Copyright (c) 2011, 2013-2017 Ingo Schwarze +# Copyright (c) 2011, 2013-2018 Ingo Schwarze # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -VERSION = 1.14.3 +VERSION = 1.14.4 # === LIST OF FILES ==================================================== @@ -30,6 +30,7 @@ TESTSRCS = test-be32toh.c \ test-isblank.c \ test-mkdtemp.c \ test-nanosleep.c \ + test-noop.c \ test-ntohl.c \ test-O_DIRECTORY.c \ test-ohash.c \ @@ -46,6 +47,7 @@ TESTSRCS = test-be32toh.c \ test-stringlist.c \ test-strlcat.c \ test-strlcpy.c \ + test-strndup.c \ test-strptime.c \ test-strsep.c \ test-strtonum.c \ @@ -70,6 +72,7 @@ SRCS = att.c \ compat_stringlist.c \ compat_strlcat.c \ compat_strlcpy.c \ + compat_strndup.c \ compat_strsep.c \ compat_strtonum.c \ compat_vasprintf.c \ @@ -249,6 +252,7 @@ COMPAT_OBJS = compat_err.o \ compat_strcasestr.o \ compat_strlcat.o \ compat_strlcpy.o \ + compat_strndup.o \ compat_strsep.o \ compat_strtonum.o \ compat_vasprintf.o @@ -544,12 +548,12 @@ regress-distcheck: ! -path regress/regress.pl \ ! -path regress/regress.pl.1 -dist: mandoc.sha256 +dist: mandoc-$(VERSION).sha256 -mandoc.sha256: mandoc.tar.gz - sha256 mandoc.tar.gz > $@ +mandoc-$(VERSION).sha256: mandoc-$(VERSION).tar.gz + sha256 mandoc-$(VERSION).tar.gz > $@ -mandoc.tar.gz: $(DISTFILES) +mandoc-$(VERSION).tar.gz: $(DISTFILES) ls regress/*/*/*.mandoc_* && exit 1 || true mkdir -p .dist/mandoc-$(VERSION)/ $(INSTALL) -m 0644 $(DISTFILES) .dist/mandoc-$(VERSION) diff --git a/contrib/mdocml/Makefile.depend b/contrib/mandoc/Makefile.depend similarity index 97% rename from contrib/mdocml/Makefile.depend rename to contrib/mandoc/Makefile.depend index 4f5dc808823e..da366a1cd596 100644 --- a/contrib/mdocml/Makefile.depend +++ b/contrib/mandoc/Makefile.depend @@ -16,6 +16,7 @@ compat_strcasestr.o: compat_strcasestr.c config.h compat_stringlist.o: compat_stringlist.c config.h compat_stringlist.h compat_strlcat.o: compat_strlcat.c config.h compat_strlcpy.o: compat_strlcpy.c config.h +compat_strndup.o: compat_strndup.c config.h compat_strsep.o: compat_strsep.c config.h compat_strtonum.o: compat_strtonum.c config.h compat_vasprintf.o: compat_vasprintf.c config.h @@ -29,7 +30,7 @@ demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h libroff.h eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h -html.o: html.c config.h mandoc_aux.h mandoc.h roff.h out.h html.h manconf.h main.h +html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h lib.o: lib.c config.h mandoc.h roff.h mdoc.h libmdoc.h lib.in main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h diff --git a/contrib/mdocml/NEWS b/contrib/mandoc/NEWS similarity index 92% rename from contrib/mdocml/NEWS rename to contrib/mandoc/NEWS index 3d35e2b7bdc5..3bb5b4728b99 100644 --- a/contrib/mdocml/NEWS +++ b/contrib/mandoc/NEWS @@ -1,7 +1,84 @@ -$Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $ +$Id: NEWS,v 1.32 2018/08/08 14:47:38 schwarze Exp $ This file lists the most important changes in the mandoc.bsd.lv distribution. +Changes in version 1.14.4, released on August 8, 2018 + + --- MAJOR NEW FEATURES --- + * In ASCII output, render mathematical symbols and greek letters + as transliterations conveying the characters' meanings rather + than trying to imitate their shape. Consequently, such characters + can now be used in portable manual pages. All the same, please + limit their use to contexts where they really matter, for example + when showing complicated mathematical formulae. + * First steps towards better support for small screens in HTML + output (responsive design): avoid most style= attributes, in + particular all hard-coded indentations and column widths, and + provide a better mandoc.css style sheet with a @media query, + using em units throughout, and avoiding redundancy in selectors. + * Better HTML output with some more fitting HTML elements, eliminating + needless class= attributes, and avoiding various HTML syntax errors + (element nesting, URL-fragment syntax, duplicate id= attributes). + --- MINOR NEW FEATURES --- + * When a man(1) argument contains a slash, imply -l like in man-db. + * Use TIOCGWINSZ to reduce the default -Owidth and -Oindent during + interactive use on terminals narrower than 79 columns. + * Generated PostScript files are now more than 50% smaller. + * Terminal rendering of eqn(7) is improved in several respects. + * Simplified and nicer output from the mdoc(7) .Lk macro, formatting + all links in-line, even long ones. + * roff(7) \n+ and \n- numerical register auto-increment and -decrement + * roff(7) .nr optional third argument (auto-increment step size) + * Autodetect in ./configure whether the compiler can use -W and -static, + allowing to build on Solaris 10 and 11 without any configure.local. + --- RELIABILITY BUGFIXES --- + * Only activate UTF-8 output when the user really selected UTF-8, + not some other multibyte character encoding. + * Prevent excessive .ll arguments from generating infinite output. + * Fix out of bounds accesses to parse buffers that could happen when + using renamed or user defined macros after roff(7) conditionals. + * Avoid an assertion failure in certain .Bl -column lists. + * Avoid a NULL pointer access on deroff() failure after '.SS ""'. + * Fix a segfault that could be triggered by two invalid .Dt macros. + * Fix two syntax errors in generated PDF files. + * Properly state the page size in generated PostScript files. + * Close a memory leak caused by missing gzclose(3). + * Fix misformatting of man(7) documents lacking .SH macros + in PostScript and PDF output. + * And many minor bugfixes. + --- THANKS TO --- + * Marc Espie (OpenBSD) for implementing the size reduction of + PostScript files, one additional patch for code simplification, + and two bug reports. + * Theo Buehler (OpenBSD) for a bugfix patch, + and Theo de Raadt (OpenBSD) for checking it. + * John Gardner for more than a dozen suggestions regarding HTML output. + * Mike Williams for teaching me how to use %%DocumentMedia and + setpagedevice in PostScript files. + * Werner Lemberg (groff) for feedback on mdoc(7) language changes. + * Colin Watson (man-db) for feedback on man-db semantics. + * Jason McIntyre (OpenBSD) for lots of feedback and suggestions + on diagnostic messages and on the documentation. + * Thomas Klausner (NetBSD) for suggesting two new style messages + and one new feature, for two bug reports, and for release testing. + * Leah Neukirchen (Void Linux) for suggesting a new style message, + five bug reports, and release testing. + * Anthony Bentley (OpenBSD) for reporting multiple bugs and missing + features. + * Paul Irofti (OpenBSD) and Nate Bargmann for suggesting new features. + * Michael Stapelberg (Debian) for bug reports and release testing. + * Christian Weisgerber, Jonathan Gray, Stuart Henderson, + Ted Unangst (OpenBSD), Takeshi Nakayama (NetBSD), + Anton Lazarov, Jakub Klinkovsky, Jan Stary, Jesper Wallin, + Will Backmam, and Wolfgang Mueller for bug reports. + * Sevan Janiyan (NetBSD) for additions to lib.in. + * George Brown for suggesting code simplifications. + * David Coppa, Igor Sobrado (OpenBSD), and Alexander Kuleshov + for documentation improvements. + * Laura Morales and Raf Czlonka for questions resulting in better + documentation. + * Yuri Pankov (illumos) for release testing. + Changes in version 1.14.3, released on August 5, 2017 --- BUG FIXES --- diff --git a/contrib/mdocml/TODO b/contrib/mandoc/TODO similarity index 87% rename from contrib/mdocml/TODO rename to contrib/mandoc/TODO index 70371a0e9e5c..6df63ea3c79b 100644 --- a/contrib/mdocml/TODO +++ b/contrib/mandoc/TODO @@ -1,6 +1,6 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.246 2017/07/24 11:15:12 schwarze Exp $ +* $Id: TODO,v 1.258 2018/08/06 14:16:30 schwarze Exp $ ************************************************************************ Many issues are annotated for difficulty as follows: @@ -38,6 +38,18 @@ are mere guesses, and some may be wrong. --- missing roff features ---------------------------------------------- +- .nop prints its arguments as text, + see groff(7) for an example + +- .ft CB selects constant-width bold font + see groff_out(7) for examples + +- \*(.T prints the device being used, + see groff_char(7) for an example + +- \[charNN], \[charNNN] prints a single-byte codepoint + see groff_char(7) for examples + - .ad (adjust margins) .ad l -- adjust left margin only (flush left) .ad r -- adjust right margin only (flush right) @@ -52,10 +64,6 @@ are mere guesses, and some may be wrong. found by naddy@ in xloadimage(1) loc ** exist *** algo * size * imp * -- .nr third argument (auto-increment step size, requires \n+) - found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700 - loc * exist * algo * size * imp ** - - .ns (no-space mode) occurs in xine-config(1) when implementing this, also let .TH set it reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500 @@ -65,10 +73,6 @@ are mere guesses, and some may be wrong. found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200 loc * exist ** algo ** size ** imp ** -- \n+ and \n- numerical register increment and decrement - found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700 - loc * exist * algo * size * imp ** - - \w'' improve width measurements would not be very useful without an expression parser, see below needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100 @@ -87,9 +91,11 @@ are mere guesses, and some may be wrong. Found by naddy@ in devel/cutils cobfusc(1) Mon, 16 Feb 2015 19:10:52 +0100 loc *** exist *** algo *** size ** imp * -- using undefined strings or macros defines them to be empty - wl@ Mon, 14 Nov 2011 14:37:01 +0000 - loc * exist * algo * size * imp * +- check for missing roff escape sequences, implement those that are + trivial even if not usually appearing in manual pages, gracefully + ignore the non-trivial ones, document what they are supposed to do + and what mandoc does instead + loc * exist ** algo * size * imp * --- missing mdoc features ---------------------------------------------- @@ -146,10 +152,6 @@ are mere guesses, and some may be wrong. is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab." but should give "ab ." -- check whether it is correct that `D1' uses INDENT+1; - does it need its own constant? - loc * exist ** algo ** size * imp ** - - prohibit `Nm' from having non-text HEAD children (e.g., NetBSD mDNSShared/dns-sd.1) (mdoc_html.c and mdoc_term.c `Nm' handlers can be slightly simplified) @@ -170,6 +172,25 @@ are mere guesses, and some may be wrong. uqs@ Thu, 2 Jun 2011 11:33:35 +0200 loc * exist ** algo *** size * imp ** +--- missing man features ----------------------------------------------- + +- .SY and .YS, + used by many groff manual pages + +- preserve punctuation following .ME, + see ditroff(7) for an example + +- .TQ tagged paragraph continuation, + see groff_diff(7) for examples + +- groff_www(7) .MTO and .URL + These macros were used by the GNU grep(1) man page. + The groff_www(7) manual page itself uses them, too. + We should probably *not* add them to mandoc. + Just mentioning this here to keep track of the abuse. + Laura Morales 20 Apr 2018 07:33:02 +0200 + loc ** exist * algo * size ** imp * + --- missing tbl features ----------------------------------------------- - the "s" layout column specifier is used for placement of data @@ -177,6 +198,13 @@ are mere guesses, and some may be wrong. synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 loc * exist ** algo *** size * imp ** +- vertical centering in cells vertically spanned with ^ + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist *** algo *** size ** imp * + +- support .ds requests inside tbl(7) code, + see tbl(1) for an example + - support mdoc(7) and man(7) macros inside tbl(7) code; probably requires the parser reorg and letting tbl(7) use roff_node such that macro sets can mix; @@ -195,6 +223,18 @@ are mere guesses, and some may be wrong. suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600 loc * exist ** algo * size * imp ** +- implement horizontal and vertical alignment in HTML output + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo * size * imp *** + +- implement cell spanning in HTML output + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo ** size ** imp ** + +- implement table borders in HTML output + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo ** size ** imp ** + --- missing eqn features ----------------------------------------------- - In a matrix, break the output line after each matrix line. @@ -219,12 +259,15 @@ are mere guesses, and some may be wrong. surrounded by blanks, not when it is part of an unquoted word. Also, check whether there are more such cases (e.g., +?). reported by bentley@ 20 Jun 2017 02:04:29 -0600 + loc * exist ** algo ** size * imp * - Primes, opprime, and ' bentley@ Thu, 13 Jul 2017 23:14:20 -0600 --- missing misc features ---------------------------------------------- +- man -ks 1,8 route; kn@ Jul 13, 2018 orally + - italic correction (\/) in PostScript mode Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46 loc ** exist ** algo * size * imp * @@ -298,6 +341,9 @@ are mere guesses, and some may be wrong. * formatting issues: ugly output ************************************************************************ +- .UR can nest inside .TP, + see roff(7) for examples + - revisit empty in-line macros look at the difference between "Em x Em ." and "Sq x Em ." Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100 @@ -375,6 +421,17 @@ are mere guesses, and some may be wrong. --- HTML issues -------------------------------------------------------- +- wrap Sh and Ss content into
+ Laura Morales 21 Apr 2018 18:10:48 +0200 + (Evaluate whether this is really useful and has no adverse + side effects before implementing; if it is possible, + it does seem cleaner.) + loc ** exist ** algo * size * imp *** + +- format ".IP *" etc. as
    rather than
    + https://github.com/Debian/debiman/issues/67 + loc ** exist ** algo ** size * imp *** + - .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal space, see for example random(3). Introduced in http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92 @@ -471,6 +528,10 @@ are mere guesses, and some may be wrong. * warning issues ************************************************************************ +- warn about duplicate .Sh/.Ss heads + gre(4): Rename duplicate sections 20 Apr 2018 15:27:33 +0200 + loc * exist * algo * size * imp ** + - style message about macros inside .Bd -literal and .Dl, in particular font changing macros like .Cm, .Ar, .Fa (from the mdoclint TODO) @@ -509,6 +570,10 @@ are mere guesses, and some may be wrong. but just the overall format loc ** exist ** algo *** size ** imp ** +- makewhatis -p complains about language subdirectories: + /usr/local/man//ru: Unknown directory part + + ************************************************************************ * documentation issues ************************************************************************ @@ -562,7 +627,7 @@ are mere guesses, and some may be wrong. - Enable HTTP compression by detecting gzip encoding and filtering output through libz. - - Sandbox (see OpenSSH). + - Privilege separation (see OpenSSH). - Enable caching support via HTTP 304 and If-Modified-Since. - Have Mac OSX systems automatically disable -static compilation of the CGI: -static isn't supported. @@ -571,6 +636,16 @@ are mere guesses, and some may be wrong. * to improve in the groff_mdoc(7) macros ************************************************************************ +- .Cd # arch1, arch2 in section 4 pages: + find better way to indicate multiple architectures, maybe: + allow .Dt vgafb 4 "macppc sparc64" + already shown as "Device Drivers Manual (macppc sparc64)" + for apropos, make that "vgafb(4) - macppc # sparc64" instead of "- all" + groff can be made to show multiple arches, too, but it is + tedious to do the string parsing in roff code... + jmc@ 23 Apr 2018 07:24:52 +0100 [man for vgafb(4)...] + loc ** exist ** algo * size * imp *** + - use uname(1) to set doc-default-operating-system at install time tobimensch Mon, 1 Dec 2014 00:25:07 +0100 diff --git a/contrib/mdocml/apropos.1 b/contrib/mandoc/apropos.1 similarity index 94% rename from contrib/mdocml/apropos.1 rename to contrib/mandoc/apropos.1 index 4a4fa0adbc04..c0895a87e4c3 100644 --- a/contrib/mdocml/apropos.1 +++ b/contrib/mandoc/apropos.1 @@ -1,4 +1,4 @@ -.\" $Id: apropos.1,v 1.46 2017/07/04 23:40:01 schwarze Exp $ +.\" $Id: apropos.1,v 1.47 2018/02/23 18:54:02 schwarze Exp $ .\" .\" Copyright (c) 2011, 2012 Kristaps Dzonsons .\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 8 2018 $ +.Dd $Mdocdate: February 23 2018 $ .Dt APROPOS 1 .Os .Sh NAME @@ -74,7 +74,7 @@ would. If the standard output is a terminal device and .Fl c is not specified, use -.Xr less 1 +.Xr more 1 to paginate them. In .Fl a @@ -328,13 +328,36 @@ Text production: .It Li \&Ox Ta Ox No version reference .It Li \&Dx Ta Dx No version reference .El +.Pp +In general, macro keys are supposed to yield complete results without +expecting the user to consider actual macro usage. +For example, results include: +.Pp +.Bl -tag -width 3n -offset 3n -compact +.It Li \&Fa +function arguments appearing on +.Ic \&Fn +lines +.It Li \&Fn +fuction names marked up with +.Ic \&Fo +macros +.It Li \&In +include file names marked up with +.Ic \&Fd +macros +.It Li \&Vt +types appearing as function return types and +.It \& +types appearing in function arguments in the SYNOPSIS +.El .Sh ENVIRONMENT .Bl -tag -width MANPAGER .It Ev MANPAGER Any non-empty value of the environment variable .Ev MANPAGER is used instead of the standard pagination program, -.Xr less 1 ; +.Xr more 1 ; see .Xr man 1 for details. @@ -357,7 +380,7 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Xr less 1 +.Xr more 1 .Fl s is used. Only used if diff --git a/contrib/mdocml/att.c b/contrib/mandoc/att.c similarity index 100% rename from contrib/mdocml/att.c rename to contrib/mandoc/att.c diff --git a/contrib/mdocml/catman.8 b/contrib/mandoc/catman.8 similarity index 100% rename from contrib/mdocml/catman.8 rename to contrib/mandoc/catman.8 diff --git a/contrib/mdocml/catman.c b/contrib/mandoc/catman.c similarity index 100% rename from contrib/mdocml/catman.c rename to contrib/mandoc/catman.c diff --git a/contrib/mdocml/cgi.c b/contrib/mandoc/cgi.c similarity index 98% rename from contrib/mdocml/cgi.c rename to contrib/mandoc/cgi.c index 746c481ac524..8098352d6140 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mandoc/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.156 2017/06/24 14:38:32 schwarze Exp $ */ +/* $Id: cgi.c,v 1.158 2018/05/29 20:32:45 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze @@ -356,6 +356,8 @@ resp_begin_html(int code, const char *msg, const char *file) "\n" "\n" " \n" + " \n" " \n" " ", @@ -398,7 +400,7 @@ resp_searchform(const struct req *req, enum focus focus) /* Write query input box. */ - printf(" <input type=\"text\" name=\"query\" value=\""); + printf(" <input type=\"search\" name=\"query\" value=\""); if (req->q.query != NULL) html_print(req->q.query); printf( "\" size=\"40\""); @@ -434,7 +436,7 @@ resp_searchform(const struct req *req, enum focus focus) printf(" selected=\"selected\""); puts(">All Architectures</option>"); for (i = 0; i < arch_MAX; i++) { - printf(" <option value=\"%s\"", arch_names[i]); + printf(" <option"); if (NULL != req->q.arch && 0 == strcmp(arch_names[i], req->q.arch)) printf(" selected=\"selected\""); @@ -447,12 +449,10 @@ resp_searchform(const struct req *req, enum focus focus) if (req->psz > 1) { puts(" <select name=\"manpath\">"); for (i = 0; i < (int)req->psz; i++) { - printf(" <option "); + printf(" <option"); if (strcmp(req->q.manpath, req->p[i]) == 0) - printf("selected=\"selected\" "); - printf("value=\""); - html_print(req->p[i]); - printf("\">"); + printf(" selected=\"selected\""); + printf(">"); html_print(req->p[i]); puts("</option>"); } diff --git a/contrib/mdocml/cgi.h.example b/contrib/mandoc/cgi.h.example similarity index 100% rename from contrib/mdocml/cgi.h.example rename to contrib/mandoc/cgi.h.example diff --git a/contrib/mdocml/chars.c b/contrib/mandoc/chars.c similarity index 79% rename from contrib/mdocml/chars.c rename to contrib/mandoc/chars.c index 039e6dc0909c..fb9ded8baef6 100644 --- a/contrib/mdocml/chars.c +++ b/contrib/mandoc/chars.c @@ -1,4 +1,4 @@ -/* $Id: chars.c,v 1.71 2017/06/14 20:57:07 schwarze Exp $ */ +/* $Id: chars.c,v 1.73 2017/08/23 13:01:29 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -70,17 +70,17 @@ static struct ln lines[] = { /* Text markers. */ { "ci", "O", 0x25cb }, { "bu", "+\bo", 0x2022 }, - { "dd", "|\b=", 0x2021 }, - { "dg", "|\b-", 0x2020 }, + { "dd", "<**>", 0x2021 }, + { "dg", "<*>", 0x2020 }, { "lz", "<>", 0x25ca }, { "sq", "[]", 0x25a1 }, - { "ps", "<par>", 0x00b6 }, - { "sc", "<sec>", 0x00a7 }, + { "ps", "<paragraph>", 0x00b6 }, + { "sc", "<section>", 0x00a7 }, { "lh", "<=", 0x261c }, { "rh", "=>", 0x261e }, { "at", "@", 0x0040 }, { "sh", "#", 0x0023 }, - { "CR", "_|", 0x21b5 }, + { "CR", "<cr>", 0x21b5 }, { "OK", "\\/", 0x2713 }, { "CL", "<club>", 0x2663 }, { "SP", "<spade>", 0x2660 }, @@ -173,11 +173,11 @@ static struct ln lines[] = { { "OR", "v", 0x2228 }, { "no", "~", 0x00ac }, { "tno", "~", 0x00ac }, - { "te", "3", 0x2203 }, - { "fa", "-\bV", 0x2200 }, - { "st", "-)", 0x220b }, - { "tf", ".:.", 0x2234 }, - { "3d", ".:.", 0x2234 }, + { "te", "<there\037exists>", 0x2203 }, + { "fa", "<for\037all>", 0x2200 }, + { "st", "<such\037that>", 0x220b }, + { "tf", "<therefore>", 0x2234 }, + { "3d", "<therefore>", 0x2234 }, { "or", "|", 0x007c }, /* Mathematicals. */ @@ -193,8 +193,8 @@ static struct ln lines[] = { { "tmu", "x", 0x00d7 }, { "c*", "O\bx", 0x2297 }, { "c+", "O\b+", 0x2295 }, - { "di", "-:-", 0x00f7 }, - { "tdi", "-:-", 0x00f7 }, + { "di", "/", 0x00f7 }, + { "tdi", "/", 0x00f7 }, { "f/", "/", 0x2044 }, { "**", "*", 0x2217 }, { "<=", "<=", 0x2264 }, @@ -210,38 +210,38 @@ static struct ln lines[] = { { "=~", "=~", 0x2245 }, { "~~", "~~", 0x2248 }, { "~=", "~=", 0x2248 }, - { "pt", "oc", 0x221d }, + { "pt", "<proportional\037to>", 0x221d }, { "es", "{}", 0x2205 }, - { "mo", "E", 0x2208 }, - { "nm", "!E", 0x2209 }, - { "sb", "(=", 0x2282 }, - { "nb", "(!=", 0x2284 }, - { "sp", "=)", 0x2283 }, - { "nc", "!=)", 0x2285 }, - { "ib", "(=\b_", 0x2286 }, - { "ip", "=\b_)", 0x2287 }, - { "ca", "(^)", 0x2229 }, - { "cu", "U", 0x222a }, - { "/_", "_\b/", 0x2220 }, - { "pp", "_\b|", 0x22a5 }, - { "is", "'\b,\bI", 0x222b }, - { "integral", "'\b,\bI", 0x222b }, - { "sum", "E", 0x2211 }, - { "product", "TT", 0x220f }, - { "coproduct", "U", 0x2210 }, - { "gr", "V", 0x2207 }, - { "sr", "\\/", 0x221a }, - { "sqrt", "\\/", 0x221a }, + { "mo", "<element\037of>", 0x2208 }, + { "nm", "<not\037element\037of>", 0x2209 }, + { "sb", "<proper\037subset>", 0x2282 }, + { "nb", "<not\037subset>", 0x2284 }, + { "sp", "<proper\037superset>", 0x2283 }, + { "nc", "<not\037superset>", 0x2285 }, + { "ib", "<subset\037or\037equal>", 0x2286 }, + { "ip", "<superset\037or\037equal>", 0x2287 }, + { "ca", "<intersection>", 0x2229 }, + { "cu", "<union>", 0x222a }, + { "/_", "<angle>", 0x2220 }, + { "pp", "<perpendicular>", 0x22a5 }, + { "is", "<integral>", 0x222b }, + { "integral", "<integral>", 0x222b }, + { "sum", "<sum>", 0x2211 }, + { "product", "<product>", 0x220f }, + { "coproduct", "<coproduct>", 0x2210 }, + { "gr", "<nabla>", 0x2207 }, + { "sr", "<sqrt>", 0x221a }, + { "sqrt", "<sqrt>", 0x221a }, { "lc", "|~", 0x2308 }, { "rc", "~|", 0x2309 }, { "lf", "|_", 0x230a }, { "rf", "_|", 0x230b }, - { "if", "oo", 0x221e }, - { "Ah", "N", 0x2135 }, - { "Im", "I", 0x2111 }, - { "Re", "R", 0x211c }, + { "if", "<infinity>", 0x221e }, + { "Ah", "<Aleph>", 0x2135 }, + { "Im", "<Im>", 0x2111 }, + { "Re", "<Re>", 0x211c }, { "wp", "P", 0x2118 }, - { "pd", "a", 0x2202 }, + { "pd", "<del>", 0x2202 }, { "-h", "/h", 0x210f }, { "hbar", "/h", 0x210f }, { "12", "1/2", 0x00bd }, @@ -251,9 +251,9 @@ static struct ln lines[] = { { "38", "3/8", 0x215C }, { "58", "5/8", 0x215D }, { "78", "7/8", 0x215E }, - { "S1", "1", 0x00B9 }, - { "S2", "2", 0x00B2 }, - { "S3", "3", 0x00B3 }, + { "S1", "^1", 0x00B9 }, + { "S2", "^2", 0x00B2 }, + { "S3", "^3", 0x00B3 }, /* Ligatures. */ { "ff", "ff", 0xfb00 }, @@ -346,8 +346,8 @@ static struct ln lines[] = { { "oa", "o\ba", 0x00e5 }, /* Special letters. */ - { "-D", "-\bD", 0x00d0 }, - { "Sd", "d", 0x00f0 }, + { "-D", "Dh", 0x00d0 }, + { "Sd", "dh", 0x00f0 }, { "TP", "Th", 0x00de }, { "Tp", "th", 0x00fe }, { ".i", "i", 0x0131 }, @@ -364,68 +364,68 @@ static struct ln lines[] = { { "Fn", ",\bf", 0x0192 }, /* Units. */ - { "de", "<deg>", 0x00b0 }, - { "%0", "%o", 0x2030 }, + { "de", "<degree>", 0x00b0 }, + { "%0", "<permille>", 0x2030 }, { "fm", "\'", 0x2032 }, { "sd", "''", 0x2033 }, - { "mc", ",\bu", 0x00b5 }, + { "mc", "<micro>", 0x00b5 }, { "Of", "_\ba", 0x00aa }, { "Om", "_\bo", 0x00ba }, /* Greek characters. */ { "*A", "A", 0x0391 }, { "*B", "B", 0x0392 }, - { "*G", "G", 0x0393 }, - { "*D", "_\b/_\b\\", 0x0394 }, + { "*G", "<Gamma>", 0x0393 }, + { "*D", "<Delta>", 0x0394 }, { "*E", "E", 0x0395 }, { "*Z", "Z", 0x0396 }, { "*Y", "H", 0x0397 }, - { "*H", "-\bO", 0x0398 }, + { "*H", "<Theta>", 0x0398 }, { "*I", "I", 0x0399 }, { "*K", "K", 0x039a }, - { "*L", "/\\", 0x039b }, + { "*L", "<Lambda>", 0x039b }, { "*M", "M", 0x039c }, { "*N", "N", 0x039d }, - { "*C", "_\bH", 0x039e }, + { "*C", "<Xi>", 0x039e }, { "*O", "O", 0x039f }, - { "*P", "TT", 0x03a0 }, + { "*P", "<Pi>", 0x03a0 }, { "*R", "P", 0x03a1 }, - { "*S", "S", 0x03a3 }, + { "*S", "<Sigma>", 0x03a3 }, { "*T", "T", 0x03a4 }, { "*U", "Y", 0x03a5 }, - { "*F", "I\bO", 0x03a6 }, + { "*F", "<Phi>", 0x03a6 }, { "*X", "X", 0x03a7 }, - { "*Q", "I\bY", 0x03a8 }, - { "*W", "_\bO", 0x03a9 }, - { "*a", "a", 0x03b1 }, - { "*b", "B", 0x03b2 }, - { "*g", "y", 0x03b3 }, - { "*d", "d", 0x03b4 }, - { "*e", "e", 0x03b5 }, - { "*z", ",\bC", 0x03b6 }, - { "*y", "n", 0x03b7 }, - { "*h", "-\b0", 0x03b8 }, - { "*i", "i", 0x03b9 }, - { "*k", "k", 0x03ba }, - { "*l", ">\b\\", 0x03bb }, - { "*m", ",\bu", 0x03bc }, - { "*n", "v", 0x03bd }, - { "*c", ",\bE", 0x03be }, + { "*Q", "<Psi>", 0x03a8 }, + { "*W", "<Omega>", 0x03a9 }, + { "*a", "<alpha>", 0x03b1 }, + { "*b", "<beta>", 0x03b2 }, + { "*g", "<gamma>", 0x03b3 }, + { "*d", "<delta>", 0x03b4 }, + { "*e", "<epsilon>", 0x03b5 }, + { "*z", "<zeta>", 0x03b6 }, + { "*y", "<eta>", 0x03b7 }, + { "*h", "<theta>", 0x03b8 }, + { "*i", "<iota>", 0x03b9 }, + { "*k", "<kappa>", 0x03ba }, + { "*l", "<lambda>", 0x03bb }, + { "*m", "<mu>", 0x03bc }, + { "*n", "<nu>", 0x03bd }, + { "*c", "<xi>", 0x03be }, { "*o", "o", 0x03bf }, - { "*p", "-\bn", 0x03c0 }, - { "*r", "p", 0x03c1 }, - { "*s", "-\bo", 0x03c3 }, - { "*t", "~\bt", 0x03c4 }, - { "*u", "u", 0x03c5 }, - { "*f", "|\bo", 0x03d5 }, - { "*x", "x", 0x03c7 }, - { "*q", "|\bu", 0x03c8 }, - { "*w", "w", 0x03c9 }, - { "+h", "-\b0", 0x03d1 }, - { "+f", "|\bo", 0x03c6 }, - { "+p", "-\bw", 0x03d6 }, - { "+e", "e", 0x03f5 }, - { "ts", "s", 0x03c2 }, + { "*p", "<pi>", 0x03c0 }, + { "*r", "<rho>", 0x03c1 }, + { "*s", "<sigma>", 0x03c3 }, + { "*t", "<tau>", 0x03c4 }, + { "*u", "<upsilon>", 0x03c5 }, + { "*f", "<phi>", 0x03d5 }, + { "*x", "<chi>", 0x03c7 }, + { "*q", "<psi>", 0x03c8 }, + { "*w", "<omega>", 0x03c9 }, + { "+h", "<theta>", 0x03d1 }, + { "+f", "<phi>", 0x03c6 }, + { "+p", "<pi>", 0x03d6 }, + { "+e", "<epsilon>", 0x03f5 }, + { "ts", "<sigma>", 0x03c2 }, }; static struct ohash mchars; diff --git a/contrib/mdocml/compat_err.c b/contrib/mandoc/compat_err.c similarity index 100% rename from contrib/mdocml/compat_err.c rename to contrib/mandoc/compat_err.c diff --git a/contrib/mdocml/compat_fts.c b/contrib/mandoc/compat_fts.c similarity index 100% rename from contrib/mdocml/compat_fts.c rename to contrib/mandoc/compat_fts.c diff --git a/contrib/mdocml/compat_fts.h b/contrib/mandoc/compat_fts.h similarity index 100% rename from contrib/mdocml/compat_fts.h rename to contrib/mandoc/compat_fts.h diff --git a/contrib/mdocml/compat_getline.c b/contrib/mandoc/compat_getline.c similarity index 100% rename from contrib/mdocml/compat_getline.c rename to contrib/mandoc/compat_getline.c diff --git a/contrib/mdocml/compat_getsubopt.c b/contrib/mandoc/compat_getsubopt.c similarity index 100% rename from contrib/mdocml/compat_getsubopt.c rename to contrib/mandoc/compat_getsubopt.c diff --git a/contrib/mdocml/compat_isblank.c b/contrib/mandoc/compat_isblank.c similarity index 100% rename from contrib/mdocml/compat_isblank.c rename to contrib/mandoc/compat_isblank.c diff --git a/contrib/mdocml/compat_mkdtemp.c b/contrib/mandoc/compat_mkdtemp.c similarity index 100% rename from contrib/mdocml/compat_mkdtemp.c rename to contrib/mandoc/compat_mkdtemp.c diff --git a/contrib/mdocml/compat_ohash.c b/contrib/mandoc/compat_ohash.c similarity index 100% rename from contrib/mdocml/compat_ohash.c rename to contrib/mandoc/compat_ohash.c diff --git a/contrib/mdocml/compat_ohash.h b/contrib/mandoc/compat_ohash.h similarity index 100% rename from contrib/mdocml/compat_ohash.h rename to contrib/mandoc/compat_ohash.h diff --git a/contrib/mdocml/compat_progname.c b/contrib/mandoc/compat_progname.c similarity index 100% rename from contrib/mdocml/compat_progname.c rename to contrib/mandoc/compat_progname.c diff --git a/contrib/mdocml/compat_reallocarray.c b/contrib/mandoc/compat_reallocarray.c similarity index 100% rename from contrib/mdocml/compat_reallocarray.c rename to contrib/mandoc/compat_reallocarray.c diff --git a/contrib/mdocml/compat_recallocarray.c b/contrib/mandoc/compat_recallocarray.c similarity index 100% rename from contrib/mdocml/compat_recallocarray.c rename to contrib/mandoc/compat_recallocarray.c diff --git a/contrib/mdocml/compat_strcasestr.c b/contrib/mandoc/compat_strcasestr.c similarity index 100% rename from contrib/mdocml/compat_strcasestr.c rename to contrib/mandoc/compat_strcasestr.c diff --git a/contrib/mdocml/compat_stringlist.c b/contrib/mandoc/compat_stringlist.c similarity index 100% rename from contrib/mdocml/compat_stringlist.c rename to contrib/mandoc/compat_stringlist.c diff --git a/contrib/mdocml/compat_stringlist.h b/contrib/mandoc/compat_stringlist.h similarity index 100% rename from contrib/mdocml/compat_stringlist.h rename to contrib/mandoc/compat_stringlist.h diff --git a/contrib/mdocml/compat_strlcat.c b/contrib/mandoc/compat_strlcat.c similarity index 100% rename from contrib/mdocml/compat_strlcat.c rename to contrib/mandoc/compat_strlcat.c diff --git a/contrib/mdocml/compat_strlcpy.c b/contrib/mandoc/compat_strlcpy.c similarity index 100% rename from contrib/mdocml/compat_strlcpy.c rename to contrib/mandoc/compat_strlcpy.c diff --git a/contrib/mandoc/compat_strndup.c b/contrib/mandoc/compat_strndup.c new file mode 100644 index 000000000000..5e127364f5c8 --- /dev/null +++ b/contrib/mandoc/compat_strndup.c @@ -0,0 +1,50 @@ +#include "config.h" + +#if HAVE_STRNDUP + +int dummy; + +#else + +/* $Id: compat_strndup.c,v 1.1 2018/02/27 11:16:23 schwarze Exp $ */ +/* OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp */ +/* + * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> + * + * 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/types.h> + +#include <stdlib.h> +#include <string.h> + +char * +strndup(const char *str, size_t maxlen) +{ + char *copy; + size_t len; + + for (len = 0; len < maxlen && str[len] != '\0'; len++) + continue; + + copy = malloc(len + 1); + if (copy != NULL) { + (void)memcpy(copy, str, len); + copy[len] = '\0'; + } + + return copy; +} + +#endif diff --git a/contrib/mdocml/compat_strsep.c b/contrib/mandoc/compat_strsep.c similarity index 100% rename from contrib/mdocml/compat_strsep.c rename to contrib/mandoc/compat_strsep.c diff --git a/contrib/mdocml/compat_strtonum.c b/contrib/mandoc/compat_strtonum.c similarity index 100% rename from contrib/mdocml/compat_strtonum.c rename to contrib/mandoc/compat_strtonum.c diff --git a/contrib/mdocml/compat_vasprintf.c b/contrib/mandoc/compat_vasprintf.c similarity index 100% rename from contrib/mdocml/compat_vasprintf.c rename to contrib/mandoc/compat_vasprintf.c diff --git a/contrib/mdocml/config.h b/contrib/mandoc/config.h similarity index 96% rename from contrib/mdocml/config.h rename to contrib/mandoc/config.h index 57d3f3137814..4525870756b7 100644 --- a/contrib/mdocml/config.h +++ b/contrib/mandoc/config.h @@ -38,6 +38,7 @@ #define HAVE_STRINGLIST 1 #define HAVE_STRLCAT 1 #define HAVE_STRLCPY 1 +#define HAVE_STRNDUP 1 #define HAVE_STRPTIME 1 #define HAVE_STRSEP 1 #define HAVE_STRTONUM 1 @@ -47,6 +48,7 @@ #define HAVE_OHASH 1 #define BINM_APROPOS "apropos" +#define BINM_CATMAN "catman" #define BINM_MAKEWHATIS "makewhatis" #define BINM_MAN "man" #define BINM_SOELIM "soelim" diff --git a/contrib/mdocml/configure b/contrib/mandoc/configure similarity index 81% rename from contrib/mdocml/configure rename to contrib/mandoc/configure index f9416ce7399d..1ccc37dc0cdc 100755 --- a/contrib/mdocml/configure +++ b/contrib/mandoc/configure @@ -1,8 +1,8 @@ #!/bin/sh # -# $Id: configure,v 1.64 2017/07/01 09:47:30 schwarze Exp $ +# $Id: configure,v 1.66 2018/07/31 15:34:00 schwarze Exp $ # -# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -27,7 +27,7 @@ set -e # 3: config.log exec 3> config.log -echo "config.log: writing..." +echo "file config.log: writing..." # --- default settings ------------------------------------------------- # Initialize all variables here, @@ -41,14 +41,13 @@ OSNAME= UTF8_LOCALE= CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | env -i make -sf -` -CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings" -CFLAGS="${CFLAGS} -Wno-unused-parameter" +CFLAGS= LDADD= LDFLAGS= LD_NANOSLEEP= LD_OHASH= LD_RECVMSG= -STATIC="-static" +STATIC= BUILD_CGI=0 BUILD_CATMAN=0 @@ -83,6 +82,7 @@ HAVE_STRCASESTR= HAVE_STRINGLIST= HAVE_STRLCAT= HAVE_STRLCPY= +HAVE_STRNDUP= HAVE_STRPTIME= HAVE_STRSEP= HAVE_STRTONUM= @@ -126,27 +126,25 @@ LN="ln -f" # --- manual settings from configure.local ----------------------------- if [ -r ./configure.local ]; then - echo "configure.local: reading..." 1>&2 - echo "configure.local: reading..." 1>&3 + echo "file configure.local: reading..." 1>&2 + echo "file configure.local: reading..." 1>&3 cat ./configure.local 1>&3 . ./configure.local else - echo "configure.local: no (fully automatic configuration)" 1>&2 - echo "configure.local: no (fully automatic configuration)" 1>&3 + echo "file configure.local: no (fully automatic configuration)" 1>&2 + echo "file configure.local: no (fully automatic configuration)" 1>&3 fi echo 1>&3 -# --- tests for config.h ---------------------------------------------- - -COMP="${CC} ${CFLAGS} -Wno-unused -Werror" +# --- tests functions -------------------------------------------------- # Check whether this HAVE_ setting is manually overridden. # If yes, use the override, if no, do not decide anything yet. -# Arguments: lower-case test name, manual value +# Arguments: test file name, test var name, manual value ismanual() { [ -z "${3}" ] && return 1 - echo "${1}: manual (HAVE_${2}=${3})" 1>&2 - echo "${1}: manual (HAVE_${2}=${3})" 1>&3 + echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&2 + echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&3 echo 1>&3 return 0 } @@ -154,31 +152,33 @@ ismanual() { # Run a single autoconfiguration test. # In case of success, enable the feature. # In case of failure, do not decide anything yet. -# Arguments: lower-case test name, upper-case test name, additional CFLAGS +# Arguments: test file name, test var name, additional CFLAGS singletest() { cat 1>&3 << __HEREDOC__ -${1}${3}: testing... +testing ${1}${3} ... ${COMP} -o test-${1} test-${1}.c ${3} __HEREDOC__ if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} 1>&3 2>&3 then - echo "${1}${3}: ${CC} succeeded" 1>&3 + echo "partial result of ${1}${3}: ${CC} succeeded" 1>&3 else - echo "${1}${3}: ${CC} failed with $?" 1>&3 + echo "result of ${1}${3}: ${CC} failed with exit status $?" 1>&3 + echo "result of compiling ${1}${3}: no" 1>&3 echo 1>&3 return 1 fi if ./test-${1} 1>&3 2>&3; then - echo "${1}${3}: yes" 1>&2 - echo "${1}${3}: yes" 1>&3 + echo "tested ${1}${3}: yes" 1>&2 + echo "result of running ${1}${3}: yes" 1>&3 echo 1>&3 eval HAVE_${2}=1 rm "test-${1}" return 0 else - echo "${1}${3}: execution failed with $?" 1>&3 + echo "result of ${1}${3}: execution failed with exit status $?" 1>&3 + echo "result of running ${1}${3}: no" 1>&3 echo 1>&3 rm "test-${1}" return 1 @@ -187,12 +187,12 @@ __HEREDOC__ # Run a complete autoconfiguration test, including the check for # a manual override and disabling the feature on failure. -# Arguments: lower case name, upper case name, additional CFLAGS +# Arguments: test file name, test var name, additional CFLAGS runtest() { eval _manual=\${HAVE_${2}} ismanual "${1}" "${2}" "${_manual}" && return 0 singletest "${1}" "${2}" "${3}" && return 0 - echo "${1}${3}: no" 1>&2 + echo "tested ${1}${3}: no" 1>&2 eval HAVE_${2}=0 return 1 } @@ -201,18 +201,54 @@ runtest() { get_locale() { [ -n "${HAVE_WCHAR}" ] && [ "${HAVE_WCHAR}" -eq 0 ] && return 0 ismanual UTF8_LOCALE UTF8_LOCALE "$UTF8_LOCALE" && return 0 - echo "UTF8_LOCALE: testing..." 1>&3 + echo "testing UTF8_LOCALE ..." 1>&3 UTF8_LOCALE=`locale -a | grep -i '^en_US\.UTF-*8$' | head -n 1` if [ -z "${UTF8_LOCALE}" ]; then UTF8_LOCALE=`locale -a | grep -i '\.UTF-*8' | head -n 1` [ -n "${UTF8_LOCALE}" ] || return 1 fi - echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&2 - echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&3 + echo "selected UTF8_LOCALE=${UTF8_LOCALE}" 1>&2 + echo "selected UTF8_LOCALE=${UTF8_LOCALE}" 1>&3 echo 1>&3 return 0; } +# --- compiler options ------------------------------------------------- + +if [ -n "${CFLAGS}" ]; then + COMP="${CC} ${CFLAGS}" + echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&2 + echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&3 + echo 1>&3 +else + CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes" + CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter" + COMP="${CC} ${CFLAGS} -Wno-unused -Werror" + echo -n "tested ${CC} -W: " 1>&2 + echo -n "testing ${CC} -W: " 1>&3 + runtest noop WFLAG || true + if [ "${HAVE_WFLAG}" -eq 0 ]; then + CFLAGS="-g" + COMP="${CC} ${CFLAGS}" + fi + echo "selected CFLAGS=\"${CFLAGS}\"" 1>&2 + echo "selected CFLAGS=\"${CFLAGS}\"" 1>&3 + echo 1>&3 +fi + +if [ -n "${STATIC}" ]; then + echo "selected STATIC=\"${STATIC}\" (manual)" 1>&2 + echo "selected STATIC=\"${STATIC}\" (manual)" 1>&3 + echo 1>&3 +else + runtest noop STATIC -static || true + [ ${HAVE_STATIC} -eq 0 ] || STATIC="-static" + echo "selected STATIC=\"${STATIC}\"" 1>&2 + echo "selected STATIC=\"${STATIC}\"" 1>&3 + echo 1>&3 +fi + +# --- tests for config.h ---------------------------------------------- # --- library functions --- runtest dirent-namlen DIRENT_NAMLEN || true @@ -238,6 +274,7 @@ runtest strcasestr STRCASESTR || true runtest stringlist STRINGLIST || true runtest strlcat STRLCAT || true runtest strlcpy STRLCPY || true +runtest strndup STRNDUP || true runtest strptime STRPTIME || true runtest strsep STRSEP || true runtest strtonum STRTONUM || true @@ -264,8 +301,9 @@ if get_locale; then runtest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true else HAVE_WCHAR=0 - echo "wchar: no (no UTF8_LOCALE)" 1>&2 - echo "wchar: no (no UTF8_LOCALE)" 1>&3 + echo "tested wchar: no (no UTF8_LOCALE)" 1>&2 + echo "tested wchar: no (no UTF8_LOCALE)" 1>&3 + echo 1>&3 fi # --- nanosleep --- @@ -328,8 +366,8 @@ fi # --- LDADD --- LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_RECVMSG} ${LD_OHASH} -lz" -echo "LDADD=\"${LDADD}\"" 1>&2 -echo "LDADD=\"${LDADD}\"" 1>&3 +echo "selected LDADD=\"${LDADD}\"" 1>&2 +echo "selected LDADD=\"${LDADD}\"" 1>&3 echo 1>&3 # --- write config.h --- @@ -353,7 +391,8 @@ __HEREDOC__ [ ${HAVE_GETLINE} -eq 0 -o \ ${HAVE_REALLOCARRAY} -eq 0 -o ${HAVE_RECALLOCARRAY} -eq 0 -o \ - ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \ + ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 -o \ + ${HAVE_STRNDUP} -eq 0 ] \ && echo "#include <sys/types.h>" [ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>" [ ${HAVE_GETLINE} -eq 0 ] && echo "#include <stdio.h>" @@ -396,6 +435,7 @@ cat << __HEREDOC__ #define HAVE_STRINGLIST ${HAVE_STRINGLIST} #define HAVE_STRLCAT ${HAVE_STRLCAT} #define HAVE_STRLCPY ${HAVE_STRLCPY} +#define HAVE_STRNDUP ${HAVE_STRNDUP} #define HAVE_STRPTIME ${HAVE_STRPTIME} #define HAVE_STRSEP ${HAVE_STRSEP} #define HAVE_STRTONUM ${HAVE_STRTONUM} @@ -452,6 +492,9 @@ fi [ ${HAVE_STRLCPY} -eq 0 ] && \ echo "extern size_t strlcpy(char *, const char *, size_t);" +[ ${HAVE_STRNDUP} -eq 0 ] && \ + echo "extern char *strndup(const char *, size_t);" + [ ${HAVE_STRSEP} -eq 0 ] && \ echo "extern char *strsep(char **, const char *);" @@ -461,8 +504,8 @@ fi [ ${HAVE_VASPRINTF} -eq 0 ] && \ echo "extern int vasprintf(char **, const char *, va_list);" -echo "config.h: written" 1>&2 -echo "config.h: written" 1>&3 +echo "file config.h: written" 1>&2 +echo "file config.h: written" 1>&3 # --- tests for Makefile.local ----------------------------------------- @@ -531,7 +574,7 @@ INSTALL_DATA = ${INSTALL_DATA} LN = ${LN} __HEREDOC__ -echo "Makefile.local: written" 1>&2 -echo "Makefile.local: written" 1>&3 +echo "file Makefile.local: written" 1>&2 +echo "file Makefile.local: written" 1>&3 exit 0 diff --git a/contrib/mdocml/configure.local.example b/contrib/mandoc/configure.local.example similarity index 91% rename from contrib/mdocml/configure.local.example rename to contrib/mandoc/configure.local.example index 4a583ad0bab2..82fc2a2c28e5 100644 --- a/contrib/mdocml/configure.local.example +++ b/contrib/mandoc/configure.local.example @@ -1,6 +1,6 @@ -# $Id: configure.local.example,v 1.33 2017/07/20 16:24:53 schwarze Exp $ +# $Id: configure.local.example,v 1.34 2018/07/31 15:34:00 schwarze Exp $ # -# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -77,7 +77,7 @@ MANPATH_BASE="/usr/share/man:/usr/X11R6/man" # If you do not want uname(3) to be called but instead want a fixed # string to be used, use the following line: -OSNAME="OpenBSD 6.0" +OSNAME="OpenBSD 6.3" # The following installation directories are used. # It is possible to set only one or a few of these variables, @@ -100,6 +100,7 @@ BIN_FROM_SBIN="../bin" # Some distributions may want to avoid naming conflicts # with the configuration files of other man(1) implementations. # This changes the name of the installed section 5 manual page as well. + MANM_MANCONF="mandoc.conf" # default is "man.conf" # Some distributions may want to avoid naming conflicts among manuals. @@ -148,13 +149,6 @@ LN="ln -sf" # default is "ln -f" LD_OHASH="-lutil" -# When library autodetection decides to use -L/usr/local/lib, -# -I/usr/local/include is automatically added to CFLAGS. -# If you manually set LD_OHASH to something including -L/usr/local/lib, -# chances are you will also need the following line: - -CFLAGS="${CFLAGS} -I/usr/local/include" - # Some platforms may need an additional linker flag for nanosleep(2). # If none is needed or it is -lrt, it is autodetected. # Otherwise, set the following variable. @@ -222,16 +216,22 @@ BUILD_CGI=1 # The remaining settings in this section are only relevant if BUILD_CGI # is enabled. Otherwise, they have no effect either way. -# By default, man.cgi(8) is linked statically. -# Some systems do not support static linking, for example Mac OS X. -# In that case, use the following line: +# By default, man.cgi(8) is linked statically if the compiler supports +# the -static option. If automatic detection fails, you can force +# static linking of man.cgi(8). -STATIC= +STATIC="-static" -# Some systems, for example Linux, require -pthread for static linking: +# Some systems may require -pthread for static linking: STATIC="-static -pthread" +# If static linking works in general but not with additional libraries +# like -lrt or -lz, you can force dynamic linking. This may for +# example be required on SunOS 5.9. + +STATIC=" " + # Some directories. # This works just like PREFIX, see above. @@ -263,15 +263,19 @@ BINM_CATMAN=mcatman # default is "catman" CC=cc +# Because the system compiler may not provide <stdint.h>, +# SunOS 5.9 may need: + +CC=gcc + # IBM AIX may need: CC=xlc -# The default compiler flags are: - -CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings" - -# IBM AIX xlc does not support -W; in that case, please use: +# Normally, leave CFLAGS unset. In that case, -g will automatically +# be used, and various -W options will be added if the compiler +# supports them. If you define CFLAGS manually, it will be used +# unchanged, and nothing will be added. CFLAGS="-g" diff --git a/contrib/mdocml/dba.c b/contrib/mandoc/dba.c similarity index 100% rename from contrib/mdocml/dba.c rename to contrib/mandoc/dba.c diff --git a/contrib/mdocml/dba.h b/contrib/mandoc/dba.h similarity index 100% rename from contrib/mdocml/dba.h rename to contrib/mandoc/dba.h diff --git a/contrib/mdocml/dba_array.c b/contrib/mandoc/dba_array.c similarity index 100% rename from contrib/mdocml/dba_array.c rename to contrib/mandoc/dba_array.c diff --git a/contrib/mdocml/dba_array.h b/contrib/mandoc/dba_array.h similarity index 100% rename from contrib/mdocml/dba_array.h rename to contrib/mandoc/dba_array.h diff --git a/contrib/mdocml/dba_read.c b/contrib/mandoc/dba_read.c similarity index 100% rename from contrib/mdocml/dba_read.c rename to contrib/mandoc/dba_read.c diff --git a/contrib/mdocml/dba_write.c b/contrib/mandoc/dba_write.c similarity index 100% rename from contrib/mdocml/dba_write.c rename to contrib/mandoc/dba_write.c diff --git a/contrib/mdocml/dba_write.h b/contrib/mandoc/dba_write.h similarity index 100% rename from contrib/mdocml/dba_write.h rename to contrib/mandoc/dba_write.h diff --git a/contrib/mdocml/dbm.c b/contrib/mandoc/dbm.c similarity index 100% rename from contrib/mdocml/dbm.c rename to contrib/mandoc/dbm.c diff --git a/contrib/mdocml/dbm.h b/contrib/mandoc/dbm.h similarity index 100% rename from contrib/mdocml/dbm.h rename to contrib/mandoc/dbm.h diff --git a/contrib/mdocml/dbm_map.c b/contrib/mandoc/dbm_map.c similarity index 100% rename from contrib/mdocml/dbm_map.c rename to contrib/mandoc/dbm_map.c diff --git a/contrib/mdocml/dbm_map.h b/contrib/mandoc/dbm_map.h similarity index 100% rename from contrib/mdocml/dbm_map.h rename to contrib/mandoc/dbm_map.h diff --git a/contrib/mdocml/demandoc.1 b/contrib/mandoc/demandoc.1 similarity index 100% rename from contrib/mdocml/demandoc.1 rename to contrib/mandoc/demandoc.1 diff --git a/contrib/mdocml/demandoc.c b/contrib/mandoc/demandoc.c similarity index 100% rename from contrib/mdocml/demandoc.c rename to contrib/mandoc/demandoc.c diff --git a/contrib/mdocml/eqn.7 b/contrib/mandoc/eqn.7 similarity index 99% rename from contrib/mdocml/eqn.7 rename to contrib/mandoc/eqn.7 index 33d509bd13e3..244903c56fe9 100644 --- a/contrib/mdocml/eqn.7 +++ b/contrib/mandoc/eqn.7 @@ -1,4 +1,4 @@ -.\" $Id: eqn.7,v 1.36 2017/07/20 11:07:27 schwarze Exp $ +.\" $Id: eqn.7,v 1.37 2017/09/04 10:35:27 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 20 2017 $ +.Dd $Mdocdate: September 4 2017 $ .Dt EQN 7 .Os .Sh NAME @@ -83,7 +83,7 @@ box : text | \(dqsqrt\(dq box | box pos box | box mark - | \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq ]* + | \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq]* \(dq}\(dq | pile \(dq{\(dq list \(dq}\(dq | font box | \(dqsize\(dq text box diff --git a/contrib/mdocml/eqn.c b/contrib/mandoc/eqn.c similarity index 100% rename from contrib/mdocml/eqn.c rename to contrib/mandoc/eqn.c diff --git a/contrib/mdocml/eqn_html.c b/contrib/mandoc/eqn_html.c similarity index 100% rename from contrib/mdocml/eqn_html.c rename to contrib/mandoc/eqn_html.c diff --git a/contrib/mdocml/eqn_term.c b/contrib/mandoc/eqn_term.c similarity index 82% rename from contrib/mdocml/eqn_term.c rename to contrib/mandoc/eqn_term.c index 08f4a993eca4..669c3c56cff7 100644 --- a/contrib/mdocml/eqn_term.c +++ b/contrib/mandoc/eqn_term.c @@ -1,4 +1,4 @@ -/* $Id: eqn_term.c,v 1.13 2017/07/08 14:51:04 schwarze Exp $ */ +/* $Id: eqn_term.c,v 1.17 2017/08/23 21:56:20 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -20,6 +20,7 @@ #include <sys/types.h> #include <assert.h> +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -51,6 +52,7 @@ static void eqn_box(struct termp *p, const struct eqn_box *bp) { const struct eqn_box *child; + const char *cp; int delim; /* Delimiters around this box? */ @@ -67,7 +69,16 @@ eqn_box(struct termp *p, const struct eqn_box *bp) ((bp->parent->type == EQN_LIST && bp->expectargs == 1) || (bp->parent->type == EQN_SUBEXPR && bp->pos != EQNPOS_SQRT)))))) { - if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) + if ((bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) || + (bp->type == EQN_LIST && + bp->first != NULL && + bp->first->type != EQN_PILE && + bp->first->type != EQN_MATRIX && + bp->prev != NULL && + (bp->prev->type == EQN_LIST || + (bp->prev->type == EQN_TEXT && + (*bp->prev->text == '\\' || + isalpha((unsigned char)*bp->prev->text)))))) p->flags |= TERMP_NOSPACE; term_word(p, bp->left != NULL ? bp->left : "("); p->flags |= TERMP_NOSPACE; @@ -80,8 +91,17 @@ eqn_box(struct termp *p, const struct eqn_box *bp) if (bp->font != EQNFONT_NONE) term_fontpush(p, fontmap[(int)bp->font]); - if (bp->text != NULL) + if (bp->text != NULL) { + if (strchr("!\"'),.:;?]}", *bp->text) != NULL) + p->flags |= TERMP_NOSPACE; term_word(p, bp->text); + if ((cp = strchr(bp->text, '\0')) > bp->text && + (strchr("\"'([{", cp[-1]) != NULL || + (bp->prev == NULL && (cp[-1] == '-' || + (cp >= bp->text + 5 && + strcmp(cp - 5, "\\[mi]") == 0))))) + p->flags |= TERMP_NOSPACE; + } /* Special box types. */ @@ -98,9 +118,9 @@ eqn_box(struct termp *p, const struct eqn_box *bp) term_word(p, bp->pos == EQNPOS_OVER ? "/" : (bp->pos == EQNPOS_SUP || bp->pos == EQNPOS_TO) ? "^" : "_"); - p->flags |= TERMP_NOSPACE; child = child->next; if (child != NULL) { + p->flags |= TERMP_NOSPACE; eqn_box(p, child); if (bp->pos == EQNPOS_FROMTO || bp->pos == EQNPOS_SUBSUP) { diff --git a/contrib/mdocml/gmdiff b/contrib/mandoc/gmdiff similarity index 74% rename from contrib/mdocml/gmdiff rename to contrib/mandoc/gmdiff index d5b1f2a76f01..65cf353daa0c 100644 --- a/contrib/mdocml/gmdiff +++ b/contrib/mandoc/gmdiff @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -19,7 +19,7 @@ if [ `id -u` -eq 0 ]; then fi if [ $# -eq 0 ]; then - echo "usage: $0 [-h] manual_source_file ..." + echo "usage: $0 [-h|-u] manual_source_file ..." exit 1 fi @@ -28,22 +28,25 @@ if [ "X$1" = "X-h" ]; then export PATH="/usr/local/heirloom-doctools/bin:$PATH" EQN="neqn" ROFF="nroff" - MOPT="-Omdoc $MOPT" + MOPT="-Ios=BSD -Tascii $MOPT" + COLPIPE="col -b" elif [ "X$1" = "X-u" ]; then shift ROFF="groff -ket -ww -Tutf8 -P -c" - MOPT="-Werror -Tutf8 $MOPT" + MOPT="-Ios=OpenBSD -Wall -Tutf8 $MOPT" + COLPIPE="cat" else - ROFF="groff -et -ww -Tascii -P -c" - MOPT="-Werror -Tascii $MOPT" + ROFF="groff -et -ww -mtty-char -Tascii -P -c" + MOPT="-Ios=OpenBSD -Wall -Tascii $MOPT" + COLPIPE="cat" fi while [ -n "$1" ]; do file=$1 shift echo " ========== $file ========== " - $ROFF -mandoc $file 2> /tmp/roff.err > /tmp/roff.out - ${MANDOC:=mandoc} -Ios=OpenBSD $MOPT $file \ + $ROFF -mandoc $file | $COLPIPE 2> /tmp/roff.err > /tmp/roff.out + ${MANDOC:=mandoc} $MOPT $file | $COLPIPE \ 2> /tmp/mandoc.err > /tmp/mandoc.out for i in roff mandoc; do [ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err diff --git a/contrib/mdocml/html.c b/contrib/mandoc/html.c similarity index 78% rename from contrib/mdocml/html.c rename to contrib/mandoc/html.c index fc55e881b784..70935dcd57e4 100644 --- a/contrib/mdocml/html.c +++ b/contrib/mandoc/html.c @@ -1,7 +1,7 @@ -/* $Id: html.c,v 1.219 2017/07/15 17:57:51 schwarze Exp $ */ +/* $Id: html.c,v 1.238 2018/06/25 16:54:59 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,6 +22,7 @@ #include <assert.h> #include <ctype.h> #include <stdarg.h> +#include <stddef.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -29,6 +30,7 @@ #include <unistd.h> #include "mandoc_aux.h" +#include "mandoc_ohash.h" #include "mandoc.h" #include "roff.h" #include "out.h" @@ -59,6 +61,7 @@ static const struct htmldata htmltags[TAG_MAX] = { {"meta", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, {"title", HTML_NLAROUND}, {"div", HTML_NLAROUND}, + {"div", 0}, {"h1", HTML_NLAROUND}, {"h2", HTML_NLAROUND}, {"span", 0}, @@ -66,8 +69,6 @@ static const struct htmldata htmltags[TAG_MAX] = { {"br", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, {"a", 0}, {"table", HTML_NLALL | HTML_INDENT}, - {"colgroup", HTML_NLALL | HTML_INDENT}, - {"col", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, {"tr", HTML_NLALL | HTML_INDENT}, {"td", HTML_NLAROUND}, {"li", HTML_NLAROUND | HTML_INDENT}, @@ -103,20 +104,9 @@ static const struct htmldata htmltags[TAG_MAX] = { {"mover", 0}, }; -static const char *const roffscales[SCALE_MAX] = { - "cm", /* SCALE_CM */ - "in", /* SCALE_IN */ - "pc", /* SCALE_PC */ - "pt", /* SCALE_PT */ - "em", /* SCALE_EM */ - "em", /* SCALE_MM */ - "ex", /* SCALE_EN */ - "ex", /* SCALE_BU */ - "em", /* SCALE_VS */ - "ex", /* SCALE_FS */ -}; +/* Avoid duplicate HTML id= attributes. */ +static struct ohash id_unique; -static void a2width(const char *, struct roffsu *); static void print_byte(struct html *, char); static void print_endword(struct html *); static void print_indent(struct html *); @@ -143,6 +133,8 @@ html_alloc(const struct manoutput *outopts) if (outopts->fragment) h->oflags |= HTML_FRAGMENT; + mandoc_ohash_init(&id_unique, 4, 0); + return h; } @@ -151,15 +143,22 @@ html_free(void *p) { struct tag *tag; struct html *h; + char *cp; + unsigned int slot; h = (struct html *)p; - while ((tag = h->tag) != NULL) { h->tag = tag->next; free(tag); } - free(h); + + cp = ohash_first(&id_unique, &slot); + while (cp != NULL) { + free(cp); + cp = ohash_next(&id_unique, &slot); + } + ohash_delete(&id_unique); } void @@ -168,9 +167,14 @@ print_gen_head(struct html *h) struct tag *t; print_otag(h, TAG_META, "?", "charset", "utf-8"); + if (h->style != NULL) { + print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet", + h->style, "type", "text/css", "media", "all"); + return; + } /* - * Print a default style-sheet. + * Print a minimal embedded style sheet. */ t = print_otag(h, TAG_STYLE, ""); @@ -181,11 +185,23 @@ print_gen_head(struct html *h) print_text(h, "td.head-vol { text-align: center; }"); print_endline(h); print_text(h, "div.Pp { margin: 1ex 0ex; }"); + print_endline(h); + print_text(h, "div.Nd, div.Bf, div.Op { display: inline; }"); + print_endline(h); + print_text(h, "span.Pa, span.Ad { font-style: italic; }"); + print_endline(h); + print_text(h, "span.Ms { font-weight: bold; }"); + print_endline(h); + print_text(h, "dl.Bl-diag "); + print_byte(h, '>'); + print_text(h, " dt { font-weight: bold; }"); + print_endline(h); + print_text(h, "code.Nm, code.Fl, code.Cm, code.Ic, " + "code.In, code.Fd, code.Fn,"); + print_endline(h); + print_text(h, "code.Cd { font-weight: bold; " + "font-family: inherit; }"); print_tagq(h, t); - - if (h->style) - print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet", - h->style, "type", "text/css", "media", "all"); } static void @@ -239,10 +255,12 @@ print_metaf(struct html *h, enum mandoc_esc deco) } char * -html_make_id(const struct roff_node *n) +html_make_id(const struct roff_node *n, int unique) { const struct roff_node *nch; - char *buf, *cp; + char *buf, *bufs, *cp; + unsigned int slot; + int suffix; for (nch = n->child; nch != NULL; nch = nch->next) if (nch->type != ROFFT_TEXT) @@ -250,65 +268,46 @@ html_make_id(const struct roff_node *n) buf = NULL; deroff(&buf, n); - - /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */ - - for (cp = buf; *cp != '\0'; cp++) - if (*cp == ' ') - *cp = '_'; - - return buf; -} - -int -html_strlen(const char *cp) -{ - size_t rsz; - int skip, sz; + if (buf == NULL) + return NULL; /* - * Account for escaped sequences within string length - * calculations. This follows the logic in term_strlen() as we - * must calculate the width of produced strings. - * Assume that characters are always width of "1". This is - * hacky, but it gets the job done for approximation of widths. + * In ID attributes, only use ASCII characters that are + * permitted in URL-fragment strings according to the + * explicit list at: + * https://url.spec.whatwg.org/#url-fragment-string */ - sz = 0; - skip = 0; - while (1) { - rsz = strcspn(cp, "\\"); - if (rsz) { - cp += rsz; - if (skip) { - skip = 0; - rsz--; + for (cp = buf; *cp != '\0'; cp++) + if (isalnum((unsigned char)*cp) == 0 && + strchr("!$&'()*+,-./:;=?@_~", *cp) == NULL) + *cp = '_'; + + if (unique == 0) + return buf; + + /* Avoid duplicate HTML id= attributes. */ + + bufs = NULL; + suffix = 1; + slot = ohash_qlookup(&id_unique, buf); + cp = ohash_find(&id_unique, slot); + if (cp != NULL) { + while (cp != NULL) { + free(bufs); + if (++suffix > 127) { + free(buf); + return NULL; } - sz += rsz; - } - if ('\0' == *cp) - break; - cp++; - switch (mandoc_escape(&cp, NULL, NULL)) { - case ESCAPE_ERROR: - return sz; - case ESCAPE_UNICODE: - case ESCAPE_NUMBERED: - case ESCAPE_SPECIAL: - case ESCAPE_OVERSTRIKE: - if (skip) - skip = 0; - else - sz++; - break; - case ESCAPE_SKIPCHAR: - skip = 1; - break; - default: - break; + mandoc_asprintf(&bufs, "%s_%d", buf, suffix); + slot = ohash_qlookup(&id_unique, bufs); + cp = ohash_find(&id_unique, slot); } + free(buf); + buf = bufs; } - return sz; + ohash_insert(&id_unique, slot, buf); + return buf; } static int @@ -490,13 +489,10 @@ struct tag * print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) { va_list ap; - struct roffsu mysu, *su; - char numbuf[16]; struct tag *t; const char *attr; char *arg1, *arg2; - double v; - int i, have_style, tflags; + int tflags; tflags = htmltags[tag].flags; @@ -536,17 +532,12 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) va_start(ap, fmt); - have_style = 0; while (*fmt != '\0') { - if (*fmt == 's') { - have_style = 1; - fmt++; - break; - } - /* Parse a non-style attribute and its arguments. */ + /* Parse attributes and arguments. */ arg1 = va_arg(ap, char *); + arg2 = NULL; switch (*fmt++) { case 'c': attr = "class"; @@ -557,6 +548,10 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) case 'i': attr = "id"; break; + case 's': + attr = "style"; + arg2 = va_arg(ap, char *); + break; case '?': attr = arg1; arg1 = va_arg(ap, char *); @@ -564,13 +559,12 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) default: abort(); } - arg2 = NULL; if (*fmt == 'M') arg2 = va_arg(ap, char *); if (arg1 == NULL) continue; - /* Print the non-style attributes. */ + /* Print the attributes. */ print_byte(h, ' '); print_word(h, attr); @@ -597,114 +591,19 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) fmt++; break; default: - print_encode(h, arg1, NULL, 1); + if (arg2 == NULL) + print_encode(h, arg1, NULL, 1); + else { + print_word(h, arg1); + print_byte(h, ':'); + print_byte(h, ' '); + print_word(h, arg2); + print_byte(h, ';'); + } break; } print_byte(h, '"'); } - - /* Print out styles. */ - - while (*fmt != '\0') { - arg1 = NULL; - su = NULL; - - /* First letter: input argument type. */ - - switch (*fmt++) { - case 'h': - i = va_arg(ap, int); - su = &mysu; - SCALE_HS_INIT(su, i); - break; - case 's': - arg1 = va_arg(ap, char *); - break; - case 'u': - su = va_arg(ap, struct roffsu *); - break; - case 'w': - if ((arg2 = va_arg(ap, char *)) != NULL) { - su = &mysu; - a2width(arg2, su); - } - if (*fmt == '*') { - if (su != NULL && su->unit == SCALE_EN && - su->scale > 5.9 && su->scale < 6.1) - su = NULL; - fmt++; - } - if (*fmt == '+') { - if (su != NULL) { - /* Make even bold text fit. */ - su->scale *= 1.2; - /* Add padding. */ - su->scale += 3.0; - } - fmt++; - } - if (*fmt == '-') { - if (su != NULL) - su->scale *= -1.0; - fmt++; - } - break; - default: - abort(); - } - - /* Second letter: style name. */ - - switch (*fmt++) { - case 'h': - attr = "height"; - break; - case 'i': - attr = "text-indent"; - break; - case 'l': - attr = "margin-left"; - break; - case 'w': - attr = "width"; - break; - case 'W': - attr = "min-width"; - break; - case '?': - attr = arg1; - arg1 = va_arg(ap, char *); - break; - default: - abort(); - } - if (su == NULL && arg1 == NULL) - continue; - - if (have_style == 1) - print_word(h, " style=\""); - else - print_byte(h, ' '); - print_word(h, attr); - print_byte(h, ':'); - print_byte(h, ' '); - if (su != NULL) { - v = su->scale; - if (su->unit == SCALE_MM && (v /= 100.0) == 0.0) - v = 1.0; - else if (su->unit == SCALE_BU) - v /= 24.0; - (void)snprintf(numbuf, sizeof(numbuf), "%.2f", v); - print_word(h, numbuf); - print_word(h, roffscales[su->unit]); - } else - print_word(h, arg1); - print_byte(h, ';'); - have_style = 2; - } - if (have_style == 2) - print_byte(h, '"'); - va_end(ap); /* Accommodate for "well-formed" singleton escaping. */ @@ -768,6 +667,32 @@ print_gen_decls(struct html *h) print_endline(h); } +void +print_gen_comment(struct html *h, struct roff_node *n) +{ + int wantblank; + + print_word(h, "<!-- This is an automatically generated file." + " Do not edit."); + h->indent = 1; + wantblank = 0; + while (n != NULL && n->type == ROFFT_COMMENT) { + if (strstr(n->string, "-->") == NULL && + (wantblank || *n->string != '\0')) { + print_endline(h); + print_indent(h); + print_word(h, n->string); + wantblank = *n->string != '\0'; + } + n = n->next; + } + if (wantblank) + print_endline(h); + print_word(h, " -->"); + print_endline(h); + h->indent = 0; +} + void print_text(struct html *h, const char *word) { @@ -959,21 +884,3 @@ print_word(struct html *h, const char *cp) while (*cp != '\0') print_byte(h, *cp++); } - -/* - * Calculate the scaling unit passed in a `-width' argument. This uses - * either a native scaling unit (e.g., 1i, 2m) or the string length of - * the value. - */ -static void -a2width(const char *p, struct roffsu *su) -{ - const char *end; - - end = a2roffsu(p, su, SCALE_MAX); - if (end == NULL || *end != '\0') { - su->unit = SCALE_EN; - su->scale = html_strlen(p); - } else if (su->scale < 0.0) - su->scale = 0.0; -} diff --git a/contrib/mdocml/html.h b/contrib/mandoc/html.h similarity index 93% rename from contrib/mdocml/html.h rename to contrib/mandoc/html.h index c727eacf5d09..6d44a47383a7 100644 --- a/contrib/mdocml/html.h +++ b/contrib/mandoc/html.h @@ -1,7 +1,7 @@ -/* $Id: html.h,v 1.87 2017/07/08 14:51:04 schwarze Exp $ */ +/* $Id: html.h,v 1.92 2018/06/25 16:54:59 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +23,7 @@ enum htmltag { TAG_META, TAG_TITLE, TAG_DIV, + TAG_IDIV, TAG_H1, TAG_H2, TAG_SPAN, @@ -30,8 +31,6 @@ enum htmltag { TAG_BR, TAG_A, TAG_TABLE, - TAG_COLGROUP, - TAG_COL, TAG_TR, TAG_TD, TAG_LI, @@ -119,6 +118,7 @@ struct eqn_box; void roff_html_pre(struct html *, const struct roff_node *); +void print_gen_comment(struct html *, struct roff_node *); void print_gen_decls(struct html *); void print_gen_head(struct html *); struct tag *print_otag(struct html *, enum htmltag, const char *, ...); @@ -131,5 +131,4 @@ void print_eqn(struct html *, const struct eqn_box *); void print_paragraph(struct html *); void print_endline(struct html *); -char *html_make_id(const struct roff_node *); -int html_strlen(const char *); +char *html_make_id(const struct roff_node *, int); diff --git a/contrib/mdocml/lib.c b/contrib/mandoc/lib.c similarity index 100% rename from contrib/mdocml/lib.c rename to contrib/mandoc/lib.c diff --git a/contrib/mdocml/lib.in b/contrib/mandoc/lib.in similarity index 96% rename from contrib/mdocml/lib.in rename to contrib/mandoc/lib.in index 646c9a2407f4..95821fc551a2 100644 --- a/contrib/mdocml/lib.in +++ b/contrib/mandoc/lib.in @@ -1,4 +1,4 @@ -/* $Id: lib.in,v 1.19 2016/11/23 20:22:13 schwarze Exp $ */ +/* $Id: lib.in,v 1.20 2017/08/20 02:30:27 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.org> @@ -25,11 +25,13 @@ */ LINE("lib80211", "802.11 Wireless Network Management Library (lib80211, \\-l80211)") +LINE("libalias", "Packet Aliasing Library (libalias, \\-lalias)") LINE("libarchive", "Streaming Archive Library (libarchive, \\-larchive)") LINE("libarm", "ARM Architecture Library (libarm, \\-larm)") LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)") LINE("libbe", "Boot Environment Library (libbe, \\-lbe)") LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)") +LINE("libbsdxml", "eXpat XML parser library (libbsdxml, \\-lbsdxml)") LINE("libbsm", "Basic Security Module Library (libbsm, \\-lbsm)") LINE("libc", "Standard C\\~Library (libc, \\-lc)") LINE("libc_r", "Reentrant C\\~Library (libc_r, \\-lc_r)") @@ -115,6 +117,7 @@ LINE("libsbuf", "Safe String Composition Library (libsbuf, \\-lsbuf)") LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)") LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)") LINE("libstdthreads", "C11 Threads Library (libstdthreads, \\-lstdthreads)") +LINE("libstdthreads", "C11 Threads Library (libstdthreads, \\-lstdthreads)") LINE("libSystem", "System Library (libSystem, \\-lSystem)") LINE("libsysdecode", "System Argument Decoding Library (libsysdecode, \\-lsysdecode)") LINE("libtacplus", "TACACS+ Client Library (libtacplus, \\-ltacplus)") diff --git a/contrib/mdocml/libman.h b/contrib/mandoc/libman.h similarity index 100% rename from contrib/mdocml/libman.h rename to contrib/mandoc/libman.h diff --git a/contrib/mdocml/libmandoc.h b/contrib/mandoc/libmandoc.h similarity index 95% rename from contrib/mdocml/libmandoc.h rename to contrib/mandoc/libmandoc.h index 2cf076286177..9cc8cce4ecca 100644 --- a/contrib/mdocml/libmandoc.h +++ b/contrib/mandoc/libmandoc.h @@ -1,4 +1,4 @@ -/* $Id: libmandoc.h,v 1.70 2017/07/08 17:52:49 schwarze Exp $ */ +/* $Id: libmandoc.h,v 1.71 2018/04/09 22:27:04 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -66,7 +66,7 @@ void roff_man_reset(struct roff_man *); enum rofferr roff_parseln(struct roff *, int, struct buf *, int *); void roff_endparse(struct roff *); void roff_setreg(struct roff *, const char *, int, char sign); -int roff_getreg(const struct roff *, const char *); +int roff_getreg(struct roff *, const char *); char *roff_strdup(const struct roff *, const char *); int roff_getcontrol(const struct roff *, const char *, int *); diff --git a/contrib/mdocml/libmdoc.h b/contrib/mandoc/libmdoc.h similarity index 100% rename from contrib/mdocml/libmdoc.h rename to contrib/mandoc/libmdoc.h diff --git a/contrib/mdocml/libroff.h b/contrib/mandoc/libroff.h similarity index 100% rename from contrib/mdocml/libroff.h rename to contrib/mandoc/libroff.h diff --git a/contrib/mdocml/main.c b/contrib/mandoc/main.c similarity index 92% rename from contrib/mdocml/main.c rename to contrib/mandoc/main.c index 09f4813f47b1..302320bba56a 100644 --- a/contrib/mdocml/main.c +++ b/contrib/mandoc/main.c @@ -1,7 +1,7 @@ -/* $Id: main.c,v 1.301 2017/07/26 10:21:55 schwarze Exp $ */ +/* $Id: main.c,v 1.306 2018/05/14 14:10:23 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -19,6 +19,7 @@ #include "config.h" #include <sys/types.h> +#include <sys/ioctl.h> #include <sys/param.h> /* MACHINE */ #include <sys/wait.h> @@ -38,6 +39,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <termios.h> #include <time.h> #include <unistd.h> @@ -120,6 +122,7 @@ main(int argc, char *argv[]) struct manconf conf; struct mansearch search; struct curparse curp; + struct winsize ws; struct tag_files *tag_files; struct manpage *res, *resp; const char *progname, *sec, *thisarg; @@ -129,7 +132,7 @@ main(int argc, char *argv[]) size_t i, sz; int prio, best_prio; enum outmode outmode; - int fd; + int fd, startdir; int show_usage; int options; int use_pager; @@ -316,6 +319,16 @@ main(int argc, char *argv[]) !isatty(STDOUT_FILENO)) use_pager = 0; + if (use_pager && + (conf.output.width == 0 || conf.output.indent == 0) && + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && + ws.ws_col > 1) { + if (conf.output.width == 0 && ws.ws_col < 79) + conf.output.width = ws.ws_col - 1; + if (conf.output.indent == 0 && ws.ws_col < 66) + conf.output.indent = 3; + } + #if HAVE_PLEDGE if (!use_pager) if (pledge("stdio rpath", NULL) == -1) @@ -374,15 +387,34 @@ main(int argc, char *argv[]) argc, argv, &res, &sz)) usage(search.argmode); - if (sz == 0) { - if (search.argmode == ARG_NAME) - fs_search(&search, &conf.manpath, - argc, argv, &res, &sz); - else - warnx("nothing appropriate"); + if (sz == 0 && search.argmode == ARG_NAME) + fs_search(&search, &conf.manpath, + argc, argv, &res, &sz); + + if (search.argmode == ARG_NAME) { + for (c = 0; c < argc; c++) { + if (strchr(argv[c], '/') == NULL) + continue; + if (access(argv[c], R_OK) == -1) { + warn("%s", argv[c]); + continue; + } + res = mandoc_reallocarray(res, + sz + 1, sizeof(*res)); + res[sz].file = mandoc_strdup(argv[c]); + res[sz].names = NULL; + res[sz].output = NULL; + res[sz].ipath = SIZE_MAX; + res[sz].bits = 0; + res[sz].sec = 10; + res[sz].form = FORM_SRC; + sz++; + } } if (sz == 0) { + if (search.argmode != ARG_NAME) + warnx("nothing appropriate"); rc = MANDOCLEVEL_BADARG; goto out; } @@ -466,7 +498,29 @@ main(int argc, char *argv[]) parse(&curp, STDIN_FILENO, "<stdin>"); } + /* + * Remember the original working directory, if possible. + * This will be needed if some names on the command line + * are page names and some are relative file names. + * Do not error out if the current directory is not + * readable: Maybe it won't be needed after all. + */ + startdir = open(".", O_RDONLY | O_DIRECTORY); + while (argc > 0) { + + /* + * Changing directories is not needed in ARG_FILE mode. + * Do it on a best-effort basis. Even in case of + * failure, some functionality may still work. + */ + if (resp != NULL) { + if (resp->ipath != SIZE_MAX) + (void)chdir(conf.manpath.paths[resp->ipath]); + else if (startdir != -1) + (void)fchdir(startdir); + } + fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv); if (fd != -1) { if (use_pager) { @@ -476,14 +530,23 @@ main(int argc, char *argv[]) if (resp == NULL) parse(&curp, fd, *argv); - else if (resp->form == FORM_SRC) { - /* For .so only; ignore failure. */ - (void)chdir(conf.manpath.paths[resp->ipath]); + else if (resp->form == FORM_SRC) parse(&curp, fd, resp->file); - } else + else passthrough(resp->file, fd, conf.output.synopsisonly); + if (ferror(stdout)) { + if (tag_files != NULL) { + warn("%s", tag_files->ofn); + tag_unlink(); + tag_files = NULL; + } else + warn("stdout"); + rc = MANDOCLEVEL_SYSERR; + break; + } + if (argc > 1 && curp.outtype <= OUTT_UTF8) { if (curp.outdata == NULL) outdata_alloc(&curp); @@ -502,6 +565,10 @@ main(int argc, char *argv[]) if (--argc) mparse_reset(curp.mp); } + if (startdir != -1) { + (void)fchdir(startdir); + close(startdir); + } if (curp.outdata != NULL) { switch (curp.outtype) { @@ -722,7 +789,8 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths, cfg->firstmatch) return 1; } - if (res != NULL && *ressz == lastsz) + if (res != NULL && *ressz == lastsz && + strchr(*argv, '/') == NULL) warnx("No entry for %s in the manual.", *argv); lastsz = *ressz; argv++; @@ -1173,7 +1241,7 @@ spawn_pager(struct tag_files *tag_files) if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) err((int)MANDOCLEVEL_SYSERR, "pager stdout"); close(tag_files->ofd); - close(tag_files->tfd); + assert(tag_files->tfd == -1); /* Do not start the pager before controlling the terminal. */ diff --git a/contrib/mdocml/main.h b/contrib/mandoc/main.h similarity index 100% rename from contrib/mdocml/main.h rename to contrib/mandoc/main.h diff --git a/contrib/mdocml/makewhatis.8 b/contrib/mandoc/makewhatis.8 similarity index 100% rename from contrib/mdocml/makewhatis.8 rename to contrib/mandoc/makewhatis.8 diff --git a/contrib/mdocml/man-cgi.css b/contrib/mandoc/man-cgi.css similarity index 100% rename from contrib/mdocml/man-cgi.css rename to contrib/mandoc/man-cgi.css diff --git a/contrib/mdocml/man.1 b/contrib/mandoc/man.1 similarity index 91% rename from contrib/mdocml/man.1 rename to contrib/mandoc/man.1 index 1719ded92238..cf03693ee981 100644 --- a/contrib/mdocml/man.1 +++ b/contrib/mandoc/man.1 @@ -1,4 +1,4 @@ -.\" $Id: man.1,v 1.29 2017/05/17 23:23:00 schwarze Exp $ +.\" $Id: man.1,v 1.33 2018/04/19 23:41:16 schwarze Exp $ .\" .\" Copyright (c) 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,7 +31,7 @@ .\" .\" @(#)man.1 8.2 (Berkeley) 1/2/94 .\" -.Dd $Mdocdate: August 8 2018 $ +.Dd $Mdocdate: April 19 2018 $ .Dt MAN 1 .Os .Sh NAME @@ -75,9 +75,21 @@ See for a description of the contents of this file. .It Fl c Copy the manual page to the standard output instead of using -.Xr less 1 +.Xr more 1 to paginate it. This is done by default if the standard output is not a terminal device. +.Pp +When using +.Fl c , +most terminal devices are unable to show the markup. +To print the output of +.Nm +to the terminal with markup but without using a pager, pipe it to +.Xr ul 1 . +To remove the markup, pipe the output to +.Xr col 1 +.Fl b +instead. .It Fl f A synonym for .Xr whatis 1 . @@ -102,8 +114,7 @@ manual. By default, it displays the header lines of all matching pages. .It Fl l A synonym for -.Xr mandoc 1 -.Fl a . +.Xr mandoc 1 . The .Ar name arguments are interpreted as filenames. @@ -115,6 +126,8 @@ No search is done and and .Fl w are ignored. +This option implies +.Fl a . .It Fl M Ar path Override the list of standard directories which .Nm @@ -233,7 +246,7 @@ is case insensitive. Any non-empty value of the environment variable .Ev MANPAGER is used instead of the standard pagination program, -.Xr less 1 . +.Xr more 1 . If .Xr less 1 is used, the interactive @@ -282,14 +295,9 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Xr less 1 +.Xr more 1 .Fl s is used. -Only used if -.Fl a -or -.Fl l -is specified. .El .Sh FILES .Bl -tag -width /etc/man.conf -compact @@ -301,20 +309,24 @@ default man configuration file See .Xr mandoc 1 for details. +.Sh EXAMPLES +Format a page for pasting extracts into an email message \(em +avoid printing any UTF-8 characters, reduce the width to ease +quoting in replies, and remove markup: +.Pp +.Dl $ man -T ascii -O width=65 pledge | col -b +.Pp +Read a typeset page in a PDF viewer: +.Pp +.Dl $ MANPAGER=mupdf man -T pdf lpd .Sh SEE ALSO .Xr apropos 1 , -.Xr intro 1 , +.Xr col 1 , +.Xr mandoc 1 , +.Xr ul 1 , .Xr whereis 1 , -.Xr intro 2 , -.Xr intro 3 , -.Xr intro 4 , -.Xr intro 5 , .Xr man.conf 5 , -.Xr intro 6 , -.Xr intro 7 , -.Xr mdoc 7 , -.Xr intro 8 , -.Xr intro 9 +.Xr mdoc 7 .Sh STANDARDS The .Nm diff --git a/contrib/mdocml/man.7 b/contrib/mandoc/man.7 similarity index 98% rename from contrib/mdocml/man.7 rename to contrib/mandoc/man.7 index 570e7ac3bdcd..d418b9ee76ca 100644 --- a/contrib/mdocml/man.7 +++ b/contrib/mandoc/man.7 @@ -1,4 +1,4 @@ -.\" $Id: man.7,v 1.136 2017/06/25 11:42:02 schwarze Exp $ +.\" $Id: man.7,v 1.137 2018/04/05 22:12:33 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 25 2017 $ +.Dd $Mdocdate: April 5 2018 $ .Dt MAN 7 .Os .Sh NAME @@ -273,7 +273,6 @@ in the alphabetical reference below. .Bl -column "PP, LP, P" description .It Sx B Ta boldface font .It Sx I Ta italic font -.It Sx R Ta roman (default) font .It Sx SB Ta small boldface font .It Sx SM Ta small roman font .It Sx BI Ta alternate between boldface and italic fonts @@ -297,9 +296,7 @@ The optional arguments specify which release it is from. Text is rendered in bold face. .Pp See also -.Sx \&I -and -.Sx \&R . +.Sx \&I . .Ss \&BI Text is rendered alternately in bold face and italic. Thus, @@ -393,9 +390,7 @@ and Text is rendered in italics. .Pp See also -.Sx \&B -and -.Sx \&R . +.Sx \&B . .Ss \&IB Text is rendered alternately in italics and bold face. Whitespace between arguments is omitted in output. @@ -546,13 +541,6 @@ See also .Sx \&P , and .Sx \&TP . -.Ss \&R -Text is rendered in roman (the default font). -.Pp -See also -.Sx \&I -and -.Sx \&B . .Ss \&RB Text is rendered alternately in roman (the default font) and bold face. Whitespace between arguments is omitted in output. @@ -790,7 +778,6 @@ The syntax is as follows: .It Sx \&IR Ta n Ta current Ta \& .It Sx \&OP Ta 0, 1 Ta current Ta compat .It Sx \&PD Ta 1 Ta current Ta \& -.It Sx \&R Ta n Ta next-line Ta \& .It Sx \&RB Ta n Ta current Ta \& .It Sx \&RI Ta n Ta current Ta \& .It Sx \&SB Ta n Ta next-line Ta \& diff --git a/contrib/mdocml/man.c b/contrib/mandoc/man.c similarity index 100% rename from contrib/mdocml/man.c rename to contrib/mandoc/man.c diff --git a/contrib/mdocml/man.cgi.3 b/contrib/mandoc/man.cgi.3 similarity index 100% rename from contrib/mdocml/man.cgi.3 rename to contrib/mandoc/man.cgi.3 diff --git a/contrib/mdocml/man.cgi.8 b/contrib/mandoc/man.cgi.8 similarity index 97% rename from contrib/mdocml/man.cgi.8 rename to contrib/mandoc/man.cgi.8 index eba3cec45a8a..b8cd623c598d 100644 --- a/contrib/mdocml/man.cgi.8 +++ b/contrib/mandoc/man.cgi.8 @@ -1,4 +1,4 @@ -.\" $Id: man.cgi.8,v 1.22 2017/03/18 16:48:24 schwarze Exp $ +.\" $Id: man.cgi.8,v 1.23 2018/05/20 21:48:44 schwarze Exp $ .\" .\" Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 18 2017 $ +.Dd $Mdocdate: May 20 2018 $ .Dt MAN.CGI 8 .Os .Sh NAME @@ -104,6 +104,9 @@ Lists are returned when searches match more than one manual page. The first column shows the names and section numbers of manuals as clickable links. The second column shows the one-line descriptions of the manuals. +For +.Xr man 1 +style searches, the content of the first manual page follows the list. .It A manual page. This output format is used when a search matches exactly one manual page, or when a link on a list page or an @@ -111,7 +114,7 @@ manual page, or when a link on a list page or an link on another manual page is followed. .It A no-result page. This is shown when a search request returns no results - -eiher because it violates the query syntax, or because +either because it violates the query syntax, or because the search does not match any manual pages. .It \&An error page. This cannot happen by merely clicking the @@ -234,6 +237,8 @@ They consist of: .It The .Cm http:// +or +.Cm https:// protocol specifier. .It The host name. @@ -394,7 +399,7 @@ The CGI program is call-compatible with queries from the traditional .Pa man.cgi script by Wolfram Schneider. -However, the output may not be quite the same. +However, the output looks quite different. .Sh SEE ALSO .Xr apropos 1 , .Xr mandoc.db 5 , diff --git a/contrib/mdocml/man.conf.5 b/contrib/mandoc/man.conf.5 similarity index 92% rename from contrib/mdocml/man.conf.5 rename to contrib/mandoc/man.conf.5 index 425895c1dc8a..be0998087d17 100644 --- a/contrib/mdocml/man.conf.5 +++ b/contrib/mandoc/man.conf.5 @@ -1,4 +1,4 @@ -.\" $Id: man.conf.5,v 1.4 2016/12/28 22:52:17 schwarze Exp $ +.\" $Id: man.conf.5,v 1.5 2017/08/22 18:17:52 schwarze Exp $ .\" .\" Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 28 2016 $ +.Dd $Mdocdate: August 22 2017 $ .Dt MAN.CONF 5 .Os .Sh NAME @@ -74,8 +74,12 @@ in each directory configured with .Ic manpath is recommended and necessary for .Xr apropos 1 -to work, but not strictly required for -.Xr man 1 . +to work, and also for +.Xr man 1 +on operating systems like +.Ox +that install each manual page with only one file name in the file system, +even if it documents multiple utilities or functions. .It Ic output Ar option Op Ar value Configure the default value of an output option. These directives are overridden by the diff --git a/contrib/mdocml/man.h b/contrib/mandoc/man.h similarity index 100% rename from contrib/mdocml/man.h rename to contrib/mandoc/man.h diff --git a/contrib/mdocml/man.options.1 b/contrib/mandoc/man.options.1 similarity index 100% rename from contrib/mdocml/man.options.1 rename to contrib/mandoc/man.options.1 diff --git a/contrib/mdocml/man_html.c b/contrib/mandoc/man_html.c similarity index 88% rename from contrib/mdocml/man_html.c rename to contrib/mandoc/man_html.c index a304b3e4d240..ae5dac1ad938 100644 --- a/contrib/mdocml/man_html.c +++ b/contrib/mandoc/man_html.c @@ -1,7 +1,7 @@ -/* $Id: man_html.c,v 1.145 2017/06/25 11:42:02 schwarze Exp $ */ +/* $Id: man_html.c,v 1.153 2018/07/27 17:49:31 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,8 +35,6 @@ /* FIXME: have PD set the default vspace width. */ -#define INDENT 5 - #define MAN_ARGS const struct roff_meta *man, \ const struct roff_node *n, \ struct html *h @@ -48,12 +46,11 @@ struct htmlman { static void print_bvspace(struct html *, const struct roff_node *); -static void print_man_head(MAN_ARGS); +static void print_man_head(const struct roff_meta *, + struct html *); static void print_man_nodelist(MAN_ARGS); static void print_man_node(MAN_ARGS); static int fillmode(struct html *, int); -static int a2width(const struct roff_node *, - struct roffsu *); static int man_B_pre(MAN_ARGS); static int man_HP_pre(MAN_ARGS); static int man_IP_pre(MAN_ARGS); @@ -68,8 +65,10 @@ static int man_UR_pre(MAN_ARGS); static int man_alt_pre(MAN_ARGS); static int man_ign_pre(MAN_ARGS); static int man_in_pre(MAN_ARGS); -static void man_root_post(MAN_ARGS); -static void man_root_pre(MAN_ARGS); +static void man_root_post(const struct roff_meta *, + struct html *); +static void man_root_pre(const struct roff_meta *, + struct html *); static const struct htmlman __mans[MAN_MAX - MAN_TH] = { { NULL, NULL }, /* TH */ @@ -138,30 +137,34 @@ print_bvspace(struct html *h, const struct roff_node *n) void html_man(void *arg, const struct roff_man *man) { - struct html *h; - struct tag *t; + struct html *h; + struct roff_node *n; + struct tag *t; h = (struct html *)arg; + n = man->first->child; if ((h->oflags & HTML_FRAGMENT) == 0) { print_gen_decls(h); print_otag(h, TAG_HTML, ""); + if (n->type == ROFFT_COMMENT) + print_gen_comment(h, n); t = print_otag(h, TAG_HEAD, ""); - print_man_head(&man->meta, man->first, h); + print_man_head(&man->meta, h); print_tagq(h, t); print_otag(h, TAG_BODY, ""); } - man_root_pre(&man->meta, man->first, h); + man_root_pre(&man->meta, h); t = print_otag(h, TAG_DIV, "c", "manual-text"); - print_man_nodelist(&man->meta, man->first->child, h); + print_man_nodelist(&man->meta, n, h); print_tagq(h, t); - man_root_post(&man->meta, man->first, h); + man_root_post(&man->meta, h); print_tagq(h, NULL); } static void -print_man_head(MAN_ARGS) +print_man_head(const struct roff_meta *man, struct html *h) { char *cp; @@ -262,6 +265,8 @@ print_man_node(MAN_ARGS) break; print_paragraph(h); return; + case ROFFT_COMMENT: + return; default: break; } @@ -359,16 +364,8 @@ fillmode(struct html *h, int want) return had; } -static int -a2width(const struct roff_node *n, struct roffsu *su) -{ - if (n->type != ROFFT_TEXT) - return 0; - return a2roffsu(n->string, su, SCALE_EN) != NULL; -} - static void -man_root_pre(MAN_ARGS) +man_root_pre(const struct roff_meta *man, struct html *h) { struct tag *t, *tt; char *title; @@ -396,7 +393,7 @@ man_root_pre(MAN_ARGS) } static void -man_root_post(MAN_ARGS) +man_root_post(const struct roff_meta *man, struct html *h) { struct tag *t, *tt; @@ -419,11 +416,10 @@ man_SH_pre(MAN_ARGS) char *id; if (n->type == ROFFT_HEAD) { - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H1, "cTi", "Sh", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); } return 1; } @@ -489,11 +485,10 @@ man_SS_pre(MAN_ARGS) char *id; if (n->type == ROFFT_HEAD) { - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H2, "cTi", "Ss", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); } return 1; } @@ -516,7 +511,7 @@ man_IP_pre(MAN_ARGS) const struct roff_node *nn; if (n->type == ROFFT_BODY) { - print_otag(h, TAG_DD, "c", "It-tag"); + print_otag(h, TAG_DD, ""); return 1; } else if (n->type != ROFFT_HEAD) { print_otag(h, TAG_DL, "c", "Bl-tag"); @@ -525,7 +520,7 @@ man_IP_pre(MAN_ARGS) /* FIXME: width specification. */ - print_otag(h, TAG_DT, "c", "It-tag"); + print_otag(h, TAG_DT, ""); /* For IP, only print the first header element. */ @@ -550,24 +545,13 @@ man_IP_pre(MAN_ARGS) static int man_HP_pre(MAN_ARGS) { - struct roffsu sum, sui; - const struct roff_node *np; - if (n->type == ROFFT_HEAD) return 0; - else if (n->type != ROFFT_BLOCK) - return 1; - np = n->head->child; - - if (np == NULL || !a2width(np, &sum)) - SCALE_HS_INIT(&sum, INDENT); - - sui.unit = sum.unit; - sui.scale = -sum.scale; - - print_bvspace(h, n); - print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui); + if (n->type == ROFFT_BLOCK) { + print_bvspace(h, n); + print_otag(h, TAG_DIV, "c", "HP"); + } return 1; } @@ -629,18 +613,10 @@ man_ign_pre(MAN_ARGS) static int man_RS_pre(MAN_ARGS) { - struct roffsu su; - if (n->type == ROFFT_HEAD) return 0; - else if (n->type == ROFFT_BODY) - return 1; - - SCALE_HS_INIT(&su, INDENT); - if (n->head->child) - a2width(n->head->child, &su); - - print_otag(h, TAG_DIV, "sul", &su); + if (n->type == ROFFT_BLOCK) + print_otag(h, TAG_DIV, "c", "Bd-indent"); return 1; } diff --git a/contrib/mdocml/man_macro.c b/contrib/mandoc/man_macro.c similarity index 100% rename from contrib/mdocml/man_macro.c rename to contrib/mandoc/man_macro.c diff --git a/contrib/mdocml/man_term.c b/contrib/mandoc/man_term.c similarity index 97% rename from contrib/mdocml/man_term.c rename to contrib/mandoc/man_term.c index 8946a05067a7..b5723ccf8383 100644 --- a/contrib/mdocml/man_term.c +++ b/contrib/mandoc/man_term.c @@ -1,7 +1,7 @@ -/* $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */ +/* $Id: man_term.c,v 1.211 2018/06/10 15:12:35 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -675,7 +675,8 @@ pre_SS(DECL_ARGS) n = n->prev; } while (n != NULL && n->tok >= MAN_TH && termacts[n->tok].flags & MAN_NOTEXT); - if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL)) + if (n == NULL || n->type == ROFFT_COMMENT || + (n->tok == MAN_SS && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) @@ -737,7 +738,8 @@ pre_SH(DECL_ARGS) n = n->prev; } while (n != NULL && n->tok >= MAN_TH && termacts[n->tok].flags & MAN_NOTEXT); - if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL)) + if (n == NULL || n->type == ROFFT_COMMENT || + (n->tok == MAN_SH && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) @@ -885,7 +887,8 @@ print_man_node(DECL_ARGS) term_word(p, n->string); goto out; - + case ROFFT_COMMENT: + return; case ROFFT_EQN: if ( ! (n->flags & NODE_LINE)) p->flags |= TERMP_NOSPACE; @@ -1029,6 +1032,18 @@ print_man_foot(struct termp *p, const struct roff_meta *meta) term_word(p, title); term_flushln(p); + + /* + * Reset the terminal state for more output after the footer: + * Some output modes, in particular PostScript and PDF, print + * the header and the footer into a buffer such that it can be + * reused for multiple output pages, then go on to format the + * main text. + */ + + p->tcol->offset = 0; + p->flags = 0; + free(title); } diff --git a/contrib/mdocml/man_validate.c b/contrib/mandoc/man_validate.c similarity index 98% rename from contrib/mdocml/man_validate.c rename to contrib/mandoc/man_validate.c index b3356ccb3d3f..d6c51af5255c 100644 --- a/contrib/mdocml/man_validate.c +++ b/contrib/mandoc/man_validate.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -120,6 +120,7 @@ man_node_validate(struct roff_man *man) case ROFFT_ROOT: check_root(man, n); break; + case ROFFT_COMMENT: case ROFFT_EQN: case ROFFT_TBL: break; @@ -149,10 +150,9 @@ man_node_validate(struct roff_man *man) static void check_root(CHKARGS) { - assert((man->flags & (MAN_BLINE | MAN_ELINE)) == 0); - if (NULL == man->first->child) + if (n->last == NULL || n->last->type == ROFFT_COMMENT) mandoc_msg(MANDOCERR_DOC_EMPTY, man->parse, n->line, n->pos, NULL); else diff --git a/contrib/mdocml/manconf.h b/contrib/mandoc/manconf.h similarity index 100% rename from contrib/mdocml/manconf.h rename to contrib/mandoc/manconf.h diff --git a/contrib/mdocml/mandoc.1 b/contrib/mandoc/mandoc.1 similarity index 93% rename from contrib/mdocml/mandoc.1 rename to contrib/mandoc/mandoc.1 index b9a44b2743e4..76b3cda5a704 100644 --- a/contrib/mdocml/mandoc.1 +++ b/contrib/mandoc/mandoc.1 @@ -1,7 +1,7 @@ -.\" $Id: mandoc.1,v 1.217 2017/07/20 15:26:41 schwarze Exp $ +.\" $Id: mandoc.1,v 1.226 2018/07/28 18:34:15 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 8 2018 $ +.Dd $Mdocdate: July 28 2018 $ .Dt MANDOC 1 .Os .Sh NAME @@ -34,9 +34,7 @@ .Sh DESCRIPTION The .Nm -utility formats -.Ux -manual pages for display. +utility formats manual pages for display. .Pp By default, .Nm @@ -54,13 +52,13 @@ The options are as follows: If the standard output is a terminal device and .Fl c is not specified, use -.Xr less 1 +.Xr more 1 to paginate the output, just like .Xr man 1 would. .It Fl c Copy the formatted manual pages to the standard output without using -.Xr less 1 +.Xr more 1 to paginate them. This is the default. It can be specified to override @@ -118,7 +116,7 @@ With all input files are interpreted as .Xr man 7 . By default, the input language is automatically detected for each file: -if the the first macro is +if the first macro is .Ic \&Dd or .Ic \&Dt , @@ -132,13 +130,32 @@ With other arguments, is silently ignored. .It Fl O Ar options Comma-separated output options. +See the descriptions of the individual output formats for supported +.Ar options . .It Fl T Ar output -Output format. -See -.Sx Output Formats -for available formats. -Defaults to -.Fl T Cm locale . +Select the output format. +Supported values for the +.Ar output +argument are +.Cm ascii , +.Cm html , +the default of +.Cm locale , +.Cm man , +.Cm markdown , +.Cm pdf , +.Cm ps , +.Cm tree , +and +.Cm utf8 . +.Pp +The special +.Fl T Cm lint +mode only parses the input and produces no output. +It implies +.Fl W Cm all +and redirects parser messages, which usually appear on standard +error output, to standard output. .It Fl W Ar level Specify the minimum message .Ar level @@ -196,11 +213,11 @@ and are requested, they can be joined with a comma, for example .Fl W Cm error , Ns Cm stop . .It Ar file -Read input from zero or more files. -If unspecified, reads from stdin. -If multiple files are specified, +Read from the given input file. +If multiple files are specified, they are processed in the given order. +If unspecified, .Nm -will halt with the first failed parse. +reads from standard input. .El .Pp The options @@ -220,69 +237,14 @@ manual. The options .Fl fkl are mutually exclusive and override each other. -.Ss Output Formats -The -.Nm -utility accepts the following -.Fl T -arguments, which correspond to output modes: -.Bl -tag -width "-T markdown" -.It Fl T Cm ascii -Produce 7-bit ASCII output. -See -.Sx ASCII Output . -.It Fl T Cm html -Produce HTML5, CSS1, and MathML output. -See -.Sx HTML Output . -.It Fl T Cm lint -Parse only: produce no output. -Implies -.Fl W Cm all -and redirects parser messages, which usually appear -on standard error output, to standard output. -.It Fl T Cm locale -Encode output using the current locale. -This is the default. -See -.Sx Locale Output . -.It Fl T Cm man -Produce -.Xr man 7 -format output. -See -.Sx Man Output . -.It Fl T Cm markdown -Produce output in -.Sy markdown -format. -See -.Sx Markdown Output . -.It Fl T Cm pdf -Produce PDF output. -See -.Sx PDF Output . -.It Fl T Cm ps -Produce PostScript output. -See -.Sx PostScript Output . -.It Fl T Cm tree -Produce an indented parse tree. -See -.Sx Syntax tree output . -.It Fl T Cm utf8 -Encode output in the UTF\-8 multi-byte format. -See -.Sx UTF\-8 Output . -.El -.Pp -If multiple input files are specified, these will be processed by the -corresponding filter in-order. .Ss ASCII Output -Output produced by +Use .Fl T Cm ascii -is rendered in standard 7-bit ASCII documented in -.Xr ascii 7 . +to force text output in 7-bit ASCII character encoding documented in the +.Xr ascii 7 +manual page, ignoring the +.Xr locale 1 +set in the environment. .Pp Font styles are applied by using back-spaced encoding such that an underlined character @@ -299,9 +261,6 @@ The special characters documented in .Xr mandoc_char 7 are rendered best-effort in an ASCII equivalent. .Pp -Output width is limited to 78 visible columns unless literal input lines -exceed this limit. -.Pp The following .Fl O arguments are accepted: @@ -315,9 +274,30 @@ and seven for .Xr man 7 . Increasing this is not recommended; it may result in degraded formatting, for example overfull lines or ugly line breaks. +When output is to a pager on a terminal that is less than 66 columns +wide, the default is reduced to three columns. +.It Cm mdoc +Format +.Xr man 7 +input files in +.Xr mdoc 7 +output style. +Specifically, this suppresses the two additional blank lines near the +top and the bottom of each page, and it implies +.Fl O Cm indent Ns =5 . +One useful application is for checking that +.Fl T Cm man +output formats in the same way as the +.Xr mdoc 7 +source it was generated from. .It Cm width Ns = Ns Ar width The output width is set to -.Ar width . +.Ar width +instead of the default of 78. +When output is to a pager on a terminal that is less than 79 columns +wide, the default is reduced to one less than the terminal width. +In any case, lines that are output in literal mode are never wrapped +and may exceed the output width. .El .Ss HTML Output Output produced by @@ -338,7 +318,8 @@ defaults to simple output (via an embedded style-sheet) readable in any graphical or text-based web browser. .Pp -Special characters are rendered in decimal-encoded UTF\-8. +Non-ASCII characters are rendered +as hexadecimal Unicode character references. .Pp The following .Fl O @@ -388,19 +369,28 @@ This must be a valid absolute or relative URI. .El .Ss Locale Output -Locale-depending output encoding is triggered with +By default, +.Nm +automatically selects UTF-8 or ASCII output according to the current +.Xr locale 1 . +If any of the environment variables +.Ev LC_ALL , +.Ev LC_CTYPE , +or +.Ev LANG +are set and the first one that is set +selects the UTF-8 character encoding, it produces +.Sx UTF-8 Output ; +otherwise, it falls back to +.Sx ASCII Output . +This output mode can also be selected explicitly with .Fl T Cm locale . -This is the default. -.Pp -This option is not available on all systems: systems without locale -support, or those whose internal representation is not natively UCS-4, -will fall back to -.Fl T Cm ascii . -See -.Sx ASCII Output -for font style specification and available command-line arguments. .Ss Man Output -Translate input format into +Use +.Fl T Cm man +to translate +.Xr mdoc 7 +input into .Xr man 7 output format. This is useful for distributing manual sources to legacy systems @@ -408,11 +398,7 @@ lacking .Xr mdoc 7 formatters. .Pp -If -.Xr mdoc 7 -is passed as input, it is translated into -.Xr man 7 . -If the input format is +If the input format of a file is .Xr man 7 , the input is copied to the output, expanding any .Xr roff 7 @@ -424,11 +410,11 @@ level controls which .Sx DIAGNOSTICS are displayed before copying the input to the output. .Ss Markdown Output -Translate +Use +.Fl T Cm markdown +to translate .Xr mdoc 7 -input to the -.Sy markdown -format conforming to +input to the markdown format conforming to .Lk http://daringfireball.net/projects/markdown/syntax.text\ "John Gruber's 2004 specification" . The output also almost conforms to the @@ -499,13 +485,24 @@ If an unknown value is encountered, .Ar letter is used. .El -.Ss UTF\-8 Output +.Ss UTF-8 Output Use .Fl T Cm utf8 -to force a UTF\-8 locale. +to force text output in UTF-8 multi-byte character encoding, +ignoring the +.Xr locale 1 +settings in the environment. See -.Sx Locale Output -for details and options. +.Sx ASCII Output +regarding font styles and +.Fl O +arguments. +.Pp +On operating systems lacking locale or wide character support, and +on those where the internal character representation is not UCS-4, +.Nm +always falls back to +.Sx ASCII Output . .Ss Syntax tree output Use .Fl T Cm tree @@ -574,11 +571,18 @@ Meta data is not available in this case. .El .Sh ENVIRONMENT .Bl -tag -width MANPAGER +.It Ev LC_CTYPE +The character encoding +.Xr locale 1 . +When +.Sx Locale Output +is selected, it decides whether to use ASCII or UTF-8 output format. +It never affects the interpretation of input files. .It Ev MANPAGER Any non-empty value of the environment variable .Ev MANPAGER is used instead of the standard pagination program, -.Xr less 1 ; +.Xr more 1 ; see .Xr man 1 for details. @@ -592,7 +596,7 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Xr less 1 +.Xr more 1 .Fl s is used. Only used if @@ -741,7 +745,7 @@ Please use your good judgement to decide whether any particular .Cm style suggestion really justifies a change to the input file. .It Cm base -A convertion used in the base system of a specific operating system +A convention used in the base system of a specific operating system is not adhered to. These are not markup mistakes, and neither the quality of formatting nor portability are in danger. @@ -849,6 +853,16 @@ Consider using the conventional date format .Dq "Month dd, yyyy" instead. +.It Sy "normalizing date format to" : No ... +.Pq mdoc , man +The +.Ic \&Dd +or +.Ic \&TH +macro provides an abbreviated month name or a day number with a +leading zero. +In the formatted output, the month name is written out in full +and the leading zero is omitted. .It Sy "lower case character in document title" .Pq mdoc , man The title is still used as given in the @@ -861,7 +875,7 @@ A single manual page contains two copies of the RCS identifier for the same operating system. Consider deleting the later instance and moving the first one up to the top of the page. -.It Sy "typo in section name" +.It Sy "possible typo in section name" .Pq mdoc Fuzzy string matching revealed that the argument of an .Ic \&Sh @@ -938,6 +952,12 @@ An request occurs even though the document already switched to no-fill mode and did not switch back to fill mode yet. It has no effect. +.It Sy "verbatim \(dq--\(dq, maybe consider using \e(em" +.Pq mdoc +Even though the ASCII output device renders an em-dash as +.Qq \-\- , +that is not a good way to write it in an input file +because it renders poorly on all other output devices. .It Sy "function name without markup" .Pq mdoc A word followed by an empty pair of parentheses occurs on a text line. diff --git a/contrib/mdocml/mandoc.3 b/contrib/mandoc/mandoc.3 similarity index 100% rename from contrib/mdocml/mandoc.3 rename to contrib/mandoc/mandoc.3 diff --git a/contrib/mdocml/mandoc.c b/contrib/mandoc/mandoc.c similarity index 98% rename from contrib/mdocml/mandoc.c rename to contrib/mandoc/mandoc.c index 3e16d2c64fbc..1279b52ed50f 100644 --- a/contrib/mdocml/mandoc.c +++ b/contrib/mandoc/mandoc.c @@ -1,7 +1,7 @@ -/* $Id: mandoc.c,v 1.103 2017/07/03 13:40:19 schwarze Exp $ */ +/* $Id: mandoc.c,v 1.104 2018/07/28 18:34:15 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -541,6 +541,9 @@ mandoc_normdate(struct roff_man *man, char *in, int ln, int pos) if (t > time(NULL) + 86400) mandoc_msg(MANDOCERR_DATE_FUTURE, man->parse, ln, pos, cp); + else if (*in != '$' && strcmp(in, cp) != 0) + mandoc_msg(MANDOCERR_DATE_NORM, man->parse, + ln, pos, cp); return cp; } diff --git a/contrib/mandoc/mandoc.css b/contrib/mandoc/mandoc.css new file mode 100644 index 000000000000..c93bc22a2d14 --- /dev/null +++ b/contrib/mandoc/mandoc.css @@ -0,0 +1,253 @@ +/* $Id: mandoc.css,v 1.36 2018/07/23 22:51:26 schwarze Exp $ */ +/* + * Standard style sheet for mandoc(1) -Thtml and man.cgi(8). + */ + +/* Global defaults. */ + +html { max-width: 65em; } +body { font-family: Helvetica,Arial,sans-serif; } +table { margin-top: 0em; + margin-bottom: 0em; } +td { vertical-align: top; } +ul, ol, dl { margin-top: 0em; + margin-bottom: 0em; } +li, dt { margin-top: 1em; } + +.permalink { border-bottom: thin dotted; + color: inherit; + font: inherit; + text-decoration: inherit; } +* { clear: both } + +/* Search form and search results. */ + +fieldset { border: thin solid silver; + border-radius: 1em; + text-align: center; } +input[name=expr] { + width: 25%; } + +table.results { margin-top: 1em; + margin-left: 2em; + font-size: smaller; } + +/* Header and footer lines. */ + +table.head { width: 100%; + border-bottom: 1px dotted #808080; + margin-bottom: 1em; + font-size: smaller; } +td.head-vol { text-align: center; } +td.head-rtitle { + text-align: right; } + +table.foot { width: 100%; + border-top: 1px dotted #808080; + margin-top: 1em; + font-size: smaller; } +td.foot-os { text-align: right; } + +/* Sections and paragraphs. */ + +.manual-text { + margin-left: 3.8em; } +.Nd { display: inline; } +.Sh { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -3.2em; + font-size: 110%; } +.Ss { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -1.2em; + font-size: 105%; } +.Pp { margin: 0.6em 0em; } +.Sx { } +.Xr { } + +/* Displays and lists. */ + +.Bd { } +.Bd-indent { margin-left: 3.8em; } + +.Bl-bullet { list-style-type: disc; + padding-left: 1em; } +.Bl-bullet > li { } +.Bl-dash { list-style-type: none; + padding-left: 0em; } +.Bl-dash > li:before { + content: "\2014 "; } +.Bl-item { list-style-type: none; + padding-left: 0em; } +.Bl-item > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-enum { padding-left: 2em; } +.Bl-enum > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-diag { } +.Bl-diag > dt { + font-style: normal; + font-weight: bold; } +.Bl-diag > dd { + margin-left: 0em; } +.Bl-hang { } +.Bl-hang > dt { } +.Bl-hang > dd { + margin-left: 5.5em; } +.Bl-inset { } +.Bl-inset > dt { } +.Bl-inset > dd { + margin-left: 0em; } +.Bl-ohang { } +.Bl-ohang > dt { } +.Bl-ohang > dd { + margin-left: 0em; } +.Bl-tag { margin-left: 5.5em; } +.Bl-tag > dt { + float: left; + margin-top: 0em; + margin-left: -5.5em; + padding-right: 1.2em; + vertical-align: top; } +.Bl-tag > dd { + clear: right; + width: 100%; + margin-top: 0em; + margin-left: 0em; + vertical-align: top; + overflow: auto; } +.Bl-compact > dt { + margin-top: 0em; } + +.Bl-column { } +.Bl-column > tbody > tr { } +.Bl-column > tbody > tr > td { + margin-top: 1em; } +.Bl-compact > tbody > tr > td { + margin-top: 0em; } + +.Rs { font-style: normal; + font-weight: normal; } +.RsA { } +.RsB { font-style: italic; + font-weight: normal; } +.RsC { } +.RsD { } +.RsI { font-style: italic; + font-weight: normal; } +.RsJ { font-style: italic; + font-weight: normal; } +.RsN { } +.RsO { } +.RsP { } +.RsQ { } +.RsR { } +.RsT { text-decoration: underline; } +.RsU { } +.RsV { } + +.eqn { } +.tbl { } + +.HP { margin-left: 3.8em; + text-indent: -3.8em; } + +/* Semantic markup for command line utilities. */ + +table.Nm { } +code.Nm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fl { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Cm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ar { font-style: italic; + font-weight: normal; } +.Op { display: inline; } +.Ic { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ev { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Pa { font-style: italic; + font-weight: normal; } + +/* Semantic markup for function libraries. */ + +.Lb { } +code.In { font-style: normal; + font-weight: bold; + font-family: inherit; } +a.In { } +.Fd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ft { font-style: italic; + font-weight: normal; } +.Fn { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fa { font-style: italic; + font-weight: normal; } +.Vt { font-style: italic; + font-weight: normal; } +.Va { font-style: italic; + font-weight: normal; } +.Dv { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Er { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Various semantic markup. */ + +.An { } +.Lk { } +.Mt { } +.Cd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ad { font-style: italic; + font-weight: normal; } +.Ms { font-style: normal; + font-weight: bold; } +.St { } +.Ux { } + +/* Physical markup. */ + +.Bf { display: inline; } +.No { font-style: normal; + font-weight: normal; } +.Em { font-style: italic; + font-weight: normal; } +.Sy { font-style: normal; + font-weight: bold; } +.Li { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Overrides to avoid excessive margins on small devices. */ + +@media (max-width: 37.5em) { +.manual-text { + margin-left: 0.5em; } +.Sh, .Ss { margin-left: 0em; } +.Bd-indent { margin-left: 2em; } +.Bl-hang > dd { + margin-left: 2em; } +.Bl-tag { margin-left: 2em; } +.Bl-tag > dt { + margin-left: -2em; } +.HP { margin-left: 2em; + text-indent: -2em; } +} diff --git a/contrib/mdocml/mandoc.db.5 b/contrib/mandoc/mandoc.db.5 similarity index 100% rename from contrib/mdocml/mandoc.db.5 rename to contrib/mandoc/mandoc.db.5 diff --git a/contrib/mdocml/mandoc.h b/contrib/mandoc/mandoc.h similarity index 98% rename from contrib/mdocml/mandoc.h rename to contrib/mandoc/mandoc.h index b234cb5ee136..dbc266cc3b06 100644 --- a/contrib/mdocml/mandoc.h +++ b/contrib/mandoc/mandoc.h @@ -1,7 +1,7 @@ -/* $Id: mandoc.h,v 1.245 2017/07/08 14:51:04 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.248 2018/07/28 18:34:15 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -56,9 +56,10 @@ enum mandocerr { MANDOCERR_STYLE, /* ===== start of style suggestions ===== */ MANDOCERR_DATE_LEGACY, /* legacy man(7) date format: Dd ... */ + MANDOCERR_DATE_NORM, /* normalizing date format to: ... */ MANDOCERR_TITLE_CASE, /* lower case character in document title */ MANDOCERR_RCS_REP, /* duplicate RCS id: ... */ - MANDOCERR_SEC_TYPO, /* typo in section name: Sh ... */ + MANDOCERR_SEC_TYPO, /* possible typo in section name: Sh ... */ MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */ MANDOCERR_MACRO_USELESS, /* useless macro: macro */ MANDOCERR_BX, /* consider using OS macro: macro */ @@ -68,6 +69,7 @@ enum mandocerr { MANDOCERR_DELIM_NB, /* no blank before trailing delimiter: macro ... */ MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */ MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */ + MANDOCERR_DASHDASH, /* verbatim "--", maybe consider using \(em */ MANDOCERR_FUNC, /* function name without markup: name() */ MANDOCERR_SPACE_EOL, /* whitespace at end of input line */ MANDOCERR_COMMENT_BAD, /* bad comment style */ diff --git a/contrib/mdocml/mandoc_aux.c b/contrib/mandoc/mandoc_aux.c similarity index 94% rename from contrib/mdocml/mandoc_aux.c rename to contrib/mandoc/mandoc_aux.c index db593e444c48..5d595ce0c292 100644 --- a/contrib/mdocml/mandoc_aux.c +++ b/contrib/mandoc/mandoc_aux.c @@ -1,4 +1,4 @@ -/* $Id: mandoc_aux.c,v 1.10 2017/06/12 19:05:47 schwarze Exp $ */ +/* $Id: mandoc_aux.c,v 1.11 2018/02/07 20:04:57 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -111,8 +111,8 @@ mandoc_strndup(const char *ptr, size_t sz) { char *p; - p = mandoc_malloc(sz + 1); - memcpy(p, ptr, sz); - p[(int)sz] = '\0'; + p = strndup(ptr, sz); + if (p == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); return p; } diff --git a/contrib/mdocml/mandoc_aux.h b/contrib/mandoc/mandoc_aux.h similarity index 100% rename from contrib/mdocml/mandoc_aux.h rename to contrib/mandoc/mandoc_aux.h diff --git a/contrib/mdocml/mandoc_char.7 b/contrib/mandoc/mandoc_char.7 similarity index 92% rename from contrib/mdocml/mandoc_char.7 rename to contrib/mandoc/mandoc_char.7 index a372b3e91dfc..f63cdaea8fcc 100644 --- a/contrib/mdocml/mandoc_char.7 +++ b/contrib/mandoc/mandoc_char.7 @@ -1,4 +1,4 @@ -.\" $Id: mandoc_char.7,v 1.67 2017/06/14 20:57:07 schwarze Exp $ +.\" $Id: mandoc_char.7,v 1.72 2018/08/08 14:30:48 schwarze Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org> .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 14 2017 $ +.Dd $Mdocdate: August 8 2018 $ .Dt MANDOC_CHAR 7 .Os .Sh NAME @@ -35,23 +35,37 @@ documents. .Pp The rendering depends on the .Xr mandoc 1 -output mode; in ASCII output, most characters are completely -unintelligible. -For that reason, using any of the special characters documented here, -except those discussed in the +output mode; it can be inspected by calling +.Xr man 1 +on the +.Nm +manual page with different +.Fl T +arguments. +In ASCII output, the rendering of some characters may be hard +to interpret for the reader. +Many are rendered as descriptive strings like +.Qq <integral> , +.Qq <degree> , +or +.Qq <Gamma> , +which may look ugly, and many are replaced by similar ASCII characters. +In particular, accented characters are usually shown without the accent. +For that reason, try to avoid using any of the special characters +documented here except those discussed in the .Sx DESCRIPTION , -is strongly discouraged; they are supported merely for backwards -compatibility with existing documents. +unless they are essential for explaining the subject matter at hand, +for example when documenting complicated mathematical functions. .Pp In particular, in English manual pages, do not use special-character escape sequences to represent national language characters in author names; instead, provide ASCII transcriptions of the names. .Ss Dashes and Hyphens In typography there are different types of dashes of various width: -the hyphen (-), -the minus sign (\(mi), +the hyphen (\(hy), the en-dash (\(en), -and the em-dash (\(em). +the em-dash (\(em), +and the mathematical minus sign (\(mi). .Pp Hyphens are used for adjectives; to separate the two parts of a compound word; @@ -62,6 +76,42 @@ blue-eyed lorry-driver .Ed .Pp +The en-dash is used to separate the two elements of a range, +or can be used the same way as an em-dash. +It should be written as +.Sq \e(en : +.Bd -unfilled -offset indent +pp. 95\e(en97. +Go away \e(en or else! +.Ed +.Pp +The em-dash can be used to show an interruption +or can be used the same way as colons, semi-colons, or parentheses. +It should be written as +.Sq \e(em : +.Bd -unfilled -offset indent +Three things \e(em apples, oranges, and bananas. +This is not that \e(em rather, this is that. +.Ed +.Pp +In +.Xr roff 7 +documents, the minus sign is normally written as +.Sq \e- . +In manual pages, some style guides recommend to also use +.Sq \e- +if an ASCII 0x2d +.Dq hyphen-minus +output glyph that can be copied and pasted is desired in output modes +supporting it, for example in +.Fl T Cm utf8 +and +.Fl T Cm html . +But currently, no practically relevant manual page formatter actually +requires that subtlety, so in manual pages just write plain +.Sq - +to represent hyphen, minus, and hyphen-minus. +.Pp If a word on a text input line contains a hyphen, a formatter may decide to insert an output line break after the hyphen if that helps filling the current output line, but the whole word would overflow the line. @@ -85,37 +135,6 @@ Such automatic hyphenation is not supported by .Xr mandoc 1 , which only breaks the line at whitespace, and inside words only after existing hyphens. -.Pp -The mathematical minus sign is used for negative numbers or subtraction. -It should be written as -.Sq \e(mi : -.Bd -unfilled -offset indent -a = 3 \e(mi 1; -b = \e(mi2; -.Ed -.Pp -The en-dash is used to separate the two elements of a range, -or can be used the same way as an em-dash. -It should be written as -.Sq \e(en : -.Bd -unfilled -offset indent -pp. 95\e(en97. -Go away \e(en or else! -.Ed -.Pp -The em-dash can be used to show an interruption -or can be used the same way as colons, semi-colons, or parentheses. -It should be written as -.Sq \e(em : -.Bd -unfilled -offset indent -Three things \e(em apples, oranges, and bananas. -This is not that \e(em rather, this is that. -.Ed -.Pp -Note: -hyphens, minus signs, and en-dashes look identical under normal ASCII output. -Other formats, such as PostScript, render them correctly, -with differing widths. .Ss Spaces To separate words in normal text, for indenting and alignment in literal context, and when none of the following special cases apply, @@ -319,8 +338,8 @@ Quotes: .It \e(rq Ta \(rq Ta right double-quote .It \e(oq Ta \(oq Ta left single-quote .It \e(cq Ta \(cq Ta right single-quote -.It \e(aq Ta \(aq Ta apostrophe quote (text) -.It \e(dq Ta \(dq Ta double quote (text) +.It \e(aq Ta \(aq Ta apostrophe quote (ASCII character) +.It \e(dq Ta \(dq Ta double quote (ASCII character) .It \e(Fo Ta \(Fo Ta left guillemet .It \e(Fc Ta \(Fc Ta right guillemet .It \e(fo Ta \(fo Ta left single guillemet @@ -336,7 +355,7 @@ Brackets: .It \e(rC Ta \(rC Ta right brace .It \e(la Ta \(la Ta left angle .It \e(ra Ta \(ra Ta right angle -.It \e(bv Ta \(bv Ta brace extension +.It \e(bv Ta \(bv Ta brace extension (special font) .It \e[braceex] Ta \[braceex] Ta brace extension .It \e[bracketlefttp] Ta \[bracketlefttp] Ta top-left hooked bracket .It \e[bracketleftbt] Ta \[bracketleftbt] Ta bottom-left hooked bracket @@ -389,8 +408,8 @@ Logical: .It Em Input Ta Em Rendered Ta Em Description .It \e(AN Ta \(AN Ta logical and .It \e(OR Ta \(OR Ta logical or -.It \e(no Ta \(no Ta logical not -.It \e[tno] Ta \[tno] Ta logical not (text) +.It \e[tno] Ta \[tno] Ta logical not (text font) +.It \e(no Ta \(no Ta logical not (special font) .It \e(te Ta \(te Ta existential quantifier .It \e(fa Ta \(fa Ta universal quantifier .It \e(st Ta \(st Ta such that @@ -402,19 +421,20 @@ Logical: Mathematical: .Bl -column "xxcoproductxx" "Rendered" "Description" -offset indent -compact .It Em Input Ta Em Rendered Ta Em Description -.It \e(pl Ta \(pl Ta plus -.It \e(mi Ta \(mi Ta minus -.It \e- Ta \- Ta minus (text) +.It \e- Ta \- Ta minus (text font) +.It \e(mi Ta \(mi Ta minus (special font) +.It + Ta + Ta plus (text font) +.It \e(pl Ta \(pl Ta plus (special font) .It \e(-+ Ta \(-+ Ta minus-plus -.It \e(+- Ta \(+- Ta plus-minus -.It \e[t+-] Ta \[t+-] Ta plus-minus (text) +.It \e[t+-] Ta \[t+-] Ta plus-minus (text font) +.It \e(+- Ta \(+- Ta plus-minus (special font) .It \e(pc Ta \(pc Ta center-dot -.It \e(mu Ta \(mu Ta multiply -.It \e[tmu] Ta \[tmu] Ta multiply (text) +.It \e[tmu] Ta \[tmu] Ta multiply (text font) +.It \e(mu Ta \(mu Ta multiply (special font) .It \e(c* Ta \(c* Ta circle-multiply .It \e(c+ Ta \(c+ Ta circle-plus -.It \e(di Ta \(di Ta divide -.It \e[tdi] Ta \[tdi] Ta divide (text) +.It \e[tdi] Ta \[tdi] Ta divide (text font) +.It \e(di Ta \(di Ta divide (special font) .It \e(f/ Ta \(f/ Ta fraction .It \e(** Ta \(** Ta asterisk .It \e(<= Ta \(<= Ta less-than-equal @@ -511,8 +531,8 @@ Accents: .It \e(ao Ta \(ao Ta ring .It \e(a\(ti Ta \(a~ Ta tilde .It \e(ho Ta \(ho Ta ogonek -.It \e(ha Ta \(ha Ta hat (text) -.It \e(ti Ta \(ti Ta tilde (text) +.It \e(ha Ta \(ha Ta hat (ASCII character) +.It \e(ti Ta \(ti Ta tilde (ASCII character) .El .Pp Accented letters: diff --git a/contrib/mdocml/mandoc_escape.3 b/contrib/mandoc/mandoc_escape.3 similarity index 100% rename from contrib/mdocml/mandoc_escape.3 rename to contrib/mandoc/mandoc_escape.3 diff --git a/contrib/mdocml/mandoc_headers.3 b/contrib/mandoc/mandoc_headers.3 similarity index 100% rename from contrib/mdocml/mandoc_headers.3 rename to contrib/mandoc/mandoc_headers.3 diff --git a/contrib/mdocml/mandoc_html.3 b/contrib/mandoc/mandoc_html.3 similarity index 80% rename from contrib/mdocml/mandoc_html.3 rename to contrib/mandoc/mandoc_html.3 index ba25e0ad6a7d..5bd9446da824 100644 --- a/contrib/mdocml/mandoc_html.3 +++ b/contrib/mandoc/mandoc_html.3 @@ -1,6 +1,6 @@ -.\" $Id: mandoc_html.3,v 1.10 2017/07/15 17:57:51 schwarze Exp $ +.\" $Id: mandoc_html.3,v 1.17 2018/06/25 16:54:59 schwarze Exp $ .\" -.\" Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 15 2017 $ +.Dd $Mdocdate: June 25 2018 $ .Dt MANDOC_HTML 3 .Os .Sh NAME @@ -25,6 +25,8 @@ .Ft void .Fn print_gen_decls "struct html *h" .Ft void +.Fn print_gen_comment "struct html *h" "struct roff_node *n" +.Ft void .Fn print_gen_head "struct html *h" .Ft struct tag * .Fo print_otag @@ -109,6 +111,18 @@ and declarations required for the current document type. .Pp The function +.Fn print_gen_comment +prints the leading comments, usually containing a Copyright notice +and license, as an HTML comment. +It is intended to be called right after opening the +.Aq Ic HTML +element. +Pass the first +.Dv ROFFT_COMMENT +node in +.Fa n . +.Pp +The function .Fn print_gen_head prints the opening .Aq Ic META @@ -198,84 +212,10 @@ Print a .Cm style attribute. If present, it must be the last format letter. -In contrast to the other format letters, this one does not yet -print the value and does not take an argument. -Instead, the rest of the format string consists of pairs of -argument type letters and style name letters. -.El -.Pp -Argument type letters each require one argument as follows: -.Bl -tag -width 1n -offset indent -.It Cm h -Requires one -.Vt int -argument, interpreted as a horizontal length in units of -.Dv SCALE_EN . -.It Cm s -Requires one -.Vt char * -argument, used as a style value. -.It Cm u -Requires one -.Vt struct roffsu * -argument, used as a length. -.It Cm w -Requires one -.Vt char * -argument, interpreted as an -.Xr mdoc 7 Ns -style -width specifier. -If the argument is -.Dv NULL , -nothing is printed for this pair. -.Pp -The -.Cm w -argument type letter can optionally be followed by one, two, or three -modifier letters. -The modifier -.Cm * -suppresses printing of the pair if the argument matches 6n. -The modifier -.Cm + -increases the width by 20% to make even bold text fit -and adds three units for padding between columns. -The modifier -.Cm \- -makes the width negative by multiplying it with \-1. -.El -.Pp -Style name letters decide what to do with the preceding argument: -.Bl -tag -width 1n -offset indent -.It Cm h -Set -.Cm height -to the given length. -.It Cm i -Set -.Cm text-indent -to the given length. -.It Cm l -Set -.Cm margin-left -to the given length. -.It Cm w -Set -.Cm width -to the given length. -.It Cm W -Set -.Cm min-width -to the given length. -.It Cm \&? -The special pair -.Cm s? -requires two -.Vt char * +It requires two +.Va char * arguments. -The first is the style name, the second its value. -The style name must not be -.Dv NULL . +The first is the name of the style property, the second its value. .El .Pp .Fn print_otag diff --git a/contrib/mdocml/mandoc_malloc.3 b/contrib/mandoc/mandoc_malloc.3 similarity index 100% rename from contrib/mdocml/mandoc_malloc.3 rename to contrib/mandoc/mandoc_malloc.3 diff --git a/contrib/mdocml/mandoc_ohash.c b/contrib/mandoc/mandoc_ohash.c similarity index 100% rename from contrib/mdocml/mandoc_ohash.c rename to contrib/mandoc/mandoc_ohash.c diff --git a/contrib/mdocml/mandoc_ohash.h b/contrib/mandoc/mandoc_ohash.h similarity index 100% rename from contrib/mdocml/mandoc_ohash.h rename to contrib/mandoc/mandoc_ohash.h diff --git a/contrib/mdocml/mandoc_xr.c b/contrib/mandoc/mandoc_xr.c similarity index 100% rename from contrib/mdocml/mandoc_xr.c rename to contrib/mandoc/mandoc_xr.c diff --git a/contrib/mdocml/mandoc_xr.h b/contrib/mandoc/mandoc_xr.h similarity index 100% rename from contrib/mdocml/mandoc_xr.h rename to contrib/mandoc/mandoc_xr.h diff --git a/contrib/mdocml/mandocd.8 b/contrib/mandoc/mandocd.8 similarity index 100% rename from contrib/mdocml/mandocd.8 rename to contrib/mandoc/mandocd.8 diff --git a/contrib/mdocml/mandocd.c b/contrib/mandoc/mandocd.c similarity index 100% rename from contrib/mdocml/mandocd.c rename to contrib/mandoc/mandocd.c diff --git a/contrib/mdocml/mandocdb.c b/contrib/mandoc/mandocdb.c similarity index 96% rename from contrib/mdocml/mandocdb.c rename to contrib/mandoc/mandocdb.c index 26117cf82781..86dbce2d9fe6 100644 --- a/contrib/mdocml/mandocdb.c +++ b/contrib/mandoc/mandocdb.c @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.253 2017/07/28 14:48:25 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.258 2018/02/23 18:25:57 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -19,8 +19,8 @@ #include "config.h" #include <sys/types.h> +#include <sys/mman.h> #include <sys/stat.h> -#include <sys/wait.h> #include <assert.h> #include <ctype.h> @@ -139,6 +139,8 @@ static void parse_mdoc(struct mpage *, const struct roff_meta *, const struct roff_node *); static int parse_mdoc_head(struct mpage *, const struct roff_meta *, const struct roff_node *); +static int parse_mdoc_Fa(struct mpage *, const struct roff_meta *, + const struct roff_node *); static int parse_mdoc_Fd(struct mpage *, const struct roff_meta *, const struct roff_node *); static void parse_mdoc_fname(struct mpage *, const struct roff_node *); @@ -207,11 +209,11 @@ static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = { { NULL, TYPE_Er, 0 }, /* Er */ { NULL, TYPE_Ev, 0 }, /* Ev */ { NULL, 0, 0 }, /* Ex */ - { NULL, TYPE_Fa, 0 }, /* Fa */ + { parse_mdoc_Fa, 0, 0 }, /* Fa */ { parse_mdoc_Fd, 0, 0 }, /* Fd */ { NULL, TYPE_Fl, 0 }, /* Fl */ { parse_mdoc_Fn, 0, 0 }, /* Fn */ - { NULL, TYPE_Ft, 0 }, /* Ft */ + { NULL, TYPE_Ft | TYPE_Vt, 0 }, /* Ft */ { NULL, TYPE_Ic, 0 }, /* Ic */ { NULL, TYPE_In, 0 }, /* In */ { NULL, TYPE_Li, 0 }, /* Li */ @@ -319,7 +321,7 @@ mandocdb(int argc, char *argv[]) int ch, i; #if HAVE_PLEDGE - if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { warn("pledge"); return (int)MANDOCLEVEL_SYSERR; } @@ -440,15 +442,6 @@ mandocdb(int argc, char *argv[]) * The existing database is usable. Process * all files specified on the command-line. */ -#if HAVE_PLEDGE - if (!nodb) { - if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1) { - warn("pledge"); - exitcode = (int)MANDOCLEVEL_SYSERR; - goto out; - } - } -#endif use_all = 1; for (i = 0; i < argc; i++) filescan(argv[i]); @@ -1382,7 +1375,12 @@ parse_cat(struct mpage *mpage, int fd) plen -= 2; } - mpage->desc = mandoc_strdup(p); + /* + * Cut off excessive one-line descriptions. + * Bad pages are not worth better heuristics. + */ + + mpage->desc = mandoc_strndup(p, 150); fclose(stream); free(title); } @@ -1526,7 +1524,12 @@ parse_man(struct mpage *mpage, const struct roff_meta *meta, while (' ' == *start) start++; - mpage->desc = mandoc_strdup(start); + /* + * Cut off excessive one-line descriptions. + * Bad pages are not worth better heuristics. + */ + + mpage->desc = mandoc_strndup(start, 150); free(title); return; } @@ -1571,6 +1574,20 @@ parse_mdoc(struct mpage *mpage, const struct roff_meta *meta, } } +static int +parse_mdoc_Fa(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) +{ + uint64_t mask; + + mask = TYPE_Fa; + if (n->sec == SEC_SYNOPSIS) + mask |= TYPE_Vt; + + putmdockey(mpage, n->child, mask, 0); + return 0; +} + static int parse_mdoc_Fd(struct mpage *mpage, const struct roff_meta *meta, const struct roff_node *n) @@ -1640,15 +1657,20 @@ static int parse_mdoc_Fn(struct mpage *mpage, const struct roff_meta *meta, const struct roff_node *n) { + uint64_t mask; if (n->child == NULL) return 0; parse_mdoc_fname(mpage, n->child); - for (n = n->child->next; n != NULL; n = n->next) - if (n->type == ROFFT_TEXT) - putkey(mpage, n->string, TYPE_Fa); + n = n->child->next; + if (n != NULL && n->type == ROFFT_TEXT) { + mask = TYPE_Fa; + if (n->sec == SEC_SYNOPSIS) + mask |= TYPE_Vt; + putmdockey(mpage, n, mask, 0); + } return 0; } @@ -2119,9 +2141,10 @@ dbprune(struct dba *dba) static void dbwrite(struct dba *dba) { - char tfn[32]; - int status; - pid_t child; + struct stat sb1, sb2; + char tfn[33], *cp1, *cp2; + off_t i; + int fd1, fd2; /* * Do not write empty databases, and delete existing ones @@ -2160,59 +2183,62 @@ dbwrite(struct dba *dba) say("", "&%s", tfn); return; } - + cp1 = cp2 = MAP_FAILED; + fd1 = fd2 = -1; (void)strlcat(tfn, "/" MANDOC_DB, sizeof(tfn)); if (dba_write(tfn, dba) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; say(tfn, "&dba_write"); - goto out; + goto err; } + if ((fd1 = open(MANDOC_DB, O_RDONLY, 0)) == -1) { + say(MANDOC_DB, "&open"); + goto err; + } + if ((fd2 = open(tfn, O_RDONLY, 0)) == -1) { + say(tfn, "&open"); + goto err; + } + if (fstat(fd1, &sb1) == -1) { + say(MANDOC_DB, "&fstat"); + goto err; + } + if (fstat(fd2, &sb2) == -1) { + say(tfn, "&fstat"); + goto err; + } + if (sb1.st_size != sb2.st_size) + goto err; + if ((cp1 = mmap(NULL, sb1.st_size, PROT_READ, MAP_PRIVATE, + fd1, 0)) == MAP_FAILED) { + say(MANDOC_DB, "&mmap"); + goto err; + } + if ((cp2 = mmap(NULL, sb2.st_size, PROT_READ, MAP_PRIVATE, + fd2, 0)) == MAP_FAILED) { + say(tfn, "&mmap"); + goto err; + } + for (i = 0; i < sb1.st_size; i++) + if (cp1[i] != cp2[i]) + goto err; + goto out; - switch (child = fork()) { - case -1: - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&fork cmp"); - return; - case 0: - execlp("cmp", "cmp", "-s", tfn, MANDOC_DB, (char *)NULL); - say("", "&exec cmp"); - exit(0); - default: - break; - } - if (waitpid(child, &status, 0) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&wait cmp"); - } else if (WIFSIGNALED(status)) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "cmp died from signal %d", WTERMSIG(status)); - } else if (WEXITSTATUS(status)) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say(MANDOC_DB, - "Data changed, but cannot replace database"); - } +err: + exitcode = (int)MANDOCLEVEL_SYSERR; + say(MANDOC_DB, "Data changed, but cannot replace database"); out: + if (cp1 != MAP_FAILED) + munmap(cp1, sb1.st_size); + if (cp2 != MAP_FAILED) + munmap(cp2, sb2.st_size); + if (fd1 != -1) + close(fd1); + if (fd2 != -1) + close(fd2); + unlink(tfn); *strrchr(tfn, '/') = '\0'; - switch (child = fork()) { - case -1: - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&fork rm"); - return; - case 0: - execlp("rm", "rm", "-rf", tfn, (char *)NULL); - say("", "&exec rm"); - exit((int)MANDOCLEVEL_SYSERR); - default: - break; - } - if (waitpid(child, &status, 0) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&wait rm"); - } else if (WIFSIGNALED(status) || WEXITSTATUS(status)) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "%s: Cannot remove temporary directory", tfn); - } + rmdir(tfn); } static int diff --git a/contrib/mdocml/manpath.c b/contrib/mandoc/manpath.c similarity index 100% rename from contrib/mdocml/manpath.c rename to contrib/mandoc/manpath.c diff --git a/contrib/mdocml/manpath.h b/contrib/mandoc/manpath.h similarity index 100% rename from contrib/mdocml/manpath.h rename to contrib/mandoc/manpath.h diff --git a/contrib/mdocml/mansearch.3 b/contrib/mandoc/mansearch.3 similarity index 100% rename from contrib/mdocml/mansearch.3 rename to contrib/mandoc/mansearch.3 diff --git a/contrib/mdocml/mansearch.c b/contrib/mandoc/mansearch.c similarity index 98% rename from contrib/mdocml/mansearch.c rename to contrib/mandoc/mansearch.c index 0d60c3bed731..784c17bee714 100644 --- a/contrib/mdocml/mansearch.c +++ b/contrib/mandoc/mansearch.c @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.76 2017/08/02 13:29:04 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.77 2017/08/22 17:50:11 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -188,6 +188,16 @@ mansearch(const struct mansearch *search, mpage = *res + cur; mandoc_asprintf(&mpage->file, "%s/%s", paths->paths[i], page->file + 1); + if (access(chdir_status ? page->file + 1 : + mpage->file, R_OK) == -1) { + warn("%s", mpage->file); + warnx("outdated mandoc.db contains " + "bogus %s entry, run makewhatis %s", + page->file + 1, paths->paths[i]); + free(mpage->file); + free(rp); + continue; + } mpage->names = buildnames(page); mpage->output = buildoutput(outkey, page); mpage->ipath = i; diff --git a/contrib/mdocml/mansearch.h b/contrib/mandoc/mansearch.h similarity index 100% rename from contrib/mdocml/mansearch.h rename to contrib/mandoc/mansearch.h diff --git a/contrib/mdocml/mchars_alloc.3 b/contrib/mandoc/mchars_alloc.3 similarity index 100% rename from contrib/mdocml/mchars_alloc.3 rename to contrib/mandoc/mchars_alloc.3 diff --git a/contrib/mdocml/mdoc.7 b/contrib/mandoc/mdoc.7 similarity index 98% rename from contrib/mdocml/mdoc.7 rename to contrib/mandoc/mdoc.7 index 69cccd2b6b2a..5c07434cd80e 100644 --- a/contrib/mdocml/mdoc.7 +++ b/contrib/mandoc/mdoc.7 @@ -1,7 +1,7 @@ -.\" $Id: mdoc.7,v 1.269 2017/07/20 16:24:53 schwarze Exp $ +.\" $Id: mdoc.7,v 1.271 2018/07/28 18:34:15 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2010, 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010, 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 5 2017 $ +.Dd $Mdocdate: July 28 2018 $ .Dt MDOC 7 .Os .Sh NAME @@ -674,12 +674,10 @@ Examples: .Ss \&Ao Begin a block enclosed by angle brackets. Does not have any head arguments. -.Pp -Examples: -.Dl \&.Fl -key= \&Ns \&Ao \&Ar val \&Ac -.Pp -See also -.Sx \&Aq . +This macro is almost never useful. +See +.Sx \&Aq +for more details. .Ss \&Ap Inserts an apostrophe without any surrounding whitespace. This is generally used as a grammatical device when referring to the verb @@ -689,19 +687,45 @@ Examples: .Dl \&.Fn execve \&Ap d .Ss \&Aq Encloses its arguments in angle brackets. +The only important use case is for email addresses. +See +.Sx \&Mt +for an example. .Pp -Examples: -.Dl \&.Fl -key= \&Ns \&Aq \&Ar val +Occasionally, it is used for names of characters and keys, for example: +.Bd -literal -offset indent +Press the +\&.Aq escape +key to ... +.Ed .Pp -.Em Remarks : -this macro is often abused for rendering URIs, which should instead use +For URIs, use .Sx \&Lk +instead, and +.Sx \&In +for +.Dq #include +directives. +Never wrap +.Sx \&Ar +in +.Sx \&Aq . +.Pp +Since +.Sx \&Aq +usually renders with non-ASCII characters in non-ASCII output modes, +do not use it where the ASCII characters +.Sq < +and +.Sq > +are required as syntax elements. +Instead, use these characters directly in such cases, combining them +with the macros +.Sx \&Pf , +.Sx \&Ns , or -.Sx \&Mt , -or to note pre-processor -.Dq Li #include -statements, which should use -.Sx \&In . +.Sx \&Eo +as needed. .Pp See also .Sx \&Ao . @@ -1210,7 +1234,7 @@ The .Ar month is the full English month name, the .Ar day -is an optionally zero-padded numeral, and the +is an integer number, and the .Ar year is the full four-digit year. .Pp @@ -1240,8 +1264,8 @@ If no date string is given, the current date is used. .Pp Examples: .Dl \&.Dd $\&Mdocdate$ -.Dl \&.Dd $\&Mdocdate: July 21 2007$ -.Dl \&.Dd July 21, 2007 +.Dl \&.Dd $\&Mdocdate: July 2 2018$ +.Dl \&.Dd July 2, 2018 .Pp See also .Sx \&Dt @@ -2575,17 +2599,6 @@ The second and last Technical Corrigendum. .br This standard is also called X/Open Portability Guide version 7. -.Pp -.It \-p1003.1-2013 -.St -p1003.1-2013 -.br -The 2013 edition incorporates Technical Corrigendum 1. -.Pp -.It \-p1003.1-2016 -.St -p1003.1-2016 -.br -The 2016 edition incorporates Technical Corrigendum 1 and -Technical Corrigendum 2. .El .It Other standards .Pp diff --git a/contrib/mdocml/mdoc.c b/contrib/mandoc/mdoc.c similarity index 98% rename from contrib/mdocml/mdoc.c rename to contrib/mandoc/mdoc.c index 7afcc5d29e1c..71803531ddfb 100644 --- a/contrib/mdocml/mdoc.c +++ b/contrib/mandoc/mdoc.c @@ -1,4 +1,4 @@ -/* $Id: mdoc.c,v 1.267 2017/06/17 13:06:16 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.268 2017/08/11 16:56:21 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -297,8 +297,8 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs) if (end - c < 3) break; if (c[1] != ' ' || - isalpha((unsigned char)c[-2]) == 0 || - isalpha((unsigned char)c[-1]) == 0 || + isalnum((unsigned char)c[-2]) == 0 || + isalnum((unsigned char)c[-1]) == 0 || (c[-2] == 'n' && c[-1] == 'c') || (c[-2] == 'v' && c[-1] == 's')) continue; diff --git a/contrib/mdocml/mdoc.h b/contrib/mandoc/mdoc.h similarity index 100% rename from contrib/mdocml/mdoc.h rename to contrib/mandoc/mdoc.h diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mandoc/mdoc_argv.c similarity index 100% rename from contrib/mdocml/mdoc_argv.c rename to contrib/mandoc/mdoc_argv.c diff --git a/contrib/mdocml/mdoc_html.c b/contrib/mandoc/mdoc_html.c similarity index 87% rename from contrib/mdocml/mdoc_html.c rename to contrib/mandoc/mdoc_html.c index 0b4b9adf34f2..f50de8a77af0 100644 --- a/contrib/mdocml/mdoc_html.c +++ b/contrib/mandoc/mdoc_html.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_html.c,v 1.294 2017/07/15 17:57:51 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.310 2018/07/27 17:49:31 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -34,8 +34,6 @@ #include "html.h" #include "main.h" -#define INDENT 5 - #define MDOC_ARGS const struct roff_meta *meta, \ struct roff_node *n, \ struct html *h @@ -50,14 +48,17 @@ struct htmlmdoc { }; static char *cond_id(const struct roff_node *); -static void print_mdoc_head(MDOC_ARGS); +static void print_mdoc_head(const struct roff_meta *, + struct html *); static void print_mdoc_node(MDOC_ARGS); static void print_mdoc_nodelist(MDOC_ARGS); static void synopsis_pre(struct html *, const struct roff_node *); -static void mdoc_root_post(MDOC_ARGS); -static int mdoc_root_pre(MDOC_ARGS); +static void mdoc_root_post(const struct roff_meta *, + struct html *); +static int mdoc_root_pre(const struct roff_meta *, + struct html *); static void mdoc__x_post(MDOC_ARGS); static int mdoc__x_pre(MDOC_ARGS); @@ -284,30 +285,34 @@ synopsis_pre(struct html *h, const struct roff_node *n) void html_mdoc(void *arg, const struct roff_man *mdoc) { - struct html *h; - struct tag *t; + struct html *h; + struct roff_node *n; + struct tag *t; h = (struct html *)arg; + n = mdoc->first->child; if ((h->oflags & HTML_FRAGMENT) == 0) { print_gen_decls(h); print_otag(h, TAG_HTML, ""); + if (n->type == ROFFT_COMMENT) + print_gen_comment(h, n); t = print_otag(h, TAG_HEAD, ""); - print_mdoc_head(&mdoc->meta, mdoc->first->child, h); + print_mdoc_head(&mdoc->meta, h); print_tagq(h, t); print_otag(h, TAG_BODY, ""); } - mdoc_root_pre(&mdoc->meta, mdoc->first->child, h); + mdoc_root_pre(&mdoc->meta, h); t = print_otag(h, TAG_DIV, "c", "manual-text"); - print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h); + print_mdoc_nodelist(&mdoc->meta, n, h); print_tagq(h, t); - mdoc_root_post(&mdoc->meta, mdoc->first->child, h); + mdoc_root_post(&mdoc->meta, h); print_tagq(h, NULL); } static void -print_mdoc_head(MDOC_ARGS) +print_mdoc_head(const struct roff_meta *meta, struct html *h) { char *cp; @@ -344,7 +349,7 @@ print_mdoc_node(MDOC_ARGS) int child; struct tag *t; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; child = 1; @@ -429,7 +434,7 @@ print_mdoc_node(MDOC_ARGS) } static void -mdoc_root_post(MDOC_ARGS) +mdoc_root_post(const struct roff_meta *meta, struct html *h) { struct tag *t, *tt; @@ -446,7 +451,7 @@ mdoc_root_post(MDOC_ARGS) } static int -mdoc_root_pre(MDOC_ARGS) +mdoc_root_pre(const struct roff_meta *meta, struct html *h) { struct tag *t, *tt; char *volume, *title; @@ -495,7 +500,7 @@ cond_id(const struct roff_node *n) (n->parent->tok == MDOC_Xo && n->parent->parent->prev == NULL && n->parent->parent->parent->tok == MDOC_It))) - return html_make_id(n); + return html_make_id(n, 1); return NULL; } @@ -506,11 +511,10 @@ mdoc_sh_pre(MDOC_ARGS) switch (n->type) { case ROFFT_HEAD: - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H1, "cTi", "Sh", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); break; case ROFFT_BODY: if (n->sec == SEC_AUTHORS) @@ -530,11 +534,10 @@ mdoc_ss_pre(MDOC_ARGS) if (n->type != ROFFT_HEAD) return 1; - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H2, "cTi", "Ss", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); return 1; } @@ -544,9 +547,8 @@ mdoc_fl_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Fl", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_CODE, "cTi", "Fl", id); print_text(h, "\\-"); if (!(n->child == NULL && @@ -564,9 +566,8 @@ mdoc_cm_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Cm", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_CODE, "cTi", "Cm", id); return 1; } @@ -576,10 +577,9 @@ mdoc_nd_pre(MDOC_ARGS) if (n->type != ROFFT_BODY) return 1; - /* XXX: this tag in theory can contain block elements. */ - print_text(h, "\\(em"); - print_otag(h, TAG_SPAN, "cT", "Nd"); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_DIV, "cT", "Nd"); return 1; } @@ -591,7 +591,7 @@ mdoc_nm_pre(MDOC_ARGS) print_otag(h, TAG_TD, ""); /* FALLTHROUGH */ case ROFFT_ELEM: - print_otag(h, TAG_B, "cT", "Nm"); + print_otag(h, TAG_CODE, "cT", "Nm"); return 1; case ROFFT_BODY: print_otag(h, TAG_TD, ""); @@ -661,7 +661,6 @@ mdoc_it_pre(MDOC_ARGS) { const struct roff_node *bl; struct tag *t; - const char *cattr; enum mdoc_list type; bl = n->parent; @@ -669,42 +668,6 @@ mdoc_it_pre(MDOC_ARGS) bl = bl->parent; type = bl->norm->Bl.type; - switch (type) { - case LIST_bullet: - cattr = "It-bullet"; - break; - case LIST_dash: - case LIST_hyphen: - cattr = "It-dash"; - break; - case LIST_item: - cattr = "It-item"; - break; - case LIST_enum: - cattr = "It-enum"; - break; - case LIST_diag: - cattr = "It-diag"; - break; - case LIST_hang: - cattr = "It-hang"; - break; - case LIST_inset: - cattr = "It-inset"; - break; - case LIST_ohang: - cattr = "It-ohang"; - break; - case LIST_tag: - cattr = "It-tag"; - break; - case LIST_column: - cattr = "It-column"; - break; - default: - break; - } - switch (type) { case LIST_bullet: case LIST_dash: @@ -715,7 +678,7 @@ mdoc_it_pre(MDOC_ARGS) case ROFFT_HEAD: return 0; case ROFFT_BODY: - print_otag(h, TAG_LI, "c", cattr); + print_otag(h, TAG_LI, ""); break; default: break; @@ -727,13 +690,10 @@ mdoc_it_pre(MDOC_ARGS) case LIST_ohang: switch (n->type) { case ROFFT_HEAD: - print_otag(h, TAG_DT, "c", cattr); - if (type == LIST_diag) - print_otag(h, TAG_B, "c", cattr); + print_otag(h, TAG_DT, ""); break; case ROFFT_BODY: - print_otag(h, TAG_DD, "csw*+l", cattr, - bl->norm->Bl.width); + print_otag(h, TAG_DD, ""); break; default: break; @@ -746,24 +706,21 @@ mdoc_it_pre(MDOC_ARGS) (n->parent->prev == NULL || n->parent->prev->body == NULL || n->parent->prev->body->child != NULL)) { - t = print_otag(h, TAG_DT, "csw*+-l", - cattr, bl->norm->Bl.width); + t = print_otag(h, TAG_DT, ""); print_text(h, "\\ "); print_tagq(h, t); - t = print_otag(h, TAG_DD, "c", cattr); + t = print_otag(h, TAG_DD, ""); print_text(h, "\\ "); print_tagq(h, t); } - print_otag(h, TAG_DT, "csw*+-l", cattr, - bl->norm->Bl.width); + print_otag(h, TAG_DT, ""); break; case ROFFT_BODY: if (n->child == NULL) { - print_otag(h, TAG_DD, "css?", cattr, - "width", "auto"); + print_otag(h, TAG_DD, "s", "width", "auto"); print_text(h, "\\ "); } else - print_otag(h, TAG_DD, "c", cattr); + print_otag(h, TAG_DD, ""); break; default: break; @@ -774,10 +731,10 @@ mdoc_it_pre(MDOC_ARGS) case ROFFT_HEAD: break; case ROFFT_BODY: - print_otag(h, TAG_TD, "c", cattr); + print_otag(h, TAG_TD, ""); break; default: - print_otag(h, TAG_TR, "c", cattr); + print_otag(h, TAG_TR, ""); } default: break; @@ -789,40 +746,20 @@ mdoc_it_pre(MDOC_ARGS) static int mdoc_bl_pre(MDOC_ARGS) { - char cattr[21]; - struct tag *t; + char cattr[28]; struct mdoc_bl *bl; - size_t i; enum htmltag elemtype; - bl = &n->norm->Bl; - switch (n->type) { case ROFFT_BODY: return 1; - case ROFFT_HEAD: - if (bl->type != LIST_column || bl->ncols == 0) - return 0; - - /* - * For each column, print out the <COL> tag with our - * suggested width. The last column gets min-width, as - * in terminal mode it auto-sizes to the width of the - * screen and we want to preserve that behaviour. - */ - - t = print_otag(h, TAG_COLGROUP, ""); - for (i = 0; i < bl->ncols - 1; i++) - print_otag(h, TAG_COL, "sw+w", bl->cols[i]); - print_otag(h, TAG_COL, "swW", bl->cols[i]); - print_tagq(h, t); return 0; - default: break; } + bl = &n->norm->Bl; switch (bl->type) { case LIST_bullet: elemtype = TAG_UL; @@ -859,9 +796,9 @@ mdoc_bl_pre(MDOC_ARGS) break; case LIST_tag: if (bl->offs) - print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs); - print_otag(h, TAG_DL, "csw*+l", bl->comp ? - "Bl-tag Bl-compact" : "Bl-tag", bl->width); + print_otag(h, TAG_DIV, "c", "Bd-indent"); + print_otag(h, TAG_DL, "c", bl->comp ? + "Bl-tag Bl-compact" : "Bl-tag"); return 1; case LIST_column: elemtype = TAG_TABLE; @@ -870,9 +807,11 @@ mdoc_bl_pre(MDOC_ARGS) default: abort(); } + if (bl->offs != NULL) + (void)strlcat(cattr, " Bd-indent", sizeof(cattr)); if (bl->comp) (void)strlcat(cattr, " Bl-compact", sizeof(cattr)); - print_otag(h, elemtype, "cswl", cattr, bl->offs); + print_otag(h, elemtype, "c", cattr); return 1; } @@ -904,7 +843,7 @@ mdoc_d1_pre(MDOC_ARGS) if (n->type != ROFFT_BLOCK) return 1; - print_otag(h, TAG_DIV, "c", "D1"); + print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); if (n->tok == MDOC_Dl) print_otag(h, TAG_CODE, "c", "Li"); @@ -917,7 +856,7 @@ mdoc_sx_pre(MDOC_ARGS) { char *id; - id = html_make_id(n); + id = html_make_id(n, 0); print_otag(h, TAG_A, "cThR", "Sx", id); free(id); return 1; @@ -926,7 +865,7 @@ mdoc_sx_pre(MDOC_ARGS) static int mdoc_bd_pre(MDOC_ARGS) { - int comp, offs, sv; + int comp, sv; struct roff_node *nn; if (n->type == ROFFT_HEAD) @@ -951,18 +890,9 @@ mdoc_bd_pre(MDOC_ARGS) if (n->norm->Bd.offs == NULL || ! strcmp(n->norm->Bd.offs, "left")) - offs = 0; - else if ( ! strcmp(n->norm->Bd.offs, "indent")) - offs = INDENT; - else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) - offs = INDENT * 2; + print_otag(h, TAG_DIV, "c", "Bd"); else - offs = -1; - - if (offs == -1) - print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs); - else - print_otag(h, TAG_DIV, "cshl", "Bd", offs); + print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); if (n->norm->Bd.type != DISP_unfilled && n->norm->Bd.type != DISP_literal) @@ -1014,14 +944,14 @@ mdoc_bd_pre(MDOC_ARGS) static int mdoc_pa_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "cT", "Pa"); + print_otag(h, TAG_SPAN, "cT", "Pa"); return 1; } static int mdoc_ad_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "c", "Ad"); + print_otag(h, TAG_SPAN, "c", "Ad"); return 1; } @@ -1053,7 +983,7 @@ static int mdoc_cd_pre(MDOC_ARGS) { synopsis_pre(h, n); - print_otag(h, TAG_B, "cT", "Cd"); + print_otag(h, TAG_CODE, "cT", "Cd"); return 1; } @@ -1063,9 +993,8 @@ mdoc_dv_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Dv", id); - free(id); return 1; } @@ -1075,9 +1004,8 @@ mdoc_ev_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Ev", id); - free(id); return 1; } @@ -1090,12 +1018,11 @@ mdoc_er_pre(MDOC_ARGS) (n->parent->tok == MDOC_It || (n->parent->tok == MDOC_Bq && n->parent->parent->parent->tok == MDOC_It)) ? - html_make_id(n) : NULL; + html_make_id(n, 1) : NULL; if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Er", id); - free(id); return 1; } @@ -1142,11 +1069,11 @@ mdoc_fd_pre(MDOC_ARGS) assert(n->type == ROFFT_TEXT); if (strcmp(n->string, "#include")) { - print_otag(h, TAG_B, "cT", "Fd"); + print_otag(h, TAG_CODE, "cT", "Fd"); return 1; } - print_otag(h, TAG_B, "cT", "In"); + print_otag(h, TAG_CODE, "cT", "In"); print_text(h, n->string); if (NULL != (n = n->next)) { @@ -1232,7 +1159,7 @@ mdoc_fn_pre(MDOC_ARGS) print_tagq(h, t); } - t = print_otag(h, TAG_B, "cT", "Fn"); + t = print_otag(h, TAG_CODE, "cT", "Fn"); if (sp) print_text(h, sp); @@ -1245,7 +1172,7 @@ mdoc_fn_pre(MDOC_ARGS) for (n = n->child->next; n; n = n->next) { if (NODE_SYNPRETTY & n->flags) - t = print_otag(h, TAG_VAR, "cTss?", "Fa", + t = print_otag(h, TAG_VAR, "cTs", "Fa", "white-space", "nowrap"); else t = print_otag(h, TAG_VAR, "cT", "Fa"); @@ -1375,7 +1302,7 @@ mdoc_fo_pre(MDOC_ARGS) return 0; assert(n->child->string); - t = print_otag(h, TAG_B, "cT", "Fn"); + t = print_otag(h, TAG_CODE, "cT", "Fn"); print_text(h, n->child->string); print_tagq(h, t); return 0; @@ -1399,7 +1326,7 @@ mdoc_in_pre(MDOC_ARGS) struct tag *t; synopsis_pre(h, n); - print_otag(h, TAG_B, "cT", "In"); + print_otag(h, TAG_CODE, "cT", "In"); /* * The first argument of the `In' gets special treatment as @@ -1444,9 +1371,8 @@ mdoc_ic_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Ic", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_CODE, "cTi", "Ic", id); return 1; } @@ -1478,20 +1404,16 @@ mdoc_bf_pre(MDOC_ARGS) return 1; if (FONT_Em == n->norm->Bf.font) - cattr = "Em"; + cattr = "Bf Em"; else if (FONT_Sy == n->norm->Bf.font) - cattr = "Sy"; + cattr = "Bf Sy"; else if (FONT_Li == n->norm->Bf.font) - cattr = "Li"; + cattr = "Bf Li"; else - cattr = "No"; + cattr = "Bf No"; - /* - * We want this to be inline-formatted, but needs to be div to - * accept block children. - */ - - print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_DIV, "c", cattr); return 1; } @@ -1501,9 +1423,8 @@ mdoc_ms_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Ms", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_SPAN, "cTi", "Ms", id); return 1; } @@ -1542,9 +1463,8 @@ mdoc_no_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_SPAN, "ci", "No", id); - free(id); return 1; } @@ -1554,9 +1474,8 @@ mdoc_li_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "ci", "Li", id); - free(id); return 1; } @@ -1712,7 +1631,8 @@ mdoc_quote_pre(MDOC_ARGS) case MDOC_Op: print_text(h, "\\(lB"); h->flags |= HTML_NOSPACE; - print_otag(h, TAG_SPAN, "c", "Op"); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_IDIV, "c", "Op"); break; case MDOC_En: if (NULL == n->norm->Es || diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mandoc/mdoc_macro.c similarity index 100% rename from contrib/mdocml/mdoc_macro.c rename to contrib/mandoc/mdoc_macro.c diff --git a/contrib/mdocml/mdoc_man.c b/contrib/mandoc/mdoc_man.c similarity index 98% rename from contrib/mdocml/mdoc_man.c rename to contrib/mandoc/mdoc_man.c index cf552ce902bb..bcf9207f79cc 100644 --- a/contrib/mdocml/mdoc_man.c +++ b/contrib/mandoc/mdoc_man.c @@ -1,6 +1,6 @@ -/* $Id: mdoc_man.c,v 1.122 2017/06/14 22:51:25 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.126 2018/04/11 17:11:13 schwarze Exp $ */ /* - * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -202,8 +202,8 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = { { NULL, pre_bk, post_bk, NULL, NULL }, /* Bx */ { NULL, pre_skip, NULL, NULL, NULL }, /* Db */ { NULL, NULL, NULL, NULL, NULL }, /* Dc */ - { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */ - { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Dq */ + { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */ + { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */ { NULL, NULL, NULL, NULL, NULL }, /* Ec */ { NULL, NULL, NULL, NULL, NULL }, /* Ef */ { NULL, pre_em, post_font, NULL, NULL }, /* Em */ @@ -610,6 +610,14 @@ man_mdoc(void *arg, const struct roff_man *mdoc) { struct roff_node *n; + printf(".\\\" Automatically generated from an mdoc input file." + " Do not edit.\n"); + for (n = mdoc->first->child; n != NULL; n = n->next) { + if (n->type != ROFFT_COMMENT) + break; + printf(".\\\"%s\n", n->string); + } + printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n", mdoc->meta.title, (mdoc->meta.msec == NULL ? "" : mdoc->meta.msec), @@ -624,7 +632,7 @@ man_mdoc(void *arg, const struct roff_man *mdoc) fontqueue.head = fontqueue.tail = mandoc_malloc(8); *fontqueue.tail = 'R'; } - for (n = mdoc->first->child; n != NULL; n = n->next) + for (; n != NULL; n = n->next) print_node(&mdoc->meta, n); putchar('\n'); } @@ -1408,7 +1416,7 @@ pre_it(DECL_ARGS) if (bln->norm->Bl.type == LIST_diag) print_line(".B \"", 0); else - print_line(".R \"", 0); + print_line(".BR \\& \"", 0); outflags &= ~MMAN_spc; return 1; case LIST_bullet: @@ -1547,7 +1555,6 @@ static int pre_lk(DECL_ARGS) { const struct roff_node *link, *descr, *punct; - int display; if ((link = n->child) == NULL) return 0; @@ -1570,12 +1577,6 @@ pre_lk(DECL_ARGS) } /* Link target. */ - display = man_strlen(link->string) >= 26; - if (display) { - print_line(".RS", MMAN_Bk_susp); - print_word("6n"); - outflags |= MMAN_nl; - } font_push('B'); print_word(link->string); font_pop(); @@ -1585,8 +1586,6 @@ pre_lk(DECL_ARGS) print_word(punct->string); punct = punct->next; } - if (display) - print_line(".RE", MMAN_nl); return 0; } diff --git a/contrib/mdocml/mdoc_markdown.c b/contrib/mandoc/mdoc_markdown.c similarity index 99% rename from contrib/mdocml/mdoc_markdown.c rename to contrib/mandoc/mdoc_markdown.c index 0b0f184821e5..e73440a4e5cd 100644 --- a/contrib/mdocml/mdoc_markdown.c +++ b/contrib/mandoc/mdoc_markdown.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_markdown.c,v 1.23 2017/06/14 01:31:26 schwarze Exp $ */ +/* $Id: mdoc_markdown.c,v 1.24 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> * @@ -294,7 +294,7 @@ md_node(struct roff_node *n) const struct md_act *act; int cond, process_children; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; if (outflags & MD_nonl) diff --git a/contrib/mdocml/mdoc_state.c b/contrib/mandoc/mdoc_state.c similarity index 94% rename from contrib/mdocml/mdoc_state.c rename to contrib/mandoc/mdoc_state.c index d9cad18b1052..2d8563f5bf16 100644 --- a/contrib/mdocml/mdoc_state.c +++ b/contrib/mandoc/mdoc_state.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_state.c,v 1.8 2017/05/05 15:17:32 schwarze Exp $ */ +/* $Id: mdoc_state.c,v 1.9 2017/11/29 20:05:33 schwarze Exp $ */ /* * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> * @@ -208,19 +208,24 @@ state_bd(STATE_ARGS) static void state_bl(STATE_ARGS) { + struct mdoc_arg *args; + size_t i; if (n->type != ROFFT_HEAD || n->parent->args == NULL) return; - switch(n->parent->args->argv[0].arg) { - case MDOC_Diag: - n->norm->Bl.type = LIST_diag; - break; - case MDOC_Column: - n->norm->Bl.type = LIST_column; - break; - default: - break; + args = n->parent->args; + for (i = 0; i < args->argc; i++) { + switch(args->argv[i].arg) { + case MDOC_Diag: + n->norm->Bl.type = LIST_diag; + return; + case MDOC_Column: + n->norm->Bl.type = LIST_column; + return; + default: + break; + } } } diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mandoc/mdoc_term.c similarity index 98% rename from contrib/mdocml/mdoc_term.c rename to contrib/mandoc/mdoc_term.c index 4e420c5c2114..cf3e7ef3dd64 100644 --- a/contrib/mdocml/mdoc_term.c +++ b/contrib/mandoc/mdoc_term.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_term.c,v 1.364 2017/06/14 17:51:15 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.367 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> * * Permission to use, copy, modify, and distribute this software for any @@ -283,7 +283,9 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc) p->defindent = 5; term_begin(p, print_mdoc_head, print_mdoc_foot, &mdoc->meta); - while (n != NULL && n->flags & NODE_NOPRT) + while (n != NULL && + (n->type == ROFFT_COMMENT || + n->flags & NODE_NOPRT)) n = n->next; if (n != NULL) { if (n->tok != MDOC_Sh) @@ -312,7 +314,7 @@ print_mdoc_node(DECL_ARGS) struct termpair npair; size_t offset, rmargin; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; chld = 1; @@ -567,7 +569,9 @@ print_bvspace(struct termp *p, /* Do not vspace directly after Ss/Sh. */ nn = n; - while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT) + while (nn->prev != NULL && + (nn->prev->type == ROFFT_COMMENT || + nn->prev->flags & NODE_NOPRT)) nn = nn->prev; while (nn->prev == NULL) { do { @@ -1550,7 +1554,8 @@ termp_ss_pre(DECL_ARGS) case ROFFT_BLOCK: term_newln(p); for (nn = n->prev; nn != NULL; nn = nn->prev) - if ((nn->flags & NODE_NOPRT) == 0) + if (nn->type != ROFFT_COMMENT && + (nn->flags & NODE_NOPRT) == 0) break; if (nn != NULL) term_vspace(p); @@ -1664,7 +1669,7 @@ termp_quote_pre(DECL_ARGS) /* FALLTHROUGH */ case MDOC_Do: case MDOC_Dq: - term_word(p, "\\(Lq"); + term_word(p, "\\(lq"); break; case MDOC_En: if (NULL == n->norm->Es || @@ -1722,7 +1727,7 @@ termp_quote_post(DECL_ARGS) /* FALLTHROUGH */ case MDOC_Do: case MDOC_Dq: - term_word(p, "\\(Rq"); + term_word(p, "\\(rq"); break; case MDOC_En: if (n->norm->Es == NULL || @@ -1940,7 +1945,6 @@ static int termp_lk_pre(DECL_ARGS) { const struct roff_node *link, *descr, *punct; - int display; if ((link = n->child) == NULL) return 0; @@ -1966,11 +1970,6 @@ termp_lk_pre(DECL_ARGS) } /* Link target. */ - display = term_strlen(p, link->string) >= 26; - if (display) { - term_newln(p); - p->tcol->offset += term_len(p, p->defindent + 1); - } term_fontpush(p, TERMFONT_BOLD); term_word(p, link->string); term_fontpop(p); @@ -1981,8 +1980,6 @@ termp_lk_pre(DECL_ARGS) term_word(p, punct->string); punct = punct->next; } - if (display) - term_newln(p); return 0; } diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mandoc/mdoc_validate.c similarity index 96% rename from contrib/mdocml/mdoc_validate.c rename to contrib/mandoc/mdoc_validate.c index 3a9b86f3fd2b..b36d3c0a926c 100644 --- a/contrib/mdocml/mdoc_validate.c +++ b/contrib/mandoc/mdoc_validate.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.360 2018/08/01 16:00:58 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -53,10 +53,11 @@ enum check_ineq { typedef void (*v_post)(POST_ARGS); static int build_list(struct roff_man *, int); -static void check_text(struct roff_man *, int, int, char *); static void check_argv(struct roff_man *, struct roff_node *, struct mdoc_argv *); static void check_args(struct roff_man *, struct roff_node *); +static void check_text(struct roff_man *, int, int, char *); +static void check_text_em(struct roff_man *, int, int, char *); static void check_toptext(struct roff_man *, int, int, const char *); static int child_an(const struct roff_node *); static size_t macro2len(enum roff_tok); @@ -169,12 +170,12 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ NULL, /* %V */ NULL, /* Ac */ - post_delim_nb, /* Ao */ + NULL, /* Ao */ post_delim_nb, /* Aq */ post_at, /* At */ NULL, /* Bc */ post_bf, /* Bf */ - post_delim_nb, /* Bo */ + NULL, /* Bo */ NULL, /* Bq */ post_xx, /* Bsx */ post_bx, /* Bx */ @@ -194,16 +195,16 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_xx, /* Ox */ NULL, /* Pc */ NULL, /* Pf */ - post_delim_nb, /* Po */ + NULL, /* Po */ post_delim_nb, /* Pq */ NULL, /* Qc */ post_delim_nb, /* Ql */ - post_delim_nb, /* Qo */ + NULL, /* Qo */ post_delim_nb, /* Qq */ NULL, /* Re */ post_rs, /* Rs */ NULL, /* Sc */ - post_delim_nb, /* So */ + NULL, /* So */ post_delim_nb, /* Sq */ post_sm, /* Sm */ post_sx, /* Sx */ @@ -214,7 +215,7 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { NULL, /* Xo */ post_fo, /* Fo */ NULL, /* Fc */ - post_delim_nb, /* Oo */ + NULL, /* Oo */ NULL, /* Oc */ post_bk, /* Bk */ NULL, /* Ek */ @@ -227,7 +228,7 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_delim_nb, /* Lk */ post_defaults, /* Mt */ post_delim_nb, /* Brq */ - post_delim_nb, /* Bro */ + NULL, /* Bro */ NULL, /* Brc */ NULL, /* %C */ post_es, /* Es */ @@ -288,7 +289,7 @@ static const char * const secnames[SEC__MAX] = { void mdoc_node_validate(struct roff_man *mdoc) { - struct roff_node *n; + struct roff_node *n, *np; const v_post *p; n = mdoc->last; @@ -305,15 +306,21 @@ mdoc_node_validate(struct roff_man *mdoc) mdoc->next = ROFF_NEXT_SIBLING; switch (n->type) { case ROFFT_TEXT: + np = n->parent; if (n->sec != SEC_SYNOPSIS || - (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd)) + (np->tok != MDOC_Cd && np->tok != MDOC_Fd)) check_text(mdoc, n->line, n->pos, n->string); - if (n->parent->tok == MDOC_It || - (n->parent->type == ROFFT_BODY && - (n->parent->tok == MDOC_Sh || - n->parent->tok == MDOC_Ss))) + if (np->tok != MDOC_Ql && np->tok != MDOC_Dl && + (np->tok != MDOC_Bd || + (mdoc->flags & MDOC_LITERAL) == 0) && + (np->tok != MDOC_It || np->type != ROFFT_HEAD || + np->parent->parent->norm->Bl.type != LIST_diag)) + check_text_em(mdoc, n->line, n->pos, n->string); + if (np->tok == MDOC_It || (np->type == ROFFT_BODY && + (np->tok == MDOC_Sh || np->tok == MDOC_Ss))) check_toptext(mdoc, n->line, n->pos, n->string); break; + case ROFFT_COMMENT: case ROFFT_EQN: case ROFFT_TBL: break; @@ -394,6 +401,57 @@ check_text(struct roff_man *mdoc, int ln, int pos, char *p) ln, pos + (int)(p - cp), NULL); } +static void +check_text_em(struct roff_man *mdoc, int ln, int pos, char *p) +{ + const struct roff_node *np, *nn; + char *cp; + + np = mdoc->last->prev; + nn = mdoc->last->next; + + /* Look for em-dashes wrongly encoded as "--". */ + + for (cp = p; *cp != '\0'; cp++) { + if (cp[0] != '-' || cp[1] != '-') + continue; + cp++; + + /* Skip input sequences of more than two '-'. */ + + if (cp[1] == '-') { + while (cp[1] == '-') + cp++; + continue; + } + + /* Skip "--" directly attached to something else. */ + + if ((cp - p > 1 && cp[-2] != ' ') || + (cp[1] != '\0' && cp[1] != ' ')) + continue; + + /* Require a letter right before or right afterwards. */ + + if ((cp - p > 2 ? + isalpha((unsigned char)cp[-3]) : + np != NULL && + np->type == ROFFT_TEXT && + *np->string != '\0' && + isalpha((unsigned char)np->string[ + strlen(np->string) - 1])) || + (cp[1] != '\0' && cp[2] != '\0' ? + isalpha((unsigned char)cp[2]) : + nn != NULL && + nn->type == ROFFT_TEXT && + isalpha((unsigned char)*nn->string))) { + mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse, + ln, pos + (int)(cp - p) - 1, NULL); + break; + } + } +} + static void check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p) { @@ -530,8 +588,7 @@ post_delim_nb(POST_ARGS) /* At least three alphabetic words with a sentence ending. */ if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em || - tok == MDOC_Li || tok == MDOC_Po || tok == MDOC_Pq || - tok == MDOC_Sy)) { + tok == MDOC_Li || tok == MDOC_Pq || tok == MDOC_Sy)) { nw = 0; for (cp = lc - 1; cp >= nch->string; cp--) { if (*cp == ' ') { @@ -947,10 +1004,10 @@ post_lb(POST_ARGS) roff_word_alloc(mdoc, n->line, n->pos, "library"); mdoc->last->flags = NODE_NOSRC; - roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq"); + roff_word_alloc(mdoc, n->line, n->pos, "\\(lq"); mdoc->last->flags = NODE_DELIMO | NODE_NOSRC; mdoc->last = mdoc->last->next; - roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq"); + roff_word_alloc(mdoc, n->line, n->pos, "\\(rq"); mdoc->last->flags = NODE_DELIMC | NODE_NOSRC; mdoc->last = n; } @@ -1914,7 +1971,10 @@ post_root(POST_ARGS) arch++; if (*arch == NULL) { n = mdoc->first->child; - while (n->tok != MDOC_Dt) + while (n->tok != MDOC_Dt || + n->child == NULL || + n->child->next == NULL || + n->child->next->next == NULL) n = n->next; n = n->child->next->next; mandoc_vmsg(MANDOCERR_ARCH_BAD, @@ -1928,8 +1988,10 @@ post_root(POST_ARGS) /* Check that we begin with a proper `Sh'. */ n = mdoc->first->child; - while (n != NULL && n->tok >= MDOC_Dd && - mdoc_macros[n->tok].flags & MDOC_PROLOGUE) + while (n != NULL && + (n->type == ROFFT_COMMENT || + (n->tok >= MDOC_Dd && + mdoc_macros[n->tok].flags & MDOC_PROLOGUE))) n = n->next; if (n == NULL) diff --git a/contrib/mdocml/msec.c b/contrib/mandoc/msec.c similarity index 100% rename from contrib/mdocml/msec.c rename to contrib/mandoc/msec.c diff --git a/contrib/mdocml/msec.in b/contrib/mandoc/msec.in similarity index 100% rename from contrib/mdocml/msec.in rename to contrib/mandoc/msec.in diff --git a/contrib/mdocml/out.c b/contrib/mandoc/out.c similarity index 100% rename from contrib/mdocml/out.c rename to contrib/mandoc/out.c diff --git a/contrib/mdocml/out.h b/contrib/mandoc/out.h similarity index 92% rename from contrib/mdocml/out.h rename to contrib/mandoc/out.h index f6aceb9c13f4..9f0a541d5dfd 100644 --- a/contrib/mdocml/out.h +++ b/contrib/mandoc/out.h @@ -1,4 +1,4 @@ -/* $Id: out.h,v 1.31 2017/06/27 18:25:02 schwarze Exp $ */ +/* $Id: out.h,v 1.32 2018/06/25 16:54:59 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -54,11 +54,6 @@ struct rofftbl { void *arg; /* passed to sulen, slen, and len */ }; -#define SCALE_VS_INIT(p, v) \ - do { (p)->unit = SCALE_VS; \ - (p)->scale = (v); } \ - while (/* CONSTCOND */ 0) - #define SCALE_HS_INIT(p, v) \ do { (p)->unit = SCALE_EN; \ (p)->scale = (v); } \ diff --git a/contrib/mdocml/preconv.c b/contrib/mandoc/preconv.c similarity index 100% rename from contrib/mdocml/preconv.c rename to contrib/mandoc/preconv.c diff --git a/contrib/mdocml/predefs.in b/contrib/mandoc/predefs.in similarity index 100% rename from contrib/mdocml/predefs.in rename to contrib/mandoc/predefs.in diff --git a/contrib/mdocml/read.c b/contrib/mandoc/read.c similarity index 95% rename from contrib/mdocml/read.c rename to contrib/mandoc/read.c index 1af1b2836383..0a583445f2cd 100644 --- a/contrib/mdocml/read.c +++ b/contrib/mandoc/read.c @@ -1,7 +1,7 @@ -/* $Id: read.c,v 1.192 2017/07/20 14:36:36 schwarze Exp $ */ +/* $Id: read.c,v 1.196 2018/07/28 18:34:15 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -94,9 +94,10 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "generic style suggestion", "legacy man(7) date format", + "normalizing date format to", "lower case character in document title", "duplicate RCS id", - "typo in section name", + "possible typo in section name", "unterminated quoted argument", "useless macro", "consider using OS macro", @@ -106,6 +107,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "no blank before trailing delimiter", "fill mode already enabled, skipping", "fill mode already disabled, skipping", + "verbatim \"--\", maybe consider using \\(em", "function name without markup", "whitespace at end of input line", "bad comment style", @@ -556,6 +558,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd, gzFile gz; size_t off; ssize_t ssz; + int gzerrnum, retval; if (fstat(fd, &st) == -1) { mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, @@ -583,9 +586,22 @@ read_whole_file(struct mparse *curp, const char *file, int fd, } if (curp->gzip) { + /* + * Duplicating the file descriptor is required + * because we will have to call gzclose(3) + * to free memory used internally by zlib, + * but that will also close the file descriptor, + * which this function must not do. + */ + if ((fd = dup(fd)) == -1) { + mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, + "dup: %s", strerror(errno)); + return 0; + } if ((gz = gzdopen(fd, "rb")) == NULL) { mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "gzdopen: %s", strerror(errno)); + close(fd); return 0; } } else @@ -598,6 +614,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd, *with_mmap = 0; off = 0; + retval = 0; fb->sz = 0; fb->buf = NULL; for (;;) { @@ -614,19 +631,29 @@ read_whole_file(struct mparse *curp, const char *file, int fd, read(fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; - return 1; + retval = 1; + break; } if (ssz == -1) { - mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, - "read: %s", strerror(errno)); + if (curp->gzip) + (void)gzerror(gz, &gzerrnum); + mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "read: %s", + curp->gzip && gzerrnum != Z_ERRNO ? + zError(gzerrnum) : strerror(errno)); break; } off += (size_t)ssz; } - free(fb->buf); - fb->buf = NULL; - return 0; + if (curp->gzip && (gzerrnum = gzclose(gz)) != Z_OK) + mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "gzclose: %s", + gzerrnum == Z_ERRNO ? strerror(errno) : + zError(gzerrnum)); + if (retval == 0) { + free(fb->buf); + fb->buf = NULL; + } + return retval; } static void diff --git a/contrib/mdocml/roff.7 b/contrib/mandoc/roff.7 similarity index 98% rename from contrib/mdocml/roff.7 rename to contrib/mandoc/roff.7 index 74780e9a7704..8cb922c70676 100644 --- a/contrib/mdocml/roff.7 +++ b/contrib/mandoc/roff.7 @@ -1,7 +1,7 @@ -.\" $Id: roff.7,v 1.94 2017/07/05 12:25:17 schwarze Exp $ +.\" $Id: roff.7,v 1.96 2018/04/10 00:52:30 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2010,2011,2013-2015,2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 5 2017 $ +.Dd $Mdocdate: April 10 2018 $ .Dt ROFF 7 .Os .Sh NAME @@ -1348,7 +1348,7 @@ Currently unsupported. .It Ic \&nop Ar body Execute the rest of the input line as a request or macro line. Currently unsupported. -.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression +.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression Op Ar stepsize Define or change a register. A register is an arbitrary string value that defines some sort of state, which influences parsing and/or formatting. @@ -1360,6 +1360,14 @@ below. If it is prefixed by a sign, the register will be incremented or decremented instead of assigned to. .Pp +The +.Ar stepsize +is used by the +.Ic \en+ +auto-increment feature. +It remains unchanged when omitted while changing an existing register, +and it defaults to 0 when defining a new register. +.Pp The following .Ar register is handled specially: @@ -1471,7 +1479,7 @@ This is a groff extension and currently ignored. .It Ic \&rchar Ar glyph ... Remove glyph definitions. Currently unsupported. -.It Ic \&rd Op Ar prompt Op Ar agument ... +.It Ic \&rd Op Ar prompt Op Ar argument ... Read from standard input. Currently ignored. .It Ic \&recursionlimit Ar maxrec maxtail @@ -1996,13 +2004,19 @@ and Character .Ar number on the current font. -.Ss \en Ns Bq Ar name +.Ss \en Ns Oo +|- Oc Ns Bq Ar name Interpolate the number register .Ar name . For short names, there are variants .No \en Ns Ar c and .No \en( Ns Ar cc . +If the optional sign is specified, +the register is first incremented or decremented by the +.Ar stepsize +that was specified in the relevant +.Ic \&nr +request, and the changed value is interpolated. .Ss \eo\(aq Ns Ar string Ns \(aq Overstrike, writing all the characters contained in the .Ar string diff --git a/contrib/mdocml/roff.c b/contrib/mandoc/roff.c similarity index 95% rename from contrib/mdocml/roff.c rename to contrib/mandoc/roff.c index e2e498da0ce4..86e145e36685 100644 --- a/contrib/mdocml/roff.c +++ b/contrib/mandoc/roff.c @@ -1,7 +1,7 @@ -/* $Id: roff.c,v 1.324 2017/07/14 17:16:16 schwarze Exp $ */ +/* $Id: roff.c,v 1.329 2018/08/01 15:40:17 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,6 +46,7 @@ #define ROFFDEF_STD (1 << 4) /* mdoc(7) or man(7) macro. */ #define ROFFDEF_ANY (ROFFDEF_USER | ROFFDEF_PRE | \ ROFFDEF_REN | ROFFDEF_STD) +#define ROFFDEF_UNDEF (1 << 5) /* Completely undefined. */ /* --- data types --------------------------------------------------------- */ @@ -72,6 +73,7 @@ struct roffkv { struct roffreg { struct roffstr key; int val; + int step; struct roffreg *next; }; @@ -181,11 +183,11 @@ static void roff_freestr(struct roffkv *); static size_t roff_getname(struct roff *, char **, int, int); static int roff_getnum(const char *, int *, int *, int); static int roff_getop(const char *, int *, char *); -static int roff_getregn(const struct roff *, - const char *, size_t); +static int roff_getregn(struct roff *, + const char *, size_t, char); static int roff_getregro(const struct roff *, const char *name); -static const char *roff_getstrn(const struct roff *, +static const char *roff_getstrn(struct roff *, const char *, size_t, int *); static int roff_hasregn(const struct roff *, const char *, size_t); @@ -206,6 +208,8 @@ static enum rofferr roff_res(struct roff *, struct buf *, int, int); static enum rofferr roff_rm(ROFF_ARGS); static enum rofferr roff_rn(ROFF_ARGS); static enum rofferr roff_rr(ROFF_ARGS); +static void roff_setregn(struct roff *, const char *, + size_t, int, char, int); static void roff_setstr(struct roff *, const char *, const char *, int); static void roff_setstrn(struct roffkv **, const char *, @@ -758,7 +762,7 @@ roff_alloc(struct mparse *parse, int options) r = mandoc_calloc(1, sizeof(struct roff)); r->parse = parse; - r->reqtab = roffhash_alloc(0, ROFF_USERDEF); + r->reqtab = roffhash_alloc(0, ROFF_RENAMED); r->options = options; r->format = options & (MPARSE_MDOC | MPARSE_MAN); r->rstackpos = -1; @@ -1118,8 +1122,10 @@ static enum rofferr roff_res(struct roff *r, struct buf *buf, int ln, int pos) { char ubuf[24]; /* buffer to print the number */ + struct roff_node *n; /* used for header comments */ const char *start; /* start of the string to process */ char *stesc; /* start of an escape sequence ('\\') */ + char *ep; /* end of comment string */ const char *stnam; /* start of the name, after "[(*" */ const char *cp; /* end of the name, e.g. before ']' */ const char *res; /* the string to be substituted */ @@ -1134,6 +1140,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) int done; /* no more input available */ int deftype; /* type of definition to paste */ int rcsid; /* kind of RCS id seen */ + char sign; /* increment number register */ char term; /* character terminating the escape */ /* Search forward for comments. */ @@ -1168,14 +1175,35 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) /* Handle trailing whitespace. */ - cp = strchr(stesc--, '\0') - 1; - if (*cp == '\n') { + ep = strchr(stesc--, '\0') - 1; + if (*ep == '\n') { done = 1; - cp--; + ep--; } - if (*cp == ' ' || *cp == '\t') + if (*ep == ' ' || *ep == '\t') mandoc_msg(MANDOCERR_SPACE_EOL, r->parse, - ln, cp - buf->buf, NULL); + ln, ep - buf->buf, NULL); + + /* + * Save comments preceding the title macro + * in the syntax tree. + */ + + if (r->format == 0) { + while (*ep == ' ' || *ep == '\t') + ep--; + ep[1] = '\0'; + n = roff_node_alloc(r->man, + ln, stesc + 1 - buf->buf, + ROFFT_COMMENT, TOKEN_NONE); + n->string = mandoc_strdup(stesc + 2); + roff_node_append(r->man, n); + n->flags |= NODE_VALID | NODE_ENDED; + r->man->next = ROFF_NEXT_SIBLING; + } + + /* Discard comments. */ + while (stesc > start && stesc[-1] == ' ') stesc--; *stesc = '\0'; @@ -1244,6 +1272,9 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) term = cp[1]; /* FALLTHROUGH */ case 'n': + sign = cp[1]; + if (sign == '+' || sign == '-') + cp++; res = ubuf; break; default: @@ -1348,7 +1379,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) case 'n': if (arg_complete) (void)snprintf(ubuf, sizeof(ubuf), "%d", - roff_getregn(r, stnam, naml)); + roff_getregn(r, stnam, naml, sign)); else ubuf[0] = '\0'; break; @@ -1639,6 +1670,11 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) } if (t != TOKEN_NONE) *pos = cp - buf; + else if (deftype == ROFFDEF_UNDEF) { + /* Using an undefined macro defines it to be empty. */ + roff_setstrn(&r->strtab, mac, maclen, "", 0, 0); + roff_setstrn(&r->rentab, mac, maclen, NULL, 0, 0); + } return t; } @@ -2514,21 +2550,30 @@ roff_evalnum(struct roff *r, int ln, const char *v, void roff_setreg(struct roff *r, const char *name, int val, char sign) +{ + roff_setregn(r, name, strlen(name), val, sign, INT_MIN); +} + +static void +roff_setregn(struct roff *r, const char *name, size_t len, + int val, char sign, int step) { struct roffreg *reg; /* Search for an existing register with the same name. */ reg = r->regtab; - while (reg && strcmp(name, reg->key.p)) + while (reg != NULL && (reg->key.sz != len || + strncmp(reg->key.p, name, len) != 0)) reg = reg->next; if (NULL == reg) { /* Create a new register. */ reg = mandoc_malloc(sizeof(struct roffreg)); - reg->key.p = mandoc_strdup(name); - reg->key.sz = strlen(name); + reg->key.p = mandoc_strndup(name, len); + reg->key.sz = len; reg->val = 0; + reg->step = 0; reg->next = r->regtab; r->regtab = reg; } @@ -2539,6 +2584,8 @@ roff_setreg(struct roff *r, const char *name, int val, char sign) reg->val -= val; else reg->val = val; + if (step != INT_MIN) + reg->step = step; } /* @@ -2572,26 +2619,13 @@ roff_getregro(const struct roff *r, const char *name) } int -roff_getreg(const struct roff *r, const char *name) +roff_getreg(struct roff *r, const char *name) { - struct roffreg *reg; - int val; - - if ('.' == name[0] && '\0' != name[1] && '\0' == name[2]) { - val = roff_getregro(r, name + 1); - if (-1 != val) - return val; - } - - for (reg = r->regtab; reg; reg = reg->next) - if (0 == strcmp(name, reg->key.p)) - return reg->val; - - return 0; + return roff_getregn(r, name, strlen(name), '\0'); } static int -roff_getregn(const struct roff *r, const char *name, size_t len) +roff_getregn(struct roff *r, const char *name, size_t len, char sign) { struct roffreg *reg; int val; @@ -2602,11 +2636,24 @@ roff_getregn(const struct roff *r, const char *name, size_t len) return val; } - for (reg = r->regtab; reg; reg = reg->next) + for (reg = r->regtab; reg; reg = reg->next) { if (len == reg->key.sz && - 0 == strncmp(name, reg->key.p, len)) + 0 == strncmp(name, reg->key.p, len)) { + switch (sign) { + case '+': + reg->val += reg->step; + break; + case '-': + reg->val -= reg->step; + break; + default: + break; + } return reg->val; + } + } + roff_setregn(r, name, len, 0, '\0', INT_MIN); return 0; } @@ -2646,9 +2693,9 @@ roff_freereg(struct roffreg *reg) static enum rofferr roff_nr(ROFF_ARGS) { - char *key, *val; + char *key, *val, *step; size_t keysz; - int iv; + int iv, is, len; char sign; key = val = buf->buf + pos; @@ -2658,15 +2705,22 @@ roff_nr(ROFF_ARGS) keysz = roff_getname(r, &val, ln, pos); if (key[keysz] == '\\') return ROFF_IGN; - key[keysz] = '\0'; sign = *val; if (sign == '+' || sign == '-') val++; - if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE)) - roff_setreg(r, key, iv, sign); + len = 0; + if (roff_evalnum(r, ln, val, &len, &iv, ROFFNUM_SCALE) == 0) + return ROFF_IGN; + step = val + len; + while (isspace((unsigned char)*step)) + step++; + if (roff_evalnum(r, ln, step, NULL, &is, 0) == 0) + is = INT_MIN; + + roff_setregn(r, key, keysz, iv, sign, is); return ROFF_IGN; } @@ -2791,6 +2845,7 @@ roff_TE(ROFF_ARGS) free(buf->buf); buf->buf = mandoc_strdup(".sp"); buf->sz = 4; + *offs = 0; return ROFF_REPARSE; } r->tbl = NULL; @@ -3310,6 +3365,7 @@ roff_userdef(ROFF_ARGS) ln, (int)(cp - n1), NULL); free(buf->buf); buf->buf = n1; + *offs = 0; return ROFF_IGN; } @@ -3404,6 +3460,7 @@ roff_renamed(ROFF_ARGS) buf->buf[pos] == '\0' ? "" : " ", buf->buf + pos) + 1; free(buf->buf); buf->buf = nbuf; + *offs = 0; return ROFF_CONT; } @@ -3537,62 +3594,95 @@ roff_setstrn(struct roffkv **r, const char *name, size_t namesz, } static const char * -roff_getstrn(const struct roff *r, const char *name, size_t len, +roff_getstrn(struct roff *r, const char *name, size_t len, int *deftype) { const struct roffkv *n; - int i; + int found, i; enum roff_tok tok; - if (*deftype & ROFFDEF_USER) { - for (n = r->strtab; n != NULL; n = n->next) { - if (strncmp(name, n->key.p, len) == 0 && - n->key.p[len] == '\0' && - n->val.p != NULL) { - *deftype = ROFFDEF_USER; - return n->val.p; + found = 0; + for (n = r->strtab; n != NULL; n = n->next) { + if (strncmp(name, n->key.p, len) != 0 || + n->key.p[len] != '\0' || n->val.p == NULL) + continue; + if (*deftype & ROFFDEF_USER) { + *deftype = ROFFDEF_USER; + return n->val.p; + } else { + found = 1; + break; + } + } + for (n = r->rentab; n != NULL; n = n->next) { + if (strncmp(name, n->key.p, len) != 0 || + n->key.p[len] != '\0' || n->val.p == NULL) + continue; + if (*deftype & ROFFDEF_REN) { + *deftype = ROFFDEF_REN; + return n->val.p; + } else { + found = 1; + break; + } + } + for (i = 0; i < PREDEFS_MAX; i++) { + if (strncmp(name, predefs[i].name, len) != 0 || + predefs[i].name[len] != '\0') + continue; + if (*deftype & ROFFDEF_PRE) { + *deftype = ROFFDEF_PRE; + return predefs[i].str; + } else { + found = 1; + break; + } + } + if (r->man->macroset != MACROSET_MAN) { + for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) { + if (strncmp(name, roff_name[tok], len) != 0 || + roff_name[tok][len] != '\0') + continue; + if (*deftype & ROFFDEF_STD) { + *deftype = ROFFDEF_STD; + return NULL; + } else { + found = 1; + break; } } } - if (*deftype & ROFFDEF_PRE) { - for (i = 0; i < PREDEFS_MAX; i++) { - if (strncmp(name, predefs[i].name, len) == 0 && - predefs[i].name[len] == '\0') { - *deftype = ROFFDEF_PRE; - return predefs[i].str; + if (r->man->macroset != MACROSET_MDOC) { + for (tok = MAN_TH; tok < MAN_MAX; tok++) { + if (strncmp(name, roff_name[tok], len) != 0 || + roff_name[tok][len] != '\0') + continue; + if (*deftype & ROFFDEF_STD) { + *deftype = ROFFDEF_STD; + return NULL; + } else { + found = 1; + break; } } } - if (*deftype & ROFFDEF_REN) { - for (n = r->rentab; n != NULL; n = n->next) { - if (strncmp(name, n->key.p, len) == 0 && - n->key.p[len] == '\0' && - n->val.p != NULL) { - *deftype = ROFFDEF_REN; - return n->val.p; - } - } - } - if (*deftype & ROFFDEF_STD) { - if (r->man->macroset != MACROSET_MAN) { - for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) { - if (strncmp(name, roff_name[tok], len) == 0 && - roff_name[tok][len] == '\0') { - *deftype = ROFFDEF_STD; - return NULL; - } - } - } - if (r->man->macroset != MACROSET_MDOC) { - for (tok = MAN_TH; tok < MAN_MAX; tok++) { - if (strncmp(name, roff_name[tok], len) == 0 && - roff_name[tok][len] == '\0') { - *deftype = ROFFDEF_STD; - return NULL; - } - } + + if (found == 0 && *deftype != ROFFDEF_ANY) { + if (*deftype & ROFFDEF_REN) { + /* + * This might still be a request, + * so do not treat it as undefined yet. + */ + *deftype = ROFFDEF_UNDEF; + return NULL; } + + /* Using an undefined string defines it to be empty. */ + + roff_setstrn(&r->strtab, name, len, "", 0, 0); + roff_setstrn(&r->rentab, name, len, NULL, 0, 0); } + *deftype = 0; return NULL; } diff --git a/contrib/mdocml/roff.h b/contrib/mandoc/roff.h similarity index 99% rename from contrib/mdocml/roff.h rename to contrib/mandoc/roff.h index 8b28d5960974..f0da74bd9ac6 100644 --- a/contrib/mdocml/roff.h +++ b/contrib/mandoc/roff.h @@ -1,4 +1,4 @@ -/* $Id: roff.h,v 1.58 2017/07/08 14:51:05 schwarze Exp $ */ +/* $Id: roff.h,v 1.59 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -61,6 +61,7 @@ enum roff_type { ROFFT_TAIL, ROFFT_ELEM, ROFFT_TEXT, + ROFFT_COMMENT, ROFFT_TBL, ROFFT_EQN }; diff --git a/contrib/mdocml/roff_html.c b/contrib/mandoc/roff_html.c similarity index 83% rename from contrib/mdocml/roff_html.c rename to contrib/mandoc/roff_html.c index 53ae6d7ca2d0..6a06c0d8789d 100644 --- a/contrib/mdocml/roff_html.c +++ b/contrib/mandoc/roff_html.c @@ -1,7 +1,7 @@ -/* $Id: roff_html.c,v 1.11 2017/06/24 14:38:33 schwarze Exp $ */ +/* $Id: roff_html.c,v 1.12 2018/06/25 14:53:58 schwarze Exp $ */ /* * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -82,15 +82,5 @@ roff_html_pre_ce(ROFF_HTML_ARGS) static void roff_html_pre_sp(ROFF_HTML_ARGS) { - struct roffsu su; - - SCALE_VS_INIT(&su, 1); - if ((n = n->child) != NULL) { - if (a2roffsu(n->string, &su, SCALE_VS) == NULL) - su.scale = 1.0; - else if (su.scale < 0.0) - su.scale = 0.0; - } - print_otag(h, TAG_DIV, "suh", &su); - print_text(h, "\\~"); /* So the div isn't empty. */ + print_paragraph(h); } diff --git a/contrib/mdocml/roff_int.h b/contrib/mandoc/roff_int.h similarity index 100% rename from contrib/mdocml/roff_int.h rename to contrib/mandoc/roff_int.h diff --git a/contrib/mdocml/roff_term.c b/contrib/mandoc/roff_term.c similarity index 100% rename from contrib/mdocml/roff_term.c rename to contrib/mandoc/roff_term.c diff --git a/contrib/mdocml/roff_validate.c b/contrib/mandoc/roff_validate.c similarity index 100% rename from contrib/mdocml/roff_validate.c rename to contrib/mandoc/roff_validate.c diff --git a/contrib/mdocml/soelim.1 b/contrib/mandoc/soelim.1 similarity index 100% rename from contrib/mdocml/soelim.1 rename to contrib/mandoc/soelim.1 diff --git a/contrib/mdocml/soelim.c b/contrib/mandoc/soelim.c similarity index 100% rename from contrib/mdocml/soelim.c rename to contrib/mandoc/soelim.c diff --git a/contrib/mdocml/st.c b/contrib/mandoc/st.c similarity index 100% rename from contrib/mdocml/st.c rename to contrib/mandoc/st.c diff --git a/contrib/mdocml/st.in b/contrib/mandoc/st.in similarity index 82% rename from contrib/mdocml/st.in rename to contrib/mandoc/st.in index 39f597cff31d..fefabdcf5894 100644 --- a/contrib/mdocml/st.in +++ b/contrib/mandoc/st.in @@ -1,4 +1,4 @@ -/* $Id: st.in,v 1.29 2017/06/24 13:49:29 schwarze Exp $ */ +/* $Id: st.in,v 1.30 2018/04/05 09:17:26 schwarze Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -60,19 +60,19 @@ LINE("-ansiC-89", "ANSI X3.159-1989 (\\(LqANSI\\~C89\\(Rq)") LINE("-ieee754", "IEEE Std 754-1985") LINE("-iso8802-3", "ISO 8802-3: 1989") LINE("-iso8601", "ISO 8601") -LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(LqOpen Firmware\\(Rq)") -LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(LqXPG3\\(Rq)") -LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(LqXPG4\\(Rq)") -LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(LqXPG4.2\\(Rq)") -LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(LqXBD5\\(Rq)") -LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(LqXCU5\\(Rq)") -LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(LqXSH4.2\\(Rq)") -LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(LqXSH5\\(Rq)") -LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(LqXNS5\\(Rq)") -LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(LqXNS5.2\\(Rq)") -LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(LqXCURSES4.2\\(Rq)") -LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(LqSUSv1\\(Rq)") -LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(LqSUSv2\\(Rq)") -LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(LqSUSv3\\(Rq)") -LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(LqSUSv4\\(Rq)") -LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(LqSVID4\\(Rq)") +LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)") +LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)") +LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)") +LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)") +LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)") +LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)") +LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)") +LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)") +LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)") +LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)") +LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)") +LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(lqSUSv1\\(rq)") +LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(lqSUSv2\\(rq)") +LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(lqSUSv3\\(rq)") +LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(lqSUSv4\\(rq)") +LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)") diff --git a/contrib/mdocml/tag.c b/contrib/mandoc/tag.c similarity index 98% rename from contrib/mdocml/tag.c rename to contrib/mandoc/tag.c index 21ac6b32e4d3..c0832c4f74b7 100644 --- a/contrib/mdocml/tag.c +++ b/contrib/mandoc/tag.c @@ -1,4 +1,4 @@ -/* $Id: tag.c,v 1.18 2017/02/17 14:31:52 schwarze Exp $ */ +/* $Id: tag.c,v 1.19 2018/02/23 16:47:10 schwarze Exp $ */ /* * Copyright (c) 2015, 2016 Ingo Schwarze <schwarze@openbsd.org> * @@ -213,6 +213,9 @@ tag_write(void) ohash_delete(&tag_data); if (stream != NULL) fclose(stream); + else + close(tag_files.tfd); + tag_files.tfd = -1; } void diff --git a/contrib/mdocml/tag.h b/contrib/mandoc/tag.h similarity index 100% rename from contrib/mdocml/tag.h rename to contrib/mandoc/tag.h diff --git a/contrib/mdocml/tbl.3 b/contrib/mandoc/tbl.3 similarity index 100% rename from contrib/mdocml/tbl.3 rename to contrib/mandoc/tbl.3 diff --git a/contrib/mdocml/tbl.7 b/contrib/mandoc/tbl.7 similarity index 98% rename from contrib/mdocml/tbl.7 rename to contrib/mandoc/tbl.7 index e2f84538370b..3883b40904ee 100644 --- a/contrib/mdocml/tbl.7 +++ b/contrib/mandoc/tbl.7 @@ -1,4 +1,4 @@ -.\" $Id: tbl.7,v 1.28 2017/06/28 00:59:57 schwarze Exp $ +.\" $Id: tbl.7,v 1.29 2017/10/17 23:19:12 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 28 2017 $ +.Dd $Mdocdate: October 17 2017 $ .Dt TBL 7 .Os .Sh NAME @@ -420,7 +420,9 @@ The GNU reimplementation of tbl, part of the groff package, was released in 1990 by James Clark. A standalone tbl implementation was written by Kristaps Dzonsons in 2010. -This formed the basis of the implementation that is part of the +This formed the basis of the implementation that first appeared in +.Ox 4.9 +as a part of the .Xr mandoc 1 utility. .Sh AUTHORS diff --git a/contrib/mdocml/tbl.c b/contrib/mandoc/tbl.c similarity index 100% rename from contrib/mdocml/tbl.c rename to contrib/mandoc/tbl.c diff --git a/contrib/mdocml/tbl_data.c b/contrib/mandoc/tbl_data.c similarity index 100% rename from contrib/mdocml/tbl_data.c rename to contrib/mandoc/tbl_data.c diff --git a/contrib/mdocml/tbl_html.c b/contrib/mandoc/tbl_html.c similarity index 93% rename from contrib/mdocml/tbl_html.c rename to contrib/mandoc/tbl_html.c index d59f1635d013..b87804fda354 100644 --- a/contrib/mdocml/tbl_html.c +++ b/contrib/mandoc/tbl_html.c @@ -1,4 +1,4 @@ -/* $Id: tbl_html.c,v 1.23 2017/07/31 16:14:10 schwarze Exp $ */ +/* $Id: tbl_html.c,v 1.24 2018/06/25 13:45:57 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -79,23 +79,14 @@ html_tbl_sulen(const struct roffsu *su, void *arg) static void html_tblopen(struct html *h, const struct tbl_span *sp) { - struct tag *t; - int ic; - if (h->tbl.cols == NULL) { h->tbl.len = html_tbl_len; h->tbl.slen = html_tbl_strlen; h->tbl.sulen = html_tbl_sulen; tblcalc(&h->tbl, sp, 0, 0); } - assert(NULL == h->tblt); h->tblt = print_otag(h, TAG_TABLE, "c", "tbl"); - - t = print_otag(h, TAG_COLGROUP, ""); - for (ic = 0; ic < sp->opts->cols; ic++) - print_otag(h, TAG_COL, "shw", h->tbl.cols[ic].width); - print_tagq(h, t); } void diff --git a/contrib/mdocml/tbl_layout.c b/contrib/mandoc/tbl_layout.c similarity index 100% rename from contrib/mdocml/tbl_layout.c rename to contrib/mandoc/tbl_layout.c diff --git a/contrib/mdocml/tbl_opts.c b/contrib/mandoc/tbl_opts.c similarity index 100% rename from contrib/mdocml/tbl_opts.c rename to contrib/mandoc/tbl_opts.c diff --git a/contrib/mdocml/tbl_term.c b/contrib/mandoc/tbl_term.c similarity index 100% rename from contrib/mdocml/tbl_term.c rename to contrib/mandoc/tbl_term.c diff --git a/contrib/mdocml/term.c b/contrib/mandoc/term.c similarity index 100% rename from contrib/mdocml/term.c rename to contrib/mandoc/term.c diff --git a/contrib/mdocml/term.h b/contrib/mandoc/term.h similarity index 100% rename from contrib/mdocml/term.h rename to contrib/mandoc/term.h diff --git a/contrib/mdocml/term_ascii.c b/contrib/mandoc/term_ascii.c similarity index 91% rename from contrib/mdocml/term_ascii.c rename to contrib/mandoc/term_ascii.c index e819c0ef8a86..f47ffd75d9c3 100644 --- a/contrib/mdocml/term_ascii.c +++ b/contrib/mandoc/term_ascii.c @@ -1,7 +1,7 @@ -/* $Id: term_ascii.c,v 1.58 2017/06/14 14:24:20 schwarze Exp $ */ +/* $Id: term_ascii.c,v 1.61 2018/05/20 21:37:34 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,11 +21,13 @@ #include <assert.h> #if HAVE_WCHAR +#include <langinfo.h> #include <locale.h> #endif #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #if HAVE_WCHAR #include <wchar.h> @@ -100,7 +102,17 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) v = TERMENC_LOCALE == enc ? setlocale(LC_CTYPE, "") : setlocale(LC_CTYPE, UTF8_LOCALE); - if (NULL != v && MB_CUR_MAX > 1) { + + /* + * We only support UTF-8, + * so revert to ASCII for anything else. + */ + + if (v != NULL && + strcmp(nl_langinfo(CODESET), "UTF-8") != 0) + v = setlocale(LC_CTYPE, "C"); + + if (v != NULL && MB_CUR_MAX > 1) { p->enc = enc; p->advance = locale_advance; p->endline = locale_endline; @@ -121,6 +133,8 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) if (outopts->synopsisonly) p->synopsisonly = 1; + assert(p->defindent < UINT16_MAX); + assert(p->defrmargin < UINT16_MAX); return p; } @@ -159,6 +173,8 @@ ascii_setwidth(struct termp *p, int iop, int width) p->defrmargin -= width; else p->defrmargin = 0; + if (p->defrmargin > 1000) + p->defrmargin = 1000; p->lastrmargin = p->tcol->rmargin; p->tcol->rmargin = p->maxrmargin = p->defrmargin; } @@ -227,6 +243,7 @@ ascii_advance(struct termp *p, size_t len) { size_t i; + assert(len < UINT16_MAX); for (i = 0; i < len; i++) putchar(' '); } @@ -294,17 +311,17 @@ ascii_uc2str(int uc) "<88>", "<89>", "<8A>", "<8B>", "<8C>", "<8D>", "<8E>", "<8F>", "<90>", "<91>", "<92>", "<93>", "<94>", "<95>", "<96>", "<97>", "<98>", "<99>", "<9A>", "<9B>", "<9C>", "<9D>", "<9E>", "<9F>", - nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<sec>", + nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<section>", "\"", "(C)", "_\ba", "<<", "~", "", "(R)", "-", - "<deg>","+-", "2", "3", "'", ",\bu", "<par>",".", - ",", "1", "_\bo", ">>", "1/4", "1/2", "3/4", "?", + "<degree>","+-","^2", "^3", "'","<micro>","<paragraph>",".", + ",", "^1", "_\bo", ">>", "1/4", "1/2", "3/4", "?", "`\bA", "'\bA", "^\bA", "~\bA", "\"\bA","o\bA", "AE", ",\bC", "`\bE", "'\bE", "^\bE", "\"\bE","`\bI", "'\bI", "^\bI", "\"\bI", - "-\bD", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x", + "Dh", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x", "/\bO", "`\bU", "'\bU", "^\bU", "\"\bU","'\bY", "Th", "ss", "`\ba", "'\ba", "^\ba", "~\ba", "\"\ba","o\ba", "ae", ",\bc", "`\be", "'\be", "^\be", "\"\be","`\bi", "'\bi", "^\bi", "\"\bi", - "d", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","-:-", + "dh", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","/", "/\bo", "`\bu", "'\bu", "^\bu", "\"\bu","'\by", "th", "\"\by", "A", "a", "A", "a", "A", "a", "'\bC", "'\bc", "^\bC", "^\bc", "C", "c", "C", "c", "D", "d", @@ -364,6 +381,7 @@ locale_advance(struct termp *p, size_t len) { size_t i; + assert(len < UINT16_MAX); for (i = 0; i < len; i++) putwchar(L' '); } diff --git a/contrib/mdocml/term_ps.c b/contrib/mandoc/term_ps.c similarity index 89% rename from contrib/mdocml/term_ps.c rename to contrib/mandoc/term_ps.c index 9638ae4cb9a3..2cd94c923156 100644 --- a/contrib/mdocml/term_ps.c +++ b/contrib/mandoc/term_ps.c @@ -1,7 +1,8 @@ -/* $Id: term_ps.c,v 1.85 2017/06/07 17:38:26 schwarze Exp $ */ +/* $Id: term_ps.c,v 1.91 2017/11/10 23:42:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2017 Marc Espie <espie@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -66,6 +67,7 @@ struct termp_ps { size_t pscol; /* visible column (AFM units) */ size_t pscolnext; /* used for overstrike */ size_t psrow; /* visible row (AFM units) */ + size_t lastrow; /* psrow of the previous word */ char *psmarg; /* margin buf */ size_t psmargsz; /* margin buf size */ size_t psmargcur; /* cur index in margin buf */ @@ -77,6 +79,7 @@ struct termp_ps { size_t lineheight; /* line height (AFM units) */ size_t top; /* body top (AFM units) */ size_t bottom; /* body bottom (AFM units) */ + const char *medianame; /* for DocumentMedia and PageSize */ size_t height; /* page height (AFM units */ size_t width; /* page width (AFM units) */ size_t lastwidth; /* page width before last ll */ @@ -108,7 +111,7 @@ static void ps_printf(struct termp *, const char *, ...) static void ps_putchar(struct termp *, char); static void ps_setfont(struct termp *, enum termfont); static void ps_setwidth(struct termp *, int, int); -static struct termp *pspdf_alloc(const struct manoutput *); +static struct termp *pspdf_alloc(const struct manoutput *, enum termtype); static void pdf_obj(struct termp *, size_t); /* @@ -511,27 +514,17 @@ static const struct font fonts[TERMFONT__MAX] = { void * pdf_alloc(const struct manoutput *outopts) { - struct termp *p; - - if (NULL != (p = pspdf_alloc(outopts))) - p->type = TERMTYPE_PDF; - - return p; + return pspdf_alloc(outopts, TERMTYPE_PDF); } void * ps_alloc(const struct manoutput *outopts) { - struct termp *p; - - if (NULL != (p = pspdf_alloc(outopts))) - p->type = TERMTYPE_PS; - - return p; + return pspdf_alloc(outopts, TERMTYPE_PS); } static struct termp * -pspdf_alloc(const struct manoutput *outopts) +pspdf_alloc(const struct manoutput *outopts, enum termtype type) { struct termp *p; unsigned int pagex, pagey; @@ -541,6 +534,7 @@ pspdf_alloc(const struct manoutput *outopts) p = mandoc_calloc(1, sizeof(*p)); p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol)); p->maxtcol = 1; + p->type = type; p->enc = TERMENC_ASCII; p->fontq = mandoc_reallocarray(NULL, @@ -559,6 +553,7 @@ pspdf_alloc(const struct manoutput *outopts) /* Default to US letter (millimetres). */ + p->ps->medianame = "Letter"; pagex = 216; pagey = 279; @@ -570,20 +565,26 @@ pspdf_alloc(const struct manoutput *outopts) */ pp = outopts->paper; - if (pp && strcasecmp(pp, "letter")) { - if (0 == strcasecmp(pp, "a3")) { + if (pp != NULL && strcasecmp(pp, "letter") != 0) { + if (strcasecmp(pp, "a3") == 0) { + p->ps->medianame = "A3"; pagex = 297; pagey = 420; - } else if (0 == strcasecmp(pp, "a4")) { + } else if (strcasecmp(pp, "a4") == 0) { + p->ps->medianame = "A4"; pagex = 210; pagey = 297; - } else if (0 == strcasecmp(pp, "a5")) { + } else if (strcasecmp(pp, "a5") == 0) { + p->ps->medianame = "A5"; pagex = 148; pagey = 210; - } else if (0 == strcasecmp(pp, "legal")) { + } else if (strcasecmp(pp, "legal") == 0) { + p->ps->medianame = "Legal"; pagex = 216; pagey = 356; - } else if (2 != sscanf(pp, "%ux%u", &pagex, &pagey)) + } else if (sscanf(pp, "%ux%u", &pagex, &pagey) == 2) + p->ps->medianame = "CustomSize"; + else warnx("%s: Unknown paper", pp); } @@ -596,8 +597,8 @@ pspdf_alloc(const struct manoutput *outopts) /* Remember millimetres -> AFM units. */ - pagex = PNT2AFM(p, ((double)pagex * 2.834)); - pagey = PNT2AFM(p, ((double)pagey * 2.834)); + pagex = PNT2AFM(p, ((double)pagex * 72.0 / 25.4)); + pagey = PNT2AFM(p, ((double)pagey * 72.0 / 25.4)); /* Margins are 1/9 the page x and y. */ @@ -733,7 +734,7 @@ ps_closepage(struct termp *p) /* * Close out a page that we've already flushed to output. In - * PostScript, we simply note that the page must be showed. In + * PostScript, we simply note that the page must be shown. In * PDF, we must now create the Length, Resource, and Page node * for the page contents. */ @@ -742,8 +743,6 @@ ps_closepage(struct termp *p) ps_printf(p, "%s", p->ps->psmarg); if (TERMTYPE_PS != p->type) { - ps_printf(p, "ET\n"); - len = p->ps->pdfbytes - p->ps->pdflastpg; base = p->ps->pages * 4 + p->ps->pdfbody; @@ -759,7 +758,7 @@ ps_closepage(struct termp *p) ps_printf(p, "/Font <<\n"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, "/F%d %d 0 R\n", i, 3 + i); - ps_printf(p, ">>\n>>\n"); + ps_printf(p, ">>\n>>\nendobj\n"); /* Page node. */ pdf_obj(p, base + 3); @@ -824,7 +823,7 @@ ps_end(struct termp *p) ps_printf(p, "<<\n"); ps_printf(p, "/Type /Catalog\n"); ps_printf(p, "/Pages 2 0 R\n"); - ps_printf(p, ">>\n"); + ps_printf(p, ">>\nendobj\n"); xref = p->ps->pdfbytes; ps_printf(p, "xref\n"); ps_printf(p, "0 %zu\n", base + 1); @@ -848,6 +847,7 @@ ps_end(struct termp *p) static void ps_begin(struct termp *p) { + size_t width, height; int i; /* @@ -865,6 +865,7 @@ ps_begin(struct termp *p) p->ps->flags = PS_MARGINS; p->ps->pscol = p->ps->left; p->ps->psrow = p->ps->header; + p->ps->lastrow = 0; /* impossible row */ ps_setfont(p, TERMFONT_NONE); @@ -889,21 +890,44 @@ ps_begin(struct termp *p) */ if (TERMTYPE_PS == p->type) { + width = AFM2PNT(p, p->ps->width); + height = AFM2PNT(p, p->ps->height); + ps_printf(p, "%%!PS-Adobe-3.0\n"); ps_printf(p, "%%%%DocumentData: Clean7Bit\n"); ps_printf(p, "%%%%Orientation: Portrait\n"); ps_printf(p, "%%%%Pages: (atend)\n"); ps_printf(p, "%%%%PageOrder: Ascend\n"); - ps_printf(p, "%%%%DocumentMedia: " - "Default %zu %zu 0 () ()\n", - (size_t)AFM2PNT(p, p->ps->width), - (size_t)AFM2PNT(p, p->ps->height)); + ps_printf(p, "%%%%DocumentMedia: man-%s %zu %zu 0 () ()\n", + p->ps->medianame, width, height); ps_printf(p, "%%%%DocumentNeededResources: font"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, " %s", fonts[i].name); - ps_printf(p, "\n%%%%EndComments\n"); + ps_printf(p, "\n%%%%DocumentSuppliedResources: " + "procset MandocProcs 1.0 0\n"); + ps_printf(p, "%%%%EndComments\n"); + ps_printf(p, "%%%%BeginProlog\n"); + ps_printf(p, "%%%%BeginResource: procset MandocProcs " + "10170 10170\n"); + /* The font size is effectively hard-coded for now. */ + ps_printf(p, "/fs %zu def\n", p->ps->scale); + for (i = 0; i < (int)TERMFONT__MAX; i++) + ps_printf(p, "/f%d { /%s fs selectfont } def\n", + i, fonts[i].name); + ps_printf(p, "/s { 3 1 roll moveto show } bind def\n"); + ps_printf(p, "/c { exch currentpoint exch pop " + "moveto show } bind def\n"); + ps_printf(p, "%%%%EndResource\n"); + ps_printf(p, "%%%%EndProlog\n"); + ps_printf(p, "%%%%BeginSetup\n"); + ps_printf(p, "%%%%BeginFeature: *PageSize %s\n", + p->ps->medianame); + ps_printf(p, "<</PageSize [%zu %zu]>>setpagedevice\n", + width, height); + ps_printf(p, "%%%%EndFeature\n"); + ps_printf(p, "%%%%EndSetup\n"); } else { ps_printf(p, "%%PDF-1.1\n"); pdf_obj(p, 1); @@ -918,7 +942,7 @@ ps_begin(struct termp *p) ps_printf(p, "/Subtype /Type1\n"); ps_printf(p, "/Name /F%d\n", i); ps_printf(p, "/BaseFont /%s\n", fonts[i].name); - ps_printf(p, ">>\n"); + ps_printf(p, ">>\nendobj\n"); } } @@ -943,9 +967,7 @@ ps_pletter(struct termp *p, int c) if (TERMTYPE_PS == p->type) { ps_printf(p, "%%%%Page: %zu %zu\n", p->ps->pages + 1, p->ps->pages + 1); - ps_printf(p, "/%s %zu selectfont\n", - fonts[(int)p->ps->lastf].name, - p->ps->scale); + ps_printf(p, "f%d\n", (int)p->ps->lastf); } else { pdf_obj(p, p->ps->pdfbody + p->ps->pages * 4); @@ -970,10 +992,13 @@ ps_pletter(struct termp *p, int c) ps_printf(p, "%.3f %.3f Td\n(", AFM2PNT(p, p->ps->pscol), AFM2PNT(p, p->ps->psrow)); - } else - ps_printf(p, "%.3f %.3f moveto\n(", - AFM2PNT(p, p->ps->pscol), - AFM2PNT(p, p->ps->psrow)); + } else { + ps_printf(p, "%.3f", AFM2PNT(p, p->ps->pscol)); + if (p->ps->psrow != p->ps->lastrow) + ps_printf(p, " %.3f", + AFM2PNT(p, p->ps->psrow)); + ps_printf(p, "("); + } p->ps->flags |= PS_INLINE; } @@ -1021,10 +1046,14 @@ ps_pclose(struct termp *p) if ( ! (PS_INLINE & p->ps->flags)) return; - if (TERMTYPE_PS != p->type) { + if (TERMTYPE_PS != p->type) ps_printf(p, ") Tj\nET\n"); - } else - ps_printf(p, ") show\n"); + else if (p->ps->psrow == p->ps->lastrow) + ps_printf(p, ")c\n"); + else { + ps_printf(p, ")s\n"); + p->ps->lastrow = p->ps->psrow; + } p->ps->flags &= ~PS_INLINE; } @@ -1243,8 +1272,7 @@ ps_setfont(struct termp *p, enum termfont f) return; if (TERMTYPE_PS == p->type) - ps_printf(p, "/%s %zu selectfont\n", - fonts[(int)f].name, p->ps->scale); + ps_printf(p, "f%d\n", (int)f); else ps_printf(p, "/F%d %zu Tf\n", (int)f, p->ps->scale); diff --git a/contrib/mdocml/term_tab.c b/contrib/mandoc/term_tab.c similarity index 100% rename from contrib/mdocml/term_tab.c rename to contrib/mandoc/term_tab.c diff --git a/contrib/mdocml/test-EFTYPE.c b/contrib/mandoc/test-EFTYPE.c similarity index 100% rename from contrib/mdocml/test-EFTYPE.c rename to contrib/mandoc/test-EFTYPE.c diff --git a/contrib/mdocml/test-O_DIRECTORY.c b/contrib/mandoc/test-O_DIRECTORY.c similarity index 100% rename from contrib/mdocml/test-O_DIRECTORY.c rename to contrib/mandoc/test-O_DIRECTORY.c diff --git a/contrib/mdocml/test-PATH_MAX.c b/contrib/mandoc/test-PATH_MAX.c similarity index 100% rename from contrib/mdocml/test-PATH_MAX.c rename to contrib/mandoc/test-PATH_MAX.c diff --git a/contrib/mdocml/test-be32toh.c b/contrib/mandoc/test-be32toh.c similarity index 100% rename from contrib/mdocml/test-be32toh.c rename to contrib/mandoc/test-be32toh.c diff --git a/contrib/mdocml/test-cmsg.c b/contrib/mandoc/test-cmsg.c similarity index 100% rename from contrib/mdocml/test-cmsg.c rename to contrib/mandoc/test-cmsg.c diff --git a/contrib/mdocml/test-dirent-namlen.c b/contrib/mandoc/test-dirent-namlen.c similarity index 100% rename from contrib/mdocml/test-dirent-namlen.c rename to contrib/mandoc/test-dirent-namlen.c diff --git a/contrib/mdocml/test-err.c b/contrib/mandoc/test-err.c similarity index 100% rename from contrib/mdocml/test-err.c rename to contrib/mandoc/test-err.c diff --git a/contrib/mdocml/test-fgetln.c b/contrib/mandoc/test-fgetln.c similarity index 100% rename from contrib/mdocml/test-fgetln.c rename to contrib/mandoc/test-fgetln.c diff --git a/contrib/mdocml/test-fts.c b/contrib/mandoc/test-fts.c similarity index 100% rename from contrib/mdocml/test-fts.c rename to contrib/mandoc/test-fts.c diff --git a/contrib/mdocml/test-getline.c b/contrib/mandoc/test-getline.c similarity index 100% rename from contrib/mdocml/test-getline.c rename to contrib/mandoc/test-getline.c diff --git a/contrib/mdocml/test-getsubopt.c b/contrib/mandoc/test-getsubopt.c similarity index 100% rename from contrib/mdocml/test-getsubopt.c rename to contrib/mandoc/test-getsubopt.c diff --git a/contrib/mdocml/test-isblank.c b/contrib/mandoc/test-isblank.c similarity index 100% rename from contrib/mdocml/test-isblank.c rename to contrib/mandoc/test-isblank.c diff --git a/contrib/mdocml/test-mkdtemp.c b/contrib/mandoc/test-mkdtemp.c similarity index 100% rename from contrib/mdocml/test-mkdtemp.c rename to contrib/mandoc/test-mkdtemp.c diff --git a/contrib/mdocml/test-nanosleep.c b/contrib/mandoc/test-nanosleep.c similarity index 100% rename from contrib/mdocml/test-nanosleep.c rename to contrib/mandoc/test-nanosleep.c diff --git a/contrib/mandoc/test-noop.c b/contrib/mandoc/test-noop.c new file mode 100644 index 000000000000..95485db80176 --- /dev/null +++ b/contrib/mandoc/test-noop.c @@ -0,0 +1,5 @@ +int +main(void) +{ + return 0; +} diff --git a/contrib/mdocml/test-ntohl.c b/contrib/mandoc/test-ntohl.c similarity index 100% rename from contrib/mdocml/test-ntohl.c rename to contrib/mandoc/test-ntohl.c diff --git a/contrib/mdocml/test-ohash.c b/contrib/mandoc/test-ohash.c similarity index 100% rename from contrib/mdocml/test-ohash.c rename to contrib/mandoc/test-ohash.c diff --git a/contrib/mdocml/test-pledge.c b/contrib/mandoc/test-pledge.c similarity index 100% rename from contrib/mdocml/test-pledge.c rename to contrib/mandoc/test-pledge.c diff --git a/contrib/mdocml/test-progname.c b/contrib/mandoc/test-progname.c similarity index 100% rename from contrib/mdocml/test-progname.c rename to contrib/mandoc/test-progname.c diff --git a/contrib/mdocml/test-reallocarray.c b/contrib/mandoc/test-reallocarray.c similarity index 100% rename from contrib/mdocml/test-reallocarray.c rename to contrib/mandoc/test-reallocarray.c diff --git a/contrib/mdocml/test-recallocarray.c b/contrib/mandoc/test-recallocarray.c similarity index 100% rename from contrib/mdocml/test-recallocarray.c rename to contrib/mandoc/test-recallocarray.c diff --git a/contrib/mdocml/test-recvmsg.c b/contrib/mandoc/test-recvmsg.c similarity index 100% rename from contrib/mdocml/test-recvmsg.c rename to contrib/mandoc/test-recvmsg.c diff --git a/contrib/mdocml/test-rewb-bsd.c b/contrib/mandoc/test-rewb-bsd.c similarity index 100% rename from contrib/mdocml/test-rewb-bsd.c rename to contrib/mandoc/test-rewb-bsd.c diff --git a/contrib/mdocml/test-rewb-sysv.c b/contrib/mandoc/test-rewb-sysv.c similarity index 100% rename from contrib/mdocml/test-rewb-sysv.c rename to contrib/mandoc/test-rewb-sysv.c diff --git a/contrib/mdocml/test-sandbox_init.c b/contrib/mandoc/test-sandbox_init.c similarity index 100% rename from contrib/mdocml/test-sandbox_init.c rename to contrib/mandoc/test-sandbox_init.c diff --git a/contrib/mdocml/test-strcasestr.c b/contrib/mandoc/test-strcasestr.c similarity index 100% rename from contrib/mdocml/test-strcasestr.c rename to contrib/mandoc/test-strcasestr.c diff --git a/contrib/mdocml/test-stringlist.c b/contrib/mandoc/test-stringlist.c similarity index 100% rename from contrib/mdocml/test-stringlist.c rename to contrib/mandoc/test-stringlist.c diff --git a/contrib/mdocml/test-strlcat.c b/contrib/mandoc/test-strlcat.c similarity index 100% rename from contrib/mdocml/test-strlcat.c rename to contrib/mandoc/test-strlcat.c diff --git a/contrib/mdocml/test-strlcpy.c b/contrib/mandoc/test-strlcpy.c similarity index 100% rename from contrib/mdocml/test-strlcpy.c rename to contrib/mandoc/test-strlcpy.c diff --git a/contrib/mandoc/test-strndup.c b/contrib/mandoc/test-strndup.c new file mode 100644 index 000000000000..82e4e547e097 --- /dev/null +++ b/contrib/mandoc/test-strndup.c @@ -0,0 +1,10 @@ +#include <string.h> + +int +main(void) +{ + char *s; + + s = strndup("123", 2); + return s[0] != '1' ? 1 : s[1] != '2' ? 2 : s[2] != '\0' ? 3 : 0; +} diff --git a/contrib/mdocml/test-strptime.c b/contrib/mandoc/test-strptime.c similarity index 100% rename from contrib/mdocml/test-strptime.c rename to contrib/mandoc/test-strptime.c diff --git a/contrib/mdocml/test-strsep.c b/contrib/mandoc/test-strsep.c similarity index 100% rename from contrib/mdocml/test-strsep.c rename to contrib/mandoc/test-strsep.c diff --git a/contrib/mdocml/test-strtonum.c b/contrib/mandoc/test-strtonum.c similarity index 100% rename from contrib/mdocml/test-strtonum.c rename to contrib/mandoc/test-strtonum.c diff --git a/contrib/mdocml/test-vasprintf.c b/contrib/mandoc/test-vasprintf.c similarity index 100% rename from contrib/mdocml/test-vasprintf.c rename to contrib/mandoc/test-vasprintf.c diff --git a/contrib/mdocml/test-wchar.c b/contrib/mandoc/test-wchar.c similarity index 100% rename from contrib/mdocml/test-wchar.c rename to contrib/mandoc/test-wchar.c diff --git a/contrib/mdocml/tree.c b/contrib/mandoc/tree.c similarity index 96% rename from contrib/mdocml/tree.c rename to contrib/mandoc/tree.c index 7d18b9d9e686..b9774e1cd8e1 100644 --- a/contrib/mdocml/tree.c +++ b/contrib/mandoc/tree.c @@ -1,7 +1,7 @@ -/* $Id: tree.c,v 1.77 2017/07/08 14:51:05 schwarze Exp $ */ +/* $Id: tree.c,v 1.78 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -115,6 +115,9 @@ print_mdoc(const struct roff_node *n, int indent) case ROFFT_TEXT: t = "text"; break; + case ROFFT_COMMENT: + t = "comment"; + break; case ROFFT_TBL: break; case ROFFT_EQN: @@ -126,6 +129,7 @@ print_mdoc(const struct roff_node *n, int indent) switch (n->type) { case ROFFT_TEXT: + case ROFFT_COMMENT: p = n->string; break; case ROFFT_BODY: @@ -231,6 +235,9 @@ print_man(const struct roff_node *n, int indent) case ROFFT_TEXT: t = "text"; break; + case ROFFT_COMMENT: + t = "comment"; + break; case ROFFT_BLOCK: t = "block"; break; @@ -251,6 +258,7 @@ print_man(const struct roff_node *n, int indent) switch (n->type) { case ROFFT_TEXT: + case ROFFT_COMMENT: p = n->string; break; case ROFFT_ELEM: diff --git a/contrib/mdocml/mandoc.css b/contrib/mdocml/mandoc.css deleted file mode 100644 index 2a57a18f9d69..000000000000 --- a/contrib/mdocml/mandoc.css +++ /dev/null @@ -1,203 +0,0 @@ -/* $Id: mandoc.css,v 1.22 2017/07/16 18:45:00 schwarze Exp $ */ -/* - * Standard style sheet for mandoc(1) -Thtml and man.cgi(8). - */ - -/* Global defaults. */ - -html { max-width: 100ex; } -body { font-family: Helvetica,Arial,sans-serif; } -table { margin-top: 0em; - margin-bottom: 0em; } -td { vertical-align: top; } -ul, ol, dl { margin-top: 0em; - margin-bottom: 0em; } -li, dt { margin-top: 1em; } - -a.selflink { border-bottom: thin dotted; - color: inherit; - font: inherit; - text-decoration: inherit; } -* { clear: both } - -/* Search form and search results. */ - -fieldset { border: thin solid silver; - border-radius: 1em; - text-align: center; } -input[name=expr] { - width: 25%; } - -table.results { margin-top: 1em; - margin-left: 2em; - font-size: smaller; } - -/* Header and footer lines. */ - -table.head { width: 100%; - border-bottom: 1px dotted #808080; - margin-bottom: 1em; - font-size: smaller; } -td.head-vol { text-align: center; } -td.head-rtitle { - text-align: right; } -span.Nd { } - -table.foot { width: 100%; - border-top: 1px dotted #808080; - margin-top: 1em; - font-size: smaller; } -td.foot-os { text-align: right; } - -/* Sections and paragraphs. */ - -div.manual-text { - margin-left: 5ex; } -h1.Sh { margin-top: 2ex; - margin-bottom: 1ex; - margin-left: -4ex; - font-size: 110%; } -h2.Ss { margin-top: 2ex; - margin-bottom: 1ex; - margin-left: -2ex; - font-size: 105%; } -div.Pp { margin: 1ex 0ex; } -a.Sx { } -a.Xr { } - -/* Displays and lists. */ - -div.Bd { } -div.D1 { margin-left: 5ex; } - -ul.Bl-bullet { list-style-type: disc; - padding-left: 1em; } -li.It-bullet { } -ul.Bl-dash { list-style-type: none; - padding-left: 0em; } -li.It-dash:before { - content: "\2014 "; } -ul.Bl-item { list-style-type: none; - padding-left: 0em; } -li.It-item { } -ul.Bl-compact > li { - margin-top: 0ex; } - -ol.Bl-enum { padding-left: 2em; } -li.It-enum { } -ol.Bl-compact > li { - margin-top: 0ex; } - -dl.Bl-diag { } -dt.It-diag { } -dd.It-diag { margin-left: 0ex; } -b.It-diag { font-style: normal; } -dl.Bl-hang { } -dt.It-hang { } -dd.It-hang { margin-left: 10.2ex; } -dl.Bl-inset { } -dt.It-inset { } -dd.It-inset { margin-left: 0ex; } -dl.Bl-ohang { } -dt.It-ohang { } -dd.It-ohang { margin-left: 0ex; } -dl.Bl-tag { margin-left: 10.2ex; } -dt.It-tag { float: left; - margin-top: 0ex; - margin-left: -10.2ex; - padding-right: 2ex; - vertical-align: top; } -dd.It-tag { clear: right; - width: 100%; - margin-top: 0ex; - margin-left: 0ex; - vertical-align: top; - overflow: auto; } -dl.Bl-compact > dt { - margin-top: 0ex; } - -table.Bl-column { } -tr.It-column { } -td.It-column { margin-top: 1em; } -table.Bl-compact > tbody > tr > td { - margin-top: 0ex; } - -cite.Rs { font-style: normal; - font-weight: normal; } -span.RsA { } -i.RsB { font-weight: normal; } -span.RsC { } -span.RsD { } -i.RsI { font-weight: normal; } -i.RsJ { font-weight: normal; } -span.RsN { } -span.RsO { } -span.RsP { } -span.RsQ { } -span.RsR { } -span.RsT { text-decoration: underline; } -a.RsU { } -span.RsV { } - -span.eqn { } -table.tbl { } - -/* Semantic markup for command line utilities. */ - -table.Nm { } -b.Nm { font-style: normal; } -b.Fl { font-style: normal; } -b.Cm { font-style: normal; } -var.Ar { font-style: italic; - font-weight: normal; } -span.Op { } -b.Ic { font-style: normal; } -code.Ev { font-style: normal; - font-weight: normal; - font-family: monospace; } -i.Pa { font-weight: normal; } - -/* Semantic markup for function libraries. */ - -span.Lb { } -b.In { font-style: normal; } -a.In { } -b.Fd { font-style: normal; } -var.Ft { font-style: italic; - font-weight: normal; } -b.Fn { font-style: normal; } -var.Fa { font-style: italic; - font-weight: normal; } -var.Vt { font-style: italic; - font-weight: normal; } -var.Va { font-style: italic; - font-weight: normal; } -code.Dv { font-style: normal; - font-weight: normal; - font-family: monospace; } -code.Er { font-style: normal; - font-weight: normal; - font-family: monospace; } - -/* Various semantic markup. */ - -span.An { } -a.Lk { } -a.Mt { } -b.Cd { font-style: normal; } -i.Ad { font-weight: normal; } -b.Ms { font-style: normal; } -span.St { } -a.Ux { } - -/* Physical markup. */ - -.No { font-style: normal; - font-weight: normal; } -.Em { font-style: italic; - font-weight: normal; } -.Sy { font-style: normal; - font-weight: bold; } -.Li { font-style: normal; - font-weight: normal; - font-family: monospace; } diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index e78a1366aaef..f79437034a4e 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -811,10 +811,10 @@ main(int ac, char **av) *options.version_addendum != '\0') fprintf(stderr, "%s %s, %s\n", SSH_RELEASE, options.version_addendum, - OPENSSL_VERSION); + OPENSSL_VERSION_STRING); else fprintf(stderr, "%s, %s\n", SSH_RELEASE, - OPENSSL_VERSION); + OPENSSL_VERSION_STRING); if (opt == 'V') exit(0); break; @@ -1078,7 +1078,7 @@ main(int ac, char **av) if (debug_flag) /* version_addendum is always NULL at this point */ - logit("%s, %s", SSH_RELEASE, OPENSSL_VERSION); + logit("%s, %s", SSH_RELEASE, OPENSSL_VERSION_STRING); /* Parse the configuration files */ process_config_files(host_arg, pw, 0); diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 7eb282316cff..23d31dd1aeff 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -939,10 +939,10 @@ usage(void) if (options.version_addendum && *options.version_addendum != '\0') fprintf(stderr, "%s %s, %s\n", SSH_RELEASE, - options.version_addendum, OPENSSL_VERSION); + options.version_addendum, OPENSSL_VERSION_STRING); else fprintf(stderr, "%s, %s\n", - SSH_RELEASE, OPENSSL_VERSION); + SSH_RELEASE, OPENSSL_VERSION_STRING); fprintf(stderr, "usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n" " [-E log_file] [-f config_file] [-g login_grace_time]\n" diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index c362549551e2..e2adeeec3f33 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -9,7 +9,7 @@ #define SSH_VERSION_FREEBSD "FreeBSD-20180909" #ifdef WITH_OPENSSL -#define OPENSSL_VERSION SSLeay_version(SSLEAY_VERSION) +#define OPENSSL_VERSION_STRING SSLeay_version(SSLEAY_VERSION) #else -#define OPENSSL_VERSION "without OpenSSL" +#define OPENSSL_VERSION_STRING "without OpenSSL" #endif diff --git a/etc/Makefile b/etc/Makefile index 91eaa0ca50fc..df8f99e4c3de 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -13,52 +13,18 @@ SUBDIR+=sendmail .endif BIN1= \ - dhclient.conf \ - disktab \ group \ - hosts.allow \ - libalias.conf \ - libmap.conf \ login.access \ - mac.conf \ - netconfig \ - phones \ rc.bsdextended \ rc.firewall \ - remote \ - rpc \ termcap.small # NB: keep these sorted by MK_* knobs -.if ${MK_AMD} != "no" -BIN1+= amd.map -.endif - -.if ${MK_LOCATE} != "no" -BIN1+= ${SRCTOP}/usr.bin/locate/locate/locate.rc -.endif - -.if ${MK_LPR} != "no" -BIN1+= hosts.lpd printcap -.endif - -.if ${MK_MAIL} != "no" -BIN1+= ${SRCTOP}/usr.bin/mail/misc/mail.rc -.endif - -.if ${MK_OPENSSL} != "no" -SSL= ${SRCTOP}/crypto/openssl/apps/openssl.cnf -.endif - .if ${MK_SENDMAIL} != "no" BIN1+= rc.sendmail .endif -.if ${MK_WIRELESS} != "no" -BIN1+= regdomain.xml -.endif - .if ${MK_SENDMAIL} == "no" ETCMAIL=mailer.conf aliases .else @@ -99,7 +65,7 @@ distribution: ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ ${BIN1} ${DESTDIR}/etc; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \ - master.passwd nsmb.conf opieaccess ${DESTDIR}/etc; + master.passwd ${DESTDIR}/etc; .if ${MK_TCSH} == "no" sed -i "" -e 's;/bin/csh;/bin/sh;' ${DESTDIR}/etc/master.passwd @@ -124,10 +90,6 @@ distribution: .if ${MK_SENDMAIL} != "no" ${_+_}cd ${.CURDIR}/sendmail; ${MAKE} distribution .endif -.if ${MK_OPENSSL} != "no" - cd ${.CURDIR}; ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ - ${SSL} ${DESTDIR}/etc/ssl -.endif .if ${MK_KERBEROS} != "no" cd ${.CURDIR}/root; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ @@ -235,7 +197,7 @@ distrib-dirs: ${MTREES:N/*} distrib-cleanup .PHONY etc-examples: ${META_DEPS} cd ${.CURDIR}; ${INSTALL} ${TAG_ARGS} -o ${BINOWN} -g ${BINGRP} -m 444 \ - ${BIN1} ${BIN2} nsmb.conf opieaccess \ + ${BIN1} ${BIN2} \ ${DESTDIR}${SHAREDIR}/examples/etc .include <bsd.prog.mk> diff --git a/etc/dhclient.conf b/etc/dhclient.conf deleted file mode 100644 index a7639d904aad..000000000000 --- a/etc/dhclient.conf +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ -# -# This file is required by the ISC DHCP client. -# See ``man 5 dhclient.conf'' for details. -# -# In most cases an empty file is sufficient for most people as the -# defaults are usually fine. -# diff --git a/gnu/usr.bin/binutils/as/config.h b/gnu/usr.bin/binutils/as/config.h index 9723ac77ece0..84cd51590e58 100644 --- a/gnu/usr.bin/binutils/as/config.h +++ b/gnu/usr.bin/binutils/as/config.h @@ -69,7 +69,7 @@ /* #undef HAVE_REMOVE */ /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the <stdarg.h> header file. */ #define HAVE_STDARG_H 1 diff --git a/gnu/usr.bin/binutils/ld/config.h b/gnu/usr.bin/binutils/ld/config.h index 42a7f778cf6c..ac9a78d729de 100644 --- a/gnu/usr.bin/binutils/ld/config.h +++ b/gnu/usr.bin/binutils/ld/config.h @@ -65,7 +65,7 @@ #define HAVE_REALPATH 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the <stdint.h> header file. */ #define HAVE_STDINT_H 1 diff --git a/gnu/usr.bin/binutils/libbinutils/config.h b/gnu/usr.bin/binutils/libbinutils/config.h index 873ae5b1e4b1..5c457f1eeaff 100644 --- a/gnu/usr.bin/binutils/libbinutils/config.h +++ b/gnu/usr.bin/binutils/libbinutils/config.h @@ -104,7 +104,7 @@ #define HAVE_MKSTEMP 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the `setmode' function. */ #define HAVE_SETMODE 1 diff --git a/gnu/usr.bin/binutils/libiberty/config.h b/gnu/usr.bin/binutils/libiberty/config.h index 2b00517fb17c..4361330c7f1f 100644 --- a/gnu/usr.bin/binutils/libiberty/config.h +++ b/gnu/usr.bin/binutils/libiberty/config.h @@ -188,7 +188,7 @@ #define HAVE_RINDEX 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/cc/libiberty/config.h b/gnu/usr.bin/cc/libiberty/config.h index 236e07689498..5a99758f8635 100644 --- a/gnu/usr.bin/cc/libiberty/config.h +++ b/gnu/usr.bin/cc/libiberty/config.h @@ -187,7 +187,7 @@ #define HAVE_RINDEX 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/amd64/config.h b/gnu/usr.bin/gdb/arch/amd64/config.h index 674f81854935..6908c793ece9 100644 --- a/gnu/usr.bin/gdb/arch/amd64/config.h +++ b/gnu/usr.bin/gdb/arch/amd64/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/arm/config.h b/gnu/usr.bin/gdb/arch/arm/config.h index b2481f8b2a0d..863f2d9c701b 100644 --- a/gnu/usr.bin/gdb/arch/arm/config.h +++ b/gnu/usr.bin/gdb/arch/arm/config.h @@ -239,7 +239,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/i386/config.h b/gnu/usr.bin/gdb/arch/i386/config.h index e849e0ad078d..3f7f579433d5 100644 --- a/gnu/usr.bin/gdb/arch/i386/config.h +++ b/gnu/usr.bin/gdb/arch/i386/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/mips/config.h b/gnu/usr.bin/gdb/arch/mips/config.h index 2b375a6f0cd2..c0b04cc5e550 100644 --- a/gnu/usr.bin/gdb/arch/mips/config.h +++ b/gnu/usr.bin/gdb/arch/mips/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/powerpc/config.h b/gnu/usr.bin/gdb/arch/powerpc/config.h index 37416a75593d..8686a99d1f56 100644 --- a/gnu/usr.bin/gdb/arch/powerpc/config.h +++ b/gnu/usr.bin/gdb/arch/powerpc/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/powerpc64/config.h b/gnu/usr.bin/gdb/arch/powerpc64/config.h index 58843fbb7417..6ec6560e4200 100644 --- a/gnu/usr.bin/gdb/arch/powerpc64/config.h +++ b/gnu/usr.bin/gdb/arch/powerpc64/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/sparc64/config.h b/gnu/usr.bin/gdb/arch/sparc64/config.h index 974e4264d201..8bcfdb28c8f5 100644 --- a/gnu/usr.bin/gdb/arch/sparc64/config.h +++ b/gnu/usr.bin/gdb/arch/sparc64/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/include/time.h b/include/time.h index 26e208ffa65b..cec901a1e8ba 100644 --- a/include/time.h +++ b/include/time.h @@ -207,9 +207,13 @@ time_t posix2time(time_t t); #include <xlocale/_time.h> #endif +#if defined(__BSD_VISIBLE) || __ISO_C_VISIBLE >= 2011 || \ + (defined(cplusplus) && cplusplus >= 201703) +#include <sys/_timespec.h> /* ISO/IEC 9899:201x 7.27.2.5 The timespec_get function */ #define TIME_UTC 1 /* time elapsed since epoch */ int timespec_get(struct timespec *ts, int base); +#endif __END_DECLS diff --git a/lib/lib80211/Makefile b/lib/lib80211/Makefile index fe103ce81cbd..54efe869b84a 100644 --- a/lib/lib80211/Makefile +++ b/lib/lib80211/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ +CONFS= regdomain.xml PACKAGE=lib${LIB} LIB= 80211 SHLIBDIR?= /lib diff --git a/etc/regdomain.xml b/lib/lib80211/regdomain.xml similarity index 100% rename from etc/regdomain.xml rename to lib/lib80211/regdomain.xml diff --git a/lib/libalias/libalias/Makefile b/lib/libalias/libalias/Makefile index 60c59a3ed313..bfbd523aa0b7 100644 --- a/lib/libalias/libalias/Makefile +++ b/lib/libalias/libalias/Makefile @@ -2,6 +2,7 @@ .PATH: ${SRCTOP}/sys/netinet/libalias +CONFS= libalias.conf PACKAGE=lib${LIB} LIB= alias SHLIBDIR?= /lib diff --git a/etc/libalias.conf b/lib/libalias/libalias/libalias.conf similarity index 100% rename from etc/libalias.conf rename to lib/libalias/libalias/libalias.conf diff --git a/lib/libc/Makefile b/lib/libc/Makefile index f82a5b190a22..d6a3598ae314 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -181,6 +181,12 @@ SUBDIR.${MK_TESTS}+= tests .include <bsd.lib.mk> +.if (${LIBC_ARCH} == amd64 || ${LIBC_ARCH} == i386) && \ + ${.TARGETS:Mall} == all && \ + defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" +.error ${LIBC_ARCH} libc requires linker ifunc support +.endif + .if !defined(_SKIP_BUILD) # We need libutil.h, get it directly to avoid # recording a build dependency diff --git a/lib/libc/amd64/string/bcmp.S b/lib/libc/amd64/string/bcmp.S index d01b76bc10e5..efdc6d33e4dd 100644 --- a/lib/libc/amd64/string/bcmp.S +++ b/lib/libc/amd64/string/bcmp.S @@ -1,27 +1,121 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Mateusz Guzik <mjg@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + #include <machine/asm.h> __FBSDID("$FreeBSD$"); -#if 0 - RCSID("$NetBSD: bcmp.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $") -#endif - ENTRY(bcmp) - cld /* set compare direction forward */ - - movq %rdx,%rcx /* compare by words */ - shrq $3,%rcx - repe - cmpsq - jne L1 - - movq %rdx,%rcx /* compare remainder by bytes */ - andq $7,%rcx - repe - cmpsb -L1: - setne %al - movsbl %al,%eax + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax ret +4: + movl $1,%eax + ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 4b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 4b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 4b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b END(bcmp) .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/memcmp.S b/lib/libc/amd64/string/memcmp.S index 66d64a0b5a48..3012ffa688c2 100644 --- a/lib/libc/amd64/string/memcmp.S +++ b/lib/libc/amd64/string/memcmp.S @@ -1,44 +1,121 @@ -/* - * Written by J.T. Conklin <jtc@NetBSD.org>. - * Public domain. - * Adapted for NetBSD/x86_64 by Frank van der Linden <fvdl@wasabisystems.com> +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Mateusz Guzik <mjg@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ */ #include <machine/asm.h> __FBSDID("$FreeBSD$"); -#if 0 - RCSID("$NetBSD: memcmp.S,v 1.2 2003/07/26 19:24:39 salo Exp $") -#endif - ENTRY(memcmp) - cld /* set compare direction forward */ - movq %rdx,%rcx /* compare by longs */ - shrq $3,%rcx - repe - cmpsq - jne L5 /* do we match so far? */ - - movq %rdx,%rcx /* compare remainder by bytes */ - andq $7,%rcx - repe - cmpsb - jne L6 /* do we match? */ - - xorl %eax,%eax /* we match, return zero */ + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax ret - -L5: movl $8,%ecx /* We know that one of the next */ - subq %rcx,%rdi /* eight pairs of bytes do not */ - subq %rcx,%rsi /* match. */ - repe - cmpsb -L6: xorl %eax,%eax /* Perform unsigned comparison */ - movb -1(%rdi),%al - xorl %edx,%edx - movb -1(%rsi),%dl - subl %edx,%eax +4: + subl %r8d,%eax ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 1b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 1b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 1b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b END(memcmp) .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index 151f85068204..fb5cf6e39cc6 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -8,6 +8,7 @@ CFLAGS+=-D_ACL_PRIVATE subr_acl_nfs4.c: ${SRCTOP}/sys/kern/subr_acl_nfs4.c cat ${.ALLSRC} > ${.TARGET} +CONFS+= posix1e/mac.conf SRCS+= acl_branding.c \ acl_calc_mask.c \ acl_copy.c \ diff --git a/etc/mac.conf b/lib/libc/posix1e/mac.conf similarity index 100% rename from etc/mac.conf rename to lib/libc/posix1e/mac.conf diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index c3e5502d68df..5ca9bd3757c0 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -2,6 +2,7 @@ # $FreeBSD$ .PATH: ${LIBC_SRCTOP}/rpc ${LIBC_SRCTOP}/. +CONFS+= rpc/netconfig rpc/rpc SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \ clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \ diff --git a/etc/netconfig b/lib/libc/rpc/netconfig similarity index 100% rename from etc/netconfig rename to lib/libc/rpc/netconfig diff --git a/etc/rpc b/lib/libc/rpc/rpc similarity index 100% rename from etc/rpc rename to lib/libc/rpc/rpc diff --git a/lib/libopie/Makefile b/lib/libopie/Makefile index 4507d252ea9a..2dda575e94ef 100644 --- a/lib/libopie/Makefile +++ b/lib/libopie/Makefile @@ -2,6 +2,9 @@ # # $FreeBSD$ # + +CONFS= opieaccess +CONFSMODE= 600 PACKAGE=lib${LIB} OPIE_DIST?= ${SRCTOP}/contrib/opie DIST_DIR= ${OPIE_DIST}/${.CURDIR:T} diff --git a/etc/opieaccess b/lib/libopie/opieaccess similarity index 100% rename from etc/opieaccess rename to lib/libopie/opieaccess diff --git a/lib/libsmb/Makefile b/lib/libsmb/Makefile index 519db5ff9465..3c310819f876 100644 --- a/lib/libsmb/Makefile +++ b/lib/libsmb/Makefile @@ -2,6 +2,8 @@ .include <src.opts.mk> +CONFS= nsmb.conf +CONFSMODE= 600 PACKAGE=lib${LIB} CONTRIBDIR= ${SRCTOP}/contrib/smbfs .PATH: ${CONTRIBDIR}/lib/smb diff --git a/etc/nsmb.conf b/lib/libsmb/nsmb.conf similarity index 100% rename from etc/nsmb.conf rename to lib/libsmb/nsmb.conf diff --git a/lib/libwrap/Makefile b/lib/libwrap/Makefile index 180ef35b9b95..1326b43bad23 100644 --- a/lib/libwrap/Makefile +++ b/lib/libwrap/Makefile @@ -4,6 +4,7 @@ .include <src.opts.mk> +CONFS= hosts.allow PACKAGE=lib${LIB} LIB= wrap SHLIB_MAJOR= 6 diff --git a/etc/hosts.allow b/lib/libwrap/hosts.allow similarity index 100% rename from etc/hosts.allow rename to lib/libwrap/hosts.allow diff --git a/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile index 5d5e99fb2484..5135469f5eab 100644 --- a/libexec/rtld-elf/Makefile +++ b/libexec/rtld-elf/Makefile @@ -8,6 +8,7 @@ PACKAGE= clibs MK_SSP= no +CONFS= libmap.conf PROG?= ld-elf.so.1 .if (${PROG:M*ld-elf32*} != "") TAGS+= lib32 diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c index 592b7664eea1..33c824a65aff 100644 --- a/libexec/rtld-elf/libmap.c +++ b/libexec/rtld-elf/libmap.c @@ -353,6 +353,7 @@ lm_add(const char *p, const char *f, const char *t) { struct lm_list *lml; struct lm *lm; + const char *t1; if (p == NULL) p = "$DEFAULT$"; @@ -362,11 +363,14 @@ lm_add(const char *p, const char *f, const char *t) if ((lml = lmp_find(p)) == NULL) lml = lmp_init(xstrdup(p)); - lm = xmalloc(sizeof(struct lm)); - lm->f = xstrdup(f); - lm->t = xstrdup(t); - TAILQ_INSERT_HEAD(lml, lm, lm_link); - lm_count++; + t1 = lml_find(lml, f); + if (t1 == NULL || strcmp(t1, t) != 0) { + lm = xmalloc(sizeof(struct lm)); + lm->f = xstrdup(f); + lm->t = xstrdup(t); + TAILQ_INSERT_HEAD(lml, lm, lm_link); + lm_count++; + } } char * diff --git a/etc/libmap.conf b/libexec/rtld-elf/libmap.conf similarity index 100% rename from etc/libmap.conf rename to libexec/rtld-elf/libmap.conf diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h index c89ec4817401..4e7854d34661 100644 --- a/libexec/rtld-elf/powerpc/rtld_machdep.h +++ b/libexec/rtld-elf/powerpc/rtld_machdep.h @@ -69,12 +69,12 @@ void _rtld_powerpc_pltcall(void); #define TLS_TP_OFFSET 0x7000 #define TLS_DTV_OFFSET 0x8000 -#define TLS_TCB_SIZE 8 +#define TLS_TCB_SIZE 16 #define round(size, align) \ (((size) + (align) - 1) & ~((align) - 1)) #define calculate_first_tls_offset(size, align) \ - TLS_TCB_SIZE + round(8, align) #define calculate_tls_offset(prev_offset, prev_size, size, align) \ round(prev_offset + prev_size, align) #define calculate_tls_end(off, size) ((off) + (size)) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index dfd0388478f9..83d5e28e287b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -125,7 +125,7 @@ static void objlist_remove(Objlist *, Obj_Entry *); static int open_binary_fd(const char *argv0, bool search_in_path); static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp); static int parse_integer(const char *); -static void *path_enumerate(const char *, path_enum_proc, void *); +static void *path_enumerate(const char *, path_enum_proc, const char *, void *); static void print_usage(const char *argv0); static void release_object(Obj_Entry *); static int relocate_object_dag(Obj_Entry *root, bool bind_now, @@ -140,7 +140,8 @@ static int rtld_dirname(const char *, char *); static int rtld_dirname_abs(const char *, char *); static void *rtld_dlopen(const char *name, int fd, int mode); static void rtld_exit(void); -static char *search_library_path(const char *, const char *, int *); +static char *search_library_path(const char *, const char *, const char *, + int *); static char *search_library_pathfds(const char *, const char *, int *); static const void **get_program_var_addr(const char *, RtldLockState *); static void set_program_var(const char *, const void *); @@ -1576,8 +1577,7 @@ gnu_hash(const char *s) static char * find_library(const char *xname, const Obj_Entry *refobj, int *fdp) { - char *pathname; - char *name; + char *name, *pathname, *refobj_path; bool nodeflib, objgiven; objgiven = refobj != NULL; @@ -1597,6 +1597,7 @@ find_library(const char *xname, const Obj_Entry *refobj, int *fdp) } dbg(" Searching for \"%s\"", name); + refobj_path = objgiven ? refobj->path : NULL; /* * If refobj->rpath != NULL, then refobj->runpath is NULL. Fall @@ -1605,52 +1606,61 @@ find_library(const char *xname, const Obj_Entry *refobj, int *fdp) * nodeflib. */ if (objgiven && refobj->rpath != NULL && ld_library_path_rpath) { - pathname = search_library_path(name, ld_library_path, fdp); + pathname = search_library_path(name, ld_library_path, + refobj_path, fdp); if (pathname != NULL) return (pathname); if (refobj != NULL) { - pathname = search_library_path(name, refobj->rpath, fdp); + pathname = search_library_path(name, refobj->rpath, + refobj_path, fdp); if (pathname != NULL) return (pathname); } pathname = search_library_pathfds(name, ld_library_dirs, fdp); if (pathname != NULL) return (pathname); - pathname = search_library_path(name, gethints(false), fdp); + pathname = search_library_path(name, gethints(false), + refobj_path, fdp); if (pathname != NULL) return (pathname); - pathname = search_library_path(name, ld_standard_library_path, fdp); + pathname = search_library_path(name, ld_standard_library_path, + refobj_path, fdp); if (pathname != NULL) return (pathname); } else { nodeflib = objgiven ? refobj->z_nodeflib : false; if (objgiven) { - pathname = search_library_path(name, refobj->rpath, fdp); + pathname = search_library_path(name, refobj->rpath, + refobj->path, fdp); if (pathname != NULL) return (pathname); } if (objgiven && refobj->runpath == NULL && refobj != obj_main) { - pathname = search_library_path(name, obj_main->rpath, fdp); + pathname = search_library_path(name, obj_main->rpath, + refobj_path, fdp); if (pathname != NULL) return (pathname); } - pathname = search_library_path(name, ld_library_path, fdp); + pathname = search_library_path(name, ld_library_path, + refobj_path, fdp); if (pathname != NULL) return (pathname); if (objgiven) { - pathname = search_library_path(name, refobj->runpath, fdp); + pathname = search_library_path(name, refobj->runpath, + refobj_path, fdp); if (pathname != NULL) return (pathname); } pathname = search_library_pathfds(name, ld_library_dirs, fdp); if (pathname != NULL) return (pathname); - pathname = search_library_path(name, gethints(nodeflib), fdp); + pathname = search_library_path(name, gethints(nodeflib), + refobj_path, fdp); if (pathname != NULL) return (pathname); if (objgiven && !nodeflib) { pathname = search_library_path(name, - ld_standard_library_path, fdp); + ld_standard_library_path, refobj_path, fdp); if (pathname != NULL) return (pathname); } @@ -1845,8 +1855,9 @@ gethints(bool nostdlib) hargs.request = RTLD_DI_SERINFOSIZE; hargs.serinfo = &hmeta; - path_enumerate(ld_standard_library_path, fill_search_info, &sargs); - path_enumerate(hints, fill_search_info, &hargs); + path_enumerate(ld_standard_library_path, fill_search_info, NULL, + &sargs); + path_enumerate(hints, fill_search_info, NULL, &hargs); SLPinfo = xmalloc(smeta.dls_size); hintinfo = xmalloc(hmeta.dls_size); @@ -1864,8 +1875,9 @@ gethints(bool nostdlib) hargs.serpath = &hintinfo->dls_serpath[0]; hargs.strspace = (char *)&hintinfo->dls_serpath[hmeta.dls_cnt]; - path_enumerate(ld_standard_library_path, fill_search_info, &sargs); - path_enumerate(hints, fill_search_info, &hargs); + path_enumerate(ld_standard_library_path, fill_search_info, NULL, + &sargs); + path_enumerate(hints, fill_search_info, NULL, &hargs); /* * Now calculate the difference between two sets, by excluding @@ -2974,7 +2986,8 @@ rtld_exit(void) * callback on the result. */ static void * -path_enumerate(const char *path, path_enum_proc callback, void *arg) +path_enumerate(const char *path, path_enum_proc callback, + const char *refobj_path, void *arg) { const char *trans; if (path == NULL) @@ -2986,7 +2999,7 @@ path_enumerate(const char *path, path_enum_proc callback, void *arg) char *res; len = strcspn(path, ":;"); - trans = lm_findn(NULL, path, len); + trans = lm_findn(refobj_path, path, len); if (trans) res = callback(trans, strlen(trans), arg); else @@ -3045,7 +3058,8 @@ try_library_path(const char *dir, size_t dirlen, void *param) } static char * -search_library_path(const char *name, const char *path, int *fdp) +search_library_path(const char *name, const char *path, + const char *refobj_path, int *fdp) { char *p; struct try_library_args arg; @@ -3059,7 +3073,7 @@ search_library_path(const char *name, const char *path, int *fdp) arg.buflen = PATH_MAX; arg.fd = -1; - p = path_enumerate(path, try_library_path, &arg); + p = path_enumerate(path, try_library_path, refobj_path, &arg); *fdp = arg.fd; free(arg.buffer); @@ -3776,12 +3790,12 @@ do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info) _info.dls_size = __offsetof(struct dl_serinfo, dls_serpath); _info.dls_cnt = 0; - path_enumerate(obj->rpath, fill_search_info, &args); - path_enumerate(ld_library_path, fill_search_info, &args); - path_enumerate(obj->runpath, fill_search_info, &args); - path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args); + path_enumerate(obj->rpath, fill_search_info, NULL, &args); + path_enumerate(ld_library_path, fill_search_info, NULL, &args); + path_enumerate(obj->runpath, fill_search_info, NULL, &args); + path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL, &args); if (!obj->z_nodeflib) - path_enumerate(ld_standard_library_path, fill_search_info, &args); + path_enumerate(ld_standard_library_path, fill_search_info, NULL, &args); if (request == RTLD_DI_SERINFOSIZE) { @@ -3801,25 +3815,25 @@ do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info) args.strspace = (char *)&info->dls_serpath[_info.dls_cnt]; args.flags = LA_SER_RUNPATH; - if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL) + if (path_enumerate(obj->rpath, fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_LIBPATH; - if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL) + if (path_enumerate(ld_library_path, fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_RUNPATH; - if (path_enumerate(obj->runpath, fill_search_info, &args) != NULL) + if (path_enumerate(obj->runpath, fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_CONFIG; - if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args) + if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_DEFAULT; - if (!obj->z_nodeflib && - path_enumerate(ld_standard_library_path, fill_search_info, &args) != NULL) + if (!obj->z_nodeflib && path_enumerate(ld_standard_library_path, + fill_search_info, NULL, &args) != NULL) return (-1); return (0); } diff --git a/release/scripts/pkg-stage.sh b/release/scripts/pkg-stage.sh index fe4ffd9695d0..6c7cb0e76a3e 100755 --- a/release/scripts/pkg-stage.sh +++ b/release/scripts/pkg-stage.sh @@ -30,7 +30,7 @@ www/firefox www/links x11-drivers/xf86-video-vmware x11/gnome3 -x11/kde4 +x11/kde5 x11/xorg" # If NOPORTS is set for the release, do not attempt to build pkg(8). diff --git a/sbin/bsdlabel/Makefile b/sbin/bsdlabel/Makefile index b1a71a2a74f2..6921a655af10 100644 --- a/sbin/bsdlabel/Makefile +++ b/sbin/bsdlabel/Makefile @@ -3,6 +3,7 @@ .PATH: ${SRCTOP}/sys/geom +CONFS= disktab PACKAGE=runtime PROG= bsdlabel SRCS= bsdlabel.c geom_bsd_enc.c diff --git a/etc/disktab b/sbin/bsdlabel/disktab similarity index 100% rename from etc/disktab rename to sbin/bsdlabel/disktab diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc index e81f718159b1..b2d08324511f 100644 --- a/sbin/devd/devd.cc +++ b/sbin/devd/devd.cc @@ -666,7 +666,7 @@ config::shell_quote(const string &s) } void -config::expand_one(const char *&src, string &dst) +config::expand_one(const char *&src, string &dst, bool is_shell) { int count; string buffer; @@ -705,7 +705,7 @@ config::expand_one(const char *&src, string &dst) do { buffer += *src++; } while (is_id_char(*src)); - dst.append(shell_quote(get_variable(buffer))); + dst.append(is_shell ? shell_quote(get_variable(buffer)) : get_variable(buffer)); } const string @@ -731,7 +731,7 @@ config::expand_string(const char *src, const char *prepend, const char *append) } dst.append(src, var_at - src); src = var_at; - expand_one(src, dst); + expand_one(src, dst, prepend == NULL); } if (append != NULL) diff --git a/sbin/devd/devd.hh b/sbin/devd/devd.hh index 534c4d4c5a9d..d770da22226a 100644 --- a/sbin/devd/devd.hh +++ b/sbin/devd/devd.hh @@ -172,7 +172,7 @@ protected: void sort_vector(std::vector<event_proc *> &); void parse_one_file(const char *fn); void parse_files_in_dir(const char *dirname); - void expand_one(const char *&src, std::string &dst); + void expand_one(const char *&src, std::string &dst, bool is_shell); std::string shell_quote(const std::string &s); bool is_id_char(char) const; bool chop_var(char *&buffer, char *&lhs, char *&rhs) const; diff --git a/sbin/dhclient/Makefile b/sbin/dhclient/Makefile index 99b749eb720f..cdf93b8b8145 100644 --- a/sbin/dhclient/Makefile +++ b/sbin/dhclient/Makefile @@ -33,6 +33,7 @@ .include <src.opts.mk> +CONFS= dhclient.conf PACKAGE=runtime SRCS= dhclient.c clparse.c alloc.c dispatch.c hash.c bpf.c options.c \ tree.c conflex.c errwarn.c inet.c packet.c convert.c tables.c \ diff --git a/sbin/dhclient/dhclient.conf b/sbin/dhclient/dhclient.conf index 7eaeeb8eb40a..a7639d904aad 100644 --- a/sbin/dhclient/dhclient.conf +++ b/sbin/dhclient/dhclient.conf @@ -1,39 +1,8 @@ # $FreeBSD$ - -send host-name "andare.fugue.com"; -send dhcp-client-identifier 1:0:a0:24:ab:fb:9c; -send dhcp-lease-time 3600; -supersede domain-name "fugue.com home.vix.com"; -prepend domain-name-servers 127.0.0.1; -request subnet-mask, broadcast-address, time-offset, - classless-routes, routers, domain-name, - domain-name-servers, host-name; -require subnet-mask, domain-name-servers; -timeout 60; -retry 60; -reboot 10; -select-timeout 5; -initial-interval 2; -script "/etc/dhclient-script"; -media "-link0 -link1 -link2", "link0 link1"; -reject 192.33.137.209; - -alias { - interface "ep0"; - fixed-address 192.5.5.213; - option subnet-mask 255.255.255.255; -} - -lease { - interface "ep0"; - fixed-address 192.33.137.200; - medium "link0 link1"; - option host-name "andare.swiftmedia.com"; - option subnet-mask 255.255.255.0; - option broadcast-address 192.33.137.255; - option routers 192.33.137.250; - option domain-name-servers 127.0.0.1; - renew 2 2000/1/12 00:00:01; - rebind 2 2000/1/12 00:00:01; - expire 2 2000/1/12 00:00:01; -} +# +# This file is required by the ISC DHCP client. +# See ``man 5 dhclient.conf'' for details. +# +# In most cases an empty file is sufficient for most people as the +# defaults are usually fine. +# diff --git a/sbin/ifconfig/ifipsec.c b/sbin/ifconfig/ifipsec.c index fed5a842235c..0e615a27e205 100644 --- a/sbin/ifconfig/ifipsec.c +++ b/sbin/ifconfig/ifipsec.c @@ -72,6 +72,7 @@ DECL_CMD_FUNC(setreqid, val, arg) warn("Invalid reqid value %s", val); return; } + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_data = (char *)&v; if (ioctl(s, IPSECSREQID, &ifr) == -1) { warn("ioctl(IPSECSREQID)"); diff --git a/sbin/init/rc.d/ldconfig b/sbin/init/rc.d/ldconfig index 3af9562d3bfa..2d2bd143de73 100755 --- a/sbin/init/rc.d/ldconfig +++ b/sbin/init/rc.d/ldconfig @@ -58,7 +58,7 @@ ldconfig_start() done check_startmsgs && echo '32-bit compatibility ldconfig path:' ${_LDC} - ${ldconfig} -32 -m ${_ins} ${_LDC} + ${ldconfig} -32 ${_ins} ${_LDC} ;; esac @@ -80,7 +80,7 @@ ldconfig_start() done check_startmsgs && echo 'Soft Float compatibility ldconfig path:' ${_LDC} - ${ldconfig} -soft -m ${_ins} ${_LDC} + ${ldconfig} -soft ${_ins} ${_LDC} ;; esac diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 8364de827787..acb4d347644d 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 10, 2018 +.Dd September 27, 2018 .Dt IPFW 8 .Os .Sh NAME @@ -2711,7 +2711,7 @@ The following case-insensitive parameters can be configured for a scheduler: .Pp .Bl -tag -width indent -compact -.It Cm type Ar {fifo | wf2q+ | rr | qfq} +.It Cm type Ar {fifo | wf2q+ | rr | qfq | fq_codel | fq_pie} specifies the scheduling algorithm to use. .Bl -tag -width indent -compact .It Cm fifo @@ -2738,7 +2738,68 @@ with poor service guarantees. implements the QFQ algorithm, which is a very fast variant of WF2Q+, with similar service guarantees and O(1) processing costs (roughly, 200-250ns per packet). +.It Cm fq_codel +implements the FQ-CoDel (FlowQueue-CoDel) scheduler/AQM algorithm, which +uses a modified Deficit Round Robin scheduler to manage two lists of sub-queues +(old sub-queues and new sub-queues) for providing brief periods of priority to +lightweight or short burst flows. +By default, the total number of sub-queues is 1024. +FQ-CoDel's internal, dynamically +created sub-queues are controlled by separate instances of CoDel AQM. +.It Cm fq_pie +implements the FQ-PIE (FlowQueue-PIE) scheduler/AQM algorithm, which similar to +.Cm fq_codel +but uses per sub-queue PIE AQM instance to control the queue delay. .El +.Pp +.Cm fq_codel +inherits AQM parameters and options from +.Cm codel +(see below), and +.Cm fq_pie +inherits AQM parameters and options from +.Cm pie +(see below). +Additionally, both of +.Cm fq_codel +and +.Cm fq_pie +have shared scheduler parameters which are: +.Bl -tag -width indent +.It Cm quantum +.Ar m +specifies the quantum (credit) of the scheduler. +.Ar m +is the number of bytes a queue can serve before being moved to the tail +of old queues list. +The default is 1514 bytes, and the maximum accepable value +is 9000 bytes. +.It Cm limit +.Ar m +specifies the hard size limit (in unit of packets) of all queues managed by an +instance of the scheduler. +The default value of +.Ar m +is 10240 packets, and the maximum accepable value is 20480 packets. +.It Cm flows +.Ar m +specifies the total number of flow queues (sub-queues) that fq_* +creates and manages. +By default, 1024 sub-queues are created when an instance +of the fq_{codel/pie} scheduler is created. +The maximum accepable value is +65536. +.El +.Pp +Note that any token after +.Cm fq_codel +or +.Cm fq_pie +is considered a parameter for fq_{codel/pie}. +So, ensure all scheduler +configuration options not related to fq_{codel/pie} are written before +.Cm fq_codel/fq_pie +tokens. .El .Pp In addition to the type, all parameters allowed for a pipe can also @@ -2869,6 +2930,135 @@ greater than zero) specifies the expected maximum packet size, only used when queue thresholds are in bytes (defaults to 1500, must be greater than zero). .El +.Pp +.It Cm codel Oo Cm target Ar time Oc Oo Cm interval Ar time Oc Oo Cm ecn | +.Cm noecn Oc +Make use of the CoDel (Controlled-Delay) queue management algorithm. +.Ar time +is interpreted as milliseconds by default but seconds (s), milliseconds (ms) or +microseconds (us) can be specified instead. +CoDel drops or marks (ECN) packets +depending on packet sojourn time in the queue. +.Cm target +.Ar time +(5ms by default) is the minimum acceptable persistent queue delay that CoDel +allows. +CoDel does not drop packets directly after packets sojourn time becomes +higher than +.Cm target +.Ar time +but waits for +.Cm interval +.Ar time +(100ms default) before dropping. +.Cm interval +.Ar time +should be set to maximum RTT for all expected connections. +.Cm ecn +enables (disabled by default) packet marking (instead of dropping) for +ECN-enabled TCP flows when queue delay becomes high. +.Pp +Note that any token after +.Cm codel +is considered a parameter for CoDel. +So, ensure all pipe/queue +configuration options are written before +.Cm codel +token. +.Pp +The +.Xr sysctl 8 +variables +.Va net.inet.ip.dummynet.codel.target +and +.Va net.inet.ip.dummynet.codel.interval +can be used to set CoDel default parameters. +.Pp +.It Cm pie Oo Cm target Ar time Oc Oo Cm tupdate Ar time Oc Oo +.Cm alpha Ar n Oc Oo Cm beta Ar n Oc Oo Cm max_burst Ar time Oc Oo +.Cm max_ecnth Ar n Oc Oo Cm ecn | Cm noecn Oc Oo Cm capdrop | +.Cm nocapdrop Oc Oo Cm drand | Cm nodrand Oc Oo Cm onoff +.Oc Oo Cm dre | Cm ts Oc +Make use of the PIE (Proportional Integral controller Enhanced) queue management +algorithm. +PIE drops or marks packets depending on a calculated drop probability during +en-queue process, with the aim of achieving high throughput while keeping queue +delay low. +At regular time intervals of +.Cm tupdate +.Ar time +(15ms by default) a background process (re)calculates the probability based on queue delay +deviations from +.Cm target +.Ar time +(15ms by default) and queue delay trends. +PIE approximates current queue +delay by using a departure rate estimation method, or (optionally) by using a +packet timestamp method similar to CoDel. +.Ar time +is interpreted as milliseconds by default but seconds (s), milliseconds (ms) or +microseconds (us) can be specified instead. +The other PIE parameters and options are as follows: +.Bl -tag -width indent +.It Cm alpha Ar n +.Ar n +is a floating point number between 0 and 7 which specifies the weight of queue +delay deviations that is used in drop probability calculation. +0.125 is the default. +.It Cm beta Ar n +.Ar n +is a floating point number between 0 and 7 which specifies is the weight of queue +delay trend that is used in drop probability calculation. +1.25 is the default. +.It Cm max_burst Ar time +The maximum period of time that PIE does not drop/mark packets. +150ms is the +default and 10s is the maximum value. +.It Cm max_ecnth Ar n +Even when ECN is enabled, PIE drops packets instead of marking them when drop +probability becomes higher than ECN probability threshold +.Cm max_ecnth Ar n +, the default is 0.1 (i.e 10%) and 1 is the maximum value. +.It Cm ecn | noecn +enable or disable ECN marking for ECN-enabled TCP flows. +Disabled by default. +.It Cm capdrop | nocapdrop +enable or disable cap drop adjustment. +Cap drop adjustment is enabled by default. +.It Cm drand | nodrand +enable or disable drop probability de-randomisation. +De-randomisation eliminates +the problem of dropping packets too close or too far. +De-randomisation is enabled by default. +.It Cm onoff +enable turning PIE on and off depending on queue load. +If this option is enabled, +PIE turnes on when over 1/3 of queue becomes full. +This option is disabled by +default. +.It Cm dre | ts +Calculate queue delay using departure rate estimation +.Cm dre +or timestamps +.Cm ts . +.Cm dre +is used by default. +.El +.Pp +Note that any token after +.Cm pie +is considered a parameter for PIE. +So ensure all pipe/queue +the configuration options are written before +.Cm pie +token. +.Xr sysctl 8 +variables can be used to control the +.Cm pie +default parameters. +See the +.Sx SYSCTL VARIABLES +section for more details. .El .Pp When used with IPv6 data, @@ -3461,10 +3651,102 @@ global IP addresses, this will still result in a fully functional .It Va net.inet.ip.alias.sctp.up_timer: No 300 Timeout value to keep an association up with no traffic. This value cannot be 0. +.It Va net.inet.ip.dummynet.codel.interval : No 100000 +Default +.Cm codel +AQM interval in microseconds. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.codel.target : No 5000 +Default +.Cm codel +AQM target delay time in microseconds (the minimum acceptable persistent queue +delay). +The value must be in the range 1..5000000. .It Va net.inet.ip.dummynet.expire : No 1 Lazily delete dynamic pipes/queue once they have no pending traffic. You can disable this by setting the variable to 0, in which case the pipes/queues will only be deleted when the threshold is reached. +.It Va net.inet.ip.dummynet.fqcodel.flows : No 1024 +Defines the default total number of flow queues (sub-queues) that +.Cm fq_codel +creates and manages. +The value must be in the range 1..65536. +.It Va net.inet.ip.dummynet.fqcodel.interval : No 100000 +Default +.Cm fq_codel +scheduler/AQM interval in microseconds. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.fqcodel.limit : No 10240 +The default hard size limit (in unit of packet) of all queues managed by an +instance of the +.Cm fq_codel +scheduler. +The value must be in the range 1..20480. +.It Va net.inet.ip.dummynet.fqcodel.quantum : No 1514 +The default quantum (credit) of the +.Cm fq_codel +in unit of byte. +The value must be in the range 1..9000. +.It Va net.inet.ip.dummynet.fqcodel.target : No 5000 +Default +.Cm fq_codel +scheduler/AQM target delay time in microseconds (the minimum acceptable +persistent queue delay). +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.fqpie.alpha : No 125 +The default +.Ar alpha +parameter (scaled by 1000) for +.Cm fq_pie +scheduler/AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.fqpie.beta : No 1250 +The default +.Ar beta +parameter (scaled by 1000) for +.Cm fq_pie +scheduler/AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.fqpie.flows : No 1024 +Defines the default total number of flow queues (sub-queues) that +.Cm fq_pie +creates and manages. +The value must be in the range 1..65536. +.It Va net.inet.ip.dummynet.fqpie.limit : No 10240 +The default hard size limit (in unit of packet) of all queues managed by an +instance of the +.Cm fq_pie +scheduler. +The value must be in the range 1..20480. +.It Va net.inet.ip.dummynet.fqpie.max_burst : No 150000 +The default maximum period of microseconds that +.Cm fq_pie +scheduler/AQM does not drop/mark packets. +The value must be in the range 1..10000000. +.It Va net.inet.ip.dummynet.fqpie.max_ecnth : No 99 +The default maximum ECN probability threshold (scaled by 1000) for +.Cm fq_pie +scheduler/AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.fqpie.quantum : No 1514 +The default quantum (credit) of the +.Cm fq_pie +in unit of byte. +The value must be in the range 1..9000. +.It Va net.inet.ip.dummynet.fqpie.target : No 15000 +The default +.Cm target +delay of the +.Cm fq_pie +in unit of microsecond. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.fqpie.tupdate : No 15000 +The default +.Cm tupdate +of the +.Cm fq_pie +in unit of microsecond. +The value must be in the range 1..5000000. .It Va net.inet.ip.dummynet.hash_size : No 64 Default size of the hash table used for dynamic pipes/queues. This value is used when no @@ -3499,6 +3781,44 @@ will be expired even when .It Va net.inet.ip.dummynet.red_max_pkt_size : No 1500 Parameters used in the computations of the drop probability for the RED algorithm. +.It Va net.inet.ip.dummynet.pie.alpha : No 125 +The default +.Ar alpha +parameter (scaled by 1000) for +.Cm pie +AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.pie.beta : No 1250 +The default +.Ar beta +parameter (scaled by 1000) for +.Cm pie +AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.pie.max_burst : No 150000 +The default maximum period of microseconds that +.Cm pie +AQM does not drop/mark packets. +The value must be in the range 1..10000000. +.It Va net.inet.ip.dummynet.pie.max_ecnth : No 99 +The default maximum ECN probability threshold (scaled by 1000) for +.Cm pie +AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.pie.target : No 15000 +The default +.Cm target +delay of +.Cm pie +AQM in unit of microsecond. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.pie.tupdate : No 15000 +The default +.Cm tupdate +of +.Cm pie +AQM in unit of microsecond. +The value must be in the range 1..5000000. .It Va net.inet.ip.dummynet.pipe_byte_limit : No 1048576 .It Va net.inet.ip.dummynet.pipe_slot_limit : No 100 The maximum queue size that can be specified in bytes or packets. @@ -4029,6 +4349,102 @@ action, if it is not created yet. Later, this dynamic rule is used on way in by .Cm check-state rule. +.Ss CONFIGURING CODEL, PIE, FQ-CODEL and FQ-PIE AQM +.Cm codel +and +.Cm pie +AQM can be configured for +.Nm dummynet +.Cm pipe +or +.Cm queue. +.Pp +To configure a +.Cm pipe +with +.Cm codel +AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s +rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s codel" +.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any" +.Pp +To configure a +.Cm queue +with +.Cm codel +AQM using different configurations parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw queue 1 config pipe 1 codel target 8ms interval 160ms ecn" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +To configure a +.Cm pipe +with +.Cm pie +AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s +rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s pie" +.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any" +.Pp +To configure a +.Cm queue +with +.Cm pie +AQM using different configuration parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw queue 1 config pipe 1 pie target 20ms tupdate 30ms ecn" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +.Cm fq_codel +and +.Cm fq_pie +AQM can be configured for +.Nm dummynet +schedulers. +.Pp +To configure +.Cm fq_codel +scheduler using different configurations parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw sched 1 config pipe 1 type fq_codel" +.Dl "ipfw queue 1 config sched 1" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +To change +.Cm fq_codel +default configuration for a +.Cm sched +such as disable ECN and change the +.Ar target +to 10ms, we do: +.Pp +.Dl "ipfw sched 1 config pipe 1 type fq_codel target 10ms noecn" +.Pp +Similar to +.Cm fq_codel, +to configure +.Cm fq_pie +scheduler using different configurations parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw sched 1 config pipe 1 type fq_pie" +.Dl "ipfw queue 1 config sched 1" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +The configurations of +.Cm fq_pie +.Cm sched +can be changed in a similar way as for +.Cm fq_codel .Sh SEE ALSO .Xr cpp 1 , .Xr m4 1 , @@ -4063,7 +4479,8 @@ was introduced in Summer 2002. .An Poul-Henning Kamp , .An Alex Nash , .An Archie Cobbs , -.An Luigi Rizzo . +.An Luigi Rizzo , +.An Rasool Al-Saadi . .Pp .An -nosplit API based upon code written by @@ -4098,6 +4515,12 @@ For further information visit: Delay profiles have been developed by Alessandro Cerri and Luigi Rizzo, supported by the European Commission within Projects Onelab and Onelab2. +.Pp +CoDel, PIE, FQ-CoDel and FQ-PIE AQM for Dummynet have been implemented by +.An The Centre for Advanced Internet Architectures (CAIA) +in 2016, supported by The Comcast Innovation Fund. +The primary developer is +Rasool Al-Saadi. .Sh BUGS The syntax has grown over the years and sometimes it might be confusing. Unfortunately, backward compatibility prevents cleaning up mistakes diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 32a94edf7c42..203c852b372f 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -1466,19 +1466,31 @@ print_instruction(struct buf_pr *bp, const struct format_opts *fo, case O_IP_SRC_MASK: case O_IP_SRC_ME: case O_IP_SRC_SET: + if (state->flags & HAVE_SRCIP) + bprintf(bp, " src-ip"); + print_ip(bp, fo, insntod(cmd, ip)); + break; case O_IP_DST: case O_IP_DST_LOOKUP: case O_IP_DST_MASK: case O_IP_DST_ME: case O_IP_DST_SET: + if (state->flags & HAVE_DSTIP) + bprintf(bp, " dst-ip"); print_ip(bp, fo, insntod(cmd, ip)); break; case O_IP6_SRC: case O_IP6_SRC_MASK: case O_IP6_SRC_ME: + if (state->flags & HAVE_SRCIP) + bprintf(bp, " src-ip6"); + print_ip6(bp, insntod(cmd, ip6)); + break; case O_IP6_DST: case O_IP6_DST_MASK: case O_IP6_DST_ME: + if (state->flags & HAVE_DSTIP) + bprintf(bp, " dst-ip6"); print_ip6(bp, insntod(cmd, ip6)); break; case O_FLOW6ID: diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index 1f3041b1f6c7..35a2cc941748 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -28,7 +28,7 @@ .\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd March 9, 2018 +.Dd September 24, 2018 .Dt SYSCTL 8 .Os .Sh NAME @@ -276,6 +276,8 @@ definitions for fourth level ICMP identifiers .It In netinet/udp_var.h definitions for fourth level UDP identifiers .El +.Sh EXIT STATUS +.Ex -std .Sh EXAMPLES For example, to retrieve the maximum number of processes allowed in the system, one would use the following request: diff --git a/secure/usr.bin/openssl/Makefile b/secure/usr.bin/openssl/Makefile index fad775faab5f..d7d38f0742dc 100644 --- a/secure/usr.bin/openssl/Makefile +++ b/secure/usr.bin/openssl/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +CONFS= openssl.cnf +CONFSDIR= /etc/ssl PROG= openssl LIBADD= ssl crypto diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index c40e47c8ffaf..3a6738a2ef42 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -202,6 +202,7 @@ MAN= aac.4 \ icmp6.4 \ ida.4 \ if_ipsec.4 \ + iflib.4 \ ifmib.4 \ ig4.4 \ igmp.4 \ diff --git a/share/man/man4/bnxt.4 b/share/man/man4/bnxt.4 index 20cc3b83b0ef..12c2f9a0626a 100644 --- a/share/man/man4/bnxt.4 +++ b/share/man/man4/bnxt.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 9, 2017 +.Dd September 20, 2018 .Dt BNXT 4 .Os .Sh NAME @@ -110,7 +110,7 @@ These variables must be set before loading the driver, either via or through the use of .Xr kenv 1 . These are provided by the -.Xr iflib 9 +.Xr iflib 4 framework, and might be better documented there. .Bl -tag -width indent .It Va dev.bnxt.X.iflib.override_nrxds diff --git a/share/man/man4/cxgbe.4 b/share/man/man4/cxgbe.4 index c98f96ad3678..970472efca21 100644 --- a/share/man/man4/cxgbe.4 +++ b/share/man/man4/cxgbe.4 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Aug 9, 2018 +.Dd Sep 24, 2018 .Dt CXGBE 4 .Os .Sh NAME @@ -279,19 +279,21 @@ This usually results in the port emitting PAUSE frames. 1 instructs the hardware to drop frames destined for congested queues. .It Va hw.cxgbe.pause_settings PAUSE frame settings. -Bit 0 is rx_pause, bit 1 is tx_pause. +Bit 0 is rx_pause, bit 1 is tx_pause, bit 2 is pause_autoneg. rx_pause = 1 instructs the hardware to heed incoming PAUSE frames, 0 instructs it to ignore them. tx_pause = 1 allows the hardware to emit PAUSE frames when its receive FIFO reaches a high threshold, 0 prohibits the hardware from emitting PAUSE frames. -The default is 3 (both rx_pause and tx_pause = 1). +pause_autoneg = 1 overrides the rx_pause and tx_pause bits and instructs the +hardware to negotiate PAUSE settings with the link peer. +The default is 7 (all three = 1). This tunable establishes the default PAUSE settings for all ports. Settings can be displayed and controlled on a per-port basis via the dev.<port>.X.pause_settings sysctl. .It Va hw.cxgbe.fec FEC (Forward Error Correction) settings. 0 diables FEC. -Bit 0 enables RS FEC, bit 1 enables BASE-R RS, bit 3 is reserved. +Bit 0 enables RS FEC, bit 1 enables BASE-R FEC (aka Firecode FEC). The default is -1 which lets the driver pick a value. This tunable establishes the default FEC settings for all ports. Settings can be displayed and controlled on a per-port basis via the diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4 index aeec111adefe..188b5c8fc5ec 100644 --- a/share/man/man4/ddb.4 +++ b/share/man/man4/ddb.4 @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 20, 2018 +.Dd September 7, 2018 .Dt DDB 4 .Os .Sh NAME @@ -1280,6 +1280,7 @@ The width of the displayed line. .It Va lines The number of lines. It is used by the built-in pager. +Setting it to 0 disables paging. .It Va tabstops Tab stop width. .It Va work Ns Ar xx diff --git a/share/man/man4/em.4 b/share/man/man4/em.4 index 9a9249fdcaf7..7f84be1fbbf4 100644 --- a/share/man/man4/em.4 +++ b/share/man/man4/em.4 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 22, 2017 +.Dd September 20, 2018 .Dt EM 4 .Os .Sh NAME @@ -298,6 +298,7 @@ issue to .Sh SEE ALSO .Xr altq 4 , .Xr arp 4 , +.Xr iflib 4 , .Xr led 4 , .Xr netintro 4 , .Xr ng_ether 4 , diff --git a/share/man/man4/iflib.4 b/share/man/man4/iflib.4 new file mode 100644 index 000000000000..ffd7c1153f59 --- /dev/null +++ b/share/man/man4/iflib.4 @@ -0,0 +1,204 @@ +.\" $FreeBSD$ +.Dd September 27, 2018 +.Dt IFLIB 4 +.Os +.Sh NAME +.Nm iflib +.Nd Network Interface Driver Framework +.Sh SYNOPSIS +.Cd "device pci" +.Cd "device iflib" +.Sh DESCRIPTION +.Nm +is a framework for network interface drivers for +.Fx . +It is designed to remove a large amount of the boilerplate that is often +needed for modern network interface devices, allowing driver authors to +focus on the specific code needed for their hardware. +This allows for a shared set of +.Xr sysctl 8 +names, rather than each driver naming them individually. +.Sh SYSCTL VARIABLES +These variables must be set before loading the driver, either via +.Xr loader.conf 5 +or through the use of +.Xr kenv 1 . +They are all prefixed by +.Va dev.X.Y.iflib\&. +where X is the driver name, and Y is the instance number. +.Bl -tag -width indent +.It Va override_nrxds +Override the number of RX descriptors for each queue. +The value is a comma separated list of positive integers. +Some drivers only use a single value, but others may use more. +These numbers must be powers of two, and zero means to use the default. +Individual drivers may have additional restrictions on allowable values. +Defaults to all zeros. +.It Va override_ntxds +Override the number of TX descriptors for each queue. +The value is a comma separated list of positive integers. +Some drivers only use a single value, but others may use more. +These numbers must be powers of two, and zero means to use the default. +Individual drivers may have additional restrictions on allowable values. +Defaults to all zeros. +.It Va override_qs_enable +When set, allows the number of transmit and receive queues to be different. +If not set, the lower of the number of TX or RX queues will be used for both. +.It Va override_nrxqs +Set the number of RX queues. +If zero, the number of RX queues is derived from the number of cores on the +socket connected to the controller. +Defaults to 0. +.It Va override_ntxqs +Set the number of TX queues. +If zero, the number of TX queues is derived from the number of cores on the +socket connected to the controller. +.It Va disable_msix +Disables MSI-X interrupts for the device. +.El +.Pp +These +.Xr sysctl 8 +variables can be changed at any time: +.Bl -tag -width indent +.It Va tx_abdicate +Controls how the transmit ring is serviced. +If set to zero, when a frame is submitted to the transmission ring, the same +task that is submitting it will service the ring unless there's already a +task servicing the TX ring. +This ensures that whenever there is a pending transmission, +the transmit ring is being serviced. +This results in higher transmit throughput. +If set to a non-zero value, task returns immediately and the transmit +ring is serviced by a different task. +This returns control to the caller faster and under high receive load, +may result in fewer dropped RX frames. +.It Va rx_budget +Sets the maximum number of frames to be received at a time. +Zero (the default) indicates the default (currently 16) should be used. +.El +.Pp +There are also some global sysctls which can change behaviour for all drivers, +and may be changed at any time. +.Bl -tag -width indent +.It Va net.iflib.min_tx_latency +If this is set to a non-zero value, iflib will avoid any attempt to combine +multiple transmits, and notify the hardware as quickly as possible of +new descriptors. +This will lower the maximum throughput, but will also lower transmit latency. +.It Va net.iflib.no_tx_batch +Some NICs allow processing completed transmit descriptors in batches. +Doing so usually increases the transmit throughput by reducing the number of +transmit interrupts. +Setting this to a non-zero value will disable the use of this feature. +.El +.Pp +These +.Xr sysctl 8 +variables are read-only: +.Bl -tag -width indent +.It Va driver_version +A string indicating the internal version of the driver. +.El +.Pp +There are a number of queue state +.Xr sysctl 8 +variables as well: +.Bl -tag -width indent +.It Va txqZ +The following are repeated for each transmit queue, where Z is the transmit +queue instance number: +.Bl -tag -width indent +.It Va r_abdications +Number of consumer abdications in the MP ring for this queue. +An abdication occurs on every ring submission when tx_abdicate is true. +.It Va r_restarts +Number of consumer restarts in the MP ring for this queue. +A restart occurs when an attempt to drain a non-empty ring fails, +and the ring is already in the STALLED state. +.It Va r_stalls +Number of consumer stalls in the MP ring for this queue. +A stall occurs when an attempt to drain a non-empty ring fails. +.It Va r_starts +Number of normal consumer starts in the MP ring for this queue. +A start occurs when the MP ring transitions from IDLE to BUSY. +.It Va r_drops +Number of drops in the MP ring for this queue. +A drop occurs when there is an attempt to add an entry to an MP ring with +no available space. +.It Va r_enqueues +Number of entries which have been enqueued to the MP ring for this queue. +.It Va ring_state +MP (soft) ring state. +This privides a snapshot of the current MP ring state, including the producer +head and tail indexes, the consumer index, and the state. +The state is one of "IDLE", "BUSY", +"STALLED", or "ABDICATED". +.It Va txq_cleaned +The number of transmit descriptors which have been reclaimed. +Total cleaned. +.It Va txq_processed +The number of transmit descriptors which have been processed, but may not yet +have been reclaimed. +.It Va txq_in_use +Descriptors which have been added to the transmit queue, +but have not yet been cleaned. +This value will include both untransmitted descriptors as well as descriptors +which have been processed. +.It Va txq_cidx_processed +The transmit queue consumer index of the next descriptor to process. +.It Va txq_cidx +The transmit queue consumer index of the oldest descriptor to reclaim. +.It Va txq_pidx +The transmit queue producer index where the next descriptor to transmit will +be inserted. +.It Va no_tx_dma_setup +Number of times DMA mapping a transmit mbuf failed for reasons other than +.Er EFBIG . +.It Va txd_encap_efbig +Number of times DMA mapping a transmit mbuf failed due to requiring too many +segments. +.It Va tx_map_failed +Number of times DMA mapping a transmit mbuf failed for any reason +(sum of no_tx_dma_setup and txd_encap_efbig) +.It Va no_desc_avail +Number of times a descriptor couldn't be added to the transmit ring because +the transmit ring was full. +.It Va mbuf_defrag_failed +Number of times both +.Xr m_collapse 9 +and +.Xr m_defrag 9 +failed after an +.Er EFBIG +error +result from DMA mapping a transmit mbuf. +.It Va m_pullups +Number of times +.Xr m_pullup 9 +was called attempting to parse a header. +.It Va mbuf_defrag +Number of times +.Xr m_defrag 9 +was called. +.El +.It Va rxqZ +The following are repeated for each receive queue, where Z is the +receive queue instance number: +.Bl -tag -width indent +.It Va rxq_fl0.credits +Credits currently available in the receive ring. +.It Va rxq_fl0.cidx +Current receive ring consumer index. +.It Va rxq_fl0.pidx +Current receive ring producer index. +.El +.El +.Pp +Additional OIDs useful for driver and iflib development are exposed when the +INVARIANTS and/or WITNESS options are enabled in the kernel. +.Sh SEE ALSO +.Xr iflib 9 +.Sh HISTORY +This framework was introduced in +.Fx 11.0 . diff --git a/share/man/man5/make.conf.5 b/share/man/man5/make.conf.5 index 7517d20db193..f8c148e62ccb 100644 --- a/share/man/man5/make.conf.5 +++ b/share/man/man5/make.conf.5 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 15, 2018 +.Dd September 27, 2018 .Dt MAKE.CONF 5 .Os .Sh NAME @@ -676,6 +676,7 @@ Porter's Handbook. .Xr install 1 , .Xr make 1 , .Xr src.conf 5 , +.Xr style.Makefile 5 , .Xr environ 7 , .Xr ports 7 , .Xr sendmail 8 diff --git a/share/man/man5/msdosfs.5 b/share/man/man5/msdosfs.5 index ff1df4ba525b..7e8d31fa75c5 100644 --- a/share/man/man5/msdosfs.5 +++ b/share/man/man5/msdosfs.5 @@ -2,7 +2,7 @@ .\" Written by Tom Rhodes .\" This file is in the public domain. .\" -.Dd October 1, 2013 +.Dd September 27, 2018 .Dt MSDOSFS 5 .Os .Sh NAME @@ -15,9 +15,7 @@ The .Nm driver will permit the .Fx -kernel to read and write -.Tn MS-DOS -based file systems. +kernel to read and write MS-DOS based file systems. .Pp The most common usage follows: .Pp @@ -43,9 +41,7 @@ that looks similar to: /dev/ada0sN /dos msdosfs rw 0 0 .Ed .Pp -This will mount an -.Tn MS-DOS -based partition at the +This will mount an MS-DOS based partition at the .Pa /dos mount point during system boot. Using @@ -58,6 +54,15 @@ See for more information on .Fx directory layout. +.Sh EXAMPLES +Determine which FAT file system version (e.g, FAT16, FAT32) +is a partition formatted with: +.Bd -literal -offset indent +file -s /dev/da0s1 +.Ed +.Pp +.Xr gpart 8 +may also be used to extract this information. .Sh SEE ALSO .Xr mount 2 , .Xr unmount 2 , diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 8a0104171975..42ba5f2803ca 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,6 +1,6 @@ .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman. .\" $FreeBSD$ -.Dd September 13, 2018 +.Dd September 18, 2018 .Dt SRC.CONF 5 .Os .Sh NAME @@ -807,6 +807,14 @@ Set to build Hesiod support. Set to not build HTML docs. .It Va WITHOUT_HYPERV Set to not build or install HyperV utilities. +.Pp +This is a default setting on +arm/arm, arm/armv6, arm/armv7, arm64/aarch64, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +.It Va WITH_HYPERV +Set to build or install HyperV utilities. +.Pp +This is a default setting on +amd64/amd64 and i386/i386. .It Va WITHOUT_ICONV Set to not build iconv as part of libc. .It Va WITHOUT_INCLUDES diff --git a/share/man/man9/iflib.9 b/share/man/man9/iflib.9 index 33d0293b45fc..f833c5c44d37 100644 --- a/share/man/man9/iflib.9 +++ b/share/man/man9/iflib.9 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd May 3, 2018 +.Dd September 20, 2018 .Dt IFLIB 9 .Os .Sh NAME @@ -32,6 +32,7 @@ Device-dependent transmit and receive functions, used when writing new .Nm based drivers. .Sh SEE ALSO +.Xr iflib 4 , .Xr iflibdd 9 , .Xr iflibdi 9 , .Xr iflibtxrx 9 , diff --git a/share/mk/bsd.dirs.mk b/share/mk/bsd.dirs.mk index 72e6c2cb46f1..cdd8b09b1bc3 100644 --- a/share/mk/bsd.dirs.mk +++ b/share/mk/bsd.dirs.mk @@ -27,18 +27,29 @@ ${dir}TAG_ARGS= -T ${${dir}TAGS:[*]:S/ /,/g} . endif installdirs: installdirs-${dir} - -installdirs-${dir}: installdirs-${DESTDIR}${${dir}} - -. if !target(installdirs-${DESTDIR}${${dir}}) -installdirs-${DESTDIR}${${dir}}: - @${ECHO} installing DIRS ${dir} +# Coalesce duplicate destdirs +. if !defined(_uniquedirs_${${dir}}) +_uniquedirs_${${dir}}= ${dir} +_alldirs_${dir}= ${dir} +installdirs-${dir}: .PHONY + @${ECHO} installing DIRS ${_alldirs_${dir}} ${INSTALL} ${${dir}TAG_ARGS} -d -m ${${dir}_MODE} -o ${${dir}_OWN} \ -g ${${dir}_GRP} ${${dir}_FLAG} ${DESTDIR}${${dir}} -. endif -. endif - -realinstall: installdirs-${dir} +. else +_uniquedir:= ${_uniquedirs_${${dir}}} +_alldirs_${_uniquedir}+=${dir} +# Connect to the single target +installdirs-${dir}: installdirs-${_uniquedir} +# Validate that duplicate dirs have the same metadata. +. for v in TAG_ARGS _MODE _OWN _GRP _FLAG +. if ${${dir}${v}:Uunset} != ${${_uniquedir}${v}:Uunset} +. warning ${RELDIR}: ${dir}${v} (${${dir}${v}:U}) does not match ${_uniquedir}${v} (${${_uniquedir}${v}:U}) but both install to ${${dir}} +. endif +. endfor +. endif # !defined(_uniquedirs_${${dir}}) +. endif # defined(${dir}) && !empty(${dir}) . endfor +realinstall: installdirs + .endif diff --git a/share/mk/bsd.progs.mk b/share/mk/bsd.progs.mk index 7415092011eb..b4ba16dc5993 100644 --- a/share/mk/bsd.progs.mk +++ b/share/mk/bsd.progs.mk @@ -77,7 +77,7 @@ stage_as.prog.${_prog}: ${_prog} .ifdef _RECURSING_PROGS MK_STAGING= no -_PROGS_GLOBAL_VARS= CLEANFILES CLEANDIRS CONFGROUPS FILESGROUPS INCSGROUPS \ +_PROGS_GLOBAL_VARS= CLEANFILES CLEANDIRS CONFGROUPS DIRS FILESGROUPS INCSGROUPS \ SCRIPTS .for v in ${_PROGS_GLOBAL_VARS} $v = diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk index 486043a63bb7..145c17dff754 100644 --- a/share/mk/bsd.subdir.mk +++ b/share/mk/bsd.subdir.mk @@ -46,6 +46,7 @@ SUBDIR_TARGETS+= \ all all-man analyze buildconfig buildfiles buildincludes \ checkdpadd clean cleandepend cleandir cleanilinks \ cleanobj depend distribute files includes installconfig \ + installdirs \ installfiles installincludes print-dir realinstall \ maninstall manlint ${_obj} objlink tags \ @@ -53,7 +54,7 @@ SUBDIR_TARGETS+= \ STANDALONE_SUBDIR_TARGETS+= \ all-man buildconfig buildfiles buildincludes check checkdpadd \ clean cleandepend cleandir cleanilinks cleanobj files includes \ - installconfig installincludes installfiles print-dir \ + installconfig installdirs installincludes installfiles print-dir \ maninstall manlint obj objlink # It is safe to install in parallel when staging. diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index e1ce566815bc..f2c78a0c2426 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -254,8 +254,8 @@ PHONY_NOTMAIN = analyze afterdepend afterinstall all beforedepend beforeinstall beforelinking build build-tools buildconfig buildfiles \ buildincludes check checkdpadd clean cleandepend cleandir \ cleanobj configure depend distclean distribute exe \ - files html includes install installconfig installfiles \ - installincludes lint obj objlink objs objwarn \ + files html includes install installconfig installdirs \ + installfiles installincludes lint obj objlink objs objwarn \ realinstall tags whereobj # we don't want ${PROG} to be PHONY diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 7667b97bdf2f..02e4ed229f5d 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -111,7 +111,6 @@ __DEFAULT_YES_OPTIONS = \ GPIO \ HAST \ HTML \ - HYPERV \ ICONV \ INET \ INET6 \ @@ -359,6 +358,11 @@ BROKEN_OPTIONS+=LOADER_UBOOT .if ${__T} == "sparc64" BROKEN_OPTIONS+=LOADER_GELI LOADER_LUA .endif +# Lua in loader currently cause boot failures on powerpc. +# Further debugging is required. +.if ${__T} == "powerpc" +BROKEN_OPTIONS+=LOADER_LUA +.endif .if ${__T:Mmips64*} # profiling won't work on MIPS64 because there is only assembly for o32 @@ -373,6 +377,13 @@ __DEFAULT_NO_OPTIONS+=CXGBETOOL __DEFAULT_NO_OPTIONS+=MLX5TOOL .endif +# HyperV is currently x86-only +.if ${__T} == "amd64" || ${__T} == "i386" +__DEFAULT_YES_OPTIONS+=HYPERV +.else +__DEFAULT_NO_OPTIONS+=HYPERV +.endif + # NVME is only x86 and powerpc64 .if ${__T} == "amd64" || ${__T} == "i386" || ${__T} == "powerpc64" __DEFAULT_YES_OPTIONS+=NVME diff --git a/stand/lua/password.lua b/stand/lua/password.lua index 72466cbcadb6..4dfaf1a6525d 100644 --- a/stand/lua/password.lua +++ b/stand/lua/password.lua @@ -34,7 +34,7 @@ local screen = require("screen") local password = {} -local INCORRECT_PASSWORD = "loader: incorrect password!" +local INCORRECT_PASSWORD = "loader: incorrect password" -- Asterisks as a password mask local show_password_mask = false local twiddle_chars = {"/", "-", "\\", "|"} @@ -45,7 +45,7 @@ function password.read(prompt_length) local twiddle_pos = 1 local function draw_twiddle() - printc(" " .. twiddle_chars[twiddle_pos]) + printc(twiddle_chars[twiddle_pos]) -- Reset cursor to just after the password prompt screen.setcursor(prompt_length + 2, screen.default_y) twiddle_pos = (twiddle_pos % #twiddle_chars) + 1 @@ -87,20 +87,19 @@ function password.check() local attempts = 1 local function clear_incorrect_text_prompt() - printc("\n") - printc(string.rep(" ", #INCORRECT_PASSWORD)) + printc("\r" .. string.rep(" ", #INCORRECT_PASSWORD)) end while true do + if attempts > 1 then + clear_incorrect_text_prompt() + end screen.defcursor() printc(prompt) local read_pwd = password.read(#prompt) if pwd == nil or pwd == read_pwd then -- Clear the prompt + twiddle printc(string.rep(" ", #prompt + 5)) - if attempts > 1 then - clear_incorrect_text_prompt() - end return read_pwd end printc("\n" .. INCORRECT_PASSWORD) @@ -116,11 +115,11 @@ function password.check() end local boot_pwd = loader.getenv("bootlock_password") - compare("Boot password: ", boot_pwd) + compare("Bootlock password:", boot_pwd) local geli_prompt = loader.getenv("geom_eli_passphrase_prompt") if geli_prompt ~= nil and geli_prompt:lower() == "yes" then - local passphrase = doPrompt("GELI Passphrase: ") + local passphrase = doPrompt("GELI Passphrase:") loader.setenv("kern.geom.eli.passphrase", passphrase) end @@ -128,7 +127,7 @@ function password.check() if pwd ~= nil then core.autoboot() end - compare("Password: ", pwd) + compare("Loader password:", pwd) end return password diff --git a/sys/amd64/amd64/copyout.c b/sys/amd64/amd64/copyout.c index dce20fb27769..59b7ad5c1307 100644 --- a/sys/amd64/amd64/copyout.c +++ b/sys/amd64/amd64/copyout.c @@ -159,20 +159,41 @@ DEFINE_IFUNC(, int, copyinstr, (const void *, void *, size_t, size_t *), copyinstr_smap : copyinstr_nosmap); } -int copyin_nosmap(const void *udaddr, void *kaddr, size_t len); -int copyin_smap(const void *udaddr, void *kaddr, size_t len); +int copyin_nosmap_std(const void *udaddr, void *kaddr, size_t len); +int copyin_smap_std(const void *udaddr, void *kaddr, size_t len); +int copyin_nosmap_erms(const void *udaddr, void *kaddr, size_t len); +int copyin_smap_erms(const void *udaddr, void *kaddr, size_t len); DEFINE_IFUNC(, int, copyin, (const void *, void *, size_t), static) { - return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ? - copyin_smap : copyin_nosmap); + switch (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS)) { + case CPUID_STDEXT_SMAP: + return (copyin_smap_std); + case CPUID_STDEXT_ERMS: + return (copyin_nosmap_erms); + case CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS: + return (copyin_smap_erms); + default: + return (copyin_nosmap_std); + + } } -int copyout_nosmap(const void *kaddr, void *udaddr, size_t len); -int copyout_smap(const void *kaddr, void *udaddr, size_t len); +int copyout_nosmap_std(const void *kaddr, void *udaddr, size_t len); +int copyout_smap_std(const void *kaddr, void *udaddr, size_t len); +int copyout_nosmap_erms(const void *kaddr, void *udaddr, size_t len); +int copyout_smap_erms(const void *kaddr, void *udaddr, size_t len); DEFINE_IFUNC(, int, copyout, (const void *, void *, size_t), static) { - return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ? - copyout_smap : copyout_nosmap); + switch (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS)) { + case CPUID_STDEXT_SMAP: + return (copyout_smap_std); + case CPUID_STDEXT_ERMS: + return (copyout_nosmap_erms); + case CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS: + return (copyout_smap_erms); + default: + return (copyout_nosmap_std); + } } diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 9f43f3cfadc7..61dfd2607b40 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -648,6 +648,10 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte, struct rwlock **lockp); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static int pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); +static void pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, + vm_offset_t eva); +static void pmap_invalidate_cache_range_all(vm_offset_t sva, + vm_offset_t eva); static void pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); @@ -1418,7 +1422,7 @@ pmap_init(void) if (ppim->va == 0) continue; /* Make the direct map consistent */ - if (ppim->pa < dmaplimit && ppim->pa + ppim->sz < dmaplimit) { + if (ppim->pa < dmaplimit && ppim->pa + ppim->sz <= dmaplimit) { (void)pmap_change_attr(PHYS_TO_DMAP(ppim->pa), ppim->sz, ppim->mode); } @@ -1700,15 +1704,100 @@ pmap_invalidate_ept(pmap_t pmap) sched_unpin(); } -void -pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +static cpuset_t +pmap_invalidate_cpu_mask(pmap_t pmap) +{ + + return (pmap == kernel_pmap ? all_cpus : pmap->pm_active); +} + +static inline void +pmap_invalidate_page_pcid(pmap_t pmap, vm_offset_t va, + const bool invpcid_works1) { - cpuset_t *mask; struct invpcid_descr d; uint64_t kcr3, ucr3; uint32_t pcid; u_int cpuid, i; + cpuid = PCPU_GET(cpuid); + if (pmap == PCPU_GET(curpmap)) { + if (pmap->pm_ucr3 != PMAP_NO_CR3) { + /* + * Because pm_pcid is recalculated on a + * context switch, we must disable switching. + * Otherwise, we might use a stale value + * below. + */ + critical_enter(); + pcid = pmap->pm_pcids[cpuid].pm_pcid; + if (invpcid_works1) { + d.pcid = pcid | PMAP_PCID_USER_PT; + d.pad = 0; + d.addr = va; + invpcid(&d, INVPCID_ADDR); + } else { + kcr3 = pmap->pm_cr3 | pcid | CR3_PCID_SAVE; + ucr3 = pmap->pm_ucr3 | pcid | + PMAP_PCID_USER_PT | CR3_PCID_SAVE; + pmap_pti_pcid_invlpg(ucr3, kcr3, va); + } + critical_exit(); + } + } else + pmap->pm_pcids[cpuid].pm_gen = 0; + + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } + + /* + * The fence is between stores to pm_gen and the read of the + * pm_active mask. We need to ensure that it is impossible + * for us to miss the bit update in pm_active and + * simultaneously observe a non-zero pm_gen in + * pmap_activate_sw(), otherwise TLB update is missed. + * Without the fence, IA32 allows such an outcome. Note that + * pm_active is updated by a locked operation, which provides + * the reciprocal fence. + */ + atomic_thread_fence_seq_cst(); +} + +static void +pmap_invalidate_page_pcid_invpcid(pmap_t pmap, vm_offset_t va) +{ + + pmap_invalidate_page_pcid(pmap, va, true); +} + +static void +pmap_invalidate_page_pcid_noinvpcid(pmap_t pmap, vm_offset_t va) +{ + + pmap_invalidate_page_pcid(pmap, va, false); +} + +static void +pmap_invalidate_page_nopcid(pmap_t pmap, vm_offset_t va) +{ +} + +DEFINE_IFUNC(static, void, pmap_invalidate_page_mode, (pmap_t, vm_offset_t), + static) +{ + + if (pmap_pcid_enabled) + return (invpcid_works ? pmap_invalidate_page_pcid_invpcid : + pmap_invalidate_page_pcid_noinvpcid); + return (pmap_invalidate_page_nopcid); +} + +void +pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +{ + if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); return; @@ -1718,75 +1807,95 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va) ("pmap_invalidate_page: invalid type %d", pmap->pm_type)); sched_pin(); + smp_masked_invlpg(pmap_invalidate_cpu_mask(pmap), va, pmap); if (pmap == kernel_pmap) { invlpg(va); - mask = &all_cpus; } else { - cpuid = PCPU_GET(cpuid); - if (pmap == PCPU_GET(curpmap)) { + if (pmap == PCPU_GET(curpmap)) invlpg(va); - if (pmap_pcid_enabled && pmap->pm_ucr3 != PMAP_NO_CR3) { - /* - * Disable context switching. pm_pcid - * is recalculated on switch, which - * might make us use wrong pcid below. - */ - critical_enter(); - pcid = pmap->pm_pcids[cpuid].pm_pcid; - - if (invpcid_works) { - d.pcid = pcid | PMAP_PCID_USER_PT; - d.pad = 0; - d.addr = va; - invpcid(&d, INVPCID_ADDR); - } else { - kcr3 = pmap->pm_cr3 | pcid | - CR3_PCID_SAVE; - ucr3 = pmap->pm_ucr3 | pcid | - PMAP_PCID_USER_PT | CR3_PCID_SAVE; - pmap_pti_pcid_invlpg(ucr3, kcr3, va); - } - critical_exit(); - } - } else if (pmap_pcid_enabled) - pmap->pm_pcids[cpuid].pm_gen = 0; - if (pmap_pcid_enabled) { - CPU_FOREACH(i) { - if (cpuid != i) - pmap->pm_pcids[i].pm_gen = 0; - } - - /* - * The fence is between stores to pm_gen and the read of - * the pm_active mask. We need to ensure that it is - * impossible for us to miss the bit update in pm_active - * and simultaneously observe a non-zero pm_gen in - * pmap_activate_sw(), otherwise TLB update is missed. - * Without the fence, IA32 allows such an outcome. - * Note that pm_active is updated by a locked operation, - * which provides the reciprocal fence. - */ - atomic_thread_fence_seq_cst(); - } - mask = &pmap->pm_active; + pmap_invalidate_page_mode(pmap, va); } - smp_masked_invlpg(*mask, va, pmap); sched_unpin(); } /* 4k PTEs -- Chosen to exceed the total size of Broadwell L2 TLB */ #define PMAP_INVLPG_THRESHOLD (4 * 1024 * PAGE_SIZE) -void -pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +static void +pmap_invalidate_range_pcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, + const bool invpcid_works1) { - cpuset_t *mask; struct invpcid_descr d; - vm_offset_t addr; uint64_t kcr3, ucr3; uint32_t pcid; u_int cpuid, i; + cpuid = PCPU_GET(cpuid); + if (pmap == PCPU_GET(curpmap)) { + if (pmap->pm_ucr3 != PMAP_NO_CR3) { + critical_enter(); + pcid = pmap->pm_pcids[cpuid].pm_pcid; + if (invpcid_works1) { + d.pcid = pcid | PMAP_PCID_USER_PT; + d.pad = 0; + d.addr = sva; + for (; d.addr < eva; d.addr += PAGE_SIZE) + invpcid(&d, INVPCID_ADDR); + } else { + kcr3 = pmap->pm_cr3 | pcid | CR3_PCID_SAVE; + ucr3 = pmap->pm_ucr3 | pcid | + PMAP_PCID_USER_PT | CR3_PCID_SAVE; + pmap_pti_pcid_invlrng(ucr3, kcr3, sva, eva); + } + critical_exit(); + } + } else + pmap->pm_pcids[cpuid].pm_gen = 0; + + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } + /* See the comment in pmap_invalidate_page_pcid(). */ + atomic_thread_fence_seq_cst(); +} + +static void +pmap_invalidate_range_pcid_invpcid(pmap_t pmap, vm_offset_t sva, + vm_offset_t eva) +{ + + pmap_invalidate_range_pcid(pmap, sva, eva, true); +} + +static void +pmap_invalidate_range_pcid_noinvpcid(pmap_t pmap, vm_offset_t sva, + vm_offset_t eva) +{ + + pmap_invalidate_range_pcid(pmap, sva, eva, false); +} + +static void +pmap_invalidate_range_nopcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ +} + +DEFINE_IFUNC(static, void, pmap_invalidate_range_mode, (pmap_t, vm_offset_t, + vm_offset_t), static) +{ + + if (pmap_pcid_enabled) + return (invpcid_works ? pmap_invalidate_range_pcid_invpcid : + pmap_invalidate_range_pcid_noinvpcid); + return (pmap_invalidate_range_nopcid); +} + +void +pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) +{ + vm_offset_t addr; + if (eva - sva >= PMAP_INVLPG_THRESHOLD) { pmap_invalidate_all(pmap); return; @@ -1801,60 +1910,107 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) ("pmap_invalidate_range: invalid type %d", pmap->pm_type)); sched_pin(); - cpuid = PCPU_GET(cpuid); + smp_masked_invlpg_range(pmap_invalidate_cpu_mask(pmap), sva, eva, pmap); if (pmap == kernel_pmap) { for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); - mask = &all_cpus; } else { if (pmap == PCPU_GET(curpmap)) { for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); - if (pmap_pcid_enabled && pmap->pm_ucr3 != PMAP_NO_CR3) { - critical_enter(); - pcid = pmap->pm_pcids[cpuid].pm_pcid; - if (invpcid_works) { - d.pcid = pcid | PMAP_PCID_USER_PT; - d.pad = 0; - d.addr = sva; - for (; d.addr < eva; d.addr += - PAGE_SIZE) - invpcid(&d, INVPCID_ADDR); - } else { - kcr3 = pmap->pm_cr3 | pcid | - CR3_PCID_SAVE; - ucr3 = pmap->pm_ucr3 | pcid | - PMAP_PCID_USER_PT | CR3_PCID_SAVE; - pmap_pti_pcid_invlrng(ucr3, kcr3, sva, - eva); - } - critical_exit(); - } - } else if (pmap_pcid_enabled) { - pmap->pm_pcids[cpuid].pm_gen = 0; } - if (pmap_pcid_enabled) { - CPU_FOREACH(i) { - if (cpuid != i) - pmap->pm_pcids[i].pm_gen = 0; - } - /* See the comment in pmap_invalidate_page(). */ - atomic_thread_fence_seq_cst(); - } - mask = &pmap->pm_active; + pmap_invalidate_range_mode(pmap, sva, eva); } - smp_masked_invlpg_range(*mask, sva, eva, pmap); sched_unpin(); } +static inline void +pmap_invalidate_all_pcid(pmap_t pmap, bool invpcid_works1) +{ + struct invpcid_descr d; + uint64_t kcr3, ucr3; + uint32_t pcid; + u_int cpuid, i; + + if (pmap == kernel_pmap) { + if (invpcid_works1) { + bzero(&d, sizeof(d)); + invpcid(&d, INVPCID_CTXGLOB); + } else { + invltlb_glob(); + } + } else { + cpuid = PCPU_GET(cpuid); + if (pmap == PCPU_GET(curpmap)) { + critical_enter(); + pcid = pmap->pm_pcids[cpuid].pm_pcid; + if (invpcid_works1) { + d.pcid = pcid; + d.pad = 0; + d.addr = 0; + invpcid(&d, INVPCID_CTX); + if (pmap->pm_ucr3 != PMAP_NO_CR3) { + d.pcid |= PMAP_PCID_USER_PT; + invpcid(&d, INVPCID_CTX); + } + } else { + kcr3 = pmap->pm_cr3 | pcid; + ucr3 = pmap->pm_ucr3; + if (ucr3 != PMAP_NO_CR3) { + ucr3 |= pcid | PMAP_PCID_USER_PT; + pmap_pti_pcid_invalidate(ucr3, kcr3); + } else { + load_cr3(kcr3); + } + } + critical_exit(); + } else + pmap->pm_pcids[cpuid].pm_gen = 0; + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } + } + /* See the comment in pmap_invalidate_page_pcid(). */ + atomic_thread_fence_seq_cst(); +} + +static void +pmap_invalidate_all_pcid_invpcid(pmap_t pmap) +{ + + pmap_invalidate_all_pcid(pmap, true); +} + +static void +pmap_invalidate_all_pcid_noinvpcid(pmap_t pmap) +{ + + pmap_invalidate_all_pcid(pmap, false); +} + +static void +pmap_invalidate_all_nopcid(pmap_t pmap) +{ + + if (pmap == kernel_pmap) + invltlb_glob(); + else if (pmap == PCPU_GET(curpmap)) + invltlb(); +} + +DEFINE_IFUNC(static, void, pmap_invalidate_all_mode, (pmap_t), static) +{ + + if (pmap_pcid_enabled) + return (invpcid_works ? pmap_invalidate_all_pcid_invpcid : + pmap_invalidate_all_pcid_noinvpcid); + return (pmap_invalidate_all_nopcid); +} + void pmap_invalidate_all(pmap_t pmap) { - cpuset_t *mask; - struct invpcid_descr d; - uint64_t kcr3, ucr3; - uint32_t pcid; - u_int cpuid, i; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -1865,58 +2021,8 @@ pmap_invalidate_all(pmap_t pmap) ("pmap_invalidate_all: invalid type %d", pmap->pm_type)); sched_pin(); - if (pmap == kernel_pmap) { - if (pmap_pcid_enabled && invpcid_works) { - bzero(&d, sizeof(d)); - invpcid(&d, INVPCID_CTXGLOB); - } else { - invltlb_glob(); - } - mask = &all_cpus; - } else { - cpuid = PCPU_GET(cpuid); - if (pmap == PCPU_GET(curpmap)) { - if (pmap_pcid_enabled) { - critical_enter(); - pcid = pmap->pm_pcids[cpuid].pm_pcid; - if (invpcid_works) { - d.pcid = pcid; - d.pad = 0; - d.addr = 0; - invpcid(&d, INVPCID_CTX); - if (pmap->pm_ucr3 != PMAP_NO_CR3) { - d.pcid |= PMAP_PCID_USER_PT; - invpcid(&d, INVPCID_CTX); - } - } else { - kcr3 = pmap->pm_cr3 | pcid; - ucr3 = pmap->pm_ucr3; - if (ucr3 != PMAP_NO_CR3) { - ucr3 |= pcid | PMAP_PCID_USER_PT; - pmap_pti_pcid_invalidate(ucr3, - kcr3); - } else { - load_cr3(kcr3); - } - } - critical_exit(); - } else { - invltlb(); - } - } else if (pmap_pcid_enabled) { - pmap->pm_pcids[cpuid].pm_gen = 0; - } - if (pmap_pcid_enabled) { - CPU_FOREACH(i) { - if (cpuid != i) - pmap->pm_pcids[i].pm_gen = 0; - } - /* See the comment in pmap_invalidate_page(). */ - atomic_thread_fence_seq_cst(); - } - mask = &pmap->pm_active; - } - smp_masked_invltlb(*mask, pmap); + smp_masked_invltlb(pmap_invalidate_cpu_mask(pmap), pmap); + pmap_invalidate_all_mode(pmap); sched_unpin(); } @@ -2171,36 +2277,62 @@ pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde) pmap_invalidate_page(pmap, va); } -#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) - -void -pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) +DEFINE_IFUNC(, void, pmap_invalidate_cache_range, + (vm_offset_t sva, vm_offset_t eva), static) { - if (force) { - sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); - } else { - KASSERT((sva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: sva not page-aligned")); - KASSERT((eva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: eva not page-aligned")); + if ((cpu_feature & CPUID_SS) != 0) + return (pmap_invalidate_cache_range_selfsnoop); + if ((cpu_feature & CPUID_CLFSH) != 0) + return (pmap_force_invalidate_cache_range); + return (pmap_invalidate_cache_range_all); +} + +#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) + +static void +pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva) +{ + + KASSERT((sva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: sva not page-aligned")); + KASSERT((eva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: eva not page-aligned")); +} + +static void +pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); +} + +void +pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) +{ + + sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); + if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) { + /* + * The supplied range is bigger than 2MB. + * Globally invalidate cache. + */ + pmap_invalidate_cache(); + return; } - if ((cpu_feature & CPUID_SS) != 0 && !force) - ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { - /* - * XXX: Some CPUs fault, hang, or trash the local APIC - * registers if we use CLFLUSH on the local APIC - * range. The local APIC is always uncached, so we - * don't need to flush for that range anyway. - */ - if (pmap_kextract(sva) == lapic_paddr) - return; + /* + * XXX: Some CPUs fault, hang, or trash the local APIC + * registers if we use CLFLUSH on the local APIC range. The + * local APIC is always uncached, so we don't need to flush + * for that range anyway. + */ + if (pmap_kextract(sva) == lapic_paddr) + return; + if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) { /* - * Otherwise, do per-cache line flush. Use the sfence + * Do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache @@ -2210,10 +2342,7 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) for (; sva < eva; sva += cpu_clflush_line_size) clflushopt(sva); sfence(); - } else if ((cpu_feature & CPUID_CLFSH) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { - if (pmap_kextract(sva) == lapic_paddr) - return; + } else { /* * Writes are ordered by CLFLUSH on Intel CPUs. */ @@ -2223,17 +2352,17 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) clflush(sva); if (cpu_vendor_id != CPU_VENDOR_INTEL) mfence(); - } else { - - /* - * No targeted cache flush methods are supported by CPU, - * or the supplied range is bigger than 2MB. - * Globally invalidate cache. - */ - pmap_invalidate_cache(); } } +static void +pmap_invalidate_cache_range_all(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); + pmap_invalidate_cache(); +} + /* * Remove the specified set of pages from the data and instruction caches. * @@ -6926,7 +7055,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) * If the specified range of physical addresses fits within * the direct map window, use the direct map. */ - if (pa < dmaplimit && pa + size < dmaplimit) { + if (pa < dmaplimit && pa + size <= dmaplimit) { va = PHYS_TO_DMAP(pa); if (!pmap_change_attr(va, size, mode)) return ((void *)(va + offset)); @@ -6938,7 +7067,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); - pmap_invalidate_cache_range(va, va + tmpsize, FALSE); + pmap_invalidate_cache_range(va, va + tmpsize); return ((void *)(va + offset)); } @@ -7297,7 +7426,7 @@ pmap_change_attr_locked(vm_offset_t va, vm_size_t size, int mode) */ if (changed) { pmap_invalidate_range(kernel_pmap, base, tmpva); - pmap_invalidate_cache_range(base, tmpva, FALSE); + pmap_invalidate_cache_range(base, tmpva); } return (error); } @@ -7442,8 +7571,7 @@ pmap_pcid_alloc_checked(pmap_t pmap, u_int cpuid) uint64_t cached; cached = pmap_pcid_alloc(pmap, cpuid); - KASSERT(pmap->pm_pcids[cpuid].pm_pcid >= 0 && - pmap->pm_pcids[cpuid].pm_pcid < PMAP_PCID_OVERMAX, + KASSERT(pmap->pm_pcids[cpuid].pm_pcid < PMAP_PCID_OVERMAX, ("pmap %p cpu %d pcid %#x", pmap, cpuid, pmap->pm_pcids[cpuid].pm_pcid)); KASSERT(pmap->pm_pcids[cpuid].pm_pcid != PMAP_PCID_KERN || diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index bc849b21d965..be92ff2d7234 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -100,6 +100,100 @@ ENTRY(sse2_pagezero) ret END(sse2_pagezero) +/* + * memcmpy(b1, b2, len) + * rdi,rsi,len + */ +ENTRY(memcmp) + PUSH_FRAME_POINTER + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax + POP_FRAME_POINTER + ret +4: + subl %r8d,%eax + POP_FRAME_POINTER + ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 1b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 1b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 1b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b +END(memcmp) + /* * memmove(dst, src, cnt) * rdi, rsi, rdx @@ -116,6 +210,8 @@ ENTRY(memmove_std) cmpq %rcx,%r8 /* overlapping && src < dst? */ jb 2f + cmpq $15,%rcx + jbe 1f shrq $3,%rcx /* copy by 64-bit words */ rep movsq @@ -124,6 +220,7 @@ ENTRY(memmove_std) jne 1f POP_FRAME_POINTER ret + ALIGN_TEXT 1: rep movsb @@ -191,6 +288,8 @@ ENTRY(memcpy_std) PUSH_FRAME_POINTER movq %rdi,%rax movq %rdx,%rcx + cmpq $15,%rcx + jbe 1f shrq $3,%rcx /* copy by 64-bit words */ rep movsq @@ -199,6 +298,7 @@ ENTRY(memcpy_std) jne 1f POP_FRAME_POINTER ret + ALIGN_TEXT 1: rep movsb @@ -227,6 +327,8 @@ ENTRY(memset_std) movzbq %sil,%r8 movabs $0x0101010101010101,%rax imulq %r8,%rax + cmpq $15,%rcx + jbe 1f shrq $3,%rcx rep stosq @@ -236,6 +338,7 @@ ENTRY(memset_std) movq %r9,%rax POP_FRAME_POINTER ret + ALIGN_TEXT 1: rep stosb @@ -281,62 +384,27 @@ END(fillw) * returns to *curpcb->pcb_onfault instead of the function. */ +.macro SMAP_DISABLE smap +.if \smap + stac +.endif +.endm + + +.macro SMAP_ENABLE smap +.if \smap + clac +.endif +.endm + /* * copyout(from_kernel, to_user, len) * %rdi, %rsi, %rdx */ -ENTRY(copyout_nosmap) +.macro COPYOUT smap erms PUSH_FRAME_POINTER - movq PCPU(CURPCB),%rax - movq $copyout_fault,PCB_ONFAULT(%rax) - testq %rdx,%rdx /* anything to do? */ - jz done_copyout - - /* - * Check explicitly for non-user addresses. This check is essential - * because it prevents usermode from writing into the kernel. We do - * not verify anywhere else that the user did not specify a rogue - * address. - */ - /* - * First, prevent address wrapping. - */ - movq %rsi,%rax - addq %rdx,%rax - jc copyout_fault -/* - * XXX STOP USING VM_MAXUSER_ADDRESS. - * It is an end address, not a max, so every time it is used correctly it - * looks like there is an off by one error, and of course it caused an off - * by one error in several places. - */ - movq $VM_MAXUSER_ADDRESS,%rcx - cmpq %rcx,%rax - ja copyout_fault - - xchgq %rdi,%rsi - /* bcopy(%rsi, %rdi, %rdx) */ - movq %rdx,%rcx - - shrq $3,%rcx - rep - movsq - movb %dl,%cl - andb $7,%cl - je done_copyout - rep - movsb - - jmp done_copyout -END(copyout_nosmap) - -ENTRY(copyout_smap) - PUSH_FRAME_POINTER - movq PCPU(CURPCB),%rax - /* Trap entry clears PSL.AC */ - movq $copyout_fault,PCB_ONFAULT(%rax) - testq %rdx,%rdx /* anything to do? */ - jz done_copyout + movq PCPU(CURPCB),%r9 + movq $copy_fault,PCB_ONFAULT(%r9) /* * Check explicitly for non-user addresses. If 486 write protection @@ -350,7 +418,7 @@ ENTRY(copyout_smap) */ movq %rsi,%rax addq %rdx,%rax - jc copyout_fault + jc copy_fault /* * XXX STOP USING VM_MAXUSER_ADDRESS. * It is an end address, not a max, so every time it is used correctly it @@ -359,119 +427,137 @@ ENTRY(copyout_smap) */ movq $VM_MAXUSER_ADDRESS,%rcx cmpq %rcx,%rax - ja copyout_fault + ja copy_fault - xchgq %rdi,%rsi - /* bcopy(%rsi, %rdi, %rdx) */ + /* + * Set up arguments for rep movs*. + */ + movq %rdi,%r8 + movq %rsi,%rdi + movq %r8,%rsi movq %rdx,%rcx + /* + * Set return value to zero. Remaining failure mode goes through + * copy_fault. + */ + xorl %eax,%eax + + SMAP_DISABLE \smap +.if \erms == 0 + cmpq $15,%rcx + jbe 1f shrq $3,%rcx - stac rep movsq movb %dl,%cl andb $7,%cl - je 1f + jne 1f + SMAP_ENABLE \smap + movq %rax,PCB_ONFAULT(%r9) + POP_FRAME_POINTER + ret +.endif + ALIGN_TEXT +1: rep movsb -1: clac -done_copyout: - xorl %eax,%eax - movq PCPU(CURPCB),%rdx - movq %rax,PCB_ONFAULT(%rdx) + SMAP_ENABLE \smap + movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret +.endm - ALIGN_TEXT -copyout_fault: - movq PCPU(CURPCB),%rdx - movq $0,PCB_ONFAULT(%rdx) - movq $EFAULT,%rax - POP_FRAME_POINTER - ret -END(copyout_smap) +ENTRY(copyout_nosmap_std) + COPYOUT smap=0 erms=0 +END(copyout_nosmap_std) + +ENTRY(copyout_smap_std) + COPYOUT smap=1 erms=0 +END(copyout_smap_std) + +ENTRY(copyout_nosmap_erms) + COPYOUT smap=0 erms=1 +END(copyout_nosmap_erms) + +ENTRY(copyout_smap_erms) + COPYOUT smap=1 erms=1 +END(copyout_smap_erms) /* * copyin(from_user, to_kernel, len) * %rdi, %rsi, %rdx */ -ENTRY(copyin_nosmap) +.macro COPYIN smap erms PUSH_FRAME_POINTER - movq PCPU(CURPCB),%rax - movq $copyin_fault,PCB_ONFAULT(%rax) - testq %rdx,%rdx /* anything to do? */ - jz done_copyin + movq PCPU(CURPCB),%r9 + movq $copy_fault,PCB_ONFAULT(%r9) /* * make sure address is valid */ movq %rdi,%rax addq %rdx,%rax - jc copyin_fault + jc copy_fault movq $VM_MAXUSER_ADDRESS,%rcx cmpq %rcx,%rax - ja copyin_fault + ja copy_fault - xchgq %rdi,%rsi + movq %rdi,%r8 + movq %rsi,%rdi + movq %r8,%rsi movq %rdx,%rcx - movb %cl,%al - shrq $3,%rcx /* copy longword-wise */ - rep - movsq - movb %al,%cl - andb $7,%cl /* copy remaining bytes */ - je done_copyin - rep - movsb - jmp done_copyin -END(copyin_nosmap) - -ENTRY(copyin_smap) - PUSH_FRAME_POINTER - movq PCPU(CURPCB),%rax - movq $copyin_fault,PCB_ONFAULT(%rax) - testq %rdx,%rdx /* anything to do? */ - jz done_copyin - - /* - * make sure address is valid - */ - movq %rdi,%rax - addq %rdx,%rax - jc copyin_fault - movq $VM_MAXUSER_ADDRESS,%rcx - cmpq %rcx,%rax - ja copyin_fault - - xchgq %rdi,%rsi - movq %rdx,%rcx - movb %cl,%al - shrq $3,%rcx /* copy longword-wise */ - stac - rep - movsq - movb %al,%cl - andb $7,%cl /* copy remaining bytes */ - je 1f - rep - movsb -1: clac - -done_copyin: xorl %eax,%eax - movq PCPU(CURPCB),%rdx - movq %rax,PCB_ONFAULT(%rdx) + + SMAP_DISABLE \smap +.if \erms == 0 + cmpq $15,%rcx + jbe 1f + shrq $3,%rcx /* copy longword-wise */ + rep + movsq + movb %dl,%cl + andb $7,%cl /* copy remaining bytes */ + jne 1f + SMAP_ENABLE \smap + movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret -END(copyin_smap) +.endif + ALIGN_TEXT +1: + rep + movsb + + SMAP_ENABLE \smap + movq %rax,PCB_ONFAULT(%r9) + POP_FRAME_POINTER + ret +.endm + +ENTRY(copyin_nosmap_std) + COPYIN smap=0 erms=0 +END(copyin_nosmap_std) + +ENTRY(copyin_smap_std) + COPYIN smap=1 erms=0 +END(copyin_smap_std) + +ENTRY(copyin_nosmap_erms) + COPYIN smap=0 erms=1 +END(copyin_nosmap_erms) + +ENTRY(copyin_smap_erms) + COPYIN smap=1 erms=1 +END(copyin_smap_erms) ALIGN_TEXT -copyin_fault: - movq PCPU(CURPCB),%rdx - movq $0,PCB_ONFAULT(%rdx) - movq $EFAULT,%rax + /* Trap entry clears PSL.AC */ +copy_fault: + movq $0,PCB_ONFAULT(%r9) + movl $EFAULT,%eax POP_FRAME_POINTER ret @@ -755,16 +841,6 @@ ENTRY(fubyte_smap) ret END(fubyte_smap) - ALIGN_TEXT - /* Fault entry clears PSL.AC */ -fusufault: - movq PCPU(CURPCB),%rcx - xorl %eax,%eax - movq %rax,PCB_ONFAULT(%rcx) - decq %rax - POP_FRAME_POINTER - ret - /* * Store a 64-bit word, a 32-bit word, a 16-bit word, or an 8-bit byte to * user memory. @@ -916,6 +992,16 @@ ENTRY(subyte_smap) ret END(subyte_smap) + ALIGN_TEXT + /* Fault entry clears PSL.AC */ +fusufault: + movq PCPU(CURPCB),%rcx + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%rcx) + decq %rax + POP_FRAME_POINTER + ret + /* * copyinstr(from, to, maxlen, int *lencopied) * %rdi, %rsi, %rdx, %rcx @@ -925,96 +1011,86 @@ END(subyte_smap) * EFAULT on protection violations. If lencopied is non-zero, * return the actual length in *lencopied. */ -ENTRY(copyinstr_nosmap) +.macro COPYINSTR smap PUSH_FRAME_POINTER movq %rdx,%r8 /* %r8 = maxlen */ - movq %rcx,%r9 /* %r9 = *len */ - xchgq %rdi,%rsi /* %rdi = from, %rsi = to */ - movq PCPU(CURPCB),%rcx - movq $cpystrflt,PCB_ONFAULT(%rcx) + movq PCPU(CURPCB),%r9 + movq $cpystrflt,PCB_ONFAULT(%r9) movq $VM_MAXUSER_ADDRESS,%rax /* make sure 'from' is within bounds */ - subq %rsi,%rax + subq %rdi,%rax jbe cpystrflt + SMAP_DISABLE \smap + /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */ cmpq %rdx,%rax - jae 1f - movq %rax,%rdx - movq %rax,%r8 + jb 8f 1: incq %rdx - 2: decq %rdx +.if \smap == 0 jz copyinstr_toolong - - lodsb - stosb - orb %al,%al - jnz 2b - - jmp copyinstr_succ -END(copyinstr_nosmap) - -ENTRY(copyinstr_smap) - PUSH_FRAME_POINTER - movq %rdx,%r8 /* %r8 = maxlen */ - movq %rcx,%r9 /* %r9 = *len */ - xchgq %rdi,%rsi /* %rdi = from, %rsi = to */ - movq PCPU(CURPCB),%rcx - movq $cpystrflt,PCB_ONFAULT(%rcx) - - movq $VM_MAXUSER_ADDRESS,%rax - - /* make sure 'from' is within bounds */ - subq %rsi,%rax - jbe cpystrflt - - stac - - /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */ - cmpq %rdx,%rax - jae 1f - movq %rax,%rdx - movq %rax,%r8 -1: - incq %rdx - -2: - decq %rdx +.else jz copyinstr_toolong_smap +.endif - lodsb - stosb - orb %al,%al + movb (%rdi),%al + movb %al,(%rsi) + incq %rsi + incq %rdi + testb %al,%al jnz 2b - clac + SMAP_ENABLE \smap -copyinstr_succ: /* Success -- 0 byte reached */ decq %rdx xorl %eax,%eax + /* set *lencopied and return %eax */ + movq %rax,PCB_ONFAULT(%r9) + + testq %rcx,%rcx + jz 3f + subq %rdx,%r8 + movq %r8,(%rcx) +3: + POP_FRAME_POINTER + ret + ALIGN_TEXT +8: + movq %rax,%rdx + movq %rax,%r8 + jmp 1b + +.endm + +ENTRY(copyinstr_nosmap) + COPYINSTR smap=0 +END(copyinstr_nosmap) + +ENTRY(copyinstr_smap) + COPYINSTR smap=1 +END(copyinstr_smap) + +cpystrflt: + /* Fault entry clears PSL.AC */ + movl $EFAULT,%eax cpystrflt_x: /* set *lencopied and return %eax */ - movq PCPU(CURPCB),%rcx - movq $0,PCB_ONFAULT(%rcx) + movq $0,PCB_ONFAULT(%r9) - testq %r9,%r9 + testq %rcx,%rcx jz 1f subq %rdx,%r8 - movq %r8,(%r9) + movq %r8,(%rcx) 1: POP_FRAME_POINTER ret - /* Fault entry clears PSL.AC */ -cpystrflt: - movq $EFAULT,%rax - jmp cpystrflt_x copyinstr_toolong_smap: clac @@ -1023,11 +1099,9 @@ copyinstr_toolong: movq $VM_MAXUSER_ADDRESS,%rax cmpq %rax,%rsi jae cpystrflt - movq $ENAMETOOLONG,%rax + movl $ENAMETOOLONG,%eax jmp cpystrflt_x -END(copyinstr_smap) - /* * copystr(from, to, maxlen, int *lencopied) * %rdi, %rsi, %rdx, %rcx @@ -1036,34 +1110,33 @@ ENTRY(copystr) PUSH_FRAME_POINTER movq %rdx,%r8 /* %r8 = maxlen */ - xchgq %rdi,%rsi - incq %rdx + incq %rdx 1: decq %rdx jz 4f - lodsb - stosb - orb %al,%al + movb (%rdi),%al + movb %al,(%rsi) + incq %rsi + incq %rdi + testb %al,%al jnz 1b /* Success -- 0 byte reached */ decq %rdx xorl %eax,%eax - jmp 6f -4: - /* rdx is zero -- return ENAMETOOLONG */ - movq $ENAMETOOLONG,%rax - -6: - +2: testq %rcx,%rcx - jz 7f + jz 3f /* set *lencopied and return %rax */ subq %rdx,%r8 movq %r8,(%rcx) -7: +3: POP_FRAME_POINTER ret +4: + /* rdx is zero -- return ENAMETOOLONG */ + movl $ENAMETOOLONG,%eax + jmp 2b END(copystr) /* diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 72b9b3e78d96..1a8e5d23ff3a 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -659,12 +659,6 @@ trap(struct trapframe *frame) KASSERT((read_rflags() & PSL_I) != 0, ("interrupts disabled")); trapsignal(td, &ksi); - /* - * Clear any pending debug exceptions after allowing a - * debugger to read DR6 while stopped in trapsignal(). - */ - if (type == T_TRCTRAP) - load_dr6(0); userret: userret(td, frame); KASSERT(PCB_USER_FPU(td->td_pcb), diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 34c3fb868ce3..5b83307bbb68 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -431,8 +431,8 @@ void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); void pmap_invalidate_all(pmap_t); void pmap_invalidate_cache(void); void pmap_invalidate_cache_pages(vm_page_t *pages, int count); -void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, - boolean_t force); +void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); +void pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); void pmap_get_mapping(pmap_t pmap, vm_offset_t va, uint64_t *ptr, int *num); boolean_t pmap_map_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t); void pmap_unmap_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t); diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 6b8a14224874..b66eda0f4768 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -557,6 +557,7 @@ enum vm_exitcode { VM_EXITCODE_SVM, VM_EXITCODE_REQIDLE, VM_EXITCODE_DEBUG, + VM_EXITCODE_VMINSN, VM_EXITCODE_MAX }; diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index b40846cae6e6..61871e9338eb 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -267,6 +267,9 @@ SDT_PROBE_DEFINE3(vmm, vmx, exit, monitor, SDT_PROBE_DEFINE3(vmm, vmx, exit, mwait, "struct vmx *", "int", "struct vm_exit *"); +SDT_PROBE_DEFINE3(vmm, vmx, exit, vminsn, + "struct vmx *", "int", "struct vm_exit *"); + SDT_PROBE_DEFINE4(vmm, vmx, exit, unknown, "struct vmx *", "int", "struct vm_exit *", "uint32_t"); @@ -2638,6 +2641,19 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) SDT_PROBE3(vmm, vmx, exit, mwait, vmx, vcpu, vmexit); vmexit->exitcode = VM_EXITCODE_MWAIT; break; + case EXIT_REASON_VMCALL: + case EXIT_REASON_VMCLEAR: + case EXIT_REASON_VMLAUNCH: + case EXIT_REASON_VMPTRLD: + case EXIT_REASON_VMPTRST: + case EXIT_REASON_VMREAD: + case EXIT_REASON_VMRESUME: + case EXIT_REASON_VMWRITE: + case EXIT_REASON_VMXOFF: + case EXIT_REASON_VMXON: + SDT_PROBE3(vmm, vmx, exit, vminsn, vmx, vcpu, vmexit); + vmexit->exitcode = VM_EXITCODE_VMINSN; + break; default: SDT_PROBE4(vmm, vmx, exit, unknown, vmx, vcpu, vmexit, reason); diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 6f0e0b2b9554..aecd21f13b4a 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -1737,6 +1737,7 @@ vm_run(struct vm *vm, struct vm_run *vmrun) break; case VM_EXITCODE_MONITOR: case VM_EXITCODE_MWAIT: + case VM_EXITCODE_VMINSN: vm_inject_ud(vm, vcpuid); break; default: diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index a79490441e91..286b4358f4a5 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include <machine/atomic.h> #include <machine/cpu.h> #include <machine/cpufunc.h> +#include <machine/undefined.h> static int ident_lock; @@ -87,6 +88,7 @@ struct cpu_desc { }; struct cpu_desc cpu_desc[MAXCPU]; +struct cpu_desc user_cpu_desc; static u_int cpu_print_regs; #define PRINT_ID_AA64_AFR0 0x00000001 #define PRINT_ID_AA64_AFR1 0x00000002 @@ -162,14 +164,211 @@ const struct cpu_implementers cpu_implementers[] = { CPU_IMPLEMENTER_NONE, }; +#define MRS_TYPE_MASK 0xf +#define MRS_INVALID 0 +#define MRS_EXACT 1 +#define MRS_EXACT_VAL(x) (MRS_EXACT | ((x) << 4)) +#define MRS_EXACT_FIELD(x) ((x) >> 4) +#define MRS_LOWER 2 + +struct mrs_field { + bool sign; + u_int type; + u_int shift; +}; + +#define MRS_FIELD(_sign, _type, _shift) \ + { \ + .sign = (_sign), \ + .type = (_type), \ + .shift = (_shift), \ + } + +#define MRS_FIELD_END { .type = MRS_INVALID, } + +static struct mrs_field id_aa64pfr0_fields[] = { + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_SVE_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_RAS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_GIC_SHIFT), + MRS_FIELD(true, MRS_LOWER, ID_AA64PFR0_ADV_SIMD_SHIFT), + MRS_FIELD(true, MRS_LOWER, ID_AA64PFR0_FP_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_EL3_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_EL2_SHIFT), + MRS_FIELD(false, MRS_LOWER, ID_AA64PFR0_EL1_SHIFT), + MRS_FIELD(false, MRS_LOWER, ID_AA64PFR0_EL0_SHIFT), + MRS_FIELD_END, +}; + +static struct mrs_field id_aa64dfr0_fields[] = { + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_PMS_VER_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_CTX_CMPS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_WRPS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_BRPS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_PMU_VER_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_TRACE_VER_SHIFT), + MRS_FIELD(false, MRS_EXACT_VAL(0x6), ID_AA64DFR0_DEBUG_VER_SHIFT), + MRS_FIELD_END, +}; + +struct mrs_user_reg { + u_int CRm; + u_int Op2; + size_t offset; + struct mrs_field *fields; +}; + +static struct mrs_user_reg user_regs[] = { + { /* id_aa64pfr0_el1 */ + .CRm = 4, + .Op2 = 0, + .offset = __offsetof(struct cpu_desc, id_aa64pfr0), + .fields = id_aa64pfr0_fields, + }, + { /* id_aa64dfr0_el1 */ + .CRm = 5, + .Op2 = 0, + .offset = __offsetof(struct cpu_desc, id_aa64dfr0), + .fields = id_aa64dfr0_fields, + }, +}; + +#define CPU_DESC_FIELD(desc, idx) \ + *(uint64_t *)((char *)&(desc) + user_regs[(idx)].offset) + +static int +user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, + uint32_t esr) +{ + uint64_t value; + int CRm, Op2, i, reg; + + if ((insn & MRS_MASK) != MRS_VALUE) + return (0); + + /* + * We only emulate Op0 == 3, Op1 == 0, CRn == 0, CRm == {0, 4-7}. + * These are in the EL1 CPU identification space. + * CRm == 0 holds MIDR_EL1, MPIDR_EL1, and REVID_EL1. + * CRm == {4-7} holds the ID_AA64 registers. + * + * For full details see the ARMv8 ARM (ARM DDI 0487C.a) + * Table D9-2 System instruction encodings for non-Debug System + * register accesses. + */ + if (mrs_Op0(insn) != 3 || mrs_Op1(insn) != 0 || mrs_CRn(insn) != 0) + return (0); + + CRm = mrs_CRm(insn); + if (CRm > 7 || (CRm < 4 && CRm != 0)) + return (0); + + Op2 = mrs_Op2(insn); + value = 0; + + for (i = 0; i < nitems(user_regs); i++) { + if (user_regs[i].CRm == CRm && user_regs[i].Op2 == Op2) { + value = CPU_DESC_FIELD(user_cpu_desc, i); + break; + } + } + + if (CRm == 0) { + switch (Op2) { + case 0: + value = READ_SPECIALREG(midr_el1); + break; + case 5: + value = READ_SPECIALREG(mpidr_el1); + break; + case 6: + value = READ_SPECIALREG(revidr_el1); + break; + default: + return (0); + } + } + + /* + * We will handle this instruction, move to the next so we + * don't trap here again. + */ + frame->tf_elr += INSN_SIZE; + + reg = MRS_REGISTER(insn); + /* If reg is 31 then write to xzr, i.e. do nothing */ + if (reg == 31) + return (1); + + if (reg < nitems(frame->tf_x)) + frame->tf_x[reg] = value; + else if (reg == 30) + frame->tf_lr = value; + + return (1); +} + +static void +update_user_regs(u_int cpu) +{ + struct mrs_field *fields; + uint64_t cur, value; + int i, j, cur_field, new_field; + + for (i = 0; i < nitems(user_regs); i++) { + value = CPU_DESC_FIELD(cpu_desc[cpu], i); + if (cpu == 0) + cur = value; + else + cur = CPU_DESC_FIELD(user_cpu_desc, i); + + fields = user_regs[i].fields; + for (j = 0; fields[j].type != 0; j++) { + switch (fields[j].type & MRS_TYPE_MASK) { + case MRS_EXACT: + cur &= ~(0xfu << fields[j].shift); + cur |= + (uint64_t)MRS_EXACT_FIELD(fields[j].type) << + fields[j].shift; + break; + case MRS_LOWER: + new_field = (value >> fields[j].shift) & 0xf; + cur_field = (cur >> fields[j].shift) & 0xf; + if ((fields[j].sign && + (int)new_field < (int)cur_field) || + (!fields[j].sign && + (u_int)new_field < (u_int)cur_field)) { + cur &= ~(0xfu << fields[j].shift); + cur |= new_field << fields[j].shift; + } + break; + default: + panic("Invalid field type: %d", fields[j].type); + } + } + + CPU_DESC_FIELD(user_cpu_desc, i) = cur; + } +} + static void identify_cpu_sysinit(void *dummy __unused) { int cpu; + /* Create a user visible cpu description with safe values */ + memset(&user_cpu_desc, 0, sizeof(user_cpu_desc)); + /* Safe values for these registers */ + user_cpu_desc.id_aa64pfr0 = ID_AA64PFR0_ADV_SIMD_NONE | + ID_AA64PFR0_FP_NONE | ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64; + user_cpu_desc.id_aa64dfr0 = ID_AA64DFR0_DEBUG_VER_8; + + CPU_FOREACH(cpu) { print_cpu_features(cpu); + update_user_regs(cpu); } + + install_undef_handler(true, user_mrs_handler); } SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL); diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index dc243c958a63..e82b9e4ab0bf 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -236,7 +236,7 @@ fill_fpregs(struct thread *td, struct fpreg *regs) regs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; } else #endif - memset(regs->fp_q, 0, sizeof(regs->fp_q)); + memset(regs, 0, sizeof(*regs)); return (0); } diff --git a/sys/arm64/arm64/undefined.c b/sys/arm64/arm64/undefined.c index a96d5f88ddd5..753558a085dd 100644 --- a/sys/arm64/arm64/undefined.c +++ b/sys/arm64/arm64/undefined.c @@ -53,135 +53,6 @@ struct undef_handler { */ LIST_HEAD(, undef_handler) undef_handlers[2]; -#define MRS_MASK 0xfff00000 -#define MRS_VALUE 0xd5300000 -#define MRS_SPECIAL(insn) ((insn) & 0x000fffe0) -#define MRS_REGISTER(insn) ((insn) & 0x0000001f) -#define MRS_Op0_SHIFT 19 -#define MRS_Op0_MASK 0x00080000 -#define MRS_Op1_SHIFT 16 -#define MRS_Op1_MASK 0x00070000 -#define MRS_CRn_SHIFT 12 -#define MRS_CRn_MASK 0x0000f000 -#define MRS_CRm_SHIFT 8 -#define MRS_CRm_MASK 0x00000f00 -#define MRS_Op2_SHIFT 5 -#define MRS_Op2_MASK 0x000000e0 -#define MRS_Rt_SHIFT 0 -#define MRS_Rt_MASK 0x0000001f - -static inline int -mrs_Op0(uint32_t insn) -{ - - /* op0 is encoded without the top bit in a mrs instruction */ - return (2 | ((insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT)); -} - -#define MRS_GET(op) \ -static inline int \ -mrs_##op(uint32_t insn) \ -{ \ - \ - return ((insn & MRS_##op##_MASK) >> MRS_##op##_SHIFT); \ -} -MRS_GET(Op1) -MRS_GET(CRn) -MRS_GET(CRm) -MRS_GET(Op2) - -struct mrs_safe_value { - u_int CRm; - u_int Op2; - uint64_t value; -}; - -static struct mrs_safe_value safe_values[] = { - { /* id_aa64pfr0_el1 */ - .CRm = 4, - .Op2 = 0, - .value = ID_AA64PFR0_ADV_SIMD_NONE | ID_AA64PFR0_FP_NONE | - ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64, - }, - { /* id_aa64dfr0_el1 */ - .CRm = 5, - .Op2 = 0, - .value = ID_AA64DFR0_DEBUG_VER_8, - }, -}; - -static int -user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, - uint32_t esr) -{ - uint64_t value; - int CRm, Op2, i, reg; - - if ((insn & MRS_MASK) != MRS_VALUE) - return (0); - - /* - * We only emulate Op0 == 3, Op1 == 0, CRn == 0, CRm == {0, 4-7}. - * These are in the EL1 CPU identification space. - * CRm == 0 holds MIDR_EL1, MPIDR_EL1, and REVID_EL1. - * CRm == {4-7} holds the ID_AA64 registers. - * - * For full details see the ARMv8 ARM (ARM DDI 0487C.a) - * Table D9-2 System instruction encodings for non-Debug System - * register accesses. - */ - if (mrs_Op0(insn) != 3 || mrs_Op1(insn) != 0 || mrs_CRn(insn) != 0) - return (0); - - CRm = mrs_CRm(insn); - if (CRm > 7 || (CRm < 4 && CRm != 0)) - return (0); - - Op2 = mrs_Op2(insn); - value = 0; - - for (i = 0; i < nitems(safe_values); i++) { - if (safe_values[i].CRm == CRm && safe_values[i].Op2 == Op2) { - value = safe_values[i].value; - break; - } - } - - if (CRm == 0) { - switch (Op2) { - case 0: - value = READ_SPECIALREG(midr_el1); - break; - case 5: - value = READ_SPECIALREG(mpidr_el1); - break; - case 6: - value = READ_SPECIALREG(revidr_el1); - break; - default: - return (0); - } - } - - /* - * We will handle this instruction, move to the next so we - * don't trap here again. - */ - frame->tf_elr += INSN_SIZE; - - reg = MRS_REGISTER(insn); - /* If reg is 31 then write to xzr, i.e. do nothing */ - if (reg == 31) - return (1); - - if (reg < nitems(frame->tf_x)) - frame->tf_x[reg] = value; - else if (reg == 30) - frame->tf_lr = value; - - return (1); -} - /* * Work around a bug in QEMU prior to 2.5.1 where reading unknown ID * registers would raise an exception when they should return 0. @@ -219,7 +90,6 @@ undef_init(void) LIST_INIT(&undef_handlers[0]); LIST_INIT(&undef_handlers[1]); - install_undef_handler(true, user_mrs_handler); install_undef_handler(false, id_aa64mmfr2_handler); } diff --git a/sys/arm64/include/undefined.h b/sys/arm64/include/undefined.h index 7fded28c31f2..ee25af6e3f9c 100644 --- a/sys/arm64/include/undefined.h +++ b/sys/arm64/include/undefined.h @@ -36,6 +36,43 @@ typedef int (*undef_handler_t)(vm_offset_t, uint32_t, struct trapframe *, uint32_t); +#define MRS_MASK 0xfff00000 +#define MRS_VALUE 0xd5300000 +#define MRS_SPECIAL(insn) ((insn) & 0x000fffe0) +#define MRS_REGISTER(insn) ((insn) & 0x0000001f) +#define MRS_Op0_SHIFT 19 +#define MRS_Op0_MASK 0x00080000 +#define MRS_Op1_SHIFT 16 +#define MRS_Op1_MASK 0x00070000 +#define MRS_CRn_SHIFT 12 +#define MRS_CRn_MASK 0x0000f000 +#define MRS_CRm_SHIFT 8 +#define MRS_CRm_MASK 0x00000f00 +#define MRS_Op2_SHIFT 5 +#define MRS_Op2_MASK 0x000000e0 +#define MRS_Rt_SHIFT 0 +#define MRS_Rt_MASK 0x0000001f + +static inline int +mrs_Op0(uint32_t insn) +{ + + /* op0 is encoded without the top bit in a mrs instruction */ + return (2 | ((insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT)); +} + +#define MRS_GET(op) \ +static inline int \ +mrs_##op(uint32_t insn) \ +{ \ + \ + return ((insn & MRS_##op##_MASK) >> MRS_##op##_SHIFT); \ +} +MRS_GET(Op1) +MRS_GET(CRn) +MRS_GET(CRm) +MRS_GET(Op2) + void undef_init(void); void *install_undef_handler(bool, undef_handler_t); void remove_undef_handler(void *); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index 2b5547ce5986..3a25d8463d33 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -28,7 +28,7 @@ * Copyright 2013 Saso Kiselkov. All rights reserved. * Copyright (c) 2014 Integros [integros.com] * Copyright 2016 Toomas Soome <tsoome@me.com> - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. * Copyright (c) 2017 Datto Inc. * Copyright 2018 OmniOS Community Edition (OmniOSce) Association. */ @@ -6923,6 +6923,7 @@ spa_vdev_resilver_done_hunt(vdev_t *vd) /* * Check for a completed resilver with the 'unspare' flag set. + * Also potentially update faulted state. */ if (vd->vdev_ops == &vdev_spare_ops) { vdev_t *first = vd->vdev_child[0]; @@ -6944,6 +6945,8 @@ spa_vdev_resilver_done_hunt(vdev_t *vd) !vdev_dtl_required(oldvd)) return (oldvd); + vdev_propagate_state(vd); + /* * If there are more than two spares attached to a disk, * and those spares are not required, then we want to diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h index 8cd6360e4cf5..bbfb79ce24d3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h @@ -46,6 +46,8 @@ struct zfsvfs { zfsvfs_t *z_parent; /* parent fs */ objset_t *z_os; /* objset reference */ uint64_t z_root; /* id of root znode */ + struct vnode *z_rootvnode; /* root vnode */ + struct rmlock z_rootvnodelock;/* protection for root vnode */ uint64_t z_unlinkedobj; /* id of unlinked zapobj */ uint64_t z_max_blksz; /* maximum block size for files */ uint64_t z_fuid_obj; /* fuid table object number */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 92f51420e321..1ab51ba77a1f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -65,6 +65,7 @@ #include <sys/spa_boot.h> #include <sys/jail.h> #include <ufs/ufs/quota.h> +#include <sys/rmlock.h> #include "zfs_comutil.h" @@ -92,6 +93,9 @@ static int zfs_version_zpl = ZPL_VERSION; SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0, "ZPL_VERSION"); +static int zfs_root_setvnode(zfsvfs_t *zfsvfs); +static void zfs_root_dropvnode(zfsvfs_t *zfsvfs); + static int zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg); static int zfs_mount(vfs_t *vfsp); static int zfs_umount(vfs_t *vfsp, int fflag); @@ -198,6 +202,8 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg) break; default: error = EINVAL; + if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF) + vfs_unbusy(vfsp); goto done; } } @@ -255,9 +261,11 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg) case Q_QUOTAON: // As far as I can tell, you can't turn quotas on or off on zfs error = 0; + vfs_unbusy(vfsp); break; case Q_QUOTAOFF: error = ENOTSUP; + vfs_unbusy(vfsp); break; case Q_SETQUOTA: error = copyin(&dqblk, arg, sizeof(dqblk)); @@ -1205,6 +1213,8 @@ zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os) for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++) mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); + rm_init(&zfsvfs->z_rootvnodelock, "zfs root vnode lock"); + error = zfsvfs_init(zfsvfs, os); if (error != 0) { *zfvp = NULL; @@ -1311,6 +1321,8 @@ zfsvfs_free(zfsvfs_t *zfsvfs) rw_enter(&zfsvfs_lock, RW_READER); rw_exit(&zfsvfs_lock); + rm_destroy(&zfsvfs->z_rootvnodelock); + zfs_fuid_destroy(zfsvfs); mutex_destroy(&zfsvfs->z_znodes_lock); @@ -1917,6 +1929,8 @@ zfs_mount(vfs_t *vfsp) error = zfs_domount(vfsp, osname); PICKUP_GIANT(); + zfs_root_setvnode((zfsvfs_t *)vfsp->vfs_data); + #ifdef illumos /* * Add an extra VFS_HOLD on our parent vfs so that it can't @@ -1989,14 +2003,65 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp) } static int -zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) +zfs_root_setvnode(zfsvfs_t *zfsvfs) { - zfsvfs_t *zfsvfs = vfsp->vfs_data; znode_t *rootzp; int error; ZFS_ENTER(zfsvfs); + error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); + if (error != 0) + panic("could not zfs_zget for root vnode"); + ZFS_EXIT(zfsvfs); + rm_wlock(&zfsvfs->z_rootvnodelock); + if (zfsvfs->z_rootvnode != NULL) + panic("zfs mount point already has a root vnode: %p\n", + zfsvfs->z_rootvnode); + zfsvfs->z_rootvnode = ZTOV(rootzp); + rm_wunlock(&zfsvfs->z_rootvnodelock); + return (0); +} + +static void +zfs_root_putvnode(zfsvfs_t *zfsvfs) +{ + struct vnode *vp; + + rm_wlock(&zfsvfs->z_rootvnodelock); + vp = zfsvfs->z_rootvnode; + zfsvfs->z_rootvnode = NULL; + rm_wunlock(&zfsvfs->z_rootvnodelock); + if (vp != NULL) + vrele(vp); +} + +static int +zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) +{ + struct rm_priotracker tracker; + zfsvfs_t *zfsvfs = vfsp->vfs_data; + znode_t *rootzp; + int error; + + rm_rlock(&zfsvfs->z_rootvnodelock, &tracker); + *vpp = zfsvfs->z_rootvnode; + if (*vpp != NULL && (((*vpp)->v_iflag & VI_DOOMED) == 0)) { + vrefact(*vpp); + rm_runlock(&zfsvfs->z_rootvnodelock, &tracker); + goto lock; + } + rm_runlock(&zfsvfs->z_rootvnodelock, &tracker); + + /* + * We found the vnode but did not like it. + */ + if (*vpp != NULL) { + *vpp = NULL; + zfs_root_putvnode(zfsvfs); + } + + ZFS_ENTER(zfsvfs); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); if (error == 0) *vpp = ZTOV(rootzp); @@ -2004,6 +2069,7 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) ZFS_EXIT(zfsvfs); if (error == 0) { +lock: error = vn_lock(*vpp, flags); if (error != 0) { VN_RELE(*vpp); @@ -2122,6 +2188,8 @@ zfs_umount(vfs_t *vfsp, int fflag) cred_t *cr = td->td_ucred; int ret; + zfs_root_putvnode(zfsvfs); + ret = secpolicy_fs_unmount(cr, vfsp); if (ret) { if (dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource), diff --git a/sys/conf/files b/sys/conf/files index 23b50122a0a8..fd154bc09ac5 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4042,7 +4042,6 @@ libkern/murmur3_32.c standard libkern/mcount.c optional profiling-routine libkern/memcchr.c standard libkern/memchr.c standard -libkern/memcmp.c standard libkern/memmem.c optional gdb libkern/qsort.c standard libkern/qsort_r.c standard diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 98d452a8f7ab..087f4c695fa1 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -163,6 +163,7 @@ libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/lshrdi3.c standard +libkern/memcmp.c standard libkern/moddi3.c standard libkern/qdivrem.c standard libkern/ucmpdi2.c standard diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 76e9e8e36479..010fbc7460c7 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -244,6 +244,7 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard +libkern/memcmp.c standard libkern/memset.c standard libkern/arm64/crc32c_armv8.S standard cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S optional zfs | dtrace compile-with "${CDDL_C}" diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index d2591137a990..f7a86cf5ee49 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -548,6 +548,7 @@ kern/subr_sfbuf.c standard libkern/divdi3.c standard libkern/ffsll.c standard libkern/flsll.c standard +libkern/memcmp.c standard libkern/memset.c standard libkern/moddi3.c standard libkern/qdivrem.c standard diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 07448f44497c..1977fb9dcce2 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -65,6 +65,7 @@ libkern/cmpdi2.c optional mips | mipshf | mipsel | mipselhf libkern/ucmpdi2.c optional mips | mipshf | mipsel | mipselhf libkern/ashldi3.c standard libkern/ashrdi3.c standard +libkern/memcmp.c standard # cfe support dev/cfe/cfe_api.c optional cfe diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index d6df0c878641..faa057bfc882 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -98,6 +98,7 @@ libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/lshrdi3.c optional powerpc | powerpcspe +libkern/memcmp.c standard libkern/memset.c standard libkern/moddi3.c optional powerpc | powerpcspe libkern/qdivrem.c optional powerpc | powerpcspe diff --git a/sys/conf/files.riscv b/sys/conf/files.riscv index daba1826331b..8a70023eb91a 100644 --- a/sys/conf/files.riscv +++ b/sys/conf/files.riscv @@ -22,6 +22,7 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard +libkern/memcmp.c standard libkern/memset.c standard riscv/riscv/autoconf.c standard riscv/riscv/bus_machdep.c standard diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 7d8cc3c5cb88..ed61aa49648e 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -71,6 +71,7 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard +libkern/memcmp.c standard sparc64/central/central.c optional central sparc64/ebus/ebus.c optional ebus sparc64/ebus/epic.c optional epic ebus diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index 97db5dec0637..5db5966b0afe 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -121,10 +121,11 @@ CFLAGS+= ${CONF_CFLAGS} LDFLAGS+= -Wl,--build-id=sha1 .endif -.if ${MACHINE_CPUARCH} == "amd64" -.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" -.error amd64 kernel requires linker ifunc support +.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386") && \ + defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" +.error amd64/i386 kernel requires linker ifunc support .endif +.if ${MACHINE_CPUARCH} == "amd64" LDFLAGS+= -Wl,-z max-page-size=2097152 .if ${LINKER_TYPE} != "lld" LDFLAGS+= -Wl,-z common-page-size=4096 diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index ce32cf2950af..e0cf2cfa9c13 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -46,7 +46,7 @@ TYPE="FreeBSD" REVISION="12.0" -BRANCH="ALPHA6" +BRANCH="ALPHA7" if [ -n "${BRANCH_OVERRIDE}" ]; then BRANCH=${BRANCH_OVERRIDE} fi @@ -183,7 +183,7 @@ done if findvcs .git; then for dir in /usr/bin /usr/local/bin; do if [ -x "${dir}/git" ] ; then - git_cmd="${dir}/git --git-dir=${VCSDIR}" + git_cmd="${dir}/git -c help.autocorrect=0 --git-dir=${VCSDIR}" break fi done @@ -293,7 +293,7 @@ done shift $((OPTIND - 1)) if [ -z "${include_metadata}" ]; then - VERINFO="${VERSION} ${svn}${git}${hg}${p4version}" + VERINFO="${VERSION}${svn}${git}${hg}${p4version} ${i}" VERSTR="${VERINFO}\\n" else VERINFO="${VERSION} #${v}${svn}${git}${hg}${p4version}: ${t}" diff --git a/sys/crypto/ccp/ccp.c b/sys/crypto/ccp/ccp.c index 163fa748b2ef..1983eac79444 100644 --- a/sys/crypto/ccp/ccp.c +++ b/sys/crypto/ccp/ccp.c @@ -735,7 +735,7 @@ MODULE_VERSION(ccp, 1); MODULE_DEPEND(ccp, crypto, 1, 1, 1); MODULE_DEPEND(ccp, random_device, 1, 1, 1); #if 0 /* There are enough known issues that we shouldn't load automatically */ -MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, sizeof(ccp_ids[0]), +MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, nitems(ccp_ids)); #endif diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c index 399e55a9a47f..738bfbf79167 100644 --- a/sys/dev/aac/aac_pci.c +++ b/sys/dev/aac/aac_pci.c @@ -494,7 +494,7 @@ static driver_t aacch_driver = { static devclass_t aacch_devclass; DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;", pci, aac, - aac_identifiers, sizeof(aac_identifiers[0]), nitems(aac_identifiers) - 1); + aac_identifiers, nitems(aac_identifiers) - 1); static int aacch_probe(device_t dev) diff --git a/sys/dev/aacraid/aacraid_pci.c b/sys/dev/aacraid/aacraid_pci.c index 74ac0ee23312..f445a073b6d5 100644 --- a/sys/dev/aacraid/aacraid_pci.c +++ b/sys/dev/aacraid/aacraid_pci.c @@ -106,7 +106,7 @@ struct aac_ident DRIVER_MODULE(aacraid, pci, aacraid_pci_driver, aacraid_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, aacraid, - aacraid_family_identifiers, sizeof(aacraid_family_identifiers[0]), + aacraid_family_identifiers, nitems(aacraid_family_identifiers) - 1); MODULE_DEPEND(aacraid, pci, 1, 1, 1); diff --git a/sys/dev/adlink/adlink.c b/sys/dev/adlink/adlink.c index 2ae3d768c2fd..19b2f9388c6f 100644 --- a/sys/dev/adlink/adlink.c +++ b/sys/dev/adlink/adlink.c @@ -438,6 +438,6 @@ static driver_t adlink_driver = { }; DRIVER_MODULE(adlink, pci, adlink_driver, adlink_devclass, 0, 0); -MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, adlink, adlink_id, sizeof(adlink_id[0]), +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, adlink, adlink_id, nitems(adlink_id)); #endif /* _KERNEL */ diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c index f70afb27fa56..cb9474db8553 100644 --- a/sys/dev/ae/if_ae.c +++ b/sys/dev/ae/if_ae.c @@ -178,7 +178,7 @@ static devclass_t ae_devclass; DRIVER_MODULE(ae, pci, ae_driver, ae_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ae, ae_devs, - sizeof(ae_devs[0]), nitems(ae_devs)); + nitems(ae_devs)); DRIVER_MODULE(miibus, ae, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(ae, pci, 1, 1, 1); MODULE_DEPEND(ae, ether, 1, 1, 1); diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c index 764363f19856..ee52564d7cc8 100644 --- a/sys/dev/age/if_age.c +++ b/sys/dev/age/if_age.c @@ -184,7 +184,7 @@ static devclass_t age_devclass; DRIVER_MODULE(age, pci, age_driver, age_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, age, age_devs, - sizeof(age_devs[0]), nitems(age_devs)); + nitems(age_devs)); DRIVER_MODULE(miibus, age, miibus_driver, miibus_devclass, 0, 0); static struct resource_spec age_res_spec_mem[] = { diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c index a117a5720c86..2bc2a243837b 100644 --- a/sys/dev/ahci/ahci_pci.c +++ b/sys/dev/ahci/ahci_pci.c @@ -667,7 +667,7 @@ static driver_t ahci_driver = { DRIVER_MODULE(ahci, pci, ahci_driver, ahci_devclass, NULL, NULL); /* Also matches class / subclass / progid XXX need to add when we have masking support */ MODULE_PNP_INFO("W32:vendor/device", pci, ahci, ahci_ids, - sizeof(ahci_ids[0]), nitems(ahci_ids) - 1); + nitems(ahci_ids) - 1); static device_method_t ahci_ata_methods[] = { DEVMETHOD(device_probe, ahci_ata_probe), DEVMETHOD(device_attach, ahci_pci_attach), diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index ede7bd49c193..1bafdab235d0 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -244,7 +244,7 @@ static devclass_t alc_devclass; DRIVER_MODULE(alc, pci, alc_driver, alc_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, alc, alc_ident_table, - sizeof(alc_ident_table[0]), nitems(alc_ident_table) - 1); + nitems(alc_ident_table) - 1); DRIVER_MODULE(miibus, alc, miibus_driver, miibus_devclass, 0, 0); static struct resource_spec alc_res_spec_mem[] = { diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c index 987bd2db7421..802fdafd63cf 100644 --- a/sys/dev/ale/if_ale.c +++ b/sys/dev/ale/if_ale.c @@ -179,7 +179,7 @@ static devclass_t ale_devclass; DRIVER_MODULE(ale, pci, ale_driver, ale_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ale, ale_devs, - sizeof(ale_devs[0]), nitems(ale_devs)); + nitems(ale_devs)); DRIVER_MODULE(miibus, ale, miibus_driver, miibus_devclass, NULL, NULL); static struct resource_spec ale_res_spec_mem[] = { diff --git a/sys/dev/amdsmn/amdsmn.c b/sys/dev/amdsmn/amdsmn.c index fb2c8b17328c..17792dd922cd 100644 --- a/sys/dev/amdsmn/amdsmn.c +++ b/sys/dev/amdsmn/amdsmn.c @@ -90,7 +90,7 @@ static devclass_t amdsmn_devclass; DRIVER_MODULE(amdsmn, hostb, amdsmn_driver, amdsmn_devclass, NULL, NULL); MODULE_VERSION(amdsmn, 1); MODULE_PNP_INFO("W32:vendor/device", pci, amdsmn, amdsmn_ids, - sizeof(amdsmn_ids[0]), nitems(amdsmn_ids)); + nitems(amdsmn_ids)); static bool amdsmn_match(device_t parent) diff --git a/sys/dev/amdtemp/amdtemp.c b/sys/dev/amdtemp/amdtemp.c index 45f8d6397ed0..2463212c25f5 100644 --- a/sys/dev/amdtemp/amdtemp.c +++ b/sys/dev/amdtemp/amdtemp.c @@ -167,7 +167,7 @@ DRIVER_MODULE(amdtemp, hostb, amdtemp_driver, amdtemp_devclass, NULL, NULL); MODULE_VERSION(amdtemp, 1); MODULE_DEPEND(amdtemp, amdsmn, 1, 1, 1); MODULE_PNP_INFO("U16:vendor;U16:device", pci, amdtemp, amdtemp_products, - sizeof(amdtemp_products[0]), nitems(amdtemp_products)); + nitems(amdtemp_products)); static int amdtemp_match(device_t dev) diff --git a/sys/dev/amr/amr_pci.c b/sys/dev/amr/amr_pci.c index 80cd58b5ccd3..25b37eda3895 100644 --- a/sys/dev/amr/amr_pci.c +++ b/sys/dev/amr/amr_pci.c @@ -142,7 +142,7 @@ static struct amr_ident static devclass_t amr_devclass; DRIVER_MODULE(amr, pci, amr_pci_driver, amr_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, amr, amr_device_ids, - sizeof(amr_device_ids[0]), nitems(amr_device_ids) - 1); + nitems(amr_device_ids) - 1); MODULE_DEPEND(amr, pci, 1, 1, 1); MODULE_DEPEND(amr, cam, 1, 1, 1); diff --git a/sys/dev/an/if_an_pci.c b/sys/dev/an/if_an_pci.c index 1105a963128e..15ae3e320e54 100644 --- a/sys/dev/an/if_an_pci.c +++ b/sys/dev/an/if_an_pci.c @@ -274,6 +274,6 @@ static devclass_t an_devclass; DRIVER_MODULE(an, pci, an_pci_driver, an_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, an, - an_devs, sizeof(an_devs[0]), nitems(an_devs) - 1); + an_devs, nitems(an_devs) - 1); MODULE_DEPEND(an, pci, 1, 1, 1); MODULE_DEPEND(an, wlan, 1, 1, 1); diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c index 37eed4abcbc0..3d5c0742580c 100644 --- a/sys/dev/bce/if_bce.c +++ b/sys/dev/bce/if_bce.c @@ -530,7 +530,7 @@ MODULE_DEPEND(bce, miibus, 1, 1, 1); DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL); DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce, - bce_devs, sizeof(bce_devs[0]), nitems(bce_devs) - 1); + bce_devs, nitems(bce_devs) - 1); /****************************************************************************/ /* Tunable device values */ diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c index fb0c2949c82d..6a86f3488b4c 100644 --- a/sys/dev/bfe/if_bfe.c +++ b/sys/dev/bfe/if_bfe.c @@ -158,7 +158,7 @@ static devclass_t bfe_devclass; DRIVER_MODULE(bfe, pci, bfe_driver, bfe_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bfe, bfe_devs, - sizeof(bfe_devs[0]), nitems(bfe_devs) - 1); + nitems(bfe_devs) - 1); DRIVER_MODULE(miibus, bfe, miibus_driver, miibus_devclass, 0, 0); /* diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index c7134b9a2abd..193116e10681 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -548,7 +548,7 @@ static devclass_t bge_devclass; DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, bge, bge_devs, - sizeof(bge_devs[0]), nitems(bge_devs) - 1); + nitems(bge_devs) - 1); DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0); static int bge_allow_asf = 1; diff --git a/sys/dev/bwi/if_bwi_pci.c b/sys/dev/bwi/if_bwi_pci.c index 63378be0452d..f95ef854ceaa 100644 --- a/sys/dev/bwi/if_bwi_pci.c +++ b/sys/dev/bwi/if_bwi_pci.c @@ -257,7 +257,7 @@ static driver_t bwi_driver = { static devclass_t bwi_devclass; DRIVER_MODULE(bwi, pci, bwi_driver, bwi_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwi, bwi_devices, - sizeof(bwi_devices[0]), nitems(bwi_devices) - 1); + nitems(bwi_devices) - 1); MODULE_DEPEND(bwi, wlan, 1, 1, 1); /* 802.11 media layer */ MODULE_DEPEND(bwi, firmware, 1, 1, 1); /* firmware support */ MODULE_DEPEND(bwi, wlan_amrr, 1, 1, 1); diff --git a/sys/dev/bwn/if_bwn_pci.c b/sys/dev/bwn/if_bwn_pci.c index dfe7b50e7bc0..610f8bdeb823 100644 --- a/sys/dev/bwn/if_bwn_pci.c +++ b/sys/dev/bwn/if_bwn_pci.c @@ -296,9 +296,9 @@ DEFINE_CLASS_0(bwn_pci, bwn_pci_driver, bwn_pci_methods, DRIVER_MODULE_ORDERED(bwn_pci, pci, bwn_pci_driver, bwn_pci_devclass, NULL, NULL, SI_ORDER_ANY); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwn_siba, - siba_devices, sizeof(siba_devices[0]), nitems(siba_devices) - 1); + siba_devices, nitems(siba_devices) - 1); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwn_bcma, - bcma_devices, sizeof(bcma_devices[0]), nitems(bcma_devices) - 1); + bcma_devices, nitems(bcma_devices) - 1); DRIVER_MODULE(bhndb, bwn_pci, bhndb_pci_driver, bhndb_devclass, NULL, NULL); MODULE_DEPEND(bwn_pci, bwn, 1, 1, 1); diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index 393b78f540ff..4ef92e39d1f9 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -7076,13 +7076,13 @@ bxe_link_attn(struct bxe_softc *sc) if (sc->state == BXE_STATE_OPEN) { bxe_stats_handle(sc, STATS_EVENT_LINK_UP); + /* Restart tx when the link comes back. */ + FOR_EACH_ETH_QUEUE(sc, i) { + fp = &sc->fp[i]; + taskqueue_enqueue(fp->tq, &fp->tx_task); + } } - /* Restart tx when the link comes back. */ - FOR_EACH_ETH_QUEUE(sc, i) { - fp = &sc->fp[i]; - taskqueue_enqueue(fp->tq, &fp->tx_task); - } } if (sc->link_vars.link_up && sc->link_vars.line_speed) { @@ -16279,9 +16279,11 @@ bxe_shutdown(device_t dev) /* stop the periodic callout */ bxe_periodic_stop(sc); - BXE_CORE_LOCK(sc); - bxe_nic_unload(sc, UNLOAD_NORMAL, FALSE); - BXE_CORE_UNLOCK(sc); + if (sc->state != BXE_STATE_CLOSED) { + BXE_CORE_LOCK(sc); + bxe_nic_unload(sc, UNLOAD_NORMAL, FALSE); + BXE_CORE_UNLOCK(sc); + } return (0); } diff --git a/sys/dev/cas/if_cas.c b/sys/dev/cas/if_cas.c index 3e6dbfe7b463..d1b3761302a1 100644 --- a/sys/dev/cas/if_cas.c +++ b/sys/dev/cas/if_cas.c @@ -2617,7 +2617,7 @@ static const struct cas_pci_dev { DRIVER_MODULE(cas, pci, cas_pci_driver, cas_devclass, 0, 0); MODULE_PNP_INFO("W32:vendor/device", pci, cas, cas_pci_devlist, - sizeof(cas_pci_devlist[0]), nitems(cas_pci_devlist) - 1); + nitems(cas_pci_devlist) - 1); DRIVER_MODULE(miibus, cas, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(cas, pci, 1, 1, 1); diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index 94bd9c69e1c5..e4b887a38e60 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -365,7 +365,7 @@ static struct static devclass_t ciss_devclass; DRIVER_MODULE(ciss, pci, ciss_pci_driver, ciss_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;", pci, ciss, ciss_vendor_data, - sizeof(ciss_vendor_data[0]), nitems(ciss_vendor_data) - 1); + nitems(ciss_vendor_data) - 1); MODULE_DEPEND(ciss, cam, 1, 1, 1); MODULE_DEPEND(ciss, pci, 1, 1, 1); diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 127a61d61c21..a47aa909c237 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -133,6 +133,30 @@ static void cxgb_update_mac_settings(struct port_info *p); static int toe_capability(struct port_info *, int); #endif +/* Table for probing the cards. The desc field isn't actually used */ +struct cxgb_ident { + uint16_t vendor; + uint16_t device; + int index; + char *desc; +} cxgb_identifiers[] = { + {PCI_VENDOR_ID_CHELSIO, 0x0020, 0, "PE9000"}, + {PCI_VENDOR_ID_CHELSIO, 0x0021, 1, "T302E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0022, 2, "T310E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0023, 3, "T320X"}, + {PCI_VENDOR_ID_CHELSIO, 0x0024, 1, "T302X"}, + {PCI_VENDOR_ID_CHELSIO, 0x0025, 3, "T320E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0026, 2, "T310X"}, + {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"}, + {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"}, + {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"}, + {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"}, + {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "T3C10"}, + {PCI_VENDOR_ID_CHELSIO, 0x0036, 3, "S320E-CR"}, + {PCI_VENDOR_ID_CHELSIO, 0x0037, 7, "N320E-G2"}, + {0, 0, 0, NULL} +}; + static device_method_t cxgb_controller_methods[] = { DEVMETHOD(device_probe, cxgb_controller_probe), DEVMETHOD(device_attach, cxgb_controller_attach), @@ -151,6 +175,8 @@ static int cxgbc_mod_event(module_t, int, void *); static devclass_t cxgb_controller_devclass; DRIVER_MODULE(cxgbc, pci, cxgb_controller_driver, cxgb_controller_devclass, cxgbc_mod_event, 0); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, cxgbc, cxgb_identifiers, + nitems(cxgb_identifiers) - 1); MODULE_VERSION(cxgbc, 1); MODULE_DEPEND(cxgbc, firmware, 1, 1, 1); @@ -280,29 +306,6 @@ enum { FILTER_NO_VLAN_PRI = 7 }; #define PORT_MASK ((1 << MAX_NPORTS) - 1) -/* Table for probing the cards. The desc field isn't actually used */ -struct cxgb_ident { - uint16_t vendor; - uint16_t device; - int index; - char *desc; -} cxgb_identifiers[] = { - {PCI_VENDOR_ID_CHELSIO, 0x0020, 0, "PE9000"}, - {PCI_VENDOR_ID_CHELSIO, 0x0021, 1, "T302E"}, - {PCI_VENDOR_ID_CHELSIO, 0x0022, 2, "T310E"}, - {PCI_VENDOR_ID_CHELSIO, 0x0023, 3, "T320X"}, - {PCI_VENDOR_ID_CHELSIO, 0x0024, 1, "T302X"}, - {PCI_VENDOR_ID_CHELSIO, 0x0025, 3, "T320E"}, - {PCI_VENDOR_ID_CHELSIO, 0x0026, 2, "T310X"}, - {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"}, - {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"}, - {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"}, - {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"}, - {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "T3C10"}, - {PCI_VENDOR_ID_CHELSIO, 0x0036, 3, "S320E-CR"}, - {PCI_VENDOR_ID_CHELSIO, 0x0037, 7, "N320E-G2"}, - {0, 0, 0, NULL} -}; static int set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset); diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 866bace84c36..f23d16479ee8 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -289,7 +289,6 @@ struct port_info { uint8_t rx_e_chan_map; /* rx TP e-channel bitmap */ struct link_config link_cfg; - struct link_config old_link_cfg; struct ifmedia media; struct timeval last_refreshed; @@ -1073,52 +1072,6 @@ t4_os_set_hw_addr(struct port_info *pi, uint8_t hw_addr[]) bcopy(hw_addr, pi->vi[0].hw_addr, ETHER_ADDR_LEN); } -static inline bool -is_10G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) != 0); -} - -static inline bool -is_25G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) != 0); -} - -static inline bool -is_40G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) != 0); -} - -static inline bool -is_100G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) != 0); -} - -static inline int -port_top_speed(const struct port_info *pi) -{ - - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) - return (100); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) - return (40); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) - return (25); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) - return (10); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) - return (1); - - return (0); -} - static inline int tx_resume_threshold(struct sge_eq *eq) { diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index 044582db6ede..ada4fa4fa775 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -66,9 +66,10 @@ enum { }; enum { + FEC_NONE = 0, FEC_RS = 1 << 0, FEC_BASER_RS = 1 << 1, - FEC_RESERVED = 1 << 2, + FEC_AUTO = 1 << 5, /* M_FW_PORT_CAP32_FEC + 1 */ }; enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS }; @@ -368,6 +369,7 @@ struct adapter_params { unsigned int ethoffload:1; unsigned int hash_filter:1; unsigned int filter2_wr_support:1; + unsigned int port_caps32:1; unsigned int ofldq_wr_cred; unsigned int eo_wr_cred; @@ -409,20 +411,21 @@ struct trace_params { }; struct link_config { - /* OS-specific code owns all the requested_* fields */ - unsigned char requested_aneg; /* link aneg user has requested */ - unsigned char requested_fc; /* flow control user has requested */ - unsigned char requested_fec; /* FEC user has requested */ - unsigned int requested_speed; /* speed user has requested (Mbps) */ + /* OS-specific code owns all the requested_* fields. */ + int8_t requested_aneg; /* link autonegotiation */ + int8_t requested_fc; /* flow control */ + int8_t requested_fec; /* FEC */ + u_int requested_speed; /* speed (Mbps) */ - unsigned short supported; /* link capabilities */ - unsigned short advertising; /* advertised capabilities */ - unsigned short lp_advertising; /* peer advertised capabilities */ - unsigned int speed; /* actual link speed (Mbps) */ - unsigned char fc; /* actual link flow control */ - unsigned char fec; /* actual FEC */ - unsigned char link_ok; /* link up? */ - unsigned char link_down_rc; /* link down reason */ + uint32_t supported; /* link capabilities */ + uint32_t advertising; /* advertised capabilities */ + uint32_t lp_advertising; /* peer advertised capabilities */ + uint32_t fec_hint; /* use this fec */ + u_int speed; /* actual link speed (Mbps) */ + int8_t fc; /* actual link flow control */ + int8_t fec; /* actual FEC */ + bool link_ok; /* link up? */ + uint8_t link_down_rc; /* link down reason */ }; #include "adapter.h" @@ -874,5 +877,16 @@ int t4vf_prep_adapter(struct adapter *adapter); int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid, enum t4_bar2_qtype qtype, int user, u64 *pbar2_qoffset, unsigned int *pbar2_qid); +unsigned int fwcap_to_speed(uint32_t caps); +uint32_t speed_to_fwcap(unsigned int speed); +uint32_t fwcap_top_speed(uint32_t caps); + +static inline int +port_top_speed(const struct port_info *pi) +{ + + /* Mbps -> Gbps */ + return (fwcap_to_speed(pi->link_cfg.supported) / 1000); +} #endif /* __CHELSIO_COMMON_H */ diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 2312b66cf7a8..cec8ebbf00e7 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -3755,6 +3755,93 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) } } +/** + * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits + * @caps16: a 16-bit Port Capabilities value + * + * Returns the equivalent 32-bit Port Capabilities value. + */ +static uint32_t fwcaps16_to_caps32(uint16_t caps16) +{ + uint32_t caps32 = 0; + + #define CAP16_TO_CAP32(__cap) \ + do { \ + if (caps16 & FW_PORT_CAP_##__cap) \ + caps32 |= FW_PORT_CAP32_##__cap; \ + } while (0) + + CAP16_TO_CAP32(SPEED_100M); + CAP16_TO_CAP32(SPEED_1G); + CAP16_TO_CAP32(SPEED_25G); + CAP16_TO_CAP32(SPEED_10G); + CAP16_TO_CAP32(SPEED_40G); + CAP16_TO_CAP32(SPEED_100G); + CAP16_TO_CAP32(FC_RX); + CAP16_TO_CAP32(FC_TX); + CAP16_TO_CAP32(ANEG); + CAP16_TO_CAP32(FORCE_PAUSE); + CAP16_TO_CAP32(MDIAUTO); + CAP16_TO_CAP32(MDISTRAIGHT); + CAP16_TO_CAP32(FEC_RS); + CAP16_TO_CAP32(FEC_BASER_RS); + CAP16_TO_CAP32(802_3_PAUSE); + CAP16_TO_CAP32(802_3_ASM_DIR); + + #undef CAP16_TO_CAP32 + + return caps32; +} + +/** + * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits + * @caps32: a 32-bit Port Capabilities value + * + * Returns the equivalent 16-bit Port Capabilities value. Note that + * not all 32-bit Port Capabilities can be represented in the 16-bit + * Port Capabilities and some fields/values may not make it. + */ +static uint16_t fwcaps32_to_caps16(uint32_t caps32) +{ + uint16_t caps16 = 0; + + #define CAP32_TO_CAP16(__cap) \ + do { \ + if (caps32 & FW_PORT_CAP32_##__cap) \ + caps16 |= FW_PORT_CAP_##__cap; \ + } while (0) + + CAP32_TO_CAP16(SPEED_100M); + CAP32_TO_CAP16(SPEED_1G); + CAP32_TO_CAP16(SPEED_10G); + CAP32_TO_CAP16(SPEED_25G); + CAP32_TO_CAP16(SPEED_40G); + CAP32_TO_CAP16(SPEED_100G); + CAP32_TO_CAP16(FC_RX); + CAP32_TO_CAP16(FC_TX); + CAP32_TO_CAP16(802_3_PAUSE); + CAP32_TO_CAP16(802_3_ASM_DIR); + CAP32_TO_CAP16(ANEG); + CAP32_TO_CAP16(FORCE_PAUSE); + CAP32_TO_CAP16(MDIAUTO); + CAP32_TO_CAP16(MDISTRAIGHT); + CAP32_TO_CAP16(FEC_RS); + CAP32_TO_CAP16(FEC_BASER_RS); + + #undef CAP32_TO_CAP16 + + return caps16; +} + +static bool +is_bt(struct port_info *pi) +{ + + return (pi->port_type == FW_PORT_TYPE_BT_SGMII || + pi->port_type == FW_PORT_TYPE_BT_XFI || + pi->port_type == FW_PORT_TYPE_BT_XAUI); +} + /** * t4_link_l1cfg - apply link configuration to MAC/PHY * @phy: the PHY to setup @@ -3772,53 +3859,45 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc) { struct fw_port_cmd c; - unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO); + unsigned int mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO); unsigned int aneg, fc, fec, speed, rcap; fc = 0; if (lc->requested_fc & PAUSE_RX) - fc |= FW_PORT_CAP_FC_RX; + fc |= FW_PORT_CAP32_FC_RX; if (lc->requested_fc & PAUSE_TX) - fc |= FW_PORT_CAP_FC_TX; + fc |= FW_PORT_CAP32_FC_TX; + if (!(lc->requested_fc & PAUSE_AUTONEG)) + fc |= FW_PORT_CAP32_FORCE_PAUSE; fec = 0; - if (lc->requested_fec & FEC_RS) - fec = FW_PORT_CAP_FEC_RS; - else if (lc->requested_fec & FEC_BASER_RS) - fec = FW_PORT_CAP_FEC_BASER_RS; - - if (!(lc->supported & FW_PORT_CAP_ANEG) || - lc->requested_aneg == AUTONEG_DISABLE) { - aneg = 0; - switch (lc->requested_speed) { - case 100000: - speed = FW_PORT_CAP_SPEED_100G; - break; - case 40000: - speed = FW_PORT_CAP_SPEED_40G; - break; - case 25000: - speed = FW_PORT_CAP_SPEED_25G; - break; - case 10000: - speed = FW_PORT_CAP_SPEED_10G; - break; - case 1000: - speed = FW_PORT_CAP_SPEED_1G; - break; - case 100: - speed = FW_PORT_CAP_SPEED_100M; - break; - default: - return -EINVAL; - break; - } - } else { - aneg = FW_PORT_CAP_ANEG; - speed = lc->supported & - V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED); + if (lc->requested_fec == FEC_AUTO) + fec = lc->fec_hint; + else { + if (lc->requested_fec & FEC_RS) + fec |= FW_PORT_CAP32_FEC_RS; + if (lc->requested_fec & FEC_BASER_RS) + fec |= FW_PORT_CAP32_FEC_BASER_RS; } + if (lc->requested_aneg == AUTONEG_DISABLE) + aneg = 0; + else if (lc->requested_aneg == AUTONEG_ENABLE) + aneg = FW_PORT_CAP32_ANEG; + else + aneg = lc->supported & FW_PORT_CAP32_ANEG; + + if (aneg) { + speed = lc->supported & V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED); + } else if (lc->requested_speed != 0) + speed = speed_to_fwcap(lc->requested_speed); + else + speed = fwcap_top_speed(lc->supported); + + /* Force AN on for BT cards. */ + if (is_bt(adap->port[port])) + aneg = lc->supported & FW_PORT_CAP32_ANEG; + rcap = aneg | speed | fc | fec; if ((rcap | lc->supported) != lc->supported) { #ifdef INVARIANTS @@ -3833,10 +3912,17 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_EXEC | V_FW_PORT_CMD_PORTID(port)); - c.action_to_len16 = - cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | + if (adap->params.port_caps32) { + c.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) | + FW_LEN16(c)); + c.u.l1cfg32.rcap32 = cpu_to_be32(rcap); + } else { + c.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); - c.u.l1cfg.rcap = cpu_to_be32(rcap); + c.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap)); + } return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); } @@ -7735,57 +7821,206 @@ const char *t4_link_down_rc_str(unsigned char link_down_rc) return reason[link_down_rc]; } +/* + * Return the highest speed set in the port capabilities, in Mb/s. + */ +unsigned int fwcap_to_speed(uint32_t caps) +{ + #define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return __speed; \ + } while (0) + + TEST_SPEED_RETURN(400G, 400000); + TEST_SPEED_RETURN(200G, 200000); + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + + #undef TEST_SPEED_RETURN + + return 0; +} + +/* + * Return the port capabilities bit for the given speed, which is in Mb/s. + */ +uint32_t speed_to_fwcap(unsigned int speed) +{ + #define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (speed == __speed) \ + return FW_PORT_CAP32_SPEED_##__caps_speed; \ + } while (0) + + TEST_SPEED_RETURN(400G, 400000); + TEST_SPEED_RETURN(200G, 200000); + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + + #undef TEST_SPEED_RETURN + + return 0; +} + +/* + * Return the port capabilities bit for the highest speed in the capabilities. + */ +uint32_t fwcap_top_speed(uint32_t caps) +{ + #define TEST_SPEED_RETURN(__caps_speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return FW_PORT_CAP32_SPEED_##__caps_speed; \ + } while (0) + + TEST_SPEED_RETURN(400G); + TEST_SPEED_RETURN(200G); + TEST_SPEED_RETURN(100G); + TEST_SPEED_RETURN(50G); + TEST_SPEED_RETURN(40G); + TEST_SPEED_RETURN(25G); + TEST_SPEED_RETURN(10G); + TEST_SPEED_RETURN(1G); + TEST_SPEED_RETURN(100M); + + #undef TEST_SPEED_RETURN + + return 0; +} + + +/** + * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities + * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value + * + * Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new + * 32-bit Port Capabilities value. + */ +static uint32_t lstatus_to_fwcap(u32 lstatus) +{ + uint32_t linkattr = 0; + + /* + * Unfortunately the format of the Link Status in the old + * 16-bit Port Information message isn't the same as the + * 16-bit Port Capabilities bitfield used everywhere else ... + */ + if (lstatus & F_FW_PORT_CMD_RXPAUSE) + linkattr |= FW_PORT_CAP32_FC_RX; + if (lstatus & F_FW_PORT_CMD_TXPAUSE) + linkattr |= FW_PORT_CAP32_FC_TX; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) + linkattr |= FW_PORT_CAP32_SPEED_100M; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) + linkattr |= FW_PORT_CAP32_SPEED_1G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) + linkattr |= FW_PORT_CAP32_SPEED_10G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) + linkattr |= FW_PORT_CAP32_SPEED_25G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + linkattr |= FW_PORT_CAP32_SPEED_40G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) + linkattr |= FW_PORT_CAP32_SPEED_100G; + + return linkattr; +} + /* * Updates all fields owned by the common code in port_info and link_config * based on information provided by the firmware. Does not touch any * requested_* field. */ -static void handle_port_info(struct port_info *pi, const struct fw_port_info *p) +static void handle_port_info(struct port_info *pi, const struct fw_port_cmd *p, + enum fw_port_action action, bool *mod_changed, bool *link_changed) { - struct link_config *lc = &pi->link_cfg; - int speed; + struct link_config old_lc, *lc = &pi->link_cfg; unsigned char fc, fec; - u32 stat = be32_to_cpu(p->lstatus_to_modtype); + u32 stat, linkattr; + int old_ptype, old_mtype; - pi->port_type = G_FW_PORT_CMD_PTYPE(stat); - pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); - pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? - G_FW_PORT_CMD_MDIOADDR(stat) : -1; + old_ptype = pi->port_type; + old_mtype = pi->mod_type; + old_lc = *lc; + if (action == FW_PORT_ACTION_GET_PORT_INFO) { + stat = be32_to_cpu(p->u.info.lstatus_to_modtype); - lc->supported = be16_to_cpu(p->pcap); - lc->advertising = be16_to_cpu(p->acap); - lc->lp_advertising = be16_to_cpu(p->lpacap); - lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; - lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); + pi->port_type = G_FW_PORT_CMD_PTYPE(stat); + pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); + pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? + G_FW_PORT_CMD_MDIOADDR(stat) : -1; - speed = 0; - if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) - speed = 100; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) - speed = 1000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) - speed = 10000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) - speed = 25000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) - speed = 40000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) - speed = 100000; - lc->speed = speed; + lc->supported = fwcaps16_to_caps32(be16_to_cpu(p->u.info.pcap)); + lc->advertising = fwcaps16_to_caps32(be16_to_cpu(p->u.info.acap)); + lc->lp_advertising = fwcaps16_to_caps32(be16_to_cpu(p->u.info.lpacap)); + lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); + + linkattr = lstatus_to_fwcap(stat); + } else if (action == FW_PORT_ACTION_GET_PORT_INFO32) { + stat = be32_to_cpu(p->u.info32.lstatus32_to_cbllen32); + + pi->port_type = G_FW_PORT_CMD_PORTTYPE32(stat); + pi->mod_type = G_FW_PORT_CMD_MODTYPE32(stat); + pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP32 ? + G_FW_PORT_CMD_MDIOADDR32(stat) : -1; + + lc->supported = be32_to_cpu(p->u.info32.pcaps32); + lc->advertising = be32_to_cpu(p->u.info32.acaps32); + lc->lp_advertising = be16_to_cpu(p->u.info32.lpacaps32); + lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS32) != 0; + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC32(stat); + + linkattr = be32_to_cpu(p->u.info32.linkattr32); + } else { + CH_ERR(pi->adapter, "bad port_info action 0x%x\n", action); + return; + } + + lc->speed = fwcap_to_speed(linkattr); fc = 0; - if (stat & F_FW_PORT_CMD_RXPAUSE) + if (linkattr & FW_PORT_CAP32_FC_RX) fc |= PAUSE_RX; - if (stat & F_FW_PORT_CMD_TXPAUSE) + if (linkattr & FW_PORT_CAP32_FC_TX) fc |= PAUSE_TX; lc->fc = fc; - fec = 0; - if (lc->advertising & FW_PORT_CAP_FEC_RS) - fec = FEC_RS; - else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS) - fec = FEC_BASER_RS; + fec = FEC_NONE; + if (linkattr & FW_PORT_CAP32_FEC_RS) + fec |= FEC_RS; + if (linkattr & FW_PORT_CAP32_FEC_BASER_RS) + fec |= FEC_BASER_RS; lc->fec = fec; + + if (mod_changed != NULL) + *mod_changed = false; + if (link_changed != NULL) + *link_changed = false; + if (old_ptype != pi->port_type || old_mtype != pi->mod_type || + old_lc.supported != lc->supported) { + if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) { + lc->fec_hint = lc->advertising & + V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC); + } + if (mod_changed != NULL) + *mod_changed = true; + } + if (old_lc.link_ok != lc->link_ok || old_lc.speed != lc->speed || + old_lc.fec != lc->fec || old_lc.fc != lc->fc) { + if (link_changed != NULL) + *link_changed = true; + } } /** @@ -7798,22 +8033,24 @@ static void handle_port_info(struct port_info *pi, const struct fw_port_info *p) */ int t4_update_port_info(struct port_info *pi) { - struct fw_port_cmd port_cmd; + struct adapter *sc = pi->adapter; + struct fw_port_cmd cmd; + enum fw_port_action action; int ret; - memset(&port_cmd, 0, sizeof port_cmd); - port_cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | - F_FW_CMD_REQUEST | F_FW_CMD_READ | - V_FW_PORT_CMD_PORTID(pi->tx_chan)); - port_cmd.action_to_len16 = cpu_to_be32( - V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | - FW_LEN16(port_cmd)); - ret = t4_wr_mbox_ns(pi->adapter, pi->adapter->mbox, - &port_cmd, sizeof(port_cmd), &port_cmd); + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | + F_FW_CMD_REQUEST | F_FW_CMD_READ | + V_FW_PORT_CMD_PORTID(pi->tx_chan)); + action = sc->params.port_caps32 ? FW_PORT_ACTION_GET_PORT_INFO32 : + FW_PORT_ACTION_GET_PORT_INFO; + cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) | + FW_LEN16(cmd)); + ret = t4_wr_mbox_ns(sc, sc->mbox, &cmd, sizeof(cmd), &cmd); if (ret) return ret; - handle_port_info(pi, &port_cmd.u.info); + handle_port_info(pi, &cmd, action, NULL, NULL); return 0; } @@ -7828,15 +8065,18 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) { u8 opcode = *(const u8 *)rpl; const struct fw_port_cmd *p = (const void *)rpl; - unsigned int action = - G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); + enum fw_port_action action = + G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); + bool mod_changed, link_changed; - if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) { + if (opcode == FW_PORT_CMD && + (action == FW_PORT_ACTION_GET_PORT_INFO || + action == FW_PORT_ACTION_GET_PORT_INFO32)) { /* link/module state change message */ - int i, old_ptype, old_mtype; + int i; int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid)); struct port_info *pi = NULL; - struct link_config *lc, *old_lc; + struct link_config *lc; for_each_port(adap, i) { pi = adap2pinfo(adap, i); @@ -7846,23 +8086,15 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) lc = &pi->link_cfg; PORT_LOCK(pi); - old_lc = &pi->old_link_cfg; - old_ptype = pi->port_type; - old_mtype = pi->mod_type; - handle_port_info(pi, &p->u.info); + handle_port_info(pi, p, action, &mod_changed, &link_changed); PORT_UNLOCK(pi); - if (old_ptype != pi->port_type || old_mtype != pi->mod_type) { + if (mod_changed) t4_os_portmod_changed(pi); - } - PORT_LOCK(pi); - if (old_lc->link_ok != lc->link_ok || - old_lc->speed != lc->speed || - old_lc->fec != lc->fec || - old_lc->fc != lc->fc) { + if (link_changed) { + PORT_LOCK(pi); t4_os_link_changed(pi); - *old_lc = *lc; + PORT_UNLOCK(pi); } - PORT_UNLOCK(pi); } else { CH_WARN_RATELIMIT(adap, "Unknown firmware reply %d\n", opcode); return -EINVAL; @@ -8595,6 +8827,11 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) } while ((adap->params.portvec & (1 << j)) == 0); } + p->tx_chan = j; + p->mps_bg_map = t4_get_mps_bg_map(adap, j); + p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); + p->lport = j; + if (!(adap->flags & IS_VF) || adap->params.vfres.r_caps & FW_CMD_CAP_PORT) { t4_update_port_info(p); @@ -8609,10 +8846,6 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) p->vi[0].smt_idx = (ret & 0x7f) << 1; else p->vi[0].smt_idx = (ret & 0x7f); - p->tx_chan = j; - p->mps_bg_map = t4_get_mps_bg_map(adap, j); - p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); - p->lport = j; p->vi[0].rss_size = rss_size; t4_os_set_hw_addr(p, addr); diff --git a/sys/dev/cxgbe/firmware/t4fw_cfg.txt b/sys/dev/cxgbe/firmware/t4fw_cfg.txt index 43820a0b44cb..11721a1ed648 100644 --- a/sys/dev/cxgbe/firmware/t4fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t4fw_cfg.txt @@ -110,6 +110,7 @@ nexactf = 280 cmask = all pmask = all + nethofld = 2048 # driver will mask off features it won't use protocol = ofld, rddp, rdmac, iscsi_initiator_pdu, iscsi_target_pdu @@ -245,7 +246,7 @@ [fini] version = 0x1 - checksum = 0xbec0621 + checksum = 0x159b9295 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg.txt b/sys/dev/cxgbe/firmware/t5fw_cfg.txt index 721ff372ef80..f42966c62e49 100644 --- a/sys/dev/cxgbe/firmware/t5fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t5fw_cfg.txt @@ -155,6 +155,7 @@ nexactf = 456 cmask = all pmask = all + nethofld = 8192 # driver will mask off features it won't use protocol = ofld, rddp, rdmac, iscsi_initiator_pdu, iscsi_target_pdu, iscsi_t10dif @@ -290,7 +291,7 @@ [fini] version = 0x1 - checksum = 0x89c83d98 + checksum = 0x30b6a157 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t6fw_cfg.txt b/sys/dev/cxgbe/firmware/t6fw_cfg.txt index 3b62ed83b344..c542cfcadf5e 100644 --- a/sys/dev/cxgbe/firmware/t6fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t6fw_cfg.txt @@ -155,6 +155,7 @@ pmask = all ncrypto_lookaside = 16 nclip = 320 + nethofld = 8192 # TCAM has 6K cells; each region must start at a multiple of 128 cell. # Each entry in these categories takes 2 cells each. nhash will use the @@ -275,7 +276,7 @@ [fini] version = 0x1 - checksum = 0x9e8952d2 + checksum = 0xf3e93001 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/osdep.h b/sys/dev/cxgbe/osdep.h index 5cd3e88803ad..6eec287db1a7 100644 --- a/sys/dev/cxgbe/osdep.h +++ b/sys/dev/cxgbe/osdep.h @@ -108,6 +108,7 @@ typedef boolean_t bool; #define DUPLEX_HALF 0 #define DUPLEX_FULL 1 +#define AUTONEG_AUTO (-1) #define AUTONEG_DISABLE 0 #define AUTONEG_ENABLE 1 diff --git a/sys/dev/cxgbe/t4_filter.c b/sys/dev/cxgbe/t4_filter.c index fe26b47566e1..4f325bdd235d 100644 --- a/sys/dev/cxgbe/t4_filter.c +++ b/sys/dev/cxgbe/t4_filter.c @@ -593,13 +593,8 @@ set_tcamfilter(struct adapter *sc, struct t4_filter *t, struct l2t_entry *l2te, } } mtx_unlock(&sc->tids.ftid_lock); - if (rc != 0) { - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); + if (rc != 0) return (rc); - } /* * Can't fail now. A set-filter WR will definitely be sent. @@ -817,8 +812,8 @@ int set_filter(struct adapter *sc, struct t4_filter *t) { struct tid_info *ti = &sc->tids; - struct l2t_entry *l2te; - struct smt_entry *smt; + struct l2t_entry *l2te = NULL; + struct smt_entry *smt = NULL; uint64_t ftuple; int rc; @@ -942,43 +937,41 @@ set_filter(struct adapter *sc, struct t4_filter *t) * Allocate L2T entry, SMT entry, etc. */ - l2te = NULL; if (t->fs.newdmac || t->fs.newvlan) { /* This filter needs an L2T entry; allocate one. */ - l2te = t4_l2t_alloc_switching(sc->l2t); - if (__predict_false(l2te == NULL)) - return (EAGAIN); - rc = t4_l2t_set_switching(sc, l2te, t->fs.vlan, t->fs.eport, + l2te = t4_l2t_alloc_switching(sc, t->fs.vlan, t->fs.eport, t->fs.dmac); - if (rc) { - t4_l2t_release(l2te); - return (ENOMEM); + if (__predict_false(l2te == NULL)) { + rc = EAGAIN; + goto error; } } - smt = NULL; if (t->fs.newsmac) { /* This filter needs an SMT entry; allocate one. */ smt = t4_smt_alloc_switching(sc->smt, t->fs.smac); if (__predict_false(smt == NULL)) { - if (l2te != NULL) - t4_l2t_release(l2te); - return (EAGAIN); + rc = EAGAIN; + goto error; } rc = t4_smt_set_switching(sc, smt, 0x0, t->fs.smac); - if (rc) { - t4_smt_release(smt); - if (l2te != NULL) - t4_l2t_release(l2te); - return (rc); - } + if (rc) + goto error; } if (t->fs.hash) - return (set_hashfilter(sc, t, ftuple, l2te, smt)); + rc = set_hashfilter(sc, t, ftuple, l2te, smt); else - return (set_tcamfilter(sc, t, l2te, smt)); + rc = set_tcamfilter(sc, t, l2te, smt); + if (rc != 0 && rc != EINPROGRESS) { +error: + if (l2te) + t4_l2t_release(l2te); + if (smt) + t4_smt_release(smt); + } + return (rc); } static int @@ -1552,10 +1545,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple, f = malloc(sizeof(*f), M_CXGBE, M_ZERO | M_NOWAIT); if (__predict_false(f == NULL)) { - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); rc = ENOMEM; goto done; } @@ -1565,10 +1554,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple, atid = alloc_atid(sc, f); if (__predict_false(atid) == -1) { - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); free(f, M_CXGBE); rc = EAGAIN; goto done; @@ -1579,10 +1564,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple, &cookie); if (wr == NULL) { free_atid(sc, atid); - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); free(f, M_CXGBE); rc = ENOMEM; goto done; diff --git a/sys/dev/cxgbe/t4_l2t.c b/sys/dev/cxgbe/t4_l2t.c index 22e84d320aa2..5e96579f1717 100644 --- a/sys/dev/cxgbe/t4_l2t.c +++ b/sys/dev/cxgbe/t4_l2t.c @@ -108,6 +108,44 @@ t4_alloc_l2e(struct l2t_data *d) return (e); } +static struct l2t_entry * +find_or_alloc_l2e(struct l2t_data *d, uint16_t vlan, uint8_t port, uint8_t *dmac) +{ + struct l2t_entry *end, *e, **p; + struct l2t_entry *first_free = NULL; + + for (e = &d->l2tab[0], end = &d->l2tab[d->l2t_size]; e != end; ++e) { + if (atomic_load_acq_int(&e->refcnt) == 0) { + if (!first_free) + first_free = e; + } else if (e->state == L2T_STATE_SWITCHING && + memcmp(e->dmac, dmac, ETHER_ADDR_LEN) == 0 && + e->vlan == vlan && e->lport == port) + return (e); /* Found existing entry that matches. */ + } + + if (first_free == NULL) + return (NULL); /* No match and no room for a new entry. */ + + /* + * The entry we found may be an inactive entry that is + * presently in the hash table. We need to remove it. + */ + e = first_free; + if (e->state < L2T_STATE_SWITCHING) { + for (p = &d->l2tab[e->hash].first; *p; p = &(*p)->next) { + if (*p == e) { + *p = e->next; + e->next = NULL; + break; + } + } + } + e->state = L2T_STATE_UNUSED; + return (e); +} + + /* * Write an L2T entry. Must be called with the entry locked. * The write may be synchronous or asynchronous. @@ -154,41 +192,38 @@ t4_write_l2e(struct l2t_entry *e, int sync) * address resolution updates do not see them. */ struct l2t_entry * -t4_l2t_alloc_switching(struct l2t_data *d) +t4_l2t_alloc_switching(struct adapter *sc, uint16_t vlan, uint8_t port, + uint8_t *eth_addr) { + struct l2t_data *d = sc->l2t; struct l2t_entry *e; - - rw_wlock(&d->lock); - e = t4_alloc_l2e(d); - if (e) { - mtx_lock(&e->lock); /* avoid race with t4_l2t_free */ - e->state = L2T_STATE_SWITCHING; - atomic_store_rel_int(&e->refcnt, 1); - mtx_unlock(&e->lock); - } - rw_wunlock(&d->lock); - return e; -} - -/* - * Sets/updates the contents of a switching L2T entry that has been allocated - * with an earlier call to @t4_l2t_alloc_switching. - */ -int -t4_l2t_set_switching(struct adapter *sc, struct l2t_entry *e, uint16_t vlan, - uint8_t port, uint8_t *eth_addr) -{ int rc; - e->vlan = vlan; - e->lport = port; - e->wrq = &sc->sge.ctrlq[0]; - e->iqid = sc->sge.fwq.abs_id; - memcpy(e->dmac, eth_addr, ETHER_ADDR_LEN); - mtx_lock(&e->lock); - rc = t4_write_l2e(e, 0); - mtx_unlock(&e->lock); - return (rc); + rw_wlock(&d->lock); + e = find_or_alloc_l2e(d, vlan, port, eth_addr); + if (e) { + if (atomic_load_acq_int(&e->refcnt) == 0) { + mtx_lock(&e->lock); /* avoid race with t4_l2t_free */ + e->wrq = &sc->sge.ctrlq[0]; + e->iqid = sc->sge.fwq.abs_id; + e->state = L2T_STATE_SWITCHING; + e->vlan = vlan; + e->lport = port; + memcpy(e->dmac, eth_addr, ETHER_ADDR_LEN); + atomic_store_rel_int(&e->refcnt, 1); + atomic_subtract_int(&d->nfree, 1); + rc = t4_write_l2e(e, 0); + mtx_unlock(&e->lock); + if (rc != 0) + e = NULL; + } else { + MPASS(e->vlan == vlan); + MPASS(e->lport == port); + atomic_add_int(&e->refcnt, 1); + } + } + rw_wunlock(&d->lock); + return (e); } int diff --git a/sys/dev/cxgbe/t4_l2t.h b/sys/dev/cxgbe/t4_l2t.h index 21c392018fe8..188669e80261 100644 --- a/sys/dev/cxgbe/t4_l2t.h +++ b/sys/dev/cxgbe/t4_l2t.h @@ -91,7 +91,8 @@ struct l2t_data { int t4_init_l2t(struct adapter *, int); int t4_free_l2t(struct l2t_data *); struct l2t_entry *t4_alloc_l2e(struct l2t_data *); -struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *); +struct l2t_entry *t4_l2t_alloc_switching(struct adapter *, uint16_t, uint8_t, + uint8_t *); int t4_l2t_set_switching(struct adapter *, struct l2t_entry *, uint16_t, uint8_t, uint8_t *); int t4_write_l2e(struct l2t_entry *, int); diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 60bdff978b69..898cbf4db465 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -390,18 +390,20 @@ static char t4_cfg_file[32] = DEFAULT_CF; TUNABLE_STR("hw.cxgbe.config_file", t4_cfg_file, sizeof(t4_cfg_file)); /* - * PAUSE settings (bit 0, 1 = rx_pause, tx_pause respectively). + * PAUSE settings (bit 0, 1, 2 = rx_pause, tx_pause, pause_autoneg respectively). * rx_pause = 1 to heed incoming PAUSE frames, 0 to ignore them. * tx_pause = 1 to emit PAUSE frames when the rx FIFO reaches its high water * mark or when signalled to do so, 0 to never emit PAUSE. + * pause_autoneg = 1 means PAUSE will be negotiated if possible and the + * negotiated settings will override rx_pause/tx_pause. + * Otherwise rx_pause/tx_pause are applied forcibly. */ -static int t4_pause_settings = PAUSE_TX | PAUSE_RX; +static int t4_pause_settings = PAUSE_RX | PAUSE_TX | PAUSE_AUTONEG; TUNABLE_INT("hw.cxgbe.pause_settings", &t4_pause_settings); /* - * Forward Error Correction settings (bit 0, 1, 2 = FEC_RS, FEC_BASER_RS, - * FEC_RESERVED respectively). - * -1 to run with the firmware default. + * Forward Error Correction settings (bit 0, 1 = RS, BASER respectively). + * -1 to run with the firmware default. Same as FEC_AUTO (bit 5) * 0 to disable FEC. */ static int t4_fec = -1; @@ -437,8 +439,13 @@ static int t4_switchcaps_allowed = FW_CAPS_CONFIG_SWITCH_INGRESS | FW_CAPS_CONFIG_SWITCH_EGRESS; TUNABLE_INT("hw.cxgbe.switchcaps_allowed", &t4_switchcaps_allowed); +#ifdef RATELIMIT static int t4_niccaps_allowed = FW_CAPS_CONFIG_NIC | FW_CAPS_CONFIG_NIC_HASHFILTER | FW_CAPS_CONFIG_NIC_ETHOFLD; +#else +static int t4_niccaps_allowed = FW_CAPS_CONFIG_NIC | + FW_CAPS_CONFIG_NIC_HASHFILTER; +#endif TUNABLE_INT("hw.cxgbe.niccaps_allowed", &t4_niccaps_allowed); static int t4_toecaps_allowed = -1; @@ -526,9 +533,11 @@ static int get_params__pre_init(struct adapter *); static int get_params__post_init(struct adapter *); static int set_params__post_init(struct adapter *); static void t4_set_desc(struct adapter *); -static void build_medialist(struct port_info *, struct ifmedia *); -static void init_l1cfg(struct port_info *); -static int apply_l1cfg(struct port_info *); +static bool fixed_ifmedia(struct port_info *); +static void build_medialist(struct port_info *); +static void init_link_config(struct port_info *); +static int fixup_link_config(struct port_info *); +static int apply_link_config(struct port_info *); static int cxgbe_init_synchronized(struct vi_info *); static int cxgbe_uninit_synchronized(struct vi_info *); static void quiesce_txq(struct adapter *, struct sge_txq *); @@ -1018,6 +1027,14 @@ t4_attach(device_t dev) ifmedia_init(&pi->media, IFM_IMASK, cxgbe_media_change, cxgbe_media_status); + PORT_LOCK(pi); + init_link_config(pi); + fixup_link_config(pi); + build_medialist(pi); + if (fixed_ifmedia(pi)) + pi->flags |= FIXED_IFMEDIA; + PORT_UNLOCK(pi); + pi->dev = device_add_child(dev, sc->names->ifnet_name, -1); if (pi->dev == NULL) { device_printf(dev, @@ -1500,6 +1517,7 @@ cxgbe_vi_attach(device_t dev, struct vi_info *vi) #endif ifp->if_capabilities = T4_CAP; + ifp->if_capenable = T4_CAP_ENABLE; #ifdef TCP_OFFLOAD if (vi->nofldrxq != 0) ifp->if_capabilities |= IFCAP_TOE; @@ -1509,10 +1527,11 @@ cxgbe_vi_attach(device_t dev, struct vi_info *vi) ifp->if_capabilities |= IFCAP_NETMAP; #endif #ifdef RATELIMIT - if (is_ethoffload(vi->pi->adapter) && vi->nofldtxq != 0) + if (is_ethoffload(vi->pi->adapter) && vi->nofldtxq != 0) { ifp->if_capabilities |= IFCAP_TXRTLMT; + ifp->if_capenable |= IFCAP_TXRTLMT; + } #endif - ifp->if_capenable = T4_CAP_ENABLE; ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_IP | CSUM_TSO | CSUM_UDP_IPV6 | CSUM_TCP_IPV6; @@ -1883,7 +1902,7 @@ cxgbe_transmit(struct ifnet *ifp, struct mbuf *m) M_ASSERTPKTHDR(m); MPASS(m->m_nextpkt == NULL); /* not quite ready for this yet */ - if (__predict_false(pi->link_cfg.link_ok == 0)) { + if (__predict_false(pi->link_cfg.link_ok == false)) { m_freem(m); return (ENETDOWN); } @@ -2061,8 +2080,8 @@ cxgbe_get_counter(struct ifnet *ifp, ift_counter c) } /* - * The kernel picks a media from the list we had provided so we do not have to - * validate the request. + * The kernel picks a media from the list we had provided but we still validate + * the requeste. */ int cxgbe_media_change(struct ifnet *ifp) @@ -2079,8 +2098,14 @@ cxgbe_media_change(struct ifnet *ifp) return (rc); PORT_LOCK(pi); if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) { - MPASS(lc->supported & FW_PORT_CAP_ANEG); + /* ifconfig .. media autoselect */ + if (!(lc->supported & FW_PORT_CAP32_ANEG)) { + rc = ENOTSUP; /* AN not supported by transceiver */ + goto done; + } lc->requested_aneg = AUTONEG_ENABLE; + lc->requested_speed = 0; + lc->requested_fc |= PAUSE_AUTONEG; } else { lc->requested_aneg = AUTONEG_DISABLE; lc->requested_speed = @@ -2091,47 +2116,25 @@ cxgbe_media_change(struct ifnet *ifp) if (IFM_OPTIONS(ifm->ifm_media) & IFM_ETH_TXPAUSE) lc->requested_fc |= PAUSE_TX; } - if (pi->up_vis > 0) - rc = apply_l1cfg(pi); + if (pi->up_vis > 0) { + fixup_link_config(pi); + rc = apply_link_config(pi); + } +done: PORT_UNLOCK(pi); end_synchronized_op(sc, 0); return (rc); } -/* - * Mbps to FW_PORT_CAP_SPEED_* bit. - */ -static uint16_t -speed_to_fwspeed(int speed) -{ - - switch (speed) { - case 100000: - return (FW_PORT_CAP_SPEED_100G); - case 40000: - return (FW_PORT_CAP_SPEED_40G); - case 25000: - return (FW_PORT_CAP_SPEED_25G); - case 10000: - return (FW_PORT_CAP_SPEED_10G); - case 1000: - return (FW_PORT_CAP_SPEED_1G); - case 100: - return (FW_PORT_CAP_SPEED_100M); - } - - return (0); -} - /* * Base media word (without ETHER, pause, link active, etc.) for the port at the * given speed. */ static int -port_mword(struct port_info *pi, uint16_t speed) +port_mword(struct port_info *pi, uint32_t speed) { - MPASS(speed & M_FW_PORT_CAP_SPEED); + MPASS(speed & M_FW_PORT_CAP32_SPEED); MPASS(powerof2(speed)); switch(pi->port_type) { @@ -2140,24 +2143,24 @@ port_mword(struct port_info *pi, uint16_t speed) case FW_PORT_TYPE_BT_XAUI: /* BaseT */ switch (speed) { - case FW_PORT_CAP_SPEED_100M: + case FW_PORT_CAP32_SPEED_100M: return (IFM_100_T); - case FW_PORT_CAP_SPEED_1G: + case FW_PORT_CAP32_SPEED_1G: return (IFM_1000_T); - case FW_PORT_CAP_SPEED_10G: + case FW_PORT_CAP32_SPEED_10G: return (IFM_10G_T); } break; case FW_PORT_TYPE_KX4: - if (speed == FW_PORT_CAP_SPEED_10G) + if (speed == FW_PORT_CAP32_SPEED_10G) return (IFM_10G_KX4); break; case FW_PORT_TYPE_CX4: - if (speed == FW_PORT_CAP_SPEED_10G) + if (speed == FW_PORT_CAP32_SPEED_10G) return (IFM_10G_CX4); break; case FW_PORT_TYPE_KX: - if (speed == FW_PORT_CAP_SPEED_1G) + if (speed == FW_PORT_CAP32_SPEED_1G) return (IFM_1000_KX); break; case FW_PORT_TYPE_KR: @@ -2168,15 +2171,17 @@ port_mword(struct port_info *pi, uint16_t speed) case FW_PORT_TYPE_KR_SFP28: case FW_PORT_TYPE_KR_XLAUI: switch (speed) { - case FW_PORT_CAP_SPEED_1G: + case FW_PORT_CAP32_SPEED_1G: return (IFM_1000_KX); - case FW_PORT_CAP_SPEED_10G: + case FW_PORT_CAP32_SPEED_10G: return (IFM_10G_KR); - case FW_PORT_CAP_SPEED_25G: + case FW_PORT_CAP32_SPEED_25G: return (IFM_25G_KR); - case FW_PORT_CAP_SPEED_40G: + case FW_PORT_CAP32_SPEED_40G: return (IFM_40G_KR4); - case FW_PORT_CAP_SPEED_100G: + case FW_PORT_CAP32_SPEED_50G: + return (IFM_50G_KR2); + case FW_PORT_CAP32_SPEED_100G: return (IFM_100G_KR4); } break; @@ -2194,53 +2199,59 @@ port_mword(struct port_info *pi, uint16_t speed) switch (pi->mod_type) { case FW_PORT_MOD_TYPE_LR: switch (speed) { - case FW_PORT_CAP_SPEED_1G: + case FW_PORT_CAP32_SPEED_1G: return (IFM_1000_LX); - case FW_PORT_CAP_SPEED_10G: + case FW_PORT_CAP32_SPEED_10G: return (IFM_10G_LR); - case FW_PORT_CAP_SPEED_25G: + case FW_PORT_CAP32_SPEED_25G: return (IFM_25G_LR); - case FW_PORT_CAP_SPEED_40G: + case FW_PORT_CAP32_SPEED_40G: return (IFM_40G_LR4); - case FW_PORT_CAP_SPEED_100G: + case FW_PORT_CAP32_SPEED_50G: + return (IFM_50G_LR2); + case FW_PORT_CAP32_SPEED_100G: return (IFM_100G_LR4); } break; case FW_PORT_MOD_TYPE_SR: switch (speed) { - case FW_PORT_CAP_SPEED_1G: + case FW_PORT_CAP32_SPEED_1G: return (IFM_1000_SX); - case FW_PORT_CAP_SPEED_10G: + case FW_PORT_CAP32_SPEED_10G: return (IFM_10G_SR); - case FW_PORT_CAP_SPEED_25G: + case FW_PORT_CAP32_SPEED_25G: return (IFM_25G_SR); - case FW_PORT_CAP_SPEED_40G: + case FW_PORT_CAP32_SPEED_40G: return (IFM_40G_SR4); - case FW_PORT_CAP_SPEED_100G: + case FW_PORT_CAP32_SPEED_50G: + return (IFM_50G_SR2); + case FW_PORT_CAP32_SPEED_100G: return (IFM_100G_SR4); } break; case FW_PORT_MOD_TYPE_ER: - if (speed == FW_PORT_CAP_SPEED_10G) + if (speed == FW_PORT_CAP32_SPEED_10G) return (IFM_10G_ER); break; case FW_PORT_MOD_TYPE_TWINAX_PASSIVE: case FW_PORT_MOD_TYPE_TWINAX_ACTIVE: switch (speed) { - case FW_PORT_CAP_SPEED_1G: + case FW_PORT_CAP32_SPEED_1G: return (IFM_1000_CX); - case FW_PORT_CAP_SPEED_10G: + case FW_PORT_CAP32_SPEED_10G: return (IFM_10G_TWINAX); - case FW_PORT_CAP_SPEED_25G: + case FW_PORT_CAP32_SPEED_25G: return (IFM_25G_CR); - case FW_PORT_CAP_SPEED_40G: + case FW_PORT_CAP32_SPEED_40G: return (IFM_40G_CR4); - case FW_PORT_CAP_SPEED_100G: + case FW_PORT_CAP32_SPEED_50G: + return (IFM_50G_CR2); + case FW_PORT_CAP32_SPEED_100G: return (IFM_100G_CR4); } break; case FW_PORT_MOD_TYPE_LRM: - if (speed == FW_PORT_CAP_SPEED_10G) + if (speed == FW_PORT_CAP32_SPEED_10G) return (IFM_10G_LRM); break; case FW_PORT_MOD_TYPE_NA: @@ -2282,12 +2293,12 @@ cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) * function. Just PORT_LOCK would have been enough otherwise. */ t4_update_port_info(pi); - build_medialist(pi, &pi->media); + build_medialist(pi); } /* ifm_status */ ifmr->ifm_status = IFM_AVALID; - if (lc->link_ok == 0) + if (lc->link_ok == false) goto done; ifmr->ifm_status |= IFM_ACTIVE; @@ -2298,7 +2309,7 @@ cxgbe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) ifmr->ifm_active |= IFM_ETH_RXPAUSE; if (lc->fc & PAUSE_TX) ifmr->ifm_active |= IFM_ETH_TXPAUSE; - ifmr->ifm_active |= port_mword(pi, speed_to_fwspeed(lc->speed)); + ifmr->ifm_active |= port_mword(pi, speed_to_fwcap(lc->speed)); done: PORT_UNLOCK(pi); end_synchronized_op(sc, 0); @@ -3845,7 +3856,7 @@ get_params__post_init(struct adapter *sc) sc->sge.iq_start = val[0]; sc->sge.eq_start = val[1]; - if (val[3] > val[2]) { + if ((int)val[3] > (int)val[2]) { sc->tids.ftid_base = val[2]; sc->tids.ftid_end = val[3]; sc->tids.nftids = val[3] - val[2] + 1; @@ -3980,7 +3991,7 @@ get_params__post_init(struct adapter *sc) "failed to query NIC parameters: %d.\n", rc); return (rc); } - if (val[1] > val[0]) { + if ((int)val[1] > (int)val[0]) { sc->tids.etid_base = val[0]; sc->tids.etid_end = val[1]; sc->tids.netids = val[1] - val[0] + 1; @@ -4010,7 +4021,7 @@ get_params__post_init(struct adapter *sc) sc->tids.ntids -= sc->tids.nhpftids; } sc->tids.natids = min(sc->tids.ntids / 2, MAX_ATIDS); - if (val[2] > val[1]) { + if ((int)val[2] > (int)val[1]) { sc->tids.stid_base = val[1]; sc->tids.nstids = val[2] - val[1] + 1; } @@ -4133,6 +4144,12 @@ set_params__post_init(struct adapter *sc) val = 1; (void)t4_set_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); + /* Enable 32b port caps if the firmware supports it. */ + param = FW_PARAM_PFVF(PORT_CAPS32); + val = 1; + if (t4_set_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val) == 0) + sc->params.port_caps32 = 1; + #ifdef TCP_OFFLOAD /* * Override the TOE timers with user provided tunables. This is not the @@ -4215,22 +4232,30 @@ ifmedia_add4(struct ifmedia *ifm, int m) ifmedia_add(ifm, m | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE, 0, NULL); } +/* + * This is the selected media, which is not quite the same as the active media. + * The media line in ifconfig is "media: Ethernet selected (active)" if selected + * and active are not the same, and "media: Ethernet selected" otherwise. + */ static void -set_current_media(struct port_info *pi, struct ifmedia *ifm) +set_current_media(struct port_info *pi) { struct link_config *lc; + struct ifmedia *ifm; int mword; + u_int speed; PORT_LOCK_ASSERT_OWNED(pi); /* Leave current media alone if it's already set to IFM_NONE. */ + ifm = &pi->media; if (ifm->ifm_cur != NULL && IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_NONE) return; lc = &pi->link_cfg; - if (lc->requested_aneg == AUTONEG_ENABLE && - lc->supported & FW_PORT_CAP_ANEG) { + if (lc->requested_aneg != AUTONEG_DISABLE && + lc->supported & FW_PORT_CAP32_ANEG) { ifmedia_set(ifm, IFM_ETHER | IFM_AUTO); return; } @@ -4239,16 +4264,42 @@ set_current_media(struct port_info *pi, struct ifmedia *ifm) mword |= IFM_ETH_TXPAUSE; if (lc->requested_fc & PAUSE_RX) mword |= IFM_ETH_RXPAUSE; - mword |= port_mword(pi, speed_to_fwspeed(lc->requested_speed)); + if (lc->requested_speed == 0) + speed = port_top_speed(pi) * 1000; /* Gbps -> Mbps */ + else + speed = lc->requested_speed; + mword |= port_mword(pi, speed_to_fwcap(speed)); ifmedia_set(ifm, mword); } -static void -build_medialist(struct port_info *pi, struct ifmedia *ifm) +/* + * Returns true if the ifmedia list for the port cannot change. + */ +static bool +fixed_ifmedia(struct port_info *pi) { - uint16_t ss, speed; + + return (pi->port_type == FW_PORT_TYPE_BT_SGMII || + pi->port_type == FW_PORT_TYPE_BT_XFI || + pi->port_type == FW_PORT_TYPE_BT_XAUI || + pi->port_type == FW_PORT_TYPE_KX4 || + pi->port_type == FW_PORT_TYPE_KX || + pi->port_type == FW_PORT_TYPE_KR || + pi->port_type == FW_PORT_TYPE_BP_AP || + pi->port_type == FW_PORT_TYPE_BP4_AP || + pi->port_type == FW_PORT_TYPE_BP40_BA || + pi->port_type == FW_PORT_TYPE_KR4_100G || + pi->port_type == FW_PORT_TYPE_KR_SFP28 || + pi->port_type == FW_PORT_TYPE_KR_XLAUI); +} + +static void +build_medialist(struct port_info *pi) +{ + uint32_t ss, speed; int unknown, mword, bit; struct link_config *lc; + struct ifmedia *ifm; PORT_LOCK_ASSERT_OWNED(pi); @@ -4256,18 +4307,12 @@ build_medialist(struct port_info *pi, struct ifmedia *ifm) return; /* - * First setup all the requested_ fields so that they comply with what's - * supported by the port + transceiver. Note that this clobbers any - * user preferences set via sysctl_pause_settings or sysctl_autoneg. - */ - init_l1cfg(pi); - - /* - * Now (re)build the ifmedia list. + * Rebuild the ifmedia list. */ + ifm = &pi->media; ifmedia_removeall(ifm); lc = &pi->link_cfg; - ss = G_FW_PORT_CAP_SPEED(lc->supported); /* Supported Speeds */ + ss = G_FW_PORT_CAP32_SPEED(lc->supported); /* Supported Speeds */ if (__predict_false(ss == 0)) { /* not supposed to happen. */ MPASS(ss != 0); no_media: @@ -4278,9 +4323,9 @@ build_medialist(struct port_info *pi, struct ifmedia *ifm) } unknown = 0; - for (bit = 0; bit < fls(ss); bit++) { + for (bit = S_FW_PORT_CAP32_SPEED; bit < fls(ss); bit++) { speed = 1 << bit; - MPASS(speed & M_FW_PORT_CAP_SPEED); + MPASS(speed & M_FW_PORT_CAP32_SPEED); if (ss & speed) { mword = port_mword(pi, speed); if (mword == IFM_NONE) { @@ -4293,86 +4338,134 @@ build_medialist(struct port_info *pi, struct ifmedia *ifm) } if (unknown > 0) /* Add one unknown for all unknown media types. */ ifmedia_add4(ifm, IFM_ETHER | IFM_FDX | IFM_UNKNOWN); - if (lc->supported & FW_PORT_CAP_ANEG) + if (lc->supported & FW_PORT_CAP32_ANEG) ifmedia_add(ifm, IFM_ETHER | IFM_AUTO, 0, NULL); - set_current_media(pi, ifm); + set_current_media(pi); } /* - * Update all the requested_* fields in the link config to something valid (and - * reasonable). + * Initialize the requested fields in the link config based on driver tunables. */ static void -init_l1cfg(struct port_info *pi) +init_link_config(struct port_info *pi) { struct link_config *lc = &pi->link_cfg; PORT_LOCK_ASSERT_OWNED(pi); - /* Gbps -> Mbps */ - lc->requested_speed = port_top_speed(pi) * 1000; + lc->requested_speed = 0; - if (t4_autoneg != 0 && lc->supported & FW_PORT_CAP_ANEG) { - lc->requested_aneg = AUTONEG_ENABLE; - } else { + if (t4_autoneg == 0) lc->requested_aneg = AUTONEG_DISABLE; - } + else if (t4_autoneg == 1) + lc->requested_aneg = AUTONEG_ENABLE; + else + lc->requested_aneg = AUTONEG_AUTO; - lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX); + lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX | + PAUSE_AUTONEG); - if (t4_fec != -1) { - if (t4_fec & FEC_RS && lc->supported & FW_PORT_CAP_FEC_RS) { - lc->requested_fec = FEC_RS; - } else if (t4_fec & FEC_BASER_RS && - lc->supported & FW_PORT_CAP_FEC_BASER_RS) { - lc->requested_fec = FEC_BASER_RS; - } else { - lc->requested_fec = 0; - } - } else { - /* Use the suggested value provided by the firmware in acaps */ - if (lc->advertising & FW_PORT_CAP_FEC_RS && - lc->supported & FW_PORT_CAP_FEC_RS) { - lc->requested_fec = FEC_RS; - } else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS && - lc->supported & FW_PORT_CAP_FEC_BASER_RS) { - lc->requested_fec = FEC_BASER_RS; - } else { - lc->requested_fec = 0; - } + if (t4_fec == -1 || t4_fec & FEC_AUTO) + lc->requested_fec = FEC_AUTO; + else { + lc->requested_fec = FEC_NONE; + if (t4_fec & FEC_RS) + lc->requested_fec |= FEC_RS; + if (t4_fec & FEC_BASER_RS) + lc->requested_fec |= FEC_BASER_RS; } } /* - * Apply the settings in requested_* to the hardware. The parameters are - * expected to be sane. + * Makes sure that all requested settings comply with what's supported by the + * port. Returns the number of settings that were invalid and had to be fixed. */ static int -apply_l1cfg(struct port_info *pi) +fixup_link_config(struct port_info *pi) +{ + int n = 0; + struct link_config *lc = &pi->link_cfg; + uint32_t fwspeed; + + PORT_LOCK_ASSERT_OWNED(pi); + + /* Speed (when not autonegotiating) */ + if (lc->requested_speed != 0) { + fwspeed = speed_to_fwcap(lc->requested_speed); + if ((fwspeed & lc->supported) == 0) { + n++; + lc->requested_speed = 0; + } + } + + /* Link autonegotiation */ + MPASS(lc->requested_aneg == AUTONEG_ENABLE || + lc->requested_aneg == AUTONEG_DISABLE || + lc->requested_aneg == AUTONEG_AUTO); + if (lc->requested_aneg == AUTONEG_ENABLE && + !(lc->supported & FW_PORT_CAP32_ANEG)) { + n++; + lc->requested_aneg = AUTONEG_AUTO; + } + + /* Flow control */ + MPASS((lc->requested_fc & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) == 0); + if (lc->requested_fc & PAUSE_TX && + !(lc->supported & FW_PORT_CAP32_FC_TX)) { + n++; + lc->requested_fc &= ~PAUSE_TX; + } + if (lc->requested_fc & PAUSE_RX && + !(lc->supported & FW_PORT_CAP32_FC_RX)) { + n++; + lc->requested_fc &= ~PAUSE_RX; + } + if (!(lc->requested_fc & PAUSE_AUTONEG) && + !(lc->supported & FW_PORT_CAP32_FORCE_PAUSE)) { + n++; + lc->requested_fc |= PAUSE_AUTONEG; + } + + /* FEC */ + if ((lc->requested_fec & FEC_RS && + !(lc->supported & FW_PORT_CAP32_FEC_RS)) || + (lc->requested_fec & FEC_BASER_RS && + !(lc->supported & FW_PORT_CAP32_FEC_BASER_RS))) { + n++; + lc->requested_fec = FEC_AUTO; + } + + return (n); +} + +/* + * Apply the requested L1 settings, which are expected to be valid, to the + * hardware. + */ +static int +apply_link_config(struct port_info *pi) { struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; -#ifdef INVARIANTS - uint16_t fwspeed; +#ifdef INVARIANTS ASSERT_SYNCHRONIZED_OP(sc); PORT_LOCK_ASSERT_OWNED(pi); if (lc->requested_aneg == AUTONEG_ENABLE) - MPASS(lc->supported & FW_PORT_CAP_ANEG); + MPASS(lc->supported & FW_PORT_CAP32_ANEG); + if (!(lc->requested_fc & PAUSE_AUTONEG)) + MPASS(lc->supported & FW_PORT_CAP32_FORCE_PAUSE); if (lc->requested_fc & PAUSE_TX) - MPASS(lc->supported & FW_PORT_CAP_FC_TX); + MPASS(lc->supported & FW_PORT_CAP32_FC_TX); if (lc->requested_fc & PAUSE_RX) - MPASS(lc->supported & FW_PORT_CAP_FC_RX); - if (lc->requested_fec == FEC_RS) - MPASS(lc->supported & FW_PORT_CAP_FEC_RS); - if (lc->requested_fec == FEC_BASER_RS) - MPASS(lc->supported & FW_PORT_CAP_FEC_BASER_RS); - fwspeed = speed_to_fwspeed(lc->requested_speed); - MPASS(fwspeed != 0); - MPASS(lc->supported & fwspeed); + MPASS(lc->supported & FW_PORT_CAP32_FC_RX); + if (lc->requested_fec & FEC_RS) + MPASS(lc->supported & FW_PORT_CAP32_FEC_RS); + if (lc->requested_fec & FEC_BASER_RS) + MPASS(lc->supported & FW_PORT_CAP32_FEC_BASER_RS); #endif rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc != 0) { @@ -4380,8 +4473,17 @@ apply_l1cfg(struct port_info *pi) if (!(sc->flags & IS_VF) || rc != FW_EPERM) device_printf(pi->dev, "l1cfg failed: %d\n", rc); } else { - lc->fc = lc->requested_fc; - lc->fec = lc->requested_fec; + /* + * An L1_CFG will almost always result in a link-change event if + * the link is up, and the driver will refresh the actual + * fec/fc/etc. when the notification is processed. If the link + * is down then the actual settings are meaningless. + * + * This takes care of the case where a change in the L1 settings + * may not result in a notification. + */ + if (lc->link_ok && !(lc->requested_fc & PAUSE_AUTONEG)) + lc->fc = lc->requested_fc & (PAUSE_TX | PAUSE_RX); } return (rc); } @@ -4635,9 +4737,18 @@ cxgbe_init_synchronized(struct vi_info *vi) if (rc) goto done; /* error message displayed already */ + PORT_LOCK(pi); + if (pi->up_vis == 0) { + t4_update_port_info(pi); + fixup_link_config(pi); + build_medialist(pi); + apply_link_config(pi); + } + rc = -t4_enable_vi(sc, sc->mbox, vi->viid, true, true); if (rc != 0) { if_printf(ifp, "enable_vi failed: %d\n", rc); + PORT_UNLOCK(pi); goto done; } @@ -4664,12 +4775,7 @@ cxgbe_init_synchronized(struct vi_info *vi) } /* all ok */ - PORT_LOCK(pi); - if (pi->up_vis++ == 0) { - t4_update_port_info(pi); - build_medialist(pi, &pi->media); - apply_l1cfg(pi); - } + pi->up_vis++; ifp->if_drv_flags |= IFF_DRV_RUNNING; if (pi->nvi > 1 || sc->flags & IS_VF) @@ -4744,11 +4850,10 @@ cxgbe_uninit_synchronized(struct vi_info *vi) return (0); } - pi->link_cfg.link_ok = 0; + pi->link_cfg.link_ok = false; pi->link_cfg.speed = 0; pi->link_cfg.link_down_rc = 255; t4_os_link_changed(pi); - pi->old_link_cfg = pi->link_cfg; PORT_UNLOCK(pi); return (0); @@ -6512,7 +6617,7 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (req->newptr == NULL) { struct sbuf *sb; - static char *bits = "\20\1PAUSE_RX\2PAUSE_TX"; + static char *bits = "\20\1RX\2TX\3AUTO"; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -6522,14 +6627,21 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - sbuf_printf(sb, "%b", lc->fc & (PAUSE_TX | PAUSE_RX), bits); + if (lc->link_ok) { + sbuf_printf(sb, "%b", (lc->fc & (PAUSE_TX | PAUSE_RX)) | + (lc->requested_fc & PAUSE_AUTONEG), bits); + } else { + sbuf_printf(sb, "%b", lc->requested_fc & (PAUSE_TX | + PAUSE_RX | PAUSE_AUTONEG), bits); + } rc = sbuf_finish(sb); sbuf_delete(sb); } else { char s[2]; int n; - s[0] = '0' + (lc->requested_fc & (PAUSE_TX | PAUSE_RX)); + s[0] = '0' + (lc->requested_fc & (PAUSE_TX | PAUSE_RX | + PAUSE_AUTONEG)); s[1] = 0; rc = sysctl_handle_string(oidp, s, sizeof(s), req); @@ -6541,7 +6653,7 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (s[0] < '0' || s[0] > '9') return (EINVAL); /* not a number */ n = s[0] - '0'; - if (n & ~(PAUSE_TX | PAUSE_RX)) + if (n & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) return (EINVAL); /* some other bit is set too */ rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, @@ -6549,15 +6661,11 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (rc) return (rc); PORT_LOCK(pi); - if ((lc->requested_fc & (PAUSE_TX | PAUSE_RX)) != n) { - lc->requested_fc &= ~(PAUSE_TX | PAUSE_RX); - lc->requested_fc |= n; - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - if (rc == 0) { - lc->fc = lc->requested_fc; - set_current_media(pi, &pi->media); - } - } + lc->requested_fc = n; + fixup_link_config(pi); + if (pi->up_vis > 0) + rc = apply_link_config(pi); + set_current_media(pi); PORT_UNLOCK(pi); end_synchronized_op(sc, 0); } @@ -6572,10 +6680,11 @@ sysctl_fec(SYSCTL_HANDLER_ARGS) struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; + int8_t old; if (req->newptr == NULL) { struct sbuf *sb; - static char *bits = "\20\1RS\2BASER_RS\3RESERVED"; + static char *bits = "\20\1RS\2BASE-R\3RSVD1\4RSVD2\5RSVD3\6AUTO"; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -6585,43 +6694,68 @@ sysctl_fec(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - sbuf_printf(sb, "%b", lc->fec & M_FW_PORT_CAP_FEC, bits); + /* + * Display the requested_fec when the link is down -- the actual + * FEC makes sense only when the link is up. + */ + if (lc->link_ok) { + sbuf_printf(sb, "%b", (lc->fec & M_FW_PORT_CAP32_FEC) | + (lc->requested_fec & FEC_AUTO), bits); + } else { + sbuf_printf(sb, "%b", lc->requested_fec, bits); + } rc = sbuf_finish(sb); sbuf_delete(sb); } else { - char s[2]; + char s[3]; int n; - s[0] = '0' + (lc->requested_fec & M_FW_PORT_CAP_FEC); - s[1] = 0; + snprintf(s, sizeof(s), "%d", + lc->requested_fec == FEC_AUTO ? -1 : + lc->requested_fec & M_FW_PORT_CAP32_FEC); rc = sysctl_handle_string(oidp, s, sizeof(s), req); if (rc != 0) return(rc); - if (s[1] != 0) - return (EINVAL); - if (s[0] < '0' || s[0] > '9') - return (EINVAL); /* not a number */ - n = s[0] - '0'; - if (n & ~M_FW_PORT_CAP_FEC) - return (EINVAL); /* some other bit is set too */ - if (!powerof2(n)) - return (EINVAL); /* one bit can be set at most */ + n = strtol(&s[0], NULL, 0); + if (n < 0 || n & FEC_AUTO) + n = FEC_AUTO; + else { + if (n & ~M_FW_PORT_CAP32_FEC) + return (EINVAL);/* some other bit is set too */ + if (!powerof2(n)) + return (EINVAL);/* one bit can be set at most */ + } rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4fec"); if (rc) return (rc); PORT_LOCK(pi); - if ((lc->requested_fec & M_FW_PORT_CAP_FEC) != n) { - lc->requested_fec = n & - G_FW_PORT_CAP_FEC(lc->supported); - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - if (rc == 0) { - lc->fec = lc->requested_fec; + old = lc->requested_fec; + if (n == FEC_AUTO) + lc->requested_fec = FEC_AUTO; + else if (n == 0) + lc->requested_fec = FEC_NONE; + else { + if ((lc->supported | V_FW_PORT_CAP32_FEC(n)) != + lc->supported) { + rc = ENOTSUP; + goto done; + } + lc->requested_fec = n; + } + fixup_link_config(pi); + if (pi->up_vis > 0) { + rc = apply_link_config(pi); + if (rc != 0) { + lc->requested_fec = old; + if (rc == FW_EPROTO) + rc = ENOTSUP; } } +done: PORT_UNLOCK(pi); end_synchronized_op(sc, 0); } @@ -6635,10 +6769,10 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS) struct port_info *pi = arg1; struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; - int rc, val, old; + int rc, val; - if (lc->supported & FW_PORT_CAP_ANEG) - val = lc->requested_aneg == AUTONEG_ENABLE ? 1 : 0; + if (lc->supported & FW_PORT_CAP32_ANEG) + val = lc->requested_aneg == AUTONEG_DISABLE ? 0 : 1; else val = -1; rc = sysctl_handle_int(oidp, &val, 0, req); @@ -6649,28 +6783,22 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS) else if (val == 1) val = AUTONEG_ENABLE; else - return (EINVAL); + val = AUTONEG_AUTO; rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4aneg"); if (rc) return (rc); PORT_LOCK(pi); - if ((lc->supported & FW_PORT_CAP_ANEG) == 0) { + if (val == AUTONEG_ENABLE && !(lc->supported & FW_PORT_CAP32_ANEG)) { rc = ENOTSUP; goto done; } - if (lc->requested_aneg == val) { - rc = 0; /* no change, do nothing. */ - goto done; - } - old = lc->requested_aneg; lc->requested_aneg = val; - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - if (rc != 0) - lc->requested_aneg = old; - else - set_current_media(pi, &pi->media); + fixup_link_config(pi); + if (pi->up_vis > 0) + rc = apply_link_config(pi); + set_current_media(pi); done: PORT_UNLOCK(pi); end_synchronized_op(sc, 0); @@ -9407,13 +9535,17 @@ t4_os_portmod_changed(struct port_info *pi) NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM" }; - MPASS((pi->flags & FIXED_IFMEDIA) == 0); + KASSERT((pi->flags & FIXED_IFMEDIA) == 0, + ("%s: port_type %u", __func__, pi->port_type)); vi = &pi->vi[0]; if (begin_synchronized_op(sc, vi, HOLD_LOCK, "t4mod") == 0) { PORT_LOCK(pi); - build_medialist(pi, &pi->media); - apply_l1cfg(pi); + build_medialist(pi); + if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) { + fixup_link_config(pi); + apply_link_config(pi); + } PORT_UNLOCK(pi); end_synchronized_op(sc, LOCK_HELD); } diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 4a6ac900962b..684606a8d5b5 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -634,7 +634,7 @@ write_tx_wr(void *dst, struct toepcb *toep, unsigned int immdlen, if (txalign > 0) { struct tcpcb *tp = intotcpcb(toep->inp); - if (plen < 2 * tp->t_maxseg || is_10G_port(toep->vi->pi)) + if (plen < 2 * tp->t_maxseg) txwr->lsodisable_to_flags |= htobe32(F_FW_OFLD_TX_DATA_WR_LSODISABLE); else diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index e1593b02db25..a4394de9c552 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -360,7 +360,7 @@ static devclass_t dc_devclass; DRIVER_MODULE_ORDERED(dc, pci, dc_driver, dc_devclass, NULL, NULL, SI_ORDER_ANY); MODULE_PNP_INFO("W32:vendor/device;U8:revision;D:#", pci, dc, dc_devs, - sizeof(dc_devs[0]), nitems(dc_devs) - 1); + nitems(dc_devs) - 1); DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, NULL, NULL); #define DC_SETBIT(sc, reg, x) \ diff --git a/sys/dev/drm2/drm_os_freebsd.c b/sys/dev/drm2/drm_os_freebsd.c index 8489ca848027..c7b0bce2c7ab 100644 --- a/sys/dev/drm2/drm_os_freebsd.c +++ b/sys/dev/drm2/drm_os_freebsd.c @@ -395,8 +395,8 @@ drm_clflush_virt_range(char *addr, unsigned long length) { #if defined(__i386__) || defined(__amd64__) - pmap_invalidate_cache_range((vm_offset_t)addr, - (vm_offset_t)addr + length, TRUE); + pmap_force_invalidate_cache_range((vm_offset_t)addr, + (vm_offset_t)addr + length); #else DRM_ERROR("drm_clflush_virt_range not implemented on this architecture"); #endif diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm2/i915/i915_drv.c index f0c8867501b3..8a7168861aca 100644 --- a/sys/dev/drm2/i915/i915_drv.c +++ b/sys/dev/drm2/i915/i915_drv.c @@ -1237,7 +1237,7 @@ MODULE_DEPEND(i915kms, iicbus, 1, 1, 1); MODULE_DEPEND(i915kms, iic, 1, 1, 1); MODULE_DEPEND(i915kms, iicbb, 1, 1, 1); MODULE_PNP_INFO("U32:vendor;U32:device;P:#;D:#", vgapci, i915, pciidlist, - sizeof(pciidlist[0]), nitems(pciidlist) - 1); + nitems(pciidlist) - 1); /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ diff --git a/sys/dev/drm2/i915/intel_ringbuffer.c b/sys/dev/drm2/i915/intel_ringbuffer.c index 92a792746b1b..c6c242c875c3 100644 --- a/sys/dev/drm2/i915/intel_ringbuffer.c +++ b/sys/dev/drm2/i915/intel_ringbuffer.c @@ -471,8 +471,8 @@ init_pipe_control(struct intel_ring_buffer *ring) if (pc->cpu_page == NULL) goto err_unpin; pmap_qenter((uintptr_t)pc->cpu_page, &obj->pages[0], 1); - pmap_invalidate_cache_range((vm_offset_t)pc->cpu_page, - (vm_offset_t)pc->cpu_page + PAGE_SIZE, FALSE); + pmap_force_invalidate_cache_range((vm_offset_t)pc->cpu_page, + (vm_offset_t)pc->cpu_page + PAGE_SIZE); pc->obj = obj; ring->private = pc; @@ -1102,8 +1102,9 @@ static int init_status_page(struct intel_ring_buffer *ring) } pmap_qenter((vm_offset_t)ring->status_page.page_addr, &obj->pages[0], 1); - pmap_invalidate_cache_range((vm_offset_t)ring->status_page.page_addr, - (vm_offset_t)ring->status_page.page_addr + PAGE_SIZE, FALSE); + pmap_force_invalidate_cache_range( + (vm_offset_t)ring->status_page.page_addr, + (vm_offset_t)ring->status_page.page_addr + PAGE_SIZE); ring->status_page.obj = obj; memset(ring->status_page.page_addr, 0, PAGE_SIZE); diff --git a/sys/dev/drm2/radeon/radeon_drv.c b/sys/dev/drm2/radeon/radeon_drv.c index bf3dd063c178..73f83ccef0cb 100644 --- a/sys/dev/drm2/radeon/radeon_drv.c +++ b/sys/dev/drm2/radeon/radeon_drv.c @@ -402,4 +402,4 @@ MODULE_DEPEND(radeonkms, iic, 1, 1, 1); MODULE_DEPEND(radeonkms, iicbb, 1, 1, 1); MODULE_DEPEND(radeonkms, firmware, 1, 1, 1); MODULE_PNP_INFO("U32:vendor;U32:device;P:#;D:#", vgapci, radeonkms, - pciidlist, sizeof(pciidlist[0]), nitems(pciidlist) - 1); + pciidlist, nitems(pciidlist) - 1); diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index a95d606ac34f..93714cd10710 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -709,7 +709,8 @@ em_set_num_queues(if_ctx_t ctx) #define IGB_CAPS \ IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \ - IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6; + IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 |\ + IFCAP_TSO6 /********************************************************************* * Device initialization routine diff --git a/sys/dev/ed/if_ed_pci.c b/sys/dev/ed/if_ed_pci.c index b487b97de820..8ada958abcbe 100644 --- a/sys/dev/ed/if_ed_pci.c +++ b/sys/dev/ed/if_ed_pci.c @@ -145,5 +145,5 @@ static driver_t ed_pci_driver = { DRIVER_MODULE(ed, pci, ed_pci_driver, ed_devclass, 0, 0); MODULE_DEPEND(ed, pci, 1, 1, 1); MODULE_DEPEND(ed, ether, 1, 1, 1); -MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ed, pci_ids, sizeof(pci_ids[0]), +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ed, pci_ids, nitems(pci_ids) - 1); diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c index cadc8bdbf677..a27de7db593f 100644 --- a/sys/dev/ena/ena.c +++ b/sys/dev/ena/ena.c @@ -3948,7 +3948,7 @@ static driver_t ena_driver = { devclass_t ena_devclass; DRIVER_MODULE(ena, pci, ena_driver, ena_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, ena, ena_vendor_info_array, - sizeof(ena_vendor_info_array[0]), nitems(ena_vendor_info_array) - 1); + nitems(ena_vendor_info_array) - 1); MODULE_DEPEND(ena, pci, 1, 1, 1); MODULE_DEPEND(ena, ether, 1, 1, 1); diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index a5ce9e452872..294d9d5e55aa 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -189,7 +189,7 @@ static devclass_t et_devclass; DRIVER_MODULE(et, pci, et_driver, et_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, et, et_devices, - sizeof(et_devices[0]), nitems(et_devices) - 1); + nitems(et_devices) - 1); DRIVER_MODULE(miibus, et, miibus_driver, miibus_devclass, 0, 0); static int et_rx_intr_npkts = 32; diff --git a/sys/dev/ffec/if_ffec.c b/sys/dev/ffec/if_ffec.c index ea291ab8df2d..d52bf9a4e3d5 100644 --- a/sys/dev/ffec/if_ffec.c +++ b/sys/dev/ffec/if_ffec.c @@ -801,7 +801,8 @@ ffec_alloc_mbufcl(struct ffec_softc *sc) struct mbuf *m; m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; + if (m != NULL) + m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; return (m); } diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index b89f8329a4f2..2c3297a05bea 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -308,7 +308,7 @@ static devclass_t fxp_devclass; DRIVER_MODULE_ORDERED(fxp, pci, fxp_driver, fxp_devclass, NULL, NULL, SI_ORDER_ANY); MODULE_PNP_INFO("U16:vendor;U16:device", pci, fxp, fxp_ident_table, - sizeof(fxp_ident_table[0]), nitems(fxp_ident_table) - 1); + nitems(fxp_ident_table) - 1); DRIVER_MODULE(miibus, fxp, miibus_driver, miibus_devclass, NULL, NULL); static struct resource_spec fxp_res_spec_mem[] = { diff --git a/sys/dev/gem/if_gem_pci.c b/sys/dev/gem/if_gem_pci.c index af9db3da9c3e..ce3027fb3441 100644 --- a/sys/dev/gem/if_gem_pci.c +++ b/sys/dev/gem/if_gem_pci.c @@ -116,7 +116,7 @@ static driver_t gem_pci_driver = { DRIVER_MODULE(gem, pci, gem_pci_driver, gem_devclass, 0, 0); MODULE_PNP_INFO("W32:vendor/device", pci, gem, gem_pci_devlist, - sizeof(gem_pci_devlist[0]), nitems(gem_pci_devlist) - 1); + nitems(gem_pci_devlist) - 1); MODULE_DEPEND(gem, pci, 1, 1, 1); MODULE_DEPEND(gem, ether, 1, 1, 1); diff --git a/sys/dev/ida/ida_pci.c b/sys/dev/ida/ida_pci.c index 63a18ecf0259..3911a70c0b46 100644 --- a/sys/dev/ida/ida_pci.c +++ b/sys/dev/ida/ida_pci.c @@ -306,3 +306,5 @@ ida_pci_attach(device_t dev) } DRIVER_MODULE(ida, pci, ida_pci_driver, ida_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ida, board_id, + nitems(board_id) - 1); diff --git a/sys/dev/intpm/intpm.c b/sys/dev/intpm/intpm.c index 4b4cf9ab10c8..15da5e861a07 100644 --- a/sys/dev/intpm/intpm.c +++ b/sys/dev/intpm/intpm.c @@ -896,4 +896,4 @@ DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); MODULE_VERSION(intsmb, 1); MODULE_PNP_INFO("W32:vendor/device;D:#", pci, intpm, intsmb_products, - sizeof(intsmb_products[0]), nitems(intsmb_products)); + nitems(intsmb_products)); diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 744c26dfafdc..b03de58fcb55 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -241,7 +241,7 @@ static struct _pcsid }; MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ioat, pci_ids, - sizeof(pci_ids[0]), nitems(pci_ids)); + nitems(pci_ids)); /* * OS <-> Driver linkage functions diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 1da31934f738..e99d5aedc714 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -203,7 +203,7 @@ static devclass_t ipw_devclass; DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ipw, ipw_ident_table, - sizeof(ipw_ident_table[0]), nitems(ipw_ident_table) - 1); + nitems(ipw_ident_table) - 1); MODULE_VERSION(ipw, 1); diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index e46082c0b3b8..3e79f4b400c0 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -372,7 +372,8 @@ static driver_t iwn_driver = { static devclass_t iwn_devclass; DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, NULL, NULL); - +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, iwn, iwn_ident_table, + nitems(iwn_ident_table) - 1); MODULE_VERSION(iwn, 1); MODULE_DEPEND(iwn, firmware, 1, 1, 1); diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index cca610664065..44843ff3fc98 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -238,7 +238,7 @@ static driver_t ix_driver = { devclass_t ix_devclass; DRIVER_MODULE(ix, pci, ix_driver, ix_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, ix, ixgbe_vendor_info_array, - sizeof(ixgbe_vendor_info_array[0]), nitems(ixgbe_vendor_info_array) - 1); + nitems(ixgbe_vendor_info_array) - 1); MODULE_DEPEND(ix, pci, 1, 1, 1); MODULE_DEPEND(ix, ether, 1, 1, 1); diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c index a6a3465b60d7..91f2f8ef755e 100644 --- a/sys/dev/ixgbe/if_ixv.c +++ b/sys/dev/ixgbe/if_ixv.c @@ -144,7 +144,7 @@ static driver_t ixv_driver = { devclass_t ixv_devclass; DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, ixv, ixv_vendor_info_array, - sizeof(ixv_vendor_info_array[0]), nitems(ixv_vendor_info_array) - 1); + nitems(ixv_vendor_info_array) - 1); MODULE_DEPEND(ixv, pci, 1, 1, 1); MODULE_DEPEND(ixv, ether, 1, 1, 1); #ifdef DEV_NETMAP diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 6d83545ae941..23c9d13c695d 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -150,6 +150,7 @@ static driver_t ixl_driver = { devclass_t ixl_devclass; DRIVER_MODULE(ixl, pci, ixl_driver, ixl_devclass, 0, 0); +IFLIB_PNP_INFO(pci, ixl, ixl_vendor_info_array); MODULE_VERSION(ixl, 3); MODULE_DEPEND(ixl, pci, 1, 1, 1); diff --git a/sys/dev/ixl/if_ixlv.c b/sys/dev/ixl/if_ixlv.c index f0a91b761f87..dd72d52ab187 100644 --- a/sys/dev/ixl/if_ixlv.c +++ b/sys/dev/ixl/if_ixlv.c @@ -149,7 +149,9 @@ static driver_t ixlv_driver = { devclass_t ixlv_devclass; DRIVER_MODULE(ixlv, pci, ixlv_driver, ixlv_devclass, 0, 0); - +MODULE_PNP_INFO("U32:vendor;U32:device;U32:subvendor;U32:subdevice;U32:revision", + pci, ixlv, ixlv_vendor_info_array, + nitems(ixlv_vendor_info_array) - 1); MODULE_DEPEND(ixlv, pci, 1, 1, 1); MODULE_DEPEND(ixlv, ether, 1, 1, 1); MODULE_DEPEND(ixlv, iflib, 1, 1, 1); diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c index d63c5ae6435f..ee609b328990 100644 --- a/sys/dev/mfi/mfi_pci.c +++ b/sys/dev/mfi/mfi_pci.c @@ -106,8 +106,6 @@ static driver_t mfi_pci_driver = { }; static devclass_t mfi_devclass; -DRIVER_MODULE(mfi, pci, mfi_pci_driver, mfi_devclass, 0, 0); -MODULE_VERSION(mfi, 1); static int mfi_msi = 1; SYSCTL_INT(_hw_mfi, OID_AUTO, msi, CTLFLAG_RDTUN, &mfi_msi, 0, @@ -159,6 +157,11 @@ struct mfi_ident { {0, 0, 0, 0, 0, NULL} }; +DRIVER_MODULE(mfi, pci, mfi_pci_driver, mfi_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;U16:subvendor;U16:subdevice", pci, mfi, + mfi_identifiers, nitems(mfi_identifiers) - 1); +MODULE_VERSION(mfi, 1); + static struct mfi_ident * mfi_find_ident(device_t dev) { diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c index 03f3143040c2..e86bd9e102ba 100644 --- a/sys/dev/mpr/mpr_pci.c +++ b/sys/dev/mpr/mpr_pci.c @@ -88,9 +88,6 @@ static driver_t mpr_pci_driver = { sizeof(struct mpr_softc) }; -static devclass_t mpr_devclass; -DRIVER_MODULE(mpr, pci, mpr_pci_driver, mpr_devclass, 0, 0); -MODULE_DEPEND(mpr, cam, 1, 1, 1); struct mpr_ident { uint16_t vendor; @@ -154,6 +151,14 @@ struct mpr_ident { { 0, 0, 0, 0, 0, NULL } }; + +static devclass_t mpr_devclass; +DRIVER_MODULE(mpr, pci, mpr_pci_driver, mpr_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;U16:subvendor;U16:subdevice;D:#", pci, + mpr, mpr_identifiers, nitems(mpr_identifiers) - 1); + +MODULE_DEPEND(mpr, cam, 1, 1, 1); + static struct mpr_ident * mpr_find_ident(device_t dev) { diff --git a/sys/dev/mps/mps_pci.c b/sys/dev/mps/mps_pci.c index a81fe8a7300f..1e12c9a6906a 100644 --- a/sys/dev/mps/mps_pci.c +++ b/sys/dev/mps/mps_pci.c @@ -88,10 +88,6 @@ static driver_t mps_pci_driver = { sizeof(struct mps_softc) }; -static devclass_t mps_devclass; -DRIVER_MODULE(mps, pci, mps_pci_driver, mps_devclass, 0, 0); -MODULE_DEPEND(mps, cam, 1, 1, 1); - struct mps_ident { uint16_t vendor; uint16_t device; @@ -147,6 +143,10 @@ struct mps_ident { { 0, 0, 0, 0, 0, NULL } }; +static devclass_t mps_devclass; +DRIVER_MODULE(mps, pci, mps_pci_driver, mps_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;U16:subvendor;U16:subdevice", pci, mps, + mps_identifiers, nitems(mps_identifiers) - 1); static struct mps_ident * mps_find_ident(device_t dev) { diff --git a/sys/dev/mvs/mvs_pci.c b/sys/dev/mvs/mvs_pci.c index cd6afce40f5c..4774390b272c 100644 --- a/sys/dev/mvs/mvs_pci.c +++ b/sys/dev/mvs/mvs_pci.c @@ -521,6 +521,8 @@ static driver_t mvs_driver = { sizeof(struct mvs_controller) }; DRIVER_MODULE(mvs, pci, mvs_driver, mvs_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device", pci, mvs, mvs_ids, + nitems(mvs_ids) - 1); MODULE_VERSION(mvs, 1); MODULE_DEPEND(mvs, cam, 1, 1, 1); diff --git a/sys/dev/my/if_my.c b/sys/dev/my/if_my.c index b1d5e3586c9d..ef5ef7613b99 100644 --- a/sys/dev/my/if_my.c +++ b/sys/dev/my/if_my.c @@ -163,6 +163,8 @@ static driver_t my_driver = { static devclass_t my_devclass; DRIVER_MODULE(my, pci, my_driver, my_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, my, my_devs, + nitems(my_devs) - 1); MODULE_DEPEND(my, pci, 1, 1, 1); MODULE_DEPEND(my, ether, 1, 1, 1); diff --git a/sys/dev/ncr/ncr.c b/sys/dev/ncr/ncr.c index 5cfb413731c2..58bc2a6af01c 100644 --- a/sys/dev/ncr/ncr.c +++ b/sys/dev/ncr/ncr.c @@ -7109,7 +7109,7 @@ static devclass_t ncr_devclass; DRIVER_MODULE(ncr, pci, ncr_driver, ncr_devclass, 0, 0); MODULE_PNP_INFO("W32:vendor/device;U16:#;D:#", pci, ncr, ncr_chip_table, - sizeof(ncr_chip_table[0]), nitems(ncr_chip_table)); + nitems(ncr_chip_table)); MODULE_DEPEND(ncr, cam, 1, 1, 1); MODULE_DEPEND(ncr, pci, 1, 1, 1); diff --git a/sys/dev/ntb/ntb_hw/ntb_hw_intel.c b/sys/dev/ntb/ntb_hw/ntb_hw_intel.c index 3bb57fcb71d0..d61f664d8cff 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw_intel.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw_intel.c @@ -3120,4 +3120,4 @@ DRIVER_MODULE(ntb_hw_intel, pci, ntb_intel_driver, ntb_hw_devclass, NULL, NULL); MODULE_DEPEND(ntb_hw_intel, ntb, 1, 1, 1); MODULE_VERSION(ntb_hw_intel, 1); MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ntb_hw_intel, pci_ids, - sizeof(pci_ids[0]), nitems(pci_ids)); + nitems(pci_ids)); diff --git a/sys/dev/oce/oce_if.c b/sys/dev/oce/oce_if.c index 23e32a59de49..0b7aa4da2372 100644 --- a/sys/dev/oce/oce_if.c +++ b/sys/dev/oce/oce_if.c @@ -214,12 +214,6 @@ static driver_t oce_driver = { static devclass_t oce_devclass; -DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, 0, 0); -MODULE_DEPEND(oce, pci, 1, 1, 1); -MODULE_DEPEND(oce, ether, 1, 1, 1); -MODULE_VERSION(oce, 1); - - /* global vars */ const char component_revision[32] = {"///" COMPONENT_REVISION "///"}; @@ -242,6 +236,15 @@ static uint32_t supportedDevices[] = { (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_SH }; + +DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device", pci, oce, supportedDevices, + nitems(supportedDevices)); +MODULE_DEPEND(oce, pci, 1, 1, 1); +MODULE_DEPEND(oce, ether, 1, 1, 1); +MODULE_VERSION(oce, 1); + + POCE_SOFTC softc_head = NULL; POCE_SOFTC softc_tail = NULL; diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h index 537856b97ef7..edc90ed7bf3c 100644 --- a/sys/dev/ofw/ofw_bus_subr.h +++ b/sys/dev/ofw/ofw_bus_subr.h @@ -67,7 +67,7 @@ struct intr_map_data_fdt { #define SIMPLEBUS_PNP_DESCR "Z:compat;P:#;" #define SIMPLEBUS_PNP_INFO(t) \ - MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); + MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t) / sizeof(t[0])); /* Generic implementation of ofw_bus_if.m methods and helper routines */ int ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *, phandle_t); diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h index 5138c243f5b7..87f41850ec5c 100644 --- a/sys/dev/pccard/pccardvar.h +++ b/sys/dev/pccard/pccardvar.h @@ -102,7 +102,7 @@ struct pccard_product { */ #define PCCARD_PNP_DESCR "D:#;V32:manufacturer;V32:product;Z:cisvendor;Z:cisproduct;" #define PCCARD_PNP_INFO(t) \ - MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), nitems(t) - 1); \ + MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, nitems(t) - 1) typedef int (*pccard_product_match_fn) (device_t dev, const struct pccard_product *ent, int vpfmatch); diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c index bbffb8b53200..f2f6387c8aaa 100644 --- a/sys/dev/pccbb/pccbb_pci.c +++ b/sys/dev/pccbb/pccbb_pci.c @@ -983,4 +983,6 @@ static driver_t cbb_driver = { }; DRIVER_MODULE(cbb, pci, cbb_driver, cbb_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, cbb, yc_chipsets, + nitems(yc_chipsets) - 1); MODULE_DEPEND(cbb, exca, 1, 1, 1); diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index 00589c4b83da..edec95c8e67f 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -122,6 +122,9 @@ #define PCIM_MFDEV 0x80 #define PCIR_BIST 0x0f +/* PCI Spec rev 2.2: 0FFFFh is an invalid value for Vendor ID. */ +#define PCIV_INVALID 0xffff + /* Capability Register Offsets */ #define PCICAP_ID 0x0 diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index c5a8afb4ed23..376fb96594ce 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -311,7 +311,7 @@ struct pci_device_table { "M16:mask;U16:vendor;U16:device;U16:subvendor;U16:subdevice;" \ "U16:class;U16:subclass;U16:revid;" #define PCI_PNP_INFO(table) \ - MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, \ sizeof(table) / sizeof(table[0])) const struct pci_device_table *pci_match_device(device_t child, diff --git a/sys/dev/pcn/if_pcn.c b/sys/dev/pcn/if_pcn.c index 6073310b2ac9..0e91df03ea18 100644 --- a/sys/dev/pcn/if_pcn.c +++ b/sys/dev/pcn/if_pcn.c @@ -193,6 +193,8 @@ static driver_t pcn_driver = { static devclass_t pcn_devclass; DRIVER_MODULE(pcn, pci, pcn_driver, pcn_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, pcn, pcn_devs, + nitems(pcn_devs) - 1); DRIVER_MODULE(miibus, pcn, miibus_driver, miibus_devclass, 0, 0); #define PCN_CSR_SETBIT(sc, reg, x) \ diff --git a/sys/dev/puc/puc_pci.c b/sys/dev/puc/puc_pci.c index f0c6aa81dde4..012a16dc9e9b 100644 --- a/sys/dev/puc/puc_pci.c +++ b/sys/dev/puc/puc_pci.c @@ -200,4 +200,4 @@ static driver_t puc_pci_driver = { DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, puc, - puc_pci_devices, sizeof(puc_pci_devices[0]), nitems(puc_pci_devices) - 1); + puc_pci_devices, nitems(puc_pci_devices) - 1); diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c index 6d9de66e53c8..41e81d573536 100644 --- a/sys/dev/ral/if_ral_pci.c +++ b/sys/dev/ral/if_ral_pci.c @@ -178,6 +178,8 @@ static driver_t ral_pci_driver = { static devclass_t ral_devclass; DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, NULL, NULL); +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ral, ral_pci_ids, + nitems(ral_pci_ids) - 1); static int ral_pci_probe(device_t dev) diff --git a/sys/dev/rl/if_rl.c b/sys/dev/rl/if_rl.c index 7e8c63131607..e5d4787ebbe9 100644 --- a/sys/dev/rl/if_rl.c +++ b/sys/dev/rl/if_rl.c @@ -259,6 +259,8 @@ static driver_t rl_driver = { static devclass_t rl_devclass; DRIVER_MODULE(rl, pci, rl_driver, rl_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, rl, rl_devs, + nitems(rl_devs) - 1); DRIVER_MODULE(rl, cardbus, rl_driver, rl_devclass, 0, 0); DRIVER_MODULE(miibus, rl, miibus_driver, miibus_devclass, 0, 0); diff --git a/sys/dev/spibus/spi.h b/sys/dev/spibus/spi.h index 1a9c1496a77d..0c12929bee15 100644 --- a/sys/dev/spibus/spi.h +++ b/sys/dev/spibus/spi.h @@ -43,4 +43,4 @@ struct spi_command { #define SPIBUS_PNP_DESCR "Z:compat;P:#;" #define SPIBUS_PNP_INFO(t) \ - MODULE_PNP_INFO(SPIBUS_PNP_DESCR, spibus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); + MODULE_PNP_INFO(SPIBUS_PNP_DESCR, spibus, t, t, sizeof(t) / sizeof(t[0])); diff --git a/sys/dev/uart/uart_bus_pccard.c b/sys/dev/uart/uart_bus_pccard.c index 3a8446a871f6..8b672ebeadb0 100644 --- a/sys/dev/uart/uart_bus_pccard.c +++ b/sys/dev/uart/uart_bus_pccard.c @@ -103,4 +103,4 @@ uart_pccard_attach(device_t dev) DRIVER_MODULE(uart, pccard, uart_pccard_driver, uart_devclass, 0, 0); MODULE_PNP_INFO("U32:function_type;", pccard, uart, &uart_pccard_function, - sizeof(uart_pccard_function), 1); + 1); diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c index f4be108ab7b2..15b4472a37b2 100644 --- a/sys/dev/uart/uart_bus_pci.c +++ b/sys/dev/uart/uart_bus_pci.c @@ -125,6 +125,7 @@ static const struct pci_id pci_ns8250_ids[] = { 128 * DEFAULT_RCLK, 2}, { 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10}, { 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, +{ 0x1d0f, 0x8250, 0x1d0f, 0, "Amazon PCI serial device", 0x10 }, { 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10, 8 * DEFAULT_RCLK }, { 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10, diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 147b5d5e71b8..d5648c0301ea 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -342,13 +342,13 @@ struct usb_device_id { #define USB_STD_PNP_HOST_INFO USB_STD_PNP_INFO "T:mode=host;" #define USB_STD_PNP_DEVICE_INFO USB_STD_PNP_INFO "T:mode=device;" #define USB_PNP_HOST_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_HOST_INFO, uhub, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(USB_STD_PNP_HOST_INFO, uhub, table, table, \ sizeof(table) / sizeof(table[0])) #define USB_PNP_DEVICE_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, uhub, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, uhub, table, table, \ sizeof(table) / sizeof(table[0])) #define USB_PNP_DUAL_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_INFO, uhub, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(USB_STD_PNP_INFO, uhub, table, table, \ sizeof(table) / sizeof(table[0])) /* check that the size of the structure above is correct */ diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 0afe62a522de..29d323399894 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -334,7 +334,7 @@ static devclass_t xl_devclass; DRIVER_MODULE_ORDERED(xl, pci, xl_driver, xl_devclass, NULL, NULL, SI_ORDER_ANY); DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, NULL, NULL); -MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, xl, xl_devs, sizeof(xl_devs[0]), +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, xl, xl_devs, nitems(xl_devs) - 1); static void diff --git a/sys/geom/raid/tr_raid0.c b/sys/geom/raid/tr_raid0.c index 78fa1b920f8a..33a802103f0c 100644 --- a/sys/geom/raid/tr_raid0.c +++ b/sys/geom/raid/tr_raid0.c @@ -323,7 +323,7 @@ g_raid_tr_iodone_raid0(struct g_raid_tr_object *tr, pbp->bio_inbed++; if (pbp->bio_children == pbp->bio_inbed) { pbp->bio_completed = pbp->bio_length; - g_raid_iodone(pbp, bp->bio_error); + g_raid_iodone(pbp, pbp->bio_error); } } diff --git a/sys/i386/i386/npx.c b/sys/i386/i386/npx.c index a2edacec987e..665b55b1c35b 100644 --- a/sys/i386/i386/npx.c +++ b/sys/i386/i386/npx.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #include <machine/segments.h> #include <machine/ucontext.h> +#include <x86/ifunc.h> #include <machine/intr_machdep.h> @@ -183,7 +184,6 @@ CTASSERT(X86_XSTATE_XCR0_OFFSET >= offsetof(struct savexmm, sv_pad) && static void fpu_clean_state(void); -static void fpusave(union savefpu *); static void fpurstor(union savefpu *); int hw_float; @@ -206,8 +206,6 @@ struct xsave_area_elm_descr { u_int size; } *xsave_area_desc; -static int use_xsaveopt; - static volatile u_int npx_traps_while_probing; alias_for_inthand_t probetrap; @@ -314,6 +312,69 @@ npx_probe(void) return (hw_float); } +static void +npxsave_xsaveopt(union savefpu *addr) +{ + + xsaveopt((char *)addr, xsave_mask); +} + +static void +fpusave_xsave(union savefpu *addr) +{ + + xsave((char *)addr, xsave_mask); +} + +static void +fpusave_fxsave(union savefpu *addr) +{ + + fxsave((char *)addr); +} + +static void +fpusave_fnsave(union savefpu *addr) +{ + + fnsave((char *)addr); +} + +static void +init_xsave(void) +{ + + if (use_xsave) + return; + if (!cpu_fxsr || (cpu_feature2 & CPUID2_XSAVE) == 0) + return; + use_xsave = 1; + TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); +} + +DEFINE_IFUNC(, void, npxsave_core, (union savefpu *), static) +{ + + init_xsave(); + if (use_xsave) + return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ? + npxsave_xsaveopt : fpusave_xsave); + if (cpu_fxsr) + return (fpusave_fxsave); + return (fpusave_fnsave); +} + +DEFINE_IFUNC(, void, fpusave, (union savefpu *), static) +{ + + init_xsave(); + if (use_xsave) + return (fpusave_xsave); + if (cpu_fxsr) + return (fpusave_fxsave); + return (fpusave_fnsave); +} + /* * Enable XSAVE if supported and allowed by user. * Calculate the xsave_mask. @@ -325,13 +386,8 @@ npxinit_bsp1(void) uint64_t xsave_mask_user; TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch); - if (cpu_fxsr && (cpu_feature2 & CPUID2_XSAVE) != 0) { - use_xsave = 1; - TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); - } if (!use_xsave) return; - cpuid_count(0xd, 0x0, cp); xsave_mask = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; if ((cp[0] & xsave_mask) != xsave_mask) @@ -345,14 +401,9 @@ npxinit_bsp1(void) xsave_mask &= ~XFEATURE_AVX512; if ((xsave_mask & XFEATURE_MPX) != XFEATURE_MPX) xsave_mask &= ~XFEATURE_MPX; - - cpuid_count(0xd, 0x1, cp); - if ((cp[0] & CPUID_EXTSTATE_XSAVEOPT) != 0) - use_xsaveopt = 1; } /* - * Calculate the fpu save area size. */ static void @@ -867,15 +918,11 @@ npxdna(void) * npxsave() atomically with checking fpcurthread. */ void -npxsave(addr) - union savefpu *addr; +npxsave(union savefpu *addr) { stop_emulating(); - if (use_xsaveopt) - xsaveopt((char *)addr, xsave_mask); - else - fpusave(addr); + npxsave_core(addr); } void npxswitch(struct thread *td, struct pcb *pcb); @@ -1099,19 +1146,6 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, return (error); } -static void -fpusave(addr) - union savefpu *addr; -{ - - if (use_xsave) - xsave((char *)addr, xsave_mask); - else if (cpu_fxsr) - fxsave(addr); - else - fnsave(addr); -} - static void npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct save87 *sv_87) { diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 0c1437df5187..a969eef28810 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -148,6 +148,7 @@ __FBSDID("$FreeBSD$"); #include <machine/intr_machdep.h> #include <x86/apicvar.h> #endif +#include <x86/ifunc.h> #include <machine/bootinfo.h> #include <machine/cpu.h> #include <machine/cputypes.h> @@ -314,6 +315,10 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte); static void pmap_flush_page(vm_page_t m); static int pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); +static void pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, + vm_offset_t eva); +static void pmap_invalidate_cache_range_all(vm_offset_t sva, + vm_offset_t eva); static void pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); @@ -1407,37 +1412,62 @@ pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde) pmap_invalidate_page(pmap, va); } -#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) - -void -pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) +DEFINE_IFUNC(, void, pmap_invalidate_cache_range, (vm_offset_t, vm_offset_t), + static) { - if (force) { - sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); - } else { - KASSERT((sva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: sva not page-aligned")); - KASSERT((eva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: eva not page-aligned")); + if ((cpu_feature & CPUID_SS) != 0) + return (pmap_invalidate_cache_range_selfsnoop); + if ((cpu_feature & CPUID_CLFSH) != 0) + return (pmap_force_invalidate_cache_range); + return (pmap_invalidate_cache_range_all); +} + +#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) + +static void +pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva) +{ + + KASSERT((sva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: sva not page-aligned")); + KASSERT((eva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: eva not page-aligned")); +} + +static void +pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); +} + +void +pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) +{ + + sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); + if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) { + /* + * The supplied range is bigger than 2MB. + * Globally invalidate cache. + */ + pmap_invalidate_cache(); + return; } - if ((cpu_feature & CPUID_SS) != 0 && !force) - ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { -#ifdef DEV_APIC + /* + * XXX: Some CPUs fault, hang, or trash the local APIC + * registers if we use CLFLUSH on the local APIC + * range. The local APIC is always uncached, so we + * don't need to flush for that range anyway. + */ + if (pmap_kextract(sva) == lapic_paddr) + return; + + if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) { /* - * XXX: Some CPUs fault, hang, or trash the local APIC - * registers if we use CLFLUSH on the local APIC - * range. The local APIC is always uncached, so we - * don't need to flush for that range anyway. - */ - if (pmap_kextract(sva) == lapic_paddr) - return; -#endif - /* - * Otherwise, do per-cache line flush. Use the sfence + * Do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache @@ -1447,12 +1477,7 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) for (; sva < eva; sva += cpu_clflush_line_size) clflushopt(sva); sfence(); - } else if ((cpu_feature & CPUID_CLFSH) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { -#ifdef DEV_APIC - if (pmap_kextract(sva) == lapic_paddr) - return; -#endif + } else { /* * Writes are ordered by CLFLUSH on Intel CPUs. */ @@ -1462,17 +1487,17 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) clflush(sva); if (cpu_vendor_id != CPU_VENDOR_INTEL) mfence(); - } else { - - /* - * No targeted cache flush methods are supported by CPU, - * or the supplied range is bigger than 2MB. - * Globally invalidate cache. - */ - pmap_invalidate_cache(); } } +static void +pmap_invalidate_cache_range_all(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); + pmap_invalidate_cache(); +} + void pmap_invalidate_cache_pages(vm_page_t *pages, int count) { @@ -5479,7 +5504,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); - pmap_invalidate_cache_range(va, va + size, FALSE); + pmap_invalidate_cache_range(va, va + size); return ((void *)(va + offset)); } @@ -5718,7 +5743,7 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) */ if (changed) { pmap_invalidate_range(kernel_pmap, base, tmpva); - pmap_invalidate_cache_range(base, tmpva, FALSE); + pmap_invalidate_cache_range(base, tmpva); } return (0); } diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 19086221b11b..4b62484533c4 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -762,12 +762,6 @@ trap(struct trapframe *frame) KASSERT((read_eflags() & PSL_I) != 0, ("interrupts disabled")); trapsignal(td, &ksi); - /* - * Clear any pending debug exceptions after allowing a - * debugger to read DR6 while stopped in trapsignal(). - */ - if (type == T_TRCTRAP) - load_dr6(0); user: userret(td, frame); KASSERT(PCB_USER_FPU(td->td_pcb), diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index c3ed95dd4d02..250689459643 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -650,7 +650,7 @@ sf_buf_invalidate(struct sf_buf *sf) * settings are recalculated. */ pmap_qenter(sf->kva, &m, 1); - pmap_invalidate_cache_range(sf->kva, sf->kva + PAGE_SIZE, FALSE); + pmap_invalidate_cache_range(sf->kva, sf->kva + PAGE_SIZE); } /* diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index da9ae6588189..e48c0d3c6af5 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -394,8 +394,8 @@ void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); void pmap_invalidate_all(pmap_t); void pmap_invalidate_cache(void); void pmap_invalidate_cache_pages(vm_page_t *pages, int count); -void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, - boolean_t force); +void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); +void pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); void *pmap_trm_alloc(size_t size, int flags); void pmap_trm_free(void *addr, size_t size); diff --git a/sys/isa/isavar.h b/sys/isa/isavar.h index 1a3e661b67a4..d95a9c1ab3f2 100644 --- a/sys/isa/isavar.h +++ b/sys/isa/isavar.h @@ -142,7 +142,7 @@ enum isa_device_ivars { #define ISA_PNP_DESCR "E:pnpid;D:#" #define ISA_PNP_INFO(t) \ - MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, sizeof(t[0]), nitems(t) - 1); \ + MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, nitems(t) - 1); \ /* * Simplified accessors for isa devices diff --git a/sys/kern/kern_context.c b/sys/kern/kern_context.c index 5afb371bfb27..3bd5f31082ac 100644 --- a/sys/kern/kern_context.c +++ b/sys/kern/kern_context.c @@ -70,6 +70,7 @@ sys_getcontext(struct thread *td, struct getcontext_args *uap) if (uap->ucp == NULL) ret = EINVAL; else { + bzero(&uc, sizeof(ucontext_t)); get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); PROC_LOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; @@ -110,6 +111,7 @@ sys_swapcontext(struct thread *td, struct swapcontext_args *uap) if (uap->oucp == NULL || uap->ucp == NULL) ret = EINVAL; else { + bzero(&uc, sizeof(ucontext_t)); get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); bzero(uc.__spare__, sizeof(uc.__spare__)); PROC_LOCK(td->td_proc); diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index ca1f7326fe3f..08a704d904b1 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2936,8 +2936,11 @@ fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, /* * Handle the last reference to a file being closed. + * + * Without the noinline attribute clang keeps inlining the func thorough this + * file when fdrop is used. */ -int +int __noinline _fdrop(struct file *fp, struct thread *td) { int error; diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index c102eb52e5bd..a8d42a85d949 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <sys/vmmeter.h> #include <sys/proc.h> #include <sys/sbuf.h> +#include <sys/smp.h> #include <sys/sysctl.h> #include <sys/time.h> #include <sys/vmem.h> @@ -173,6 +174,7 @@ struct { * declare malloc types. */ static uma_zone_t mt_zone; +static uma_zone_t mt_stats_zone; u_long vm_kmem_size; SYSCTL_ULONG(_vm, OID_AUTO, kmem_size, CTLFLAG_RDTUN, &vm_kmem_size, 0, @@ -368,7 +370,7 @@ malloc_type_zone_allocated(struct malloc_type *mtp, unsigned long size, critical_enter(); mtip = mtp->ks_handle; - mtsp = &mtip->mti_stats[curcpu]; + mtsp = zpcpu_get(mtip->mti_stats); if (size > 0) { mtsp->mts_memalloced += size; mtsp->mts_numallocs++; @@ -411,7 +413,7 @@ malloc_type_freed(struct malloc_type *mtp, unsigned long size) critical_enter(); mtip = mtp->ks_handle; - mtsp = &mtip->mti_stats[curcpu]; + mtsp = zpcpu_get(mtip->mti_stats); mtsp->mts_memfreed += size; mtsp->mts_numfrees++; @@ -953,6 +955,9 @@ mallocinit(void *dummy) if (kmem_zmax < PAGE_SIZE || kmem_zmax > KMEM_ZMAX) kmem_zmax = KMEM_ZMAX; + mt_stats_zone = uma_zcreate("mt_stats_zone", + sizeof(struct malloc_type_stats), NULL, NULL, NULL, NULL, + UMA_ALIGN_PTR, UMA_ZONE_PCPU); mt_zone = uma_zcreate("mt_zone", sizeof(struct malloc_type_internal), #ifdef INVARIANTS mtrash_ctor, mtrash_dtor, mtrash_init, mtrash_fini, @@ -995,6 +1000,7 @@ malloc_init(void *data) panic("malloc_init: bad malloc type magic"); mtip = uma_zalloc(mt_zone, M_WAITOK | M_ZERO); + mtip->mti_stats = uma_zalloc_pcpu(mt_stats_zone, M_WAITOK | M_ZERO); mtp->ks_handle = mtip; mtp_set_subzone(mtp); @@ -1042,8 +1048,8 @@ malloc_uninit(void *data) * Look for memory leaks. */ temp_allocs = temp_bytes = 0; - for (i = 0; i < MAXCPU; i++) { - mtsp = &mtip->mti_stats[i]; + for (i = 0; i <= mp_maxid; i++) { + mtsp = zpcpu_get_cpu(mtip->mti_stats, i); temp_allocs += mtsp->mts_numallocs; temp_allocs -= mtsp->mts_numfrees; temp_bytes += mtsp->mts_memalloced; @@ -1056,6 +1062,7 @@ malloc_uninit(void *data) } slab = vtoslab((vm_offset_t) mtip & (~UMA_SLAB_MASK)); + uma_zfree_pcpu(mt_stats_zone, mtip->mti_stats); uma_zfree_arg(mt_zone, mtip, slab); } @@ -1077,6 +1084,7 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) { struct malloc_type_stream_header mtsh; struct malloc_type_internal *mtip; + struct malloc_type_stats *mtsp, zeromts; struct malloc_type_header mth; struct malloc_type *mtp; int error, i; @@ -1089,6 +1097,8 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) sbuf_clear_flags(&sbuf, SBUF_INCLUDENUL); mtx_lock(&malloc_mtx); + bzero(&zeromts, sizeof(zeromts)); + /* * Insert stream header. */ @@ -1114,10 +1124,17 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) /* * Insert type statistics for each CPU. */ - for (i = 0; i < MAXCPU; i++) { - (void)sbuf_bcat(&sbuf, &mtip->mti_stats[i], - sizeof(mtip->mti_stats[i])); + for (i = 0; i <= mp_maxid; i++) { + mtsp = zpcpu_get_cpu(mtip->mti_stats, i); + (void)sbuf_bcat(&sbuf, mtsp, sizeof(*mtsp)); } + /* + * Fill in the missing CPUs. + */ + for (; i < MAXCPU; i++) { + (void)sbuf_bcat(&sbuf, &zeromts, sizeof(zeromts)); + } + } mtx_unlock(&malloc_mtx); error = sbuf_finish(&sbuf); @@ -1170,6 +1187,7 @@ malloc_type_list(malloc_type_list_func_t *func, void *arg) DB_SHOW_COMMAND(malloc, db_show_malloc) { struct malloc_type_internal *mtip; + struct malloc_type_internal *mtsp; struct malloc_type *mtp; uint64_t allocs, frees; uint64_t alloced, freed; @@ -1183,7 +1201,8 @@ DB_SHOW_COMMAND(malloc, db_show_malloc) frees = 0; alloced = 0; freed = 0; - for (i = 0; i < MAXCPU; i++) { + for (i = 0; i <= mp_maxid; i++) { + mtsp = zpcpu_get_cpu(mtip->mti_stats, i); allocs += mtip->mti_stats[i].mts_numallocs; frees += mtip->mti_stats[i].mts_numfrees; alloced += mtip->mti_stats[i].mts_memalloced; diff --git a/sys/kern/subr_vmem.c b/sys/kern/subr_vmem.c index 3c83c777b6a9..8529266f381c 100644 --- a/sys/kern/subr_vmem.c +++ b/sys/kern/subr_vmem.c @@ -241,9 +241,6 @@ static struct vmem buffer_arena_storage; static struct vmem transient_arena_storage; /* kernel and kmem arenas are aliased for backwards KPI compat. */ vmem_t *kernel_arena = &kernel_arena_storage; -#if VM_NRESERVLEVEL > 0 -vmem_t *kernel_rwx_arena = NULL; -#endif vmem_t *kmem_arena = &kernel_arena_storage; vmem_t *buffer_arena = &buffer_arena_storage; vmem_t *transient_arena = &transient_arena_storage; diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 649cfb191b7f..455220c36752 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1031,8 +1031,9 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, error = copyin(name, ibits[x], ncpubytes); \ if (error != 0) \ goto done; \ - bzero((char *)ibits[x] + ncpubytes, \ - ncpbytes - ncpubytes); \ + if (ncpbytes != ncpubytes) \ + bzero((char *)ibits[x] + ncpubytes, \ + ncpbytes - ncpubytes); \ } \ } while (0) getbits(fd_in, 0); diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index cdfb84e42447..675c0aa02ac3 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -160,10 +160,6 @@ nameiinit(void *dummy __unused) } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL); -static int lookup_shared = 1; -SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RWTUN, &lookup_shared, 0, - "enables shared locks for path name translation"); - static int lookup_cap_dotdot = 1; SYSCTL_INT(_vfs, OID_AUTO, lookup_cap_dotdot, CTLFLAG_RWTUN, &lookup_cap_dotdot, 0, @@ -307,8 +303,6 @@ namei(struct nameidata *ndp) ("namei: flags contaminated with nameiops")); MPASS(ndp->ni_startdir == NULL || ndp->ni_startdir->v_type == VDIR || ndp->ni_startdir->v_type == VBAD); - if (!lookup_shared) - cnp->cn_flags &= ~LOCKSHARED; fdp = p->p_fd; TAILQ_INIT(&ndp->ni_cap_tracker); ndp->ni_lcf = 0; @@ -660,10 +654,7 @@ lookup(struct nameidata *ndp) * We use shared locks until we hit the parent of the last cn then * we adjust based on the requesting flags. */ - if (lookup_shared) - cnp->cn_lkflags = LK_SHARED; - else - cnp->cn_lkflags = LK_EXCLUSIVE; + cnp->cn_lkflags = LK_SHARED; dp = ndp->ni_startdir; ndp->ni_startdir = NULLVP; vn_lock(dp, @@ -1087,7 +1078,7 @@ lookup(struct nameidata *ndp) VOP_UNLOCK(dp, 0); success: /* - * Because of lookup_shared we may have the vnode shared locked, but + * Because of shared lookup we may have the vnode shared locked, but * the caller may want it to be exclusively locked. */ if (needs_exclusive_leaf(dp->v_mount, cnp->cn_flags) && diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 91d93bb89207..a0ddefaa15df 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -190,7 +190,8 @@ sys_quotactl(struct thread *td, struct quotactl_args *uap) * Require that Q_QUOTAON handles the vfs_busy() reference on * its own, always returning with ubusied mount point. */ - if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON) + if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON && + (uap->cmd >> SUBCMDSHIFT) != Q_QUOTAOFF) vfs_unbusy(mp); return (error); } diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 480df7433a6d..68341ef75025 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -411,6 +411,7 @@ struct ifnet { #define NET_EPOCH_ENTER_ET(et) epoch_enter_preempt(net_epoch_preempt, &(et)) #define NET_EPOCH_EXIT() epoch_exit_preempt(net_epoch_preempt, &nep_et) #define NET_EPOCH_EXIT_ET(et) epoch_exit_preempt(net_epoch_preempt, &(et)) +#define NET_EPOCH_WAIT() epoch_wait_preempt(net_epoch_preempt) /* diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 11baf8a018b4..5170ee6ae35c 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -87,11 +87,11 @@ __FBSDID("$FreeBSD$"); #define UP_AND_RUNNING(ifp) \ ((ifp)->if_flags & IFF_UP && (ifp)->if_drv_flags & IFF_DRV_RUNNING) -LIST_HEAD(ifvlanhead, ifvlan); +CK_SLIST_HEAD(ifvlanhead, ifvlan); struct ifvlantrunk { struct ifnet *parent; /* parent interface of this trunk */ - struct rmlock lock; + struct mtx lock; #ifdef VLAN_ARRAY #define VLAN_ARRAY_SIZE (EVL_VLID_MASK + 1) struct ifvlan *vlans[VLAN_ARRAY_SIZE]; /* static table */ @@ -117,7 +117,7 @@ struct ifvlantrunk { struct ifvlan *_next; \ size_t _i; \ for (_i = 0; _i < (1 << (_trunk)->hwidth); _i++) \ - LIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next) + CK_SLIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next) #endif /* VLAN_ARRAY */ /* @@ -146,13 +146,13 @@ struct ifvlantrunk { for (_i = 0; \ !(_cond) && _i < (1 << (_trunk)->hwidth); \ _i = (_touch && ((_trunk) != NULL) ? 0 : _i + 1), _touch = false) \ - if (((_ifv) = LIST_FIRST(&(_trunk)->hash[_i])) != NULL && \ + if (((_ifv) = CK_SLIST_FIRST(&(_trunk)->hash[_i])) != NULL && \ (_touch = true)) #endif /* VLAN_ARRAY */ struct vlan_mc_entry { struct sockaddr_dl mc_addr; - SLIST_ENTRY(vlan_mc_entry) mc_entries; + CK_SLIST_ENTRY(vlan_mc_entry) mc_entries; }; struct ifvlan { @@ -173,9 +173,9 @@ struct ifvlan { uint8_t ifvm_pcp; /* Priority Code Point (PCP). */ } ifv_mib; struct task lladdr_task; - SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; + CK_SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; #ifndef VLAN_ARRAY - LIST_ENTRY(ifvlan) ifv_list; + CK_SLIST_ENTRY(ifvlan) ifv_list; #endif }; #define ifv_proto ifv_mib.ifvm_proto @@ -205,55 +205,36 @@ static eventhandler_tag ifdetach_tag; static eventhandler_tag iflladdr_tag; /* - * if_vlan uses two module-level locks to allow concurrent modification of vlan - * interfaces and (mostly) allow for vlans to be destroyed while they are being - * used for tx/rx. To accomplish this in a way that has acceptable performance - * and cooperation with other parts of the network stack there is a - * non-sleepable rmlock(9) and an sx(9). Both locks are exclusively acquired - * when destroying a vlan interface, i.e. when the if_vlantrunk field of struct - * ifnet is de-allocated and NULL'd. Thus a reader holding either lock has a - * guarantee that the struct ifvlantrunk references a valid vlan trunk. + * if_vlan uses two module-level synchronizations primitives to allow concurrent + * modification of vlan interfaces and (mostly) allow for vlans to be destroyed + * while they are being used for tx/rx. To accomplish this in a way that has + * acceptable performance and cooperation with other parts of the network stack + * there is a non-sleepable epoch(9) and an sx(9). * - * The performance-sensitive paths that warrant using the rmlock(9) are + * The performance-sensitive paths that warrant using the epoch(9) are * vlan_transmit and vlan_input. Both have to check for the vlan interface's * existence using if_vlantrunk, and being in the network tx/rx paths the use - * of an rmlock(9) gives a measureable improvement in performance. + * of an epoch(9) gives a measureable improvement in performance. * * The reason for having an sx(9) is mostly because there are still areas that * must be sleepable and also have safe concurrent access to a vlan interface. * Since the sx(9) exists, it is used by default in most paths unless sleeping * is not permitted, or if it is not clear whether sleeping is permitted. * - * Note that despite these protections, there is still an inherent race in the - * destruction of vlans since there's no guarantee that the ifnet hasn't been - * freed/reused when the tx/rx functions are called by the stack. This can only - * be fixed by addressing ifnet's lifetime issues. */ -#define _VLAN_RM_ID ifv_rm_lock #define _VLAN_SX_ID ifv_sx -static struct rmlock _VLAN_RM_ID; static struct sx _VLAN_SX_ID; #define VLAN_LOCKING_INIT() \ - rm_init(&_VLAN_RM_ID, "vlan_rm"); \ sx_init(&_VLAN_SX_ID, "vlan_sx") #define VLAN_LOCKING_DESTROY() \ - rm_destroy(&_VLAN_RM_ID); \ sx_destroy(&_VLAN_SX_ID) -#define _VLAN_RM_TRACKER _vlan_rm_tracker -#define VLAN_RLOCK() rm_rlock(&_VLAN_RM_ID, \ - &_VLAN_RM_TRACKER) -#define VLAN_RUNLOCK() rm_runlock(&_VLAN_RM_ID, \ - &_VLAN_RM_TRACKER) -#define VLAN_WLOCK() rm_wlock(&_VLAN_RM_ID) -#define VLAN_WUNLOCK() rm_wunlock(&_VLAN_RM_ID) -#define VLAN_RLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_RLOCKED) -#define VLAN_WLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_WLOCKED) -#define VLAN_RWLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_LOCKED) -#define VLAN_LOCK_READER struct rm_priotracker _VLAN_RM_TRACKER +#define VLAN_RLOCK() NET_EPOCH_ENTER(); +#define VLAN_RUNLOCK() NET_EPOCH_EXIT(); +#define VLAN_RLOCK_ASSERT() MPASS(in_epoch(net_epoch_preempt)) #define VLAN_SLOCK() sx_slock(&_VLAN_SX_ID) #define VLAN_SUNLOCK() sx_sunlock(&_VLAN_SX_ID) @@ -265,25 +246,18 @@ static struct sx _VLAN_SX_ID; /* - * We also have a per-trunk rmlock(9), that is locked shared on packet - * processing and exclusive when configuration is changed. Note: This should - * only be acquired while there is a shared lock on either of the global locks - * via VLAN_SLOCK or VLAN_RLOCK. Thus, an exclusive lock on the global locks - * makes a call to TRUNK_RLOCK/TRUNK_WLOCK technically superfluous. + * We also have a per-trunk mutex that should be acquired when changing + * its state. */ -#define _TRUNK_RM_TRACKER _trunk_rm_tracker -#define TRUNK_LOCK_INIT(trunk) rm_init(&(trunk)->lock, vlanname) -#define TRUNK_LOCK_DESTROY(trunk) rm_destroy(&(trunk)->lock) -#define TRUNK_RLOCK(trunk) rm_rlock(&(trunk)->lock, \ - &_TRUNK_RM_TRACKER) -#define TRUNK_WLOCK(trunk) rm_wlock(&(trunk)->lock) -#define TRUNK_RUNLOCK(trunk) rm_runlock(&(trunk)->lock, \ - &_TRUNK_RM_TRACKER) -#define TRUNK_WUNLOCK(trunk) rm_wunlock(&(trunk)->lock) -#define TRUNK_RLOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_RLOCKED) -#define TRUNK_LOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_LOCKED) -#define TRUNK_WLOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_WLOCKED) -#define TRUNK_LOCK_READER struct rm_priotracker _TRUNK_RM_TRACKER +#define TRUNK_LOCK_INIT(trunk) mtx_init(&(trunk)->lock, vlanname, NULL, MTX_DEF) +#define TRUNK_LOCK_DESTROY(trunk) mtx_destroy(&(trunk)->lock) +#define TRUNK_RLOCK(trunk) NET_EPOCH_ENTER() +#define TRUNK_WLOCK(trunk) mtx_lock(&(trunk)->lock) +#define TRUNK_RUNLOCK(trunk) NET_EPOCH_EXIT(); +#define TRUNK_WUNLOCK(trunk) mtx_unlock(&(trunk)->lock) +#define TRUNK_RLOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt)) +#define TRUNK_LOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(trunk)->lock)) +#define TRUNK_WLOCK_ASSERT(trunk) mtx_assert(&(trunk)->lock, MA_OWNED); /* * The VLAN_ARRAY substitutes the dynamic hash with a static array @@ -361,7 +335,7 @@ vlan_inithash(struct ifvlantrunk *trunk) trunk->hmask = n - 1; trunk->hash = malloc(sizeof(struct ifvlanhead) * n, M_VLAN, M_WAITOK); for (i = 0; i < n; i++) - LIST_INIT(&trunk->hash[i]); + CK_SLIST_INIT(&trunk->hash[i]); } static void @@ -372,7 +346,7 @@ vlan_freehash(struct ifvlantrunk *trunk) KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); for (i = 0; i < (1 << trunk->hwidth); i++) - KASSERT(LIST_EMPTY(&trunk->hash[i]), + KASSERT(CK_SLIST_EMPTY(&trunk->hash[i]), ("%s: hash table not empty", __func__)); #endif free(trunk->hash, M_VLAN); @@ -386,12 +360,12 @@ vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv) int i, b; struct ifvlan *ifv2; - TRUNK_WLOCK_ASSERT(trunk); + VLAN_XLOCK_ASSERT(); KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); b = 1 << trunk->hwidth; i = HASH(ifv->ifv_vid, trunk->hmask); - LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) + CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) if (ifv->ifv_vid == ifv2->ifv_vid) return (EEXIST); @@ -404,7 +378,7 @@ vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv) vlan_growhash(trunk, 1); i = HASH(ifv->ifv_vid, trunk->hmask); } - LIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list); + CK_SLIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list); trunk->refcnt++; return (0); @@ -416,15 +390,15 @@ vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv) int i, b; struct ifvlan *ifv2; - TRUNK_WLOCK_ASSERT(trunk); + VLAN_XLOCK_ASSERT(); KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); b = 1 << trunk->hwidth; i = HASH(ifv->ifv_vid, trunk->hmask); - LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) + CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) if (ifv2 == ifv) { trunk->refcnt--; - LIST_REMOVE(ifv2, ifv_list); + CK_SLIST_REMOVE(&trunk->hash[i], ifv2, ifvlan, ifv_list); if (trunk->refcnt < (b * b) / 2) vlan_growhash(trunk, -1); return (0); @@ -444,7 +418,7 @@ vlan_growhash(struct ifvlantrunk *trunk, int howmuch) struct ifvlanhead *hash2; int hwidth2, i, j, n, n2; - TRUNK_WLOCK_ASSERT(trunk); + VLAN_XLOCK_ASSERT(); KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); if (howmuch == 0) { @@ -460,21 +434,21 @@ vlan_growhash(struct ifvlantrunk *trunk, int howmuch) if (hwidth2 < VLAN_DEF_HWIDTH) return; - /* M_NOWAIT because we're called with trunk mutex held */ - hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_NOWAIT); + hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_WAITOK); if (hash2 == NULL) { printf("%s: out of memory -- hash size not changed\n", __func__); return; /* We can live with the old hash table */ } for (j = 0; j < n2; j++) - LIST_INIT(&hash2[j]); + CK_SLIST_INIT(&hash2[j]); for (i = 0; i < n; i++) - while ((ifv = LIST_FIRST(&trunk->hash[i])) != NULL) { - LIST_REMOVE(ifv, ifv_list); + while ((ifv = CK_SLIST_FIRST(&trunk->hash[i])) != NULL) { + CK_SLIST_REMOVE(&trunk->hash[i], ifv, ifvlan, ifv_list); j = HASH(ifv->ifv_vid, n2 - 1); - LIST_INSERT_HEAD(&hash2[j], ifv, ifv_list); + CK_SLIST_INSERT_HEAD(&hash2[j], ifv, ifv_list); } + NET_EPOCH_WAIT(); free(trunk->hash, M_VLAN); trunk->hash = hash2; trunk->hwidth = hwidth2; @@ -492,7 +466,7 @@ vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid) TRUNK_RLOCK_ASSERT(trunk); - LIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list) + CK_SLIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list) if (ifv->ifv_vid == vid) return (ifv); return (NULL); @@ -508,7 +482,7 @@ vlan_dumphash(struct ifvlantrunk *trunk) for (i = 0; i < (1 << trunk->hwidth); i++) { printf("%d: ", i); - LIST_FOREACH(ifv, &trunk->hash[i], ifv_list) + CK_SLIST_FOREACH(ifv, &trunk->hash[i], ifv_list) printf("%s ", ifv->ifv_ifp->if_xname); printf("\n"); } @@ -561,7 +535,6 @@ static void trunk_destroy(struct ifvlantrunk *trunk) { VLAN_XLOCK_ASSERT(); - VLAN_WLOCK_ASSERT(); vlan_freehash(trunk); trunk->parent->if_vlantrunk = NULL; @@ -587,23 +560,19 @@ vlan_setmulti(struct ifnet *ifp) struct vlan_mc_entry *mc; int error; - /* - * XXX This stupidly needs the rmlock to avoid sleeping while holding - * the in6_multi_mtx (see in6_mc_join_locked). - */ - VLAN_RWLOCK_ASSERT(); + VLAN_XLOCK_ASSERT(); /* Find the parent. */ sc = ifp->if_softc; - TRUNK_WLOCK_ASSERT(TRUNK(sc)); ifp_p = PARENT(sc); CURVNET_SET_QUIET(ifp_p->if_vnet); /* First, remove any existing filter entries. */ - while ((mc = SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { - SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); + while ((mc = CK_SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { + CK_SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); (void)if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr); + NET_EPOCH_WAIT(); free(mc, M_VLAN); } @@ -619,10 +588,10 @@ vlan_setmulti(struct ifnet *ifp) } bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len); mc->mc_addr.sdl_index = ifp_p->if_index; - SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); + CK_SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); } IF_ADDR_WUNLOCK(ifp); - SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) { + CK_SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) { error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr, NULL); if (error) @@ -645,7 +614,6 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp) struct ifnet *ifv_ifp; struct ifvlantrunk *trunk; struct sockaddr_dl *sdl; - VLAN_LOCK_READER; /* Need the rmlock since this is run on taskqueue_swi. */ VLAN_RLOCK(); @@ -724,12 +692,10 @@ static struct ifnet * vlan_trunkdev(struct ifnet *ifp) { struct ifvlan *ifv; - VLAN_LOCK_READER; if (ifp->if_type != IFT_L2VLAN) return (NULL); - /* Not clear if callers are sleepable, so acquire the rmlock. */ VLAN_RLOCK(); ifv = ifp->if_softc; ifp = NULL; @@ -809,10 +775,7 @@ vlan_devat(struct ifnet *ifp, uint16_t vid) { struct ifvlantrunk *trunk; struct ifvlan *ifv; - VLAN_LOCK_READER; - TRUNK_LOCK_READER; - /* Not clear if callers are sleepable, so acquire the rmlock. */ VLAN_RLOCK(); trunk = ifp->if_vlantrunk; if (trunk == NULL) { @@ -820,11 +783,9 @@ vlan_devat(struct ifnet *ifp, uint16_t vid) return (NULL); } ifp = NULL; - TRUNK_RLOCK(trunk); ifv = vlan_gethash(trunk, vid); if (ifv) ifp = ifv->ifv_ifp; - TRUNK_RUNLOCK(trunk); VLAN_RUNLOCK(); return (ifp); } @@ -1076,7 +1037,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) if_rele(p); return (ENOSPC); } - SLIST_INIT(&ifv->vlan_mc_listhead); + CK_SLIST_INIT(&ifv->vlan_mc_listhead); ifp->if_softc = ifv; /* * Set the name manually rather than using if_initname because @@ -1143,6 +1104,7 @@ vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) * ifvlan. */ taskqueue_drain(taskqueue_thread, &ifv->lladdr_task); + NET_EPOCH_WAIT(); if_free(ifp); free(ifv, M_VLAN); ifc_free_unit(ifc, unit); @@ -1167,7 +1129,6 @@ vlan_transmit(struct ifnet *ifp, struct mbuf *m) struct ifvlan *ifv; struct ifnet *p; int error, len, mcast; - VLAN_LOCK_READER; VLAN_RLOCK(); ifv = ifp->if_softc; @@ -1227,8 +1188,6 @@ vlan_input(struct ifnet *ifp, struct mbuf *m) { struct ifvlantrunk *trunk; struct ifvlan *ifv; - VLAN_LOCK_READER; - TRUNK_LOCK_READER; struct m_tag *mtag; uint16_t vid, tag; @@ -1289,16 +1248,13 @@ vlan_input(struct ifnet *ifp, struct mbuf *m) vid = EVL_VLANOFTAG(tag); - TRUNK_RLOCK(trunk); ifv = vlan_gethash(trunk, vid); if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) { - TRUNK_RUNLOCK(trunk); - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); VLAN_RUNLOCK(); + if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); m_freem(m); return; } - TRUNK_RUNLOCK(trunk); if (vlan_mtag_pcp) { /* @@ -1369,22 +1325,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) if (ifv->ifv_trunk) return (EBUSY); - /* Acquire rmlock after the branch so we can M_WAITOK. */ VLAN_XLOCK(); if (p->if_vlantrunk == NULL) { trunk = malloc(sizeof(struct ifvlantrunk), M_VLAN, M_WAITOK | M_ZERO); vlan_inithash(trunk); TRUNK_LOCK_INIT(trunk); - VLAN_WLOCK(); TRUNK_WLOCK(trunk); p->if_vlantrunk = trunk; trunk->parent = p; if_ref(trunk->parent); + TRUNK_WUNLOCK(trunk); } else { - VLAN_WLOCK(); trunk = p->if_vlantrunk; - TRUNK_WLOCK(trunk); } ifv->ifv_vid = vid; /* must set this before vlan_inshash() */ @@ -1448,7 +1401,9 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) ifp->if_link_state = p->if_link_state; + TRUNK_RLOCK(TRUNK(ifv)); vlan_capabilities(ifv); + TRUNK_RUNLOCK(TRUNK(ifv)); /* * Set up our interface address to reflect the underlying @@ -1458,12 +1413,6 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) ((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen = p->if_addrlen; - /* - * Configure multicast addresses that may already be - * joined on the vlan device. - */ - (void)vlan_setmulti(ifp); - TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv); /* We are ready for operation now. */ @@ -1471,13 +1420,14 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) /* Update flags on the parent, if necessary. */ vlan_setflags(ifp, 1); -done: + /* - * We need to drop the non-sleepable rmlock so that the underlying - * devices can sleep in their vlan_config hooks. + * Configure multicast addresses that may already be + * joined on the vlan device. */ - TRUNK_WUNLOCK(trunk); - VLAN_WUNLOCK(); + (void)vlan_setmulti(ifp); + +done: if (error == 0) EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid); VLAN_XUNLOCK(); @@ -1510,13 +1460,6 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) parent = NULL; if (trunk != NULL) { - /* - * Both vlan_transmit and vlan_input rely on the trunk fields - * being NULL to determine whether to bail, so we need to get - * an exclusive lock here to prevent them from using bad - * ifvlans. - */ - VLAN_WLOCK(); parent = trunk->parent; /* @@ -1524,7 +1467,7 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) * empty the list of multicast groups that we may have joined * while we were alive from the parent's list. */ - while ((mc = SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { + while ((mc = CK_SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { /* * If the parent interface is being detached, * all its multicast addresses have already @@ -1541,19 +1484,14 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) "Failed to delete multicast address from parent: %d\n", error); } - SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries); + CK_SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries); + NET_EPOCH_WAIT(); free(mc, M_VLAN); } vlan_setflags(ifp, 0); /* clear special flags on parent */ - /* - * The trunk lock isn't actually required here, but - * vlan_remhash expects it. - */ - TRUNK_WLOCK(trunk); vlan_remhash(trunk, ifv); - TRUNK_WUNLOCK(trunk); ifv->ifv_trunk = NULL; /* @@ -1561,9 +1499,9 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) */ if (trunk->refcnt == 0) { parent->if_vlantrunk = NULL; + NET_EPOCH_WAIT(); trunk_destroy(trunk); } - VLAN_WUNLOCK(); } /* Disconnect from parent. */ @@ -1640,7 +1578,6 @@ vlan_link_state(struct ifnet *ifp) { struct ifvlantrunk *trunk; struct ifvlan *ifv; - VLAN_LOCK_READER; /* Called from a taskqueue_swi task, so we cannot sleep. */ VLAN_RLOCK(); @@ -1670,7 +1607,7 @@ vlan_capabilities(struct ifvlan *ifv) u_long hwa = 0; VLAN_SXLOCK_ASSERT(); - TRUNK_WLOCK_ASSERT(TRUNK(ifv)); + TRUNK_RLOCK_ASSERT(TRUNK(ifv)); p = PARENT(ifv); ifp = ifv->ifv_ifp; @@ -1771,11 +1708,11 @@ vlan_trunk_capabilities(struct ifnet *ifp) VLAN_SUNLOCK(); return; } - TRUNK_WLOCK(trunk); + TRUNK_RLOCK(trunk); VLAN_FOREACH(ifv, trunk) { vlan_capabilities(ifv); } - TRUNK_WUNLOCK(trunk); + TRUNK_RUNLOCK(trunk); VLAN_SUNLOCK(); } @@ -1789,7 +1726,6 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifvlantrunk *trunk; struct vlanreq vlr; int error = 0; - VLAN_LOCK_READER; ifr = (struct ifreq *)data; ifa = (struct ifaddr *) data; @@ -1925,16 +1861,13 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * XXX We need the rmlock here to avoid sleeping while * holding in6_multi_mtx. */ - VLAN_RLOCK(); + VLAN_XLOCK(); trunk = TRUNK(ifv); - if (trunk != NULL) { - TRUNK_WLOCK(trunk); + if (trunk != NULL) error = vlan_setmulti(ifp); - TRUNK_WUNLOCK(trunk); - } - VLAN_RUNLOCK(); - break; + VLAN_XUNLOCK(); + break; case SIOCGVLANPCP: #ifdef VIMAGE if (ifp->if_vnet != ifp->if_home_vnet) { @@ -1971,9 +1904,9 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifv->ifv_capenable = ifr->ifr_reqcap; trunk = TRUNK(ifv); if (trunk != NULL) { - TRUNK_WLOCK(trunk); + TRUNK_RLOCK(trunk); vlan_capabilities(ifv); - TRUNK_WUNLOCK(trunk); + TRUNK_RUNLOCK(trunk); } VLAN_SUNLOCK(); break; diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 65bf07a0b2c1..d9a6e3b962d7 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -4100,9 +4100,10 @@ iflib_if_qflush(if_t ifp) } -#define IFCAP_FLAGS (IFCAP_TXCSUM_IPV6 | IFCAP_RXCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ - IFCAP_TSO4 | IFCAP_TSO6 | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ - IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | IFCAP_VLAN_HWTSO) +#define IFCAP_FLAGS (IFCAP_HWCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ + IFCAP_TSO | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ + IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | \ + IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM) static int iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) @@ -4223,39 +4224,51 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) } case SIOCSIFCAP: { - int mask, setmask; + int mask, setmask, oldmask; - mask = ifr->ifr_reqcap ^ if_getcapenable(ifp); + oldmask = if_getcapenable(ifp); + mask = ifr->ifr_reqcap ^ oldmask; + mask &= ctx->ifc_softc_ctx.isc_capabilities; setmask = 0; #ifdef TCP_OFFLOAD setmask |= mask & (IFCAP_TOE4|IFCAP_TOE6); #endif setmask |= (mask & IFCAP_FLAGS); + setmask |= (mask & IFCAP_WOL); + + /* + * If we're disabling any RX csum, disable all the ones + * the driver supports. This assumes all supported are + * enabled. + * + * Otherwise, if they've changed, enable all of them. + */ + if ((setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) < + (oldmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))) + setmask &= ~(IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); + else if ((setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != + (oldmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))) + setmask |= (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)); - if (setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) - setmask |= (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); - if ((mask & IFCAP_WOL) && - (if_getcapabilities(ifp) & IFCAP_WOL) != 0) - setmask |= (mask & (IFCAP_WOL_MCAST|IFCAP_WOL_MAGIC)); - if_vlancap(ifp); /* * want to ensure that traffic has stopped before we change any of the flags */ if (setmask) { CTX_LOCK(ctx); bits = if_getdrvflags(ifp); - if (bits & IFF_DRV_RUNNING) + if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_stop(ctx); STATE_LOCK(ctx); if_togglecapenable(ifp, setmask); STATE_UNLOCK(ctx); - if (bits & IFF_DRV_RUNNING) + if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_init_locked(ctx); STATE_LOCK(ctx); if_setdrvflags(ifp, bits); STATE_UNLOCK(ctx); CTX_UNLOCK(ctx); } + if_vlancap(ifp); break; } case SIOCGPRIVATE_0: diff --git a/sys/net/iflib.h b/sys/net/iflib.h index 6e1eee633a2c..bda5ad45dfc8 100644 --- a/sys/net/iflib.h +++ b/sys/net/iflib.h @@ -173,7 +173,7 @@ typedef struct pci_vendor_info { #define IFLIB_PNP_DESCR "U32:vendor;U32:device;U32:subvendor;U32:subdevice;" \ "U32:revision;U32:class;D:#" #define IFLIB_PNP_INFO(b, u, t) \ - MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t) - 1) + MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, nitems(t) - 1) typedef struct if_txrx { int (*ift_txd_encap) (void *, if_pkt_info_t); diff --git a/sys/netinet/ip_encap.h b/sys/netinet/ip_encap.h index f3d1d3afcab8..65ac922fc1bb 100644 --- a/sys/netinet/ip_encap.h +++ b/sys/netinet/ip_encap.h @@ -48,12 +48,15 @@ typedef int (*encap_input_t)(struct mbuf *, int , int, void *); struct encap_config { int proto; /* protocol */ int min_length; /* minimum packet length */ + int max_hdrsize; /* maximum header size */ int exact_match; /* a packet is exactly matched */ #define ENCAP_DRV_LOOKUP 0x7fffffff encap_lookup_t lookup; encap_check_t check; encap_input_t input; + + void *pad[3]; }; struct encaptab; diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 3150306356dc..5a5b7880fd30 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -1060,40 +1060,6 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, return (digestlen); } -/*- - * verify the HMAC digest using the desired hash key, text, and HMAC - * algorithm. - * Returns -1 on error, 0 on success. - */ -int -sctp_verify_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, - uint8_t *text, uint32_t textlen, - uint8_t *digest, uint32_t digestlen) -{ - uint32_t len; - uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX]; - - /* sanity check the material and length */ - if ((key == NULL) || (keylen == 0) || - (text == NULL) || (textlen == 0) || (digest == NULL)) { - /* can't do HMAC with empty key or text or digest */ - return (-1); - } - len = sctp_get_hmac_digest_len(hmac_algo); - if ((len == 0) || (digestlen != len)) - return (-1); - - /* compute the expected hash */ - if (sctp_hmac(hmac_algo, key, keylen, text, textlen, temp) != len) - return (-1); - - if (memcmp(digest, temp, digestlen) != 0) - return (-1); - else - return (0); -} - - /* * computes the requested HMAC using a key struct (which may be modified if * the keylen exceeds the HMAC block len). diff --git a/sys/netinet/sctp_auth.h b/sys/netinet/sctp_auth.h index 44126e3e590f..5c22cc749c65 100644 --- a/sys/netinet/sctp_auth.h +++ b/sys/netinet/sctp_auth.h @@ -178,9 +178,6 @@ extern uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo); extern uint32_t sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, uint8_t *text, uint32_t textlen, uint8_t *digest); -extern int -sctp_verify_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, - uint8_t *text, uint32_t textlen, uint8_t *digest, uint32_t digestlen); extern uint32_t sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, uint8_t *text, uint32_t textlen, uint8_t *digest); diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index b77abf4768ce..3a7d93833a0a 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -5669,7 +5669,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt vrf_id, port); goto out; } - } if (IS_SCTP_CONTROL(ch)) { /* process the control portion of the SCTP packet */ diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index e7807b331629..a0b09ddd3336 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -7210,7 +7210,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, if ((sp->msg_is_complete) && (sp->length == 0)) { if (sp->sender_all_done) { /* - * We are doing differed cleanup. Last time through + * We are doing defered cleanup. Last time through * when we took all the data the sender_all_done was * not set. */ diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 12047ad91293..5fc57fe139ea 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3700,7 +3700,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, return; } if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || - (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { + (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) || (notification == SCTP_NOTIFY_INTERFACE_UP) || (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) { @@ -7391,8 +7391,8 @@ sctp_set_state(struct sctp_tcb *stcb, int new_state) #endif KASSERT((new_state & ~SCTP_STATE_MASK) == 0, - ("sctp_set_state: Can't set substate (new_state = %x)", - new_state)); + ("sctp_set_state: Can't set substate (new_state = %x)", + new_state)); stcb->asoc.state = (stcb->asoc.state & ~SCTP_STATE_MASK) | new_state; if ((new_state == SCTP_STATE_SHUTDOWN_RECEIVED) || (new_state == SCTP_STATE_SHUTDOWN_SENT) || @@ -7402,7 +7402,7 @@ sctp_set_state(struct sctp_tcb *stcb, int new_state) #if defined(KDTRACE_HOOKS) if (((old_state & SCTP_STATE_MASK) != new_state) && !(((old_state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY) && - (new_state == SCTP_STATE_INUSE))) { + (new_state == SCTP_STATE_INUSE))) { SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state); } #endif @@ -7416,14 +7416,14 @@ sctp_add_substate(struct sctp_tcb *stcb, int substate) #endif KASSERT((substate & SCTP_STATE_MASK) == 0, - ("sctp_add_substate: Can't set state (substate = %x)", - substate)); + ("sctp_add_substate: Can't set state (substate = %x)", + substate)); stcb->asoc.state |= substate; #if defined(KDTRACE_HOOKS) if (((substate & SCTP_STATE_ABOUT_TO_BE_FREED) && - ((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) || + ((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) || ((substate & SCTP_STATE_SHUTDOWN_PENDING) && - ((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) { + ((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) { SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state); } #endif diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index e5a184fb713e..9eefd0d948d7 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -130,7 +130,7 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, functions_inherit_listen_socket_stack, static void syncache_drop(struct syncache *, struct syncache_head *); static void syncache_free(struct syncache *); static void syncache_insert(struct syncache *, struct syncache_head *); -static int syncache_respond(struct syncache *, struct syncache_head *, int, +static int syncache_respond(struct syncache *, struct syncache_head *, const struct mbuf *); static struct socket *syncache_socket(struct syncache *, struct socket *, struct mbuf *m); @@ -489,7 +489,7 @@ syncache_timer(void *xsch) free(s, M_TCPLOG); } - syncache_respond(sc, sch, 1, NULL); + syncache_respond(sc, sch, NULL); TCPSTAT_INC(tcps_sc_retransmitted); syncache_timeout(sc, sch, 0); } @@ -1413,7 +1413,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, s, __func__); free(s, M_TCPLOG); } - if (syncache_respond(sc, sch, 1, m) == 0) { + if (syncache_respond(sc, sch, m) == 0) { sc->sc_rxmits = 0; syncache_timeout(sc, sch, 1); TCPSTAT_INC(tcps_sndacks); @@ -1577,7 +1577,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, /* * Do a standard 3-way handshake. */ - if (syncache_respond(sc, sch, 0, m) == 0) { + if (syncache_respond(sc, sch, m) == 0) { if (V_tcp_syncookies && V_tcp_syncookiesonly && sc != &scs) syncache_free(sc); else if (sc != &scs) @@ -1622,7 +1622,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, * i.e. m0 != NULL, or upon 3WHS ACK timeout, i.e. m0 == NULL. */ static int -syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked, +syncache_respond(struct syncache *sc, struct syncache_head *sch, const struct mbuf *m0) { struct ip *ip = NULL; diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 0bb5636602ff..93cbfe66140b 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1936,6 +1936,10 @@ icmp6_rip6_input(struct mbuf **mp, int off) !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) continue; INP_RLOCK(in6p); + if (__predict_false(in6p->inp_flags2 & INP_FREED)) { + INP_RUNLOCK(in6p); + continue; + } if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, in6p->in6p_icmp6filt)) { INP_RUNLOCK(in6p); diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index a9c73798b18c..b9d8e9e3187a 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -809,6 +809,10 @@ in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) INP_INFO_WLOCK(pcbinfo); CK_LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) { INP_WLOCK(in6p); + if (__predict_false(in6p->inp_flags2 & INP_FREED)) { + INP_WUNLOCK(in6p); + continue; + } im6o = in6p->in6p_moptions; if ((in6p->inp_vflag & INP_IPV6) && im6o != NULL) { /* diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index b32e88663172..d5ab934c9d41 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -698,7 +698,7 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, u_int32_t ulen, plen; uint16_t cscov; u_short fport; - uint8_t nxt, unlock_udbinfo; + uint8_t nxt, unlock_inp, unlock_udbinfo; /* addr6 has been validated in udp6_send(). */ sin6 = (struct sockaddr_in6 *)addr6; @@ -734,7 +734,22 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, inp = sotoinpcb(so); KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); - INP_RLOCK(inp); + /* + * In the following cases we want a write lock on the inp for either + * local operations or for possible route cache updates in the IPv6 + * output path: + * - on connected sockets (sin6 is NULL) for route cache updates, + * - when we are not bound to an address and source port (it is + * in6_pcbsetport() which will require the write lock). + */ + if (sin6 == NULL || (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) && + inp->inp_lport == 0)) { + INP_WLOCK(inp); + unlock_inp = UH_WLOCKED; + } else { + INP_RLOCK(inp); + unlock_inp = UH_RLOCKED; + } nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ? IPPROTO_UDP : IPPROTO_UDPLITE; @@ -758,7 +773,10 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, * potential race in which the factors causing us to * select the UDPv4 output routine are invalidated? */ - INP_RUNLOCK(inp); + if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else + INP_RUNLOCK(inp); if (sin6) in6_sin6_2_sin_in_sock((struct sockaddr *)sin6); pru = inetsw[ip_protox[nxt]].pr_usrreqs; @@ -772,7 +790,10 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, if (control) { if ((error = ip6_setpktopts(control, &opt, inp->in6p_outputopts, td->td_ucred, nxt)) != 0) { - INP_RUNLOCK(inp); + if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else + INP_RUNLOCK(inp); ip6_clearpktopts(&opt, -1); if (control) m_freem(control); @@ -786,12 +807,6 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); if (sin6 != NULL && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) && inp->inp_lport == 0) { - INP_RUNLOCK(inp); - /* - * XXX there is a short window here which could lead to a race; - * should we re-check that what got us here is still valid? - */ - INP_WLOCK(inp); INP_HASH_WLOCK(pcbinfo); unlock_udbinfo = UH_WLOCKED; } else if (sin6 != NULL && @@ -972,9 +987,10 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, UDPLITE_PROBE(send, NULL, inp, ip6, inp, udp6); else UDP_PROBE(send, NULL, inp, ip6, inp, udp6); - error = ip6_output(m, optp, &inp->inp_route6, flags, + error = ip6_output(m, optp, + (unlock_inp == UH_WLOCKED) ? &inp->inp_route6 : NULL, flags, inp->in6p_moptions, NULL, inp); - if (unlock_udbinfo == UH_WLOCKED) + if (unlock_inp == UH_WLOCKED) INP_WUNLOCK(inp); else INP_RUNLOCK(inp); @@ -987,12 +1003,20 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, release: if (unlock_udbinfo == UH_WLOCKED) { + KASSERT(unlock_inp == UH_WLOCKED, ("%s: excl udbinfo lock, " + "non-excl inp lock: pcbinfo %p %#x inp %p %#x", + __func__, pcbinfo, unlock_udbinfo, inp, unlock_inp)); INP_HASH_WUNLOCK(pcbinfo); INP_WUNLOCK(inp); } else if (unlock_udbinfo == UH_RLOCKED) { + KASSERT(unlock_inp == UH_RLOCKED, ("%s: non-excl udbinfo lock, " + "excl inp lock: pcbinfo %p %#x inp %p %#x", + __func__, pcbinfo, unlock_udbinfo, inp, unlock_inp)); INP_HASH_RUNLOCK_ET(pcbinfo, et); INP_RUNLOCK(inp); - } else + } else if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else INP_RUNLOCK(inp); if (control) { ip6_clearpktopts(&opt, -1); diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 8f5004a0613c..1e027bf6076e 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -534,14 +534,6 @@ MALLOC_DEFINE(M_IPSEC_SPDCACHE, "ipsec-spdcache", "ipsec SPD cache"); VNET_DEFINE_STATIC(uma_zone_t, key_lft_zone); #define V_key_lft_zone VNET(key_lft_zone) -static LIST_HEAD(xforms_list, xformsw) xforms = LIST_HEAD_INITIALIZER(); -static struct mtx xforms_lock; -#define XFORMS_LOCK_INIT() \ - mtx_init(&xforms_lock, "xforms_list", "IPsec transforms list", MTX_DEF) -#define XFORMS_LOCK_DESTROY() mtx_destroy(&xforms_lock) -#define XFORMS_LOCK() mtx_lock(&xforms_lock) -#define XFORMS_UNLOCK() mtx_unlock(&xforms_lock) - /* * set parameters into secpolicyindex buffer. * Must allocate secpolicyindex buffer passed to this function. @@ -717,7 +709,6 @@ static int key_delete(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_delete_all(struct socket *, struct mbuf *, const struct sadb_msghdr *, struct secasindex *); -static void key_delete_xform(const struct xformsw *); static int key_get(struct socket *, struct mbuf *, const struct sadb_msghdr *); @@ -750,7 +741,6 @@ static int key_validate_ext(const struct sadb_ext *, int); static int key_align(struct mbuf *, struct sadb_msghdr *); static struct mbuf *key_setlifetime(struct seclifetime *, uint16_t); static struct mbuf *key_setkey(struct seckey *, uint16_t); -static int xform_init(struct secasvar *, u_short); static void spdcache_init(void); static void spdcache_clear(void); @@ -6167,7 +6157,7 @@ key_delete_all(struct socket *so, struct mbuf *m, * Larval SAs have not initialized tdb_xform, so it is safe to leave them * here when xform disappears. */ -static void +void key_delete_xform(const struct xformsw *xsp) { struct secasvar_queue drainq; @@ -8335,7 +8325,6 @@ key_init(void) if (!IS_DEFAULT_VNET(curvnet)) return; - XFORMS_LOCK_INIT(); SPTREE_LOCK_INIT(); REGTREE_LOCK_INIT(); SAHTREE_LOCK_INIT(); @@ -8458,7 +8447,6 @@ key_destroy(void) #ifndef IPSEC_DEBUG2 callout_drain(&key_timer); #endif - XFORMS_LOCK_DESTROY(); SPTREE_LOCK_DESTROY(); REGTREE_LOCK_DESTROY(); SAHTREE_LOCK_DESTROY(); @@ -8617,70 +8605,3 @@ comp_algorithm_lookup(int alg) return (NULL); } -/* - * Register a transform. - */ -static int -xform_register(struct xformsw* xsp) -{ - struct xformsw *entry; - - XFORMS_LOCK(); - LIST_FOREACH(entry, &xforms, chain) { - if (entry->xf_type == xsp->xf_type) { - XFORMS_UNLOCK(); - return (EEXIST); - } - } - LIST_INSERT_HEAD(&xforms, xsp, chain); - XFORMS_UNLOCK(); - return (0); -} - -void -xform_attach(void *data) -{ - struct xformsw *xsp = (struct xformsw *)data; - - if (xform_register(xsp) != 0) - printf("%s: failed to register %s xform\n", __func__, - xsp->xf_name); -} - -void -xform_detach(void *data) -{ - struct xformsw *xsp = (struct xformsw *)data; - - XFORMS_LOCK(); - LIST_REMOVE(xsp, chain); - XFORMS_UNLOCK(); - - /* Delete all SAs related to this xform. */ - key_delete_xform(xsp); -} - -/* - * Initialize transform support in an sav. - */ -static int -xform_init(struct secasvar *sav, u_short xftype) -{ - struct xformsw *entry; - int ret; - - IPSEC_ASSERT(sav->tdb_xform == NULL, - ("tdb_xform is already initialized")); - - ret = EINVAL; - XFORMS_LOCK(); - LIST_FOREACH(entry, &xforms, chain) { - if (entry->xf_type == xftype) { - ret = (*entry->xf_init)(sav, entry); - break; - } - } - XFORMS_UNLOCK(); - return (ret); -} - diff --git a/sys/netipsec/key.h b/sys/netipsec/key.h index 6c3e05c039e8..7d7ae69f379d 100644 --- a/sys/netipsec/key.h +++ b/sys/netipsec/key.h @@ -46,6 +46,7 @@ struct sadb_msg; struct sadb_x_policy; struct secasindex; union sockaddr_union; +struct xformsw; struct secpolicy *key_newsp(void); struct secpolicy *key_allocsp(struct secpolicyindex *, u_int); @@ -74,6 +75,8 @@ int key_sockaddrcmp_withmask(const struct sockaddr *, const struct sockaddr *, int key_register_ifnet(struct secpolicy **, u_int); void key_unregister_ifnet(struct secpolicy **, u_int); +void key_delete_xform(const struct xformsw *); + extern u_long key_random(void); extern void key_randomfill(void *, size_t); extern void key_freereg(struct socket *); diff --git a/sys/netipsec/subr_ipsec.c b/sys/netipsec/subr_ipsec.c index acfe66acf458..37b686a7e91e 100644 --- a/sys/netipsec/subr_ipsec.c +++ b/sys/netipsec/subr_ipsec.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include <netipsec/ipsec6.h> #include <netipsec/key.h> #include <netipsec/key_debug.h> +#include <netipsec/xform.h> #include <machine/atomic.h> /* @@ -124,14 +125,6 @@ ipsec6_setsockaddrs(const struct mbuf *m, union sockaddr_union *src, } #endif -#ifdef IPSEC_SUPPORT -/* - * IPSEC_SUPPORT - loading of ipsec.ko and tcpmd5.ko is supported. - * IPSEC + IPSEC_SUPPORT - loading tcpmd5.ko is supported. - * IPSEC + TCP_SIGNATURE - all is build in the kernel, do not build - * IPSEC_SUPPORT. - */ -#if !defined(IPSEC) || !defined(TCP_SIGNATURE) #define IPSEC_MODULE_INCR 2 static int ipsec_kmod_enter(volatile u_int *cntr) @@ -171,6 +164,83 @@ ipsec_kmod_drain(volatile u_int *cntr) pause("ipsecd", hz/2); } +static LIST_HEAD(xforms_list, xformsw) xforms = LIST_HEAD_INITIALIZER(); +static struct mtx xforms_lock; +MTX_SYSINIT(xfroms_list, &xforms_lock, "IPsec transforms list", MTX_DEF); +#define XFORMS_LOCK() mtx_lock(&xforms_lock) +#define XFORMS_UNLOCK() mtx_unlock(&xforms_lock) + +void +xform_attach(void *data) +{ + struct xformsw *xsp, *entry; + + xsp = (struct xformsw *)data; + XFORMS_LOCK(); + LIST_FOREACH(entry, &xforms, chain) { + if (entry->xf_type == xsp->xf_type) { + XFORMS_UNLOCK(); + printf("%s: failed to register %s xform\n", + __func__, xsp->xf_name); + return; + } + } + LIST_INSERT_HEAD(&xforms, xsp, chain); + xsp->xf_cntr = IPSEC_MODULE_ENABLED; + XFORMS_UNLOCK(); +} + +void +xform_detach(void *data) +{ + struct xformsw *xsp = (struct xformsw *)data; + + XFORMS_LOCK(); + LIST_REMOVE(xsp, chain); + XFORMS_UNLOCK(); + + /* Delete all SAs related to this xform. */ + key_delete_xform(xsp); + if (xsp->xf_cntr & IPSEC_MODULE_ENABLED) + ipsec_kmod_drain(&xsp->xf_cntr); +} + +/* + * Initialize transform support in an sav. + */ +int +xform_init(struct secasvar *sav, u_short xftype) +{ + struct xformsw *entry; + int ret; + + IPSEC_ASSERT(sav->tdb_xform == NULL, + ("tdb_xform is already initialized")); + + XFORMS_LOCK(); + LIST_FOREACH(entry, &xforms, chain) { + if (entry->xf_type == xftype) { + ret = ipsec_kmod_enter(&entry->xf_cntr); + XFORMS_UNLOCK(); + if (ret != 0) + return (ret); + ret = (*entry->xf_init)(sav, entry); + ipsec_kmod_exit(&entry->xf_cntr); + return (ret); + } + } + XFORMS_UNLOCK(); + return (EINVAL); +} + +#ifdef IPSEC_SUPPORT +/* + * IPSEC_SUPPORT - loading of ipsec.ko and tcpmd5.ko is supported. + * IPSEC + IPSEC_SUPPORT - loading tcpmd5.ko is supported. + * IPSEC + TCP_SIGNATURE - all is build in the kernel, do not build + * IPSEC_SUPPORT. + */ +#if !defined(IPSEC) || !defined(TCP_SIGNATURE) #define METHOD_DECL(...) __VA_ARGS__ #define METHOD_ARGS(...) __VA_ARGS__ #define IPSEC_KMOD_METHOD(type, name, sc, method, decl, args) \ diff --git a/sys/netipsec/xform.h b/sys/netipsec/xform.h index 389d0b66850b..910a88a706f3 100644 --- a/sys/netipsec/xform.h +++ b/sys/netipsec/xform.h @@ -86,14 +86,16 @@ struct xform_data { #define XF_IPCOMP 6 /* IPCOMP */ struct xformsw { - u_short xf_type; /* xform ID */ - char *xf_name; /* human-readable name */ + u_short xf_type; /* xform ID */ + const char *xf_name; /* human-readable name */ int (*xf_init)(struct secasvar*, struct xformsw*); /* setup */ int (*xf_zeroize)(struct secasvar*); /* cleanup */ int (*xf_input)(struct mbuf*, struct secasvar*, /* input */ int, int); int (*xf_output)(struct mbuf*, /* output */ struct secpolicy *, struct secasvar *, u_int, int, int); + + volatile u_int xf_cntr; LIST_ENTRY(xformsw) chain; }; @@ -103,6 +105,7 @@ const struct comp_algo * comp_algorithm_lookup(int); void xform_attach(void *); void xform_detach(void *); +int xform_init(struct secasvar *, u_short); struct cryptoini; /* XF_AH */ diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index a4a719b5fbed..0a5a20640a66 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rwlock.h> #include <sys/endian.h> #include <sys/limits.h> +#include <sys/mutex.h> #include <crypto/blowfish/blowfish.h> #include <crypto/sha1.h> @@ -765,6 +766,7 @@ swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri) return EINVAL; ses = crypto_get_driver_session(cses); + mtx_init(&ses->swcr_lock, "swcr session lock", NULL, MTX_DEF); for (i = 0; cri != NULL && i < nitems(ses->swcr_algorithms); i++) { swd = &ses->swcr_algorithms[i]; @@ -1022,6 +1024,7 @@ swcr_freesession(device_t dev, crypto_session_t cses) ses = crypto_get_driver_session(cses); + mtx_destroy(&ses->swcr_lock); for (i = 0; i < nitems(ses->swcr_algorithms); i++) { swd = &ses->swcr_algorithms[i]; @@ -1109,7 +1112,7 @@ swcr_freesession(device_t dev, crypto_session_t cses) static int swcr_process(device_t dev, struct cryptop *crp, int hint) { - struct swcr_session *ses; + struct swcr_session *ses = NULL; struct cryptodesc *crd; struct swcr_data *sw; size_t i; @@ -1124,6 +1127,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) } ses = crypto_get_driver_session(crp->crp_session); + mtx_lock(&ses->swcr_lock); /* Go through crypto descriptors, processing as we go */ for (crd = crp->crp_desc; crd; crd = crd->crd_next) { @@ -1213,6 +1217,8 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) } done: + if (ses) + mtx_unlock(&ses->swcr_lock); crypto_done(crp); return 0; } diff --git a/sys/opencrypto/cryptosoft.h b/sys/opencrypto/cryptosoft.h index d88b09d4e1c0..d787dc243ae6 100644 --- a/sys/opencrypto/cryptosoft.h +++ b/sys/opencrypto/cryptosoft.h @@ -58,6 +58,7 @@ struct swcr_data { }; struct swcr_session { + struct mtx swcr_lock; struct swcr_data swcr_algorithms[2]; unsigned swcr_nalgs; }; diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c index 7e231373d829..c647ce817905 100644 --- a/sys/powerpc/ofw/ofw_machdep.c +++ b/sys/powerpc/ofw/ofw_machdep.c @@ -69,6 +69,10 @@ __FBSDID("$FreeBSD$"); #include <contrib/libfdt/libfdt.h> +#ifdef POWERNV +#include <powerpc/powernv/opal.h> +#endif + static void *fdt; int ofw_real_mode; @@ -338,6 +342,34 @@ excise_initrd_region(struct mem_region *avail, int asz) return (asz); } +#ifdef POWERNV +static int +excise_msi_region(struct mem_region *avail, int asz) +{ + uint64_t start, end; + struct mem_region initrdmap[1]; + + /* + * This range of physical addresses is used to implement optimized + * 32 bit MSI interrupts on POWER9. Exclude it to avoid accidentally + * using it for DMA, as this will cause an immediate PHB fence. + * While we could theoretically turn off this behavior in the ETU, + * doing so would break 32-bit MSI, so just reserve the range in + * the physical map instead. + * See section 4.4.2.8 of the PHB4 specification. + */ + start = 0x00000000ffff0000ul; + end = 0x00000000fffffffful; + + initrdmap[0].mr_start = start; + initrdmap[0].mr_size = end - start; + + asz = excise_reserved_regions(avail, asz, initrdmap, 1); + + return (asz); +} +#endif + static int excise_fdt_reserved(struct mem_region *avail, int asz) { @@ -430,6 +462,11 @@ ofw_mem_regions(struct mem_region *memp, int *memsz, asz = excise_initrd_region(availp, asz); #endif +#ifdef POWERNV + if (opal_check() == 0) + asz = excise_msi_region(availp, asz); +#endif + *memsz = msz; *availsz = asz; } diff --git a/sys/riscv/include/fpe.h b/sys/riscv/include/fpe.h index 1294ab0de8fa..a519094d4272 100644 --- a/sys/riscv/include/fpe.h +++ b/sys/riscv/include/fpe.h @@ -34,5 +34,6 @@ #define _MACHINE_FPE_H_ void fpe_state_save(struct thread *td); +void fpe_state_clear(void); #endif /* !_MACHINE_FPE_H_ */ diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c index 64d20126f3ad..430336408368 100644 --- a/sys/riscv/riscv/machdep.c +++ b/sys/riscv/riscv/machdep.c @@ -204,13 +204,14 @@ fill_fpregs(struct thread *td, struct fpreg *regs) * If we have just been running FPE instructions we will * need to save the state to memcpy it below. */ - fpe_state_save(td); + if (td == curthread) + fpe_state_save(td); memcpy(regs->fp_x, pcb->pcb_x, sizeof(regs->fp_x)); regs->fp_fcsr = pcb->pcb_fcsr; } else #endif - memset(regs->fp_x, 0, sizeof(regs->fp_x)); + memset(regs, 0, sizeof(*regs)); return (0); } @@ -219,12 +220,17 @@ int set_fpregs(struct thread *td, struct fpreg *regs) { #ifdef FPE + struct trapframe *frame; struct pcb *pcb; + frame = td->td_frame; pcb = td->td_pcb; memcpy(pcb->pcb_x, regs->fp_x, sizeof(regs->fp_x)); pcb->pcb_fcsr = regs->fp_fcsr; + pcb->pcb_fpflags |= PCB_FP_STARTED; + frame->tf_sstatus &= ~SSTATUS_FS_MASK; + frame->tf_sstatus |= SSTATUS_FS_CLEAN; #endif return (0); diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 8582667b27b9..b6a58ed796b6 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -3244,11 +3244,27 @@ pmap_activate(struct thread *td) critical_exit(); } +static void +pmap_sync_icache_one(void *arg __unused) +{ + + __asm __volatile("fence.i"); +} + void pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz) { - panic("RISCVTODO: pmap_sync_icache"); + /* + * From the RISC-V User-Level ISA V2.2: + * + * "To make a store to instruction memory visible to all + * RISC-V harts, the writing hart has to execute a data FENCE + * before requesting that all remote RISC-V harts execute a + * FENCE.I." + */ + __asm __volatile("fence"); + smp_rendezvous(NULL, pmap_sync_icache_one, NULL, NULL); } /* diff --git a/sys/riscv/riscv/swtch.S b/sys/riscv/riscv/swtch.S index b17de23ad395..8192abaf9869 100644 --- a/sys/riscv/riscv/swtch.S +++ b/sys/riscv/riscv/swtch.S @@ -153,6 +153,59 @@ ENTRY(fpe_state_save) END(fpe_state_save) #endif /* FPE */ +/* + * void + * fpe_state_clear(void) + */ +ENTRY(fpe_state_clear) + /* + * Enable FPE usage in supervisor mode, + * so we can access registers. + */ + li t0, SSTATUS_FS_INITIAL + csrs sstatus, t0 + + fscsr zero + fcvt.d.l f0, zero + fcvt.d.l f1, zero + fcvt.d.l f2, zero + fcvt.d.l f3, zero + fcvt.d.l f4, zero + fcvt.d.l f5, zero + fcvt.d.l f6, zero + fcvt.d.l f7, zero + fcvt.d.l f8, zero + fcvt.d.l f9, zero + fcvt.d.l f10, zero + fcvt.d.l f11, zero + fcvt.d.l f12, zero + fcvt.d.l f13, zero + fcvt.d.l f14, zero + fcvt.d.l f15, zero + fcvt.d.l f16, zero + fcvt.d.l f17, zero + fcvt.d.l f18, zero + fcvt.d.l f19, zero + fcvt.d.l f20, zero + fcvt.d.l f21, zero + fcvt.d.l f22, zero + fcvt.d.l f23, zero + fcvt.d.l f24, zero + fcvt.d.l f25, zero + fcvt.d.l f26, zero + fcvt.d.l f27, zero + fcvt.d.l f28, zero + fcvt.d.l f29, zero + fcvt.d.l f30, zero + fcvt.d.l f31, zero + + /* Disable FPE usage in supervisor mode. */ + li t0, SSTATUS_FS_MASK + csrc sstatus, t0 + + ret +END(fpe_state_clear) + /* * void cpu_throw(struct thread *old, struct thread *new) */ diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c index ced05c52588f..57f5c558d286 100644 --- a/sys/riscv/riscv/trap.c +++ b/sys/riscv/riscv/trap.c @@ -57,6 +57,9 @@ __FBSDID("$FreeBSD$"); #include <vm/vm_param.h> #include <vm/vm_extern.h> +#ifdef FPE +#include <machine/fpe.h> +#endif #include <machine/frame.h> #include <machine/pcb.h> #include <machine/pcpu.h> @@ -363,7 +366,9 @@ do_trap_user(struct trapframe *frame) * May be a FPE trap. Enable FPE usage * for this thread and try again. */ - frame->tf_sstatus |= SSTATUS_FS_INITIAL; + fpe_state_clear(); + frame->tf_sstatus &= ~SSTATUS_FS_MASK; + frame->tf_sstatus |= SSTATUS_FS_CLEAN; pcb->pcb_fpflags |= PCB_FP_STARTED; break; } diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h index 68595091a580..520f18c5a969 100644 --- a/sys/sys/malloc.h +++ b/sys/sys/malloc.h @@ -101,7 +101,7 @@ struct malloc_type_internal { uint32_t mti_probes[DTMALLOC_PROBE_MAX]; /* DTrace probe ID array. */ u_char mti_zone; - struct malloc_type_stats mti_stats[MAXCPU]; + struct malloc_type_stats *mti_stats; }; /* diff --git a/sys/sys/module.h b/sys/sys/module.h index b40870d32941..89377df401a8 100644 --- a/sys/sys/module.h +++ b/sys/sys/module.h @@ -178,12 +178,12 @@ struct mod_pnp_match_info * to allow external tools to parse their internal device tables * to make an informed guess about what driver(s) to load. */ -#define MODULE_PNP_INFO(d, b, unique, t, l, n) \ +#define MODULE_PNP_INFO(d, b, unique, t, n) \ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \ .descr = d, \ .bus = #b, \ .table = t, \ - .entry_len = l, \ + .entry_len = sizeof((t)[0]), \ .num_entry = n \ }; \ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \ diff --git a/sys/sys/racct.h b/sys/sys/racct.h index ec3322bdfdf9..84de705f24af 100644 --- a/sys/sys/racct.h +++ b/sys/sys/racct.h @@ -164,6 +164,15 @@ extern struct mtx racct_lock; #define RACCT_UNLOCK() mtx_unlock(&racct_lock) #define RACCT_LOCK_ASSERT() mtx_assert(&racct_lock, MA_OWNED) +#define RACCT_PROC_LOCK(p) do { \ + if (__predict_false(racct_enable)) \ + PROC_LOCK(p); \ +} while (0) +#define RACCT_PROC_UNLOCK(p) do { \ + if (__predict_false(racct_enable)) \ + PROC_UNLOCK(p); \ +} while (0) + int racct_add(struct proc *p, int resource, uint64_t amount); void racct_add_cred(struct ucred *cred, int resource, uint64_t amount); void racct_add_force(struct proc *p, int resource, uint64_t amount); @@ -189,6 +198,9 @@ void racct_proc_throttle(struct proc *p, int timeout); #else +#define RACCT_PROC_LOCK(p) do { } while (0) +#define RACCT_PROC_UNLOCK(p) do { } while (0) + static inline int racct_add(struct proc *p, int resource, uint64_t amount) { diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 3b5f750db5c9..c6c7d083cefb 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -349,7 +349,7 @@ static inline int sigdeferstop(int mode) { - if (mode == SIGDEFERSTOP_NOP) + if (__predict_true(mode == SIGDEFERSTOP_NOP)) return (SIGDEFERSTOP_VAL_NCHG); return (sigdeferstop_impl(mode)); } @@ -358,7 +358,7 @@ static inline void sigallowstop(int prev) { - if (prev == SIGDEFERSTOP_VAL_NCHG) + if (__predict_true(prev == SIGDEFERSTOP_VAL_NCHG)) return; sigallowstop_impl(prev); } diff --git a/sys/sys/user.h b/sys/sys/user.h index f5353f15b0fc..67acf2d0740d 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -346,85 +346,96 @@ struct kinfo_file { int64_t kf_offset; /* Seek location. */ union { struct { - /* Sendq size */ - uint32_t kf_sock_sendq; - /* Socket domain. */ - int kf_sock_domain0; - /* Socket type. */ - int kf_sock_type0; - /* Socket protocol. */ - int kf_sock_protocol0; - /* Socket address. */ + /* API compatiblity with FreeBSD < 12. */ + int kf_vnode_type; + int kf_sock_domain; + int kf_sock_type; + int kf_sock_protocol; struct sockaddr_storage kf_sa_local; - /* Peer address. */ struct sockaddr_storage kf_sa_peer; - /* Address of so_pcb. */ - uint64_t kf_sock_pcb; - /* Address of inp_ppcb. */ - uint64_t kf_sock_inpcb; - /* Address of unp_conn. */ - uint64_t kf_sock_unpconn; - /* Send buffer state. */ - uint16_t kf_sock_snd_sb_state; - /* Receive buffer state. */ - uint16_t kf_sock_rcv_sb_state; - /* Recvq size. */ - uint32_t kf_sock_recvq; - } kf_sock; - struct { - /* Vnode type. */ - int kf_file_type; - /* Space for future use */ - int kf_spareint[3]; - uint64_t kf_spareint64[30]; - /* Vnode filesystem id. */ - uint64_t kf_file_fsid; - /* File device. */ - uint64_t kf_file_rdev; - /* Global file id. */ - uint64_t kf_file_fileid; - /* File size. */ - uint64_t kf_file_size; - /* Vnode filesystem id, FreeBSD 11 compat. */ - uint32_t kf_file_fsid_freebsd11; - /* File device, FreeBSD 11 compat. */ - uint32_t kf_file_rdev_freebsd11; - /* File mode. */ - uint16_t kf_file_mode; - /* Round to 64 bit alignment. */ - uint16_t kf_file_pad0; - uint32_t kf_file_pad1; - } kf_file; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - uint32_t kf_sem_value; - uint16_t kf_sem_mode; - } kf_sem; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - uint64_t kf_pipe_addr; - uint64_t kf_pipe_peer; - uint32_t kf_pipe_buffer_cnt; - /* Round to 64 bit alignment. */ - uint32_t kf_pipe_pad0[3]; - } kf_pipe; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - uint32_t kf_pts_dev_freebsd11; - uint32_t kf_pts_pad0; - uint64_t kf_pts_dev; - /* Round to 64 bit alignment. */ - uint32_t kf_pts_pad1[4]; - } kf_pts; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - pid_t kf_pid; - } kf_proc; - } kf_un; + }; + union { + struct { + /* Sendq size */ + uint32_t kf_sock_sendq; + /* Socket domain. */ + int kf_sock_domain0; + /* Socket type. */ + int kf_sock_type0; + /* Socket protocol. */ + int kf_sock_protocol0; + /* Socket address. */ + struct sockaddr_storage kf_sa_local; + /* Peer address. */ + struct sockaddr_storage kf_sa_peer; + /* Address of so_pcb. */ + uint64_t kf_sock_pcb; + /* Address of inp_ppcb. */ + uint64_t kf_sock_inpcb; + /* Address of unp_conn. */ + uint64_t kf_sock_unpconn; + /* Send buffer state. */ + uint16_t kf_sock_snd_sb_state; + /* Receive buffer state. */ + uint16_t kf_sock_rcv_sb_state; + /* Recvq size. */ + uint32_t kf_sock_recvq; + } kf_sock; + struct { + /* Vnode type. */ + int kf_file_type; + /* Space for future use */ + int kf_spareint[3]; + uint64_t kf_spareint64[30]; + /* Vnode filesystem id. */ + uint64_t kf_file_fsid; + /* File device. */ + uint64_t kf_file_rdev; + /* Global file id. */ + uint64_t kf_file_fileid; + /* File size. */ + uint64_t kf_file_size; + /* Vnode filesystem id, FreeBSD 11 compat. */ + uint32_t kf_file_fsid_freebsd11; + /* File device, FreeBSD 11 compat. */ + uint32_t kf_file_rdev_freebsd11; + /* File mode. */ + uint16_t kf_file_mode; + /* Round to 64 bit alignment. */ + uint16_t kf_file_pad0; + uint32_t kf_file_pad1; + } kf_file; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint32_t kf_sem_value; + uint16_t kf_sem_mode; + } kf_sem; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint64_t kf_pipe_addr; + uint64_t kf_pipe_peer; + uint32_t kf_pipe_buffer_cnt; + /* Round to 64 bit alignment. */ + uint32_t kf_pipe_pad0[3]; + } kf_pipe; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint32_t kf_pts_dev_freebsd11; + uint32_t kf_pts_pad0; + uint64_t kf_pts_dev; + /* Round to 64 bit alignment. */ + uint32_t kf_pts_pad1[4]; + } kf_pts; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + pid_t kf_pid; + } kf_proc; + } kf_un; + }; uint16_t kf_status; /* Status flags. */ uint16_t kf_pad1; /* Round to 32 bit alignment. */ int _kf_ispare0; /* Space for more stuff. */ @@ -433,12 +444,6 @@ struct kinfo_file { /* Truncated before copyout in sysctl */ char kf_path[PATH_MAX]; /* Path to file, if any. */ }; -#ifndef _KERNEL -#define kf_vnode_type kf_un.kf_file.kf_file_type -#define kf_sock_domain kf_un.kf_sock.kf_sock_domain0 -#define kf_sock_type kf_un.kf_sock.kf_sock_type0 -#define kf_sock_protocol kf_un.kf_sock.kf_sock_protocol0 -#endif /* * The KERN_PROC_VMMAP sysctl allows a process to dump the VM layout of diff --git a/sys/sys/vmmeter.h b/sys/sys/vmmeter.h index c41b151fa502..579d16756e99 100644 --- a/sys/sys/vmmeter.h +++ b/sys/sys/vmmeter.h @@ -145,6 +145,7 @@ struct vmmeter { #include <sys/domainset.h> extern struct vmmeter vm_cnt; +extern domainset_t all_domains; extern domainset_t vm_min_domains; extern domainset_t vm_severe_domains; @@ -177,7 +178,7 @@ vm_wire_count(void) /* * Return TRUE if we are under our severe low-free-pages threshold * - * This routine is typically used at the user<->system interface to determine + * These routines are typically used at the user<->system interface to determine * whether we need to block in order to avoid a low memory deadlock. */ static inline int @@ -188,7 +189,14 @@ vm_page_count_severe(void) } static inline int -vm_page_count_severe_set(domainset_t *mask) +vm_page_count_severe_domain(int domain) +{ + + return (DOMAINSET_ISSET(domain, &vm_severe_domains)); +} + +static inline int +vm_page_count_severe_set(const domainset_t *mask) { return (DOMAINSET_SUBSET(&vm_severe_domains, mask)); @@ -197,7 +205,7 @@ vm_page_count_severe_set(domainset_t *mask) /* * Return TRUE if we are under our minimum low-free-pages threshold. * - * This routine is typically used within the system to determine whether + * These routines are typically used within the system to determine whether * we can execute potentially very expensive code in terms of memory. It * is also used by the pageout daemon to calculate when to sleep, when * to wake waiters up, and when (after making a pass) to become more @@ -210,5 +218,19 @@ vm_page_count_min(void) return (!DOMAINSET_EMPTY(&vm_min_domains)); } +static inline int +vm_page_count_min_domain(int domain) +{ + + return (DOMAINSET_ISSET(domain, &vm_min_domains)); +} + +static inline int +vm_page_count_min_set(const domainset_t *mask) +{ + + return (DOMAINSET_SUBSET(&vm_min_domains, mask)); +} + #endif /* _KERNEL */ #endif /* _SYS_VMMETER_H_ */ diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 89d0b7382e4d..dcc72b2fdfd3 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -10261,22 +10261,22 @@ initiate_write_inodeblock_ufs1(inodedep, bp) prevlbn = adp->ad_offset; if (adp->ad_offset < UFS_NDADDR && dp->di_db[adp->ad_offset] != adp->ad_newblkno) - panic("%s: direct pointer #%jd mismatch %d != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs1: " + "direct pointer #%jd mismatch %d != %jd", (intmax_t)adp->ad_offset, dp->di_db[adp->ad_offset], (intmax_t)adp->ad_newblkno); if (adp->ad_offset >= UFS_NDADDR && dp->di_ib[adp->ad_offset - UFS_NDADDR] != adp->ad_newblkno) - panic("%s: indirect pointer #%jd mismatch %d != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs1: " + "indirect pointer #%jd mismatch %d != %jd", (intmax_t)adp->ad_offset - UFS_NDADDR, dp->di_ib[adp->ad_offset - UFS_NDADDR], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) - panic("softdep_write_inodeblock: Unknown state 0x%x", - adp->ad_state); + panic("initiate_write_inodeblock_ufs1: " + "Unknown state 0x%x", adp->ad_state); #endif /* INVARIANTS */ adp->ad_state &= ~ATTACHED; adp->ad_state |= UNDONE; @@ -10299,7 +10299,8 @@ initiate_write_inodeblock_ufs1(inodedep, bp) for (i = adp->ad_offset + 1; i < UFS_NDADDR; i++) { #ifdef INVARIANTS if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) - panic("softdep_write_inodeblock: lost dep1"); + panic("initiate_write_inodeblock_ufs1: " + "lost dep1"); #endif /* INVARIANTS */ dp->di_db[i] = 0; } @@ -10307,7 +10308,8 @@ initiate_write_inodeblock_ufs1(inodedep, bp) #ifdef INVARIANTS if (dp->di_ib[i] != 0 && (deplist & ((1 << UFS_NDADDR) << i)) == 0) - panic("softdep_write_inodeblock: lost dep2"); + panic("initiate_write_inodeblock_ufs1: " + "lost dep2"); #endif /* INVARIANTS */ dp->di_ib[i] = 0; } @@ -10429,18 +10431,18 @@ initiate_write_inodeblock_ufs2(inodedep, bp) adp = TAILQ_NEXT(adp, ad_next)) { #ifdef INVARIANTS if (deplist != 0 && prevlbn >= adp->ad_offset) - panic("softdep_write_inodeblock: lbn order"); + panic("initiate_write_inodeblock_ufs2: lbn order"); prevlbn = adp->ad_offset; if (dp->di_extb[adp->ad_offset] != adp->ad_newblkno) - panic("%s: direct pointer #%jd mismatch %jd != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs2: " + "ext pointer #%jd mismatch %jd != %jd", (intmax_t)adp->ad_offset, (intmax_t)dp->di_extb[adp->ad_offset], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) - panic("softdep_write_inodeblock: Unknown state 0x%x", - adp->ad_state); + panic("initiate_write_inodeblock_ufs2: Unknown " + "state 0x%x", adp->ad_state); #endif /* INVARIANTS */ adp->ad_state &= ~ATTACHED; adp->ad_state |= UNDONE; @@ -10461,7 +10463,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp) for (i = adp->ad_offset + 1; i < UFS_NXADDR; i++) { #ifdef INVARIANTS if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0) - panic("softdep_write_inodeblock: lost dep1"); + panic("initiate_write_inodeblock_ufs2: " + "lost dep1"); #endif /* INVARIANTS */ dp->di_extb[i] = 0; } @@ -10494,22 +10497,22 @@ initiate_write_inodeblock_ufs2(inodedep, bp) prevlbn = adp->ad_offset; if (adp->ad_offset < UFS_NDADDR && dp->di_db[adp->ad_offset] != adp->ad_newblkno) - panic("%s: direct pointer #%jd mismatch %jd != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs2: " + "direct pointer #%jd mismatch %jd != %jd", (intmax_t)adp->ad_offset, (intmax_t)dp->di_db[adp->ad_offset], (intmax_t)adp->ad_newblkno); if (adp->ad_offset >= UFS_NDADDR && dp->di_ib[adp->ad_offset - UFS_NDADDR] != adp->ad_newblkno) - panic("%s indirect pointer #%jd mismatch %jd != %jd", - "softdep_write_inodeblock:", + panic("initiate_write_inodeblock_ufs2: " + "indirect pointer #%jd mismatch %jd != %jd", (intmax_t)adp->ad_offset - UFS_NDADDR, (intmax_t)dp->di_ib[adp->ad_offset - UFS_NDADDR], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) - panic("softdep_write_inodeblock: Unknown state 0x%x", - adp->ad_state); + panic("initiate_write_inodeblock_ufs2: Unknown " + "state 0x%x", adp->ad_state); #endif /* INVARIANTS */ adp->ad_state &= ~ATTACHED; adp->ad_state |= UNDONE; @@ -10532,7 +10535,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp) for (i = adp->ad_offset + 1; i < UFS_NDADDR; i++) { #ifdef INVARIANTS if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) - panic("softdep_write_inodeblock: lost dep2"); + panic("initiate_write_inodeblock_ufs2: " + "lost dep2"); #endif /* INVARIANTS */ dp->di_db[i] = 0; } @@ -10540,7 +10544,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp) #ifdef INVARIANTS if (dp->di_ib[i] != 0 && (deplist & ((1 << UFS_NDADDR) << i)) == 0) - panic("softdep_write_inodeblock: lost dep3"); + panic("initiate_write_inodeblock_ufs2: " + "lost dep3"); #endif /* INVARIANTS */ dp->di_ib[i] = 0; } diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 25133b834861..31fc49b7b4cf 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -712,6 +712,34 @@ quotaoff1(struct thread *td, struct mount *mp, int type) return (error); } +static int +quotaoff_inchange1(struct thread *td, struct mount *mp, int type) +{ + int error; + bool need_resume; + + /* + * mp is already suspended on unmount. If not, suspend it, to + * avoid the situation where quotaoff operation eventually + * failing due to SU structures still keeping references on + * dquots, but vnode's references are already clean. This + * would cause quota accounting leak and asserts otherwise. + * Note that the thread has already called vn_start_write(). + */ + if (mp->mnt_susp_owner == td) { + need_resume = false; + } else { + error = vfs_write_suspend_umnt(mp); + if (error != 0) + return (error); + need_resume = true; + } + error = quotaoff1(td, mp, type); + if (need_resume) + vfs_write_resume(mp, VR_START_WRITE); + return (error); +} + /* * Turns off quotas, assumes that ump->um_qflags are already checked * and QTF_CLOSING is set to indicate operation in progress. Fixes @@ -721,10 +749,9 @@ int quotaoff_inchange(struct thread *td, struct mount *mp, int type) { struct ufsmount *ump; - int i; - int error; + int error, i; - error = quotaoff1(td, mp, type); + error = quotaoff_inchange1(td, mp, type); ump = VFSTOUFS(mp); UFS_LOCK(ump); diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index cf5b1d792aef..f39f50cc9a61 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -94,7 +94,8 @@ ufs_quotactl(mp, cmds, id, arg) void *arg; { #ifndef QUOTA - if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON) + if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON || + (cmds >> SUBCMDSHIFT) == Q_QUOTAOFF) vfs_unbusy(mp); return (EOPNOTSUPP); @@ -117,13 +118,13 @@ ufs_quotactl(mp, cmds, id, arg) break; default: - if (cmd == Q_QUOTAON) + if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF) vfs_unbusy(mp); return (EINVAL); } } if ((u_int)type >= MAXQUOTAS) { - if (cmd == Q_QUOTAON) + if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF) vfs_unbusy(mp); return (EINVAL); } @@ -134,7 +135,11 @@ ufs_quotactl(mp, cmds, id, arg) break; case Q_QUOTAOFF: + vfs_ref(mp); + vfs_unbusy(mp); + vn_start_write(NULL, &mp, V_WAIT | V_MNTREF); error = quotaoff(td, mp, type); + vn_finished_write(mp); break; case Q_SETQUOTA32: diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 9e6e24c32db9..9e8896866660 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -325,9 +325,6 @@ ufs_accessx(ap) struct inode *ip = VTOI(vp); accmode_t accmode = ap->a_accmode; int error; -#ifdef QUOTA - int relocked; -#endif #ifdef UFS_ACL struct acl *acl; acl_type_t type; @@ -350,32 +347,14 @@ ufs_accessx(ap) * Inode is accounted in the quotas only if struct * dquot is attached to it. VOP_ACCESS() is called * from vn_open_cred() and provides a convenient - * point to call getinoquota(). + * point to call getinoquota(). The lock mode is + * exclusive when the file is opening for write. */ - if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { - - /* - * Upgrade vnode lock, since getinoquota() - * requires exclusive lock to modify inode. - */ - relocked = 1; - vhold(vp); - vn_lock(vp, LK_UPGRADE | LK_RETRY); - VI_LOCK(vp); - if (vp->v_iflag & VI_DOOMED) { - vdropl(vp); - error = ENOENT; - goto relock; - } - vdropl(vp); - } else - relocked = 0; - error = getinoquota(ip); -relock: - if (relocked) - vn_lock(vp, LK_DOWNGRADE | LK_RETRY); - if (error != 0) - return (error); + if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) { + error = getinoquota(ip); + if (error != 0) + return (error); + } #endif break; default: diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 858a9e884626..0bd4bde8b57e 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -545,13 +545,11 @@ swap_pager_swap_init(void) if (maxswzone && n > maxswzone / sizeof(struct swblk)) n = maxswzone / sizeof(struct swblk); swpctrie_zone = uma_zcreate("swpctrie", pctrie_node_size(), NULL, NULL, - pctrie_zone_init, NULL, UMA_ALIGN_PTR, - UMA_ZONE_NOFREE | UMA_ZONE_VM); + pctrie_zone_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM); if (swpctrie_zone == NULL) panic("failed to create swap pctrie zone."); swblk_zone = uma_zcreate("swblk", sizeof(struct swblk), NULL, NULL, - NULL, NULL, _Alignof(struct swblk) - 1, - UMA_ZONE_NOFREE | UMA_ZONE_VM); + NULL, NULL, _Alignof(struct swblk) - 1, UMA_ZONE_VM); if (swblk_zone == NULL) panic("failed to create swap blk zone."); n2 = n; diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 908349379763..937e78452021 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -2698,10 +2698,8 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, int flags) LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link); return (slab); } - if (rr) { - keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains; - domain = keg->uk_cursor; - } + if (rr) + domain = (domain + 1) % vm_ndomains; } while (domain != start); /* Retry domain scan with blocking. */ diff --git a/sys/vm/vm_domainset.c b/sys/vm/vm_domainset.c index 16b078e7dabd..b9348d6c632b 100644 --- a/sys/vm/vm_domainset.c +++ b/sys/vm/vm_domainset.c @@ -66,6 +66,7 @@ vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj, vm_pindex_t pindex) { struct domainset *domain; + struct thread *td; /* * object policy takes precedence over thread policy. The policies @@ -76,8 +77,9 @@ vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj, di->di_domain = domain; di->di_iter = &obj->domain.dr_iterator; } else { - di->di_domain = curthread->td_domain.dr_policy; - di->di_iter = &curthread->td_domain.dr_iterator; + td = curthread; + di->di_domain = td->td_domain.dr_policy; + di->di_iter = &td->td_domain.dr_iterator; } di->di_policy = di->di_domain->ds_policy; if (di->di_policy == DOMAINSET_POLICY_INTERLEAVE) { @@ -215,7 +217,7 @@ vm_domainset_iter_page_init(struct vm_domainset_iter *di, struct vm_object *obj, *req = (di->di_flags & ~(VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL)) | VM_ALLOC_NOWAIT; vm_domainset_iter_first(di, domain); - if (DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (vm_page_count_min_domain(*domain)) vm_domainset_iter_page(di, domain, req); } @@ -233,8 +235,7 @@ vm_domainset_iter_page(struct vm_domainset_iter *di, int *domain, int *req) /* If there are more domains to visit we run the iterator. */ while (--di->di_n != 0) { vm_domainset_iter_next(di, domain); - if (!di->di_minskip || - !DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (!di->di_minskip || !vm_page_count_min_domain(*domain)) return (0); } if (di->di_minskip) { @@ -269,7 +270,7 @@ vm_domainset_iter_malloc_init(struct vm_domainset_iter *di, di->di_flags = *flags; *flags = (di->di_flags & ~M_WAITOK) | M_NOWAIT; vm_domainset_iter_first(di, domain); - if (DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (vm_page_count_min_domain(*domain)) vm_domainset_iter_malloc(di, domain, flags); } @@ -280,8 +281,7 @@ vm_domainset_iter_malloc(struct vm_domainset_iter *di, int *domain, int *flags) /* If there are more domains to visit we run the iterator. */ while (--di->di_n != 0) { vm_domainset_iter_next(di, domain); - if (!di->di_minskip || - !DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (!di->di_minskip || !vm_page_count_min_domain(*domain)) return (0); } diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 832dbce324ef..beccb31f0b64 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -327,7 +327,7 @@ vm_thread_new(struct thread *td, int pages) else if (pages > KSTACK_MAX_PAGES) pages = KSTACK_MAX_PAGES; - if (pages == kstack_pages) { + if (pages == kstack_pages && kstack_cache != NULL) { mtx_lock(&kstack_cache_mtx); if (kstack_cache != NULL) { ks_ce = kstack_cache; diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index 09e87ed231ed..27ecb960201e 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -98,12 +98,6 @@ extern void uma_startup1(void); extern void uma_startup2(void); extern void vm_radix_reserve_kva(void); -#if VM_NRESERVLEVEL > 0 -#define KVA_QUANTUM (1 << (VM_LEVEL_0_ORDER + PAGE_SHIFT)) -#else - /* On non-superpage architectures want large import sizes. */ -#define KVA_QUANTUM (PAGE_SIZE * 1024) -#endif long physmem; /* @@ -112,58 +106,15 @@ long physmem; static void vm_mem_init(void *); SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL); -/* - * Import kva into the kernel arena. - */ -static int -kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) -{ - vm_offset_t addr; - int result; - - KASSERT((size % KVA_QUANTUM) == 0, - ("kva_import: Size %jd is not a multiple of %d", - (intmax_t)size, (int)KVA_QUANTUM)); - addr = vm_map_min(kernel_map); - result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, - VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); - if (result != KERN_SUCCESS) - return (ENOMEM); - - *addrp = addr; - - return (0); -} - -#if VM_NRESERVLEVEL > 0 -/* - * Import a superpage from the normal kernel arena into the special - * arena for allocations with different permissions. - */ -static int -kernel_rwx_alloc(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp) -{ - - KASSERT((size % KVA_QUANTUM) == 0, - ("kernel_rwx_alloc: Size %jd is not a multiple of %d", - (intmax_t)size, (int)KVA_QUANTUM)); - return (vmem_xalloc(arena, size, KVA_QUANTUM, 0, 0, VMEM_ADDR_MIN, - VMEM_ADDR_MAX, flags, addrp)); -} -#endif - /* * vm_init initializes the virtual memory system. * This is done only by the first cpu up. * * The start and end address of physical memory is passed in. */ -/* ARGSUSED*/ static void -vm_mem_init(dummy) - void *dummy; +vm_mem_init(void *dummy) { - int domain; /* * Initializes resident memory structures. From here on, all physical @@ -184,39 +135,6 @@ vm_mem_init(dummy) vm_map_startup(); kmem_init(virtual_avail, virtual_end); - /* - * Initialize the kernel_arena. This can grow on demand. - */ - vmem_init(kernel_arena, "kernel arena", 0, 0, PAGE_SIZE, 0, 0); - vmem_set_import(kernel_arena, kva_import, NULL, NULL, KVA_QUANTUM); - -#if VM_NRESERVLEVEL > 0 - /* - * In an architecture with superpages, maintain a separate arena - * for allocations with permissions that differ from the "standard" - * read/write permissions used for memory in the kernel_arena. - */ - kernel_rwx_arena = vmem_create("kernel rwx arena", 0, 0, PAGE_SIZE, - 0, M_WAITOK); - vmem_set_import(kernel_rwx_arena, kernel_rwx_alloc, - (vmem_release_t *)vmem_xfree, kernel_arena, KVA_QUANTUM); -#endif - - for (domain = 0; domain < vm_ndomains; domain++) { - vm_dom[domain].vmd_kernel_arena = vmem_create( - "kernel arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); - vmem_set_import(vm_dom[domain].vmd_kernel_arena, - (vmem_import_t *)vmem_alloc, NULL, kernel_arena, - KVA_QUANTUM); -#if VM_NRESERVLEVEL > 0 - vm_dom[domain].vmd_kernel_rwx_arena = vmem_create( - "kernel rwx arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); - vmem_set_import(vm_dom[domain].vmd_kernel_rwx_arena, - kernel_rwx_alloc, (vmem_release_t *)vmem_xfree, - vm_dom[domain].vmd_kernel_arena, KVA_QUANTUM); -#endif - } - #ifndef UMA_MD_SMALL_ALLOC /* Set up radix zone to use noobj_alloc. */ vm_radix_reserve_kva(); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 5dee4d758dd0..9774e0b4f22d 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -121,6 +121,14 @@ SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD, #endif "Max kernel address"); +#if VM_NRESERVLEVEL > 0 +#define KVA_QUANTUM_SHIFT (VM_LEVEL_0_ORDER + PAGE_SHIFT) +#else +/* On non-superpage architectures want large import sizes. */ +#define KVA_QUANTUM_SHIFT (10 + PAGE_SHIFT) +#endif +#define KVA_QUANTUM (1 << KVA_QUANTUM_SHIFT) + /* * kva_alloc: * @@ -409,9 +417,10 @@ kmem_malloc(vm_size_t size, int flags) } /* - * kmem_back: + * kmem_back_domain: * - * Allocate physical pages for the specified virtual address range. + * Allocate physical pages from the specified domain for the specified + * virtual address range. */ int kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr, @@ -472,24 +481,41 @@ kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr, return (KERN_SUCCESS); } +/* + * kmem_back: + * + * Allocate physical pages for the specified virtual address range. + */ int kmem_back(vm_object_t object, vm_offset_t addr, vm_size_t size, int flags) { - struct vm_domainset_iter di; - int domain; - int ret; + vm_offset_t end, next, start; + int domain, rv; KASSERT(object == kernel_object, ("kmem_back: only supports kernel object.")); - vm_domainset_iter_malloc_init(&di, kernel_object, &domain, &flags); - do { - ret = kmem_back_domain(domain, object, addr, size, flags); - if (ret == KERN_SUCCESS) + for (start = addr, end = addr + size; addr < end; addr = next) { + /* + * We must ensure that pages backing a given large virtual page + * all come from the same physical domain. + */ + if (vm_ndomains > 1) { + domain = (addr >> KVA_QUANTUM_SHIFT) % vm_ndomains; + next = roundup2(addr + 1, KVA_QUANTUM); + if (next > end || next < start) + next = end; + } else { + domain = 0; + next = end; + } + rv = kmem_back_domain(domain, object, addr, next - addr, flags); + if (rv != KERN_SUCCESS) { + kmem_unback(object, start, addr - start); break; - } while (vm_domainset_iter_malloc(&di, &domain, &flags) == 0); - - return (ret); + } + } + return (rv); } /* @@ -644,6 +670,44 @@ kmem_init_zero_region(void) zero_region = (const void *)addr; } +/* + * Import KVA from the kernel map into the kernel arena. + */ +static int +kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) +{ + vm_offset_t addr; + int result; + + KASSERT((size % KVA_QUANTUM) == 0, + ("kva_import: Size %jd is not a multiple of %d", + (intmax_t)size, (int)KVA_QUANTUM)); + addr = vm_map_min(kernel_map); + result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, + VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); + if (result != KERN_SUCCESS) + return (ENOMEM); + + *addrp = addr; + + return (0); +} + +/* + * Import KVA from a parent arena into a per-domain arena. Imports must be + * KVA_QUANTUM-aligned and a multiple of KVA_QUANTUM in size. + */ +static int +kva_import_domain(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp) +{ + + KASSERT((size % KVA_QUANTUM) == 0, + ("kva_import_domain: Size %jd is not a multiple of %d", + (intmax_t)size, (int)KVA_QUANTUM)); + return (vmem_xalloc(arena, size, KVA_QUANTUM, 0, 0, VMEM_ADDR_MIN, + VMEM_ADDR_MAX, flags, addrp)); +} + /* * kmem_init: * @@ -651,11 +715,13 @@ kmem_init_zero_region(void) * data, bss, and all space allocated thus far (`boostrap' data). The * new map will thus map the range between VM_MIN_KERNEL_ADDRESS and * `start' as allocated, and the range between `start' and `end' as free. + * Create the kernel vmem arena and its per-domain children. */ void kmem_init(vm_offset_t start, vm_offset_t end) { vm_map_t m; + int domain; m = vm_map_create(kernel_pmap, VM_MIN_KERNEL_ADDRESS, end); m->system_map = 1; @@ -671,6 +737,39 @@ kmem_init(vm_offset_t start, vm_offset_t end) start, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); /* ... and ending with the completion of the above `insert' */ vm_map_unlock(m); + + /* + * Initialize the kernel_arena. This can grow on demand. + */ + vmem_init(kernel_arena, "kernel arena", 0, 0, PAGE_SIZE, 0, 0); + vmem_set_import(kernel_arena, kva_import, NULL, NULL, KVA_QUANTUM); + + for (domain = 0; domain < vm_ndomains; domain++) { + /* + * Initialize the per-domain arenas. These are used to color + * the KVA space in a way that ensures that virtual large pages + * are backed by memory from the same physical domain, + * maximizing the potential for superpage promotion. + */ + vm_dom[domain].vmd_kernel_arena = vmem_create( + "kernel arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); + vmem_set_import(vm_dom[domain].vmd_kernel_arena, + kva_import_domain, NULL, kernel_arena, KVA_QUANTUM); + + /* + * In architectures with superpages, maintain separate arenas + * for allocations with permissions that differ from the + * "standard" read/write permissions used for kernel memory, + * so as not to inhibit superpage promotion. + */ +#if VM_NRESERVLEVEL > 0 + vm_dom[domain].vmd_kernel_rwx_arena = vmem_create( + "kernel rwx arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); + vmem_set_import(vm_dom[domain].vmd_kernel_rwx_arena, + kva_import_domain, (vmem_release_t *)vmem_xfree, + kernel_arena, KVA_QUANTUM); +#endif + } } /* diff --git a/sys/vm/vm_kern.h b/sys/vm/vm_kern.h index 8d49a598f26d..20e847f5e5af 100644 --- a/sys/vm/vm_kern.h +++ b/sys/vm/vm_kern.h @@ -70,7 +70,6 @@ extern vm_map_t kernel_map; extern vm_map_t exec_map; extern vm_map_t pipe_map; extern struct vmem *kernel_arena; -extern struct vmem *kernel_rwx_arena; extern struct vmem *kmem_arena; extern struct vmem *buffer_arena; extern struct vmem *transient_arena; diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index e184b8ff5c1f..e8772a1eadde 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1055,12 +1055,8 @@ sys_mlockall(struct thread *td, struct mlockall_args *uap) * a hard resource limit, return ENOMEM. */ if (!old_mlock && uap->how & MCL_CURRENT) { - PROC_LOCK(td->td_proc); - if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) { - PROC_UNLOCK(td->td_proc); + if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) return (ENOMEM); - } - PROC_UNLOCK(td->td_proc); } #ifdef RACCT if (racct_enable) { @@ -1445,21 +1441,21 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, curmap = map == &td->td_proc->p_vmspace->vm_map; if (curmap) { - PROC_LOCK(td->td_proc); - if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) { - PROC_UNLOCK(td->td_proc); + RACCT_PROC_LOCK(td->td_proc); + if (map->size + size > lim_cur(td, RLIMIT_VMEM)) { + RACCT_PROC_UNLOCK(td->td_proc); return (ENOMEM); } if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) { - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); return (ENOMEM); } if (!old_mlock && map->flags & MAP_WIREFUTURE) { if (ptoa(pmap_wired_count(map->pmap)) + size > - lim_cur_proc(td->td_proc, RLIMIT_MEMLOCK)) { + lim_cur(td, RLIMIT_MEMLOCK)) { racct_set_force(td->td_proc, RACCT_VMEM, map->size); - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); return (ENOMEM); } error = racct_set(td->td_proc, RACCT_MEMLOCK, @@ -1467,11 +1463,11 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, if (error != 0) { racct_set_force(td->td_proc, RACCT_VMEM, map->size); - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); return (error); } } - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); } /* diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index d022435704f1..47628cba2ac1 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2959,7 +2959,7 @@ vm_wait_doms(const domainset_t *wdoms) * consume all freed pages while old allocators wait. */ mtx_lock(&vm_domainset_lock); - if (DOMAINSET_SUBSET(&vm_min_domains, wdoms)) { + if (vm_page_count_min_set(wdoms)) { vm_min_waiters++; msleep(&vm_min_domains, &vm_domainset_lock, PVM | PDROP, "vmwait", 0); @@ -3078,7 +3078,7 @@ vm_waitpfault(struct domainset *dset) * consume all freed pages while old allocators wait. */ mtx_lock(&vm_domainset_lock); - if (DOMAINSET_SUBSET(&vm_min_domains, &dset->ds_mask)) { + if (vm_page_count_min_set(&dset->ds_mask)) { vm_min_waiters++; msleep(&vm_min_domains, &vm_domainset_lock, PUSER | PDROP, "pfault", 0); diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index 890f5dad9213..5206ba6e658f 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -78,6 +78,7 @@ int __read_mostly *mem_locality; #endif int __read_mostly vm_ndomains = 1; +domainset_t __read_mostly all_domains = DOMAINSET_T_INITIALIZER(0x1); struct vm_phys_seg __read_mostly vm_phys_segs[VM_PHYSSEG_MAX]; int __read_mostly vm_phys_nsegs; diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c index 0ea747ccc30b..08a98429a03d 100644 --- a/sys/x86/acpica/srat.c +++ b/sys/x86/acpica/srat.c @@ -470,8 +470,9 @@ parse_srat(void) } #ifdef NUMA - /* Point vm_phys at our memory affinity table. */ vm_ndomains = ndomain; + for (int i = 0; i < vm_ndomains; i++) + DOMAINSET_SET(i, &all_domains); mem_affinity = mem_info; #endif diff --git a/sys/x86/iommu/intel_utils.c b/sys/x86/iommu/intel_utils.c index 5b145c5aeae9..944aa214baa6 100644 --- a/sys/x86/iommu/intel_utils.c +++ b/sys/x86/iommu/intel_utils.c @@ -368,8 +368,7 @@ dmar_flush_transl_to_ram(struct dmar_unit *unit, void *dst, size_t sz) * If DMAR does not snoop paging structures accesses, flush * CPU cache to memory. */ - pmap_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz, - TRUE); + pmap_force_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz); } void diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index d2fa981873cc..151b51b5599f 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -206,6 +206,7 @@ OLD_DIRS+=usr/share/examples/bhyve OLD_FILES+=usr/bin/as .if ${MK_LLD_IS_LD} == no OLD_FILES+=usr/bin/ld +OLD_FILES+=usr/share/man/man1/ld.1.gz .endif OLD_FILES+=usr/bin/ld.bfd OLD_FILES+=usr/bin/objdump @@ -405,7 +406,6 @@ OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xw OLD_FILES+=usr/share/man/man1/as.1.gz -OLD_FILES+=usr/share/man/man1/ld.1.gz OLD_FILES+=usr/share/man/man1/objdump.1.gz OLD_FILES+=usr/share/man/man7/as.7.gz OLD_FILES+=usr/share/man/man7/ld.7.gz diff --git a/tools/build/options/WITH_HYPERV b/tools/build/options/WITH_HYPERV new file mode 100644 index 000000000000..06d6f81c8fe1 --- /dev/null +++ b/tools/build/options/WITH_HYPERV @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Set to build or install HyperV utilities. diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config index a8d35ea3112f..1b4fa796e722 100644 --- a/usr.bin/bmake/Makefile.config +++ b/usr.bin/bmake/Makefile.config @@ -16,7 +16,7 @@ DEFAULT_SYS_PATH?= .../share/mk:/usr/share/mk CPPFLAGS+= CFLAGS+= ${CPPFLAGS} -DHAVE_CONFIG_H -LDFLAGS= +LDFLAGS+= LIBOBJS= ${LIBOBJDIR}stresep$U.o LDADD= USE_META= yes diff --git a/usr.bin/locate/locate/Makefile b/usr.bin/locate/locate/Makefile index a139ff282028..7d56c57457c7 100644 --- a/usr.bin/locate/locate/Makefile +++ b/usr.bin/locate/locate/Makefile @@ -1,6 +1,7 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +CONFS= locate.rc PROG= locate SRCS= util.c locate.c CFLAGS+= -I${.CURDIR} -DMMAP # -DDEBUG (print time) -O2 (10% faster) @@ -15,9 +16,5 @@ SCRIPTSNAME_${script}= locate.${script:R} .endfor MLINKS+= locate.updatedb.8 updatedb.8 -# only /usr/src/etc/Makefile install files in /etc -# ${INSTALL} -o root -g wheel -m 644 \ -# ${.CURDIR}/locate.rc ${DESTDIR}/etc - .include "../../Makefile.inc" .include <bsd.prog.mk> diff --git a/usr.bin/mail/Makefile b/usr.bin/mail/Makefile index ea2338b3dded..7b205b8019d8 100644 --- a/usr.bin/mail/Makefile +++ b/usr.bin/mail/Makefile @@ -1,6 +1,7 @@ # @(#)Makefile 8.2 (Berkeley) 1/25/94 # $FreeBSD$ +CONFS= misc/mail.rc PROG= mail SRCS= version.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c edit.c fio.c \ getname.c head.c v7.local.c lex.c list.c main.c names.c popen.c \ diff --git a/usr.bin/mandoc/Makefile b/usr.bin/mandoc/Makefile index d6b9aa059dd3..877ae6af0e24 100644 --- a/usr.bin/mandoc/Makefile +++ b/usr.bin/mandoc/Makefile @@ -2,8 +2,8 @@ .include <src.opts.mk> -MDOCMLDIR= ${SRCTOP}/contrib/mdocml -.PATH: ${MDOCMLDIR} +MANDOCDIR= ${SRCTOP}/contrib/mandoc +.PATH: ${MANDOCDIR} PROG= mandoc MAN= mandoc.1 eqn.7 mandoc_char.7 tbl.7 man.7 mdoc.7 roff.7 diff --git a/usr.bin/tip/tip/Makefile b/usr.bin/tip/tip/Makefile index a8ed43f7c579..f177ad15d3b8 100644 --- a/usr.bin/tip/tip/Makefile +++ b/usr.bin/tip/tip/Makefile @@ -31,6 +31,7 @@ # explicitly to remcap.c if not 1024 # CONNECT enable ~C command (connect pgm to remote) +CONFS= phones remote PROG= tip LINKS= ${BINDIR}/tip ${BINDIR}/cu MAN= tip.1 cu.1 @@ -47,6 +48,9 @@ SRCS= acu.c acutab.c cmds.c cmdtab.c cu.c hunt.c log.c partab.c \ # -- log.o depends on the Makefile because of ACULOG acutab.o log.o remote.o: Makefile +# Don't rebuild based on remote.c +remote: .MADE + .include <bsd.prog.mk> # Dirty, rotten hack. This can be removed when we are confident that there diff --git a/etc/phones b/usr.bin/tip/tip/phones similarity index 100% rename from etc/phones rename to usr.bin/tip/tip/phones diff --git a/etc/remote b/usr.bin/tip/tip/remote similarity index 100% rename from etc/remote rename to usr.bin/tip/tip/remote diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile index c1d5f4a295ff..9e95e6f72a0b 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -10,6 +10,7 @@ .PATH: ${SRCTOP}/contrib/amd/amd +CONFS= amd.map PROG= amd MAN= amd.8 SRCS= am_ops.c amd.c amfs_auto.c amfs_direct.c amfs_error.c amfs_generic.c diff --git a/etc/amd.map b/usr.sbin/amd/amd/amd.map similarity index 100% rename from etc/amd.map rename to usr.sbin/amd/amd/amd.map diff --git a/usr.sbin/bsdinstall/scripts/config b/usr.sbin/bsdinstall/scripts/config index 501430359030..d2abb5671fcb 100755 --- a/usr.sbin/bsdinstall/scripts/config +++ b/usr.sbin/bsdinstall/scripts/config @@ -35,9 +35,9 @@ rm $BSDINSTALL_TMPETC/rc.conf.* cat $BSDINSTALL_CHROOT/etc/sysctl.conf $BSDINSTALL_TMPETC/sysctl.conf.* >> $BSDINSTALL_TMPETC/sysctl.conf rm $BSDINSTALL_TMPETC/sysctl.conf.* -if [ -f $BSDINSTALL_TMPTEC/ttys.hardening ]; then - cat $BSDINSTALL_TMPTEC/ttys.hardening > $BSDINSTALL_TMPTEC/ttys - rm $BSDINSTALL_TMPTEC/ttys.hardening +if [ -f $BSDINSTALL_TMPETC/ttys.hardening ]; then + cat $BSDINSTALL_TMPETC/ttys.hardening > $BSDINSTALL_TMPETC/ttys + rm $BSDINSTALL_TMPETC/ttys.hardening fi cp $BSDINSTALL_TMPETC/* $BSDINSTALL_CHROOT/etc diff --git a/usr.sbin/bsdinstall/scripts/hardening b/usr.sbin/bsdinstall/scripts/hardening index 1b82f8121753..9fea1b6aed5d 100755 --- a/usr.sbin/bsdinstall/scripts/hardening +++ b/usr.sbin/bsdinstall/scripts/hardening @@ -30,6 +30,7 @@ echo -n > $BSDINSTALL_TMPETC/rc.conf.hardening echo -n > $BSDINSTALL_TMPETC/sysctl.conf.hardening +echo -n > $BSDINSTALL_TMPBOOT/loader.conf.hardening exec 3>&1 FEATURES=$( dialog --backtitle "FreeBSD Installer" \ @@ -46,6 +47,7 @@ FEATURES=$( dialog --backtitle "FreeBSD Installer" \ "7 disable_syslogd" "Disable opening Syslogd network socket (disables remote logging)" ${disable_syslogd:-off} \ "8 disable_sendmail" "Disable Sendmail service" ${disable_sendmail:-off} \ "9 secure_console" "Enable console password prompt" ${secure_console:-off} \ + "10 disable_ddtrace" "Disallow DTrace destructive-mode" ${disable_ddtrace:-off} \ 2>&1 1>&3 ) exec 3>&- @@ -80,5 +82,8 @@ for feature in $FEATURES; do if [ "$feature" = "secure_console" ]; then sed "s/unknown off secure/unknown off insecure/g" $BSDINSTALL_CHROOT/etc/ttys > $BSDINSTALL_TMPETC/ttys.hardening fi + if [ "$feature" = "disable_ddtrace" ]; then + echo 'security.bsd.allow_destructive_dtrace=0' >> $BSDINSTALL_TMPBOOT/loader.conf.hardening + fi done diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c index e568fe8acc13..8f09b62d10ca 100644 --- a/usr.sbin/chown/chown.c +++ b/usr.sbin/chown/chown.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <libgen.h> #include <pwd.h> #include <signal.h> +#include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -246,16 +247,13 @@ a_uid(const char *s) static uid_t id(const char *name, const char *type) { - uid_t val; + unsigned long val; char *ep; - /* - * XXX - * We know that uid_t's and gid_t's are unsigned longs. - */ errno = 0; val = strtoul(name, &ep, 10); - if (errno || *ep != '\0') + _Static_assert(UID_MAX >= GID_MAX, "UID MAX less than GID MAX"); + if (errno || *ep != '\0' || val > UID_MAX) errx(1, "%s: illegal %s name", name, type); return (val); } diff --git a/usr.sbin/cxgbetool/cxgbetool.8 b/usr.sbin/cxgbetool/cxgbetool.8 index 080fc8559b33..e6b3d2847c75 100644 --- a/usr.sbin/cxgbetool/cxgbetool.8 +++ b/usr.sbin/cxgbetool/cxgbetool.8 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Aug 8, 2018 +.Dd Sep 21, 2018 .Dt CXGBETOOL 8 .Os .Sh NAME @@ -418,9 +418,12 @@ Filter has priority over active and server regions of TCAM: 0 (default) or 1. Operational parameters that can be used with filters with .Cm action pass Ns : .It Cm queue -Rx queue index to which to deliver the packet. By default, packets that hit a -filter with action pass are delivered based on their RSS hash as usual. Use -this to steer them to a particular queue. +Context id of an ingress queue to which to deliver the packet. +The context id is available in +.Va dev.cxgbe.%d.rxq.%d.cntxt_id . +By default, packets that hit a filter with action pass are delivered based on +their RSS hash as usual. +Use this to steer them to a particular queue. .It Cm rpttid Report the filter tid instead of the RSS hash in the rx descriptor. 0 (default) or 1. @@ -447,11 +450,11 @@ eport. .It Cm vlan Insert, remove, or rewrite the VLAN tag before switching the packet out of eport. -.Cm vlan=none +.Cm none removes the tag, -.Cm vlan= Ns Ar tag +.Cm = Ns Ar tag replaces the existing tag with the one provided, and -.Cm vlan=+ Ns Ar tag +.Cm + Ns Ar tag inserts the given tag into the frame. .It Cm nat Specify the desired NAT mode. Valid NAT modes values are: diff --git a/usr.sbin/cxgbetool/cxgbetool.c b/usr.sbin/cxgbetool/cxgbetool.c index be76948d4f01..a67e863ad1da 100644 --- a/usr.sbin/cxgbetool/cxgbetool.c +++ b/usr.sbin/cxgbetool/cxgbetool.c @@ -1327,17 +1327,10 @@ set_filter(uint32_t idx, int argc, const char *argv[], int hash) t.fs.newvlan = VLAN_REWRITE; } else if (argv[start_arg + 1][0] == '+') { t.fs.newvlan = VLAN_INSERT; - } else if (isdigit(argv[start_arg + 1][0]) && - !parse_val_mask("vlan", args, &val, &mask, hash)) { - t.fs.val.vlan = val; - t.fs.mask.vlan = mask; - t.fs.val.vlan_vld = 1; - t.fs.mask.vlan_vld = 1; } else { warnx("unknown vlan parameter \"%s\"; must" " be one of \"none\", \"=<vlan>\", " - " \"+<vlan>\", or \"<vlan>\"", - argv[start_arg + 1]); + " \"+<vlan>\"", argv[start_arg + 1]); return (EINVAL); } if (t.fs.newvlan == VLAN_REWRITE || diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c index f0d699369dbd..4e456a05c25b 100644 --- a/usr.sbin/kldxref/kldxref.c +++ b/usr.sbin/kldxref/kldxref.c @@ -46,6 +46,7 @@ #include <sys/module.h> #define FREEBSD_ELF +#include <ctype.h> #include <err.h> #include <errno.h> #include <fts.h> @@ -259,6 +260,9 @@ parse_pnp_list(const char *desc, char **new_desc, pnp_list *list) strncpy(key, colon + 1, semi - colon - 1); key[semi - colon - 1] = '\0'; walker = semi + 1; + /* Fail safe if we have spaces after ; */ + while (walker < ep && isspace(*walker)) + walker++; } else { if (strlen(colon + 1) >= sizeof(key)) goto err; diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile index af2582c4bb1c..6a152c46268f 100644 --- a/usr.sbin/lpr/lpd/Makefile +++ b/usr.sbin/lpr/lpd/Makefile @@ -1,6 +1,7 @@ # From: @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +CONFS= hosts.lpd printcap PROG= lpd MAN= lpd.8 SRCS= lpd.c printjob.c recvjob.c lpdchar.c modes.c diff --git a/etc/hosts.lpd b/usr.sbin/lpr/lpd/hosts.lpd similarity index 100% rename from etc/hosts.lpd rename to usr.sbin/lpr/lpd/hosts.lpd diff --git a/etc/printcap b/usr.sbin/lpr/lpd/printcap similarity index 100% rename from etc/printcap rename to usr.sbin/lpr/lpd/printcap diff --git a/usr.sbin/pmccontrol/pmccontrol.c b/usr.sbin/pmccontrol/pmccontrol.c index b80db1f348be..147aab2d2ba1 100644 --- a/usr.sbin/pmccontrol/pmccontrol.c +++ b/usr.sbin/pmccontrol/pmccontrol.c @@ -282,6 +282,14 @@ pmcc_do_list_state(void) return 0; } +#if defined(__i386__) || defined(__amd64__) +static int +pmcc_do_list_events(void) +{ + pmc_pmu_print_counters(NULL); + return (0); +} +#else static int pmcc_do_list_events(void) { @@ -311,6 +319,7 @@ pmcc_do_list_events(void) } return 0; } +#endif static int pmcc_show_statistics(void)