summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlen Barber <gjb@FreeBSD.org>2018-10-05 17:53:47 +0000
committerGlen Barber <gjb@FreeBSD.org>2018-10-05 17:53:47 +0000
commit01d4e2149e5566e5d9394913dc9fb032da259e0b (patch)
tree4bc35787f1ac2632cbdbd5f1627bf552fb11501b
parente4456411a8c2d4a9bfbccd60f2cf914fd402f817 (diff)
parentc84dbc532904f2342f06fed592c384fd0c6436f5 (diff)
downloadsrc-test2-01d4e2149e5566e5d9394913dc9fb032da259e0b.tar.gz
src-test2-01d4e2149e5566e5d9394913dc9fb032da259e0b.zip
MFH r338661 through r339200.
Sponsored by: The FreeBSD Foundation
Notes
Notes: svn path=/projects/openssl111/; revision=339201
-rw-r--r--UPDATING23
-rw-r--r--contrib/blacklist/bin/blacklistd.825
-rw-r--r--contrib/bmake/make.17
-rw-r--r--contrib/elftoolchain/libelf/gelf_mips64el.c5
-rw-r--r--contrib/libarchive/README.md1
-rw-r--r--contrib/libarchive/libarchive/archive_acl.c6
-rw-r--r--contrib/libarchive/libarchive/archive_cryptor.c7
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_ar.c1
-rw-r--r--contrib/libarchive/libarchive/archive_read_support_format_zip.c5
-rw-r--r--contrib/libarchive/libarchive/test/test_sparse_basic.c2
-rw-r--r--contrib/libarchive/test_utils/test_main.c2
-rw-r--r--contrib/llvm/lib/CodeGen/BranchFolding.cpp3
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp36
-rw-r--r--contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--contrib/llvm/tools/lld/ELF/Config.h1
-rw-r--r--contrib/llvm/tools/lld/ELF/Driver.cpp1
-rw-r--r--contrib/llvm/tools/lld/ELF/SyntheticSections.cpp2
-rw-r--r--contrib/llvm/tools/lld/ELF/Writer.cpp2
-rw-r--r--contrib/mandoc/INSTALL (renamed from contrib/mdocml/INSTALL)20
-rw-r--r--contrib/mandoc/LICENSE (renamed from contrib/mdocml/LICENSE)6
-rw-r--r--contrib/mandoc/Makefile (renamed from contrib/mdocml/Makefile)18
-rw-r--r--contrib/mandoc/Makefile.depend (renamed from contrib/mdocml/Makefile.depend)3
-rw-r--r--contrib/mandoc/NEWS (renamed from contrib/mdocml/NEWS)79
-rw-r--r--contrib/mandoc/TODO (renamed from contrib/mdocml/TODO)109
-rw-r--r--contrib/mandoc/apropos.1 (renamed from contrib/mdocml/apropos.1)33
-rw-r--r--contrib/mandoc/att.c (renamed from contrib/mdocml/att.c)0
-rw-r--r--contrib/mandoc/catman.8 (renamed from contrib/mdocml/catman.8)0
-rw-r--r--contrib/mandoc/catman.c (renamed from contrib/mdocml/catman.c)0
-rw-r--r--contrib/mandoc/cgi.c (renamed from contrib/mdocml/cgi.c)16
-rw-r--r--contrib/mandoc/cgi.h.example (renamed from contrib/mdocml/cgi.h.example)0
-rw-r--r--contrib/mandoc/chars.c (renamed from contrib/mdocml/chars.c)170
-rw-r--r--contrib/mandoc/compat_err.c (renamed from contrib/mdocml/compat_err.c)0
-rw-r--r--contrib/mandoc/compat_fts.c (renamed from contrib/mdocml/compat_fts.c)0
-rw-r--r--contrib/mandoc/compat_fts.h (renamed from contrib/mdocml/compat_fts.h)0
-rw-r--r--contrib/mandoc/compat_getline.c (renamed from contrib/mdocml/compat_getline.c)0
-rw-r--r--contrib/mandoc/compat_getsubopt.c (renamed from contrib/mdocml/compat_getsubopt.c)0
-rw-r--r--contrib/mandoc/compat_isblank.c (renamed from contrib/mdocml/compat_isblank.c)0
-rw-r--r--contrib/mandoc/compat_mkdtemp.c (renamed from contrib/mdocml/compat_mkdtemp.c)0
-rw-r--r--contrib/mandoc/compat_ohash.c (renamed from contrib/mdocml/compat_ohash.c)0
-rw-r--r--contrib/mandoc/compat_ohash.h (renamed from contrib/mdocml/compat_ohash.h)0
-rw-r--r--contrib/mandoc/compat_progname.c (renamed from contrib/mdocml/compat_progname.c)0
-rw-r--r--contrib/mandoc/compat_reallocarray.c (renamed from contrib/mdocml/compat_reallocarray.c)0
-rw-r--r--contrib/mandoc/compat_recallocarray.c (renamed from contrib/mdocml/compat_recallocarray.c)0
-rw-r--r--contrib/mandoc/compat_strcasestr.c (renamed from contrib/mdocml/compat_strcasestr.c)0
-rw-r--r--contrib/mandoc/compat_stringlist.c (renamed from contrib/mdocml/compat_stringlist.c)0
-rw-r--r--contrib/mandoc/compat_stringlist.h (renamed from contrib/mdocml/compat_stringlist.h)0
-rw-r--r--contrib/mandoc/compat_strlcat.c (renamed from contrib/mdocml/compat_strlcat.c)0
-rw-r--r--contrib/mandoc/compat_strlcpy.c (renamed from contrib/mdocml/compat_strlcpy.c)0
-rw-r--r--contrib/mandoc/compat_strndup.c50
-rw-r--r--contrib/mandoc/compat_strsep.c (renamed from contrib/mdocml/compat_strsep.c)0
-rw-r--r--contrib/mandoc/compat_strtonum.c (renamed from contrib/mdocml/compat_strtonum.c)0
-rw-r--r--contrib/mandoc/compat_vasprintf.c (renamed from contrib/mdocml/compat_vasprintf.c)0
-rw-r--r--contrib/mandoc/config.h (renamed from contrib/mdocml/config.h)2
-rwxr-xr-xcontrib/mandoc/configure (renamed from contrib/mdocml/configure)117
-rw-r--r--contrib/mandoc/configure.local.example (renamed from contrib/mdocml/configure.local.example)44
-rw-r--r--contrib/mandoc/dba.c (renamed from contrib/mdocml/dba.c)0
-rw-r--r--contrib/mandoc/dba.h (renamed from contrib/mdocml/dba.h)0
-rw-r--r--contrib/mandoc/dba_array.c (renamed from contrib/mdocml/dba_array.c)0
-rw-r--r--contrib/mandoc/dba_array.h (renamed from contrib/mdocml/dba_array.h)0
-rw-r--r--contrib/mandoc/dba_read.c (renamed from contrib/mdocml/dba_read.c)0
-rw-r--r--contrib/mandoc/dba_write.c (renamed from contrib/mdocml/dba_write.c)0
-rw-r--r--contrib/mandoc/dba_write.h (renamed from contrib/mdocml/dba_write.h)0
-rw-r--r--contrib/mandoc/dbm.c (renamed from contrib/mdocml/dbm.c)0
-rw-r--r--contrib/mandoc/dbm.h (renamed from contrib/mdocml/dbm.h)0
-rw-r--r--contrib/mandoc/dbm_map.c (renamed from contrib/mdocml/dbm_map.c)0
-rw-r--r--contrib/mandoc/dbm_map.h (renamed from contrib/mdocml/dbm_map.h)0
-rw-r--r--contrib/mandoc/demandoc.1 (renamed from contrib/mdocml/demandoc.1)0
-rw-r--r--contrib/mandoc/demandoc.c (renamed from contrib/mdocml/demandoc.c)0
-rw-r--r--contrib/mandoc/eqn.7 (renamed from contrib/mdocml/eqn.7)6
-rw-r--r--contrib/mandoc/eqn.c (renamed from contrib/mdocml/eqn.c)0
-rw-r--r--contrib/mandoc/eqn_html.c (renamed from contrib/mdocml/eqn_html.c)0
-rw-r--r--contrib/mandoc/eqn_term.c (renamed from contrib/mdocml/eqn_term.c)28
-rw-r--r--contrib/mandoc/gmdiff (renamed from contrib/mdocml/gmdiff)19
-rw-r--r--contrib/mandoc/html.c (renamed from contrib/mdocml/html.c)331
-rw-r--r--contrib/mandoc/html.h (renamed from contrib/mdocml/html.h)11
-rw-r--r--contrib/mandoc/lib.c (renamed from contrib/mdocml/lib.c)0
-rw-r--r--contrib/mandoc/lib.in (renamed from contrib/mdocml/lib.in)5
-rw-r--r--contrib/mandoc/libman.h (renamed from contrib/mdocml/libman.h)0
-rw-r--r--contrib/mandoc/libmandoc.h (renamed from contrib/mdocml/libmandoc.h)4
-rw-r--r--contrib/mandoc/libmdoc.h (renamed from contrib/mdocml/libmdoc.h)0
-rw-r--r--contrib/mandoc/libroff.h (renamed from contrib/mdocml/libroff.h)0
-rw-r--r--contrib/mandoc/main.c (renamed from contrib/mdocml/main.c)98
-rw-r--r--contrib/mandoc/main.h (renamed from contrib/mdocml/main.h)0
-rw-r--r--contrib/mandoc/makewhatis.8 (renamed from contrib/mdocml/makewhatis.8)0
-rw-r--r--contrib/mandoc/man-cgi.css (renamed from contrib/mdocml/man-cgi.css)0
-rw-r--r--contrib/mandoc/man.1 (renamed from contrib/mdocml/man.1)56
-rw-r--r--contrib/mandoc/man.7 (renamed from contrib/mdocml/man.7)21
-rw-r--r--contrib/mandoc/man.c (renamed from contrib/mdocml/man.c)0
-rw-r--r--contrib/mandoc/man.cgi.3 (renamed from contrib/mdocml/man.cgi.3)0
-rw-r--r--contrib/mandoc/man.cgi.8 (renamed from contrib/mdocml/man.cgi.8)13
-rw-r--r--contrib/mandoc/man.conf.5 (renamed from contrib/mdocml/man.conf.5)12
-rw-r--r--contrib/mandoc/man.h (renamed from contrib/mdocml/man.h)0
-rw-r--r--contrib/mandoc/man.options.1 (renamed from contrib/mdocml/man.options.1)0
-rw-r--r--contrib/mandoc/man_html.c (renamed from contrib/mdocml/man_html.c)94
-rw-r--r--contrib/mandoc/man_macro.c (renamed from contrib/mdocml/man_macro.c)0
-rw-r--r--contrib/mandoc/man_term.c (renamed from contrib/mdocml/man_term.c)25
-rw-r--r--contrib/mandoc/man_validate.c (renamed from contrib/mdocml/man_validate.c)6
-rw-r--r--contrib/mandoc/manconf.h (renamed from contrib/mdocml/manconf.h)0
-rw-r--r--contrib/mandoc/mandoc.1 (renamed from contrib/mdocml/mandoc.1)246
-rw-r--r--contrib/mandoc/mandoc.3 (renamed from contrib/mdocml/mandoc.3)0
-rw-r--r--contrib/mandoc/mandoc.c (renamed from contrib/mdocml/mandoc.c)7
-rw-r--r--contrib/mandoc/mandoc.css253
-rw-r--r--contrib/mandoc/mandoc.db.5 (renamed from contrib/mdocml/mandoc.db.5)0
-rw-r--r--contrib/mandoc/mandoc.h (renamed from contrib/mdocml/mandoc.h)8
-rw-r--r--contrib/mandoc/mandoc_aux.c (renamed from contrib/mdocml/mandoc_aux.c)8
-rw-r--r--contrib/mandoc/mandoc_aux.h (renamed from contrib/mdocml/mandoc_aux.h)0
-rw-r--r--contrib/mandoc/mandoc_char.7 (renamed from contrib/mdocml/mandoc_char.7)136
-rw-r--r--contrib/mandoc/mandoc_escape.3 (renamed from contrib/mdocml/mandoc_escape.3)0
-rw-r--r--contrib/mandoc/mandoc_headers.3 (renamed from contrib/mdocml/mandoc_headers.3)0
-rw-r--r--contrib/mandoc/mandoc_html.3 (renamed from contrib/mdocml/mandoc_html.3)100
-rw-r--r--contrib/mandoc/mandoc_malloc.3 (renamed from contrib/mdocml/mandoc_malloc.3)0
-rw-r--r--contrib/mandoc/mandoc_ohash.c (renamed from contrib/mdocml/mandoc_ohash.c)0
-rw-r--r--contrib/mandoc/mandoc_ohash.h (renamed from contrib/mdocml/mandoc_ohash.h)0
-rw-r--r--contrib/mandoc/mandoc_xr.c (renamed from contrib/mdocml/mandoc_xr.c)0
-rw-r--r--contrib/mandoc/mandoc_xr.h (renamed from contrib/mdocml/mandoc_xr.h)0
-rw-r--r--contrib/mandoc/mandocd.8 (renamed from contrib/mdocml/mandocd.8)0
-rw-r--r--contrib/mandoc/mandocd.c (renamed from contrib/mdocml/mandocd.c)0
-rw-r--r--contrib/mandoc/mandocdb.c (renamed from contrib/mdocml/mandocdb.c)158
-rw-r--r--contrib/mandoc/manpath.c (renamed from contrib/mdocml/manpath.c)0
-rw-r--r--contrib/mandoc/manpath.h (renamed from contrib/mdocml/manpath.h)0
-rw-r--r--contrib/mandoc/mansearch.3 (renamed from contrib/mdocml/mansearch.3)0
-rw-r--r--contrib/mandoc/mansearch.c (renamed from contrib/mdocml/mansearch.c)12
-rw-r--r--contrib/mandoc/mansearch.h (renamed from contrib/mdocml/mansearch.h)0
-rw-r--r--contrib/mandoc/mchars_alloc.3 (renamed from contrib/mdocml/mchars_alloc.3)0
-rw-r--r--contrib/mandoc/mdoc.7 (renamed from contrib/mdocml/mdoc.7)77
-rw-r--r--contrib/mandoc/mdoc.c (renamed from contrib/mdocml/mdoc.c)6
-rw-r--r--contrib/mandoc/mdoc.h (renamed from contrib/mdocml/mdoc.h)0
-rw-r--r--contrib/mandoc/mdoc_argv.c (renamed from contrib/mdocml/mdoc_argv.c)0
-rw-r--r--contrib/mandoc/mdoc_html.c (renamed from contrib/mdocml/mdoc_html.c)248
-rw-r--r--contrib/mandoc/mdoc_macro.c (renamed from contrib/mdocml/mdoc_macro.c)0
-rw-r--r--contrib/mandoc/mdoc_man.c (renamed from contrib/mdocml/mdoc_man.c)29
-rw-r--r--contrib/mandoc/mdoc_markdown.c (renamed from contrib/mdocml/mdoc_markdown.c)4
-rw-r--r--contrib/mandoc/mdoc_state.c (renamed from contrib/mdocml/mdoc_state.c)25
-rw-r--r--contrib/mandoc/mdoc_term.c (renamed from contrib/mdocml/mdoc_term.c)29
-rw-r--r--contrib/mandoc/mdoc_validate.c (renamed from contrib/mdocml/mdoc_validate.c)108
-rw-r--r--contrib/mandoc/msec.c (renamed from contrib/mdocml/msec.c)0
-rw-r--r--contrib/mandoc/msec.in (renamed from contrib/mdocml/msec.in)0
-rw-r--r--contrib/mandoc/out.c (renamed from contrib/mdocml/out.c)0
-rw-r--r--contrib/mandoc/out.h (renamed from contrib/mdocml/out.h)7
-rw-r--r--contrib/mandoc/preconv.c (renamed from contrib/mdocml/preconv.c)0
-rw-r--r--contrib/mandoc/predefs.in (renamed from contrib/mdocml/predefs.in)0
-rw-r--r--contrib/mandoc/read.c (renamed from contrib/mdocml/read.c)45
-rw-r--r--contrib/mandoc/roff.7 (renamed from contrib/mdocml/roff.7)26
-rw-r--r--contrib/mandoc/roff.c (renamed from contrib/mdocml/roff.c)246
-rw-r--r--contrib/mandoc/roff.h (renamed from contrib/mdocml/roff.h)3
-rw-r--r--contrib/mandoc/roff_html.c (renamed from contrib/mdocml/roff_html.c)16
-rw-r--r--contrib/mandoc/roff_int.h (renamed from contrib/mdocml/roff_int.h)0
-rw-r--r--contrib/mandoc/roff_term.c (renamed from contrib/mdocml/roff_term.c)0
-rw-r--r--contrib/mandoc/roff_validate.c (renamed from contrib/mdocml/roff_validate.c)0
-rw-r--r--contrib/mandoc/soelim.1 (renamed from contrib/mdocml/soelim.1)0
-rw-r--r--contrib/mandoc/soelim.c (renamed from contrib/mdocml/soelim.c)0
-rw-r--r--contrib/mandoc/st.c (renamed from contrib/mdocml/st.c)0
-rw-r--r--contrib/mandoc/st.in (renamed from contrib/mdocml/st.in)34
-rw-r--r--contrib/mandoc/tag.c (renamed from contrib/mdocml/tag.c)5
-rw-r--r--contrib/mandoc/tag.h (renamed from contrib/mdocml/tag.h)0
-rw-r--r--contrib/mandoc/tbl.3 (renamed from contrib/mdocml/tbl.3)0
-rw-r--r--contrib/mandoc/tbl.7 (renamed from contrib/mdocml/tbl.7)8
-rw-r--r--contrib/mandoc/tbl.c (renamed from contrib/mdocml/tbl.c)0
-rw-r--r--contrib/mandoc/tbl_data.c (renamed from contrib/mdocml/tbl_data.c)0
-rw-r--r--contrib/mandoc/tbl_html.c (renamed from contrib/mdocml/tbl_html.c)11
-rw-r--r--contrib/mandoc/tbl_layout.c (renamed from contrib/mdocml/tbl_layout.c)0
-rw-r--r--contrib/mandoc/tbl_opts.c (renamed from contrib/mdocml/tbl_opts.c)0
-rw-r--r--contrib/mandoc/tbl_term.c (renamed from contrib/mdocml/tbl_term.c)0
-rw-r--r--contrib/mandoc/term.c (renamed from contrib/mdocml/term.c)0
-rw-r--r--contrib/mandoc/term.h (renamed from contrib/mdocml/term.h)0
-rw-r--r--contrib/mandoc/term_ascii.c (renamed from contrib/mdocml/term_ascii.c)34
-rw-r--r--contrib/mandoc/term_ps.c (renamed from contrib/mdocml/term_ps.c)120
-rw-r--r--contrib/mandoc/term_tab.c (renamed from contrib/mdocml/term_tab.c)0
-rw-r--r--contrib/mandoc/test-EFTYPE.c (renamed from contrib/mdocml/test-EFTYPE.c)0
-rw-r--r--contrib/mandoc/test-O_DIRECTORY.c (renamed from contrib/mdocml/test-O_DIRECTORY.c)0
-rw-r--r--contrib/mandoc/test-PATH_MAX.c (renamed from contrib/mdocml/test-PATH_MAX.c)0
-rw-r--r--contrib/mandoc/test-be32toh.c (renamed from contrib/mdocml/test-be32toh.c)0
-rw-r--r--contrib/mandoc/test-cmsg.c (renamed from contrib/mdocml/test-cmsg.c)0
-rw-r--r--contrib/mandoc/test-dirent-namlen.c (renamed from contrib/mdocml/test-dirent-namlen.c)0
-rw-r--r--contrib/mandoc/test-err.c (renamed from contrib/mdocml/test-err.c)0
-rw-r--r--contrib/mandoc/test-fgetln.c (renamed from contrib/mdocml/test-fgetln.c)0
-rw-r--r--contrib/mandoc/test-fts.c (renamed from contrib/mdocml/test-fts.c)0
-rw-r--r--contrib/mandoc/test-getline.c (renamed from contrib/mdocml/test-getline.c)0
-rw-r--r--contrib/mandoc/test-getsubopt.c (renamed from contrib/mdocml/test-getsubopt.c)0
-rw-r--r--contrib/mandoc/test-isblank.c (renamed from contrib/mdocml/test-isblank.c)0
-rw-r--r--contrib/mandoc/test-mkdtemp.c (renamed from contrib/mdocml/test-mkdtemp.c)0
-rw-r--r--contrib/mandoc/test-nanosleep.c (renamed from contrib/mdocml/test-nanosleep.c)0
-rw-r--r--contrib/mandoc/test-noop.c5
-rw-r--r--contrib/mandoc/test-ntohl.c (renamed from contrib/mdocml/test-ntohl.c)0
-rw-r--r--contrib/mandoc/test-ohash.c (renamed from contrib/mdocml/test-ohash.c)0
-rw-r--r--contrib/mandoc/test-pledge.c (renamed from contrib/mdocml/test-pledge.c)0
-rw-r--r--contrib/mandoc/test-progname.c (renamed from contrib/mdocml/test-progname.c)0
-rw-r--r--contrib/mandoc/test-reallocarray.c (renamed from contrib/mdocml/test-reallocarray.c)0
-rw-r--r--contrib/mandoc/test-recallocarray.c (renamed from contrib/mdocml/test-recallocarray.c)0
-rw-r--r--contrib/mandoc/test-recvmsg.c (renamed from contrib/mdocml/test-recvmsg.c)0
-rw-r--r--contrib/mandoc/test-rewb-bsd.c (renamed from contrib/mdocml/test-rewb-bsd.c)0
-rw-r--r--contrib/mandoc/test-rewb-sysv.c (renamed from contrib/mdocml/test-rewb-sysv.c)0
-rw-r--r--contrib/mandoc/test-sandbox_init.c (renamed from contrib/mdocml/test-sandbox_init.c)0
-rw-r--r--contrib/mandoc/test-strcasestr.c (renamed from contrib/mdocml/test-strcasestr.c)0
-rw-r--r--contrib/mandoc/test-stringlist.c (renamed from contrib/mdocml/test-stringlist.c)0
-rw-r--r--contrib/mandoc/test-strlcat.c (renamed from contrib/mdocml/test-strlcat.c)0
-rw-r--r--contrib/mandoc/test-strlcpy.c (renamed from contrib/mdocml/test-strlcpy.c)0
-rw-r--r--contrib/mandoc/test-strndup.c10
-rw-r--r--contrib/mandoc/test-strptime.c (renamed from contrib/mdocml/test-strptime.c)0
-rw-r--r--contrib/mandoc/test-strsep.c (renamed from contrib/mdocml/test-strsep.c)0
-rw-r--r--contrib/mandoc/test-strtonum.c (renamed from contrib/mdocml/test-strtonum.c)0
-rw-r--r--contrib/mandoc/test-vasprintf.c (renamed from contrib/mdocml/test-vasprintf.c)0
-rw-r--r--contrib/mandoc/test-wchar.c (renamed from contrib/mdocml/test-wchar.c)0
-rw-r--r--contrib/mandoc/tree.c (renamed from contrib/mdocml/tree.c)12
-rw-r--r--contrib/mdocml/mandoc.css203
-rw-r--r--contrib/openbsm/bin/auditdistd/auditdistd.h15
-rw-r--r--contrib/openbsm/bin/auditdistd/receiver.c2
-rw-r--r--contrib/openbsm/bin/auditdistd/sender.c24
-rw-r--r--contrib/openbsm/bin/auditdistd/trail.c33
-rw-r--r--etc/Makefile51
-rw-r--r--etc/dhclient.conf8
-rw-r--r--gnu/usr.bin/binutils/as/config.h2
-rw-r--r--gnu/usr.bin/binutils/ld/config.h2
-rw-r--r--gnu/usr.bin/binutils/libbinutils/config.h2
-rw-r--r--gnu/usr.bin/binutils/libiberty/config.h2
-rw-r--r--gnu/usr.bin/cc/libiberty/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/amd64/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/arm/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/i386/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/mips/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/powerpc/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/powerpc64/config.h2
-rw-r--r--gnu/usr.bin/gdb/arch/sparc64/config.h2
-rw-r--r--include/limits.h2
-rw-r--r--include/time.h4
-rw-r--r--lib/Makefile5
-rw-r--r--lib/clang/freebsd_cc_version.h2
-rw-r--r--lib/csu/arm/crt1.c4
-rw-r--r--lib/csu/common/crtbrand.c3
-rw-r--r--lib/csu/common/ignore_init.c4
-rw-r--r--lib/csu/common/notes.h4
-rw-r--r--lib/lib80211/Makefile1
-rw-r--r--lib/lib80211/regdomain.xml (renamed from etc/regdomain.xml)0
-rw-r--r--lib/libalias/libalias/Makefile1
-rw-r--r--lib/libalias/libalias/libalias.conf (renamed from etc/libalias.conf)0
-rw-r--r--lib/libbe/be.c20
-rw-r--r--lib/libc/Makefile6
-rw-r--r--lib/libc/amd64/string/bcmp.S130
-rw-r--r--lib/libc/amd64/string/bcopy.S8
-rw-r--r--lib/libc/amd64/string/bzero.S45
-rw-r--r--lib/libc/amd64/string/memcmp.S143
-rw-r--r--lib/libc/amd64/string/memset.S112
-rw-r--r--lib/libc/i386/string/bcopy.S13
-rw-r--r--lib/libc/net/Makefile.inc6
-rw-r--r--lib/libc/net/hosts (renamed from etc/hosts)0
-rw-r--r--lib/libc/net/hosts.equiv (renamed from etc/hosts.equiv)0
-rw-r--r--lib/libc/net/networks (renamed from etc/networks)0
-rw-r--r--lib/libc/net/nsswitch.conf (renamed from etc/nsswitch.conf)0
-rw-r--r--lib/libc/net/protocols (renamed from etc/protocols)0
-rw-r--r--lib/libc/posix1e/Makefile.inc1
-rw-r--r--lib/libc/posix1e/mac.conf (renamed from etc/mac.conf)0
-rw-r--r--lib/libc/rpc/Makefile.inc1
-rw-r--r--lib/libc/rpc/netconfig (renamed from etc/netconfig)0
-rw-r--r--lib/libc/rpc/rpc (renamed from etc/rpc)0
-rw-r--r--lib/libopie/Makefile3
-rw-r--r--lib/libopie/opieaccess (renamed from etc/opieaccess)0
-rw-r--r--lib/libpmc/Makefile2
-rw-r--r--lib/libpmc/libpmc_pmu_util.c1
-rw-r--r--lib/libsmb/Makefile2
-rw-r--r--lib/libsmb/nsmb.conf (renamed from etc/nsmb.conf)0
-rw-r--r--lib/libusb/libusb10.h34
-rw-r--r--lib/libusb/libusb10_io.c27
-rw-r--r--lib/libwrap/Makefile1
-rw-r--r--lib/libwrap/hosts.allow (renamed from etc/hosts.allow)0
-rw-r--r--libexec/rtld-elf/Makefile1
-rw-r--r--libexec/rtld-elf/aarch64/reloc.c132
-rw-r--r--libexec/rtld-elf/aarch64/rtld_machdep.h10
-rw-r--r--libexec/rtld-elf/libmap.c14
-rw-r--r--libexec/rtld-elf/libmap.conf (renamed from etc/libmap.conf)0
-rw-r--r--libexec/rtld-elf/powerpc/reloc.c2
-rw-r--r--libexec/rtld-elf/rtld.c80
-rw-r--r--release/Makefile10
-rwxr-xr-xrelease/scripts/pkg-stage.sh2
-rw-r--r--sbin/bsdlabel/Makefile1
-rw-r--r--sbin/bsdlabel/disktab (renamed from etc/disktab)0
-rw-r--r--sbin/devd/devd.cc6
-rw-r--r--sbin/devd/devd.hh2
-rw-r--r--sbin/dhclient/Makefile1
-rw-r--r--sbin/dhclient/dhclient.conf45
-rw-r--r--sbin/fsck_ffs/pass5.c2
-rw-r--r--sbin/geom/core/geom.86
-rw-r--r--sbin/geom/core/geom.c140
-rw-r--r--sbin/ifconfig/ifipsec.c1
-rwxr-xr-xsbin/init/rc.d/ldconfig6
-rw-r--r--sbin/ipfw/ipfw.8429
-rw-r--r--sbin/ipfw/ipfw2.c12
-rw-r--r--sbin/reboot/reboot.c2
-rw-r--r--sbin/sysctl/sysctl.84
-rw-r--r--secure/usr.bin/openssl/Makefile2
-rw-r--r--share/man/man4/Makefile1
-rw-r--r--share/man/man4/bnxt.44
-rw-r--r--share/man/man4/cxgbe.410
-rw-r--r--share/man/man4/ddb.43
-rw-r--r--share/man/man4/em.43
-rw-r--r--share/man/man4/iflib.4204
-rw-r--r--share/man/man5/make.conf.53
-rw-r--r--share/man/man5/msdosfs.519
-rw-r--r--share/man/man5/src.conf.510
-rw-r--r--share/man/man9/MODULE_PNP_INFO.944
-rw-r--r--share/man/man9/iflib.93
-rw-r--r--share/mk/bsd.dirs.mk31
-rw-r--r--share/mk/bsd.progs.mk2
-rw-r--r--share/mk/bsd.subdir.mk3
-rw-r--r--share/mk/bsd.sys.mk4
-rw-r--r--share/mk/src.opts.mk13
-rw-r--r--stand/lua/menu.lua30
-rw-r--r--stand/lua/password.lua19
-rw-r--r--sys/amd64/amd64/copyout.c37
-rw-r--r--sys/amd64/amd64/machdep.c27
-rw-r--r--sys/amd64/amd64/pmap.c748
-rw-r--r--sys/amd64/amd64/support.S530
-rw-r--r--sys/amd64/amd64/trap.c25
-rw-r--r--sys/amd64/include/pmap.h4
-rw-r--r--sys/amd64/include/vmm.h1
-rw-r--r--sys/amd64/vmm/intel/vmx.c16
-rw-r--r--sys/amd64/vmm/vmm.c1
-rw-r--r--sys/arm/conf/std.armv62
-rw-r--r--sys/arm/conf/std.armv72
-rw-r--r--sys/arm64/arm64/elf_machdep.c10
-rw-r--r--sys/arm64/arm64/identcpu.c237
-rw-r--r--sys/arm64/arm64/machdep.c3
-rw-r--r--sys/arm64/arm64/undefined.c130
-rw-r--r--sys/arm64/conf/GENERIC-MMCCAM1
-rw-r--r--sys/arm64/include/ifunc.h51
-rw-r--r--sys/arm64/include/pte.h2
-rw-r--r--sys/arm64/include/undefined.h37
-rw-r--r--sys/cam/scsi/scsi_cd.c42
-rw-r--r--sys/cam/scsi/scsi_da.c3
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c7
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c5
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c21
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c9
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c70
-rw-r--r--sys/compat/freebsd32/freebsd32_ioctl.c140
-rw-r--r--sys/compat/freebsd32/freebsd32_ioctl.h48
-rw-r--r--sys/compat/freebsd32/freebsd32_syscall.h20
-rw-r--r--sys/compat/freebsd32/freebsd32_syscalls.c40
-rw-r--r--sys/compat/freebsd32/freebsd32_sysent.c40
-rw-r--r--sys/compat/freebsd32/syscalls.master40
-rw-r--r--sys/conf/files1
-rw-r--r--sys/conf/files.arm1
-rw-r--r--sys/conf/files.arm641
-rw-r--r--sys/conf/files.i3861
-rw-r--r--sys/conf/files.mips1
-rw-r--r--sys/conf/files.powerpc1
-rw-r--r--sys/conf/files.riscv1
-rw-r--r--sys/conf/files.sparc641
-rw-r--r--sys/conf/kern.pre.mk8
-rw-r--r--sys/conf/newvers.sh6
-rw-r--r--sys/crypto/ccp/ccp.c2
-rw-r--r--sys/dev/aac/aac_pci.c2
-rw-r--r--sys/dev/aacraid/aacraid_pci.c2
-rw-r--r--sys/dev/adlink/adlink.c2
-rw-r--r--sys/dev/ae/if_ae.c2
-rw-r--r--sys/dev/age/if_age.c2
-rw-r--r--sys/dev/ahci/ahci_pci.c2
-rw-r--r--sys/dev/alc/if_alc.c2
-rw-r--r--sys/dev/ale/if_ale.c2
-rw-r--r--sys/dev/amdsmn/amdsmn.c2
-rw-r--r--sys/dev/amdtemp/amdtemp.c2
-rw-r--r--sys/dev/amr/amr_pci.c2
-rw-r--r--sys/dev/an/if_an_pci.c2
-rw-r--r--sys/dev/bce/if_bce.c2
-rw-r--r--sys/dev/bfe/if_bfe.c2
-rw-r--r--sys/dev/bge/if_bge.c2
-rw-r--r--sys/dev/bwi/if_bwi_pci.c2
-rw-r--r--sys/dev/bwn/if_bwn_pci.c4
-rw-r--r--sys/dev/bxe/bxe.c18
-rw-r--r--sys/dev/cas/if_cas.c2
-rw-r--r--sys/dev/ciss/ciss.c2
-rw-r--r--sys/dev/cpuctl/cpuctl.c2
-rw-r--r--sys/dev/cxgb/cxgb_main.c49
-rw-r--r--sys/dev/cxgbe/adapter.h47
-rw-r--r--sys/dev/cxgbe/common/common.h44
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c453
-rw-r--r--sys/dev/cxgbe/firmware/t4fw_cfg.txt3
-rw-r--r--sys/dev/cxgbe/firmware/t5fw_cfg.txt3
-rw-r--r--sys/dev/cxgbe/firmware/t6fw_cfg.txt3
-rw-r--r--sys/dev/cxgbe/osdep.h1
-rw-r--r--sys/dev/cxgbe/t4_filter.c61
-rw-r--r--sys/dev/cxgbe/t4_l2t.c91
-rw-r--r--sys/dev/cxgbe/t4_l2t.h3
-rw-r--r--sys/dev/cxgbe/t4_main.c534
-rw-r--r--sys/dev/cxgbe/tom/t4_cpl_io.c2
-rw-r--r--sys/dev/dc/if_dc.c2
-rw-r--r--sys/dev/drm2/drm_os_freebsd.c4
-rw-r--r--sys/dev/drm2/i915/i915_drv.c2
-rw-r--r--sys/dev/drm2/i915/intel_ringbuffer.c9
-rw-r--r--sys/dev/drm2/radeon/radeon_drv.c2
-rw-r--r--sys/dev/e1000/if_em.c3
-rw-r--r--sys/dev/ed/if_ed_pci.c2
-rw-r--r--sys/dev/ena/ena.c2
-rw-r--r--sys/dev/et/if_et.c2
-rw-r--r--sys/dev/ffec/if_ffec.c3
-rw-r--r--sys/dev/fxp/if_fxp.c2
-rw-r--r--sys/dev/gem/if_gem_pci.c2
-rw-r--r--sys/dev/hwpmc/hwpmc_logging.c15
-rw-r--r--sys/dev/hwpmc/hwpmc_mod.c247
-rw-r--r--sys/dev/ichiic/ig4_iic.c4
-rw-r--r--sys/dev/ichiic/ig4_pci.c4
-rw-r--r--sys/dev/ida/ida_pci.c2
-rw-r--r--sys/dev/intpm/intpm.c2
-rw-r--r--sys/dev/ioat/ioat.c2
-rw-r--r--sys/dev/ipw/if_ipw.c2
-rw-r--r--sys/dev/iwm/if_iwm.c2
-rw-r--r--sys/dev/iwn/if_iwn.c3
-rw-r--r--sys/dev/ixgbe/if_ix.c2
-rw-r--r--sys/dev/ixgbe/if_ixv.c2
-rw-r--r--sys/dev/ixl/if_ixl.c1
-rw-r--r--sys/dev/ixl/if_ixlv.c4
-rw-r--r--sys/dev/mfi/mfi_pci.c7
-rw-r--r--sys/dev/mpr/mpr_pci.c11
-rw-r--r--sys/dev/mps/mps_pci.c8
-rw-r--r--sys/dev/mvs/mvs_pci.c2
-rw-r--r--sys/dev/my/if_my.c2
-rw-r--r--sys/dev/ncr/ncr.c2
-rw-r--r--sys/dev/ntb/ntb_hw/ntb_hw_intel.c2
-rw-r--r--sys/dev/oce/oce_if.c15
-rw-r--r--sys/dev/ofw/ofw_bus_subr.h2
-rw-r--r--sys/dev/pccard/pccardvar.h2
-rw-r--r--sys/dev/pccbb/pccbb_pci.c2
-rw-r--r--sys/dev/pci/pci_user.c172
-rw-r--r--sys/dev/pci/pcireg.h3
-rw-r--r--sys/dev/pci/pcivar.h2
-rw-r--r--sys/dev/pcn/if_pcn.c2
-rw-r--r--sys/dev/puc/puc_pci.c2
-rw-r--r--sys/dev/ral/if_ral_pci.c2
-rw-r--r--sys/dev/rl/if_rl.c2
-rw-r--r--sys/dev/sdhci/sdhci_acpi.c3
-rw-r--r--sys/dev/spibus/spi.h2
-rw-r--r--sys/dev/uart/uart_bus_pccard.c2
-rw-r--r--sys/dev/uart/uart_bus_pci.c1
-rw-r--r--sys/dev/usb/net/if_ure.c1
-rw-r--r--sys/dev/usb/usbdi.h6
-rw-r--r--sys/dev/xl/if_xl.c2
-rw-r--r--sys/geom/raid/tr_raid0.c2
-rw-r--r--sys/i386/i386/npx.c98
-rw-r--r--sys/i386/i386/pmap.c108
-rw-r--r--sys/i386/i386/trap.c6
-rw-r--r--sys/i386/i386/vm_machdep.c2
-rw-r--r--sys/i386/include/pmap.h4
-rw-r--r--sys/isa/isavar.h2
-rw-r--r--sys/kern/init_sysent.c40
-rw-r--r--sys/kern/kern_context.c2
-rw-r--r--sys/kern/kern_cpuset.c33
-rw-r--r--sys/kern/kern_descrip.c5
-rw-r--r--sys/kern/kern_malloc.c35
-rw-r--r--sys/kern/kern_resource.c3
-rw-r--r--sys/kern/link_elf.c2
-rw-r--r--sys/kern/subr_vmem.c3
-rw-r--r--sys/kern/sys_generic.c5
-rw-r--r--sys/kern/syscalls.c40
-rw-r--r--sys/kern/syscalls.master40
-rw-r--r--sys/kern/uipc_socket.c28
-rw-r--r--sys/kern/vfs_lookup.c13
-rw-r--r--sys/kern/vfs_syscalls.c3
-rw-r--r--sys/net/if.c3
-rw-r--r--sys/net/if_gre.c2
-rw-r--r--sys/net/if_tap.c15
-rw-r--r--sys/net/if_tun.c23
-rw-r--r--sys/net/if_var.h3
-rw-r--r--sys/net/if_vlan.c219
-rw-r--r--sys/net/iflib.c39
-rw-r--r--sys/net/iflib.h2
-rw-r--r--sys/netinet/in_pcb.h2
-rw-r--r--sys/netinet/ip_encap.h3
-rw-r--r--sys/netinet/ip_output.c5
-rw-r--r--sys/netinet/sctp_asconf.c1
-rw-r--r--sys/netinet/sctp_auth.c36
-rw-r--r--sys/netinet/sctp_auth.h3
-rw-r--r--sys/netinet/sctp_input.c5
-rw-r--r--sys/netinet/sctp_output.c76
-rw-r--r--sys/netinet/sctputil.c16
-rw-r--r--sys/netinet/siftr.c2
-rw-r--r--sys/netinet/tcp_hpts.c4
-rw-r--r--sys/netinet/tcp_input.c10
-rw-r--r--sys/netinet/tcp_syncache.c10
-rw-r--r--sys/netinet/udp_usrreq.c14
-rw-r--r--sys/netinet6/icmp6.c4
-rw-r--r--sys/netinet6/in6_pcb.c4
-rw-r--r--sys/netinet6/udp6_usrreq.c64
-rw-r--r--sys/netipsec/key.c81
-rw-r--r--sys/netipsec/key.h3
-rw-r--r--sys/netipsec/subr_ipsec.c86
-rw-r--r--sys/netipsec/xform.h7
-rw-r--r--sys/netpfil/pf/pf.c34
-rw-r--r--sys/opencrypto/cryptosoft.c8
-rw-r--r--sys/opencrypto/cryptosoft.h1
-rw-r--r--sys/powerpc/conf/GENERIC641
-rw-r--r--sys/powerpc/ofw/ofw_machdep.c37
-rw-r--r--sys/riscv/include/fpe.h1
-rw-r--r--sys/riscv/riscv/machdep.c10
-rw-r--r--sys/riscv/riscv/pmap.c18
-rw-r--r--sys/riscv/riscv/swtch.S53
-rw-r--r--sys/riscv/riscv/trap.c7
-rw-r--r--sys/security/audit/audit.c66
-rw-r--r--sys/security/audit/audit.h23
-rw-r--r--sys/security/audit/audit_dtrace.c16
-rw-r--r--sys/security/audit/audit_private.h9
-rw-r--r--sys/security/audit/audit_syscalls.c25
-rw-r--r--sys/security/audit/audit_worker.c8
-rw-r--r--sys/sys/_domainset.h2
-rw-r--r--sys/sys/malloc.h2
-rw-r--r--sys/sys/module.h4
-rw-r--r--sys/sys/pmc.h18
-rw-r--r--sys/sys/pmckern.h10
-rw-r--r--sys/sys/racct.h12
-rw-r--r--sys/sys/resourcevar.h4
-rw-r--r--sys/sys/signalvar.h4
-rw-r--r--sys/sys/syscall.h20
-rw-r--r--sys/sys/user.h171
-rw-r--r--sys/sys/vmmeter.h28
-rw-r--r--sys/ufs/ffs/ffs_softdep.c49
-rw-r--r--sys/ufs/ufs/ufs_quota.c33
-rw-r--r--sys/ufs/ufs/ufs_vfsops.c11
-rw-r--r--sys/ufs/ufs/ufs_vnops.c35
-rw-r--r--sys/vm/swap_pager.c121
-rw-r--r--sys/vm/uma_core.c40
-rw-r--r--sys/vm/vm_domainset.c16
-rw-r--r--sys/vm/vm_domainset.h2
-rw-r--r--sys/vm/vm_fault.c15
-rw-r--r--sys/vm/vm_glue.c2
-rw-r--r--sys/vm/vm_init.c84
-rw-r--r--sys/vm/vm_kern.c125
-rw-r--r--sys/vm/vm_kern.h1
-rw-r--r--sys/vm/vm_mmap.c22
-rw-r--r--sys/vm/vm_page.c4
-rw-r--r--sys/vm/vm_pageout.c7
-rw-r--r--sys/vm/vm_pagequeue.h3
-rw-r--r--sys/vm/vm_phys.c1
-rw-r--r--sys/x86/acpica/srat.c19
-rw-r--r--sys/x86/include/ifunc.h32
-rw-r--r--sys/x86/include/ucode.h3
-rw-r--r--sys/x86/iommu/intel_utils.c3
-rw-r--r--sys/x86/isa/atpic.c10
-rw-r--r--sys/x86/x86/ucode.c119
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc2
-rw-r--r--tools/build/options/WITH_HYPERV2
-rw-r--r--usr.bin/bmake/Makefile.config2
-rw-r--r--usr.bin/clang/lld/ld.lld.18
-rw-r--r--usr.bin/locate/locate/Makefile5
-rw-r--r--usr.bin/mail/Makefile1
-rw-r--r--usr.bin/mandoc/Makefile4
-rw-r--r--usr.bin/nfsstat/nfsstat.17
-rw-r--r--usr.bin/tip/tip/Makefile4
-rw-r--r--usr.bin/tip/tip/phones (renamed from etc/phones)0
-rw-r--r--usr.bin/tip/tip/remote (renamed from etc/remote)0
-rw-r--r--usr.bin/top/top.1110
-rw-r--r--usr.sbin/Makefile8
-rw-r--r--usr.sbin/amd/amd/Makefile1
-rw-r--r--usr.sbin/amd/amd/amd.map (renamed from etc/amd.map)0
-rw-r--r--usr.sbin/bsdinstall/bsdinstall.8199
-rwxr-xr-xusr.sbin/bsdinstall/scripts/config6
-rwxr-xr-xusr.sbin/bsdinstall/scripts/hardening5
-rw-r--r--usr.sbin/chown/chown.c10
-rw-r--r--usr.sbin/cxgbetool/cxgbetool.817
-rw-r--r--usr.sbin/cxgbetool/cxgbetool.c9
-rw-r--r--usr.sbin/kldxref/kldxref.c4
-rw-r--r--usr.sbin/lpr/lpd/Makefile1
-rw-r--r--usr.sbin/lpr/lpd/hosts.lpd (renamed from etc/hosts.lpd)0
-rw-r--r--usr.sbin/lpr/lpd/printcap (renamed from etc/printcap)0
-rw-r--r--usr.sbin/nscd/nscd.85
-rw-r--r--usr.sbin/pmc/Makefile1
-rw-r--r--usr.sbin/pmccontrol/pmccontrol.c9
565 files changed, 8302 insertions, 4820 deletions
diff --git a/UPDATING b/UPDATING
index 122b0600e827..607b16ff6d35 100644
--- a/UPDATING
+++ b/UPDATING
@@ -31,6 +31,21 @@ 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".)
+20181002:
+ The cam(4) based nda(4) driver will be used over nvd(4) by default on
+ powerpc64. You may set 'options NVME_USE_NVD=1' in your kernel conf or
+ loader tunable 'hw.nvme.use_nvd=1' if you wish to use the existing
+ driver. Make sure to edit /boot/etc/kboot.conf and fstab to use the
+ nda device name.
+
+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
@@ -170,6 +185,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW:
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
lib/libdevinfo is all that's required). devinfo and devmatch will
@@ -196,6 +216,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/blacklist/bin/blacklistd.8 b/contrib/blacklist/bin/blacklistd.8
index 8349c780ef88..81e3e9ca31e8 100644
--- a/contrib/blacklist/bin/blacklistd.8
+++ b/contrib/blacklist/bin/blacklistd.8
@@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd June 7, 2016
+.Dd October 5, 2018
.Dt BLACKLISTD 8
.Os
.Sh NAME
@@ -178,7 +178,7 @@ Specify the default rule name for the packet filter rules, usually
.It Fl r
Re-read the firewall rules from the internal database, then
remove and re-add them.
-This helps for packet filters that don't retain state across reboots.
+This helps for packet filters that do not retain state across reboots.
.It Fl s Ar sockpath
Add
.Ar sockpath
@@ -198,6 +198,27 @@ diagnostic messages to
instead of
.Xr syslogd 8 .
.El
+.Sh SIGNAL HANDLING
+.Nm
+deals with the following signals:
+.Bl -tag -width "USR2"
+.It HUP
+Receipt of this signal causes
+.Nm
+to re-read the configuration file.
+.It INT, TERM & QUIT
+These signals tell
+.Nm
+to exit in an orderly fashion.
+.It USR1
+This signal tells
+.Nm
+to increase the internal debugging level by 1.
+.It USR2
+This signal tells
+.Nm
+to decrease the internal debugging level by 1.
+.El
.Sh FILES
.Bl -tag -width /usr/libexec/blacklistd-helper -compact
.It Pa /usr/libexec/blacklistd-helper
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/elftoolchain/libelf/gelf_mips64el.c b/contrib/elftoolchain/libelf/gelf_mips64el.c
index 02131f0d4335..24a78a71ed23 100644
--- a/contrib/elftoolchain/libelf/gelf_mips64el.c
+++ b/contrib/elftoolchain/libelf/gelf_mips64el.c
@@ -34,8 +34,9 @@ int
_libelf_is_mips64el(Elf *e)
{
- return (e->e_kind == ELF_K_ELF && e->e_byteorder == ELFDATA2LSB &&
- e->e_u.e_elf.e_ehdr.e_ehdr64->e_machine == EM_MIPS);
+ return (e->e_kind == ELF_K_ELF &&
+ e->e_u.e_elf.e_ehdr.e_ehdr64->e_machine == EM_MIPS &&
+ e->e_u.e_elf.e_ehdr.e_ehdr64->e_ident[EI_DATA] == ELFDATA2LSB);
}
/*
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/llvm/lib/CodeGen/BranchFolding.cpp b/contrib/llvm/lib/CodeGen/BranchFolding.cpp
index 7f358a679366..5f3cfacfd991 100644
--- a/contrib/llvm/lib/CodeGen/BranchFolding.cpp
+++ b/contrib/llvm/lib/CodeGen/BranchFolding.cpp
@@ -884,11 +884,12 @@ void BranchFolder::mergeCommonTails(unsigned commonTailIndex) {
if (UpdateLiveIns) {
LivePhysRegs NewLiveIns(*TRI);
computeLiveIns(NewLiveIns, *MBB);
+ LiveRegs.init(*TRI);
// The flag merging may lead to some register uses no longer using the
// <undef> flag, add IMPLICIT_DEFs in the predecessors as necessary.
for (MachineBasicBlock *Pred : MBB->predecessors()) {
- LiveRegs.init(*TRI);
+ LiveRegs.clear();
LiveRegs.addLiveOuts(*Pred);
MachineBasicBlock::iterator InsertBefore = Pred->getFirstTerminator();
for (unsigned Reg : NewLiveIns) {
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp
index 0f05cab66d7e..93d157140919 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CGExprAgg.cpp
@@ -14,6 +14,7 @@
#include "CodeGenFunction.h"
#include "CGObjCRuntime.h"
#include "CodeGenModule.h"
+#include "ConstantEmitter.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
@@ -85,7 +86,7 @@ public:
void EmitMoveFromReturnSlot(const Expr *E, RValue Src);
void EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
- QualType elementType, InitListExpr *E);
+ QualType ArrayQTy, InitListExpr *E);
AggValueSlot::NeedsGCBarriers_t needsGC(QualType T) {
if (CGF.getLangOpts().getGC() && TypeRequiresGCollection(T))
@@ -392,12 +393,15 @@ static bool isTrivialFiller(Expr *E) {
/// \brief Emit initialization of an array from an initializer list.
void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
- QualType elementType, InitListExpr *E) {
+ QualType ArrayQTy, InitListExpr *E) {
uint64_t NumInitElements = E->getNumInits();
uint64_t NumArrayElements = AType->getNumElements();
assert(NumInitElements <= NumArrayElements);
+ QualType elementType =
+ CGF.getContext().getAsArrayType(ArrayQTy)->getElementType();
+
// DestPtr is an array*. Construct an elementType* by drilling
// down a level.
llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
@@ -409,6 +413,29 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
CharUnits elementAlign =
DestPtr.getAlignment().alignmentOfArrayElement(elementSize);
+ // Consider initializing the array by copying from a global. For this to be
+ // more efficient than per-element initialization, the size of the elements
+ // with explicit initializers should be large enough.
+ if (NumInitElements * elementSize.getQuantity() > 16 &&
+ elementType.isTriviallyCopyableType(CGF.getContext())) {
+ CodeGen::CodeGenModule &CGM = CGF.CGM;
+ ConstantEmitter Emitter(CGM);
+ LangAS AS = ArrayQTy.getAddressSpace();
+ if (llvm::Constant *C = Emitter.tryEmitForInitializer(E, AS, ArrayQTy)) {
+ auto GV = new llvm::GlobalVariable(
+ CGM.getModule(), C->getType(),
+ CGM.isTypeConstant(ArrayQTy, /* ExcludeCtorDtor= */ true),
+ llvm::GlobalValue::PrivateLinkage, C, "constinit",
+ /* InsertBefore= */ nullptr, llvm::GlobalVariable::NotThreadLocal,
+ CGM.getContext().getTargetAddressSpace(AS));
+ Emitter.finalize(GV);
+ CharUnits Align = CGM.getContext().getTypeAlignInChars(ArrayQTy);
+ GV->setAlignment(Align.getQuantity());
+ EmitFinalDestCopy(ArrayQTy, CGF.MakeAddrLValue(GV, ArrayQTy, Align));
+ return;
+ }
+ }
+
// Exception safety requires us to destroy all the
// already-constructed members if an initializer throws.
// For that, we'll need an EH cleanup.
@@ -1156,11 +1183,8 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
// Handle initialization of an array.
if (E->getType()->isArrayType()) {
- QualType elementType =
- CGF.getContext().getAsArrayType(E->getType())->getElementType();
-
auto AType = cast<llvm::ArrayType>(Dest.getAddress().getElementType());
- EmitArrayInit(Dest.getAddress(), AType, elementType, E);
+ EmitArrayInit(Dest.getAddress(), AType, E->getType(), E);
return;
}
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
index 2172486682cf..226dc193aed4 100644
--- a/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/contrib/llvm/tools/clang/lib/CodeGen/CodeGenModule.cpp
@@ -321,8 +321,6 @@ void CodeGenModule::checkAliases() {
assert(FTy);
if (!FTy->getReturnType()->isPointerTy())
Diags.Report(Location, diag::err_ifunc_resolver_return);
- if (FTy->getNumParams())
- Diags.Report(Location, diag::err_ifunc_resolver_params);
}
llvm::Constant *Aliasee = Alias->getIndirectSymbol();
diff --git a/contrib/llvm/tools/lld/ELF/Config.h b/contrib/llvm/tools/lld/ELF/Config.h
index a9f3e7d3d2de..df688a76017e 100644
--- a/contrib/llvm/tools/lld/ELF/Config.h
+++ b/contrib/llvm/tools/lld/ELF/Config.h
@@ -156,6 +156,7 @@ struct Configuration {
bool ZExecstack;
bool ZHazardplt;
bool ZIfuncnoplt;
+ bool ZInterpose;
bool ZNocopyreloc;
bool ZNodelete;
bool ZNodlopen;
diff --git a/contrib/llvm/tools/lld/ELF/Driver.cpp b/contrib/llvm/tools/lld/ELF/Driver.cpp
index e6f4eea18b13..93cf7180314f 100644
--- a/contrib/llvm/tools/lld/ELF/Driver.cpp
+++ b/contrib/llvm/tools/lld/ELF/Driver.cpp
@@ -670,6 +670,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->ZExecstack = hasZOption(Args, "execstack");
Config->ZHazardplt = hasZOption(Args, "hazardplt");
Config->ZIfuncnoplt = hasZOption(Args, "ifunc-noplt");
+ Config->ZInterpose = hasZOption(Args, "interpose");
Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
Config->ZNodelete = hasZOption(Args, "nodelete");
Config->ZNodlopen = hasZOption(Args, "nodlopen");
diff --git a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
index a5a851f95400..bc787bc59070 100644
--- a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
+++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp
@@ -1034,6 +1034,8 @@ template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
uint32_t DtFlags1 = 0;
if (Config->Bsymbolic)
DtFlags |= DF_SYMBOLIC;
+ if (Config->ZInterpose)
+ DtFlags1 |= DF_1_INTERPOSE;
if (Config->ZNodelete)
DtFlags1 |= DF_1_NODELETE;
if (Config->ZNodlopen)
diff --git a/contrib/llvm/tools/lld/ELF/Writer.cpp b/contrib/llvm/tools/lld/ELF/Writer.cpp
index 40834a3e9522..71daf1d2a6eb 100644
--- a/contrib/llvm/tools/lld/ELF/Writer.cpp
+++ b/contrib/llvm/tools/lld/ELF/Writer.cpp
@@ -487,7 +487,7 @@ template <class ELFT> void Writer<ELFT>::run() {
static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
const Symbol &B) {
- if (B.isFile() || B.isSection())
+ if (B.isSection())
return false;
// If sym references a section in a discarded group, don't keep it.
diff --git a/contrib/mdocml/INSTALL b/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
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 <kristaps@bsd.lv>
-Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org>
+Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org>
+Copyright (c) 1999, 2004, 2017 Marc Espie <espie@openbsd.org>
Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger <joerg@netbsd.org>
Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de>
Copyright (c) 2014 Baptiste Daroussin <bapt@freebsd.org>
Copyright (c) 2016 Ed Maste <emaste@freebsd.org>
Copyright (c) 2017 Michael Stapelberg <stapelberg@debian.org>
-Copyright (c) 1999, 2004 Marc Espie <espie@openbsd.org>
Copyright (c) 1998, 2004, 2010 Todd C. Miller <Todd.Miller@courtesan.com>
Copyright (c) 2008, 2017 Otto Moerbeek <otto@drijf.net>
Copyright (c) 2004 Ted Unangst <tedu@openbsd.org>
diff --git a/contrib/mdocml/Makefile b/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 <kristaps@bsd.lv>
-# Copyright (c) 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org>
+# Copyright (c) 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.
-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
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
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
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 <lauretas at mail dot com> 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 <div>
+ Laura Morales <lauretas at mail dot com> 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 <ul> rather than <dl>
+ 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
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 <kristaps@bsd.lv>
.\" Copyright (c) 2011, 2012, 2014, 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: 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
index dd7f2a0d7711..dd7f2a0d7711 100644
--- a/contrib/mdocml/att.c
+++ b/contrib/mandoc/att.c
diff --git a/contrib/mdocml/catman.8 b/contrib/mandoc/catman.8
index 903fa1fa82c9..903fa1fa82c9 100644
--- a/contrib/mdocml/catman.8
+++ b/contrib/mandoc/catman.8
diff --git a/contrib/mdocml/catman.c b/contrib/mandoc/catman.c
index 7d62c0e74add..7d62c0e74add 100644
--- a/contrib/mdocml/catman.c
+++ b/contrib/mandoc/catman.c
diff --git a/contrib/mdocml/cgi.c b/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 <kristaps@bsd.lv>
* Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@usta.de>
@@ -356,6 +356,8 @@ resp_begin_html(int code, const char *msg, const char *file)
"<html>\n"
"<head>\n"
" <meta charset=\"UTF-8\"/>\n"
+ " <meta name=\"viewport\""
+ " content=\"width=device-width, initial-scale=1.0\">\n"
" <link rel=\"stylesheet\" href=\"%s/mandoc.css\""
" type=\"text/css\" media=\"all\">\n"
" <title>",
@@ -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
index 2ccbe25b2d87..2ccbe25b2d87 100644
--- a/contrib/mdocml/cgi.h.example
+++ b/contrib/mandoc/cgi.h.example
diff --git a/contrib/mdocml/chars.c b/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
index d8b09cb2a307..d8b09cb2a307 100644
--- a/contrib/mdocml/compat_err.c
+++ b/contrib/mandoc/compat_err.c
diff --git a/contrib/mdocml/compat_fts.c b/contrib/mandoc/compat_fts.c
index 3859111a52f8..3859111a52f8 100644
--- a/contrib/mdocml/compat_fts.c
+++ b/contrib/mandoc/compat_fts.c
diff --git a/contrib/mdocml/compat_fts.h b/contrib/mandoc/compat_fts.h
index f4a97a4c3a56..f4a97a4c3a56 100644
--- a/contrib/mdocml/compat_fts.h
+++ b/contrib/mandoc/compat_fts.h
diff --git a/contrib/mdocml/compat_getline.c b/contrib/mandoc/compat_getline.c
index aed4754ffdae..aed4754ffdae 100644
--- a/contrib/mdocml/compat_getline.c
+++ b/contrib/mandoc/compat_getline.c
diff --git a/contrib/mdocml/compat_getsubopt.c b/contrib/mandoc/compat_getsubopt.c
index 880f2f789d4a..880f2f789d4a 100644
--- a/contrib/mdocml/compat_getsubopt.c
+++ b/contrib/mandoc/compat_getsubopt.c
diff --git a/contrib/mdocml/compat_isblank.c b/contrib/mandoc/compat_isblank.c
index 9e3c74706c3d..9e3c74706c3d 100644
--- a/contrib/mdocml/compat_isblank.c
+++ b/contrib/mandoc/compat_isblank.c
diff --git a/contrib/mdocml/compat_mkdtemp.c b/contrib/mandoc/compat_mkdtemp.c
index 1fcb325f4f9a..1fcb325f4f9a 100644
--- a/contrib/mdocml/compat_mkdtemp.c
+++ b/contrib/mandoc/compat_mkdtemp.c
diff --git a/contrib/mdocml/compat_ohash.c b/contrib/mandoc/compat_ohash.c
index cbd6052182f2..cbd6052182f2 100644
--- a/contrib/mdocml/compat_ohash.c
+++ b/contrib/mandoc/compat_ohash.c
diff --git a/contrib/mdocml/compat_ohash.h b/contrib/mandoc/compat_ohash.h
index 58fb220c96c0..58fb220c96c0 100644
--- a/contrib/mdocml/compat_ohash.h
+++ b/contrib/mandoc/compat_ohash.h
diff --git a/contrib/mdocml/compat_progname.c b/contrib/mandoc/compat_progname.c
index 9840cc7c6c61..9840cc7c6c61 100644
--- a/contrib/mdocml/compat_progname.c
+++ b/contrib/mandoc/compat_progname.c
diff --git a/contrib/mdocml/compat_reallocarray.c b/contrib/mandoc/compat_reallocarray.c
index 66151904257d..66151904257d 100644
--- a/contrib/mdocml/compat_reallocarray.c
+++ b/contrib/mandoc/compat_reallocarray.c
diff --git a/contrib/mdocml/compat_recallocarray.c b/contrib/mandoc/compat_recallocarray.c
index d86dc5091a0a..d86dc5091a0a 100644
--- a/contrib/mdocml/compat_recallocarray.c
+++ b/contrib/mandoc/compat_recallocarray.c
diff --git a/contrib/mdocml/compat_strcasestr.c b/contrib/mandoc/compat_strcasestr.c
index 62c0ff740c81..62c0ff740c81 100644
--- a/contrib/mdocml/compat_strcasestr.c
+++ b/contrib/mandoc/compat_strcasestr.c
diff --git a/contrib/mdocml/compat_stringlist.c b/contrib/mandoc/compat_stringlist.c
index 17eba7724af5..17eba7724af5 100644
--- a/contrib/mdocml/compat_stringlist.c
+++ b/contrib/mandoc/compat_stringlist.c
diff --git a/contrib/mdocml/compat_stringlist.h b/contrib/mandoc/compat_stringlist.h
index f04e8435047d..f04e8435047d 100644
--- a/contrib/mdocml/compat_stringlist.h
+++ b/contrib/mandoc/compat_stringlist.h
diff --git a/contrib/mdocml/compat_strlcat.c b/contrib/mandoc/compat_strlcat.c
index acaae4fb1506..acaae4fb1506 100644
--- a/contrib/mdocml/compat_strlcat.c
+++ b/contrib/mandoc/compat_strlcat.c
diff --git a/contrib/mdocml/compat_strlcpy.c b/contrib/mandoc/compat_strlcpy.c
index a00d511817a3..a00d511817a3 100644
--- a/contrib/mdocml/compat_strlcpy.c
+++ b/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
index 1df57582802b..1df57582802b 100644
--- a/contrib/mdocml/compat_strsep.c
+++ b/contrib/mandoc/compat_strsep.c
diff --git a/contrib/mdocml/compat_strtonum.c b/contrib/mandoc/compat_strtonum.c
index 628e5d51b86b..628e5d51b86b 100644
--- a/contrib/mdocml/compat_strtonum.c
+++ b/contrib/mandoc/compat_strtonum.c
diff --git a/contrib/mdocml/compat_vasprintf.c b/contrib/mandoc/compat_vasprintf.c
index 9040822b0097..9040822b0097 100644
--- a/contrib/mdocml/compat_vasprintf.c
+++ b/contrib/mandoc/compat_vasprintf.c
diff --git a/contrib/mdocml/config.h b/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
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
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
-# IBM AIX may need:
+# Because the system compiler may not provide <stdint.h>,
+# SunOS 5.9 may need:
-CC=xlc
+CC=gcc
-# The default compiler flags are:
+# IBM AIX may need:
-CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings"
+CC=xlc
-# 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
index ee43933de3bf..ee43933de3bf 100644
--- a/contrib/mdocml/dba.c
+++ b/contrib/mandoc/dba.c
diff --git a/contrib/mdocml/dba.h b/contrib/mandoc/dba.h
index 67a2759a2071..67a2759a2071 100644
--- a/contrib/mdocml/dba.h
+++ b/contrib/mandoc/dba.h
diff --git a/contrib/mdocml/dba_array.c b/contrib/mandoc/dba_array.c
index 18c9f09f1a21..18c9f09f1a21 100644
--- a/contrib/mdocml/dba_array.c
+++ b/contrib/mandoc/dba_array.c
diff --git a/contrib/mdocml/dba_array.h b/contrib/mandoc/dba_array.h
index d9a6ee6b1a43..d9a6ee6b1a43 100644
--- a/contrib/mdocml/dba_array.h
+++ b/contrib/mandoc/dba_array.h
diff --git a/contrib/mdocml/dba_read.c b/contrib/mandoc/dba_read.c
index e976057064ab..e976057064ab 100644
--- a/contrib/mdocml/dba_read.c
+++ b/contrib/mandoc/dba_read.c
diff --git a/contrib/mdocml/dba_write.c b/contrib/mandoc/dba_write.c
index 89883b87c1e7..89883b87c1e7 100644
--- a/contrib/mdocml/dba_write.c
+++ b/contrib/mandoc/dba_write.c
diff --git a/contrib/mdocml/dba_write.h b/contrib/mandoc/dba_write.h
index 6adda05b6506..6adda05b6506 100644
--- a/contrib/mdocml/dba_write.h
+++ b/contrib/mandoc/dba_write.h
diff --git a/contrib/mdocml/dbm.c b/contrib/mandoc/dbm.c
index 4aedf66d136f..4aedf66d136f 100644
--- a/contrib/mdocml/dbm.c
+++ b/contrib/mandoc/dbm.c
diff --git a/contrib/mdocml/dbm.h b/contrib/mandoc/dbm.h
index ec2cd479a739..ec2cd479a739 100644
--- a/contrib/mdocml/dbm.h
+++ b/contrib/mandoc/dbm.h
diff --git a/contrib/mdocml/dbm_map.c b/contrib/mandoc/dbm_map.c
index 87c085d22ec1..87c085d22ec1 100644
--- a/contrib/mdocml/dbm_map.c
+++ b/contrib/mandoc/dbm_map.c
diff --git a/contrib/mdocml/dbm_map.h b/contrib/mandoc/dbm_map.h
index 9768fc5f2dcc..9768fc5f2dcc 100644
--- a/contrib/mdocml/dbm_map.h
+++ b/contrib/mandoc/dbm_map.h
diff --git a/contrib/mdocml/demandoc.1 b/contrib/mandoc/demandoc.1
index bca69eff1b5b..bca69eff1b5b 100644
--- a/contrib/mdocml/demandoc.1
+++ b/contrib/mandoc/demandoc.1
diff --git a/contrib/mdocml/demandoc.c b/contrib/mandoc/demandoc.c
index 8b202ab023a0..8b202ab023a0 100644
--- a/contrib/mdocml/demandoc.c
+++ b/contrib/mandoc/demandoc.c
diff --git a/contrib/mdocml/eqn.7 b/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
index 01601a713734..01601a713734 100644
--- a/contrib/mdocml/eqn.c
+++ b/contrib/mandoc/eqn.c
diff --git a/contrib/mdocml/eqn_html.c b/contrib/mandoc/eqn_html.c
index 51f144234275..51f144234275 100644
--- a/contrib/mdocml/eqn_html.c
+++ b/contrib/mandoc/eqn_html.c
diff --git a/contrib/mdocml/eqn_term.c b/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
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
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);
+ if (buf == NULL)
+ return NULL;
- /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */
+ /*
+ * 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
+ */
for (cp = buf; *cp != '\0'; cp++)
- if (*cp == ' ')
+ if (isalnum((unsigned char)*cp) == 0 &&
+ strchr("!$&'()*+,-./:;=?@_~", *cp) == NULL)
*cp = '_';
- return buf;
-}
-
-int
-html_strlen(const char *cp)
-{
- size_t rsz;
- int skip, sz;
-
- /*
- * 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.
- */
-
- sz = 0;
- skip = 0;
- while (1) {
- rsz = strcspn(cp, "\\");
- if (rsz) {
- cp += rsz;
- if (skip) {
- skip = 0;
- rsz--;
+ 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);
- 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++;
+ 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;
- 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. */
@@ -769,6 +668,32 @@ print_gen_decls(struct html *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)
{
if (h->col && (h->flags & HTML_NOSPACE) == 0) {
@@ -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
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
index 0474924d735a..0474924d735a 100644
--- a/contrib/mdocml/lib.c
+++ b/contrib/mandoc/lib.c
diff --git a/contrib/mdocml/lib.in b/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
index 312093dd018c..312093dd018c 100644
--- a/contrib/mdocml/libman.h
+++ b/contrib/mandoc/libman.h
diff --git a/contrib/mdocml/libmandoc.h b/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
index 57dff61b4aa3..57dff61b4aa3 100644
--- a/contrib/mdocml/libmdoc.h
+++ b/contrib/mandoc/libmdoc.h
diff --git a/contrib/mdocml/libroff.h b/contrib/mandoc/libroff.h
index b6a026d820b3..b6a026d820b3 100644
--- a/contrib/mdocml/libroff.h
+++ b/contrib/mandoc/libroff.h
diff --git a/contrib/mdocml/main.c b/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
index f9b8f135f885..f9b8f135f885 100644
--- a/contrib/mdocml/main.h
+++ b/contrib/mandoc/main.h
diff --git a/contrib/mdocml/makewhatis.8 b/contrib/mandoc/makewhatis.8
index 9f307a351d3d..9f307a351d3d 100644
--- a/contrib/mdocml/makewhatis.8
+++ b/contrib/mandoc/makewhatis.8
diff --git a/contrib/mdocml/man-cgi.css b/contrib/mandoc/man-cgi.css
index 256e8c6693ef..256e8c6693ef 100644
--- a/contrib/mdocml/man-cgi.css
+++ b/contrib/mandoc/man-cgi.css
diff --git a/contrib/mdocml/man.1 b/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
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
index 7a2bcc968818..7a2bcc968818 100644
--- a/contrib/mdocml/man.c
+++ b/contrib/mandoc/man.c
diff --git a/contrib/mdocml/man.cgi.3 b/contrib/mandoc/man.cgi.3
index e83248cc2f5b..e83248cc2f5b 100644
--- a/contrib/mdocml/man.cgi.3
+++ b/contrib/mandoc/man.cgi.3
diff --git a/contrib/mdocml/man.cgi.8 b/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
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
index d671f9a9e41e..d671f9a9e41e 100644
--- a/contrib/mdocml/man.h
+++ b/contrib/mandoc/man.h
diff --git a/contrib/mdocml/man.options.1 b/contrib/mandoc/man.options.1
index d8c790f4fa04..d8c790f4fa04 100644
--- a/contrib/mdocml/man.options.1
+++ b/contrib/mandoc/man.options.1
diff --git a/contrib/mdocml/man_html.c b/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
index aa8b200196a6..aa8b200196a6 100644
--- a/contrib/mdocml/man_macro.c
+++ b/contrib/mandoc/man_macro.c
diff --git a/contrib/mdocml/man_term.c b/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
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
index b4cd31646c91..b4cd31646c91 100644
--- a/contrib/mdocml/manconf.h
+++ b/contrib/mandoc/manconf.h
diff --git a/contrib/mdocml/mandoc.1 b/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
index 6914a76808f7..6914a76808f7 100644
--- a/contrib/mdocml/mandoc.3
+++ b/contrib/mandoc/mandoc.3
diff --git a/contrib/mdocml/mandoc.c b/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
index 26907d139f41..26907d139f41 100644
--- a/contrib/mdocml/mandoc.db.5
+++ b/contrib/mandoc/mandoc.db.5
diff --git a/contrib/mdocml/mandoc.h b/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
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
index 469e331eb4bf..469e331eb4bf 100644
--- a/contrib/mdocml/mandoc_aux.h
+++ b/contrib/mandoc/mandoc_aux.h
diff --git a/contrib/mdocml/mandoc_char.7 b/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
index 90b672c9d29b..90b672c9d29b 100644
--- a/contrib/mdocml/mandoc_escape.3
+++ b/contrib/mandoc/mandoc_escape.3
diff --git a/contrib/mdocml/mandoc_headers.3 b/contrib/mandoc/mandoc_headers.3
index 4a05d49678fd..4a05d49678fd 100644
--- a/contrib/mdocml/mandoc_headers.3
+++ b/contrib/mandoc/mandoc_headers.3
diff --git a/contrib/mdocml/mandoc_html.3 b/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
index ae3ca16aa4a8..ae3ca16aa4a8 100644
--- a/contrib/mdocml/mandoc_malloc.3
+++ b/contrib/mandoc/mandoc_malloc.3
diff --git a/contrib/mdocml/mandoc_ohash.c b/contrib/mandoc/mandoc_ohash.c
index 0627b469c60b..0627b469c60b 100644
--- a/contrib/mdocml/mandoc_ohash.c
+++ b/contrib/mandoc/mandoc_ohash.c
diff --git a/contrib/mdocml/mandoc_ohash.h b/contrib/mandoc/mandoc_ohash.h
index 571c4cda93c7..571c4cda93c7 100644
--- a/contrib/mdocml/mandoc_ohash.h
+++ b/contrib/mandoc/mandoc_ohash.h
diff --git a/contrib/mdocml/mandoc_xr.c b/contrib/mandoc/mandoc_xr.c
index da0a7f0cf23b..da0a7f0cf23b 100644
--- a/contrib/mdocml/mandoc_xr.c
+++ b/contrib/mandoc/mandoc_xr.c
diff --git a/contrib/mdocml/mandoc_xr.h b/contrib/mandoc/mandoc_xr.h
index e0c6af0ebf92..e0c6af0ebf92 100644
--- a/contrib/mdocml/mandoc_xr.h
+++ b/contrib/mandoc/mandoc_xr.h
diff --git a/contrib/mdocml/mandocd.8 b/contrib/mandoc/mandocd.8
index 2ea18cfc9f07..2ea18cfc9f07 100644
--- a/contrib/mdocml/mandocd.8
+++ b/contrib/mandoc/mandocd.8
diff --git a/contrib/mdocml/mandocd.c b/contrib/mandoc/mandocd.c
index 9aba9cc1d94c..9aba9cc1d94c 100644
--- a/contrib/mdocml/mandocd.c
+++ b/contrib/mandoc/mandocd.c
diff --git a/contrib/mdocml/mandocdb.c b/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;
}
@@ -1572,6 +1575,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;
}
-
- 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 ((fd1 = open(MANDOC_DB, O_RDONLY, 0)) == -1) {
+ say(MANDOC_DB, "&open");
+ goto err;
}
- 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");
+ 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;
+
+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
index 54f7a6b110ad..54f7a6b110ad 100644
--- a/contrib/mdocml/manpath.c
+++ b/contrib/mandoc/manpath.c
diff --git a/contrib/mdocml/manpath.h b/contrib/mandoc/manpath.h
index 728373b2cc0b..728373b2cc0b 100644
--- a/contrib/mdocml/manpath.h
+++ b/contrib/mandoc/manpath.h
diff --git a/contrib/mdocml/mansearch.3 b/contrib/mandoc/mansearch.3
index b94815a02b45..b94815a02b45 100644
--- a/contrib/mdocml/mansearch.3
+++ b/contrib/mandoc/mansearch.3
diff --git a/contrib/mdocml/mansearch.c b/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
index cc4f364f6932..cc4f364f6932 100644
--- a/contrib/mdocml/mansearch.h
+++ b/contrib/mandoc/mansearch.h
diff --git a/contrib/mdocml/mchars_alloc.3 b/contrib/mandoc/mchars_alloc.3
index 4bb862083ab3..4bb862083ab3 100644
--- a/contrib/mdocml/mchars_alloc.3
+++ b/contrib/mandoc/mchars_alloc.3
diff --git a/contrib/mdocml/mdoc.7 b/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
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
index 1628e0c80c94..1628e0c80c94 100644
--- a/contrib/mdocml/mdoc.h
+++ b/contrib/mandoc/mdoc.h
diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mandoc/mdoc_argv.c
index db4c63f0d6d2..db4c63f0d6d2 100644
--- a/contrib/mdocml/mdoc_argv.c
+++ b/contrib/mandoc/mdoc_argv.c
diff --git a/contrib/mdocml/mdoc_html.c b/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;
@@ -671,42 +670,6 @@ mdoc_it_pre(MDOC_ARGS)
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:
case LIST_hyphen:
case LIST_item:
@@ -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;
- else
- offs = -1;
-
- if (offs == -1)
- print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs);
+ print_otag(h, TAG_DIV, "c", "Bd");
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";
-
- /*
- * We want this to be inline-formatted, but needs to be div to
- * accept block children.
- */
+ cattr = "Bf No";
- 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
index b463d03e225c..b463d03e225c 100644
--- a/contrib/mdocml/mdoc_macro.c
+++ b/contrib/mandoc/mdoc_macro.c
diff --git a/contrib/mdocml/mdoc_man.c b/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
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
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
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
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;
@@ -395,6 +402,57 @@ check_text(struct roff_man *mdoc, int ln, int pos, char *p)
}
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)
{
const char *cp, *cpr;
@@ -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
index 9d41511696d0..9d41511696d0 100644
--- a/contrib/mdocml/msec.c
+++ b/contrib/mandoc/msec.c
diff --git a/contrib/mdocml/msec.in b/contrib/mandoc/msec.in
index d5b319f16a9f..d5b319f16a9f 100644
--- a/contrib/mdocml/msec.in
+++ b/contrib/mandoc/msec.in
diff --git a/contrib/mdocml/out.c b/contrib/mandoc/out.c
index b2b643787ec1..b2b643787ec1 100644
--- a/contrib/mdocml/out.c
+++ b/contrib/mandoc/out.c
diff --git a/contrib/mdocml/out.h b/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
index 08f8df86a61b..08f8df86a61b 100644
--- a/contrib/mdocml/preconv.c
+++ b/contrib/mandoc/preconv.c
diff --git a/contrib/mdocml/predefs.in b/contrib/mandoc/predefs.in
index d1690e356808..d1690e356808 100644
--- a/contrib/mdocml/predefs.in
+++ b/contrib/mandoc/predefs.in
diff --git a/contrib/mdocml/read.c b/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
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
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;
}
@@ -2515,20 +2551,29 @@ 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;
}
}
- 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;
- }
+ 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;
}
}
- 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;
- }
+ 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 (*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_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 (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 (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 (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
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
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
index 48996dce53f1..48996dce53f1 100644
--- a/contrib/mdocml/roff_int.h
+++ b/contrib/mandoc/roff_int.h
diff --git a/contrib/mdocml/roff_term.c b/contrib/mandoc/roff_term.c
index b5ec764963ea..b5ec764963ea 100644
--- a/contrib/mdocml/roff_term.c
+++ b/contrib/mandoc/roff_term.c
diff --git a/contrib/mdocml/roff_validate.c b/contrib/mandoc/roff_validate.c
index 801e93148532..801e93148532 100644
--- a/contrib/mdocml/roff_validate.c
+++ b/contrib/mandoc/roff_validate.c
diff --git a/contrib/mdocml/soelim.1 b/contrib/mandoc/soelim.1
index 6b42750c05f7..6b42750c05f7 100644
--- a/contrib/mdocml/soelim.1
+++ b/contrib/mandoc/soelim.1
diff --git a/contrib/mdocml/soelim.c b/contrib/mandoc/soelim.c
index 3ef30820e318..3ef30820e318 100644
--- a/contrib/mdocml/soelim.c
+++ b/contrib/mandoc/soelim.c
diff --git a/contrib/mdocml/st.c b/contrib/mandoc/st.c
index d166566eceff..d166566eceff 100644
--- a/contrib/mdocml/st.c
+++ b/contrib/mandoc/st.c
diff --git a/contrib/mdocml/st.in b/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
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
index ab1388d7984c..ab1388d7984c 100644
--- a/contrib/mdocml/tag.h
+++ b/contrib/mandoc/tag.h
diff --git a/contrib/mdocml/tbl.3 b/contrib/mandoc/tbl.3
index f3db622e33cb..f3db622e33cb 100644
--- a/contrib/mdocml/tbl.3
+++ b/contrib/mandoc/tbl.3
diff --git a/contrib/mdocml/tbl.7 b/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
index 3fb8e52a4c6e..3fb8e52a4c6e 100644
--- a/contrib/mdocml/tbl.c
+++ b/contrib/mandoc/tbl.c
diff --git a/contrib/mdocml/tbl_data.c b/contrib/mandoc/tbl_data.c
index ae1906ef735a..ae1906ef735a 100644
--- a/contrib/mdocml/tbl_data.c
+++ b/contrib/mandoc/tbl_data.c
diff --git a/contrib/mdocml/tbl_html.c b/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
index 42fc0e8296f5..42fc0e8296f5 100644
--- a/contrib/mdocml/tbl_layout.c
+++ b/contrib/mandoc/tbl_layout.c
diff --git a/contrib/mdocml/tbl_opts.c b/contrib/mandoc/tbl_opts.c
index f2f5942ae64c..f2f5942ae64c 100644
--- a/contrib/mdocml/tbl_opts.c
+++ b/contrib/mandoc/tbl_opts.c
diff --git a/contrib/mdocml/tbl_term.c b/contrib/mandoc/tbl_term.c
index c154a0e9b967..c154a0e9b967 100644
--- a/contrib/mdocml/tbl_term.c
+++ b/contrib/mandoc/tbl_term.c
diff --git a/contrib/mdocml/term.c b/contrib/mandoc/term.c
index f67fcf9d959f..f67fcf9d959f 100644
--- a/contrib/mdocml/term.c
+++ b/contrib/mandoc/term.c
diff --git a/contrib/mdocml/term.h b/contrib/mandoc/term.h
index 493191d7d369..493191d7d369 100644
--- a/contrib/mdocml/term.h
+++ b/contrib/mandoc/term.h
diff --git a/contrib/mdocml/term_ascii.c b/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
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
index 5251a8425a3c..5251a8425a3c 100644
--- a/contrib/mdocml/term_tab.c
+++ b/contrib/mandoc/term_tab.c
diff --git a/contrib/mdocml/test-EFTYPE.c b/contrib/mandoc/test-EFTYPE.c
index 148f54f769ed..148f54f769ed 100644
--- a/contrib/mdocml/test-EFTYPE.c
+++ b/contrib/mandoc/test-EFTYPE.c
diff --git a/contrib/mdocml/test-O_DIRECTORY.c b/contrib/mandoc/test-O_DIRECTORY.c
index e44d51ca4ff7..e44d51ca4ff7 100644
--- a/contrib/mdocml/test-O_DIRECTORY.c
+++ b/contrib/mandoc/test-O_DIRECTORY.c
diff --git a/contrib/mdocml/test-PATH_MAX.c b/contrib/mandoc/test-PATH_MAX.c
index 99bcc0b48695..99bcc0b48695 100644
--- a/contrib/mdocml/test-PATH_MAX.c
+++ b/contrib/mandoc/test-PATH_MAX.c
diff --git a/contrib/mdocml/test-be32toh.c b/contrib/mandoc/test-be32toh.c
index 471e85ea5e43..471e85ea5e43 100644
--- a/contrib/mdocml/test-be32toh.c
+++ b/contrib/mandoc/test-be32toh.c
diff --git a/contrib/mdocml/test-cmsg.c b/contrib/mandoc/test-cmsg.c
index b5441f9c82fe..b5441f9c82fe 100644
--- a/contrib/mdocml/test-cmsg.c
+++ b/contrib/mandoc/test-cmsg.c
diff --git a/contrib/mdocml/test-dirent-namlen.c b/contrib/mandoc/test-dirent-namlen.c
index 032e75eb09d2..032e75eb09d2 100644
--- a/contrib/mdocml/test-dirent-namlen.c
+++ b/contrib/mandoc/test-dirent-namlen.c
diff --git a/contrib/mdocml/test-err.c b/contrib/mandoc/test-err.c
index d17e0f0da407..d17e0f0da407 100644
--- a/contrib/mdocml/test-err.c
+++ b/contrib/mandoc/test-err.c
diff --git a/contrib/mdocml/test-fgetln.c b/contrib/mandoc/test-fgetln.c
index ac225a178f35..ac225a178f35 100644
--- a/contrib/mdocml/test-fgetln.c
+++ b/contrib/mandoc/test-fgetln.c
diff --git a/contrib/mdocml/test-fts.c b/contrib/mandoc/test-fts.c
index 23e441525760..23e441525760 100644
--- a/contrib/mdocml/test-fts.c
+++ b/contrib/mandoc/test-fts.c
diff --git a/contrib/mdocml/test-getline.c b/contrib/mandoc/test-getline.c
index d05df217121f..d05df217121f 100644
--- a/contrib/mdocml/test-getline.c
+++ b/contrib/mandoc/test-getline.c
diff --git a/contrib/mdocml/test-getsubopt.c b/contrib/mandoc/test-getsubopt.c
index afcc5599d75f..afcc5599d75f 100644
--- a/contrib/mdocml/test-getsubopt.c
+++ b/contrib/mandoc/test-getsubopt.c
diff --git a/contrib/mdocml/test-isblank.c b/contrib/mandoc/test-isblank.c
index eb2cfdfcd865..eb2cfdfcd865 100644
--- a/contrib/mdocml/test-isblank.c
+++ b/contrib/mandoc/test-isblank.c
diff --git a/contrib/mdocml/test-mkdtemp.c b/contrib/mandoc/test-mkdtemp.c
index a0cb30e22f4a..a0cb30e22f4a 100644
--- a/contrib/mdocml/test-mkdtemp.c
+++ b/contrib/mandoc/test-mkdtemp.c
diff --git a/contrib/mdocml/test-nanosleep.c b/contrib/mandoc/test-nanosleep.c
index 4b25ca4cfbf9..4b25ca4cfbf9 100644
--- a/contrib/mdocml/test-nanosleep.c
+++ b/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
index 52dcc256ff56..52dcc256ff56 100644
--- a/contrib/mdocml/test-ntohl.c
+++ b/contrib/mandoc/test-ntohl.c
diff --git a/contrib/mdocml/test-ohash.c b/contrib/mandoc/test-ohash.c
index 1844fe56ad8a..1844fe56ad8a 100644
--- a/contrib/mdocml/test-ohash.c
+++ b/contrib/mandoc/test-ohash.c
diff --git a/contrib/mdocml/test-pledge.c b/contrib/mandoc/test-pledge.c
index ab2dfb474081..ab2dfb474081 100644
--- a/contrib/mdocml/test-pledge.c
+++ b/contrib/mandoc/test-pledge.c
diff --git a/contrib/mdocml/test-progname.c b/contrib/mandoc/test-progname.c
index 0418b3c07bd8..0418b3c07bd8 100644
--- a/contrib/mdocml/test-progname.c
+++ b/contrib/mandoc/test-progname.c
diff --git a/contrib/mdocml/test-reallocarray.c b/contrib/mandoc/test-reallocarray.c
index f99e685d8350..f99e685d8350 100644
--- a/contrib/mdocml/test-reallocarray.c
+++ b/contrib/mandoc/test-reallocarray.c
diff --git a/contrib/mdocml/test-recallocarray.c b/contrib/mandoc/test-recallocarray.c
index e0c60d7118f8..e0c60d7118f8 100644
--- a/contrib/mdocml/test-recallocarray.c
+++ b/contrib/mandoc/test-recallocarray.c
diff --git a/contrib/mdocml/test-recvmsg.c b/contrib/mandoc/test-recvmsg.c
index d026c70fb8c7..d026c70fb8c7 100644
--- a/contrib/mdocml/test-recvmsg.c
+++ b/contrib/mandoc/test-recvmsg.c
diff --git a/contrib/mdocml/test-rewb-bsd.c b/contrib/mandoc/test-rewb-bsd.c
index 872dd4c81d02..872dd4c81d02 100644
--- a/contrib/mdocml/test-rewb-bsd.c
+++ b/contrib/mandoc/test-rewb-bsd.c
diff --git a/contrib/mdocml/test-rewb-sysv.c b/contrib/mandoc/test-rewb-sysv.c
index 1e7fbc821944..1e7fbc821944 100644
--- a/contrib/mdocml/test-rewb-sysv.c
+++ b/contrib/mandoc/test-rewb-sysv.c
diff --git a/contrib/mdocml/test-sandbox_init.c b/contrib/mandoc/test-sandbox_init.c
index a4902ee61669..a4902ee61669 100644
--- a/contrib/mdocml/test-sandbox_init.c
+++ b/contrib/mandoc/test-sandbox_init.c
diff --git a/contrib/mdocml/test-strcasestr.c b/contrib/mandoc/test-strcasestr.c
index c3a87de82e16..c3a87de82e16 100644
--- a/contrib/mdocml/test-strcasestr.c
+++ b/contrib/mandoc/test-strcasestr.c
diff --git a/contrib/mdocml/test-stringlist.c b/contrib/mandoc/test-stringlist.c
index 7555d208d94c..7555d208d94c 100644
--- a/contrib/mdocml/test-stringlist.c
+++ b/contrib/mandoc/test-stringlist.c
diff --git a/contrib/mdocml/test-strlcat.c b/contrib/mandoc/test-strlcat.c
index 48ab38a4df03..48ab38a4df03 100644
--- a/contrib/mdocml/test-strlcat.c
+++ b/contrib/mandoc/test-strlcat.c
diff --git a/contrib/mdocml/test-strlcpy.c b/contrib/mandoc/test-strlcpy.c
index 12e1db39e704..12e1db39e704 100644
--- a/contrib/mdocml/test-strlcpy.c
+++ b/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
index d8799e94455c..d8799e94455c 100644
--- a/contrib/mdocml/test-strptime.c
+++ b/contrib/mandoc/test-strptime.c
diff --git a/contrib/mdocml/test-strsep.c b/contrib/mandoc/test-strsep.c
index 18bbb109a5b0..18bbb109a5b0 100644
--- a/contrib/mdocml/test-strsep.c
+++ b/contrib/mandoc/test-strsep.c
diff --git a/contrib/mdocml/test-strtonum.c b/contrib/mandoc/test-strtonum.c
index 4b6cd3f56173..4b6cd3f56173 100644
--- a/contrib/mdocml/test-strtonum.c
+++ b/contrib/mandoc/test-strtonum.c
diff --git a/contrib/mdocml/test-vasprintf.c b/contrib/mandoc/test-vasprintf.c
index ee6980a28955..ee6980a28955 100644
--- a/contrib/mdocml/test-vasprintf.c
+++ b/contrib/mandoc/test-vasprintf.c
diff --git a/contrib/mdocml/test-wchar.c b/contrib/mandoc/test-wchar.c
index 32962d9fe665..32962d9fe665 100644
--- a/contrib/mdocml/test-wchar.c
+++ b/contrib/mandoc/test-wchar.c
diff --git a/contrib/mdocml/tree.c b/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/contrib/openbsm/bin/auditdistd/auditdistd.h b/contrib/openbsm/bin/auditdistd/auditdistd.h
index d0594f2ebcd8..26dd51bdff8e 100644
--- a/contrib/openbsm/bin/auditdistd/auditdistd.h
+++ b/contrib/openbsm/bin/auditdistd/auditdistd.h
@@ -248,6 +248,21 @@ struct adrep {
if (_wakeup) \
cv_signal(list##_cond); \
} while (0)
+#define QUEUE_CONCAT2(tolist, fromlist1, fromlist2) do { \
+ bool _wakeup; \
+ \
+ mtx_lock(tolist##_lock); \
+ _wakeup = TAILQ_EMPTY(tolist); \
+ mtx_lock(fromlist1##_lock); \
+ TAILQ_CONCAT((tolist), (fromlist1), adr_next); \
+ mtx_unlock(fromlist1##_lock); \
+ mtx_lock(fromlist2##_lock); \
+ TAILQ_CONCAT((tolist), (fromlist2), adr_next); \
+ mtx_unlock(fromlist2##_lock); \
+ mtx_unlock(tolist##_lock); \
+ if (_wakeup) \
+ cv_signal(tolist##_cond); \
+} while (0)
#define QUEUE_WAIT(list) do { \
mtx_lock(list##_lock); \
while (TAILQ_EMPTY(list)) \
diff --git a/contrib/openbsm/bin/auditdistd/receiver.c b/contrib/openbsm/bin/auditdistd/receiver.c
index 9dc3b0184c63..38cf2d448d42 100644
--- a/contrib/openbsm/bin/auditdistd/receiver.c
+++ b/contrib/openbsm/bin/auditdistd/receiver.c
@@ -140,7 +140,7 @@ static void
adreq_decode_and_validate_header(struct adreq *adreq)
{
- /* Byte-swap only is the sender is using different byte order. */
+ /* Byte-swap only if the sender is using different byte order. */
if (adreq->adr_byteorder != ADIST_BYTEORDER) {
adreq->adr_byteorder = ADIST_BYTEORDER;
adreq->adr_seq = bswap64(adreq->adr_seq);
diff --git a/contrib/openbsm/bin/auditdistd/sender.c b/contrib/openbsm/bin/auditdistd/sender.c
index 4349b0f54cc9..c19fd93d5a3f 100644
--- a/contrib/openbsm/bin/auditdistd/sender.c
+++ b/contrib/openbsm/bin/auditdistd/sender.c
@@ -342,14 +342,7 @@ sender_disconnect(void)
pjdlog_warning("Disconnected from %s.", adhost->adh_remoteaddr);
/* Move all in-flight requests back onto free list. */
- mtx_lock(&adist_free_list_lock);
- mtx_lock(&adist_send_list_lock);
- TAILQ_CONCAT(&adist_free_list, &adist_send_list, adr_next);
- mtx_unlock(&adist_send_list_lock);
- mtx_lock(&adist_recv_list_lock);
- TAILQ_CONCAT(&adist_free_list, &adist_recv_list, adr_next);
- mtx_unlock(&adist_recv_list_lock);
- mtx_unlock(&adist_free_list_lock);
+ QUEUE_CONCAT2(&adist_free_list, &adist_send_list, &adist_recv_list);
}
static void
@@ -519,9 +512,6 @@ keepalive_send(void)
pjdlog_debug(3, "keepalive_send: Request sent.");
}
-/*
- * Thread sends request to secondary node.
- */
static void *
send_thread(void *arg __unused)
{
@@ -581,7 +571,7 @@ static void
adrep_decode_header(struct adrep *adrep)
{
- /* Byte-swap only is the receiver is using different byte order. */
+ /* Byte-swap only if the receiver is using different byte order. */
if (adrep->adrp_byteorder != ADIST_BYTEORDER) {
adrep->adrp_byteorder = ADIST_BYTEORDER;
adrep->adrp_seq = bswap64(adrep->adrp_seq);
@@ -589,10 +579,6 @@ adrep_decode_header(struct adrep *adrep)
}
}
-/*
- * Thread receives answer from secondary node and passes it to ggate_send
- * thread.
- */
static void *
recv_thread(void *arg __unused)
{
@@ -609,9 +595,13 @@ recv_thread(void *arg __unused)
if (adhost->adh_remote == NULL) {
/*
* Connection is dead.
- * XXX: We shouldn't be here.
+ * There is a short race in sender_disconnect() between
+ * setting adh_remote to NULL and removing entries from
+ * the recv list, which can result in us being here.
+ * To avoid just spinning, wait for 0.1s.
*/
rw_unlock(&adist_remote_lock);
+ usleep(100000);
continue;
}
if (proto_recv(adhost->adh_remote, &adrep,
diff --git a/contrib/openbsm/bin/auditdistd/trail.c b/contrib/openbsm/bin/auditdistd/trail.c
index b8a9881c1ba5..0a0bf882c45e 100644
--- a/contrib/openbsm/bin/auditdistd/trail.c
+++ b/contrib/openbsm/bin/auditdistd/trail.c
@@ -361,17 +361,38 @@ again:
pjdlog_debug(1, "No new trail files.");
return;
}
- PJDLOG_VERIFY(strlcpy(trail->tr_filename, curfile,
- sizeof(trail->tr_filename)) < sizeof(trail->tr_filename));
dfd = dirfd(trail->tr_dirfp);
PJDLOG_ASSERT(dfd >= 0);
- trail->tr_filefd = openat(dfd, trail->tr_filename, O_RDONLY);
+ trail->tr_filefd = openat(dfd, curfile, O_RDONLY);
if (trail->tr_filefd == -1) {
- pjdlog_errno(LOG_ERR,
- "Unable to open file \"%s/%s\", skipping",
- trail->tr_dirname, trail->tr_filename);
+ if (errno == ENOENT && trail_is_not_terminated(curfile)) {
+ /*
+ * The .not_terminated file was most likely renamed.
+ * Keep trail->tr_filename as a starting point and
+ * search again.
+ */
+ pjdlog_debug(1,
+ "Unable to open \"%s/%s\", most likely renamed in the meantime, retrying.",
+ trail->tr_dirname, curfile);
+ } else {
+ /*
+ * We were unable to open the file, but not because of
+ * the above. This shouldn't happen, but it did.
+ * We don't know why it happen, so the best we can do
+ * is to just skip this file - this is why we copy the
+ * name, so we can start and the next entry.
+ */
+ PJDLOG_VERIFY(strlcpy(trail->tr_filename, curfile,
+ sizeof(trail->tr_filename)) <
+ sizeof(trail->tr_filename));
+ pjdlog_errno(LOG_ERR,
+ "Unable to open file \"%s/%s\", skipping",
+ trail->tr_dirname, curfile);
+ }
goto again;
}
+ PJDLOG_VERIFY(strlcpy(trail->tr_filename, curfile,
+ sizeof(trail->tr_filename)) < sizeof(trail->tr_filename));
pjdlog_debug(1, "Found next trail file: \"%s/%s\".", trail->tr_dirname,
trail->tr_filename);
}
diff --git a/etc/Makefile b/etc/Makefile
index 71283a973eaa..df8f99e4c3de 100644
--- a/etc/Makefile
+++ b/etc/Makefile
@@ -13,57 +13,18 @@ SUBDIR+=sendmail
.endif
BIN1= \
- dhclient.conf \
- disktab \
group \
- hosts \
- hosts.allow \
- hosts.equiv \
- libalias.conf \
- libmap.conf \
login.access \
- mac.conf \
- netconfig \
- networks \
- nsswitch.conf \
- phones \
- protocols \
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
@@ -104,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
@@ -129,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 \
@@ -160,10 +117,6 @@ distribution:
${DESTDIR}/boot/device.hints
.endif
.endif
-.if ${MK_NIS} == "no"
- sed -i "" -e 's/.*_compat:/# &/' -e 's/compat$$/files/' \
- ${DESTDIR}/etc/nsswitch.conf
-.endif
MTREE_CMD?= mtree
@@ -244,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/limits.h b/include/limits.h
index e26a741c83a1..fc1470c058cb 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -122,7 +122,7 @@
#endif
#if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809
-#define NL_ARGMAX 65536 /* max # of position args for printf */
+#define NL_ARGMAX 4096 /* max # of position args for printf */
#define NL_MSGMAX 32767
#define NL_SETMAX 255
#define NL_TEXTMAX 2048
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/Makefile b/lib/Makefile
index da30e8403a21..4332aa13a70c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -70,6 +70,8 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libpathconv \
libpcap \
libpjdlog \
+ libpmc \
+ libpmcstat \
${_libproc} \
libprocstat \
libregex \
@@ -198,9 +200,6 @@ _libdl= libdl
.endif
SUBDIR.${MK_OPENSSL}+= libmp
-.if (${COMPILER_TYPE} == "clang" || (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 60100 && ${MACHINE_CPUARCH} != "riscv"))
-SUBDIR.${MK_PMC}+= libpmc libpmcstat
-.endif
SUBDIR.${MK_RADIUS_SUPPORT}+= libradius
SUBDIR.${MK_SENDMAIL}+= libmilter libsm libsmdb libsmutil
SUBDIR.${MK_TELNET}+= libtelnet
diff --git a/lib/clang/freebsd_cc_version.h b/lib/clang/freebsd_cc_version.h
index cb89cc37f126..9096dc913f14 100644
--- a/lib/clang/freebsd_cc_version.h
+++ b/lib/clang/freebsd_cc_version.h
@@ -1,3 +1,3 @@
/* $FreeBSD$ */
-#define FREEBSD_CC_VERSION 1200015
+#define FREEBSD_CC_VERSION 1200016
diff --git a/lib/csu/arm/crt1.c b/lib/csu/arm/crt1.c
index 5fe92947dbfb..0d61d319f351 100644
--- a/lib/csu/arm/crt1.c
+++ b/lib/csu/arm/crt1.c
@@ -44,6 +44,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/elf_common.h>
#include <stdlib.h>
#include "libc_private.h"
@@ -120,7 +122,7 @@ static const struct {
} archtag __attribute__ ((section (NOTE_SECTION), aligned(4))) __used = {
.namesz = sizeof(NOTE_FREEBSD_VENDOR),
.descsz = sizeof(MACHINE_ARCH),
- .type = ARCH_NOTETYPE,
+ .type = NT_FREEBSD_ARCH_TAG,
.name = NOTE_FREEBSD_VENDOR,
.desc = MACHINE_ARCH
};
diff --git a/lib/csu/common/crtbrand.c b/lib/csu/common/crtbrand.c
index fcdb824cf749..c407de435b96 100644
--- a/lib/csu/common/crtbrand.c
+++ b/lib/csu/common/crtbrand.c
@@ -29,6 +29,7 @@
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/elf_common.h>
#include "notes.h"
/*
@@ -62,7 +63,7 @@ static const struct {
} abitag __attribute__ ((section (NOTE_SECTION), aligned(4))) __used = {
.namesz = sizeof(NOTE_FREEBSD_VENDOR),
.descsz = sizeof(int32_t),
- .type = ABI_NOTETYPE,
+ .type = NT_FREEBSD_ABI_TAG,
.name = NOTE_FREEBSD_VENDOR,
.desc = __FreeBSD_version
};
diff --git a/lib/csu/common/ignore_init.c b/lib/csu/common/ignore_init.c
index 184bcbdf5447..6199c778ab52 100644
--- a/lib/csu/common/ignore_init.c
+++ b/lib/csu/common/ignore_init.c
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/param.h>
+#include <sys/elf_common.h>
#include "notes.h"
extern int main(int, char **, char **);
@@ -114,7 +116,7 @@ static const struct {
aligned(4))) __used = {
.namesz = sizeof(NOTE_FREEBSD_VENDOR),
.descsz = sizeof(uint32_t),
- .type = CRT_NOINIT_NOTETYPE,
+ .type = NT_FREEBSD_NOINIT_TAG,
.name = NOTE_FREEBSD_VENDOR,
.desc = 0
};
diff --git a/lib/csu/common/notes.h b/lib/csu/common/notes.h
index aeb5203d8dc1..44d2d95487cb 100644
--- a/lib/csu/common/notes.h
+++ b/lib/csu/common/notes.h
@@ -34,8 +34,4 @@
#define NOTE_SECTION ".note.tag"
-#define ABI_NOTETYPE 1
-#define CRT_NOINIT_NOTETYPE 2
-#define ARCH_NOTETYPE 3
-
#endif
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
index 21d544cbb043..21d544cbb043 100644
--- a/etc/regdomain.xml
+++ b/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
index a938e67aaabd..a938e67aaabd 100644
--- a/etc/libalias.conf
+++ b/lib/libalias/libalias/libalias.conf
diff --git a/lib/libbe/be.c b/lib/libbe/be.c
index c1cdd55825fe..2872abed6dec 100644
--- a/lib/libbe/be.c
+++ b/lib/libbe/be.c
@@ -928,8 +928,9 @@ be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
{
char be_path[BE_MAXPATHLEN];
char buf[BE_MAXPATHLEN];
- uint64_t pool_guid;
nvlist_t *config, *vdevs;
+ uint64_t pool_guid;
+ zfs_handle_t *zhp;
int err;
be_root_concat(lbh, bootenv, be_path);
@@ -961,14 +962,19 @@ be_activate(libbe_handle_t *lbh, const char *bootenv, bool temporary)
} else {
/* Obtain bootenv zpool */
err = zpool_set_prop(lbh->active_phandle, "bootfs", be_path);
+ if (err)
+ return (-1);
- switch (err) {
- case 0:
- return (BE_ERR_SUCCESS);
+ zhp = zfs_open(lbh->lzh, be_path, ZFS_TYPE_FILESYSTEM);
+ if (zhp == NULL)
+ return (-1);
- default:
- /* XXX TODO correct errors */
+ err = zfs_promote(zhp);
+ zfs_close(zhp);
+
+ if (err)
return (-1);
- }
}
+
+ return (BE_ERR_SUCCESS);
}
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 */
+ 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 %rdx,%rcx /* compare by words */
- shrq $3,%rcx
- repe
- cmpsq
- jne L1
+ movq 16(%rsi),%r8
+ movq 24(%rsi),%r9
+ subq 16(%rdi),%r8
+ subq 24(%rdi),%r9
+ or %r8,%r9
+ jnz 4b
- movq %rdx,%rcx /* compare remainder by bytes */
- andq $7,%rcx
- repe
- cmpsb
-L1:
- setne %al
- movsbl %al,%eax
- ret
+ 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/bcopy.S b/lib/libc/amd64/string/bcopy.S
index cc38f4755254..9446e75b8053 100644
--- a/lib/libc/amd64/string/bcopy.S
+++ b/lib/libc/amd64/string/bcopy.S
@@ -60,12 +60,14 @@ ENTRY(bcopy)
subq %rsi,%r8
cmpq %rcx,%r8 /* overlapping? */
jb 1f
- cld /* nope, copy forwards. */
shrq $3,%rcx /* copy by words */
rep
movsq
movq %rdx,%rcx
andq $7,%rcx /* any bytes left? */
+ jne 2f
+ ret
+2:
rep
movsb
ret
@@ -73,11 +75,13 @@ ENTRY(bcopy)
addq %rcx,%rdi /* copy backwards. */
addq %rcx,%rsi
std
- andq $7,%rcx /* any fractional bytes? */
decq %rdi
decq %rsi
+ andq $7,%rcx /* any fractional bytes? */
+ je 3f
rep
movsb
+3:
movq %rdx,%rcx /* copy remainder by words */
shrq $3,%rcx
subq $7,%rsi
diff --git a/lib/libc/amd64/string/bzero.S b/lib/libc/amd64/string/bzero.S
index cf46a2a317b7..123d9c4a7efb 100644
--- a/lib/libc/amd64/string/bzero.S
+++ b/lib/libc/amd64/string/bzero.S
@@ -1,46 +1,7 @@
-/*
- * Written by J.T. Conklin <jtc@NetBSD.org>.
- * Public domain.
- * Adapted for NetBSD/x86_64 by Frank van der Linden <fvdl@wasabisystems.com>
- */
+/* $FreeBSD */
#include <machine/asm.h>
__FBSDID("$FreeBSD$");
-#if 0
- RCSID("$NetBSD: bzero.S,v 1.2 2003/07/26 19:24:38 salo Exp $")
-#endif
-
-ENTRY(bzero)
- cld /* set fill direction forward */
- xorq %rax,%rax /* set fill data to 0 */
-
- /*
- * if the string is too short, it's really not worth the overhead
- * of aligning to word boundries, etc. So we jump to a plain
- * unaligned set.
- */
- cmpq $16,%rsi
- jb L1
-
- movq %rdi,%rcx /* compute misalignment */
- negq %rcx
- andq $7,%rcx
- subq %rcx,%rsi
- rep /* zero until word aligned */
- stosb
-
- movq %rsi,%rcx /* zero by words */
- shrq $3,%rcx
- andq $7,%rsi
- rep
- stosq
-
-L1: movq %rsi,%rcx /* zero remainder by bytes */
- rep
- stosb
-
- ret
-END(bzero)
-
- .section .note.GNU-stack,"",%progbits
+#define BZERO
+#include "memset.S"
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/amd64/string/memset.S b/lib/libc/amd64/string/memset.S
index 84d15628766a..06c9869c2d6c 100644
--- a/lib/libc/amd64/string/memset.S
+++ b/lib/libc/amd64/string/memset.S
@@ -1,63 +1,77 @@
-/*
- * 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: memset.S,v 1.3 2004/02/26 20:50:06 drochner Exp $")
-#endif
-
-ENTRY(memset)
- movq %rsi,%rax
- andq $0xff,%rax
+.macro MEMSET bzero
+.if \bzero == 1
+ movq %rsi,%rcx
+ movq %rsi,%rdx
+ xorl %eax,%eax
+.else
+ movq %rdi,%r9
movq %rdx,%rcx
- movq %rdi,%r11
-
- cld /* set fill direction forward */
-
- /*
- * if the string is too short, it's really not worth the overhead
- * of aligning to word boundries, etc. So we jump to a plain
- * unaligned set.
- */
- cmpq $0x0f,%rcx
- jle L1
-
- movb %al,%ah /* copy char to all bytes in word */
- movl %eax,%edx
- sall $16,%eax
- orl %edx,%eax
-
- movl %eax,%edx
- salq $32,%rax
- orq %rdx,%rax
-
- movq %rdi,%rdx /* compute misalignment */
- negq %rdx
- andq $7,%rdx
- movq %rcx,%r8
- subq %rdx,%r8
-
- movq %rdx,%rcx /* set until word aligned */
- rep
- stosb
-
- movq %r8,%rcx
- shrq $3,%rcx /* set by words */
+ movzbq %sil,%r8
+ movabs $0x0101010101010101,%rax
+ imulq %r8,%rax
+.endif
+ cmpq $15,%rcx
+ jbe 1f
+ shrq $3,%rcx
rep
stosq
-
- movq %r8,%rcx /* set remainder by bytes */
+ movq %rdx,%rcx
andq $7,%rcx
-L1: rep
+ jne 1f
+.if \bzero == 0
+ movq %r9,%rax
+.endif
+ ret
+1:
+ rep
stosb
- movq %r11,%rax
-
+.if \bzero == 0
+ movq %r9,%rax
+.endif
ret
+.endm
+
+#ifndef BZERO
+ENTRY(memset)
+ MEMSET bzero=0
END(memset)
+#else
+ENTRY(bzero)
+ MEMSET bzero=1
+END(bzero)
+#endif
.section .note.GNU-stack,"",%progbits
diff --git a/lib/libc/i386/string/bcopy.S b/lib/libc/i386/string/bcopy.S
index 89576f379d6a..4c653d744f15 100644
--- a/lib/libc/i386/string/bcopy.S
+++ b/lib/libc/i386/string/bcopy.S
@@ -64,7 +64,7 @@ ENTRY(bcopy)
movl %edi,%edx
subl %esi,%edx
cmpl %ecx,%edx /* overlapping? */
- jb 1f
+ jb 2f
cld /* nope, copy forwards. */
movl %ecx,%edx
shrl $2,%ecx /* copy by words */
@@ -72,21 +72,28 @@ ENTRY(bcopy)
movsl
movl %edx,%ecx
andl $3,%ecx /* any bytes left? */
+ jne 1f
+ popl %edi
+ popl %esi
+ ret
+1:
rep
movsb
popl %edi
popl %esi
ret
-1:
+2:
addl %ecx,%edi /* copy backwards. */
addl %ecx,%esi
std
movl %ecx,%edx
- andl $3,%ecx /* any fractional bytes? */
decl %edi
decl %esi
+ andl $3,%ecx /* any fractional bytes? */
+ je 3f
rep
movsb
+3:
movl %edx,%ecx /* copy remainder by words */
shrl $2,%ecx
subl $3,%esi
diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc
index 304c465b8545..b31c1a36fcfe 100644
--- a/lib/libc/net/Makefile.inc
+++ b/lib/libc/net/Makefile.inc
@@ -4,6 +4,7 @@
# machine-independent net sources
.PATH: ${LIBC_SRCTOP}/net
+CONFS+= net/hosts net/hosts.equiv net/networks net/nsswitch.conf net/protocols
SRCS+= base64.c ether_addr.c eui64.c \
gai_strerror.c getaddrinfo.c \
gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
@@ -123,3 +124,8 @@ SRCS+= hesiod.c
MAN+= hesiod.3
.endif
+.if ${MK_NIS} == "no"
+afterinstallconfig:
+ sed -i "" -e 's/.*_compat:/# &/' -e 's/compat$$/files/' \
+ ${DESTDIR}/etc/nsswitch.conf
+.endif
diff --git a/etc/hosts b/lib/libc/net/hosts
index 2690a9ad48e1..2690a9ad48e1 100644
--- a/etc/hosts
+++ b/lib/libc/net/hosts
diff --git a/etc/hosts.equiv b/lib/libc/net/hosts.equiv
index d8a71c1ebc7f..d8a71c1ebc7f 100644
--- a/etc/hosts.equiv
+++ b/lib/libc/net/hosts.equiv
diff --git a/etc/networks b/lib/libc/net/networks
index a6b15d4519b7..a6b15d4519b7 100644
--- a/etc/networks
+++ b/lib/libc/net/networks
diff --git a/etc/nsswitch.conf b/lib/libc/net/nsswitch.conf
index e0f14af76f2d..e0f14af76f2d 100644
--- a/etc/nsswitch.conf
+++ b/lib/libc/net/nsswitch.conf
diff --git a/etc/protocols b/lib/libc/net/protocols
index 05702d430da1..05702d430da1 100644
--- a/etc/protocols
+++ b/lib/libc/net/protocols
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
index 36f3a6a57b1f..36f3a6a57b1f 100644
--- a/etc/mac.conf
+++ b/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
index 109f2e36ad43..109f2e36ad43 100644
--- a/etc/netconfig
+++ b/lib/libc/rpc/netconfig
diff --git a/etc/rpc b/lib/libc/rpc/rpc
index 935ea2f1b592..935ea2f1b592 100644
--- a/etc/rpc
+++ b/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
index ed57ef13a33a..ed57ef13a33a 100644
--- a/etc/opieaccess
+++ b/lib/libopie/opieaccess
diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile
index 48e94a2a078c..f40ba3b28271 100644
--- a/lib/libpmc/Makefile
+++ b/lib/libpmc/Makefile
@@ -7,7 +7,7 @@ SRCS= libpmc.c pmclog.c libpmc_pmu_util.c libpmc_json.cc
INCS= pmc.h pmclog.h pmcformat.h
CFLAGS+= -I${.CURDIR}
-CWARNFLAGS.gcc+= -Wno-shadow
+CWARNFLAGS.gcc+= -Wno-shadow -Wno-cast-align
.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386"
diff --git a/lib/libpmc/libpmc_pmu_util.c b/lib/libpmc/libpmc_pmu_util.c
index 7aaf6f2a5b18..583a2d36bc74 100644
--- a/lib/libpmc/libpmc_pmu_util.c
+++ b/lib/libpmc/libpmc_pmu_util.c
@@ -237,6 +237,7 @@ pmu_parse_event(struct pmu_event_desc *ped, const char *eventin)
return (ENOMEM);
r = event;
bzero(ped, sizeof(*ped));
+ ped->ped_period = DEFAULT_SAMPLE_COUNT;
ped->ped_umask = -1;
while ((kvp = strsep(&event, ",")) != NULL) {
key = strsep(&kvp, "=");
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
index 531d0941001d..531d0941001d 100644
--- a/etc/nsmb.conf
+++ b/lib/libsmb/nsmb.conf
diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h
index 7c34f895b0aa..c3deb562c6d4 100644
--- a/lib/libusb/libusb10.h
+++ b/lib/libusb/libusb10.h
@@ -41,22 +41,24 @@
#define HOTPLUG_LOCK(ctx) pthread_mutex_lock(&(ctx)->hotplug_lock)
#define HOTPLUG_UNLOCK(ctx) pthread_mutex_unlock(&(ctx)->hotplug_lock)
-#define DPRINTF(ctx, dbg, format, args...) do { \
- if ((ctx)->debug == dbg) { \
- switch (dbg) { \
- case LIBUSB_DEBUG_FUNCTION: \
- printf("LIBUSB_FUNCTION: " \
- format "\n", ## args); \
- break; \
- case LIBUSB_DEBUG_TRANSFER: \
- printf("LIBUSB_TRANSFER: " \
- format "\n", ## args); \
- break; \
- default: \
- break; \
- } \
- } \
-} while(0)
+#define DPRINTF(ctx, dbg, format, ...) do { \
+ switch (dbg) { \
+ case LIBUSB_DEBUG_FUNCTION: \
+ if ((ctx)->debug & LIBUSB_DEBUG_FUNCTION) { \
+ printf("LIBUSB_FUNCTION: " \
+ format "\n", ## __VA_ARGS__); \
+ } \
+ break; \
+ case LIBUSB_DEBUG_TRANSFER: \
+ if ((ctx)->debug & LIBUSB_DEBUG_TRANSFER) { \
+ printf("LIBUSB_TRANSFER: " \
+ format "\n", ## __VA_ARGS__); \
+ } \
+ break; \
+ default: \
+ break; \
+ } \
+} while (0)
/* internal structures */
diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c
index 42fbd0e2e30b..53f5b040436d 100644
--- a/lib/libusb/libusb10_io.c
+++ b/lib/libusb/libusb10_io.c
@@ -312,6 +312,9 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
if (tv == NULL) {
pthread_cond_wait(&ctx->ctx_cond,
&ctx->ctx_lock);
+ /* try to grab polling of actual events, if any */
+ if (ctx->ctx_handler == NO_THREAD)
+ ctx->ctx_handler = pthread_self();
return (0);
}
err = clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -330,6 +333,9 @@ libusb_wait_for_event(libusb_context *ctx, struct timeval *tv)
}
err = pthread_cond_timedwait(&ctx->ctx_cond,
&ctx->ctx_lock, &ts);
+ /* try to grab polling of actual events, if any */
+ if (ctx->ctx_handler == NO_THREAD)
+ ctx->ctx_handler = pthread_self();
if (err == ETIMEDOUT)
return (1);
@@ -489,13 +495,26 @@ libusb_control_transfer(libusb_device_handle *devh,
return (actlen);
}
+static libusb_context *
+libusb10_get_context_by_device_handle(libusb_device_handle *devh)
+{
+ libusb_context *ctx;
+
+ if (devh != NULL)
+ ctx = libusb_get_device(devh)->ctx;
+ else
+ ctx = NULL;
+
+ return (GET_CONTEXT(ctx));
+}
+
static void
libusb10_do_transfer_cb(struct libusb_transfer *transfer)
{
libusb_context *ctx;
int *pdone;
- ctx = GET_CONTEXT(NULL);
+ ctx = libusb10_get_context_by_device_handle(transfer->dev_handle);
DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "sync I/O done");
@@ -585,7 +604,8 @@ libusb_bulk_transfer(libusb_device_handle *devh,
libusb_context *ctx;
int ret;
- ctx = GET_CONTEXT(NULL);
+ ctx = libusb10_get_context_by_device_handle(devh);
+
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_bulk_transfer enter");
ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
@@ -603,7 +623,8 @@ libusb_interrupt_transfer(libusb_device_handle *devh,
libusb_context *ctx;
int ret;
- ctx = GET_CONTEXT(NULL);
+ ctx = libusb10_get_context_by_device_handle(devh);
+
DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_interrupt_transfer enter");
ret = libusb10_do_transfer(devh, endpoint, data, length, transferred,
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
index 3e19bc840402..3e19bc840402 100644
--- a/etc/hosts.allow
+++ b/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/aarch64/reloc.c b/libexec/rtld-elf/aarch64/reloc.c
index 2ca13d8c7c86..eb355ea6ff50 100644
--- a/libexec/rtld-elf/aarch64/reloc.c
+++ b/libexec/rtld-elf/aarch64/reloc.c
@@ -218,6 +218,9 @@ reloc_plt(Obj_Entry *obj)
case R_AARCH64_TLSDESC:
reloc_tlsdesc(obj, rela, where);
break;
+ case R_AARCH64_IRELATIVE:
+ obj->irelative = true;
+ break;
default:
_rtld_error("Unknown relocation type %u in PLT",
(unsigned int)ELF_R_TYPE(rela->r_info));
@@ -242,19 +245,22 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
for (rela = obj->pltrela; rela < relalim; rela++) {
- Elf_Addr *where;
+ Elf_Addr *where, target;
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
switch(ELF_R_TYPE(rela->r_info)) {
case R_AARCH64_JUMP_SLOT:
def = find_symdef(ELF_R_SYM(rela->r_info), obj,
&defobj, SYMLOOK_IN_PLT | flags, NULL, lockstate);
- if (def == NULL) {
- dbg("reloc_jmpslots: sym not found");
+ if (def == NULL)
return (-1);
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ obj->gnu_ifunc = true;
+ continue;
}
-
- *where = (Elf_Addr)(defobj->relocbase + def->st_value);
+ target = (Elf_Addr)(defobj->relocbase + def->st_value);
+ reloc_jmpslot(where, target, defobj, obj,
+ (const Elf_Rel *)rela);
break;
case R_AARCH64_TLSDESC:
if (ELF_R_SYM(rela->r_info) != 0) {
@@ -277,8 +283,24 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockState *lockstate)
int
reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
{
+ const Elf_Rela *relalim;
+ const Elf_Rela *rela;
+ Elf_Addr *where, target, *ptr;
- /* XXX not implemented */
+ if (!obj->irelative)
+ return (0);
+ relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
+ for (rela = obj->pltrela; rela < relalim; rela++) {
+ if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE) {
+ ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ lock_release(rtld_bind_lock, lockstate);
+ target = call_ifunc_resolver(ptr);
+ wlock_acquire(rtld_bind_lock, lockstate);
+ *where = target;
+ }
+ }
+ obj->irelative = false;
return (0);
}
@@ -286,8 +308,32 @@ int
reloc_gnu_ifunc(Obj_Entry *obj, int flags,
struct Struct_RtldLockState *lockstate)
{
+ const Elf_Rela *relalim;
+ const Elf_Rela *rela;
+ Elf_Addr *where, target;
+ const Elf_Sym *def;
+ const Obj_Entry *defobj;
- /* XXX not implemented */
+ if (!obj->gnu_ifunc)
+ return (0);
+ relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
+ for (rela = obj->pltrela; rela < relalim; rela++) {
+ if (ELF_R_TYPE(rela->r_info) == R_AARCH64_JUMP_SLOT) {
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
+ SYMLOOK_IN_PLT | flags, NULL, lockstate);
+ if (def == NULL)
+ return (-1);
+ if (ELF_ST_TYPE(def->st_info) != STT_GNU_IFUNC)
+ continue;
+ lock_release(rtld_bind_lock, lockstate);
+ target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
+ wlock_acquire(rtld_bind_lock, lockstate);
+ reloc_jmpslot(where, target, defobj, obj,
+ (const Elf_Rel *)rela);
+ }
+ }
+ obj->gnu_ifunc = false;
return (0);
}
@@ -296,7 +342,8 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
const Obj_Entry *obj, const Elf_Rel *rel)
{
- assert(ELF_R_TYPE(rel->r_info) == R_AARCH64_JUMP_SLOT);
+ assert(ELF_R_TYPE(rel->r_info) == R_AARCH64_JUMP_SLOT ||
+ ELF_R_TYPE(rel->r_info) == R_AARCH64_IRELATIVE);
if (*where != target && !ld_bind_not)
*where = target;
@@ -327,12 +374,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
const Elf_Rela *rela;
const Elf_Sym *def;
SymCache *cache;
- Elf_Addr *where;
- unsigned long symnum;
-
- if ((flags & SYMLOOK_IFUNC) != 0)
- /* XXX not implemented */
- return (0);
+ Elf_Addr *where, symval;
/*
* The dynamic loader may be called from a thread, we have
@@ -346,19 +388,62 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
relalim = (const Elf_Rela *)((caddr_t)obj->rela + obj->relasize);
for (rela = obj->rela; rela < relalim; rela++) {
- where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- symnum = ELF_R_SYM(rela->r_info);
-
+ /*
+ * First, resolve symbol for relocations which
+ * reference symbols.
+ */
switch (ELF_R_TYPE(rela->r_info)) {
case R_AARCH64_ABS64:
case R_AARCH64_GLOB_DAT:
- def = find_symdef(symnum, obj, &defobj, flags, cache,
- lockstate);
+ case R_AARCH64_TLS_TPREL64:
+ def = find_symdef(ELF_R_SYM(rela->r_info), obj,
+ &defobj, flags, cache, lockstate);
if (def == NULL)
return (-1);
+ /*
+ * If symbol is IFUNC, only perform relocation
+ * when caller allowed it by passing
+ * SYMLOOK_IFUNC flag. Skip the relocations
+ * otherwise.
+ *
+ * Also error out in case IFUNC relocations
+ * are specified for TLS, which cannot be
+ * usefully interpreted.
+ */
+ if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_AARCH64_ABS64:
+ case R_AARCH64_GLOB_DAT:
+ if ((flags & SYMLOOK_IFUNC) == 0) {
+ obj->non_plt_gnu_ifunc = true;
+ continue;
+ }
+ symval = (Elf_Addr)rtld_resolve_ifunc(
+ defobj, def);
+ break;
+ default:
+ _rtld_error("%s: IFUNC for TLS reloc",
+ obj->path);
+ return (-1);
+ }
+ } else {
+ if ((flags & SYMLOOK_IFUNC) != 0)
+ continue;
+ symval = (Elf_Addr)defobj->relocbase +
+ def->st_value;
+ }
+ break;
+ default:
+ if ((flags & SYMLOOK_IFUNC) != 0)
+ continue;
+ }
- *where = (Elf_Addr)defobj->relocbase + def->st_value +
- rela->r_addend;
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+
+ switch (ELF_R_TYPE(rela->r_info)) {
+ case R_AARCH64_ABS64:
+ case R_AARCH64_GLOB_DAT:
+ *where = symval + rela->r_addend;
break;
case R_AARCH64_COPY:
/*
@@ -377,11 +462,6 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
reloc_tlsdesc(obj, rela, where);
break;
case R_AARCH64_TLS_TPREL64:
- def = find_symdef(symnum, obj, &defobj, flags, cache,
- lockstate);
- if (def == NULL)
- return (-1);
-
/*
* We lazily allocate offsets for static TLS as we
* see the first relocation that references the
diff --git a/libexec/rtld-elf/aarch64/rtld_machdep.h b/libexec/rtld-elf/aarch64/rtld_machdep.h
index 9ff53d900aaa..9cc0f2443318 100644
--- a/libexec/rtld-elf/aarch64/rtld_machdep.h
+++ b/libexec/rtld-elf/aarch64/rtld_machdep.h
@@ -59,8 +59,16 @@ Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define call_init_pointer(obj, target) \
(((InitArrFunc)(target))(main_argc, main_argv, environ))
+/*
+ * Pass zeros into the ifunc resolver so we can change them later. The first
+ * 8 arguments on arm64 are passed in registers so make them known values
+ * if we decide to use them later. Because of this ifunc resolvers can assume
+ * no arguments are passeed in, and if this changes later will be able to
+ * compare the argument with 0 to see if it is set.
+ */
#define call_ifunc_resolver(ptr) \
- (((Elf_Addr (*)(void))ptr)())
+ (((Elf_Addr (*)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, \
+ uint64_t, uint64_t, uint64_t))ptr)(0, 0, 0, 0, 0, 0, 0, 0))
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
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
index b2c91b29f777..b2c91b29f777 100644
--- a/etc/libmap.conf
+++ b/libexec/rtld-elf/libmap.conf
diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c
index 09c305089c19..3c157b23f2fa 100644
--- a/libexec/rtld-elf/powerpc/reloc.c
+++ b/libexec/rtld-elf/powerpc/reloc.c
@@ -258,7 +258,7 @@ reloc_nonplt_object(Obj_Entry *obj_rtld, Obj_Entry *obj, const Elf_Rela *rela,
*(Elf_Addr **)where = *where * sizeof(Elf_Addr)
+ (Elf_Addr *)(def->st_value + rela->r_addend
- + defobj->tlsoffset - TLS_TP_OFFSET);
+ + defobj->tlsoffset - TLS_TP_OFFSET - TLS_TCB_SIZE);
break;
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 @@ cleanup1:
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 @@ cleanup1:
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/Makefile b/release/Makefile
index 79d53b4cbb61..6eddf11d7231 100644
--- a/release/Makefile
+++ b/release/Makefile
@@ -90,6 +90,15 @@ EXTRA_PACKAGES+= src.txz
.endif
.if !defined(NODOC)
EXTRA_PACKAGES+= reldoc
+. if !defined(SVN) || empty(SVN)
+. for S in svn svnlite
+. for D in /usr/local/bin /usr/bin
+. if(exists(${D}/${S}))
+SVN?= ${D}/${S}
+. endif
+. endfor
+. endfor
+. endif
.endif
RELEASE_TARGETS= ftp
@@ -164,6 +173,7 @@ ports.txz:
reldoc:
cd ${DOCDIR}/en_US.ISO8859-1/htdocs/releases/${REVISION}R && \
env MAN4DIR=${WORLDDIR}/share/man/man4 \
+ SVN=${SVN} \
${MAKE} all install clean "FORMATS=html txt" \
INSTALL_COMPRESSED='' URLS_ABSOLUTE=YES DOCDIR=${.OBJDIR}/rdoc \
WEBDIR=${DOCDIR} DESTDIR=${.OBJDIR}/rdoc
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
index b9bf610d597f..b9bf610d597f 100644
--- a/etc/disktab
+++ b/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/fsck_ffs/pass5.c b/sbin/fsck_ffs/pass5.c
index 0da8998f9b51..71e3eda74c1b 100644
--- a/sbin/fsck_ffs/pass5.c
+++ b/sbin/fsck_ffs/pass5.c
@@ -186,7 +186,7 @@ pass5(void)
cg->cg_ckhash = 0;
thishash = calculate_crc32c(~0L, cg, fs->fs_cgsize);
if (ckhash != thishash)
- pwarn("CG %d: BAD CHECK-HASH %#x vs %#x",
+ pwarn("CG %d: BAD CHECK-HASH %#x vs %#x\n",
c, ckhash, thishash);
cg->cg_ckhash = ckhash;
}
diff --git a/sbin/geom/core/geom.8 b/sbin/geom/core/geom.8
index 8cd88cb7792f..298fc2b1d4fd 100644
--- a/sbin/geom/core/geom.8
+++ b/sbin/geom/core/geom.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd September 13, 2018
+.Dd September 14, 2018
.Dt GEOM 8
.Os
.Sh NAME
@@ -55,6 +55,8 @@
.Nm
.Fl p
.Ar provider-name
+.Nm
+.Fl t
.Sh DESCRIPTION
The
.Nm
@@ -111,6 +113,8 @@ Additional options include:
.It Fl p Ar provider-name
Print detailed information about the geom which provides
.Ar provider-name .
+.It Fl t
+Display geoms hierarchy as a tree.
.El
.Pp
Class-specific commands are implemented as shared libraries which
diff --git a/sbin/geom/core/geom.c b/sbin/geom/core/geom.c
index 9f1655c61a51..e6d6d789908f 100644
--- a/sbin/geom/core/geom.c
+++ b/sbin/geom/core/geom.c
@@ -66,8 +66,11 @@ static uint32_t *version = NULL;
static int verbose = 0;
static struct g_command *class_commands = NULL;
-#define GEOM_CLASS_CMDS 0x01
-#define GEOM_STD_CMDS 0x02
+#define GEOM_CLASS_CMDS 0x01
+#define GEOM_STD_CMDS 0x02
+
+#define GEOM_CLASS_WIDTH 10
+
static struct g_command *find_command(const char *cmdstr, int flags);
static void list_one_geom_by_provider(const char *provider_name);
static int std_available(const char *name);
@@ -149,6 +152,7 @@ usage(void)
if (class_name == NULL) {
fprintf(stderr, "usage: geom <class> <command> [options]\n");
fprintf(stderr, " geom -p <provider-name>\n");
+ fprintf(stderr, " geom -t\n");
exit(EXIT_FAILURE);
} else {
struct g_command *cmd;
@@ -672,22 +676,142 @@ find_geom_by_provider(struct gmesh *mesh, const char *name)
return (NULL);
}
+static int
+compute_tree_width_geom(struct gmesh *mesh, struct ggeom *gp, int indent)
+{
+ struct gclass *classp2;
+ struct ggeom *gp2;
+ struct gconsumer *cp2;
+ struct gprovider *pp;
+ int max_width, width;
+
+ max_width = width = indent + strlen(gp->lg_name);
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ LIST_FOREACH(classp2, &mesh->lg_class, lg_class) {
+ LIST_FOREACH(gp2, &classp2->lg_geom, lg_geom) {
+ LIST_FOREACH(cp2,
+ &gp2->lg_consumer, lg_consumer) {
+ if (pp != cp2->lg_provider)
+ continue;
+ width = compute_tree_width_geom(mesh,
+ gp2, indent + 2);
+ if (width > max_width)
+ max_width = width;
+ }
+ }
+ }
+ }
+
+ return (max_width);
+}
+
+static int
+compute_tree_width(struct gmesh *mesh)
+{
+ struct gclass *classp;
+ struct ggeom *gp;
+ int max_width, width;
+
+ max_width = width = 0;
+
+ LIST_FOREACH(classp, &mesh->lg_class, lg_class) {
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ if (!LIST_EMPTY(&gp->lg_consumer))
+ continue;
+ width = compute_tree_width_geom(mesh, gp, 0);
+ if (width > max_width)
+ max_width = width;
+ }
+ }
+
+ return (max_width);
+}
+
+static void
+show_tree_geom(struct gmesh *mesh, struct ggeom *gp, int indent, int width)
+{
+ struct gclass *classp2;
+ struct ggeom *gp2;
+ struct gconsumer *cp2;
+ struct gprovider *pp;
+
+ if (LIST_EMPTY(&gp->lg_provider)) {
+ printf("%*s%-*.*s %-*.*s\n", indent, "",
+ width - indent, width - indent, gp->lg_name,
+ GEOM_CLASS_WIDTH, GEOM_CLASS_WIDTH, gp->lg_class->lg_name);
+ return;
+ }
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ printf("%*s%-*.*s %-*.*s %s\n", indent, "",
+ width - indent, width - indent, gp->lg_name,
+ GEOM_CLASS_WIDTH, GEOM_CLASS_WIDTH, gp->lg_class->lg_name,
+ pp->lg_name);
+
+ LIST_FOREACH(classp2, &mesh->lg_class, lg_class) {
+ LIST_FOREACH(gp2, &classp2->lg_geom, lg_geom) {
+ LIST_FOREACH(cp2,
+ &gp2->lg_consumer, lg_consumer) {
+ if (pp != cp2->lg_provider)
+ continue;
+ show_tree_geom(mesh, gp2,
+ indent + 2, width);
+ }
+ }
+ }
+ }
+}
+
+static void
+show_tree(void)
+{
+ struct gmesh mesh;
+ struct gclass *classp;
+ struct ggeom *gp;
+ int error, width;
+
+ error = geom_gettree(&mesh);
+ if (error != 0)
+ errc(EXIT_FAILURE, error, "Cannot get GEOM tree");
+
+ width = compute_tree_width(&mesh);
+
+ printf("%-*.*s %-*.*s %s\n",
+ width, width, "Geom",
+ GEOM_CLASS_WIDTH, GEOM_CLASS_WIDTH, "Class",
+ "Provider");
+
+ LIST_FOREACH(classp, &mesh.lg_class, lg_class) {
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ if (!LIST_EMPTY(&gp->lg_consumer))
+ continue;
+ show_tree_geom(&mesh, gp, 0, width);
+ }
+ }
+}
+
int
main(int argc, char *argv[])
{
char *provider_name;
+ bool tflag;
int ch;
provider_name = NULL;
+ tflag = false;
if (strcmp(getprogname(), "geom") == 0) {
- while ((ch = getopt(argc, argv, "hp:")) != -1) {
+ while ((ch = getopt(argc, argv, "hp:t")) != -1) {
switch (ch) {
case 'p':
provider_name = strdup(optarg);
if (provider_name == NULL)
err(1, "strdup");
break;
+ case 't':
+ tflag = true;
+ break;
case 'h':
default:
usage();
@@ -699,11 +823,21 @@ main(int argc, char *argv[])
*/
}
+ if (tflag && provider_name != NULL) {
+ errx(EXIT_FAILURE,
+ "At most one of -P and -t may be specified.");
+ }
+
if (provider_name != NULL) {
list_one_geom_by_provider(provider_name);
return (0);
}
+ if (tflag) {
+ show_tree();
+ return (0);
+ }
+
get_class(&argc, &argv);
run_command(argc, argv);
/* NOTREACHED */
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..9e5e02ab29d5 100755
--- a/sbin/init/rc.d/ldconfig
+++ b/sbin/init/rc.d/ldconfig
@@ -41,7 +41,7 @@ ldconfig_start()
${ldconfig} -elf ${_ins} ${_LDC}
case `sysctl -n hw.machine_arch` in
- amd64|powerpc64)
+ amd64|mips64|powerpc64)
for i in ${ldconfig_local32_dirs}; do
if [ -d "${i}" ]; then
_files=`find ${i} -type f`
@@ -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/reboot/reboot.c b/sbin/reboot/reboot.c
index 28b84ff25bce..4dcade7611c2 100644
--- a/sbin/reboot/reboot.c
+++ b/sbin/reboot/reboot.c
@@ -73,7 +73,7 @@ main(int argc, char *argv[])
u_int pageins;
const char *user, *kernel = NULL;
- if (strcmp(getprogname(), "halt") == 0) {
+ if (strstr(getprogname(), "halt") != NULL) {
dohalt = 1;
howto = RB_HALT;
} else
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 3ee1da7faa2d..e71be39bae56 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/MODULE_PNP_INFO.9 b/share/man/man9/MODULE_PNP_INFO.9
index a71800c1a510..4c605e3627ce 100644
--- a/share/man/man9/MODULE_PNP_INFO.9
+++ b/share/man/man9/MODULE_PNP_INFO.9
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 12, 2018
+.Dd October 2, 2018
.Dt MODULE_PNP_INFO 9
.Os
.Sh NAME
@@ -113,7 +113,7 @@ A pointer that should be ignored.
.It Dq Vt E
EISA PNP Identifier.
.It Dq Vt T
-PNP info that's true for the for the whole table.
+PNP info that is true for the whole table.
The driver code checks for these condition pragmatically before using
this table to match devices.
This item must come last in the list.
@@ -157,9 +157,18 @@ included in
.Fa num_entries .
.\"
.Sh EXAMPLES
-.Bd -literal -offset indent -compact
+.Bl -tag -width ""
+.It Sy Example 1\&: No Using W32 for vendor/device pair
+.Pp
+The following example shows usage of
+.Vt W32
+type when vendor/device values are combined into single
+.Vt uint32_t
+value:
+.Bd -literal
#include <sys/param.h>
#include <sys/module.h>
+
static struct my_pciids {
uint32_t devid;
const char *desc;
@@ -168,14 +177,35 @@ static struct my_pciids {
{ 0x9abcdef0, "Baz fizz" },
};
-MODULE_PNP_INFO("W32:vendor/device", pci, my_driver, my_ids, sizeof(my_ids[0]),
- nitems(my_ids));
+MODULE_PNP_INFO("W32:vendor/device;D:#", pci, my_driver, my_ids,
+ sizeof(my_ids[0]), nitems(my_ids));
+.Ed
+.It Sy Example 2\&: No Using T for common vendor value
+.Pp
+The following example shows usage of
+.Vt T
+type when all entries in the table have the same vendor value:
+.Bd -literal
+#include <sys/param.h>
+#include <sys/module.h>
+
+static struct my_pciids {
+ uint16_t device;
+ const char *desc;
+} my_ids[] = {
+ { 0x9abc, "Foo bar" },
+ { 0xdef0, "Baz fizz" },
+};
+
+MODULE_PNP_INFO("U16:device;D:#;T:vendor=0x1234", pci, my_driver,
+ my_ids, sizeof(my_ids[0]), nitems(my_ids));
.Ed
+.El
.\"
.Sh SEE ALSO
-.Xr module 9 ,
+.Xr devmatch 8 ,
.Xr DRIVER_MODULE 9 ,
-.Xr devmatch 8
+.Xr module 9
.Sh HISTORY
The macro
.Nm
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 5454095df8a6..5b585ed12603 100644
--- a/share/mk/bsd.sys.mk
+++ b/share/mk/bsd.sys.mk
@@ -250,8 +250,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..d6f1d8e4b5b6 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" || ${__T} == "powerpc64"
+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/menu.lua b/stand/lua/menu.lua
index 9824c3ebb7e3..cd45238b44a7 100644
--- a/stand/lua/menu.lua
+++ b/stand/lua/menu.lua
@@ -401,8 +401,22 @@ function menu.process(menudef, keypress)
end
function menu.run()
+ local delay = loader.getenv("autoboot_delay")
+
+ if delay ~= nil and delay:lower() == "no" then
+ delay = nil
+ else
+ delay = tonumber(delay) or 10
+ end
+
+ if delay == -1 then
+ core.boot()
+ return
+ end
+
menu.draw(menu.default)
- local autoboot_key = menu.autoboot()
+
+ local autoboot_key = menu.autoboot(delay)
menu.process(menu.default, autoboot_key)
drawn_menu = nil
@@ -411,19 +425,15 @@ function menu.run()
print("Exiting menu!")
end
-function menu.autoboot()
- local ab = loader.getenv("autoboot_delay")
- if ab ~= nil and ab:lower() == "no" then
+function menu.autoboot(delay)
+ -- If we've specified a nil delay, we can do nothing but assume that
+ -- we aren't supposed to be autobooting.
+ if delay == nil then
return nil
- elseif tonumber(ab) == -1 then
- core.boot()
end
- ab = tonumber(ab) or 10
-
local x = loader.getenv("loader_menu_timeout_x") or 4
local y = loader.getenv("loader_menu_timeout_y") or 23
-
- local endtime = loader.time() + ab
+ local endtime = loader.time() + delay
local time
local last
repeat
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/machdep.c b/sys/amd64/amd64/machdep.c
index 092dc095bf65..dc174e85a61f 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1581,6 +1581,21 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
*/
identify_cpu2();
+ /*
+ * Check for pti, pcid, and invpcid before ifuncs are
+ * resolved, to correctly select the implementation for
+ * pmap_activate_sw_mode().
+ */
+ pti = pti_get_default();
+ TUNABLE_INT_FETCH("vm.pmap.pti", &pti);
+ TUNABLE_INT_FETCH("vm.pmap.pcid_enabled", &pmap_pcid_enabled);
+ if ((cpu_feature2 & CPUID2_PCID) != 0 && pmap_pcid_enabled) {
+ invpcid_works = (cpu_stdext_feature &
+ CPUID_STDEXT_INVPCID) != 0;
+ } else {
+ pmap_pcid_enabled = 0;
+ }
+
link_elf_ireloc(kmdp);
/*
@@ -1645,9 +1660,6 @@ hammer_time(u_int64_t modulep, u_int64_t physfree)
mtx_init(&dt_lock, "descriptor tables", NULL, MTX_DEF);
/* exceptions */
- pti = pti_get_default();
- TUNABLE_INT_FETCH("vm.pmap.pti", &pti);
-
for (x = 0; x < NIDT; x++)
setidt(x, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_SYSIGT,
SEL_KPL, 0);
@@ -2693,3 +2705,12 @@ DEFINE_IFUNC(, void *, memcpy, (void * _Nonnull, const void * _Nonnull, size_t),
return ((cpu_stdext_feature & CPUID_STDEXT_ERMS) != 0 ?
memcpy_erms : memcpy_std);
}
+
+void pagezero_std(void *addr);
+void pagezero_erms(void *addr);
+DEFINE_IFUNC(, void , pagezero, (void *), static)
+{
+
+ return ((cpu_stdext_feature & CPUID_STDEXT_ERMS) != 0 ?
+ pagezero_erms : pagezero_std);
+}
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 8cb09df626be..bab8072d9ec1 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -146,6 +146,7 @@ __FBSDID("$FreeBSD$");
#include <machine/intr_machdep.h>
#include <x86/apicvar.h>
+#include <x86/ifunc.h>
#include <machine/cpu.h>
#include <machine/cputypes.h>
#include <machine/md_var.h>
@@ -647,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);
@@ -1093,9 +1098,11 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
vm_offset_t va;
pt_entry_t *pte;
uint64_t cr4;
+ u_long res;
int i;
KERNend = *firstaddr;
+ res = atop(KERNend - (vm_paddr_t)kernphys);
if (!pti)
pg_g = X86_PG_G;
@@ -1115,10 +1122,8 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
vm_phys_add_seg(KPTphys, KPTphys + ptoa(nkpt));
virtual_avail = (vm_offset_t) KERNBASE + *firstaddr;
-
virtual_end = VM_MAX_KERNEL_ADDRESS;
-
/*
* Enable PG_G global pages, then switch to the kernel page
* table from the bootstrap page table. After the switch, it
@@ -1137,6 +1142,8 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
/*
* Initialize the kernel pmap (which is statically allocated).
+ * Count bootstrap data as being resident in case any of this data is
+ * later unmapped (using pmap_remove()) and freed.
*/
PMAP_LOCK_INIT(kernel_pmap);
kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys);
@@ -1144,6 +1151,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
kernel_pmap->pm_ucr3 = PMAP_NO_CR3;
CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */
TAILQ_INIT(&kernel_pmap->pm_pvchunk);
+ kernel_pmap->pm_stats.resident_count = res;
kernel_pmap->pm_flags = pmap_flags;
/*
@@ -1179,11 +1187,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
pmap_init_pat();
/* Initialize TLB Context Id. */
- TUNABLE_INT_FETCH("vm.pmap.pcid_enabled", &pmap_pcid_enabled);
- if ((cpu_feature2 & CPUID2_PCID) != 0 && pmap_pcid_enabled) {
- /* Check for INVPCID support */
- invpcid_works = (cpu_stdext_feature & CPUID_STDEXT_INVPCID)
- != 0;
+ if (pmap_pcid_enabled) {
for (i = 0; i < MAXCPU; i++) {
kernel_pmap->pm_pcids[i].pm_pcid = PMAP_PCID_KERN;
kernel_pmap->pm_pcids[i].pm_gen = 1;
@@ -1204,8 +1208,6 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
* during pcpu setup.
*/
load_cr4(rcr4() | CR4_PCIDE);
- } else {
- pmap_pcid_enabled = 0;
}
}
@@ -1423,7 +1425,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);
}
@@ -1705,15 +1707,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;
@@ -1725,73 +1812,93 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
sched_pin();
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);
+ smp_masked_invlpg(pmap_invalidate_cpu_mask(pmap), 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;
@@ -1806,122 +1913,119 @@ 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);
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);
+ smp_masked_invlpg_range(pmap_invalidate_cpu_mask(pmap), sva, eva, pmap);
sched_unpin();
}
-void
-pmap_invalidate_all(pmap_t pmap)
+static inline void
+pmap_invalidate_all_pcid(pmap_t pmap, bool invpcid_works1)
{
- 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);
- return;
- }
-
- KASSERT(pmap->pm_type == PT_X86,
- ("pmap_invalidate_all: invalid type %d", pmap->pm_type));
-
- sched_pin();
if (pmap == kernel_pmap) {
- if (pmap_pcid_enabled && invpcid_works) {
+ if (invpcid_works1) {
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;
+ 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);
- 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();
+ 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);
+ }
}
- } else if (pmap_pcid_enabled) {
+ critical_exit();
+ } else
pmap->pm_pcids[cpuid].pm_gen = 0;
+ CPU_FOREACH(i) {
+ if (cpuid != i)
+ pmap->pm_pcids[i].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);
+ /* 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)
+{
+
+ if (pmap_type_guest(pmap)) {
+ pmap_invalidate_ept(pmap);
+ return;
+ }
+
+ KASSERT(pmap->pm_type == PT_X86,
+ ("pmap_invalidate_all: invalid type %d", pmap->pm_type));
+
+ sched_pin();
+ pmap_invalidate_all_mode(pmap);
+ smp_masked_invltlb(pmap_invalidate_cpu_mask(pmap), pmap);
sched_unpin();
}
@@ -2176,36 +2280,62 @@ pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde)
pmap_invalidate_page(pmap, va);
}
+DEFINE_IFUNC(, void, pmap_invalidate_cache_range,
+ (vm_offset_t sva, vm_offset_t eva), static)
+{
+
+ 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)
-void
-pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force)
+static void
+pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva)
{
- 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"));
- }
+ 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 && !force)
- ; /* If "Self Snoop" is supported and allowed, do nothing. */
- else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 &&
- eva - sva < PMAP_CLFLUSH_THRESHOLD) {
+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) {
/*
- * 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.
+ * The supplied range is bigger than 2MB.
+ * Globally invalidate cache.
*/
- if (pmap_kextract(sva) == lapic_paddr)
- return;
+ pmap_invalidate_cache();
+ 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
@@ -2215,10 +2345,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.
*/
@@ -2228,17 +2355,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.
*
@@ -6931,7 +7058,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));
@@ -6943,7 +7070,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));
}
@@ -7302,7 +7429,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);
}
@@ -7441,17 +7568,176 @@ pmap_pcid_alloc(pmap_t pmap, u_int cpuid)
return (0);
}
+static uint64_t
+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 < 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 ||
+ pmap == kernel_pmap,
+ ("non-kernel pmap pmap %p cpu %d pcid %#x",
+ pmap, cpuid, pmap->pm_pcids[cpuid].pm_pcid));
+ return (cached);
+}
+
+static void
+pmap_activate_sw_pti_post(pmap_t pmap)
+{
+
+ if (pmap->pm_ucr3 != PMAP_NO_CR3)
+ PCPU_GET(tssp)->tss_rsp0 = ((vm_offset_t)PCPU_PTR(pti_stack) +
+ PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful;
+}
+
+static void inline
+pmap_activate_sw_pcid_pti(pmap_t pmap, u_int cpuid, const bool invpcid_works1)
+{
+ struct invpcid_descr d;
+ uint64_t cached, cr3, kcr3, ucr3;
+
+ cached = pmap_pcid_alloc_checked(pmap, cpuid);
+ cr3 = rcr3();
+ if ((cr3 & ~CR3_PCID_MASK) != pmap->pm_cr3)
+ load_cr3(pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid);
+ PCPU_SET(curpmap, pmap);
+ kcr3 = pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid;
+ ucr3 = pmap->pm_ucr3 | pmap->pm_pcids[cpuid].pm_pcid |
+ PMAP_PCID_USER_PT;
+
+ if (!cached && pmap->pm_ucr3 != PMAP_NO_CR3) {
+ /*
+ * Explicitly invalidate translations cached from the
+ * user page table. They are not automatically
+ * flushed by reload of cr3 with the kernel page table
+ * pointer above.
+ *
+ * Note that the if() condition is resolved statically
+ * by using the function argument instead of
+ * runtime-evaluated invpcid_works value.
+ */
+ if (invpcid_works1) {
+ d.pcid = PMAP_PCID_USER_PT |
+ pmap->pm_pcids[cpuid].pm_pcid;
+ d.pad = 0;
+ d.addr = 0;
+ invpcid(&d, INVPCID_CTX);
+ } else {
+ pmap_pti_pcid_invalidate(ucr3, kcr3);
+ }
+ }
+
+ PCPU_SET(kcr3, kcr3 | CR3_PCID_SAVE);
+ PCPU_SET(ucr3, ucr3 | CR3_PCID_SAVE);
+ if (cached)
+ PCPU_INC(pm_save_cnt);
+}
+
+static void
+pmap_activate_sw_pcid_invpcid_pti(pmap_t pmap, u_int cpuid)
+{
+
+ pmap_activate_sw_pcid_pti(pmap, cpuid, true);
+ pmap_activate_sw_pti_post(pmap);
+}
+
+static void
+pmap_activate_sw_pcid_noinvpcid_pti(pmap_t pmap, u_int cpuid)
+{
+ register_t rflags;
+
+ /*
+ * If the INVPCID instruction is not available,
+ * invltlb_pcid_handler() is used to handle an invalidate_all
+ * IPI, which checks for curpmap == smp_tlb_pmap. The below
+ * sequence of operations has a window where %CR3 is loaded
+ * with the new pmap's PML4 address, but the curpmap value has
+ * not yet been updated. This causes the invltlb IPI handler,
+ * which is called between the updates, to execute as a NOP,
+ * which leaves stale TLB entries.
+ *
+ * Note that the most typical use of pmap_activate_sw(), from
+ * the context switch, is immune to this race, because
+ * interrupts are disabled (while the thread lock is owned),
+ * and the IPI happens after curpmap is updated. Protect
+ * other callers in a similar way, by disabling interrupts
+ * around the %cr3 register reload and curpmap assignment.
+ */
+ rflags = intr_disable();
+ pmap_activate_sw_pcid_pti(pmap, cpuid, false);
+ intr_restore(rflags);
+ pmap_activate_sw_pti_post(pmap);
+}
+
+static void
+pmap_activate_sw_pcid_nopti(pmap_t pmap, u_int cpuid)
+{
+ uint64_t cached, cr3;
+
+ cached = pmap_pcid_alloc_checked(pmap, cpuid);
+ cr3 = rcr3();
+ if (!cached || (cr3 & ~CR3_PCID_MASK) != pmap->pm_cr3)
+ load_cr3(pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid |
+ cached);
+ PCPU_SET(curpmap, pmap);
+ if (cached)
+ PCPU_INC(pm_save_cnt);
+}
+
+static void
+pmap_activate_sw_pcid_noinvpcid_nopti(pmap_t pmap, u_int cpuid)
+{
+ register_t rflags;
+
+ rflags = intr_disable();
+ pmap_activate_sw_pcid_nopti(pmap, cpuid);
+ intr_restore(rflags);
+}
+
+static void
+pmap_activate_sw_nopcid_nopti(pmap_t pmap, u_int cpuid __unused)
+{
+
+ load_cr3(pmap->pm_cr3);
+ PCPU_SET(curpmap, pmap);
+}
+
+static void
+pmap_activate_sw_nopcid_pti(pmap_t pmap, u_int cpuid __unused)
+{
+
+ pmap_activate_sw_nopcid_nopti(pmap, cpuid);
+ PCPU_SET(kcr3, pmap->pm_cr3);
+ PCPU_SET(ucr3, pmap->pm_ucr3);
+ pmap_activate_sw_pti_post(pmap);
+}
+
+DEFINE_IFUNC(static, void, pmap_activate_sw_mode, (pmap_t, u_int), static)
+{
+
+ if (pmap_pcid_enabled && pti && invpcid_works)
+ return (pmap_activate_sw_pcid_invpcid_pti);
+ else if (pmap_pcid_enabled && pti && !invpcid_works)
+ return (pmap_activate_sw_pcid_noinvpcid_pti);
+ else if (pmap_pcid_enabled && !pti && invpcid_works)
+ return (pmap_activate_sw_pcid_nopti);
+ else if (pmap_pcid_enabled && !pti && !invpcid_works)
+ return (pmap_activate_sw_pcid_noinvpcid_nopti);
+ else if (!pmap_pcid_enabled && pti)
+ return (pmap_activate_sw_nopcid_pti);
+ else /* if (!pmap_pcid_enabled && !pti) */
+ return (pmap_activate_sw_nopcid_nopti);
+}
+
void
pmap_activate_sw(struct thread *td)
{
pmap_t oldpmap, pmap;
- struct invpcid_descr d;
- uint64_t cached, cr3, kcr3, kern_pti_cached, rsp0, ucr3;
- register_t rflags;
u_int cpuid;
- struct amd64tss *tssp;
- rflags = 0;
oldpmap = PCPU_GET(curpmap);
pmap = vmspace_pmap(td->td_proc->p_vmspace);
if (oldpmap == pmap)
@@ -7462,91 +7748,7 @@ pmap_activate_sw(struct thread *td)
#else
CPU_SET(cpuid, &pmap->pm_active);
#endif
- cr3 = rcr3();
- if (pmap_pcid_enabled) {
- cached = pmap_pcid_alloc(pmap, cpuid);
- KASSERT(pmap->pm_pcids[cpuid].pm_pcid >= 0 &&
- 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 ||
- pmap == kernel_pmap,
- ("non-kernel pmap thread %p pmap %p cpu %d pcid %#x",
- td, pmap, cpuid, pmap->pm_pcids[cpuid].pm_pcid));
-
- /*
- * If the INVPCID instruction is not available,
- * invltlb_pcid_handler() is used for handle
- * invalidate_all IPI, which checks for curpmap ==
- * smp_tlb_pmap. Below operations sequence has a
- * window where %CR3 is loaded with the new pmap's
- * PML4 address, but curpmap value is not yet updated.
- * This causes invltlb IPI handler, called between the
- * updates, to execute as NOP, which leaves stale TLB
- * entries.
- *
- * Note that the most typical use of
- * pmap_activate_sw(), from the context switch, is
- * immune to this race, because interrupts are
- * disabled (while the thread lock is owned), and IPI
- * happens after curpmap is updated. Protect other
- * callers in a similar way, by disabling interrupts
- * around the %cr3 register reload and curpmap
- * assignment.
- */
- if (!invpcid_works)
- rflags = intr_disable();
-
- kern_pti_cached = pti ? 0 : cached;
- if (!kern_pti_cached || (cr3 & ~CR3_PCID_MASK) != pmap->pm_cr3) {
- load_cr3(pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid |
- kern_pti_cached);
- }
- PCPU_SET(curpmap, pmap);
- if (pti) {
- kcr3 = pmap->pm_cr3 | pmap->pm_pcids[cpuid].pm_pcid;
- ucr3 = pmap->pm_ucr3 | pmap->pm_pcids[cpuid].pm_pcid |
- PMAP_PCID_USER_PT;
-
- if (!cached && pmap->pm_ucr3 != PMAP_NO_CR3) {
- /*
- * Manually invalidate translations cached
- * from the user page table. They are not
- * flushed by reload of cr3 with the kernel
- * page table pointer above.
- */
- if (invpcid_works) {
- d.pcid = PMAP_PCID_USER_PT |
- pmap->pm_pcids[cpuid].pm_pcid;
- d.pad = 0;
- d.addr = 0;
- invpcid(&d, INVPCID_CTX);
- } else {
- pmap_pti_pcid_invalidate(ucr3, kcr3);
- }
- }
-
- PCPU_SET(kcr3, kcr3 | CR3_PCID_SAVE);
- PCPU_SET(ucr3, ucr3 | CR3_PCID_SAVE);
- }
- if (!invpcid_works)
- intr_restore(rflags);
- if (cached)
- PCPU_INC(pm_save_cnt);
- } else {
- load_cr3(pmap->pm_cr3);
- PCPU_SET(curpmap, pmap);
- if (pti) {
- PCPU_SET(kcr3, pmap->pm_cr3);
- PCPU_SET(ucr3, pmap->pm_ucr3);
- }
- }
- if (pmap->pm_ucr3 != PMAP_NO_CR3) {
- rsp0 = ((vm_offset_t)PCPU_PTR(pti_stack) +
- PC_PTI_STACK_SZ * sizeof(uint64_t)) & ~0xful;
- tssp = PCPU_GET(tssp);
- tssp->tss_rsp0 = rsp0;
- }
+ pmap_activate_sw_mode(pmap, cpuid);
#ifdef SMP
CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active);
#else
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index db89a6fadd3c..f0086e298ea5 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -41,7 +41,7 @@
.text
/* Address: %rdi */
-ENTRY(pagezero)
+ENTRY(pagezero_std)
PUSH_FRAME_POINTER
movq $PAGE_SIZE/8,%rcx
xorl %eax,%eax
@@ -49,7 +49,17 @@ ENTRY(pagezero)
stosq
POP_FRAME_POINTER
ret
-END(pagezero)
+END(pagezero_std)
+
+ENTRY(pagezero_erms)
+ PUSH_FRAME_POINTER
+ movq $PAGE_SIZE,%rcx
+ xorl %eax,%eax
+ rep
+ stosb
+ POP_FRAME_POINTER
+ ret
+END(pagezero_erms)
/*
* pagecopy(%rdi=from, %rsi=to)
@@ -91,6 +101,100 @@ ENTRY(sse2_pagezero)
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
* Adapted from bcopy written by:
@@ -98,40 +202,43 @@ END(sse2_pagezero)
*/
ENTRY(memmove_std)
PUSH_FRAME_POINTER
- movq %rdi,%r9
+ movq %rdi,%rax
movq %rdx,%rcx
- movq %rdi,%rax
- subq %rsi,%rax
- cmpq %rcx,%rax /* overlapping && src < dst? */
- jb 1f
+ movq %rdi,%r8
+ subq %rsi,%r8
+ cmpq %rcx,%r8 /* overlapping && src < dst? */
+ jb 2f
+ cmpq $15,%rcx
+ jbe 1f
shrq $3,%rcx /* copy by 64-bit words */
rep
movsq
movq %rdx,%rcx
andq $7,%rcx /* any bytes left? */
- jne 2f
- movq %r9,%rax
+ jne 1f
POP_FRAME_POINTER
ret
-2:
+ ALIGN_TEXT
+1:
rep
movsb
- movq %r9,%rax
POP_FRAME_POINTER
ret
/* ALIGN_TEXT */
-1:
+2:
addq %rcx,%rdi /* copy backwards */
addq %rcx,%rsi
decq %rdi
decq %rsi
- andq $7,%rcx /* any fractional bytes? */
std
+ andq $7,%rcx /* any fractional bytes? */
+ je 3f
rep
movsb
+3:
movq %rdx,%rcx /* copy remainder by 32-bit words */
shrq $3,%rcx
subq $7,%rsi
@@ -139,24 +246,22 @@ ENTRY(memmove_std)
rep
movsq
cld
- movq %r9,%rax
POP_FRAME_POINTER
ret
END(memmove_std)
ENTRY(memmove_erms)
PUSH_FRAME_POINTER
- movq %rdi,%r9
+ movq %rdi,%rax
movq %rdx,%rcx
- movq %rdi,%rax
- subq %rsi,%rax
- cmpq %rcx,%rax /* overlapping && src < dst? */
+ movq %rdi,%r8
+ subq %rsi,%r8
+ cmpq %rcx,%r8 /* overlapping && src < dst? */
jb 1f
rep
movsb
- movq %r9,%rax
POP_FRAME_POINTER
ret
@@ -169,7 +274,6 @@ ENTRY(memmove_erms)
rep
movsb
cld
- movq %r9,%rax
POP_FRAME_POINTER
ret
END(memmove_erms)
@@ -184,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
@@ -192,6 +298,7 @@ ENTRY(memcpy_std)
jne 1f
POP_FRAME_POINTER
ret
+ ALIGN_TEXT
1:
rep
movsb
@@ -220,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
@@ -229,6 +338,7 @@ ENTRY(memset_std)
movq %r9,%rax
POP_FRAME_POINTER
ret
+ ALIGN_TEXT
1:
rep
stosb
@@ -274,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
@@ -343,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
@@ -352,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
+ ALIGN_TEXT
+1:
+.endif
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
+ xorl %eax,%eax
- xchgq %rdi,%rsi
- movq %rdx,%rcx
- movb %cl,%al
+ SMAP_DISABLE \smap
+.if \erms == 0
+ cmpq $15,%rcx
+ jbe 1f
shrq $3,%rcx /* copy longword-wise */
- stac
rep
movsq
- movb %al,%cl
+ movb %dl,%cl
andb $7,%cl /* copy remaining bytes */
- je 1f
+ jne 1f
+ SMAP_ENABLE \smap
+ movq %rax,PCB_ONFAULT(%r9)
+ POP_FRAME_POINTER
+ ret
+ ALIGN_TEXT
+1:
+.endif
rep
movsb
-1: clac
-done_copyin:
- xorl %eax,%eax
- movq PCPU(CURPCB),%rdx
- movq %rax,PCB_ONFAULT(%rdx)
+ SMAP_ENABLE \smap
+ movq %rax,PCB_ONFAULT(%r9)
POP_FRAME_POINTER
ret
-END(copyin_smap)
+.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
@@ -748,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.
@@ -909,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
@@ -918,109 +1011,97 @@ 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
+.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
- jmp copyinstr_succ
-END(copyinstr_nosmap)
+ SMAP_ENABLE \smap
-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
+ /* Success -- 0 byte reached */
+ decq %rdx
+ xorl %eax,%eax
- stac
+ /* set *lencopied and return %eax */
+ movq %rax,PCB_ONFAULT(%r9)
- /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */
- cmpq %rdx,%rax
- jae 1f
+ 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
-1:
- incq %rdx
-
-2:
- decq %rdx
- jz copyinstr_toolong_smap
+ jmp 1b
- lodsb
- stosb
- orb %al,%al
- jnz 2b
+.endm
- clac
+ENTRY(copyinstr_nosmap)
+ COPYINSTR smap=0
+END(copyinstr_nosmap)
-copyinstr_succ:
- /* Success -- 0 byte reached */
- decq %rdx
- xorl %eax,%eax
+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
copyinstr_toolong:
/* rdx is zero - return ENAMETOOLONG or EFAULT */
movq $VM_MAXUSER_ADDRESS,%rax
- cmpq %rax,%rsi
+ cmpq %rax,%rdi
jae cpystrflt
- movq $ENAMETOOLONG,%rax
+ movl $ENAMETOOLONG,%eax
jmp cpystrflt_x
-END(copyinstr_smap)
-
/*
* copystr(from, to, maxlen, int *lencopied)
* %rdi, %rsi, %rdx, %rcx
@@ -1029,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 4d03da234f19..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),
@@ -705,6 +699,17 @@ trap_is_smap(struct trapframe *frame)
PGEX_P && (frame->tf_rflags & PSL_AC) == 0);
}
+static bool
+trap_is_pti(struct trapframe *frame)
+{
+
+ return (PCPU_GET(curpmap)->pm_ucr3 != PMAP_NO_CR3 &&
+ pg_nx != 0 && (frame->tf_err & (PGEX_P | PGEX_W |
+ PGEX_U | PGEX_I)) == (PGEX_P | PGEX_U | PGEX_I) &&
+ (curpcb->pcb_saved_ucr3 & ~CR3_PCID_MASK) ==
+ (PCPU_GET(curpmap)->pm_cr3 & ~CR3_PCID_MASK));
+}
+
static int
trap_pfault(struct trapframe *frame, int usermode)
{
@@ -806,12 +811,8 @@ trap_pfault(struct trapframe *frame, int usermode)
* If nx protection of the usermode portion of kernel page
* tables caused trap, panic.
*/
- if (usermode && PCPU_GET(curpmap)->pm_ucr3 != PMAP_NO_CR3 &&
- pg_nx != 0 && (frame->tf_err & (PGEX_P | PGEX_W |
- PGEX_U | PGEX_I)) == (PGEX_P | PGEX_U | PGEX_I) &&
- (curpcb->pcb_saved_ucr3 & ~CR3_PCID_MASK)==
- (PCPU_GET(curpmap)->pm_cr3 & ~CR3_PCID_MASK))
- panic("PTI: pid %d comm %s tf_err %#lx\n", p->p_pid,
+ if (usermode && trap_is_pti(frame))
+ panic("PTI: pid %d comm %s tf_err %#lx", p->p_pid,
p->p_comm, frame->tf_err);
/*
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 @@ restart:
break;
case VM_EXITCODE_MONITOR:
case VM_EXITCODE_MWAIT:
+ case VM_EXITCODE_VMINSN:
vm_inject_ud(vm, vcpuid);
break;
default:
diff --git a/sys/arm/conf/std.armv6 b/sys/arm/conf/std.armv6
index 2f6f9c93af4f..52685a9b13bf 100644
--- a/sys/arm/conf/std.armv6
+++ b/sys/arm/conf/std.armv6
@@ -41,6 +41,8 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
+options CAPABILITY_MODE # Capsicum capability mode
+options CAPABILITIES # Capsicum capabilites
options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
options VFP # Enable floating point hardware support
options MAC # Support for Mandatory Access Control (MAC)
diff --git a/sys/arm/conf/std.armv7 b/sys/arm/conf/std.armv7
index 5754f4780fea..c3ab6852e615 100644
--- a/sys/arm/conf/std.armv7
+++ b/sys/arm/conf/std.armv7
@@ -41,6 +41,8 @@ options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions
options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed.
options KBD_INSTALL_CDEV # install a CDEV entry in /dev
options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4)
+options CAPABILITY_MODE # Capsicum capability mode
+options CAPABILITIES # Capsicum capabilites
options FREEBSD_BOOT_LOADER # Process metadata passed from loader(8)
options VFP # Enable floating point hardware support
options MAC # Support for Mandatory Access Control (MAC)
diff --git a/sys/arm64/arm64/elf_machdep.c b/sys/arm64/arm64/elf_machdep.c
index 67244adfb0c9..f39eb3558b5f 100644
--- a/sys/arm64/arm64/elf_machdep.c
+++ b/sys/arm64/arm64/elf_machdep.c
@@ -133,14 +133,14 @@ bool
elf_is_ifunc_reloc(Elf_Size r_info __unused)
{
- return (false);
+ return (ELF_R_TYPE(r_info) == R_AARCH64_IRELATIVE);
}
static int
elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
int type, int local, elf_lookup_fn lookup)
{
- Elf_Addr *where, addr, addend;
+ Elf_Addr *where, addr, addend, val;
Elf_Word rtype, symidx;
const Elf_Rel *rel;
const Elf_Rela *rela;
@@ -183,6 +183,12 @@ elf_reloc_internal(linker_file_t lf, Elf_Addr relocbase, const void *data,
return (-1);
*where = addr + addend;
break;
+ case R_AARCH64_IRELATIVE:
+ addr = relocbase + addend;
+ val = ((Elf64_Addr (*)(void))addr)();
+ if (*where != val)
+ *where = val;
+ break;
default:
printf("kldload: unexpected relocation type %d\n", rtype);
return (-1);
diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index a79490441e91..b9e7826e3435 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,249 @@ 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_aa64isar0_fields[] = {
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_DP_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_SM4_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_SM3_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_SHA3_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_RDM_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_ATOMIC_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_CRC32_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_SHA2_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_SHA1_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR0_AES_SHIFT),
+ MRS_FIELD_END,
+};
+
+static struct mrs_field id_aa64isar1_fields[] = {
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_GPI_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_GPA_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_LRCPC_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_FCMA_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_JSCVT_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_API_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_APA_SHIFT),
+ MRS_FIELD(false, MRS_LOWER, ID_AA64ISAR1_DPB_SHIFT),
+ MRS_FIELD_END,
+};
+
+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_aa64isar0_el1 */
+ .CRm = 6,
+ .Op2 = 0,
+ .offset = __offsetof(struct cpu_desc, id_aa64isar0),
+ .fields = id_aa64isar0_fields,
+ },
+ { /* id_aa64isar1_el1 */
+ .CRm = 6,
+ .Op2 = 1,
+ .offset = __offsetof(struct cpu_desc, id_aa64isar1),
+ .fields = id_aa64isar1_fields,
+ },
+ { /* 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..613dcbc53a09 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);
}
@@ -1004,6 +1004,7 @@ initarm(struct arm64_bootparams *abp)
boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
init_static_kenv(MD_FETCH(kmdp, MODINFOMD_ENVP, char *), 0);
+ link_elf_ireloc(kmdp);
#ifdef FDT
try_load_dtb(kmdp);
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/conf/GENERIC-MMCCAM b/sys/arm64/conf/GENERIC-MMCCAM
index 0d1e91cd58c8..ab45fcb8168d 100644
--- a/sys/arm64/conf/GENERIC-MMCCAM
+++ b/sys/arm64/conf/GENERIC-MMCCAM
@@ -9,6 +9,7 @@
#NO_UNIVERSE
include GENERIC
+ident GENERIC-MMCCAM
# Add CAMDEBUG stuff
options CAMDEBUG
diff --git a/sys/arm64/include/ifunc.h b/sys/arm64/include/ifunc.h
new file mode 100644
index 000000000000..2ce29154180b
--- /dev/null
+++ b/sys/arm64/include/ifunc.h
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2015-2018 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __ARM64_IFUNC_H
+#define __ARM64_IFUNC_H
+
+#define DEFINE_IFUNC(qual, ret_type, name, args, resolver_qual) \
+ resolver_qual ret_type (*name##_resolver(void))args __used; \
+ qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \
+ resolver_qual ret_type (*name##_resolver(void))args
+
+#define DEFINE_UIFUNC(qual, ret_type, name, args, resolver_qual) \
+ resolver_qual ret_type (*name##_resolver(uint64_t, uint64_t, \
+ uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, \
+ uint64_t))args __used; \
+ qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \
+ resolver_qual ret_type (*name##_resolver(uint64_t _arg1 __unused, \
+ uint64_t _arg2 __unused, uint64_t _arg3 __unused, \
+ uint64_t _arg4 __unused, uint64_t _arg5 __unused, \
+ uint64_t _arg6 __unused, uint64_t _arg7 __unused, \
+ uint64_t _arg8 __unused))args
+
+#endif
diff --git a/sys/arm64/include/pte.h b/sys/arm64/include/pte.h
index acd3f81ab41c..7aa216e92b43 100644
--- a/sys/arm64/include/pte.h
+++ b/sys/arm64/include/pte.h
@@ -109,7 +109,7 @@ typedef uint64_t pt_entry_t; /* page table entry */
/* 0x2 also marks an invalid address */
#define L3_PAGE 0x3
-#define PMAP_MAPDEV_EARLY_SIZE (L2_SIZE * 4)
+#define PMAP_MAPDEV_EARLY_SIZE (L2_SIZE * 8)
#define L0_ENTRIES_SHIFT 9
#define L0_ENTRIES (1 << L0_ENTRIES_SHIFT)
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/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index b0d4fe5d11c5..599ebc272629 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -63,8 +63,10 @@ __FBSDID("$FreeBSD$");
#include <sys/cdrio.h>
#include <sys/dvdio.h>
#include <sys/devicestat.h>
+#include <sys/proc.h>
#include <sys/sbuf.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#include <sys/taskqueue.h>
#include <geom/geom_disk.h>
@@ -210,6 +212,17 @@ static struct cd_quirk_entry cd_quirk_table[] =
}
};
+#ifdef COMPAT_FREEBSD32
+struct ioc_read_toc_entry32 {
+ u_char address_format;
+ u_char starting_track;
+ u_short data_len;
+ uint32_t data; /* (struct cd_toc_entry *) */
+};
+#define CDIOREADTOCENTRYS_32 \
+ _IOC_NEWTYPE(CDIOREADTOCENTRYS, struct ioc_read_toc_entry32)
+#endif
+
static disk_open_t cdopen;
static disk_close_t cdclose;
static disk_ioctl_t cdioctl;
@@ -1272,6 +1285,29 @@ cdgetpagesize(int page_num)
return (-1);
}
+static struct cd_toc_entry *
+te_data_get_ptr(void *irtep, u_long cmd)
+{
+ union {
+ struct ioc_read_toc_entry irte;
+#ifdef COMPAT_FREEBSD32
+ struct ioc_read_toc_entry32 irte32;
+#endif
+ } *irteup;
+
+ irteup = irtep;
+ switch (IOCPARM_LEN(cmd)) {
+ case sizeof(irteup->irte):
+ return (irteup->irte.data);
+#ifdef COMPAT_FREEBSD32
+ case sizeof(irteup->irte32):
+ return ((struct cd_toc_entry *)(uintptr_t)irteup->irte32.data);
+#endif
+ default:
+ panic("Unhandled ioctl command %ld", cmd);
+ }
+}
+
static int
cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
{
@@ -1587,6 +1623,9 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
}
break;
case CDIOREADTOCENTRYS:
+#ifdef COMPAT_FREEBSD32
+ case CDIOREADTOCENTRYS_32:
+#endif
{
struct cd_tocdata *data;
struct cd_toc_single *lead;
@@ -1712,7 +1751,8 @@ cdioctl(struct disk *dp, u_long cmd, void *addr, int flag, struct thread *td)
}
cam_periph_unlock(periph);
- error = copyout(data->entries, te->data, len);
+ error = copyout(data->entries, te_data_get_ptr(te, cmd),
+ len);
free(data, M_SCSICD);
free(lead, M_SCSICD);
}
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index 40f593f9b629..80dcb34a0a78 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -5674,6 +5674,9 @@ dadone_probezone(struct cam_periph *periph, union ccb *done_ccb)
}
}
}
+
+ free(csio->data_ptr, M_SCSIDA);
+
daprobedone(periph, done_ccb);
return;
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
index 0a352b1e9798..9012baa0a994 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c
@@ -292,8 +292,15 @@ uint_t dbuf_cache_lowater_pct = 10;
SYSCTL_DECL(_vfs_zfs);
SYSCTL_QUAD(_vfs_zfs, OID_AUTO, dbuf_cache_max_bytes, CTLFLAG_RWTUN,
&dbuf_cache_max_bytes, 0, "dbuf cache size in bytes");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, dbuf_metadata_cache_max_bytes, CTLFLAG_RWTUN,
+ &dbuf_metadata_cache_max_bytes, 0, "dbuf metadata cache size in bytes");
SYSCTL_INT(_vfs_zfs, OID_AUTO, dbuf_cache_shift, CTLFLAG_RDTUN,
&dbuf_cache_shift, 0, "dbuf cache size as log2 fraction of ARC");
+SYSCTL_INT(_vfs_zfs, OID_AUTO, dbuf_metadata_cache_shift, CTLFLAG_RDTUN,
+ &dbuf_metadata_cache_shift, 0,
+ "dbuf metadata cache size as log2 fraction of ARC");
+SYSCTL_QUAD(_vfs_zfs, OID_AUTO, dbuf_metadata_cache_overflow, CTLFLAG_RD,
+ &dbuf_metadata_cache_overflow, 0, "dbuf metadata cache overflow");
SYSCTL_UINT(_vfs_zfs, OID_AUTO, dbuf_cache_hiwater_pct, CTLFLAG_RWTUN,
&dbuf_cache_hiwater_pct, 0, "max percents above the dbuf cache size");
SYSCTL_UINT(_vfs_zfs, OID_AUTO, dbuf_cache_lowater_pct, CTLFLAG_RWTUN,
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/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
index aa8a400f2d78..7794bd505525 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -415,9 +415,10 @@ vdev_geom_io(struct g_consumer *cp, int *cmds, void **datas, off_t *offsets,
* least one valid label was found.
*/
static int
-vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
+vdev_geom_read_config(struct g_consumer *cp, nvlist_t **configp)
{
struct g_provider *pp;
+ nvlist_t *config;
vdev_phys_t *vdev_lists[VDEV_LABELS];
char *buf;
size_t buflen;
@@ -442,7 +443,6 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
buflen = sizeof(vdev_lists[0]->vp_nvlist);
- *config = NULL;
/* Create all of the IO requests */
for (l = 0; l < VDEV_LABELS; l++) {
cmds[l] = BIO_READ;
@@ -458,6 +458,7 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
VDEV_LABELS);
/* Parse the labels */
+ config = *configp = NULL;
nlabels = 0;
for (l = 0; l < VDEV_LABELS; l++) {
if (errors[l] != 0)
@@ -465,25 +466,27 @@ vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
buf = vdev_lists[l]->vp_nvlist;
- if (nvlist_unpack(buf, buflen, config, 0) != 0)
+ if (nvlist_unpack(buf, buflen, &config, 0) != 0)
continue;
- if (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_STATE,
+ if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
&state) != 0 || state > POOL_STATE_L2CACHE) {
- nvlist_free(*config);
- *config = NULL;
+ nvlist_free(config);
continue;
}
if (state != POOL_STATE_SPARE &&
state != POOL_STATE_L2CACHE &&
- (nvlist_lookup_uint64(*config, ZPOOL_CONFIG_POOL_TXG,
+ (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
&txg) != 0 || txg == 0)) {
- nvlist_free(*config);
- *config = NULL;
+ nvlist_free(config);
continue;
}
+ if (*configp != NULL)
+ nvlist_free(*configp);
+ *configp = config;
+
nlabels++;
}
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
index 3fad5a76957b..cf75ab0856c0 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c
@@ -958,6 +958,15 @@ vdev_queue_change_io_priority(zio_t *zio, zio_priority_t priority)
vdev_queue_t *vq = &zio->io_vd->vdev_queue;
avl_tree_t *tree;
+ /*
+ * ZIO_PRIORITY_NOW is used by the vdev cache code and the aggregate zio
+ * code to issue IOs without adding them to the vdev queue. In this
+ * case, the zio is already going to be issued as quickly as possible
+ * and so it doesn't need any reprioitization to help.
+ */
+ if (zio->io_priority == ZIO_PRIORITY_NOW)
+ return;
+
ASSERT3U(zio->io_priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
ASSERT3U(priority, <, ZIO_PRIORITY_NUM_QUEUEABLE);
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_setvnode(zfsvfs_t *zfsvfs)
+{
+ 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;
- ZFS_ENTER(zfsvfs);
+ 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/compat/freebsd32/freebsd32_ioctl.c b/sys/compat/freebsd32/freebsd32_ioctl.c
index a3226cdcd9a0..414178a7bffd 100644
--- a/sys/compat/freebsd32/freebsd32_ioctl.c
+++ b/sys/compat/freebsd32/freebsd32_ioctl.c
@@ -56,37 +56,7 @@ __FBSDID("$FreeBSD$");
#include <compat/freebsd32/freebsd32_misc.h>
#include <compat/freebsd32/freebsd32_proto.h>
-CTASSERT(sizeof(struct ioc_read_toc_entry32) == 8);
CTASSERT(sizeof(struct mem_range_op32) == 12);
-CTASSERT(sizeof(struct pci_conf_io32) == 36);
-CTASSERT(sizeof(struct pci_match_conf32) == 44);
-CTASSERT(sizeof(struct pci_conf32) == 44);
-
-static int
-freebsd32_ioctl_ioc_read_toc(struct thread *td,
- struct freebsd32_ioctl_args *uap, struct file *fp)
-{
- struct ioc_read_toc_entry toce;
- struct ioc_read_toc_entry32 toce32;
- int error;
-
- if ((error = copyin(uap->data, &toce32, sizeof(toce32))))
- return (error);
- CP(toce32, toce, address_format);
- CP(toce32, toce, starting_track);
- CP(toce32, toce, data_len);
- PTRIN_CP(toce32, toce, data);
-
- if ((error = fo_ioctl(fp, CDIOREADTOCENTRYS, (caddr_t)&toce,
- td->td_ucred, td))) {
- CP(toce, toce32, address_format);
- CP(toce, toce32, starting_track);
- CP(toce, toce32, data_len);
- PTROUT_CP(toce, toce32, data);
- error = copyout(&toce32, uap->data, sizeof(toce32));
- }
- return error;
-}
static int
freebsd32_ioctl_fiodgname(struct thread *td,
@@ -148,108 +118,6 @@ freebsd32_ioctl_memrange(struct thread *td,
}
static int
-freebsd32_ioctl_pciocgetconf(struct thread *td,
- struct freebsd32_ioctl_args *uap, struct file *fp)
-{
- struct pci_conf_io pci;
- struct pci_conf_io32 pci32;
- struct pci_match_conf32 pmc32;
- struct pci_match_conf32 *pmc32p;
- struct pci_match_conf pmc;
- struct pci_match_conf *pmcp;
- struct pci_conf32 pc32;
- struct pci_conf32 *pc32p;
- struct pci_conf pc;
- struct pci_conf *pcp;
- u_int32_t i;
- u_int32_t npat_to_convert;
- u_int32_t nmatch_to_convert;
- vm_offset_t addr;
- int error;
-
- if ((error = copyin(uap->data, &pci32, sizeof(pci32))) != 0)
- return (error);
-
- CP(pci32, pci, num_patterns);
- CP(pci32, pci, offset);
- CP(pci32, pci, generation);
-
- npat_to_convert = pci32.pat_buf_len / sizeof(struct pci_match_conf32);
- pci.pat_buf_len = npat_to_convert * sizeof(struct pci_match_conf);
- pci.patterns = NULL;
- nmatch_to_convert = pci32.match_buf_len / sizeof(struct pci_conf32);
- pci.match_buf_len = nmatch_to_convert * sizeof(struct pci_conf);
- pci.matches = NULL;
-
- if ((error = copyout_map(td, &addr, pci.pat_buf_len)) != 0)
- goto cleanup;
- pci.patterns = (struct pci_match_conf *)addr;
- if ((error = copyout_map(td, &addr, pci.match_buf_len)) != 0)
- goto cleanup;
- pci.matches = (struct pci_conf *)addr;
-
- npat_to_convert = min(npat_to_convert, pci.num_patterns);
-
- for (i = 0, pmc32p = (struct pci_match_conf32 *)PTRIN(pci32.patterns),
- pmcp = pci.patterns;
- i < npat_to_convert; i++, pmc32p++, pmcp++) {
- if ((error = copyin(pmc32p, &pmc32, sizeof(pmc32))) != 0)
- goto cleanup;
- CP(pmc32,pmc,pc_sel);
- strlcpy(pmc.pd_name, pmc32.pd_name, sizeof(pmc.pd_name));
- CP(pmc32,pmc,pd_unit);
- CP(pmc32,pmc,pc_vendor);
- CP(pmc32,pmc,pc_device);
- CP(pmc32,pmc,pc_class);
- CP(pmc32,pmc,flags);
- if ((error = copyout(&pmc, pmcp, sizeof(pmc))) != 0)
- goto cleanup;
- }
-
- if ((error = fo_ioctl(fp, PCIOCGETCONF, (caddr_t)&pci,
- td->td_ucred, td)) != 0)
- goto cleanup;
-
- nmatch_to_convert = min(nmatch_to_convert, pci.num_matches);
-
- for (i = 0, pcp = pci.matches,
- pc32p = (struct pci_conf32 *)PTRIN(pci32.matches);
- i < nmatch_to_convert; i++, pcp++, pc32p++) {
- if ((error = copyin(pcp, &pc, sizeof(pc))) != 0)
- goto cleanup;
- CP(pc,pc32,pc_sel);
- CP(pc,pc32,pc_hdr);
- CP(pc,pc32,pc_subvendor);
- CP(pc,pc32,pc_subdevice);
- CP(pc,pc32,pc_vendor);
- CP(pc,pc32,pc_device);
- CP(pc,pc32,pc_class);
- CP(pc,pc32,pc_subclass);
- CP(pc,pc32,pc_progif);
- CP(pc,pc32,pc_revid);
- strlcpy(pc32.pd_name, pc.pd_name, sizeof(pc32.pd_name));
- CP(pc,pc32,pd_unit);
- if ((error = copyout(&pc32, pc32p, sizeof(pc32))) != 0)
- goto cleanup;
- }
-
- CP(pci, pci32, num_matches);
- CP(pci, pci32, offset);
- CP(pci, pci32, generation);
- CP(pci, pci32, status);
-
- error = copyout(&pci32, uap->data, sizeof(pci32));
-
-cleanup:
- if (pci.patterns)
- copyout_unmap(td, (vm_offset_t)pci.patterns, pci.pat_buf_len);
- if (pci.matches)
- copyout_unmap(td, (vm_offset_t)pci.matches, pci.match_buf_len);
-
- return (error);
-}
-
-static int
freebsd32_ioctl_barmmap(struct thread *td,
struct freebsd32_ioctl_args *uap, struct file *fp)
{
@@ -369,10 +237,6 @@ freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap)
}
switch (uap->com) {
- case CDIOREADTOCENTRYS_32:
- error = freebsd32_ioctl_ioc_read_toc(td, uap, fp);
- break;
-
case FIODGNAME_32:
error = freebsd32_ioctl_fiodgname(td, uap, fp);
break;
@@ -382,10 +246,6 @@ freebsd32_ioctl(struct thread *td, struct freebsd32_ioctl_args *uap)
error = freebsd32_ioctl_memrange(td, uap, fp);
break;
- case PCIOCGETCONF_32:
- error = freebsd32_ioctl_pciocgetconf(td, uap, fp);
- break;
-
case SG_IO_32:
error = freebsd32_ioctl_sg(td, uap, fp);
break;
diff --git a/sys/compat/freebsd32/freebsd32_ioctl.h b/sys/compat/freebsd32/freebsd32_ioctl.h
index fc9c93a7a29b..1d2312b41c14 100644
--- a/sys/compat/freebsd32/freebsd32_ioctl.h
+++ b/sys/compat/freebsd32/freebsd32_ioctl.h
@@ -38,13 +38,6 @@
typedef __uint32_t caddr_t32;
-struct ioc_read_toc_entry32 {
- u_char address_format;
- u_char starting_track;
- u_short data_len;
- uint32_t data; /* struct cd_toc_entry* */
-};
-
struct fiodgname_arg32 {
int len;
caddr_t32 buf;
@@ -56,45 +49,6 @@ struct mem_range_op32
int mo_arg[2];
};
-struct pci_conf32 {
- struct pcisel pc_sel; /* domain+bus+slot+function */
- u_int8_t pc_hdr; /* PCI header type */
- u_int16_t pc_subvendor; /* card vendor ID */
- u_int16_t pc_subdevice; /* card device ID, assigned by
- card vendor */
- u_int16_t pc_vendor; /* chip vendor ID */
- u_int16_t pc_device; /* chip device ID, assigned by
- chip vendor */
- u_int8_t pc_class; /* chip PCI class */
- u_int8_t pc_subclass; /* chip PCI subclass */
- u_int8_t pc_progif; /* chip PCI programming interface */
- u_int8_t pc_revid; /* chip revision ID */
- char pd_name[PCI_MAXNAMELEN + 1]; /* device name */
- u_int32_t pd_unit; /* device unit number */
-};
-
-struct pci_match_conf32 {
- struct pcisel pc_sel; /* domain+bus+slot+function */
- char pd_name[PCI_MAXNAMELEN + 1]; /* device name */
- u_int32_t pd_unit; /* Unit number */
- u_int16_t pc_vendor; /* PCI Vendor ID */
- u_int16_t pc_device; /* PCI Device ID */
- u_int8_t pc_class; /* PCI class */
- u_int32_t flags; /* Matching expression */
-};
-
-struct pci_conf_io32 {
- u_int32_t pat_buf_len; /* pattern buffer length */
- u_int32_t num_patterns; /* number of patterns */
- caddr_t32 patterns; /* struct pci_match_conf ptr */
- u_int32_t match_buf_len; /* match buffer length */
- u_int32_t num_matches; /* number of matches returned */
- caddr_t32 matches; /* struct pci_conf ptr */
- u_int32_t offset; /* offset into device list */
- u_int32_t generation; /* device list generation */
- u_int32_t status; /* request status */
-};
-
struct pci_bar_mmap32 {
uint32_t pbm_map_base;
uint32_t pbm_map_length;
@@ -106,11 +60,9 @@ struct pci_bar_mmap32 {
int pbm_memattr;
};
-#define CDIOREADTOCENTRYS_32 _IOWR('c', 5, struct ioc_read_toc_entry32)
#define FIODGNAME_32 _IOW('f', 120, struct fiodgname_arg32)
#define MEMRANGE_GET32 _IOWR('m', 50, struct mem_range_op32)
#define MEMRANGE_SET32 _IOW('m', 51, struct mem_range_op32)
-#define PCIOCGETCONF_32 _IOWR('p', 5, struct pci_conf_io32)
#define SG_IO_32 _IOWR(SGIOC, 0x85, struct sg_io_hdr32)
#define PCIOCBARMMAP_32 _IOWR('p', 8, struct pci_bar_mmap32)
diff --git a/sys/compat/freebsd32/freebsd32_syscall.h b/sys/compat/freebsd32/freebsd32_syscall.h
index 6cc72e423997..66ab072edab8 100644
--- a/sys/compat/freebsd32/freebsd32_syscall.h
+++ b/sys/compat/freebsd32/freebsd32_syscall.h
@@ -171,6 +171,10 @@
#define FREEBSD32_SYS_setgid 181
#define FREEBSD32_SYS_setegid 182
#define FREEBSD32_SYS_seteuid 183
+ /* 184 is obsolete lfs_bmapv */
+ /* 185 is obsolete lfs_markv */
+ /* 186 is obsolete lfs_segclean */
+ /* 187 is obsolete lfs_segwait */
#define FREEBSD32_SYS_freebsd11_freebsd32_stat 188
#define FREEBSD32_SYS_freebsd11_freebsd32_fstat 189
#define FREEBSD32_SYS_freebsd11_freebsd32_lstat 190
@@ -194,6 +198,7 @@
#define FREEBSD32_SYS_freebsd7_freebsd32_semctl 220
#define FREEBSD32_SYS_semget 221
#define FREEBSD32_SYS_semop 222
+ /* 223 is obsolete semconfig */
#define FREEBSD32_SYS_freebsd7_freebsd32_msgctl 224
#define FREEBSD32_SYS_msgget 225
#define FREEBSD32_SYS_freebsd32_msgsnd 226
@@ -300,12 +305,24 @@
#define FREEBSD32_SYS_getresgid 361
#define FREEBSD32_SYS_kqueue 362
#define FREEBSD32_SYS_freebsd11_freebsd32_kevent 363
+ /* 364 is obsolete __cap_get_proc */
+ /* 365 is obsolete __cap_set_proc */
+ /* 366 is obsolete __cap_get_fd */
+ /* 367 is obsolete __cap_get_file */
+ /* 368 is obsolete __cap_set_fd */
+ /* 369 is obsolete __cap_set_file */
#define FREEBSD32_SYS_extattr_set_fd 371
#define FREEBSD32_SYS_extattr_get_fd 372
#define FREEBSD32_SYS_extattr_delete_fd 373
#define FREEBSD32_SYS___setugid 374
+ /* 375 is obsolete nfsclnt */
#define FREEBSD32_SYS_eaccess 376
#define FREEBSD32_SYS_freebsd32_nmount 378
+ /* 379 is obsolete kse_exit */
+ /* 380 is obsolete kse_wakeup */
+ /* 381 is obsolete kse_create */
+ /* 382 is obsolete kse_thr_interrupt */
+ /* 383 is obsolete kse_release */
#define FREEBSD32_SYS_kenv 390
#define FREEBSD32_SYS_lchflags 391
#define FREEBSD32_SYS_uuidgen 392
@@ -343,6 +360,7 @@
#define FREEBSD32_SYS_extattr_list_fd 437
#define FREEBSD32_SYS_extattr_list_file 438
#define FREEBSD32_SYS_extattr_list_link 439
+ /* 440 is obsolete kse_switchin */
#define FREEBSD32_SYS_freebsd32_ksem_timedwait 441
#define FREEBSD32_SYS_freebsd32_thr_suspend 442
#define FREEBSD32_SYS_thr_wake 443
@@ -455,6 +473,8 @@
#define FREEBSD32_SYS_freebsd32_ppoll 545
#define FREEBSD32_SYS_freebsd32_futimens 546
#define FREEBSD32_SYS_freebsd32_utimensat 547
+ /* 548 is obsolete numa_getaffinity */
+ /* 549 is obsolete numa_setaffinity */
#define FREEBSD32_SYS_fdatasync 550
#define FREEBSD32_SYS_freebsd32_fstat 551
#define FREEBSD32_SYS_freebsd32_fstatat 552
diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c
index cc554b0efb64..c186771f0704 100644
--- a/sys/compat/freebsd32/freebsd32_syscalls.c
+++ b/sys/compat/freebsd32/freebsd32_syscalls.c
@@ -193,10 +193,10 @@ const char *freebsd32_syscallnames[] = {
"setgid", /* 181 = setgid */
"setegid", /* 182 = setegid */
"seteuid", /* 183 = seteuid */
- "#184", /* 184 = lfs_bmapv */
- "#185", /* 185 = lfs_markv */
- "#186", /* 186 = lfs_segclean */
- "#187", /* 187 = lfs_segwait */
+ "obs_lfs_bmapv", /* 184 = obsolete lfs_bmapv */
+ "obs_lfs_markv", /* 185 = obsolete lfs_markv */
+ "obs_lfs_segclean", /* 186 = obsolete lfs_segclean */
+ "obs_lfs_segwait", /* 187 = obsolete lfs_segwait */
"compat11.freebsd32_stat", /* 188 = freebsd11 freebsd32_stat */
"compat11.freebsd32_fstat", /* 189 = freebsd11 freebsd32_fstat */
"compat11.freebsd32_lstat", /* 190 = freebsd11 freebsd32_lstat */
@@ -232,7 +232,7 @@ const char *freebsd32_syscallnames[] = {
"compat7.freebsd32_semctl", /* 220 = freebsd7 freebsd32_semctl */
"semget", /* 221 = semget */
"semop", /* 222 = semop */
- "#223", /* 223 = semconfig */
+ "obs_semconfig", /* 223 = obsolete semconfig */
"compat7.freebsd32_msgctl", /* 224 = freebsd7 freebsd32_msgctl */
"msgget", /* 225 = msgget */
"freebsd32_msgsnd", /* 226 = freebsd32_msgsnd */
@@ -373,26 +373,26 @@ const char *freebsd32_syscallnames[] = {
"getresgid", /* 361 = getresgid */
"kqueue", /* 362 = kqueue */
"compat11.freebsd32_kevent", /* 363 = freebsd11 freebsd32_kevent */
- "#364", /* 364 = __cap_get_proc */
- "#365", /* 365 = __cap_set_proc */
- "#366", /* 366 = __cap_get_fd */
- "#367", /* 367 = __cap_get_file */
- "#368", /* 368 = __cap_set_fd */
- "#369", /* 369 = __cap_set_file */
+ "obs___cap_get_proc", /* 364 = obsolete __cap_get_proc */
+ "obs___cap_set_proc", /* 365 = obsolete __cap_set_proc */
+ "obs___cap_get_fd", /* 366 = obsolete __cap_get_fd */
+ "obs___cap_get_file", /* 367 = obsolete __cap_get_file */
+ "obs___cap_set_fd", /* 368 = obsolete __cap_set_fd */
+ "obs___cap_set_file", /* 369 = obsolete __cap_set_file */
"#370", /* 370 = nosys */
"extattr_set_fd", /* 371 = extattr_set_fd */
"extattr_get_fd", /* 372 = extattr_get_fd */
"extattr_delete_fd", /* 373 = extattr_delete_fd */
"__setugid", /* 374 = __setugid */
- "#375", /* 375 = nfsclnt */
+ "obs_nfsclnt", /* 375 = obsolete nfsclnt */
"eaccess", /* 376 = eaccess */
"#377", /* 377 = afs_syscall */
"freebsd32_nmount", /* 378 = freebsd32_nmount */
- "#379", /* 379 = kse_exit */
- "#380", /* 380 = kse_wakeup */
- "#381", /* 381 = kse_create */
- "#382", /* 382 = kse_thr_interrupt */
- "#383", /* 383 = kse_release */
+ "obs_kse_exit", /* 379 = obsolete kse_exit */
+ "obs_kse_wakeup", /* 380 = obsolete kse_wakeup */
+ "obs_kse_create", /* 381 = obsolete kse_create */
+ "obs_kse_thr_interrupt", /* 382 = obsolete kse_thr_interrupt */
+ "obs_kse_release", /* 383 = obsolete kse_release */
"#384", /* 384 = __mac_get_proc */
"#385", /* 385 = __mac_set_proc */
"#386", /* 386 = __mac_get_fd */
@@ -449,7 +449,7 @@ const char *freebsd32_syscallnames[] = {
"extattr_list_fd", /* 437 = extattr_list_fd */
"extattr_list_file", /* 438 = extattr_list_file */
"extattr_list_link", /* 439 = extattr_list_link */
- "#440", /* 440 = kse_switchin */
+ "obs_kse_switchin", /* 440 = obsolete kse_switchin */
"freebsd32_ksem_timedwait", /* 441 = freebsd32_ksem_timedwait */
"freebsd32_thr_suspend", /* 442 = freebsd32_thr_suspend */
"thr_wake", /* 443 = thr_wake */
@@ -580,8 +580,8 @@ const char *freebsd32_syscallnames[] = {
"freebsd32_ppoll", /* 545 = freebsd32_ppoll */
"freebsd32_futimens", /* 546 = freebsd32_futimens */
"freebsd32_utimensat", /* 547 = freebsd32_utimensat */
- "#548", /* 548 = numa_getaffinity */
- "#549", /* 549 = numa_setaffinity */
+ "obs_numa_getaffinity", /* 548 = obsolete numa_getaffinity */
+ "obs_numa_setaffinity", /* 549 = obsolete numa_setaffinity */
"fdatasync", /* 550 = fdatasync */
"freebsd32_fstat", /* 551 = freebsd32_fstat */
"freebsd32_fstatat", /* 552 = freebsd32_fstatat */
diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c
index 27caed81eefa..1a6ff314dfa2 100644
--- a/sys/compat/freebsd32/freebsd32_sysent.c
+++ b/sys/compat/freebsd32/freebsd32_sysent.c
@@ -240,10 +240,10 @@ struct sysent freebsd32_sysent[] = {
{ AS(setgid_args), (sy_call_t *)sys_setgid, AUE_SETGID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 181 = setgid */
{ AS(setegid_args), (sy_call_t *)sys_setegid, AUE_SETEGID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 182 = setegid */
{ AS(seteuid_args), (sy_call_t *)sys_seteuid, AUE_SETEUID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 183 = seteuid */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 184 = lfs_bmapv */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 185 = lfs_markv */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 186 = lfs_segclean */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = lfs_segwait */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 184 = obsolete lfs_bmapv */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 185 = obsolete lfs_markv */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 186 = obsolete lfs_segclean */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = obsolete lfs_segwait */
{ compat11(AS(freebsd11_freebsd32_stat_args),freebsd32_stat), AUE_STAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 188 = freebsd11 freebsd32_stat */
{ compat11(AS(freebsd11_freebsd32_fstat_args),freebsd32_fstat), AUE_FSTAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 189 = freebsd11 freebsd32_fstat */
{ compat11(AS(freebsd11_freebsd32_lstat_args),freebsd32_lstat), AUE_LSTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = freebsd11 freebsd32_lstat */
@@ -279,7 +279,7 @@ struct sysent freebsd32_sysent[] = {
{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 220 = freebsd7 freebsd32_semctl */
{ AS(semget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 221 = semget */
{ AS(semop_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 222 = semop */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 223 = semconfig */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 223 = obsolete semconfig */
{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 224 = freebsd7 freebsd32_msgctl */
{ AS(msgget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 225 = msgget */
{ AS(freebsd32_msgsnd_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 226 = freebsd32_msgsnd */
@@ -420,26 +420,26 @@ struct sysent freebsd32_sysent[] = {
{ AS(getresgid_args), (sy_call_t *)sys_getresgid, AUE_GETRESGID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 361 = getresgid */
{ 0, (sy_call_t *)sys_kqueue, AUE_KQUEUE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 362 = kqueue */
{ compat11(AS(freebsd11_freebsd32_kevent_args),freebsd32_kevent), AUE_KEVENT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 363 = freebsd11 freebsd32_kevent */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 364 = __cap_get_proc */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 365 = __cap_set_proc */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 366 = __cap_get_fd */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 367 = __cap_get_file */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 368 = __cap_set_fd */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 369 = __cap_set_file */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 364 = obsolete __cap_get_proc */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 365 = obsolete __cap_set_proc */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 366 = obsolete __cap_get_fd */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 367 = obsolete __cap_get_file */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 368 = obsolete __cap_set_fd */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 369 = obsolete __cap_set_file */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 370 = nosys */
{ AS(extattr_set_fd_args), (sy_call_t *)sys_extattr_set_fd, AUE_EXTATTR_SET_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 371 = extattr_set_fd */
{ AS(extattr_get_fd_args), (sy_call_t *)sys_extattr_get_fd, AUE_EXTATTR_GET_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 372 = extattr_get_fd */
{ AS(extattr_delete_fd_args), (sy_call_t *)sys_extattr_delete_fd, AUE_EXTATTR_DELETE_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 373 = extattr_delete_fd */
{ AS(__setugid_args), (sy_call_t *)sys___setugid, AUE_SETUGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 374 = __setugid */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 375 = nfsclnt */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 375 = obsolete nfsclnt */
{ AS(eaccess_args), (sy_call_t *)sys_eaccess, AUE_EACCESS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 376 = eaccess */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 377 = afs_syscall */
{ AS(freebsd32_nmount_args), (sy_call_t *)freebsd32_nmount, AUE_NMOUNT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 378 = freebsd32_nmount */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 379 = kse_exit */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 380 = kse_wakeup */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 381 = kse_create */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 382 = kse_thr_interrupt */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 383 = kse_release */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 379 = obsolete kse_exit */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 380 = obsolete kse_wakeup */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 381 = obsolete kse_create */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 382 = obsolete kse_thr_interrupt */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 383 = obsolete kse_release */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 384 = __mac_get_proc */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 385 = __mac_set_proc */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 386 = __mac_get_fd */
@@ -496,7 +496,7 @@ struct sysent freebsd32_sysent[] = {
{ AS(extattr_list_fd_args), (sy_call_t *)sys_extattr_list_fd, AUE_EXTATTR_LIST_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 437 = extattr_list_fd */
{ AS(extattr_list_file_args), (sy_call_t *)sys_extattr_list_file, AUE_EXTATTR_LIST_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 438 = extattr_list_file */
{ AS(extattr_list_link_args), (sy_call_t *)sys_extattr_list_link, AUE_EXTATTR_LIST_LINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 439 = extattr_list_link */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 440 = kse_switchin */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 440 = obsolete kse_switchin */
{ AS(freebsd32_ksem_timedwait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 441 = freebsd32_ksem_timedwait */
{ AS(freebsd32_thr_suspend_args), (sy_call_t *)freebsd32_thr_suspend, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 442 = freebsd32_thr_suspend */
{ AS(thr_wake_args), (sy_call_t *)sys_thr_wake, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 443 = thr_wake */
@@ -627,8 +627,8 @@ struct sysent freebsd32_sysent[] = {
{ AS(freebsd32_ppoll_args), (sy_call_t *)freebsd32_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = freebsd32_ppoll */
{ AS(freebsd32_futimens_args), (sy_call_t *)freebsd32_futimens, AUE_FUTIMES, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 546 = freebsd32_futimens */
{ AS(freebsd32_utimensat_args), (sy_call_t *)freebsd32_utimensat, AUE_FUTIMESAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 547 = freebsd32_utimensat */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 548 = numa_getaffinity */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 549 = numa_setaffinity */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 548 = obsolete numa_getaffinity */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 549 = obsolete numa_setaffinity */
{ AS(fdatasync_args), (sy_call_t *)sys_fdatasync, AUE_FSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 550 = fdatasync */
{ AS(freebsd32_fstat_args), (sy_call_t *)freebsd32_fstat, AUE_FSTAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 551 = freebsd32_fstat */
{ AS(freebsd32_fstatat_args), (sy_call_t *)freebsd32_fstatat, AUE_FSTATAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 552 = freebsd32_fstatat */
diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master
index 99103a3553b5..9b5aafe41244 100644
--- a/sys/compat/freebsd32/syscalls.master
+++ b/sys/compat/freebsd32/syscalls.master
@@ -343,10 +343,10 @@
181 AUE_SETGID NOPROTO { int setgid(gid_t gid); }
182 AUE_SETEGID NOPROTO { int setegid(gid_t egid); }
183 AUE_SETEUID NOPROTO { int seteuid(uid_t euid); }
-184 AUE_NULL UNIMPL lfs_bmapv
-185 AUE_NULL UNIMPL lfs_markv
-186 AUE_NULL UNIMPL lfs_segclean
-187 AUE_NULL UNIMPL lfs_segwait
+184 AUE_NULL OBSOL lfs_bmapv
+185 AUE_NULL OBSOL lfs_markv
+186 AUE_NULL OBSOL lfs_segclean
+187 AUE_NULL OBSOL lfs_segwait
188 AUE_STAT COMPAT11 { int freebsd32_stat(char *path, \
struct freebsd11_stat32 *ub); }
189 AUE_FSTAT COMPAT11 { int freebsd32_fstat(int fd, \
@@ -414,7 +414,7 @@
int semflg); }
222 AUE_SEMOP NOSTD|NOPROTO { int semop(int semid, \
struct sembuf *sops, u_int nsops); }
-223 AUE_NULL UNIMPL semconfig
+223 AUE_NULL OBSOL semconfig
224 AUE_MSGCTL COMPAT7|NOSTD { int freebsd32_msgctl( \
int msqid, int cmd, \
struct msqid_ds32_old *buf); }
@@ -662,12 +662,12 @@
struct kevent32_freebsd11 *eventlist, \
int nevents, \
const struct timespec32 *timeout); }
-364 AUE_NULL UNIMPL __cap_get_proc
-365 AUE_NULL UNIMPL __cap_set_proc
-366 AUE_NULL UNIMPL __cap_get_fd
-367 AUE_NULL UNIMPL __cap_get_file
-368 AUE_NULL UNIMPL __cap_set_fd
-369 AUE_NULL UNIMPL __cap_set_file
+364 AUE_NULL OBSOL __cap_get_proc
+365 AUE_NULL OBSOL __cap_set_proc
+366 AUE_NULL OBSOL __cap_get_fd
+367 AUE_NULL OBSOL __cap_get_file
+368 AUE_NULL OBSOL __cap_set_fd
+369 AUE_NULL OBSOL __cap_set_file
370 AUE_NULL UNIMPL nosys
371 AUE_EXTATTR_SET_FD NOPROTO { ssize_t extattr_set_fd(int fd, \
int attrnamespace, const char *attrname, \
@@ -679,16 +679,16 @@
int attrnamespace, \
const char *attrname); }
374 AUE_SETUGID NOPROTO { int __setugid(int flag); }
-375 AUE_NULL UNIMPL nfsclnt
+375 AUE_NULL OBSOL nfsclnt
376 AUE_EACCESS NOPROTO { int eaccess(char *path, int amode); }
377 AUE_NULL UNIMPL afs_syscall
378 AUE_NMOUNT STD { int freebsd32_nmount(struct iovec32 *iovp, \
unsigned int iovcnt, int flags); }
-379 AUE_NULL UNIMPL kse_exit
-380 AUE_NULL UNIMPL kse_wakeup
-381 AUE_NULL UNIMPL kse_create
-382 AUE_NULL UNIMPL kse_thr_interrupt
-383 AUE_NULL UNIMPL kse_release
+379 AUE_NULL OBSOL kse_exit
+380 AUE_NULL OBSOL kse_wakeup
+381 AUE_NULL OBSOL kse_create
+382 AUE_NULL OBSOL kse_thr_interrupt
+383 AUE_NULL OBSOL kse_release
384 AUE_NULL UNIMPL __mac_get_proc
385 AUE_NULL UNIMPL __mac_set_proc
386 AUE_NULL UNIMPL __mac_get_fd
@@ -787,7 +787,7 @@
439 AUE_EXTATTR_LIST_LINK NOPROTO { ssize_t extattr_list_link( \
const char *path, int attrnamespace, \
void *data, size_t nbytes); }
-440 AUE_NULL UNIMPL kse_switchin
+440 AUE_NULL OBSOL kse_switchin
441 AUE_SEMWAIT NOSTD { int freebsd32_ksem_timedwait(semid_t id, \
const struct timespec32 *abstime); }
442 AUE_NULL STD { int freebsd32_thr_suspend( \
@@ -1074,8 +1074,8 @@
547 AUE_FUTIMESAT STD { int freebsd32_utimensat(int fd, \
char *path, \
struct timespec *times, int flag); }
-548 AUE_NULL UNIMPL numa_getaffinity
-549 AUE_NULL UNIMPL numa_setaffinity
+548 AUE_NULL OBSOL numa_getaffinity
+549 AUE_NULL OBSOL numa_setaffinity
550 AUE_FSYNC NOPROTO { int fdatasync(int fd); }
551 AUE_FSTAT STD { int freebsd32_fstat(int fd, \
struct stat32 *ub); }
diff --git a/sys/conf/files b/sys/conf/files
index b2fcc65773e0..ee18125a034f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -4041,7 +4041,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 a663deb59d1f..55072f1046f8 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -121,10 +121,12 @@ 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} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \
+ ${MACHINE_CPUARCH} == "i386") && \
+ defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == ""
+.error amd64/arm64/i386 kernel requires linker ifunc support
.endif
+.if ${MACHINE_CPUARCH} == "amd64"
LDFLAGS+= -Wl,-z max-page-size=2097152 -Wl,-z common-page-size=4096 -Wl,-z -Wl,ifunc-noplt
.endif
diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh
index 9e83b6379f51..5e749d52126d 100644
--- a/sys/conf/newvers.sh
+++ b/sys/conf/newvers.sh
@@ -46,7 +46,7 @@
TYPE="FreeBSD"
REVISION="12.0"
-BRANCH="ALPHA5"
+BRANCH="ALPHA8"
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/cpuctl/cpuctl.c b/sys/dev/cpuctl/cpuctl.c
index 33ac83eb731a..4f91b4fbbf28 100644
--- a/sys/dev/cpuctl/cpuctl.c
+++ b/sys/dev/cpuctl/cpuctl.c
@@ -362,7 +362,7 @@ update_intel(int cpu, cpuctl_update_args_t *args, struct thread *td)
set_cpu(cpu, td);
critical_enter();
- ret = ucode_intel_load(ptr, true);
+ ret = ucode_intel_load(ptr, true, NULL, NULL);
critical_exit();
restore_cpu(oldcpu, is_bound, td);
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) */
-
- 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 */
+ /* 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) */
+
+ 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
@@ -3756,6 +3756,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
* @mac: the MAC to setup
@@ -3772,52 +3859,44 @@ 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->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->supported & FW_PORT_CAP_ANEG) ||
- lc->requested_aneg == AUTONEG_DISABLE) {
+ if (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);
- }
+ 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) {
@@ -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);
}
@@ -7736,56 +7822,205 @@ const char *t4_link_down_rc_str(unsigned char 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);
-
- 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;
-
- 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);
-
- 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;
+ u32 stat, linkattr;
+ int old_ptype, old_mtype;
+
+ 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);
+
+ 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;
+
+ 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 @@ done:
* 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 @@ found:
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;
+ int rc;
rw_wlock(&d->lock);
- e = t4_alloc_l2e(d);
+ e = find_or_alloc_l2e(d, vlan, port, eth_addr);
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);
+ 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;
-}
-
-/*
- * 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);
+ 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 d6bf50121a15..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;
@@ -3954,7 +3965,7 @@ get_params__post_init(struct adapter *sc)
sc->toecaps = 0;
param[0] = FW_PARAM_DEV(NTID);
- rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 6, param, val);
+ rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, param, val);
if (rc != 0) {
device_printf(sc->dev,
"failed to query HASHFILTER parameters: %d.\n", rc);
@@ -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, &param, &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, &param, &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);
}
+/*
+ * Returns true if the ifmedia list for the port cannot change.
+ */
+static bool
+fixed_ifmedia(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 ||
+ 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, struct ifmedia *ifm)
+build_medialist(struct port_info *pi)
{
- uint16_t ss, speed;
+ 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 @@ no_media:
}
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 @@ no_media:
}
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 |
+ PAUSE_AUTONEG);
+
+ 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;
}
+}
- lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX);
+/*
+ * 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
+fixup_link_config(struct port_info *pi)
+{
+ int n = 0;
+ struct link_config *lc = &pi->link_cfg;
+ uint32_t fwspeed;
- 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;
+ 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 settings in requested_* to the hardware. The parameters are
- * expected to be sane.
+ * Apply the requested L1 settings, which are expected to be valid, to the
+ * hardware.
*/
static int
-apply_l1cfg(struct port_info *pi)
+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/hwpmc/hwpmc_logging.c b/sys/dev/hwpmc/hwpmc_logging.c
index 4d2e08fe157a..8764ac9e922c 100644
--- a/sys/dev/hwpmc/hwpmc_logging.c
+++ b/sys/dev/hwpmc/hwpmc_logging.c
@@ -234,7 +234,7 @@ static void pmclog_loop(void *arg);
static void pmclog_release(struct pmc_owner *po);
static uint32_t *pmclog_reserve(struct pmc_owner *po, int length);
static void pmclog_schedule_io(struct pmc_owner *po, int wakeup);
-static void pmclog_schedule_all(struct pmc_owner *po, int force);
+static void pmclog_schedule_all(struct pmc_owner *po);
static void pmclog_stop_kthread(struct pmc_owner *po);
/*
@@ -842,7 +842,7 @@ pmclog_flush(struct pmc_owner *po, int force)
goto error;
}
- pmclog_schedule_all(po, force);
+ pmclog_schedule_all(po);
error:
mtx_unlock(&pmc_kthread_mtx);
@@ -850,7 +850,7 @@ pmclog_flush(struct pmc_owner *po, int force)
}
static void
-pmclog_schedule_one_cond(struct pmc_owner *po, int force)
+pmclog_schedule_one_cond(struct pmc_owner *po)
{
struct pmclog_buffer *plb;
int cpu;
@@ -860,8 +860,7 @@ pmclog_schedule_one_cond(struct pmc_owner *po, int force)
/* tell hardclock not to run again */
if (PMC_CPU_HAS_SAMPLES(cpu))
PMC_CALL_HOOK_UNLOCKED(curthread, PMC_FN_DO_SAMPLES, NULL);
- if (force)
- pmc_flush_samples(cpu);
+
plb = po->po_curbuf[cpu];
if (plb && plb->plb_ptr != plb->plb_base)
pmclog_schedule_io(po, 1);
@@ -869,7 +868,7 @@ pmclog_schedule_one_cond(struct pmc_owner *po, int force)
}
static void
-pmclog_schedule_all(struct pmc_owner *po, int force)
+pmclog_schedule_all(struct pmc_owner *po)
{
/*
* Schedule the current buffer if any and not empty.
@@ -878,7 +877,7 @@ pmclog_schedule_all(struct pmc_owner *po, int force)
thread_lock(curthread);
sched_bind(curthread, i);
thread_unlock(curthread);
- pmclog_schedule_one_cond(po, force);
+ pmclog_schedule_one_cond(po);
}
thread_lock(curthread);
sched_unbind(curthread);
@@ -905,7 +904,7 @@ pmclog_close(struct pmc_owner *po)
/*
* Schedule the current buffer.
*/
- pmclog_schedule_all(po, 0);
+ pmclog_schedule_all(po);
wakeup_one(po);
mtx_unlock(&pmc_kthread_mtx);
diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c
index 4d7a4535d27b..1fad25c55702 100644
--- a/sys/dev/hwpmc/hwpmc_mod.c
+++ b/sys/dev/hwpmc/hwpmc_mod.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <sys/sx.h>
#include <sys/sysctl.h>
#include <sys/sysent.h>
+#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/vnode.h>
@@ -210,7 +211,7 @@ static int pmc_debugflags_parse(char *newstr, char *fence);
#endif
static int load(struct module *module, int cmd, void *arg);
-static int pmc_add_sample(int ring, struct pmc *pm, struct trapframe *tf);
+static int pmc_add_sample(ring_type_t ring, struct pmc *pm, struct trapframe *tf);
static void pmc_add_thread_descriptors_from_proc(struct proc *p,
struct pmc_process *pp);
static int pmc_attach_process(struct proc *p, struct pmc *pm);
@@ -248,7 +249,7 @@ static void pmc_process_csw_out(struct thread *td);
static void pmc_process_exit(void *arg, struct proc *p);
static void pmc_process_fork(void *arg, struct proc *p1,
struct proc *p2, int n);
-static void pmc_process_samples(int cpu, int soft);
+static void pmc_process_samples(int cpu, ring_type_t soft);
static void pmc_release_pmc_descriptor(struct pmc *pmc);
static void pmc_process_thread_add(struct thread *td);
static void pmc_process_thread_delete(struct thread *td);
@@ -341,6 +342,7 @@ static int pmc_nsamples = PMC_NSAMPLES;
SYSCTL_INT(_kern_hwpmc, OID_AUTO, nsamples, CTLFLAG_RDTUN,
&pmc_nsamples, 0, "number of PC samples per CPU");
+static uint64_t pmc_sample_mask = PMC_NSAMPLES-1;
/*
* kern.hwpmc.mtxpoolsize -- number of mutexes in the mutex pool.
@@ -1401,6 +1403,10 @@ pmc_process_csw_in(struct thread *td)
if (pm->pm_state != PMC_STATE_RUNNING)
continue;
+ KASSERT(counter_u64_fetch(pm->pm_runcount) >= 0,
+ ("[pmc,%d] pm=%p runcount %ld", __LINE__, (void *) pm,
+ (unsigned long)counter_u64_fetch(pm->pm_runcount)));
+
/* increment PMC runcount */
counter_u64_add(pm->pm_runcount, 1);
@@ -1595,6 +1601,10 @@ pmc_process_csw_out(struct thread *td)
if (pm->pm_pcpu_state[cpu].pps_stalled == 0)
pcd->pcd_stop_pmc(cpu, adjri);
+ KASSERT(counter_u64_fetch(pm->pm_runcount) > 0,
+ ("[pmc,%d] pm=%p runcount %ld", __LINE__, (void *) pm,
+ (unsigned long)counter_u64_fetch(pm->pm_runcount)));
+
/* reduce this PMC's runcount */
counter_u64_add(pm->pm_runcount, -1);
@@ -2724,7 +2734,7 @@ pmc_destroy_pmc_descriptor(struct pmc *pm)
static void
pmc_wait_for_pmc_idle(struct pmc *pm)
{
-#ifdef HWPMC_DEBUG
+#ifdef INVARIANTS
volatile int maxloop;
maxloop = 100 * pmc_cpu_max();
@@ -2736,7 +2746,7 @@ pmc_wait_for_pmc_idle(struct pmc *pm)
pmclog_flush(pm->pm_owner, 1);
while (counter_u64_fetch(pm->pm_runcount) > 0) {
pmclog_flush(pm->pm_owner, 1);
-#ifdef HWPMC_DEBUG
+#ifdef INVARIANTS
maxloop--;
KASSERT(maxloop > 0,
("[pmc,%d] (ri%d, rc%ld) waiting too long for "
@@ -3942,9 +3952,16 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
pmc->pm_flags = pa.pm_flags;
/* XXX set lower bound on sampling for process counters */
- if (PMC_IS_SAMPLING_MODE(mode))
- pmc->pm_sc.pm_reloadcount = pa.pm_count;
- else
+ if (PMC_IS_SAMPLING_MODE(mode)) {
+ /*
+ * Don't permit requested sample rate to be less than 1000
+ */
+ if (pa.pm_count < 1000)
+ log(LOG_WARNING,
+ "pmcallocate: passed sample rate %ju - setting to 1000\n",
+ (uintmax_t)pa.pm_count);
+ pmc->pm_sc.pm_reloadcount = MAX(1000, pa.pm_count);
+ } else
pmc->pm_sc.pm_initial = pa.pm_count;
/* switch thread to CPU 'cpu' */
@@ -4460,9 +4477,16 @@ pmc_syscall_handler(struct thread *td, void *syscall_args)
break;
}
- if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm)))
- pm->pm_sc.pm_reloadcount = sc.pm_count;
- else
+ if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) {
+ /*
+ * Don't permit requested sample rate to be less than 1000
+ */
+ if (sc.pm_count < 1000)
+ log(LOG_WARNING,
+ "pmcsetcount: passed sample rate %ju - setting to 1000\n",
+ (uintmax_t)sc.pm_count);
+ pm->pm_sc.pm_reloadcount = MAX(1000, sc.pm_count);
+ } else
pm->pm_sc.pm_initial = sc.pm_count;
}
break;
@@ -4642,7 +4666,7 @@ pmc_post_callchain_callback(void)
*/
static int
-pmc_add_sample(int ring, struct pmc *pm, struct trapframe *tf)
+pmc_add_sample(ring_type_t ring, struct pmc *pm, struct trapframe *tf)
{
int error, cpu, callchaindepth, inuserspace;
struct thread *td;
@@ -4657,18 +4681,15 @@ pmc_add_sample(int ring, struct pmc *pm, struct trapframe *tf)
cpu = curcpu;
psb = pmc_pcpu[cpu]->pc_sb[ring];
inuserspace = TRAPF_USERMODE(tf);
- ps = psb->ps_write;
- if (ps->ps_nsamples == PMC_SAMPLE_INUSE) {
- counter_u64_add(ps->ps_pmc->pm_runcount, -1);
- counter_u64_add(pmc_stats.pm_overwrites, 1);
- ps->ps_nsamples = 0;
- } else if (ps->ps_nsamples) { /* in use, reader hasn't caught up */
+ ps = PMC_PROD_SAMPLE(psb);
+ if (psb->ps_considx != psb->ps_prodidx &&
+ ps->ps_nsamples) { /* in use, reader hasn't caught up */
pm->pm_pcpu_state[cpu].pps_stalled = 1;
counter_u64_add(pmc_stats.pm_intr_bufferfull, 1);
PMCDBG6(SAM,INT,1,"(spc) cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d",
cpu, pm, (void *) tf, inuserspace,
- (int) (psb->ps_write - psb->ps_samples),
- (int) (psb->ps_read - psb->ps_samples));
+ (int) (psb->ps_prodidx & pmc_sample_mask),
+ (int) (psb->ps_considx & pmc_sample_mask));
callchaindepth = 1;
error = ENOMEM;
goto done;
@@ -4677,14 +4698,8 @@ pmc_add_sample(int ring, struct pmc *pm, struct trapframe *tf)
/* Fill in entry. */
PMCDBG6(SAM,INT,1,"cpu=%d pm=%p tf=%p um=%d wr=%d rd=%d", cpu, pm,
(void *) tf, inuserspace,
- (int) (psb->ps_write - psb->ps_samples),
- (int) (psb->ps_read - psb->ps_samples));
-
- KASSERT(counter_u64_fetch(pm->pm_runcount) >= 0,
- ("[pmc,%d] pm=%p runcount %ld", __LINE__, (void *) pm,
- (unsigned long)counter_u64_fetch(pm->pm_runcount)));
-
- counter_u64_add(pm->pm_runcount, 1); /* hold onto PMC */
+ (int) (psb->ps_prodidx & pmc_sample_mask),
+ (int) (psb->ps_considx & pmc_sample_mask));
td = curthread;
ps->ps_pmc = pm;
@@ -4692,13 +4707,14 @@ pmc_add_sample(int ring, struct pmc *pm, struct trapframe *tf)
ps->ps_pid = td->td_proc->p_pid;
ps->ps_tid = td->td_tid;
ps->ps_tsc = pmc_rdtsc();
-
+ ps->ps_ticks = ticks;
ps->ps_cpu = cpu;
ps->ps_flags = inuserspace ? PMC_CC_F_USERSPACE : 0;
callchaindepth = (pm->pm_flags & PMC_F_CALLCHAIN) ?
pmc_callchaindepth : 1;
+ MPASS(ps->ps_pc != NULL);
if (callchaindepth == 1)
ps->ps_pc[0] = PMC_TRAPFRAME_TO_PC(tf);
else {
@@ -4712,26 +4728,27 @@ pmc_add_sample(int ring, struct pmc *pm, struct trapframe *tf)
callchaindepth, tf);
} else {
pmc_post_callchain_callback();
- callchaindepth = PMC_SAMPLE_INUSE;
+ callchaindepth = PMC_USER_CALLCHAIN_PENDING;
}
}
ps->ps_nsamples = callchaindepth; /* mark entry as in use */
if (ring == PMC_UR) {
ps->ps_nsamples_actual = callchaindepth; /* mark entry as in use */
- ps->ps_nsamples = PMC_SAMPLE_INUSE;
+ ps->ps_nsamples = PMC_USER_CALLCHAIN_PENDING;
} else
ps->ps_nsamples = callchaindepth; /* mark entry as in use */
- /* increment write pointer, modulo ring buffer size */
- ps++;
- if (ps == psb->ps_fence)
- psb->ps_write = psb->ps_samples;
- else
- psb->ps_write = ps;
+ KASSERT(counter_u64_fetch(pm->pm_runcount) >= 0,
+ ("[pmc,%d] pm=%p runcount %ld", __LINE__, (void *) pm,
+ (unsigned long)counter_u64_fetch(pm->pm_runcount)));
+
+ counter_u64_add(pm->pm_runcount, 1); /* hold onto PMC */
+ /* increment write pointer */
+ psb->ps_prodidx++;
done:
/* mark CPU as needing processing */
- if (callchaindepth != PMC_SAMPLE_INUSE)
+ if (callchaindepth != PMC_USER_CALLCHAIN_PENDING)
DPCPU_SET(pmc_sampled, 1);
return (error);
@@ -4770,14 +4787,15 @@ pmc_capture_user_callchain(int cpu, int ring, struct trapframe *tf)
{
struct pmc *pm;
struct thread *td;
- struct pmc_sample *ps, *ps_end;
+ struct pmc_sample *ps;
struct pmc_samplebuffer *psb;
- int nsamples, nrecords, pass;
+ uint64_t considx, prodidx;
+ int nsamples, nrecords, pass, iter;
#ifdef INVARIANTS
int ncallchains;
int nfree;
+ int start_ticks = ticks;
#endif
-
psb = pmc_pcpu[cpu]->pc_sb[ring];
td = curthread;
@@ -4795,29 +4813,30 @@ pmc_capture_user_callchain(int cpu, int ring, struct trapframe *tf)
if (ring == PMC_UR)
nrecords = atomic_readandclear_32(&td->td_pmcpend);
+ for (iter = 0, considx = psb->ps_considx, prodidx = psb->ps_prodidx;
+ considx < prodidx && iter < pmc_nsamples; considx++, iter++) {
+ ps = PMC_CONS_SAMPLE_OFF(psb, considx);
+
/*
* Iterate through all deferred callchain requests.
* Walk from the current read pointer to the current
* write pointer.
*/
- ps = psb->ps_read;
- ps_end = psb->ps_write;
- do {
#ifdef INVARIANTS
if (ps->ps_nsamples == PMC_SAMPLE_FREE) {
nfree++;
- goto next;
+ continue;
}
if ((ps->ps_pmc == NULL) ||
(ps->ps_pmc->pm_state != PMC_STATE_RUNNING))
nfree++;
#endif
- if (ps->ps_nsamples != PMC_SAMPLE_INUSE)
- goto next;
- if (ps->ps_td != td)
- goto next;
+ if (ps->ps_td != td ||
+ ps->ps_nsamples == PMC_USER_CALLCHAIN_PENDING ||
+ ps->ps_pmc->pm_state != PMC_STATE_RUNNING)
+ continue;
KASSERT(ps->ps_cpu == cpu,
("[pmc,%d] cpu mismatch ps_cpu=%d pcpu=%d", __LINE__,
@@ -4850,15 +4869,28 @@ pmc_capture_user_callchain(int cpu, int ring, struct trapframe *tf)
if (__predict_true(nsamples < pmc_callchaindepth - 1))
nsamples += pmc_save_user_callchain(ps->ps_pc + nsamples,
pmc_callchaindepth - nsamples - 1, tf);
- wmb();
- ps->ps_nsamples = nsamples;
+
+ /*
+ * We have to prevent hardclock from potentially overwriting
+ * this sample between when we read the value and when we set
+ * it
+ */
+ spinlock_enter();
+ /*
+ * Verify that the sample hasn't been dropped in the meantime
+ */
+ if (ps->ps_nsamples == PMC_USER_CALLCHAIN_PENDING) {
+ ps->ps_nsamples = nsamples;
+ /*
+ * If we couldn't get a sample, simply drop the reference
+ */
+ if (nsamples == 0)
+ counter_u64_add(pm->pm_runcount, -1);
+ }
+ spinlock_exit();
if (nrecords-- == 1)
break;
-next:
- /* increment the pointer, modulo sample ring size */
- if (++ps == psb->ps_fence)
- ps = psb->ps_samples;
- } while (ps != ps_end);
+ }
if (__predict_false(ring == PMC_UR && td->td_pmcpend)) {
if (pass == 0) {
pass = 1;
@@ -4869,60 +4901,20 @@ next:
}
#ifdef INVARIANTS
- if (ring == PMC_HR)
- KASSERT(ncallchains > 0 || nfree > 0,
- ("[pmc,%d] cpu %d didn't find a sample to collect", __LINE__,
- cpu));
+ if ((ticks - start_ticks) > hz)
+ log(LOG_ERR, "%s took %d ticks\n", __func__, (ticks - start_ticks));
#endif
/* mark CPU as needing processing */
DPCPU_SET(pmc_sampled, 1);
}
-
-static void
-pmc_flush_ring(int cpu, int ring)
-{
- struct pmc *pm;
- struct pmc_sample *ps;
- struct pmc_samplebuffer *psb;
- int n;
-
- psb = pmc_pcpu[cpu]->pc_sb[ring];
-
- for (n = 0; n < pmc_nsamples; n++) { /* bound on #iterations */
-
- ps = psb->ps_read;
- if (ps->ps_nsamples == PMC_SAMPLE_FREE)
- goto next;
- pm = ps->ps_pmc;
- counter_u64_add(pm->pm_runcount, -1);
- ps->ps_nsamples = PMC_SAMPLE_FREE;
- /* increment read pointer, modulo sample size */
- next:
- if (++ps == psb->ps_fence)
- psb->ps_read = psb->ps_samples;
- else
- psb->ps_read = ps;
- }
-}
-
-void
-pmc_flush_samples(int cpu)
-{
- int n;
-
- for (n = 0; n < PMC_NUM_SR; n++)
- pmc_flush_ring(cpu, n);
-}
-
-
/*
* Process saved PC samples.
*/
static void
-pmc_process_samples(int cpu, int ring)
+pmc_process_samples(int cpu, ring_type_t ring)
{
struct pmc *pm;
int adjri, n;
@@ -4931,20 +4923,25 @@ pmc_process_samples(int cpu, int ring)
struct pmc_sample *ps;
struct pmc_classdep *pcd;
struct pmc_samplebuffer *psb;
+ uint64_t delta;
KASSERT(PCPU_GET(cpuid) == cpu,
("[pmc,%d] not on the correct CPU pcpu=%d cpu=%d", __LINE__,
PCPU_GET(cpuid), cpu));
psb = pmc_pcpu[cpu]->pc_sb[ring];
+ delta = psb->ps_prodidx - psb->ps_considx;
+ MPASS(delta <= pmc_nsamples);
+ MPASS(psb->ps_considx <= psb->ps_prodidx);
+ for (n = 0; psb->ps_considx < psb->ps_prodidx; psb->ps_considx++, n++) {
+ ps = PMC_CONS_SAMPLE(psb);
- for (n = 0; n < pmc_nsamples; n++) { /* bound on #iterations */
-
- ps = psb->ps_read;
- if (ps->ps_nsamples == PMC_SAMPLE_FREE)
- break;
-
+ if (__predict_false(ps->ps_nsamples == PMC_SAMPLE_FREE))
+ continue;
pm = ps->ps_pmc;
+ /* skip non-running samples */
+ if (pm->pm_state != PMC_STATE_RUNNING)
+ goto entrydone;
KASSERT(counter_u64_fetch(pm->pm_runcount) > 0,
("[pmc,%d] pm=%p runcount %ld", __LINE__, (void *) pm,
@@ -4956,12 +4953,19 @@ pmc_process_samples(int cpu, int ring)
("[pmc,%d] pmc=%p non-sampling mode=%d", __LINE__,
pm, PMC_TO_MODE(pm)));
- /* Ignore PMCs that have been switched off */
- if (pm->pm_state != PMC_STATE_RUNNING)
- goto entrydone;
/* If there is a pending AST wait for completion */
- if (ps->ps_nsamples == PMC_SAMPLE_INUSE) {
+ if (ps->ps_nsamples == PMC_USER_CALLCHAIN_PENDING) {
+ /* if sample is more than 65 ms old, drop it */
+ if (ticks - ps->ps_ticks > (hz >> 4)) {
+ /*
+ * track how often we hit this as it will
+ * preferentially lose user samples
+ * for long running system calls
+ */
+ counter_u64_add(pmc_stats.pm_overwrites, 1);
+ goto entrydone;
+ }
/* Need a rescan at a later time. */
DPCPU_SET(pmc_sampled, 1);
break;
@@ -4969,8 +4973,8 @@ pmc_process_samples(int cpu, int ring)
PMCDBG6(SAM,OPS,1,"cpu=%d pm=%p n=%d fl=%x wr=%d rd=%d", cpu,
pm, ps->ps_nsamples, ps->ps_flags,
- (int) (psb->ps_write - psb->ps_samples),
- (int) (psb->ps_read - psb->ps_samples));
+ (int) (psb->ps_prodidx & pmc_sample_mask),
+ (int) (psb->ps_considx & pmc_sample_mask));
/*
* If this is a process-mode PMC that is attached to
@@ -4993,13 +4997,11 @@ pmc_process_samples(int cpu, int ring)
entrydone:
ps->ps_nsamples = 0; /* mark entry as free */
- counter_u64_add(pm->pm_runcount, -1);
+ KASSERT(counter_u64_fetch(pm->pm_runcount) > 0,
+ ("[pmc,%d] pm=%p runcount %ld", __LINE__, (void *) pm,
+ (unsigned long)counter_u64_fetch(pm->pm_runcount)));
- /* increment read pointer, modulo sample size */
- if (++ps == psb->ps_fence)
- psb->ps_read = psb->ps_samples;
- else
- psb->ps_read = ps;
+ counter_u64_add(pm->pm_runcount, -1);
}
counter_u64_add(pmc_stats.pm_log_sweeps, 1);
@@ -5182,11 +5184,11 @@ pmc_process_exit(void *arg __unused, struct proc *p)
}
}
- counter_u64_add(pm->pm_runcount, -1);
-
- KASSERT((int) counter_u64_fetch(pm->pm_runcount) >= 0,
+ KASSERT((int64_t) counter_u64_fetch(pm->pm_runcount) > 0,
("[pmc,%d] runcount is %d", __LINE__, ri));
+ counter_u64_add(pm->pm_runcount, -1);
+
(void) pcd->pcd_config_pmc(cpu, adjri, NULL);
}
@@ -5568,6 +5570,7 @@ pmc_initialize(void)
"range.\n", pmc_nsamples);
pmc_nsamples = PMC_NSAMPLES;
}
+ pmc_sample_mask = pmc_nsamples-1;
if (pmc_callchaindepth <= 0 ||
pmc_callchaindepth > PMC_CALLCHAIN_DEPTH_MAX) {
@@ -5643,8 +5646,6 @@ pmc_initialize(void)
sb = malloc_domain(sizeof(struct pmc_samplebuffer) +
pmc_nsamples * sizeof(struct pmc_sample), M_PMC, domain,
M_WAITOK|M_ZERO);
- sb->ps_read = sb->ps_write = sb->ps_samples;
- sb->ps_fence = sb->ps_samples + pmc_nsamples;
KASSERT(pmc_pcpu[cpu] != NULL,
("[pmc,%d] cpu=%d Null per-cpu data", __LINE__, cpu));
@@ -5661,8 +5662,6 @@ pmc_initialize(void)
sb = malloc_domain(sizeof(struct pmc_samplebuffer) +
pmc_nsamples * sizeof(struct pmc_sample), M_PMC, domain,
M_WAITOK|M_ZERO);
- sb->ps_read = sb->ps_write = sb->ps_samples;
- sb->ps_fence = sb->ps_samples + pmc_nsamples;
KASSERT(pmc_pcpu[cpu] != NULL,
("[pmc,%d] cpu=%d Null per-cpu data", __LINE__, cpu));
@@ -5679,8 +5678,6 @@ pmc_initialize(void)
sb = malloc_domain(sizeof(struct pmc_samplebuffer) +
pmc_nsamples * sizeof(struct pmc_sample), M_PMC, domain,
M_WAITOK|M_ZERO);
- sb->ps_read = sb->ps_write = sb->ps_samples;
- sb->ps_fence = sb->ps_samples + pmc_nsamples;
KASSERT(pmc_pcpu[cpu] != NULL,
("[pmc,%d] cpu=%d Null per-cpu data", __LINE__, cpu));
diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c
index 237e24c10706..11beb743ed4b 100644
--- a/sys/dev/ichiic/ig4_iic.c
+++ b/sys/dev/ichiic/ig4_iic.c
@@ -729,9 +729,9 @@ ig4iic_intr(void *cookie)
* Workaround to trigger pending interrupt if IG4_REG_INTR_STAT
* is changed after clearing it
*/
- if(sc->access_intr_mask) {
+ if (sc->access_intr_mask != 0) {
status = reg_read(sc, IG4_REG_INTR_MASK);
- if(status) {
+ if (status != 0) {
reg_write(sc, IG4_REG_INTR_MASK, 0);
reg_write(sc, IG4_REG_INTR_MASK, status);
}
diff --git a/sys/dev/ichiic/ig4_pci.c b/sys/dev/ichiic/ig4_pci.c
index eed7d651bfde..ae73f3b2abca 100644
--- a/sys/dev/ichiic/ig4_pci.c
+++ b/sys/dev/ichiic/ig4_pci.c
@@ -112,8 +112,8 @@ static struct ig4iic_pci_device ig4iic_pci_devices[] = {
{ PCI_CHIP_SKYLAKE_I2C_3, "Intel Sunrise Point-LP I2C Controller-3", IG4_SKYLAKE},
{ PCI_CHIP_SKYLAKE_I2C_4, "Intel Sunrise Point-LP I2C Controller-4", IG4_SKYLAKE},
{ PCI_CHIP_SKYLAKE_I2C_5, "Intel Sunrise Point-LP I2C Controller-5", IG4_SKYLAKE},
- { PCI_CHIP_KABYLAKE_I2C_0, "Intel Sunrise Point-LP I2C Controller-0", IG4_SKYLAKE},
- { PCI_CHIP_KABYLAKE_I2C_1, "Intel Sunrise Point-LP I2C Controller-1", IG4_SKYLAKE},
+ { PCI_CHIP_KABYLAKE_I2C_0, "Intel Sunrise Point-H I2C Controller-0", IG4_SKYLAKE},
+ { PCI_CHIP_KABYLAKE_I2C_1, "Intel Sunrise Point-H I2C Controller-1", IG4_SKYLAKE},
{ PCI_CHIP_APL_I2C_0, "Intel Apollo Lake I2C Controller-0", IG4_APL},
{ PCI_CHIP_APL_I2C_1, "Intel Apollo Lake I2C Controller-1", IG4_APL},
{ PCI_CHIP_APL_I2C_2, "Intel Apollo Lake I2C Controller-2", IG4_APL},
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/iwm/if_iwm.c b/sys/dev/iwm/if_iwm.c
index 9daa85257ac9..4e08dacf8c4f 100644
--- a/sys/dev/iwm/if_iwm.c
+++ b/sys/dev/iwm/if_iwm.c
@@ -6460,6 +6460,8 @@ static driver_t iwm_pci_driver = {
static devclass_t iwm_devclass;
DRIVER_MODULE(iwm, pci, iwm_pci_driver, iwm_devclass, NULL, NULL);
+MODULE_PNP_INFO("U16:device;P:#;T:vendor=0x8086", pci, iwm_pci_driver,
+ iwm_devices, nitems(iwm_devices));
MODULE_DEPEND(iwm, firmware, 1, 1, 1);
MODULE_DEPEND(iwm, pci, 1, 1, 1);
MODULE_DEPEND(iwm, wlan, 1, 1, 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/pci_user.c b/sys/dev/pci/pci_user.c
index 4e40a8167362..380beff0d310 100644
--- a/sys/dev/pci/pci_user.c
+++ b/sys/dev/pci/pci_user.c
@@ -66,6 +66,49 @@ __FBSDID("$FreeBSD$");
#include "pcib_if.h"
#include "pci_if.h"
+#ifdef COMPAT_FREEBSD32
+struct pci_conf32 {
+ struct pcisel pc_sel; /* domain+bus+slot+function */
+ u_int8_t pc_hdr; /* PCI header type */
+ u_int16_t pc_subvendor; /* card vendor ID */
+ u_int16_t pc_subdevice; /* card device ID, assigned by
+ card vendor */
+ u_int16_t pc_vendor; /* chip vendor ID */
+ u_int16_t pc_device; /* chip device ID, assigned by
+ chip vendor */
+ u_int8_t pc_class; /* chip PCI class */
+ u_int8_t pc_subclass; /* chip PCI subclass */
+ u_int8_t pc_progif; /* chip PCI programming interface */
+ u_int8_t pc_revid; /* chip revision ID */
+ char pd_name[PCI_MAXNAMELEN + 1]; /* device name */
+ u_int32_t pd_unit; /* device unit number */
+};
+
+struct pci_match_conf32 {
+ struct pcisel pc_sel; /* domain+bus+slot+function */
+ char pd_name[PCI_MAXNAMELEN + 1]; /* device name */
+ u_int32_t pd_unit; /* Unit number */
+ u_int16_t pc_vendor; /* PCI Vendor ID */
+ u_int16_t pc_device; /* PCI Device ID */
+ u_int8_t pc_class; /* PCI class */
+ u_int32_t flags; /* Matching expression */
+};
+
+struct pci_conf_io32 {
+ u_int32_t pat_buf_len; /* pattern buffer length */
+ u_int32_t num_patterns; /* number of patterns */
+ u_int32_t patterns; /* struct pci_match_conf ptr */
+ u_int32_t match_buf_len; /* match buffer length */
+ u_int32_t num_matches; /* number of matches returned */
+ u_int32_t matches; /* struct pci_conf ptr */
+ u_int32_t offset; /* offset into device list */
+ u_int32_t generation; /* device list generation */
+ u_int32_t status; /* request status */
+};
+
+#define PCIOCGETCONF32 _IOC_NEWTYPE(PCIOCGETCONF, struct pci_conf_io32)
+#endif
+
/*
* This is the user interface to PCI configuration space.
*/
@@ -175,6 +218,73 @@ pci_conf_match_native(struct pci_match_conf *matches, int num_matches,
return(1);
}
+#ifdef COMPAT_FREEBSD32
+static int
+pci_conf_match32(struct pci_match_conf32 *matches, int num_matches,
+ struct pci_conf *match_buf)
+{
+ int i;
+
+ if ((matches == NULL) || (match_buf == NULL) || (num_matches <= 0))
+ return(1);
+
+ for (i = 0; i < num_matches; i++) {
+ /*
+ * I'm not sure why someone would do this...but...
+ */
+ if (matches[i].flags == PCI_GETCONF_NO_MATCH)
+ continue;
+
+ /*
+ * Look at each of the match flags. If it's set, do the
+ * comparison. If the comparison fails, we don't have a
+ * match, go on to the next item if there is one.
+ */
+ if (((matches[i].flags & PCI_GETCONF_MATCH_DOMAIN) != 0)
+ && (match_buf->pc_sel.pc_domain !=
+ matches[i].pc_sel.pc_domain))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_BUS) != 0)
+ && (match_buf->pc_sel.pc_bus != matches[i].pc_sel.pc_bus))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_DEV) != 0)
+ && (match_buf->pc_sel.pc_dev != matches[i].pc_sel.pc_dev))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_FUNC) != 0)
+ && (match_buf->pc_sel.pc_func != matches[i].pc_sel.pc_func))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_VENDOR) != 0)
+ && (match_buf->pc_vendor != matches[i].pc_vendor))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_DEVICE) != 0)
+ && (match_buf->pc_device != matches[i].pc_device))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_CLASS) != 0)
+ && (match_buf->pc_class != matches[i].pc_class))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_UNIT) != 0)
+ && (match_buf->pd_unit != matches[i].pd_unit))
+ continue;
+
+ if (((matches[i].flags & PCI_GETCONF_MATCH_NAME) != 0)
+ && (strncmp(matches[i].pd_name, match_buf->pd_name,
+ sizeof(match_buf->pd_name)) != 0))
+ continue;
+
+ return(0);
+ }
+
+ return(1);
+}
+#endif /* COMPAT_FREEBSD32 */
+
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6)
#define PRE7_COMPAT
@@ -259,20 +369,6 @@ struct pci_match_conf_old32 {
pci_getconf_flags_old flags; /* Matching expression */
};
-struct pci_conf_io32 {
- uint32_t pat_buf_len; /* pattern buffer length */
- uint32_t num_patterns; /* number of patterns */
- uint32_t patterns; /* pattern buffer
- (struct pci_match_conf_old32 *) */
- uint32_t match_buf_len; /* match buffer length */
- uint32_t num_matches; /* number of matches returned */
- uint32_t matches; /* match buffer
- (struct pci_conf_old32 *) */
- uint32_t offset; /* offset into device list */
- uint32_t generation; /* device list generation */
- pci_getconf_status status; /* request status */
-};
-
#define PCIOCGETCONF_OLD32 _IOWR('p', 1, struct pci_conf_io32)
#endif /* COMPAT_FREEBSD32 */
@@ -411,6 +507,9 @@ pci_conf_match_old32(struct pci_match_conf_old32 *matches, int num_matches,
union pci_conf_union {
struct pci_conf pc;
+#ifdef COMPAT_FREEBSD32
+ struct pci_conf32 pc32;
+#endif
#ifdef PRE7_COMPAT
struct pci_conf_old pco;
#ifdef COMPAT_FREEBSD32
@@ -428,6 +527,11 @@ pci_conf_match(u_long cmd, struct pci_match_conf *matches, int num_matches,
case PCIOCGETCONF:
return (pci_conf_match_native(
(struct pci_match_conf *)matches, num_matches, match_buf));
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+ return (pci_conf_match32((struct pci_match_conf32 *)matches,
+ num_matches, match_buf));
+#endif
#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD:
return (pci_conf_match_old(
@@ -544,6 +648,10 @@ pci_match_conf_size(u_long cmd)
switch (cmd) {
case PCIOCGETCONF:
return (sizeof(struct pci_match_conf));
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+ return (sizeof(struct pci_match_conf32));
+#endif
#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD:
return (sizeof(struct pci_match_conf_old));
@@ -565,6 +673,10 @@ pci_conf_size(u_long cmd)
switch (cmd) {
case PCIOCGETCONF:
return (sizeof(struct pci_conf));
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+ return (sizeof(struct pci_conf32));
+#endif
#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD:
return (sizeof(struct pci_conf_old));
@@ -582,7 +694,7 @@ pci_conf_size(u_long cmd)
static void
pci_conf_io_init(struct pci_conf_io *cio, caddr_t data, u_long cmd)
{
-#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+#if defined(COMPAT_FREEBSD32)
struct pci_conf_io32 *cio32;
#endif
@@ -594,8 +706,11 @@ pci_conf_io_init(struct pci_conf_io *cio, caddr_t data, u_long cmd)
*cio = *(struct pci_conf_io *)data;
return;
-#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD32:
+#endif
cio32 = (struct pci_conf_io32 *)data;
cio->pat_buf_len = cio32->pat_buf_len;
cio->num_patterns = cio32->num_patterns;
@@ -620,7 +735,7 @@ pci_conf_io_update_data(const struct pci_conf_io *cio, caddr_t data,
u_long cmd)
{
struct pci_conf_io *d_cio;
-#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+#if defined(COMPAT_FREEBSD32)
struct pci_conf_io32 *cio32;
#endif
@@ -636,8 +751,11 @@ pci_conf_io_update_data(const struct pci_conf_io *cio, caddr_t data,
d_cio->num_matches = cio->num_matches;
return;
-#if defined(PRE7_COMPAT) && defined(COMPAT_FREEBSD32)
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+#ifdef PRE7_COMPAT
case PCIOCGETCONF_OLD32:
+#endif
cio32 = (struct pci_conf_io32 *)data;
cio32->status = cio->status;
@@ -665,6 +783,24 @@ pci_conf_for_copyout(const struct pci_conf *pcp, union pci_conf_union *pcup,
pcup->pc = *pcp;
return;
+#ifdef COMPAT_FREEBSD32
+ case PCIOCGETCONF32:
+ pcup->pc32.pc_sel = pcp->pc_sel;
+ pcup->pc32.pc_hdr = pcp->pc_hdr;
+ pcup->pc32.pc_subvendor = pcp->pc_subvendor;
+ pcup->pc32.pc_subdevice = pcp->pc_subdevice;
+ pcup->pc32.pc_vendor = pcp->pc_vendor;
+ pcup->pc32.pc_device = pcp->pc_device;
+ pcup->pc32.pc_class = pcp->pc_class;
+ pcup->pc32.pc_subclass = pcp->pc_subclass;
+ pcup->pc32.pc_progif = pcp->pc_progif;
+ pcup->pc32.pc_revid = pcp->pc_revid;
+ strlcpy(pcup->pc32.pd_name, pcp->pd_name,
+ sizeof(pcup->pc32.pd_name));
+ pcup->pc32.pd_unit = (uint32_t)pcp->pd_unit;
+ return;
+#endif
+
#ifdef PRE7_COMPAT
#ifdef COMPAT_FREEBSD32
case PCIOCGETCONF_OLD32:
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/sdhci/sdhci_acpi.c b/sys/dev/sdhci/sdhci_acpi.c
index 844be21d64bc..c202ba054cfc 100644
--- a/sys/dev/sdhci/sdhci_acpi.c
+++ b/sys/dev/sdhci/sdhci_acpi.c
@@ -79,6 +79,8 @@ static const struct sdhci_acpi_device {
SDHCI_QUIRK_MMC_DDR52 |
SDHCI_QUIRK_CAPS_BIT63_FOR_MMC_HS400 |
SDHCI_QUIRK_PRESET_VALUE_BROKEN },
+ { "AMDI0040", 0, "AMD eMMC 5.0 Controller",
+ SDHCI_QUIRK_32BIT_DMA_SIZE },
{ NULL, 0, NULL, 0}
};
@@ -87,6 +89,7 @@ static char *sdhci_ids[] = {
"80860F16",
"80865ACA",
"80865ACC",
+ "AMDI0040",
NULL
};
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/net/if_ure.c b/sys/dev/usb/net/if_ure.c
index 2bf0609697ed..24ce36b64a62 100644
--- a/sys/dev/usb/net/if_ure.c
+++ b/sys/dev/usb/net/if_ure.c
@@ -169,6 +169,7 @@ MODULE_DEPEND(ure, usb, 1, 1, 1);
MODULE_DEPEND(ure, ether, 1, 1, 1);
MODULE_DEPEND(ure, miibus, 1, 1, 1);
MODULE_VERSION(ure, 1);
+USB_PNP_HOST_INFO(ure_devs);
static const struct usb_ether_methods ure_ue_methods = {
.ue_attach_post = ure_attach_post,
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 @@ cleanup:
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);
@@ -1100,19 +1147,6 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate,
}
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)
{
struct env87 *penv_87;
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 0c1437df5187..9dd80ad72d49 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);
@@ -574,8 +579,11 @@ pmap_bootstrap(vm_paddr_t firstaddr)
vm_offset_t va;
pt_entry_t *pte, *unused;
struct pcpu *pc;
+ u_long res;
int i;
+ res = atop(firstaddr - (vm_paddr_t)KERNLOAD);
+
/*
* Add a physical memory segment (vm_phys_seg) corresponding to the
* preallocated kernel page table pages so that vm_page structures
@@ -593,11 +601,12 @@ pmap_bootstrap(vm_paddr_t firstaddr)
* unused virtual address in addition to "firstaddr".
*/
virtual_avail = (vm_offset_t)firstaddr;
-
virtual_end = VM_MAX_KERNEL_ADDRESS;
/*
* Initialize the kernel pmap (which is statically allocated).
+ * Count bootstrap data as being resident in case any of this data is
+ * later unmapped (using pmap_remove()) and freed.
*/
PMAP_LOCK_INIT(kernel_pmap);
kernel_pmap->pm_pdir = IdlePTD;
@@ -605,6 +614,7 @@ pmap_bootstrap(vm_paddr_t firstaddr)
kernel_pmap->pm_pdpt = IdlePDPT;
#endif
CPU_FILL(&kernel_pmap->pm_active); /* don't allow deactivation */
+ kernel_pmap->pm_stats.resident_count = res;
TAILQ_INIT(&kernel_pmap->pm_pvchunk);
/*
@@ -1407,37 +1417,64 @@ pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde)
pmap_invalidate_page(pmap, va);
}
+DEFINE_IFUNC(, void, pmap_invalidate_cache_range, (vm_offset_t, vm_offset_t),
+ static)
+{
+
+ 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_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force)
+pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
{
- 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"));
+ 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;
+ /*
+ * 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
+
+ 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
@@ -1447,12 +1484,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 +1494,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 +5511,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 +5750,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 @@ kernel_trctrap:
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/init_sysent.c b/sys/kern/init_sysent.c
index 5ea572ff0381..885b5dc6f030 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -233,10 +233,10 @@ struct sysent sysent[] = {
{ AS(setgid_args), (sy_call_t *)sys_setgid, AUE_SETGID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 181 = setgid */
{ AS(setegid_args), (sy_call_t *)sys_setegid, AUE_SETEGID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 182 = setegid */
{ AS(seteuid_args), (sy_call_t *)sys_seteuid, AUE_SETEUID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 183 = seteuid */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 184 = lfs_bmapv */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 185 = lfs_markv */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 186 = lfs_segclean */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = lfs_segwait */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 184 = obsolete lfs_bmapv */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 185 = obsolete lfs_markv */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 186 = obsolete lfs_segclean */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 187 = obsolete lfs_segwait */
{ compat11(AS(freebsd11_stat_args),stat), AUE_STAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 188 = freebsd11 stat */
{ compat11(AS(freebsd11_fstat_args),fstat), AUE_FSTAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 189 = freebsd11 fstat */
{ compat11(AS(freebsd11_lstat_args),lstat), AUE_LSTAT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 190 = freebsd11 lstat */
@@ -272,7 +272,7 @@ struct sysent sysent[] = {
{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 220 = freebsd7 __semctl */
{ AS(semget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 221 = semget */
{ AS(semop_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 222 = semop */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 223 = semconfig */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 223 = obsolete semconfig */
{ 0, (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 224 = freebsd7 msgctl */
{ AS(msgget_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 225 = msgget */
{ AS(msgsnd_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 226 = msgsnd */
@@ -413,26 +413,26 @@ struct sysent sysent[] = {
{ AS(getresgid_args), (sy_call_t *)sys_getresgid, AUE_GETRESGID, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 361 = getresgid */
{ 0, (sy_call_t *)sys_kqueue, AUE_KQUEUE, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 362 = kqueue */
{ compat11(AS(freebsd11_kevent_args),kevent), AUE_KEVENT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 363 = freebsd11 kevent */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 364 = __cap_get_proc */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 365 = __cap_set_proc */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 366 = __cap_get_fd */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 367 = __cap_get_file */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 368 = __cap_set_fd */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 369 = __cap_set_file */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 364 = obsolete __cap_get_proc */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 365 = obsolete __cap_set_proc */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 366 = obsolete __cap_get_fd */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 367 = obsolete __cap_get_file */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 368 = obsolete __cap_set_fd */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 369 = obsolete __cap_set_file */
{ 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 370 = nosys */
{ AS(extattr_set_fd_args), (sy_call_t *)sys_extattr_set_fd, AUE_EXTATTR_SET_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 371 = extattr_set_fd */
{ AS(extattr_get_fd_args), (sy_call_t *)sys_extattr_get_fd, AUE_EXTATTR_GET_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 372 = extattr_get_fd */
{ AS(extattr_delete_fd_args), (sy_call_t *)sys_extattr_delete_fd, AUE_EXTATTR_DELETE_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 373 = extattr_delete_fd */
{ AS(__setugid_args), (sy_call_t *)sys___setugid, AUE_SETUGID, NULL, 0, 0, 0, SY_THR_STATIC }, /* 374 = __setugid */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 375 = nfsclnt */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 375 = obsolete nfsclnt */
{ AS(eaccess_args), (sy_call_t *)sys_eaccess, AUE_EACCESS, NULL, 0, 0, 0, SY_THR_STATIC }, /* 376 = eaccess */
{ AS(afs3_syscall_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 377 = afs3_syscall */
{ AS(nmount_args), (sy_call_t *)sys_nmount, AUE_NMOUNT, NULL, 0, 0, 0, SY_THR_STATIC }, /* 378 = nmount */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 379 = kse_exit */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 380 = kse_wakeup */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 381 = kse_create */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 382 = kse_thr_interrupt */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 383 = kse_release */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 379 = obsolete kse_exit */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 380 = obsolete kse_wakeup */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 381 = obsolete kse_create */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 382 = obsolete kse_thr_interrupt */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 383 = obsolete kse_release */
{ AS(__mac_get_proc_args), (sy_call_t *)sys___mac_get_proc, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 384 = __mac_get_proc */
{ AS(__mac_set_proc_args), (sy_call_t *)sys___mac_set_proc, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 385 = __mac_set_proc */
{ AS(__mac_get_fd_args), (sy_call_t *)sys___mac_get_fd, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 386 = __mac_get_fd */
@@ -489,7 +489,7 @@ struct sysent sysent[] = {
{ AS(extattr_list_fd_args), (sy_call_t *)sys_extattr_list_fd, AUE_EXTATTR_LIST_FD, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 437 = extattr_list_fd */
{ AS(extattr_list_file_args), (sy_call_t *)sys_extattr_list_file, AUE_EXTATTR_LIST_FILE, NULL, 0, 0, 0, SY_THR_STATIC }, /* 438 = extattr_list_file */
{ AS(extattr_list_link_args), (sy_call_t *)sys_extattr_list_link, AUE_EXTATTR_LIST_LINK, NULL, 0, 0, 0, SY_THR_STATIC }, /* 439 = extattr_list_link */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 440 = kse_switchin */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 440 = obsolete kse_switchin */
{ AS(ksem_timedwait_args), (sy_call_t *)lkmressys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 441 = ksem_timedwait */
{ AS(thr_suspend_args), (sy_call_t *)sys_thr_suspend, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 442 = thr_suspend */
{ AS(thr_wake_args), (sy_call_t *)sys_thr_wake, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 443 = thr_wake */
@@ -597,8 +597,8 @@ struct sysent sysent[] = {
{ AS(ppoll_args), (sy_call_t *)sys_ppoll, AUE_POLL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 545 = ppoll */
{ AS(futimens_args), (sy_call_t *)sys_futimens, AUE_FUTIMES, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 546 = futimens */
{ AS(utimensat_args), (sy_call_t *)sys_utimensat, AUE_FUTIMESAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 547 = utimensat */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 548 = numa_getaffinity */
- { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 549 = numa_setaffinity */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 548 = obsolete numa_getaffinity */
+ { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_ABSENT }, /* 549 = obsolete numa_setaffinity */
{ AS(fdatasync_args), (sy_call_t *)sys_fdatasync, AUE_FSYNC, NULL, 0, 0, 0, SY_THR_STATIC }, /* 550 = fdatasync */
{ AS(fstat_args), (sy_call_t *)sys_fstat, AUE_FSTAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 551 = fstat */
{ AS(fstatat_args), (sy_call_t *)sys_fstatat, AUE_FSTATAT, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 552 = fstatat */
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_cpuset.c b/sys/kern/kern_cpuset.c
index b1612b11f770..3f4a81ff70d7 100644
--- a/sys/kern/kern_cpuset.c
+++ b/sys/kern/kern_cpuset.c
@@ -65,7 +65,12 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pageout.h>
#include <vm/vm_extern.h>
+#include <vm/vm_param.h>
+#include <vm/vm_phys.h>
+#include <vm/vm_pagequeue.h>
#ifdef DDB
#include <ddb/ddb.h>
@@ -479,6 +484,26 @@ _domainset_create(struct domainset *domain, struct domainlist *freelist)
}
/*
+ * Are any of the domains in the mask empty? If so, silently
+ * remove them. If only empty domains are present, we must
+ * return failure.
+ */
+static bool
+domainset_empty_vm(struct domainset *domain)
+{
+ int i, max;
+
+ max = DOMAINSET_FLS(&domain->ds_mask) + 1;
+ for (i = 0; i < max; i++) {
+ if (DOMAINSET_ISSET(i, &domain->ds_mask) &&
+ VM_DOMAIN_EMPTY(i))
+ DOMAINSET_CLR(i, &domain->ds_mask);
+ }
+
+ return (DOMAINSET_EMPTY(&domain->ds_mask));
+}
+
+/*
* Create or lookup a domainset based on the key held in 'domain'.
*/
struct domainset *
@@ -1360,6 +1385,7 @@ domainset_zero(void)
DOMAINSET_SET(i, &dset->ds_mask);
dset->ds_policy = DOMAINSET_POLICY_FIRSTTOUCH;
dset->ds_prefer = -1;
+ (void)domainset_empty_vm(dset);
curthread->td_domain.dr_policy = _domainset_create(dset, NULL);
domainset_copy(dset, &domainset2);
@@ -2087,6 +2113,13 @@ kern_cpuset_setdomain(struct thread *td, cpulevel_t level, cpuwhich_t which,
DOMAINSET_FILL(&domain.ds_mask);
}
+ /*
+ * When given an impossible policy, fall back to interleaving
+ * across all domains
+ */
+ if (domainset_empty_vm(&domain))
+ domainset_copy(&domainset2, &domain);
+
switch (level) {
case CPU_LEVEL_ROOT:
case CPU_LEVEL_CPUSET:
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 @@ restart:
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/kern_resource.c b/sys/kern/kern_resource.c
index bed34bf4a7fe..271339e5c4c4 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -1276,7 +1276,6 @@ uifind(uid_t uid)
racct_create(&new_uip->ui_racct);
refcount_init(&new_uip->ui_ref, 1);
new_uip->ui_uid = uid;
- mtx_init(&new_uip->ui_vmsize_mtx, "ui_vmsize", NULL, MTX_DEF);
rw_wlock(&uihashtbl_lock);
/*
@@ -1291,7 +1290,6 @@ uifind(uid_t uid)
} else {
rw_wunlock(&uihashtbl_lock);
racct_destroy(&new_uip->ui_racct);
- mtx_destroy(&new_uip->ui_vmsize_mtx);
free(new_uip, M_UIDINFO);
}
return (uip);
@@ -1352,7 +1350,6 @@ uifree(struct uidinfo *uip)
if (uip->ui_vmsize != 0)
printf("freeing uidinfo: uid = %d, swapuse = %lld\n",
uip->ui_uid, (unsigned long long)uip->ui_vmsize);
- mtx_destroy(&uip->ui_vmsize_mtx);
free(uip, M_UIDINFO);
}
diff --git a/sys/kern/link_elf.c b/sys/kern/link_elf.c
index 94fe5c407aeb..9338b06bb268 100644
--- a/sys/kern/link_elf.c
+++ b/sys/kern/link_elf.c
@@ -1653,7 +1653,7 @@ link_elf_strtab_get(linker_file_t lf, caddr_t *strtab)
return (ef->ddbstrcnt);
}
-#if defined(__i386__) || defined(__amd64__)
+#if defined(__i386__) || defined(__amd64__) || defined(__aarch64__)
/*
* Use this lookup routine when performing relocations early during boot.
* The generic lookup routine depends on kobj, which is not initialized
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/syscalls.c b/sys/kern/syscalls.c
index a107b5571b3c..8e74163fe6d8 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -190,10 +190,10 @@ const char *syscallnames[] = {
"setgid", /* 181 = setgid */
"setegid", /* 182 = setegid */
"seteuid", /* 183 = seteuid */
- "#184", /* 184 = lfs_bmapv */
- "#185", /* 185 = lfs_markv */
- "#186", /* 186 = lfs_segclean */
- "#187", /* 187 = lfs_segwait */
+ "obs_lfs_bmapv", /* 184 = obsolete lfs_bmapv */
+ "obs_lfs_markv", /* 185 = obsolete lfs_markv */
+ "obs_lfs_segclean", /* 186 = obsolete lfs_segclean */
+ "obs_lfs_segwait", /* 187 = obsolete lfs_segwait */
"compat11.stat", /* 188 = freebsd11 stat */
"compat11.fstat", /* 189 = freebsd11 fstat */
"compat11.lstat", /* 190 = freebsd11 lstat */
@@ -229,7 +229,7 @@ const char *syscallnames[] = {
"compat7.__semctl", /* 220 = freebsd7 __semctl */
"semget", /* 221 = semget */
"semop", /* 222 = semop */
- "#223", /* 223 = semconfig */
+ "obs_semconfig", /* 223 = obsolete semconfig */
"compat7.msgctl", /* 224 = freebsd7 msgctl */
"msgget", /* 225 = msgget */
"msgsnd", /* 226 = msgsnd */
@@ -370,26 +370,26 @@ const char *syscallnames[] = {
"getresgid", /* 361 = getresgid */
"kqueue", /* 362 = kqueue */
"compat11.kevent", /* 363 = freebsd11 kevent */
- "#364", /* 364 = __cap_get_proc */
- "#365", /* 365 = __cap_set_proc */
- "#366", /* 366 = __cap_get_fd */
- "#367", /* 367 = __cap_get_file */
- "#368", /* 368 = __cap_set_fd */
- "#369", /* 369 = __cap_set_file */
+ "obs___cap_get_proc", /* 364 = obsolete __cap_get_proc */
+ "obs___cap_set_proc", /* 365 = obsolete __cap_set_proc */
+ "obs___cap_get_fd", /* 366 = obsolete __cap_get_fd */
+ "obs___cap_get_file", /* 367 = obsolete __cap_get_file */
+ "obs___cap_set_fd", /* 368 = obsolete __cap_set_fd */
+ "obs___cap_set_file", /* 369 = obsolete __cap_set_file */
"#370", /* 370 = nosys */
"extattr_set_fd", /* 371 = extattr_set_fd */
"extattr_get_fd", /* 372 = extattr_get_fd */
"extattr_delete_fd", /* 373 = extattr_delete_fd */
"__setugid", /* 374 = __setugid */
- "#375", /* 375 = nfsclnt */
+ "obs_nfsclnt", /* 375 = obsolete nfsclnt */
"eaccess", /* 376 = eaccess */
"afs3_syscall", /* 377 = afs3_syscall */
"nmount", /* 378 = nmount */
- "#379", /* 379 = kse_exit */
- "#380", /* 380 = kse_wakeup */
- "#381", /* 381 = kse_create */
- "#382", /* 382 = kse_thr_interrupt */
- "#383", /* 383 = kse_release */
+ "obs_kse_exit", /* 379 = obsolete kse_exit */
+ "obs_kse_wakeup", /* 380 = obsolete kse_wakeup */
+ "obs_kse_create", /* 381 = obsolete kse_create */
+ "obs_kse_thr_interrupt", /* 382 = obsolete kse_thr_interrupt */
+ "obs_kse_release", /* 383 = obsolete kse_release */
"__mac_get_proc", /* 384 = __mac_get_proc */
"__mac_set_proc", /* 385 = __mac_set_proc */
"__mac_get_fd", /* 386 = __mac_get_fd */
@@ -446,7 +446,7 @@ const char *syscallnames[] = {
"extattr_list_fd", /* 437 = extattr_list_fd */
"extattr_list_file", /* 438 = extattr_list_file */
"extattr_list_link", /* 439 = extattr_list_link */
- "#440", /* 440 = kse_switchin */
+ "obs_kse_switchin", /* 440 = obsolete kse_switchin */
"ksem_timedwait", /* 441 = ksem_timedwait */
"thr_suspend", /* 442 = thr_suspend */
"thr_wake", /* 443 = thr_wake */
@@ -554,8 +554,8 @@ const char *syscallnames[] = {
"ppoll", /* 545 = ppoll */
"futimens", /* 546 = futimens */
"utimensat", /* 547 = utimensat */
- "#548", /* 548 = numa_getaffinity */
- "#549", /* 549 = numa_setaffinity */
+ "obs_numa_getaffinity", /* 548 = obsolete numa_getaffinity */
+ "obs_numa_setaffinity", /* 549 = obsolete numa_setaffinity */
"fdatasync", /* 550 = fdatasync */
"fstat", /* 551 = fstat */
"fstatat", /* 552 = fstatat */
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 9ea0f1b5353b..08b254655ee5 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -459,10 +459,10 @@
181 AUE_SETGID STD { int setgid(gid_t gid); }
182 AUE_SETEGID STD { int setegid(gid_t egid); }
183 AUE_SETEUID STD { int seteuid(uid_t euid); }
-184 AUE_NULL UNIMPL lfs_bmapv
-185 AUE_NULL UNIMPL lfs_markv
-186 AUE_NULL UNIMPL lfs_segclean
-187 AUE_NULL UNIMPL lfs_segwait
+184 AUE_NULL OBSOL lfs_bmapv
+185 AUE_NULL OBSOL lfs_markv
+186 AUE_NULL OBSOL lfs_segclean
+187 AUE_NULL OBSOL lfs_segwait
188 AUE_STAT COMPAT11 { int stat(_In_z_ char *path, \
_Out_ struct freebsd11_stat *ub); }
189 AUE_FSTAT COMPAT11 { int fstat(int fd, \
@@ -536,7 +536,7 @@
222 AUE_SEMOP NOSTD { int semop(int semid, \
_In_reads_(nsops) struct sembuf *sops, \
size_t nsops); }
-223 AUE_NULL UNIMPL semconfig
+223 AUE_NULL OBSOL semconfig
224 AUE_MSGCTL COMPAT7|NOSTD { int msgctl(int msqid, int cmd, \
struct msqid_ds_old *buf); }
225 AUE_MSGGET NOSTD { int msgget(key_t key, int msgflg); }
@@ -821,12 +821,12 @@
struct kevent_freebsd11 *eventlist, \
int nevents, \
_In_opt_ const struct timespec *timeout); }
-364 AUE_NULL UNIMPL __cap_get_proc
-365 AUE_NULL UNIMPL __cap_set_proc
-366 AUE_NULL UNIMPL __cap_get_fd
-367 AUE_NULL UNIMPL __cap_get_file
-368 AUE_NULL UNIMPL __cap_set_fd
-369 AUE_NULL UNIMPL __cap_set_file
+364 AUE_NULL OBSOL __cap_get_proc
+365 AUE_NULL OBSOL __cap_set_proc
+366 AUE_NULL OBSOL __cap_get_fd
+367 AUE_NULL OBSOL __cap_get_file
+368 AUE_NULL OBSOL __cap_set_fd
+369 AUE_NULL OBSOL __cap_set_file
370 AUE_NULL UNIMPL nosys
371 AUE_EXTATTR_SET_FD STD { ssize_t extattr_set_fd(int fd, \
int attrnamespace, \
@@ -842,7 +842,7 @@
int attrnamespace, \
_In_z_ const char *attrname); }
374 AUE_SETUGID STD { int __setugid(int flag); }
-375 AUE_NULL UNIMPL nfsclnt
+375 AUE_NULL OBSOL nfsclnt
376 AUE_EACCESS STD { int eaccess(_In_z_ char *path, int amode); }
377 AUE_NULL NOSTD|NOTSTATIC { int afs3_syscall(long syscall, \
long parm1, long parm2, long parm3, \
@@ -850,11 +850,11 @@
378 AUE_NMOUNT STD { int nmount( \
_In_reads_(iovcnt) struct iovec *iovp, \
unsigned int iovcnt, int flags); }
-379 AUE_NULL UNIMPL kse_exit
-380 AUE_NULL UNIMPL kse_wakeup
-381 AUE_NULL UNIMPL kse_create
-382 AUE_NULL UNIMPL kse_thr_interrupt
-383 AUE_NULL UNIMPL kse_release
+379 AUE_NULL OBSOL kse_exit
+380 AUE_NULL OBSOL kse_wakeup
+381 AUE_NULL OBSOL kse_create
+382 AUE_NULL OBSOL kse_thr_interrupt
+383 AUE_NULL OBSOL kse_release
384 AUE_NULL STD { int __mac_get_proc( \
_In_ struct mac *mac_p); }
385 AUE_NULL STD { int __mac_set_proc( \
@@ -994,7 +994,7 @@
int attrnamespace, \
_Out_writes_bytes_opt_(nbytes) \
void *data, size_t nbytes); }
-440 AUE_NULL UNIMPL kse_switchin
+440 AUE_NULL OBSOL kse_switchin
441 AUE_SEMWAIT NOSTD { int ksem_timedwait(semid_t id, \
_In_opt_ const struct timespec *abstime); }
442 AUE_NULL STD { int thr_suspend( \
@@ -1295,8 +1295,8 @@
_In_reads_(2) \
struct timespec *times, \
int flag); }
-548 AUE_NULL UNIMPL numa_getaffinity
-549 AUE_NULL UNIMPL numa_setaffinity
+548 AUE_NULL OBSOL numa_getaffinity
+549 AUE_NULL OBSOL numa_setaffinity
550 AUE_FSYNC STD { int fdatasync(int fd); }
551 AUE_FSTAT STD { int fstat(int fd, _Out_ struct stat *sb); }
552 AUE_FSTATAT STD { int fstatat(int fd, _In_z_ char *path, \
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 18a4c6c9e835..af2fd1ff65f7 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -917,12 +917,13 @@ solisten_dequeue(struct socket *head, struct socket **ret, int flags)
if (head->so_error) {
error = head->so_error;
head->so_error = 0;
+ } else if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->sol_comp))
+ error = EWOULDBLOCK;
+ else
+ error = 0;
+ if (error) {
SOLISTEN_UNLOCK(head);
return (error);
- }
- if ((head->so_state & SS_NBIO) && TAILQ_EMPTY(&head->sol_comp)) {
- SOLISTEN_UNLOCK(head);
- return (EWOULDBLOCK);
}
so = TAILQ_FIRST(&head->sol_comp);
SOCK_LOCK(so);
@@ -2585,11 +2586,20 @@ soshutdown(struct socket *so, int how)
* both backward-compatibility and POSIX requirements by forcing
* ENOTCONN but still asking protocol to perform pru_shutdown().
*/
- if (so->so_type != SOCK_DGRAM)
+ if (so->so_type != SOCK_DGRAM && !SOLISTENING(so))
return (ENOTCONN);
soerror_enotconn = 1;
}
+ if (SOLISTENING(so)) {
+ if (how != SHUT_WR) {
+ SOLISTEN_LOCK(so);
+ so->so_error = ECONNABORTED;
+ solisten_wakeup(so); /* unlocks so */
+ }
+ goto done;
+ }
+
CURVNET_SET(so->so_vnet);
if (pr->pr_usrreqs->pru_flush != NULL)
(*pr->pr_usrreqs->pru_flush)(so, how);
@@ -2604,6 +2614,7 @@ soshutdown(struct socket *so, int how)
wakeup(&so->so_timeo);
CURVNET_RESTORE();
+done:
return (soerror_enotconn ? ENOTCONN : 0);
}
@@ -3279,6 +3290,8 @@ sopoll_generic(struct socket *so, int events, struct ucred *active_cred,
revents = 0;
else if (!TAILQ_EMPTY(&so->sol_comp))
revents = events & (POLLIN | POLLRDNORM);
+ else if ((events & POLLINIGNEOF) == 0 && so->so_error)
+ revents = (events & (POLLIN | POLLRDNORM)) | POLLHUP;
else {
selrecord(td, &so->so_rdsel);
revents = 0;
@@ -3555,6 +3568,11 @@ filt_soread(struct knote *kn, long hint)
if (SOLISTENING(so)) {
SOCK_LOCK_ASSERT(so);
kn->kn_data = so->sol_qlen;
+ if (so->so_error) {
+ kn->kn_flags |= EV_EOF;
+ kn->kn_fflags = so->so_error;
+ return (1);
+ }
return (!TAILQ_EMPTY(&so->sol_comp));
}
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 @@ nextname:
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.c b/sys/net/if.c
index 3147eafb7c78..2acea128cdfd 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -264,7 +264,6 @@ static int if_setflag(struct ifnet *, int, int, int *, int);
static int if_transmit(struct ifnet *ifp, struct mbuf *m);
static void if_unroute(struct ifnet *, int flag, int fam);
static void link_rtrequest(int, struct rtentry *, struct rt_addrinfo *);
-static int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
static int if_delmulti_locked(struct ifnet *, struct ifmultiaddr *, int);
static void do_link_state_change(void *, int);
static int if_getgroup(struct ifgroupreq *, struct ifnet *);
@@ -2512,7 +2511,7 @@ ifr_data_get_ptr(void *ifrp)
/*
* Hardware specific interface ioctls.
*/
-static int
+int
ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td)
{
struct ifreq *ifr;
diff --git a/sys/net/if_gre.c b/sys/net/if_gre.c
index 591396c588dd..a2b923ee04e9 100644
--- a/sys/net/if_gre.c
+++ b/sys/net/if_gre.c
@@ -569,6 +569,8 @@ gre_transmit(struct ifnet *ifp, struct mbuf *m)
goto drop;
}
af = m->m_pkthdr.csum_data;
+ BPF_MTAP2(ifp, &af, sizeof(af), m);
+ m->m_flags &= ~(M_BCAST|M_MCAST);
M_SETFIB(m, sc->gre_fibnum);
M_PREPEND(m, sc->gre_hlen, M_NOWAIT);
if (m == NULL) {
diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c
index 2bce8c1e7aad..1efd5ea20c6e 100644
--- a/sys/net/if_tap.c
+++ b/sys/net/if_tap.c
@@ -723,10 +723,12 @@ tapifstart(struct ifnet *ifp)
static int
tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td)
{
+ struct ifreq ifr;
struct tap_softc *tp = dev->si_drv1;
struct ifnet *ifp = tp->tap_ifp;
struct tapinfo *tapp = NULL;
int f;
+ int error;
#if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD4)
int ival;
@@ -738,7 +740,18 @@ tapioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td
if (ifp->if_type != tapp->type)
return (EPROTOTYPE);
mtx_lock(&tp->tap_mtx);
- ifp->if_mtu = tapp->mtu;
+ if (ifp->if_mtu != tapp->mtu) {
+ strlcpy(ifr.ifr_name, if_name(ifp), IFNAMSIZ);
+ ifr.ifr_mtu = tapp->mtu;
+ CURVNET_SET(ifp->if_vnet);
+ error = ifhwioctl(SIOCSIFMTU, ifp,
+ (caddr_t)&ifr, td);
+ CURVNET_RESTORE();
+ if (error) {
+ mtx_unlock(&tp->tap_mtx);
+ return (error);
+ }
+ }
ifp->if_baudrate = tapp->baudrate;
mtx_unlock(&tp->tap_mtx);
break;
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c
index cf404012a2e8..d47117f17b8e 100644
--- a/sys/net/if_tun.c
+++ b/sys/net/if_tun.c
@@ -662,24 +662,29 @@ static int
tunioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
struct thread *td)
{
- int error;
+ struct ifreq ifr;
struct tun_softc *tp = dev->si_drv1;
struct tuninfo *tunp;
+ int error;
switch (cmd) {
case TUNSIFINFO:
tunp = (struct tuninfo *)data;
- if (tunp->mtu < IF_MINMTU)
- return (EINVAL);
- if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
- error = priv_check(td, PRIV_NET_SETIFMTU);
- if (error)
- return (error);
- }
if (TUN2IFP(tp)->if_type != tunp->type)
return (EPROTOTYPE);
mtx_lock(&tp->tun_mtx);
- TUN2IFP(tp)->if_mtu = tunp->mtu;
+ if (TUN2IFP(tp)->if_mtu != tunp->mtu) {
+ strlcpy(ifr.ifr_name, if_name(TUN2IFP(tp)), IFNAMSIZ);
+ ifr.ifr_mtu = tunp->mtu;
+ CURVNET_SET(TUN2IFP(tp)->if_vnet);
+ error = ifhwioctl(SIOCSIFMTU, TUN2IFP(tp),
+ (caddr_t)&ifr, td);
+ CURVNET_RESTORE();
+ if (error) {
+ mtx_unlock(&tp->tun_mtx);
+ return (error);
+ }
+ }
TUN2IFP(tp)->if_baudrate = tunp->baudrate;
mtx_unlock(&tp->tun_mtx);
break;
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 480df7433a6d..c9452406a151 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)
/*
@@ -759,6 +760,8 @@ int if_hw_tsomax_update(if_t ifp, struct ifnet_hw_tsomax *);
/* accessors for struct ifreq */
void *ifr_data_get_ptr(void *ifrp);
+int ifhwioctl(u_long, struct ifnet *, caddr_t, struct thread *);
+
#ifdef DEVICE_POLLING
enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS };
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/in_pcb.h b/sys/netinet/in_pcb.h
index 86c9705cb905..6d2c86d5014e 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -642,6 +642,8 @@ int inp_so_options(const struct inpcb *inp);
#define INP_INFO_LOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(ipi)->ipi_lock))
#define INP_INFO_RLOCK_ASSERT(ipi) MPASS(in_epoch(net_epoch_preempt))
#define INP_INFO_WLOCK_ASSERT(ipi) mtx_assert(&(ipi)->ipi_lock, MA_OWNED)
+#define INP_INFO_WUNLOCK_ASSERT(ipi) \
+ mtx_assert(&(ipi)->ipi_lock, MA_NOTOWNED)
#define INP_INFO_UNLOCK_ASSERT(ipi) MPASS(!in_epoch(net_epoch_preempt) && !mtx_owned(&(ipi)->ipi_lock))
#define INP_LIST_LOCK_INIT(ipi, d) \
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/ip_output.c b/sys/netinet/ip_output.c
index 9d7b9cbe8661..a08806a686bd 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -932,10 +932,11 @@ in_delayed_cksum(struct mbuf *m)
if (m->m_pkthdr.csum_flags & CSUM_UDP) {
/* if udp header is not in the first mbuf copy udplen */
- if (offset + sizeof(struct udphdr) > m->m_len)
+ if (offset + sizeof(struct udphdr) > m->m_len) {
m_copydata(m, offset + offsetof(struct udphdr,
uh_ulen), sizeof(cklen), (caddr_t)&cklen);
- else {
+ cklen = ntohs(cklen);
+ } else {
uh = (struct udphdr *)mtodo(m, offset);
cklen = ntohs(uh->uh_ulen);
}
diff --git a/sys/netinet/sctp_asconf.c b/sys/netinet/sctp_asconf.c
index 26b1ba6f508b..611280f1ae42 100644
--- a/sys/netinet/sctp_asconf.c
+++ b/sys/netinet/sctp_asconf.c
@@ -670,6 +670,7 @@ sctp_handle_asconf(struct mbuf *m, unsigned int offset,
SCTPDBG(SCTP_DEBUG_ASCONF1,
"handle_asconf: couldn't get lookup addr!\n");
/* respond with a missing/invalid mandatory parameter error */
+ sctp_m_freem(m_ack);
return;
}
/* param_length is already validated in process_control... */
diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c
index 3150306356dc..d379dd0a143e 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).
@@ -1740,7 +1706,7 @@ sctp_handle_auth(struct sctp_tcb *stcb, struct sctp_auth_chunk *auth,
m, offset, computed_digest);
/* compare the computed digest with the one in the AUTH chunk */
- if (memcmp(digest, computed_digest, digestlen) != 0) {
+ if (timingsafe_bcmp(digest, computed_digest, digestlen) != 0) {
SCTP_STAT_INCR(sctps_recvauthfailed);
SCTPDBG(SCTP_DEBUG_AUTH1,
"SCTP Auth: HMAC digest check failed\n");
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..86656a7f7eb2 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -2554,7 +2554,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
return (NULL);
}
/* compare the received digest with the computed digest */
- if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) != 0) {
+ if (timingsafe_bcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) != 0) {
/* try the old cookie? */
if ((cookie->time_entered.tv_sec == (long)ep->time_of_secret_change) &&
(ep->current_secret_number != ep->last_secret_number)) {
@@ -2563,7 +2563,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
(uint8_t *)ep->secret_key[(int)ep->last_secret_number],
SCTP_SECRET_SIZE, m, cookie_offset, calc_sig, 0);
/* compare */
- if (memcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) == 0)
+ if (timingsafe_bcmp(calc_sig, sig, SCTP_SIGNATURE_SIZE) == 0)
cookie_ok = 1;
}
} else {
@@ -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..34e91d8b0af6 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3572,7 +3572,6 @@ static int
sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *error)
{
struct cmsghdr cmh;
- int tlen, at;
struct sctp_initmsg initmsg;
#ifdef INET
struct sockaddr_in sin;
@@ -3580,34 +3579,37 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
#ifdef INET6
struct sockaddr_in6 sin6;
#endif
+ int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off;
- tlen = SCTP_BUF_LEN(control);
- at = 0;
- while (at < tlen) {
- if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) {
+ tot_len = SCTP_BUF_LEN(control);
+ for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) {
+ rem_len = tot_len - off;
+ if (rem_len < (int)CMSG_ALIGN(sizeof(cmh))) {
/* There is not enough room for one more. */
*error = EINVAL;
return (1);
}
- m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh);
+ m_copydata(control, off, sizeof(cmh), (caddr_t)&cmh);
if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) {
/* We dont't have a complete CMSG header. */
*error = EINVAL;
return (1);
}
- if (((int)cmh.cmsg_len + at) > tlen) {
+ if ((cmh.cmsg_len > INT_MAX) || ((int)cmh.cmsg_len > rem_len)) {
/* We don't have the complete CMSG. */
*error = EINVAL;
return (1);
}
+ cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh));
+ cmsg_data_off = off + CMSG_ALIGN(sizeof(cmh));
if (cmh.cmsg_level == IPPROTO_SCTP) {
switch (cmh.cmsg_type) {
case SCTP_INIT:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct sctp_initmsg)) {
+ if (cmsg_data_len < (int)sizeof(struct sctp_initmsg)) {
*error = EINVAL;
return (1);
}
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct sctp_initmsg), (caddr_t)&initmsg);
+ m_copydata(control, cmsg_data_off, sizeof(struct sctp_initmsg), (caddr_t)&initmsg);
if (initmsg.sinit_max_attempts)
stcb->asoc.max_init_times = initmsg.sinit_max_attempts;
if (initmsg.sinit_num_ostreams)
@@ -3662,7 +3664,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
break;
#ifdef INET
case SCTP_DSTADDRV4:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in_addr)) {
+ if (cmsg_data_len < (int)sizeof(struct in_addr)) {
*error = EINVAL;
return (1);
}
@@ -3670,7 +3672,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_port = stcb->rport;
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
+ m_copydata(control, cmsg_data_off, sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
if ((sin.sin_addr.s_addr == INADDR_ANY) ||
(sin.sin_addr.s_addr == INADDR_BROADCAST) ||
IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
@@ -3686,7 +3688,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
#endif
#ifdef INET6
case SCTP_DSTADDRV6:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in6_addr)) {
+ if (cmsg_data_len < (int)sizeof(struct in6_addr)) {
*error = EINVAL;
return (1);
}
@@ -3694,7 +3696,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_port = stcb->rport;
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in6_addr), (caddr_t)&sin6.sin6_addr);
+ m_copydata(control, cmsg_data_off, sizeof(struct in6_addr), (caddr_t)&sin6.sin6_addr);
if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr) ||
IN6_IS_ADDR_MULTICAST(&sin6.sin6_addr)) {
*error = EINVAL;
@@ -3727,7 +3729,6 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
break;
}
}
- at += CMSG_ALIGN(cmh.cmsg_len);
}
return (0);
}
@@ -3740,7 +3741,6 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
int *error)
{
struct cmsghdr cmh;
- int tlen, at;
struct sctp_tcb *stcb;
struct sockaddr *addr;
#ifdef INET
@@ -3749,31 +3749,34 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
#ifdef INET6
struct sockaddr_in6 sin6;
#endif
+ int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off;
- tlen = SCTP_BUF_LEN(control);
- at = 0;
- while (at < tlen) {
- if ((tlen - at) < (int)CMSG_ALIGN(sizeof(cmh))) {
+ tot_len = SCTP_BUF_LEN(control);
+ for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) {
+ rem_len = tot_len - off;
+ if (rem_len < (int)CMSG_ALIGN(sizeof(cmh))) {
/* There is not enough room for one more. */
*error = EINVAL;
return (NULL);
}
- m_copydata(control, at, sizeof(cmh), (caddr_t)&cmh);
+ m_copydata(control, off, sizeof(cmh), (caddr_t)&cmh);
if (cmh.cmsg_len < CMSG_ALIGN(sizeof(cmh))) {
/* We dont't have a complete CMSG header. */
*error = EINVAL;
return (NULL);
}
- if (((int)cmh.cmsg_len + at) > tlen) {
+ if ((cmh.cmsg_len > INT_MAX) || ((int)cmh.cmsg_len > rem_len)) {
/* We don't have the complete CMSG. */
*error = EINVAL;
return (NULL);
}
+ cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh));
+ cmsg_data_off = off + CMSG_ALIGN(sizeof(cmh));
if (cmh.cmsg_level == IPPROTO_SCTP) {
switch (cmh.cmsg_type) {
#ifdef INET
case SCTP_DSTADDRV4:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in_addr)) {
+ if (cmsg_data_len < (int)sizeof(struct in_addr)) {
*error = EINVAL;
return (NULL);
}
@@ -3781,13 +3784,13 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
sin.sin_family = AF_INET;
sin.sin_len = sizeof(struct sockaddr_in);
sin.sin_port = port;
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
+ m_copydata(control, cmsg_data_off, sizeof(struct in_addr), (caddr_t)&sin.sin_addr);
addr = (struct sockaddr *)&sin;
break;
#endif
#ifdef INET6
case SCTP_DSTADDRV6:
- if ((size_t)(cmh.cmsg_len - CMSG_ALIGN(sizeof(cmh))) < sizeof(struct in6_addr)) {
+ if (cmsg_data_len < (int)sizeof(struct in6_addr)) {
*error = EINVAL;
return (NULL);
}
@@ -3795,7 +3798,7 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
sin6.sin6_family = AF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
sin6.sin6_port = port;
- m_copydata(control, at + CMSG_ALIGN(sizeof(cmh)), sizeof(struct in6_addr), (caddr_t)&sin6.sin6_addr);
+ m_copydata(control, cmsg_data_off, sizeof(struct in6_addr), (caddr_t)&sin6.sin6_addr);
#ifdef INET
if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
in6_sin6_2_sin(&sin, &sin6);
@@ -3816,7 +3819,6 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p,
}
}
}
- at += CMSG_ALIGN(cmh.cmsg_len);
}
return (NULL);
}
@@ -4263,6 +4265,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
atomic_subtract_int(&stcb->asoc.refcnt, 1);
}
#endif
+ if (port) {
+ UDPSTAT_INC(udps_opackets);
+ }
SCTP_STAT_INCR(sctps_sendpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
if (ret)
@@ -4362,6 +4367,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* KAME hack: embed scopeid */
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ sctp_m_freem(m);
return (EINVAL);
}
if (net == NULL) {
@@ -4426,6 +4432,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* KAME hack: embed scopeid */
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ sctp_m_freem(m);
return (EINVAL);
}
/* Cache the source address */
@@ -4452,6 +4459,7 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
/* KAME hack: embed scopeid */
if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, SCTP_FROM_SCTP_OUTPUT, EINVAL);
+ sctp_m_freem(m);
return (EINVAL);
}
if (over_addr == NULL) {
@@ -4603,6 +4611,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
sin6->sin6_port = prev_port;
}
SCTPDBG(SCTP_DEBUG_OUTPUT3, "return from send is %d\n", ret);
+ if (port) {
+ UDPSTAT_INC(udps_opackets);
+ }
SCTP_STAT_INCR(sctps_sendpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
if (ret) {
@@ -7210,7 +7221,7 @@ one_more_time:
if ((sp->msg_is_complete) && (sp->length == 0)) {
if (sp->sender_all_done) {
/*
- * We are doing differed cleanup. Last time through
+ * We are doing deferred cleanup. Last time through
* when we took all the data the sender_all_done was
* not set.
*/
@@ -8964,14 +8975,15 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
return;
}
chk->copy_by_ref = 0;
+ chk->rec.chunk_id.id = SCTP_OPERATION_ERROR;
+ chk->rec.chunk_id.can_take_data = 0;
+ chk->flags = 0;
chk->send_size = (uint16_t)chunk_length;
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
chk->asoc = &stcb->asoc;
chk->data = op_err;
chk->whoTo = NULL;
- chk->rec.chunk_id.id = SCTP_OPERATION_ERROR;
- chk->rec.chunk_id.can_take_data = 0;
hdr = mtod(op_err, struct sctp_chunkhdr *);
hdr->chunk_type = SCTP_OPERATION_ERROR;
hdr->chunk_flags = 0;
@@ -9193,7 +9205,6 @@ sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
chk->send_size = sizeof(struct sctp_chunkhdr);
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->data = m_shutdown_ack;
chk->whoTo = net;
@@ -9248,7 +9259,6 @@ sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
chk->send_size = sizeof(struct sctp_shutdown_chunk);
chk->sent = SCTP_DATAGRAM_UNSENT;
chk->snd_count = 0;
- chk->flags = 0;
chk->asoc = &stcb->asoc;
chk->data = m_shutdown;
chk->whoTo = net;
@@ -11290,6 +11300,9 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst,
return;
}
SCTPDBG(SCTP_DEBUG_OUTPUT3, "return from send is %d\n", ret);
+ if (port) {
+ UDPSTAT_INC(udps_opackets);
+ }
SCTP_STAT_INCR(sctps_sendpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks);
@@ -12154,7 +12167,6 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
chk->book_size = sizeof(struct sctp_chunkhdr);
chk->send_size = SCTP_SIZE32(chk->book_size);
chk->book_size_scale = 0;
-
chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
if (chk->data == NULL) {
sctp_free_a_chunk(stcb, chk, SCTP_SO_LOCKED);
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/siftr.c b/sys/netinet/siftr.c
index 83af89570d5e..bc59e312bb00 100644
--- a/sys/netinet/siftr.c
+++ b/sys/netinet/siftr.c
@@ -710,7 +710,7 @@ siftr_findinpcb(int ipver, struct ip *ip, struct mbuf *m, uint16_t sport,
struct inpcb *inp;
/* We need the tcbinfo lock. */
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
if (dir == PFIL_IN)
inp = (ipver == INP_IPV4 ?
diff --git a/sys/netinet/tcp_hpts.c b/sys/netinet/tcp_hpts.c
index 32047180f883..f3737888f3d0 100644
--- a/sys/netinet/tcp_hpts.c
+++ b/sys/netinet/tcp_hpts.c
@@ -1282,7 +1282,7 @@ out:
* lock again but we also need some kasserts
* here.
*/
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
INP_UNLOCK_ASSERT(inp);
m = n;
if (m)
@@ -1324,7 +1324,7 @@ out:
INP_WUNLOCK(inp);
if (ti_locked == TI_RLOCKED)
INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
INP_UNLOCK_ASSERT(inp);
ti_locked = TI_UNLOCKED;
mtx_lock(&hpts->p_mtx);
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index b61161c3eed8..bbb031439fc8 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -800,7 +800,7 @@ findpcb:
if (ti_locked == TI_RLOCKED) {
INP_INFO_RLOCK_ASSERT(&V_tcbinfo);
} else {
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
}
#endif
#ifdef INET6
@@ -1358,7 +1358,7 @@ tfo_socket_result:
INP_INFO_RUNLOCK_ET(&V_tcbinfo, et);
ti_locked = TI_UNLOCKED;
}
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
return (IPPROTO_DONE);
} else if (tp->t_state == TCPS_LISTEN) {
/*
@@ -1405,7 +1405,7 @@ dropwithreset:
else {
KASSERT(ti_locked == TI_UNLOCKED, ("%s: dropwithreset "
"ti_locked: %d", __func__, ti_locked));
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
}
#endif
@@ -1429,7 +1429,7 @@ dropunlock:
else {
KASSERT(ti_locked == TI_UNLOCKED, ("%s: dropunlock "
"ti_locked: %d", __func__, ti_locked));
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
}
#endif
@@ -1437,7 +1437,7 @@ dropunlock:
INP_WUNLOCK(inp);
drop:
- INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ INP_INFO_WUNLOCK_ASSERT(&V_tcbinfo);
if (s != NULL)
free(s, M_TCPLOG);
if (m != NULL)
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 @@ skip_alloc:
/*
* 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 @@ tfo_expanded:
* 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/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index cae044c066c3..429f195ee954 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -756,13 +756,7 @@ struct inpcb *
udp_notify(struct inpcb *inp, int errno)
{
- /*
- * While udp_ctlinput() always calls udp_notify() with a read lock
- * when invoking it directly, in_pcbnotifyall() currently uses write
- * locks due to sharing code with TCP. For now, accept either a read
- * or a write lock, but a read lock is sufficient.
- */
- INP_LOCK_ASSERT(inp);
+ INP_WLOCK_ASSERT(inp);
if ((errno == EHOSTUNREACH || errno == ENETUNREACH ||
errno == EHOSTDOWN) && inp->inp_route.ro_rt) {
RTFREE(inp->inp_route.ro_rt);
@@ -808,13 +802,13 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void *vip,
if (ip != NULL) {
uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
- ip->ip_src, uh->uh_sport, INPLOOKUP_RLOCKPCB, NULL);
+ ip->ip_src, uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL);
if (inp != NULL) {
- INP_RLOCK_ASSERT(inp);
+ INP_WLOCK_ASSERT(inp);
if (inp->inp_socket != NULL) {
udp_notify(inp, inetctlerrmap[cmd]);
}
- INP_RUNLOCK(inp);
+ INP_WUNLOCK(inp);
} else {
inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
ip->ip_src, uh->uh_sport,
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..93aebbd3440b 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;
@@ -766,13 +784,28 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m,
return ((*pru->pru_send)(so, flags_arg, m,
(struct sockaddr *)sin6, control, td));
}
- }
+ } else
#endif
+ if (sin6 && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+ /*
+ * Given this is either an IPv6-only socket or no INET is
+ * supported we will fail the send if the given destination
+ * address is a v4mapped address.
+ */
+ if (unlock_inp == UH_WLOCKED)
+ INP_WUNLOCK(inp);
+ else
+ INP_RUNLOCK(inp);
+ return (EINVAL);
+ }
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 +819,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 +999,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 +1015,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/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
index 08eea294b4e2..13c3c6463c0c 100644
--- a/sys/netpfil/pf/pf.c
+++ b/sys/netpfil/pf/pf.c
@@ -1719,24 +1719,28 @@ pf_purge_expired_states(u_int i, int maxcheck)
while (maxcheck > 0) {
ih = &V_pf_idhash[i];
+
+ /* only take the lock if we expect to do work */
+ if (!LIST_EMPTY(&ih->states)) {
relock:
- PF_HASHROW_LOCK(ih);
- LIST_FOREACH(s, &ih->states, entry) {
- if (pf_state_expires(s) <= time_uptime) {
- V_pf_status.states -=
- pf_unlink_state(s, PF_ENTER_LOCKED);
- goto relock;
+ PF_HASHROW_LOCK(ih);
+ LIST_FOREACH(s, &ih->states, entry) {
+ if (pf_state_expires(s) <= time_uptime) {
+ V_pf_status.states -=
+ pf_unlink_state(s, PF_ENTER_LOCKED);
+ goto relock;
+ }
+ s->rule.ptr->rule_flag |= PFRULE_REFS;
+ if (s->nat_rule.ptr != NULL)
+ s->nat_rule.ptr->rule_flag |= PFRULE_REFS;
+ if (s->anchor.ptr != NULL)
+ s->anchor.ptr->rule_flag |= PFRULE_REFS;
+ s->kif->pfik_flags |= PFI_IFLAG_REFS;
+ if (s->rt_kif)
+ s->rt_kif->pfik_flags |= PFI_IFLAG_REFS;
}
- s->rule.ptr->rule_flag |= PFRULE_REFS;
- if (s->nat_rule.ptr != NULL)
- s->nat_rule.ptr->rule_flag |= PFRULE_REFS;
- if (s->anchor.ptr != NULL)
- s->anchor.ptr->rule_flag |= PFRULE_REFS;
- s->kif->pfik_flags |= PFI_IFLAG_REFS;
- if (s->rt_kif)
- s->rt_kif->pfik_flags |= PFI_IFLAG_REFS;
+ PF_HASHROW_UNLOCK(ih);
}
- PF_HASHROW_UNLOCK(ih);
/* Return when we hit end of hash. */
if (++i > pf_hashmask) {
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/conf/GENERIC64 b/sys/powerpc/conf/GENERIC64
index ec8dc06f0980..5913100d037a 100644
--- a/sys/powerpc/conf/GENERIC64
+++ b/sys/powerpc/conf/GENERIC64
@@ -120,6 +120,7 @@ device siis # SiliconImage SiI3124/SiI3132/SiI3531 SATA
# NVM Express (NVMe) support
device nvme # base NVMe driver
+options NVME_USE_NVD=0 # prefer the cam(4) based nda(4) driver
device nvd # expose NVMe namespaces as disks, depends on nvme
# SCSI Controllers
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
@@ -154,6 +154,59 @@ 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)
*/
ENTRY(cpu_throw)
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/security/audit/audit.c b/sys/security/audit/audit.c
index 87ceeb670e76..c00ddc126f5a 100644
--- a/sys/security/audit/audit.c
+++ b/sys/security/audit/audit.c
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1999-2005 Apple Inc.
- * Copyright (c) 2006-2007, 2016-2017 Robert N. M. Watson
+ * Copyright (c) 2006-2007, 2016-2018 Robert N. M. Watson
* All rights reserved.
*
* Portions of this software were developed by BAE Systems, the University of
@@ -98,8 +98,12 @@ static SYSCTL_NODE(_security, OID_AUTO, audit, CTLFLAG_RW, 0,
*
* Define the audit control flags.
*/
-int __read_frequently audit_enabled;
-int audit_suspended;
+int audit_trail_enabled;
+int audit_trail_suspended;
+#ifdef KDTRACE_HOOKS
+u_int audit_dtrace_enabled;
+#endif
+int __read_frequently audit_syscalls_enabled;
/*
* Flags controlling behavior in low storage situations. Should we panic if
@@ -198,6 +202,33 @@ static struct rwlock audit_kinfo_lock;
#define KINFO_RUNLOCK() rw_runlock(&audit_kinfo_lock)
#define KINFO_WUNLOCK() rw_wunlock(&audit_kinfo_lock)
+/*
+ * Check various policies to see if we should enable system-call audit hooks.
+ * Note that despite the mutex being held, we want to assign a value exactly
+ * once, as checks of the flag are performed lock-free for performance
+ * reasons. The mutex is used to get a consistent snapshot of policy state --
+ * e.g., safely accessing the two audit_trail flags.
+ */
+void
+audit_syscalls_enabled_update(void)
+{
+
+ mtx_lock(&audit_mtx);
+#ifdef KDTRACE_HOOKS
+ if (audit_dtrace_enabled)
+ audit_syscalls_enabled = 1;
+ else {
+#endif
+ if (audit_trail_enabled && !audit_trail_suspended)
+ audit_syscalls_enabled = 1;
+ else
+ audit_syscalls_enabled = 0;
+#ifdef KDTRACE_HOOKS
+ }
+#endif
+ mtx_unlock(&audit_mtx);
+}
+
void
audit_set_kinfo(struct auditinfo_addr *ak)
{
@@ -303,8 +334,9 @@ static void
audit_init(void)
{
- audit_enabled = 0;
- audit_suspended = 0;
+ audit_trail_enabled = 0;
+ audit_trail_suspended = 0;
+ audit_syscalls_enabled = 0;
audit_panic_on_write_fail = 0;
audit_fail_stop = 0;
audit_in_failure = 0;
@@ -337,6 +369,9 @@ audit_init(void)
sizeof(struct kaudit_record), audit_record_ctor,
audit_record_dtor, NULL, NULL, UMA_ALIGN_PTR, 0);
+ /* First initialisation of audit_syscalls_enabled. */
+ audit_syscalls_enabled_update();
+
/* Initialize the BSM audit subsystem. */
kau_init();
@@ -378,10 +413,6 @@ currecord(void)
}
/*
- * XXXAUDIT: There are a number of races present in the code below due to
- * release and re-grab of the mutex. The code should be revised to become
- * slightly less racy.
- *
* XXXAUDIT: Shouldn't there be logic here to sleep waiting on available
* pre_q space, suspending the system call until there is room?
*/
@@ -389,13 +420,6 @@ struct kaudit_record *
audit_new(int event, struct thread *td)
{
struct kaudit_record *ar;
- int no_record;
-
- mtx_lock(&audit_mtx);
- no_record = (audit_suspended || !audit_enabled);
- mtx_unlock(&audit_mtx);
- if (no_record)
- return (NULL);
/*
* Note: the number of outstanding uncommitted audit records is
@@ -529,9 +553,13 @@ audit_commit(struct kaudit_record *ar, int error, int retval)
/*
* Note: it could be that some records initiated while audit was
* enabled should still be committed?
+ *
+ * NB: The check here is not for audit_syscalls because any
+ * DTrace-related obligations have been fulfilled above -- we're just
+ * down to the trail and pipes now.
*/
mtx_lock(&audit_mtx);
- if (audit_suspended || !audit_enabled) {
+ if (audit_trail_suspended || !audit_trail_enabled) {
audit_pre_q_len--;
mtx_unlock(&audit_mtx);
audit_free(ar);
@@ -557,6 +585,10 @@ audit_commit(struct kaudit_record *ar, int error, int retval)
* responsible for deciding whether or not to audit the call (preselection),
* and if so, allocating a per-thread audit record. audit_new() will fill in
* basic thread/credential properties.
+ *
+ * This function will be entered only if audit_syscalls_enabled was set in the
+ * macro wrapper for this function. It could be cleared by the time this
+ * function runs, but that is an acceptable race.
*/
void
audit_syscall_enter(unsigned short code, struct thread *td)
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index 055194d3a88d..f24bc1e503b2 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1999-2005 Apple Inc.
- * Copyright (c) 2016-2017 Robert N. M. Watson
+ * Copyright (c) 2016-2018 Robert N. M. Watson
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -55,14 +55,23 @@
#include <sys/sysctl.h>
/*
- * Audit subsystem condition flags. The audit_enabled flag is set and
+ * Audit subsystem condition flags. The audit_trail_enabled flag is set and
* removed automatically as a result of configuring log files, and can be
* observed but should not be directly manipulated. The audit suspension
* flag permits audit to be temporarily disabled without reconfiguring the
* audit target.
+ *
+ * As DTrace can also request system-call auditing, a further
+ * audit_syscalls_enabled flag tracks whether newly entering system calls
+ * should be considered for auditing or not.
+ *
+ * XXXRW: Move trail flags to audit_private.h, as they no longer need to be
+ * visible outside the audit code...?
*/
-extern int audit_enabled;
-extern int audit_suspended;
+extern u_int audit_dtrace_enabled;
+extern int audit_trail_enabled;
+extern int audit_trail_suspended;
+extern int audit_syscalls_enabled;
void audit_syscall_enter(unsigned short code, struct thread *td);
void audit_syscall_exit(int error, struct thread *td);
@@ -139,7 +148,7 @@ void audit_thread_free(struct thread *td);
/*
* Define macros to wrap the audit_arg_* calls by checking the global
- * audit_enabled flag before performing the actual call.
+ * audit_syscalls_enabled flag before performing the actual call.
*/
#define AUDITING_TD(td) ((td)->td_pflags & TDP_AUDITREC)
@@ -369,7 +378,7 @@ void audit_thread_free(struct thread *td);
} while (0)
#define AUDIT_SYSCALL_ENTER(code, td) do { \
- if (audit_enabled) { \
+ if (audit_syscalls_enabled) { \
audit_syscall_enter(code, td); \
} \
} while (0)
@@ -377,7 +386,7 @@ void audit_thread_free(struct thread *td);
/*
* Wrap the audit_syscall_exit() function so that it is called only when
* we have a audit record on the thread. Audit records can persist after
- * auditing is disabled, so we don't just check audit_enabled here.
+ * auditing is disabled, so we don't just check audit_syscalls_enabled here.
*/
#define AUDIT_SYSCALL_EXIT(error, td) do { \
if (td->td_pflags & TDP_AUDITREC) \
diff --git a/sys/security/audit/audit_dtrace.c b/sys/security/audit/audit_dtrace.c
index c456ab71400a..985baf142ab3 100644
--- a/sys/security/audit/audit_dtrace.c
+++ b/sys/security/audit/audit_dtrace.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2016 Robert N. M. Watson
+ * Copyright (c) 2016, 2018 Robert N. M. Watson
* All rights reserved.
*
* This software was developed by BAE Systems, the University of Cambridge
@@ -147,8 +147,12 @@ static dtrace_provider_id_t dtaudit_id;
* maintain a global flag tracking whether any dtaudit probes are enabled. If
* not, don't bother doing all that work whenever potential queries about
* events turn up during preselection or commit.
+ *
+ * NB: We used to maintain our own variable in dtaudit, but now use the
+ * centralized audit_dtrace_enabled variable imported from the audit code.
+ *
+ * static uint_t dtaudit_probes_enabled;
*/
-static uint_t dtaudit_probes_enabled;
/*
* Check dtaudit policy for the event to see whether this is an event we would
@@ -179,7 +183,7 @@ dtaudit_preselect(au_id_t auid, au_event_t event, au_class_t class)
* NB: Lockless reads here may return a slightly stale value; this is
* considered better than acquiring a lock, however.
*/
- if (!dtaudit_probes_enabled)
+ if (!audit_dtrace_enabled)
return (NULL);
ene = au_evnamemap_lookup(event);
if (ene == NULL)
@@ -457,7 +461,8 @@ dtaudit_enable(void *arg, dtrace_id_t id, void *parg)
ene->ene_commit_probe_enabled = 1;
else
ene->ene_bsm_probe_enabled = 1;
- refcount_acquire(&dtaudit_probes_enabled);
+ refcount_acquire(&audit_dtrace_enabled);
+ audit_syscalls_enabled_update();
}
static void
@@ -474,7 +479,8 @@ dtaudit_disable(void *arg, dtrace_id_t id, void *parg)
ene->ene_commit_probe_enabled = 0;
else
ene->ene_bsm_probe_enabled = 0;
- (void)refcount_release(&dtaudit_probes_enabled);
+ (void)refcount_release(&audit_dtrace_enabled);
+ audit_syscalls_enabled_update();
}
static void
diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h
index 5e7a3934835e..4aa811bc1516 100644
--- a/sys/security/audit/audit_private.h
+++ b/sys/security/audit/audit_private.h
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1999-2009 Apple Inc.
- * Copyright (c) 2016-2017 Robert N. M. Watson
+ * Copyright (c) 2016, 2018 Robert N. M. Watson
* All rights reserved.
*
* Portions of this software were developed by BAE Systems, the University of
@@ -344,6 +344,13 @@ void audit_commit(struct kaudit_record *ar, int error,
struct kaudit_record *audit_new(int event, struct thread *td);
/*
+ * Function to update the audit_syscalls_enabled flag, whose value is affected
+ * by configuration of the audit trail/pipe mechanism and DTrace. Call this
+ * function when any of the inputs to that policy change.
+ */
+void audit_syscalls_enabled_update(void);
+
+/*
* Functions relating to the conversion of internal kernel audit records to
* the BSM file format.
*/
diff --git a/sys/security/audit/audit_syscalls.c b/sys/security/audit/audit_syscalls.c
index 89af1a7d2817..a092e27b0a74 100644
--- a/sys/security/audit/audit_syscalls.c
+++ b/sys/security/audit/audit_syscalls.c
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1999-2009 Apple Inc.
- * Copyright (c) 2016 Robert N. M. Watson
+ * Copyright (c) 2016, 2018 Robert N. M. Watson
* All rights reserved.
*
* Portions of this software were developed by BAE Systems, the University of
@@ -368,7 +368,7 @@ sys_auditon(struct thread *td, struct auditon_args *uap)
case A_OLDGETCOND:
case A_GETCOND:
if (uap->length == sizeof(udata.au_cond64)) {
- if (audit_enabled && !audit_suspended)
+ if (audit_trail_enabled && !audit_trail_suspended)
udata.au_cond64 = AUC_AUDITING;
else
udata.au_cond64 = AUC_NOAUDIT;
@@ -376,7 +376,7 @@ sys_auditon(struct thread *td, struct auditon_args *uap)
}
if (uap->length != sizeof(udata.au_cond))
return (EINVAL);
- if (audit_enabled && !audit_suspended)
+ if (audit_trail_enabled && !audit_trail_suspended)
udata.au_cond = AUC_AUDITING;
else
udata.au_cond = AUC_NOAUDIT;
@@ -386,25 +386,27 @@ sys_auditon(struct thread *td, struct auditon_args *uap)
case A_SETCOND:
if (uap->length == sizeof(udata.au_cond64)) {
if (udata.au_cond64 == AUC_NOAUDIT)
- audit_suspended = 1;
+ audit_trail_suspended = 1;
if (udata.au_cond64 == AUC_AUDITING)
- audit_suspended = 0;
+ audit_trail_suspended = 0;
if (udata.au_cond64 == AUC_DISABLED) {
- audit_suspended = 1;
+ audit_trail_suspended = 1;
audit_shutdown(NULL, 0);
}
+ audit_syscalls_enabled_update();
break;
}
if (uap->length != sizeof(udata.au_cond))
return (EINVAL);
if (udata.au_cond == AUC_NOAUDIT)
- audit_suspended = 1;
+ audit_trail_suspended = 1;
if (udata.au_cond == AUC_AUDITING)
- audit_suspended = 0;
+ audit_trail_suspended = 0;
if (udata.au_cond == AUC_DISABLED) {
- audit_suspended = 1;
+ audit_trail_suspended = 1;
audit_shutdown(NULL, 0);
}
+ audit_syscalls_enabled_update();
break;
case A_GETCLASS:
@@ -826,10 +828,11 @@ sys_auditctl(struct thread *td, struct auditctl_args *uap)
crhold(cred);
/*
- * XXXAUDIT: Should audit_suspended actually be cleared by
+ * XXXAUDIT: Should audit_trail_suspended actually be cleared by
* audit_worker?
*/
- audit_suspended = 0;
+ audit_trail_suspended = 0;
+ audit_syscalls_enabled_update();
audit_rotate_vnode(cred, vp);
diff --git a/sys/security/audit/audit_worker.c b/sys/security/audit/audit_worker.c
index fa6fe66db259..f169ab8d9dd1 100644
--- a/sys/security/audit/audit_worker.c
+++ b/sys/security/audit/audit_worker.c
@@ -2,7 +2,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 1999-2008 Apple Inc.
- * Copyright (c) 2006-2008, 2016 Robert N. M. Watson
+ * Copyright (c) 2006-2008, 2016, 2018 Robert N. M. Watson
* All rights reserved.
*
* Portions of this software were developed by BAE Systems, the University of
@@ -305,7 +305,8 @@ fail_enospc:
"Audit log space exhausted and fail-stop set.");
}
(void)audit_send_trigger(AUDIT_TRIGGER_NO_SPACE);
- audit_suspended = 1;
+ audit_trail_suspended = 1;
+ audit_syscalls_enabled_update();
/* FALLTHROUGH */
fail:
@@ -518,7 +519,8 @@ audit_rotate_vnode(struct ucred *cred, struct vnode *vp)
audit_vp = vp;
audit_size = vattr.va_size;
audit_file_rotate_wait = 0;
- audit_enabled = (audit_vp != NULL);
+ audit_trail_enabled = (audit_vp != NULL);
+ audit_syscalls_enabled_update();
AUDIT_WORKER_UNLOCK();
/*
diff --git a/sys/sys/_domainset.h b/sys/sys/_domainset.h
index 30d8501c8e4a..34d8f61ca9fc 100644
--- a/sys/sys/_domainset.h
+++ b/sys/sys/_domainset.h
@@ -54,7 +54,7 @@ typedef struct _domainset domainset_t;
struct domainset;
struct domainset_ref {
struct domainset * volatile dr_policy;
- int dr_iterator;
+ unsigned int dr_iterator;
};
#endif /* !_SYS__DOMAINSET_H_ */
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/pmc.h b/sys/sys/pmc.h
index 0c7a3a331abd..be4c1cda03b0 100644
--- a/sys/sys/pmc.h
+++ b/sys/sys/pmc.h
@@ -936,6 +936,8 @@ struct pmc_sample {
uint16_t ps_flags; /* other flags */
lwpid_t ps_tid; /* thread id */
pid_t ps_pid; /* process PID or -1 */
+ int ps_ticks; /* ticks at sample time */
+ /* pad */
struct thread *ps_td; /* which thread */
struct pmc *ps_pmc; /* interrupting PMC */
uintptr_t *ps_pc; /* (const) callchain start */
@@ -943,16 +945,23 @@ struct pmc_sample {
};
#define PMC_SAMPLE_FREE ((uint16_t) 0)
-#define PMC_SAMPLE_INUSE ((uint16_t) 0xFFFF)
+#define PMC_USER_CALLCHAIN_PENDING ((uint16_t) 0xFFFF)
struct pmc_samplebuffer {
- struct pmc_sample * volatile ps_read; /* read pointer */
- struct pmc_sample * volatile ps_write; /* write pointer */
+ volatile uint64_t ps_prodidx; /* producer index */
+ volatile uint64_t ps_considx; /* consumer index */
uintptr_t *ps_callchains; /* all saved call chains */
- struct pmc_sample *ps_fence; /* one beyond ps_samples[] */
struct pmc_sample ps_samples[]; /* array of sample entries */
};
+#define PMC_CONS_SAMPLE(psb) \
+ (&(psb)->ps_samples[(psb)->ps_considx & pmc_sample_mask])
+
+#define PMC_CONS_SAMPLE_OFF(psb, off) \
+ (&(psb)->ps_samples[(off) & pmc_sample_mask])
+
+#define PMC_PROD_SAMPLE(psb) \
+ (&(psb)->ps_samples[(psb)->ps_prodidx & pmc_sample_mask])
/*
* struct pmc_cpustate
@@ -1216,7 +1225,6 @@ int pmc_save_user_callchain(uintptr_t *_cc, int _maxsamples,
struct trapframe *_tf);
struct pmc_mdep *pmc_mdep_alloc(int nclasses);
void pmc_mdep_free(struct pmc_mdep *md);
-void pmc_flush_samples(int cpu);
uint64_t pmc_rdtsc(void);
#endif /* _KERNEL */
#endif /* _SYS_PMC_H_ */
diff --git a/sys/sys/pmckern.h b/sys/sys/pmckern.h
index 27e02af73cf2..e892d658a1ca 100644
--- a/sys/sys/pmckern.h
+++ b/sys/sys/pmckern.h
@@ -67,10 +67,12 @@
#define PMC_FN_THR_EXIT_LOG 16
#define PMC_FN_PROC_CREATE_LOG 17
-#define PMC_HR 0 /* Hardware ring buffer */
-#define PMC_SR 1 /* Software ring buffer */
-#define PMC_UR 2 /* userret ring buffer */
-#define PMC_NUM_SR (PMC_UR+1)
+typedef enum ring_type {
+ PMC_HR = 0, /* Hardware ring buffer */
+ PMC_SR = 1, /* Software ring buffer */
+ PMC_UR = 2, /* userret ring buffer */
+ PMC_NUM_SR = PMC_UR+1
+} ring_type_t;
struct pmckern_procexec {
int pm_credentialschanged;
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/resourcevar.h b/sys/sys/resourcevar.h
index c61ac3e1a6cf..a60eb3b6dbb3 100644
--- a/sys/sys/resourcevar.h
+++ b/sys/sys/resourcevar.h
@@ -93,12 +93,10 @@ struct racct;
* (a) Constant from inception
* (b) Lockless, updated using atomics
* (c) Locked by global uihashtbl_lock
- * (d) Locked by the ui_vmsize_mtx
*/
struct uidinfo {
LIST_ENTRY(uidinfo) ui_hash; /* (c) hash chain of uidinfos */
- struct mtx ui_vmsize_mtx;
- vm_ooffset_t ui_vmsize; /* (d) swap reservation by uid */
+ u_long ui_vmsize; /* (b) pages of swap reservation by uid */
long ui_sbsize; /* (b) socket buffer space consumed */
long ui_proccnt; /* (b) number of processes */
long ui_ptscnt; /* (b) number of pseudo-terminals */
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/syscall.h b/sys/sys/syscall.h
index 6e880f04950c..436186e90d29 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -175,6 +175,10 @@
#define SYS_setgid 181
#define SYS_setegid 182
#define SYS_seteuid 183
+ /* 184 is obsolete lfs_bmapv */
+ /* 185 is obsolete lfs_markv */
+ /* 186 is obsolete lfs_segclean */
+ /* 187 is obsolete lfs_segwait */
#define SYS_freebsd11_stat 188
#define SYS_freebsd11_fstat 189
#define SYS_freebsd11_lstat 190
@@ -198,6 +202,7 @@
#define SYS_freebsd7___semctl 220
#define SYS_semget 221
#define SYS_semop 222
+ /* 223 is obsolete semconfig */
#define SYS_freebsd7_msgctl 224
#define SYS_msgget 225
#define SYS_msgsnd 226
@@ -306,13 +311,25 @@
#define SYS_getresgid 361
#define SYS_kqueue 362
#define SYS_freebsd11_kevent 363
+ /* 364 is obsolete __cap_get_proc */
+ /* 365 is obsolete __cap_set_proc */
+ /* 366 is obsolete __cap_get_fd */
+ /* 367 is obsolete __cap_get_file */
+ /* 368 is obsolete __cap_set_fd */
+ /* 369 is obsolete __cap_set_file */
#define SYS_extattr_set_fd 371
#define SYS_extattr_get_fd 372
#define SYS_extattr_delete_fd 373
#define SYS___setugid 374
+ /* 375 is obsolete nfsclnt */
#define SYS_eaccess 376
#define SYS_afs3_syscall 377
#define SYS_nmount 378
+ /* 379 is obsolete kse_exit */
+ /* 380 is obsolete kse_wakeup */
+ /* 381 is obsolete kse_create */
+ /* 382 is obsolete kse_thr_interrupt */
+ /* 383 is obsolete kse_release */
#define SYS___mac_get_proc 384
#define SYS___mac_set_proc 385
#define SYS___mac_get_fd 386
@@ -363,6 +380,7 @@
#define SYS_extattr_list_fd 437
#define SYS_extattr_list_file 438
#define SYS_extattr_list_link 439
+ /* 440 is obsolete kse_switchin */
#define SYS_ksem_timedwait 441
#define SYS_thr_suspend 442
#define SYS_thr_wake 443
@@ -465,6 +483,8 @@
#define SYS_ppoll 545
#define SYS_futimens 546
#define SYS_utimensat 547
+ /* 548 is obsolete numa_getaffinity */
+ /* 549 is obsolete numa_setaffinity */
#define SYS_fdatasync 550
#define SYS_fstat 551
#define SYS_fstatat 552
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 @@ again:
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..76a574883619 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -151,12 +151,16 @@ static int nswapdev; /* Number of swap devices */
int swap_pager_avail;
static struct sx swdev_syscall_lock; /* serialize swap(on|off) */
-static vm_ooffset_t swap_total;
-SYSCTL_QUAD(_vm, OID_AUTO, swap_total, CTLFLAG_RD, &swap_total, 0,
- "Total amount of available swap storage.");
-static vm_ooffset_t swap_reserved;
-SYSCTL_QUAD(_vm, OID_AUTO, swap_reserved, CTLFLAG_RD, &swap_reserved, 0,
+static u_long swap_reserved;
+static u_long swap_total;
+static int sysctl_page_shift(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_vm, OID_AUTO, swap_reserved, CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ &swap_reserved, 0, sysctl_page_shift, "A",
"Amount of swap storage needed to back all allocated anonymous memory.");
+SYSCTL_PROC(_vm, OID_AUTO, swap_total, CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ &swap_total, 0, sysctl_page_shift, "A",
+ "Total amount of available swap storage.");
+
static int overcommit = 0;
SYSCTL_INT(_vm, VM_OVERCOMMIT, overcommit, CTLFLAG_RW, &overcommit, 0,
"Configure virtual memory overcommit behavior. See tuning(7) "
@@ -173,6 +177,16 @@ SYSCTL_ULONG(_vm, OID_AUTO, swap_maxpages, CTLFLAG_RD, &swap_maxpages, 0,
#define SWAP_RESERVE_RLIMIT_ON (1 << 1)
#define SWAP_RESERVE_ALLOW_NONWIRED (1 << 2)
+static int
+sysctl_page_shift(SYSCTL_HANDLER_ARGS)
+{
+ uint64_t newval;
+ u_long value = *(u_long *)arg1;
+
+ newval = ((uint64_t)value) << PAGE_SHIFT;
+ return (sysctl_handle_64(oidp, &newval, 0, req));
+}
+
int
swap_reserve(vm_ooffset_t incr)
{
@@ -183,7 +197,7 @@ swap_reserve(vm_ooffset_t incr)
int
swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
{
- vm_ooffset_t r, s;
+ u_long r, s, prev, pincr;
int res, error;
static int curfail;
static struct timeval lastfail;
@@ -191,8 +205,8 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
uip = cred->cr_ruidinfo;
- if (incr & PAGE_MASK)
- panic("swap_reserve: & PAGE_MASK");
+ KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__,
+ (uintmax_t)incr));
#ifdef RACCT
if (racct_enable) {
@@ -204,36 +218,33 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
}
#endif
+ pincr = atop(incr);
res = 0;
- mtx_lock(&sw_dev_mtx);
- r = swap_reserved + incr;
+ prev = atomic_fetchadd_long(&swap_reserved, pincr);
+ r = prev + pincr;
if (overcommit & SWAP_RESERVE_ALLOW_NONWIRED) {
s = vm_cnt.v_page_count - vm_cnt.v_free_reserved -
vm_wire_count();
- s *= PAGE_SIZE;
} else
s = 0;
s += swap_total;
if ((overcommit & SWAP_RESERVE_FORCE_ON) == 0 || r <= s ||
(error = priv_check(curthread, PRIV_VM_SWAP_NOQUOTA)) == 0) {
res = 1;
- swap_reserved = r;
+ } else {
+ prev = atomic_fetchadd_long(&swap_reserved, -pincr);
+ if (prev < pincr)
+ panic("swap_reserved < incr on overcommit fail");
}
- mtx_unlock(&sw_dev_mtx);
-
if (res) {
- UIDINFO_VMSIZE_LOCK(uip);
+ prev = atomic_fetchadd_long(&uip->ui_vmsize, pincr);
if ((overcommit & SWAP_RESERVE_RLIMIT_ON) != 0 &&
- uip->ui_vmsize + incr > lim_cur(curthread, RLIMIT_SWAP) &&
- priv_check(curthread, PRIV_VM_SWAP_NORLIMIT))
+ prev + pincr > lim_cur(curthread, RLIMIT_SWAP) &&
+ priv_check(curthread, PRIV_VM_SWAP_NORLIMIT)) {
res = 0;
- else
- uip->ui_vmsize += incr;
- UIDINFO_VMSIZE_UNLOCK(uip);
- if (!res) {
- mtx_lock(&sw_dev_mtx);
- swap_reserved -= incr;
- mtx_unlock(&sw_dev_mtx);
+ prev = atomic_fetchadd_long(&uip->ui_vmsize, -pincr);
+ if (prev < pincr)
+ panic("uip->ui_vmsize < incr on overcommit fail");
}
}
if (!res && ppsratecheck(&lastfail, &curfail, 1)) {
@@ -242,7 +253,7 @@ swap_reserve_by_cred(vm_ooffset_t incr, struct ucred *cred)
}
#ifdef RACCT
- if (!res) {
+ if (racct_enable && !res) {
PROC_LOCK(curproc);
racct_sub(curproc, RACCT_SWAP, incr);
PROC_UNLOCK(curproc);
@@ -256,22 +267,20 @@ void
swap_reserve_force(vm_ooffset_t incr)
{
struct uidinfo *uip;
+ u_long pincr;
- mtx_lock(&sw_dev_mtx);
- swap_reserved += incr;
- mtx_unlock(&sw_dev_mtx);
+ KASSERT((incr & PAGE_MASK) == 0, ("%s: incr: %ju & PAGE_MASK", __func__,
+ (uintmax_t)incr));
-#ifdef RACCT
PROC_LOCK(curproc);
- racct_add_force(curproc, RACCT_SWAP, incr);
- PROC_UNLOCK(curproc);
+#ifdef RACCT
+ if (racct_enable)
+ racct_add_force(curproc, RACCT_SWAP, incr);
#endif
-
- uip = curthread->td_ucred->cr_ruidinfo;
- PROC_LOCK(curproc);
- UIDINFO_VMSIZE_LOCK(uip);
- uip->ui_vmsize += incr;
- UIDINFO_VMSIZE_UNLOCK(uip);
+ pincr = atop(incr);
+ atomic_add_long(&swap_reserved, pincr);
+ uip = curproc->p_ucred->cr_ruidinfo;
+ atomic_add_long(&uip->ui_vmsize, pincr);
PROC_UNLOCK(curproc);
}
@@ -281,7 +290,7 @@ swap_release(vm_ooffset_t decr)
struct ucred *cred;
PROC_LOCK(curproc);
- cred = curthread->td_ucred;
+ cred = curproc->p_ucred;
swap_release_by_cred(decr, cred);
PROC_UNLOCK(curproc);
}
@@ -289,26 +298,26 @@ swap_release(vm_ooffset_t decr)
void
swap_release_by_cred(vm_ooffset_t decr, struct ucred *cred)
{
+ u_long prev, pdecr;
struct uidinfo *uip;
uip = cred->cr_ruidinfo;
- if (decr & PAGE_MASK)
- panic("swap_release: & PAGE_MASK");
+ KASSERT((decr & PAGE_MASK) == 0, ("%s: decr: %ju & PAGE_MASK", __func__,
+ (uintmax_t)decr));
- mtx_lock(&sw_dev_mtx);
- if (swap_reserved < decr)
+ pdecr = atop(decr);
+ prev = atomic_fetchadd_long(&swap_reserved, -pdecr);
+ if (prev < pdecr)
panic("swap_reserved < decr");
- swap_reserved -= decr;
- mtx_unlock(&sw_dev_mtx);
- UIDINFO_VMSIZE_LOCK(uip);
- if (uip->ui_vmsize < decr)
+ prev = atomic_fetchadd_long(&uip->ui_vmsize, -pdecr);
+ if (prev < pdecr)
printf("negative vmsize for uid = %d\n", uip->ui_uid);
- uip->ui_vmsize -= decr;
- UIDINFO_VMSIZE_UNLOCK(uip);
-
- racct_sub_cred(cred, RACCT_SWAP, decr);
+#ifdef RACCT
+ if (racct_enable)
+ racct_sub_cred(cred, RACCT_SWAP, decr);
+#endif
}
#define SWM_POP 0x01 /* pop out */
@@ -545,13 +554,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;
@@ -2178,7 +2185,7 @@ swapon_check_swzone(void)
{
unsigned long maxpages, npages;
- npages = swap_total / PAGE_SIZE;
+ npages = swap_total;
/* absolute maximum we can handle assuming 100% efficiency */
maxpages = uma_zone_get_max(swblk_zone) * SWAP_META_PAGES;
@@ -2256,7 +2263,7 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks,
TAILQ_INSERT_TAIL(&swtailq, sp, sw_list);
nswapdev++;
swap_pager_avail += nblks - 2;
- swap_total += (vm_ooffset_t)nblks * PAGE_SIZE;
+ swap_total += nblks;
swapon_check_swzone();
swp_sizecheck();
mtx_unlock(&sw_dev_mtx);
@@ -2353,7 +2360,7 @@ swapoff_one(struct swdevt *sp, struct ucred *cred)
mtx_lock(&sw_dev_mtx);
sp->sw_flags |= SW_CLOSING;
swap_pager_avail -= blist_fill(sp->sw_blist, 0, nblks);
- swap_total -= (vm_ooffset_t)nblks * PAGE_SIZE;
+ swap_total -= nblks;
mtx_unlock(&sw_dev_mtx);
/*
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c
index 908349379763..837eb0787915 100644
--- a/sys/vm/uma_core.c
+++ b/sys/vm/uma_core.c
@@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_pageout.h>
#include <vm/vm_param.h>
#include <vm/vm_phys.h>
+#include <vm/vm_pagequeue.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
@@ -2469,9 +2470,11 @@ zalloc_start:
if (bucket != NULL)
bucket_free(zone, bucket, udata);
- if (zone->uz_flags & UMA_ZONE_NUMA)
+ if (zone->uz_flags & UMA_ZONE_NUMA) {
domain = PCPU_GET(domain);
- else
+ if (VM_DOMAIN_EMPTY(domain))
+ domain = UMA_ANYDOMAIN;
+ } else
domain = UMA_ANYDOMAIN;
/* Short-circuit for zones without buckets and low memory. */
@@ -2647,7 +2650,11 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, int flags)
rdomain = 0;
rr = rdomain == UMA_ANYDOMAIN;
if (rr) {
- keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains;
+ start = keg->uk_cursor;
+ do {
+ keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains;
+ domain = keg->uk_cursor;
+ } while (VM_DOMAIN_EMPTY(domain) && domain != start);
domain = start = keg->uk_cursor;
/* Only block on the second pass. */
if ((flags & (M_WAITOK | M_NOVM)) == M_WAITOK)
@@ -2699,8 +2706,9 @@ again:
return (slab);
}
if (rr) {
- keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains;
- domain = keg->uk_cursor;
+ do {
+ domain = (domain + 1) % vm_ndomains;
+ } while (VM_DOMAIN_EMPTY(domain) && domain != start);
}
} while (domain != start);
@@ -2905,6 +2913,8 @@ zone_alloc_bucket(uma_zone_t zone, void *udata, int domain, int flags)
uma_bucket_t bucket;
int max;
+ CTR1(KTR_UMA, "zone_alloc:_bucket domain %d)", domain);
+
/* Don't wait for buckets, preserve caller's NOVM setting. */
bucket = bucket_alloc(zone, udata, M_NOWAIT | (flags & M_NOVM));
if (bucket == NULL)
@@ -2972,6 +2982,11 @@ zone_alloc_item(uma_zone_t zone, void *udata, int domain, int flags)
item = NULL;
+ if (domain != UMA_ANYDOMAIN) {
+ /* avoid allocs targeting empty domains */
+ if (VM_DOMAIN_EMPTY(domain))
+ domain = UMA_ANYDOMAIN;
+ }
if (zone->uz_import(zone->uz_arg, &item, 1, domain, flags) != 1)
goto fail;
atomic_add_long(&zone->uz_allocs, 1);
@@ -3141,9 +3156,11 @@ zfree_start:
/* We are no longer associated with this CPU. */
critical_exit();
- if ((zone->uz_flags & UMA_ZONE_NUMA) != 0)
+ if ((zone->uz_flags & UMA_ZONE_NUMA) != 0) {
domain = PCPU_GET(domain);
- else
+ if (VM_DOMAIN_EMPTY(domain))
+ domain = UMA_ANYDOMAIN;
+ } else
domain = 0;
zdom = &zone->uz_domain[0];
@@ -3590,7 +3607,9 @@ uma_prealloc(uma_zone_t zone, int items)
dom = &keg->uk_domain[slab->us_domain];
LIST_INSERT_HEAD(&dom->ud_free_slab, slab, us_link);
slabs--;
- domain = (domain + 1) % vm_ndomains;
+ do {
+ domain = (domain + 1) % vm_ndomains;
+ } while (VM_DOMAIN_EMPTY(domain));
}
KEG_UNLOCK(keg);
}
@@ -3680,6 +3699,11 @@ uma_large_malloc_domain(vm_size_t size, int domain, int wait)
vm_offset_t addr;
uma_slab_t slab;
+ if (domain != UMA_ANYDOMAIN) {
+ /* avoid allocs targeting empty domains */
+ if (VM_DOMAIN_EMPTY(domain))
+ domain = UMA_ANYDOMAIN;
+ }
slab = zone_alloc_item(slabzone, NULL, domain, wait);
if (slab == NULL)
return (NULL);
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_domainset.h b/sys/vm/vm_domainset.h
index 10da5caa0ea7..b1c5766c1c67 100644
--- a/sys/vm/vm_domainset.h
+++ b/sys/vm/vm_domainset.h
@@ -32,7 +32,7 @@
struct vm_domainset_iter {
struct domainset *di_domain;
- int *di_iter;
+ unsigned int *di_iter;
vm_pindex_t di_offset;
int di_flags;
uint16_t di_policy;
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index d5a6b57f47e3..c56e51f3dbfe 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1633,16 +1633,16 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
dst_object->flags |= OBJ_COLORED;
dst_object->pg_color = atop(dst_entry->start);
#endif
+ dst_object->domain = src_object->domain;
+ dst_object->charge = dst_entry->end - dst_entry->start;
}
VM_OBJECT_WLOCK(dst_object);
KASSERT(upgrade || dst_entry->object.vm_object == NULL,
("vm_fault_copy_entry: vm_object not NULL"));
if (src_object != dst_object) {
- dst_object->domain = src_object->domain;
dst_entry->object.vm_object = dst_object;
dst_entry->offset = 0;
- dst_object->charge = dst_entry->end - dst_entry->start;
}
if (fork_charge != NULL) {
KASSERT(dst_entry->cred == NULL,
@@ -1650,7 +1650,9 @@ vm_fault_copy_entry(vm_map_t dst_map, vm_map_t src_map,
dst_object->cred = curthread->td_ucred;
crhold(dst_object->cred);
*fork_charge += dst_object->charge;
- } else if (dst_object->cred == NULL) {
+ } else if ((dst_object->type == OBJT_DEFAULT ||
+ dst_object->type == OBJT_SWAP) &&
+ dst_object->cred == NULL) {
KASSERT(dst_entry->cred != NULL, ("no cred for entry %p",
dst_entry));
dst_object->cred = dst_entry->cred;
@@ -1737,6 +1739,13 @@ again:
dst_m = src_m;
if (vm_page_sleep_if_busy(dst_m, "fltupg"))
goto again;
+ if (dst_m->pindex >= dst_object->size)
+ /*
+ * We are upgrading. Index can occur
+ * out of bounds if the object type is
+ * vnode and the file was truncated.
+ */
+ break;
vm_page_xbusy(dst_m);
KASSERT(dst_m->valid == VM_PAGE_BITS_ALL,
("invalid dst page %p", dst_m));
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;
/*
@@ -113,57 +107,14 @@ 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..88fbc74848df 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,43 @@ retry:
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;
+ while (VM_DOMAIN_EMPTY(domain))
+ domain++;
+ 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);
}
/*
@@ -645,17 +673,57 @@ kmem_init_zero_region(void)
}
/*
+ * 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:
*
* Create the kernel map; insert a mapping covering kernel text,
* 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 +739,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_pageout.c b/sys/vm/vm_pageout.c
index c084de7aca44..5c309a04a402 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -2082,6 +2082,13 @@ vm_pageout(void)
if (error != 0)
panic("starting laundry for domain 0, error %d", error);
for (i = 1; i < vm_ndomains; i++) {
+ if (VM_DOMAIN_EMPTY(i)) {
+ if (bootverbose)
+ printf("domain %d empty; skipping pageout\n",
+ i);
+ continue;
+ }
+
error = kthread_add(vm_pageout_worker, (void *)(uintptr_t)i,
curproc, NULL, 0, 0, "dom%d", i);
if (error != 0) {
diff --git a/sys/vm/vm_pagequeue.h b/sys/vm/vm_pagequeue.h
index ac04f2b3ea61..758e51d8ef6e 100644
--- a/sys/vm/vm_pagequeue.h
+++ b/sys/vm/vm_pagequeue.h
@@ -151,7 +151,8 @@ struct vm_domain {
extern struct vm_domain vm_dom[MAXMEMDOM];
-#define VM_DOMAIN(n) (&vm_dom[(n)])
+#define VM_DOMAIN(n) (&vm_dom[(n)])
+#define VM_DOMAIN_EMPTY(n) (vm_dom[(n)].vmd_page_count == 0)
#define vm_pagequeue_assert_locked(pq) mtx_assert(&(pq)->pq_mutex, MA_OWNED)
#define vm_pagequeue_lock(pq) mtx_lock(&(pq)->pq_mutex)
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..42b506c4447b 100644
--- a/sys/x86/acpica/srat.c
+++ b/sys/x86/acpica/srat.c
@@ -311,8 +311,20 @@ check_domains(void)
}
for (i = 0; i <= max_apic_id; i++)
if (cpus[i].enabled && !cpus[i].has_memory) {
- printf("SRAT: No memory found for CPU %d\n", i);
- return (ENXIO);
+ found = 0;
+ for (j = 0; j < num_mem && !found; j++) {
+ if (mem_info[j].domain == cpus[i].domain)
+ found = 1;
+ }
+ if (!found) {
+ if (bootverbose)
+ printf("SRAT: mem dom %d is empty\n",
+ cpus[i].domain);
+ mem_info[num_mem].start = 0;
+ mem_info[num_mem].end = 0;
+ mem_info[num_mem].domain = cpus[i].domain;
+ num_mem++;
+ }
}
return (0);
}
@@ -470,8 +482,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/include/ifunc.h b/sys/x86/include/ifunc.h
index 13f4b886430e..38c82570770e 100644
--- a/sys/x86/include/ifunc.h
+++ b/sys/x86/include/ifunc.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2015, 2017 The FreeBSD Foundation
+ * Copyright (c) 2015-2018 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Konstantin Belousov <kib@FreeBSD.org>
@@ -32,27 +32,19 @@
#ifndef __X86_IFUNC_H
#define __X86_IFUNC_H
-#define DECLARE_LIFUNC(ret_type, name, args) \
-ret_type name args
-
-#define DEFINE_LIFUNC(scope, selector_qual, ret_type, name, args) \
-__asm__ (scope "\t" #name "\n" \
- "\t.type\t" #name ",@function\n" \
- #name ":\n" \
- "\tjmp *" #name "_selector\n" \
- "\t.size\t" #name ",\t. - "#name); \
-selector_qual ret_type (*name##_selector)args __used; \
-DECLARE_LIFUNC(ret_type, name, args)
-
-#define DEFINE_STATIC_LIFUNC(ret_type, name, args) \
- DEFINE_LIFUNC(".local", static, ret_type, name, args)
-
-#define DEFINE_GLOBAL_LIFUNC(ret_type, name, args) \
- DEFINE_LIFUNC(".globl", , ret_type, name, args)
-
-#define DEFINE_IFUNC(qual, ret_type, name, args, resolver_qual) \
+#define DEFINE_IFUNC(qual, ret_type, name, args, resolver_qual) \
resolver_qual ret_type (*name##_resolver(void))args __used; \
qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \
resolver_qual ret_type (*name##_resolver(void))args
+#define DEFINE_UIFUNC(qual, ret_type, name, args, resolver_qual) \
+ resolver_qual ret_type (*name##_resolver(uint32_t, uint32_t, \
+ uint32_t, uint32_t))args __used; \
+ qual ret_type name args __attribute__((ifunc(#name "_resolver"))); \
+ resolver_qual ret_type (*name##_resolver( \
+ uint32_t cpu_feature __unused, \
+ uint32_t cpu_feature2 __unused, \
+ uint32_t cpu_stdext_feature __unused, \
+ uint32_t cpu_stdext_feature2 __unused))args
+
#endif
diff --git a/sys/x86/include/ucode.h b/sys/x86/include/ucode.h
index d9c860d20ca8..5c8868108930 100644
--- a/sys/x86/include/ucode.h
+++ b/sys/x86/include/ucode.h
@@ -58,7 +58,8 @@ struct ucode_intel_extsig_table {
} entries[0];
};
-int ucode_intel_load(void *data, bool unsafe);
+int ucode_intel_load(void *data, bool unsafe,
+ uint64_t *nrevp, uint64_t *orevp);
size_t ucode_load_bsp(uintptr_t free);
void ucode_load_ap(int cpu);
void ucode_reload(void);
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/sys/x86/isa/atpic.c b/sys/x86/isa/atpic.c
index 8560793df503..e7e0cc79b54c 100644
--- a/sys/x86/isa/atpic.c
+++ b/sys/x86/isa/atpic.c
@@ -221,14 +221,20 @@ atpic_register_sources(struct pic *pic)
* that APIC ISA routing and allowing the ATPIC source for that IRQ
* to leak through. We used to depend on this feature for routing
* IRQ0 via mixed mode, but now we don't use mixed mode at all.
+ *
+ * To avoid the slave not register sources after the master
+ * registers its sources, register all IRQs when this function is
+ * called on the master.
*/
+ if (ap != &atpics[MASTER])
+ return;
for (i = 0; i < NUM_ISA_IRQS; i++)
if (intr_lookup_source(i) != NULL)
return;
/* Loop through all interrupt sources and add them. */
- for (i = 0, ai = atintrs + ap->at_irqbase; i < 8; i++, ai++) {
- if (ap->at_irqbase + i == ICU_SLAVEID)
+ for (i = 0, ai = atintrs; i < NUM_ISA_IRQS; i++, ai++) {
+ if (i == ICU_SLAVEID)
continue;
intr_register_source(&ai->at_intsrc);
}
diff --git a/sys/x86/x86/ucode.c b/sys/x86/x86/ucode.c
index e1229a8401ec..5b039491345a 100644
--- a/sys/x86/x86/ucode.c
+++ b/sys/x86/x86/ucode.c
@@ -59,7 +59,7 @@ static int ucode_intel_verify(struct ucode_intel_header *hdr,
static struct ucode_ops {
const char *vendor;
- int (*load)(void *, bool);
+ int (*load)(void *, bool, uint64_t *, uint64_t *);
void *(*match)(uint8_t *, size_t *);
} loaders[] = {
{
@@ -72,35 +72,46 @@ static struct ucode_ops {
/* Selected microcode update data. */
static void *early_ucode_data;
static void *ucode_data;
+static struct ucode_ops *ucode_loader;
-static char errbuf[128];
-
-static void __printflike(1, 2)
-log_err(const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
- va_end(ap);
-}
+/* Variables used for reporting success or failure. */
+enum {
+ NO_ERROR,
+ NO_MATCH,
+ VERIFICATION_FAILED,
+} ucode_error = NO_ERROR;
+static uint64_t ucode_nrev, ucode_orev;
static void
-print_err(void *arg __unused)
+log_msg(void *arg __unused)
{
- if (errbuf[0] != '\0')
- printf("microcode load error: %s\n", errbuf);
+ if (ucode_nrev != 0) {
+ printf("CPU microcode: updated from %#jx to %#jx\n",
+ (uintmax_t)ucode_orev, (uintmax_t)ucode_nrev);
+ return;
+ }
+
+ switch (ucode_error) {
+ case NO_MATCH:
+ printf("CPU microcode: no matching update found\n");
+ break;
+ case VERIFICATION_FAILED:
+ printf("CPU microcode: microcode verification failed\n");
+ break;
+ default:
+ break;
+ }
}
-SYSINIT(ucode_print_err, SI_SUB_CPU, SI_ORDER_FIRST, print_err, NULL);
+SYSINIT(ucode_log, SI_SUB_CPU, SI_ORDER_FIRST, log_msg, NULL);
int
-ucode_intel_load(void *data, bool unsafe)
+ucode_intel_load(void *data, bool unsafe, uint64_t *nrevp, uint64_t *orevp)
{
- uint64_t rev0, rev1;
+ uint64_t nrev, orev;
uint32_t cpuid[4];
- rev0 = rdmsr(MSR_BIOS_SIGN);
+ orev = rdmsr(MSR_BIOS_SIGN) >> 32;
/*
* Perform update. Flush caches first to work around seemingly
@@ -118,8 +129,15 @@ ucode_intel_load(void *data, bool unsafe)
*/
do_cpuid(0, cpuid);
- rev1 = rdmsr(MSR_BIOS_SIGN);
- if (rev1 <= rev0)
+ /*
+ * Verify that the microcode revision changed.
+ */
+ nrev = rdmsr(MSR_BIOS_SIGN) >> 32;
+ if (nrevp != NULL)
+ *nrevp = nrev;
+ if (orevp != NULL)
+ *orevp = orev;
+ if (nrev <= orev)
return (EEXIST);
return (0);
}
@@ -130,36 +148,26 @@ ucode_intel_verify(struct ucode_intel_header *hdr, size_t resid)
uint32_t cksum, *data, size;
int i;
- if (resid < sizeof(struct ucode_intel_header)) {
- log_err("truncated update header");
+ if (resid < sizeof(struct ucode_intel_header))
return (1);
- }
size = hdr->total_size;
if (size == 0)
size = UCODE_INTEL_DEFAULT_DATA_SIZE +
sizeof(struct ucode_intel_header);
- if (hdr->header_version != 1) {
- log_err("unexpected header version %u", hdr->header_version);
+ if (hdr->header_version != 1)
return (1);
- }
- if (size % 16 != 0) {
- log_err("unexpected update size %u", hdr->total_size);
+ if (size % 16 != 0)
return (1);
- }
- if (resid < size) {
- log_err("truncated update");
+ if (resid < size)
return (1);
- }
cksum = 0;
data = (uint32_t *)hdr;
for (i = 0; i < size / sizeof(uint32_t); i++)
cksum += data[i];
- if (cksum != 0) {
- log_err("checksum failed");
+ if (cksum != 0)
return (1);
- }
return (0);
}
@@ -182,8 +190,10 @@ ucode_intel_match(uint8_t *data, size_t *len)
for (resid = *len; resid > 0; data += total_size, resid -= total_size) {
hdr = (struct ucode_intel_header *)data;
- if (ucode_intel_verify(hdr, resid) != 0)
+ if (ucode_intel_verify(hdr, resid) != 0) {
+ ucode_error = VERIFICATION_FAILED;
break;
+ }
data_size = hdr->data_size;
total_size = hdr->total_size;
@@ -259,12 +269,12 @@ ucode_load_ap(int cpu)
KASSERT(cpu_info[cpu_apic_ids[cpu]].cpu_present,
("cpu %d not present", cpu));
- if (!cpu_info[cpu_apic_ids[cpu]].cpu_hyperthread)
+ if (cpu_info[cpu_apic_ids[cpu]].cpu_hyperthread)
return;
#endif
if (ucode_data != NULL)
- (void)ucode_intel_load(ucode_data, false);
+ (void)ucode_loader->load(ucode_data, false, NULL, NULL);
}
static void *
@@ -308,11 +318,12 @@ ucode_load_bsp(uintptr_t free)
uint32_t regs[4];
char vendor[13];
} cpuid;
- struct ucode_ops *loader;
uint8_t *addr, *fileaddr, *match;
char *type;
+ uint64_t nrev, orev;
caddr_t file;
- size_t i, len, ucode_len;
+ size_t i, len;
+ int error;
KASSERT(free % PAGE_SIZE == 0, ("unaligned boundary %p", (void *)free));
@@ -320,17 +331,16 @@ ucode_load_bsp(uintptr_t free)
cpuid.regs[0] = cpuid.regs[1];
cpuid.regs[1] = cpuid.regs[3];
cpuid.vendor[12] = '\0';
- for (i = 0, loader = NULL; i < nitems(loaders); i++)
+ for (i = 0; i < nitems(loaders); i++)
if (strcmp(cpuid.vendor, loaders[i].vendor) == 0) {
- loader = &loaders[i];
+ ucode_loader = &loaders[i];
break;
}
- if (loader == NULL)
+ if (ucode_loader == NULL)
return (0);
file = 0;
fileaddr = match = NULL;
- ucode_len = 0;
for (;;) {
file = preload_search_next_name(file);
if (file == 0)
@@ -341,7 +351,7 @@ ucode_load_bsp(uintptr_t free)
fileaddr = preload_fetch_addr(file);
len = preload_fetch_size(file);
- match = loader->match(fileaddr, &len);
+ match = ucode_loader->match(fileaddr, &len);
if (match != NULL) {
addr = map_ucode(free, len);
/* We can't use memcpy() before ifunc resolution. */
@@ -349,18 +359,19 @@ ucode_load_bsp(uintptr_t free)
addr[i] = ((volatile uint8_t *)match)[i];
match = addr;
- if (loader->load(match, false) == 0) {
- ucode_data = match;
- ucode_len = len;
- early_ucode_data = ucode_data;
- break;
+ error = ucode_loader->load(match, false, &nrev, &orev);
+ if (error == 0) {
+ ucode_data = early_ucode_data = match;
+ ucode_nrev = nrev;
+ ucode_orev = orev;
+ return (len);
}
unmap_ucode(free, len);
}
}
- if (fileaddr != NULL && ucode_data == NULL)
- log_err("no matching update found");
- return (ucode_len);
+ if (fileaddr != NULL && ucode_error == NO_ERROR)
+ ucode_error = NO_MATCH;
+ return (0);
}
/*
diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc
index 0de449a50fab..ee8d3552ecb0 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/clang/lld/ld.lld.1 b/usr.bin/clang/lld/ld.lld.1
index 1149866f5a01..948411fb05c3 100644
--- a/usr.bin/clang/lld/ld.lld.1
+++ b/usr.bin/clang/lld/ld.lld.1
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 22, 2018
+.Dd September 14, 2018
.Dt LD.LLD 1
.Os
.Sh NAME
@@ -450,6 +450,12 @@ be applied by a run-time loader.
Note that this feature requires special loader support and will
generally result in application crashes when used outside of freestanding
environments.
+.It Cm interpose
+Set the
+.Dv DF_1_INTERPOSE
+flag to indicate that the object is an interposer.
+Runtime linkers perform symbol resolution by first searching the application,
+followed by interposers, and then any other dependencies.
.It Cm muldefs
Do not error if a symbol is defined multiple times.
The first definition will be used.
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/nfsstat/nfsstat.1 b/usr.bin/nfsstat/nfsstat.1
index 5a2030cb88ad..286e42c00952 100644
--- a/usr.bin/nfsstat/nfsstat.1
+++ b/usr.bin/nfsstat/nfsstat.1
@@ -28,7 +28,7 @@
.\" From: @(#)nfsstat.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd January 22, 2018
+.Dd October 1, 2018
.Dt NFSSTAT 1
.Os
.Sh NAME
@@ -59,7 +59,7 @@ The options are as follows:
.It Fl c
Only display client side statistics.
.It Fl d
-Display statistics for the new NFS server that are similar to those
+Display statistics for the NFS server that are similar to those
displayed by
.Xr iostat 8 .
This includes kilobytes per transfer, transfers per second, and megabytes per
@@ -98,11 +98,10 @@ Extract values associated with the name list from the specified core
instead of the default
.Pa /dev/kmem .
.It Fl m
-Report the mount options for all new NFS client mounts.
+Report the mount options for all NFS client mounts.
This option overrides all others and
.Nm
will exit after completing the report.
-This option is only supported by the new NFS client.
.It Fl N
Extract the name list from the specified system instead of the default
.Pa /boot/kernel/kernel .
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
index fbeddf613cbb..fbeddf613cbb 100644
--- a/etc/phones
+++ b/usr.bin/tip/tip/phones
diff --git a/etc/remote b/usr.bin/tip/tip/remote
index c3e7808952d8..c3e7808952d8 100644
--- a/etc/remote
+++ b/usr.bin/tip/tip/remote
diff --git a/usr.bin/top/top.1 b/usr.bin/top/top.1
index cde24adc1148..ea56914819f4 100644
--- a/usr.bin/top/top.1
+++ b/usr.bin/top/top.1
@@ -1,5 +1,5 @@
.\" $FreeBSD$
-.Dd June 9, 2018
+.Dd October 2, 2018
.Dt TOP 1
.Os
.Sh NAME
@@ -359,81 +359,87 @@ the state column will report the name of the event or lock on which the
process is waiting.
Lock names are prefixed with an asterisk \*(lq*\*(rq while sleep events
are not.
-.Sh AUTHORS
-.An William LeFebvre, EECS Department, Northwestern University
-.Sh BUGS
-The command name for swapped processes should be tracked down, but this
-would make the program run slower.
-.Pp
-As with
-.Xr ps 1 ,
-things can change while
-.Nm
-is collecting information for an update.
-The picture it gives is only a
-close approximation to reality.
-.Sh ENVIRONMENT
-.Bl -tag -width TOP -compact
-.It Pa TOP
-Default set of arguments to
-.Nm .
-.El
-.Sh SEE ALSO
-.Xr kill 1 ,
-.Xr ps 1 ,
-.Xr stty 1 ,
-.Xr getrusage 2 ,
-.Xr humanize_number 3 ,
-.Xr mem 4 ,
-.Xr renice 8
.Sh DESCRIPTION OF MEMORY
+.Bd -literal
Mem: 61M Active, 86M Inact, 368K Laundry, 22G Wired, 102G Free
ARC: 15G Total, 9303M MFU, 6155M MRU, 1464K Anon, 98M Header, 35M Other
15G Compressed, 27G Uncompressed, 1.75:1 Ratio, 174M Overhead
Swap: 4096M Total, 532M Free, 13% Inuse, 80K In, 104K Out
-.Sh Physical Memory Stats
-.Bl -tag -width indent
-.It Active:
+.Ed
+.Ss Physical Memory Stats
+.Bl -tag -width "Uncompressed" -compact
+.It Em Active
number of bytes active
-.It Inact:
+.It Em Inact
number of clean bytes inactive
-.It Laundry:
+.It Em Laundry
number of dirty bytes queued for laundering
-.It Wired:
+.It Em Wired
number of bytes wired down, including IO-level cached file data pages
-.It Buf:
+.It Em Buf
number of bytes used for IO-level disk caching
-.It Free:
+.It Em Free
number of bytes free
-.It ZFS ARC Stats
+.El
+.Ss ZFS ARC Stats
These stats are only displayed when the ARC is in use.
-.It Total:
+.Pp
+.Bl -tag -width "Uncompressed" -compact
+.It Em Total
number of wired bytes used for the ZFS ARC
-.It MRU:
+.It Em MRU
number of ARC bytes holding most recently used data
-.It MFU:
+.It Em MFU
number of ARC bytes holding most frequently used data
-.It Anon:
+.It Em Anon
number of ARC bytes holding in flight data
-.It Header:
+.It Em Header
number of ARC bytes holding headers
-.It Other:
+.It Em Other
miscellaneous ARC bytes
-.It Compressed:
+.It Em Compressed
bytes of memory used by ARC caches
-.It Uncompressed:
+.It Em Uncompressed
bytes of data stored in ARC caches before compression
-.It Ratio:
+.It Em Ratio
compression ratio of data cached in the ARC
-.It Swap Stats
-.It Total:
+.El
+.Ss Swap Stats
+.Bl -tag -width "Uncompressed" -compact
+.It Em Total
total available swap usage
-.It Free:
+.It Em Free
total free swap usage
-.It Inuse:
+.It Em Inuse
swap usage
-.It In:
+.It Em \&In
bytes paged in from swap devices (last interval)
-.It Out:
+.It Em Out
bytes paged out to swap devices (last interval)
.El
+.Sh ENVIRONMENT
+.Bl -tag -width "Uncompressed"
+.It Ev TOP
+Default set of arguments to
+.Nm .
+.El
+.Sh SEE ALSO
+.Xr kill 1 ,
+.Xr ps 1 ,
+.Xr stty 1 ,
+.Xr getrusage 2 ,
+.Xr humanize_number 3 ,
+.Xr mem 4 ,
+.Xr renice 8
+.Sh AUTHORS
+.An William LeFebvre, EECS Department, Northwestern University
+.Sh BUGS
+The command name for swapped processes should be tracked down, but this
+would make the program run slower.
+.Pp
+As with
+.Xr ps 1 ,
+things can change while
+.Nm
+is collecting information for an update.
+The picture it gives is only a close approximation to reality.
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 20a101eaef5b..25e3265b6992 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -59,6 +59,9 @@ SUBDIR= adduser \
nologin \
pciconf \
periodic \
+ pmcannotate \
+ pmccontrol \
+ pmcstat \
pnfsdscopymr \
pnfsdsfile \
pnfsdskill \
@@ -185,11 +188,8 @@ SUBDIR.${MK_OPENSSL}+= keyserv
SUBDIR.${MK_PC_SYSINSTALL}+= pc-sysinstall
SUBDIR.${MK_PF}+= ftp-proxy
SUBDIR.${MK_PKGBOOTSTRAP}+= pkg
-.if (${COMPILER_TYPE} == "clang" || (${COMPILER_TYPE} == "gcc" && ${COMPILER_VERSION} >= 60100 && ${MACHINE_CPUARCH} != "riscv"))
+.if ${COMPILER_FEATURES:Mc++11}
SUBDIR.${MK_PMC}+= pmc
-SUBDIR.${MK_PMC}+= pmcannotate
-SUBDIR.${MK_PMC}+= pmccontrol
-SUBDIR.${MK_PMC}+= pmcstat
.endif
SUBDIR.${MK_PMC}+= pmcstudy
SUBDIR.${MK_PORTSNAP}+= portsnap
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
index 375ef34a6272..375ef34a6272 100644
--- a/etc/amd.map
+++ b/usr.sbin/amd/amd/amd.map
diff --git a/usr.sbin/bsdinstall/bsdinstall.8 b/usr.sbin/bsdinstall/bsdinstall.8
index 714a1f23fe7e..d6f446576b94 100644
--- a/usr.sbin/bsdinstall/bsdinstall.8
+++ b/usr.sbin/bsdinstall/bsdinstall.8
@@ -1,6 +1,6 @@
.\"-
-.\" Copyright (c) 2011-2013 Nathan Whitehorn <nwhitehorn@FreeBSD.org>
-.\" All rights reserved.
+.\" Copyright (c) 2011-2013 Nathan Whitehorn <nwhitehorn@FreeBSD.org> All rights reserved.
+.\" Copyright (c) 2018 Roberto Fernandez Cueto <roberfern@gmail.com>
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 23, 2017
+.Dd October 4, 2018
.Dt BSDINSTALL 8
.Os
.Sh NAME
@@ -261,12 +261,12 @@ overridden when making scripted or customized installers.
.Bl -tag -width ".Ev BSDINSTALL_DISTSITE"
.It Ev DISTRIBUTIONS
The set of distributions to install, e.g., "base kernel ports".
-Default: none
+Default: unset
.It Ev BSDINSTALL_DISTDIR
The directory in which the distribution files can be found (or to which they
should be downloaded).
Default:
-.Pa /usr/freebsd-dist
+.Dq Pa /usr/freebsd-dist
.It Ev BSDINSTALL_DISTSITE
URL from which the distribution files should be downloaded if they are not
already present in the directory defined by
@@ -287,11 +287,11 @@ Example:
The directory into which the distribution files should be unpacked and the
directory at which the root file system of the new system should be mounted.
Default:
-.Pa /mnt
+.Dq Pa /mnt
.It Ev BSDINSTALL_LOG
Path to a log file for the installation.
Default:
-.Pa /tmp/bsdinstall_log
+.Dq Pa /tmp/bsdinstall_log
.It Ev BSDINSTALL_TMPETC
Directory where files destined for the new system's
.Pa /etc
@@ -300,7 +300,7 @@ will be stored until the
target is executed.
If this directory does not already exist, it will be created.
Default:
-.Pa /tmp/bsdinstall_etc
+.Dq Pa /tmp/bsdinstall_etc
.It Ev BSDINSTALL_TMPBOOT
Directory where files destined for the new system's
.Pa /boot
@@ -309,7 +309,113 @@ will be stored until the
target is executed.
If this directory does not already exist, it will be created.
Default:
-.Pa /tmp/bsdinstall_boot
+.Dq Pa /tmp/bsdinstall_boot
+.It Ev ZFSBOOT_POOL_NAME
+Name for the pool containing the base system.
+Default:
+.Dq zroot
+.It Ev ZFSBOOT_POOL_CREATE_OPTIONS
+Options to be used when creating the base system's pool.
+Each option must be followed by the -O flag to be taken into consideration
+or the pool will not be created due to errors using the command
+.Cm zpool .
+Default:
+.Dq Li "-O compress=lz4 -O atime=off"
+.It Ev ZFSBOOT_BEROOT_NAME
+Name for the boot environment parent dataset.
+This is a non-mountable dataset meant to be a parent dataset where different
+boot environment are going to be created.
+Default:
+.Dq ROOT
+.It Ev ZFSBOOT_BOOTFS_NAME
+Name for the primary boot environment, which will be the default boot
+environment for the system.
+Default:
+.Dq default
+.It Ev ZFSBOOT_VDEV_TYPE
+The type of pool to be created for the base system.
+This variable can take one of this values: stripe (No redundacy),
+mirror (n-Way mirroring), raid10 (RAID 1+0 - n x 2-Way Mirrors),
+raidz1 (RAID-Z1 - Single Redundacy RAID), raidz2 (RAID-Z2 - Double Redundacy RAID)
+or raidz3 (RAID-Z3 Triple Redundacy RAID).
+Default:
+.Dq stripe
+.It Ev ZFSBOOT_FORCE_4K_SECTORS
+Indicates either the pool will use 4K or 512 sectors.
+If this variable is not empty, 4K sectors will be used.
+Default:
+.Dq 1
+.It Ev ZFSBOOT_GELI_ENCRYPTION
+If this variable is not empty, it will use
+.Xr geli 8
+to encrypt the root pool, enabling automatically the
+.Ev ZFSBOOT_BOOT_POOL
+variable.
+Default:
+.Dq ""
+.It Ev ZFSBOOT_GELI_KEY_FILE
+Path to the
+.Xr geli 8
+keyfile used to encrypt the pool where the base system is stored.
+Default:
+.Dq Pa /boot/encryption.key
+.It Ev ZFSBOOT_BOOT_POOL
+If set a separated boot pool will be created for the kernel of the
+system and
+.Xr loader 8 .
+Default: unset
+.It Ev ZFSBOOT_BOOT_POOL_CREATE_OPTIONS
+Options to use when creating the boot pool, when enabled (See
+.Ev ZFSBOOT_BOOT_POOL ).
+Default: unset
+.It Ev ZFSBOOT_BOOT_POOL_NAME
+Name for the optional boot pool when it is enabled, (See
+.Ev ZFSBOOT_BOOT_POOL ).
+Default:
+.Dq bootpool
+.It Ev ZFSBOOT_BOOT_POOL_SIZE
+Size of the boot pool when it is enabled (See
+.Ev ZFSBOOT_BOOT_POOL ).
+Default:
+.Dq 2g
+.It Ev ZFSBOOT_DISKS
+Disks to be used for the base system, including the boot pool.
+This variable must only be used on a scripted installation.
+See
+.Sx SCRIPTING
+for more information.
+Default: unset
+.It Ev ZFSBOOT_SWAP_SIZE
+Size of the swap partition on each block device.
+This variable will be passed to
+.Xr gpart 8 ;
+which supports SI unit suffixes.
+Default:
+.Dq 2g
+.It Ev ZFSBOOT_SWAP_ENCRYPTION
+If set, enables the encryption of the swap partition using
+.Xr geli 8 .
+Default: ""
+.It Ev ZFSBOOT_SWAP_MIRROR
+If set, enables a swap mirroring using
+.Xr gmirror 8 .
+Default:
+unset
+.It Ev ZFSBOOT_DATASETS
+ZFS datasets to be created on the root zpool, it requires the
+following datasets:
+.Pa /tmp ,
+.Pa /var/tmp ,
+.Pa /$ZFSBOOT_BEROOT_NAME/$ZFSBOOT_BOOTFS_NAME .
+See
+.Sx ZFS DATASETS
+for more information about who to write this variable and to
+take a look into the default value of it.
+.It Ev ZFSBOOT_CONFIRM_LAYOUT
+If set and the installation is interactive, allow the user to confirm
+the layout before continuing with the installation.
+Default:
+.Dq 1
.El
.Sh SCRIPTING
.Nm
@@ -338,6 +444,19 @@ sysrc sshd_enable=YES
pkg install puppet
.Ed
.Pp
+For a ZFS scripted installation, the script looks like this:
+.Bd -literal -offset indent
+DISTRIBUTIONS="kernel.txz base.txz"
+export ZFSBOOT_VDEV_TYPE=stripe
+export ZFSBOOT_DISKS=ada0
+export nonInteractive="YES"
+
+#!/bin/sh
+echo "ifconfig_em0=DHCP" >> /etc/rc.conf
+echo "sshd_enable=YES" >> /etc/rc.conf
+pkg install puppet
+.Ed
+.Pp
On
.Fx
release media, such a script placed at
@@ -374,7 +493,21 @@ instead of
the preamble can contain the variable
.Ev ZFSBOOT_DATASETS
instead of
-.Ev PARTITIONS .
+.Ev PARTITIONS ,
+and setting the variables
+.Ev ZFSBOOT_DISKS
+and
+.Ev ZFSBOOT_VDEV_TYPE
+to create the pool of disks for the base system.
+Usually, for a mirrored booting disk, this two variables looks like this:
+.Bd -literal -offset indent
+ZFSBOOT_DISKS="ada0 ada1"
+ZFSBOOT_VDEV_TYPE=mirror
+.Ed
+.Pp
+Remenber to export all the variables for the
+.Cm zfsboot
+command, otherwise it will not get set.
.Ss SETUP SCRIPT
Following the preamble is an optional shell script, beginning with a #!
declaration.
@@ -385,6 +518,52 @@ configuration files, install packages, etc.
Note that newly configured system services, e.g., networking have not
been started in the installed system at this time and only installation
host services are available.
+.Ss ZFS DATASETS
+The
+.Cm zfsboot
+partitioning takes the
+.Ev ZFSBOOT_DATASETS
+variable to create the datasets on the base system.
+This variable can get pretty huge if the pool contains a lot of datasets.
+The default value of the
+.Ev ZFSBOOT_DATASETS
+looks like this:
+.Bd -literal -offset indent
+# DATASET OPTIONS (comma or space separated; or both)
+
+# Boot Environment [BE] root and default boot dataset
+/$ZFSBOOT_BEROOT_NAME mountpoint=none
+/$ZFSBOOT_BEROOT_NAME/$ZFSBOOT_BOOTFS_NAME mountpoint=/
+
+# Compress /tmp, allow exec but not setuid
+/tmp mountpoint=/tmp,exec=on,setuid=off
+
+# Do not mount /usr so that 'base' files go to the BEROOT
+/usr mountpoint=/usr,canmount=off
+
+# Home directories separated so they are common to all BEs
+/usr/home # NB: /home is a symlink to /usr/home
+
+# Ports tree
+/usr/ports setuid=off
+
+# Source tree (compressed)
+/usr/src
+
+# Create /var and friends
+/var mountpoint=/var,canmount=off
+/var/audit exec=off,setuid=off
+/var/crash exec=off,setuid=off
+/var/log exec=off,setuid=off
+/var/mail atime=on
+/var/tmp setuid=off
+.Ed
+.Pp
+The first column if the dataset to be created on the top of the
+.Ev ZFSBOOT_POOL_NAME
+and the rest of the columns are the options to be set on each dataset.
+The options must be written on a coma or space separated list, or both.
+And everything behind a pound/hash character is ignored as a comment.
.Sh HISTORY
This version of
.Nm
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
index b53202ab18e5..b53202ab18e5 100644
--- a/etc/hosts.lpd
+++ b/usr.sbin/lpr/lpd/hosts.lpd
diff --git a/etc/printcap b/usr.sbin/lpr/lpd/printcap
index b1f83b344c8f..b1f83b344c8f 100644
--- a/etc/printcap
+++ b/usr.sbin/lpr/lpd/printcap
diff --git a/usr.sbin/nscd/nscd.8 b/usr.sbin/nscd/nscd.8
index f54c18582ee3..7858a30af04f 100644
--- a/usr.sbin/nscd/nscd.8
+++ b/usr.sbin/nscd/nscd.8
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 20, 2005
+.Dd October 5, 2018
.Dt NSCD 8
.Os
.Sh NAME
@@ -160,6 +160,3 @@ The default configuration file.
.Xr nsswitch.conf 5
.Sh AUTHORS
.An Michael Bushkov Aq Mt bushman@FreeBSD.org
-.Sh BUGS
-Please send bug reports and suggestions to
-.Aq Mt bushman@FreeBSD.org .
diff --git a/usr.sbin/pmc/Makefile b/usr.sbin/pmc/Makefile
index 2f94d3e274ef..090134711b92 100644
--- a/usr.sbin/pmc/Makefile
+++ b/usr.sbin/pmc/Makefile
@@ -5,6 +5,7 @@
.include <src.opts.mk>
PROG_CXX= pmc
MAN=
+WARNS?= 3
CXXFLAGS+= -O0 -std=c++14
CWARNFLAGS.gcc+= -Wno-redundant-decls
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)