diff --git a/UPDATING b/UPDATING index 122b0600e82..607b16ff6d3 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 @@ -169,6 +184,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: r334930 changed the interface between the NFS modules, so they all need to be rebuilt. r335018 did a __FreeBSD_version bump for this. +20180530: + As of r334391 lld is the default amd64 system linker; it is installed + as /usr/bin/ld. Kernel build workarounds (see 20180510 entry) are no + longer necessary. + 20180530: The kernel / userland interface for devinfo changed, so you'll need a new kernel and userland as a pair for it to work (rebuilding @@ -196,6 +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 8349c780ef8..81e3e9ca31e 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 c4479f1b845..631b17c46f5 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 02131f0d433..24a78a71ed2 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 b48142191f2..1a127bbb265 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 4736531afa1..9941d2f6fdb 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 71967c9d46f..74df5c405b0 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 22e64bf4d6b..3818fa8ac18 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 1a540279242..ac658f15593 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 58d53a94e07..0df0f1d321a 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 20ce551828c..2ff942c84a4 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 7f358a67936..5f3cfacfd99 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 // 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 0f05cab66d7..93d15714091 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(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 2172486682c..226dc193aed 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 a9f3e7d3d2d..df688a76017 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 e6f4eea18b1..93cf7180314 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 a5a851f9540..bc787bc5907 100644 --- a/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp +++ b/contrib/llvm/tools/lld/ELF/SyntheticSections.cpp @@ -1034,6 +1034,8 @@ template void DynamicSection::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 40834a3e952..71daf1d2a6e 100644 --- a/contrib/llvm/tools/lld/ELF/Writer.cpp +++ b/contrib/llvm/tools/lld/ELF/Writer.cpp @@ -487,7 +487,7 @@ template void Writer::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 similarity index 91% rename from contrib/mdocml/INSTALL rename to contrib/mandoc/INSTALL index d80e8e31925..558574b903d 100644 --- a/contrib/mdocml/INSTALL +++ b/contrib/mandoc/INSTALL @@ -1,4 +1,4 @@ -$Id: INSTALL,v 1.20 2017/07/28 14:57:56 schwarze Exp $ +$Id: INSTALL,v 1.22 2018/07/31 15:34:00 schwarze Exp $ About the portable mandoc distribution -------------------------------------- @@ -18,7 +18,7 @@ tech@ mailing list, too. Enjoy using the mandoc toolset! -Ingo Schwarze, Karlsruhe, July 2017 +Ingo Schwarze, Karlsruhe, August 2018 Installation @@ -54,8 +54,6 @@ generates. If anything looks wrong or different from what you wish, read the file "configure.local.example", create and edit a file "configure.local", and re-run "./configure" until the result seems right to you. -On Solaris 10 and earlier, you may have to run "ksh ./configure" -because the native /bin/sh lacks some POSIX features. 5. Run "make". Any POSIX-compatible make, in particular both BSD make and GNU make, @@ -83,12 +81,14 @@ apropos(1) will not find the new pages. 10. To set up a man.cgi(8) server, read its manual page. -Note that some man(7) pages may contain low-level roff(7) markup -that mandoc does not yet understand. On some BSD systems using -mandoc, third-party software is vetted on whether it may be formatted -with mandoc. If not, groff(1) is pulled in as a dependency and -used to install a pre-formatted "catpage" instead of directly as -manual page source. +Note that a very small number of man(7) pages contain low-level +roff(7) markup that mandoc does not yet understand. On some BSD +systems using mandoc, third-party software is vetted on whether it +may be formatted with mandoc. If not, groff(1) is pulled in as a +dependency and used to install pre-formatted "catpages" instead of +manual page sources. This mechanism is used much less frequently +than in the past. On OpenBSD, only 25 out of about 10000 ports +still require formatting with groff(1). Understanding mandoc dependencies diff --git a/contrib/mdocml/LICENSE b/contrib/mandoc/LICENSE similarity index 92% rename from contrib/mdocml/LICENSE rename to contrib/mandoc/LICENSE index aca7ee7a6c7..ec7fc029d82 100644 --- a/contrib/mdocml/LICENSE +++ b/contrib/mandoc/LICENSE @@ -1,17 +1,17 @@ -$Id: LICENSE,v 1.17 2017/06/23 15:58:14 schwarze Exp $ +$Id: LICENSE,v 1.19 2018/07/31 10:18:15 schwarze Exp $ With the exceptions noted below, all code and documentation contained in the mandoc toolkit is protected by the Copyright of the following developers: Copyright (c) 2008-2012, 2014 Kristaps Dzonsons -Copyright (c) 2010-2017 Ingo Schwarze +Copyright (c) 2010-2018 Ingo Schwarze +Copyright (c) 1999, 2004, 2017 Marc Espie Copyright (c) 2009, 2010, 2011, 2012 Joerg Sonnenberger Copyright (c) 2013 Franco Fichtner Copyright (c) 2014 Baptiste Daroussin Copyright (c) 2016 Ed Maste Copyright (c) 2017 Michael Stapelberg -Copyright (c) 1999, 2004 Marc Espie Copyright (c) 1998, 2004, 2010 Todd C. Miller Copyright (c) 2008, 2017 Otto Moerbeek Copyright (c) 2004 Ted Unangst diff --git a/contrib/mdocml/Makefile b/contrib/mandoc/Makefile similarity index 97% rename from contrib/mdocml/Makefile rename to contrib/mandoc/Makefile index 9855c9f8f1e..09738579f0d 100644 --- a/contrib/mdocml/Makefile +++ b/contrib/mandoc/Makefile @@ -1,7 +1,7 @@ -# $Id: Makefile,v 1.516 2017/07/20 16:24:53 schwarze Exp $ +# $Id: Makefile,v 1.519 2018/07/31 15:34:00 schwarze Exp $ # # Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons -# Copyright (c) 2011, 2013-2017 Ingo Schwarze +# Copyright (c) 2011, 2013-2018 Ingo Schwarze # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -VERSION = 1.14.3 +VERSION = 1.14.4 # === LIST OF FILES ==================================================== @@ -30,6 +30,7 @@ TESTSRCS = test-be32toh.c \ test-isblank.c \ test-mkdtemp.c \ test-nanosleep.c \ + test-noop.c \ test-ntohl.c \ test-O_DIRECTORY.c \ test-ohash.c \ @@ -46,6 +47,7 @@ TESTSRCS = test-be32toh.c \ test-stringlist.c \ test-strlcat.c \ test-strlcpy.c \ + test-strndup.c \ test-strptime.c \ test-strsep.c \ test-strtonum.c \ @@ -70,6 +72,7 @@ SRCS = att.c \ compat_stringlist.c \ compat_strlcat.c \ compat_strlcpy.c \ + compat_strndup.c \ compat_strsep.c \ compat_strtonum.c \ compat_vasprintf.c \ @@ -249,6 +252,7 @@ COMPAT_OBJS = compat_err.o \ compat_strcasestr.o \ compat_strlcat.o \ compat_strlcpy.o \ + compat_strndup.o \ compat_strsep.o \ compat_strtonum.o \ compat_vasprintf.o @@ -544,12 +548,12 @@ regress-distcheck: ! -path regress/regress.pl \ ! -path regress/regress.pl.1 -dist: mandoc.sha256 +dist: mandoc-$(VERSION).sha256 -mandoc.sha256: mandoc.tar.gz - sha256 mandoc.tar.gz > $@ +mandoc-$(VERSION).sha256: mandoc-$(VERSION).tar.gz + sha256 mandoc-$(VERSION).tar.gz > $@ -mandoc.tar.gz: $(DISTFILES) +mandoc-$(VERSION).tar.gz: $(DISTFILES) ls regress/*/*/*.mandoc_* && exit 1 || true mkdir -p .dist/mandoc-$(VERSION)/ $(INSTALL) -m 0644 $(DISTFILES) .dist/mandoc-$(VERSION) diff --git a/contrib/mdocml/Makefile.depend b/contrib/mandoc/Makefile.depend similarity index 97% rename from contrib/mdocml/Makefile.depend rename to contrib/mandoc/Makefile.depend index 4f5dc808823..da366a1cd59 100644 --- a/contrib/mdocml/Makefile.depend +++ b/contrib/mandoc/Makefile.depend @@ -16,6 +16,7 @@ compat_strcasestr.o: compat_strcasestr.c config.h compat_stringlist.o: compat_stringlist.c config.h compat_stringlist.h compat_strlcat.o: compat_strlcat.c config.h compat_strlcpy.o: compat_strlcpy.c config.h +compat_strndup.o: compat_strndup.c config.h compat_strsep.o: compat_strsep.c config.h compat_strtonum.o: compat_strtonum.c config.h compat_vasprintf.o: compat_vasprintf.c config.h @@ -29,7 +30,7 @@ demandoc.o: demandoc.c config.h mandoc.h roff.h man.h mdoc.h eqn.o: eqn.c config.h mandoc_aux.h mandoc.h roff.h libmandoc.h libroff.h eqn_html.o: eqn_html.c config.h mandoc.h out.h html.h eqn_term.o: eqn_term.c config.h mandoc.h out.h term.h -html.o: html.c config.h mandoc_aux.h mandoc.h roff.h out.h html.h manconf.h main.h +html.o: html.c config.h mandoc_aux.h mandoc_ohash.h compat_ohash.h mandoc.h roff.h out.h html.h manconf.h main.h lib.o: lib.c config.h mandoc.h roff.h mdoc.h libmdoc.h lib.in main.o: main.c config.h mandoc_aux.h mandoc.h mandoc_xr.h roff.h mdoc.h man.h tag.h main.h manconf.h mansearch.h man.o: man.c config.h mandoc_aux.h mandoc.h roff.h man.h libmandoc.h roff_int.h libman.h diff --git a/contrib/mdocml/NEWS b/contrib/mandoc/NEWS similarity index 92% rename from contrib/mdocml/NEWS rename to contrib/mandoc/NEWS index 3d35e2b7bdc..3bb5b4728b9 100644 --- a/contrib/mdocml/NEWS +++ b/contrib/mandoc/NEWS @@ -1,7 +1,84 @@ -$Id: NEWS,v 1.26 2017/07/28 14:57:56 schwarze Exp $ +$Id: NEWS,v 1.32 2018/08/08 14:47:38 schwarze Exp $ This file lists the most important changes in the mandoc.bsd.lv distribution. +Changes in version 1.14.4, released on August 8, 2018 + + --- MAJOR NEW FEATURES --- + * In ASCII output, render mathematical symbols and greek letters + as transliterations conveying the characters' meanings rather + than trying to imitate their shape. Consequently, such characters + can now be used in portable manual pages. All the same, please + limit their use to contexts where they really matter, for example + when showing complicated mathematical formulae. + * First steps towards better support for small screens in HTML + output (responsive design): avoid most style= attributes, in + particular all hard-coded indentations and column widths, and + provide a better mandoc.css style sheet with a @media query, + using em units throughout, and avoiding redundancy in selectors. + * Better HTML output with some more fitting HTML elements, eliminating + needless class= attributes, and avoiding various HTML syntax errors + (element nesting, URL-fragment syntax, duplicate id= attributes). + --- MINOR NEW FEATURES --- + * When a man(1) argument contains a slash, imply -l like in man-db. + * Use TIOCGWINSZ to reduce the default -Owidth and -Oindent during + interactive use on terminals narrower than 79 columns. + * Generated PostScript files are now more than 50% smaller. + * Terminal rendering of eqn(7) is improved in several respects. + * Simplified and nicer output from the mdoc(7) .Lk macro, formatting + all links in-line, even long ones. + * roff(7) \n+ and \n- numerical register auto-increment and -decrement + * roff(7) .nr optional third argument (auto-increment step size) + * Autodetect in ./configure whether the compiler can use -W and -static, + allowing to build on Solaris 10 and 11 without any configure.local. + --- RELIABILITY BUGFIXES --- + * Only activate UTF-8 output when the user really selected UTF-8, + not some other multibyte character encoding. + * Prevent excessive .ll arguments from generating infinite output. + * Fix out of bounds accesses to parse buffers that could happen when + using renamed or user defined macros after roff(7) conditionals. + * Avoid an assertion failure in certain .Bl -column lists. + * Avoid a NULL pointer access on deroff() failure after '.SS ""'. + * Fix a segfault that could be triggered by two invalid .Dt macros. + * Fix two syntax errors in generated PDF files. + * Properly state the page size in generated PostScript files. + * Close a memory leak caused by missing gzclose(3). + * Fix misformatting of man(7) documents lacking .SH macros + in PostScript and PDF output. + * And many minor bugfixes. + --- THANKS TO --- + * Marc Espie (OpenBSD) for implementing the size reduction of + PostScript files, one additional patch for code simplification, + and two bug reports. + * Theo Buehler (OpenBSD) for a bugfix patch, + and Theo de Raadt (OpenBSD) for checking it. + * John Gardner for more than a dozen suggestions regarding HTML output. + * Mike Williams for teaching me how to use %%DocumentMedia and + setpagedevice in PostScript files. + * Werner Lemberg (groff) for feedback on mdoc(7) language changes. + * Colin Watson (man-db) for feedback on man-db semantics. + * Jason McIntyre (OpenBSD) for lots of feedback and suggestions + on diagnostic messages and on the documentation. + * Thomas Klausner (NetBSD) for suggesting two new style messages + and one new feature, for two bug reports, and for release testing. + * Leah Neukirchen (Void Linux) for suggesting a new style message, + five bug reports, and release testing. + * Anthony Bentley (OpenBSD) for reporting multiple bugs and missing + features. + * Paul Irofti (OpenBSD) and Nate Bargmann for suggesting new features. + * Michael Stapelberg (Debian) for bug reports and release testing. + * Christian Weisgerber, Jonathan Gray, Stuart Henderson, + Ted Unangst (OpenBSD), Takeshi Nakayama (NetBSD), + Anton Lazarov, Jakub Klinkovsky, Jan Stary, Jesper Wallin, + Will Backmam, and Wolfgang Mueller for bug reports. + * Sevan Janiyan (NetBSD) for additions to lib.in. + * George Brown for suggesting code simplifications. + * David Coppa, Igor Sobrado (OpenBSD), and Alexander Kuleshov + for documentation improvements. + * Laura Morales and Raf Czlonka for questions resulting in better + documentation. + * Yuri Pankov (illumos) for release testing. + Changes in version 1.14.3, released on August 5, 2017 --- BUG FIXES --- diff --git a/contrib/mdocml/TODO b/contrib/mandoc/TODO similarity index 87% rename from contrib/mdocml/TODO rename to contrib/mandoc/TODO index 70371a0e9e5..6df63ea3c79 100644 --- a/contrib/mdocml/TODO +++ b/contrib/mandoc/TODO @@ -1,6 +1,6 @@ ************************************************************************ * Official mandoc TODO. -* $Id: TODO,v 1.246 2017/07/24 11:15:12 schwarze Exp $ +* $Id: TODO,v 1.258 2018/08/06 14:16:30 schwarze Exp $ ************************************************************************ Many issues are annotated for difficulty as follows: @@ -38,6 +38,18 @@ are mere guesses, and some may be wrong. --- missing roff features ---------------------------------------------- +- .nop prints its arguments as text, + see groff(7) for an example + +- .ft CB selects constant-width bold font + see groff_out(7) for examples + +- \*(.T prints the device being used, + see groff_char(7) for an example + +- \[charNN], \[charNNN] prints a single-byte codepoint + see groff_char(7) for examples + - .ad (adjust margins) .ad l -- adjust left margin only (flush left) .ad r -- adjust right margin only (flush right) @@ -52,10 +64,6 @@ are mere guesses, and some may be wrong. found by naddy@ in xloadimage(1) loc ** exist *** algo * size * imp * -- .nr third argument (auto-increment step size, requires \n+) - found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700 - loc * exist * algo * size * imp ** - - .ns (no-space mode) occurs in xine-config(1) when implementing this, also let .TH set it reported by brad@ Sat, 15 Jan 2011 15:45:23 -0500 @@ -65,10 +73,6 @@ are mere guesses, and some may be wrong. found by jca@ in ratpoison(1) Sun, 30 Jun 2013 12:01:09 +0200 loc * exist ** algo ** size ** imp ** -- \n+ and \n- numerical register increment and decrement - found by bentley@ in sbcl(1) Mon, 9 Dec 2013 18:36:57 -0700 - loc * exist * algo * size * imp ** - - \w'' improve width measurements would not be very useful without an expression parser, see below needed for Tcl_NewStringObj(3) via wiz@ Wed, 5 Mar 2014 22:27:43 +0100 @@ -87,9 +91,11 @@ are mere guesses, and some may be wrong. Found by naddy@ in devel/cutils cobfusc(1) Mon, 16 Feb 2015 19:10:52 +0100 loc *** exist *** algo *** size ** imp * -- using undefined strings or macros defines them to be empty - wl@ Mon, 14 Nov 2011 14:37:01 +0000 - loc * exist * algo * size * imp * +- check for missing roff escape sequences, implement those that are + trivial even if not usually appearing in manual pages, gracefully + ignore the non-trivial ones, document what they are supposed to do + and what mandoc does instead + loc * exist ** algo * size * imp * --- missing mdoc features ---------------------------------------------- @@ -146,10 +152,6 @@ are mere guesses, and some may be wrong. is not safe, e.g. `.Bl -column .It Pf a b .' gives "ab." but should give "ab ." -- check whether it is correct that `D1' uses INDENT+1; - does it need its own constant? - loc * exist ** algo ** size * imp ** - - prohibit `Nm' from having non-text HEAD children (e.g., NetBSD mDNSShared/dns-sd.1) (mdoc_html.c and mdoc_term.c `Nm' handlers can be slightly simplified) @@ -170,6 +172,25 @@ are mere guesses, and some may be wrong. uqs@ Thu, 2 Jun 2011 11:33:35 +0200 loc * exist ** algo *** size * imp ** +--- missing man features ----------------------------------------------- + +- .SY and .YS, + used by many groff manual pages + +- preserve punctuation following .ME, + see ditroff(7) for an example + +- .TQ tagged paragraph continuation, + see groff_diff(7) for examples + +- groff_www(7) .MTO and .URL + These macros were used by the GNU grep(1) man page. + The groff_www(7) manual page itself uses them, too. + We should probably *not* add them to mandoc. + Just mentioning this here to keep track of the abuse. + Laura Morales 20 Apr 2018 07:33:02 +0200 + loc ** exist * algo * size ** imp * + --- missing tbl features ----------------------------------------------- - the "s" layout column specifier is used for placement of data @@ -177,6 +198,13 @@ are mere guesses, and some may be wrong. synaptics(4) found by tedu@ Mon, 17 Aug 2015 21:17:42 -0400 loc * exist ** algo *** size * imp ** +- vertical centering in cells vertically spanned with ^ + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist *** algo *** size ** imp * + +- support .ds requests inside tbl(7) code, + see tbl(1) for an example + - support mdoc(7) and man(7) macros inside tbl(7) code; probably requires the parser reorg and letting tbl(7) use roff_node such that macro sets can mix; @@ -195,6 +223,18 @@ are mere guesses, and some may be wrong. suggested by bentley@ Tue, 14 Oct 2014 04:10:55 -0600 loc * exist ** algo * size * imp ** +- implement horizontal and vertical alignment in HTML output + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo * size * imp *** + +- implement cell spanning in HTML output + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo ** size ** imp ** + +- implement table borders in HTML output + pali dot rohar at gmail dot com 16 Jul 2018 13:03:35 +0200 + loc * exist * algo ** size ** imp ** + --- missing eqn features ----------------------------------------------- - In a matrix, break the output line after each matrix line. @@ -219,12 +259,15 @@ are mere guesses, and some may be wrong. surrounded by blanks, not when it is part of an unquoted word. Also, check whether there are more such cases (e.g., +?). reported by bentley@ 20 Jun 2017 02:04:29 -0600 + loc * exist ** algo ** size * imp * - Primes, opprime, and ' bentley@ Thu, 13 Jul 2017 23:14:20 -0600 --- missing misc features ---------------------------------------------- +- man -ks 1,8 route; kn@ Jul 13, 2018 orally + - italic correction (\/) in PostScript mode Werner LEMBERG on groff at gnu dot org Sun, 10 Nov 2013 12:47:46 loc ** exist ** algo * size * imp * @@ -298,6 +341,9 @@ are mere guesses, and some may be wrong. * formatting issues: ugly output ************************************************************************ +- .UR can nest inside .TP, + see roff(7) for examples + - revisit empty in-line macros look at the difference between "Em x Em ." and "Sq x Em ." Carsten Kunze Fri, 12 Dec 2014 00:15:41 +0100 @@ -375,6 +421,17 @@ are mere guesses, and some may be wrong. --- HTML issues -------------------------------------------------------- +- wrap Sh and Ss content into
+ Laura Morales 21 Apr 2018 18:10:48 +0200 + (Evaluate whether this is really useful and has no adverse + side effects before implementing; if it is possible, + it does seem cleaner.) + loc ** exist ** algo * size * imp *** + +- format ".IP *" etc. as
    rather than
    + https://github.com/Debian/debiman/issues/67 + loc ** exist ** algo ** size * imp *** + - .Bf at the beginning of a paragraph inserts a bogus 1ex horizontal space, see for example random(3). Introduced in http://mdocml.bsd.lv/cgi-bin/cvsweb/mdoc_html.c.diff?r1=1.91&r2=1.92 @@ -471,6 +528,10 @@ are mere guesses, and some may be wrong. * warning issues ************************************************************************ +- warn about duplicate .Sh/.Ss heads + gre(4): Rename duplicate sections 20 Apr 2018 15:27:33 +0200 + loc * exist * algo * size * imp ** + - style message about macros inside .Bd -literal and .Dl, in particular font changing macros like .Cm, .Ar, .Fa (from the mdoclint TODO) @@ -509,6 +570,10 @@ are mere guesses, and some may be wrong. but just the overall format loc ** exist ** algo *** size ** imp ** +- makewhatis -p complains about language subdirectories: + /usr/local/man//ru: Unknown directory part + + ************************************************************************ * documentation issues ************************************************************************ @@ -562,7 +627,7 @@ are mere guesses, and some may be wrong. - Enable HTTP compression by detecting gzip encoding and filtering output through libz. - - Sandbox (see OpenSSH). + - Privilege separation (see OpenSSH). - Enable caching support via HTTP 304 and If-Modified-Since. - Have Mac OSX systems automatically disable -static compilation of the CGI: -static isn't supported. @@ -571,6 +636,16 @@ are mere guesses, and some may be wrong. * to improve in the groff_mdoc(7) macros ************************************************************************ +- .Cd # arch1, arch2 in section 4 pages: + find better way to indicate multiple architectures, maybe: + allow .Dt vgafb 4 "macppc sparc64" + already shown as "Device Drivers Manual (macppc sparc64)" + for apropos, make that "vgafb(4) - macppc # sparc64" instead of "- all" + groff can be made to show multiple arches, too, but it is + tedious to do the string parsing in roff code... + jmc@ 23 Apr 2018 07:24:52 +0100 [man for vgafb(4)...] + loc ** exist ** algo * size * imp *** + - use uname(1) to set doc-default-operating-system at install time tobimensch Mon, 1 Dec 2014 00:25:07 +0100 diff --git a/contrib/mdocml/apropos.1 b/contrib/mandoc/apropos.1 similarity index 94% rename from contrib/mdocml/apropos.1 rename to contrib/mandoc/apropos.1 index 4a4fa0adbc0..c0895a87e4c 100644 --- a/contrib/mdocml/apropos.1 +++ b/contrib/mandoc/apropos.1 @@ -1,4 +1,4 @@ -.\" $Id: apropos.1,v 1.46 2017/07/04 23:40:01 schwarze Exp $ +.\" $Id: apropos.1,v 1.47 2018/02/23 18:54:02 schwarze Exp $ .\" .\" Copyright (c) 2011, 2012 Kristaps Dzonsons .\" Copyright (c) 2011, 2012, 2014, 2017 Ingo Schwarze @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 8 2018 $ +.Dd $Mdocdate: February 23 2018 $ .Dt APROPOS 1 .Os .Sh NAME @@ -74,7 +74,7 @@ would. If the standard output is a terminal device and .Fl c is not specified, use -.Xr less 1 +.Xr more 1 to paginate them. In .Fl a @@ -328,13 +328,36 @@ Text production: .It Li \&Ox Ta Ox No version reference .It Li \&Dx Ta Dx No version reference .El +.Pp +In general, macro keys are supposed to yield complete results without +expecting the user to consider actual macro usage. +For example, results include: +.Pp +.Bl -tag -width 3n -offset 3n -compact +.It Li \&Fa +function arguments appearing on +.Ic \&Fn +lines +.It Li \&Fn +fuction names marked up with +.Ic \&Fo +macros +.It Li \&In +include file names marked up with +.Ic \&Fd +macros +.It Li \&Vt +types appearing as function return types and +.It \& +types appearing in function arguments in the SYNOPSIS +.El .Sh ENVIRONMENT .Bl -tag -width MANPAGER .It Ev MANPAGER Any non-empty value of the environment variable .Ev MANPAGER is used instead of the standard pagination program, -.Xr less 1 ; +.Xr more 1 ; see .Xr man 1 for details. @@ -357,7 +380,7 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Xr less 1 +.Xr more 1 .Fl s is used. Only used if diff --git a/contrib/mdocml/att.c b/contrib/mandoc/att.c similarity index 100% rename from contrib/mdocml/att.c rename to contrib/mandoc/att.c diff --git a/contrib/mdocml/catman.8 b/contrib/mandoc/catman.8 similarity index 100% rename from contrib/mdocml/catman.8 rename to contrib/mandoc/catman.8 diff --git a/contrib/mdocml/catman.c b/contrib/mandoc/catman.c similarity index 100% rename from contrib/mdocml/catman.c rename to contrib/mandoc/catman.c diff --git a/contrib/mdocml/cgi.c b/contrib/mandoc/cgi.c similarity index 98% rename from contrib/mdocml/cgi.c rename to contrib/mandoc/cgi.c index 746c481ac52..8098352d614 100644 --- a/contrib/mdocml/cgi.c +++ b/contrib/mandoc/cgi.c @@ -1,4 +1,4 @@ -/* $Id: cgi.c,v 1.156 2017/06/24 14:38:32 schwarze Exp $ */ +/* $Id: cgi.c,v 1.158 2018/05/29 20:32:45 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze @@ -356,6 +356,8 @@ resp_begin_html(int code, const char *msg, const char *file) "\n" "\n" " \n" + " \n" " \n" " ", @@ -398,7 +400,7 @@ resp_searchform(const struct req *req, enum focus focus) /* Write query input box. */ - printf(" <input type=\"text\" name=\"query\" value=\""); + printf(" <input type=\"search\" name=\"query\" value=\""); if (req->q.query != NULL) html_print(req->q.query); printf( "\" size=\"40\""); @@ -434,7 +436,7 @@ resp_searchform(const struct req *req, enum focus focus) printf(" selected=\"selected\""); puts(">All Architectures</option>"); for (i = 0; i < arch_MAX; i++) { - printf(" <option value=\"%s\"", arch_names[i]); + printf(" <option"); if (NULL != req->q.arch && 0 == strcmp(arch_names[i], req->q.arch)) printf(" selected=\"selected\""); @@ -447,12 +449,10 @@ resp_searchform(const struct req *req, enum focus focus) if (req->psz > 1) { puts(" <select name=\"manpath\">"); for (i = 0; i < (int)req->psz; i++) { - printf(" <option "); + printf(" <option"); if (strcmp(req->q.manpath, req->p[i]) == 0) - printf("selected=\"selected\" "); - printf("value=\""); - html_print(req->p[i]); - printf("\">"); + printf(" selected=\"selected\""); + printf(">"); html_print(req->p[i]); puts("</option>"); } diff --git a/contrib/mdocml/cgi.h.example b/contrib/mandoc/cgi.h.example similarity index 100% rename from contrib/mdocml/cgi.h.example rename to contrib/mandoc/cgi.h.example diff --git a/contrib/mdocml/chars.c b/contrib/mandoc/chars.c similarity index 79% rename from contrib/mdocml/chars.c rename to contrib/mandoc/chars.c index 039e6dc0909..fb9ded8baef 100644 --- a/contrib/mdocml/chars.c +++ b/contrib/mandoc/chars.c @@ -1,4 +1,4 @@ -/* $Id: chars.c,v 1.71 2017/06/14 20:57:07 schwarze Exp $ */ +/* $Id: chars.c,v 1.73 2017/08/23 13:01:29 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -70,17 +70,17 @@ static struct ln lines[] = { /* Text markers. */ { "ci", "O", 0x25cb }, { "bu", "+\bo", 0x2022 }, - { "dd", "|\b=", 0x2021 }, - { "dg", "|\b-", 0x2020 }, + { "dd", "<**>", 0x2021 }, + { "dg", "<*>", 0x2020 }, { "lz", "<>", 0x25ca }, { "sq", "[]", 0x25a1 }, - { "ps", "<par>", 0x00b6 }, - { "sc", "<sec>", 0x00a7 }, + { "ps", "<paragraph>", 0x00b6 }, + { "sc", "<section>", 0x00a7 }, { "lh", "<=", 0x261c }, { "rh", "=>", 0x261e }, { "at", "@", 0x0040 }, { "sh", "#", 0x0023 }, - { "CR", "_|", 0x21b5 }, + { "CR", "<cr>", 0x21b5 }, { "OK", "\\/", 0x2713 }, { "CL", "<club>", 0x2663 }, { "SP", "<spade>", 0x2660 }, @@ -173,11 +173,11 @@ static struct ln lines[] = { { "OR", "v", 0x2228 }, { "no", "~", 0x00ac }, { "tno", "~", 0x00ac }, - { "te", "3", 0x2203 }, - { "fa", "-\bV", 0x2200 }, - { "st", "-)", 0x220b }, - { "tf", ".:.", 0x2234 }, - { "3d", ".:.", 0x2234 }, + { "te", "<there\037exists>", 0x2203 }, + { "fa", "<for\037all>", 0x2200 }, + { "st", "<such\037that>", 0x220b }, + { "tf", "<therefore>", 0x2234 }, + { "3d", "<therefore>", 0x2234 }, { "or", "|", 0x007c }, /* Mathematicals. */ @@ -193,8 +193,8 @@ static struct ln lines[] = { { "tmu", "x", 0x00d7 }, { "c*", "O\bx", 0x2297 }, { "c+", "O\b+", 0x2295 }, - { "di", "-:-", 0x00f7 }, - { "tdi", "-:-", 0x00f7 }, + { "di", "/", 0x00f7 }, + { "tdi", "/", 0x00f7 }, { "f/", "/", 0x2044 }, { "**", "*", 0x2217 }, { "<=", "<=", 0x2264 }, @@ -210,38 +210,38 @@ static struct ln lines[] = { { "=~", "=~", 0x2245 }, { "~~", "~~", 0x2248 }, { "~=", "~=", 0x2248 }, - { "pt", "oc", 0x221d }, + { "pt", "<proportional\037to>", 0x221d }, { "es", "{}", 0x2205 }, - { "mo", "E", 0x2208 }, - { "nm", "!E", 0x2209 }, - { "sb", "(=", 0x2282 }, - { "nb", "(!=", 0x2284 }, - { "sp", "=)", 0x2283 }, - { "nc", "!=)", 0x2285 }, - { "ib", "(=\b_", 0x2286 }, - { "ip", "=\b_)", 0x2287 }, - { "ca", "(^)", 0x2229 }, - { "cu", "U", 0x222a }, - { "/_", "_\b/", 0x2220 }, - { "pp", "_\b|", 0x22a5 }, - { "is", "'\b,\bI", 0x222b }, - { "integral", "'\b,\bI", 0x222b }, - { "sum", "E", 0x2211 }, - { "product", "TT", 0x220f }, - { "coproduct", "U", 0x2210 }, - { "gr", "V", 0x2207 }, - { "sr", "\\/", 0x221a }, - { "sqrt", "\\/", 0x221a }, + { "mo", "<element\037of>", 0x2208 }, + { "nm", "<not\037element\037of>", 0x2209 }, + { "sb", "<proper\037subset>", 0x2282 }, + { "nb", "<not\037subset>", 0x2284 }, + { "sp", "<proper\037superset>", 0x2283 }, + { "nc", "<not\037superset>", 0x2285 }, + { "ib", "<subset\037or\037equal>", 0x2286 }, + { "ip", "<superset\037or\037equal>", 0x2287 }, + { "ca", "<intersection>", 0x2229 }, + { "cu", "<union>", 0x222a }, + { "/_", "<angle>", 0x2220 }, + { "pp", "<perpendicular>", 0x22a5 }, + { "is", "<integral>", 0x222b }, + { "integral", "<integral>", 0x222b }, + { "sum", "<sum>", 0x2211 }, + { "product", "<product>", 0x220f }, + { "coproduct", "<coproduct>", 0x2210 }, + { "gr", "<nabla>", 0x2207 }, + { "sr", "<sqrt>", 0x221a }, + { "sqrt", "<sqrt>", 0x221a }, { "lc", "|~", 0x2308 }, { "rc", "~|", 0x2309 }, { "lf", "|_", 0x230a }, { "rf", "_|", 0x230b }, - { "if", "oo", 0x221e }, - { "Ah", "N", 0x2135 }, - { "Im", "I", 0x2111 }, - { "Re", "R", 0x211c }, + { "if", "<infinity>", 0x221e }, + { "Ah", "<Aleph>", 0x2135 }, + { "Im", "<Im>", 0x2111 }, + { "Re", "<Re>", 0x211c }, { "wp", "P", 0x2118 }, - { "pd", "a", 0x2202 }, + { "pd", "<del>", 0x2202 }, { "-h", "/h", 0x210f }, { "hbar", "/h", 0x210f }, { "12", "1/2", 0x00bd }, @@ -251,9 +251,9 @@ static struct ln lines[] = { { "38", "3/8", 0x215C }, { "58", "5/8", 0x215D }, { "78", "7/8", 0x215E }, - { "S1", "1", 0x00B9 }, - { "S2", "2", 0x00B2 }, - { "S3", "3", 0x00B3 }, + { "S1", "^1", 0x00B9 }, + { "S2", "^2", 0x00B2 }, + { "S3", "^3", 0x00B3 }, /* Ligatures. */ { "ff", "ff", 0xfb00 }, @@ -346,8 +346,8 @@ static struct ln lines[] = { { "oa", "o\ba", 0x00e5 }, /* Special letters. */ - { "-D", "-\bD", 0x00d0 }, - { "Sd", "d", 0x00f0 }, + { "-D", "Dh", 0x00d0 }, + { "Sd", "dh", 0x00f0 }, { "TP", "Th", 0x00de }, { "Tp", "th", 0x00fe }, { ".i", "i", 0x0131 }, @@ -364,68 +364,68 @@ static struct ln lines[] = { { "Fn", ",\bf", 0x0192 }, /* Units. */ - { "de", "<deg>", 0x00b0 }, - { "%0", "%o", 0x2030 }, + { "de", "<degree>", 0x00b0 }, + { "%0", "<permille>", 0x2030 }, { "fm", "\'", 0x2032 }, { "sd", "''", 0x2033 }, - { "mc", ",\bu", 0x00b5 }, + { "mc", "<micro>", 0x00b5 }, { "Of", "_\ba", 0x00aa }, { "Om", "_\bo", 0x00ba }, /* Greek characters. */ { "*A", "A", 0x0391 }, { "*B", "B", 0x0392 }, - { "*G", "G", 0x0393 }, - { "*D", "_\b/_\b\\", 0x0394 }, + { "*G", "<Gamma>", 0x0393 }, + { "*D", "<Delta>", 0x0394 }, { "*E", "E", 0x0395 }, { "*Z", "Z", 0x0396 }, { "*Y", "H", 0x0397 }, - { "*H", "-\bO", 0x0398 }, + { "*H", "<Theta>", 0x0398 }, { "*I", "I", 0x0399 }, { "*K", "K", 0x039a }, - { "*L", "/\\", 0x039b }, + { "*L", "<Lambda>", 0x039b }, { "*M", "M", 0x039c }, { "*N", "N", 0x039d }, - { "*C", "_\bH", 0x039e }, + { "*C", "<Xi>", 0x039e }, { "*O", "O", 0x039f }, - { "*P", "TT", 0x03a0 }, + { "*P", "<Pi>", 0x03a0 }, { "*R", "P", 0x03a1 }, - { "*S", "S", 0x03a3 }, + { "*S", "<Sigma>", 0x03a3 }, { "*T", "T", 0x03a4 }, { "*U", "Y", 0x03a5 }, - { "*F", "I\bO", 0x03a6 }, + { "*F", "<Phi>", 0x03a6 }, { "*X", "X", 0x03a7 }, - { "*Q", "I\bY", 0x03a8 }, - { "*W", "_\bO", 0x03a9 }, - { "*a", "a", 0x03b1 }, - { "*b", "B", 0x03b2 }, - { "*g", "y", 0x03b3 }, - { "*d", "d", 0x03b4 }, - { "*e", "e", 0x03b5 }, - { "*z", ",\bC", 0x03b6 }, - { "*y", "n", 0x03b7 }, - { "*h", "-\b0", 0x03b8 }, - { "*i", "i", 0x03b9 }, - { "*k", "k", 0x03ba }, - { "*l", ">\b\\", 0x03bb }, - { "*m", ",\bu", 0x03bc }, - { "*n", "v", 0x03bd }, - { "*c", ",\bE", 0x03be }, + { "*Q", "<Psi>", 0x03a8 }, + { "*W", "<Omega>", 0x03a9 }, + { "*a", "<alpha>", 0x03b1 }, + { "*b", "<beta>", 0x03b2 }, + { "*g", "<gamma>", 0x03b3 }, + { "*d", "<delta>", 0x03b4 }, + { "*e", "<epsilon>", 0x03b5 }, + { "*z", "<zeta>", 0x03b6 }, + { "*y", "<eta>", 0x03b7 }, + { "*h", "<theta>", 0x03b8 }, + { "*i", "<iota>", 0x03b9 }, + { "*k", "<kappa>", 0x03ba }, + { "*l", "<lambda>", 0x03bb }, + { "*m", "<mu>", 0x03bc }, + { "*n", "<nu>", 0x03bd }, + { "*c", "<xi>", 0x03be }, { "*o", "o", 0x03bf }, - { "*p", "-\bn", 0x03c0 }, - { "*r", "p", 0x03c1 }, - { "*s", "-\bo", 0x03c3 }, - { "*t", "~\bt", 0x03c4 }, - { "*u", "u", 0x03c5 }, - { "*f", "|\bo", 0x03d5 }, - { "*x", "x", 0x03c7 }, - { "*q", "|\bu", 0x03c8 }, - { "*w", "w", 0x03c9 }, - { "+h", "-\b0", 0x03d1 }, - { "+f", "|\bo", 0x03c6 }, - { "+p", "-\bw", 0x03d6 }, - { "+e", "e", 0x03f5 }, - { "ts", "s", 0x03c2 }, + { "*p", "<pi>", 0x03c0 }, + { "*r", "<rho>", 0x03c1 }, + { "*s", "<sigma>", 0x03c3 }, + { "*t", "<tau>", 0x03c4 }, + { "*u", "<upsilon>", 0x03c5 }, + { "*f", "<phi>", 0x03d5 }, + { "*x", "<chi>", 0x03c7 }, + { "*q", "<psi>", 0x03c8 }, + { "*w", "<omega>", 0x03c9 }, + { "+h", "<theta>", 0x03d1 }, + { "+f", "<phi>", 0x03c6 }, + { "+p", "<pi>", 0x03d6 }, + { "+e", "<epsilon>", 0x03f5 }, + { "ts", "<sigma>", 0x03c2 }, }; static struct ohash mchars; diff --git a/contrib/mdocml/compat_err.c b/contrib/mandoc/compat_err.c similarity index 100% rename from contrib/mdocml/compat_err.c rename to contrib/mandoc/compat_err.c diff --git a/contrib/mdocml/compat_fts.c b/contrib/mandoc/compat_fts.c similarity index 100% rename from contrib/mdocml/compat_fts.c rename to contrib/mandoc/compat_fts.c diff --git a/contrib/mdocml/compat_fts.h b/contrib/mandoc/compat_fts.h similarity index 100% rename from contrib/mdocml/compat_fts.h rename to contrib/mandoc/compat_fts.h diff --git a/contrib/mdocml/compat_getline.c b/contrib/mandoc/compat_getline.c similarity index 100% rename from contrib/mdocml/compat_getline.c rename to contrib/mandoc/compat_getline.c diff --git a/contrib/mdocml/compat_getsubopt.c b/contrib/mandoc/compat_getsubopt.c similarity index 100% rename from contrib/mdocml/compat_getsubopt.c rename to contrib/mandoc/compat_getsubopt.c diff --git a/contrib/mdocml/compat_isblank.c b/contrib/mandoc/compat_isblank.c similarity index 100% rename from contrib/mdocml/compat_isblank.c rename to contrib/mandoc/compat_isblank.c diff --git a/contrib/mdocml/compat_mkdtemp.c b/contrib/mandoc/compat_mkdtemp.c similarity index 100% rename from contrib/mdocml/compat_mkdtemp.c rename to contrib/mandoc/compat_mkdtemp.c diff --git a/contrib/mdocml/compat_ohash.c b/contrib/mandoc/compat_ohash.c similarity index 100% rename from contrib/mdocml/compat_ohash.c rename to contrib/mandoc/compat_ohash.c diff --git a/contrib/mdocml/compat_ohash.h b/contrib/mandoc/compat_ohash.h similarity index 100% rename from contrib/mdocml/compat_ohash.h rename to contrib/mandoc/compat_ohash.h diff --git a/contrib/mdocml/compat_progname.c b/contrib/mandoc/compat_progname.c similarity index 100% rename from contrib/mdocml/compat_progname.c rename to contrib/mandoc/compat_progname.c diff --git a/contrib/mdocml/compat_reallocarray.c b/contrib/mandoc/compat_reallocarray.c similarity index 100% rename from contrib/mdocml/compat_reallocarray.c rename to contrib/mandoc/compat_reallocarray.c diff --git a/contrib/mdocml/compat_recallocarray.c b/contrib/mandoc/compat_recallocarray.c similarity index 100% rename from contrib/mdocml/compat_recallocarray.c rename to contrib/mandoc/compat_recallocarray.c diff --git a/contrib/mdocml/compat_strcasestr.c b/contrib/mandoc/compat_strcasestr.c similarity index 100% rename from contrib/mdocml/compat_strcasestr.c rename to contrib/mandoc/compat_strcasestr.c diff --git a/contrib/mdocml/compat_stringlist.c b/contrib/mandoc/compat_stringlist.c similarity index 100% rename from contrib/mdocml/compat_stringlist.c rename to contrib/mandoc/compat_stringlist.c diff --git a/contrib/mdocml/compat_stringlist.h b/contrib/mandoc/compat_stringlist.h similarity index 100% rename from contrib/mdocml/compat_stringlist.h rename to contrib/mandoc/compat_stringlist.h diff --git a/contrib/mdocml/compat_strlcat.c b/contrib/mandoc/compat_strlcat.c similarity index 100% rename from contrib/mdocml/compat_strlcat.c rename to contrib/mandoc/compat_strlcat.c diff --git a/contrib/mdocml/compat_strlcpy.c b/contrib/mandoc/compat_strlcpy.c similarity index 100% rename from contrib/mdocml/compat_strlcpy.c rename to contrib/mandoc/compat_strlcpy.c diff --git a/contrib/mandoc/compat_strndup.c b/contrib/mandoc/compat_strndup.c new file mode 100644 index 00000000000..5e127364f5c --- /dev/null +++ b/contrib/mandoc/compat_strndup.c @@ -0,0 +1,50 @@ +#include "config.h" + +#if HAVE_STRNDUP + +int dummy; + +#else + +/* $Id: compat_strndup.c,v 1.1 2018/02/27 11:16:23 schwarze Exp $ */ +/* OpenBSD: strndup.c,v 1.2 2015/08/31 02:53:57 guenther Exp */ +/* + * Copyright (c) 2010 Todd C. Miller <Todd.Miller@courtesan.com> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> + +#include <stdlib.h> +#include <string.h> + +char * +strndup(const char *str, size_t maxlen) +{ + char *copy; + size_t len; + + for (len = 0; len < maxlen && str[len] != '\0'; len++) + continue; + + copy = malloc(len + 1); + if (copy != NULL) { + (void)memcpy(copy, str, len); + copy[len] = '\0'; + } + + return copy; +} + +#endif diff --git a/contrib/mdocml/compat_strsep.c b/contrib/mandoc/compat_strsep.c similarity index 100% rename from contrib/mdocml/compat_strsep.c rename to contrib/mandoc/compat_strsep.c diff --git a/contrib/mdocml/compat_strtonum.c b/contrib/mandoc/compat_strtonum.c similarity index 100% rename from contrib/mdocml/compat_strtonum.c rename to contrib/mandoc/compat_strtonum.c diff --git a/contrib/mdocml/compat_vasprintf.c b/contrib/mandoc/compat_vasprintf.c similarity index 100% rename from contrib/mdocml/compat_vasprintf.c rename to contrib/mandoc/compat_vasprintf.c diff --git a/contrib/mdocml/config.h b/contrib/mandoc/config.h similarity index 96% rename from contrib/mdocml/config.h rename to contrib/mandoc/config.h index 57d3f313781..4525870756b 100644 --- a/contrib/mdocml/config.h +++ b/contrib/mandoc/config.h @@ -38,6 +38,7 @@ #define HAVE_STRINGLIST 1 #define HAVE_STRLCAT 1 #define HAVE_STRLCPY 1 +#define HAVE_STRNDUP 1 #define HAVE_STRPTIME 1 #define HAVE_STRSEP 1 #define HAVE_STRTONUM 1 @@ -47,6 +48,7 @@ #define HAVE_OHASH 1 #define BINM_APROPOS "apropos" +#define BINM_CATMAN "catman" #define BINM_MAKEWHATIS "makewhatis" #define BINM_MAN "man" #define BINM_SOELIM "soelim" diff --git a/contrib/mdocml/configure b/contrib/mandoc/configure similarity index 81% rename from contrib/mdocml/configure rename to contrib/mandoc/configure index f9416ce7399..1ccc37dc0cd 100755 --- a/contrib/mdocml/configure +++ b/contrib/mandoc/configure @@ -1,8 +1,8 @@ #!/bin/sh # -# $Id: configure,v 1.64 2017/07/01 09:47:30 schwarze Exp $ +# $Id: configure,v 1.66 2018/07/31 15:34:00 schwarze Exp $ # -# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -27,7 +27,7 @@ set -e # 3: config.log exec 3> config.log -echo "config.log: writing..." +echo "file config.log: writing..." # --- default settings ------------------------------------------------- # Initialize all variables here, @@ -41,14 +41,13 @@ OSNAME= UTF8_LOCALE= CC=`printf "all:\\n\\t@echo \\\$(CC)\\n" | env -i make -sf -` -CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wwrite-strings" -CFLAGS="${CFLAGS} -Wno-unused-parameter" +CFLAGS= LDADD= LDFLAGS= LD_NANOSLEEP= LD_OHASH= LD_RECVMSG= -STATIC="-static" +STATIC= BUILD_CGI=0 BUILD_CATMAN=0 @@ -83,6 +82,7 @@ HAVE_STRCASESTR= HAVE_STRINGLIST= HAVE_STRLCAT= HAVE_STRLCPY= +HAVE_STRNDUP= HAVE_STRPTIME= HAVE_STRSEP= HAVE_STRTONUM= @@ -126,27 +126,25 @@ LN="ln -f" # --- manual settings from configure.local ----------------------------- if [ -r ./configure.local ]; then - echo "configure.local: reading..." 1>&2 - echo "configure.local: reading..." 1>&3 + echo "file configure.local: reading..." 1>&2 + echo "file configure.local: reading..." 1>&3 cat ./configure.local 1>&3 . ./configure.local else - echo "configure.local: no (fully automatic configuration)" 1>&2 - echo "configure.local: no (fully automatic configuration)" 1>&3 + echo "file configure.local: no (fully automatic configuration)" 1>&2 + echo "file configure.local: no (fully automatic configuration)" 1>&3 fi echo 1>&3 -# --- tests for config.h ---------------------------------------------- - -COMP="${CC} ${CFLAGS} -Wno-unused -Werror" +# --- tests functions -------------------------------------------------- # Check whether this HAVE_ setting is manually overridden. # If yes, use the override, if no, do not decide anything yet. -# Arguments: lower-case test name, manual value +# Arguments: test file name, test var name, manual value ismanual() { [ -z "${3}" ] && return 1 - echo "${1}: manual (HAVE_${2}=${3})" 1>&2 - echo "${1}: manual (HAVE_${2}=${3})" 1>&3 + echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&2 + echo "tested ${1}: HAVE_${2}=${3} (manual)" 1>&3 echo 1>&3 return 0 } @@ -154,31 +152,33 @@ ismanual() { # Run a single autoconfiguration test. # In case of success, enable the feature. # In case of failure, do not decide anything yet. -# Arguments: lower-case test name, upper-case test name, additional CFLAGS +# Arguments: test file name, test var name, additional CFLAGS singletest() { cat 1>&3 << __HEREDOC__ -${1}${3}: testing... +testing ${1}${3} ... ${COMP} -o test-${1} test-${1}.c ${3} __HEREDOC__ if ${COMP} -o "test-${1}" "${SOURCEDIR}/test-${1}.c" ${3} 1>&3 2>&3 then - echo "${1}${3}: ${CC} succeeded" 1>&3 + echo "partial result of ${1}${3}: ${CC} succeeded" 1>&3 else - echo "${1}${3}: ${CC} failed with $?" 1>&3 + echo "result of ${1}${3}: ${CC} failed with exit status $?" 1>&3 + echo "result of compiling ${1}${3}: no" 1>&3 echo 1>&3 return 1 fi if ./test-${1} 1>&3 2>&3; then - echo "${1}${3}: yes" 1>&2 - echo "${1}${3}: yes" 1>&3 + echo "tested ${1}${3}: yes" 1>&2 + echo "result of running ${1}${3}: yes" 1>&3 echo 1>&3 eval HAVE_${2}=1 rm "test-${1}" return 0 else - echo "${1}${3}: execution failed with $?" 1>&3 + echo "result of ${1}${3}: execution failed with exit status $?" 1>&3 + echo "result of running ${1}${3}: no" 1>&3 echo 1>&3 rm "test-${1}" return 1 @@ -187,12 +187,12 @@ __HEREDOC__ # Run a complete autoconfiguration test, including the check for # a manual override and disabling the feature on failure. -# Arguments: lower case name, upper case name, additional CFLAGS +# Arguments: test file name, test var name, additional CFLAGS runtest() { eval _manual=\${HAVE_${2}} ismanual "${1}" "${2}" "${_manual}" && return 0 singletest "${1}" "${2}" "${3}" && return 0 - echo "${1}${3}: no" 1>&2 + echo "tested ${1}${3}: no" 1>&2 eval HAVE_${2}=0 return 1 } @@ -201,18 +201,54 @@ runtest() { get_locale() { [ -n "${HAVE_WCHAR}" ] && [ "${HAVE_WCHAR}" -eq 0 ] && return 0 ismanual UTF8_LOCALE UTF8_LOCALE "$UTF8_LOCALE" && return 0 - echo "UTF8_LOCALE: testing..." 1>&3 + echo "testing UTF8_LOCALE ..." 1>&3 UTF8_LOCALE=`locale -a | grep -i '^en_US\.UTF-*8$' | head -n 1` if [ -z "${UTF8_LOCALE}" ]; then UTF8_LOCALE=`locale -a | grep -i '\.UTF-*8' | head -n 1` [ -n "${UTF8_LOCALE}" ] || return 1 fi - echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&2 - echo "UTF8_LOCALE=${UTF8_LOCALE}" 1>&3 + echo "selected UTF8_LOCALE=${UTF8_LOCALE}" 1>&2 + echo "selected UTF8_LOCALE=${UTF8_LOCALE}" 1>&3 echo 1>&3 return 0; } +# --- compiler options ------------------------------------------------- + +if [ -n "${CFLAGS}" ]; then + COMP="${CC} ${CFLAGS}" + echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&2 + echo "selected CFLAGS=\"${CFLAGS}\" (manual)" 1>&3 + echo 1>&3 +else + CFLAGS="-g -W -Wall -Wmissing-prototypes -Wstrict-prototypes" + CFLAGS="${CFLAGS} -Wwrite-strings -Wno-unused-parameter" + COMP="${CC} ${CFLAGS} -Wno-unused -Werror" + echo -n "tested ${CC} -W: " 1>&2 + echo -n "testing ${CC} -W: " 1>&3 + runtest noop WFLAG || true + if [ "${HAVE_WFLAG}" -eq 0 ]; then + CFLAGS="-g" + COMP="${CC} ${CFLAGS}" + fi + echo "selected CFLAGS=\"${CFLAGS}\"" 1>&2 + echo "selected CFLAGS=\"${CFLAGS}\"" 1>&3 + echo 1>&3 +fi + +if [ -n "${STATIC}" ]; then + echo "selected STATIC=\"${STATIC}\" (manual)" 1>&2 + echo "selected STATIC=\"${STATIC}\" (manual)" 1>&3 + echo 1>&3 +else + runtest noop STATIC -static || true + [ ${HAVE_STATIC} -eq 0 ] || STATIC="-static" + echo "selected STATIC=\"${STATIC}\"" 1>&2 + echo "selected STATIC=\"${STATIC}\"" 1>&3 + echo 1>&3 +fi + +# --- tests for config.h ---------------------------------------------- # --- library functions --- runtest dirent-namlen DIRENT_NAMLEN || true @@ -238,6 +274,7 @@ runtest strcasestr STRCASESTR || true runtest stringlist STRINGLIST || true runtest strlcat STRLCAT || true runtest strlcpy STRLCPY || true +runtest strndup STRNDUP || true runtest strptime STRPTIME || true runtest strsep STRSEP || true runtest strtonum STRTONUM || true @@ -264,8 +301,9 @@ if get_locale; then runtest wchar WCHAR -DUTF8_LOCALE=\"${UTF8_LOCALE}\" || true else HAVE_WCHAR=0 - echo "wchar: no (no UTF8_LOCALE)" 1>&2 - echo "wchar: no (no UTF8_LOCALE)" 1>&3 + echo "tested wchar: no (no UTF8_LOCALE)" 1>&2 + echo "tested wchar: no (no UTF8_LOCALE)" 1>&3 + echo 1>&3 fi # --- nanosleep --- @@ -328,8 +366,8 @@ fi # --- LDADD --- LDADD="${LDADD} ${LD_NANOSLEEP} ${LD_RECVMSG} ${LD_OHASH} -lz" -echo "LDADD=\"${LDADD}\"" 1>&2 -echo "LDADD=\"${LDADD}\"" 1>&3 +echo "selected LDADD=\"${LDADD}\"" 1>&2 +echo "selected LDADD=\"${LDADD}\"" 1>&3 echo 1>&3 # --- write config.h --- @@ -353,7 +391,8 @@ __HEREDOC__ [ ${HAVE_GETLINE} -eq 0 -o \ ${HAVE_REALLOCARRAY} -eq 0 -o ${HAVE_RECALLOCARRAY} -eq 0 -o \ - ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 ] \ + ${HAVE_STRLCAT} -eq 0 -o ${HAVE_STRLCPY} -eq 0 -o \ + ${HAVE_STRNDUP} -eq 0 ] \ && echo "#include <sys/types.h>" [ ${HAVE_VASPRINTF} -eq 0 ] && echo "#include <stdarg.h>" [ ${HAVE_GETLINE} -eq 0 ] && echo "#include <stdio.h>" @@ -396,6 +435,7 @@ cat << __HEREDOC__ #define HAVE_STRINGLIST ${HAVE_STRINGLIST} #define HAVE_STRLCAT ${HAVE_STRLCAT} #define HAVE_STRLCPY ${HAVE_STRLCPY} +#define HAVE_STRNDUP ${HAVE_STRNDUP} #define HAVE_STRPTIME ${HAVE_STRPTIME} #define HAVE_STRSEP ${HAVE_STRSEP} #define HAVE_STRTONUM ${HAVE_STRTONUM} @@ -452,6 +492,9 @@ fi [ ${HAVE_STRLCPY} -eq 0 ] && \ echo "extern size_t strlcpy(char *, const char *, size_t);" +[ ${HAVE_STRNDUP} -eq 0 ] && \ + echo "extern char *strndup(const char *, size_t);" + [ ${HAVE_STRSEP} -eq 0 ] && \ echo "extern char *strsep(char **, const char *);" @@ -461,8 +504,8 @@ fi [ ${HAVE_VASPRINTF} -eq 0 ] && \ echo "extern int vasprintf(char **, const char *, va_list);" -echo "config.h: written" 1>&2 -echo "config.h: written" 1>&3 +echo "file config.h: written" 1>&2 +echo "file config.h: written" 1>&3 # --- tests for Makefile.local ----------------------------------------- @@ -531,7 +574,7 @@ INSTALL_DATA = ${INSTALL_DATA} LN = ${LN} __HEREDOC__ -echo "Makefile.local: written" 1>&2 -echo "Makefile.local: written" 1>&3 +echo "file Makefile.local: written" 1>&2 +echo "file Makefile.local: written" 1>&3 exit 0 diff --git a/contrib/mdocml/configure.local.example b/contrib/mandoc/configure.local.example similarity index 91% rename from contrib/mdocml/configure.local.example rename to contrib/mandoc/configure.local.example index 4a583ad0bab..82fc2a2c28e 100644 --- a/contrib/mdocml/configure.local.example +++ b/contrib/mandoc/configure.local.example @@ -1,6 +1,6 @@ -# $Id: configure.local.example,v 1.33 2017/07/20 16:24:53 schwarze Exp $ +# $Id: configure.local.example,v 1.34 2018/07/31 15:34:00 schwarze Exp $ # -# Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -77,7 +77,7 @@ MANPATH_BASE="/usr/share/man:/usr/X11R6/man" # If you do not want uname(3) to be called but instead want a fixed # string to be used, use the following line: -OSNAME="OpenBSD 6.0" +OSNAME="OpenBSD 6.3" # The following installation directories are used. # It is possible to set only one or a few of these variables, @@ -100,6 +100,7 @@ BIN_FROM_SBIN="../bin" # Some distributions may want to avoid naming conflicts # with the configuration files of other man(1) implementations. # This changes the name of the installed section 5 manual page as well. + MANM_MANCONF="mandoc.conf" # default is "man.conf" # Some distributions may want to avoid naming conflicts among manuals. @@ -148,13 +149,6 @@ LN="ln -sf" # default is "ln -f" LD_OHASH="-lutil" -# When library autodetection decides to use -L/usr/local/lib, -# -I/usr/local/include is automatically added to CFLAGS. -# If you manually set LD_OHASH to something including -L/usr/local/lib, -# chances are you will also need the following line: - -CFLAGS="${CFLAGS} -I/usr/local/include" - # Some platforms may need an additional linker flag for nanosleep(2). # If none is needed or it is -lrt, it is autodetected. # Otherwise, set the following variable. @@ -222,16 +216,22 @@ BUILD_CGI=1 # The remaining settings in this section are only relevant if BUILD_CGI # is enabled. Otherwise, they have no effect either way. -# By default, man.cgi(8) is linked statically. -# Some systems do not support static linking, for example Mac OS X. -# In that case, use the following line: +# By default, man.cgi(8) is linked statically if the compiler supports +# the -static option. If automatic detection fails, you can force +# static linking of man.cgi(8). -STATIC= +STATIC="-static" -# Some systems, for example Linux, require -pthread for static linking: +# Some systems may require -pthread for static linking: STATIC="-static -pthread" +# If static linking works in general but not with additional libraries +# like -lrt or -lz, you can force dynamic linking. This may for +# example be required on SunOS 5.9. + +STATIC=" " + # Some directories. # This works just like PREFIX, see above. @@ -263,15 +263,19 @@ BINM_CATMAN=mcatman # default is "catman" CC=cc +# Because the system compiler may not provide <stdint.h>, +# SunOS 5.9 may need: + +CC=gcc + # IBM AIX may need: CC=xlc -# The default compiler flags are: - -CFLAGS="-g -W -Wall -Wstrict-prototypes -Wno-unused-parameter -Wwrite-strings" - -# IBM AIX xlc does not support -W; in that case, please use: +# Normally, leave CFLAGS unset. In that case, -g will automatically +# be used, and various -W options will be added if the compiler +# supports them. If you define CFLAGS manually, it will be used +# unchanged, and nothing will be added. CFLAGS="-g" diff --git a/contrib/mdocml/dba.c b/contrib/mandoc/dba.c similarity index 100% rename from contrib/mdocml/dba.c rename to contrib/mandoc/dba.c diff --git a/contrib/mdocml/dba.h b/contrib/mandoc/dba.h similarity index 100% rename from contrib/mdocml/dba.h rename to contrib/mandoc/dba.h diff --git a/contrib/mdocml/dba_array.c b/contrib/mandoc/dba_array.c similarity index 100% rename from contrib/mdocml/dba_array.c rename to contrib/mandoc/dba_array.c diff --git a/contrib/mdocml/dba_array.h b/contrib/mandoc/dba_array.h similarity index 100% rename from contrib/mdocml/dba_array.h rename to contrib/mandoc/dba_array.h diff --git a/contrib/mdocml/dba_read.c b/contrib/mandoc/dba_read.c similarity index 100% rename from contrib/mdocml/dba_read.c rename to contrib/mandoc/dba_read.c diff --git a/contrib/mdocml/dba_write.c b/contrib/mandoc/dba_write.c similarity index 100% rename from contrib/mdocml/dba_write.c rename to contrib/mandoc/dba_write.c diff --git a/contrib/mdocml/dba_write.h b/contrib/mandoc/dba_write.h similarity index 100% rename from contrib/mdocml/dba_write.h rename to contrib/mandoc/dba_write.h diff --git a/contrib/mdocml/dbm.c b/contrib/mandoc/dbm.c similarity index 100% rename from contrib/mdocml/dbm.c rename to contrib/mandoc/dbm.c diff --git a/contrib/mdocml/dbm.h b/contrib/mandoc/dbm.h similarity index 100% rename from contrib/mdocml/dbm.h rename to contrib/mandoc/dbm.h diff --git a/contrib/mdocml/dbm_map.c b/contrib/mandoc/dbm_map.c similarity index 100% rename from contrib/mdocml/dbm_map.c rename to contrib/mandoc/dbm_map.c diff --git a/contrib/mdocml/dbm_map.h b/contrib/mandoc/dbm_map.h similarity index 100% rename from contrib/mdocml/dbm_map.h rename to contrib/mandoc/dbm_map.h diff --git a/contrib/mdocml/demandoc.1 b/contrib/mandoc/demandoc.1 similarity index 100% rename from contrib/mdocml/demandoc.1 rename to contrib/mandoc/demandoc.1 diff --git a/contrib/mdocml/demandoc.c b/contrib/mandoc/demandoc.c similarity index 100% rename from contrib/mdocml/demandoc.c rename to contrib/mandoc/demandoc.c diff --git a/contrib/mdocml/eqn.7 b/contrib/mandoc/eqn.7 similarity index 99% rename from contrib/mdocml/eqn.7 rename to contrib/mandoc/eqn.7 index 33d509bd13e..244903c56fe 100644 --- a/contrib/mdocml/eqn.7 +++ b/contrib/mandoc/eqn.7 @@ -1,4 +1,4 @@ -.\" $Id: eqn.7,v 1.36 2017/07/20 11:07:27 schwarze Exp $ +.\" $Id: eqn.7,v 1.37 2017/09/04 10:35:27 schwarze Exp $ .\" .\" Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 20 2017 $ +.Dd $Mdocdate: September 4 2017 $ .Dt EQN 7 .Os .Sh NAME @@ -83,7 +83,7 @@ box : text | \(dqsqrt\(dq box | box pos box | box mark - | \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq ]* + | \(dqmatrix\(dq \(dq{\(dq [col \(dq{\(dq list \(dq}\(dq]* \(dq}\(dq | pile \(dq{\(dq list \(dq}\(dq | font box | \(dqsize\(dq text box diff --git a/contrib/mdocml/eqn.c b/contrib/mandoc/eqn.c similarity index 100% rename from contrib/mdocml/eqn.c rename to contrib/mandoc/eqn.c diff --git a/contrib/mdocml/eqn_html.c b/contrib/mandoc/eqn_html.c similarity index 100% rename from contrib/mdocml/eqn_html.c rename to contrib/mandoc/eqn_html.c diff --git a/contrib/mdocml/eqn_term.c b/contrib/mandoc/eqn_term.c similarity index 82% rename from contrib/mdocml/eqn_term.c rename to contrib/mandoc/eqn_term.c index 08f4a993eca..669c3c56cff 100644 --- a/contrib/mdocml/eqn_term.c +++ b/contrib/mandoc/eqn_term.c @@ -1,4 +1,4 @@ -/* $Id: eqn_term.c,v 1.13 2017/07/08 14:51:04 schwarze Exp $ */ +/* $Id: eqn_term.c,v 1.17 2017/08/23 21:56:20 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -20,6 +20,7 @@ #include <sys/types.h> #include <assert.h> +#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -51,6 +52,7 @@ static void eqn_box(struct termp *p, const struct eqn_box *bp) { const struct eqn_box *child; + const char *cp; int delim; /* Delimiters around this box? */ @@ -67,7 +69,16 @@ eqn_box(struct termp *p, const struct eqn_box *bp) ((bp->parent->type == EQN_LIST && bp->expectargs == 1) || (bp->parent->type == EQN_SUBEXPR && bp->pos != EQNPOS_SQRT)))))) { - if (bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) + if ((bp->parent->type == EQN_SUBEXPR && bp->prev != NULL) || + (bp->type == EQN_LIST && + bp->first != NULL && + bp->first->type != EQN_PILE && + bp->first->type != EQN_MATRIX && + bp->prev != NULL && + (bp->prev->type == EQN_LIST || + (bp->prev->type == EQN_TEXT && + (*bp->prev->text == '\\' || + isalpha((unsigned char)*bp->prev->text)))))) p->flags |= TERMP_NOSPACE; term_word(p, bp->left != NULL ? bp->left : "("); p->flags |= TERMP_NOSPACE; @@ -80,8 +91,17 @@ eqn_box(struct termp *p, const struct eqn_box *bp) if (bp->font != EQNFONT_NONE) term_fontpush(p, fontmap[(int)bp->font]); - if (bp->text != NULL) + if (bp->text != NULL) { + if (strchr("!\"'),.:;?]}", *bp->text) != NULL) + p->flags |= TERMP_NOSPACE; term_word(p, bp->text); + if ((cp = strchr(bp->text, '\0')) > bp->text && + (strchr("\"'([{", cp[-1]) != NULL || + (bp->prev == NULL && (cp[-1] == '-' || + (cp >= bp->text + 5 && + strcmp(cp - 5, "\\[mi]") == 0))))) + p->flags |= TERMP_NOSPACE; + } /* Special box types. */ @@ -98,9 +118,9 @@ eqn_box(struct termp *p, const struct eqn_box *bp) term_word(p, bp->pos == EQNPOS_OVER ? "/" : (bp->pos == EQNPOS_SUP || bp->pos == EQNPOS_TO) ? "^" : "_"); - p->flags |= TERMP_NOSPACE; child = child->next; if (child != NULL) { + p->flags |= TERMP_NOSPACE; eqn_box(p, child); if (bp->pos == EQNPOS_FROMTO || bp->pos == EQNPOS_SUBSUP) { diff --git a/contrib/mdocml/gmdiff b/contrib/mandoc/gmdiff similarity index 74% rename from contrib/mdocml/gmdiff rename to contrib/mandoc/gmdiff index d5b1f2a76f0..65cf353daa0 100644 --- a/contrib/mdocml/gmdiff +++ b/contrib/mandoc/gmdiff @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org> +# Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above @@ -19,7 +19,7 @@ if [ `id -u` -eq 0 ]; then fi if [ $# -eq 0 ]; then - echo "usage: $0 [-h] manual_source_file ..." + echo "usage: $0 [-h|-u] manual_source_file ..." exit 1 fi @@ -28,22 +28,25 @@ if [ "X$1" = "X-h" ]; then export PATH="/usr/local/heirloom-doctools/bin:$PATH" EQN="neqn" ROFF="nroff" - MOPT="-Omdoc $MOPT" + MOPT="-Ios=BSD -Tascii $MOPT" + COLPIPE="col -b" elif [ "X$1" = "X-u" ]; then shift ROFF="groff -ket -ww -Tutf8 -P -c" - MOPT="-Werror -Tutf8 $MOPT" + MOPT="-Ios=OpenBSD -Wall -Tutf8 $MOPT" + COLPIPE="cat" else - ROFF="groff -et -ww -Tascii -P -c" - MOPT="-Werror -Tascii $MOPT" + ROFF="groff -et -ww -mtty-char -Tascii -P -c" + MOPT="-Ios=OpenBSD -Wall -Tascii $MOPT" + COLPIPE="cat" fi while [ -n "$1" ]; do file=$1 shift echo " ========== $file ========== " - $ROFF -mandoc $file 2> /tmp/roff.err > /tmp/roff.out - ${MANDOC:=mandoc} -Ios=OpenBSD $MOPT $file \ + $ROFF -mandoc $file | $COLPIPE 2> /tmp/roff.err > /tmp/roff.out + ${MANDOC:=mandoc} $MOPT $file | $COLPIPE \ 2> /tmp/mandoc.err > /tmp/mandoc.out for i in roff mandoc; do [ -s /tmp/$i.err ] && echo "$i errors:" && cat /tmp/$i.err diff --git a/contrib/mdocml/html.c b/contrib/mandoc/html.c similarity index 78% rename from contrib/mdocml/html.c rename to contrib/mandoc/html.c index fc55e881b78..70935dcd57e 100644 --- a/contrib/mdocml/html.c +++ b/contrib/mandoc/html.c @@ -1,7 +1,7 @@ -/* $Id: html.c,v 1.219 2017/07/15 17:57:51 schwarze Exp $ */ +/* $Id: html.c,v 1.238 2018/06/25 16:54:59 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2011-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,6 +22,7 @@ #include <assert.h> #include <ctype.h> #include <stdarg.h> +#include <stddef.h> #include <stdio.h> #include <stdint.h> #include <stdlib.h> @@ -29,6 +30,7 @@ #include <unistd.h> #include "mandoc_aux.h" +#include "mandoc_ohash.h" #include "mandoc.h" #include "roff.h" #include "out.h" @@ -59,6 +61,7 @@ static const struct htmldata htmltags[TAG_MAX] = { {"meta", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, {"title", HTML_NLAROUND}, {"div", HTML_NLAROUND}, + {"div", 0}, {"h1", HTML_NLAROUND}, {"h2", HTML_NLAROUND}, {"span", 0}, @@ -66,8 +69,6 @@ static const struct htmldata htmltags[TAG_MAX] = { {"br", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, {"a", 0}, {"table", HTML_NLALL | HTML_INDENT}, - {"colgroup", HTML_NLALL | HTML_INDENT}, - {"col", HTML_NOSTACK | HTML_AUTOCLOSE | HTML_NLALL}, {"tr", HTML_NLALL | HTML_INDENT}, {"td", HTML_NLAROUND}, {"li", HTML_NLAROUND | HTML_INDENT}, @@ -103,20 +104,9 @@ static const struct htmldata htmltags[TAG_MAX] = { {"mover", 0}, }; -static const char *const roffscales[SCALE_MAX] = { - "cm", /* SCALE_CM */ - "in", /* SCALE_IN */ - "pc", /* SCALE_PC */ - "pt", /* SCALE_PT */ - "em", /* SCALE_EM */ - "em", /* SCALE_MM */ - "ex", /* SCALE_EN */ - "ex", /* SCALE_BU */ - "em", /* SCALE_VS */ - "ex", /* SCALE_FS */ -}; +/* Avoid duplicate HTML id= attributes. */ +static struct ohash id_unique; -static void a2width(const char *, struct roffsu *); static void print_byte(struct html *, char); static void print_endword(struct html *); static void print_indent(struct html *); @@ -143,6 +133,8 @@ html_alloc(const struct manoutput *outopts) if (outopts->fragment) h->oflags |= HTML_FRAGMENT; + mandoc_ohash_init(&id_unique, 4, 0); + return h; } @@ -151,15 +143,22 @@ html_free(void *p) { struct tag *tag; struct html *h; + char *cp; + unsigned int slot; h = (struct html *)p; - while ((tag = h->tag) != NULL) { h->tag = tag->next; free(tag); } - free(h); + + cp = ohash_first(&id_unique, &slot); + while (cp != NULL) { + free(cp); + cp = ohash_next(&id_unique, &slot); + } + ohash_delete(&id_unique); } void @@ -168,9 +167,14 @@ print_gen_head(struct html *h) struct tag *t; print_otag(h, TAG_META, "?", "charset", "utf-8"); + if (h->style != NULL) { + print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet", + h->style, "type", "text/css", "media", "all"); + return; + } /* - * Print a default style-sheet. + * Print a minimal embedded style sheet. */ t = print_otag(h, TAG_STYLE, ""); @@ -181,11 +185,23 @@ print_gen_head(struct html *h) print_text(h, "td.head-vol { text-align: center; }"); print_endline(h); print_text(h, "div.Pp { margin: 1ex 0ex; }"); + print_endline(h); + print_text(h, "div.Nd, div.Bf, div.Op { display: inline; }"); + print_endline(h); + print_text(h, "span.Pa, span.Ad { font-style: italic; }"); + print_endline(h); + print_text(h, "span.Ms { font-weight: bold; }"); + print_endline(h); + print_text(h, "dl.Bl-diag "); + print_byte(h, '>'); + print_text(h, " dt { font-weight: bold; }"); + print_endline(h); + print_text(h, "code.Nm, code.Fl, code.Cm, code.Ic, " + "code.In, code.Fd, code.Fn,"); + print_endline(h); + print_text(h, "code.Cd { font-weight: bold; " + "font-family: inherit; }"); print_tagq(h, t); - - if (h->style) - print_otag(h, TAG_LINK, "?h??", "rel", "stylesheet", - h->style, "type", "text/css", "media", "all"); } static void @@ -239,10 +255,12 @@ print_metaf(struct html *h, enum mandoc_esc deco) } char * -html_make_id(const struct roff_node *n) +html_make_id(const struct roff_node *n, int unique) { const struct roff_node *nch; - char *buf, *cp; + char *buf, *bufs, *cp; + unsigned int slot; + int suffix; for (nch = n->child; nch != NULL; nch = nch->next) if (nch->type != ROFFT_TEXT) @@ -250,65 +268,46 @@ html_make_id(const struct roff_node *n) buf = NULL; deroff(&buf, n); - - /* http://www.w3.org/TR/html5/dom.html#the-id-attribute */ - - for (cp = buf; *cp != '\0'; cp++) - if (*cp == ' ') - *cp = '_'; - - return buf; -} - -int -html_strlen(const char *cp) -{ - size_t rsz; - int skip, sz; + if (buf == NULL) + return NULL; /* - * Account for escaped sequences within string length - * calculations. This follows the logic in term_strlen() as we - * must calculate the width of produced strings. - * Assume that characters are always width of "1". This is - * hacky, but it gets the job done for approximation of widths. + * In ID attributes, only use ASCII characters that are + * permitted in URL-fragment strings according to the + * explicit list at: + * https://url.spec.whatwg.org/#url-fragment-string */ - sz = 0; - skip = 0; - while (1) { - rsz = strcspn(cp, "\\"); - if (rsz) { - cp += rsz; - if (skip) { - skip = 0; - rsz--; + for (cp = buf; *cp != '\0'; cp++) + if (isalnum((unsigned char)*cp) == 0 && + strchr("!$&'()*+,-./:;=?@_~", *cp) == NULL) + *cp = '_'; + + if (unique == 0) + return buf; + + /* Avoid duplicate HTML id= attributes. */ + + bufs = NULL; + suffix = 1; + slot = ohash_qlookup(&id_unique, buf); + cp = ohash_find(&id_unique, slot); + if (cp != NULL) { + while (cp != NULL) { + free(bufs); + if (++suffix > 127) { + free(buf); + return NULL; } - sz += rsz; - } - if ('\0' == *cp) - break; - cp++; - switch (mandoc_escape(&cp, NULL, NULL)) { - case ESCAPE_ERROR: - return sz; - case ESCAPE_UNICODE: - case ESCAPE_NUMBERED: - case ESCAPE_SPECIAL: - case ESCAPE_OVERSTRIKE: - if (skip) - skip = 0; - else - sz++; - break; - case ESCAPE_SKIPCHAR: - skip = 1; - break; - default: - break; + mandoc_asprintf(&bufs, "%s_%d", buf, suffix); + slot = ohash_qlookup(&id_unique, bufs); + cp = ohash_find(&id_unique, slot); } + free(buf); + buf = bufs; } - return sz; + ohash_insert(&id_unique, slot, buf); + return buf; } static int @@ -490,13 +489,10 @@ struct tag * print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) { va_list ap; - struct roffsu mysu, *su; - char numbuf[16]; struct tag *t; const char *attr; char *arg1, *arg2; - double v; - int i, have_style, tflags; + int tflags; tflags = htmltags[tag].flags; @@ -536,17 +532,12 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) va_start(ap, fmt); - have_style = 0; while (*fmt != '\0') { - if (*fmt == 's') { - have_style = 1; - fmt++; - break; - } - /* Parse a non-style attribute and its arguments. */ + /* Parse attributes and arguments. */ arg1 = va_arg(ap, char *); + arg2 = NULL; switch (*fmt++) { case 'c': attr = "class"; @@ -557,6 +548,10 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) case 'i': attr = "id"; break; + case 's': + attr = "style"; + arg2 = va_arg(ap, char *); + break; case '?': attr = arg1; arg1 = va_arg(ap, char *); @@ -564,13 +559,12 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) default: abort(); } - arg2 = NULL; if (*fmt == 'M') arg2 = va_arg(ap, char *); if (arg1 == NULL) continue; - /* Print the non-style attributes. */ + /* Print the attributes. */ print_byte(h, ' '); print_word(h, attr); @@ -597,114 +591,19 @@ print_otag(struct html *h, enum htmltag tag, const char *fmt, ...) fmt++; break; default: - print_encode(h, arg1, NULL, 1); + if (arg2 == NULL) + print_encode(h, arg1, NULL, 1); + else { + print_word(h, arg1); + print_byte(h, ':'); + print_byte(h, ' '); + print_word(h, arg2); + print_byte(h, ';'); + } break; } print_byte(h, '"'); } - - /* Print out styles. */ - - while (*fmt != '\0') { - arg1 = NULL; - su = NULL; - - /* First letter: input argument type. */ - - switch (*fmt++) { - case 'h': - i = va_arg(ap, int); - su = &mysu; - SCALE_HS_INIT(su, i); - break; - case 's': - arg1 = va_arg(ap, char *); - break; - case 'u': - su = va_arg(ap, struct roffsu *); - break; - case 'w': - if ((arg2 = va_arg(ap, char *)) != NULL) { - su = &mysu; - a2width(arg2, su); - } - if (*fmt == '*') { - if (su != NULL && su->unit == SCALE_EN && - su->scale > 5.9 && su->scale < 6.1) - su = NULL; - fmt++; - } - if (*fmt == '+') { - if (su != NULL) { - /* Make even bold text fit. */ - su->scale *= 1.2; - /* Add padding. */ - su->scale += 3.0; - } - fmt++; - } - if (*fmt == '-') { - if (su != NULL) - su->scale *= -1.0; - fmt++; - } - break; - default: - abort(); - } - - /* Second letter: style name. */ - - switch (*fmt++) { - case 'h': - attr = "height"; - break; - case 'i': - attr = "text-indent"; - break; - case 'l': - attr = "margin-left"; - break; - case 'w': - attr = "width"; - break; - case 'W': - attr = "min-width"; - break; - case '?': - attr = arg1; - arg1 = va_arg(ap, char *); - break; - default: - abort(); - } - if (su == NULL && arg1 == NULL) - continue; - - if (have_style == 1) - print_word(h, " style=\""); - else - print_byte(h, ' '); - print_word(h, attr); - print_byte(h, ':'); - print_byte(h, ' '); - if (su != NULL) { - v = su->scale; - if (su->unit == SCALE_MM && (v /= 100.0) == 0.0) - v = 1.0; - else if (su->unit == SCALE_BU) - v /= 24.0; - (void)snprintf(numbuf, sizeof(numbuf), "%.2f", v); - print_word(h, numbuf); - print_word(h, roffscales[su->unit]); - } else - print_word(h, arg1); - print_byte(h, ';'); - have_style = 2; - } - if (have_style == 2) - print_byte(h, '"'); - va_end(ap); /* Accommodate for "well-formed" singleton escaping. */ @@ -768,6 +667,32 @@ print_gen_decls(struct html *h) print_endline(h); } +void +print_gen_comment(struct html *h, struct roff_node *n) +{ + int wantblank; + + print_word(h, "<!-- This is an automatically generated file." + " Do not edit."); + h->indent = 1; + wantblank = 0; + while (n != NULL && n->type == ROFFT_COMMENT) { + if (strstr(n->string, "-->") == NULL && + (wantblank || *n->string != '\0')) { + print_endline(h); + print_indent(h); + print_word(h, n->string); + wantblank = *n->string != '\0'; + } + n = n->next; + } + if (wantblank) + print_endline(h); + print_word(h, " -->"); + print_endline(h); + h->indent = 0; +} + void print_text(struct html *h, const char *word) { @@ -959,21 +884,3 @@ print_word(struct html *h, const char *cp) while (*cp != '\0') print_byte(h, *cp++); } - -/* - * Calculate the scaling unit passed in a `-width' argument. This uses - * either a native scaling unit (e.g., 1i, 2m) or the string length of - * the value. - */ -static void -a2width(const char *p, struct roffsu *su) -{ - const char *end; - - end = a2roffsu(p, su, SCALE_MAX); - if (end == NULL || *end != '\0') { - su->unit = SCALE_EN; - su->scale = html_strlen(p); - } else if (su->scale < 0.0) - su->scale = 0.0; -} diff --git a/contrib/mdocml/html.h b/contrib/mandoc/html.h similarity index 93% rename from contrib/mdocml/html.h rename to contrib/mandoc/html.h index c727eacf5d0..6d44a47383a 100644 --- a/contrib/mdocml/html.h +++ b/contrib/mandoc/html.h @@ -1,7 +1,7 @@ -/* $Id: html.h,v 1.87 2017/07/08 14:51:04 schwarze Exp $ */ +/* $Id: html.h,v 1.92 2018/06/25 16:54:59 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -23,6 +23,7 @@ enum htmltag { TAG_META, TAG_TITLE, TAG_DIV, + TAG_IDIV, TAG_H1, TAG_H2, TAG_SPAN, @@ -30,8 +31,6 @@ enum htmltag { TAG_BR, TAG_A, TAG_TABLE, - TAG_COLGROUP, - TAG_COL, TAG_TR, TAG_TD, TAG_LI, @@ -119,6 +118,7 @@ struct eqn_box; void roff_html_pre(struct html *, const struct roff_node *); +void print_gen_comment(struct html *, struct roff_node *); void print_gen_decls(struct html *); void print_gen_head(struct html *); struct tag *print_otag(struct html *, enum htmltag, const char *, ...); @@ -131,5 +131,4 @@ void print_eqn(struct html *, const struct eqn_box *); void print_paragraph(struct html *); void print_endline(struct html *); -char *html_make_id(const struct roff_node *); -int html_strlen(const char *); +char *html_make_id(const struct roff_node *, int); diff --git a/contrib/mdocml/lib.c b/contrib/mandoc/lib.c similarity index 100% rename from contrib/mdocml/lib.c rename to contrib/mandoc/lib.c diff --git a/contrib/mdocml/lib.in b/contrib/mandoc/lib.in similarity index 96% rename from contrib/mdocml/lib.in rename to contrib/mandoc/lib.in index 646c9a2407f..95821fc551a 100644 --- a/contrib/mdocml/lib.in +++ b/contrib/mandoc/lib.in @@ -1,4 +1,4 @@ -/* $Id: lib.in,v 1.19 2016/11/23 20:22:13 schwarze Exp $ */ +/* $Id: lib.in,v 1.20 2017/08/20 02:30:27 schwarze Exp $ */ /* * Copyright (c) 2009 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2009, 2012 Joerg Sonnenberger <joerg@netbsd.org> @@ -25,11 +25,13 @@ */ LINE("lib80211", "802.11 Wireless Network Management Library (lib80211, \\-l80211)") +LINE("libalias", "Packet Aliasing Library (libalias, \\-lalias)") LINE("libarchive", "Streaming Archive Library (libarchive, \\-larchive)") LINE("libarm", "ARM Architecture Library (libarm, \\-larm)") LINE("libarm32", "ARM32 Architecture Library (libarm32, \\-larm32)") LINE("libbe", "Boot Environment Library (libbe, \\-lbe)") LINE("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)") +LINE("libbsdxml", "eXpat XML parser library (libbsdxml, \\-lbsdxml)") LINE("libbsm", "Basic Security Module Library (libbsm, \\-lbsm)") LINE("libc", "Standard C\\~Library (libc, \\-lc)") LINE("libc_r", "Reentrant C\\~Library (libc_r, \\-lc_r)") @@ -115,6 +117,7 @@ LINE("libsbuf", "Safe String Composition Library (libsbuf, \\-lsbuf)") LINE("libsdp", "Bluetooth Service Discovery Protocol User Library (libsdp, \\-lsdp)") LINE("libssp", "Buffer Overflow Protection Library (libssp, \\-lssp)") LINE("libstdthreads", "C11 Threads Library (libstdthreads, \\-lstdthreads)") +LINE("libstdthreads", "C11 Threads Library (libstdthreads, \\-lstdthreads)") LINE("libSystem", "System Library (libSystem, \\-lSystem)") LINE("libsysdecode", "System Argument Decoding Library (libsysdecode, \\-lsysdecode)") LINE("libtacplus", "TACACS+ Client Library (libtacplus, \\-ltacplus)") diff --git a/contrib/mdocml/libman.h b/contrib/mandoc/libman.h similarity index 100% rename from contrib/mdocml/libman.h rename to contrib/mandoc/libman.h diff --git a/contrib/mdocml/libmandoc.h b/contrib/mandoc/libmandoc.h similarity index 95% rename from contrib/mdocml/libmandoc.h rename to contrib/mandoc/libmandoc.h index 2cf07628617..9cc8cce4ecc 100644 --- a/contrib/mdocml/libmandoc.h +++ b/contrib/mandoc/libmandoc.h @@ -1,4 +1,4 @@ -/* $Id: libmandoc.h,v 1.70 2017/07/08 17:52:49 schwarze Exp $ */ +/* $Id: libmandoc.h,v 1.71 2018/04/09 22:27:04 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -66,7 +66,7 @@ void roff_man_reset(struct roff_man *); enum rofferr roff_parseln(struct roff *, int, struct buf *, int *); void roff_endparse(struct roff *); void roff_setreg(struct roff *, const char *, int, char sign); -int roff_getreg(const struct roff *, const char *); +int roff_getreg(struct roff *, const char *); char *roff_strdup(const struct roff *, const char *); int roff_getcontrol(const struct roff *, const char *, int *); diff --git a/contrib/mdocml/libmdoc.h b/contrib/mandoc/libmdoc.h similarity index 100% rename from contrib/mdocml/libmdoc.h rename to contrib/mandoc/libmdoc.h diff --git a/contrib/mdocml/libroff.h b/contrib/mandoc/libroff.h similarity index 100% rename from contrib/mdocml/libroff.h rename to contrib/mandoc/libroff.h diff --git a/contrib/mdocml/main.c b/contrib/mandoc/main.c similarity index 92% rename from contrib/mdocml/main.c rename to contrib/mandoc/main.c index 09f4813f47b..302320bba56 100644 --- a/contrib/mdocml/main.c +++ b/contrib/mandoc/main.c @@ -1,7 +1,7 @@ -/* $Id: main.c,v 1.301 2017/07/26 10:21:55 schwarze Exp $ */ +/* $Id: main.c,v 1.306 2018/05/14 14:10:23 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -19,6 +19,7 @@ #include "config.h" #include <sys/types.h> +#include <sys/ioctl.h> #include <sys/param.h> /* MACHINE */ #include <sys/wait.h> @@ -38,6 +39,7 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <termios.h> #include <time.h> #include <unistd.h> @@ -120,6 +122,7 @@ main(int argc, char *argv[]) struct manconf conf; struct mansearch search; struct curparse curp; + struct winsize ws; struct tag_files *tag_files; struct manpage *res, *resp; const char *progname, *sec, *thisarg; @@ -129,7 +132,7 @@ main(int argc, char *argv[]) size_t i, sz; int prio, best_prio; enum outmode outmode; - int fd; + int fd, startdir; int show_usage; int options; int use_pager; @@ -316,6 +319,16 @@ main(int argc, char *argv[]) !isatty(STDOUT_FILENO)) use_pager = 0; + if (use_pager && + (conf.output.width == 0 || conf.output.indent == 0) && + ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1 && + ws.ws_col > 1) { + if (conf.output.width == 0 && ws.ws_col < 79) + conf.output.width = ws.ws_col - 1; + if (conf.output.indent == 0 && ws.ws_col < 66) + conf.output.indent = 3; + } + #if HAVE_PLEDGE if (!use_pager) if (pledge("stdio rpath", NULL) == -1) @@ -374,15 +387,34 @@ main(int argc, char *argv[]) argc, argv, &res, &sz)) usage(search.argmode); - if (sz == 0) { - if (search.argmode == ARG_NAME) - fs_search(&search, &conf.manpath, - argc, argv, &res, &sz); - else - warnx("nothing appropriate"); + if (sz == 0 && search.argmode == ARG_NAME) + fs_search(&search, &conf.manpath, + argc, argv, &res, &sz); + + if (search.argmode == ARG_NAME) { + for (c = 0; c < argc; c++) { + if (strchr(argv[c], '/') == NULL) + continue; + if (access(argv[c], R_OK) == -1) { + warn("%s", argv[c]); + continue; + } + res = mandoc_reallocarray(res, + sz + 1, sizeof(*res)); + res[sz].file = mandoc_strdup(argv[c]); + res[sz].names = NULL; + res[sz].output = NULL; + res[sz].ipath = SIZE_MAX; + res[sz].bits = 0; + res[sz].sec = 10; + res[sz].form = FORM_SRC; + sz++; + } } if (sz == 0) { + if (search.argmode != ARG_NAME) + warnx("nothing appropriate"); rc = MANDOCLEVEL_BADARG; goto out; } @@ -466,7 +498,29 @@ main(int argc, char *argv[]) parse(&curp, STDIN_FILENO, "<stdin>"); } + /* + * Remember the original working directory, if possible. + * This will be needed if some names on the command line + * are page names and some are relative file names. + * Do not error out if the current directory is not + * readable: Maybe it won't be needed after all. + */ + startdir = open(".", O_RDONLY | O_DIRECTORY); + while (argc > 0) { + + /* + * Changing directories is not needed in ARG_FILE mode. + * Do it on a best-effort basis. Even in case of + * failure, some functionality may still work. + */ + if (resp != NULL) { + if (resp->ipath != SIZE_MAX) + (void)chdir(conf.manpath.paths[resp->ipath]); + else if (startdir != -1) + (void)fchdir(startdir); + } + fd = mparse_open(curp.mp, resp != NULL ? resp->file : *argv); if (fd != -1) { if (use_pager) { @@ -476,14 +530,23 @@ main(int argc, char *argv[]) if (resp == NULL) parse(&curp, fd, *argv); - else if (resp->form == FORM_SRC) { - /* For .so only; ignore failure. */ - (void)chdir(conf.manpath.paths[resp->ipath]); + else if (resp->form == FORM_SRC) parse(&curp, fd, resp->file); - } else + else passthrough(resp->file, fd, conf.output.synopsisonly); + if (ferror(stdout)) { + if (tag_files != NULL) { + warn("%s", tag_files->ofn); + tag_unlink(); + tag_files = NULL; + } else + warn("stdout"); + rc = MANDOCLEVEL_SYSERR; + break; + } + if (argc > 1 && curp.outtype <= OUTT_UTF8) { if (curp.outdata == NULL) outdata_alloc(&curp); @@ -502,6 +565,10 @@ main(int argc, char *argv[]) if (--argc) mparse_reset(curp.mp); } + if (startdir != -1) { + (void)fchdir(startdir); + close(startdir); + } if (curp.outdata != NULL) { switch (curp.outtype) { @@ -722,7 +789,8 @@ fs_search(const struct mansearch *cfg, const struct manpaths *paths, cfg->firstmatch) return 1; } - if (res != NULL && *ressz == lastsz) + if (res != NULL && *ressz == lastsz && + strchr(*argv, '/') == NULL) warnx("No entry for %s in the manual.", *argv); lastsz = *ressz; argv++; @@ -1173,7 +1241,7 @@ spawn_pager(struct tag_files *tag_files) if (dup2(tag_files->ofd, STDOUT_FILENO) == -1) err((int)MANDOCLEVEL_SYSERR, "pager stdout"); close(tag_files->ofd); - close(tag_files->tfd); + assert(tag_files->tfd == -1); /* Do not start the pager before controlling the terminal. */ diff --git a/contrib/mdocml/main.h b/contrib/mandoc/main.h similarity index 100% rename from contrib/mdocml/main.h rename to contrib/mandoc/main.h diff --git a/contrib/mdocml/makewhatis.8 b/contrib/mandoc/makewhatis.8 similarity index 100% rename from contrib/mdocml/makewhatis.8 rename to contrib/mandoc/makewhatis.8 diff --git a/contrib/mdocml/man-cgi.css b/contrib/mandoc/man-cgi.css similarity index 100% rename from contrib/mdocml/man-cgi.css rename to contrib/mandoc/man-cgi.css diff --git a/contrib/mdocml/man.1 b/contrib/mandoc/man.1 similarity index 91% rename from contrib/mdocml/man.1 rename to contrib/mandoc/man.1 index 1719ded9223..cf03693ee98 100644 --- a/contrib/mdocml/man.1 +++ b/contrib/mandoc/man.1 @@ -1,4 +1,4 @@ -.\" $Id: man.1,v 1.29 2017/05/17 23:23:00 schwarze Exp $ +.\" $Id: man.1,v 1.33 2018/04/19 23:41:16 schwarze Exp $ .\" .\" Copyright (c) 1989, 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -31,7 +31,7 @@ .\" .\" @(#)man.1 8.2 (Berkeley) 1/2/94 .\" -.Dd $Mdocdate: August 8 2018 $ +.Dd $Mdocdate: April 19 2018 $ .Dt MAN 1 .Os .Sh NAME @@ -75,9 +75,21 @@ See for a description of the contents of this file. .It Fl c Copy the manual page to the standard output instead of using -.Xr less 1 +.Xr more 1 to paginate it. This is done by default if the standard output is not a terminal device. +.Pp +When using +.Fl c , +most terminal devices are unable to show the markup. +To print the output of +.Nm +to the terminal with markup but without using a pager, pipe it to +.Xr ul 1 . +To remove the markup, pipe the output to +.Xr col 1 +.Fl b +instead. .It Fl f A synonym for .Xr whatis 1 . @@ -102,8 +114,7 @@ manual. By default, it displays the header lines of all matching pages. .It Fl l A synonym for -.Xr mandoc 1 -.Fl a . +.Xr mandoc 1 . The .Ar name arguments are interpreted as filenames. @@ -115,6 +126,8 @@ No search is done and and .Fl w are ignored. +This option implies +.Fl a . .It Fl M Ar path Override the list of standard directories which .Nm @@ -233,7 +246,7 @@ is case insensitive. Any non-empty value of the environment variable .Ev MANPAGER is used instead of the standard pagination program, -.Xr less 1 . +.Xr more 1 . If .Xr less 1 is used, the interactive @@ -282,14 +295,9 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Xr less 1 +.Xr more 1 .Fl s is used. -Only used if -.Fl a -or -.Fl l -is specified. .El .Sh FILES .Bl -tag -width /etc/man.conf -compact @@ -301,20 +309,24 @@ default man configuration file See .Xr mandoc 1 for details. +.Sh EXAMPLES +Format a page for pasting extracts into an email message \(em +avoid printing any UTF-8 characters, reduce the width to ease +quoting in replies, and remove markup: +.Pp +.Dl $ man -T ascii -O width=65 pledge | col -b +.Pp +Read a typeset page in a PDF viewer: +.Pp +.Dl $ MANPAGER=mupdf man -T pdf lpd .Sh SEE ALSO .Xr apropos 1 , -.Xr intro 1 , +.Xr col 1 , +.Xr mandoc 1 , +.Xr ul 1 , .Xr whereis 1 , -.Xr intro 2 , -.Xr intro 3 , -.Xr intro 4 , -.Xr intro 5 , .Xr man.conf 5 , -.Xr intro 6 , -.Xr intro 7 , -.Xr mdoc 7 , -.Xr intro 8 , -.Xr intro 9 +.Xr mdoc 7 .Sh STANDARDS The .Nm diff --git a/contrib/mdocml/man.7 b/contrib/mandoc/man.7 similarity index 98% rename from contrib/mdocml/man.7 rename to contrib/mandoc/man.7 index 570e7ac3bdc..d418b9ee76c 100644 --- a/contrib/mdocml/man.7 +++ b/contrib/mandoc/man.7 @@ -1,4 +1,4 @@ -.\" $Id: man.7,v 1.136 2017/06/25 11:42:02 schwarze Exp $ +.\" $Id: man.7,v 1.137 2018/04/05 22:12:33 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2011-2015 Ingo Schwarze <schwarze@openbsd.org> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 25 2017 $ +.Dd $Mdocdate: April 5 2018 $ .Dt MAN 7 .Os .Sh NAME @@ -273,7 +273,6 @@ in the alphabetical reference below. .Bl -column "PP, LP, P" description .It Sx B Ta boldface font .It Sx I Ta italic font -.It Sx R Ta roman (default) font .It Sx SB Ta small boldface font .It Sx SM Ta small roman font .It Sx BI Ta alternate between boldface and italic fonts @@ -297,9 +296,7 @@ The optional arguments specify which release it is from. Text is rendered in bold face. .Pp See also -.Sx \&I -and -.Sx \&R . +.Sx \&I . .Ss \&BI Text is rendered alternately in bold face and italic. Thus, @@ -393,9 +390,7 @@ and Text is rendered in italics. .Pp See also -.Sx \&B -and -.Sx \&R . +.Sx \&B . .Ss \&IB Text is rendered alternately in italics and bold face. Whitespace between arguments is omitted in output. @@ -546,13 +541,6 @@ See also .Sx \&P , and .Sx \&TP . -.Ss \&R -Text is rendered in roman (the default font). -.Pp -See also -.Sx \&I -and -.Sx \&B . .Ss \&RB Text is rendered alternately in roman (the default font) and bold face. Whitespace between arguments is omitted in output. @@ -790,7 +778,6 @@ The syntax is as follows: .It Sx \&IR Ta n Ta current Ta \& .It Sx \&OP Ta 0, 1 Ta current Ta compat .It Sx \&PD Ta 1 Ta current Ta \& -.It Sx \&R Ta n Ta next-line Ta \& .It Sx \&RB Ta n Ta current Ta \& .It Sx \&RI Ta n Ta current Ta \& .It Sx \&SB Ta n Ta next-line Ta \& diff --git a/contrib/mdocml/man.c b/contrib/mandoc/man.c similarity index 100% rename from contrib/mdocml/man.c rename to contrib/mandoc/man.c diff --git a/contrib/mdocml/man.cgi.3 b/contrib/mandoc/man.cgi.3 similarity index 100% rename from contrib/mdocml/man.cgi.3 rename to contrib/mandoc/man.cgi.3 diff --git a/contrib/mdocml/man.cgi.8 b/contrib/mandoc/man.cgi.8 similarity index 97% rename from contrib/mdocml/man.cgi.8 rename to contrib/mandoc/man.cgi.8 index eba3cec45a8..b8cd623c598 100644 --- a/contrib/mdocml/man.cgi.8 +++ b/contrib/mandoc/man.cgi.8 @@ -1,4 +1,4 @@ -.\" $Id: man.cgi.8,v 1.22 2017/03/18 16:48:24 schwarze Exp $ +.\" $Id: man.cgi.8,v 1.23 2018/05/20 21:48:44 schwarze Exp $ .\" .\" Copyright (c) 2014, 2015, 2016 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: March 18 2017 $ +.Dd $Mdocdate: May 20 2018 $ .Dt MAN.CGI 8 .Os .Sh NAME @@ -104,6 +104,9 @@ Lists are returned when searches match more than one manual page. The first column shows the names and section numbers of manuals as clickable links. The second column shows the one-line descriptions of the manuals. +For +.Xr man 1 +style searches, the content of the first manual page follows the list. .It A manual page. This output format is used when a search matches exactly one manual page, or when a link on a list page or an @@ -111,7 +114,7 @@ manual page, or when a link on a list page or an link on another manual page is followed. .It A no-result page. This is shown when a search request returns no results - -eiher because it violates the query syntax, or because +either because it violates the query syntax, or because the search does not match any manual pages. .It \&An error page. This cannot happen by merely clicking the @@ -234,6 +237,8 @@ They consist of: .It The .Cm http:// +or +.Cm https:// protocol specifier. .It The host name. @@ -394,7 +399,7 @@ The CGI program is call-compatible with queries from the traditional .Pa man.cgi script by Wolfram Schneider. -However, the output may not be quite the same. +However, the output looks quite different. .Sh SEE ALSO .Xr apropos 1 , .Xr mandoc.db 5 , diff --git a/contrib/mdocml/man.conf.5 b/contrib/mandoc/man.conf.5 similarity index 92% rename from contrib/mdocml/man.conf.5 rename to contrib/mandoc/man.conf.5 index 425895c1dc8..be0998087d1 100644 --- a/contrib/mdocml/man.conf.5 +++ b/contrib/mandoc/man.conf.5 @@ -1,4 +1,4 @@ -.\" $Id: man.conf.5,v 1.4 2016/12/28 22:52:17 schwarze Exp $ +.\" $Id: man.conf.5,v 1.5 2017/08/22 18:17:52 schwarze Exp $ .\" .\" Copyright (c) 2015 Ingo Schwarze <schwarze@openbsd.org> .\" @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 28 2016 $ +.Dd $Mdocdate: August 22 2017 $ .Dt MAN.CONF 5 .Os .Sh NAME @@ -74,8 +74,12 @@ in each directory configured with .Ic manpath is recommended and necessary for .Xr apropos 1 -to work, but not strictly required for -.Xr man 1 . +to work, and also for +.Xr man 1 +on operating systems like +.Ox +that install each manual page with only one file name in the file system, +even if it documents multiple utilities or functions. .It Ic output Ar option Op Ar value Configure the default value of an output option. These directives are overridden by the diff --git a/contrib/mdocml/man.h b/contrib/mandoc/man.h similarity index 100% rename from contrib/mdocml/man.h rename to contrib/mandoc/man.h diff --git a/contrib/mdocml/man.options.1 b/contrib/mandoc/man.options.1 similarity index 100% rename from contrib/mdocml/man.options.1 rename to contrib/mandoc/man.options.1 diff --git a/contrib/mdocml/man_html.c b/contrib/mandoc/man_html.c similarity index 88% rename from contrib/mdocml/man_html.c rename to contrib/mandoc/man_html.c index a304b3e4d24..ae5dac1ad93 100644 --- a/contrib/mdocml/man_html.c +++ b/contrib/mandoc/man_html.c @@ -1,7 +1,7 @@ -/* $Id: man_html.c,v 1.145 2017/06/25 11:42:02 schwarze Exp $ */ +/* $Id: man_html.c,v 1.153 2018/07/27 17:49:31 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2013,2014,2015,2017,2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,8 +35,6 @@ /* FIXME: have PD set the default vspace width. */ -#define INDENT 5 - #define MAN_ARGS const struct roff_meta *man, \ const struct roff_node *n, \ struct html *h @@ -48,12 +46,11 @@ struct htmlman { static void print_bvspace(struct html *, const struct roff_node *); -static void print_man_head(MAN_ARGS); +static void print_man_head(const struct roff_meta *, + struct html *); static void print_man_nodelist(MAN_ARGS); static void print_man_node(MAN_ARGS); static int fillmode(struct html *, int); -static int a2width(const struct roff_node *, - struct roffsu *); static int man_B_pre(MAN_ARGS); static int man_HP_pre(MAN_ARGS); static int man_IP_pre(MAN_ARGS); @@ -68,8 +65,10 @@ static int man_UR_pre(MAN_ARGS); static int man_alt_pre(MAN_ARGS); static int man_ign_pre(MAN_ARGS); static int man_in_pre(MAN_ARGS); -static void man_root_post(MAN_ARGS); -static void man_root_pre(MAN_ARGS); +static void man_root_post(const struct roff_meta *, + struct html *); +static void man_root_pre(const struct roff_meta *, + struct html *); static const struct htmlman __mans[MAN_MAX - MAN_TH] = { { NULL, NULL }, /* TH */ @@ -138,30 +137,34 @@ print_bvspace(struct html *h, const struct roff_node *n) void html_man(void *arg, const struct roff_man *man) { - struct html *h; - struct tag *t; + struct html *h; + struct roff_node *n; + struct tag *t; h = (struct html *)arg; + n = man->first->child; if ((h->oflags & HTML_FRAGMENT) == 0) { print_gen_decls(h); print_otag(h, TAG_HTML, ""); + if (n->type == ROFFT_COMMENT) + print_gen_comment(h, n); t = print_otag(h, TAG_HEAD, ""); - print_man_head(&man->meta, man->first, h); + print_man_head(&man->meta, h); print_tagq(h, t); print_otag(h, TAG_BODY, ""); } - man_root_pre(&man->meta, man->first, h); + man_root_pre(&man->meta, h); t = print_otag(h, TAG_DIV, "c", "manual-text"); - print_man_nodelist(&man->meta, man->first->child, h); + print_man_nodelist(&man->meta, n, h); print_tagq(h, t); - man_root_post(&man->meta, man->first, h); + man_root_post(&man->meta, h); print_tagq(h, NULL); } static void -print_man_head(MAN_ARGS) +print_man_head(const struct roff_meta *man, struct html *h) { char *cp; @@ -262,6 +265,8 @@ print_man_node(MAN_ARGS) break; print_paragraph(h); return; + case ROFFT_COMMENT: + return; default: break; } @@ -359,16 +364,8 @@ fillmode(struct html *h, int want) return had; } -static int -a2width(const struct roff_node *n, struct roffsu *su) -{ - if (n->type != ROFFT_TEXT) - return 0; - return a2roffsu(n->string, su, SCALE_EN) != NULL; -} - static void -man_root_pre(MAN_ARGS) +man_root_pre(const struct roff_meta *man, struct html *h) { struct tag *t, *tt; char *title; @@ -396,7 +393,7 @@ man_root_pre(MAN_ARGS) } static void -man_root_post(MAN_ARGS) +man_root_post(const struct roff_meta *man, struct html *h) { struct tag *t, *tt; @@ -419,11 +416,10 @@ man_SH_pre(MAN_ARGS) char *id; if (n->type == ROFFT_HEAD) { - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H1, "cTi", "Sh", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); } return 1; } @@ -489,11 +485,10 @@ man_SS_pre(MAN_ARGS) char *id; if (n->type == ROFFT_HEAD) { - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H2, "cTi", "Ss", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); } return 1; } @@ -516,7 +511,7 @@ man_IP_pre(MAN_ARGS) const struct roff_node *nn; if (n->type == ROFFT_BODY) { - print_otag(h, TAG_DD, "c", "It-tag"); + print_otag(h, TAG_DD, ""); return 1; } else if (n->type != ROFFT_HEAD) { print_otag(h, TAG_DL, "c", "Bl-tag"); @@ -525,7 +520,7 @@ man_IP_pre(MAN_ARGS) /* FIXME: width specification. */ - print_otag(h, TAG_DT, "c", "It-tag"); + print_otag(h, TAG_DT, ""); /* For IP, only print the first header element. */ @@ -550,24 +545,13 @@ man_IP_pre(MAN_ARGS) static int man_HP_pre(MAN_ARGS) { - struct roffsu sum, sui; - const struct roff_node *np; - if (n->type == ROFFT_HEAD) return 0; - else if (n->type != ROFFT_BLOCK) - return 1; - np = n->head->child; - - if (np == NULL || !a2width(np, &sum)) - SCALE_HS_INIT(&sum, INDENT); - - sui.unit = sum.unit; - sui.scale = -sum.scale; - - print_bvspace(h, n); - print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui); + if (n->type == ROFFT_BLOCK) { + print_bvspace(h, n); + print_otag(h, TAG_DIV, "c", "HP"); + } return 1; } @@ -629,18 +613,10 @@ man_ign_pre(MAN_ARGS) static int man_RS_pre(MAN_ARGS) { - struct roffsu su; - if (n->type == ROFFT_HEAD) return 0; - else if (n->type == ROFFT_BODY) - return 1; - - SCALE_HS_INIT(&su, INDENT); - if (n->head->child) - a2width(n->head->child, &su); - - print_otag(h, TAG_DIV, "sul", &su); + if (n->type == ROFFT_BLOCK) + print_otag(h, TAG_DIV, "c", "Bd-indent"); return 1; } diff --git a/contrib/mdocml/man_macro.c b/contrib/mandoc/man_macro.c similarity index 100% rename from contrib/mdocml/man_macro.c rename to contrib/mandoc/man_macro.c diff --git a/contrib/mdocml/man_term.c b/contrib/mandoc/man_term.c similarity index 97% rename from contrib/mdocml/man_term.c rename to contrib/mandoc/man_term.c index 8946a05067a..b5723ccf838 100644 --- a/contrib/mdocml/man_term.c +++ b/contrib/mandoc/man_term.c @@ -1,7 +1,7 @@ -/* $Id: man_term.c,v 1.209 2017/07/31 15:19:06 schwarze Exp $ */ +/* $Id: man_term.c,v 1.211 2018/06/10 15:12:35 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -675,7 +675,8 @@ pre_SS(DECL_ARGS) n = n->prev; } while (n != NULL && n->tok >= MAN_TH && termacts[n->tok].flags & MAN_NOTEXT); - if (n == NULL || (n->tok == MAN_SS && n->body->child == NULL)) + if (n == NULL || n->type == ROFFT_COMMENT || + (n->tok == MAN_SS && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) @@ -737,7 +738,8 @@ pre_SH(DECL_ARGS) n = n->prev; } while (n != NULL && n->tok >= MAN_TH && termacts[n->tok].flags & MAN_NOTEXT); - if (n == NULL || (n->tok == MAN_SH && n->body->child == NULL)) + if (n == NULL || n->type == ROFFT_COMMENT || + (n->tok == MAN_SH && n->body->child == NULL)) break; for (i = 0; i < mt->pardist; i++) @@ -885,7 +887,8 @@ print_man_node(DECL_ARGS) term_word(p, n->string); goto out; - + case ROFFT_COMMENT: + return; case ROFFT_EQN: if ( ! (n->flags & NODE_LINE)) p->flags |= TERMP_NOSPACE; @@ -1029,6 +1032,18 @@ print_man_foot(struct termp *p, const struct roff_meta *meta) term_word(p, title); term_flushln(p); + + /* + * Reset the terminal state for more output after the footer: + * Some output modes, in particular PostScript and PDF, print + * the header and the footer into a buffer such that it can be + * reused for multiple output pages, then go on to format the + * main text. + */ + + p->tcol->offset = 0; + p->flags = 0; + free(title); } diff --git a/contrib/mdocml/man_validate.c b/contrib/mandoc/man_validate.c similarity index 98% rename from contrib/mdocml/man_validate.c rename to contrib/mandoc/man_validate.c index b3356ccb3d3..d6c51af5255 100644 --- a/contrib/mdocml/man_validate.c +++ b/contrib/mandoc/man_validate.c @@ -1,7 +1,7 @@ /* $OpenBSD$ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -120,6 +120,7 @@ man_node_validate(struct roff_man *man) case ROFFT_ROOT: check_root(man, n); break; + case ROFFT_COMMENT: case ROFFT_EQN: case ROFFT_TBL: break; @@ -149,10 +150,9 @@ man_node_validate(struct roff_man *man) static void check_root(CHKARGS) { - assert((man->flags & (MAN_BLINE | MAN_ELINE)) == 0); - if (NULL == man->first->child) + if (n->last == NULL || n->last->type == ROFFT_COMMENT) mandoc_msg(MANDOCERR_DOC_EMPTY, man->parse, n->line, n->pos, NULL); else diff --git a/contrib/mdocml/manconf.h b/contrib/mandoc/manconf.h similarity index 100% rename from contrib/mdocml/manconf.h rename to contrib/mandoc/manconf.h diff --git a/contrib/mdocml/mandoc.1 b/contrib/mandoc/mandoc.1 similarity index 93% rename from contrib/mdocml/mandoc.1 rename to contrib/mandoc/mandoc.1 index b9a44b2743e..76b3cda5a70 100644 --- a/contrib/mdocml/mandoc.1 +++ b/contrib/mandoc/mandoc.1 @@ -1,7 +1,7 @@ -.\" $Id: mandoc.1,v 1.217 2017/07/20 15:26:41 schwarze Exp $ +.\" $Id: mandoc.1,v 1.226 2018/07/28 18:34:15 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2012, 2014-2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2012, 2014-2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: August 8 2018 $ +.Dd $Mdocdate: July 28 2018 $ .Dt MANDOC 1 .Os .Sh NAME @@ -34,9 +34,7 @@ .Sh DESCRIPTION The .Nm -utility formats -.Ux -manual pages for display. +utility formats manual pages for display. .Pp By default, .Nm @@ -54,13 +52,13 @@ The options are as follows: If the standard output is a terminal device and .Fl c is not specified, use -.Xr less 1 +.Xr more 1 to paginate the output, just like .Xr man 1 would. .It Fl c Copy the formatted manual pages to the standard output without using -.Xr less 1 +.Xr more 1 to paginate them. This is the default. It can be specified to override @@ -118,7 +116,7 @@ With all input files are interpreted as .Xr man 7 . By default, the input language is automatically detected for each file: -if the the first macro is +if the first macro is .Ic \&Dd or .Ic \&Dt , @@ -132,13 +130,32 @@ With other arguments, is silently ignored. .It Fl O Ar options Comma-separated output options. +See the descriptions of the individual output formats for supported +.Ar options . .It Fl T Ar output -Output format. -See -.Sx Output Formats -for available formats. -Defaults to -.Fl T Cm locale . +Select the output format. +Supported values for the +.Ar output +argument are +.Cm ascii , +.Cm html , +the default of +.Cm locale , +.Cm man , +.Cm markdown , +.Cm pdf , +.Cm ps , +.Cm tree , +and +.Cm utf8 . +.Pp +The special +.Fl T Cm lint +mode only parses the input and produces no output. +It implies +.Fl W Cm all +and redirects parser messages, which usually appear on standard +error output, to standard output. .It Fl W Ar level Specify the minimum message .Ar level @@ -196,11 +213,11 @@ and are requested, they can be joined with a comma, for example .Fl W Cm error , Ns Cm stop . .It Ar file -Read input from zero or more files. -If unspecified, reads from stdin. -If multiple files are specified, +Read from the given input file. +If multiple files are specified, they are processed in the given order. +If unspecified, .Nm -will halt with the first failed parse. +reads from standard input. .El .Pp The options @@ -220,69 +237,14 @@ manual. The options .Fl fkl are mutually exclusive and override each other. -.Ss Output Formats -The -.Nm -utility accepts the following -.Fl T -arguments, which correspond to output modes: -.Bl -tag -width "-T markdown" -.It Fl T Cm ascii -Produce 7-bit ASCII output. -See -.Sx ASCII Output . -.It Fl T Cm html -Produce HTML5, CSS1, and MathML output. -See -.Sx HTML Output . -.It Fl T Cm lint -Parse only: produce no output. -Implies -.Fl W Cm all -and redirects parser messages, which usually appear -on standard error output, to standard output. -.It Fl T Cm locale -Encode output using the current locale. -This is the default. -See -.Sx Locale Output . -.It Fl T Cm man -Produce -.Xr man 7 -format output. -See -.Sx Man Output . -.It Fl T Cm markdown -Produce output in -.Sy markdown -format. -See -.Sx Markdown Output . -.It Fl T Cm pdf -Produce PDF output. -See -.Sx PDF Output . -.It Fl T Cm ps -Produce PostScript output. -See -.Sx PostScript Output . -.It Fl T Cm tree -Produce an indented parse tree. -See -.Sx Syntax tree output . -.It Fl T Cm utf8 -Encode output in the UTF\-8 multi-byte format. -See -.Sx UTF\-8 Output . -.El -.Pp -If multiple input files are specified, these will be processed by the -corresponding filter in-order. .Ss ASCII Output -Output produced by +Use .Fl T Cm ascii -is rendered in standard 7-bit ASCII documented in -.Xr ascii 7 . +to force text output in 7-bit ASCII character encoding documented in the +.Xr ascii 7 +manual page, ignoring the +.Xr locale 1 +set in the environment. .Pp Font styles are applied by using back-spaced encoding such that an underlined character @@ -299,9 +261,6 @@ The special characters documented in .Xr mandoc_char 7 are rendered best-effort in an ASCII equivalent. .Pp -Output width is limited to 78 visible columns unless literal input lines -exceed this limit. -.Pp The following .Fl O arguments are accepted: @@ -315,9 +274,30 @@ and seven for .Xr man 7 . Increasing this is not recommended; it may result in degraded formatting, for example overfull lines or ugly line breaks. +When output is to a pager on a terminal that is less than 66 columns +wide, the default is reduced to three columns. +.It Cm mdoc +Format +.Xr man 7 +input files in +.Xr mdoc 7 +output style. +Specifically, this suppresses the two additional blank lines near the +top and the bottom of each page, and it implies +.Fl O Cm indent Ns =5 . +One useful application is for checking that +.Fl T Cm man +output formats in the same way as the +.Xr mdoc 7 +source it was generated from. .It Cm width Ns = Ns Ar width The output width is set to -.Ar width . +.Ar width +instead of the default of 78. +When output is to a pager on a terminal that is less than 79 columns +wide, the default is reduced to one less than the terminal width. +In any case, lines that are output in literal mode are never wrapped +and may exceed the output width. .El .Ss HTML Output Output produced by @@ -338,7 +318,8 @@ defaults to simple output (via an embedded style-sheet) readable in any graphical or text-based web browser. .Pp -Special characters are rendered in decimal-encoded UTF\-8. +Non-ASCII characters are rendered +as hexadecimal Unicode character references. .Pp The following .Fl O @@ -388,19 +369,28 @@ This must be a valid absolute or relative URI. .El .Ss Locale Output -Locale-depending output encoding is triggered with +By default, +.Nm +automatically selects UTF-8 or ASCII output according to the current +.Xr locale 1 . +If any of the environment variables +.Ev LC_ALL , +.Ev LC_CTYPE , +or +.Ev LANG +are set and the first one that is set +selects the UTF-8 character encoding, it produces +.Sx UTF-8 Output ; +otherwise, it falls back to +.Sx ASCII Output . +This output mode can also be selected explicitly with .Fl T Cm locale . -This is the default. -.Pp -This option is not available on all systems: systems without locale -support, or those whose internal representation is not natively UCS-4, -will fall back to -.Fl T Cm ascii . -See -.Sx ASCII Output -for font style specification and available command-line arguments. .Ss Man Output -Translate input format into +Use +.Fl T Cm man +to translate +.Xr mdoc 7 +input into .Xr man 7 output format. This is useful for distributing manual sources to legacy systems @@ -408,11 +398,7 @@ lacking .Xr mdoc 7 formatters. .Pp -If -.Xr mdoc 7 -is passed as input, it is translated into -.Xr man 7 . -If the input format is +If the input format of a file is .Xr man 7 , the input is copied to the output, expanding any .Xr roff 7 @@ -424,11 +410,11 @@ level controls which .Sx DIAGNOSTICS are displayed before copying the input to the output. .Ss Markdown Output -Translate +Use +.Fl T Cm markdown +to translate .Xr mdoc 7 -input to the -.Sy markdown -format conforming to +input to the markdown format conforming to .Lk http://daringfireball.net/projects/markdown/syntax.text\ "John Gruber's 2004 specification" . The output also almost conforms to the @@ -499,13 +485,24 @@ If an unknown value is encountered, .Ar letter is used. .El -.Ss UTF\-8 Output +.Ss UTF-8 Output Use .Fl T Cm utf8 -to force a UTF\-8 locale. +to force text output in UTF-8 multi-byte character encoding, +ignoring the +.Xr locale 1 +settings in the environment. See -.Sx Locale Output -for details and options. +.Sx ASCII Output +regarding font styles and +.Fl O +arguments. +.Pp +On operating systems lacking locale or wide character support, and +on those where the internal character representation is not UCS-4, +.Nm +always falls back to +.Sx ASCII Output . .Ss Syntax tree output Use .Fl T Cm tree @@ -574,11 +571,18 @@ Meta data is not available in this case. .El .Sh ENVIRONMENT .Bl -tag -width MANPAGER +.It Ev LC_CTYPE +The character encoding +.Xr locale 1 . +When +.Sx Locale Output +is selected, it decides whether to use ASCII or UTF-8 output format. +It never affects the interpretation of input files. .It Ev MANPAGER Any non-empty value of the environment variable .Ev MANPAGER is used instead of the standard pagination program, -.Xr less 1 ; +.Xr more 1 ; see .Xr man 1 for details. @@ -592,7 +596,7 @@ Specifies the pagination program to use when .Ev MANPAGER is not defined. If neither PAGER nor MANPAGER is defined, -.Xr less 1 +.Xr more 1 .Fl s is used. Only used if @@ -741,7 +745,7 @@ Please use your good judgement to decide whether any particular .Cm style suggestion really justifies a change to the input file. .It Cm base -A convertion used in the base system of a specific operating system +A convention used in the base system of a specific operating system is not adhered to. These are not markup mistakes, and neither the quality of formatting nor portability are in danger. @@ -849,6 +853,16 @@ Consider using the conventional date format .Dq "Month dd, yyyy" instead. +.It Sy "normalizing date format to" : No ... +.Pq mdoc , man +The +.Ic \&Dd +or +.Ic \&TH +macro provides an abbreviated month name or a day number with a +leading zero. +In the formatted output, the month name is written out in full +and the leading zero is omitted. .It Sy "lower case character in document title" .Pq mdoc , man The title is still used as given in the @@ -861,7 +875,7 @@ A single manual page contains two copies of the RCS identifier for the same operating system. Consider deleting the later instance and moving the first one up to the top of the page. -.It Sy "typo in section name" +.It Sy "possible typo in section name" .Pq mdoc Fuzzy string matching revealed that the argument of an .Ic \&Sh @@ -938,6 +952,12 @@ An request occurs even though the document already switched to no-fill mode and did not switch back to fill mode yet. It has no effect. +.It Sy "verbatim \(dq--\(dq, maybe consider using \e(em" +.Pq mdoc +Even though the ASCII output device renders an em-dash as +.Qq \-\- , +that is not a good way to write it in an input file +because it renders poorly on all other output devices. .It Sy "function name without markup" .Pq mdoc A word followed by an empty pair of parentheses occurs on a text line. diff --git a/contrib/mdocml/mandoc.3 b/contrib/mandoc/mandoc.3 similarity index 100% rename from contrib/mdocml/mandoc.3 rename to contrib/mandoc/mandoc.3 diff --git a/contrib/mdocml/mandoc.c b/contrib/mandoc/mandoc.c similarity index 98% rename from contrib/mdocml/mandoc.c rename to contrib/mandoc/mandoc.c index 3e16d2c64fb..1279b52ed50 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 00000000000..c93bc22a2d1 --- /dev/null +++ b/contrib/mandoc/mandoc.css @@ -0,0 +1,253 @@ +/* $Id: mandoc.css,v 1.36 2018/07/23 22:51:26 schwarze Exp $ */ +/* + * Standard style sheet for mandoc(1) -Thtml and man.cgi(8). + */ + +/* Global defaults. */ + +html { max-width: 65em; } +body { font-family: Helvetica,Arial,sans-serif; } +table { margin-top: 0em; + margin-bottom: 0em; } +td { vertical-align: top; } +ul, ol, dl { margin-top: 0em; + margin-bottom: 0em; } +li, dt { margin-top: 1em; } + +.permalink { border-bottom: thin dotted; + color: inherit; + font: inherit; + text-decoration: inherit; } +* { clear: both } + +/* Search form and search results. */ + +fieldset { border: thin solid silver; + border-radius: 1em; + text-align: center; } +input[name=expr] { + width: 25%; } + +table.results { margin-top: 1em; + margin-left: 2em; + font-size: smaller; } + +/* Header and footer lines. */ + +table.head { width: 100%; + border-bottom: 1px dotted #808080; + margin-bottom: 1em; + font-size: smaller; } +td.head-vol { text-align: center; } +td.head-rtitle { + text-align: right; } + +table.foot { width: 100%; + border-top: 1px dotted #808080; + margin-top: 1em; + font-size: smaller; } +td.foot-os { text-align: right; } + +/* Sections and paragraphs. */ + +.manual-text { + margin-left: 3.8em; } +.Nd { display: inline; } +.Sh { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -3.2em; + font-size: 110%; } +.Ss { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -1.2em; + font-size: 105%; } +.Pp { margin: 0.6em 0em; } +.Sx { } +.Xr { } + +/* Displays and lists. */ + +.Bd { } +.Bd-indent { margin-left: 3.8em; } + +.Bl-bullet { list-style-type: disc; + padding-left: 1em; } +.Bl-bullet > li { } +.Bl-dash { list-style-type: none; + padding-left: 0em; } +.Bl-dash > li:before { + content: "\2014 "; } +.Bl-item { list-style-type: none; + padding-left: 0em; } +.Bl-item > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-enum { padding-left: 2em; } +.Bl-enum > li { } +.Bl-compact > li { + margin-top: 0em; } + +.Bl-diag { } +.Bl-diag > dt { + font-style: normal; + font-weight: bold; } +.Bl-diag > dd { + margin-left: 0em; } +.Bl-hang { } +.Bl-hang > dt { } +.Bl-hang > dd { + margin-left: 5.5em; } +.Bl-inset { } +.Bl-inset > dt { } +.Bl-inset > dd { + margin-left: 0em; } +.Bl-ohang { } +.Bl-ohang > dt { } +.Bl-ohang > dd { + margin-left: 0em; } +.Bl-tag { margin-left: 5.5em; } +.Bl-tag > dt { + float: left; + margin-top: 0em; + margin-left: -5.5em; + padding-right: 1.2em; + vertical-align: top; } +.Bl-tag > dd { + clear: right; + width: 100%; + margin-top: 0em; + margin-left: 0em; + vertical-align: top; + overflow: auto; } +.Bl-compact > dt { + margin-top: 0em; } + +.Bl-column { } +.Bl-column > tbody > tr { } +.Bl-column > tbody > tr > td { + margin-top: 1em; } +.Bl-compact > tbody > tr > td { + margin-top: 0em; } + +.Rs { font-style: normal; + font-weight: normal; } +.RsA { } +.RsB { font-style: italic; + font-weight: normal; } +.RsC { } +.RsD { } +.RsI { font-style: italic; + font-weight: normal; } +.RsJ { font-style: italic; + font-weight: normal; } +.RsN { } +.RsO { } +.RsP { } +.RsQ { } +.RsR { } +.RsT { text-decoration: underline; } +.RsU { } +.RsV { } + +.eqn { } +.tbl { } + +.HP { margin-left: 3.8em; + text-indent: -3.8em; } + +/* Semantic markup for command line utilities. */ + +table.Nm { } +code.Nm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fl { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Cm { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ar { font-style: italic; + font-weight: normal; } +.Op { display: inline; } +.Ic { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ev { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Pa { font-style: italic; + font-weight: normal; } + +/* Semantic markup for function libraries. */ + +.Lb { } +code.In { font-style: normal; + font-weight: bold; + font-family: inherit; } +a.In { } +.Fd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ft { font-style: italic; + font-weight: normal; } +.Fn { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fa { font-style: italic; + font-weight: normal; } +.Vt { font-style: italic; + font-weight: normal; } +.Va { font-style: italic; + font-weight: normal; } +.Dv { font-style: normal; + font-weight: normal; + font-family: monospace; } +.Er { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Various semantic markup. */ + +.An { } +.Lk { } +.Mt { } +.Cd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ad { font-style: italic; + font-weight: normal; } +.Ms { font-style: normal; + font-weight: bold; } +.St { } +.Ux { } + +/* Physical markup. */ + +.Bf { display: inline; } +.No { font-style: normal; + font-weight: normal; } +.Em { font-style: italic; + font-weight: normal; } +.Sy { font-style: normal; + font-weight: bold; } +.Li { font-style: normal; + font-weight: normal; + font-family: monospace; } + +/* Overrides to avoid excessive margins on small devices. */ + +@media (max-width: 37.5em) { +.manual-text { + margin-left: 0.5em; } +.Sh, .Ss { margin-left: 0em; } +.Bd-indent { margin-left: 2em; } +.Bl-hang > dd { + margin-left: 2em; } +.Bl-tag { margin-left: 2em; } +.Bl-tag > dt { + margin-left: -2em; } +.HP { margin-left: 2em; + text-indent: -2em; } +} diff --git a/contrib/mdocml/mandoc.db.5 b/contrib/mandoc/mandoc.db.5 similarity index 100% rename from contrib/mdocml/mandoc.db.5 rename to contrib/mandoc/mandoc.db.5 diff --git a/contrib/mdocml/mandoc.h b/contrib/mandoc/mandoc.h similarity index 98% rename from contrib/mdocml/mandoc.h rename to contrib/mandoc/mandoc.h index b234cb5ee13..dbc266cc3b0 100644 --- a/contrib/mdocml/mandoc.h +++ b/contrib/mandoc/mandoc.h @@ -1,7 +1,7 @@ -/* $Id: mandoc.h,v 1.245 2017/07/08 14:51:04 schwarze Exp $ */ +/* $Id: mandoc.h,v 1.248 2018/07/28 18:34:15 schwarze Exp $ */ /* * Copyright (c) 2010, 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -56,9 +56,10 @@ enum mandocerr { MANDOCERR_STYLE, /* ===== start of style suggestions ===== */ MANDOCERR_DATE_LEGACY, /* legacy man(7) date format: Dd ... */ + MANDOCERR_DATE_NORM, /* normalizing date format to: ... */ MANDOCERR_TITLE_CASE, /* lower case character in document title */ MANDOCERR_RCS_REP, /* duplicate RCS id: ... */ - MANDOCERR_SEC_TYPO, /* typo in section name: Sh ... */ + MANDOCERR_SEC_TYPO, /* possible typo in section name: Sh ... */ MANDOCERR_ARG_QUOTE, /* unterminated quoted argument */ MANDOCERR_MACRO_USELESS, /* useless macro: macro */ MANDOCERR_BX, /* consider using OS macro: macro */ @@ -68,6 +69,7 @@ enum mandocerr { MANDOCERR_DELIM_NB, /* no blank before trailing delimiter: macro ... */ MANDOCERR_FI_SKIP, /* fill mode already enabled, skipping: fi */ MANDOCERR_NF_SKIP, /* fill mode already disabled, skipping: nf */ + MANDOCERR_DASHDASH, /* verbatim "--", maybe consider using \(em */ MANDOCERR_FUNC, /* function name without markup: name() */ MANDOCERR_SPACE_EOL, /* whitespace at end of input line */ MANDOCERR_COMMENT_BAD, /* bad comment style */ diff --git a/contrib/mdocml/mandoc_aux.c b/contrib/mandoc/mandoc_aux.c similarity index 94% rename from contrib/mdocml/mandoc_aux.c rename to contrib/mandoc/mandoc_aux.c index db593e444c4..5d595ce0c29 100644 --- a/contrib/mdocml/mandoc_aux.c +++ b/contrib/mandoc/mandoc_aux.c @@ -1,4 +1,4 @@ -/* $Id: mandoc_aux.c,v 1.10 2017/06/12 19:05:47 schwarze Exp $ */ +/* $Id: mandoc_aux.c,v 1.11 2018/02/07 20:04:57 schwarze Exp $ */ /* * Copyright (c) 2009, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -111,8 +111,8 @@ mandoc_strndup(const char *ptr, size_t sz) { char *p; - p = mandoc_malloc(sz + 1); - memcpy(p, ptr, sz); - p[(int)sz] = '\0'; + p = strndup(ptr, sz); + if (p == NULL) + err((int)MANDOCLEVEL_SYSERR, NULL); return p; } diff --git a/contrib/mdocml/mandoc_aux.h b/contrib/mandoc/mandoc_aux.h similarity index 100% rename from contrib/mdocml/mandoc_aux.h rename to contrib/mandoc/mandoc_aux.h diff --git a/contrib/mdocml/mandoc_char.7 b/contrib/mandoc/mandoc_char.7 similarity index 92% rename from contrib/mdocml/mandoc_char.7 rename to contrib/mandoc/mandoc_char.7 index a372b3e91df..f63cdaea8fc 100644 --- a/contrib/mdocml/mandoc_char.7 +++ b/contrib/mandoc/mandoc_char.7 @@ -1,4 +1,4 @@ -.\" $Id: mandoc_char.7,v 1.67 2017/06/14 20:57:07 schwarze Exp $ +.\" $Id: mandoc_char.7,v 1.72 2018/08/08 14:30:48 schwarze Exp $ .\" .\" Copyright (c) 2003 Jason McIntyre <jmc@openbsd.org> .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 14 2017 $ +.Dd $Mdocdate: August 8 2018 $ .Dt MANDOC_CHAR 7 .Os .Sh NAME @@ -35,23 +35,37 @@ documents. .Pp The rendering depends on the .Xr mandoc 1 -output mode; in ASCII output, most characters are completely -unintelligible. -For that reason, using any of the special characters documented here, -except those discussed in the +output mode; it can be inspected by calling +.Xr man 1 +on the +.Nm +manual page with different +.Fl T +arguments. +In ASCII output, the rendering of some characters may be hard +to interpret for the reader. +Many are rendered as descriptive strings like +.Qq <integral> , +.Qq <degree> , +or +.Qq <Gamma> , +which may look ugly, and many are replaced by similar ASCII characters. +In particular, accented characters are usually shown without the accent. +For that reason, try to avoid using any of the special characters +documented here except those discussed in the .Sx DESCRIPTION , -is strongly discouraged; they are supported merely for backwards -compatibility with existing documents. +unless they are essential for explaining the subject matter at hand, +for example when documenting complicated mathematical functions. .Pp In particular, in English manual pages, do not use special-character escape sequences to represent national language characters in author names; instead, provide ASCII transcriptions of the names. .Ss Dashes and Hyphens In typography there are different types of dashes of various width: -the hyphen (-), -the minus sign (\(mi), +the hyphen (\(hy), the en-dash (\(en), -and the em-dash (\(em). +the em-dash (\(em), +and the mathematical minus sign (\(mi). .Pp Hyphens are used for adjectives; to separate the two parts of a compound word; @@ -62,6 +76,42 @@ blue-eyed lorry-driver .Ed .Pp +The en-dash is used to separate the two elements of a range, +or can be used the same way as an em-dash. +It should be written as +.Sq \e(en : +.Bd -unfilled -offset indent +pp. 95\e(en97. +Go away \e(en or else! +.Ed +.Pp +The em-dash can be used to show an interruption +or can be used the same way as colons, semi-colons, or parentheses. +It should be written as +.Sq \e(em : +.Bd -unfilled -offset indent +Three things \e(em apples, oranges, and bananas. +This is not that \e(em rather, this is that. +.Ed +.Pp +In +.Xr roff 7 +documents, the minus sign is normally written as +.Sq \e- . +In manual pages, some style guides recommend to also use +.Sq \e- +if an ASCII 0x2d +.Dq hyphen-minus +output glyph that can be copied and pasted is desired in output modes +supporting it, for example in +.Fl T Cm utf8 +and +.Fl T Cm html . +But currently, no practically relevant manual page formatter actually +requires that subtlety, so in manual pages just write plain +.Sq - +to represent hyphen, minus, and hyphen-minus. +.Pp If a word on a text input line contains a hyphen, a formatter may decide to insert an output line break after the hyphen if that helps filling the current output line, but the whole word would overflow the line. @@ -85,37 +135,6 @@ Such automatic hyphenation is not supported by .Xr mandoc 1 , which only breaks the line at whitespace, and inside words only after existing hyphens. -.Pp -The mathematical minus sign is used for negative numbers or subtraction. -It should be written as -.Sq \e(mi : -.Bd -unfilled -offset indent -a = 3 \e(mi 1; -b = \e(mi2; -.Ed -.Pp -The en-dash is used to separate the two elements of a range, -or can be used the same way as an em-dash. -It should be written as -.Sq \e(en : -.Bd -unfilled -offset indent -pp. 95\e(en97. -Go away \e(en or else! -.Ed -.Pp -The em-dash can be used to show an interruption -or can be used the same way as colons, semi-colons, or parentheses. -It should be written as -.Sq \e(em : -.Bd -unfilled -offset indent -Three things \e(em apples, oranges, and bananas. -This is not that \e(em rather, this is that. -.Ed -.Pp -Note: -hyphens, minus signs, and en-dashes look identical under normal ASCII output. -Other formats, such as PostScript, render them correctly, -with differing widths. .Ss Spaces To separate words in normal text, for indenting and alignment in literal context, and when none of the following special cases apply, @@ -319,8 +338,8 @@ Quotes: .It \e(rq Ta \(rq Ta right double-quote .It \e(oq Ta \(oq Ta left single-quote .It \e(cq Ta \(cq Ta right single-quote -.It \e(aq Ta \(aq Ta apostrophe quote (text) -.It \e(dq Ta \(dq Ta double quote (text) +.It \e(aq Ta \(aq Ta apostrophe quote (ASCII character) +.It \e(dq Ta \(dq Ta double quote (ASCII character) .It \e(Fo Ta \(Fo Ta left guillemet .It \e(Fc Ta \(Fc Ta right guillemet .It \e(fo Ta \(fo Ta left single guillemet @@ -336,7 +355,7 @@ Brackets: .It \e(rC Ta \(rC Ta right brace .It \e(la Ta \(la Ta left angle .It \e(ra Ta \(ra Ta right angle -.It \e(bv Ta \(bv Ta brace extension +.It \e(bv Ta \(bv Ta brace extension (special font) .It \e[braceex] Ta \[braceex] Ta brace extension .It \e[bracketlefttp] Ta \[bracketlefttp] Ta top-left hooked bracket .It \e[bracketleftbt] Ta \[bracketleftbt] Ta bottom-left hooked bracket @@ -389,8 +408,8 @@ Logical: .It Em Input Ta Em Rendered Ta Em Description .It \e(AN Ta \(AN Ta logical and .It \e(OR Ta \(OR Ta logical or -.It \e(no Ta \(no Ta logical not -.It \e[tno] Ta \[tno] Ta logical not (text) +.It \e[tno] Ta \[tno] Ta logical not (text font) +.It \e(no Ta \(no Ta logical not (special font) .It \e(te Ta \(te Ta existential quantifier .It \e(fa Ta \(fa Ta universal quantifier .It \e(st Ta \(st Ta such that @@ -402,19 +421,20 @@ Logical: Mathematical: .Bl -column "xxcoproductxx" "Rendered" "Description" -offset indent -compact .It Em Input Ta Em Rendered Ta Em Description -.It \e(pl Ta \(pl Ta plus -.It \e(mi Ta \(mi Ta minus -.It \e- Ta \- Ta minus (text) +.It \e- Ta \- Ta minus (text font) +.It \e(mi Ta \(mi Ta minus (special font) +.It + Ta + Ta plus (text font) +.It \e(pl Ta \(pl Ta plus (special font) .It \e(-+ Ta \(-+ Ta minus-plus -.It \e(+- Ta \(+- Ta plus-minus -.It \e[t+-] Ta \[t+-] Ta plus-minus (text) +.It \e[t+-] Ta \[t+-] Ta plus-minus (text font) +.It \e(+- Ta \(+- Ta plus-minus (special font) .It \e(pc Ta \(pc Ta center-dot -.It \e(mu Ta \(mu Ta multiply -.It \e[tmu] Ta \[tmu] Ta multiply (text) +.It \e[tmu] Ta \[tmu] Ta multiply (text font) +.It \e(mu Ta \(mu Ta multiply (special font) .It \e(c* Ta \(c* Ta circle-multiply .It \e(c+ Ta \(c+ Ta circle-plus -.It \e(di Ta \(di Ta divide -.It \e[tdi] Ta \[tdi] Ta divide (text) +.It \e[tdi] Ta \[tdi] Ta divide (text font) +.It \e(di Ta \(di Ta divide (special font) .It \e(f/ Ta \(f/ Ta fraction .It \e(** Ta \(** Ta asterisk .It \e(<= Ta \(<= Ta less-than-equal @@ -511,8 +531,8 @@ Accents: .It \e(ao Ta \(ao Ta ring .It \e(a\(ti Ta \(a~ Ta tilde .It \e(ho Ta \(ho Ta ogonek -.It \e(ha Ta \(ha Ta hat (text) -.It \e(ti Ta \(ti Ta tilde (text) +.It \e(ha Ta \(ha Ta hat (ASCII character) +.It \e(ti Ta \(ti Ta tilde (ASCII character) .El .Pp Accented letters: diff --git a/contrib/mdocml/mandoc_escape.3 b/contrib/mandoc/mandoc_escape.3 similarity index 100% rename from contrib/mdocml/mandoc_escape.3 rename to contrib/mandoc/mandoc_escape.3 diff --git a/contrib/mdocml/mandoc_headers.3 b/contrib/mandoc/mandoc_headers.3 similarity index 100% rename from contrib/mdocml/mandoc_headers.3 rename to contrib/mandoc/mandoc_headers.3 diff --git a/contrib/mdocml/mandoc_html.3 b/contrib/mandoc/mandoc_html.3 similarity index 80% rename from contrib/mdocml/mandoc_html.3 rename to contrib/mandoc/mandoc_html.3 index ba25e0ad6a7..5bd9446da82 100644 --- a/contrib/mdocml/mandoc_html.3 +++ b/contrib/mandoc/mandoc_html.3 @@ -1,6 +1,6 @@ -.\" $Id: mandoc_html.3,v 1.10 2017/07/15 17:57:51 schwarze Exp $ +.\" $Id: mandoc_html.3,v 1.17 2018/06/25 16:54:59 schwarze Exp $ .\" -.\" Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 15 2017 $ +.Dd $Mdocdate: June 25 2018 $ .Dt MANDOC_HTML 3 .Os .Sh NAME @@ -25,6 +25,8 @@ .Ft void .Fn print_gen_decls "struct html *h" .Ft void +.Fn print_gen_comment "struct html *h" "struct roff_node *n" +.Ft void .Fn print_gen_head "struct html *h" .Ft struct tag * .Fo print_otag @@ -109,6 +111,18 @@ and declarations required for the current document type. .Pp The function +.Fn print_gen_comment +prints the leading comments, usually containing a Copyright notice +and license, as an HTML comment. +It is intended to be called right after opening the +.Aq Ic HTML +element. +Pass the first +.Dv ROFFT_COMMENT +node in +.Fa n . +.Pp +The function .Fn print_gen_head prints the opening .Aq Ic META @@ -198,84 +212,10 @@ Print a .Cm style attribute. If present, it must be the last format letter. -In contrast to the other format letters, this one does not yet -print the value and does not take an argument. -Instead, the rest of the format string consists of pairs of -argument type letters and style name letters. -.El -.Pp -Argument type letters each require one argument as follows: -.Bl -tag -width 1n -offset indent -.It Cm h -Requires one -.Vt int -argument, interpreted as a horizontal length in units of -.Dv SCALE_EN . -.It Cm s -Requires one -.Vt char * -argument, used as a style value. -.It Cm u -Requires one -.Vt struct roffsu * -argument, used as a length. -.It Cm w -Requires one -.Vt char * -argument, interpreted as an -.Xr mdoc 7 Ns -style -width specifier. -If the argument is -.Dv NULL , -nothing is printed for this pair. -.Pp -The -.Cm w -argument type letter can optionally be followed by one, two, or three -modifier letters. -The modifier -.Cm * -suppresses printing of the pair if the argument matches 6n. -The modifier -.Cm + -increases the width by 20% to make even bold text fit -and adds three units for padding between columns. -The modifier -.Cm \- -makes the width negative by multiplying it with \-1. -.El -.Pp -Style name letters decide what to do with the preceding argument: -.Bl -tag -width 1n -offset indent -.It Cm h -Set -.Cm height -to the given length. -.It Cm i -Set -.Cm text-indent -to the given length. -.It Cm l -Set -.Cm margin-left -to the given length. -.It Cm w -Set -.Cm width -to the given length. -.It Cm W -Set -.Cm min-width -to the given length. -.It Cm \&? -The special pair -.Cm s? -requires two -.Vt char * +It requires two +.Va char * arguments. -The first is the style name, the second its value. -The style name must not be -.Dv NULL . +The first is the name of the style property, the second its value. .El .Pp .Fn print_otag diff --git a/contrib/mdocml/mandoc_malloc.3 b/contrib/mandoc/mandoc_malloc.3 similarity index 100% rename from contrib/mdocml/mandoc_malloc.3 rename to contrib/mandoc/mandoc_malloc.3 diff --git a/contrib/mdocml/mandoc_ohash.c b/contrib/mandoc/mandoc_ohash.c similarity index 100% rename from contrib/mdocml/mandoc_ohash.c rename to contrib/mandoc/mandoc_ohash.c diff --git a/contrib/mdocml/mandoc_ohash.h b/contrib/mandoc/mandoc_ohash.h similarity index 100% rename from contrib/mdocml/mandoc_ohash.h rename to contrib/mandoc/mandoc_ohash.h diff --git a/contrib/mdocml/mandoc_xr.c b/contrib/mandoc/mandoc_xr.c similarity index 100% rename from contrib/mdocml/mandoc_xr.c rename to contrib/mandoc/mandoc_xr.c diff --git a/contrib/mdocml/mandoc_xr.h b/contrib/mandoc/mandoc_xr.h similarity index 100% rename from contrib/mdocml/mandoc_xr.h rename to contrib/mandoc/mandoc_xr.h diff --git a/contrib/mdocml/mandocd.8 b/contrib/mandoc/mandocd.8 similarity index 100% rename from contrib/mdocml/mandocd.8 rename to contrib/mandoc/mandocd.8 diff --git a/contrib/mdocml/mandocd.c b/contrib/mandoc/mandocd.c similarity index 100% rename from contrib/mdocml/mandocd.c rename to contrib/mandoc/mandocd.c diff --git a/contrib/mdocml/mandocdb.c b/contrib/mandoc/mandocdb.c similarity index 96% rename from contrib/mdocml/mandocdb.c rename to contrib/mandoc/mandocdb.c index 26117cf8278..86dbce2d9fe 100644 --- a/contrib/mdocml/mandocdb.c +++ b/contrib/mandoc/mandocdb.c @@ -1,4 +1,4 @@ -/* $Id: mandocdb.c,v 1.253 2017/07/28 14:48:25 schwarze Exp $ */ +/* $Id: mandocdb.c,v 1.258 2018/02/23 18:25:57 schwarze Exp $ */ /* * Copyright (c) 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -19,8 +19,8 @@ #include "config.h" #include <sys/types.h> +#include <sys/mman.h> #include <sys/stat.h> -#include <sys/wait.h> #include <assert.h> #include <ctype.h> @@ -139,6 +139,8 @@ static void parse_mdoc(struct mpage *, const struct roff_meta *, const struct roff_node *); static int parse_mdoc_head(struct mpage *, const struct roff_meta *, const struct roff_node *); +static int parse_mdoc_Fa(struct mpage *, const struct roff_meta *, + const struct roff_node *); static int parse_mdoc_Fd(struct mpage *, const struct roff_meta *, const struct roff_node *); static void parse_mdoc_fname(struct mpage *, const struct roff_node *); @@ -207,11 +209,11 @@ static const struct mdoc_handler __mdocs[MDOC_MAX - MDOC_Dd] = { { NULL, TYPE_Er, 0 }, /* Er */ { NULL, TYPE_Ev, 0 }, /* Ev */ { NULL, 0, 0 }, /* Ex */ - { NULL, TYPE_Fa, 0 }, /* Fa */ + { parse_mdoc_Fa, 0, 0 }, /* Fa */ { parse_mdoc_Fd, 0, 0 }, /* Fd */ { NULL, TYPE_Fl, 0 }, /* Fl */ { parse_mdoc_Fn, 0, 0 }, /* Fn */ - { NULL, TYPE_Ft, 0 }, /* Ft */ + { NULL, TYPE_Ft | TYPE_Vt, 0 }, /* Ft */ { NULL, TYPE_Ic, 0 }, /* Ic */ { NULL, TYPE_In, 0 }, /* In */ { NULL, TYPE_Li, 0 }, /* Li */ @@ -319,7 +321,7 @@ mandocdb(int argc, char *argv[]) int ch, i; #if HAVE_PLEDGE - if (pledge("stdio rpath wpath cpath fattr flock proc exec", NULL) == -1) { + if (pledge("stdio rpath wpath cpath", NULL) == -1) { warn("pledge"); return (int)MANDOCLEVEL_SYSERR; } @@ -440,15 +442,6 @@ mandocdb(int argc, char *argv[]) * The existing database is usable. Process * all files specified on the command-line. */ -#if HAVE_PLEDGE - if (!nodb) { - if (pledge("stdio rpath wpath cpath fattr flock", NULL) == -1) { - warn("pledge"); - exitcode = (int)MANDOCLEVEL_SYSERR; - goto out; - } - } -#endif use_all = 1; for (i = 0; i < argc; i++) filescan(argv[i]); @@ -1382,7 +1375,12 @@ parse_cat(struct mpage *mpage, int fd) plen -= 2; } - mpage->desc = mandoc_strdup(p); + /* + * Cut off excessive one-line descriptions. + * Bad pages are not worth better heuristics. + */ + + mpage->desc = mandoc_strndup(p, 150); fclose(stream); free(title); } @@ -1526,7 +1524,12 @@ parse_man(struct mpage *mpage, const struct roff_meta *meta, while (' ' == *start) start++; - mpage->desc = mandoc_strdup(start); + /* + * Cut off excessive one-line descriptions. + * Bad pages are not worth better heuristics. + */ + + mpage->desc = mandoc_strndup(start, 150); free(title); return; } @@ -1571,6 +1574,20 @@ parse_mdoc(struct mpage *mpage, const struct roff_meta *meta, } } +static int +parse_mdoc_Fa(struct mpage *mpage, const struct roff_meta *meta, + const struct roff_node *n) +{ + uint64_t mask; + + mask = TYPE_Fa; + if (n->sec == SEC_SYNOPSIS) + mask |= TYPE_Vt; + + putmdockey(mpage, n->child, mask, 0); + return 0; +} + static int parse_mdoc_Fd(struct mpage *mpage, const struct roff_meta *meta, const struct roff_node *n) @@ -1640,15 +1657,20 @@ static int parse_mdoc_Fn(struct mpage *mpage, const struct roff_meta *meta, const struct roff_node *n) { + uint64_t mask; if (n->child == NULL) return 0; parse_mdoc_fname(mpage, n->child); - for (n = n->child->next; n != NULL; n = n->next) - if (n->type == ROFFT_TEXT) - putkey(mpage, n->string, TYPE_Fa); + n = n->child->next; + if (n != NULL && n->type == ROFFT_TEXT) { + mask = TYPE_Fa; + if (n->sec == SEC_SYNOPSIS) + mask |= TYPE_Vt; + putmdockey(mpage, n, mask, 0); + } return 0; } @@ -2119,9 +2141,10 @@ dbprune(struct dba *dba) static void dbwrite(struct dba *dba) { - char tfn[32]; - int status; - pid_t child; + struct stat sb1, sb2; + char tfn[33], *cp1, *cp2; + off_t i; + int fd1, fd2; /* * Do not write empty databases, and delete existing ones @@ -2160,59 +2183,62 @@ dbwrite(struct dba *dba) say("", "&%s", tfn); return; } - + cp1 = cp2 = MAP_FAILED; + fd1 = fd2 = -1; (void)strlcat(tfn, "/" MANDOC_DB, sizeof(tfn)); if (dba_write(tfn, dba) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; say(tfn, "&dba_write"); - goto out; + goto err; } + if ((fd1 = open(MANDOC_DB, O_RDONLY, 0)) == -1) { + say(MANDOC_DB, "&open"); + goto err; + } + if ((fd2 = open(tfn, O_RDONLY, 0)) == -1) { + say(tfn, "&open"); + goto err; + } + if (fstat(fd1, &sb1) == -1) { + say(MANDOC_DB, "&fstat"); + goto err; + } + if (fstat(fd2, &sb2) == -1) { + say(tfn, "&fstat"); + goto err; + } + if (sb1.st_size != sb2.st_size) + goto err; + if ((cp1 = mmap(NULL, sb1.st_size, PROT_READ, MAP_PRIVATE, + fd1, 0)) == MAP_FAILED) { + say(MANDOC_DB, "&mmap"); + goto err; + } + if ((cp2 = mmap(NULL, sb2.st_size, PROT_READ, MAP_PRIVATE, + fd2, 0)) == MAP_FAILED) { + say(tfn, "&mmap"); + goto err; + } + for (i = 0; i < sb1.st_size; i++) + if (cp1[i] != cp2[i]) + goto err; + goto out; - switch (child = fork()) { - case -1: - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&fork cmp"); - return; - case 0: - execlp("cmp", "cmp", "-s", tfn, MANDOC_DB, (char *)NULL); - say("", "&exec cmp"); - exit(0); - default: - break; - } - if (waitpid(child, &status, 0) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&wait cmp"); - } else if (WIFSIGNALED(status)) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "cmp died from signal %d", WTERMSIG(status)); - } else if (WEXITSTATUS(status)) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say(MANDOC_DB, - "Data changed, but cannot replace database"); - } +err: + exitcode = (int)MANDOCLEVEL_SYSERR; + say(MANDOC_DB, "Data changed, but cannot replace database"); out: + if (cp1 != MAP_FAILED) + munmap(cp1, sb1.st_size); + if (cp2 != MAP_FAILED) + munmap(cp2, sb2.st_size); + if (fd1 != -1) + close(fd1); + if (fd2 != -1) + close(fd2); + unlink(tfn); *strrchr(tfn, '/') = '\0'; - switch (child = fork()) { - case -1: - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&fork rm"); - return; - case 0: - execlp("rm", "rm", "-rf", tfn, (char *)NULL); - say("", "&exec rm"); - exit((int)MANDOCLEVEL_SYSERR); - default: - break; - } - if (waitpid(child, &status, 0) == -1) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "&wait rm"); - } else if (WIFSIGNALED(status) || WEXITSTATUS(status)) { - exitcode = (int)MANDOCLEVEL_SYSERR; - say("", "%s: Cannot remove temporary directory", tfn); - } + rmdir(tfn); } static int diff --git a/contrib/mdocml/manpath.c b/contrib/mandoc/manpath.c similarity index 100% rename from contrib/mdocml/manpath.c rename to contrib/mandoc/manpath.c diff --git a/contrib/mdocml/manpath.h b/contrib/mandoc/manpath.h similarity index 100% rename from contrib/mdocml/manpath.h rename to contrib/mandoc/manpath.h diff --git a/contrib/mdocml/mansearch.3 b/contrib/mandoc/mansearch.3 similarity index 100% rename from contrib/mdocml/mansearch.3 rename to contrib/mandoc/mansearch.3 diff --git a/contrib/mdocml/mansearch.c b/contrib/mandoc/mansearch.c similarity index 98% rename from contrib/mdocml/mansearch.c rename to contrib/mandoc/mansearch.c index 0d60c3bed73..784c17bee71 100644 --- a/contrib/mdocml/mansearch.c +++ b/contrib/mandoc/mansearch.c @@ -1,4 +1,4 @@ -/* $Id: mansearch.c,v 1.76 2017/08/02 13:29:04 schwarze Exp $ */ +/* $Id: mansearch.c,v 1.77 2017/08/22 17:50:11 schwarze Exp $ */ /* * Copyright (c) 2012 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -188,6 +188,16 @@ mansearch(const struct mansearch *search, mpage = *res + cur; mandoc_asprintf(&mpage->file, "%s/%s", paths->paths[i], page->file + 1); + if (access(chdir_status ? page->file + 1 : + mpage->file, R_OK) == -1) { + warn("%s", mpage->file); + warnx("outdated mandoc.db contains " + "bogus %s entry, run makewhatis %s", + page->file + 1, paths->paths[i]); + free(mpage->file); + free(rp); + continue; + } mpage->names = buildnames(page); mpage->output = buildoutput(outkey, page); mpage->ipath = i; diff --git a/contrib/mdocml/mansearch.h b/contrib/mandoc/mansearch.h similarity index 100% rename from contrib/mdocml/mansearch.h rename to contrib/mandoc/mansearch.h diff --git a/contrib/mdocml/mchars_alloc.3 b/contrib/mandoc/mchars_alloc.3 similarity index 100% rename from contrib/mdocml/mchars_alloc.3 rename to contrib/mandoc/mchars_alloc.3 diff --git a/contrib/mdocml/mdoc.7 b/contrib/mandoc/mdoc.7 similarity index 98% rename from contrib/mdocml/mdoc.7 rename to contrib/mandoc/mdoc.7 index 69cccd2b6b2..5c07434cd80 100644 --- a/contrib/mdocml/mdoc.7 +++ b/contrib/mandoc/mdoc.7 @@ -1,7 +1,7 @@ -.\" $Id: mdoc.7,v 1.269 2017/07/20 16:24:53 schwarze Exp $ +.\" $Id: mdoc.7,v 1.271 2018/07/28 18:34:15 schwarze Exp $ .\" .\" Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2010, 2011, 2013-2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010, 2011, 2013-2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: December 5 2017 $ +.Dd $Mdocdate: July 28 2018 $ .Dt MDOC 7 .Os .Sh NAME @@ -674,12 +674,10 @@ Examples: .Ss \&Ao Begin a block enclosed by angle brackets. Does not have any head arguments. -.Pp -Examples: -.Dl \&.Fl -key= \&Ns \&Ao \&Ar val \&Ac -.Pp -See also -.Sx \&Aq . +This macro is almost never useful. +See +.Sx \&Aq +for more details. .Ss \&Ap Inserts an apostrophe without any surrounding whitespace. This is generally used as a grammatical device when referring to the verb @@ -689,19 +687,45 @@ Examples: .Dl \&.Fn execve \&Ap d .Ss \&Aq Encloses its arguments in angle brackets. +The only important use case is for email addresses. +See +.Sx \&Mt +for an example. .Pp -Examples: -.Dl \&.Fl -key= \&Ns \&Aq \&Ar val +Occasionally, it is used for names of characters and keys, for example: +.Bd -literal -offset indent +Press the +\&.Aq escape +key to ... +.Ed .Pp -.Em Remarks : -this macro is often abused for rendering URIs, which should instead use +For URIs, use .Sx \&Lk +instead, and +.Sx \&In +for +.Dq #include +directives. +Never wrap +.Sx \&Ar +in +.Sx \&Aq . +.Pp +Since +.Sx \&Aq +usually renders with non-ASCII characters in non-ASCII output modes, +do not use it where the ASCII characters +.Sq < +and +.Sq > +are required as syntax elements. +Instead, use these characters directly in such cases, combining them +with the macros +.Sx \&Pf , +.Sx \&Ns , or -.Sx \&Mt , -or to note pre-processor -.Dq Li #include -statements, which should use -.Sx \&In . +.Sx \&Eo +as needed. .Pp See also .Sx \&Ao . @@ -1210,7 +1234,7 @@ The .Ar month is the full English month name, the .Ar day -is an optionally zero-padded numeral, and the +is an integer number, and the .Ar year is the full four-digit year. .Pp @@ -1240,8 +1264,8 @@ If no date string is given, the current date is used. .Pp Examples: .Dl \&.Dd $\&Mdocdate$ -.Dl \&.Dd $\&Mdocdate: July 21 2007$ -.Dl \&.Dd July 21, 2007 +.Dl \&.Dd $\&Mdocdate: July 2 2018$ +.Dl \&.Dd July 2, 2018 .Pp See also .Sx \&Dt @@ -2575,17 +2599,6 @@ The second and last Technical Corrigendum. .br This standard is also called X/Open Portability Guide version 7. -.Pp -.It \-p1003.1-2013 -.St -p1003.1-2013 -.br -The 2013 edition incorporates Technical Corrigendum 1. -.Pp -.It \-p1003.1-2016 -.St -p1003.1-2016 -.br -The 2016 edition incorporates Technical Corrigendum 1 and -Technical Corrigendum 2. .El .It Other standards .Pp diff --git a/contrib/mdocml/mdoc.c b/contrib/mandoc/mdoc.c similarity index 98% rename from contrib/mdocml/mdoc.c rename to contrib/mandoc/mdoc.c index 7afcc5d29e1..71803531ddf 100644 --- a/contrib/mdocml/mdoc.c +++ b/contrib/mandoc/mdoc.c @@ -1,4 +1,4 @@ -/* $Id: mdoc.c,v 1.267 2017/06/17 13:06:16 schwarze Exp $ */ +/* $Id: mdoc.c,v 1.268 2017/08/11 16:56:21 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> @@ -297,8 +297,8 @@ mdoc_ptext(struct roff_man *mdoc, int line, char *buf, int offs) if (end - c < 3) break; if (c[1] != ' ' || - isalpha((unsigned char)c[-2]) == 0 || - isalpha((unsigned char)c[-1]) == 0 || + isalnum((unsigned char)c[-2]) == 0 || + isalnum((unsigned char)c[-1]) == 0 || (c[-2] == 'n' && c[-1] == 'c') || (c[-2] == 'v' && c[-1] == 's')) continue; diff --git a/contrib/mdocml/mdoc.h b/contrib/mandoc/mdoc.h similarity index 100% rename from contrib/mdocml/mdoc.h rename to contrib/mandoc/mdoc.h diff --git a/contrib/mdocml/mdoc_argv.c b/contrib/mandoc/mdoc_argv.c similarity index 100% rename from contrib/mdocml/mdoc_argv.c rename to contrib/mandoc/mdoc_argv.c diff --git a/contrib/mdocml/mdoc_html.c b/contrib/mandoc/mdoc_html.c similarity index 87% rename from contrib/mdocml/mdoc_html.c rename to contrib/mandoc/mdoc_html.c index 0b4b9adf34f..f50de8a77af 100644 --- a/contrib/mdocml/mdoc_html.c +++ b/contrib/mandoc/mdoc_html.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_html.c,v 1.294 2017/07/15 17:57:51 schwarze Exp $ */ +/* $Id: mdoc_html.c,v 1.310 2018/07/27 17:49:31 schwarze Exp $ */ /* * Copyright (c) 2008-2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014,2015,2016,2017,2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -34,8 +34,6 @@ #include "html.h" #include "main.h" -#define INDENT 5 - #define MDOC_ARGS const struct roff_meta *meta, \ struct roff_node *n, \ struct html *h @@ -50,14 +48,17 @@ struct htmlmdoc { }; static char *cond_id(const struct roff_node *); -static void print_mdoc_head(MDOC_ARGS); +static void print_mdoc_head(const struct roff_meta *, + struct html *); static void print_mdoc_node(MDOC_ARGS); static void print_mdoc_nodelist(MDOC_ARGS); static void synopsis_pre(struct html *, const struct roff_node *); -static void mdoc_root_post(MDOC_ARGS); -static int mdoc_root_pre(MDOC_ARGS); +static void mdoc_root_post(const struct roff_meta *, + struct html *); +static int mdoc_root_pre(const struct roff_meta *, + struct html *); static void mdoc__x_post(MDOC_ARGS); static int mdoc__x_pre(MDOC_ARGS); @@ -284,30 +285,34 @@ synopsis_pre(struct html *h, const struct roff_node *n) void html_mdoc(void *arg, const struct roff_man *mdoc) { - struct html *h; - struct tag *t; + struct html *h; + struct roff_node *n; + struct tag *t; h = (struct html *)arg; + n = mdoc->first->child; if ((h->oflags & HTML_FRAGMENT) == 0) { print_gen_decls(h); print_otag(h, TAG_HTML, ""); + if (n->type == ROFFT_COMMENT) + print_gen_comment(h, n); t = print_otag(h, TAG_HEAD, ""); - print_mdoc_head(&mdoc->meta, mdoc->first->child, h); + print_mdoc_head(&mdoc->meta, h); print_tagq(h, t); print_otag(h, TAG_BODY, ""); } - mdoc_root_pre(&mdoc->meta, mdoc->first->child, h); + mdoc_root_pre(&mdoc->meta, h); t = print_otag(h, TAG_DIV, "c", "manual-text"); - print_mdoc_nodelist(&mdoc->meta, mdoc->first->child, h); + print_mdoc_nodelist(&mdoc->meta, n, h); print_tagq(h, t); - mdoc_root_post(&mdoc->meta, mdoc->first->child, h); + mdoc_root_post(&mdoc->meta, h); print_tagq(h, NULL); } static void -print_mdoc_head(MDOC_ARGS) +print_mdoc_head(const struct roff_meta *meta, struct html *h) { char *cp; @@ -344,7 +349,7 @@ print_mdoc_node(MDOC_ARGS) int child; struct tag *t; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; child = 1; @@ -429,7 +434,7 @@ print_mdoc_node(MDOC_ARGS) } static void -mdoc_root_post(MDOC_ARGS) +mdoc_root_post(const struct roff_meta *meta, struct html *h) { struct tag *t, *tt; @@ -446,7 +451,7 @@ mdoc_root_post(MDOC_ARGS) } static int -mdoc_root_pre(MDOC_ARGS) +mdoc_root_pre(const struct roff_meta *meta, struct html *h) { struct tag *t, *tt; char *volume, *title; @@ -495,7 +500,7 @@ cond_id(const struct roff_node *n) (n->parent->tok == MDOC_Xo && n->parent->parent->prev == NULL && n->parent->parent->parent->tok == MDOC_It))) - return html_make_id(n); + return html_make_id(n, 1); return NULL; } @@ -506,11 +511,10 @@ mdoc_sh_pre(MDOC_ARGS) switch (n->type) { case ROFFT_HEAD: - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H1, "cTi", "Sh", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); break; case ROFFT_BODY: if (n->sec == SEC_AUTHORS) @@ -530,11 +534,10 @@ mdoc_ss_pre(MDOC_ARGS) if (n->type != ROFFT_HEAD) return 1; - id = html_make_id(n); + id = html_make_id(n, 1); print_otag(h, TAG_H2, "cTi", "Ss", id); if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); return 1; } @@ -544,9 +547,8 @@ mdoc_fl_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Fl", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_CODE, "cTi", "Fl", id); print_text(h, "\\-"); if (!(n->child == NULL && @@ -564,9 +566,8 @@ mdoc_cm_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Cm", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_CODE, "cTi", "Cm", id); return 1; } @@ -576,10 +577,9 @@ mdoc_nd_pre(MDOC_ARGS) if (n->type != ROFFT_BODY) return 1; - /* XXX: this tag in theory can contain block elements. */ - print_text(h, "\\(em"); - print_otag(h, TAG_SPAN, "cT", "Nd"); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_DIV, "cT", "Nd"); return 1; } @@ -591,7 +591,7 @@ mdoc_nm_pre(MDOC_ARGS) print_otag(h, TAG_TD, ""); /* FALLTHROUGH */ case ROFFT_ELEM: - print_otag(h, TAG_B, "cT", "Nm"); + print_otag(h, TAG_CODE, "cT", "Nm"); return 1; case ROFFT_BODY: print_otag(h, TAG_TD, ""); @@ -661,7 +661,6 @@ mdoc_it_pre(MDOC_ARGS) { const struct roff_node *bl; struct tag *t; - const char *cattr; enum mdoc_list type; bl = n->parent; @@ -669,42 +668,6 @@ mdoc_it_pre(MDOC_ARGS) bl = bl->parent; type = bl->norm->Bl.type; - switch (type) { - case LIST_bullet: - cattr = "It-bullet"; - break; - case LIST_dash: - case LIST_hyphen: - cattr = "It-dash"; - break; - case LIST_item: - cattr = "It-item"; - break; - case LIST_enum: - cattr = "It-enum"; - break; - case LIST_diag: - cattr = "It-diag"; - break; - case LIST_hang: - cattr = "It-hang"; - break; - case LIST_inset: - cattr = "It-inset"; - break; - case LIST_ohang: - cattr = "It-ohang"; - break; - case LIST_tag: - cattr = "It-tag"; - break; - case LIST_column: - cattr = "It-column"; - break; - default: - break; - } - switch (type) { case LIST_bullet: case LIST_dash: @@ -715,7 +678,7 @@ mdoc_it_pre(MDOC_ARGS) case ROFFT_HEAD: return 0; case ROFFT_BODY: - print_otag(h, TAG_LI, "c", cattr); + print_otag(h, TAG_LI, ""); break; default: break; @@ -727,13 +690,10 @@ mdoc_it_pre(MDOC_ARGS) case LIST_ohang: switch (n->type) { case ROFFT_HEAD: - print_otag(h, TAG_DT, "c", cattr); - if (type == LIST_diag) - print_otag(h, TAG_B, "c", cattr); + print_otag(h, TAG_DT, ""); break; case ROFFT_BODY: - print_otag(h, TAG_DD, "csw*+l", cattr, - bl->norm->Bl.width); + print_otag(h, TAG_DD, ""); break; default: break; @@ -746,24 +706,21 @@ mdoc_it_pre(MDOC_ARGS) (n->parent->prev == NULL || n->parent->prev->body == NULL || n->parent->prev->body->child != NULL)) { - t = print_otag(h, TAG_DT, "csw*+-l", - cattr, bl->norm->Bl.width); + t = print_otag(h, TAG_DT, ""); print_text(h, "\\ "); print_tagq(h, t); - t = print_otag(h, TAG_DD, "c", cattr); + t = print_otag(h, TAG_DD, ""); print_text(h, "\\ "); print_tagq(h, t); } - print_otag(h, TAG_DT, "csw*+-l", cattr, - bl->norm->Bl.width); + print_otag(h, TAG_DT, ""); break; case ROFFT_BODY: if (n->child == NULL) { - print_otag(h, TAG_DD, "css?", cattr, - "width", "auto"); + print_otag(h, TAG_DD, "s", "width", "auto"); print_text(h, "\\ "); } else - print_otag(h, TAG_DD, "c", cattr); + print_otag(h, TAG_DD, ""); break; default: break; @@ -774,10 +731,10 @@ mdoc_it_pre(MDOC_ARGS) case ROFFT_HEAD: break; case ROFFT_BODY: - print_otag(h, TAG_TD, "c", cattr); + print_otag(h, TAG_TD, ""); break; default: - print_otag(h, TAG_TR, "c", cattr); + print_otag(h, TAG_TR, ""); } default: break; @@ -789,40 +746,20 @@ mdoc_it_pre(MDOC_ARGS) static int mdoc_bl_pre(MDOC_ARGS) { - char cattr[21]; - struct tag *t; + char cattr[28]; struct mdoc_bl *bl; - size_t i; enum htmltag elemtype; - bl = &n->norm->Bl; - switch (n->type) { case ROFFT_BODY: return 1; - case ROFFT_HEAD: - if (bl->type != LIST_column || bl->ncols == 0) - return 0; - - /* - * For each column, print out the <COL> tag with our - * suggested width. The last column gets min-width, as - * in terminal mode it auto-sizes to the width of the - * screen and we want to preserve that behaviour. - */ - - t = print_otag(h, TAG_COLGROUP, ""); - for (i = 0; i < bl->ncols - 1; i++) - print_otag(h, TAG_COL, "sw+w", bl->cols[i]); - print_otag(h, TAG_COL, "swW", bl->cols[i]); - print_tagq(h, t); return 0; - default: break; } + bl = &n->norm->Bl; switch (bl->type) { case LIST_bullet: elemtype = TAG_UL; @@ -859,9 +796,9 @@ mdoc_bl_pre(MDOC_ARGS) break; case LIST_tag: if (bl->offs) - print_otag(h, TAG_DIV, "cswl", "Bl-tag", bl->offs); - print_otag(h, TAG_DL, "csw*+l", bl->comp ? - "Bl-tag Bl-compact" : "Bl-tag", bl->width); + print_otag(h, TAG_DIV, "c", "Bd-indent"); + print_otag(h, TAG_DL, "c", bl->comp ? + "Bl-tag Bl-compact" : "Bl-tag"); return 1; case LIST_column: elemtype = TAG_TABLE; @@ -870,9 +807,11 @@ mdoc_bl_pre(MDOC_ARGS) default: abort(); } + if (bl->offs != NULL) + (void)strlcat(cattr, " Bd-indent", sizeof(cattr)); if (bl->comp) (void)strlcat(cattr, " Bl-compact", sizeof(cattr)); - print_otag(h, elemtype, "cswl", cattr, bl->offs); + print_otag(h, elemtype, "c", cattr); return 1; } @@ -904,7 +843,7 @@ mdoc_d1_pre(MDOC_ARGS) if (n->type != ROFFT_BLOCK) return 1; - print_otag(h, TAG_DIV, "c", "D1"); + print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); if (n->tok == MDOC_Dl) print_otag(h, TAG_CODE, "c", "Li"); @@ -917,7 +856,7 @@ mdoc_sx_pre(MDOC_ARGS) { char *id; - id = html_make_id(n); + id = html_make_id(n, 0); print_otag(h, TAG_A, "cThR", "Sx", id); free(id); return 1; @@ -926,7 +865,7 @@ mdoc_sx_pre(MDOC_ARGS) static int mdoc_bd_pre(MDOC_ARGS) { - int comp, offs, sv; + int comp, sv; struct roff_node *nn; if (n->type == ROFFT_HEAD) @@ -951,18 +890,9 @@ mdoc_bd_pre(MDOC_ARGS) if (n->norm->Bd.offs == NULL || ! strcmp(n->norm->Bd.offs, "left")) - offs = 0; - else if ( ! strcmp(n->norm->Bd.offs, "indent")) - offs = INDENT; - else if ( ! strcmp(n->norm->Bd.offs, "indent-two")) - offs = INDENT * 2; + print_otag(h, TAG_DIV, "c", "Bd"); else - offs = -1; - - if (offs == -1) - print_otag(h, TAG_DIV, "cswl", "Bd", n->norm->Bd.offs); - else - print_otag(h, TAG_DIV, "cshl", "Bd", offs); + print_otag(h, TAG_DIV, "c", "Bd Bd-indent"); if (n->norm->Bd.type != DISP_unfilled && n->norm->Bd.type != DISP_literal) @@ -1014,14 +944,14 @@ mdoc_bd_pre(MDOC_ARGS) static int mdoc_pa_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "cT", "Pa"); + print_otag(h, TAG_SPAN, "cT", "Pa"); return 1; } static int mdoc_ad_pre(MDOC_ARGS) { - print_otag(h, TAG_I, "c", "Ad"); + print_otag(h, TAG_SPAN, "c", "Ad"); return 1; } @@ -1053,7 +983,7 @@ static int mdoc_cd_pre(MDOC_ARGS) { synopsis_pre(h, n); - print_otag(h, TAG_B, "cT", "Cd"); + print_otag(h, TAG_CODE, "cT", "Cd"); return 1; } @@ -1063,9 +993,8 @@ mdoc_dv_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Dv", id); - free(id); return 1; } @@ -1075,9 +1004,8 @@ mdoc_ev_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Ev", id); - free(id); return 1; } @@ -1090,12 +1018,11 @@ mdoc_er_pre(MDOC_ARGS) (n->parent->tok == MDOC_It || (n->parent->tok == MDOC_Bq && n->parent->parent->parent->tok == MDOC_It)) ? - html_make_id(n) : NULL; + html_make_id(n, 1) : NULL; if (id != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "cTi", "Er", id); - free(id); return 1; } @@ -1142,11 +1069,11 @@ mdoc_fd_pre(MDOC_ARGS) assert(n->type == ROFFT_TEXT); if (strcmp(n->string, "#include")) { - print_otag(h, TAG_B, "cT", "Fd"); + print_otag(h, TAG_CODE, "cT", "Fd"); return 1; } - print_otag(h, TAG_B, "cT", "In"); + print_otag(h, TAG_CODE, "cT", "In"); print_text(h, n->string); if (NULL != (n = n->next)) { @@ -1232,7 +1159,7 @@ mdoc_fn_pre(MDOC_ARGS) print_tagq(h, t); } - t = print_otag(h, TAG_B, "cT", "Fn"); + t = print_otag(h, TAG_CODE, "cT", "Fn"); if (sp) print_text(h, sp); @@ -1245,7 +1172,7 @@ mdoc_fn_pre(MDOC_ARGS) for (n = n->child->next; n; n = n->next) { if (NODE_SYNPRETTY & n->flags) - t = print_otag(h, TAG_VAR, "cTss?", "Fa", + t = print_otag(h, TAG_VAR, "cTs", "Fa", "white-space", "nowrap"); else t = print_otag(h, TAG_VAR, "cT", "Fa"); @@ -1375,7 +1302,7 @@ mdoc_fo_pre(MDOC_ARGS) return 0; assert(n->child->string); - t = print_otag(h, TAG_B, "cT", "Fn"); + t = print_otag(h, TAG_CODE, "cT", "Fn"); print_text(h, n->child->string); print_tagq(h, t); return 0; @@ -1399,7 +1326,7 @@ mdoc_in_pre(MDOC_ARGS) struct tag *t; synopsis_pre(h, n); - print_otag(h, TAG_B, "cT", "In"); + print_otag(h, TAG_CODE, "cT", "In"); /* * The first argument of the `In' gets special treatment as @@ -1444,9 +1371,8 @@ mdoc_ic_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Ic", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_CODE, "cTi", "Ic", id); return 1; } @@ -1478,20 +1404,16 @@ mdoc_bf_pre(MDOC_ARGS) return 1; if (FONT_Em == n->norm->Bf.font) - cattr = "Em"; + cattr = "Bf Em"; else if (FONT_Sy == n->norm->Bf.font) - cattr = "Sy"; + cattr = "Bf Sy"; else if (FONT_Li == n->norm->Bf.font) - cattr = "Li"; + cattr = "Bf Li"; else - cattr = "No"; + cattr = "Bf No"; - /* - * We want this to be inline-formatted, but needs to be div to - * accept block children. - */ - - print_otag(h, TAG_DIV, "css?hl", cattr, "display", "inline", 1); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_DIV, "c", cattr); return 1; } @@ -1501,9 +1423,8 @@ mdoc_ms_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); - print_otag(h, TAG_B, "cTi", "Ms", id); - free(id); + print_otag(h, TAG_A, "chR", "permalink", id); + print_otag(h, TAG_SPAN, "cTi", "Ms", id); return 1; } @@ -1542,9 +1463,8 @@ mdoc_no_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_SPAN, "ci", "No", id); - free(id); return 1; } @@ -1554,9 +1474,8 @@ mdoc_li_pre(MDOC_ARGS) char *id; if ((id = cond_id(n)) != NULL) - print_otag(h, TAG_A, "chR", "selflink", id); + print_otag(h, TAG_A, "chR", "permalink", id); print_otag(h, TAG_CODE, "ci", "Li", id); - free(id); return 1; } @@ -1712,7 +1631,8 @@ mdoc_quote_pre(MDOC_ARGS) case MDOC_Op: print_text(h, "\\(lB"); h->flags |= HTML_NOSPACE; - print_otag(h, TAG_SPAN, "c", "Op"); + /* Cannot use TAG_SPAN because it may contain blocks. */ + print_otag(h, TAG_IDIV, "c", "Op"); break; case MDOC_En: if (NULL == n->norm->Es || diff --git a/contrib/mdocml/mdoc_macro.c b/contrib/mandoc/mdoc_macro.c similarity index 100% rename from contrib/mdocml/mdoc_macro.c rename to contrib/mandoc/mdoc_macro.c diff --git a/contrib/mdocml/mdoc_man.c b/contrib/mandoc/mdoc_man.c similarity index 98% rename from contrib/mdocml/mdoc_man.c rename to contrib/mandoc/mdoc_man.c index cf552ce902b..bcf9207f79c 100644 --- a/contrib/mdocml/mdoc_man.c +++ b/contrib/mandoc/mdoc_man.c @@ -1,6 +1,6 @@ -/* $Id: mdoc_man.c,v 1.122 2017/06/14 22:51:25 schwarze Exp $ */ +/* $Id: mdoc_man.c,v 1.126 2018/04/11 17:11:13 schwarze Exp $ */ /* - * Copyright (c) 2011-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2011-2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -202,8 +202,8 @@ static const struct manact __manacts[MDOC_MAX - MDOC_Dd] = { { NULL, pre_bk, post_bk, NULL, NULL }, /* Bx */ { NULL, pre_skip, NULL, NULL, NULL }, /* Db */ { NULL, NULL, NULL, NULL, NULL }, /* Dc */ - { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Do */ - { cond_body, pre_enc, post_enc, "\\(Lq", "\\(Rq" }, /* Dq */ + { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Do */ + { cond_body, pre_enc, post_enc, "\\(lq", "\\(rq" }, /* Dq */ { NULL, NULL, NULL, NULL, NULL }, /* Ec */ { NULL, NULL, NULL, NULL, NULL }, /* Ef */ { NULL, pre_em, post_font, NULL, NULL }, /* Em */ @@ -610,6 +610,14 @@ man_mdoc(void *arg, const struct roff_man *mdoc) { struct roff_node *n; + printf(".\\\" Automatically generated from an mdoc input file." + " Do not edit.\n"); + for (n = mdoc->first->child; n != NULL; n = n->next) { + if (n->type != ROFFT_COMMENT) + break; + printf(".\\\"%s\n", n->string); + } + printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"\n", mdoc->meta.title, (mdoc->meta.msec == NULL ? "" : mdoc->meta.msec), @@ -624,7 +632,7 @@ man_mdoc(void *arg, const struct roff_man *mdoc) fontqueue.head = fontqueue.tail = mandoc_malloc(8); *fontqueue.tail = 'R'; } - for (n = mdoc->first->child; n != NULL; n = n->next) + for (; n != NULL; n = n->next) print_node(&mdoc->meta, n); putchar('\n'); } @@ -1408,7 +1416,7 @@ pre_it(DECL_ARGS) if (bln->norm->Bl.type == LIST_diag) print_line(".B \"", 0); else - print_line(".R \"", 0); + print_line(".BR \\& \"", 0); outflags &= ~MMAN_spc; return 1; case LIST_bullet: @@ -1547,7 +1555,6 @@ static int pre_lk(DECL_ARGS) { const struct roff_node *link, *descr, *punct; - int display; if ((link = n->child) == NULL) return 0; @@ -1570,12 +1577,6 @@ pre_lk(DECL_ARGS) } /* Link target. */ - display = man_strlen(link->string) >= 26; - if (display) { - print_line(".RS", MMAN_Bk_susp); - print_word("6n"); - outflags |= MMAN_nl; - } font_push('B'); print_word(link->string); font_pop(); @@ -1585,8 +1586,6 @@ pre_lk(DECL_ARGS) print_word(punct->string); punct = punct->next; } - if (display) - print_line(".RE", MMAN_nl); return 0; } diff --git a/contrib/mdocml/mdoc_markdown.c b/contrib/mandoc/mdoc_markdown.c similarity index 99% rename from contrib/mdocml/mdoc_markdown.c rename to contrib/mandoc/mdoc_markdown.c index 0b0f184821e..e73440a4e5c 100644 --- a/contrib/mdocml/mdoc_markdown.c +++ b/contrib/mandoc/mdoc_markdown.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_markdown.c,v 1.23 2017/06/14 01:31:26 schwarze Exp $ */ +/* $Id: mdoc_markdown.c,v 1.24 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org> * @@ -294,7 +294,7 @@ md_node(struct roff_node *n) const struct md_act *act; int cond, process_children; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; if (outflags & MD_nonl) diff --git a/contrib/mdocml/mdoc_state.c b/contrib/mandoc/mdoc_state.c similarity index 94% rename from contrib/mdocml/mdoc_state.c rename to contrib/mandoc/mdoc_state.c index d9cad18b105..2d8563f5bf1 100644 --- a/contrib/mdocml/mdoc_state.c +++ b/contrib/mandoc/mdoc_state.c @@ -1,4 +1,4 @@ -/* $Id: mdoc_state.c,v 1.8 2017/05/05 15:17:32 schwarze Exp $ */ +/* $Id: mdoc_state.c,v 1.9 2017/11/29 20:05:33 schwarze Exp $ */ /* * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> * @@ -208,19 +208,24 @@ state_bd(STATE_ARGS) static void state_bl(STATE_ARGS) { + struct mdoc_arg *args; + size_t i; if (n->type != ROFFT_HEAD || n->parent->args == NULL) return; - switch(n->parent->args->argv[0].arg) { - case MDOC_Diag: - n->norm->Bl.type = LIST_diag; - break; - case MDOC_Column: - n->norm->Bl.type = LIST_column; - break; - default: - break; + args = n->parent->args; + for (i = 0; i < args->argc; i++) { + switch(args->argv[i].arg) { + case MDOC_Diag: + n->norm->Bl.type = LIST_diag; + return; + case MDOC_Column: + n->norm->Bl.type = LIST_column; + return; + default: + break; + } } } diff --git a/contrib/mdocml/mdoc_term.c b/contrib/mandoc/mdoc_term.c similarity index 98% rename from contrib/mdocml/mdoc_term.c rename to contrib/mandoc/mdoc_term.c index 4e420c5c211..cf3e7ef3dd6 100644 --- a/contrib/mdocml/mdoc_term.c +++ b/contrib/mandoc/mdoc_term.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_term.c,v 1.364 2017/06/14 17:51:15 schwarze Exp $ */ +/* $Id: mdoc_term.c,v 1.367 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010, 2012-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010, 2012-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2013 Franco Fichtner <franco@lastsummer.de> * * Permission to use, copy, modify, and distribute this software for any @@ -283,7 +283,9 @@ terminal_mdoc(void *arg, const struct roff_man *mdoc) p->defindent = 5; term_begin(p, print_mdoc_head, print_mdoc_foot, &mdoc->meta); - while (n != NULL && n->flags & NODE_NOPRT) + while (n != NULL && + (n->type == ROFFT_COMMENT || + n->flags & NODE_NOPRT)) n = n->next; if (n != NULL) { if (n->tok != MDOC_Sh) @@ -312,7 +314,7 @@ print_mdoc_node(DECL_ARGS) struct termpair npair; size_t offset, rmargin; - if (n->flags & NODE_NOPRT) + if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) return; chld = 1; @@ -567,7 +569,9 @@ print_bvspace(struct termp *p, /* Do not vspace directly after Ss/Sh. */ nn = n; - while (nn->prev != NULL && nn->prev->flags & NODE_NOPRT) + while (nn->prev != NULL && + (nn->prev->type == ROFFT_COMMENT || + nn->prev->flags & NODE_NOPRT)) nn = nn->prev; while (nn->prev == NULL) { do { @@ -1550,7 +1554,8 @@ termp_ss_pre(DECL_ARGS) case ROFFT_BLOCK: term_newln(p); for (nn = n->prev; nn != NULL; nn = nn->prev) - if ((nn->flags & NODE_NOPRT) == 0) + if (nn->type != ROFFT_COMMENT && + (nn->flags & NODE_NOPRT) == 0) break; if (nn != NULL) term_vspace(p); @@ -1664,7 +1669,7 @@ termp_quote_pre(DECL_ARGS) /* FALLTHROUGH */ case MDOC_Do: case MDOC_Dq: - term_word(p, "\\(Lq"); + term_word(p, "\\(lq"); break; case MDOC_En: if (NULL == n->norm->Es || @@ -1722,7 +1727,7 @@ termp_quote_post(DECL_ARGS) /* FALLTHROUGH */ case MDOC_Do: case MDOC_Dq: - term_word(p, "\\(Rq"); + term_word(p, "\\(rq"); break; case MDOC_En: if (n->norm->Es == NULL || @@ -1940,7 +1945,6 @@ static int termp_lk_pre(DECL_ARGS) { const struct roff_node *link, *descr, *punct; - int display; if ((link = n->child) == NULL) return 0; @@ -1966,11 +1970,6 @@ termp_lk_pre(DECL_ARGS) } /* Link target. */ - display = term_strlen(p, link->string) >= 26; - if (display) { - term_newln(p); - p->tcol->offset += term_len(p, p->defindent + 1); - } term_fontpush(p, TERMFONT_BOLD); term_word(p, link->string); term_fontpop(p); @@ -1981,8 +1980,6 @@ termp_lk_pre(DECL_ARGS) term_word(p, punct->string); punct = punct->next; } - if (display) - term_newln(p); return 0; } diff --git a/contrib/mdocml/mdoc_validate.c b/contrib/mandoc/mdoc_validate.c similarity index 96% rename from contrib/mdocml/mdoc_validate.c rename to contrib/mandoc/mdoc_validate.c index 3a9b86f3fd2..b36d3c0a926 100644 --- a/contrib/mdocml/mdoc_validate.c +++ b/contrib/mandoc/mdoc_validate.c @@ -1,7 +1,7 @@ -/* $Id: mdoc_validate.c,v 1.352 2017/08/02 13:29:04 schwarze Exp $ */ +/* $Id: mdoc_validate.c,v 1.360 2018/08/01 16:00:58 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -53,10 +53,11 @@ enum check_ineq { typedef void (*v_post)(POST_ARGS); static int build_list(struct roff_man *, int); -static void check_text(struct roff_man *, int, int, char *); static void check_argv(struct roff_man *, struct roff_node *, struct mdoc_argv *); static void check_args(struct roff_man *, struct roff_node *); +static void check_text(struct roff_man *, int, int, char *); +static void check_text_em(struct roff_man *, int, int, char *); static void check_toptext(struct roff_man *, int, int, const char *); static int child_an(const struct roff_node *); static size_t macro2len(enum roff_tok); @@ -169,12 +170,12 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_hyph, /* %T */ /* FIXME: can be used outside Rs/Re. */ NULL, /* %V */ NULL, /* Ac */ - post_delim_nb, /* Ao */ + NULL, /* Ao */ post_delim_nb, /* Aq */ post_at, /* At */ NULL, /* Bc */ post_bf, /* Bf */ - post_delim_nb, /* Bo */ + NULL, /* Bo */ NULL, /* Bq */ post_xx, /* Bsx */ post_bx, /* Bx */ @@ -194,16 +195,16 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_xx, /* Ox */ NULL, /* Pc */ NULL, /* Pf */ - post_delim_nb, /* Po */ + NULL, /* Po */ post_delim_nb, /* Pq */ NULL, /* Qc */ post_delim_nb, /* Ql */ - post_delim_nb, /* Qo */ + NULL, /* Qo */ post_delim_nb, /* Qq */ NULL, /* Re */ post_rs, /* Rs */ NULL, /* Sc */ - post_delim_nb, /* So */ + NULL, /* So */ post_delim_nb, /* Sq */ post_sm, /* Sm */ post_sx, /* Sx */ @@ -214,7 +215,7 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { NULL, /* Xo */ post_fo, /* Fo */ NULL, /* Fc */ - post_delim_nb, /* Oo */ + NULL, /* Oo */ NULL, /* Oc */ post_bk, /* Bk */ NULL, /* Ek */ @@ -227,7 +228,7 @@ static const v_post __mdoc_valids[MDOC_MAX - MDOC_Dd] = { post_delim_nb, /* Lk */ post_defaults, /* Mt */ post_delim_nb, /* Brq */ - post_delim_nb, /* Bro */ + NULL, /* Bro */ NULL, /* Brc */ NULL, /* %C */ post_es, /* Es */ @@ -288,7 +289,7 @@ static const char * const secnames[SEC__MAX] = { void mdoc_node_validate(struct roff_man *mdoc) { - struct roff_node *n; + struct roff_node *n, *np; const v_post *p; n = mdoc->last; @@ -305,15 +306,21 @@ mdoc_node_validate(struct roff_man *mdoc) mdoc->next = ROFF_NEXT_SIBLING; switch (n->type) { case ROFFT_TEXT: + np = n->parent; if (n->sec != SEC_SYNOPSIS || - (n->parent->tok != MDOC_Cd && n->parent->tok != MDOC_Fd)) + (np->tok != MDOC_Cd && np->tok != MDOC_Fd)) check_text(mdoc, n->line, n->pos, n->string); - if (n->parent->tok == MDOC_It || - (n->parent->type == ROFFT_BODY && - (n->parent->tok == MDOC_Sh || - n->parent->tok == MDOC_Ss))) + if (np->tok != MDOC_Ql && np->tok != MDOC_Dl && + (np->tok != MDOC_Bd || + (mdoc->flags & MDOC_LITERAL) == 0) && + (np->tok != MDOC_It || np->type != ROFFT_HEAD || + np->parent->parent->norm->Bl.type != LIST_diag)) + check_text_em(mdoc, n->line, n->pos, n->string); + if (np->tok == MDOC_It || (np->type == ROFFT_BODY && + (np->tok == MDOC_Sh || np->tok == MDOC_Ss))) check_toptext(mdoc, n->line, n->pos, n->string); break; + case ROFFT_COMMENT: case ROFFT_EQN: case ROFFT_TBL: break; @@ -394,6 +401,57 @@ check_text(struct roff_man *mdoc, int ln, int pos, char *p) ln, pos + (int)(p - cp), NULL); } +static void +check_text_em(struct roff_man *mdoc, int ln, int pos, char *p) +{ + const struct roff_node *np, *nn; + char *cp; + + np = mdoc->last->prev; + nn = mdoc->last->next; + + /* Look for em-dashes wrongly encoded as "--". */ + + for (cp = p; *cp != '\0'; cp++) { + if (cp[0] != '-' || cp[1] != '-') + continue; + cp++; + + /* Skip input sequences of more than two '-'. */ + + if (cp[1] == '-') { + while (cp[1] == '-') + cp++; + continue; + } + + /* Skip "--" directly attached to something else. */ + + if ((cp - p > 1 && cp[-2] != ' ') || + (cp[1] != '\0' && cp[1] != ' ')) + continue; + + /* Require a letter right before or right afterwards. */ + + if ((cp - p > 2 ? + isalpha((unsigned char)cp[-3]) : + np != NULL && + np->type == ROFFT_TEXT && + *np->string != '\0' && + isalpha((unsigned char)np->string[ + strlen(np->string) - 1])) || + (cp[1] != '\0' && cp[2] != '\0' ? + isalpha((unsigned char)cp[2]) : + nn != NULL && + nn->type == ROFFT_TEXT && + isalpha((unsigned char)*nn->string))) { + mandoc_msg(MANDOCERR_DASHDASH, mdoc->parse, + ln, pos + (int)(cp - p) - 1, NULL); + break; + } + } +} + static void check_toptext(struct roff_man *mdoc, int ln, int pos, const char *p) { @@ -530,8 +588,7 @@ post_delim_nb(POST_ARGS) /* At least three alphabetic words with a sentence ending. */ if (strchr("!.:?", *lc) != NULL && (tok == MDOC_Em || - tok == MDOC_Li || tok == MDOC_Po || tok == MDOC_Pq || - tok == MDOC_Sy)) { + tok == MDOC_Li || tok == MDOC_Pq || tok == MDOC_Sy)) { nw = 0; for (cp = lc - 1; cp >= nch->string; cp--) { if (*cp == ' ') { @@ -947,10 +1004,10 @@ post_lb(POST_ARGS) roff_word_alloc(mdoc, n->line, n->pos, "library"); mdoc->last->flags = NODE_NOSRC; - roff_word_alloc(mdoc, n->line, n->pos, "\\(Lq"); + roff_word_alloc(mdoc, n->line, n->pos, "\\(lq"); mdoc->last->flags = NODE_DELIMO | NODE_NOSRC; mdoc->last = mdoc->last->next; - roff_word_alloc(mdoc, n->line, n->pos, "\\(Rq"); + roff_word_alloc(mdoc, n->line, n->pos, "\\(rq"); mdoc->last->flags = NODE_DELIMC | NODE_NOSRC; mdoc->last = n; } @@ -1914,7 +1971,10 @@ post_root(POST_ARGS) arch++; if (*arch == NULL) { n = mdoc->first->child; - while (n->tok != MDOC_Dt) + while (n->tok != MDOC_Dt || + n->child == NULL || + n->child->next == NULL || + n->child->next->next == NULL) n = n->next; n = n->child->next->next; mandoc_vmsg(MANDOCERR_ARCH_BAD, @@ -1928,8 +1988,10 @@ post_root(POST_ARGS) /* Check that we begin with a proper `Sh'. */ n = mdoc->first->child; - while (n != NULL && n->tok >= MDOC_Dd && - mdoc_macros[n->tok].flags & MDOC_PROLOGUE) + while (n != NULL && + (n->type == ROFFT_COMMENT || + (n->tok >= MDOC_Dd && + mdoc_macros[n->tok].flags & MDOC_PROLOGUE))) n = n->next; if (n == NULL) diff --git a/contrib/mdocml/msec.c b/contrib/mandoc/msec.c similarity index 100% rename from contrib/mdocml/msec.c rename to contrib/mandoc/msec.c diff --git a/contrib/mdocml/msec.in b/contrib/mandoc/msec.in similarity index 100% rename from contrib/mdocml/msec.in rename to contrib/mandoc/msec.in diff --git a/contrib/mdocml/out.c b/contrib/mandoc/out.c similarity index 100% rename from contrib/mdocml/out.c rename to contrib/mandoc/out.c diff --git a/contrib/mdocml/out.h b/contrib/mandoc/out.h similarity index 92% rename from contrib/mdocml/out.h rename to contrib/mandoc/out.h index f6aceb9c13f..9f0a541d5df 100644 --- a/contrib/mdocml/out.h +++ b/contrib/mandoc/out.h @@ -1,4 +1,4 @@ -/* $Id: out.h,v 1.31 2017/06/27 18:25:02 schwarze Exp $ */ +/* $Id: out.h,v 1.32 2018/06/25 16:54:59 schwarze Exp $ */ /* * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -54,11 +54,6 @@ struct rofftbl { void *arg; /* passed to sulen, slen, and len */ }; -#define SCALE_VS_INIT(p, v) \ - do { (p)->unit = SCALE_VS; \ - (p)->scale = (v); } \ - while (/* CONSTCOND */ 0) - #define SCALE_HS_INIT(p, v) \ do { (p)->unit = SCALE_EN; \ (p)->scale = (v); } \ diff --git a/contrib/mdocml/preconv.c b/contrib/mandoc/preconv.c similarity index 100% rename from contrib/mdocml/preconv.c rename to contrib/mandoc/preconv.c diff --git a/contrib/mdocml/predefs.in b/contrib/mandoc/predefs.in similarity index 100% rename from contrib/mdocml/predefs.in rename to contrib/mandoc/predefs.in diff --git a/contrib/mdocml/read.c b/contrib/mandoc/read.c similarity index 95% rename from contrib/mdocml/read.c rename to contrib/mandoc/read.c index 1af1b283638..0a583445f2c 100644 --- a/contrib/mdocml/read.c +++ b/contrib/mandoc/read.c @@ -1,7 +1,7 @@ -/* $Id: read.c,v 1.192 2017/07/20 14:36:36 schwarze Exp $ */ +/* $Id: read.c,v 1.196 2018/07/28 18:34:15 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> * Copyright (c) 2010, 2012 Joerg Sonnenberger <joerg@netbsd.org> * * Permission to use, copy, modify, and distribute this software for any @@ -94,9 +94,10 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "generic style suggestion", "legacy man(7) date format", + "normalizing date format to", "lower case character in document title", "duplicate RCS id", - "typo in section name", + "possible typo in section name", "unterminated quoted argument", "useless macro", "consider using OS macro", @@ -106,6 +107,7 @@ static const char * const mandocerrs[MANDOCERR_MAX] = { "no blank before trailing delimiter", "fill mode already enabled, skipping", "fill mode already disabled, skipping", + "verbatim \"--\", maybe consider using \\(em", "function name without markup", "whitespace at end of input line", "bad comment style", @@ -556,6 +558,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd, gzFile gz; size_t off; ssize_t ssz; + int gzerrnum, retval; if (fstat(fd, &st) == -1) { mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, @@ -583,9 +586,22 @@ read_whole_file(struct mparse *curp, const char *file, int fd, } if (curp->gzip) { + /* + * Duplicating the file descriptor is required + * because we will have to call gzclose(3) + * to free memory used internally by zlib, + * but that will also close the file descriptor, + * which this function must not do. + */ + if ((fd = dup(fd)) == -1) { + mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, + "dup: %s", strerror(errno)); + return 0; + } if ((gz = gzdopen(fd, "rb")) == NULL) { mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "gzdopen: %s", strerror(errno)); + close(fd); return 0; } } else @@ -598,6 +614,7 @@ read_whole_file(struct mparse *curp, const char *file, int fd, *with_mmap = 0; off = 0; + retval = 0; fb->sz = 0; fb->buf = NULL; for (;;) { @@ -614,19 +631,29 @@ read_whole_file(struct mparse *curp, const char *file, int fd, read(fd, fb->buf + (int)off, fb->sz - off); if (ssz == 0) { fb->sz = off; - return 1; + retval = 1; + break; } if (ssz == -1) { - mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, - "read: %s", strerror(errno)); + if (curp->gzip) + (void)gzerror(gz, &gzerrnum); + mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "read: %s", + curp->gzip && gzerrnum != Z_ERRNO ? + zError(gzerrnum) : strerror(errno)); break; } off += (size_t)ssz; } - free(fb->buf); - fb->buf = NULL; - return 0; + if (curp->gzip && (gzerrnum = gzclose(gz)) != Z_OK) + mandoc_vmsg(MANDOCERR_FILE, curp, 0, 0, "gzclose: %s", + gzerrnum == Z_ERRNO ? strerror(errno) : + zError(gzerrnum)); + if (retval == 0) { + free(fb->buf); + fb->buf = NULL; + } + return retval; } static void diff --git a/contrib/mdocml/roff.7 b/contrib/mandoc/roff.7 similarity index 98% rename from contrib/mdocml/roff.7 rename to contrib/mandoc/roff.7 index 74780e9a770..8cb922c7067 100644 --- a/contrib/mdocml/roff.7 +++ b/contrib/mandoc/roff.7 @@ -1,7 +1,7 @@ -.\" $Id: roff.7,v 1.94 2017/07/05 12:25:17 schwarze Exp $ +.\" $Id: roff.7,v 1.96 2018/04/10 00:52:30 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv> -.\" Copyright (c) 2010,2011,2013-2015,2017 Ingo Schwarze <schwarze@openbsd.org> +.\" Copyright (c) 2010-2018 Ingo Schwarze <schwarze@openbsd.org> .\" .\" Permission to use, copy, modify, and distribute this software for any .\" purpose with or without fee is hereby granted, provided that the above @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 5 2017 $ +.Dd $Mdocdate: April 10 2018 $ .Dt ROFF 7 .Os .Sh NAME @@ -1348,7 +1348,7 @@ Currently unsupported. .It Ic \&nop Ar body Execute the rest of the input line as a request or macro line. Currently unsupported. -.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression +.It Ic \&nr Ar register Oo Cm + Ns | Ns Cm - Oc Ns Ar expression Op Ar stepsize Define or change a register. A register is an arbitrary string value that defines some sort of state, which influences parsing and/or formatting. @@ -1360,6 +1360,14 @@ below. If it is prefixed by a sign, the register will be incremented or decremented instead of assigned to. .Pp +The +.Ar stepsize +is used by the +.Ic \en+ +auto-increment feature. +It remains unchanged when omitted while changing an existing register, +and it defaults to 0 when defining a new register. +.Pp The following .Ar register is handled specially: @@ -1471,7 +1479,7 @@ This is a groff extension and currently ignored. .It Ic \&rchar Ar glyph ... Remove glyph definitions. Currently unsupported. -.It Ic \&rd Op Ar prompt Op Ar agument ... +.It Ic \&rd Op Ar prompt Op Ar argument ... Read from standard input. Currently ignored. .It Ic \&recursionlimit Ar maxrec maxtail @@ -1996,13 +2004,19 @@ and Character .Ar number on the current font. -.Ss \en Ns Bq Ar name +.Ss \en Ns Oo +|- Oc Ns Bq Ar name Interpolate the number register .Ar name . For short names, there are variants .No \en Ns Ar c and .No \en( Ns Ar cc . +If the optional sign is specified, +the register is first incremented or decremented by the +.Ar stepsize +that was specified in the relevant +.Ic \&nr +request, and the changed value is interpolated. .Ss \eo\(aq Ns Ar string Ns \(aq Overstrike, writing all the characters contained in the .Ar string diff --git a/contrib/mdocml/roff.c b/contrib/mandoc/roff.c similarity index 95% rename from contrib/mdocml/roff.c rename to contrib/mandoc/roff.c index e2e498da0ce..86e145e3668 100644 --- a/contrib/mdocml/roff.c +++ b/contrib/mandoc/roff.c @@ -1,7 +1,7 @@ -/* $Id: roff.c,v 1.324 2017/07/14 17:16:16 schwarze Exp $ */ +/* $Id: roff.c,v 1.329 2018/08/01 15:40:17 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2010-2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -46,6 +46,7 @@ #define ROFFDEF_STD (1 << 4) /* mdoc(7) or man(7) macro. */ #define ROFFDEF_ANY (ROFFDEF_USER | ROFFDEF_PRE | \ ROFFDEF_REN | ROFFDEF_STD) +#define ROFFDEF_UNDEF (1 << 5) /* Completely undefined. */ /* --- data types --------------------------------------------------------- */ @@ -72,6 +73,7 @@ struct roffkv { struct roffreg { struct roffstr key; int val; + int step; struct roffreg *next; }; @@ -181,11 +183,11 @@ static void roff_freestr(struct roffkv *); static size_t roff_getname(struct roff *, char **, int, int); static int roff_getnum(const char *, int *, int *, int); static int roff_getop(const char *, int *, char *); -static int roff_getregn(const struct roff *, - const char *, size_t); +static int roff_getregn(struct roff *, + const char *, size_t, char); static int roff_getregro(const struct roff *, const char *name); -static const char *roff_getstrn(const struct roff *, +static const char *roff_getstrn(struct roff *, const char *, size_t, int *); static int roff_hasregn(const struct roff *, const char *, size_t); @@ -206,6 +208,8 @@ static enum rofferr roff_res(struct roff *, struct buf *, int, int); static enum rofferr roff_rm(ROFF_ARGS); static enum rofferr roff_rn(ROFF_ARGS); static enum rofferr roff_rr(ROFF_ARGS); +static void roff_setregn(struct roff *, const char *, + size_t, int, char, int); static void roff_setstr(struct roff *, const char *, const char *, int); static void roff_setstrn(struct roffkv **, const char *, @@ -758,7 +762,7 @@ roff_alloc(struct mparse *parse, int options) r = mandoc_calloc(1, sizeof(struct roff)); r->parse = parse; - r->reqtab = roffhash_alloc(0, ROFF_USERDEF); + r->reqtab = roffhash_alloc(0, ROFF_RENAMED); r->options = options; r->format = options & (MPARSE_MDOC | MPARSE_MAN); r->rstackpos = -1; @@ -1118,8 +1122,10 @@ static enum rofferr roff_res(struct roff *r, struct buf *buf, int ln, int pos) { char ubuf[24]; /* buffer to print the number */ + struct roff_node *n; /* used for header comments */ const char *start; /* start of the string to process */ char *stesc; /* start of an escape sequence ('\\') */ + char *ep; /* end of comment string */ const char *stnam; /* start of the name, after "[(*" */ const char *cp; /* end of the name, e.g. before ']' */ const char *res; /* the string to be substituted */ @@ -1134,6 +1140,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) int done; /* no more input available */ int deftype; /* type of definition to paste */ int rcsid; /* kind of RCS id seen */ + char sign; /* increment number register */ char term; /* character terminating the escape */ /* Search forward for comments. */ @@ -1168,14 +1175,35 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) /* Handle trailing whitespace. */ - cp = strchr(stesc--, '\0') - 1; - if (*cp == '\n') { + ep = strchr(stesc--, '\0') - 1; + if (*ep == '\n') { done = 1; - cp--; + ep--; } - if (*cp == ' ' || *cp == '\t') + if (*ep == ' ' || *ep == '\t') mandoc_msg(MANDOCERR_SPACE_EOL, r->parse, - ln, cp - buf->buf, NULL); + ln, ep - buf->buf, NULL); + + /* + * Save comments preceding the title macro + * in the syntax tree. + */ + + if (r->format == 0) { + while (*ep == ' ' || *ep == '\t') + ep--; + ep[1] = '\0'; + n = roff_node_alloc(r->man, + ln, stesc + 1 - buf->buf, + ROFFT_COMMENT, TOKEN_NONE); + n->string = mandoc_strdup(stesc + 2); + roff_node_append(r->man, n); + n->flags |= NODE_VALID | NODE_ENDED; + r->man->next = ROFF_NEXT_SIBLING; + } + + /* Discard comments. */ + while (stesc > start && stesc[-1] == ' ') stesc--; *stesc = '\0'; @@ -1244,6 +1272,9 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) term = cp[1]; /* FALLTHROUGH */ case 'n': + sign = cp[1]; + if (sign == '+' || sign == '-') + cp++; res = ubuf; break; default: @@ -1348,7 +1379,7 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos) case 'n': if (arg_complete) (void)snprintf(ubuf, sizeof(ubuf), "%d", - roff_getregn(r, stnam, naml)); + roff_getregn(r, stnam, naml, sign)); else ubuf[0] = '\0'; break; @@ -1639,6 +1670,11 @@ roff_parse(struct roff *r, char *buf, int *pos, int ln, int ppos) } if (t != TOKEN_NONE) *pos = cp - buf; + else if (deftype == ROFFDEF_UNDEF) { + /* Using an undefined macro defines it to be empty. */ + roff_setstrn(&r->strtab, mac, maclen, "", 0, 0); + roff_setstrn(&r->rentab, mac, maclen, NULL, 0, 0); + } return t; } @@ -2514,21 +2550,30 @@ roff_evalnum(struct roff *r, int ln, const char *v, void roff_setreg(struct roff *r, const char *name, int val, char sign) +{ + roff_setregn(r, name, strlen(name), val, sign, INT_MIN); +} + +static void +roff_setregn(struct roff *r, const char *name, size_t len, + int val, char sign, int step) { struct roffreg *reg; /* Search for an existing register with the same name. */ reg = r->regtab; - while (reg && strcmp(name, reg->key.p)) + while (reg != NULL && (reg->key.sz != len || + strncmp(reg->key.p, name, len) != 0)) reg = reg->next; if (NULL == reg) { /* Create a new register. */ reg = mandoc_malloc(sizeof(struct roffreg)); - reg->key.p = mandoc_strdup(name); - reg->key.sz = strlen(name); + reg->key.p = mandoc_strndup(name, len); + reg->key.sz = len; reg->val = 0; + reg->step = 0; reg->next = r->regtab; r->regtab = reg; } @@ -2539,6 +2584,8 @@ roff_setreg(struct roff *r, const char *name, int val, char sign) reg->val -= val; else reg->val = val; + if (step != INT_MIN) + reg->step = step; } /* @@ -2572,26 +2619,13 @@ roff_getregro(const struct roff *r, const char *name) } int -roff_getreg(const struct roff *r, const char *name) +roff_getreg(struct roff *r, const char *name) { - struct roffreg *reg; - int val; - - if ('.' == name[0] && '\0' != name[1] && '\0' == name[2]) { - val = roff_getregro(r, name + 1); - if (-1 != val) - return val; - } - - for (reg = r->regtab; reg; reg = reg->next) - if (0 == strcmp(name, reg->key.p)) - return reg->val; - - return 0; + return roff_getregn(r, name, strlen(name), '\0'); } static int -roff_getregn(const struct roff *r, const char *name, size_t len) +roff_getregn(struct roff *r, const char *name, size_t len, char sign) { struct roffreg *reg; int val; @@ -2602,11 +2636,24 @@ roff_getregn(const struct roff *r, const char *name, size_t len) return val; } - for (reg = r->regtab; reg; reg = reg->next) + for (reg = r->regtab; reg; reg = reg->next) { if (len == reg->key.sz && - 0 == strncmp(name, reg->key.p, len)) + 0 == strncmp(name, reg->key.p, len)) { + switch (sign) { + case '+': + reg->val += reg->step; + break; + case '-': + reg->val -= reg->step; + break; + default: + break; + } return reg->val; + } + } + roff_setregn(r, name, len, 0, '\0', INT_MIN); return 0; } @@ -2646,9 +2693,9 @@ roff_freereg(struct roffreg *reg) static enum rofferr roff_nr(ROFF_ARGS) { - char *key, *val; + char *key, *val, *step; size_t keysz; - int iv; + int iv, is, len; char sign; key = val = buf->buf + pos; @@ -2658,15 +2705,22 @@ roff_nr(ROFF_ARGS) keysz = roff_getname(r, &val, ln, pos); if (key[keysz] == '\\') return ROFF_IGN; - key[keysz] = '\0'; sign = *val; if (sign == '+' || sign == '-') val++; - if (roff_evalnum(r, ln, val, NULL, &iv, ROFFNUM_SCALE)) - roff_setreg(r, key, iv, sign); + len = 0; + if (roff_evalnum(r, ln, val, &len, &iv, ROFFNUM_SCALE) == 0) + return ROFF_IGN; + step = val + len; + while (isspace((unsigned char)*step)) + step++; + if (roff_evalnum(r, ln, step, NULL, &is, 0) == 0) + is = INT_MIN; + + roff_setregn(r, key, keysz, iv, sign, is); return ROFF_IGN; } @@ -2791,6 +2845,7 @@ roff_TE(ROFF_ARGS) free(buf->buf); buf->buf = mandoc_strdup(".sp"); buf->sz = 4; + *offs = 0; return ROFF_REPARSE; } r->tbl = NULL; @@ -3310,6 +3365,7 @@ roff_userdef(ROFF_ARGS) ln, (int)(cp - n1), NULL); free(buf->buf); buf->buf = n1; + *offs = 0; return ROFF_IGN; } @@ -3404,6 +3460,7 @@ roff_renamed(ROFF_ARGS) buf->buf[pos] == '\0' ? "" : " ", buf->buf + pos) + 1; free(buf->buf); buf->buf = nbuf; + *offs = 0; return ROFF_CONT; } @@ -3537,62 +3594,95 @@ roff_setstrn(struct roffkv **r, const char *name, size_t namesz, } static const char * -roff_getstrn(const struct roff *r, const char *name, size_t len, +roff_getstrn(struct roff *r, const char *name, size_t len, int *deftype) { const struct roffkv *n; - int i; + int found, i; enum roff_tok tok; - if (*deftype & ROFFDEF_USER) { - for (n = r->strtab; n != NULL; n = n->next) { - if (strncmp(name, n->key.p, len) == 0 && - n->key.p[len] == '\0' && - n->val.p != NULL) { - *deftype = ROFFDEF_USER; - return n->val.p; + found = 0; + for (n = r->strtab; n != NULL; n = n->next) { + if (strncmp(name, n->key.p, len) != 0 || + n->key.p[len] != '\0' || n->val.p == NULL) + continue; + if (*deftype & ROFFDEF_USER) { + *deftype = ROFFDEF_USER; + return n->val.p; + } else { + found = 1; + break; + } + } + for (n = r->rentab; n != NULL; n = n->next) { + if (strncmp(name, n->key.p, len) != 0 || + n->key.p[len] != '\0' || n->val.p == NULL) + continue; + if (*deftype & ROFFDEF_REN) { + *deftype = ROFFDEF_REN; + return n->val.p; + } else { + found = 1; + break; + } + } + for (i = 0; i < PREDEFS_MAX; i++) { + if (strncmp(name, predefs[i].name, len) != 0 || + predefs[i].name[len] != '\0') + continue; + if (*deftype & ROFFDEF_PRE) { + *deftype = ROFFDEF_PRE; + return predefs[i].str; + } else { + found = 1; + break; + } + } + if (r->man->macroset != MACROSET_MAN) { + for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) { + if (strncmp(name, roff_name[tok], len) != 0 || + roff_name[tok][len] != '\0') + continue; + if (*deftype & ROFFDEF_STD) { + *deftype = ROFFDEF_STD; + return NULL; + } else { + found = 1; + break; } } } - if (*deftype & ROFFDEF_PRE) { - for (i = 0; i < PREDEFS_MAX; i++) { - if (strncmp(name, predefs[i].name, len) == 0 && - predefs[i].name[len] == '\0') { - *deftype = ROFFDEF_PRE; - return predefs[i].str; + if (r->man->macroset != MACROSET_MDOC) { + for (tok = MAN_TH; tok < MAN_MAX; tok++) { + if (strncmp(name, roff_name[tok], len) != 0 || + roff_name[tok][len] != '\0') + continue; + if (*deftype & ROFFDEF_STD) { + *deftype = ROFFDEF_STD; + return NULL; + } else { + found = 1; + break; } } } - if (*deftype & ROFFDEF_REN) { - for (n = r->rentab; n != NULL; n = n->next) { - if (strncmp(name, n->key.p, len) == 0 && - n->key.p[len] == '\0' && - n->val.p != NULL) { - *deftype = ROFFDEF_REN; - return n->val.p; - } - } - } - if (*deftype & ROFFDEF_STD) { - if (r->man->macroset != MACROSET_MAN) { - for (tok = MDOC_Dd; tok < MDOC_MAX; tok++) { - if (strncmp(name, roff_name[tok], len) == 0 && - roff_name[tok][len] == '\0') { - *deftype = ROFFDEF_STD; - return NULL; - } - } - } - if (r->man->macroset != MACROSET_MDOC) { - for (tok = MAN_TH; tok < MAN_MAX; tok++) { - if (strncmp(name, roff_name[tok], len) == 0 && - roff_name[tok][len] == '\0') { - *deftype = ROFFDEF_STD; - return NULL; - } - } + + if (found == 0 && *deftype != ROFFDEF_ANY) { + if (*deftype & ROFFDEF_REN) { + /* + * This might still be a request, + * so do not treat it as undefined yet. + */ + *deftype = ROFFDEF_UNDEF; + return NULL; } + + /* Using an undefined string defines it to be empty. */ + + roff_setstrn(&r->strtab, name, len, "", 0, 0); + roff_setstrn(&r->rentab, name, len, NULL, 0, 0); } + *deftype = 0; return NULL; } diff --git a/contrib/mdocml/roff.h b/contrib/mandoc/roff.h similarity index 99% rename from contrib/mdocml/roff.h rename to contrib/mandoc/roff.h index 8b28d596097..f0da74bd9ac 100644 --- a/contrib/mdocml/roff.h +++ b/contrib/mandoc/roff.h @@ -1,4 +1,4 @@ -/* $Id: roff.h,v 1.58 2017/07/08 14:51:05 schwarze Exp $ */ +/* $Id: roff.h,v 1.59 2018/04/11 17:11:13 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2013, 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -61,6 +61,7 @@ enum roff_type { ROFFT_TAIL, ROFFT_ELEM, ROFFT_TEXT, + ROFFT_COMMENT, ROFFT_TBL, ROFFT_EQN }; diff --git a/contrib/mdocml/roff_html.c b/contrib/mandoc/roff_html.c similarity index 83% rename from contrib/mdocml/roff_html.c rename to contrib/mandoc/roff_html.c index 53ae6d7ca2d..6a06c0d8789 100644 --- a/contrib/mdocml/roff_html.c +++ b/contrib/mandoc/roff_html.c @@ -1,7 +1,7 @@ -/* $Id: roff_html.c,v 1.11 2017/06/24 14:38:33 schwarze Exp $ */ +/* $Id: roff_html.c,v 1.12 2018/06/25 14:53:58 schwarze Exp $ */ /* * Copyright (c) 2010 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -82,15 +82,5 @@ roff_html_pre_ce(ROFF_HTML_ARGS) static void roff_html_pre_sp(ROFF_HTML_ARGS) { - struct roffsu su; - - SCALE_VS_INIT(&su, 1); - if ((n = n->child) != NULL) { - if (a2roffsu(n->string, &su, SCALE_VS) == NULL) - su.scale = 1.0; - else if (su.scale < 0.0) - su.scale = 0.0; - } - print_otag(h, TAG_DIV, "suh", &su); - print_text(h, "\\~"); /* So the div isn't empty. */ + print_paragraph(h); } diff --git a/contrib/mdocml/roff_int.h b/contrib/mandoc/roff_int.h similarity index 100% rename from contrib/mdocml/roff_int.h rename to contrib/mandoc/roff_int.h diff --git a/contrib/mdocml/roff_term.c b/contrib/mandoc/roff_term.c similarity index 100% rename from contrib/mdocml/roff_term.c rename to contrib/mandoc/roff_term.c diff --git a/contrib/mdocml/roff_validate.c b/contrib/mandoc/roff_validate.c similarity index 100% rename from contrib/mdocml/roff_validate.c rename to contrib/mandoc/roff_validate.c diff --git a/contrib/mdocml/soelim.1 b/contrib/mandoc/soelim.1 similarity index 100% rename from contrib/mdocml/soelim.1 rename to contrib/mandoc/soelim.1 diff --git a/contrib/mdocml/soelim.c b/contrib/mandoc/soelim.c similarity index 100% rename from contrib/mdocml/soelim.c rename to contrib/mandoc/soelim.c diff --git a/contrib/mdocml/st.c b/contrib/mandoc/st.c similarity index 100% rename from contrib/mdocml/st.c rename to contrib/mandoc/st.c diff --git a/contrib/mdocml/st.in b/contrib/mandoc/st.in similarity index 82% rename from contrib/mdocml/st.in rename to contrib/mandoc/st.in index 39f597cff31..fefabdcf589 100644 --- a/contrib/mdocml/st.in +++ b/contrib/mandoc/st.in @@ -1,4 +1,4 @@ -/* $Id: st.in,v 1.29 2017/06/24 13:49:29 schwarze Exp $ */ +/* $Id: st.in,v 1.30 2018/04/05 09:17:26 schwarze Exp $ */ /* * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv> * @@ -60,19 +60,19 @@ LINE("-ansiC-89", "ANSI X3.159-1989 (\\(LqANSI\\~C89\\(Rq)") LINE("-ieee754", "IEEE Std 754-1985") LINE("-iso8802-3", "ISO 8802-3: 1989") LINE("-iso8601", "ISO 8601") -LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(LqOpen Firmware\\(Rq)") -LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(LqXPG3\\(Rq)") -LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(LqXPG4\\(Rq)") -LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(LqXPG4.2\\(Rq)") -LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(LqXBD5\\(Rq)") -LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(LqXCU5\\(Rq)") -LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(LqXSH4.2\\(Rq)") -LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(LqXSH5\\(Rq)") -LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(LqXNS5\\(Rq)") -LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(LqXNS5.2\\(Rq)") -LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(LqXCURSES4.2\\(Rq)") -LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(LqSUSv1\\(Rq)") -LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(LqSUSv2\\(Rq)") -LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(LqSUSv3\\(Rq)") -LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(LqSUSv4\\(Rq)") -LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(LqSVID4\\(Rq)") +LINE("-ieee1275-94", "IEEE Std 1275-1994 (\\(lqOpen Firmware\\(rq)") +LINE("-xpg3", "X/Open Portability Guide Issue\\~3 (\\(lqXPG3\\(rq)") +LINE("-xpg4", "X/Open Portability Guide Issue\\~4 (\\(lqXPG4\\(rq)") +LINE("-xpg4.2", "X/Open Portability Guide Issue\\~4, Version\\~2 (\\(lqXPG4.2\\(rq)") +LINE("-xbd5", "X/Open Base Definitions Issue\\~5 (\\(lqXBD5\\(rq)") +LINE("-xcu5", "X/Open Commands and Utilities Issue\\~5 (\\(lqXCU5\\(rq)") +LINE("-xsh4.2", "X/Open System Interfaces and Headers Issue\\~4, Version\\~2 (\\(lqXSH4.2\\(rq)") +LINE("-xsh5", "X/Open System Interfaces and Headers Issue\\~5 (\\(lqXSH5\\(rq)") +LINE("-xns5", "X/Open Networking Services Issue\\~5 (\\(lqXNS5\\(rq)") +LINE("-xns5.2", "X/Open Networking Services Issue\\~5.2 (\\(lqXNS5.2\\(rq)") +LINE("-xcurses4.2", "X/Open Curses Issue\\~4, Version\\~2 (\\(lqXCURSES4.2\\(rq)") +LINE("-susv1", "Version\\~1 of the Single UNIX Specification (\\(lqSUSv1\\(rq)") +LINE("-susv2", "Version\\~2 of the Single UNIX Specification (\\(lqSUSv2\\(rq)") +LINE("-susv3", "Version\\~3 of the Single UNIX Specification (\\(lqSUSv3\\(rq)") +LINE("-susv4", "Version\\~4 of the Single UNIX Specification (\\(lqSUSv4\\(rq)") +LINE("-svid4", "System\\~V Interface Definition, Fourth Edition (\\(lqSVID4\\(rq)") diff --git a/contrib/mdocml/tag.c b/contrib/mandoc/tag.c similarity index 98% rename from contrib/mdocml/tag.c rename to contrib/mandoc/tag.c index 21ac6b32e4d..c0832c4f74b 100644 --- a/contrib/mdocml/tag.c +++ b/contrib/mandoc/tag.c @@ -1,4 +1,4 @@ -/* $Id: tag.c,v 1.18 2017/02/17 14:31:52 schwarze Exp $ */ +/* $Id: tag.c,v 1.19 2018/02/23 16:47:10 schwarze Exp $ */ /* * Copyright (c) 2015, 2016 Ingo Schwarze <schwarze@openbsd.org> * @@ -213,6 +213,9 @@ tag_write(void) ohash_delete(&tag_data); if (stream != NULL) fclose(stream); + else + close(tag_files.tfd); + tag_files.tfd = -1; } void diff --git a/contrib/mdocml/tag.h b/contrib/mandoc/tag.h similarity index 100% rename from contrib/mdocml/tag.h rename to contrib/mandoc/tag.h diff --git a/contrib/mdocml/tbl.3 b/contrib/mandoc/tbl.3 similarity index 100% rename from contrib/mdocml/tbl.3 rename to contrib/mandoc/tbl.3 diff --git a/contrib/mdocml/tbl.7 b/contrib/mandoc/tbl.7 similarity index 98% rename from contrib/mdocml/tbl.7 rename to contrib/mandoc/tbl.7 index e2f84538370..3883b40904e 100644 --- a/contrib/mdocml/tbl.7 +++ b/contrib/mandoc/tbl.7 @@ -1,4 +1,4 @@ -.\" $Id: tbl.7,v 1.28 2017/06/28 00:59:57 schwarze Exp $ +.\" $Id: tbl.7,v 1.29 2017/10/17 23:19:12 schwarze Exp $ .\" .\" Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> .\" Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 28 2017 $ +.Dd $Mdocdate: October 17 2017 $ .Dt TBL 7 .Os .Sh NAME @@ -420,7 +420,9 @@ The GNU reimplementation of tbl, part of the groff package, was released in 1990 by James Clark. A standalone tbl implementation was written by Kristaps Dzonsons in 2010. -This formed the basis of the implementation that is part of the +This formed the basis of the implementation that first appeared in +.Ox 4.9 +as a part of the .Xr mandoc 1 utility. .Sh AUTHORS diff --git a/contrib/mdocml/tbl.c b/contrib/mandoc/tbl.c similarity index 100% rename from contrib/mdocml/tbl.c rename to contrib/mandoc/tbl.c diff --git a/contrib/mdocml/tbl_data.c b/contrib/mandoc/tbl_data.c similarity index 100% rename from contrib/mdocml/tbl_data.c rename to contrib/mandoc/tbl_data.c diff --git a/contrib/mdocml/tbl_html.c b/contrib/mandoc/tbl_html.c similarity index 93% rename from contrib/mdocml/tbl_html.c rename to contrib/mandoc/tbl_html.c index d59f1635d01..b87804fda35 100644 --- a/contrib/mdocml/tbl_html.c +++ b/contrib/mandoc/tbl_html.c @@ -1,4 +1,4 @@ -/* $Id: tbl_html.c,v 1.23 2017/07/31 16:14:10 schwarze Exp $ */ +/* $Id: tbl_html.c,v 1.24 2018/06/25 13:45:57 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -79,23 +79,14 @@ html_tbl_sulen(const struct roffsu *su, void *arg) static void html_tblopen(struct html *h, const struct tbl_span *sp) { - struct tag *t; - int ic; - if (h->tbl.cols == NULL) { h->tbl.len = html_tbl_len; h->tbl.slen = html_tbl_strlen; h->tbl.sulen = html_tbl_sulen; tblcalc(&h->tbl, sp, 0, 0); } - assert(NULL == h->tblt); h->tblt = print_otag(h, TAG_TABLE, "c", "tbl"); - - t = print_otag(h, TAG_COLGROUP, ""); - for (ic = 0; ic < sp->opts->cols; ic++) - print_otag(h, TAG_COL, "shw", h->tbl.cols[ic].width); - print_tagq(h, t); } void diff --git a/contrib/mdocml/tbl_layout.c b/contrib/mandoc/tbl_layout.c similarity index 100% rename from contrib/mdocml/tbl_layout.c rename to contrib/mandoc/tbl_layout.c diff --git a/contrib/mdocml/tbl_opts.c b/contrib/mandoc/tbl_opts.c similarity index 100% rename from contrib/mdocml/tbl_opts.c rename to contrib/mandoc/tbl_opts.c diff --git a/contrib/mdocml/tbl_term.c b/contrib/mandoc/tbl_term.c similarity index 100% rename from contrib/mdocml/tbl_term.c rename to contrib/mandoc/tbl_term.c diff --git a/contrib/mdocml/term.c b/contrib/mandoc/term.c similarity index 100% rename from contrib/mdocml/term.c rename to contrib/mandoc/term.c diff --git a/contrib/mdocml/term.h b/contrib/mandoc/term.h similarity index 100% rename from contrib/mdocml/term.h rename to contrib/mandoc/term.h diff --git a/contrib/mdocml/term_ascii.c b/contrib/mandoc/term_ascii.c similarity index 91% rename from contrib/mdocml/term_ascii.c rename to contrib/mandoc/term_ascii.c index e819c0ef8a8..f47ffd75d9c 100644 --- a/contrib/mdocml/term_ascii.c +++ b/contrib/mandoc/term_ascii.c @@ -1,7 +1,7 @@ -/* $Id: term_ascii.c,v 1.58 2017/06/14 14:24:20 schwarze Exp $ */ +/* $Id: term_ascii.c,v 1.61 2018/05/20 21:37:34 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> - * Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2014, 2015, 2017, 2018 Ingo Schwarze <schwarze@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -21,11 +21,13 @@ #include <assert.h> #if HAVE_WCHAR +#include <langinfo.h> #include <locale.h> #endif #include <stdint.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #if HAVE_WCHAR #include <wchar.h> @@ -100,7 +102,17 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) v = TERMENC_LOCALE == enc ? setlocale(LC_CTYPE, "") : setlocale(LC_CTYPE, UTF8_LOCALE); - if (NULL != v && MB_CUR_MAX > 1) { + + /* + * We only support UTF-8, + * so revert to ASCII for anything else. + */ + + if (v != NULL && + strcmp(nl_langinfo(CODESET), "UTF-8") != 0) + v = setlocale(LC_CTYPE, "C"); + + if (v != NULL && MB_CUR_MAX > 1) { p->enc = enc; p->advance = locale_advance; p->endline = locale_endline; @@ -121,6 +133,8 @@ ascii_init(enum termenc enc, const struct manoutput *outopts) if (outopts->synopsisonly) p->synopsisonly = 1; + assert(p->defindent < UINT16_MAX); + assert(p->defrmargin < UINT16_MAX); return p; } @@ -159,6 +173,8 @@ ascii_setwidth(struct termp *p, int iop, int width) p->defrmargin -= width; else p->defrmargin = 0; + if (p->defrmargin > 1000) + p->defrmargin = 1000; p->lastrmargin = p->tcol->rmargin; p->tcol->rmargin = p->maxrmargin = p->defrmargin; } @@ -227,6 +243,7 @@ ascii_advance(struct termp *p, size_t len) { size_t i; + assert(len < UINT16_MAX); for (i = 0; i < len; i++) putchar(' '); } @@ -294,17 +311,17 @@ ascii_uc2str(int uc) "<88>", "<89>", "<8A>", "<8B>", "<8C>", "<8D>", "<8E>", "<8F>", "<90>", "<91>", "<92>", "<93>", "<94>", "<95>", "<96>", "<97>", "<98>", "<99>", "<9A>", "<9B>", "<9C>", "<9D>", "<9E>", "<9F>", - nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<sec>", + nbrsp, "!", "/\bc", "GBP", "o\bx", "=\bY", "|", "<section>", "\"", "(C)", "_\ba", "<<", "~", "", "(R)", "-", - "<deg>","+-", "2", "3", "'", ",\bu", "<par>",".", - ",", "1", "_\bo", ">>", "1/4", "1/2", "3/4", "?", + "<degree>","+-","^2", "^3", "'","<micro>","<paragraph>",".", + ",", "^1", "_\bo", ">>", "1/4", "1/2", "3/4", "?", "`\bA", "'\bA", "^\bA", "~\bA", "\"\bA","o\bA", "AE", ",\bC", "`\bE", "'\bE", "^\bE", "\"\bE","`\bI", "'\bI", "^\bI", "\"\bI", - "-\bD", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x", + "Dh", "~\bN", "`\bO", "'\bO", "^\bO", "~\bO", "\"\bO","x", "/\bO", "`\bU", "'\bU", "^\bU", "\"\bU","'\bY", "Th", "ss", "`\ba", "'\ba", "^\ba", "~\ba", "\"\ba","o\ba", "ae", ",\bc", "`\be", "'\be", "^\be", "\"\be","`\bi", "'\bi", "^\bi", "\"\bi", - "d", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","-:-", + "dh", "~\bn", "`\bo", "'\bo", "^\bo", "~\bo", "\"\bo","/", "/\bo", "`\bu", "'\bu", "^\bu", "\"\bu","'\by", "th", "\"\by", "A", "a", "A", "a", "A", "a", "'\bC", "'\bc", "^\bC", "^\bc", "C", "c", "C", "c", "D", "d", @@ -364,6 +381,7 @@ locale_advance(struct termp *p, size_t len) { size_t i; + assert(len < UINT16_MAX); for (i = 0; i < len; i++) putwchar(L' '); } diff --git a/contrib/mdocml/term_ps.c b/contrib/mandoc/term_ps.c similarity index 89% rename from contrib/mdocml/term_ps.c rename to contrib/mandoc/term_ps.c index 9638ae4cb9a..2cd94c92315 100644 --- a/contrib/mdocml/term_ps.c +++ b/contrib/mandoc/term_ps.c @@ -1,7 +1,8 @@ -/* $Id: term_ps.c,v 1.85 2017/06/07 17:38:26 schwarze Exp $ */ +/* $Id: term_ps.c,v 1.91 2017/11/10 23:42:52 schwarze Exp $ */ /* * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org> + * Copyright (c) 2017 Marc Espie <espie@openbsd.org> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -66,6 +67,7 @@ struct termp_ps { size_t pscol; /* visible column (AFM units) */ size_t pscolnext; /* used for overstrike */ size_t psrow; /* visible row (AFM units) */ + size_t lastrow; /* psrow of the previous word */ char *psmarg; /* margin buf */ size_t psmargsz; /* margin buf size */ size_t psmargcur; /* cur index in margin buf */ @@ -77,6 +79,7 @@ struct termp_ps { size_t lineheight; /* line height (AFM units) */ size_t top; /* body top (AFM units) */ size_t bottom; /* body bottom (AFM units) */ + const char *medianame; /* for DocumentMedia and PageSize */ size_t height; /* page height (AFM units */ size_t width; /* page width (AFM units) */ size_t lastwidth; /* page width before last ll */ @@ -108,7 +111,7 @@ static void ps_printf(struct termp *, const char *, ...) static void ps_putchar(struct termp *, char); static void ps_setfont(struct termp *, enum termfont); static void ps_setwidth(struct termp *, int, int); -static struct termp *pspdf_alloc(const struct manoutput *); +static struct termp *pspdf_alloc(const struct manoutput *, enum termtype); static void pdf_obj(struct termp *, size_t); /* @@ -511,27 +514,17 @@ static const struct font fonts[TERMFONT__MAX] = { void * pdf_alloc(const struct manoutput *outopts) { - struct termp *p; - - if (NULL != (p = pspdf_alloc(outopts))) - p->type = TERMTYPE_PDF; - - return p; + return pspdf_alloc(outopts, TERMTYPE_PDF); } void * ps_alloc(const struct manoutput *outopts) { - struct termp *p; - - if (NULL != (p = pspdf_alloc(outopts))) - p->type = TERMTYPE_PS; - - return p; + return pspdf_alloc(outopts, TERMTYPE_PS); } static struct termp * -pspdf_alloc(const struct manoutput *outopts) +pspdf_alloc(const struct manoutput *outopts, enum termtype type) { struct termp *p; unsigned int pagex, pagey; @@ -541,6 +534,7 @@ pspdf_alloc(const struct manoutput *outopts) p = mandoc_calloc(1, sizeof(*p)); p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol)); p->maxtcol = 1; + p->type = type; p->enc = TERMENC_ASCII; p->fontq = mandoc_reallocarray(NULL, @@ -559,6 +553,7 @@ pspdf_alloc(const struct manoutput *outopts) /* Default to US letter (millimetres). */ + p->ps->medianame = "Letter"; pagex = 216; pagey = 279; @@ -570,20 +565,26 @@ pspdf_alloc(const struct manoutput *outopts) */ pp = outopts->paper; - if (pp && strcasecmp(pp, "letter")) { - if (0 == strcasecmp(pp, "a3")) { + if (pp != NULL && strcasecmp(pp, "letter") != 0) { + if (strcasecmp(pp, "a3") == 0) { + p->ps->medianame = "A3"; pagex = 297; pagey = 420; - } else if (0 == strcasecmp(pp, "a4")) { + } else if (strcasecmp(pp, "a4") == 0) { + p->ps->medianame = "A4"; pagex = 210; pagey = 297; - } else if (0 == strcasecmp(pp, "a5")) { + } else if (strcasecmp(pp, "a5") == 0) { + p->ps->medianame = "A5"; pagex = 148; pagey = 210; - } else if (0 == strcasecmp(pp, "legal")) { + } else if (strcasecmp(pp, "legal") == 0) { + p->ps->medianame = "Legal"; pagex = 216; pagey = 356; - } else if (2 != sscanf(pp, "%ux%u", &pagex, &pagey)) + } else if (sscanf(pp, "%ux%u", &pagex, &pagey) == 2) + p->ps->medianame = "CustomSize"; + else warnx("%s: Unknown paper", pp); } @@ -596,8 +597,8 @@ pspdf_alloc(const struct manoutput *outopts) /* Remember millimetres -> AFM units. */ - pagex = PNT2AFM(p, ((double)pagex * 2.834)); - pagey = PNT2AFM(p, ((double)pagey * 2.834)); + pagex = PNT2AFM(p, ((double)pagex * 72.0 / 25.4)); + pagey = PNT2AFM(p, ((double)pagey * 72.0 / 25.4)); /* Margins are 1/9 the page x and y. */ @@ -733,7 +734,7 @@ ps_closepage(struct termp *p) /* * Close out a page that we've already flushed to output. In - * PostScript, we simply note that the page must be showed. In + * PostScript, we simply note that the page must be shown. In * PDF, we must now create the Length, Resource, and Page node * for the page contents. */ @@ -742,8 +743,6 @@ ps_closepage(struct termp *p) ps_printf(p, "%s", p->ps->psmarg); if (TERMTYPE_PS != p->type) { - ps_printf(p, "ET\n"); - len = p->ps->pdfbytes - p->ps->pdflastpg; base = p->ps->pages * 4 + p->ps->pdfbody; @@ -759,7 +758,7 @@ ps_closepage(struct termp *p) ps_printf(p, "/Font <<\n"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, "/F%d %d 0 R\n", i, 3 + i); - ps_printf(p, ">>\n>>\n"); + ps_printf(p, ">>\n>>\nendobj\n"); /* Page node. */ pdf_obj(p, base + 3); @@ -824,7 +823,7 @@ ps_end(struct termp *p) ps_printf(p, "<<\n"); ps_printf(p, "/Type /Catalog\n"); ps_printf(p, "/Pages 2 0 R\n"); - ps_printf(p, ">>\n"); + ps_printf(p, ">>\nendobj\n"); xref = p->ps->pdfbytes; ps_printf(p, "xref\n"); ps_printf(p, "0 %zu\n", base + 1); @@ -848,6 +847,7 @@ ps_end(struct termp *p) static void ps_begin(struct termp *p) { + size_t width, height; int i; /* @@ -865,6 +865,7 @@ ps_begin(struct termp *p) p->ps->flags = PS_MARGINS; p->ps->pscol = p->ps->left; p->ps->psrow = p->ps->header; + p->ps->lastrow = 0; /* impossible row */ ps_setfont(p, TERMFONT_NONE); @@ -889,21 +890,44 @@ ps_begin(struct termp *p) */ if (TERMTYPE_PS == p->type) { + width = AFM2PNT(p, p->ps->width); + height = AFM2PNT(p, p->ps->height); + ps_printf(p, "%%!PS-Adobe-3.0\n"); ps_printf(p, "%%%%DocumentData: Clean7Bit\n"); ps_printf(p, "%%%%Orientation: Portrait\n"); ps_printf(p, "%%%%Pages: (atend)\n"); ps_printf(p, "%%%%PageOrder: Ascend\n"); - ps_printf(p, "%%%%DocumentMedia: " - "Default %zu %zu 0 () ()\n", - (size_t)AFM2PNT(p, p->ps->width), - (size_t)AFM2PNT(p, p->ps->height)); + ps_printf(p, "%%%%DocumentMedia: man-%s %zu %zu 0 () ()\n", + p->ps->medianame, width, height); ps_printf(p, "%%%%DocumentNeededResources: font"); for (i = 0; i < (int)TERMFONT__MAX; i++) ps_printf(p, " %s", fonts[i].name); - ps_printf(p, "\n%%%%EndComments\n"); + ps_printf(p, "\n%%%%DocumentSuppliedResources: " + "procset MandocProcs 1.0 0\n"); + ps_printf(p, "%%%%EndComments\n"); + ps_printf(p, "%%%%BeginProlog\n"); + ps_printf(p, "%%%%BeginResource: procset MandocProcs " + "10170 10170\n"); + /* The font size is effectively hard-coded for now. */ + ps_printf(p, "/fs %zu def\n", p->ps->scale); + for (i = 0; i < (int)TERMFONT__MAX; i++) + ps_printf(p, "/f%d { /%s fs selectfont } def\n", + i, fonts[i].name); + ps_printf(p, "/s { 3 1 roll moveto show } bind def\n"); + ps_printf(p, "/c { exch currentpoint exch pop " + "moveto show } bind def\n"); + ps_printf(p, "%%%%EndResource\n"); + ps_printf(p, "%%%%EndProlog\n"); + ps_printf(p, "%%%%BeginSetup\n"); + ps_printf(p, "%%%%BeginFeature: *PageSize %s\n", + p->ps->medianame); + ps_printf(p, "<</PageSize [%zu %zu]>>setpagedevice\n", + width, height); + ps_printf(p, "%%%%EndFeature\n"); + ps_printf(p, "%%%%EndSetup\n"); } else { ps_printf(p, "%%PDF-1.1\n"); pdf_obj(p, 1); @@ -918,7 +942,7 @@ ps_begin(struct termp *p) ps_printf(p, "/Subtype /Type1\n"); ps_printf(p, "/Name /F%d\n", i); ps_printf(p, "/BaseFont /%s\n", fonts[i].name); - ps_printf(p, ">>\n"); + ps_printf(p, ">>\nendobj\n"); } } @@ -943,9 +967,7 @@ ps_pletter(struct termp *p, int c) if (TERMTYPE_PS == p->type) { ps_printf(p, "%%%%Page: %zu %zu\n", p->ps->pages + 1, p->ps->pages + 1); - ps_printf(p, "/%s %zu selectfont\n", - fonts[(int)p->ps->lastf].name, - p->ps->scale); + ps_printf(p, "f%d\n", (int)p->ps->lastf); } else { pdf_obj(p, p->ps->pdfbody + p->ps->pages * 4); @@ -970,10 +992,13 @@ ps_pletter(struct termp *p, int c) ps_printf(p, "%.3f %.3f Td\n(", AFM2PNT(p, p->ps->pscol), AFM2PNT(p, p->ps->psrow)); - } else - ps_printf(p, "%.3f %.3f moveto\n(", - AFM2PNT(p, p->ps->pscol), - AFM2PNT(p, p->ps->psrow)); + } else { + ps_printf(p, "%.3f", AFM2PNT(p, p->ps->pscol)); + if (p->ps->psrow != p->ps->lastrow) + ps_printf(p, " %.3f", + AFM2PNT(p, p->ps->psrow)); + ps_printf(p, "("); + } p->ps->flags |= PS_INLINE; } @@ -1021,10 +1046,14 @@ ps_pclose(struct termp *p) if ( ! (PS_INLINE & p->ps->flags)) return; - if (TERMTYPE_PS != p->type) { + if (TERMTYPE_PS != p->type) ps_printf(p, ") Tj\nET\n"); - } else - ps_printf(p, ") show\n"); + else if (p->ps->psrow == p->ps->lastrow) + ps_printf(p, ")c\n"); + else { + ps_printf(p, ")s\n"); + p->ps->lastrow = p->ps->psrow; + } p->ps->flags &= ~PS_INLINE; } @@ -1243,8 +1272,7 @@ ps_setfont(struct termp *p, enum termfont f) return; if (TERMTYPE_PS == p->type) - ps_printf(p, "/%s %zu selectfont\n", - fonts[(int)f].name, p->ps->scale); + ps_printf(p, "f%d\n", (int)f); else ps_printf(p, "/F%d %zu Tf\n", (int)f, p->ps->scale); diff --git a/contrib/mdocml/term_tab.c b/contrib/mandoc/term_tab.c similarity index 100% rename from contrib/mdocml/term_tab.c rename to contrib/mandoc/term_tab.c diff --git a/contrib/mdocml/test-EFTYPE.c b/contrib/mandoc/test-EFTYPE.c similarity index 100% rename from contrib/mdocml/test-EFTYPE.c rename to contrib/mandoc/test-EFTYPE.c diff --git a/contrib/mdocml/test-O_DIRECTORY.c b/contrib/mandoc/test-O_DIRECTORY.c similarity index 100% rename from contrib/mdocml/test-O_DIRECTORY.c rename to contrib/mandoc/test-O_DIRECTORY.c diff --git a/contrib/mdocml/test-PATH_MAX.c b/contrib/mandoc/test-PATH_MAX.c similarity index 100% rename from contrib/mdocml/test-PATH_MAX.c rename to contrib/mandoc/test-PATH_MAX.c diff --git a/contrib/mdocml/test-be32toh.c b/contrib/mandoc/test-be32toh.c similarity index 100% rename from contrib/mdocml/test-be32toh.c rename to contrib/mandoc/test-be32toh.c diff --git a/contrib/mdocml/test-cmsg.c b/contrib/mandoc/test-cmsg.c similarity index 100% rename from contrib/mdocml/test-cmsg.c rename to contrib/mandoc/test-cmsg.c diff --git a/contrib/mdocml/test-dirent-namlen.c b/contrib/mandoc/test-dirent-namlen.c similarity index 100% rename from contrib/mdocml/test-dirent-namlen.c rename to contrib/mandoc/test-dirent-namlen.c diff --git a/contrib/mdocml/test-err.c b/contrib/mandoc/test-err.c similarity index 100% rename from contrib/mdocml/test-err.c rename to contrib/mandoc/test-err.c diff --git a/contrib/mdocml/test-fgetln.c b/contrib/mandoc/test-fgetln.c similarity index 100% rename from contrib/mdocml/test-fgetln.c rename to contrib/mandoc/test-fgetln.c diff --git a/contrib/mdocml/test-fts.c b/contrib/mandoc/test-fts.c similarity index 100% rename from contrib/mdocml/test-fts.c rename to contrib/mandoc/test-fts.c diff --git a/contrib/mdocml/test-getline.c b/contrib/mandoc/test-getline.c similarity index 100% rename from contrib/mdocml/test-getline.c rename to contrib/mandoc/test-getline.c diff --git a/contrib/mdocml/test-getsubopt.c b/contrib/mandoc/test-getsubopt.c similarity index 100% rename from contrib/mdocml/test-getsubopt.c rename to contrib/mandoc/test-getsubopt.c diff --git a/contrib/mdocml/test-isblank.c b/contrib/mandoc/test-isblank.c similarity index 100% rename from contrib/mdocml/test-isblank.c rename to contrib/mandoc/test-isblank.c diff --git a/contrib/mdocml/test-mkdtemp.c b/contrib/mandoc/test-mkdtemp.c similarity index 100% rename from contrib/mdocml/test-mkdtemp.c rename to contrib/mandoc/test-mkdtemp.c diff --git a/contrib/mdocml/test-nanosleep.c b/contrib/mandoc/test-nanosleep.c similarity index 100% rename from contrib/mdocml/test-nanosleep.c rename to contrib/mandoc/test-nanosleep.c diff --git a/contrib/mandoc/test-noop.c b/contrib/mandoc/test-noop.c new file mode 100644 index 00000000000..95485db8017 --- /dev/null +++ b/contrib/mandoc/test-noop.c @@ -0,0 +1,5 @@ +int +main(void) +{ + return 0; +} diff --git a/contrib/mdocml/test-ntohl.c b/contrib/mandoc/test-ntohl.c similarity index 100% rename from contrib/mdocml/test-ntohl.c rename to contrib/mandoc/test-ntohl.c diff --git a/contrib/mdocml/test-ohash.c b/contrib/mandoc/test-ohash.c similarity index 100% rename from contrib/mdocml/test-ohash.c rename to contrib/mandoc/test-ohash.c diff --git a/contrib/mdocml/test-pledge.c b/contrib/mandoc/test-pledge.c similarity index 100% rename from contrib/mdocml/test-pledge.c rename to contrib/mandoc/test-pledge.c diff --git a/contrib/mdocml/test-progname.c b/contrib/mandoc/test-progname.c similarity index 100% rename from contrib/mdocml/test-progname.c rename to contrib/mandoc/test-progname.c diff --git a/contrib/mdocml/test-reallocarray.c b/contrib/mandoc/test-reallocarray.c similarity index 100% rename from contrib/mdocml/test-reallocarray.c rename to contrib/mandoc/test-reallocarray.c diff --git a/contrib/mdocml/test-recallocarray.c b/contrib/mandoc/test-recallocarray.c similarity index 100% rename from contrib/mdocml/test-recallocarray.c rename to contrib/mandoc/test-recallocarray.c diff --git a/contrib/mdocml/test-recvmsg.c b/contrib/mandoc/test-recvmsg.c similarity index 100% rename from contrib/mdocml/test-recvmsg.c rename to contrib/mandoc/test-recvmsg.c diff --git a/contrib/mdocml/test-rewb-bsd.c b/contrib/mandoc/test-rewb-bsd.c similarity index 100% rename from contrib/mdocml/test-rewb-bsd.c rename to contrib/mandoc/test-rewb-bsd.c diff --git a/contrib/mdocml/test-rewb-sysv.c b/contrib/mandoc/test-rewb-sysv.c similarity index 100% rename from contrib/mdocml/test-rewb-sysv.c rename to contrib/mandoc/test-rewb-sysv.c diff --git a/contrib/mdocml/test-sandbox_init.c b/contrib/mandoc/test-sandbox_init.c similarity index 100% rename from contrib/mdocml/test-sandbox_init.c rename to contrib/mandoc/test-sandbox_init.c diff --git a/contrib/mdocml/test-strcasestr.c b/contrib/mandoc/test-strcasestr.c similarity index 100% rename from contrib/mdocml/test-strcasestr.c rename to contrib/mandoc/test-strcasestr.c diff --git a/contrib/mdocml/test-stringlist.c b/contrib/mandoc/test-stringlist.c similarity index 100% rename from contrib/mdocml/test-stringlist.c rename to contrib/mandoc/test-stringlist.c diff --git a/contrib/mdocml/test-strlcat.c b/contrib/mandoc/test-strlcat.c similarity index 100% rename from contrib/mdocml/test-strlcat.c rename to contrib/mandoc/test-strlcat.c diff --git a/contrib/mdocml/test-strlcpy.c b/contrib/mandoc/test-strlcpy.c similarity index 100% rename from contrib/mdocml/test-strlcpy.c rename to contrib/mandoc/test-strlcpy.c diff --git a/contrib/mandoc/test-strndup.c b/contrib/mandoc/test-strndup.c new file mode 100644 index 00000000000..82e4e547e09 --- /dev/null +++ b/contrib/mandoc/test-strndup.c @@ -0,0 +1,10 @@ +#include <string.h> + +int +main(void) +{ + char *s; + + s = strndup("123", 2); + return s[0] != '1' ? 1 : s[1] != '2' ? 2 : s[2] != '\0' ? 3 : 0; +} diff --git a/contrib/mdocml/test-strptime.c b/contrib/mandoc/test-strptime.c similarity index 100% rename from contrib/mdocml/test-strptime.c rename to contrib/mandoc/test-strptime.c diff --git a/contrib/mdocml/test-strsep.c b/contrib/mandoc/test-strsep.c similarity index 100% rename from contrib/mdocml/test-strsep.c rename to contrib/mandoc/test-strsep.c diff --git a/contrib/mdocml/test-strtonum.c b/contrib/mandoc/test-strtonum.c similarity index 100% rename from contrib/mdocml/test-strtonum.c rename to contrib/mandoc/test-strtonum.c diff --git a/contrib/mdocml/test-vasprintf.c b/contrib/mandoc/test-vasprintf.c similarity index 100% rename from contrib/mdocml/test-vasprintf.c rename to contrib/mandoc/test-vasprintf.c diff --git a/contrib/mdocml/test-wchar.c b/contrib/mandoc/test-wchar.c similarity index 100% rename from contrib/mdocml/test-wchar.c rename to contrib/mandoc/test-wchar.c diff --git a/contrib/mdocml/tree.c b/contrib/mandoc/tree.c similarity index 96% rename from contrib/mdocml/tree.c rename to contrib/mandoc/tree.c index 7d18b9d9e68..b9774e1cd8e 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 2a57a18f9d6..00000000000 --- 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 d0594f2ebcd..26dd51bdff8 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 9dc3b0184c6..38cf2d448d4 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 4349b0f54cc..c19fd93d5a3 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 b8a9881c1ba..0a0bf882c45 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 71283a973ea..df8f99e4c3d 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 a7639d904aa..00000000000 --- 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 9723ac77ece..84cd51590e5 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 42a7f778cf6..ac9a78d729d 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 873ae5b1e4b..5c457f1eeaf 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 2b00517fb17..4361330c7f1 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 236e0768949..5a99758f863 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 674f8185493..6908c793ece 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 b2481f8b2a0..863f2d9c701 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 e849e0ad078..3f7f579433d 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 2b375a6f0cd..c0b04cc5e55 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 37416a75593..8686a99d1f5 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 58843fbb741..6ec6560e420 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 974e4264d20..8bcfdb28c8f 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 e26a741c83a..fc1470c058c 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 26e208ffa65..cec901a1e8b 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 da30e8403a2..4332aa13a70 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 cb89cc37f12..9096dc913f1 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 5fe92947dbf..0d61d319f35 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 fcdb824cf74..c407de435b9 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 184bcbdf544..6199c778ab5 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 aeb5203d8dc..44d2d95487c 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 fe103ce81cb..54efe869b84 100644 --- a/lib/lib80211/Makefile +++ b/lib/lib80211/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ +CONFS= regdomain.xml PACKAGE=lib${LIB} LIB= 80211 SHLIBDIR?= /lib diff --git a/etc/regdomain.xml b/lib/lib80211/regdomain.xml similarity index 100% rename from etc/regdomain.xml rename to lib/lib80211/regdomain.xml diff --git a/lib/libalias/libalias/Makefile b/lib/libalias/libalias/Makefile index 60c59a3ed31..bfbd523aa0b 100644 --- a/lib/libalias/libalias/Makefile +++ b/lib/libalias/libalias/Makefile @@ -2,6 +2,7 @@ .PATH: ${SRCTOP}/sys/netinet/libalias +CONFS= libalias.conf PACKAGE=lib${LIB} LIB= alias SHLIBDIR?= /lib diff --git a/etc/libalias.conf b/lib/libalias/libalias/libalias.conf similarity index 100% rename from etc/libalias.conf rename to lib/libalias/libalias/libalias.conf diff --git a/lib/libbe/be.c b/lib/libbe/be.c index c1cdd55825f..2872abed6de 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); - - switch (err) { - case 0: - return (BE_ERR_SUCCESS); - - default: - /* XXX TODO correct errors */ + if (err) + return (-1); + + zhp = zfs_open(lbh->lzh, be_path, ZFS_TYPE_FILESYSTEM); + if (zhp == NULL) + return (-1); + + 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 f82a5b190a2..d6a3598ae31 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 d01b76bc10e..efdc6d33e4d 100644 --- a/lib/libc/amd64/string/bcmp.S +++ b/lib/libc/amd64/string/bcmp.S @@ -1,27 +1,121 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Mateusz Guzik <mjg@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + #include <machine/asm.h> __FBSDID("$FreeBSD$"); -#if 0 - RCSID("$NetBSD: bcmp.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $") -#endif - ENTRY(bcmp) - cld /* set compare direction forward */ - - movq %rdx,%rcx /* compare by words */ - shrq $3,%rcx - repe - cmpsq - jne L1 - - movq %rdx,%rcx /* compare remainder by bytes */ - andq $7,%rcx - repe - cmpsb -L1: - setne %al - movsbl %al,%eax + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax ret +4: + movl $1,%eax + ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 4b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 4b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 4b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b END(bcmp) .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/bcopy.S b/lib/libc/amd64/string/bcopy.S index cc38f475525..9446e75b805 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 cf46a2a317b..123d9c4a7ef 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 66d64a0b5a4..3012ffa688c 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 84d15628766..06c9869c2d6 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 - stosb - movq %r11,%rax - + jne 1f +.if \bzero == 0 + movq %r9,%rax +.endif ret +1: + rep + stosb +.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 89576f379d6..4c653d744f1 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 304c465b854..b31c1a36fcf 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 similarity index 100% rename from etc/hosts rename to lib/libc/net/hosts diff --git a/etc/hosts.equiv b/lib/libc/net/hosts.equiv similarity index 100% rename from etc/hosts.equiv rename to lib/libc/net/hosts.equiv diff --git a/etc/networks b/lib/libc/net/networks similarity index 100% rename from etc/networks rename to lib/libc/net/networks diff --git a/etc/nsswitch.conf b/lib/libc/net/nsswitch.conf similarity index 100% rename from etc/nsswitch.conf rename to lib/libc/net/nsswitch.conf diff --git a/etc/protocols b/lib/libc/net/protocols similarity index 100% rename from etc/protocols rename to lib/libc/net/protocols diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index 151f8506820..fb5cf6e39cc 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -8,6 +8,7 @@ CFLAGS+=-D_ACL_PRIVATE subr_acl_nfs4.c: ${SRCTOP}/sys/kern/subr_acl_nfs4.c cat ${.ALLSRC} > ${.TARGET} +CONFS+= posix1e/mac.conf SRCS+= acl_branding.c \ acl_calc_mask.c \ acl_copy.c \ diff --git a/etc/mac.conf b/lib/libc/posix1e/mac.conf similarity index 100% rename from etc/mac.conf rename to lib/libc/posix1e/mac.conf diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index c3e5502d68d..5ca9bd3757c 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -2,6 +2,7 @@ # $FreeBSD$ .PATH: ${LIBC_SRCTOP}/rpc ${LIBC_SRCTOP}/. +CONFS+= rpc/netconfig rpc/rpc SRCS+= auth_none.c auth_unix.c authunix_prot.c bindresvport.c clnt_bcast.c \ clnt_dg.c clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c \ clnt_vc.c rpc_dtablesize.c getnetconfig.c getnetpath.c getrpcent.c \ diff --git a/etc/netconfig b/lib/libc/rpc/netconfig similarity index 100% rename from etc/netconfig rename to lib/libc/rpc/netconfig diff --git a/etc/rpc b/lib/libc/rpc/rpc similarity index 100% rename from etc/rpc rename to lib/libc/rpc/rpc diff --git a/lib/libopie/Makefile b/lib/libopie/Makefile index 4507d252ea9..2dda575e94e 100644 --- a/lib/libopie/Makefile +++ b/lib/libopie/Makefile @@ -2,6 +2,9 @@ # # $FreeBSD$ # + +CONFS= opieaccess +CONFSMODE= 600 PACKAGE=lib${LIB} OPIE_DIST?= ${SRCTOP}/contrib/opie DIST_DIR= ${OPIE_DIST}/${.CURDIR:T} diff --git a/etc/opieaccess b/lib/libopie/opieaccess similarity index 100% rename from etc/opieaccess rename to lib/libopie/opieaccess diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile index 48e94a2a078..f40ba3b2827 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 7aaf6f2a5b1..583a2d36bc7 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 519db5ff946..3c310819f87 100644 --- a/lib/libsmb/Makefile +++ b/lib/libsmb/Makefile @@ -2,6 +2,8 @@ .include <src.opts.mk> +CONFS= nsmb.conf +CONFSMODE= 600 PACKAGE=lib${LIB} CONTRIBDIR= ${SRCTOP}/contrib/smbfs .PATH: ${CONTRIBDIR}/lib/smb diff --git a/etc/nsmb.conf b/lib/libsmb/nsmb.conf similarity index 100% rename from etc/nsmb.conf rename to lib/libsmb/nsmb.conf diff --git a/lib/libusb/libusb10.h b/lib/libusb/libusb10.h index 7c34f895b0a..c3deb562c6d 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 42fbd0e2e30..53f5b040436 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 180ef35b9b9..1326b43bad2 100644 --- a/lib/libwrap/Makefile +++ b/lib/libwrap/Makefile @@ -4,6 +4,7 @@ .include <src.opts.mk> +CONFS= hosts.allow PACKAGE=lib${LIB} LIB= wrap SHLIB_MAJOR= 6 diff --git a/etc/hosts.allow b/lib/libwrap/hosts.allow similarity index 100% rename from etc/hosts.allow rename to lib/libwrap/hosts.allow diff --git a/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile index 5d5e99fb248..5135469f5ea 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 2ca13d8c7c8..eb355ea6ff5 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++) { + /* + * First, resolve symbol for relocations which + * reference symbols. + */ + switch (ELF_R_TYPE(rela->r_info)) { + case R_AARCH64_ABS64: + case R_AARCH64_GLOB_DAT: + 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 *)(obj->relocbase + rela->r_offset); - symnum = ELF_R_SYM(rela->r_info); 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); - if (def == NULL) - return (-1); - - *where = (Elf_Addr)defobj->relocbase + def->st_value + - rela->r_addend; + *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 9ff53d900aa..9cc0f244331 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 592b7664eea..33c824a65af 100644 --- a/libexec/rtld-elf/libmap.c +++ b/libexec/rtld-elf/libmap.c @@ -353,6 +353,7 @@ lm_add(const char *p, const char *f, const char *t) { struct lm_list *lml; struct lm *lm; + const char *t1; if (p == NULL) p = "$DEFAULT$"; @@ -362,11 +363,14 @@ lm_add(const char *p, const char *f, const char *t) if ((lml = lmp_find(p)) == NULL) lml = lmp_init(xstrdup(p)); - lm = xmalloc(sizeof(struct lm)); - lm->f = xstrdup(f); - lm->t = xstrdup(t); - TAILQ_INSERT_HEAD(lml, lm, lm_link); - lm_count++; + t1 = lml_find(lml, f); + if (t1 == NULL || strcmp(t1, t) != 0) { + lm = xmalloc(sizeof(struct lm)); + lm->f = xstrdup(f); + lm->t = xstrdup(t); + TAILQ_INSERT_HEAD(lml, lm, lm_link); + lm_count++; + } } char * diff --git a/etc/libmap.conf b/libexec/rtld-elf/libmap.conf similarity index 100% rename from etc/libmap.conf rename to libexec/rtld-elf/libmap.conf diff --git a/libexec/rtld-elf/powerpc/reloc.c b/libexec/rtld-elf/powerpc/reloc.c index 09c305089c1..3c157b23f2f 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 dfd0388478f..83d5e28e287 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 79d53b4cbb6..6eddf11d723 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 fe4ffd9695d..6c7cb0e76a3 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 b1a71a2a74f..6921a655af1 100644 --- a/sbin/bsdlabel/Makefile +++ b/sbin/bsdlabel/Makefile @@ -3,6 +3,7 @@ .PATH: ${SRCTOP}/sys/geom +CONFS= disktab PACKAGE=runtime PROG= bsdlabel SRCS= bsdlabel.c geom_bsd_enc.c diff --git a/etc/disktab b/sbin/bsdlabel/disktab similarity index 100% rename from etc/disktab rename to sbin/bsdlabel/disktab diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc index e81f718159b..b2d08324511 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 534c4d4c5a9..d770da22226 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 99b749eb720..cdf93b8b814 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 7eaeeb8eb40..a7639d904aa 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 0da8998f9b5..71e3eda74c1 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 8cd88cb7792..298fc2b1d4f 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 9f1655c61a5..e6d6d789908 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 fed5a842235..0e615a27e20 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 3af9562d3bf..9e5e02ab29d 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 8364de82778..acb4d347644 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 32a94edf7c4..203c852b372 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 28b84ff25bc..4dcade7611c 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 1f3041b1f6c..35a2cc94174 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 3ee1da7faa2..e71be39bae5 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 c40e47c8ffa..3a6738a2ef4 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 20cc3b83b0e..12c2f9a0626 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 c98f96ad367..970472efca2 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 aeec111adef..188b5c8fc5e 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 9a9249fdcaf..7f84be1fbbf 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 00000000000..ffd7c1153f5 --- /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 7517d20db19..f8c148e62cc 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 ff1df4ba525..7e8d31fa75c 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 8a010417197..42ba5f2803c 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 a71800c1a51..4c605e3627c 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 33d0293b45f..f833c5c44d3 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 72e6c2cb46f..cdd8b09b1bc 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 7415092011e..b4ba16dc599 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 486043a63bb..145c17dff75 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 5454095df8a..5b585ed1260 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 7667b97bdf2..d6f1d8e4b5b 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 9824c3ebb7e..cd45238b44a 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 72466cbcadb..4dfaf1a6525 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 dce20fb2776..59b7ad5c130 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 092dc095bf6..dc174e85a61 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 8cb09df626b..bab8072d9ec 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,60 +1913,107 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) ("pmap_invalidate_range: invalid type %d", pmap->pm_type)); sched_pin(); - cpuid = PCPU_GET(cpuid); 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(); } +static inline void +pmap_invalidate_all_pcid(pmap_t pmap, bool invpcid_works1) +{ + struct invpcid_descr d; + uint64_t kcr3, ucr3; + uint32_t pcid; + u_int cpuid, i; + + if (pmap == kernel_pmap) { + if (invpcid_works1) { + bzero(&d, sizeof(d)); + invpcid(&d, INVPCID_CTXGLOB); + } else { + invltlb_glob(); + } + } else { + cpuid = PCPU_GET(cpuid); + if (pmap == PCPU_GET(curpmap)) { + critical_enter(); + pcid = pmap->pm_pcids[cpuid].pm_pcid; + if (invpcid_works1) { + d.pcid = pcid; + d.pad = 0; + d.addr = 0; + invpcid(&d, INVPCID_CTX); + if (pmap->pm_ucr3 != PMAP_NO_CR3) { + d.pcid |= PMAP_PCID_USER_PT; + invpcid(&d, INVPCID_CTX); + } + } else { + kcr3 = pmap->pm_cr3 | pcid; + ucr3 = pmap->pm_ucr3; + if (ucr3 != PMAP_NO_CR3) { + ucr3 |= pcid | PMAP_PCID_USER_PT; + pmap_pti_pcid_invalidate(ucr3, kcr3); + } else { + load_cr3(kcr3); + } + } + critical_exit(); + } else + pmap->pm_pcids[cpuid].pm_gen = 0; + CPU_FOREACH(i) { + if (cpuid != i) + pmap->pm_pcids[i].pm_gen = 0; + } + } + /* See the comment in pmap_invalidate_page_pcid(). */ + atomic_thread_fence_seq_cst(); +} + +static void +pmap_invalidate_all_pcid_invpcid(pmap_t pmap) +{ + + pmap_invalidate_all_pcid(pmap, true); +} + +static void +pmap_invalidate_all_pcid_noinvpcid(pmap_t pmap) +{ + + pmap_invalidate_all_pcid(pmap, false); +} + +static void +pmap_invalidate_all_nopcid(pmap_t pmap) +{ + + if (pmap == kernel_pmap) + invltlb_glob(); + else if (pmap == PCPU_GET(curpmap)) + invltlb(); +} + +DEFINE_IFUNC(static, void, pmap_invalidate_all_mode, (pmap_t), static) +{ + + if (pmap_pcid_enabled) + return (invpcid_works ? pmap_invalidate_all_pcid_invpcid : + pmap_invalidate_all_pcid_noinvpcid); + return (pmap_invalidate_all_nopcid); +} + void pmap_invalidate_all(pmap_t pmap) { - cpuset_t *mask; - struct invpcid_descr d; - uint64_t kcr3, ucr3; - uint32_t pcid; - u_int cpuid, i; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -1870,58 +2024,8 @@ pmap_invalidate_all(pmap_t pmap) ("pmap_invalidate_all: invalid type %d", pmap->pm_type)); sched_pin(); - if (pmap == kernel_pmap) { - if (pmap_pcid_enabled && invpcid_works) { - bzero(&d, sizeof(d)); - invpcid(&d, INVPCID_CTXGLOB); - } else { - invltlb_glob(); - } - mask = &all_cpus; - } else { - cpuid = PCPU_GET(cpuid); - if (pmap == PCPU_GET(curpmap)) { - if (pmap_pcid_enabled) { - critical_enter(); - pcid = pmap->pm_pcids[cpuid].pm_pcid; - if (invpcid_works) { - d.pcid = pcid; - d.pad = 0; - d.addr = 0; - invpcid(&d, INVPCID_CTX); - if (pmap->pm_ucr3 != PMAP_NO_CR3) { - d.pcid |= PMAP_PCID_USER_PT; - invpcid(&d, INVPCID_CTX); - } - } else { - kcr3 = pmap->pm_cr3 | pcid; - ucr3 = pmap->pm_ucr3; - if (ucr3 != PMAP_NO_CR3) { - ucr3 |= pcid | PMAP_PCID_USER_PT; - pmap_pti_pcid_invalidate(ucr3, - kcr3); - } else { - load_cr3(kcr3); - } - } - critical_exit(); - } else { - invltlb(); - } - } else if (pmap_pcid_enabled) { - pmap->pm_pcids[cpuid].pm_gen = 0; - } - if (pmap_pcid_enabled) { - CPU_FOREACH(i) { - if (cpuid != i) - pmap->pm_pcids[i].pm_gen = 0; - } - /* See the comment in pmap_invalidate_page(). */ - atomic_thread_fence_seq_cst(); - } - mask = &pmap->pm_active; - } - smp_masked_invltlb(*mask, pmap); + 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 PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) - -void -pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) +DEFINE_IFUNC(, void, pmap_invalidate_cache_range, + (vm_offset_t sva, vm_offset_t eva), static) { - if (force) { - sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); - } else { - KASSERT((sva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: sva not page-aligned")); - KASSERT((eva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: eva not page-aligned")); + if ((cpu_feature & CPUID_SS) != 0) + return (pmap_invalidate_cache_range_selfsnoop); + if ((cpu_feature & CPUID_CLFSH) != 0) + return (pmap_force_invalidate_cache_range); + return (pmap_invalidate_cache_range_all); +} + +#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) + +static void +pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva) +{ + + KASSERT((sva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: sva not page-aligned")); + KASSERT((eva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: eva not page-aligned")); +} + +static void +pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); +} + +void +pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) +{ + + sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); + if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) { + /* + * The supplied range is bigger than 2MB. + * Globally invalidate cache. + */ + pmap_invalidate_cache(); + return; } - if ((cpu_feature & CPUID_SS) != 0 && !force) - ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { - /* - * XXX: Some CPUs fault, hang, or trash the local APIC - * registers if we use CLFLUSH on the local APIC - * range. The local APIC is always uncached, so we - * don't need to flush for that range anyway. - */ - if (pmap_kextract(sva) == lapic_paddr) - return; + /* + * XXX: Some CPUs fault, hang, or trash the local APIC + * registers if we use CLFLUSH on the local APIC range. The + * local APIC is always uncached, so we don't need to flush + * for that range anyway. + */ + if (pmap_kextract(sva) == lapic_paddr) + return; + if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) { /* - * Otherwise, do per-cache line flush. Use the sfence + * Do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache @@ -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 db89a6fadd3..f0086e298ea 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) @@ -90,6 +100,100 @@ ENTRY(sse2_pagezero) ret END(sse2_pagezero) +/* + * memcmpy(b1, b2, len) + * rdi,rsi,len + */ +ENTRY(memcmp) + PUSH_FRAME_POINTER + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax + POP_FRAME_POINTER + ret +4: + subl %r8d,%eax + POP_FRAME_POINTER + ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 1b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 1b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 1b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b +END(memcmp) + /* * memmove(dst, src, cnt) * rdi, rsi, rdx @@ -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 - - xchgq %rdi,%rsi - movq %rdx,%rcx - movb %cl,%al - shrq $3,%rcx /* copy longword-wise */ - stac - rep - movsq - movb %al,%cl - andb $7,%cl /* copy remaining bytes */ - je 1f - rep - movsb -1: clac - -done_copyin: xorl %eax,%eax - movq PCPU(CURPCB),%rdx - movq %rax,PCB_ONFAULT(%rdx) + + SMAP_DISABLE \smap +.if \erms == 0 + cmpq $15,%rcx + jbe 1f + shrq $3,%rcx /* copy longword-wise */ + rep + movsq + movb %dl,%cl + andb $7,%cl /* copy remaining bytes */ + jne 1f + SMAP_ENABLE \smap + movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret -END(copyin_smap) + ALIGN_TEXT +1: +.endif + rep + movsb + + SMAP_ENABLE \smap + movq %rax,PCB_ONFAULT(%r9) + POP_FRAME_POINTER + ret +.endm + +ENTRY(copyin_nosmap_std) + COPYIN smap=0 erms=0 +END(copyin_nosmap_std) + +ENTRY(copyin_smap_std) + COPYIN smap=1 erms=0 +END(copyin_smap_std) + +ENTRY(copyin_nosmap_erms) + COPYIN smap=0 erms=1 +END(copyin_nosmap_erms) + +ENTRY(copyin_smap_erms) + COPYIN smap=1 erms=1 +END(copyin_smap_erms) ALIGN_TEXT -copyin_fault: - movq PCPU(CURPCB),%rdx - movq $0,PCB_ONFAULT(%rdx) - movq $EFAULT,%rax + /* Trap entry clears PSL.AC */ +copy_fault: + movq $0,PCB_ONFAULT(%r9) + movl $EFAULT,%eax POP_FRAME_POINTER ret @@ -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 - - lodsb - stosb - orb %al,%al - jnz 2b - - jmp copyinstr_succ -END(copyinstr_nosmap) - -ENTRY(copyinstr_smap) - PUSH_FRAME_POINTER - movq %rdx,%r8 /* %r8 = maxlen */ - movq %rcx,%r9 /* %r9 = *len */ - xchgq %rdi,%rsi /* %rdi = from, %rsi = to */ - movq PCPU(CURPCB),%rcx - movq $cpystrflt,PCB_ONFAULT(%rcx) - - movq $VM_MAXUSER_ADDRESS,%rax - - /* make sure 'from' is within bounds */ - subq %rsi,%rax - jbe cpystrflt - - stac - - /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */ - cmpq %rdx,%rax - jae 1f - movq %rax,%rdx - movq %rax,%r8 -1: - incq %rdx - -2: - decq %rdx +.else jz copyinstr_toolong_smap +.endif - lodsb - stosb - orb %al,%al + movb (%rdi),%al + movb %al,(%rsi) + incq %rsi + incq %rdi + testb %al,%al jnz 2b - clac + SMAP_ENABLE \smap -copyinstr_succ: /* Success -- 0 byte reached */ decq %rdx xorl %eax,%eax + /* set *lencopied and return %eax */ + movq %rax,PCB_ONFAULT(%r9) + + testq %rcx,%rcx + jz 3f + subq %rdx,%r8 + movq %r8,(%rcx) +3: + POP_FRAME_POINTER + ret + ALIGN_TEXT +8: + movq %rax,%rdx + movq %rax,%r8 + jmp 1b + +.endm + +ENTRY(copyinstr_nosmap) + COPYINSTR smap=0 +END(copyinstr_nosmap) + +ENTRY(copyinstr_smap) + COPYINSTR smap=1 +END(copyinstr_smap) + +cpystrflt: + /* Fault entry clears PSL.AC */ + movl $EFAULT,%eax cpystrflt_x: /* set *lencopied and return %eax */ - movq PCPU(CURPCB),%rcx - movq $0,PCB_ONFAULT(%rcx) + movq $0,PCB_ONFAULT(%r9) - testq %r9,%r9 + testq %rcx,%rcx jz 1f subq %rdx,%r8 - movq %r8,(%r9) + movq %r8,(%rcx) 1: POP_FRAME_POINTER ret - /* Fault entry clears PSL.AC */ -cpystrflt: - movq $EFAULT,%rax - jmp cpystrflt_x copyinstr_toolong_smap: clac 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 4d03da234f1..1a8e5d23ff3 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 34c3fb868ce..5b83307bbb6 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 6b8a1422487..b66eda0f476 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 b40846cae6e..61871e9338e 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 6f0e0b2b955..aecd21f13b4 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 2f6f9c93af4..52685a9b13b 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 5754f4780fe..c3ab6852e61 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 67244adfb0c..f39eb3558b5 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 a79490441e9..b9e7826e343 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 dc243c958a6..613dcbc53a0 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 a96d5f88ddd..753558a085d 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 0d1e91cd58c..ab45fcb8168 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 00000000000..2ce29154180 --- /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 acd3f81ab41..7aa216e92b4 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 7fded28c31f..ee25af6e3f9 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 b0d4fe5d11c..599ebc27262 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 40f593f9b62..80dcb34a0a7 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 0a352b1e979..9012baa0a99 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 2b5547ce598..3a25d8463d3 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 8cd6360e4cf..bbfb79ce24d 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 aa8a400f2d7..7794bd50552 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 3fad5a76957..cf75ab0856c 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 92f51420e32..1ab51ba77a1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -65,6 +65,7 @@ #include <sys/spa_boot.h> #include <sys/jail.h> #include <ufs/ufs/quota.h> +#include <sys/rmlock.h> #include "zfs_comutil.h" @@ -92,6 +93,9 @@ static int zfs_version_zpl = ZPL_VERSION; SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0, "ZPL_VERSION"); +static int zfs_root_setvnode(zfsvfs_t *zfsvfs); +static void zfs_root_dropvnode(zfsvfs_t *zfsvfs); + static int zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg); static int zfs_mount(vfs_t *vfsp); static int zfs_umount(vfs_t *vfsp, int fflag); @@ -198,6 +202,8 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg) break; default: error = EINVAL; + if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF) + vfs_unbusy(vfsp); goto done; } } @@ -255,9 +261,11 @@ zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg) case Q_QUOTAON: // As far as I can tell, you can't turn quotas on or off on zfs error = 0; + vfs_unbusy(vfsp); break; case Q_QUOTAOFF: error = ENOTSUP; + vfs_unbusy(vfsp); break; case Q_SETQUOTA: error = copyin(&dqblk, arg, sizeof(dqblk)); @@ -1205,6 +1213,8 @@ zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os) for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++) mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); + rm_init(&zfsvfs->z_rootvnodelock, "zfs root vnode lock"); + error = zfsvfs_init(zfsvfs, os); if (error != 0) { *zfvp = NULL; @@ -1311,6 +1321,8 @@ zfsvfs_free(zfsvfs_t *zfsvfs) rw_enter(&zfsvfs_lock, RW_READER); rw_exit(&zfsvfs_lock); + rm_destroy(&zfsvfs->z_rootvnodelock); + zfs_fuid_destroy(zfsvfs); mutex_destroy(&zfsvfs->z_znodes_lock); @@ -1917,6 +1929,8 @@ zfs_mount(vfs_t *vfsp) error = zfs_domount(vfsp, osname); PICKUP_GIANT(); + zfs_root_setvnode((zfsvfs_t *)vfsp->vfs_data); + #ifdef illumos /* * Add an extra VFS_HOLD on our parent vfs so that it can't @@ -1989,14 +2003,65 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp) } static int -zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) +zfs_root_setvnode(zfsvfs_t *zfsvfs) { - zfsvfs_t *zfsvfs = vfsp->vfs_data; znode_t *rootzp; int error; ZFS_ENTER(zfsvfs); + error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); + if (error != 0) + panic("could not zfs_zget for root vnode"); + ZFS_EXIT(zfsvfs); + rm_wlock(&zfsvfs->z_rootvnodelock); + if (zfsvfs->z_rootvnode != NULL) + panic("zfs mount point already has a root vnode: %p\n", + zfsvfs->z_rootvnode); + zfsvfs->z_rootvnode = ZTOV(rootzp); + rm_wunlock(&zfsvfs->z_rootvnodelock); + return (0); +} + +static void +zfs_root_putvnode(zfsvfs_t *zfsvfs) +{ + struct vnode *vp; + + rm_wlock(&zfsvfs->z_rootvnodelock); + vp = zfsvfs->z_rootvnode; + zfsvfs->z_rootvnode = NULL; + rm_wunlock(&zfsvfs->z_rootvnodelock); + if (vp != NULL) + vrele(vp); +} + +static int +zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) +{ + struct rm_priotracker tracker; + zfsvfs_t *zfsvfs = vfsp->vfs_data; + znode_t *rootzp; + int error; + + rm_rlock(&zfsvfs->z_rootvnodelock, &tracker); + *vpp = zfsvfs->z_rootvnode; + if (*vpp != NULL && (((*vpp)->v_iflag & VI_DOOMED) == 0)) { + vrefact(*vpp); + rm_runlock(&zfsvfs->z_rootvnodelock, &tracker); + goto lock; + } + rm_runlock(&zfsvfs->z_rootvnodelock, &tracker); + + /* + * We found the vnode but did not like it. + */ + if (*vpp != NULL) { + *vpp = NULL; + zfs_root_putvnode(zfsvfs); + } + + ZFS_ENTER(zfsvfs); error = zfs_zget(zfsvfs, zfsvfs->z_root, &rootzp); if (error == 0) *vpp = ZTOV(rootzp); @@ -2004,6 +2069,7 @@ zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) ZFS_EXIT(zfsvfs); if (error == 0) { +lock: error = vn_lock(*vpp, flags); if (error != 0) { VN_RELE(*vpp); @@ -2122,6 +2188,8 @@ zfs_umount(vfs_t *vfsp, int fflag) cred_t *cr = td->td_ucred; int ret; + zfs_root_putvnode(zfsvfs); + ret = secpolicy_fs_unmount(cr, vfsp); if (ret) { if (dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource), diff --git a/sys/compat/freebsd32/freebsd32_ioctl.c b/sys/compat/freebsd32/freebsd32_ioctl.c index a3226cdcd9a..414178a7bff 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, @@ -147,108 +117,6 @@ freebsd32_ioctl_memrange(struct thread *td, return (error); } -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 fc9c93a7a29..1d2312b41c1 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 6cc72e42399..66ab072edab 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 cc554b0efb6..c186771f070 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 27caed81eef..1a6ff314dfa 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 99103a3553b..9b5aafe4124 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 b2fcc65773e..ee18125a034 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 98d452a8f7a..087f4c695fa 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 76e9e8e3647..010fbc7460c 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 d2591137a99..f7a86cf5ee4 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 07448f44497..1977fb9dcce 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 d6df0c87864..faa057bfc88 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 daba1826331..8a70023eb91 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 7d8cc3c5cb8..ed61aa49648 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 a663deb59d1..55072f1046f 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 9e83b6379f5..5e749d52126 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 163fa748b2e..1983eac7944 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 399e55a9a47..738bfbf7916 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 74ac0ee2331..f445a073b6d 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 2ae3d768c2f..19b2f9388c6 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 f70afb27fa5..cb9474db855 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 764363f1985..ee52564d7cc 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 a117a5720c8..2bc2a243837 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 ede7bd49c19..1bafdab235d 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 987bd2db742..802fdafd63c 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 fb2c8b17328..17792dd922c 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 45f8d6397ed..2463212c25f 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 80cd58b5ccd..25b37eda389 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 1105a963128..15ae3e320e5 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 37eed4abcbc..3d5c0742580 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 fb0c2949c82..6a86f3488b4 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 c7134b9a2ab..193116e1068 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 63378be0452..f95ef854cea 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 dfe7b50e7bc..610f8bdeb82 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 393b78f540f..4ef92e39d1f 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 3e6dbfe7b46..d1b3761302a 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 94bd9c69e1c..e4b887a38e6 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 33ac83eb731..4f91b4fbbf2 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 127a61d61c2..a47aa909c23 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 866bace84c3..f23d16479ee 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 044582db6ed..ada4fa4fa77 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -66,9 +66,10 @@ enum { }; enum { + FEC_NONE = 0, FEC_RS = 1 << 0, FEC_BASER_RS = 1 << 1, - FEC_RESERVED = 1 << 2, + FEC_AUTO = 1 << 5, /* M_FW_PORT_CAP32_FEC + 1 */ }; enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS }; @@ -368,6 +369,7 @@ struct adapter_params { unsigned int ethoffload:1; unsigned int hash_filter:1; unsigned int filter2_wr_support:1; + unsigned int port_caps32:1; unsigned int ofldq_wr_cred; unsigned int eo_wr_cred; @@ -409,20 +411,21 @@ struct trace_params { }; struct link_config { - /* OS-specific code owns all the requested_* fields */ - unsigned char requested_aneg; /* link aneg user has requested */ - unsigned char requested_fc; /* flow control user has requested */ - unsigned char requested_fec; /* FEC user has requested */ - unsigned int requested_speed; /* speed user has requested (Mbps) */ + /* OS-specific code owns all the requested_* fields. */ + int8_t requested_aneg; /* link autonegotiation */ + int8_t requested_fc; /* flow control */ + int8_t requested_fec; /* FEC */ + u_int requested_speed; /* speed (Mbps) */ - unsigned short supported; /* link capabilities */ - unsigned short advertising; /* advertised capabilities */ - unsigned short lp_advertising; /* peer advertised capabilities */ - unsigned int speed; /* actual link speed (Mbps) */ - unsigned char fc; /* actual link flow control */ - unsigned char fec; /* actual FEC */ - unsigned char link_ok; /* link up? */ - unsigned char link_down_rc; /* link down reason */ + uint32_t supported; /* link capabilities */ + uint32_t advertising; /* advertised capabilities */ + uint32_t lp_advertising; /* peer advertised capabilities */ + uint32_t fec_hint; /* use this fec */ + u_int speed; /* actual link speed (Mbps) */ + int8_t fc; /* actual link flow control */ + int8_t fec; /* actual FEC */ + bool link_ok; /* link up? */ + uint8_t link_down_rc; /* link down reason */ }; #include "adapter.h" @@ -874,5 +877,16 @@ int t4vf_prep_adapter(struct adapter *adapter); int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid, enum t4_bar2_qtype qtype, int user, u64 *pbar2_qoffset, unsigned int *pbar2_qid); +unsigned int fwcap_to_speed(uint32_t caps); +uint32_t speed_to_fwcap(unsigned int speed); +uint32_t fwcap_top_speed(uint32_t caps); + +static inline int +port_top_speed(const struct port_info *pi) +{ + + /* Mbps -> Gbps */ + return (fwcap_to_speed(pi->link_cfg.supported) / 1000); +} #endif /* __CHELSIO_COMMON_H */ diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 2312b66cf7a..cec8ebbf00e 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -3755,6 +3755,93 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) } } +/** + * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits + * @caps16: a 16-bit Port Capabilities value + * + * Returns the equivalent 32-bit Port Capabilities value. + */ +static uint32_t fwcaps16_to_caps32(uint16_t caps16) +{ + uint32_t caps32 = 0; + + #define CAP16_TO_CAP32(__cap) \ + do { \ + if (caps16 & FW_PORT_CAP_##__cap) \ + caps32 |= FW_PORT_CAP32_##__cap; \ + } while (0) + + CAP16_TO_CAP32(SPEED_100M); + CAP16_TO_CAP32(SPEED_1G); + CAP16_TO_CAP32(SPEED_25G); + CAP16_TO_CAP32(SPEED_10G); + CAP16_TO_CAP32(SPEED_40G); + CAP16_TO_CAP32(SPEED_100G); + CAP16_TO_CAP32(FC_RX); + CAP16_TO_CAP32(FC_TX); + CAP16_TO_CAP32(ANEG); + CAP16_TO_CAP32(FORCE_PAUSE); + CAP16_TO_CAP32(MDIAUTO); + CAP16_TO_CAP32(MDISTRAIGHT); + CAP16_TO_CAP32(FEC_RS); + CAP16_TO_CAP32(FEC_BASER_RS); + CAP16_TO_CAP32(802_3_PAUSE); + CAP16_TO_CAP32(802_3_ASM_DIR); + + #undef CAP16_TO_CAP32 + + return caps32; +} + +/** + * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits + * @caps32: a 32-bit Port Capabilities value + * + * Returns the equivalent 16-bit Port Capabilities value. Note that + * not all 32-bit Port Capabilities can be represented in the 16-bit + * Port Capabilities and some fields/values may not make it. + */ +static uint16_t fwcaps32_to_caps16(uint32_t caps32) +{ + uint16_t caps16 = 0; + + #define CAP32_TO_CAP16(__cap) \ + do { \ + if (caps32 & FW_PORT_CAP32_##__cap) \ + caps16 |= FW_PORT_CAP_##__cap; \ + } while (0) + + CAP32_TO_CAP16(SPEED_100M); + CAP32_TO_CAP16(SPEED_1G); + CAP32_TO_CAP16(SPEED_10G); + CAP32_TO_CAP16(SPEED_25G); + CAP32_TO_CAP16(SPEED_40G); + CAP32_TO_CAP16(SPEED_100G); + CAP32_TO_CAP16(FC_RX); + CAP32_TO_CAP16(FC_TX); + CAP32_TO_CAP16(802_3_PAUSE); + CAP32_TO_CAP16(802_3_ASM_DIR); + CAP32_TO_CAP16(ANEG); + CAP32_TO_CAP16(FORCE_PAUSE); + CAP32_TO_CAP16(MDIAUTO); + CAP32_TO_CAP16(MDISTRAIGHT); + CAP32_TO_CAP16(FEC_RS); + CAP32_TO_CAP16(FEC_BASER_RS); + + #undef CAP32_TO_CAP16 + + return caps16; +} + +static bool +is_bt(struct port_info *pi) +{ + + return (pi->port_type == FW_PORT_TYPE_BT_SGMII || + pi->port_type == FW_PORT_TYPE_BT_XFI || + pi->port_type == FW_PORT_TYPE_BT_XAUI); +} + /** * t4_link_l1cfg - apply link configuration to MAC/PHY * @phy: the PHY to setup @@ -3772,53 +3859,45 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc) { struct fw_port_cmd c; - unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO); + unsigned int mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO); unsigned int aneg, fc, fec, speed, rcap; fc = 0; if (lc->requested_fc & PAUSE_RX) - fc |= FW_PORT_CAP_FC_RX; + fc |= FW_PORT_CAP32_FC_RX; if (lc->requested_fc & PAUSE_TX) - fc |= FW_PORT_CAP_FC_TX; + fc |= FW_PORT_CAP32_FC_TX; + if (!(lc->requested_fc & PAUSE_AUTONEG)) + fc |= FW_PORT_CAP32_FORCE_PAUSE; fec = 0; - if (lc->requested_fec & FEC_RS) - fec = FW_PORT_CAP_FEC_RS; - else if (lc->requested_fec & FEC_BASER_RS) - fec = FW_PORT_CAP_FEC_BASER_RS; - - if (!(lc->supported & FW_PORT_CAP_ANEG) || - lc->requested_aneg == AUTONEG_DISABLE) { - aneg = 0; - switch (lc->requested_speed) { - case 100000: - speed = FW_PORT_CAP_SPEED_100G; - break; - case 40000: - speed = FW_PORT_CAP_SPEED_40G; - break; - case 25000: - speed = FW_PORT_CAP_SPEED_25G; - break; - case 10000: - speed = FW_PORT_CAP_SPEED_10G; - break; - case 1000: - speed = FW_PORT_CAP_SPEED_1G; - break; - case 100: - speed = FW_PORT_CAP_SPEED_100M; - break; - default: - return -EINVAL; - break; - } - } else { - aneg = FW_PORT_CAP_ANEG; - speed = lc->supported & - V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED); + if (lc->requested_fec == FEC_AUTO) + fec = lc->fec_hint; + else { + if (lc->requested_fec & FEC_RS) + fec |= FW_PORT_CAP32_FEC_RS; + if (lc->requested_fec & FEC_BASER_RS) + fec |= FW_PORT_CAP32_FEC_BASER_RS; } + if (lc->requested_aneg == AUTONEG_DISABLE) + aneg = 0; + else if (lc->requested_aneg == AUTONEG_ENABLE) + aneg = FW_PORT_CAP32_ANEG; + else + aneg = lc->supported & FW_PORT_CAP32_ANEG; + + if (aneg) { + speed = lc->supported & V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED); + } else if (lc->requested_speed != 0) + speed = speed_to_fwcap(lc->requested_speed); + else + speed = fwcap_top_speed(lc->supported); + + /* Force AN on for BT cards. */ + if (is_bt(adap->port[port])) + aneg = lc->supported & FW_PORT_CAP32_ANEG; + rcap = aneg | speed | fc | fec; if ((rcap | lc->supported) != lc->supported) { #ifdef INVARIANTS @@ -3833,10 +3912,17 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_EXEC | V_FW_PORT_CMD_PORTID(port)); - c.action_to_len16 = - cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | + if (adap->params.port_caps32) { + c.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) | + FW_LEN16(c)); + c.u.l1cfg32.rcap32 = cpu_to_be32(rcap); + } else { + c.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); - c.u.l1cfg.rcap = cpu_to_be32(rcap); + c.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap)); + } return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); } @@ -7735,57 +7821,206 @@ const char *t4_link_down_rc_str(unsigned char link_down_rc) return reason[link_down_rc]; } +/* + * Return the highest speed set in the port capabilities, in Mb/s. + */ +unsigned int fwcap_to_speed(uint32_t caps) +{ + #define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return __speed; \ + } while (0) + + TEST_SPEED_RETURN(400G, 400000); + TEST_SPEED_RETURN(200G, 200000); + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + + #undef TEST_SPEED_RETURN + + return 0; +} + +/* + * Return the port capabilities bit for the given speed, which is in Mb/s. + */ +uint32_t speed_to_fwcap(unsigned int speed) +{ + #define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (speed == __speed) \ + return FW_PORT_CAP32_SPEED_##__caps_speed; \ + } while (0) + + TEST_SPEED_RETURN(400G, 400000); + TEST_SPEED_RETURN(200G, 200000); + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + + #undef TEST_SPEED_RETURN + + return 0; +} + +/* + * Return the port capabilities bit for the highest speed in the capabilities. + */ +uint32_t fwcap_top_speed(uint32_t caps) +{ + #define TEST_SPEED_RETURN(__caps_speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return FW_PORT_CAP32_SPEED_##__caps_speed; \ + } while (0) + + TEST_SPEED_RETURN(400G); + TEST_SPEED_RETURN(200G); + TEST_SPEED_RETURN(100G); + TEST_SPEED_RETURN(50G); + TEST_SPEED_RETURN(40G); + TEST_SPEED_RETURN(25G); + TEST_SPEED_RETURN(10G); + TEST_SPEED_RETURN(1G); + TEST_SPEED_RETURN(100M); + + #undef TEST_SPEED_RETURN + + return 0; +} + + +/** + * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities + * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value + * + * Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new + * 32-bit Port Capabilities value. + */ +static uint32_t lstatus_to_fwcap(u32 lstatus) +{ + uint32_t linkattr = 0; + + /* + * Unfortunately the format of the Link Status in the old + * 16-bit Port Information message isn't the same as the + * 16-bit Port Capabilities bitfield used everywhere else ... + */ + if (lstatus & F_FW_PORT_CMD_RXPAUSE) + linkattr |= FW_PORT_CAP32_FC_RX; + if (lstatus & F_FW_PORT_CMD_TXPAUSE) + linkattr |= FW_PORT_CAP32_FC_TX; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) + linkattr |= FW_PORT_CAP32_SPEED_100M; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) + linkattr |= FW_PORT_CAP32_SPEED_1G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) + linkattr |= FW_PORT_CAP32_SPEED_10G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) + linkattr |= FW_PORT_CAP32_SPEED_25G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + linkattr |= FW_PORT_CAP32_SPEED_40G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) + linkattr |= FW_PORT_CAP32_SPEED_100G; + + return linkattr; +} + /* * Updates all fields owned by the common code in port_info and link_config * based on information provided by the firmware. Does not touch any * requested_* field. */ -static void handle_port_info(struct port_info *pi, const struct fw_port_info *p) +static void handle_port_info(struct port_info *pi, const struct fw_port_cmd *p, + enum fw_port_action action, bool *mod_changed, bool *link_changed) { - struct link_config *lc = &pi->link_cfg; - int speed; + struct link_config old_lc, *lc = &pi->link_cfg; unsigned char fc, fec; - u32 stat = be32_to_cpu(p->lstatus_to_modtype); + u32 stat, linkattr; + int old_ptype, old_mtype; - pi->port_type = G_FW_PORT_CMD_PTYPE(stat); - pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); - pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? - G_FW_PORT_CMD_MDIOADDR(stat) : -1; + old_ptype = pi->port_type; + old_mtype = pi->mod_type; + old_lc = *lc; + if (action == FW_PORT_ACTION_GET_PORT_INFO) { + stat = be32_to_cpu(p->u.info.lstatus_to_modtype); - lc->supported = be16_to_cpu(p->pcap); - lc->advertising = be16_to_cpu(p->acap); - lc->lp_advertising = be16_to_cpu(p->lpacap); - lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; - lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); + pi->port_type = G_FW_PORT_CMD_PTYPE(stat); + pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); + pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? + G_FW_PORT_CMD_MDIOADDR(stat) : -1; - speed = 0; - if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) - speed = 100; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) - speed = 1000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) - speed = 10000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) - speed = 25000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) - speed = 40000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) - speed = 100000; - lc->speed = speed; + lc->supported = fwcaps16_to_caps32(be16_to_cpu(p->u.info.pcap)); + lc->advertising = fwcaps16_to_caps32(be16_to_cpu(p->u.info.acap)); + lc->lp_advertising = fwcaps16_to_caps32(be16_to_cpu(p->u.info.lpacap)); + lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); + + linkattr = lstatus_to_fwcap(stat); + } else if (action == FW_PORT_ACTION_GET_PORT_INFO32) { + stat = be32_to_cpu(p->u.info32.lstatus32_to_cbllen32); + + pi->port_type = G_FW_PORT_CMD_PORTTYPE32(stat); + pi->mod_type = G_FW_PORT_CMD_MODTYPE32(stat); + pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP32 ? + G_FW_PORT_CMD_MDIOADDR32(stat) : -1; + + lc->supported = be32_to_cpu(p->u.info32.pcaps32); + lc->advertising = be32_to_cpu(p->u.info32.acaps32); + lc->lp_advertising = be16_to_cpu(p->u.info32.lpacaps32); + lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS32) != 0; + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC32(stat); + + linkattr = be32_to_cpu(p->u.info32.linkattr32); + } else { + CH_ERR(pi->adapter, "bad port_info action 0x%x\n", action); + return; + } + + lc->speed = fwcap_to_speed(linkattr); fc = 0; - if (stat & F_FW_PORT_CMD_RXPAUSE) + if (linkattr & FW_PORT_CAP32_FC_RX) fc |= PAUSE_RX; - if (stat & F_FW_PORT_CMD_TXPAUSE) + if (linkattr & FW_PORT_CAP32_FC_TX) fc |= PAUSE_TX; lc->fc = fc; - fec = 0; - if (lc->advertising & FW_PORT_CAP_FEC_RS) - fec = FEC_RS; - else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS) - fec = FEC_BASER_RS; + fec = FEC_NONE; + if (linkattr & FW_PORT_CAP32_FEC_RS) + fec |= FEC_RS; + if (linkattr & FW_PORT_CAP32_FEC_BASER_RS) + fec |= FEC_BASER_RS; lc->fec = fec; + + if (mod_changed != NULL) + *mod_changed = false; + if (link_changed != NULL) + *link_changed = false; + if (old_ptype != pi->port_type || old_mtype != pi->mod_type || + old_lc.supported != lc->supported) { + if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) { + lc->fec_hint = lc->advertising & + V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC); + } + if (mod_changed != NULL) + *mod_changed = true; + } + if (old_lc.link_ok != lc->link_ok || old_lc.speed != lc->speed || + old_lc.fec != lc->fec || old_lc.fc != lc->fc) { + if (link_changed != NULL) + *link_changed = true; + } } /** @@ -7798,22 +8033,24 @@ static void handle_port_info(struct port_info *pi, const struct fw_port_info *p) */ int t4_update_port_info(struct port_info *pi) { - struct fw_port_cmd port_cmd; + struct adapter *sc = pi->adapter; + struct fw_port_cmd cmd; + enum fw_port_action action; int ret; - memset(&port_cmd, 0, sizeof port_cmd); - port_cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | - F_FW_CMD_REQUEST | F_FW_CMD_READ | - V_FW_PORT_CMD_PORTID(pi->tx_chan)); - port_cmd.action_to_len16 = cpu_to_be32( - V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | - FW_LEN16(port_cmd)); - ret = t4_wr_mbox_ns(pi->adapter, pi->adapter->mbox, - &port_cmd, sizeof(port_cmd), &port_cmd); + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | + F_FW_CMD_REQUEST | F_FW_CMD_READ | + V_FW_PORT_CMD_PORTID(pi->tx_chan)); + action = sc->params.port_caps32 ? FW_PORT_ACTION_GET_PORT_INFO32 : + FW_PORT_ACTION_GET_PORT_INFO; + cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) | + FW_LEN16(cmd)); + ret = t4_wr_mbox_ns(sc, sc->mbox, &cmd, sizeof(cmd), &cmd); if (ret) return ret; - handle_port_info(pi, &port_cmd.u.info); + handle_port_info(pi, &cmd, action, NULL, NULL); return 0; } @@ -7828,15 +8065,18 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) { u8 opcode = *(const u8 *)rpl; const struct fw_port_cmd *p = (const void *)rpl; - unsigned int action = - G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); + enum fw_port_action action = + G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); + bool mod_changed, link_changed; - if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) { + if (opcode == FW_PORT_CMD && + (action == FW_PORT_ACTION_GET_PORT_INFO || + action == FW_PORT_ACTION_GET_PORT_INFO32)) { /* link/module state change message */ - int i, old_ptype, old_mtype; + int i; int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid)); struct port_info *pi = NULL; - struct link_config *lc, *old_lc; + struct link_config *lc; for_each_port(adap, i) { pi = adap2pinfo(adap, i); @@ -7846,23 +8086,15 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) lc = &pi->link_cfg; PORT_LOCK(pi); - old_lc = &pi->old_link_cfg; - old_ptype = pi->port_type; - old_mtype = pi->mod_type; - handle_port_info(pi, &p->u.info); + handle_port_info(pi, p, action, &mod_changed, &link_changed); PORT_UNLOCK(pi); - if (old_ptype != pi->port_type || old_mtype != pi->mod_type) { + if (mod_changed) t4_os_portmod_changed(pi); - } - PORT_LOCK(pi); - if (old_lc->link_ok != lc->link_ok || - old_lc->speed != lc->speed || - old_lc->fec != lc->fec || - old_lc->fc != lc->fc) { + if (link_changed) { + PORT_LOCK(pi); t4_os_link_changed(pi); - *old_lc = *lc; + PORT_UNLOCK(pi); } - PORT_UNLOCK(pi); } else { CH_WARN_RATELIMIT(adap, "Unknown firmware reply %d\n", opcode); return -EINVAL; @@ -8595,6 +8827,11 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) } while ((adap->params.portvec & (1 << j)) == 0); } + p->tx_chan = j; + p->mps_bg_map = t4_get_mps_bg_map(adap, j); + p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); + p->lport = j; + if (!(adap->flags & IS_VF) || adap->params.vfres.r_caps & FW_CMD_CAP_PORT) { t4_update_port_info(p); @@ -8609,10 +8846,6 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) p->vi[0].smt_idx = (ret & 0x7f) << 1; else p->vi[0].smt_idx = (ret & 0x7f); - p->tx_chan = j; - p->mps_bg_map = t4_get_mps_bg_map(adap, j); - p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); - p->lport = j; p->vi[0].rss_size = rss_size; t4_os_set_hw_addr(p, addr); diff --git a/sys/dev/cxgbe/firmware/t4fw_cfg.txt b/sys/dev/cxgbe/firmware/t4fw_cfg.txt index 43820a0b44c..11721a1ed64 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 721ff372ef8..f42966c62e4 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 3b62ed83b34..c542cfcadf5 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 5cd3e88803a..6eec287db1a 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 fe26b47566e..4f325bdd235 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 22e84d320aa..5e96579f171 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; - - rw_wlock(&d->lock); - e = t4_alloc_l2e(d); - if (e) { - mtx_lock(&e->lock); /* avoid race with t4_l2t_free */ - e->state = L2T_STATE_SWITCHING; - atomic_store_rel_int(&e->refcnt, 1); - mtx_unlock(&e->lock); - } - rw_wunlock(&d->lock); - return e; -} - -/* - * Sets/updates the contents of a switching L2T entry that has been allocated - * with an earlier call to @t4_l2t_alloc_switching. - */ -int -t4_l2t_set_switching(struct adapter *sc, struct l2t_entry *e, uint16_t vlan, - uint8_t port, uint8_t *eth_addr) -{ int rc; - e->vlan = vlan; - e->lport = port; - e->wrq = &sc->sge.ctrlq[0]; - e->iqid = sc->sge.fwq.abs_id; - memcpy(e->dmac, eth_addr, ETHER_ADDR_LEN); - mtx_lock(&e->lock); - rc = t4_write_l2e(e, 0); - mtx_unlock(&e->lock); - return (rc); + rw_wlock(&d->lock); + e = find_or_alloc_l2e(d, vlan, port, eth_addr); + if (e) { + if (atomic_load_acq_int(&e->refcnt) == 0) { + mtx_lock(&e->lock); /* avoid race with t4_l2t_free */ + e->wrq = &sc->sge.ctrlq[0]; + e->iqid = sc->sge.fwq.abs_id; + e->state = L2T_STATE_SWITCHING; + e->vlan = vlan; + e->lport = port; + memcpy(e->dmac, eth_addr, ETHER_ADDR_LEN); + atomic_store_rel_int(&e->refcnt, 1); + atomic_subtract_int(&d->nfree, 1); + rc = t4_write_l2e(e, 0); + mtx_unlock(&e->lock); + if (rc != 0) + e = NULL; + } else { + MPASS(e->vlan == vlan); + MPASS(e->lport == port); + atomic_add_int(&e->refcnt, 1); + } + } + rw_wunlock(&d->lock); + return (e); } int diff --git a/sys/dev/cxgbe/t4_l2t.h b/sys/dev/cxgbe/t4_l2t.h index 21c392018fe..188669e8026 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 d6bf50121a1..898cbf4db46 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, ¶m, &val); + /* Enable 32b port caps if the firmware supports it. */ + param = FW_PARAM_PFVF(PORT_CAPS32); + val = 1; + if (t4_set_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val) == 0) + sc->params.port_caps32 = 1; + #ifdef TCP_OFFLOAD /* * Override the TOE timers with user provided tunables. This is not the @@ -4215,22 +4232,30 @@ ifmedia_add4(struct ifmedia *ifm, int m) ifmedia_add(ifm, m | IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE, 0, NULL); } +/* + * This is the selected media, which is not quite the same as the active media. + * The media line in ifconfig is "media: Ethernet selected (active)" if selected + * and active are not the same, and "media: Ethernet selected" otherwise. + */ static void -set_current_media(struct port_info *pi, struct ifmedia *ifm) +set_current_media(struct port_info *pi) { struct link_config *lc; + struct ifmedia *ifm; int mword; + u_int speed; PORT_LOCK_ASSERT_OWNED(pi); /* Leave current media alone if it's already set to IFM_NONE. */ + ifm = &pi->media; if (ifm->ifm_cur != NULL && IFM_SUBTYPE(ifm->ifm_cur->ifm_media) == IFM_NONE) return; lc = &pi->link_cfg; - if (lc->requested_aneg == AUTONEG_ENABLE && - lc->supported & FW_PORT_CAP_ANEG) { + if (lc->requested_aneg != AUTONEG_DISABLE && + lc->supported & FW_PORT_CAP32_ANEG) { ifmedia_set(ifm, IFM_ETHER | IFM_AUTO); return; } @@ -4239,16 +4264,42 @@ set_current_media(struct port_info *pi, struct ifmedia *ifm) mword |= IFM_ETH_TXPAUSE; if (lc->requested_fc & PAUSE_RX) mword |= IFM_ETH_RXPAUSE; - mword |= port_mword(pi, speed_to_fwspeed(lc->requested_speed)); + if (lc->requested_speed == 0) + speed = port_top_speed(pi) * 1000; /* Gbps -> Mbps */ + else + speed = lc->requested_speed; + mword |= port_mword(pi, speed_to_fwcap(speed)); ifmedia_set(ifm, mword); } -static void -build_medialist(struct port_info *pi, struct ifmedia *ifm) +/* + * Returns true if the ifmedia list for the port cannot change. + */ +static bool +fixed_ifmedia(struct port_info *pi) { - uint16_t ss, speed; + + return (pi->port_type == FW_PORT_TYPE_BT_SGMII || + pi->port_type == FW_PORT_TYPE_BT_XFI || + pi->port_type == FW_PORT_TYPE_BT_XAUI || + pi->port_type == FW_PORT_TYPE_KX4 || + pi->port_type == FW_PORT_TYPE_KX || + pi->port_type == FW_PORT_TYPE_KR || + pi->port_type == FW_PORT_TYPE_BP_AP || + pi->port_type == FW_PORT_TYPE_BP4_AP || + pi->port_type == FW_PORT_TYPE_BP40_BA || + pi->port_type == FW_PORT_TYPE_KR4_100G || + pi->port_type == FW_PORT_TYPE_KR_SFP28 || + pi->port_type == FW_PORT_TYPE_KR_XLAUI); +} + +static void +build_medialist(struct port_info *pi) +{ + uint32_t ss, speed; int unknown, mword, bit; struct link_config *lc; + struct ifmedia *ifm; PORT_LOCK_ASSERT_OWNED(pi); @@ -4256,18 +4307,12 @@ build_medialist(struct port_info *pi, struct ifmedia *ifm) return; /* - * First setup all the requested_ fields so that they comply with what's - * supported by the port + transceiver. Note that this clobbers any - * user preferences set via sysctl_pause_settings or sysctl_autoneg. - */ - init_l1cfg(pi); - - /* - * Now (re)build the ifmedia list. + * Rebuild the ifmedia list. */ + ifm = &pi->media; ifmedia_removeall(ifm); lc = &pi->link_cfg; - ss = G_FW_PORT_CAP_SPEED(lc->supported); /* Supported Speeds */ + ss = G_FW_PORT_CAP32_SPEED(lc->supported); /* Supported Speeds */ if (__predict_false(ss == 0)) { /* not supposed to happen. */ MPASS(ss != 0); no_media: @@ -4278,9 +4323,9 @@ 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); + lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX | + PAUSE_AUTONEG); - if (t4_fec != -1) { - if (t4_fec & FEC_RS && lc->supported & FW_PORT_CAP_FEC_RS) { - lc->requested_fec = FEC_RS; - } else if (t4_fec & FEC_BASER_RS && - lc->supported & FW_PORT_CAP_FEC_BASER_RS) { - lc->requested_fec = FEC_BASER_RS; - } else { - lc->requested_fec = 0; - } - } else { - /* Use the suggested value provided by the firmware in acaps */ - if (lc->advertising & FW_PORT_CAP_FEC_RS && - lc->supported & FW_PORT_CAP_FEC_RS) { - lc->requested_fec = FEC_RS; - } else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS && - lc->supported & FW_PORT_CAP_FEC_BASER_RS) { - lc->requested_fec = FEC_BASER_RS; - } else { - lc->requested_fec = 0; - } + if (t4_fec == -1 || t4_fec & FEC_AUTO) + lc->requested_fec = FEC_AUTO; + else { + lc->requested_fec = FEC_NONE; + if (t4_fec & FEC_RS) + lc->requested_fec |= FEC_RS; + if (t4_fec & FEC_BASER_RS) + lc->requested_fec |= FEC_BASER_RS; } } /* - * Apply the settings in requested_* to the hardware. The parameters are - * expected to be sane. + * Makes sure that all requested settings comply with what's supported by the + * port. Returns the number of settings that were invalid and had to be fixed. */ static int -apply_l1cfg(struct port_info *pi) +fixup_link_config(struct port_info *pi) +{ + int n = 0; + struct link_config *lc = &pi->link_cfg; + uint32_t fwspeed; + + PORT_LOCK_ASSERT_OWNED(pi); + + /* Speed (when not autonegotiating) */ + if (lc->requested_speed != 0) { + fwspeed = speed_to_fwcap(lc->requested_speed); + if ((fwspeed & lc->supported) == 0) { + n++; + lc->requested_speed = 0; + } + } + + /* Link autonegotiation */ + MPASS(lc->requested_aneg == AUTONEG_ENABLE || + lc->requested_aneg == AUTONEG_DISABLE || + lc->requested_aneg == AUTONEG_AUTO); + if (lc->requested_aneg == AUTONEG_ENABLE && + !(lc->supported & FW_PORT_CAP32_ANEG)) { + n++; + lc->requested_aneg = AUTONEG_AUTO; + } + + /* Flow control */ + MPASS((lc->requested_fc & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) == 0); + if (lc->requested_fc & PAUSE_TX && + !(lc->supported & FW_PORT_CAP32_FC_TX)) { + n++; + lc->requested_fc &= ~PAUSE_TX; + } + if (lc->requested_fc & PAUSE_RX && + !(lc->supported & FW_PORT_CAP32_FC_RX)) { + n++; + lc->requested_fc &= ~PAUSE_RX; + } + if (!(lc->requested_fc & PAUSE_AUTONEG) && + !(lc->supported & FW_PORT_CAP32_FORCE_PAUSE)) { + n++; + lc->requested_fc |= PAUSE_AUTONEG; + } + + /* FEC */ + if ((lc->requested_fec & FEC_RS && + !(lc->supported & FW_PORT_CAP32_FEC_RS)) || + (lc->requested_fec & FEC_BASER_RS && + !(lc->supported & FW_PORT_CAP32_FEC_BASER_RS))) { + n++; + lc->requested_fec = FEC_AUTO; + } + + return (n); +} + +/* + * Apply the requested L1 settings, which are expected to be valid, to the + * hardware. + */ +static int +apply_link_config(struct port_info *pi) { struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; -#ifdef INVARIANTS - uint16_t fwspeed; +#ifdef INVARIANTS ASSERT_SYNCHRONIZED_OP(sc); PORT_LOCK_ASSERT_OWNED(pi); if (lc->requested_aneg == AUTONEG_ENABLE) - MPASS(lc->supported & FW_PORT_CAP_ANEG); + MPASS(lc->supported & FW_PORT_CAP32_ANEG); + if (!(lc->requested_fc & PAUSE_AUTONEG)) + MPASS(lc->supported & FW_PORT_CAP32_FORCE_PAUSE); if (lc->requested_fc & PAUSE_TX) - MPASS(lc->supported & FW_PORT_CAP_FC_TX); + MPASS(lc->supported & FW_PORT_CAP32_FC_TX); if (lc->requested_fc & PAUSE_RX) - MPASS(lc->supported & FW_PORT_CAP_FC_RX); - if (lc->requested_fec == FEC_RS) - MPASS(lc->supported & FW_PORT_CAP_FEC_RS); - if (lc->requested_fec == FEC_BASER_RS) - MPASS(lc->supported & FW_PORT_CAP_FEC_BASER_RS); - fwspeed = speed_to_fwspeed(lc->requested_speed); - MPASS(fwspeed != 0); - MPASS(lc->supported & fwspeed); + MPASS(lc->supported & FW_PORT_CAP32_FC_RX); + if (lc->requested_fec & FEC_RS) + MPASS(lc->supported & FW_PORT_CAP32_FEC_RS); + if (lc->requested_fec & FEC_BASER_RS) + MPASS(lc->supported & FW_PORT_CAP32_FEC_BASER_RS); #endif rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc != 0) { @@ -4380,8 +4473,17 @@ apply_l1cfg(struct port_info *pi) if (!(sc->flags & IS_VF) || rc != FW_EPERM) device_printf(pi->dev, "l1cfg failed: %d\n", rc); } else { - lc->fc = lc->requested_fc; - lc->fec = lc->requested_fec; + /* + * An L1_CFG will almost always result in a link-change event if + * the link is up, and the driver will refresh the actual + * fec/fc/etc. when the notification is processed. If the link + * is down then the actual settings are meaningless. + * + * This takes care of the case where a change in the L1 settings + * may not result in a notification. + */ + if (lc->link_ok && !(lc->requested_fc & PAUSE_AUTONEG)) + lc->fc = lc->requested_fc & (PAUSE_TX | PAUSE_RX); } return (rc); } @@ -4635,9 +4737,18 @@ cxgbe_init_synchronized(struct vi_info *vi) if (rc) goto done; /* error message displayed already */ + PORT_LOCK(pi); + if (pi->up_vis == 0) { + t4_update_port_info(pi); + fixup_link_config(pi); + build_medialist(pi); + apply_link_config(pi); + } + rc = -t4_enable_vi(sc, sc->mbox, vi->viid, true, true); if (rc != 0) { if_printf(ifp, "enable_vi failed: %d\n", rc); + PORT_UNLOCK(pi); goto done; } @@ -4664,12 +4775,7 @@ cxgbe_init_synchronized(struct vi_info *vi) } /* all ok */ - PORT_LOCK(pi); - if (pi->up_vis++ == 0) { - t4_update_port_info(pi); - build_medialist(pi, &pi->media); - apply_l1cfg(pi); - } + pi->up_vis++; ifp->if_drv_flags |= IFF_DRV_RUNNING; if (pi->nvi > 1 || sc->flags & IS_VF) @@ -4744,11 +4850,10 @@ cxgbe_uninit_synchronized(struct vi_info *vi) return (0); } - pi->link_cfg.link_ok = 0; + pi->link_cfg.link_ok = false; pi->link_cfg.speed = 0; pi->link_cfg.link_down_rc = 255; t4_os_link_changed(pi); - pi->old_link_cfg = pi->link_cfg; PORT_UNLOCK(pi); return (0); @@ -6512,7 +6617,7 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (req->newptr == NULL) { struct sbuf *sb; - static char *bits = "\20\1PAUSE_RX\2PAUSE_TX"; + static char *bits = "\20\1RX\2TX\3AUTO"; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -6522,14 +6627,21 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - sbuf_printf(sb, "%b", lc->fc & (PAUSE_TX | PAUSE_RX), bits); + if (lc->link_ok) { + sbuf_printf(sb, "%b", (lc->fc & (PAUSE_TX | PAUSE_RX)) | + (lc->requested_fc & PAUSE_AUTONEG), bits); + } else { + sbuf_printf(sb, "%b", lc->requested_fc & (PAUSE_TX | + PAUSE_RX | PAUSE_AUTONEG), bits); + } rc = sbuf_finish(sb); sbuf_delete(sb); } else { char s[2]; int n; - s[0] = '0' + (lc->requested_fc & (PAUSE_TX | PAUSE_RX)); + s[0] = '0' + (lc->requested_fc & (PAUSE_TX | PAUSE_RX | + PAUSE_AUTONEG)); s[1] = 0; rc = sysctl_handle_string(oidp, s, sizeof(s), req); @@ -6541,7 +6653,7 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (s[0] < '0' || s[0] > '9') return (EINVAL); /* not a number */ n = s[0] - '0'; - if (n & ~(PAUSE_TX | PAUSE_RX)) + if (n & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) return (EINVAL); /* some other bit is set too */ rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, @@ -6549,15 +6661,11 @@ sysctl_pause_settings(SYSCTL_HANDLER_ARGS) if (rc) return (rc); PORT_LOCK(pi); - if ((lc->requested_fc & (PAUSE_TX | PAUSE_RX)) != n) { - lc->requested_fc &= ~(PAUSE_TX | PAUSE_RX); - lc->requested_fc |= n; - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - if (rc == 0) { - lc->fc = lc->requested_fc; - set_current_media(pi, &pi->media); - } - } + lc->requested_fc = n; + fixup_link_config(pi); + if (pi->up_vis > 0) + rc = apply_link_config(pi); + set_current_media(pi); PORT_UNLOCK(pi); end_synchronized_op(sc, 0); } @@ -6572,10 +6680,11 @@ sysctl_fec(SYSCTL_HANDLER_ARGS) struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; + int8_t old; if (req->newptr == NULL) { struct sbuf *sb; - static char *bits = "\20\1RS\2BASER_RS\3RESERVED"; + static char *bits = "\20\1RS\2BASE-R\3RSVD1\4RSVD2\5RSVD3\6AUTO"; rc = sysctl_wire_old_buffer(req, 0); if (rc != 0) @@ -6585,43 +6694,68 @@ sysctl_fec(SYSCTL_HANDLER_ARGS) if (sb == NULL) return (ENOMEM); - sbuf_printf(sb, "%b", lc->fec & M_FW_PORT_CAP_FEC, bits); + /* + * Display the requested_fec when the link is down -- the actual + * FEC makes sense only when the link is up. + */ + if (lc->link_ok) { + sbuf_printf(sb, "%b", (lc->fec & M_FW_PORT_CAP32_FEC) | + (lc->requested_fec & FEC_AUTO), bits); + } else { + sbuf_printf(sb, "%b", lc->requested_fec, bits); + } rc = sbuf_finish(sb); sbuf_delete(sb); } else { - char s[2]; + char s[3]; int n; - s[0] = '0' + (lc->requested_fec & M_FW_PORT_CAP_FEC); - s[1] = 0; + snprintf(s, sizeof(s), "%d", + lc->requested_fec == FEC_AUTO ? -1 : + lc->requested_fec & M_FW_PORT_CAP32_FEC); rc = sysctl_handle_string(oidp, s, sizeof(s), req); if (rc != 0) return(rc); - if (s[1] != 0) - return (EINVAL); - if (s[0] < '0' || s[0] > '9') - return (EINVAL); /* not a number */ - n = s[0] - '0'; - if (n & ~M_FW_PORT_CAP_FEC) - return (EINVAL); /* some other bit is set too */ - if (!powerof2(n)) - return (EINVAL); /* one bit can be set at most */ + n = strtol(&s[0], NULL, 0); + if (n < 0 || n & FEC_AUTO) + n = FEC_AUTO; + else { + if (n & ~M_FW_PORT_CAP32_FEC) + return (EINVAL);/* some other bit is set too */ + if (!powerof2(n)) + return (EINVAL);/* one bit can be set at most */ + } rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4fec"); if (rc) return (rc); PORT_LOCK(pi); - if ((lc->requested_fec & M_FW_PORT_CAP_FEC) != n) { - lc->requested_fec = n & - G_FW_PORT_CAP_FEC(lc->supported); - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - if (rc == 0) { - lc->fec = lc->requested_fec; + old = lc->requested_fec; + if (n == FEC_AUTO) + lc->requested_fec = FEC_AUTO; + else if (n == 0) + lc->requested_fec = FEC_NONE; + else { + if ((lc->supported | V_FW_PORT_CAP32_FEC(n)) != + lc->supported) { + rc = ENOTSUP; + goto done; + } + lc->requested_fec = n; + } + fixup_link_config(pi); + if (pi->up_vis > 0) { + rc = apply_link_config(pi); + if (rc != 0) { + lc->requested_fec = old; + if (rc == FW_EPROTO) + rc = ENOTSUP; } } +done: PORT_UNLOCK(pi); end_synchronized_op(sc, 0); } @@ -6635,10 +6769,10 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS) struct port_info *pi = arg1; struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; - int rc, val, old; + int rc, val; - if (lc->supported & FW_PORT_CAP_ANEG) - val = lc->requested_aneg == AUTONEG_ENABLE ? 1 : 0; + if (lc->supported & FW_PORT_CAP32_ANEG) + val = lc->requested_aneg == AUTONEG_DISABLE ? 0 : 1; else val = -1; rc = sysctl_handle_int(oidp, &val, 0, req); @@ -6649,28 +6783,22 @@ sysctl_autoneg(SYSCTL_HANDLER_ARGS) else if (val == 1) val = AUTONEG_ENABLE; else - return (EINVAL); + val = AUTONEG_AUTO; rc = begin_synchronized_op(sc, &pi->vi[0], SLEEP_OK | INTR_OK, "t4aneg"); if (rc) return (rc); PORT_LOCK(pi); - if ((lc->supported & FW_PORT_CAP_ANEG) == 0) { + if (val == AUTONEG_ENABLE && !(lc->supported & FW_PORT_CAP32_ANEG)) { rc = ENOTSUP; goto done; } - if (lc->requested_aneg == val) { - rc = 0; /* no change, do nothing. */ - goto done; - } - old = lc->requested_aneg; lc->requested_aneg = val; - rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); - if (rc != 0) - lc->requested_aneg = old; - else - set_current_media(pi, &pi->media); + fixup_link_config(pi); + if (pi->up_vis > 0) + rc = apply_link_config(pi); + set_current_media(pi); done: PORT_UNLOCK(pi); end_synchronized_op(sc, 0); @@ -9407,13 +9535,17 @@ t4_os_portmod_changed(struct port_info *pi) NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM" }; - MPASS((pi->flags & FIXED_IFMEDIA) == 0); + KASSERT((pi->flags & FIXED_IFMEDIA) == 0, + ("%s: port_type %u", __func__, pi->port_type)); vi = &pi->vi[0]; if (begin_synchronized_op(sc, vi, HOLD_LOCK, "t4mod") == 0) { PORT_LOCK(pi); - build_medialist(pi, &pi->media); - apply_l1cfg(pi); + build_medialist(pi); + if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) { + fixup_link_config(pi); + apply_link_config(pi); + } PORT_UNLOCK(pi); end_synchronized_op(sc, LOCK_HELD); } diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 4a6ac900962..684606a8d5b 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 e1593b02db2..a4394de9c55 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 8489ca84802..c7b0bce2c7a 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 f0c8867501b..8a7168861ac 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 92a792746b1..c6c242c875c 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 bf3dd063c17..73f83ccef0c 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 a95d606ac34..93714cd1071 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 b487b97de82..8ada958abcb 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 cadc8bdbf67..a27de7db593 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 a5ce9e45287..294d9d5e55a 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 ea291ab8df2..d52bf9a4e3d 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 b89f8329a4f..2c3297a05be 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 af9db3da9c3..ce3027fb344 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 4d2e08fe157..8764ac9e922 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 4d7a4535d27..1fad25c5570 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 237e24c1070..11beb743ed4 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 eed7d651bfd..ae73f3b2abc 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 63a18ecf025..3911a70c0b4 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 4b4cf9ab10c..15da5e861a0 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 744c26dfafd..b03de58fcb5 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 1da31934f73..e99d5aedc71 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 9daa85257ac..4e08dacf8c4 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 e46082c0b3b..3e79f4b400c 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 cca61066406..44843ff3fc9 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 a6a3465b60d..91f2f8ef755 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 6d83545ae94..23c9d13c695 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 f0a91b761f8..dd72d52ab18 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 d63c5ae6435..ee609b32899 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 03f3143040c..e86bd9e102b 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 a81fe8a7300..1e12c9a6906 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 cd6afce40f5..4774390b272 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 b1d5e3586c9..ef5ef7613b9 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 5cfb413731c..58bc2a6af01 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 3bb57fcb71d..d61f664d8cf 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 23e32a59de4..0b7aa4da237 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 537856b97ef..edc90ed7bf3 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 5138c243f5b..87f41850ec5 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 bbffb8b5320..f2f6387c8aa 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 4e40a816736..380beff0d31 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 00589c4b83d..edec95c8e67 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 c5a8afb4ed2..376fb96594c 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 6073310b2ac..0e91df03ea1 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 f0c6aa81dde..012a16dc9e9 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 6d9de66e53c..41e81d57353 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 7e8c6313160..e5d4787ebbe 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 844be21d64b..c202ba054cf 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 1a9c1496a77..0c12929bee1 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 3a8446a871f..8b672ebeadb 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 f4be108ab7b..15b4472a37b 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 2bf0609697e..24ce36b64a6 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 147b5d5e71b..d5648c0301e 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 0afe62a522d..29d32339989 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 78fa1b920f8..33a802103f0 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 a2edacec987..665b55b1c35 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); @@ -1099,19 +1146,6 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, return (error); } -static void -fpusave(addr) - union savefpu *addr; -{ - - if (use_xsave) - xsave((char *)addr, xsave_mask); - else if (cpu_fxsr) - fxsave(addr); - else - fnsave(addr); -} - static void npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct save87 *sv_87) { diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 0c1437df518..9dd80ad72d4 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 PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) - -void -pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) +DEFINE_IFUNC(, void, pmap_invalidate_cache_range, (vm_offset_t, vm_offset_t), + static) { - if (force) { - sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); - } else { - KASSERT((sva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: sva not page-aligned")); - KASSERT((eva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: eva not page-aligned")); + if ((cpu_feature & CPUID_SS) != 0) + return (pmap_invalidate_cache_range_selfsnoop); + if ((cpu_feature & CPUID_CLFSH) != 0) + return (pmap_force_invalidate_cache_range); + return (pmap_invalidate_cache_range_all); +} + +#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) + +static void +pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva) +{ + + KASSERT((sva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: sva not page-aligned")); + KASSERT((eva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: eva not page-aligned")); +} + +static void +pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); +} + +void +pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) +{ + + sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); + if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) { + /* + * The supplied range is bigger than 2MB. + * Globally invalidate cache. + */ + pmap_invalidate_cache(); + return; } - if ((cpu_feature & CPUID_SS) != 0 && !force) - ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { #ifdef DEV_APIC - /* - * XXX: Some CPUs fault, hang, or trash the local APIC - * registers if we use CLFLUSH on the local APIC - * range. The local APIC is always uncached, so we - * don't need to flush for that range anyway. - */ - if (pmap_kextract(sva) == lapic_paddr) - return; + /* + * 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 19086221b11..4b62484533c 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 c3ed95dd4d0..25068945964 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 da9ae658818..e48c0d3c6af 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 1a3e661b67a..d95a9c1ab3f 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 5ea572ff038..885b5dc6f03 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 5afb371bfb2..3bd5f31082a 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 b1612b11f77..3f4a81ff70d 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> @@ -478,6 +483,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'. */ @@ -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 ca1f7326fe3..08a704d904b 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 c102eb52e5b..a8d42a85d94 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 bed34bf4a7f..271339e5c4c 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 94fe5c407ae..9338b06bb26 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 3c83c777b6a..8529266f381 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 649cfb191b7..455220c3675 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 a107b5571b3..8e74163fe6d 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 9ea0f1b5353..08b254655ee 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 18a4c6c9e83..af2fd1ff65f 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 cdfb84e4244..675c0aa02ac 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 91d93bb8920..a0ddefaa15d 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 3147eafb7c7..2acea128cdf 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 591396c588d..a2b923ee04e 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 2bce8c1e7aa..1efd5ea20c6 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 cf404012a2e..d47117f17b8 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 480df7433a6..c9452406a15 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 11baf8a018b..5170ee6ae35 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 65bf07a0b2c..d9a6e3b962d 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 6e1eee633a2..bda5ad45dfc 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 86c9705cb90..6d2c86d5014 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 f3d1d3afcab..65ac922fc1b 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 9d7b9cbe866..a08806a686b 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 26b1ba6f508..611280f1ae4 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 3150306356d..d379dd0a143 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 44126e3e590..5c22cc749c6 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 b77abf4768c..86656a7f7eb 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 e7807b33162..34e91d8b0af 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 12047ad9129..5fc57fe139e 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 83af89570d5..bc59e312bb0 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 32047180f88..f3737888f3d 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 b61161c3eed..bbb031439fc 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 e5a184fb713..9eefd0d948d 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 cae044c066c..429f195ee95 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 0bb5636602f..93cbfe66140 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 a9c73798b18..b9d8e9e3187 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 b32e8866317..93aebbd3440 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 8f5004a0613..1e027bf6076 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 6c3e05c039e..7d7ae69f379 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 acfe66acf45..37b686a7e91 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 389d0b66850..910a88a706f 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 08eea294b4e..13c3c6463c0 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 a4a719b5fbe..0a5a20640a6 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 d88b09d4e1c..d787dc243ae 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 ec8dc06f098..5913100d037 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 7e231373d82..c647ce81790 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 1294ab0de8f..a519094d427 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 64d20126f3a..43033640836 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 8582667b27b..b6a58ed796b 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 b17de23ad39..8192abaf986 100644 --- a/sys/riscv/riscv/swtch.S +++ b/sys/riscv/riscv/swtch.S @@ -153,6 +153,59 @@ ENTRY(fpe_state_save) END(fpe_state_save) #endif /* FPE */ +/* + * void + * fpe_state_clear(void) + */ +ENTRY(fpe_state_clear) + /* + * Enable FPE usage in supervisor mode, + * so we can access registers. + */ + li t0, SSTATUS_FS_INITIAL + csrs sstatus, t0 + + fscsr zero + fcvt.d.l f0, zero + fcvt.d.l f1, zero + fcvt.d.l f2, zero + fcvt.d.l f3, zero + fcvt.d.l f4, zero + fcvt.d.l f5, zero + fcvt.d.l f6, zero + fcvt.d.l f7, zero + fcvt.d.l f8, zero + fcvt.d.l f9, zero + fcvt.d.l f10, zero + fcvt.d.l f11, zero + fcvt.d.l f12, zero + fcvt.d.l f13, zero + fcvt.d.l f14, zero + fcvt.d.l f15, zero + fcvt.d.l f16, zero + fcvt.d.l f17, zero + fcvt.d.l f18, zero + fcvt.d.l f19, zero + fcvt.d.l f20, zero + fcvt.d.l f21, zero + fcvt.d.l f22, zero + fcvt.d.l f23, zero + fcvt.d.l f24, zero + fcvt.d.l f25, zero + fcvt.d.l f26, zero + fcvt.d.l f27, zero + fcvt.d.l f28, zero + fcvt.d.l f29, zero + fcvt.d.l f30, zero + fcvt.d.l f31, zero + + /* Disable FPE usage in supervisor mode. */ + li t0, SSTATUS_FS_MASK + csrc sstatus, t0 + + ret +END(fpe_state_clear) + /* * void cpu_throw(struct thread *old, struct thread *new) */ diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c index ced05c52588..57f5c558d28 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 87ceeb670e7..c00ddc126f5 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 055194d3a88..f24bc1e503b 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 c456ab71400..985baf142ab 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 5e7a3934835..4aa811bc151 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 @@ -343,6 +343,13 @@ void audit_commit(struct kaudit_record *ar, int error, int retval); 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 89af1a7d281..a092e27b0a7 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 fa6fe66db25..f169ab8d9dd 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 30d8501c8e4..34d8f61ca9f 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 68595091a58..520f18c5a96 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 b40870d3294..89377df401a 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 0c7a3a331ab..be4c1cda03b 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 27e02af73cf..e892d658a1c 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 ec3322bdfdf..84de705f24a 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 c61ac3e1a6c..a60eb3b6dbb 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 3b5f750db5c..c6c7d083cef 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 6e880f04950..436186e90d2 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 f5353f15b0f..67acf2d0740 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 c41b151fa50..579d16756e9 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 89d0b7382e4..dcc72b2fdfd 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 25133b83486..31fc49b7b4c 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 cf5b1d792ae..f39f50cc9a6 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 9e6e24c32db..9e889686666 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 858a9e88462..76a57488361 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)); + PROC_LOCK(curproc); #ifdef RACCT - PROC_LOCK(curproc); - racct_add_force(curproc, RACCT_SWAP, incr); - PROC_UNLOCK(curproc); + 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 90834937976..837eb078791 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 16b078e7dab..b9348d6c632 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 10da5caa0ea..b1c5766c1c6 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 d5a6b57f47e..c56e51f3dbf 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 832dbce324e..beccb31f0b6 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 09e87ed231e..27ecb960201 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -98,12 +98,6 @@ extern void uma_startup1(void); extern void uma_startup2(void); extern void vm_radix_reserve_kva(void); -#if VM_NRESERVLEVEL > 0 -#define KVA_QUANTUM (1 << (VM_LEVEL_0_ORDER + PAGE_SHIFT)) -#else - /* On non-superpage architectures want large import sizes. */ -#define KVA_QUANTUM (PAGE_SIZE * 1024) -#endif long physmem; /* @@ -112,58 +106,15 @@ long physmem; static void vm_mem_init(void *); SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL); -/* - * Import kva into the kernel arena. - */ -static int -kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) -{ - vm_offset_t addr; - int result; - - KASSERT((size % KVA_QUANTUM) == 0, - ("kva_import: Size %jd is not a multiple of %d", - (intmax_t)size, (int)KVA_QUANTUM)); - addr = vm_map_min(kernel_map); - result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, - VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); - if (result != KERN_SUCCESS) - return (ENOMEM); - - *addrp = addr; - - return (0); -} - -#if VM_NRESERVLEVEL > 0 -/* - * Import a superpage from the normal kernel arena into the special - * arena for allocations with different permissions. - */ -static int -kernel_rwx_alloc(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp) -{ - - KASSERT((size % KVA_QUANTUM) == 0, - ("kernel_rwx_alloc: Size %jd is not a multiple of %d", - (intmax_t)size, (int)KVA_QUANTUM)); - return (vmem_xalloc(arena, size, KVA_QUANTUM, 0, 0, VMEM_ADDR_MIN, - VMEM_ADDR_MAX, flags, addrp)); -} -#endif - /* * vm_init initializes the virtual memory system. * This is done only by the first cpu up. * * The start and end address of physical memory is passed in. */ -/* ARGSUSED*/ static void -vm_mem_init(dummy) - void *dummy; +vm_mem_init(void *dummy) { - int domain; /* * Initializes resident memory structures. From here on, all physical @@ -184,39 +135,6 @@ vm_mem_init(dummy) vm_map_startup(); kmem_init(virtual_avail, virtual_end); - /* - * Initialize the kernel_arena. This can grow on demand. - */ - vmem_init(kernel_arena, "kernel arena", 0, 0, PAGE_SIZE, 0, 0); - vmem_set_import(kernel_arena, kva_import, NULL, NULL, KVA_QUANTUM); - -#if VM_NRESERVLEVEL > 0 - /* - * In an architecture with superpages, maintain a separate arena - * for allocations with permissions that differ from the "standard" - * read/write permissions used for memory in the kernel_arena. - */ - kernel_rwx_arena = vmem_create("kernel rwx arena", 0, 0, PAGE_SIZE, - 0, M_WAITOK); - vmem_set_import(kernel_rwx_arena, kernel_rwx_alloc, - (vmem_release_t *)vmem_xfree, kernel_arena, KVA_QUANTUM); -#endif - - for (domain = 0; domain < vm_ndomains; domain++) { - vm_dom[domain].vmd_kernel_arena = vmem_create( - "kernel arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); - vmem_set_import(vm_dom[domain].vmd_kernel_arena, - (vmem_import_t *)vmem_alloc, NULL, kernel_arena, - KVA_QUANTUM); -#if VM_NRESERVLEVEL > 0 - vm_dom[domain].vmd_kernel_rwx_arena = vmem_create( - "kernel rwx arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); - vmem_set_import(vm_dom[domain].vmd_kernel_rwx_arena, - kernel_rwx_alloc, (vmem_release_t *)vmem_xfree, - vm_dom[domain].vmd_kernel_arena, KVA_QUANTUM); -#endif - } - #ifndef UMA_MD_SMALL_ALLOC /* Set up radix zone to use noobj_alloc. */ vm_radix_reserve_kva(); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 5dee4d758dd..88fbc74848d 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); } /* @@ -644,6 +672,44 @@ kmem_init_zero_region(void) zero_region = (const void *)addr; } +/* + * Import KVA from the kernel map into the kernel arena. + */ +static int +kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) +{ + vm_offset_t addr; + int result; + + KASSERT((size % KVA_QUANTUM) == 0, + ("kva_import: Size %jd is not a multiple of %d", + (intmax_t)size, (int)KVA_QUANTUM)); + addr = vm_map_min(kernel_map); + result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, + VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); + if (result != KERN_SUCCESS) + return (ENOMEM); + + *addrp = addr; + + return (0); +} + +/* + * Import KVA from a parent arena into a per-domain arena. Imports must be + * KVA_QUANTUM-aligned and a multiple of KVA_QUANTUM in size. + */ +static int +kva_import_domain(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp) +{ + + KASSERT((size % KVA_QUANTUM) == 0, + ("kva_import_domain: Size %jd is not a multiple of %d", + (intmax_t)size, (int)KVA_QUANTUM)); + return (vmem_xalloc(arena, size, KVA_QUANTUM, 0, 0, VMEM_ADDR_MIN, + VMEM_ADDR_MAX, flags, addrp)); +} + /* * kmem_init: * @@ -651,11 +717,13 @@ kmem_init_zero_region(void) * data, bss, and all space allocated thus far (`boostrap' data). The * new map will thus map the range between VM_MIN_KERNEL_ADDRESS and * `start' as allocated, and the range between `start' and `end' as free. + * Create the kernel vmem arena and its per-domain children. */ void kmem_init(vm_offset_t start, vm_offset_t end) { vm_map_t m; + int domain; m = vm_map_create(kernel_pmap, VM_MIN_KERNEL_ADDRESS, end); m->system_map = 1; @@ -671,6 +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 8d49a598f26..20e847f5e5a 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 e184b8ff5c1..e8772a1eadd 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 d022435704f..47628cba2ac 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 c084de7aca4..5c309a04a40 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 ac04f2b3ea6..758e51d8ef6 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 890f5dad921..5206ba6e658 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 0ea747ccc30..42b506c4447 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 13f4b886430..38c82570770 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 d9c860d20ca..5c886810893 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 5b145c5aeae..944aa214baa 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 8560793df50..e7e0cc79b54 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 e1229a8401e..5b039491345 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 0de449a50fa..ee8d3552ecb 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 00000000000..06d6f81c8fe --- /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 a8d35ea3112..1b4fa796e72 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 1149866f5a0..948411fb05c 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 a139ff28202..7d56c57457c 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 ea2338b3dde..7b205b8019d 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 d6b9aa059dd..877ae6af0e2 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 5a2030cb88a..286e42c0095 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 a8ed43f7c57..f177ad15d3b 100644 --- a/usr.bin/tip/tip/Makefile +++ b/usr.bin/tip/tip/Makefile @@ -31,6 +31,7 @@ # explicitly to remcap.c if not 1024 # CONNECT enable ~C command (connect pgm to remote) +CONFS= phones remote PROG= tip LINKS= ${BINDIR}/tip ${BINDIR}/cu MAN= tip.1 cu.1 @@ -47,6 +48,9 @@ SRCS= acu.c acutab.c cmds.c cmdtab.c cu.c hunt.c log.c partab.c \ # -- log.o depends on the Makefile because of ACULOG acutab.o log.o remote.o: Makefile +# Don't rebuild based on remote.c +remote: .MADE + .include <bsd.prog.mk> # Dirty, rotten hack. This can be removed when we are confident that there diff --git a/etc/phones b/usr.bin/tip/tip/phones similarity index 100% rename from etc/phones rename to usr.bin/tip/tip/phones diff --git a/etc/remote b/usr.bin/tip/tip/remote similarity index 100% rename from etc/remote rename to usr.bin/tip/tip/remote diff --git a/usr.bin/top/top.1 b/usr.bin/top/top.1 index cde24adc114..ea56914819f 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,22 +359,67 @@ 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. +.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 +.Ed +.Ss Physical Memory Stats +.Bl -tag -width "Uncompressed" -compact +.It Em Active +number of bytes active +.It Em Inact +number of clean bytes inactive +.It Em Laundry +number of dirty bytes queued for laundering +.It Em Wired +number of bytes wired down, including IO-level cached file data pages +.It Em Buf +number of bytes used for IO-level disk caching +.It Em Free +number of bytes free +.El +.Ss ZFS ARC Stats +These stats are only displayed when the ARC is in use. .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. +.Bl -tag -width "Uncompressed" -compact +.It Em Total +number of wired bytes used for the ZFS ARC +.It Em MRU +number of ARC bytes holding most recently used data +.It Em MFU +number of ARC bytes holding most frequently used data +.It Em Anon +number of ARC bytes holding in flight data +.It Em Header +number of ARC bytes holding headers +.It Em Other +miscellaneous ARC bytes +.It Em Compressed +bytes of memory used by ARC caches +.It Em Uncompressed +bytes of data stored in ARC caches before compression +.It Em Ratio +compression ratio of data cached in the ARC +.El +.Ss Swap Stats +.Bl -tag -width "Uncompressed" -compact +.It Em Total +total available swap usage +.It Em Free +total free swap usage +.It Em Inuse +swap usage +.It Em \&In +bytes paged in from swap devices (last interval) +.It Em Out +bytes paged out to swap devices (last interval) +.El .Sh ENVIRONMENT -.Bl -tag -width TOP -compact -.It Pa TOP +.Bl -tag -width "Uncompressed" +.It Ev TOP Default set of arguments to .Nm . .El @@ -386,54 +431,15 @@ Default set of arguments to .Xr humanize_number 3 , .Xr mem 4 , .Xr renice 8 -.Sh DESCRIPTION OF MEMORY -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: -number of bytes active -.It Inact: -number of clean bytes inactive -.It Laundry: -number of dirty bytes queued for laundering -.It Wired: -number of bytes wired down, including IO-level cached file data pages -.It Buf: -number of bytes used for IO-level disk caching -.It Free: -number of bytes free -.It ZFS ARC Stats -These stats are only displayed when the ARC is in use. -.It Total: -number of wired bytes used for the ZFS ARC -.It MRU: -number of ARC bytes holding most recently used data -.It MFU: -number of ARC bytes holding most frequently used data -.It Anon: -number of ARC bytes holding in flight data -.It Header: -number of ARC bytes holding headers -.It Other: -miscellaneous ARC bytes -.It Compressed: -bytes of memory used by ARC caches -.It Uncompressed: -bytes of data stored in ARC caches before compression -.It Ratio: -compression ratio of data cached in the ARC -.It Swap Stats -.It Total: -total available swap usage -.It Free: -total free swap usage -.It Inuse: -swap usage -.It In: -bytes paged in from swap devices (last interval) -.It Out: -bytes paged out to swap devices (last interval) -.El +.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 20a101eaef5..25e3265b699 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 c1d5f4a295f..9e95e6f72a0 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -10,6 +10,7 @@ .PATH: ${SRCTOP}/contrib/amd/amd +CONFS= amd.map PROG= amd MAN= amd.8 SRCS= am_ops.c amd.c amfs_auto.c amfs_direct.c amfs_error.c amfs_generic.c diff --git a/etc/amd.map b/usr.sbin/amd/amd/amd.map similarity index 100% rename from etc/amd.map rename to usr.sbin/amd/amd/amd.map diff --git a/usr.sbin/bsdinstall/bsdinstall.8 b/usr.sbin/bsdinstall/bsdinstall.8 index 714a1f23fe7..d6f446576b9 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 50143035903..d2abb5671fc 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 1b82f812175..9fea1b6aed5 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 e568fe8acc1..8f09b62d10c 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 080fc8559b3..e6b3d2847c7 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 be76948d4f0..a67e863ad1d 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 f0d699369db..4e456a05c25 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 af2582c4bb1..6a152c46268 100644 --- a/usr.sbin/lpr/lpd/Makefile +++ b/usr.sbin/lpr/lpd/Makefile @@ -1,6 +1,7 @@ # From: @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +CONFS= hosts.lpd printcap PROG= lpd MAN= lpd.8 SRCS= lpd.c printjob.c recvjob.c lpdchar.c modes.c diff --git a/etc/hosts.lpd b/usr.sbin/lpr/lpd/hosts.lpd similarity index 100% rename from etc/hosts.lpd rename to usr.sbin/lpr/lpd/hosts.lpd diff --git a/etc/printcap b/usr.sbin/lpr/lpd/printcap similarity index 100% rename from etc/printcap rename to usr.sbin/lpr/lpd/printcap diff --git a/usr.sbin/nscd/nscd.8 b/usr.sbin/nscd/nscd.8 index f54c18582ee..7858a30af04 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 2f94d3e274e..090134711b9 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 b80db1f348b..147aab2d2ba 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)