From 77e4a39103314a5c1f3ca673097e0b7f78ebf361 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 17 Sep 2018 19:20:50 +0000 Subject: [PATCH 001/139] Move rpc and netconfig to lib/libc/rpc/ This uses relative paths to make it more specific to avoid any potential future problems with .PATH and leverages CONFS. libc was picked as the destination location for these because of the syscalls that use these files as the lowest level place they are referenced. Approved by: re (gjb), will (mentor) Differential Revision: https://reviews.freebsd.org/D17163 --- etc/Makefile | 2 -- lib/libc/rpc/Makefile.inc | 1 + {etc => lib/libc/rpc}/netconfig | 0 {etc => lib/libc/rpc}/rpc | 0 4 files changed, 1 insertion(+), 2 deletions(-) rename {etc => lib/libc/rpc}/netconfig (100%) rename {etc => lib/libc/rpc}/rpc (100%) diff --git a/etc/Makefile b/etc/Makefile index 91eaa0ca50fc..164e769fea11 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -21,12 +21,10 @@ BIN1= \ libmap.conf \ login.access \ mac.conf \ - netconfig \ phones \ rc.bsdextended \ rc.firewall \ remote \ - rpc \ termcap.small # NB: keep these sorted by MK_* knobs diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index c3e5502d68df..9f3bb453c0b6 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 From a4088415936d863c9f4f61d90b9306ad958ca14d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 17 Sep 2018 19:38:43 +0000 Subject: [PATCH 002/139] Do not upgrade the vnode lock to call getinoquota(). Doing so can deadlock when the thread already owns another vnode lock, e.g. during a rename, as was demonstrated by the reporter. In fact, there seems to be no need to force the call to getinoquota() always, because vn_open() locks vnode exclusively, and this is the most important case. To add to the point, directories where the dirent is added or removed, are locked exclusively as well. Reported by: bwidawsk Tested by: bwidawsk, pho (as part of the larger patch) Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week --- sys/ufs/ufs/ufs_vnops.c | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 9e6e24c32db9..9e8896866660 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -325,9 +325,6 @@ ufs_accessx(ap) struct inode *ip = VTOI(vp); accmode_t accmode = ap->a_accmode; int error; -#ifdef QUOTA - int relocked; -#endif #ifdef UFS_ACL struct acl *acl; acl_type_t type; @@ -350,32 +347,14 @@ ufs_accessx(ap) * Inode is accounted in the quotas only if struct * dquot is attached to it. VOP_ACCESS() is called * from vn_open_cred() and provides a convenient - * point to call getinoquota(). + * point to call getinoquota(). The lock mode is + * exclusive when the file is opening for write. */ - if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) { - - /* - * Upgrade vnode lock, since getinoquota() - * requires exclusive lock to modify inode. - */ - relocked = 1; - vhold(vp); - vn_lock(vp, LK_UPGRADE | LK_RETRY); - VI_LOCK(vp); - if (vp->v_iflag & VI_DOOMED) { - vdropl(vp); - error = ENOENT; - goto relock; - } - vdropl(vp); - } else - relocked = 0; - error = getinoquota(ip); -relock: - if (relocked) - vn_lock(vp, LK_DOWNGRADE | LK_RETRY); - if (error != 0) - return (error); + if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) { + error = getinoquota(ip); + if (error != 0) + return (error); + } #endif break; default: From 9d50798c61e21d9b8d52810c7da805dad348a876 Mon Sep 17 00:00:00 2001 From: David C Somayajulu Date: Mon, 17 Sep 2018 20:15:18 +0000 Subject: [PATCH 003/139] Fixed isses: State check before enqueuing transmit task in bxe_link_attn() routine. State check before invoking bxe_nic_unload in bxe_shutdown(). Submitted by:Vaishali.Kulkarni@cavium.com Approved by:re(gjb) --- sys/dev/bxe/bxe.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index 393b78f540ff..4ef92e39d1f9 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -7076,13 +7076,13 @@ bxe_link_attn(struct bxe_softc *sc) if (sc->state == BXE_STATE_OPEN) { bxe_stats_handle(sc, STATS_EVENT_LINK_UP); + /* Restart tx when the link comes back. */ + FOR_EACH_ETH_QUEUE(sc, i) { + fp = &sc->fp[i]; + taskqueue_enqueue(fp->tq, &fp->tx_task); + } } - /* Restart tx when the link comes back. */ - FOR_EACH_ETH_QUEUE(sc, i) { - fp = &sc->fp[i]; - taskqueue_enqueue(fp->tq, &fp->tx_task); - } } if (sc->link_vars.link_up && sc->link_vars.line_speed) { @@ -16279,9 +16279,11 @@ bxe_shutdown(device_t dev) /* stop the periodic callout */ bxe_periodic_stop(sc); - BXE_CORE_LOCK(sc); - bxe_nic_unload(sc, UNLOAD_NORMAL, FALSE); - BXE_CORE_UNLOCK(sc); + if (sc->state != BXE_STATE_CLOSED) { + BXE_CORE_LOCK(sc); + bxe_nic_unload(sc, UNLOAD_NORMAL, FALSE); + BXE_CORE_UNLOCK(sc); + } return (0); } From c655284641d15c3fd40b194391d582b492efff46 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 17 Sep 2018 22:14:53 +0000 Subject: [PATCH 004/139] DIRS: installdirs should also be .PHONY Sponsored by: Dell EMC Approved by: re (gjb, kib) --- share/mk/bsd.sys.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/mk/bsd.sys.mk b/share/mk/bsd.sys.mk index 5454095df8a6..5b585ed12603 100644 --- a/share/mk/bsd.sys.mk +++ b/share/mk/bsd.sys.mk @@ -250,8 +250,8 @@ PHONY_NOTMAIN = analyze afterdepend afterinstall all beforedepend beforeinstall beforelinking build build-tools buildconfig buildfiles \ buildincludes check checkdpadd clean cleandepend cleandir \ cleanobj configure depend distclean distribute exe \ - files html includes install installconfig installfiles \ - installincludes lint obj objlink objs objwarn \ + files html includes install installconfig installdirs \ + installfiles installincludes lint obj objlink objs objwarn \ realinstall tags whereobj # we don't want ${PROG} to be PHONY From c86ac3193f93735a4c60fd7bd5f27e76397dc93a Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 17 Sep 2018 22:15:06 +0000 Subject: [PATCH 005/139] PROGS: Don't redundantly process DIRS. Sponsored by: Dell EMC Approved by: re (gjb) --- share/mk/bsd.progs.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/mk/bsd.progs.mk b/share/mk/bsd.progs.mk index 7415092011eb..b4ba16dc5993 100644 --- a/share/mk/bsd.progs.mk +++ b/share/mk/bsd.progs.mk @@ -77,7 +77,7 @@ stage_as.prog.${_prog}: ${_prog} .ifdef _RECURSING_PROGS MK_STAGING= no -_PROGS_GLOBAL_VARS= CLEANFILES CLEANDIRS CONFGROUPS FILESGROUPS INCSGROUPS \ +_PROGS_GLOBAL_VARS= CLEANFILES CLEANDIRS CONFGROUPS DIRS FILESGROUPS INCSGROUPS \ SCRIPTS .for v in ${_PROGS_GLOBAL_VARS} $v = From ebd2a66265be8a19ada02031d9d543d7752cdec9 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 17 Sep 2018 22:15:09 +0000 Subject: [PATCH 006/139] installdirs can be a recursive/standalone target. Sponsored by: Dell EMC Approved by: re (gjb) --- share/mk/bsd.subdir.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk index 486043a63bb7..145c17dff754 100644 --- a/share/mk/bsd.subdir.mk +++ b/share/mk/bsd.subdir.mk @@ -46,6 +46,7 @@ SUBDIR_TARGETS+= \ all all-man analyze buildconfig buildfiles buildincludes \ checkdpadd clean cleandepend cleandir cleanilinks \ cleanobj depend distribute files includes installconfig \ + installdirs \ installfiles installincludes print-dir realinstall \ maninstall manlint ${_obj} objlink tags \ @@ -53,7 +54,7 @@ SUBDIR_TARGETS+= \ STANDALONE_SUBDIR_TARGETS+= \ all-man buildconfig buildfiles buildincludes check checkdpadd \ clean cleandepend cleandir cleanilinks cleanobj files includes \ - installconfig installincludes installfiles print-dir \ + installconfig installdirs installincludes installfiles print-dir \ maninstall manlint obj objlink # It is safe to install in parallel when staging. From 4be52feeca4b4fecfe716508b14202fcdbc5fb89 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Mon, 17 Sep 2018 22:15:12 +0000 Subject: [PATCH 007/139] DIRS: Rework how duplicated dirs are installed. - Warn if multiple DIRS have conflicting metadata - This fixes META_MODE writing to a very long .meta file that contained the full DESTDIR path. Reported by: sjg, jonathan Sponsored by: Dell EMC Approved by: re (gjb) --- share/mk/bsd.dirs.mk | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/share/mk/bsd.dirs.mk b/share/mk/bsd.dirs.mk index 72e6c2cb46f1..cdd8b09b1bc3 100644 --- a/share/mk/bsd.dirs.mk +++ b/share/mk/bsd.dirs.mk @@ -27,18 +27,29 @@ ${dir}TAG_ARGS= -T ${${dir}TAGS:[*]:S/ /,/g} . endif installdirs: installdirs-${dir} - -installdirs-${dir}: installdirs-${DESTDIR}${${dir}} - -. if !target(installdirs-${DESTDIR}${${dir}}) -installdirs-${DESTDIR}${${dir}}: - @${ECHO} installing DIRS ${dir} +# Coalesce duplicate destdirs +. if !defined(_uniquedirs_${${dir}}) +_uniquedirs_${${dir}}= ${dir} +_alldirs_${dir}= ${dir} +installdirs-${dir}: .PHONY + @${ECHO} installing DIRS ${_alldirs_${dir}} ${INSTALL} ${${dir}TAG_ARGS} -d -m ${${dir}_MODE} -o ${${dir}_OWN} \ -g ${${dir}_GRP} ${${dir}_FLAG} ${DESTDIR}${${dir}} -. endif -. endif - -realinstall: installdirs-${dir} +. else +_uniquedir:= ${_uniquedirs_${${dir}}} +_alldirs_${_uniquedir}+=${dir} +# Connect to the single target +installdirs-${dir}: installdirs-${_uniquedir} +# Validate that duplicate dirs have the same metadata. +. for v in TAG_ARGS _MODE _OWN _GRP _FLAG +. if ${${dir}${v}:Uunset} != ${${_uniquedir}${v}:Uunset} +. warning ${RELDIR}: ${dir}${v} (${${dir}${v}:U}) does not match ${_uniquedir}${v} (${${_uniquedir}${v}:U}) but both install to ${${dir}} +. endif +. endfor +. endif # !defined(_uniquedirs_${${dir}}) +. endif # defined(${dir}) && !empty(${dir}) . endfor +realinstall: installdirs + .endif From 9f1e4c08ce8615bcd0a1a484bf1900709b407d82 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 00:10:29 +0000 Subject: [PATCH 008/139] Remove dhclient.conf from here in prep for the move of it from etc/. This is being done a separate step to ease importing into other VCSes. Approved by: re (gjb), will (mentor) Differential Revision: https://reviews.freebsd.org/D17160 --- sbin/dhclient/dhclient.conf | 39 ------------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 sbin/dhclient/dhclient.conf diff --git a/sbin/dhclient/dhclient.conf b/sbin/dhclient/dhclient.conf deleted file mode 100644 index 7eaeeb8eb40a..000000000000 --- a/sbin/dhclient/dhclient.conf +++ /dev/null @@ -1,39 +0,0 @@ -# $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; -} From 62e23a47811d5ae29d0a01865952a8e23fcc977d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 00:11:45 +0000 Subject: [PATCH 009/139] Move dhclient.conf to sbin/dhclient/. This also leverages CONFS for handling config files. Approved by: re (gjb), will (mentor) Differential Revision: https://reviews.freebsd.org/D17160 --- etc/Makefile | 1 - sbin/dhclient/Makefile | 1 + {etc => sbin/dhclient}/dhclient.conf | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {etc => sbin/dhclient}/dhclient.conf (100%) diff --git a/etc/Makefile b/etc/Makefile index 164e769fea11..afb1e9890bc5 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -13,7 +13,6 @@ SUBDIR+=sendmail .endif BIN1= \ - dhclient.conf \ disktab \ group \ hosts.allow \ diff --git a/sbin/dhclient/Makefile b/sbin/dhclient/Makefile index 99b749eb720f..cdf93b8b8145 100644 --- a/sbin/dhclient/Makefile +++ b/sbin/dhclient/Makefile @@ -33,6 +33,7 @@ .include +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/etc/dhclient.conf b/sbin/dhclient/dhclient.conf similarity index 100% rename from etc/dhclient.conf rename to sbin/dhclient/dhclient.conf From 9a537769d6d0f1fc9b9e2897b215526138491435 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 00:25:00 +0000 Subject: [PATCH 010/139] Move libmap.conf to libexec/rtld-elf/ This leverages CONFS to handle the config file install. Approved by: re (gjb), will (mentor) Differential Revision: https://reviews.freebsd.org/D17161 --- etc/Makefile | 1 - libexec/rtld-elf/Makefile | 1 + {etc => libexec/rtld-elf}/libmap.conf | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {etc => libexec/rtld-elf}/libmap.conf (100%) diff --git a/etc/Makefile b/etc/Makefile index afb1e9890bc5..8f4eca19e6a1 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -17,7 +17,6 @@ BIN1= \ group \ hosts.allow \ libalias.conf \ - libmap.conf \ login.access \ mac.conf \ phones \ diff --git a/libexec/rtld-elf/Makefile b/libexec/rtld-elf/Makefile index 5d5e99fb2484..5135469f5eab 100644 --- a/libexec/rtld-elf/Makefile +++ b/libexec/rtld-elf/Makefile @@ -8,6 +8,7 @@ PACKAGE= clibs MK_SSP= no +CONFS= libmap.conf PROG?= ld-elf.so.1 .if (${PROG:M*ld-elf32*} != "") TAGS+= lib32 diff --git a/etc/libmap.conf b/libexec/rtld-elf/libmap.conf similarity index 100% rename from etc/libmap.conf rename to libexec/rtld-elf/libmap.conf From af734c774648e8374f97ad47be48dfc8cd37659f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 00:32:10 +0000 Subject: [PATCH 011/139] Move amd.map to usr.sbin/amd/amd/ This leverages CONFS to handle the install of the config file. Approved by: re (gjb), will (mentor) Differential Revision: https://reviews.freebsd.org/D17159 --- etc/Makefile | 4 ---- usr.sbin/amd/amd/Makefile | 1 + {etc => usr.sbin/amd/amd}/amd.map | 0 3 files changed, 1 insertion(+), 4 deletions(-) rename {etc => usr.sbin/amd/amd}/amd.map (100%) diff --git a/etc/Makefile b/etc/Makefile index 8f4eca19e6a1..26259c096990 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -27,10 +27,6 @@ BIN1= \ # 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 diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile index c1d5f4a295ff..9e95e6f72a0b 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -10,6 +10,7 @@ .PATH: ${SRCTOP}/contrib/amd/amd +CONFS= amd.map PROG= amd MAN= amd.8 SRCS= am_ops.c amd.c amfs_auto.c amfs_direct.c amfs_error.c amfs_generic.c diff --git a/etc/amd.map b/usr.sbin/amd/amd/amd.map similarity index 100% rename from etc/amd.map rename to usr.sbin/amd/amd/amd.map From 2554f86a8d426f6280857d184019506827e328d1 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Tue, 18 Sep 2018 01:24:30 +0000 Subject: [PATCH 012/139] vm: stop taking proc lock in mmap to satisfy racct if it is disabled Limits can be safely obtained with lim_cur from the thread. racct is compiled in but disabled by default. Note that racct enablement is a boot-only tunable. This eliminates second most common place of taking the lock while pkg building. While here don't take the lock in mlockall either. Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17210 --- sys/sys/racct.h | 12 ++++++++++++ sys/vm/vm_mmap.c | 22 +++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/sys/sys/racct.h b/sys/sys/racct.h index ec3322bdfdf9..84de705f24af 100644 --- a/sys/sys/racct.h +++ b/sys/sys/racct.h @@ -164,6 +164,15 @@ extern struct mtx racct_lock; #define RACCT_UNLOCK() mtx_unlock(&racct_lock) #define RACCT_LOCK_ASSERT() mtx_assert(&racct_lock, MA_OWNED) +#define RACCT_PROC_LOCK(p) do { \ + if (__predict_false(racct_enable)) \ + PROC_LOCK(p); \ +} while (0) +#define RACCT_PROC_UNLOCK(p) do { \ + if (__predict_false(racct_enable)) \ + PROC_UNLOCK(p); \ +} while (0) + int racct_add(struct proc *p, int resource, uint64_t amount); void racct_add_cred(struct ucred *cred, int resource, uint64_t amount); void racct_add_force(struct proc *p, int resource, uint64_t amount); @@ -189,6 +198,9 @@ void racct_proc_throttle(struct proc *p, int timeout); #else +#define RACCT_PROC_LOCK(p) do { } while (0) +#define RACCT_PROC_UNLOCK(p) do { } while (0) + static inline int racct_add(struct proc *p, int resource, uint64_t amount) { diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c index e184b8ff5c1f..e8772a1eadde 100644 --- a/sys/vm/vm_mmap.c +++ b/sys/vm/vm_mmap.c @@ -1055,12 +1055,8 @@ sys_mlockall(struct thread *td, struct mlockall_args *uap) * a hard resource limit, return ENOMEM. */ if (!old_mlock && uap->how & MCL_CURRENT) { - PROC_LOCK(td->td_proc); - if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) { - PROC_UNLOCK(td->td_proc); + if (map->size > lim_cur(td, RLIMIT_MEMLOCK)) return (ENOMEM); - } - PROC_UNLOCK(td->td_proc); } #ifdef RACCT if (racct_enable) { @@ -1445,21 +1441,21 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, curmap = map == &td->td_proc->p_vmspace->vm_map; if (curmap) { - PROC_LOCK(td->td_proc); - if (map->size + size > lim_cur_proc(td->td_proc, RLIMIT_VMEM)) { - PROC_UNLOCK(td->td_proc); + RACCT_PROC_LOCK(td->td_proc); + if (map->size + size > lim_cur(td, RLIMIT_VMEM)) { + RACCT_PROC_UNLOCK(td->td_proc); return (ENOMEM); } if (racct_set(td->td_proc, RACCT_VMEM, map->size + size)) { - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); return (ENOMEM); } if (!old_mlock && map->flags & MAP_WIREFUTURE) { if (ptoa(pmap_wired_count(map->pmap)) + size > - lim_cur_proc(td->td_proc, RLIMIT_MEMLOCK)) { + lim_cur(td, RLIMIT_MEMLOCK)) { racct_set_force(td->td_proc, RACCT_VMEM, map->size); - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); return (ENOMEM); } error = racct_set(td->td_proc, RACCT_MEMLOCK, @@ -1467,11 +1463,11 @@ vm_mmap_object(vm_map_t map, vm_offset_t *addr, vm_size_t size, vm_prot_t prot, if (error != 0) { racct_set_force(td->td_proc, RACCT_VMEM, map->size); - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); return (error); } } - PROC_UNLOCK(td->td_proc); + RACCT_PROC_UNLOCK(td->td_proc); } /* From 34da9e380257b2bcbb6de48bfbfaed5238aa69c0 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 01:38:44 +0000 Subject: [PATCH 013/139] Fix CONFS to append the value in this case. Approved by: re (blanket, pkgbase), will (mentor) --- lib/libc/rpc/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index 9f3bb453c0b6..5ca9bd3757c0 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -2,7 +2,7 @@ # $FreeBSD$ .PATH: ${LIBC_SRCTOP}/rpc ${LIBC_SRCTOP}/. -CONFS= rpc/netconfig rpc/rpc +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 \ From b6af74d28973161095946a2424026e8a5cfdd29a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 01:40:37 +0000 Subject: [PATCH 014/139] Move mac.conf to lib/libc/posix1e/ This leverages CONFS to handle the install of the config file. Approved by: re (blanket, pkgbase), will (mentor) Differential Revision: https://reviews.freebsd.org/D17162 --- etc/Makefile | 1 - lib/libc/posix1e/Makefile.inc | 1 + {etc => lib/libc/posix1e}/mac.conf | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {etc => lib/libc/posix1e}/mac.conf (100%) diff --git a/etc/Makefile b/etc/Makefile index 26259c096990..d905d6590706 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -18,7 +18,6 @@ BIN1= \ hosts.allow \ libalias.conf \ login.access \ - mac.conf \ phones \ rc.bsdextended \ rc.firewall \ diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index 151f85068204..fb5cf6e39cc6 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -8,6 +8,7 @@ CFLAGS+=-D_ACL_PRIVATE subr_acl_nfs4.c: ${SRCTOP}/sys/kern/subr_acl_nfs4.c cat ${.ALLSRC} > ${.TARGET} +CONFS+= posix1e/mac.conf SRCS+= acl_branding.c \ acl_calc_mask.c \ acl_copy.c \ diff --git a/etc/mac.conf b/lib/libc/posix1e/mac.conf similarity index 100% rename from etc/mac.conf rename to lib/libc/posix1e/mac.conf From ba4704a278264b679425b1c70b38622d76db0041 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Tue, 18 Sep 2018 10:53:07 +0000 Subject: [PATCH 015/139] Remove unused code. Approved by: re (kib@) MFC after: 1 week --- sys/netinet/sctp_auth.c | 34 ---------------------------------- sys/netinet/sctp_auth.h | 3 --- 2 files changed, 37 deletions(-) diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 3150306356dc..5a5b7880fd30 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -1060,40 +1060,6 @@ sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, return (digestlen); } -/*- - * verify the HMAC digest using the desired hash key, text, and HMAC - * algorithm. - * Returns -1 on error, 0 on success. - */ -int -sctp_verify_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, - uint8_t *text, uint32_t textlen, - uint8_t *digest, uint32_t digestlen) -{ - uint32_t len; - uint8_t temp[SCTP_AUTH_DIGEST_LEN_MAX]; - - /* sanity check the material and length */ - if ((key == NULL) || (keylen == 0) || - (text == NULL) || (textlen == 0) || (digest == NULL)) { - /* can't do HMAC with empty key or text or digest */ - return (-1); - } - len = sctp_get_hmac_digest_len(hmac_algo); - if ((len == 0) || (digestlen != len)) - return (-1); - - /* compute the expected hash */ - if (sctp_hmac(hmac_algo, key, keylen, text, textlen, temp) != len) - return (-1); - - if (memcmp(digest, temp, digestlen) != 0) - return (-1); - else - return (0); -} - - /* * computes the requested HMAC using a key struct (which may be modified if * the keylen exceeds the HMAC block len). diff --git a/sys/netinet/sctp_auth.h b/sys/netinet/sctp_auth.h index 44126e3e590f..5c22cc749c65 100644 --- a/sys/netinet/sctp_auth.h +++ b/sys/netinet/sctp_auth.h @@ -178,9 +178,6 @@ extern uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo); extern uint32_t sctp_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, uint8_t *text, uint32_t textlen, uint8_t *digest); -extern int -sctp_verify_hmac(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, - uint8_t *text, uint32_t textlen, uint8_t *digest, uint32_t digestlen); extern uint32_t sctp_compute_hmac(uint16_t hmac_algo, sctp_key_t *key, uint8_t *text, uint32_t textlen, uint8_t *digest); From 9ed6559e3e70bef18b7e18b87b9c33200b6b2849 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Tue, 18 Sep 2018 15:01:21 +0000 Subject: [PATCH 016/139] Require ifunc-capable linker for i386 The amd64 kernel started using ifunc for a variety of functions with arch-specific implementations, and we would like to make use of the same functionality on i386 and as much as possible avoid divergence between i386 and amd64. In particular, future changes for security improvements and mitigations may rely on ifunc support. Approved by: re (kib) Sponsored by: The FreeBSD Foundation --- sys/conf/kern.pre.mk | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk index a663deb59d1f..523cea605afd 100644 --- a/sys/conf/kern.pre.mk +++ b/sys/conf/kern.pre.mk @@ -121,10 +121,11 @@ CFLAGS+= ${CONF_CFLAGS} LDFLAGS+= -Wl,--build-id=sha1 .endif -.if ${MACHINE_CPUARCH} == "amd64" -.if defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" -.error amd64 kernel requires linker ifunc support +.if (${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386") && \ + defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" +.error amd64/i386 kernel requires linker ifunc support .endif +.if ${MACHINE_CPUARCH} == "amd64" LDFLAGS+= -Wl,-z max-page-size=2097152 -Wl,-z common-page-size=4096 -Wl,-z -Wl,ifunc-noplt .endif From d02489d11aed2aa5410889f18f4fe8a356f4ca3b Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 18 Sep 2018 15:31:24 +0000 Subject: [PATCH 017/139] Fix C11 and POSIX 1003.1b-1993 compliance in time.h Only expose timespec_get in C11, C++17, or BSD code. Always define struct timespect if defining timespec_get. PR: 231425 Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17174 --- include/time.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/time.h b/include/time.h index 26e208ffa65b..cec901a1e8ba 100644 --- a/include/time.h +++ b/include/time.h @@ -207,9 +207,13 @@ time_t posix2time(time_t t); #include #endif +#if defined(__BSD_VISIBLE) || __ISO_C_VISIBLE >= 2011 || \ + (defined(cplusplus) && cplusplus >= 201703) +#include /* 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 From 5b87c94a46afc739a4bd56625b5a6be10e6cd657 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 18 Sep 2018 16:06:24 +0000 Subject: [PATCH 018/139] Only enable HyperV support by default on x86. Without this we get spurious output during boot as we try to run nonexistant HyperV scripts on non-x86 models. Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17211 --- share/mk/src.opts.mk | 8 +++++++- tools/build/options/WITH_HYPERV | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tools/build/options/WITH_HYPERV diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 7667b97bdf2f..f09dd9748ac9 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 \ @@ -373,6 +372,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/tools/build/options/WITH_HYPERV b/tools/build/options/WITH_HYPERV new file mode 100644 index 000000000000..06d6f81c8fe1 --- /dev/null +++ b/tools/build/options/WITH_HYPERV @@ -0,0 +1,2 @@ +.\" $FreeBSD$ +Set to build or install HyperV utilities. From 0543ade37c59d0342dbf9a9a1fd964e72519234a Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Tue, 18 Sep 2018 16:16:58 +0000 Subject: [PATCH 019/139] Regen after r338752. Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17211 --- share/man/man5/src.conf.5 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index 8a0104171975..42ba5f2803ca 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,6 +1,6 @@ .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman. .\" $FreeBSD$ -.Dd September 13, 2018 +.Dd September 18, 2018 .Dt SRC.CONF 5 .Os .Sh NAME @@ -807,6 +807,14 @@ Set to build Hesiod support. Set to not build HTML docs. .It Va WITHOUT_HYPERV Set to not build or install HyperV utilities. +.Pp +This is a default setting on +arm/arm, arm/armv6, arm/armv7, arm64/aarch64, mips/mipsel, mips/mips, mips/mips64el, mips/mips64, mips/mipsn32, mips/mipselhf, mips/mipshf, mips/mips64elhf, mips/mips64hf, powerpc/powerpc, powerpc/powerpc64, powerpc/powerpcspe, riscv/riscv64, riscv/riscv64sf and sparc64/sparc64. +.It Va WITH_HYPERV +Set to build or install HyperV utilities. +.Pp +This is a default setting on +amd64/amd64 and i386/i386. .It Va WITHOUT_ICONV Set to not build iconv as part of libc. .It Va WITHOUT_INCLUDES From dc39aae35ec4afaa6119b1645488ef3ac525bcf3 Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Tue, 18 Sep 2018 16:57:04 +0000 Subject: [PATCH 020/139] Update the pkg-stage.sh script used to populate packages on the dvd1.iso installation medium from including KDE4 to KDE5, as the KDE4-based ports have been marked as deprecated in the Ports Collection. MFC after: 3 days Approved by: re (rgrimes) Sponsored by: The FreeBSD Foundation --- release/scripts/pkg-stage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/scripts/pkg-stage.sh b/release/scripts/pkg-stage.sh index fe4ffd9695d0..6c7cb0e76a3e 100755 --- a/release/scripts/pkg-stage.sh +++ b/release/scripts/pkg-stage.sh @@ -30,7 +30,7 @@ www/firefox www/links x11-drivers/xf86-video-vmware x11/gnome3 -x11/kde4 +x11/kde5 x11/xorg" # If NOPORTS is set for the release, do not attempt to build pkg(8). From 26fe2217bfbd6aa6ec67f5c57a2e7344bcf2fdff Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Tue, 18 Sep 2018 17:51:45 +0000 Subject: [PATCH 021/139] Only update the domain cursor once in keg_fetch_slab(). We drop the keg lock when we go to actually allocate the slab, allowing other threads to advance the cursor. This can cause us to exit the round-robin loop before having attempted allocations from all domains, resulting in a hang during a subsequent blocking allocation attempt from a depleted domain. Reported and tested by: Jan Bramkamp Reviewed by: alc, cem Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17209 --- sys/vm/uma_core.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 908349379763..937e78452021 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -2698,10 +2698,8 @@ keg_fetch_slab(uma_keg_t keg, uma_zone_t zone, int rdomain, int flags) LIST_INSERT_HEAD(&dom->ud_part_slab, slab, us_link); return (slab); } - if (rr) { - keg->uk_cursor = (keg->uk_cursor + 1) % vm_ndomains; - domain = keg->uk_cursor; - } + if (rr) + domain = (domain + 1) % vm_ndomains; } while (domain != start); /* Retry domain scan with blocking. */ From 22917b7e0ecd93f64a7112bec084ea385e0f5d1d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 20:47:06 +0000 Subject: [PATCH 022/139] Move mail.rc install to usr.bin/mail. This leverages CONFS to do the install Approved by: re (blanket, pkgbase), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17216 --- etc/Makefile | 4 ---- usr.bin/mail/Makefile | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/etc/Makefile b/etc/Makefile index d905d6590706..11f18d6e4dc5 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -34,10 +34,6 @@ BIN1+= ${SRCTOP}/usr.bin/locate/locate/locate.rc 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 diff --git a/usr.bin/mail/Makefile b/usr.bin/mail/Makefile index ea2338b3dded..7b205b8019d8 100644 --- a/usr.bin/mail/Makefile +++ b/usr.bin/mail/Makefile @@ -1,6 +1,7 @@ # @(#)Makefile 8.2 (Berkeley) 1/25/94 # $FreeBSD$ +CONFS= misc/mail.rc PROG= mail SRCS= version.c cmd1.c cmd2.c cmd3.c cmdtab.c collect.c edit.c fio.c \ getname.c head.c v7.local.c lex.c list.c main.c names.c popen.c \ From 1b491096a4a27fd09154c9c03302913bceca9a28 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 20:50:07 +0000 Subject: [PATCH 023/139] Move install of locate.rc to usr.bin/locate/locate/ This leverages CONFS to handle the install and purges an old comment. Approved by: re (blanket, pkgbase), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17215 --- etc/Makefile | 4 ---- usr.bin/locate/locate/Makefile | 5 +---- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/etc/Makefile b/etc/Makefile index 11f18d6e4dc5..71432a1142a7 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -26,10 +26,6 @@ BIN1= \ # NB: keep these sorted by MK_* knobs -.if ${MK_LOCATE} != "no" -BIN1+= ${SRCTOP}/usr.bin/locate/locate/locate.rc -.endif - .if ${MK_LPR} != "no" BIN1+= hosts.lpd printcap .endif diff --git a/usr.bin/locate/locate/Makefile b/usr.bin/locate/locate/Makefile index a139ff282028..7d56c57457c7 100644 --- a/usr.bin/locate/locate/Makefile +++ b/usr.bin/locate/locate/Makefile @@ -1,6 +1,7 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +CONFS= locate.rc PROG= locate SRCS= util.c locate.c CFLAGS+= -I${.CURDIR} -DMMAP # -DDEBUG (print time) -O2 (10% faster) @@ -15,9 +16,5 @@ SCRIPTSNAME_${script}= locate.${script:R} .endfor MLINKS+= locate.updatedb.8 updatedb.8 -# only /usr/src/etc/Makefile install files in /etc -# ${INSTALL} -o root -g wheel -m 644 \ -# ${.CURDIR}/locate.rc ${DESTDIR}/etc - .include "../../Makefile.inc" .include From a0bc3b59651d4ab9aa9cb999d5b1028f0e247c1a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 20:52:24 +0000 Subject: [PATCH 024/139] Move disktab to sbin/bsdlabel/ This leverages CONFS to handle the install. Approved by: re (blanket, pkgbase), will (mentor) Differential Revision: https://reviews.freebsd.org/D17217 --- etc/Makefile | 1 - sbin/bsdlabel/Makefile | 1 + {etc => sbin/bsdlabel}/disktab | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {etc => sbin/bsdlabel}/disktab (100%) diff --git a/etc/Makefile b/etc/Makefile index 71432a1142a7..b82704ec74b3 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -13,7 +13,6 @@ SUBDIR+=sendmail .endif BIN1= \ - disktab \ group \ hosts.allow \ libalias.conf \ diff --git a/sbin/bsdlabel/Makefile b/sbin/bsdlabel/Makefile index b1a71a2a74f2..6921a655af10 100644 --- a/sbin/bsdlabel/Makefile +++ b/sbin/bsdlabel/Makefile @@ -3,6 +3,7 @@ .PATH: ${SRCTOP}/sys/geom +CONFS= disktab PACKAGE=runtime PROG= bsdlabel SRCS= bsdlabel.c geom_bsd_enc.c diff --git a/etc/disktab b/sbin/bsdlabel/disktab similarity index 100% rename from etc/disktab rename to sbin/bsdlabel/disktab From 02b69379ea4f51703d06a2108d12ee5cf284cfd1 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 18 Sep 2018 20:54:37 +0000 Subject: [PATCH 025/139] Move libalias.conf to lib/libalias/libalias/ This leveages CONFS to handle the install. Approved by: re (blanket, pkgbase), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17218 --- etc/Makefile | 1 - lib/libalias/libalias/Makefile | 1 + {etc => lib/libalias/libalias}/libalias.conf | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {etc => lib/libalias/libalias}/libalias.conf (100%) diff --git a/etc/Makefile b/etc/Makefile index b82704ec74b3..67153d8a67c9 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -15,7 +15,6 @@ SUBDIR+=sendmail BIN1= \ group \ hosts.allow \ - libalias.conf \ login.access \ phones \ rc.bsdextended \ diff --git a/lib/libalias/libalias/Makefile b/lib/libalias/libalias/Makefile index 60c59a3ed313..bfbd523aa0b7 100644 --- a/lib/libalias/libalias/Makefile +++ b/lib/libalias/libalias/Makefile @@ -2,6 +2,7 @@ .PATH: ${SRCTOP}/sys/netinet/libalias +CONFS= libalias.conf PACKAGE=lib${LIB} LIB= alias SHLIBDIR?= /lib diff --git a/etc/libalias.conf b/lib/libalias/libalias/libalias.conf similarity index 100% rename from etc/libalias.conf rename to lib/libalias/libalias/libalias.conf From 5f65b4cab2afc98ffa7ec270fa1f06883191c777 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Tue, 18 Sep 2018 21:34:37 +0000 Subject: [PATCH 026/139] cxgbe(4): Enable TXRTLMT by default when the feature is available in the kernel (options RATELIMIT) and provisioned in the driver's configuration file (nethofld > 0). Submitted by: gallatin@ Approved by: re@ (kib@) --- sys/dev/cxgbe/t4_main.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 60bdff978b69..d6ad6048973a 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -1500,6 +1500,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 +1510,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; From 93dcd0775f4d7c4b1f89b3a1ac6e480fdc0e3449 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Tue, 18 Sep 2018 22:41:30 +0000 Subject: [PATCH 027/139] cxgbetool(8): Clarify the meaning of the "queue" parameter used to steer traffic to a particular queue. Submitted by: Krishnamraju Eraparaju @ Chelsio Approved by: re@ (kib@) --- usr.sbin/cxgbetool/cxgbetool.8 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/usr.sbin/cxgbetool/cxgbetool.8 b/usr.sbin/cxgbetool/cxgbetool.8 index 080fc8559b33..9e131368a0fa 100644 --- a/usr.sbin/cxgbetool/cxgbetool.8 +++ b/usr.sbin/cxgbetool/cxgbetool.8 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Aug 8, 2018 +.Dd Sep 18, 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. From f803ec1ef53f5da327a84057c26afae5b625ab61 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 19 Sep 2018 09:29:06 +0000 Subject: [PATCH 028/139] Move regdomain.xml to lib/lib80211/ This leverages CONFS to handle the install. lib80211 was picked because it is where this file is actually used from. Approved by: re (blanket, pkgbase), will (mentor) Differential Revision: https://reviews.freebsd.org/D17229 --- etc/Makefile | 4 ---- lib/lib80211/Makefile | 1 + {etc => lib/lib80211}/regdomain.xml | 0 3 files changed, 1 insertion(+), 4 deletions(-) rename {etc => lib/lib80211}/regdomain.xml (100%) diff --git a/etc/Makefile b/etc/Makefile index 67153d8a67c9..1534b451ef00 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -36,10 +36,6 @@ SSL= ${SRCTOP}/crypto/openssl/apps/openssl.cnf BIN1+= rc.sendmail .endif -.if ${MK_WIRELESS} != "no" -BIN1+= regdomain.xml -.endif - .if ${MK_SENDMAIL} == "no" ETCMAIL=mailer.conf aliases .else diff --git a/lib/lib80211/Makefile b/lib/lib80211/Makefile index fe103ce81cbd..54efe869b84a 100644 --- a/lib/lib80211/Makefile +++ b/lib/lib80211/Makefile @@ -1,5 +1,6 @@ # $FreeBSD$ +CONFS= regdomain.xml PACKAGE=lib${LIB} LIB= 80211 SHLIBDIR?= /lib diff --git a/etc/regdomain.xml b/lib/lib80211/regdomain.xml similarity index 100% rename from etc/regdomain.xml rename to lib/lib80211/regdomain.xml From 21d41b7887a19cdbe00ce6559aafa5b111e3efe2 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Wed, 19 Sep 2018 10:26:45 +0000 Subject: [PATCH 029/139] Update vendor/libarchive/dist to git 0cda60af13e709e670af90553b2271bf194e7ccd Relevant vendor changes: PR #1019: Add allocation check for the zip_entry struct Oss-Fuzz #10192: Handle whitespace-only ACL fields correctly --- CMakeLists.txt | 2 +- README.md | 1 - build/version | 2 +- configure.ac | 11 +++-------- contrib/android/Android.mk | 2 +- libarchive/archive.h | 4 ++-- libarchive/archive_acl.c | 6 ++++++ libarchive/archive_cryptor.c | 7 +++++++ libarchive/archive_entry.h | 2 +- libarchive/archive_read_support_format_ar.c | 1 + libarchive/archive_read_support_format_zip.c | 5 +++++ libarchive/test/test_sparse_basic.c | 2 ++ test_utils/test_main.c | 2 +- 13 files changed, 31 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80871bc941cb..3141dff772f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ endif() # RelWithDebInfo : Release build with Debug Info # MinSizeRel : Release Min Size build IF(NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build Type" FORCE) + SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build Type" FORCE) ENDIF(NOT CMAKE_BUILD_TYPE) # Set a value type to properly display CMAKE_BUILD_TYPE on GUI if the # value type is "UNINITIALIZED". diff --git a/README.md b/README.md index b48142191f2f..1a127bbb2653 100644 --- a/README.md +++ b/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/build/version b/build/version index 2427eab0f0b2..85595ba58905 100644 --- a/build/version +++ b/build/version @@ -1 +1 @@ -3003003 +3003004dev diff --git a/configure.ac b/configure.ac index cc61e724d4b2..17d6641888bf 100644 --- a/configure.ac +++ b/configure.ac @@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front. dnl In particular, this allows the version macro to be used in AC_INIT dnl These first two version numbers are updated automatically on each release. -m4_define([LIBARCHIVE_VERSION_S],[3.3.3]) -m4_define([LIBARCHIVE_VERSION_N],[3003003]) +m4_define([LIBARCHIVE_VERSION_S],[3.3.4dev]) +m4_define([LIBARCHIVE_VERSION_N],[3003004]) dnl bsdtar and bsdcpio versioning tracks libarchive m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) @@ -1153,12 +1153,7 @@ if test "x$with_openssl" != "xno"; then CRYPTO_CHECK(SHA256, OPENSSL, sha256) CRYPTO_CHECK(SHA384, OPENSSL, sha384) CRYPTO_CHECK(SHA512, OPENSSL, sha512) - if test "x$found_OPENSSL" != "xyes"; then - LIBS=$saved_LIBS - else - AC_CHECK_FUNCS([PKCS5_PBKDF2_HMAC_SHA1]) - fi - AC_CHECK_LIB(crypto,EVP_CIPHER_CTX_init) + AC_CHECK_FUNCS([PKCS5_PBKDF2_HMAC_SHA1]) fi # Probe libmd AFTER OpenSSL/libcrypto. diff --git a/contrib/android/Android.mk b/contrib/android/Android.mk index 2f2cf563697a..3f7619d66e27 100644 --- a/contrib/android/Android.mk +++ b/contrib/android/Android.mk @@ -94,9 +94,9 @@ libarchive_src_files := libarchive/archive_acl.c \ libarchive/archive_string.c \ libarchive/archive_string_sprintf.c \ libarchive/archive_util.c \ + libarchive/archive_version_details.c \ libarchive/archive_virtual.c \ libarchive/archive_write.c \ - libarchive/archive_write_disk_acl.c \ libarchive/archive_write_disk_posix.c \ libarchive/archive_write_disk_set_standard_lookup.c \ libarchive/archive_write_open_fd.c \ diff --git a/libarchive/archive.h b/libarchive/archive.h index cdbbeddf1d3c..cd65cd284b62 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -36,7 +36,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3003003 +#define ARCHIVE_VERSION_NUMBER 3003004 #include #include /* for wchar_t */ @@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.3.3" +#define ARCHIVE_VERSION_ONLY_STRING "3.3.4dev" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/libarchive/archive_acl.c b/libarchive/archive_acl.c index 4736531afa1d..9941d2f6fdb2 100644 --- a/libarchive/archive_acl.c +++ b/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/libarchive/archive_cryptor.c b/libarchive/archive_cryptor.c index 71967c9d46f0..74df5c405b08 100644 --- a/libarchive/archive_cryptor.c +++ b/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/libarchive/archive_entry.h b/libarchive/archive_entry.h index 78a060c242de..47653f37e5a0 100644 --- a/libarchive/archive_entry.h +++ b/libarchive/archive_entry.h @@ -30,7 +30,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3003003 +#define ARCHIVE_VERSION_NUMBER 3003004 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/libarchive/archive_read_support_format_ar.c b/libarchive/archive_read_support_format_ar.c index b6b9fc3c6dcd..1b0205cc7058 100644 --- a/libarchive/archive_read_support_format_ar.c +++ b/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/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c index 18f0d04e5c4e..420004dbabbc 100644 --- a/libarchive/archive_read_support_format_zip.c +++ b/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/libarchive/test/test_sparse_basic.c b/libarchive/test/test_sparse_basic.c index 58d53a94e072..0df0f1d321ac 100644 --- a/libarchive/test/test_sparse_basic.c +++ b/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/test_utils/test_main.c b/test_utils/test_main.c index 20ce551828ca..2ff942c84a44 100644 --- a/test_utils/test_main.c +++ b/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; } From bf94d6c78ba20f70a5726c5c85c7cf33c10e35da Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 19 Sep 2018 14:36:57 +0000 Subject: [PATCH 030/139] Fix state of dquot-less vnodes after failed quotaoff. UFS quotaoff iterates over all mp vnodes, and derefences and clears the pointers to corresponding dquots. If SU work items transiently reference some of dquots,quotaoff() would eventually fail, but all processed vnodes are already stripped from dquots. The state is problematic, since quotas are left enabled, but there is no dquots where blocks and inodes can be accounted. The result is assertion failures and NULL pointer dereferences. Fix it by suspending writes around quotaoff() call. Since the filesystem is synced, no dandling references to dquots from SU workitems can left behind, which means that quotaoff succeeds. The complication there is that quotaoff VFS op is performed with the mount point busied, while to suspend, we need to start write on the mp. If vn_start_write() is called on busied mp, system might deadlock against parallel unmount request. Handle this by unbusy-ing mp before starting write, which in turn requires changing the quotaoff() interface to return with the mount point not busied, same as was done for quotaon(). Reviewed by: mckusick Reported and tested by: pho Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week Differential revision: https://reviews.freebsd.org/D17208 --- sys/kern/vfs_syscalls.c | 3 ++- sys/ufs/ufs/ufs_quota.c | 33 ++++++++++++++++++++++++++++++--- sys/ufs/ufs/ufs_vfsops.c | 11 ++++++++--- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 91d93bb89207..a0ddefaa15df 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -190,7 +190,8 @@ sys_quotactl(struct thread *td, struct quotactl_args *uap) * Require that Q_QUOTAON handles the vfs_busy() reference on * its own, always returning with ubusied mount point. */ - if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON) + if ((uap->cmd >> SUBCMDSHIFT) != Q_QUOTAON && + (uap->cmd >> SUBCMDSHIFT) != Q_QUOTAOFF) vfs_unbusy(mp); return (error); } diff --git a/sys/ufs/ufs/ufs_quota.c b/sys/ufs/ufs/ufs_quota.c index 25133b834861..31fc49b7b4cf 100644 --- a/sys/ufs/ufs/ufs_quota.c +++ b/sys/ufs/ufs/ufs_quota.c @@ -712,6 +712,34 @@ quotaoff1(struct thread *td, struct mount *mp, int type) return (error); } +static int +quotaoff_inchange1(struct thread *td, struct mount *mp, int type) +{ + int error; + bool need_resume; + + /* + * mp is already suspended on unmount. If not, suspend it, to + * avoid the situation where quotaoff operation eventually + * failing due to SU structures still keeping references on + * dquots, but vnode's references are already clean. This + * would cause quota accounting leak and asserts otherwise. + * Note that the thread has already called vn_start_write(). + */ + if (mp->mnt_susp_owner == td) { + need_resume = false; + } else { + error = vfs_write_suspend_umnt(mp); + if (error != 0) + return (error); + need_resume = true; + } + error = quotaoff1(td, mp, type); + if (need_resume) + vfs_write_resume(mp, VR_START_WRITE); + return (error); +} + /* * Turns off quotas, assumes that ump->um_qflags are already checked * and QTF_CLOSING is set to indicate operation in progress. Fixes @@ -721,10 +749,9 @@ int quotaoff_inchange(struct thread *td, struct mount *mp, int type) { struct ufsmount *ump; - int i; - int error; + int error, i; - error = quotaoff1(td, mp, type); + error = quotaoff_inchange1(td, mp, type); ump = VFSTOUFS(mp); UFS_LOCK(ump); diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index cf5b1d792aef..f39f50cc9a61 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -94,7 +94,8 @@ ufs_quotactl(mp, cmds, id, arg) void *arg; { #ifndef QUOTA - if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON) + if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON || + (cmds >> SUBCMDSHIFT) == Q_QUOTAOFF) vfs_unbusy(mp); return (EOPNOTSUPP); @@ -117,13 +118,13 @@ ufs_quotactl(mp, cmds, id, arg) break; default: - if (cmd == Q_QUOTAON) + if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF) vfs_unbusy(mp); return (EINVAL); } } if ((u_int)type >= MAXQUOTAS) { - if (cmd == Q_QUOTAON) + if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF) vfs_unbusy(mp); return (EINVAL); } @@ -134,7 +135,11 @@ ufs_quotactl(mp, cmds, id, arg) break; case Q_QUOTAOFF: + vfs_ref(mp); + vfs_unbusy(mp); + vn_start_write(NULL, &mp, V_WAIT | V_MNTREF); error = quotaoff(td, mp, type); + vn_finished_write(mp); break; case Q_SETQUOTA32: From a6ade1a07b805f559ec1ebe90b97477b3c41824b Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 19 Sep 2018 14:38:01 +0000 Subject: [PATCH 031/139] Fix ZFS VFS op quotactl to follow busy protocol. Reviewed by: avg, mckusick Tested by: pho Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week Differential revision: https://reviews.freebsd.org/D17208 --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 92f51420e321..8e421132b10e 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 @@ -198,6 +198,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 +257,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)); From bca3325319305149808a0f5399d4b161f4705d78 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 19 Sep 2018 14:56:53 +0000 Subject: [PATCH 032/139] Move remote & phones to usr.bin/tip/tip/ Approved by: re (blanket, pkgbase), will (mentor) Differential Revision: https://reviews.freebsd.org/D17219 --- etc/Makefile | 2 -- usr.bin/tip/tip/Makefile | 4 ++++ {etc => usr.bin/tip/tip}/phones | 0 {etc => usr.bin/tip/tip}/remote | 0 4 files changed, 4 insertions(+), 2 deletions(-) rename {etc => usr.bin/tip/tip}/phones (100%) rename {etc => usr.bin/tip/tip}/remote (100%) diff --git a/etc/Makefile b/etc/Makefile index 1534b451ef00..a76b61cbb658 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -16,10 +16,8 @@ BIN1= \ group \ hosts.allow \ login.access \ - phones \ rc.bsdextended \ rc.firewall \ - remote \ termcap.small # NB: keep these sorted by MK_* knobs diff --git a/usr.bin/tip/tip/Makefile b/usr.bin/tip/tip/Makefile index a8ed43f7c579..f177ad15d3b8 100644 --- a/usr.bin/tip/tip/Makefile +++ b/usr.bin/tip/tip/Makefile @@ -31,6 +31,7 @@ # explicitly to remcap.c if not 1024 # CONNECT enable ~C command (connect pgm to remote) +CONFS= phones remote PROG= tip LINKS= ${BINDIR}/tip ${BINDIR}/cu MAN= tip.1 cu.1 @@ -47,6 +48,9 @@ SRCS= acu.c acutab.c cmds.c cmdtab.c cu.c hunt.c log.c partab.c \ # -- log.o depends on the Makefile because of ACULOG acutab.o log.o remote.o: Makefile +# Don't rebuild based on remote.c +remote: .MADE + .include # 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 From 215aa93033a2e7b9db61d989c51062ff82175bb2 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 19 Sep 2018 15:39:16 +0000 Subject: [PATCH 033/139] amd64 pmap: remove tautological assert. pm_pcid is unsigned. Reviewed by: cem, markj CID: 1395727 Noted by: cem Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 3 days Differential revision: https://reviews.freebsd.org/D17235 --- sys/amd64/amd64/pmap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 9f43f3cfadc7..21ec1838d1d1 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -7442,8 +7442,7 @@ pmap_pcid_alloc_checked(pmap_t pmap, u_int cpuid) uint64_t cached; cached = pmap_pcid_alloc(pmap, cpuid); - KASSERT(pmap->pm_pcids[cpuid].pm_pcid >= 0 && - pmap->pm_pcids[cpuid].pm_pcid < PMAP_PCID_OVERMAX, + KASSERT(pmap->pm_pcids[cpuid].pm_pcid < PMAP_PCID_OVERMAX, ("pmap %p cpu %d pcid %#x", pmap, cpuid, pmap->pm_pcids[cpuid].pm_pcid)); KASSERT(pmap->pm_pcids[cpuid].pm_pcid != PMAP_PCID_KERN || From c035292545cf7b7ce74236d87ef1b2f985bd0cb7 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik Date: Wed, 19 Sep 2018 16:02:33 +0000 Subject: [PATCH 034/139] vm: check for empty kstack cache before locking The current cache logic checks the total number of stacks in the kernel, which even on small boxes significantly exceeds the 128 limit (e.g. an 8-way box with zfs has almost 800 stacks allocated). Stacks are cached earlier for each main thread. As a result the code is rarely executed, but when it is then (on boxes like the above) it always fails. Since there are no provisions made for NUMA and release time is approaching, just do a quick check to avoid acquiring the lock. Approved by: re (kib) --- sys/vm/vm_glue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c index 832dbce324ef..beccb31f0b64 100644 --- a/sys/vm/vm_glue.c +++ b/sys/vm/vm_glue.c @@ -327,7 +327,7 @@ vm_thread_new(struct thread *td, int pages) else if (pages > KSTACK_MAX_PAGES) pages = KSTACK_MAX_PAGES; - if (pages == kstack_pages) { + if (pages == kstack_pages && kstack_cache != NULL) { mtx_lock(&kstack_cache_mtx); if (kstack_cache != NULL) { ks_ce = kstack_cache; From ad8edd79ccc1132b0d7c77b49c51785a619e725d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 19 Sep 2018 16:37:43 +0000 Subject: [PATCH 035/139] Convert i386 NPX hardware context save methods to ifuncs. Since ifunc-capable linker is now required on i386, bring this code in line with the amd64 counterpart. Reviewed by: alc, markj Sponsored by: The FreeBSD Foundation Approved by: re (gjb) Differential revision: https://reviews.freebsd.org/D16736 --- sys/i386/i386/npx.c | 98 ++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/sys/i386/i386/npx.c b/sys/i386/i386/npx.c index a2edacec987e..665b55b1c35b 100644 --- a/sys/i386/i386/npx.c +++ b/sys/i386/i386/npx.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include @@ -183,7 +184,6 @@ CTASSERT(X86_XSTATE_XCR0_OFFSET >= offsetof(struct savexmm, sv_pad) && static void fpu_clean_state(void); -static void fpusave(union savefpu *); static void fpurstor(union savefpu *); int hw_float; @@ -206,8 +206,6 @@ struct xsave_area_elm_descr { u_int size; } *xsave_area_desc; -static int use_xsaveopt; - static volatile u_int npx_traps_while_probing; alias_for_inthand_t probetrap; @@ -314,6 +312,69 @@ npx_probe(void) return (hw_float); } +static void +npxsave_xsaveopt(union savefpu *addr) +{ + + xsaveopt((char *)addr, xsave_mask); +} + +static void +fpusave_xsave(union savefpu *addr) +{ + + xsave((char *)addr, xsave_mask); +} + +static void +fpusave_fxsave(union savefpu *addr) +{ + + fxsave((char *)addr); +} + +static void +fpusave_fnsave(union savefpu *addr) +{ + + fnsave((char *)addr); +} + +static void +init_xsave(void) +{ + + if (use_xsave) + return; + if (!cpu_fxsr || (cpu_feature2 & CPUID2_XSAVE) == 0) + return; + use_xsave = 1; + TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); +} + +DEFINE_IFUNC(, void, npxsave_core, (union savefpu *), static) +{ + + init_xsave(); + if (use_xsave) + return ((cpu_stdext_feature & CPUID_EXTSTATE_XSAVEOPT) != 0 ? + npxsave_xsaveopt : fpusave_xsave); + if (cpu_fxsr) + return (fpusave_fxsave); + return (fpusave_fnsave); +} + +DEFINE_IFUNC(, void, fpusave, (union savefpu *), static) +{ + + init_xsave(); + if (use_xsave) + return (fpusave_xsave); + if (cpu_fxsr) + return (fpusave_fxsave); + return (fpusave_fnsave); +} + /* * Enable XSAVE if supported and allowed by user. * Calculate the xsave_mask. @@ -325,13 +386,8 @@ npxinit_bsp1(void) uint64_t xsave_mask_user; TUNABLE_INT_FETCH("hw.lazy_fpu_switch", &lazy_fpu_switch); - if (cpu_fxsr && (cpu_feature2 & CPUID2_XSAVE) != 0) { - use_xsave = 1; - TUNABLE_INT_FETCH("hw.use_xsave", &use_xsave); - } if (!use_xsave) return; - cpuid_count(0xd, 0x0, cp); xsave_mask = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE; if ((cp[0] & xsave_mask) != xsave_mask) @@ -345,14 +401,9 @@ npxinit_bsp1(void) xsave_mask &= ~XFEATURE_AVX512; if ((xsave_mask & XFEATURE_MPX) != XFEATURE_MPX) xsave_mask &= ~XFEATURE_MPX; - - cpuid_count(0xd, 0x1, cp); - if ((cp[0] & CPUID_EXTSTATE_XSAVEOPT) != 0) - use_xsaveopt = 1; } /* - * Calculate the fpu save area size. */ static void @@ -867,15 +918,11 @@ npxdna(void) * npxsave() atomically with checking fpcurthread. */ void -npxsave(addr) - union savefpu *addr; +npxsave(union savefpu *addr) { stop_emulating(); - if (use_xsaveopt) - xsaveopt((char *)addr, xsave_mask); - else - fpusave(addr); + npxsave_core(addr); } void npxswitch(struct thread *td, struct pcb *pcb); @@ -1099,19 +1146,6 @@ npxsetregs(struct thread *td, union savefpu *addr, char *xfpustate, return (error); } -static void -fpusave(addr) - union savefpu *addr; -{ - - if (use_xsave) - xsave((char *)addr, xsave_mask); - else if (cpu_fxsr) - fxsave(addr); - else - fnsave(addr); -} - static void npx_fill_fpregs_xmm1(struct savexmm *sv_xmm, struct save87 *sv_87) { From 997fecb5c2110c99002b97b647b76b4e3cf0d849 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Wed, 19 Sep 2018 18:49:37 +0000 Subject: [PATCH 036/139] Update udp6_output() inp locking to avoid concurrency issues with route cache updates. Bring over locking changes applied to udp_output() for the route cache in r297225 and fixed in r306559 which achieve multiple things: (1) acquire an exclusive inp lock earlier depending on the expected conditions; we add a comment explaining this in udp6, (2) having acquired the exclusive lock earlier eliminates a slight possible chance for a race condition which was present in v4 for multiple years as well and is now gone, and (3) only pass the inp_route6 to ip6_output() if we are holding an exclusive inp lock, so that possible route cache updates in case of routing table generation number changes can happen safely. In addition this change (as the legacy IP counterpart) decomposes the tracking of inp and pcbinfo lock and adds extra assertions, that the two together are acquired correctly. PR: 230950 Reviewed by: karels, markj Approved by: re (gjb) Pointyhat to: bz (for completely missing this bit) Differential Revision: https://reviews.freebsd.org/D17230 --- sys/netinet6/udp6_usrreq.c | 50 ++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index b32e88663172..d5ab934c9d41 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -698,7 +698,7 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, u_int32_t ulen, plen; uint16_t cscov; u_short fport; - uint8_t nxt, unlock_udbinfo; + uint8_t nxt, unlock_inp, unlock_udbinfo; /* addr6 has been validated in udp6_send(). */ sin6 = (struct sockaddr_in6 *)addr6; @@ -734,7 +734,22 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, inp = sotoinpcb(so); KASSERT(inp != NULL, ("%s: inp == NULL", __func__)); - INP_RLOCK(inp); + /* + * In the following cases we want a write lock on the inp for either + * local operations or for possible route cache updates in the IPv6 + * output path: + * - on connected sockets (sin6 is NULL) for route cache updates, + * - when we are not bound to an address and source port (it is + * in6_pcbsetport() which will require the write lock). + */ + if (sin6 == NULL || (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) && + inp->inp_lport == 0)) { + INP_WLOCK(inp); + unlock_inp = UH_WLOCKED; + } else { + INP_RLOCK(inp); + unlock_inp = UH_RLOCKED; + } nxt = (inp->inp_socket->so_proto->pr_protocol == IPPROTO_UDP) ? IPPROTO_UDP : IPPROTO_UDPLITE; @@ -758,7 +773,10 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, * potential race in which the factors causing us to * select the UDPv4 output routine are invalidated? */ - INP_RUNLOCK(inp); + if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else + INP_RUNLOCK(inp); if (sin6) in6_sin6_2_sin_in_sock((struct sockaddr *)sin6); pru = inetsw[ip_protox[nxt]].pr_usrreqs; @@ -772,7 +790,10 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, if (control) { if ((error = ip6_setpktopts(control, &opt, inp->in6p_outputopts, td->td_ucred, nxt)) != 0) { - INP_RUNLOCK(inp); + if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else + INP_RUNLOCK(inp); ip6_clearpktopts(&opt, -1); if (control) m_freem(control); @@ -786,12 +807,6 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol); if (sin6 != NULL && IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_laddr) && inp->inp_lport == 0) { - INP_RUNLOCK(inp); - /* - * XXX there is a short window here which could lead to a race; - * should we re-check that what got us here is still valid? - */ - INP_WLOCK(inp); INP_HASH_WLOCK(pcbinfo); unlock_udbinfo = UH_WLOCKED; } else if (sin6 != NULL && @@ -972,9 +987,10 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, UDPLITE_PROBE(send, NULL, inp, ip6, inp, udp6); else UDP_PROBE(send, NULL, inp, ip6, inp, udp6); - error = ip6_output(m, optp, &inp->inp_route6, flags, + error = ip6_output(m, optp, + (unlock_inp == UH_WLOCKED) ? &inp->inp_route6 : NULL, flags, inp->in6p_moptions, NULL, inp); - if (unlock_udbinfo == UH_WLOCKED) + if (unlock_inp == UH_WLOCKED) INP_WUNLOCK(inp); else INP_RUNLOCK(inp); @@ -987,12 +1003,20 @@ udp6_output(struct socket *so, int flags_arg, struct mbuf *m, release: if (unlock_udbinfo == UH_WLOCKED) { + KASSERT(unlock_inp == UH_WLOCKED, ("%s: excl udbinfo lock, " + "non-excl inp lock: pcbinfo %p %#x inp %p %#x", + __func__, pcbinfo, unlock_udbinfo, inp, unlock_inp)); INP_HASH_WUNLOCK(pcbinfo); INP_WUNLOCK(inp); } else if (unlock_udbinfo == UH_RLOCKED) { + KASSERT(unlock_inp == UH_RLOCKED, ("%s: non-excl udbinfo lock, " + "excl inp lock: pcbinfo %p %#x inp %p %#x", + __func__, pcbinfo, unlock_udbinfo, inp, unlock_inp)); INP_HASH_RUNLOCK_ET(pcbinfo, et); INP_RUNLOCK(inp); - } else + } else if (unlock_inp == UH_WLOCKED) + INP_WUNLOCK(inp); + else INP_RUNLOCK(inp); if (control) { ip6_clearpktopts(&opt, -1); From 1aed6d48a8b08d7ce7a981085d3b7379fa77d470 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Wed, 19 Sep 2018 19:13:43 +0000 Subject: [PATCH 037/139] Move kernel vmem arena initialization to vm_kern.c. This keeps the initialization coupled together with the kmem_* KPI implementation, which is the main user of these arenas. No functional change intended. Reviewed by: alc Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17247 --- sys/vm/vm_init.c | 84 +----------------------------------------------- sys/vm/vm_kern.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 83 deletions(-) diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index 09e87ed231ed..27ecb960201e 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -98,12 +98,6 @@ extern void uma_startup1(void); extern void uma_startup2(void); extern void vm_radix_reserve_kva(void); -#if VM_NRESERVLEVEL > 0 -#define KVA_QUANTUM (1 << (VM_LEVEL_0_ORDER + PAGE_SHIFT)) -#else - /* On non-superpage architectures want large import sizes. */ -#define KVA_QUANTUM (PAGE_SIZE * 1024) -#endif long physmem; /* @@ -112,58 +106,15 @@ long physmem; static void vm_mem_init(void *); SYSINIT(vm_mem, SI_SUB_VM, SI_ORDER_FIRST, vm_mem_init, NULL); -/* - * Import kva into the kernel arena. - */ -static int -kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) -{ - vm_offset_t addr; - int result; - - KASSERT((size % KVA_QUANTUM) == 0, - ("kva_import: Size %jd is not a multiple of %d", - (intmax_t)size, (int)KVA_QUANTUM)); - addr = vm_map_min(kernel_map); - result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0, - VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT); - if (result != KERN_SUCCESS) - return (ENOMEM); - - *addrp = addr; - - return (0); -} - -#if VM_NRESERVLEVEL > 0 -/* - * Import a superpage from the normal kernel arena into the special - * arena for allocations with different permissions. - */ -static int -kernel_rwx_alloc(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp) -{ - - KASSERT((size % KVA_QUANTUM) == 0, - ("kernel_rwx_alloc: Size %jd is not a multiple of %d", - (intmax_t)size, (int)KVA_QUANTUM)); - return (vmem_xalloc(arena, size, KVA_QUANTUM, 0, 0, VMEM_ADDR_MIN, - VMEM_ADDR_MAX, flags, addrp)); -} -#endif - /* * vm_init initializes the virtual memory system. * This is done only by the first cpu up. * * The start and end address of physical memory is passed in. */ -/* ARGSUSED*/ static void -vm_mem_init(dummy) - void *dummy; +vm_mem_init(void *dummy) { - int domain; /* * Initializes resident memory structures. From here on, all physical @@ -184,39 +135,6 @@ vm_mem_init(dummy) vm_map_startup(); kmem_init(virtual_avail, virtual_end); - /* - * Initialize the kernel_arena. This can grow on demand. - */ - vmem_init(kernel_arena, "kernel arena", 0, 0, PAGE_SIZE, 0, 0); - vmem_set_import(kernel_arena, kva_import, NULL, NULL, KVA_QUANTUM); - -#if VM_NRESERVLEVEL > 0 - /* - * In an architecture with superpages, maintain a separate arena - * for allocations with permissions that differ from the "standard" - * read/write permissions used for memory in the kernel_arena. - */ - kernel_rwx_arena = vmem_create("kernel rwx arena", 0, 0, PAGE_SIZE, - 0, M_WAITOK); - vmem_set_import(kernel_rwx_arena, kernel_rwx_alloc, - (vmem_release_t *)vmem_xfree, kernel_arena, KVA_QUANTUM); -#endif - - for (domain = 0; domain < vm_ndomains; domain++) { - vm_dom[domain].vmd_kernel_arena = vmem_create( - "kernel arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); - vmem_set_import(vm_dom[domain].vmd_kernel_arena, - (vmem_import_t *)vmem_alloc, NULL, kernel_arena, - KVA_QUANTUM); -#if VM_NRESERVLEVEL > 0 - vm_dom[domain].vmd_kernel_rwx_arena = vmem_create( - "kernel rwx arena domain", 0, 0, PAGE_SIZE, 0, M_WAITOK); - vmem_set_import(vm_dom[domain].vmd_kernel_rwx_arena, - kernel_rwx_alloc, (vmem_release_t *)vmem_xfree, - vm_dom[domain].vmd_kernel_arena, KVA_QUANTUM); -#endif - } - #ifndef UMA_MD_SMALL_ALLOC /* Set up radix zone to use noobj_alloc. */ vm_radix_reserve_kva(); diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 5dee4d758dd0..31b85fd81854 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -121,6 +121,13 @@ SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD, #endif "Max kernel address"); +#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 + /* * kva_alloc: * @@ -644,6 +651,46 @@ kmem_init_zero_region(void) zero_region = (const void *)addr; } +/* + * 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 + /* * kmem_init: * @@ -651,11 +698,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 +720,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); + +#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 + } } /* From d12c44655065633dd8b8c249ec271a1d8ba63ba4 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Wed, 19 Sep 2018 19:35:02 +0000 Subject: [PATCH 038/139] Convert x86 cache invalidation functions to ifuncs. This simplifies the runtime logic and reduces the number of runtime-constant branches. Reviewed by: alc, markj Sponsored by: The FreeBSD Foundation Approved by: re (gjb) Differential revision: https://reviews.freebsd.org/D16736 --- sys/amd64/amd64/pmap.c | 103 +++++++++++++++---------- sys/amd64/include/pmap.h | 4 +- sys/dev/drm2/drm_os_freebsd.c | 4 +- sys/dev/drm2/i915/intel_ringbuffer.c | 9 ++- sys/i386/i386/pmap.c | 109 ++++++++++++++++----------- sys/i386/i386/vm_machdep.c | 2 +- sys/i386/include/pmap.h | 4 +- sys/x86/iommu/intel_utils.c | 3 +- 8 files changed, 145 insertions(+), 93 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 21ec1838d1d1..d4d91e7c23a9 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -648,6 +648,10 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte, struct rwlock **lockp); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); static int pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); +static void pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, + vm_offset_t eva); +static void pmap_invalidate_cache_range_all(vm_offset_t sva, + vm_offset_t eva); static void pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde); static void pmap_kenter_attr(vm_offset_t va, vm_paddr_t pa, int mode); @@ -2171,36 +2175,62 @@ pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde) pmap_invalidate_page(pmap, va); } -#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) - -void -pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) +DEFINE_IFUNC(, void, pmap_invalidate_cache_range, + (vm_offset_t sva, vm_offset_t eva), static) { - if (force) { - sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); - } else { - KASSERT((sva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: sva not page-aligned")); - KASSERT((eva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: eva not page-aligned")); + if ((cpu_feature & CPUID_SS) != 0) + return (pmap_invalidate_cache_range_selfsnoop); + if ((cpu_feature & CPUID_CLFSH) != 0) + return (pmap_force_invalidate_cache_range); + return (pmap_invalidate_cache_range_all); +} + +#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) + +static void +pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva) +{ + + KASSERT((sva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: sva not page-aligned")); + KASSERT((eva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: eva not page-aligned")); +} + +static void +pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); +} + +void +pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) +{ + + sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); + if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) { + /* + * The supplied range is bigger than 2MB. + * Globally invalidate cache. + */ + pmap_invalidate_cache(); + return; } - if ((cpu_feature & CPUID_SS) != 0 && !force) - ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { - /* - * XXX: Some CPUs fault, hang, or trash the local APIC - * registers if we use CLFLUSH on the local APIC - * range. The local APIC is always uncached, so we - * don't need to flush for that range anyway. - */ - if (pmap_kextract(sva) == lapic_paddr) - return; + /* + * XXX: Some CPUs fault, hang, or trash the local APIC + * registers if we use CLFLUSH on the local APIC range. The + * local APIC is always uncached, so we don't need to flush + * for that range anyway. + */ + if (pmap_kextract(sva) == lapic_paddr) + return; + if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) { /* - * Otherwise, do per-cache line flush. Use the sfence + * Do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache @@ -2210,10 +2240,7 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) for (; sva < eva; sva += cpu_clflush_line_size) clflushopt(sva); sfence(); - } else if ((cpu_feature & CPUID_CLFSH) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { - if (pmap_kextract(sva) == lapic_paddr) - return; + } else { /* * Writes are ordered by CLFLUSH on Intel CPUs. */ @@ -2223,17 +2250,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. * @@ -6938,7 +6965,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); - pmap_invalidate_cache_range(va, va + tmpsize, FALSE); + pmap_invalidate_cache_range(va, va + tmpsize); return ((void *)(va + offset)); } @@ -7297,7 +7324,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); } diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 34c3fb868ce3..5b83307bbb68 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -431,8 +431,8 @@ void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); void pmap_invalidate_all(pmap_t); void pmap_invalidate_cache(void); void pmap_invalidate_cache_pages(vm_page_t *pages, int count); -void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, - boolean_t force); +void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); +void pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); void pmap_get_mapping(pmap_t pmap, vm_offset_t va, uint64_t *ptr, int *num); boolean_t pmap_map_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t); void pmap_unmap_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t); diff --git a/sys/dev/drm2/drm_os_freebsd.c b/sys/dev/drm2/drm_os_freebsd.c index 8489ca848027..c7b0bce2c7ab 100644 --- a/sys/dev/drm2/drm_os_freebsd.c +++ b/sys/dev/drm2/drm_os_freebsd.c @@ -395,8 +395,8 @@ drm_clflush_virt_range(char *addr, unsigned long length) { #if defined(__i386__) || defined(__amd64__) - pmap_invalidate_cache_range((vm_offset_t)addr, - (vm_offset_t)addr + length, TRUE); + pmap_force_invalidate_cache_range((vm_offset_t)addr, + (vm_offset_t)addr + length); #else DRM_ERROR("drm_clflush_virt_range not implemented on this architecture"); #endif diff --git a/sys/dev/drm2/i915/intel_ringbuffer.c b/sys/dev/drm2/i915/intel_ringbuffer.c index 92a792746b1b..c6c242c875c3 100644 --- a/sys/dev/drm2/i915/intel_ringbuffer.c +++ b/sys/dev/drm2/i915/intel_ringbuffer.c @@ -471,8 +471,8 @@ init_pipe_control(struct intel_ring_buffer *ring) if (pc->cpu_page == NULL) goto err_unpin; pmap_qenter((uintptr_t)pc->cpu_page, &obj->pages[0], 1); - pmap_invalidate_cache_range((vm_offset_t)pc->cpu_page, - (vm_offset_t)pc->cpu_page + PAGE_SIZE, FALSE); + pmap_force_invalidate_cache_range((vm_offset_t)pc->cpu_page, + (vm_offset_t)pc->cpu_page + PAGE_SIZE); pc->obj = obj; ring->private = pc; @@ -1102,8 +1102,9 @@ static int init_status_page(struct intel_ring_buffer *ring) } pmap_qenter((vm_offset_t)ring->status_page.page_addr, &obj->pages[0], 1); - pmap_invalidate_cache_range((vm_offset_t)ring->status_page.page_addr, - (vm_offset_t)ring->status_page.page_addr + PAGE_SIZE, FALSE); + pmap_force_invalidate_cache_range( + (vm_offset_t)ring->status_page.page_addr, + (vm_offset_t)ring->status_page.page_addr + PAGE_SIZE); ring->status_page.obj = obj; memset(ring->status_page.page_addr, 0, PAGE_SIZE); diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 0c1437df5187..a969eef28810 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -148,6 +148,7 @@ __FBSDID("$FreeBSD$"); #include #include #endif +#include #include #include #include @@ -314,6 +315,10 @@ static vm_page_t pmap_enter_quick_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, vm_page_t mpte); static void pmap_flush_page(vm_page_t m); static int pmap_insert_pt_page(pmap_t pmap, vm_page_t mpte); +static void pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, + vm_offset_t eva); +static void pmap_invalidate_cache_range_all(vm_offset_t sva, + vm_offset_t eva); static void pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde); static void pmap_fill_ptp(pt_entry_t *firstpte, pt_entry_t newpte); @@ -1407,37 +1412,62 @@ pmap_invalidate_pde_page(pmap_t pmap, vm_offset_t va, pd_entry_t pde) pmap_invalidate_page(pmap, va); } -#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) - -void -pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) +DEFINE_IFUNC(, void, pmap_invalidate_cache_range, (vm_offset_t, vm_offset_t), + static) { - if (force) { - sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); - } else { - KASSERT((sva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: sva not page-aligned")); - KASSERT((eva & PAGE_MASK) == 0, - ("pmap_invalidate_cache_range: eva not page-aligned")); + if ((cpu_feature & CPUID_SS) != 0) + return (pmap_invalidate_cache_range_selfsnoop); + if ((cpu_feature & CPUID_CLFSH) != 0) + return (pmap_force_invalidate_cache_range); + return (pmap_invalidate_cache_range_all); +} + +#define PMAP_CLFLUSH_THRESHOLD (2 * 1024 * 1024) + +static void +pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva) +{ + + KASSERT((sva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: sva not page-aligned")); + KASSERT((eva & PAGE_MASK) == 0, + ("pmap_invalidate_cache_range: eva not page-aligned")); +} + +static void +pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); +} + +void +pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) +{ + + sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1); + if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) { + /* + * The supplied range is bigger than 2MB. + * Globally invalidate cache. + */ + pmap_invalidate_cache(); + return; } - if ((cpu_feature & CPUID_SS) != 0 && !force) - ; /* If "Self Snoop" is supported and allowed, do nothing. */ - else if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { -#ifdef DEV_APIC + /* + * XXX: Some CPUs fault, hang, or trash the local APIC + * registers if we use CLFLUSH on the local APIC + * range. The local APIC is always uncached, so we + * don't need to flush for that range anyway. + */ + if (pmap_kextract(sva) == lapic_paddr) + return; + + if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) { /* - * XXX: Some CPUs fault, hang, or trash the local APIC - * registers if we use CLFLUSH on the local APIC - * range. The local APIC is always uncached, so we - * don't need to flush for that range anyway. - */ - if (pmap_kextract(sva) == lapic_paddr) - return; -#endif - /* - * Otherwise, do per-cache line flush. Use the sfence + * Do per-cache line flush. Use the sfence * instruction to insure that previous stores are * included in the write-back. The processor * propagates flush to other processors in the cache @@ -1447,12 +1477,7 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) for (; sva < eva; sva += cpu_clflush_line_size) clflushopt(sva); sfence(); - } else if ((cpu_feature & CPUID_CLFSH) != 0 && - eva - sva < PMAP_CLFLUSH_THRESHOLD) { -#ifdef DEV_APIC - if (pmap_kextract(sva) == lapic_paddr) - return; -#endif + } else { /* * Writes are ordered by CLFLUSH on Intel CPUs. */ @@ -1462,17 +1487,17 @@ pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, boolean_t force) clflush(sva); if (cpu_vendor_id != CPU_VENDOR_INTEL) mfence(); - } else { - - /* - * No targeted cache flush methods are supported by CPU, - * or the supplied range is bigger than 2MB. - * Globally invalidate cache. - */ - pmap_invalidate_cache(); } } +static void +pmap_invalidate_cache_range_all(vm_offset_t sva, vm_offset_t eva) +{ + + pmap_invalidate_cache_range_check_align(sva, eva); + pmap_invalidate_cache(); +} + void pmap_invalidate_cache_pages(vm_page_t *pages, int count) { @@ -5479,7 +5504,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); - pmap_invalidate_cache_range(va, va + size, FALSE); + pmap_invalidate_cache_range(va, va + size); return ((void *)(va + offset)); } @@ -5718,7 +5743,7 @@ pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) */ if (changed) { pmap_invalidate_range(kernel_pmap, base, tmpva); - pmap_invalidate_cache_range(base, tmpva, FALSE); + pmap_invalidate_cache_range(base, tmpva); } return (0); } diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c index c3ed95dd4d02..250689459643 100644 --- a/sys/i386/i386/vm_machdep.c +++ b/sys/i386/i386/vm_machdep.c @@ -650,7 +650,7 @@ sf_buf_invalidate(struct sf_buf *sf) * settings are recalculated. */ pmap_qenter(sf->kva, &m, 1); - pmap_invalidate_cache_range(sf->kva, sf->kva + PAGE_SIZE, FALSE); + pmap_invalidate_cache_range(sf->kva, sf->kva + PAGE_SIZE); } /* diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h index da9ae6588189..e48c0d3c6af5 100644 --- a/sys/i386/include/pmap.h +++ b/sys/i386/include/pmap.h @@ -394,8 +394,8 @@ void pmap_invalidate_range(pmap_t, vm_offset_t, vm_offset_t); void pmap_invalidate_all(pmap_t); void pmap_invalidate_cache(void); void pmap_invalidate_cache_pages(vm_page_t *pages, int count); -void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva, - boolean_t force); +void pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); +void pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva); void *pmap_trm_alloc(size_t size, int flags); void pmap_trm_free(void *addr, size_t size); diff --git a/sys/x86/iommu/intel_utils.c b/sys/x86/iommu/intel_utils.c index 5b145c5aeae9..944aa214baa6 100644 --- a/sys/x86/iommu/intel_utils.c +++ b/sys/x86/iommu/intel_utils.c @@ -368,8 +368,7 @@ dmar_flush_transl_to_ram(struct dmar_unit *unit, void *dst, size_t sz) * If DMAR does not snoop paging structures accesses, flush * CPU cache to memory. */ - pmap_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz, - TRUE); + pmap_force_invalidate_cache_range((uintptr_t)dst, (uintptr_t)dst + sz); } void From c6de6086cfc759413dd95b5fa549fe7eebca801a Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 19 Sep 2018 20:52:47 +0000 Subject: [PATCH 039/139] openssh: rename local macro to avoid OpenSSL 1.1.1 conflict Local changes introduced an OPENSSH_VERSION macro, but this conflicts with a macro of the same name introduced with OepnsSL 1.1.1 Reviewed by: des Approved by: re (gjb) MFC after: 1 week Sponsored by: The FreeBSD Foundation --- crypto/openssh/ssh.c | 6 +++--- crypto/openssh/sshd.c | 4 ++-- crypto/openssh/version.h | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crypto/openssh/ssh.c b/crypto/openssh/ssh.c index e78a1366aaef..f79437034a4e 100644 --- a/crypto/openssh/ssh.c +++ b/crypto/openssh/ssh.c @@ -811,10 +811,10 @@ main(int ac, char **av) *options.version_addendum != '\0') fprintf(stderr, "%s %s, %s\n", SSH_RELEASE, options.version_addendum, - OPENSSL_VERSION); + OPENSSL_VERSION_STRING); else fprintf(stderr, "%s, %s\n", SSH_RELEASE, - OPENSSL_VERSION); + OPENSSL_VERSION_STRING); if (opt == 'V') exit(0); break; @@ -1078,7 +1078,7 @@ main(int ac, char **av) if (debug_flag) /* version_addendum is always NULL at this point */ - logit("%s, %s", SSH_RELEASE, OPENSSL_VERSION); + logit("%s, %s", SSH_RELEASE, OPENSSL_VERSION_STRING); /* Parse the configuration files */ process_config_files(host_arg, pw, 0); diff --git a/crypto/openssh/sshd.c b/crypto/openssh/sshd.c index 7eb282316cff..23d31dd1aeff 100644 --- a/crypto/openssh/sshd.c +++ b/crypto/openssh/sshd.c @@ -939,10 +939,10 @@ usage(void) if (options.version_addendum && *options.version_addendum != '\0') fprintf(stderr, "%s %s, %s\n", SSH_RELEASE, - options.version_addendum, OPENSSL_VERSION); + options.version_addendum, OPENSSL_VERSION_STRING); else fprintf(stderr, "%s, %s\n", - SSH_RELEASE, OPENSSL_VERSION); + SSH_RELEASE, OPENSSL_VERSION_STRING); fprintf(stderr, "usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n" " [-E log_file] [-f config_file] [-g login_grace_time]\n" diff --git a/crypto/openssh/version.h b/crypto/openssh/version.h index c362549551e2..e2adeeec3f33 100644 --- a/crypto/openssh/version.h +++ b/crypto/openssh/version.h @@ -9,7 +9,7 @@ #define SSH_VERSION_FREEBSD "FreeBSD-20180909" #ifdef WITH_OPENSSL -#define OPENSSL_VERSION SSLeay_version(SSLEAY_VERSION) +#define OPENSSL_VERSION_STRING SSLeay_version(SSLEAY_VERSION) #else -#define OPENSSL_VERSION "without OpenSSL" +#define OPENSSL_VERSION_STRING "without OpenSSL" #endif From 31ce875385b8aa059add44636966821d5035a60e Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 19 Sep 2018 22:53:52 +0000 Subject: [PATCH 040/139] Clear all of the VFP state in fill_fpregs(). Zero the entire FP register set structure returned for ptrace() if a thread hasn't used FP registers rather than leaking garbage in the fp_sr and fp_cr fields. Reviewed by: emaste, andrew Approved by: re (rgrimes) MFC after: 2 weeks Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D17140 --- sys/arm64/arm64/machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index dc243c958a63..e82b9e4ab0bf 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -236,7 +236,7 @@ fill_fpregs(struct thread *td, struct fpreg *regs) regs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; } else #endif - memset(regs->fp_q, 0, sizeof(regs->fp_q)); + memset(regs, 0, sizeof(*regs)); return (0); } From 232d0b87e0047b095db8103bd06ebfdf9b431d47 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 19 Sep 2018 23:45:18 +0000 Subject: [PATCH 041/139] Various fixes for floating point on RISC-V. - Explicitly load an empty initial state into FP registers when taking the fault on the first FP instruction in a thread. Setting SSTATE.FS to INITIAL is just a marker to let context switch restore code know that it can load FP registers with zeroes instead of memory loads. It does not imply that the hardware will reset all registers to zero on first access. In addition, set the state to CLEAN instead of INITIAL after the first FP instruction. cpu_switch() doesn't do anything for INITIAL and only restores from the pcb if the state is CLEAN. We could perhaps change cpu_switch to call fpe_state_clear if the state was INITIAL and leave SSTATE.FS set to INITIAL instead of CLEAN after the first FP instruction. However, adding this complexity to cpu_switch() doesn't seem worth the supposed gain. - Only save the current FPU registers in fill_fpregs() if the request is made to save the current thread's registers. Previously if a debugger requested FP registers via ptrace() it was getting a copy of the debugger's FP registers rather than the debugee's. - Zero the entire FP register set structure returned for ptrace() if a thread hasn't used FP registers rather than leaking garbage in the fp_fcsr field. - If a debugger writes FP registers via ptrace(), always mark the pcb as having valid FP registers and set SSTATUS.FS_MASK to CLEAN so that the registers will be restored when the debugged thread resumes. - Be more explicit about clearing the SSTATUS.FS field before setting it to CLEAN on the first FP instruction trap. Submitted by: br, markj Approved by: re (rgrimes) Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D17141 --- sys/riscv/include/fpe.h | 1 + sys/riscv/riscv/machdep.c | 10 ++++++-- sys/riscv/riscv/swtch.S | 53 +++++++++++++++++++++++++++++++++++++++ sys/riscv/riscv/trap.c | 7 +++++- 4 files changed, 68 insertions(+), 3 deletions(-) diff --git a/sys/riscv/include/fpe.h b/sys/riscv/include/fpe.h index 1294ab0de8fa..a519094d4272 100644 --- a/sys/riscv/include/fpe.h +++ b/sys/riscv/include/fpe.h @@ -34,5 +34,6 @@ #define _MACHINE_FPE_H_ void fpe_state_save(struct thread *td); +void fpe_state_clear(void); #endif /* !_MACHINE_FPE_H_ */ diff --git a/sys/riscv/riscv/machdep.c b/sys/riscv/riscv/machdep.c index 64d20126f3ad..430336408368 100644 --- a/sys/riscv/riscv/machdep.c +++ b/sys/riscv/riscv/machdep.c @@ -204,13 +204,14 @@ fill_fpregs(struct thread *td, struct fpreg *regs) * If we have just been running FPE instructions we will * need to save the state to memcpy it below. */ - fpe_state_save(td); + if (td == curthread) + fpe_state_save(td); memcpy(regs->fp_x, pcb->pcb_x, sizeof(regs->fp_x)); regs->fp_fcsr = pcb->pcb_fcsr; } else #endif - memset(regs->fp_x, 0, sizeof(regs->fp_x)); + memset(regs, 0, sizeof(*regs)); return (0); } @@ -219,12 +220,17 @@ int set_fpregs(struct thread *td, struct fpreg *regs) { #ifdef FPE + struct trapframe *frame; struct pcb *pcb; + frame = td->td_frame; pcb = td->td_pcb; memcpy(pcb->pcb_x, regs->fp_x, sizeof(regs->fp_x)); pcb->pcb_fcsr = regs->fp_fcsr; + pcb->pcb_fpflags |= PCB_FP_STARTED; + frame->tf_sstatus &= ~SSTATUS_FS_MASK; + frame->tf_sstatus |= SSTATUS_FS_CLEAN; #endif return (0); diff --git a/sys/riscv/riscv/swtch.S b/sys/riscv/riscv/swtch.S index b17de23ad395..8192abaf9869 100644 --- a/sys/riscv/riscv/swtch.S +++ b/sys/riscv/riscv/swtch.S @@ -153,6 +153,59 @@ ENTRY(fpe_state_save) END(fpe_state_save) #endif /* FPE */ +/* + * void + * fpe_state_clear(void) + */ +ENTRY(fpe_state_clear) + /* + * Enable FPE usage in supervisor mode, + * so we can access registers. + */ + li t0, SSTATUS_FS_INITIAL + csrs sstatus, t0 + + fscsr zero + fcvt.d.l f0, zero + fcvt.d.l f1, zero + fcvt.d.l f2, zero + fcvt.d.l f3, zero + fcvt.d.l f4, zero + fcvt.d.l f5, zero + fcvt.d.l f6, zero + fcvt.d.l f7, zero + fcvt.d.l f8, zero + fcvt.d.l f9, zero + fcvt.d.l f10, zero + fcvt.d.l f11, zero + fcvt.d.l f12, zero + fcvt.d.l f13, zero + fcvt.d.l f14, zero + fcvt.d.l f15, zero + fcvt.d.l f16, zero + fcvt.d.l f17, zero + fcvt.d.l f18, zero + fcvt.d.l f19, zero + fcvt.d.l f20, zero + fcvt.d.l f21, zero + fcvt.d.l f22, zero + fcvt.d.l f23, zero + fcvt.d.l f24, zero + fcvt.d.l f25, zero + fcvt.d.l f26, zero + fcvt.d.l f27, zero + fcvt.d.l f28, zero + fcvt.d.l f29, zero + fcvt.d.l f30, zero + fcvt.d.l f31, zero + + /* Disable FPE usage in supervisor mode. */ + li t0, SSTATUS_FS_MASK + csrc sstatus, t0 + + ret +END(fpe_state_clear) + /* * void cpu_throw(struct thread *old, struct thread *new) */ diff --git a/sys/riscv/riscv/trap.c b/sys/riscv/riscv/trap.c index ced05c52588f..57f5c558d286 100644 --- a/sys/riscv/riscv/trap.c +++ b/sys/riscv/riscv/trap.c @@ -57,6 +57,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FPE +#include +#endif #include #include #include @@ -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; } From 1f1d4007ae66645e397e325b72643166dc3c1efe Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 20 Sep 2018 07:33:14 +0000 Subject: [PATCH 042/139] import mandoc 1.14.1 --- INSTALL | 20 +-- LICENSE | 6 +- Makefile | 18 ++- Makefile.depend | 3 +- NEWS | 79 +++++++++- TODO | 109 +++++++++++-- apropos.1 | 27 +++- cgi.c | 16 +- chars.c | 170 ++++++++++---------- compat_strndup.c | 50 ++++++ configure | 117 +++++++++----- configure.local.example | 44 +++--- eqn.7 | 6 +- eqn_term.c | 28 +++- gmdiff | 19 ++- html.c | 333 +++++++++++++++------------------------- html.h | 11 +- lib.in | 24 ++- libmandoc.h | 4 +- main.c | 98 ++++++++++-- man.1 | 50 +++--- man.7 | 21 +-- man.cgi.8 | 13 +- man.conf.5 | 12 +- man_html.c | 94 +++++------- man_term.c | 25 ++- man_validate.c | 6 +- mandoc.1 | 238 +++++++++++++++------------- mandoc.c | 7 +- mandoc.css | 250 ++++++++++++++++++------------ mandoc.h | 8 +- mandoc_aux.c | 8 +- mandoc_char.7 | 136 +++++++++------- mandoc_html.3 | 100 +++--------- mandocdb.c | 160 +++++++++++-------- mansearch.c | 12 +- mdoc.7 | 66 +++++--- mdoc.c | 6 +- mdoc_html.c | 248 ++++++++++-------------------- mdoc_man.c | 29 ++-- mdoc_markdown.c | 4 +- mdoc_state.c | 25 +-- mdoc_term.c | 29 ++-- mdoc_validate.c | 108 ++++++++++--- out.h | 7 +- read.c | 45 ++++-- roff.7 | 26 +++- roff.c | 252 ++++++++++++++++++++---------- roff.h | 3 +- roff_html.c | 16 +- st.in | 88 +++++------ tag.c | 5 +- tbl.7 | 8 +- tbl_html.c | 11 +- term_ascii.c | 34 +++- term_ps.c | 120 +++++++++------ test-noop.c | 5 + test-strndup.c | 10 ++ tree.c | 12 +- 59 files changed, 2011 insertions(+), 1468 deletions(-) create mode 100644 compat_strndup.c create mode 100644 test-noop.c create mode 100644 test-strndup.c diff --git a/INSTALL b/INSTALL index d80e8e319251..558574b903de 100644 --- a/INSTALL +++ b/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/LICENSE b/LICENSE index aca7ee7a6c7e..ec7fc029d82c 100644 --- a/LICENSE +++ b/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/Makefile b/Makefile index 9855c9f8f1e8..09738579f0d2 100644 --- a/Makefile +++ b/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/Makefile.depend b/Makefile.depend index 4f5dc808823e..da366a1cd596 100644 --- a/Makefile.depend +++ b/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/NEWS b/NEWS index 3d35e2b7bdc5..3bb5b4728b99 100644 --- a/NEWS +++ b/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/TODO b/TODO index 70371a0e9e5c..6df63ea3c79b 100644 --- a/TODO +++ b/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/apropos.1 b/apropos.1 index 16cefbda375a..c0895a87e4c3 100644 --- a/apropos.1 +++ b/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: July 4 2017 $ +.Dd $Mdocdate: February 23 2018 $ .Dt APROPOS 1 .Os .Sh NAME @@ -328,6 +328,29 @@ 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 diff --git a/cgi.c b/cgi.c index 746c481ac524..8098352d6140 100644 --- a/cgi.c +++ b/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/chars.c b/chars.c index 039e6dc0909c..fb9ded8baef6 100644 --- a/chars.c +++ b/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/compat_strndup.c b/compat_strndup.c new file mode 100644 index 000000000000..5e127364f5c8 --- /dev/null +++ b/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/configure b/configure index f9416ce7399d..1ccc37dc0cdc 100755 --- a/configure +++ b/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/configure.local.example b/configure.local.example index 4a583ad0bab2..82fc2a2c28e5 100644 --- a/configure.local.example +++ b/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/eqn.7 b/eqn.7 index 33d509bd13e3..244903c56fe9 100644 --- a/eqn.7 +++ b/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/eqn_term.c b/eqn_term.c index 08f4a993eca4..669c3c56cff7 100644 --- a/eqn_term.c +++ b/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/gmdiff b/gmdiff index d5b1f2a76f01..65cf353daa0c 100644 --- a/gmdiff +++ b/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/html.c b/html.c index fc55e881b784..70935dcd57e4 100644 --- a/html.c +++ b/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/html.h b/html.h index c727eacf5d09..6d44a47383a7 100644 --- a/html.h +++ b/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/lib.in b/lib.in index 8b03df2ed3ec..2e217ee77da4 100644 --- a/lib.in +++ b/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> @@ -24,26 +24,31 @@ * Be sure to escape strings. */ +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("libbluetooth", "Bluetooth Library (libbluetooth, \\-lbluetooth)") LINE("libbsdxml", "eXpat XML parser library (libbsdxml, \\-lbsdxml)") -LINE("libbsm", "Basic Security Module User Library (libbsm, \\-lbsm)") -LINE("libc", "Standard C Library (libc, \\-lc)") +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)") LINE("libcalendar", "Calendar Arithmetic Library (libcalendar, \\-lcalendar)") LINE("libcam", "Common Access Method User Library (libcam, \\-lcam)") +LINE("libcasper", "Casper Library (libcasper, \\-lcasper)") LINE("libcdk", "Curses Development Kit Library (libcdk, \\-lcdk)") LINE("libcipher", "FreeSec Crypt Library (libcipher, \\-lcipher)") LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)") LINE("libcrypt", "Crypt Library (libcrypt, \\-lcrypt)") LINE("libcurses", "Curses Library (libcurses, \\-lcurses)") +LINE("libcuse", "Userland Character Device Library (libcuse, \\-lcuse)") LINE("libdevattr", "Device attribute and event library (libdevattr, \\-ldevattr)") +LINE("libdevctl", "Device Control Library (libdevctl, \\-ldevctl)") LINE("libdevinfo", "Device and Resource Information Utility Library (libdevinfo, \\-ldevinfo)") LINE("libdevstat", "Device Statistics Library (libdevstat, \\-ldevstat)") LINE("libdisk", "Interface to Slice and Partition Labels Library (libdisk, \\-ldisk)") +LINE("libdl", "Dynamic Linker Services Filter (libdl, \\-ldl)") LINE("libdm", "Device Mapper Library (libdm, \\-ldm)") LINE("libdwarf", "DWARF Access Library (libdwarf, \\-ldwarf)") LINE("libedit", "Command Line Editor Library (libedit, \\-ledit)") @@ -56,12 +61,11 @@ LINE("libfsid", "Filesystem Identification Library (libfsid, \\-lfsid)") LINE("libftpio", "FTP Connection Management Library (libftpio, \\-lftpio)") LINE("libform", "Curses Form Library (libform, \\-lform)") LINE("libgeom", "Userland API Library for Kernel GEOM subsystem (libgeom, \\-lgeom)") -LINE("libgpib", "General-Purpose Instrument Bus (GPIB) library (libgpib, \\-lgpib)") +LINE("libgpio", "General-Purpose Input Output (GPIO) library (libgpio, \\-lgpio)") LINE("libhammer", "HAMMER Filesystem Userland Library (libhammer, \\-lhammer)") LINE("libi386", "i386 Architecture Library (libi386, \\-li386)") LINE("libintl", "Internationalized Message Handling Library (libintl, \\-lintl)") LINE("libipsec", "IPsec Policy Control Library (libipsec, \\-lipsec)") -LINE("libipx", "IPX Address Conversion Support Library (libipx, \\-lipx)") LINE("libiscsi", "iSCSI protocol library (libiscsi, \\-liscsi)") LINE("libisns", "Internet Storage Name Service Library (libisns, \\-lisns)") LINE("libjail", "Jail Library (libjail, \\-ljail)") @@ -81,17 +85,19 @@ LINE("libnetgraph", "Netgraph User Library (libnetgraph, \\-lnetgraph)") LINE("libnetpgp", "Netpgp Signing, Verification, Encryption and Decryption (libnetpgp, \\-lnetpgp)") LINE("libnetpgpverify", "Netpgp Verification (libnetpgpverify, \\-lnetpgpverify)") LINE("libnpf", "NPF Packet Filter Library (libnpf, \\-lnpf)") +LINE("libnv", "Name/value pairs library (libnv, \\-lnv)") LINE("libossaudio", "OSS Audio Emulation Library (libossaudio, \\-lossaudio)") LINE("libpam", "Pluggable Authentication Module Library (libpam, \\-lpam)") LINE("libpanel", "Z-order for curses windows (libpanel, \\-lpanel)") -LINE("libpcap", "Capture Library (libpcap, \\-lpcap)") +LINE("libpcap", "Packet capture Library (libpcap, \\-lpcap)") LINE("libpci", "PCI Bus Access Library (libpci, \\-lpci)") LINE("libpmc", "Performance Counters Library (libpmc, \\-lpmc)") LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)") LINE("libposix", "POSIX Compatibility Library (libposix, \\-lposix)") LINE("libposix1e", "POSIX.1e Security API Library (libposix1e, \\-lposix1e)") LINE("libppath", "Property-List Paths Library (libppath, \\-lppath)") -LINE("libproc", "Process Manipulation Library (libproc, \\-lproc)") +LINE("libproc", "Processor Monitoring and Analysis Library (libproc, \\-lproc)") +LINE("libprocstat", "Process and Files Information Retrieval (libprocstat, \\-lprocstat)") LINE("libprop", "Property Container Object Library (libprop, \\-lprop)") LINE("libpthread", "POSIX Threads Library (libpthread, \\-lpthread)") LINE("libpthread_dbg", "POSIX Debug Threads Library (libpthread_dbg, \\-lpthread_dbg)") @@ -106,10 +112,13 @@ LINE("librt", "POSIX Real\\-time Library (librt, \\-lrt)") LINE("librtld_db", "Debugging interface to the runtime linker Library (librtld_db, \\-lrtld_db)") LINE("librumpclient", "Clientside Stubs for rump Kernel Remote Protocols (librumpclient, \\-lrumpclient)") LINE("libsaslc", "Simple Authentication and Security Layer client library (libsaslc, \\-lsaslc)") +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("libstand", "Standalone Applications Library (libstand, \\-lstand)") +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)") LINE("libtcplay", "TrueCrypt-compatible API library (libtcplay, \\-ltcplay)") LINE("libtermcap", "Termcap Access Library (libtermcap, \\-ltermcap)") @@ -122,4 +131,5 @@ LINE("libusbhid", "USB Human Interface Devices Library (libusbhid, \\-lusbhid)") LINE("libutil", "System Utilities Library (libutil, \\-lutil)") LINE("libvgl", "Video Graphics Library (libvgl, \\-lvgl)") LINE("libx86_64", "x86_64 Architecture Library (libx86_64, \\-lx86_64)") +LINE("libxo", "Text, XML, JSON, and HTML Output Emission Library (libxo, \\-lxo)") LINE("libz", "Compression Library (libz, \\-lz)") diff --git a/libmandoc.h b/libmandoc.h index 2cf076286177..9cc8cce4ecca 100644 --- a/libmandoc.h +++ b/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/main.c b/main.c index 7f1411a6fbcc..600bc9bb4bef 100644 --- a/main.c +++ b/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,7 +19,9 @@ #include "config.h" #include <sys/types.h> +#include <sys/ioctl.h> #include <sys/param.h> /* MACHINE */ +#include <sys/termios.h> #include <sys/wait.h> #include <assert.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/man.1 b/man.1 index 075497acab9d..cf03693ee981 100644 --- a/man.1 +++ b/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: May 17 2017 $ +.Dd $Mdocdate: April 19 2018 $ .Dt MAN 1 .Os .Sh NAME @@ -78,6 +78,18 @@ Copy the manual page to the standard output instead of using .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 @@ -285,11 +298,6 @@ If neither PAGER nor MANPAGER is defined, .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/man.7 b/man.7 index 570e7ac3bdcd..d418b9ee76ca 100644 --- a/man.7 +++ b/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/man.cgi.8 b/man.cgi.8 index eba3cec45a8a..b8cd623c598d 100644 --- a/man.cgi.8 +++ b/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/man.conf.5 b/man.conf.5 index 425895c1dc8a..be0998087d17 100644 --- a/man.conf.5 +++ b/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/man_html.c b/man_html.c index a304b3e4d240..ae5dac1ad938 100644 --- a/man_html.c +++ b/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/man_term.c b/man_term.c index 8946a05067a7..b5723ccf8383 100644 --- a/man_term.c +++ b/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/man_validate.c b/man_validate.c index b3356ccb3d3f..d6c51af5255c 100644 --- a/man_validate.c +++ b/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/mandoc.1 b/mandoc.1 index 1db4d3251f45..76b3cda5a704 100644 --- a/mandoc.1 +++ b/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: July 20 2017 $ +.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 @@ -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,6 +571,13 @@ 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 @@ -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/mandoc.c b/mandoc.c index 3e16d2c64fbc..1279b52ed50f 100644 --- a/mandoc.c +++ b/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/mandoc.css b/mandoc.css index 2a57a18f9d69..c93bc22a2d14 100644 --- a/mandoc.css +++ b/mandoc.css @@ -1,11 +1,11 @@ -/* $Id: mandoc.css,v 1.22 2017/07/16 18:45:00 schwarze Exp $ */ +/* $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: 100ex; } +html { max-width: 65em; } body { font-family: Helvetica,Arial,sans-serif; } table { margin-top: 0em; margin-bottom: 0em; } @@ -14,7 +14,7 @@ ul, ol, dl { margin-top: 0em; margin-bottom: 0em; } li, dt { margin-top: 1em; } -a.selflink { border-bottom: thin dotted; +.permalink { border-bottom: thin dotted; color: inherit; font: inherit; text-decoration: inherit; } @@ -41,7 +41,6 @@ table.head { width: 100%; td.head-vol { text-align: center; } td.head-rtitle { text-align: right; } -span.Nd { } table.foot { width: 100%; border-top: 1px dotted #808080; @@ -51,147 +50,182 @@ 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; +.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%; } -h2.Ss { margin-top: 2ex; - margin-bottom: 1ex; - margin-left: -2ex; +.Ss { margin-top: 1.2em; + margin-bottom: 0.6em; + margin-left: -1.2em; font-size: 105%; } -div.Pp { margin: 1ex 0ex; } -a.Sx { } -a.Xr { } +.Pp { margin: 0.6em 0em; } +.Sx { } +.Xr { } /* Displays and lists. */ -div.Bd { } -div.D1 { margin-left: 5ex; } +.Bd { } +.Bd-indent { margin-left: 3.8em; } -ul.Bl-bullet { list-style-type: disc; +.Bl-bullet { list-style-type: disc; padding-left: 1em; } -li.It-bullet { } -ul.Bl-dash { list-style-type: none; +.Bl-bullet > li { } +.Bl-dash { list-style-type: none; padding-left: 0em; } -li.It-dash:before { +.Bl-dash > li:before { content: "\2014 "; } -ul.Bl-item { list-style-type: none; +.Bl-item { list-style-type: none; padding-left: 0em; } -li.It-item { } -ul.Bl-compact > li { - margin-top: 0ex; } +.Bl-item > li { } +.Bl-compact > li { + margin-top: 0em; } -ol.Bl-enum { padding-left: 2em; } -li.It-enum { } -ol.Bl-compact > li { - margin-top: 0ex; } +.Bl-enum { padding-left: 2em; } +.Bl-enum > li { } +.Bl-compact > li { + margin-top: 0em; } -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; +.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; } -dd.It-tag { clear: right; +.Bl-tag > dd { + clear: right; width: 100%; - margin-top: 0ex; - margin-left: 0ex; + margin-top: 0em; + margin-left: 0em; vertical-align: top; overflow: auto; } -dl.Bl-compact > dt { - margin-top: 0ex; } +.Bl-compact > dt { + margin-top: 0em; } -table.Bl-column { } -tr.It-column { } -td.It-column { margin-top: 1em; } -table.Bl-compact > tbody > tr > td { - margin-top: 0ex; } +.Bl-column { } +.Bl-column > tbody > tr { } +.Bl-column > tbody > tr > td { + margin-top: 1em; } +.Bl-compact > tbody > tr > td { + margin-top: 0em; } -cite.Rs { font-style: normal; +.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 { } +.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 { } -span.eqn { } -table.tbl { } +.eqn { } +.tbl { } + +.HP { margin-left: 3.8em; + text-indent: -3.8em; } /* 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; +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; } -span.Op { } -b.Ic { font-style: normal; } -code.Ev { font-style: normal; +.Op { display: inline; } +.Ic { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ev { font-style: normal; font-weight: normal; font-family: monospace; } -i.Pa { font-weight: normal; } +.Pa { font-style: italic; + font-weight: normal; } /* Semantic markup for function libraries. */ -span.Lb { } -b.In { font-style: normal; } +.Lb { } +code.In { font-style: normal; + font-weight: bold; + font-family: inherit; } a.In { } -b.Fd { font-style: normal; } -var.Ft { font-style: italic; +.Fd { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Ft { font-style: italic; font-weight: normal; } -b.Fn { font-style: normal; } -var.Fa { font-style: italic; +.Fn { font-style: normal; + font-weight: bold; + font-family: inherit; } +.Fa { font-style: italic; font-weight: normal; } -var.Vt { font-style: italic; +.Vt { font-style: italic; font-weight: normal; } -var.Va { font-style: italic; +.Va { font-style: italic; font-weight: normal; } -code.Dv { font-style: normal; +.Dv { font-style: normal; font-weight: normal; font-family: monospace; } -code.Er { font-style: normal; +.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 { } +.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; @@ -201,3 +235,19 @@ a.Ux { } .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/mandoc.h b/mandoc.h index b234cb5ee136..dbc266cc3b06 100644 --- a/mandoc.h +++ b/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/mandoc_aux.c b/mandoc_aux.c index db593e444c48..5d595ce0c292 100644 --- a/mandoc_aux.c +++ b/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/mandoc_char.7 b/mandoc_char.7 index a372b3e91dfc..f63cdaea8fcc 100644 --- a/mandoc_char.7 +++ b/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/mandoc_html.3 b/mandoc_html.3 index ba25e0ad6a7d..5bd9446da824 100644 --- a/mandoc_html.3 +++ b/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/mandocdb.c b/mandocdb.c index 26117cf82781..86dbce2d9fe6 100644 --- a/mandocdb.c +++ b/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/mansearch.c b/mansearch.c index 0d60c3bed731..784c17bee714 100644 --- a/mansearch.c +++ b/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/mdoc.7 b/mdoc.7 index 5a1863c8a43b..5c07434cd80e 100644 --- a/mdoc.7 +++ b/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: July 20 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 diff --git a/mdoc.c b/mdoc.c index 7afcc5d29e1c..71803531ddfb 100644 --- a/mdoc.c +++ b/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/mdoc_html.c b/mdoc_html.c index 0b4b9adf34f2..f50de8a77af0 100644 --- a/mdoc_html.c +++ b/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/mdoc_man.c b/mdoc_man.c index cf552ce902bb..bcf9207f79cc 100644 --- a/mdoc_man.c +++ b/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/mdoc_markdown.c b/mdoc_markdown.c index 0b0f184821e5..e73440a4e5cd 100644 --- a/mdoc_markdown.c +++ b/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/mdoc_state.c b/mdoc_state.c index d9cad18b1052..2d8563f5bf16 100644 --- a/mdoc_state.c +++ b/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/mdoc_term.c b/mdoc_term.c index 4e420c5c2114..cf3e7ef3dd64 100644 --- a/mdoc_term.c +++ b/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/mdoc_validate.c b/mdoc_validate.c index 3a9b86f3fd2b..b36d3c0a926c 100644 --- a/mdoc_validate.c +++ b/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/out.h b/out.h index f6aceb9c13f4..9f0a541d5dfd 100644 --- a/out.h +++ b/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/read.c b/read.c index 1af1b2836383..0a583445f2cd 100644 --- a/read.c +++ b/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/roff.7 b/roff.7 index 74780e9a7704..8cb922c70676 100644 --- a/roff.7 +++ b/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/roff.c b/roff.c index e2e498da0ce4..86e145e36685 100644 --- a/roff.c +++ b/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/roff.h b/roff.h index 8b28d5960974..f0da74bd9ac6 100644 --- a/roff.h +++ b/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/roff_html.c b/roff_html.c index 53ae6d7ca2d0..6a06c0d8789d 100644 --- a/roff_html.c +++ b/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/st.in b/st.in index 6087c768fbf8..557a70d10db9 100644 --- a/st.in +++ b/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> * @@ -28,49 +28,49 @@ * REMEMBER TO ADD NEW STANDARDS TO MDOC.7! */ -LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1", "IEEE Std 1003.1 (\\(LqPOSIX.1\\(Rq)") -LINE("-p1003.1b", "IEEE Std 1003.1b (\\(LqPOSIX.1b\\(Rq)") -LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(LqPOSIX.1b\\(Rq)") -LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(LqPOSIX.1c\\(Rq)") -LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(LqPOSIX.1g\\(Rq)") -LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(LqPOSIX.1i\\(Rq)") -LINE("-p1003.2", "IEEE Std 1003.2 (\\(LqPOSIX.2\\(Rq)") -LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(LqPOSIX.2\\(Rq)") -LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(LqPOSIX.2\\(Rq)") -LINE("-isoC", "ISO/IEC 9899:1990 (\\(LqISO\\~C90\\(Rq)") -LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(LqISO\\~C90\\(Rq)") -LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(LqISO\\~C90, Amendment 1\\(Rq)") -LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(LqISO\\~C90, Technical Corrigendum 1\\(Rq)") -LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(LqISO\\~C90, Technical Corrigendum 2\\(Rq)") -LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(LqISO\\~C99\\(Rq)") -LINE("-isoC-2011", "ISO/IEC 9899:2011 (\\(LqISO\\~C11\\(Rq)") -LINE("-iso9945-1-90", "ISO/IEC 9945-1:1990 (\\(LqPOSIX.1\\(Rq)") -LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(LqPOSIX.1\\(Rq)") -LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(LqPOSIX.2\\(Rq)") -LINE("-ansiC", "ANSI X3.159-1989 (\\(LqANSI\\~C89\\(Rq)") -LINE("-ansiC-89", "ANSI X3.159-1989 (\\(LqANSI\\~C89\\(Rq)") +LINE("-p1003.1-88", "IEEE Std 1003.1-1988 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1-90", "IEEE Std 1003.1-1990 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1-2001", "IEEE Std 1003.1-2001 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1-2004", "IEEE Std 1003.1-2004 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1-2008", "IEEE Std 1003.1-2008 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1", "IEEE Std 1003.1 (\\(lqPOSIX.1\\(rq)") +LINE("-p1003.1b", "IEEE Std 1003.1b (\\(lqPOSIX.1b\\(rq)") +LINE("-p1003.1b-93", "IEEE Std 1003.1b-1993 (\\(lqPOSIX.1b\\(rq)") +LINE("-p1003.1c-95", "IEEE Std 1003.1c-1995 (\\(lqPOSIX.1c\\(rq)") +LINE("-p1003.1g-2000", "IEEE Std 1003.1g-2000 (\\(lqPOSIX.1g\\(rq)") +LINE("-p1003.1i-95", "IEEE Std 1003.1i-1995 (\\(lqPOSIX.1i\\(rq)") +LINE("-p1003.2", "IEEE Std 1003.2 (\\(lqPOSIX.2\\(rq)") +LINE("-p1003.2-92", "IEEE Std 1003.2-1992 (\\(lqPOSIX.2\\(rq)") +LINE("-p1003.2a-92", "IEEE Std 1003.2a-1992 (\\(lqPOSIX.2\\(rq)") +LINE("-isoC", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)") +LINE("-isoC-90", "ISO/IEC 9899:1990 (\\(lqISO\\~C90\\(rq)") +LINE("-isoC-amd1", "ISO/IEC 9899/AMD1:1995 (\\(lqISO\\~C90, Amendment 1\\(rq)") +LINE("-isoC-tcor1", "ISO/IEC 9899/TCOR1:1994 (\\(lqISO\\~C90, Technical Corrigendum 1\\(rq)") +LINE("-isoC-tcor2", "ISO/IEC 9899/TCOR2:1995 (\\(lqISO\\~C90, Technical Corrigendum 2\\(rq)") +LINE("-isoC-99", "ISO/IEC 9899:1999 (\\(lqISO\\~C99\\(rq)") +LINE("-isoC-2011", "ISO/IEC 9899:2011 (\\(lqISO\\~C11\\(rq)") +LINE("-iso9945-1-90", "ISO/IEC 9945-1:1990 (\\(lqPOSIX.1\\(rq)") +LINE("-iso9945-1-96", "ISO/IEC 9945-1:1996 (\\(lqPOSIX.1\\(rq)") +LINE("-iso9945-2-93", "ISO/IEC 9945-2:1993 (\\(lqPOSIX.2\\(rq)") +LINE("-ansiC", "ANSI X3.159-1989 (\\(lqANSI\\~C89\\(rq)") +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/tag.c b/tag.c index 21ac6b32e4d3..c0832c4f74b7 100644 --- a/tag.c +++ b/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/tbl.7 b/tbl.7 index e2f84538370b..3883b40904ee 100644 --- a/tbl.7 +++ b/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/tbl_html.c b/tbl_html.c index d59f1635d013..b87804fda354 100644 --- a/tbl_html.c +++ b/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/term_ascii.c b/term_ascii.c index e819c0ef8a86..f47ffd75d9c3 100644 --- a/term_ascii.c +++ b/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/term_ps.c b/term_ps.c index 9638ae4cb9a3..2cd94c923156 100644 --- a/term_ps.c +++ b/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/test-noop.c b/test-noop.c new file mode 100644 index 000000000000..95485db80176 --- /dev/null +++ b/test-noop.c @@ -0,0 +1,5 @@ +int +main(void) +{ + return 0; +} diff --git a/test-strndup.c b/test-strndup.c new file mode 100644 index 000000000000..82e4e547e097 --- /dev/null +++ b/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/tree.c b/tree.c index 7d18b9d9e686..b9774e1cd8e1 100644 --- a/tree.c +++ b/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: From 80994f8119b0ad74049cd6ebc79fa569e447d2b0 Mon Sep 17 00:00:00 2001 From: Brad Davis <brd@FreeBSD.org> Date: Thu, 20 Sep 2018 09:21:05 +0000 Subject: [PATCH 043/139] Move hosts.lpd and printcap to usr.sbin/lpr/lpd/ This leverages CONFS to handle the install Approved by: re (blanket, pkgbase), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17238 --- etc/Makefile | 4 ---- usr.sbin/lpr/lpd/Makefile | 1 + {etc => usr.sbin/lpr/lpd}/hosts.lpd | 0 {etc => usr.sbin/lpr/lpd}/printcap | 0 4 files changed, 1 insertion(+), 4 deletions(-) rename {etc => usr.sbin/lpr/lpd}/hosts.lpd (100%) rename {etc => usr.sbin/lpr/lpd}/printcap (100%) diff --git a/etc/Makefile b/etc/Makefile index a76b61cbb658..8c55699d5624 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -22,10 +22,6 @@ BIN1= \ # NB: keep these sorted by MK_* knobs -.if ${MK_LPR} != "no" -BIN1+= hosts.lpd printcap -.endif - .if ${MK_OPENSSL} != "no" SSL= ${SRCTOP}/crypto/openssl/apps/openssl.cnf .endif diff --git a/usr.sbin/lpr/lpd/Makefile b/usr.sbin/lpr/lpd/Makefile index af2582c4bb1c..6a152c46268f 100644 --- a/usr.sbin/lpr/lpd/Makefile +++ b/usr.sbin/lpr/lpd/Makefile @@ -1,6 +1,7 @@ # From: @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +CONFS= hosts.lpd printcap PROG= lpd MAN= lpd.8 SRCS= lpd.c printjob.c recvjob.c lpdchar.c modes.c diff --git a/etc/hosts.lpd b/usr.sbin/lpr/lpd/hosts.lpd similarity index 100% rename from etc/hosts.lpd rename to usr.sbin/lpr/lpd/hosts.lpd diff --git a/etc/printcap b/usr.sbin/lpr/lpd/printcap similarity index 100% rename from etc/printcap rename to usr.sbin/lpr/lpd/printcap From 6999b78550143f7c17eeea04cc87f08cfd72fae8 Mon Sep 17 00:00:00 2001 From: Brad Davis <brd@FreeBSD.org> Date: Thu, 20 Sep 2018 09:26:10 +0000 Subject: [PATCH 044/139] Move opieaccess to lib/libopie/ This leverages CONFS to do the install Approved by: re (blanket, pkgbase), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17241 --- etc/Makefile | 4 ++-- lib/libopie/Makefile | 3 +++ {etc => lib/libopie}/opieaccess | 0 3 files changed, 5 insertions(+), 2 deletions(-) rename {etc => lib/libopie}/opieaccess (100%) diff --git a/etc/Makefile b/etc/Makefile index 8c55699d5624..75a745f7b865 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -70,7 +70,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 nsmb.conf ${DESTDIR}/etc; .if ${MK_TCSH} == "no" sed -i "" -e 's;/bin/csh;/bin/sh;' ${DESTDIR}/etc/master.passwd @@ -206,7 +206,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} nsmb.conf \ ${DESTDIR}${SHAREDIR}/examples/etc .include <bsd.prog.mk> diff --git a/lib/libopie/Makefile b/lib/libopie/Makefile index 4507d252ea9a..2dda575e94ef 100644 --- a/lib/libopie/Makefile +++ b/lib/libopie/Makefile @@ -2,6 +2,9 @@ # # $FreeBSD$ # + +CONFS= opieaccess +CONFSMODE= 600 PACKAGE=lib${LIB} OPIE_DIST?= ${SRCTOP}/contrib/opie DIST_DIR= ${OPIE_DIST}/${.CURDIR:T} diff --git a/etc/opieaccess b/lib/libopie/opieaccess similarity index 100% rename from etc/opieaccess rename to lib/libopie/opieaccess From 27e35a09ef24d9f90a3a719d6a2fd8544fce1dba Mon Sep 17 00:00:00 2001 From: Brad Davis <brd@FreeBSD.org> Date: Thu, 20 Sep 2018 09:31:27 +0000 Subject: [PATCH 045/139] Move nsmb.conf to lib/libsmb/ This leverages CONFS to do the install Approved by: re (pkgbase, blanket), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17243 --- etc/Makefile | 4 ++-- lib/libsmb/Makefile | 2 ++ {etc => lib/libsmb}/nsmb.conf | 0 3 files changed, 4 insertions(+), 2 deletions(-) rename {etc => lib/libsmb}/nsmb.conf (100%) diff --git a/etc/Makefile b/etc/Makefile index 75a745f7b865..22339c58517e 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -70,7 +70,7 @@ distribution: ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 644 \ ${BIN1} ${DESTDIR}/etc; \ ${INSTALL} -o ${BINOWN} -g ${BINGRP} -m 600 \ - master.passwd nsmb.conf ${DESTDIR}/etc; + master.passwd ${DESTDIR}/etc; .if ${MK_TCSH} == "no" sed -i "" -e 's;/bin/csh;/bin/sh;' ${DESTDIR}/etc/master.passwd @@ -206,7 +206,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 \ + ${BIN1} ${BIN2} \ ${DESTDIR}${SHAREDIR}/examples/etc .include <bsd.prog.mk> diff --git a/lib/libsmb/Makefile b/lib/libsmb/Makefile index 519db5ff9465..3c310819f876 100644 --- a/lib/libsmb/Makefile +++ b/lib/libsmb/Makefile @@ -2,6 +2,8 @@ .include <src.opts.mk> +CONFS= nsmb.conf +CONFSMODE= 600 PACKAGE=lib${LIB} CONTRIBDIR= ${SRCTOP}/contrib/smbfs .PATH: ${CONTRIBDIR}/lib/smb diff --git a/etc/nsmb.conf b/lib/libsmb/nsmb.conf similarity index 100% rename from etc/nsmb.conf rename to lib/libsmb/nsmb.conf From d465a4b0b320af2d6a3d09ad792f9b84fe2707f3 Mon Sep 17 00:00:00 2001 From: Brad Davis <brd@FreeBSD.org> Date: Thu, 20 Sep 2018 09:34:55 +0000 Subject: [PATCH 046/139] Move the openssl.cnf install to secure/usr.bin/openssl/ This leverages CONFS to do the install Approved by: re (pkgbase, blanket), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17245 --- etc/Makefile | 8 -------- secure/usr.bin/openssl/Makefile | 2 ++ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/etc/Makefile b/etc/Makefile index 22339c58517e..040849654cfa 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -22,10 +22,6 @@ BIN1= \ # NB: keep these sorted by MK_* knobs -.if ${MK_OPENSSL} != "no" -SSL= ${SRCTOP}/crypto/openssl/apps/openssl.cnf -.endif - .if ${MK_SENDMAIL} != "no" BIN1+= rc.sendmail .endif @@ -95,10 +91,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 \ diff --git a/secure/usr.bin/openssl/Makefile b/secure/usr.bin/openssl/Makefile index fad775faab5f..d7d38f0742dc 100644 --- a/secure/usr.bin/openssl/Makefile +++ b/secure/usr.bin/openssl/Makefile @@ -1,5 +1,7 @@ # $FreeBSD$ +CONFS= openssl.cnf +CONFSDIR= /etc/ssl PROG= openssl LIBADD= ssl crypto From a286a3099c87bf015063bac0f10cec70b261fac7 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 20 Sep 2018 13:29:43 +0000 Subject: [PATCH 047/139] amd64: move fusufault after all users A lot of function have the following check: cmpq %rax,%rdi /* verify address is valid */ ja fusufault The label is present earlier in kernel .text, which means this is a jump backwards. Absent any information in branch predictor, the cpu predicts it as taken. Since it is almost never taken in practice, this results in a completely avoidable misprediction. Move it past all consumers, so that it is predicted as not taken. Approved by: re (kib) --- sys/amd64/amd64/support.S | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index bc849b21d965..33ffec1ff5f9 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -755,16 +755,6 @@ ENTRY(fubyte_smap) ret END(fubyte_smap) - ALIGN_TEXT - /* Fault entry clears PSL.AC */ -fusufault: - movq PCPU(CURPCB),%rcx - xorl %eax,%eax - movq %rax,PCB_ONFAULT(%rcx) - decq %rax - POP_FRAME_POINTER - ret - /* * Store a 64-bit word, a 32-bit word, a 16-bit word, or an 8-bit byte to * user memory. @@ -916,6 +906,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 From 51e13c93b6ef3be997aa3b0f5247dbaddbbd45f5 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 20 Sep 2018 13:32:40 +0000 Subject: [PATCH 048/139] fd: prevent inlining of _fdrop thorough kern_descrip.c fdrop is used in several places in the file and almost never has to call _fdrop. Thus inlining it is a pure waste of space. Approved by: re (kib) --- sys/kern/kern_descrip.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index ca1f7326fe3f..08a704d904b1 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2936,8 +2936,11 @@ fgetvp_write(struct thread *td, int fd, cap_rights_t *rightsp, /* * Handle the last reference to a file being closed. + * + * Without the noinline attribute clang keeps inlining the func thorough this + * file when fdrop is used. */ -int +int __noinline _fdrop(struct file *fp, struct thread *td) { int error; From 25ed23cfbb9200f1dd96a70e74a8e3e282635557 Mon Sep 17 00:00:00 2001 From: Mark Johnston <markj@FreeBSD.org> Date: Thu, 20 Sep 2018 15:45:12 +0000 Subject: [PATCH 049/139] Change the domain selection policy in kmem_back(). Ensure that pages backing the same virtual large page come from the same physical domain, as kmem_malloc_domain() does. PR: 231038 Reviewed by: alc, kib Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17248 --- sys/vm/vm_kern.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 31b85fd81854..5f7c4033c218 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -122,11 +122,12 @@ SYSCTL_ULONG(_vm, OID_AUTO, max_kernel_address, CTLFLAG_RD, "Max kernel address"); #if VM_NRESERVLEVEL > 0 -#define KVA_QUANTUM (1 << (VM_LEVEL_0_ORDER + PAGE_SHIFT)) +#define KVA_QUANTUM_SHIFT (VM_LEVEL_0_ORDER + PAGE_SHIFT) #else /* On non-superpage architectures want large import sizes. */ -#define KVA_QUANTUM (PAGE_SIZE * 1024) +#define KVA_QUANTUM_SHIFT (10 + PAGE_SHIFT) #endif +#define KVA_QUANTUM (1 << KVA_QUANTUM_SHIFT) /* * kva_alloc: @@ -416,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, @@ -479,24 +481,39 @@ kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr, return (KERN_SUCCESS); } +/* + * kmem_back: + * + * Allocate physical pages for the specified virtual address range. + */ int kmem_back(vm_object_t object, vm_offset_t addr, vm_size_t size, int flags) { - struct vm_domainset_iter di; - int domain; - int ret; + vm_offset_t end, next, start; + int domain, rv; KASSERT(object == kernel_object, ("kmem_back: only supports kernel object.")); - vm_domainset_iter_malloc_init(&di, kernel_object, &domain, &flags); - do { - ret = kmem_back_domain(domain, object, addr, size, flags); - if (ret == KERN_SUCCESS) + for (start = addr, end = addr + size; addr < end; addr = next) { + /* + * We must ensure that pages backing a given large virtual page + * all come from the same physical domain. + */ + if (vm_ndomains > 1) { + domain = (addr >> KVA_QUANTUM_SHIFT) % vm_ndomains; + next = roundup2(addr + 1, KVA_QUANTUM); + if (next > end || next < start) + next = end; + } else + 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); } /* From 6675bee81a93be9833b47c3f4ceda9a643636579 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" <bz@FreeBSD.org> Date: Thu, 20 Sep 2018 15:45:53 +0000 Subject: [PATCH 050/139] In icmp6_rip6_input(), once we have a lock, make sure the inp is not freed. This can happen since the list traversal and locking was converted to epoch(9). If the inp is marked "freed", skip it. This prevents a NULL pointer deref panic in ip6_savecontrol_v4() trying to access the socket hanging off the inp, which was gone by the time we got there. Reported by: andrew Tested by: andrew Approved by: re (gjb) --- sys/netinet6/icmp6.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 0bb5636602ff..93cbfe66140b 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1936,6 +1936,10 @@ icmp6_rip6_input(struct mbuf **mp, int off) !IN6_ARE_ADDR_EQUAL(&in6p->in6p_faddr, &ip6->ip6_src)) continue; INP_RLOCK(in6p); + if (__predict_false(in6p->inp_flags2 & INP_FREED)) { + INP_RUNLOCK(in6p); + continue; + } if (ICMP6_FILTER_WILLBLOCK(icmp6->icmp6_type, in6p->in6p_icmp6filt)) { INP_RUNLOCK(in6p); From 33a5ef35871ac9c19afafc9dfe4cf5901236e618 Mon Sep 17 00:00:00 2001 From: Mark Johnston <markj@FreeBSD.org> Date: Thu, 20 Sep 2018 16:37:50 +0000 Subject: [PATCH 051/139] Fix variable name typo in the bsdinstall ttys hardening code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submitted by: Jörg Pernfuß <code.jpe@gmail.com> Reviewed by: allanjude, dab, emaste Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D12476 --- usr.sbin/bsdinstall/scripts/config | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/usr.sbin/bsdinstall/scripts/config b/usr.sbin/bsdinstall/scripts/config index 501430359030..d2abb5671fcb 100755 --- a/usr.sbin/bsdinstall/scripts/config +++ b/usr.sbin/bsdinstall/scripts/config @@ -35,9 +35,9 @@ rm $BSDINSTALL_TMPETC/rc.conf.* cat $BSDINSTALL_CHROOT/etc/sysctl.conf $BSDINSTALL_TMPETC/sysctl.conf.* >> $BSDINSTALL_TMPETC/sysctl.conf rm $BSDINSTALL_TMPETC/sysctl.conf.* -if [ -f $BSDINSTALL_TMPTEC/ttys.hardening ]; then - cat $BSDINSTALL_TMPTEC/ttys.hardening > $BSDINSTALL_TMPTEC/ttys - rm $BSDINSTALL_TMPTEC/ttys.hardening +if [ -f $BSDINSTALL_TMPETC/ttys.hardening ]; then + cat $BSDINSTALL_TMPETC/ttys.hardening > $BSDINSTALL_TMPETC/ttys + rm $BSDINSTALL_TMPETC/ttys.hardening fi cp $BSDINSTALL_TMPETC/* $BSDINSTALL_CHROOT/etc From 7049547cd3bb0b2b3eac3267de2ed47f2f58ff1d Mon Sep 17 00:00:00 2001 From: Stephen Hurd <shurd@FreeBSD.org> Date: Thu, 20 Sep 2018 18:24:32 +0000 Subject: [PATCH 052/139] Add iflib.4 manpage The new manpage documents the tunables and statistic sysctls exposed by iflib. Reviewed by: bcr Approved by: re (gjb) Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D16920 --- share/man/man4/Makefile | 1 + share/man/man4/bnxt.4 | 4 +- share/man/man4/em.4 | 3 +- share/man/man4/iflib.4 | 195 ++++++++++++++++++++++++++++++++++++++++ share/man/man9/iflib.9 | 3 +- 5 files changed, 202 insertions(+), 4 deletions(-) create mode 100644 share/man/man4/iflib.4 diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index c40e47c8ffaf..3a6738a2ef42 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -202,6 +202,7 @@ MAN= aac.4 \ icmp6.4 \ ida.4 \ if_ipsec.4 \ + iflib.4 \ ifmib.4 \ ig4.4 \ igmp.4 \ diff --git a/share/man/man4/bnxt.4 b/share/man/man4/bnxt.4 index 20cc3b83b0ef..12c2f9a0626a 100644 --- a/share/man/man4/bnxt.4 +++ b/share/man/man4/bnxt.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 9, 2017 +.Dd September 20, 2018 .Dt BNXT 4 .Os .Sh NAME @@ -110,7 +110,7 @@ These variables must be set before loading the driver, either via or through the use of .Xr kenv 1 . These are provided by the -.Xr iflib 9 +.Xr iflib 4 framework, and might be better documented there. .Bl -tag -width indent .It Va dev.bnxt.X.iflib.override_nrxds diff --git a/share/man/man4/em.4 b/share/man/man4/em.4 index 9a9249fdcaf7..7f84be1fbbf4 100644 --- a/share/man/man4/em.4 +++ b/share/man/man4/em.4 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 22, 2017 +.Dd September 20, 2018 .Dt EM 4 .Os .Sh NAME @@ -298,6 +298,7 @@ issue to .Sh SEE ALSO .Xr altq 4 , .Xr arp 4 , +.Xr iflib 4 , .Xr led 4 , .Xr netintro 4 , .Xr ng_ether 4 , diff --git a/share/man/man4/iflib.4 b/share/man/man4/iflib.4 new file mode 100644 index 000000000000..2e99787b9cfd --- /dev/null +++ b/share/man/man4/iflib.4 @@ -0,0 +1,195 @@ +.\" $FreeBSD$ +.Dd September 20, 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 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 EFBIG error +result from DMA mapping a transmit mbuf. +.It Va m_pullups +Number of times m_pullup was called attempting to parse a header. +.It Va mbuf_defrag +Number of times m_defrag 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 +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 11.0. diff --git a/share/man/man9/iflib.9 b/share/man/man9/iflib.9 index 33d0293b45fc..f833c5c44d37 100644 --- a/share/man/man9/iflib.9 +++ b/share/man/man9/iflib.9 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd May 3, 2018 +.Dd September 20, 2018 .Dt IFLIB 9 .Os .Sh NAME @@ -32,6 +32,7 @@ Device-dependent transmit and receive functions, used when writing new .Nm based drivers. .Sh SEE ALSO +.Xr iflib 4 , .Xr iflibdd 9 , .Xr iflibdi 9 , .Xr iflibtxrx 9 , From c396945b74fc298fd6351bd9be73541edfa89176 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 20 Sep 2018 18:25:26 +0000 Subject: [PATCH 053/139] vfs: remove lookup_shared tunable Reviewed by: kib, jhb Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17253 --- sys/kern/vfs_lookup.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index cdfb84e42447..675c0aa02ac3 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -160,10 +160,6 @@ nameiinit(void *dummy __unused) } SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nameiinit, NULL); -static int lookup_shared = 1; -SYSCTL_INT(_vfs, OID_AUTO, lookup_shared, CTLFLAG_RWTUN, &lookup_shared, 0, - "enables shared locks for path name translation"); - static int lookup_cap_dotdot = 1; SYSCTL_INT(_vfs, OID_AUTO, lookup_cap_dotdot, CTLFLAG_RWTUN, &lookup_cap_dotdot, 0, @@ -307,8 +303,6 @@ namei(struct nameidata *ndp) ("namei: flags contaminated with nameiops")); MPASS(ndp->ni_startdir == NULL || ndp->ni_startdir->v_type == VDIR || ndp->ni_startdir->v_type == VBAD); - if (!lookup_shared) - cnp->cn_flags &= ~LOCKSHARED; fdp = p->p_fd; TAILQ_INIT(&ndp->ni_cap_tracker); ndp->ni_lcf = 0; @@ -660,10 +654,7 @@ lookup(struct nameidata *ndp) * We use shared locks until we hit the parent of the last cn then * we adjust based on the requesting flags. */ - if (lookup_shared) - cnp->cn_lkflags = LK_SHARED; - else - cnp->cn_lkflags = LK_EXCLUSIVE; + cnp->cn_lkflags = LK_SHARED; dp = ndp->ni_startdir; ndp->ni_startdir = NULLVP; vn_lock(dp, @@ -1087,7 +1078,7 @@ lookup(struct nameidata *ndp) VOP_UNLOCK(dp, 0); success: /* - * Because of lookup_shared we may have the vnode shared locked, but + * Because of shared lookup we may have the vnode shared locked, but * the caller may want it to be exclusively locked. */ if (needs_exclusive_leaf(dp->v_mount, cnp->cn_flags) && From 969e147aff813235dada3b6e887df076616bdcce Mon Sep 17 00:00:00 2001 From: Mark Johnston <markj@FreeBSD.org> Date: Thu, 20 Sep 2018 18:29:55 +0000 Subject: [PATCH 054/139] Ensure that imports into per-domain kmem arenas are KVA_QUANTUM-aligned. The old code appears to assume that vmem_alloc() would import size-aligned KVA chunks from the parent kernel_arena, but vmem doesn't provide this guarantee. Also remove the unused global RWX arena and add comments explaining why we have per-domain arenas. Reported by: alc Reviewed by: alc, kib (previous version) Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17249 --- sys/kern/subr_vmem.c | 3 --- sys/vm/vm_kern.c | 44 +++++++++++++++++++++----------------------- sys/vm/vm_kern.h | 1 - 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/sys/kern/subr_vmem.c b/sys/kern/subr_vmem.c index 3c83c777b6a9..8529266f381c 100644 --- a/sys/kern/subr_vmem.c +++ b/sys/kern/subr_vmem.c @@ -241,9 +241,6 @@ static struct vmem buffer_arena_storage; static struct vmem transient_arena_storage; /* kernel and kmem arenas are aliased for backwards KPI compat. */ vmem_t *kernel_arena = &kernel_arena_storage; -#if VM_NRESERVLEVEL > 0 -vmem_t *kernel_rwx_arena = NULL; -#endif vmem_t *kmem_arena = &kernel_arena_storage; vmem_t *buffer_arena = &buffer_arena_storage; vmem_t *transient_arena = &transient_arena_storage; diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 5f7c4033c218..b5915c074ab6 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -669,7 +669,7 @@ kmem_init_zero_region(void) } /* - * Import kva into the kernel arena. + * 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) @@ -691,22 +691,20 @@ kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp) return (0); } -#if VM_NRESERVLEVEL > 0 /* - * Import a superpage from the normal kernel arena into the special - * arena for allocations with different permissions. + * 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 -kernel_rwx_alloc(void *arena, vmem_size_t size, int flags, vmem_addr_t *addrp) +kva_import_domain(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", + ("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)); } -#endif /* * kmem_init: @@ -744,30 +742,30 @@ kmem_init(vm_offset_t start, vm_offset_t end) 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++) { + /* + * 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, - (vmem_import_t *)vmem_alloc, NULL, kernel_arena, - KVA_QUANTUM); + 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, - kernel_rwx_alloc, (vmem_release_t *)vmem_xfree, - vm_dom[domain].vmd_kernel_arena, KVA_QUANTUM); + kva_import_domain, (vmem_release_t *)vmem_xfree, + kernel_arena, KVA_QUANTUM); #endif } } diff --git a/sys/vm/vm_kern.h b/sys/vm/vm_kern.h index 8d49a598f26d..20e847f5e5af 100644 --- a/sys/vm/vm_kern.h +++ b/sys/vm/vm_kern.h @@ -70,7 +70,6 @@ extern vm_map_t kernel_map; extern vm_map_t exec_map; extern vm_map_t pipe_map; extern struct vmem *kernel_arena; -extern struct vmem *kernel_rwx_arena; extern struct vmem *kmem_arena; extern struct vmem *buffer_arena; extern struct vmem *transient_arena; From 4bf0035fd1434190fc67a647879437a7919a4cf7 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 20 Sep 2018 18:30:17 +0000 Subject: [PATCH 055/139] amd64: macroify copyin/copyout and provide erms variants Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17257 --- sys/amd64/amd64/copyout.c | 37 +++++++-- sys/amd64/amd64/support.S | 156 ++++++++++++++++---------------------- 2 files changed, 94 insertions(+), 99 deletions(-) diff --git a/sys/amd64/amd64/copyout.c b/sys/amd64/amd64/copyout.c index dce20fb27769..59b7ad5c1307 100644 --- a/sys/amd64/amd64/copyout.c +++ b/sys/amd64/amd64/copyout.c @@ -159,20 +159,41 @@ DEFINE_IFUNC(, int, copyinstr, (const void *, void *, size_t, size_t *), copyinstr_smap : copyinstr_nosmap); } -int copyin_nosmap(const void *udaddr, void *kaddr, size_t len); -int copyin_smap(const void *udaddr, void *kaddr, size_t len); +int copyin_nosmap_std(const void *udaddr, void *kaddr, size_t len); +int copyin_smap_std(const void *udaddr, void *kaddr, size_t len); +int copyin_nosmap_erms(const void *udaddr, void *kaddr, size_t len); +int copyin_smap_erms(const void *udaddr, void *kaddr, size_t len); DEFINE_IFUNC(, int, copyin, (const void *, void *, size_t), static) { - return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ? - copyin_smap : copyin_nosmap); + switch (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS)) { + case CPUID_STDEXT_SMAP: + return (copyin_smap_std); + case CPUID_STDEXT_ERMS: + return (copyin_nosmap_erms); + case CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS: + return (copyin_smap_erms); + default: + return (copyin_nosmap_std); + + } } -int copyout_nosmap(const void *kaddr, void *udaddr, size_t len); -int copyout_smap(const void *kaddr, void *udaddr, size_t len); +int copyout_nosmap_std(const void *kaddr, void *udaddr, size_t len); +int copyout_smap_std(const void *kaddr, void *udaddr, size_t len); +int copyout_nosmap_erms(const void *kaddr, void *udaddr, size_t len); +int copyout_smap_erms(const void *kaddr, void *udaddr, size_t len); DEFINE_IFUNC(, int, copyout, (const void *, void *, size_t), static) { - return ((cpu_stdext_feature & CPUID_STDEXT_SMAP) != 0 ? - copyout_smap : copyout_nosmap); + switch (cpu_stdext_feature & (CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS)) { + case CPUID_STDEXT_SMAP: + return (copyout_smap_std); + case CPUID_STDEXT_ERMS: + return (copyout_nosmap_erms); + case CPUID_STDEXT_SMAP | CPUID_STDEXT_ERMS: + return (copyout_smap_erms); + default: + return (copyout_nosmap_std); + } } diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 33ffec1ff5f9..168ea5b32bcf 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -281,62 +281,30 @@ END(fillw) * returns to *curpcb->pcb_onfault instead of the function. */ +.macro SMAP_DISABLE smap +.if \smap + stac +.endif +.endmacro + + +.macro SMAP_ENABLE smap +.if \smap + clac +.endif +.endmacro + /* * copyout(from_kernel, to_user, len) * %rdi, %rsi, %rdx */ -ENTRY(copyout_nosmap) - 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) +.macro COPYOUT smap erms 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 + jz 2f /* * Check explicitly for non-user addresses. If 486 write protection @@ -365,23 +333,42 @@ ENTRY(copyout_smap) /* bcopy(%rsi, %rdi, %rdx) */ movq %rdx,%rcx + SMAP_DISABLE \smap +.if \erms == 0 shrq $3,%rcx - stac rep movsq movb %dl,%cl andb $7,%cl je 1f +.endif rep movsb -1: clac - -done_copyout: +1: + SMAP_ENABLE \smap +2: xorl %eax,%eax movq PCPU(CURPCB),%rdx movq %rax,PCB_ONFAULT(%rdx) POP_FRAME_POINTER ret +.endmacro + +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) ALIGN_TEXT copyout_fault: @@ -390,18 +377,17 @@ copyout_fault: movq $EFAULT,%rax POP_FRAME_POINTER ret -END(copyout_smap) /* * 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 + jz 2f /* * make sure address is valid @@ -416,56 +402,44 @@ ENTRY(copyin_nosmap) xchgq %rdi,%rsi movq %rdx,%rcx movb %cl,%al + + SMAP_DISABLE \smap +.if \erms == 0 shrq $3,%rcx /* copy longword-wise */ rep movsq movb %al,%cl andb $7,%cl /* copy remaining bytes */ - je done_copyin + je 1 +.endif 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: +1: + SMAP_ENABLE \smap +2: xorl %eax,%eax movq PCPU(CURPCB),%rdx movq %rax,PCB_ONFAULT(%rdx) POP_FRAME_POINTER ret -END(copyin_smap) +.endmacro + +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: From 0c919c23706c7734a9ecb6b0a95717c37c4b3d56 Mon Sep 17 00:00:00 2001 From: Stephen Hurd <shurd@FreeBSD.org> Date: Thu, 20 Sep 2018 19:35:35 +0000 Subject: [PATCH 056/139] Fix capabilities handling for iflib drivers Various capabilities were not being handled correctly in the SIOCSIFCAP handler. Specifically: IFCAP_RXCSUM and IFCAP_RXCSUM_IPV6 could be set even if not supported It was impossible to disable IFCAP_RXCSUM and/or IFCAP_RXCSUM_IPV6 via ifconfig since it does ioctl() per command-line flag rather than combine them into a single call. IFCAP_VLAN_HWCSUM could not be modified via the ioctl() Setting any combination of the three IFCAP_WOL flags would set only IFCAP_WOL_MCAST | IFCAP_WOL_MAGIC. For example, setting only IFCAP_WOL_UCAST would result in both IFCAP_WOL_MCAST and IFCAP_WOL_MAGIC being enabled, but IFCAP_WOL_UCAST would not be enabled. Because if_vlancap() was called before if_togglecapenable(), vlan flags were sometimes not applied correctly. Interfaces were being unnecessarily stopped and restarted for WoL PR: 231151 Submitted by: Kaho Toshikazu <kaho@elam.kais.kyoto-u.ac.jp> Reported by: Shirkdog <mshirk@daemon-security.com> Reviewed by: galladin Approved by: re (gjb) Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D17158 --- sys/net/iflib.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/sys/net/iflib.c b/sys/net/iflib.c index 65bf07a0b2c1..d9a6e3b962d7 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -4100,9 +4100,10 @@ iflib_if_qflush(if_t ifp) } -#define IFCAP_FLAGS (IFCAP_TXCSUM_IPV6 | IFCAP_RXCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ - IFCAP_TSO4 | IFCAP_TSO6 | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ - IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | IFCAP_VLAN_HWTSO) +#define IFCAP_FLAGS (IFCAP_HWCSUM_IPV6 | IFCAP_HWCSUM | IFCAP_LRO | \ + IFCAP_TSO | IFCAP_VLAN_HWTAGGING | IFCAP_HWSTATS | \ + IFCAP_VLAN_MTU | IFCAP_VLAN_HWFILTER | \ + IFCAP_VLAN_HWTSO | IFCAP_VLAN_HWCSUM) static int iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) @@ -4223,39 +4224,51 @@ iflib_if_ioctl(if_t ifp, u_long command, caddr_t data) } case SIOCSIFCAP: { - int mask, setmask; + int mask, setmask, oldmask; - mask = ifr->ifr_reqcap ^ if_getcapenable(ifp); + oldmask = if_getcapenable(ifp); + mask = ifr->ifr_reqcap ^ oldmask; + mask &= ctx->ifc_softc_ctx.isc_capabilities; setmask = 0; #ifdef TCP_OFFLOAD setmask |= mask & (IFCAP_TOE4|IFCAP_TOE6); #endif setmask |= (mask & IFCAP_FLAGS); + setmask |= (mask & IFCAP_WOL); + + /* + * If we're disabling any RX csum, disable all the ones + * the driver supports. This assumes all supported are + * enabled. + * + * Otherwise, if they've changed, enable all of them. + */ + if ((setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) < + (oldmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))) + setmask &= ~(IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); + else if ((setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) != + (oldmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6))) + setmask |= (mask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)); - if (setmask & (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6)) - setmask |= (IFCAP_RXCSUM | IFCAP_RXCSUM_IPV6); - if ((mask & IFCAP_WOL) && - (if_getcapabilities(ifp) & IFCAP_WOL) != 0) - setmask |= (mask & (IFCAP_WOL_MCAST|IFCAP_WOL_MAGIC)); - if_vlancap(ifp); /* * want to ensure that traffic has stopped before we change any of the flags */ if (setmask) { CTX_LOCK(ctx); bits = if_getdrvflags(ifp); - if (bits & IFF_DRV_RUNNING) + if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_stop(ctx); STATE_LOCK(ctx); if_togglecapenable(ifp, setmask); STATE_UNLOCK(ctx); - if (bits & IFF_DRV_RUNNING) + if (bits & IFF_DRV_RUNNING && setmask & ~IFCAP_WOL) iflib_init_locked(ctx); STATE_LOCK(ctx); if_setdrvflags(ifp, bits); STATE_UNLOCK(ctx); CTX_UNLOCK(ctx); } + if_vlancap(ifp); break; } case SIOCGPRIVATE_0: From 76b09d1823ee18fe4a0b8abe17d73306263765b8 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" <ae@FreeBSD.org> Date: Thu, 20 Sep 2018 19:45:27 +0000 Subject: [PATCH 057/139] Add new field max_hdrsize to struct encap_config. It is currently unused and reserved for future use to keep KBI/KPI. Also add several spare pointers to be able extend structure if it will be needed. Approved by: re (gjb) --- sys/netinet/ip_encap.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/netinet/ip_encap.h b/sys/netinet/ip_encap.h index f3d1d3afcab8..65ac922fc1bb 100644 --- a/sys/netinet/ip_encap.h +++ b/sys/netinet/ip_encap.h @@ -48,12 +48,15 @@ typedef int (*encap_input_t)(struct mbuf *, int , int, void *); struct encap_config { int proto; /* protocol */ int min_length; /* minimum packet length */ + int max_hdrsize; /* maximum header size */ int exact_match; /* a packet is exactly matched */ #define ENCAP_DRV_LOOKUP 0x7fffffff encap_lookup_t lookup; encap_check_t check; encap_input_t input; + + void *pad[3]; }; struct encaptab; From 861437f83ac101939a96c98ca9266a11de733c2a Mon Sep 17 00:00:00 2001 From: Stephen Hurd <shurd@FreeBSD.org> Date: Thu, 20 Sep 2018 20:06:44 +0000 Subject: [PATCH 058/139] Add IFCAP_TSO6 for igb It seems igb supports TSO6, but the capability got lost in the iflib update. Restore this capability. PR: 231476 Reported by: lev Reviewed by: erj Approved by: re (gjb) Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D17242 --- sys/dev/e1000/if_em.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index a95d606ac34f..93714cd10710 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -709,7 +709,8 @@ em_set_num_queues(if_ctx_t ctx) #define IGB_CAPS \ IFCAP_HWCSUM | IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING | \ IFCAP_VLAN_HWCSUM | IFCAP_WOL | IFCAP_VLAN_HWFILTER | IFCAP_TSO4 | \ - IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6; + IFCAP_LRO | IFCAP_VLAN_HWTSO | IFCAP_JUMBO_MTU | IFCAP_HWCSUM_IPV6 |\ + IFCAP_TSO6 /********************************************************************* * Device initialization routine From 5254f065abb41b7c9e9723323aae292d4e3f4739 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 20 Sep 2018 20:32:08 +0000 Subject: [PATCH 059/139] amd64: macroify copyin/copyout and provide erms variants, follow up Fix a fat-fingered typo with a "funny" side-effect: when doing copyin on a cpu without ERMS and with size being a multiply of 8 a page fault would be triggered resulting in EFAULT. Pointy hat: mjg Approved by: re (implicit) --- sys/amd64/amd64/support.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 168ea5b32bcf..043110226e22 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -410,7 +410,7 @@ copyout_fault: movsq movb %al,%cl andb $7,%cl /* copy remaining bytes */ - je 1 + je 1f .endif rep movsb From a128aaea9509f06e8de4e522a5521faee112e8a9 Mon Sep 17 00:00:00 2001 From: Glen Barber <gjb@FreeBSD.org> Date: Thu, 20 Sep 2018 23:59:42 +0000 Subject: [PATCH 060/139] Update head from ALPHA6 to ALPHA7 as part of the 12.0-RELEASE cycle. Approved by: re (implicit) Sponsored by: The FreeBSD Foundation --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index ce32cf2950af..e784b373150e 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -46,7 +46,7 @@ TYPE="FreeBSD" REVISION="12.0" -BRANCH="ALPHA6" +BRANCH="ALPHA7" if [ -n "${BRANCH_OVERRIDE}" ]; then BRANCH=${BRANCH_OVERRIDE} fi From b08d611de8351aaae68a204fa94711e0ed03945f Mon Sep 17 00:00:00 2001 From: Matt Macy <mmacy@FreeBSD.org> Date: Fri, 21 Sep 2018 01:37:08 +0000 Subject: [PATCH 061/139] fix vlan locking to permit sx acquisition in ioctl calls - update vlan(9) to handle changes earlier this year in multicast locking Tested by: np@, darkfiberu at gmail.com PR: 230510 Reviewed by: mjoras@, shurd@, sbruno@ Approved by: re (gjb@) Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D16808 --- sys/net/if_var.h | 1 + sys/net/if_vlan.c | 219 ++++++++++++++++------------------------------ 2 files changed, 77 insertions(+), 143 deletions(-) diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 480df7433a6d..68341ef75025 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -411,6 +411,7 @@ struct ifnet { #define NET_EPOCH_ENTER_ET(et) epoch_enter_preempt(net_epoch_preempt, &(et)) #define NET_EPOCH_EXIT() epoch_exit_preempt(net_epoch_preempt, &nep_et) #define NET_EPOCH_EXIT_ET(et) epoch_exit_preempt(net_epoch_preempt, &(et)) +#define NET_EPOCH_WAIT() epoch_wait_preempt(net_epoch_preempt) /* diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c index 11baf8a018b4..5170ee6ae35c 100644 --- a/sys/net/if_vlan.c +++ b/sys/net/if_vlan.c @@ -87,11 +87,11 @@ __FBSDID("$FreeBSD$"); #define UP_AND_RUNNING(ifp) \ ((ifp)->if_flags & IFF_UP && (ifp)->if_drv_flags & IFF_DRV_RUNNING) -LIST_HEAD(ifvlanhead, ifvlan); +CK_SLIST_HEAD(ifvlanhead, ifvlan); struct ifvlantrunk { struct ifnet *parent; /* parent interface of this trunk */ - struct rmlock lock; + struct mtx lock; #ifdef VLAN_ARRAY #define VLAN_ARRAY_SIZE (EVL_VLID_MASK + 1) struct ifvlan *vlans[VLAN_ARRAY_SIZE]; /* static table */ @@ -117,7 +117,7 @@ struct ifvlantrunk { struct ifvlan *_next; \ size_t _i; \ for (_i = 0; _i < (1 << (_trunk)->hwidth); _i++) \ - LIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next) + CK_SLIST_FOREACH_SAFE((_ifv), &(_trunk)->hash[_i], ifv_list, _next) #endif /* VLAN_ARRAY */ /* @@ -146,13 +146,13 @@ struct ifvlantrunk { for (_i = 0; \ !(_cond) && _i < (1 << (_trunk)->hwidth); \ _i = (_touch && ((_trunk) != NULL) ? 0 : _i + 1), _touch = false) \ - if (((_ifv) = LIST_FIRST(&(_trunk)->hash[_i])) != NULL && \ + if (((_ifv) = CK_SLIST_FIRST(&(_trunk)->hash[_i])) != NULL && \ (_touch = true)) #endif /* VLAN_ARRAY */ struct vlan_mc_entry { struct sockaddr_dl mc_addr; - SLIST_ENTRY(vlan_mc_entry) mc_entries; + CK_SLIST_ENTRY(vlan_mc_entry) mc_entries; }; struct ifvlan { @@ -173,9 +173,9 @@ struct ifvlan { uint8_t ifvm_pcp; /* Priority Code Point (PCP). */ } ifv_mib; struct task lladdr_task; - SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; + CK_SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; #ifndef VLAN_ARRAY - LIST_ENTRY(ifvlan) ifv_list; + CK_SLIST_ENTRY(ifvlan) ifv_list; #endif }; #define ifv_proto ifv_mib.ifvm_proto @@ -205,55 +205,36 @@ static eventhandler_tag ifdetach_tag; static eventhandler_tag iflladdr_tag; /* - * if_vlan uses two module-level locks to allow concurrent modification of vlan - * interfaces and (mostly) allow for vlans to be destroyed while they are being - * used for tx/rx. To accomplish this in a way that has acceptable performance - * and cooperation with other parts of the network stack there is a - * non-sleepable rmlock(9) and an sx(9). Both locks are exclusively acquired - * when destroying a vlan interface, i.e. when the if_vlantrunk field of struct - * ifnet is de-allocated and NULL'd. Thus a reader holding either lock has a - * guarantee that the struct ifvlantrunk references a valid vlan trunk. + * if_vlan uses two module-level synchronizations primitives to allow concurrent + * modification of vlan interfaces and (mostly) allow for vlans to be destroyed + * while they are being used for tx/rx. To accomplish this in a way that has + * acceptable performance and cooperation with other parts of the network stack + * there is a non-sleepable epoch(9) and an sx(9). * - * The performance-sensitive paths that warrant using the rmlock(9) are + * The performance-sensitive paths that warrant using the epoch(9) are * vlan_transmit and vlan_input. Both have to check for the vlan interface's * existence using if_vlantrunk, and being in the network tx/rx paths the use - * of an rmlock(9) gives a measureable improvement in performance. + * of an epoch(9) gives a measureable improvement in performance. * * The reason for having an sx(9) is mostly because there are still areas that * must be sleepable and also have safe concurrent access to a vlan interface. * Since the sx(9) exists, it is used by default in most paths unless sleeping * is not permitted, or if it is not clear whether sleeping is permitted. * - * Note that despite these protections, there is still an inherent race in the - * destruction of vlans since there's no guarantee that the ifnet hasn't been - * freed/reused when the tx/rx functions are called by the stack. This can only - * be fixed by addressing ifnet's lifetime issues. */ -#define _VLAN_RM_ID ifv_rm_lock #define _VLAN_SX_ID ifv_sx -static struct rmlock _VLAN_RM_ID; static struct sx _VLAN_SX_ID; #define VLAN_LOCKING_INIT() \ - rm_init(&_VLAN_RM_ID, "vlan_rm"); \ sx_init(&_VLAN_SX_ID, "vlan_sx") #define VLAN_LOCKING_DESTROY() \ - rm_destroy(&_VLAN_RM_ID); \ sx_destroy(&_VLAN_SX_ID) -#define _VLAN_RM_TRACKER _vlan_rm_tracker -#define VLAN_RLOCK() rm_rlock(&_VLAN_RM_ID, \ - &_VLAN_RM_TRACKER) -#define VLAN_RUNLOCK() rm_runlock(&_VLAN_RM_ID, \ - &_VLAN_RM_TRACKER) -#define VLAN_WLOCK() rm_wlock(&_VLAN_RM_ID) -#define VLAN_WUNLOCK() rm_wunlock(&_VLAN_RM_ID) -#define VLAN_RLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_RLOCKED) -#define VLAN_WLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_WLOCKED) -#define VLAN_RWLOCK_ASSERT() rm_assert(&_VLAN_RM_ID, RA_LOCKED) -#define VLAN_LOCK_READER struct rm_priotracker _VLAN_RM_TRACKER +#define VLAN_RLOCK() NET_EPOCH_ENTER(); +#define VLAN_RUNLOCK() NET_EPOCH_EXIT(); +#define VLAN_RLOCK_ASSERT() MPASS(in_epoch(net_epoch_preempt)) #define VLAN_SLOCK() sx_slock(&_VLAN_SX_ID) #define VLAN_SUNLOCK() sx_sunlock(&_VLAN_SX_ID) @@ -265,25 +246,18 @@ static struct sx _VLAN_SX_ID; /* - * We also have a per-trunk rmlock(9), that is locked shared on packet - * processing and exclusive when configuration is changed. Note: This should - * only be acquired while there is a shared lock on either of the global locks - * via VLAN_SLOCK or VLAN_RLOCK. Thus, an exclusive lock on the global locks - * makes a call to TRUNK_RLOCK/TRUNK_WLOCK technically superfluous. + * We also have a per-trunk mutex that should be acquired when changing + * its state. */ -#define _TRUNK_RM_TRACKER _trunk_rm_tracker -#define TRUNK_LOCK_INIT(trunk) rm_init(&(trunk)->lock, vlanname) -#define TRUNK_LOCK_DESTROY(trunk) rm_destroy(&(trunk)->lock) -#define TRUNK_RLOCK(trunk) rm_rlock(&(trunk)->lock, \ - &_TRUNK_RM_TRACKER) -#define TRUNK_WLOCK(trunk) rm_wlock(&(trunk)->lock) -#define TRUNK_RUNLOCK(trunk) rm_runlock(&(trunk)->lock, \ - &_TRUNK_RM_TRACKER) -#define TRUNK_WUNLOCK(trunk) rm_wunlock(&(trunk)->lock) -#define TRUNK_RLOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_RLOCKED) -#define TRUNK_LOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_LOCKED) -#define TRUNK_WLOCK_ASSERT(trunk) rm_assert(&(trunk)->lock, RA_WLOCKED) -#define TRUNK_LOCK_READER struct rm_priotracker _TRUNK_RM_TRACKER +#define TRUNK_LOCK_INIT(trunk) mtx_init(&(trunk)->lock, vlanname, NULL, MTX_DEF) +#define TRUNK_LOCK_DESTROY(trunk) mtx_destroy(&(trunk)->lock) +#define TRUNK_RLOCK(trunk) NET_EPOCH_ENTER() +#define TRUNK_WLOCK(trunk) mtx_lock(&(trunk)->lock) +#define TRUNK_RUNLOCK(trunk) NET_EPOCH_EXIT(); +#define TRUNK_WUNLOCK(trunk) mtx_unlock(&(trunk)->lock) +#define TRUNK_RLOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt)) +#define TRUNK_LOCK_ASSERT(trunk) MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(trunk)->lock)) +#define TRUNK_WLOCK_ASSERT(trunk) mtx_assert(&(trunk)->lock, MA_OWNED); /* * The VLAN_ARRAY substitutes the dynamic hash with a static array @@ -361,7 +335,7 @@ vlan_inithash(struct ifvlantrunk *trunk) trunk->hmask = n - 1; trunk->hash = malloc(sizeof(struct ifvlanhead) * n, M_VLAN, M_WAITOK); for (i = 0; i < n; i++) - LIST_INIT(&trunk->hash[i]); + CK_SLIST_INIT(&trunk->hash[i]); } static void @@ -372,7 +346,7 @@ vlan_freehash(struct ifvlantrunk *trunk) KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); for (i = 0; i < (1 << trunk->hwidth); i++) - KASSERT(LIST_EMPTY(&trunk->hash[i]), + KASSERT(CK_SLIST_EMPTY(&trunk->hash[i]), ("%s: hash table not empty", __func__)); #endif free(trunk->hash, M_VLAN); @@ -386,12 +360,12 @@ vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv) int i, b; struct ifvlan *ifv2; - TRUNK_WLOCK_ASSERT(trunk); + VLAN_XLOCK_ASSERT(); KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); b = 1 << trunk->hwidth; i = HASH(ifv->ifv_vid, trunk->hmask); - LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) + CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) if (ifv->ifv_vid == ifv2->ifv_vid) return (EEXIST); @@ -404,7 +378,7 @@ vlan_inshash(struct ifvlantrunk *trunk, struct ifvlan *ifv) vlan_growhash(trunk, 1); i = HASH(ifv->ifv_vid, trunk->hmask); } - LIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list); + CK_SLIST_INSERT_HEAD(&trunk->hash[i], ifv, ifv_list); trunk->refcnt++; return (0); @@ -416,15 +390,15 @@ vlan_remhash(struct ifvlantrunk *trunk, struct ifvlan *ifv) int i, b; struct ifvlan *ifv2; - TRUNK_WLOCK_ASSERT(trunk); + VLAN_XLOCK_ASSERT(); KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); b = 1 << trunk->hwidth; i = HASH(ifv->ifv_vid, trunk->hmask); - LIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) + CK_SLIST_FOREACH(ifv2, &trunk->hash[i], ifv_list) if (ifv2 == ifv) { trunk->refcnt--; - LIST_REMOVE(ifv2, ifv_list); + CK_SLIST_REMOVE(&trunk->hash[i], ifv2, ifvlan, ifv_list); if (trunk->refcnt < (b * b) / 2) vlan_growhash(trunk, -1); return (0); @@ -444,7 +418,7 @@ vlan_growhash(struct ifvlantrunk *trunk, int howmuch) struct ifvlanhead *hash2; int hwidth2, i, j, n, n2; - TRUNK_WLOCK_ASSERT(trunk); + VLAN_XLOCK_ASSERT(); KASSERT(trunk->hwidth > 0, ("%s: hwidth not positive", __func__)); if (howmuch == 0) { @@ -460,21 +434,21 @@ vlan_growhash(struct ifvlantrunk *trunk, int howmuch) if (hwidth2 < VLAN_DEF_HWIDTH) return; - /* M_NOWAIT because we're called with trunk mutex held */ - hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_NOWAIT); + hash2 = malloc(sizeof(struct ifvlanhead) * n2, M_VLAN, M_WAITOK); if (hash2 == NULL) { printf("%s: out of memory -- hash size not changed\n", __func__); return; /* We can live with the old hash table */ } for (j = 0; j < n2; j++) - LIST_INIT(&hash2[j]); + CK_SLIST_INIT(&hash2[j]); for (i = 0; i < n; i++) - while ((ifv = LIST_FIRST(&trunk->hash[i])) != NULL) { - LIST_REMOVE(ifv, ifv_list); + while ((ifv = CK_SLIST_FIRST(&trunk->hash[i])) != NULL) { + CK_SLIST_REMOVE(&trunk->hash[i], ifv, ifvlan, ifv_list); j = HASH(ifv->ifv_vid, n2 - 1); - LIST_INSERT_HEAD(&hash2[j], ifv, ifv_list); + CK_SLIST_INSERT_HEAD(&hash2[j], ifv, ifv_list); } + NET_EPOCH_WAIT(); free(trunk->hash, M_VLAN); trunk->hash = hash2; trunk->hwidth = hwidth2; @@ -492,7 +466,7 @@ vlan_gethash(struct ifvlantrunk *trunk, uint16_t vid) TRUNK_RLOCK_ASSERT(trunk); - LIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list) + CK_SLIST_FOREACH(ifv, &trunk->hash[HASH(vid, trunk->hmask)], ifv_list) if (ifv->ifv_vid == vid) return (ifv); return (NULL); @@ -508,7 +482,7 @@ vlan_dumphash(struct ifvlantrunk *trunk) for (i = 0; i < (1 << trunk->hwidth); i++) { printf("%d: ", i); - LIST_FOREACH(ifv, &trunk->hash[i], ifv_list) + CK_SLIST_FOREACH(ifv, &trunk->hash[i], ifv_list) printf("%s ", ifv->ifv_ifp->if_xname); printf("\n"); } @@ -561,7 +535,6 @@ static void trunk_destroy(struct ifvlantrunk *trunk) { VLAN_XLOCK_ASSERT(); - VLAN_WLOCK_ASSERT(); vlan_freehash(trunk); trunk->parent->if_vlantrunk = NULL; @@ -587,23 +560,19 @@ vlan_setmulti(struct ifnet *ifp) struct vlan_mc_entry *mc; int error; - /* - * XXX This stupidly needs the rmlock to avoid sleeping while holding - * the in6_multi_mtx (see in6_mc_join_locked). - */ - VLAN_RWLOCK_ASSERT(); + VLAN_XLOCK_ASSERT(); /* Find the parent. */ sc = ifp->if_softc; - TRUNK_WLOCK_ASSERT(TRUNK(sc)); ifp_p = PARENT(sc); CURVNET_SET_QUIET(ifp_p->if_vnet); /* First, remove any existing filter entries. */ - while ((mc = SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { - SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); + while ((mc = CK_SLIST_FIRST(&sc->vlan_mc_listhead)) != NULL) { + CK_SLIST_REMOVE_HEAD(&sc->vlan_mc_listhead, mc_entries); (void)if_delmulti(ifp_p, (struct sockaddr *)&mc->mc_addr); + NET_EPOCH_WAIT(); free(mc, M_VLAN); } @@ -619,10 +588,10 @@ vlan_setmulti(struct ifnet *ifp) } bcopy(ifma->ifma_addr, &mc->mc_addr, ifma->ifma_addr->sa_len); mc->mc_addr.sdl_index = ifp_p->if_index; - SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); + CK_SLIST_INSERT_HEAD(&sc->vlan_mc_listhead, mc, mc_entries); } IF_ADDR_WUNLOCK(ifp); - SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) { + CK_SLIST_FOREACH (mc, &sc->vlan_mc_listhead, mc_entries) { error = if_addmulti(ifp_p, (struct sockaddr *)&mc->mc_addr, NULL); if (error) @@ -645,7 +614,6 @@ vlan_iflladdr(void *arg __unused, struct ifnet *ifp) struct ifnet *ifv_ifp; struct ifvlantrunk *trunk; struct sockaddr_dl *sdl; - VLAN_LOCK_READER; /* Need the rmlock since this is run on taskqueue_swi. */ VLAN_RLOCK(); @@ -724,12 +692,10 @@ static struct ifnet * vlan_trunkdev(struct ifnet *ifp) { struct ifvlan *ifv; - VLAN_LOCK_READER; if (ifp->if_type != IFT_L2VLAN) return (NULL); - /* Not clear if callers are sleepable, so acquire the rmlock. */ VLAN_RLOCK(); ifv = ifp->if_softc; ifp = NULL; @@ -809,10 +775,7 @@ vlan_devat(struct ifnet *ifp, uint16_t vid) { struct ifvlantrunk *trunk; struct ifvlan *ifv; - VLAN_LOCK_READER; - TRUNK_LOCK_READER; - /* Not clear if callers are sleepable, so acquire the rmlock. */ VLAN_RLOCK(); trunk = ifp->if_vlantrunk; if (trunk == NULL) { @@ -820,11 +783,9 @@ vlan_devat(struct ifnet *ifp, uint16_t vid) return (NULL); } ifp = NULL; - TRUNK_RLOCK(trunk); ifv = vlan_gethash(trunk, vid); if (ifv) ifp = ifv->ifv_ifp; - TRUNK_RUNLOCK(trunk); VLAN_RUNLOCK(); return (ifp); } @@ -1076,7 +1037,7 @@ vlan_clone_create(struct if_clone *ifc, char *name, size_t len, caddr_t params) if_rele(p); return (ENOSPC); } - SLIST_INIT(&ifv->vlan_mc_listhead); + CK_SLIST_INIT(&ifv->vlan_mc_listhead); ifp->if_softc = ifv; /* * Set the name manually rather than using if_initname because @@ -1143,6 +1104,7 @@ vlan_clone_destroy(struct if_clone *ifc, struct ifnet *ifp) * ifvlan. */ taskqueue_drain(taskqueue_thread, &ifv->lladdr_task); + NET_EPOCH_WAIT(); if_free(ifp); free(ifv, M_VLAN); ifc_free_unit(ifc, unit); @@ -1167,7 +1129,6 @@ vlan_transmit(struct ifnet *ifp, struct mbuf *m) struct ifvlan *ifv; struct ifnet *p; int error, len, mcast; - VLAN_LOCK_READER; VLAN_RLOCK(); ifv = ifp->if_softc; @@ -1227,8 +1188,6 @@ vlan_input(struct ifnet *ifp, struct mbuf *m) { struct ifvlantrunk *trunk; struct ifvlan *ifv; - VLAN_LOCK_READER; - TRUNK_LOCK_READER; struct m_tag *mtag; uint16_t vid, tag; @@ -1289,16 +1248,13 @@ vlan_input(struct ifnet *ifp, struct mbuf *m) vid = EVL_VLANOFTAG(tag); - TRUNK_RLOCK(trunk); ifv = vlan_gethash(trunk, vid); if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) { - TRUNK_RUNLOCK(trunk); - if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); VLAN_RUNLOCK(); + if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1); m_freem(m); return; } - TRUNK_RUNLOCK(trunk); if (vlan_mtag_pcp) { /* @@ -1369,22 +1325,19 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) if (ifv->ifv_trunk) return (EBUSY); - /* Acquire rmlock after the branch so we can M_WAITOK. */ VLAN_XLOCK(); if (p->if_vlantrunk == NULL) { trunk = malloc(sizeof(struct ifvlantrunk), M_VLAN, M_WAITOK | M_ZERO); vlan_inithash(trunk); TRUNK_LOCK_INIT(trunk); - VLAN_WLOCK(); TRUNK_WLOCK(trunk); p->if_vlantrunk = trunk; trunk->parent = p; if_ref(trunk->parent); + TRUNK_WUNLOCK(trunk); } else { - VLAN_WLOCK(); trunk = p->if_vlantrunk; - TRUNK_WLOCK(trunk); } ifv->ifv_vid = vid; /* must set this before vlan_inshash() */ @@ -1448,7 +1401,9 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) ifp->if_link_state = p->if_link_state; + TRUNK_RLOCK(TRUNK(ifv)); vlan_capabilities(ifv); + TRUNK_RUNLOCK(TRUNK(ifv)); /* * Set up our interface address to reflect the underlying @@ -1458,12 +1413,6 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) ((struct sockaddr_dl *)ifp->if_addr->ifa_addr)->sdl_alen = p->if_addrlen; - /* - * Configure multicast addresses that may already be - * joined on the vlan device. - */ - (void)vlan_setmulti(ifp); - TASK_INIT(&ifv->lladdr_task, 0, vlan_lladdr_fn, ifv); /* We are ready for operation now. */ @@ -1471,13 +1420,14 @@ vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) /* Update flags on the parent, if necessary. */ vlan_setflags(ifp, 1); -done: + /* - * We need to drop the non-sleepable rmlock so that the underlying - * devices can sleep in their vlan_config hooks. + * Configure multicast addresses that may already be + * joined on the vlan device. */ - TRUNK_WUNLOCK(trunk); - VLAN_WUNLOCK(); + (void)vlan_setmulti(ifp); + +done: if (error == 0) EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid); VLAN_XUNLOCK(); @@ -1510,13 +1460,6 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) parent = NULL; if (trunk != NULL) { - /* - * Both vlan_transmit and vlan_input rely on the trunk fields - * being NULL to determine whether to bail, so we need to get - * an exclusive lock here to prevent them from using bad - * ifvlans. - */ - VLAN_WLOCK(); parent = trunk->parent; /* @@ -1524,7 +1467,7 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) * empty the list of multicast groups that we may have joined * while we were alive from the parent's list. */ - while ((mc = SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { + while ((mc = CK_SLIST_FIRST(&ifv->vlan_mc_listhead)) != NULL) { /* * If the parent interface is being detached, * all its multicast addresses have already @@ -1541,19 +1484,14 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) "Failed to delete multicast address from parent: %d\n", error); } - SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries); + CK_SLIST_REMOVE_HEAD(&ifv->vlan_mc_listhead, mc_entries); + NET_EPOCH_WAIT(); free(mc, M_VLAN); } vlan_setflags(ifp, 0); /* clear special flags on parent */ - /* - * The trunk lock isn't actually required here, but - * vlan_remhash expects it. - */ - TRUNK_WLOCK(trunk); vlan_remhash(trunk, ifv); - TRUNK_WUNLOCK(trunk); ifv->ifv_trunk = NULL; /* @@ -1561,9 +1499,9 @@ vlan_unconfig_locked(struct ifnet *ifp, int departing) */ if (trunk->refcnt == 0) { parent->if_vlantrunk = NULL; + NET_EPOCH_WAIT(); trunk_destroy(trunk); } - VLAN_WUNLOCK(); } /* Disconnect from parent. */ @@ -1640,7 +1578,6 @@ vlan_link_state(struct ifnet *ifp) { struct ifvlantrunk *trunk; struct ifvlan *ifv; - VLAN_LOCK_READER; /* Called from a taskqueue_swi task, so we cannot sleep. */ VLAN_RLOCK(); @@ -1670,7 +1607,7 @@ vlan_capabilities(struct ifvlan *ifv) u_long hwa = 0; VLAN_SXLOCK_ASSERT(); - TRUNK_WLOCK_ASSERT(TRUNK(ifv)); + TRUNK_RLOCK_ASSERT(TRUNK(ifv)); p = PARENT(ifv); ifp = ifv->ifv_ifp; @@ -1771,11 +1708,11 @@ vlan_trunk_capabilities(struct ifnet *ifp) VLAN_SUNLOCK(); return; } - TRUNK_WLOCK(trunk); + TRUNK_RLOCK(trunk); VLAN_FOREACH(ifv, trunk) { vlan_capabilities(ifv); } - TRUNK_WUNLOCK(trunk); + TRUNK_RUNLOCK(trunk); VLAN_SUNLOCK(); } @@ -1789,7 +1726,6 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct ifvlantrunk *trunk; struct vlanreq vlr; int error = 0; - VLAN_LOCK_READER; ifr = (struct ifreq *)data; ifa = (struct ifaddr *) data; @@ -1925,16 +1861,13 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * XXX We need the rmlock here to avoid sleeping while * holding in6_multi_mtx. */ - VLAN_RLOCK(); + VLAN_XLOCK(); trunk = TRUNK(ifv); - if (trunk != NULL) { - TRUNK_WLOCK(trunk); + if (trunk != NULL) error = vlan_setmulti(ifp); - TRUNK_WUNLOCK(trunk); - } - VLAN_RUNLOCK(); - break; + VLAN_XUNLOCK(); + break; case SIOCGVLANPCP: #ifdef VIMAGE if (ifp->if_vnet != ifp->if_home_vnet) { @@ -1971,9 +1904,9 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) ifv->ifv_capenable = ifr->ifr_reqcap; trunk = TRUNK(ifv); if (trunk != NULL) { - TRUNK_WLOCK(trunk); + TRUNK_RLOCK(trunk); vlan_capabilities(ifv); - TRUNK_WUNLOCK(trunk); + TRUNK_RUNLOCK(trunk); } VLAN_SUNLOCK(); break; From 5252d24a204bd142bf405dcf9fc763ca1fdda548 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu <lwhsu@FreeBSD.org> Date: Fri, 21 Sep 2018 07:36:02 +0000 Subject: [PATCH 062/139] Mention setting $lines to 0 in ddb can disable paging Reviewed by: bcr (earlier version), markj Approved by: re (kib), markj (mentor) MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17068 --- share/man/man4/ddb.4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/man/man4/ddb.4 b/share/man/man4/ddb.4 index aeec111adefe..188b5c8fc5ec 100644 --- a/share/man/man4/ddb.4 +++ b/share/man/man4/ddb.4 @@ -60,7 +60,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 20, 2018 +.Dd September 7, 2018 .Dt DDB 4 .Os .Sh NAME @@ -1280,6 +1280,7 @@ The width of the displayed line. .It Va lines The number of lines. It is used by the built-in pager. +Setting it to 0 disables paging. .It Va tabstops Tab stop width. .It Va work Ns Ar xx From c3afb29bb65fb372e2b892a4f486da1d3b9e2173 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= <des@FreeBSD.org> Date: Fri, 21 Sep 2018 09:27:32 +0000 Subject: [PATCH 063/139] Add an installer option to disable destructive dtrace. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Submitted by: Jörg Pernfuß <code.jpe@gmail.com> Approved by: re (kib) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D12474 --- usr.sbin/bsdinstall/scripts/hardening | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/usr.sbin/bsdinstall/scripts/hardening b/usr.sbin/bsdinstall/scripts/hardening index 1b82f8121753..9fea1b6aed5d 100755 --- a/usr.sbin/bsdinstall/scripts/hardening +++ b/usr.sbin/bsdinstall/scripts/hardening @@ -30,6 +30,7 @@ echo -n > $BSDINSTALL_TMPETC/rc.conf.hardening echo -n > $BSDINSTALL_TMPETC/sysctl.conf.hardening +echo -n > $BSDINSTALL_TMPBOOT/loader.conf.hardening exec 3>&1 FEATURES=$( dialog --backtitle "FreeBSD Installer" \ @@ -46,6 +47,7 @@ FEATURES=$( dialog --backtitle "FreeBSD Installer" \ "7 disable_syslogd" "Disable opening Syslogd network socket (disables remote logging)" ${disable_syslogd:-off} \ "8 disable_sendmail" "Disable Sendmail service" ${disable_sendmail:-off} \ "9 secure_console" "Enable console password prompt" ${secure_console:-off} \ + "10 disable_ddtrace" "Disallow DTrace destructive-mode" ${disable_ddtrace:-off} \ 2>&1 1>&3 ) exec 3>&- @@ -80,5 +82,8 @@ for feature in $FEATURES; do if [ "$feature" = "secure_console" ]; then sed "s/unknown off secure/unknown off insecure/g" $BSDINSTALL_CHROOT/etc/ttys > $BSDINSTALL_TMPETC/ttys.hardening fi + if [ "$feature" = "disable_ddtrace" ]; then + echo 'security.bsd.allow_destructive_dtrace=0' >> $BSDINSTALL_TMPBOOT/loader.conf.hardening + fi done From bb322680862c8eef7a6dae9e19f4e8dd52c52eba Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Fri, 21 Sep 2018 12:27:36 +0000 Subject: [PATCH 064/139] amd64: check for small size in memmove, memcpy and memset If the size is 15 bytes or less avoid spinning up rep just to copy the 8 bytes. In my tests on EPYC and old Intel microarchs without ERMS (like Westmere) it provided a nice win over the current version (e.g. for EPYC memset with 15 bytes of size goes from 59712651 ops/s to 70600095) all while almost not pessimizing the other cases. Data collected during package building shows that < 16 sizes are pretty common. Verified with the glibc test suite. Approved by: re (kib) --- sys/amd64/amd64/support.S | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 043110226e22..c7f0d9472b66 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -116,6 +116,8 @@ ENTRY(memmove_std) cmpq %rcx,%r8 /* overlapping && src < dst? */ jb 2f + cmpq $15,%rcx + jbe 1f shrq $3,%rcx /* copy by 64-bit words */ rep movsq @@ -124,6 +126,7 @@ ENTRY(memmove_std) jne 1f POP_FRAME_POINTER ret + ALIGN_TEXT 1: rep movsb @@ -191,6 +194,8 @@ ENTRY(memcpy_std) PUSH_FRAME_POINTER movq %rdi,%rax movq %rdx,%rcx + cmpq $15,%rcx + jbe 1f shrq $3,%rcx /* copy by 64-bit words */ rep movsq @@ -199,6 +204,7 @@ ENTRY(memcpy_std) jne 1f POP_FRAME_POINTER ret + ALIGN_TEXT 1: rep movsb @@ -227,6 +233,8 @@ ENTRY(memset_std) movzbq %sil,%r8 movabs $0x0101010101010101,%rax imulq %r8,%rax + cmpq $15,%rcx + jbe 1f shrq $3,%rcx rep stosq @@ -236,6 +244,7 @@ ENTRY(memset_std) movq %r9,%rax POP_FRAME_POINTER ret + ALIGN_TEXT 1: rep stosb From 18c00da8065d999152abd3ddd2dfd0bf156df113 Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Fri, 21 Sep 2018 13:02:25 +0000 Subject: [PATCH 065/139] remove double space between branch and version in kernel ident Reported by: dim Approved by: re (kib) Sponsored by: The FreeBSD Foundation --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index e784b373150e..9603de313ecf 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -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}" VERSTR="${VERINFO}\\n" else VERINFO="${VERSION} #${v}${svn}${git}${hg}${p4version}: ${t}" From d6fda03a64403a2e10340a3b29f898461962fe5b Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Fri, 21 Sep 2018 13:20:41 +0000 Subject: [PATCH 066/139] select: stop doing zero-sized memsets Approved by: re (kib) --- sys/kern/sys_generic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 649cfb191b7f..455220c36752 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1031,8 +1031,9 @@ kern_select(struct thread *td, int nd, fd_set *fd_in, fd_set *fd_ou, error = copyin(name, ibits[x], ncpubytes); \ if (error != 0) \ goto done; \ - bzero((char *)ibits[x] + ncpubytes, \ - ncpbytes - ncpubytes); \ + if (ncpbytes != ncpubytes) \ + bzero((char *)ibits[x] + ncpubytes, \ + ncpbytes - ncpubytes); \ } \ } while (0) getbits(fd_in, 0); From f789d9839a1e38854616c1bc789f715196cecbf8 Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Fri, 21 Sep 2018 13:43:06 +0000 Subject: [PATCH 067/139] Include kernel ident in uname In non-reproducible mode we have the kernel ident as a side effect of including the build directory. Explicitly add it to the ident string in reproducible mode. Reported by: mjg Approved by: re (gjb) Sponsored by: The FreeBSD Foundation --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 9603de313ecf..db6f66d7c52c 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -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}" From 50f5c94edb1746add6a9fdbf2d3c323430836c11 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" <ae@FreeBSD.org> Date: Fri, 21 Sep 2018 13:44:05 +0000 Subject: [PATCH 068/139] Fix possible NULL pointer dereference in ffec_alloc_mbufcl(). PR: 231514 Approved by: re (kib) MFC after: 1 week --- sys/dev/ffec/if_ffec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/ffec/if_ffec.c b/sys/dev/ffec/if_ffec.c index ea291ab8df2d..d52bf9a4e3d5 100644 --- a/sys/dev/ffec/if_ffec.c +++ b/sys/dev/ffec/if_ffec.c @@ -801,7 +801,8 @@ ffec_alloc_mbufcl(struct ffec_softc *sc) struct mbuf *m; m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); - m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; + if (m != NULL) + m->m_pkthdr.len = m->m_len = m->m_ext.ext_size; return (m); } From 68c7542edfe81f74ac57cf5b09c5bc872754c462 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Fri, 21 Sep 2018 15:00:46 +0000 Subject: [PATCH 069/139] amd64: even up copyin/copyout with memcpy + other cleanup - _fault handlers for both primitives are identical, provide just one - change the copying scheme to match memcpy (in particular jump avoidance for the most common case of multiply of 8) - stop re-reading pcb address on exit, just store it locally (in r9) Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17265 --- sys/amd64/amd64/support.S | 56 +++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index c7f0d9472b66..ee4c6ee3dd5d 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -309,9 +309,9 @@ END(fillw) */ .macro COPYOUT smap erms PUSH_FRAME_POINTER - movq PCPU(CURPCB),%rax + movq PCPU(CURPCB),%r9 /* Trap entry clears PSL.AC */ - movq $copyout_fault,PCB_ONFAULT(%rax) + movq $copy_fault,PCB_ONFAULT(%r9) testq %rdx,%rdx /* anything to do? */ jz 2f @@ -327,7 +327,7 @@ END(fillw) */ 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 @@ -336,7 +336,7 @@ END(fillw) */ movq $VM_MAXUSER_ADDRESS,%rcx cmpq %rcx,%rax - ja copyout_fault + ja copy_fault xchgq %rdi,%rsi /* bcopy(%rsi, %rdi, %rdx) */ @@ -344,21 +344,27 @@ END(fillw) SMAP_DISABLE \smap .if \erms == 0 + cmpq $15,%rcx + jbe 1f shrq $3,%rcx rep movsq movb %dl,%cl andb $7,%cl - je 1f + jne 1f + SMAP_ENABLE \smap + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r9) + POP_FRAME_POINTER + ret .endif +1: rep movsb -1: SMAP_ENABLE \smap 2: xorl %eax,%eax - movq PCPU(CURPCB),%rdx - movq %rax,PCB_ONFAULT(%rdx) + movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret .endmacro @@ -379,22 +385,14 @@ ENTRY(copyout_smap_erms) COPYOUT smap=1 erms=1 END(copyout_smap_erms) - ALIGN_TEXT -copyout_fault: - movq PCPU(CURPCB),%rdx - movq $0,PCB_ONFAULT(%rdx) - movq $EFAULT,%rax - POP_FRAME_POINTER - ret - /* * copyin(from_user, to_kernel, len) * %rdi, %rsi, %rdx */ .macro COPYIN smap erms PUSH_FRAME_POINTER - movq PCPU(CURPCB),%rax - movq $copyin_fault,PCB_ONFAULT(%rax) + movq PCPU(CURPCB),%r9 + movq $copy_fault,PCB_ONFAULT(%r9) testq %rdx,%rdx /* anything to do? */ jz 2f @@ -403,10 +401,10 @@ copyout_fault: */ 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 %rdx,%rcx @@ -414,22 +412,28 @@ copyout_fault: SMAP_DISABLE \smap .if \erms == 0 + cmpq $15,%rcx + jbe 1f shrq $3,%rcx /* copy longword-wise */ rep movsq movb %al,%cl andb $7,%cl /* copy remaining bytes */ - je 1f + jne 1f + SMAP_ENABLE \smap + xorl %eax,%eax + movq %rax,PCB_ONFAULT(%r9) + POP_FRAME_POINTER + ret .endif +1: rep movsb -1: SMAP_ENABLE \smap 2: xorl %eax,%eax - movq PCPU(CURPCB),%rdx - movq %rax,PCB_ONFAULT(%rdx) + movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret .endmacro @@ -451,10 +455,10 @@ ENTRY(copyin_smap_erms) END(copyin_smap_erms) ALIGN_TEXT -copyin_fault: +copy_fault: movq PCPU(CURPCB),%rdx movq $0,PCB_ONFAULT(%rdx) - movq $EFAULT,%rax + movl $EFAULT,%eax POP_FRAME_POINTER ret From 397358d9aca10667451f7667852bee2f27b617c0 Mon Sep 17 00:00:00 2001 From: Brooks Davis <brooks@FreeBSD.org> Date: Fri, 21 Sep 2018 17:44:05 +0000 Subject: [PATCH 070/139] Disable sbrk() use in GNU tools. We're studing the possibility of deprecating sbrk(). To make it easier we're removing unnecessicary uses in the base system. None of these tools require sbrk(), but they agressively prefer it for no good reason. Reviewed by: andrew Approved by: re (kib) Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D16141 --- gnu/usr.bin/binutils/as/config.h | 2 +- gnu/usr.bin/binutils/ld/config.h | 2 +- gnu/usr.bin/binutils/libbinutils/config.h | 2 +- gnu/usr.bin/binutils/libiberty/config.h | 2 +- gnu/usr.bin/cc/libiberty/config.h | 2 +- gnu/usr.bin/gdb/arch/amd64/config.h | 2 +- gnu/usr.bin/gdb/arch/arm/config.h | 2 +- gnu/usr.bin/gdb/arch/i386/config.h | 2 +- gnu/usr.bin/gdb/arch/mips/config.h | 2 +- gnu/usr.bin/gdb/arch/powerpc/config.h | 2 +- gnu/usr.bin/gdb/arch/powerpc64/config.h | 2 +- gnu/usr.bin/gdb/arch/sparc64/config.h | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gnu/usr.bin/binutils/as/config.h b/gnu/usr.bin/binutils/as/config.h index 9723ac77ece0..84cd51590e58 100644 --- a/gnu/usr.bin/binutils/as/config.h +++ b/gnu/usr.bin/binutils/as/config.h @@ -69,7 +69,7 @@ /* #undef HAVE_REMOVE */ /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the <stdarg.h> header file. */ #define HAVE_STDARG_H 1 diff --git a/gnu/usr.bin/binutils/ld/config.h b/gnu/usr.bin/binutils/ld/config.h index 42a7f778cf6c..ac9a78d729de 100644 --- a/gnu/usr.bin/binutils/ld/config.h +++ b/gnu/usr.bin/binutils/ld/config.h @@ -65,7 +65,7 @@ #define HAVE_REALPATH 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the <stdint.h> header file. */ #define HAVE_STDINT_H 1 diff --git a/gnu/usr.bin/binutils/libbinutils/config.h b/gnu/usr.bin/binutils/libbinutils/config.h index 873ae5b1e4b1..5c457f1eeaff 100644 --- a/gnu/usr.bin/binutils/libbinutils/config.h +++ b/gnu/usr.bin/binutils/libbinutils/config.h @@ -104,7 +104,7 @@ #define HAVE_MKSTEMP 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the `setmode' function. */ #define HAVE_SETMODE 1 diff --git a/gnu/usr.bin/binutils/libiberty/config.h b/gnu/usr.bin/binutils/libiberty/config.h index 2b00517fb17c..4361330c7f1f 100644 --- a/gnu/usr.bin/binutils/libiberty/config.h +++ b/gnu/usr.bin/binutils/libiberty/config.h @@ -188,7 +188,7 @@ #define HAVE_RINDEX 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/cc/libiberty/config.h b/gnu/usr.bin/cc/libiberty/config.h index 236e07689498..5a99758f8635 100644 --- a/gnu/usr.bin/cc/libiberty/config.h +++ b/gnu/usr.bin/cc/libiberty/config.h @@ -187,7 +187,7 @@ #define HAVE_RINDEX 1 /* Define to 1 if you have the `sbrk' function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/amd64/config.h b/gnu/usr.bin/gdb/arch/amd64/config.h index 674f81854935..6908c793ece9 100644 --- a/gnu/usr.bin/gdb/arch/amd64/config.h +++ b/gnu/usr.bin/gdb/arch/amd64/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/arm/config.h b/gnu/usr.bin/gdb/arch/arm/config.h index b2481f8b2a0d..863f2d9c701b 100644 --- a/gnu/usr.bin/gdb/arch/arm/config.h +++ b/gnu/usr.bin/gdb/arch/arm/config.h @@ -239,7 +239,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/i386/config.h b/gnu/usr.bin/gdb/arch/i386/config.h index e849e0ad078d..3f7f579433d5 100644 --- a/gnu/usr.bin/gdb/arch/i386/config.h +++ b/gnu/usr.bin/gdb/arch/i386/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/mips/config.h b/gnu/usr.bin/gdb/arch/mips/config.h index 2b375a6f0cd2..c0b04cc5e550 100644 --- a/gnu/usr.bin/gdb/arch/mips/config.h +++ b/gnu/usr.bin/gdb/arch/mips/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/powerpc/config.h b/gnu/usr.bin/gdb/arch/powerpc/config.h index 37416a75593d..8686a99d1f56 100644 --- a/gnu/usr.bin/gdb/arch/powerpc/config.h +++ b/gnu/usr.bin/gdb/arch/powerpc/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/powerpc64/config.h b/gnu/usr.bin/gdb/arch/powerpc64/config.h index 58843fbb7417..6ec6560e4200 100644 --- a/gnu/usr.bin/gdb/arch/powerpc64/config.h +++ b/gnu/usr.bin/gdb/arch/powerpc64/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 diff --git a/gnu/usr.bin/gdb/arch/sparc64/config.h b/gnu/usr.bin/gdb/arch/sparc64/config.h index 974e4264d201..8bcfdb28c8f5 100644 --- a/gnu/usr.bin/gdb/arch/sparc64/config.h +++ b/gnu/usr.bin/gdb/arch/sparc64/config.h @@ -227,7 +227,7 @@ #define HAVE_REALPATH 1 /* Define if you have the sbrk function. */ -#define HAVE_SBRK 1 +/* #undef HAVE_SBRK */ /* Define if you have the setenv function. */ #define HAVE_SETENV 1 From 35d1666cbb67c30d0daa99e955d1ecb1756fe1d5 Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Fri, 21 Sep 2018 17:49:37 +0000 Subject: [PATCH 071/139] libc: require ifunc-capable linker for amd64/i386 We expect to introduce optimized libc routines in the near future, which requires use of a linker that supports ifuncs. Approved by: re (gjb, kib) Sponsored by: The FreeBSD Foundation --- lib/libc/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/libc/Makefile b/lib/libc/Makefile index f82a5b190a22..a1ce123c0f33 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -21,6 +21,11 @@ LIBC_ARCH=${MACHINE_ARCH} LIBC_ARCH=${MACHINE_CPUARCH} .endif +.if (${LIBC_ARCH} == amd64 || ${LIBC_ARCH} == i386) && \ + defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" +.error ${LIBC_ARCH} libc requires linker ifunc support +.endif + # All library objects contain FreeBSD revision strings by default; they may be # excluded as a space-saving measure. To produce a library that does # not contain these strings, add -DSTRIP_FBSDID (see <sys/cdefs.h>) to CFLAGS From d995b5b1ea85a0a584a258a75aae47f220d6a4cd Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Fri, 21 Sep 2018 17:53:06 +0000 Subject: [PATCH 072/139] Convert x86 TLB top-level invalidation functions to ifuncs. Note that shootdown IPI handlers are already per-mode. Suggested by: alc Reviewed by: alc, markj Tested by: pho Sponsored by: The FreeBSD Foundation Approved by: re (gjb) Differential revision: https://reviews.freebsd.org/D17184 --- sys/amd64/amd64/pmap.c | 377 ++++++++++++++++++++++++++--------------- 1 file changed, 240 insertions(+), 137 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d4d91e7c23a9..cb3625138a6e 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1704,15 +1704,94 @@ pmap_invalidate_ept(pmap_t pmap) sched_unpin(); } -void -pmap_invalidate_page(pmap_t pmap, vm_offset_t va) +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) +{ + cpuset_t *mask; + if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); return; @@ -1726,52 +1805,9 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va) 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(); - } + pmap_invalidate_page_mode(pmap, va); mask = &pmap->pm_active; } smp_masked_invlpg(*mask, va, pmap); @@ -1781,15 +1817,81 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va) /* 4k PTEs -- Chosen to exceed the total size of Broadwell L2 TLB */ #define PMAP_INVLPG_THRESHOLD (4 * 1024 * PAGE_SIZE) +static void +pmap_invalidate_range_pcid(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, + const bool invpcid_works1) +{ + 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) { + 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) { cpuset_t *mask; - struct invpcid_descr d; vm_offset_t addr; - uint64_t kcr3, ucr3; - uint32_t pcid; - u_int cpuid, i; if (eva - sva >= PMAP_INVLPG_THRESHOLD) { pmap_invalidate_all(pmap); @@ -1805,7 +1907,6 @@ 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); @@ -1814,52 +1915,103 @@ pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) 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(); } + pmap_invalidate_range_mode(pmap, sva, eva); mask = &pmap->pm_active; } smp_masked_invlpg_range(*mask, sva, eva, pmap); sched_unpin(); } -void -pmap_invalidate_all(pmap_t pmap) +static inline void +pmap_invalidate_all_pcid(pmap_t pmap, bool invpcid_works1) { - cpuset_t *mask; struct invpcid_descr d; uint64_t kcr3, ucr3; uint32_t pcid; u_int cpuid, i; + if (pmap == 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; + if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); return; @@ -1869,57 +2021,8 @@ pmap_invalidate_all(pmap_t pmap) ("pmap_invalidate_all: invalid type %d", pmap->pm_type)); sched_pin(); - if (pmap == kernel_pmap) { - if (pmap_pcid_enabled && invpcid_works) { - bzero(&d, sizeof(d)); - invpcid(&d, INVPCID_CTXGLOB); - } else { - invltlb_glob(); - } - mask = &all_cpus; - } else { - cpuid = PCPU_GET(cpuid); - if (pmap == PCPU_GET(curpmap)) { - if (pmap_pcid_enabled) { - critical_enter(); - pcid = pmap->pm_pcids[cpuid].pm_pcid; - if (invpcid_works) { - d.pcid = pcid; - d.pad = 0; - d.addr = 0; - invpcid(&d, INVPCID_CTX); - if (pmap->pm_ucr3 != PMAP_NO_CR3) { - d.pcid |= PMAP_PCID_USER_PT; - invpcid(&d, INVPCID_CTX); - } - } else { - kcr3 = pmap->pm_cr3 | pcid; - ucr3 = pmap->pm_ucr3; - if (ucr3 != PMAP_NO_CR3) { - ucr3 |= pcid | PMAP_PCID_USER_PT; - pmap_pti_pcid_invalidate(ucr3, - kcr3); - } else { - load_cr3(kcr3); - } - } - critical_exit(); - } else { - invltlb(); - } - } else if (pmap_pcid_enabled) { - pmap->pm_pcids[cpuid].pm_gen = 0; - } - if (pmap_pcid_enabled) { - CPU_FOREACH(i) { - if (cpuid != i) - pmap->pm_pcids[i].pm_gen = 0; - } - /* See the comment in pmap_invalidate_page(). */ - atomic_thread_fence_seq_cst(); - } - mask = &pmap->pm_active; - } + mask = pmap == kernel_pmap ? &all_cpus : &pmap->pm_active; + pmap_invalidate_all_mode(pmap); smp_masked_invltlb(*mask, pmap); sched_unpin(); } From 6cdde6fda2805b6003dd4d2b79ffb92151421455 Mon Sep 17 00:00:00 2001 From: Mark Johnston <markj@FreeBSD.org> Date: Fri, 21 Sep 2018 20:20:03 +0000 Subject: [PATCH 073/139] Use the GNU as-compatible .endm instead of .endmacro. Approved by: re (gjb) --- sys/amd64/amd64/support.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index ee4c6ee3dd5d..7d580b67656a 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -294,14 +294,14 @@ END(fillw) .if \smap stac .endif -.endmacro +.endm .macro SMAP_ENABLE smap .if \smap clac .endif -.endmacro +.endm /* * copyout(from_kernel, to_user, len) @@ -367,7 +367,7 @@ END(fillw) movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret -.endmacro +.endm ENTRY(copyout_nosmap_std) COPYOUT smap=0 erms=0 @@ -436,7 +436,7 @@ END(copyout_smap_erms) movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret -.endmacro +.endm ENTRY(copyin_nosmap_std) COPYIN smap=0 erms=0 From 81347f19407b91e0597495ed5eb7a57f516b2467 Mon Sep 17 00:00:00 2001 From: Alexander Motin <mav@FreeBSD.org> Date: Fri, 21 Sep 2018 20:34:26 +0000 Subject: [PATCH 074/139] 9672 Reserve a ZFS replication stream feature flag for ZSTD compression illumos/illumos-gate@acd7f809f0376580771fe4df8aaeecebe4c40b2f Author: Allan Jude <allanjude@freebsd.org> Reviewed by: Matt Ahrens <matt@delphix.com> Approved by: Robert Mustacchi <rm@joyent.com> --- uts/common/fs/zfs/sys/zfs_ioctl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uts/common/fs/zfs/sys/zfs_ioctl.h b/uts/common/fs/zfs/sys/zfs_ioctl.h index 03f62c0f09a0..f3df29218d41 100644 --- a/uts/common/fs/zfs/sys/zfs_ioctl.h +++ b/uts/common/fs/zfs/sys/zfs_ioctl.h @@ -94,6 +94,8 @@ typedef enum drr_headertype { /* flag #21 is reserved for a Delphix feature */ #define DMU_BACKUP_FEATURE_COMPRESSED (1 << 22) /* flag #23 is reserved for the large dnode feature */ +/* flag #24 is reserved for the raw send feature */ +/* flag #25 is reserved for the ZSTD compression feature */ /* * Mask of all supported backup features From e8551db9502c10ea24bfa13d42b301a2fd28e08c Mon Sep 17 00:00:00 2001 From: Alexander Motin <mav@FreeBSD.org> Date: Fri, 21 Sep 2018 20:36:26 +0000 Subject: [PATCH 075/139] 9626 move 'static xuio_stats_t xuio_stats' to file where it use illumos/illumos-gate@857c96d257470e097e846ab8886580991b329c32 Reviewed by: Yuri Pankov <yuripv@yuripv.net> Reviewed by: Matthew Ahrens <mahrens@delphix.com> Approved by: Dan McDonald <danmcd@joyent.com> Author: Igor Kozhukhov <igor@dilos.org> --- uts/common/fs/zfs/dmu.c | 24 ++++++++++++++++++++---- uts/common/fs/zfs/sys/dmu_impl.h | 14 +------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/uts/common/fs/zfs/dmu.c b/uts/common/fs/zfs/dmu.c index 15123f347b61..23b1c52212c7 100644 --- a/uts/common/fs/zfs/dmu.c +++ b/uts/common/fs/zfs/dmu.c @@ -20,11 +20,14 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2011, 2017 by Delphix. All rights reserved. */ -/* Copyright (c) 2013 by Saso Kiselkov. All rights reserved. */ -/* Copyright (c) 2013, Joyent, Inc. All rights reserved. */ -/* Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ +/* + * Copyright (c) 2013 by Saso Kiselkov. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. + * Copyright (c) 2011, 2017 by Delphix. All rights reserved. + * Copyright (c) 2018 DilOS + */ #include <sys/dmu.h> #include <sys/dmu_impl.h> @@ -52,6 +55,19 @@ #include <sys/zfs_znode.h> #endif +static xuio_stats_t xuio_stats = { + { "onloan_read_buf", KSTAT_DATA_UINT64 }, + { "onloan_write_buf", KSTAT_DATA_UINT64 }, + { "read_buf_copied", KSTAT_DATA_UINT64 }, + { "read_buf_nocopy", KSTAT_DATA_UINT64 }, + { "write_buf_copied", KSTAT_DATA_UINT64 }, + { "write_buf_nocopy", KSTAT_DATA_UINT64 } +}; + +#define XUIOSTAT_INCR(stat, val) \ + atomic_add_64(&xuio_stats.stat.value.ui64, (val)) +#define XUIOSTAT_BUMP(stat) XUIOSTAT_INCR(stat, 1) + /* * Enable/disable nopwrite feature. */ diff --git a/uts/common/fs/zfs/sys/dmu_impl.h b/uts/common/fs/zfs/sys/dmu_impl.h index d0636b756067..0930be6a8506 100644 --- a/uts/common/fs/zfs/sys/dmu_impl.h +++ b/uts/common/fs/zfs/sys/dmu_impl.h @@ -25,6 +25,7 @@ /* * Copyright (c) 2012, Joyent, Inc. All rights reserved. * Copyright (c) 2013, 2015 by Delphix. All rights reserved. + * Copyright (c) 2018 DilOS */ #ifndef _SYS_DMU_IMPL_H @@ -254,19 +255,6 @@ typedef struct xuio_stats { kstat_named_t xuiostat_wbuf_nocopy; } xuio_stats_t; -static xuio_stats_t xuio_stats = { - { "onloan_read_buf", KSTAT_DATA_UINT64 }, - { "onloan_write_buf", KSTAT_DATA_UINT64 }, - { "read_buf_copied", KSTAT_DATA_UINT64 }, - { "read_buf_nocopy", KSTAT_DATA_UINT64 }, - { "write_buf_copied", KSTAT_DATA_UINT64 }, - { "write_buf_nocopy", KSTAT_DATA_UINT64 } -}; - -#define XUIOSTAT_INCR(stat, val) \ - atomic_add_64(&xuio_stats.stat.value.ui64, (val)) -#define XUIOSTAT_BUMP(stat) XUIOSTAT_INCR(stat, 1) - /* * The list of data whose inclusion in a send stream can be pending from * one call to backup_cb to another. Multiple calls to dump_free() and From 4cabda1b4daa904600d6699312955b40e2e2e5ab Mon Sep 17 00:00:00 2001 From: Alexander Motin <mav@FreeBSD.org> Date: Fri, 21 Sep 2018 20:38:23 +0000 Subject: [PATCH 076/139] 9700 ZFS resilvered mirror does not balance reads illumos/illumos-gate@82f63c3c2bf5e4378706e8dcfccf717d67371be9 Reviewed by: Toomas Soome <tsoome@me.com> Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com> Reviewed by: George Wilson <george.wilson@delphix.com> Approved by: Matthew Ahrens <mahrens@delphix.com> Author: Jerry Jelinek <jerry.jelinek@joyent.com> --- uts/common/fs/zfs/spa.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/uts/common/fs/zfs/spa.c b/uts/common/fs/zfs/spa.c index b71710bbd7c5..599ae9faded9 100644 --- a/uts/common/fs/zfs/spa.c +++ b/uts/common/fs/zfs/spa.c @@ -27,7 +27,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. */ @@ -6535,6 +6535,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]; @@ -6556,6 +6557,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 From 1e16837679d4defbd8a872db748ef328158461ec Mon Sep 17 00:00:00 2001 From: Navdeep Parhar <np@FreeBSD.org> Date: Fri, 21 Sep 2018 23:48:40 +0000 Subject: [PATCH 077/139] cxgbetool(8): The VLAN tag provided in the action for a filter must be prefixed with either '=' or '+'. Fix the description of the parameter in the man page while here. Approved by: re@ (kib@) Sponsored by: Chelsio Communications --- usr.sbin/cxgbetool/cxgbetool.8 | 8 ++++---- usr.sbin/cxgbetool/cxgbetool.c | 9 +-------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/usr.sbin/cxgbetool/cxgbetool.8 b/usr.sbin/cxgbetool/cxgbetool.8 index 9e131368a0fa..e6b3d2847c75 100644 --- a/usr.sbin/cxgbetool/cxgbetool.8 +++ b/usr.sbin/cxgbetool/cxgbetool.8 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Sep 18, 2018 +.Dd Sep 21, 2018 .Dt CXGBETOOL 8 .Os .Sh NAME @@ -450,11 +450,11 @@ eport. .It Cm vlan Insert, remove, or rewrite the VLAN tag before switching the packet out of eport. -.Cm vlan=none +.Cm none removes the tag, -.Cm vlan= Ns Ar tag +.Cm = Ns Ar tag replaces the existing tag with the one provided, and -.Cm vlan=+ Ns Ar tag +.Cm + Ns Ar tag inserts the given tag into the frame. .It Cm nat Specify the desired NAT mode. Valid NAT modes values are: diff --git a/usr.sbin/cxgbetool/cxgbetool.c b/usr.sbin/cxgbetool/cxgbetool.c index be76948d4f01..a67e863ad1da 100644 --- a/usr.sbin/cxgbetool/cxgbetool.c +++ b/usr.sbin/cxgbetool/cxgbetool.c @@ -1327,17 +1327,10 @@ set_filter(uint32_t idx, int argc, const char *argv[], int hash) t.fs.newvlan = VLAN_REWRITE; } else if (argv[start_arg + 1][0] == '+') { t.fs.newvlan = VLAN_INSERT; - } else if (isdigit(argv[start_arg + 1][0]) && - !parse_val_mask("vlan", args, &val, &mask, hash)) { - t.fs.val.vlan = val; - t.fs.mask.vlan = mask; - t.fs.val.vlan_vld = 1; - t.fs.mask.vlan_vld = 1; } else { warnx("unknown vlan parameter \"%s\"; must" " be one of \"none\", \"=<vlan>\", " - " \"+<vlan>\", or \"<vlan>\"", - argv[start_arg + 1]); + " \"+<vlan>\"", argv[start_arg + 1]); return (EINVAL); } if (t.fs.newvlan == VLAN_REWRITE || From 061bbaf7e7fe46b3229bab050b604c27bde6becd Mon Sep 17 00:00:00 2001 From: Navdeep Parhar <np@FreeBSD.org> Date: Sat, 22 Sep 2018 01:24:30 +0000 Subject: [PATCH 078/139] cxgbe(4): Reuse existing "switching" L2T entries when possible. Approved by: re@ (rgrimes@) Sponsored by: Chelsio Communications --- sys/dev/cxgbe/t4_filter.c | 61 +++++++++--------------- sys/dev/cxgbe/t4_l2t.c | 97 ++++++++++++++++++++++++++------------- sys/dev/cxgbe/t4_l2t.h | 3 +- 3 files changed, 89 insertions(+), 72 deletions(-) diff --git a/sys/dev/cxgbe/t4_filter.c b/sys/dev/cxgbe/t4_filter.c index fe26b47566e1..4f325bdd235d 100644 --- a/sys/dev/cxgbe/t4_filter.c +++ b/sys/dev/cxgbe/t4_filter.c @@ -593,13 +593,8 @@ set_tcamfilter(struct adapter *sc, struct t4_filter *t, struct l2t_entry *l2te, } } mtx_unlock(&sc->tids.ftid_lock); - if (rc != 0) { - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); + if (rc != 0) return (rc); - } /* * Can't fail now. A set-filter WR will definitely be sent. @@ -817,8 +812,8 @@ int set_filter(struct adapter *sc, struct t4_filter *t) { struct tid_info *ti = &sc->tids; - struct l2t_entry *l2te; - struct smt_entry *smt; + struct l2t_entry *l2te = NULL; + struct smt_entry *smt = NULL; uint64_t ftuple; int rc; @@ -942,43 +937,41 @@ set_filter(struct adapter *sc, struct t4_filter *t) * Allocate L2T entry, SMT entry, etc. */ - l2te = NULL; if (t->fs.newdmac || t->fs.newvlan) { /* This filter needs an L2T entry; allocate one. */ - l2te = t4_l2t_alloc_switching(sc->l2t); - if (__predict_false(l2te == NULL)) - return (EAGAIN); - rc = t4_l2t_set_switching(sc, l2te, t->fs.vlan, t->fs.eport, + l2te = t4_l2t_alloc_switching(sc, t->fs.vlan, t->fs.eport, t->fs.dmac); - if (rc) { - t4_l2t_release(l2te); - return (ENOMEM); + if (__predict_false(l2te == NULL)) { + rc = EAGAIN; + goto error; } } - smt = NULL; if (t->fs.newsmac) { /* This filter needs an SMT entry; allocate one. */ smt = t4_smt_alloc_switching(sc->smt, t->fs.smac); if (__predict_false(smt == NULL)) { - if (l2te != NULL) - t4_l2t_release(l2te); - return (EAGAIN); + rc = EAGAIN; + goto error; } rc = t4_smt_set_switching(sc, smt, 0x0, t->fs.smac); - if (rc) { - t4_smt_release(smt); - if (l2te != NULL) - t4_l2t_release(l2te); - return (rc); - } + if (rc) + goto error; } if (t->fs.hash) - return (set_hashfilter(sc, t, ftuple, l2te, smt)); + rc = set_hashfilter(sc, t, ftuple, l2te, smt); else - return (set_tcamfilter(sc, t, l2te, smt)); + rc = set_tcamfilter(sc, t, l2te, smt); + if (rc != 0 && rc != EINPROGRESS) { +error: + if (l2te) + t4_l2t_release(l2te); + if (smt) + t4_smt_release(smt); + } + return (rc); } static int @@ -1552,10 +1545,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple, f = malloc(sizeof(*f), M_CXGBE, M_ZERO | M_NOWAIT); if (__predict_false(f == NULL)) { - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); rc = ENOMEM; goto done; } @@ -1565,10 +1554,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple, atid = alloc_atid(sc, f); if (__predict_false(atid) == -1) { - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); free(f, M_CXGBE); rc = EAGAIN; goto done; @@ -1579,10 +1564,6 @@ set_hashfilter(struct adapter *sc, struct t4_filter *t, uint64_t ftuple, &cookie); if (wr == NULL) { free_atid(sc, atid); - if (l2te) - t4_l2t_release(l2te); - if (smt) - t4_smt_release(smt); free(f, M_CXGBE); rc = ENOMEM; goto done; diff --git a/sys/dev/cxgbe/t4_l2t.c b/sys/dev/cxgbe/t4_l2t.c index 22e84d320aa2..5e96579f1717 100644 --- a/sys/dev/cxgbe/t4_l2t.c +++ b/sys/dev/cxgbe/t4_l2t.c @@ -108,6 +108,44 @@ t4_alloc_l2e(struct l2t_data *d) return (e); } +static struct l2t_entry * +find_or_alloc_l2e(struct l2t_data *d, uint16_t vlan, uint8_t port, uint8_t *dmac) +{ + struct l2t_entry *end, *e, **p; + struct l2t_entry *first_free = NULL; + + for (e = &d->l2tab[0], end = &d->l2tab[d->l2t_size]; e != end; ++e) { + if (atomic_load_acq_int(&e->refcnt) == 0) { + if (!first_free) + first_free = e; + } else if (e->state == L2T_STATE_SWITCHING && + memcmp(e->dmac, dmac, ETHER_ADDR_LEN) == 0 && + e->vlan == vlan && e->lport == port) + return (e); /* Found existing entry that matches. */ + } + + if (first_free == NULL) + return (NULL); /* No match and no room for a new entry. */ + + /* + * The entry we found may be an inactive entry that is + * presently in the hash table. We need to remove it. + */ + e = first_free; + if (e->state < L2T_STATE_SWITCHING) { + for (p = &d->l2tab[e->hash].first; *p; p = &(*p)->next) { + if (*p == e) { + *p = e->next; + e->next = NULL; + break; + } + } + } + e->state = L2T_STATE_UNUSED; + return (e); +} + + /* * Write an L2T entry. Must be called with the entry locked. * The write may be synchronous or asynchronous. @@ -154,41 +192,38 @@ t4_write_l2e(struct l2t_entry *e, int sync) * address resolution updates do not see them. */ struct l2t_entry * -t4_l2t_alloc_switching(struct l2t_data *d) +t4_l2t_alloc_switching(struct adapter *sc, uint16_t vlan, uint8_t port, + uint8_t *eth_addr) { + struct l2t_data *d = sc->l2t; struct l2t_entry *e; - - rw_wlock(&d->lock); - e = t4_alloc_l2e(d); - if (e) { - mtx_lock(&e->lock); /* avoid race with t4_l2t_free */ - e->state = L2T_STATE_SWITCHING; - atomic_store_rel_int(&e->refcnt, 1); - mtx_unlock(&e->lock); - } - rw_wunlock(&d->lock); - return e; -} - -/* - * Sets/updates the contents of a switching L2T entry that has been allocated - * with an earlier call to @t4_l2t_alloc_switching. - */ -int -t4_l2t_set_switching(struct adapter *sc, struct l2t_entry *e, uint16_t vlan, - uint8_t port, uint8_t *eth_addr) -{ int rc; - e->vlan = vlan; - e->lport = port; - e->wrq = &sc->sge.ctrlq[0]; - e->iqid = sc->sge.fwq.abs_id; - memcpy(e->dmac, eth_addr, ETHER_ADDR_LEN); - mtx_lock(&e->lock); - rc = t4_write_l2e(e, 0); - mtx_unlock(&e->lock); - return (rc); + rw_wlock(&d->lock); + e = find_or_alloc_l2e(d, vlan, port, eth_addr); + if (e) { + if (atomic_load_acq_int(&e->refcnt) == 0) { + mtx_lock(&e->lock); /* avoid race with t4_l2t_free */ + e->wrq = &sc->sge.ctrlq[0]; + e->iqid = sc->sge.fwq.abs_id; + e->state = L2T_STATE_SWITCHING; + e->vlan = vlan; + e->lport = port; + memcpy(e->dmac, eth_addr, ETHER_ADDR_LEN); + atomic_store_rel_int(&e->refcnt, 1); + atomic_subtract_int(&d->nfree, 1); + rc = t4_write_l2e(e, 0); + mtx_unlock(&e->lock); + if (rc != 0) + e = NULL; + } else { + MPASS(e->vlan == vlan); + MPASS(e->lport == port); + atomic_add_int(&e->refcnt, 1); + } + } + rw_wunlock(&d->lock); + return (e); } int diff --git a/sys/dev/cxgbe/t4_l2t.h b/sys/dev/cxgbe/t4_l2t.h index 21c392018fe8..188669e80261 100644 --- a/sys/dev/cxgbe/t4_l2t.h +++ b/sys/dev/cxgbe/t4_l2t.h @@ -91,7 +91,8 @@ struct l2t_data { int t4_init_l2t(struct adapter *, int); int t4_free_l2t(struct l2t_data *); struct l2t_entry *t4_alloc_l2e(struct l2t_data *); -struct l2t_entry *t4_l2t_alloc_switching(struct l2t_data *); +struct l2t_entry *t4_l2t_alloc_switching(struct adapter *, uint16_t, uint8_t, + uint8_t *); int t4_l2t_set_switching(struct adapter *, struct l2t_entry *, uint16_t, uint8_t, uint8_t *); int t4_write_l2e(struct l2t_entry *, int); From 334107b91b349741a2ffc5d9788a51fd8ab43156 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Sat, 22 Sep 2018 11:39:30 +0000 Subject: [PATCH 079/139] vfs: __predict common case in VFS_EPILOGUE/PROLOGUE NFS is the only in-tree filesystem using the feature, but all ops test for it. Currently the resulting sigdefer calls have to be jumped over in the common case. This is a bandaid, longer term fix will move this feature away. Approved by: re (kib) --- sys/sys/signalvar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h index 3b5f750db5c9..c6c7d083cefb 100644 --- a/sys/sys/signalvar.h +++ b/sys/sys/signalvar.h @@ -349,7 +349,7 @@ static inline int sigdeferstop(int mode) { - if (mode == SIGDEFERSTOP_NOP) + if (__predict_true(mode == SIGDEFERSTOP_NOP)) return (SIGDEFERSTOP_VAL_NCHG); return (sigdeferstop_impl(mode)); } @@ -358,7 +358,7 @@ static inline void sigallowstop(int prev) { - if (prev == SIGDEFERSTOP_VAL_NCHG) + if (__predict_true(prev == SIGDEFERSTOP_VAL_NCHG)) return; sigallowstop_impl(prev); } From 6c8e9a847122716ea09fef6fc7790d5be39004f6 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala <trasz@FreeBSD.org> Date: Sat, 22 Sep 2018 13:14:44 +0000 Subject: [PATCH 080/139] Improve loader passwords: 1. Be clear about which password is being requested 2. Remove extraneous whitespace between the prompt and the cursor 3. Move the twiddle to where the prompt is, instead of two characters to the right 4. Fix erasing the 'incorrect password' message when retrying; previously it was erased partially 5. Remove the unneeded exclamation mark Reviewed by: kevans Approved by: re (gjb) MFC after: 2 weeks Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D17236 --- stand/lua/password.lua | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/stand/lua/password.lua b/stand/lua/password.lua index 72466cbcadb6..4dfaf1a6525d 100644 --- a/stand/lua/password.lua +++ b/stand/lua/password.lua @@ -34,7 +34,7 @@ local screen = require("screen") local password = {} -local INCORRECT_PASSWORD = "loader: incorrect password!" +local INCORRECT_PASSWORD = "loader: incorrect password" -- Asterisks as a password mask local show_password_mask = false local twiddle_chars = {"/", "-", "\\", "|"} @@ -45,7 +45,7 @@ function password.read(prompt_length) local twiddle_pos = 1 local function draw_twiddle() - printc(" " .. twiddle_chars[twiddle_pos]) + printc(twiddle_chars[twiddle_pos]) -- Reset cursor to just after the password prompt screen.setcursor(prompt_length + 2, screen.default_y) twiddle_pos = (twiddle_pos % #twiddle_chars) + 1 @@ -87,20 +87,19 @@ function password.check() local attempts = 1 local function clear_incorrect_text_prompt() - printc("\n") - printc(string.rep(" ", #INCORRECT_PASSWORD)) + printc("\r" .. string.rep(" ", #INCORRECT_PASSWORD)) end while true do + if attempts > 1 then + clear_incorrect_text_prompt() + end screen.defcursor() printc(prompt) local read_pwd = password.read(#prompt) if pwd == nil or pwd == read_pwd then -- Clear the prompt + twiddle printc(string.rep(" ", #prompt + 5)) - if attempts > 1 then - clear_incorrect_text_prompt() - end return read_pwd end printc("\n" .. INCORRECT_PASSWORD) @@ -116,11 +115,11 @@ function password.check() end local boot_pwd = loader.getenv("bootlock_password") - compare("Boot password: ", boot_pwd) + compare("Bootlock password:", boot_pwd) local geli_prompt = loader.getenv("geom_eli_passphrase_prompt") if geli_prompt ~= nil and geli_prompt:lower() == "yes" then - local passphrase = doPrompt("GELI Passphrase: ") + local passphrase = doPrompt("GELI Passphrase:") loader.setenv("kern.geom.eli.passphrase", passphrase) end @@ -128,7 +127,7 @@ function password.check() if pwd ~= nil then core.autoboot() end - compare("Password: ", pwd) + compare("Loader password:", pwd) end return password From b8fdf588079d7bb8f45e1b894801870db00e6887 Mon Sep 17 00:00:00 2001 From: Brad Davis <brd@FreeBSD.org> Date: Sat, 22 Sep 2018 13:17:30 +0000 Subject: [PATCH 081/139] Move hosts.allow to lib/libwrap/ This leverages CONFS to handle the install. Approved by: re (blanket, pkgbase), bapt (mentor) Differential Revision: https://reviews.freebsd.org/D17240 --- etc/Makefile | 1 - lib/libwrap/Makefile | 1 + {etc => lib/libwrap}/hosts.allow | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {etc => lib/libwrap}/hosts.allow (100%) diff --git a/etc/Makefile b/etc/Makefile index 040849654cfa..df8f99e4c3de 100644 --- a/etc/Makefile +++ b/etc/Makefile @@ -14,7 +14,6 @@ SUBDIR+=sendmail BIN1= \ group \ - hosts.allow \ login.access \ rc.bsdextended \ rc.firewall \ diff --git a/lib/libwrap/Makefile b/lib/libwrap/Makefile index 180ef35b9b95..1326b43bad23 100644 --- a/lib/libwrap/Makefile +++ b/lib/libwrap/Makefile @@ -4,6 +4,7 @@ .include <src.opts.mk> +CONFS= hosts.allow PACKAGE=lib${LIB} LIB= wrap SHLIB_MAJOR= 6 diff --git a/etc/hosts.allow b/lib/libwrap/hosts.allow similarity index 100% rename from etc/hosts.allow rename to lib/libwrap/hosts.allow From 6577e8c44b5d5340bbf277265a18ac0a61cedfee Mon Sep 17 00:00:00 2001 From: Warner Losh <imp@FreeBSD.org> Date: Sat, 22 Sep 2018 15:32:53 +0000 Subject: [PATCH 082/139] We don't need shell protection for when we're expanding matches. Don't add it. This should fix when we do regepx matches against variables we've set and fix wifi bring up. PR: 231441 Approved by: re@ (kib) Differential Revision: https://reviews.freebsd.org/D17267 --- sbin/devd/devd.cc | 6 +++--- sbin/devd/devd.hh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sbin/devd/devd.cc b/sbin/devd/devd.cc index e81f718159b1..b2d08324511f 100644 --- a/sbin/devd/devd.cc +++ b/sbin/devd/devd.cc @@ -666,7 +666,7 @@ config::shell_quote(const string &s) } void -config::expand_one(const char *&src, string &dst) +config::expand_one(const char *&src, string &dst, bool is_shell) { int count; string buffer; @@ -705,7 +705,7 @@ config::expand_one(const char *&src, string &dst) do { buffer += *src++; } while (is_id_char(*src)); - dst.append(shell_quote(get_variable(buffer))); + dst.append(is_shell ? shell_quote(get_variable(buffer)) : get_variable(buffer)); } const string @@ -731,7 +731,7 @@ config::expand_string(const char *src, const char *prepend, const char *append) } dst.append(src, var_at - src); src = var_at; - expand_one(src, dst); + expand_one(src, dst, prepend == NULL); } if (append != NULL) diff --git a/sbin/devd/devd.hh b/sbin/devd/devd.hh index 534c4d4c5a9d..d770da22226a 100644 --- a/sbin/devd/devd.hh +++ b/sbin/devd/devd.hh @@ -172,7 +172,7 @@ protected: void sort_vector(std::vector<event_proc *> &); void parse_one_file(const char *fn); void parse_files_in_dir(const char *dirname); - void expand_one(const char *&src, std::string &dst); + void expand_one(const char *&src, std::string &dst, bool is_shell); std::string shell_quote(const std::string &s); bool is_id_char(char) const; bool chop_var(char *&buffer, char *&lhs, char *&rhs) const; From 068273571b8032ab405d811c43577044e6ee8a18 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" <ae@FreeBSD.org> Date: Sat, 22 Sep 2018 16:30:48 +0000 Subject: [PATCH 083/139] Update ifr_name before invoking IPSECSREQID ioctl, this fixes the case, when `ifconfig ipsec create reqid N` command invoked without interface unit number. The "name" global variable is updated after interface cloning in the ifclonecreate() and contains actual interface name. Reported by: lev Approved by: re (kib) MFC after: 1 week --- sbin/ifconfig/ifipsec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sbin/ifconfig/ifipsec.c b/sbin/ifconfig/ifipsec.c index fed5a842235c..0e615a27e205 100644 --- a/sbin/ifconfig/ifipsec.c +++ b/sbin/ifconfig/ifipsec.c @@ -72,6 +72,7 @@ DECL_CMD_FUNC(setreqid, val, arg) warn("Invalid reqid value %s", val); return; } + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_data = (char *)&v; if (ioctl(s, IPSECSREQID, &ifr) == -1) { warn("ioctl(IPSECSREQID)"); From 108ff63e8a83757adff13ebdc8c3360a596b70b2 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Sat, 22 Sep 2018 17:04:39 +0000 Subject: [PATCH 084/139] Further reorganize pmap_invalidate TLB code. Split calculation of mask for shootdown IPI and local invalidation. Reorder IPI before local. Suggested by: alc Reviewed by: alc, markj Tested by: pho Sponsored by: The FreeBSD Foundation Approved by: re (rgrimes) Differential revision: https://reviews.freebsd.org/D17277 --- sys/amd64/amd64/pmap.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index cb3625138a6e..ab8cc7d1b6f8 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1704,6 +1704,13 @@ pmap_invalidate_ept(pmap_t pmap) sched_unpin(); } +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) @@ -1790,7 +1797,6 @@ DEFINE_IFUNC(static, void, pmap_invalidate_page_mode, (pmap_t, vm_offset_t), void pmap_invalidate_page(pmap_t pmap, vm_offset_t va) { - cpuset_t *mask; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -1801,16 +1807,14 @@ pmap_invalidate_page(pmap_t pmap, vm_offset_t va) ("pmap_invalidate_page: invalid type %d", pmap->pm_type)); sched_pin(); + smp_masked_invlpg(pmap_invalidate_cpu_mask(pmap), va, pmap); if (pmap == kernel_pmap) { invlpg(va); - mask = &all_cpus; } else { if (pmap == PCPU_GET(curpmap)) invlpg(va); pmap_invalidate_page_mode(pmap, va); - mask = &pmap->pm_active; } - smp_masked_invlpg(*mask, va, pmap); sched_unpin(); } @@ -1890,7 +1894,6 @@ DEFINE_IFUNC(static, void, pmap_invalidate_range_mode, (pmap_t, vm_offset_t, void pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { - cpuset_t *mask; vm_offset_t addr; if (eva - sva >= PMAP_INVLPG_THRESHOLD) { @@ -1907,19 +1910,17 @@ 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(); + smp_masked_invlpg_range(pmap_invalidate_cpu_mask(pmap), sva, eva, pmap); if (pmap == kernel_pmap) { for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); - mask = &all_cpus; } else { if (pmap == PCPU_GET(curpmap)) { for (addr = sva; addr < eva; addr += PAGE_SIZE) invlpg(addr); } pmap_invalidate_range_mode(pmap, sva, eva); - mask = &pmap->pm_active; } - smp_masked_invlpg_range(*mask, sva, eva, pmap); sched_unpin(); } @@ -2010,7 +2011,6 @@ DEFINE_IFUNC(static, void, pmap_invalidate_all_mode, (pmap_t), static) void pmap_invalidate_all(pmap_t pmap) { - cpuset_t *mask; if (pmap_type_guest(pmap)) { pmap_invalidate_ept(pmap); @@ -2021,9 +2021,8 @@ pmap_invalidate_all(pmap_t pmap) ("pmap_invalidate_all: invalid type %d", pmap->pm_type)); sched_pin(); - mask = pmap == kernel_pmap ? &all_cpus : &pmap->pm_active; + smp_masked_invltlb(pmap_invalidate_cpu_mask(pmap), pmap); pmap_invalidate_all_mode(pmap); - smp_masked_invltlb(*mask, pmap); sched_unpin(); } From b7befdf50915fe8dda0cbf33e2ffb907c04a2d03 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Sat, 22 Sep 2018 17:05:49 +0000 Subject: [PATCH 085/139] Correct panic messages. Reviewed by: mckusick Sponsored by: The FreeBSD Foundation Approved by: re (rgrimes) MFC after: 1 week --- sys/ufs/ffs/ffs_softdep.c | 49 +++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 89d0b7382e4d..dcc72b2fdfd3 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -10261,22 +10261,22 @@ initiate_write_inodeblock_ufs1(inodedep, bp) prevlbn = adp->ad_offset; if (adp->ad_offset < UFS_NDADDR && dp->di_db[adp->ad_offset] != adp->ad_newblkno) - panic("%s: direct pointer #%jd mismatch %d != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs1: " + "direct pointer #%jd mismatch %d != %jd", (intmax_t)adp->ad_offset, dp->di_db[adp->ad_offset], (intmax_t)adp->ad_newblkno); if (adp->ad_offset >= UFS_NDADDR && dp->di_ib[adp->ad_offset - UFS_NDADDR] != adp->ad_newblkno) - panic("%s: indirect pointer #%jd mismatch %d != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs1: " + "indirect pointer #%jd mismatch %d != %jd", (intmax_t)adp->ad_offset - UFS_NDADDR, dp->di_ib[adp->ad_offset - UFS_NDADDR], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) - panic("softdep_write_inodeblock: Unknown state 0x%x", - adp->ad_state); + panic("initiate_write_inodeblock_ufs1: " + "Unknown state 0x%x", adp->ad_state); #endif /* INVARIANTS */ adp->ad_state &= ~ATTACHED; adp->ad_state |= UNDONE; @@ -10299,7 +10299,8 @@ initiate_write_inodeblock_ufs1(inodedep, bp) for (i = adp->ad_offset + 1; i < UFS_NDADDR; i++) { #ifdef INVARIANTS if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) - panic("softdep_write_inodeblock: lost dep1"); + panic("initiate_write_inodeblock_ufs1: " + "lost dep1"); #endif /* INVARIANTS */ dp->di_db[i] = 0; } @@ -10307,7 +10308,8 @@ initiate_write_inodeblock_ufs1(inodedep, bp) #ifdef INVARIANTS if (dp->di_ib[i] != 0 && (deplist & ((1 << UFS_NDADDR) << i)) == 0) - panic("softdep_write_inodeblock: lost dep2"); + panic("initiate_write_inodeblock_ufs1: " + "lost dep2"); #endif /* INVARIANTS */ dp->di_ib[i] = 0; } @@ -10429,18 +10431,18 @@ initiate_write_inodeblock_ufs2(inodedep, bp) adp = TAILQ_NEXT(adp, ad_next)) { #ifdef INVARIANTS if (deplist != 0 && prevlbn >= adp->ad_offset) - panic("softdep_write_inodeblock: lbn order"); + panic("initiate_write_inodeblock_ufs2: lbn order"); prevlbn = adp->ad_offset; if (dp->di_extb[adp->ad_offset] != adp->ad_newblkno) - panic("%s: direct pointer #%jd mismatch %jd != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs2: " + "ext pointer #%jd mismatch %jd != %jd", (intmax_t)adp->ad_offset, (intmax_t)dp->di_extb[adp->ad_offset], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) - panic("softdep_write_inodeblock: Unknown state 0x%x", - adp->ad_state); + panic("initiate_write_inodeblock_ufs2: Unknown " + "state 0x%x", adp->ad_state); #endif /* INVARIANTS */ adp->ad_state &= ~ATTACHED; adp->ad_state |= UNDONE; @@ -10461,7 +10463,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp) for (i = adp->ad_offset + 1; i < UFS_NXADDR; i++) { #ifdef INVARIANTS if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0) - panic("softdep_write_inodeblock: lost dep1"); + panic("initiate_write_inodeblock_ufs2: " + "lost dep1"); #endif /* INVARIANTS */ dp->di_extb[i] = 0; } @@ -10494,22 +10497,22 @@ initiate_write_inodeblock_ufs2(inodedep, bp) prevlbn = adp->ad_offset; if (adp->ad_offset < UFS_NDADDR && dp->di_db[adp->ad_offset] != adp->ad_newblkno) - panic("%s: direct pointer #%jd mismatch %jd != %jd", - "softdep_write_inodeblock", + panic("initiate_write_inodeblock_ufs2: " + "direct pointer #%jd mismatch %jd != %jd", (intmax_t)adp->ad_offset, (intmax_t)dp->di_db[adp->ad_offset], (intmax_t)adp->ad_newblkno); if (adp->ad_offset >= UFS_NDADDR && dp->di_ib[adp->ad_offset - UFS_NDADDR] != adp->ad_newblkno) - panic("%s indirect pointer #%jd mismatch %jd != %jd", - "softdep_write_inodeblock:", + panic("initiate_write_inodeblock_ufs2: " + "indirect pointer #%jd mismatch %jd != %jd", (intmax_t)adp->ad_offset - UFS_NDADDR, (intmax_t)dp->di_ib[adp->ad_offset - UFS_NDADDR], (intmax_t)adp->ad_newblkno); deplist |= 1 << adp->ad_offset; if ((adp->ad_state & ATTACHED) == 0) - panic("softdep_write_inodeblock: Unknown state 0x%x", - adp->ad_state); + panic("initiate_write_inodeblock_ufs2: Unknown " + "state 0x%x", adp->ad_state); #endif /* INVARIANTS */ adp->ad_state &= ~ATTACHED; adp->ad_state |= UNDONE; @@ -10532,7 +10535,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp) for (i = adp->ad_offset + 1; i < UFS_NDADDR; i++) { #ifdef INVARIANTS if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0) - panic("softdep_write_inodeblock: lost dep2"); + panic("initiate_write_inodeblock_ufs2: " + "lost dep2"); #endif /* INVARIANTS */ dp->di_db[i] = 0; } @@ -10540,7 +10544,8 @@ initiate_write_inodeblock_ufs2(inodedep, bp) #ifdef INVARIANTS if (dp->di_ib[i] != 0 && (deplist & ((1 << UFS_NDADDR) << i)) == 0) - panic("softdep_write_inodeblock: lost dep3"); + panic("initiate_write_inodeblock_ufs2: " + "lost dep3"); #endif /* INVARIANTS */ dp->di_ib[i] = 0; } From 697fb192070ee51d0ed8020e4ac5fc7a050b5e34 Mon Sep 17 00:00:00 2001 From: Andreas Tobler <andreast@FreeBSD.org> Date: Sat, 22 Sep 2018 20:58:43 +0000 Subject: [PATCH 086/139] Set the default loader for powerpc(32- and 64-bit) back to to forth. There are some issues with the lua-loader. To be on the safe side, use a well known and working loader. Approved by: re (glen) --- share/mk/src.opts.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index f09dd9748ac9..02e4ed229f5d 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -358,6 +358,11 @@ BROKEN_OPTIONS+=LOADER_UBOOT .if ${__T} == "sparc64" BROKEN_OPTIONS+=LOADER_GELI LOADER_LUA .endif +# Lua in loader currently cause boot failures on powerpc. +# Further debugging is required. +.if ${__T} == "powerpc" +BROKEN_OPTIONS+=LOADER_LUA +.endif .if ${__T:Mmips64*} # profiling won't work on MIPS64 because there is only assembly for o32 From 078a49a077790d2b57ebf8cbccc2148f5ce3358f Mon Sep 17 00:00:00 2001 From: Michael Tuexen <tuexen@FreeBSD.org> Date: Sun, 23 Sep 2018 16:37:32 +0000 Subject: [PATCH 087/139] Remove the unused parameter 'locked' from the function syncache_respond(). There is no functional change. The parameter became unused in r313330, but wasn't removed. Approved by: re (kib@) MFC after: 1 month Sponsored by: Netflix, Inc. --- sys/netinet/tcp_syncache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index e5a184fb713e..9eefd0d948d7 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -130,7 +130,7 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, functions_inherit_listen_socket_stack, static void syncache_drop(struct syncache *, struct syncache_head *); static void syncache_free(struct syncache *); static void syncache_insert(struct syncache *, struct syncache_head *); -static int syncache_respond(struct syncache *, struct syncache_head *, int, +static int syncache_respond(struct syncache *, struct syncache_head *, const struct mbuf *); static struct socket *syncache_socket(struct syncache *, struct socket *, struct mbuf *m); @@ -489,7 +489,7 @@ syncache_timer(void *xsch) free(s, M_TCPLOG); } - syncache_respond(sc, sch, 1, NULL); + syncache_respond(sc, sch, NULL); TCPSTAT_INC(tcps_sc_retransmitted); syncache_timeout(sc, sch, 0); } @@ -1413,7 +1413,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, s, __func__); free(s, M_TCPLOG); } - if (syncache_respond(sc, sch, 1, m) == 0) { + if (syncache_respond(sc, sch, m) == 0) { sc->sc_rxmits = 0; syncache_timeout(sc, sch, 1); TCPSTAT_INC(tcps_sndacks); @@ -1577,7 +1577,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, /* * Do a standard 3-way handshake. */ - if (syncache_respond(sc, sch, 0, m) == 0) { + if (syncache_respond(sc, sch, m) == 0) { if (V_tcp_syncookies && V_tcp_syncookiesonly && sc != &scs) syncache_free(sc); else if (sc != &scs) @@ -1622,7 +1622,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, * i.e. m0 != NULL, or upon 3WHS ACK timeout, i.e. m0 == NULL. */ static int -syncache_respond(struct syncache *sc, struct syncache_head *sch, int locked, +syncache_respond(struct syncache *sc, struct syncache_head *sch, const struct mbuf *m0) { struct ip *ip = NULL; From 9afff6b1c001084692b8b76fb27b4c07c2edc712 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Sun, 23 Sep 2018 19:00:06 +0000 Subject: [PATCH 088/139] Eliminate false sharing in malloc due to statistic collection Currently stats are collected in a MAXCPU-sized array which is not aligned and suffers enormous false-sharing. Fix the problem by utilizing per-cpu allocation. The counter(9) API is not used here as it is too incomplete and does not provide a win over per-cpu zone sized for malloc stats struct. In particular stats are being reported for each cpu separately by just copying what is supposed to be an array element for given cpu. This eliminates significant false-sharing during malloc-heavy tests e.g. on Skylake. See the review for details. Reviewed by: markj Approved by: re (kib) Differential Revision: https://reviews.freebsd.org/D17289 --- sys/kern/kern_malloc.c | 35 +++++++++++++++++++++++++++-------- sys/sys/malloc.h | 2 +- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index c102eb52e5bd..a8d42a85d949 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <sys/vmmeter.h> #include <sys/proc.h> #include <sys/sbuf.h> +#include <sys/smp.h> #include <sys/sysctl.h> #include <sys/time.h> #include <sys/vmem.h> @@ -173,6 +174,7 @@ struct { * declare malloc types. */ static uma_zone_t mt_zone; +static uma_zone_t mt_stats_zone; u_long vm_kmem_size; SYSCTL_ULONG(_vm, OID_AUTO, kmem_size, CTLFLAG_RDTUN, &vm_kmem_size, 0, @@ -368,7 +370,7 @@ malloc_type_zone_allocated(struct malloc_type *mtp, unsigned long size, critical_enter(); mtip = mtp->ks_handle; - mtsp = &mtip->mti_stats[curcpu]; + mtsp = zpcpu_get(mtip->mti_stats); if (size > 0) { mtsp->mts_memalloced += size; mtsp->mts_numallocs++; @@ -411,7 +413,7 @@ malloc_type_freed(struct malloc_type *mtp, unsigned long size) critical_enter(); mtip = mtp->ks_handle; - mtsp = &mtip->mti_stats[curcpu]; + mtsp = zpcpu_get(mtip->mti_stats); mtsp->mts_memfreed += size; mtsp->mts_numfrees++; @@ -953,6 +955,9 @@ mallocinit(void *dummy) if (kmem_zmax < PAGE_SIZE || kmem_zmax > KMEM_ZMAX) kmem_zmax = KMEM_ZMAX; + mt_stats_zone = uma_zcreate("mt_stats_zone", + sizeof(struct malloc_type_stats), NULL, NULL, NULL, NULL, + UMA_ALIGN_PTR, UMA_ZONE_PCPU); mt_zone = uma_zcreate("mt_zone", sizeof(struct malloc_type_internal), #ifdef INVARIANTS mtrash_ctor, mtrash_dtor, mtrash_init, mtrash_fini, @@ -995,6 +1000,7 @@ malloc_init(void *data) panic("malloc_init: bad malloc type magic"); mtip = uma_zalloc(mt_zone, M_WAITOK | M_ZERO); + mtip->mti_stats = uma_zalloc_pcpu(mt_stats_zone, M_WAITOK | M_ZERO); mtp->ks_handle = mtip; mtp_set_subzone(mtp); @@ -1042,8 +1048,8 @@ malloc_uninit(void *data) * Look for memory leaks. */ temp_allocs = temp_bytes = 0; - for (i = 0; i < MAXCPU; i++) { - mtsp = &mtip->mti_stats[i]; + for (i = 0; i <= mp_maxid; i++) { + mtsp = zpcpu_get_cpu(mtip->mti_stats, i); temp_allocs += mtsp->mts_numallocs; temp_allocs -= mtsp->mts_numfrees; temp_bytes += mtsp->mts_memalloced; @@ -1056,6 +1062,7 @@ malloc_uninit(void *data) } slab = vtoslab((vm_offset_t) mtip & (~UMA_SLAB_MASK)); + uma_zfree_pcpu(mt_stats_zone, mtip->mti_stats); uma_zfree_arg(mt_zone, mtip, slab); } @@ -1077,6 +1084,7 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) { struct malloc_type_stream_header mtsh; struct malloc_type_internal *mtip; + struct malloc_type_stats *mtsp, zeromts; struct malloc_type_header mth; struct malloc_type *mtp; int error, i; @@ -1089,6 +1097,8 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) sbuf_clear_flags(&sbuf, SBUF_INCLUDENUL); mtx_lock(&malloc_mtx); + bzero(&zeromts, sizeof(zeromts)); + /* * Insert stream header. */ @@ -1114,10 +1124,17 @@ sysctl_kern_malloc_stats(SYSCTL_HANDLER_ARGS) /* * Insert type statistics for each CPU. */ - for (i = 0; i < MAXCPU; i++) { - (void)sbuf_bcat(&sbuf, &mtip->mti_stats[i], - sizeof(mtip->mti_stats[i])); + for (i = 0; i <= mp_maxid; i++) { + mtsp = zpcpu_get_cpu(mtip->mti_stats, i); + (void)sbuf_bcat(&sbuf, mtsp, sizeof(*mtsp)); } + /* + * Fill in the missing CPUs. + */ + for (; i < MAXCPU; i++) { + (void)sbuf_bcat(&sbuf, &zeromts, sizeof(zeromts)); + } + } mtx_unlock(&malloc_mtx); error = sbuf_finish(&sbuf); @@ -1170,6 +1187,7 @@ malloc_type_list(malloc_type_list_func_t *func, void *arg) DB_SHOW_COMMAND(malloc, db_show_malloc) { struct malloc_type_internal *mtip; + struct malloc_type_internal *mtsp; struct malloc_type *mtp; uint64_t allocs, frees; uint64_t alloced, freed; @@ -1183,7 +1201,8 @@ DB_SHOW_COMMAND(malloc, db_show_malloc) frees = 0; alloced = 0; freed = 0; - for (i = 0; i < MAXCPU; i++) { + for (i = 0; i <= mp_maxid; i++) { + mtsp = zpcpu_get_cpu(mtip->mti_stats, i); allocs += mtip->mti_stats[i].mts_numallocs; frees += mtip->mti_stats[i].mts_numfrees; alloced += mtip->mti_stats[i].mts_memalloced; diff --git a/sys/sys/malloc.h b/sys/sys/malloc.h index 68595091a580..520f18c5a969 100644 --- a/sys/sys/malloc.h +++ b/sys/sys/malloc.h @@ -101,7 +101,7 @@ struct malloc_type_internal { uint32_t mti_probes[DTMALLOC_PROBE_MAX]; /* DTrace probe ID array. */ u_char mti_zone; - struct malloc_type_stats mti_stats[MAXCPU]; + struct malloc_type_stats *mti_stats; }; /* From 2417a95e023950a294651b527426796a359f7c8e Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Mon, 24 Sep 2018 13:42:46 +0000 Subject: [PATCH 089/139] Move libc linker ifunc test to build target only Targets like 'cleandir' must not depend on toolchain capabilities. Reported by: delphij, Shawn Webb Approved by: re (kib) Sponsored by: The FreeBSD Foundation --- lib/libc/Makefile | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/libc/Makefile b/lib/libc/Makefile index a1ce123c0f33..d6a3598ae314 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -21,11 +21,6 @@ LIBC_ARCH=${MACHINE_ARCH} LIBC_ARCH=${MACHINE_CPUARCH} .endif -.if (${LIBC_ARCH} == amd64 || ${LIBC_ARCH} == i386) && \ - defined(LINKER_FEATURES) && ${LINKER_FEATURES:Mifunc} == "" -.error ${LIBC_ARCH} libc requires linker ifunc support -.endif - # All library objects contain FreeBSD revision strings by default; they may be # excluded as a space-saving measure. To produce a library that does # not contain these strings, add -DSTRIP_FBSDID (see <sys/cdefs.h>) to CFLAGS @@ -186,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 From 3d14a7bb43d3bff2dad31f0bc928dda275ad86b1 Mon Sep 17 00:00:00 2001 From: Mark Johnston <markj@FreeBSD.org> Date: Mon, 24 Sep 2018 15:32:46 +0000 Subject: [PATCH 090/139] Ensure that "domain" is initialized when vm_ndomains == 1. Reported by: alc Approved by: re (gjb) --- sys/vm/vm_kern.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index b5915c074ab6..9774e0b4f22d 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -505,8 +505,10 @@ kmem_back(vm_object_t object, vm_offset_t addr, vm_size_t size, int flags) next = roundup2(addr + 1, KVA_QUANTUM); if (next > end || next < start) next = end; - } else + } 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); From f5fbe90de489d79b8d607d831451b376855f1410 Mon Sep 17 00:00:00 2001 From: Alan Cox <alc@FreeBSD.org> Date: Mon, 24 Sep 2018 16:49:02 +0000 Subject: [PATCH 091/139] Passing UMA_ZONE_NOFREE to uma_zcreate() for swpctrie_zone and swblk_zone is redundant, because uma_zone_reserve_kva() is performed on both zones and it sets this same flag on the zone. (Moreover, the implementation of the swap pager does not itself require these zones to be UMA_ZONE_NOFREE.) Reviewed by: kib, markj Approved by: re (gjb) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D17296 --- sys/vm/swap_pager.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index 858a9e884626..0bd4bde8b57e 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -545,13 +545,11 @@ swap_pager_swap_init(void) if (maxswzone && n > maxswzone / sizeof(struct swblk)) n = maxswzone / sizeof(struct swblk); swpctrie_zone = uma_zcreate("swpctrie", pctrie_node_size(), NULL, NULL, - pctrie_zone_init, NULL, UMA_ALIGN_PTR, - UMA_ZONE_NOFREE | UMA_ZONE_VM); + pctrie_zone_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_VM); if (swpctrie_zone == NULL) panic("failed to create swap pctrie zone."); swblk_zone = uma_zcreate("swblk", sizeof(struct swblk), NULL, NULL, - NULL, NULL, _Alignof(struct swblk) - 1, - UMA_ZONE_NOFREE | UMA_ZONE_VM); + NULL, NULL, _Alignof(struct swblk) - 1, UMA_ZONE_VM); if (swblk_zone == NULL) panic("failed to create swap blk zone."); n2 = n; From cf4a52cf6745dd7546f0aaec1485c522a0424319 Mon Sep 17 00:00:00 2001 From: Alexander Motin <mav@FreeBSD.org> Date: Mon, 24 Sep 2018 16:58:55 +0000 Subject: [PATCH 092/139] Fix use-after-free in RAID0 error reporting of GEOM_RAID. PR: 231510 Submitted by: yangx92@hotmail.com Approved by: re (gjb) MFC after: 1 week --- sys/geom/raid/tr_raid0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/geom/raid/tr_raid0.c b/sys/geom/raid/tr_raid0.c index 78fa1b920f8a..33a802103f0c 100644 --- a/sys/geom/raid/tr_raid0.c +++ b/sys/geom/raid/tr_raid0.c @@ -323,7 +323,7 @@ g_raid_tr_iodone_raid0(struct g_raid_tr_object *tr, pbp->bio_inbed++; if (pbp->bio_children == pbp->bio_inbed) { pbp->bio_completed = pbp->bio_length; - g_raid_iodone(pbp, bp->bio_error); + g_raid_iodone(pbp, pbp->bio_error); } } From 7a102e0463121db1249f4bb06aba7e120e7e6b84 Mon Sep 17 00:00:00 2001 From: John Baldwin <jhb@FreeBSD.org> Date: Mon, 24 Sep 2018 17:41:29 +0000 Subject: [PATCH 093/139] Implement pmap_sync_icache(). This invokes "fence" on the hart performing the write followed by an IPI to execute "fence.i" on all harts. This is required to support userland debuggers setting breakpoints in user processes. Reviewed by: br (earlier version), markj Approved by: re (gjb) Sponsored by: DARPA Differential Revision: https://reviews.freebsd.org/D17139 --- sys/riscv/riscv/pmap.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/sys/riscv/riscv/pmap.c b/sys/riscv/riscv/pmap.c index 8582667b27b9..b6a58ed796b6 100644 --- a/sys/riscv/riscv/pmap.c +++ b/sys/riscv/riscv/pmap.c @@ -3244,11 +3244,27 @@ pmap_activate(struct thread *td) critical_exit(); } +static void +pmap_sync_icache_one(void *arg __unused) +{ + + __asm __volatile("fence.i"); +} + void pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz) { - panic("RISCVTODO: pmap_sync_icache"); + /* + * From the RISC-V User-Level ISA V2.2: + * + * "To make a store to instruction memory visible to all + * RISC-V harts, the writing hart has to execute a data FENCE + * before requesting that all remote RISC-V harts execute a + * FENCE.I." + */ + __asm __volatile("fence"); + smp_rendezvous(NULL, pmap_sync_icache_one, NULL, NULL); } /* From b65a9568f89c35b4f6a292768fea4382245bd0bd Mon Sep 17 00:00:00 2001 From: John Baldwin <jhb@FreeBSD.org> Date: Mon, 24 Sep 2018 18:20:38 +0000 Subject: [PATCH 094/139] Restore the API of the kf_sa_local and kf_sa_peer members. In 11.x and earlier these were accessible as direct members of 'struct kinfo_file'. Existing code already knows about the new location of these members as well, so wrapper macros did not work for these fields. Instead, define an anonymous struct containing the fields from 'struct kinfo_file' in FreeBSD 11 that were not part of the 'kf_un' union. This anonymous struct is then placed in an anonymous union along with the new 'kf_un' union. This preserves the API of both structure layouts without requiring any wrapper macros. PR: 231525 Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17262 --- sys/sys/user.h | 171 +++++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 83 deletions(-) diff --git a/sys/sys/user.h b/sys/sys/user.h index f5353f15b0fc..67acf2d0740d 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -346,85 +346,96 @@ struct kinfo_file { int64_t kf_offset; /* Seek location. */ union { struct { - /* Sendq size */ - uint32_t kf_sock_sendq; - /* Socket domain. */ - int kf_sock_domain0; - /* Socket type. */ - int kf_sock_type0; - /* Socket protocol. */ - int kf_sock_protocol0; - /* Socket address. */ + /* API compatiblity with FreeBSD < 12. */ + int kf_vnode_type; + int kf_sock_domain; + int kf_sock_type; + int kf_sock_protocol; struct sockaddr_storage kf_sa_local; - /* Peer address. */ struct sockaddr_storage kf_sa_peer; - /* Address of so_pcb. */ - uint64_t kf_sock_pcb; - /* Address of inp_ppcb. */ - uint64_t kf_sock_inpcb; - /* Address of unp_conn. */ - uint64_t kf_sock_unpconn; - /* Send buffer state. */ - uint16_t kf_sock_snd_sb_state; - /* Receive buffer state. */ - uint16_t kf_sock_rcv_sb_state; - /* Recvq size. */ - uint32_t kf_sock_recvq; - } kf_sock; - struct { - /* Vnode type. */ - int kf_file_type; - /* Space for future use */ - int kf_spareint[3]; - uint64_t kf_spareint64[30]; - /* Vnode filesystem id. */ - uint64_t kf_file_fsid; - /* File device. */ - uint64_t kf_file_rdev; - /* Global file id. */ - uint64_t kf_file_fileid; - /* File size. */ - uint64_t kf_file_size; - /* Vnode filesystem id, FreeBSD 11 compat. */ - uint32_t kf_file_fsid_freebsd11; - /* File device, FreeBSD 11 compat. */ - uint32_t kf_file_rdev_freebsd11; - /* File mode. */ - uint16_t kf_file_mode; - /* Round to 64 bit alignment. */ - uint16_t kf_file_pad0; - uint32_t kf_file_pad1; - } kf_file; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - uint32_t kf_sem_value; - uint16_t kf_sem_mode; - } kf_sem; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - uint64_t kf_pipe_addr; - uint64_t kf_pipe_peer; - uint32_t kf_pipe_buffer_cnt; - /* Round to 64 bit alignment. */ - uint32_t kf_pipe_pad0[3]; - } kf_pipe; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - uint32_t kf_pts_dev_freebsd11; - uint32_t kf_pts_pad0; - uint64_t kf_pts_dev; - /* Round to 64 bit alignment. */ - uint32_t kf_pts_pad1[4]; - } kf_pts; - struct { - uint32_t kf_spareint[4]; - uint64_t kf_spareint64[32]; - pid_t kf_pid; - } kf_proc; - } kf_un; + }; + union { + struct { + /* Sendq size */ + uint32_t kf_sock_sendq; + /* Socket domain. */ + int kf_sock_domain0; + /* Socket type. */ + int kf_sock_type0; + /* Socket protocol. */ + int kf_sock_protocol0; + /* Socket address. */ + struct sockaddr_storage kf_sa_local; + /* Peer address. */ + struct sockaddr_storage kf_sa_peer; + /* Address of so_pcb. */ + uint64_t kf_sock_pcb; + /* Address of inp_ppcb. */ + uint64_t kf_sock_inpcb; + /* Address of unp_conn. */ + uint64_t kf_sock_unpconn; + /* Send buffer state. */ + uint16_t kf_sock_snd_sb_state; + /* Receive buffer state. */ + uint16_t kf_sock_rcv_sb_state; + /* Recvq size. */ + uint32_t kf_sock_recvq; + } kf_sock; + struct { + /* Vnode type. */ + int kf_file_type; + /* Space for future use */ + int kf_spareint[3]; + uint64_t kf_spareint64[30]; + /* Vnode filesystem id. */ + uint64_t kf_file_fsid; + /* File device. */ + uint64_t kf_file_rdev; + /* Global file id. */ + uint64_t kf_file_fileid; + /* File size. */ + uint64_t kf_file_size; + /* Vnode filesystem id, FreeBSD 11 compat. */ + uint32_t kf_file_fsid_freebsd11; + /* File device, FreeBSD 11 compat. */ + uint32_t kf_file_rdev_freebsd11; + /* File mode. */ + uint16_t kf_file_mode; + /* Round to 64 bit alignment. */ + uint16_t kf_file_pad0; + uint32_t kf_file_pad1; + } kf_file; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint32_t kf_sem_value; + uint16_t kf_sem_mode; + } kf_sem; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint64_t kf_pipe_addr; + uint64_t kf_pipe_peer; + uint32_t kf_pipe_buffer_cnt; + /* Round to 64 bit alignment. */ + uint32_t kf_pipe_pad0[3]; + } kf_pipe; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + uint32_t kf_pts_dev_freebsd11; + uint32_t kf_pts_pad0; + uint64_t kf_pts_dev; + /* Round to 64 bit alignment. */ + uint32_t kf_pts_pad1[4]; + } kf_pts; + struct { + uint32_t kf_spareint[4]; + uint64_t kf_spareint64[32]; + pid_t kf_pid; + } kf_proc; + } kf_un; + }; uint16_t kf_status; /* Status flags. */ uint16_t kf_pad1; /* Round to 32 bit alignment. */ int _kf_ispare0; /* Space for more stuff. */ @@ -433,12 +444,6 @@ struct kinfo_file { /* Truncated before copyout in sysctl */ char kf_path[PATH_MAX]; /* Path to file, if any. */ }; -#ifndef _KERNEL -#define kf_vnode_type kf_un.kf_file.kf_file_type -#define kf_sock_domain kf_un.kf_sock.kf_sock_domain0 -#define kf_sock_type kf_un.kf_sock.kf_sock_type0 -#define kf_sock_protocol kf_un.kf_sock.kf_sock_protocol0 -#endif /* * The KERN_PROC_VMMAP sysctl allows a process to dump the VM layout of From 7362ac9ca95598c2715ea3fe8f25231cf3ce104f Mon Sep 17 00:00:00 2001 From: Matt Macy <mmacy@FreeBSD.org> Date: Mon, 24 Sep 2018 19:06:09 +0000 Subject: [PATCH 095/139] restore pmccontrol -L behavior on x86 When I updated counter definition handling for x86 I broke 'pmccontrol -L' listing counter names. This just changes pmccontrol to call the library function on x86. PR: 230984 Approved by: re (kib@) --- usr.sbin/pmccontrol/pmccontrol.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/usr.sbin/pmccontrol/pmccontrol.c b/usr.sbin/pmccontrol/pmccontrol.c index b80db1f348be..147aab2d2ba1 100644 --- a/usr.sbin/pmccontrol/pmccontrol.c +++ b/usr.sbin/pmccontrol/pmccontrol.c @@ -282,6 +282,14 @@ pmcc_do_list_state(void) return 0; } +#if defined(__i386__) || defined(__amd64__) +static int +pmcc_do_list_events(void) +{ + pmc_pmu_print_counters(NULL); + return (0); +} +#else static int pmcc_do_list_events(void) { @@ -311,6 +319,7 @@ pmcc_do_list_events(void) } return 0; } +#endif static int pmcc_show_statistics(void) From 463406ac4a531b8f4c6102715c17da6183d10be3 Mon Sep 17 00:00:00 2001 From: Mark Johnston <markj@FreeBSD.org> Date: Mon, 24 Sep 2018 19:24:17 +0000 Subject: [PATCH 096/139] Add more NUMA-specific low memory predicates. Use these predicates instead of inline references to vm_min_domains. Also add a global all_domains set, akin to all_cpus. Reviewed by: alc, jeff, kib Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17278 --- sys/sys/vmmeter.h | 28 +++++++++++++++++++++++++--- sys/vm/vm_domainset.c | 16 ++++++++-------- sys/vm/vm_page.c | 4 ++-- sys/vm/vm_phys.c | 1 + sys/x86/acpica/srat.c | 3 ++- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/sys/sys/vmmeter.h b/sys/sys/vmmeter.h index c41b151fa502..579d16756e99 100644 --- a/sys/sys/vmmeter.h +++ b/sys/sys/vmmeter.h @@ -145,6 +145,7 @@ struct vmmeter { #include <sys/domainset.h> extern struct vmmeter vm_cnt; +extern domainset_t all_domains; extern domainset_t vm_min_domains; extern domainset_t vm_severe_domains; @@ -177,7 +178,7 @@ vm_wire_count(void) /* * Return TRUE if we are under our severe low-free-pages threshold * - * This routine is typically used at the user<->system interface to determine + * These routines are typically used at the user<->system interface to determine * whether we need to block in order to avoid a low memory deadlock. */ static inline int @@ -188,7 +189,14 @@ vm_page_count_severe(void) } static inline int -vm_page_count_severe_set(domainset_t *mask) +vm_page_count_severe_domain(int domain) +{ + + return (DOMAINSET_ISSET(domain, &vm_severe_domains)); +} + +static inline int +vm_page_count_severe_set(const domainset_t *mask) { return (DOMAINSET_SUBSET(&vm_severe_domains, mask)); @@ -197,7 +205,7 @@ vm_page_count_severe_set(domainset_t *mask) /* * Return TRUE if we are under our minimum low-free-pages threshold. * - * This routine is typically used within the system to determine whether + * These routines are typically used within the system to determine whether * we can execute potentially very expensive code in terms of memory. It * is also used by the pageout daemon to calculate when to sleep, when * to wake waiters up, and when (after making a pass) to become more @@ -210,5 +218,19 @@ vm_page_count_min(void) return (!DOMAINSET_EMPTY(&vm_min_domains)); } +static inline int +vm_page_count_min_domain(int domain) +{ + + return (DOMAINSET_ISSET(domain, &vm_min_domains)); +} + +static inline int +vm_page_count_min_set(const domainset_t *mask) +{ + + return (DOMAINSET_SUBSET(&vm_min_domains, mask)); +} + #endif /* _KERNEL */ #endif /* _SYS_VMMETER_H_ */ diff --git a/sys/vm/vm_domainset.c b/sys/vm/vm_domainset.c index 16b078e7dabd..b9348d6c632b 100644 --- a/sys/vm/vm_domainset.c +++ b/sys/vm/vm_domainset.c @@ -66,6 +66,7 @@ vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj, vm_pindex_t pindex) { struct domainset *domain; + struct thread *td; /* * object policy takes precedence over thread policy. The policies @@ -76,8 +77,9 @@ vm_domainset_iter_init(struct vm_domainset_iter *di, struct vm_object *obj, di->di_domain = domain; di->di_iter = &obj->domain.dr_iterator; } else { - di->di_domain = curthread->td_domain.dr_policy; - di->di_iter = &curthread->td_domain.dr_iterator; + td = curthread; + di->di_domain = td->td_domain.dr_policy; + di->di_iter = &td->td_domain.dr_iterator; } di->di_policy = di->di_domain->ds_policy; if (di->di_policy == DOMAINSET_POLICY_INTERLEAVE) { @@ -215,7 +217,7 @@ vm_domainset_iter_page_init(struct vm_domainset_iter *di, struct vm_object *obj, *req = (di->di_flags & ~(VM_ALLOC_WAITOK | VM_ALLOC_WAITFAIL)) | VM_ALLOC_NOWAIT; vm_domainset_iter_first(di, domain); - if (DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (vm_page_count_min_domain(*domain)) vm_domainset_iter_page(di, domain, req); } @@ -233,8 +235,7 @@ vm_domainset_iter_page(struct vm_domainset_iter *di, int *domain, int *req) /* If there are more domains to visit we run the iterator. */ while (--di->di_n != 0) { vm_domainset_iter_next(di, domain); - if (!di->di_minskip || - !DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (!di->di_minskip || !vm_page_count_min_domain(*domain)) return (0); } if (di->di_minskip) { @@ -269,7 +270,7 @@ vm_domainset_iter_malloc_init(struct vm_domainset_iter *di, di->di_flags = *flags; *flags = (di->di_flags & ~M_WAITOK) | M_NOWAIT; vm_domainset_iter_first(di, domain); - if (DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (vm_page_count_min_domain(*domain)) vm_domainset_iter_malloc(di, domain, flags); } @@ -280,8 +281,7 @@ vm_domainset_iter_malloc(struct vm_domainset_iter *di, int *domain, int *flags) /* If there are more domains to visit we run the iterator. */ while (--di->di_n != 0) { vm_domainset_iter_next(di, domain); - if (!di->di_minskip || - !DOMAINSET_ISSET(*domain, &vm_min_domains)) + if (!di->di_minskip || !vm_page_count_min_domain(*domain)) return (0); } diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index d022435704f1..47628cba2ac1 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -2959,7 +2959,7 @@ vm_wait_doms(const domainset_t *wdoms) * consume all freed pages while old allocators wait. */ mtx_lock(&vm_domainset_lock); - if (DOMAINSET_SUBSET(&vm_min_domains, wdoms)) { + if (vm_page_count_min_set(wdoms)) { vm_min_waiters++; msleep(&vm_min_domains, &vm_domainset_lock, PVM | PDROP, "vmwait", 0); @@ -3078,7 +3078,7 @@ vm_waitpfault(struct domainset *dset) * consume all freed pages while old allocators wait. */ mtx_lock(&vm_domainset_lock); - if (DOMAINSET_SUBSET(&vm_min_domains, &dset->ds_mask)) { + if (vm_page_count_min_set(&dset->ds_mask)) { vm_min_waiters++; msleep(&vm_min_domains, &vm_domainset_lock, PUSER | PDROP, "pfault", 0); diff --git a/sys/vm/vm_phys.c b/sys/vm/vm_phys.c index 890f5dad9213..5206ba6e658f 100644 --- a/sys/vm/vm_phys.c +++ b/sys/vm/vm_phys.c @@ -78,6 +78,7 @@ int __read_mostly *mem_locality; #endif int __read_mostly vm_ndomains = 1; +domainset_t __read_mostly all_domains = DOMAINSET_T_INITIALIZER(0x1); struct vm_phys_seg __read_mostly vm_phys_segs[VM_PHYSSEG_MAX]; int __read_mostly vm_phys_nsegs; diff --git a/sys/x86/acpica/srat.c b/sys/x86/acpica/srat.c index 0ea747ccc30b..08a98429a03d 100644 --- a/sys/x86/acpica/srat.c +++ b/sys/x86/acpica/srat.c @@ -470,8 +470,9 @@ parse_srat(void) } #ifdef NUMA - /* Point vm_phys at our memory affinity table. */ vm_ndomains = ndomain; + for (int i = 0; i < vm_ndomains; i++) + DOMAINSET_SET(i, &all_domains); mem_affinity = mem_info; #endif From 8251b8b87eab9f00c51f0a3717e73a7402ed367e Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Mon, 24 Sep 2018 20:46:45 +0000 Subject: [PATCH 097/139] sysctl(8): Add a standard exit status section. Reviewed by: bcr Approved by: re (gjb), krion (mentor) Differential Revision: https://reviews.freebsd.org/D17147 --- sbin/sysctl/sysctl.8 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sbin/sysctl/sysctl.8 b/sbin/sysctl/sysctl.8 index 1f3041b1f6c7..35a2cc941748 100644 --- a/sbin/sysctl/sysctl.8 +++ b/sbin/sysctl/sysctl.8 @@ -28,7 +28,7 @@ .\" From: @(#)sysctl.8 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd March 9, 2018 +.Dd September 24, 2018 .Dt SYSCTL 8 .Os .Sh NAME @@ -276,6 +276,8 @@ definitions for fourth level ICMP identifiers .It In netinet/udp_var.h definitions for fourth level UDP identifiers .El +.Sh EXIT STATUS +.Ex -std .Sh EXAMPLES For example, to retrieve the maximum number of processes allowed in the system, one would use the following request: From 189bd7a978a0f0a9f13cdf6175c1f6c6fa72f962 Mon Sep 17 00:00:00 2001 From: Colin Percival <cperciva@FreeBSD.org> Date: Mon, 24 Sep 2018 22:15:04 +0000 Subject: [PATCH 098/139] Recognize the Amazon PCI serial device found in i3.metal EC2 instances as an NS8250 UART. Reviewed by: sbruno, imp Approved by: re (delphij) Sponsored by: https://www.patreon.com/cperciva Differential Revision: https://reviews.freebsd.org/D17250 --- sys/dev/uart/uart_bus_pci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c index f4be108ab7b2..15b4472a37b2 100644 --- a/sys/dev/uart/uart_bus_pci.c +++ b/sys/dev/uart/uart_bus_pci.c @@ -125,6 +125,7 @@ static const struct pci_id pci_ns8250_ids[] = { 128 * DEFAULT_RCLK, 2}, { 0x14e4, 0x4344, 0xffff, 0, "Sony Ericsson GC89 PC Card", 0x10}, { 0x151f, 0x0000, 0xffff, 0, "TOPIC Semiconductor TP560 56k modem", 0x10 }, +{ 0x1d0f, 0x8250, 0x1d0f, 0, "Amazon PCI serial device", 0x10 }, { 0x1fd4, 0x1999, 0x1fd4, 0x0001, "Sunix SER5xxxx Serial Port", 0x10, 8 * DEFAULT_RCLK }, { 0x8086, 0x0f0a, 0xffff, 0, "Intel ValleyView LPIO1 HSUART#1", 0x10, From fd8cf3be5f3a1bfbe6b9b07bc610f3b1ce9361f4 Mon Sep 17 00:00:00 2001 From: Justin Hibbits <jhibbits@FreeBSD.org> Date: Tue, 25 Sep 2018 02:34:28 +0000 Subject: [PATCH 099/139] powerpc: Blacklist the top 64kB range of the lower 4GB PA space The PHB4 host bridge used by the POWER9 uses a 64kB range in 32-bit space at the address 0xffff0000-0xffffffff. Reserve this range so that DMA memory cannot be allocated within this range. This fixes seemingly random crashes on a POWER9 system. Ideally this range will have been reserved by the firmware, but as of now this is not the case. Submitted by: git_bdragon.rtk0.net Reviewed by: nwhitehorn Approved by: re(kib) Differential Revision: https://reviews.freebsd.org/D17183 --- sys/powerpc/ofw/ofw_machdep.c | 37 +++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/sys/powerpc/ofw/ofw_machdep.c b/sys/powerpc/ofw/ofw_machdep.c index 7e231373d829..c647ce817905 100644 --- a/sys/powerpc/ofw/ofw_machdep.c +++ b/sys/powerpc/ofw/ofw_machdep.c @@ -69,6 +69,10 @@ __FBSDID("$FreeBSD$"); #include <contrib/libfdt/libfdt.h> +#ifdef POWERNV +#include <powerpc/powernv/opal.h> +#endif + static void *fdt; int ofw_real_mode; @@ -338,6 +342,34 @@ excise_initrd_region(struct mem_region *avail, int asz) return (asz); } +#ifdef POWERNV +static int +excise_msi_region(struct mem_region *avail, int asz) +{ + uint64_t start, end; + struct mem_region initrdmap[1]; + + /* + * This range of physical addresses is used to implement optimized + * 32 bit MSI interrupts on POWER9. Exclude it to avoid accidentally + * using it for DMA, as this will cause an immediate PHB fence. + * While we could theoretically turn off this behavior in the ETU, + * doing so would break 32-bit MSI, so just reserve the range in + * the physical map instead. + * See section 4.4.2.8 of the PHB4 specification. + */ + start = 0x00000000ffff0000ul; + end = 0x00000000fffffffful; + + initrdmap[0].mr_start = start; + initrdmap[0].mr_size = end - start; + + asz = excise_reserved_regions(avail, asz, initrdmap, 1); + + return (asz); +} +#endif + static int excise_fdt_reserved(struct mem_region *avail, int asz) { @@ -430,6 +462,11 @@ ofw_mem_regions(struct mem_region *memp, int *memsz, asz = excise_initrd_region(availp, asz); #endif +#ifdef POWERNV + if (opal_check() == 0) + asz = excise_msi_region(availp, asz); +#endif + *memsz = msz; *availsz = asz; } From ea710848dca328f3d617ce52c5553e20d7de671c Mon Sep 17 00:00:00 2001 From: Navdeep Parhar <np@FreeBSD.org> Date: Tue, 25 Sep 2018 05:52:42 +0000 Subject: [PATCH 100/139] cxgbe(4): Link related changes. - Switch to using 32b port/link capabilities in the driver. The 32b format is used internally by firmwares > 1.16.45.0 and the driver will now interact with the firmware in its native format, whether it's 16b or 32b. Note that the 16b format doesn't have room for 50G, 200G, or 400G speeds. - Add a bit in the pause_settings knobs to allow negotiated PAUSE settings to override manual settings. - Ensure that manual link settings persist across an administrative down/up as well as transceiver unplug/replug. - Remove unused is_*G_port() functions. Approved by: re@ (gjb@) MFC after: 1 month Sponsored by: Chelsio Communications --- share/man/man4/cxgbe.4 | 10 +- sys/dev/cxgbe/adapter.h | 47 --- sys/dev/cxgbe/common/common.h | 42 ++- sys/dev/cxgbe/common/t4_hw.c | 449 ++++++++++++++++++++++------- sys/dev/cxgbe/osdep.h | 1 + sys/dev/cxgbe/t4_main.c | 521 +++++++++++++++++++++------------- sys/dev/cxgbe/tom/t4_cpl_io.c | 2 +- 7 files changed, 700 insertions(+), 372 deletions(-) diff --git a/share/man/man4/cxgbe.4 b/share/man/man4/cxgbe.4 index c98f96ad3678..970472efca21 100644 --- a/share/man/man4/cxgbe.4 +++ b/share/man/man4/cxgbe.4 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd Aug 9, 2018 +.Dd Sep 24, 2018 .Dt CXGBE 4 .Os .Sh NAME @@ -279,19 +279,21 @@ This usually results in the port emitting PAUSE frames. 1 instructs the hardware to drop frames destined for congested queues. .It Va hw.cxgbe.pause_settings PAUSE frame settings. -Bit 0 is rx_pause, bit 1 is tx_pause. +Bit 0 is rx_pause, bit 1 is tx_pause, bit 2 is pause_autoneg. rx_pause = 1 instructs the hardware to heed incoming PAUSE frames, 0 instructs it to ignore them. tx_pause = 1 allows the hardware to emit PAUSE frames when its receive FIFO reaches a high threshold, 0 prohibits the hardware from emitting PAUSE frames. -The default is 3 (both rx_pause and tx_pause = 1). +pause_autoneg = 1 overrides the rx_pause and tx_pause bits and instructs the +hardware to negotiate PAUSE settings with the link peer. +The default is 7 (all three = 1). This tunable establishes the default PAUSE settings for all ports. Settings can be displayed and controlled on a per-port basis via the dev.<port>.X.pause_settings sysctl. .It Va hw.cxgbe.fec FEC (Forward Error Correction) settings. 0 diables FEC. -Bit 0 enables RS FEC, bit 1 enables BASE-R RS, bit 3 is reserved. +Bit 0 enables RS FEC, bit 1 enables BASE-R FEC (aka Firecode FEC). The default is -1 which lets the driver pick a value. This tunable establishes the default FEC settings for all ports. Settings can be displayed and controlled on a per-port basis via the diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h index 866bace84c36..f23d16479ee8 100644 --- a/sys/dev/cxgbe/adapter.h +++ b/sys/dev/cxgbe/adapter.h @@ -289,7 +289,6 @@ struct port_info { uint8_t rx_e_chan_map; /* rx TP e-channel bitmap */ struct link_config link_cfg; - struct link_config old_link_cfg; struct ifmedia media; struct timeval last_refreshed; @@ -1073,52 +1072,6 @@ t4_os_set_hw_addr(struct port_info *pi, uint8_t hw_addr[]) bcopy(hw_addr, pi->vi[0].hw_addr, ETHER_ADDR_LEN); } -static inline bool -is_10G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) != 0); -} - -static inline bool -is_25G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) != 0); -} - -static inline bool -is_40G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) != 0); -} - -static inline bool -is_100G_port(const struct port_info *pi) -{ - - return ((pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) != 0); -} - -static inline int -port_top_speed(const struct port_info *pi) -{ - - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100G) - return (100); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_40G) - return (40); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_25G) - return (25); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_10G) - return (10); - if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_1G) - return (1); - - return (0); -} - static inline int tx_resume_threshold(struct sge_eq *eq) { diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h index 044582db6ede..ada4fa4fa775 100644 --- a/sys/dev/cxgbe/common/common.h +++ b/sys/dev/cxgbe/common/common.h @@ -66,9 +66,10 @@ enum { }; enum { + FEC_NONE = 0, FEC_RS = 1 << 0, FEC_BASER_RS = 1 << 1, - FEC_RESERVED = 1 << 2, + FEC_AUTO = 1 << 5, /* M_FW_PORT_CAP32_FEC + 1 */ }; enum t4_bar2_qtype { T4_BAR2_QTYPE_EGRESS, T4_BAR2_QTYPE_INGRESS }; @@ -368,6 +369,7 @@ struct adapter_params { unsigned int ethoffload:1; unsigned int hash_filter:1; unsigned int filter2_wr_support:1; + unsigned int port_caps32:1; unsigned int ofldq_wr_cred; unsigned int eo_wr_cred; @@ -409,20 +411,21 @@ struct trace_params { }; struct link_config { - /* OS-specific code owns all the requested_* fields */ - unsigned char requested_aneg; /* link aneg user has requested */ - unsigned char requested_fc; /* flow control user has requested */ - unsigned char requested_fec; /* FEC user has requested */ - unsigned int requested_speed; /* speed user has requested (Mbps) */ + /* OS-specific code owns all the requested_* fields. */ + int8_t requested_aneg; /* link autonegotiation */ + int8_t requested_fc; /* flow control */ + int8_t requested_fec; /* FEC */ + u_int requested_speed; /* speed (Mbps) */ - unsigned short supported; /* link capabilities */ - unsigned short advertising; /* advertised capabilities */ - unsigned short lp_advertising; /* peer advertised capabilities */ - unsigned int speed; /* actual link speed (Mbps) */ - unsigned char fc; /* actual link flow control */ - unsigned char fec; /* actual FEC */ - unsigned char link_ok; /* link up? */ - unsigned char link_down_rc; /* link down reason */ + uint32_t supported; /* link capabilities */ + uint32_t advertising; /* advertised capabilities */ + uint32_t lp_advertising; /* peer advertised capabilities */ + uint32_t fec_hint; /* use this fec */ + u_int speed; /* actual link speed (Mbps) */ + int8_t fc; /* actual link flow control */ + int8_t fec; /* actual FEC */ + bool link_ok; /* link up? */ + uint8_t link_down_rc; /* link down reason */ }; #include "adapter.h" @@ -874,5 +877,16 @@ int t4vf_prep_adapter(struct adapter *adapter); int t4_bar2_sge_qregs(struct adapter *adapter, unsigned int qid, enum t4_bar2_qtype qtype, int user, u64 *pbar2_qoffset, unsigned int *pbar2_qid); +unsigned int fwcap_to_speed(uint32_t caps); +uint32_t speed_to_fwcap(unsigned int speed); +uint32_t fwcap_top_speed(uint32_t caps); + +static inline int +port_top_speed(const struct port_info *pi) +{ + + /* Mbps -> Gbps */ + return (fwcap_to_speed(pi->link_cfg.supported) / 1000); +} #endif /* __CHELSIO_COMMON_H */ diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 2312b66cf7a8..cec8ebbf00e7 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -3755,6 +3755,93 @@ void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) } } +/** + * fwcaps16_to_caps32 - convert 16-bit Port Capabilities to 32-bits + * @caps16: a 16-bit Port Capabilities value + * + * Returns the equivalent 32-bit Port Capabilities value. + */ +static uint32_t fwcaps16_to_caps32(uint16_t caps16) +{ + uint32_t caps32 = 0; + + #define CAP16_TO_CAP32(__cap) \ + do { \ + if (caps16 & FW_PORT_CAP_##__cap) \ + caps32 |= FW_PORT_CAP32_##__cap; \ + } while (0) + + CAP16_TO_CAP32(SPEED_100M); + CAP16_TO_CAP32(SPEED_1G); + CAP16_TO_CAP32(SPEED_25G); + CAP16_TO_CAP32(SPEED_10G); + CAP16_TO_CAP32(SPEED_40G); + CAP16_TO_CAP32(SPEED_100G); + CAP16_TO_CAP32(FC_RX); + CAP16_TO_CAP32(FC_TX); + CAP16_TO_CAP32(ANEG); + CAP16_TO_CAP32(FORCE_PAUSE); + CAP16_TO_CAP32(MDIAUTO); + CAP16_TO_CAP32(MDISTRAIGHT); + CAP16_TO_CAP32(FEC_RS); + CAP16_TO_CAP32(FEC_BASER_RS); + CAP16_TO_CAP32(802_3_PAUSE); + CAP16_TO_CAP32(802_3_ASM_DIR); + + #undef CAP16_TO_CAP32 + + return caps32; +} + +/** + * fwcaps32_to_caps16 - convert 32-bit Port Capabilities to 16-bits + * @caps32: a 32-bit Port Capabilities value + * + * Returns the equivalent 16-bit Port Capabilities value. Note that + * not all 32-bit Port Capabilities can be represented in the 16-bit + * Port Capabilities and some fields/values may not make it. + */ +static uint16_t fwcaps32_to_caps16(uint32_t caps32) +{ + uint16_t caps16 = 0; + + #define CAP32_TO_CAP16(__cap) \ + do { \ + if (caps32 & FW_PORT_CAP32_##__cap) \ + caps16 |= FW_PORT_CAP_##__cap; \ + } while (0) + + CAP32_TO_CAP16(SPEED_100M); + CAP32_TO_CAP16(SPEED_1G); + CAP32_TO_CAP16(SPEED_10G); + CAP32_TO_CAP16(SPEED_25G); + CAP32_TO_CAP16(SPEED_40G); + CAP32_TO_CAP16(SPEED_100G); + CAP32_TO_CAP16(FC_RX); + CAP32_TO_CAP16(FC_TX); + CAP32_TO_CAP16(802_3_PAUSE); + CAP32_TO_CAP16(802_3_ASM_DIR); + CAP32_TO_CAP16(ANEG); + CAP32_TO_CAP16(FORCE_PAUSE); + CAP32_TO_CAP16(MDIAUTO); + CAP32_TO_CAP16(MDISTRAIGHT); + CAP32_TO_CAP16(FEC_RS); + CAP32_TO_CAP16(FEC_BASER_RS); + + #undef CAP32_TO_CAP16 + + return caps16; +} + +static bool +is_bt(struct port_info *pi) +{ + + return (pi->port_type == FW_PORT_TYPE_BT_SGMII || + pi->port_type == FW_PORT_TYPE_BT_XFI || + pi->port_type == FW_PORT_TYPE_BT_XAUI); +} + /** * t4_link_l1cfg - apply link configuration to MAC/PHY * @phy: the PHY to setup @@ -3772,53 +3859,45 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, struct link_config *lc) { struct fw_port_cmd c; - unsigned int mdi = V_FW_PORT_CAP_MDI(FW_PORT_CAP_MDI_AUTO); + unsigned int mdi = V_FW_PORT_CAP32_MDI(FW_PORT_CAP32_MDI_AUTO); unsigned int aneg, fc, fec, speed, rcap; fc = 0; if (lc->requested_fc & PAUSE_RX) - fc |= FW_PORT_CAP_FC_RX; + fc |= FW_PORT_CAP32_FC_RX; if (lc->requested_fc & PAUSE_TX) - fc |= FW_PORT_CAP_FC_TX; + fc |= FW_PORT_CAP32_FC_TX; + if (!(lc->requested_fc & PAUSE_AUTONEG)) + fc |= FW_PORT_CAP32_FORCE_PAUSE; fec = 0; - if (lc->requested_fec & FEC_RS) - fec = FW_PORT_CAP_FEC_RS; - else if (lc->requested_fec & FEC_BASER_RS) - fec = FW_PORT_CAP_FEC_BASER_RS; - - if (!(lc->supported & FW_PORT_CAP_ANEG) || - lc->requested_aneg == AUTONEG_DISABLE) { - aneg = 0; - switch (lc->requested_speed) { - case 100000: - speed = FW_PORT_CAP_SPEED_100G; - break; - case 40000: - speed = FW_PORT_CAP_SPEED_40G; - break; - case 25000: - speed = FW_PORT_CAP_SPEED_25G; - break; - case 10000: - speed = FW_PORT_CAP_SPEED_10G; - break; - case 1000: - speed = FW_PORT_CAP_SPEED_1G; - break; - case 100: - speed = FW_PORT_CAP_SPEED_100M; - break; - default: - return -EINVAL; - break; - } - } else { - aneg = FW_PORT_CAP_ANEG; - speed = lc->supported & - V_FW_PORT_CAP_SPEED(M_FW_PORT_CAP_SPEED); + if (lc->requested_fec == FEC_AUTO) + fec = lc->fec_hint; + else { + if (lc->requested_fec & FEC_RS) + fec |= FW_PORT_CAP32_FEC_RS; + if (lc->requested_fec & FEC_BASER_RS) + fec |= FW_PORT_CAP32_FEC_BASER_RS; } + if (lc->requested_aneg == AUTONEG_DISABLE) + aneg = 0; + else if (lc->requested_aneg == AUTONEG_ENABLE) + aneg = FW_PORT_CAP32_ANEG; + else + aneg = lc->supported & FW_PORT_CAP32_ANEG; + + if (aneg) { + speed = lc->supported & V_FW_PORT_CAP32_SPEED(M_FW_PORT_CAP32_SPEED); + } else if (lc->requested_speed != 0) + speed = speed_to_fwcap(lc->requested_speed); + else + speed = fwcap_top_speed(lc->supported); + + /* Force AN on for BT cards. */ + if (is_bt(adap->port[port])) + aneg = lc->supported & FW_PORT_CAP32_ANEG; + rcap = aneg | speed | fc | fec; if ((rcap | lc->supported) != lc->supported) { #ifdef INVARIANTS @@ -3833,10 +3912,17 @@ int t4_link_l1cfg(struct adapter *adap, unsigned int mbox, unsigned int port, c.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | F_FW_CMD_REQUEST | F_FW_CMD_EXEC | V_FW_PORT_CMD_PORTID(port)); - c.action_to_len16 = - cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | + if (adap->params.port_caps32) { + c.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG32) | + FW_LEN16(c)); + c.u.l1cfg32.rcap32 = cpu_to_be32(rcap); + } else { + c.action_to_len16 = + cpu_to_be32(V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_L1_CFG) | FW_LEN16(c)); - c.u.l1cfg.rcap = cpu_to_be32(rcap); + c.u.l1cfg.rcap = cpu_to_be32(fwcaps32_to_caps16(rcap)); + } return t4_wr_mbox_ns(adap, mbox, &c, sizeof(c), NULL); } @@ -7735,57 +7821,206 @@ const char *t4_link_down_rc_str(unsigned char link_down_rc) return reason[link_down_rc]; } +/* + * Return the highest speed set in the port capabilities, in Mb/s. + */ +unsigned int fwcap_to_speed(uint32_t caps) +{ + #define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return __speed; \ + } while (0) + + TEST_SPEED_RETURN(400G, 400000); + TEST_SPEED_RETURN(200G, 200000); + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + + #undef TEST_SPEED_RETURN + + return 0; +} + +/* + * Return the port capabilities bit for the given speed, which is in Mb/s. + */ +uint32_t speed_to_fwcap(unsigned int speed) +{ + #define TEST_SPEED_RETURN(__caps_speed, __speed) \ + do { \ + if (speed == __speed) \ + return FW_PORT_CAP32_SPEED_##__caps_speed; \ + } while (0) + + TEST_SPEED_RETURN(400G, 400000); + TEST_SPEED_RETURN(200G, 200000); + TEST_SPEED_RETURN(100G, 100000); + TEST_SPEED_RETURN(50G, 50000); + TEST_SPEED_RETURN(40G, 40000); + TEST_SPEED_RETURN(25G, 25000); + TEST_SPEED_RETURN(10G, 10000); + TEST_SPEED_RETURN(1G, 1000); + TEST_SPEED_RETURN(100M, 100); + + #undef TEST_SPEED_RETURN + + return 0; +} + +/* + * Return the port capabilities bit for the highest speed in the capabilities. + */ +uint32_t fwcap_top_speed(uint32_t caps) +{ + #define TEST_SPEED_RETURN(__caps_speed) \ + do { \ + if (caps & FW_PORT_CAP32_SPEED_##__caps_speed) \ + return FW_PORT_CAP32_SPEED_##__caps_speed; \ + } while (0) + + TEST_SPEED_RETURN(400G); + TEST_SPEED_RETURN(200G); + TEST_SPEED_RETURN(100G); + TEST_SPEED_RETURN(50G); + TEST_SPEED_RETURN(40G); + TEST_SPEED_RETURN(25G); + TEST_SPEED_RETURN(10G); + TEST_SPEED_RETURN(1G); + TEST_SPEED_RETURN(100M); + + #undef TEST_SPEED_RETURN + + return 0; +} + + +/** + * lstatus_to_fwcap - translate old lstatus to 32-bit Port Capabilities + * @lstatus: old FW_PORT_ACTION_GET_PORT_INFO lstatus value + * + * Translates old FW_PORT_ACTION_GET_PORT_INFO lstatus field into new + * 32-bit Port Capabilities value. + */ +static uint32_t lstatus_to_fwcap(u32 lstatus) +{ + uint32_t linkattr = 0; + + /* + * Unfortunately the format of the Link Status in the old + * 16-bit Port Information message isn't the same as the + * 16-bit Port Capabilities bitfield used everywhere else ... + */ + if (lstatus & F_FW_PORT_CMD_RXPAUSE) + linkattr |= FW_PORT_CAP32_FC_RX; + if (lstatus & F_FW_PORT_CMD_TXPAUSE) + linkattr |= FW_PORT_CAP32_FC_TX; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) + linkattr |= FW_PORT_CAP32_SPEED_100M; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) + linkattr |= FW_PORT_CAP32_SPEED_1G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) + linkattr |= FW_PORT_CAP32_SPEED_10G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) + linkattr |= FW_PORT_CAP32_SPEED_25G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) + linkattr |= FW_PORT_CAP32_SPEED_40G; + if (lstatus & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) + linkattr |= FW_PORT_CAP32_SPEED_100G; + + return linkattr; +} + /* * Updates all fields owned by the common code in port_info and link_config * based on information provided by the firmware. Does not touch any * requested_* field. */ -static void handle_port_info(struct port_info *pi, const struct fw_port_info *p) +static void handle_port_info(struct port_info *pi, const struct fw_port_cmd *p, + enum fw_port_action action, bool *mod_changed, bool *link_changed) { - struct link_config *lc = &pi->link_cfg; - int speed; + struct link_config old_lc, *lc = &pi->link_cfg; unsigned char fc, fec; - u32 stat = be32_to_cpu(p->lstatus_to_modtype); + u32 stat, linkattr; + int old_ptype, old_mtype; - pi->port_type = G_FW_PORT_CMD_PTYPE(stat); - pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); - pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? - G_FW_PORT_CMD_MDIOADDR(stat) : -1; + old_ptype = pi->port_type; + old_mtype = pi->mod_type; + old_lc = *lc; + if (action == FW_PORT_ACTION_GET_PORT_INFO) { + stat = be32_to_cpu(p->u.info.lstatus_to_modtype); - lc->supported = be16_to_cpu(p->pcap); - lc->advertising = be16_to_cpu(p->acap); - lc->lp_advertising = be16_to_cpu(p->lpacap); - lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; - lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); + pi->port_type = G_FW_PORT_CMD_PTYPE(stat); + pi->mod_type = G_FW_PORT_CMD_MODTYPE(stat); + pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP ? + G_FW_PORT_CMD_MDIOADDR(stat) : -1; - speed = 0; - if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100M)) - speed = 100; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_1G)) - speed = 1000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_10G)) - speed = 10000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_25G)) - speed = 25000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_40G)) - speed = 40000; - else if (stat & V_FW_PORT_CMD_LSPEED(FW_PORT_CAP_SPEED_100G)) - speed = 100000; - lc->speed = speed; + lc->supported = fwcaps16_to_caps32(be16_to_cpu(p->u.info.pcap)); + lc->advertising = fwcaps16_to_caps32(be16_to_cpu(p->u.info.acap)); + lc->lp_advertising = fwcaps16_to_caps32(be16_to_cpu(p->u.info.lpacap)); + lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS) != 0; + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC(stat); + + linkattr = lstatus_to_fwcap(stat); + } else if (action == FW_PORT_ACTION_GET_PORT_INFO32) { + stat = be32_to_cpu(p->u.info32.lstatus32_to_cbllen32); + + pi->port_type = G_FW_PORT_CMD_PORTTYPE32(stat); + pi->mod_type = G_FW_PORT_CMD_MODTYPE32(stat); + pi->mdio_addr = stat & F_FW_PORT_CMD_MDIOCAP32 ? + G_FW_PORT_CMD_MDIOADDR32(stat) : -1; + + lc->supported = be32_to_cpu(p->u.info32.pcaps32); + lc->advertising = be32_to_cpu(p->u.info32.acaps32); + lc->lp_advertising = be16_to_cpu(p->u.info32.lpacaps32); + lc->link_ok = (stat & F_FW_PORT_CMD_LSTATUS32) != 0; + lc->link_down_rc = G_FW_PORT_CMD_LINKDNRC32(stat); + + linkattr = be32_to_cpu(p->u.info32.linkattr32); + } else { + CH_ERR(pi->adapter, "bad port_info action 0x%x\n", action); + return; + } + + lc->speed = fwcap_to_speed(linkattr); fc = 0; - if (stat & F_FW_PORT_CMD_RXPAUSE) + if (linkattr & FW_PORT_CAP32_FC_RX) fc |= PAUSE_RX; - if (stat & F_FW_PORT_CMD_TXPAUSE) + if (linkattr & FW_PORT_CAP32_FC_TX) fc |= PAUSE_TX; lc->fc = fc; - fec = 0; - if (lc->advertising & FW_PORT_CAP_FEC_RS) - fec = FEC_RS; - else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS) - fec = FEC_BASER_RS; + fec = FEC_NONE; + if (linkattr & FW_PORT_CAP32_FEC_RS) + fec |= FEC_RS; + if (linkattr & FW_PORT_CAP32_FEC_BASER_RS) + fec |= FEC_BASER_RS; lc->fec = fec; + + if (mod_changed != NULL) + *mod_changed = false; + if (link_changed != NULL) + *link_changed = false; + if (old_ptype != pi->port_type || old_mtype != pi->mod_type || + old_lc.supported != lc->supported) { + if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) { + lc->fec_hint = lc->advertising & + V_FW_PORT_CAP32_FEC(M_FW_PORT_CAP32_FEC); + } + if (mod_changed != NULL) + *mod_changed = true; + } + if (old_lc.link_ok != lc->link_ok || old_lc.speed != lc->speed || + old_lc.fec != lc->fec || old_lc.fc != lc->fc) { + if (link_changed != NULL) + *link_changed = true; + } } /** @@ -7798,22 +8033,24 @@ static void handle_port_info(struct port_info *pi, const struct fw_port_info *p) */ int t4_update_port_info(struct port_info *pi) { - struct fw_port_cmd port_cmd; + struct adapter *sc = pi->adapter; + struct fw_port_cmd cmd; + enum fw_port_action action; int ret; - memset(&port_cmd, 0, sizeof port_cmd); - port_cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | - F_FW_CMD_REQUEST | F_FW_CMD_READ | - V_FW_PORT_CMD_PORTID(pi->tx_chan)); - port_cmd.action_to_len16 = cpu_to_be32( - V_FW_PORT_CMD_ACTION(FW_PORT_ACTION_GET_PORT_INFO) | - FW_LEN16(port_cmd)); - ret = t4_wr_mbox_ns(pi->adapter, pi->adapter->mbox, - &port_cmd, sizeof(port_cmd), &port_cmd); + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_portid = cpu_to_be32(V_FW_CMD_OP(FW_PORT_CMD) | + F_FW_CMD_REQUEST | F_FW_CMD_READ | + V_FW_PORT_CMD_PORTID(pi->tx_chan)); + action = sc->params.port_caps32 ? FW_PORT_ACTION_GET_PORT_INFO32 : + FW_PORT_ACTION_GET_PORT_INFO; + cmd.action_to_len16 = cpu_to_be32(V_FW_PORT_CMD_ACTION(action) | + FW_LEN16(cmd)); + ret = t4_wr_mbox_ns(sc, sc->mbox, &cmd, sizeof(cmd), &cmd); if (ret) return ret; - handle_port_info(pi, &port_cmd.u.info); + handle_port_info(pi, &cmd, action, NULL, NULL); return 0; } @@ -7828,15 +8065,18 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) { u8 opcode = *(const u8 *)rpl; const struct fw_port_cmd *p = (const void *)rpl; - unsigned int action = - G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); + enum fw_port_action action = + G_FW_PORT_CMD_ACTION(be32_to_cpu(p->action_to_len16)); + bool mod_changed, link_changed; - if (opcode == FW_PORT_CMD && action == FW_PORT_ACTION_GET_PORT_INFO) { + if (opcode == FW_PORT_CMD && + (action == FW_PORT_ACTION_GET_PORT_INFO || + action == FW_PORT_ACTION_GET_PORT_INFO32)) { /* link/module state change message */ - int i, old_ptype, old_mtype; + int i; int chan = G_FW_PORT_CMD_PORTID(be32_to_cpu(p->op_to_portid)); struct port_info *pi = NULL; - struct link_config *lc, *old_lc; + struct link_config *lc; for_each_port(adap, i) { pi = adap2pinfo(adap, i); @@ -7846,23 +8086,15 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl) lc = &pi->link_cfg; PORT_LOCK(pi); - old_lc = &pi->old_link_cfg; - old_ptype = pi->port_type; - old_mtype = pi->mod_type; - handle_port_info(pi, &p->u.info); + handle_port_info(pi, p, action, &mod_changed, &link_changed); PORT_UNLOCK(pi); - if (old_ptype != pi->port_type || old_mtype != pi->mod_type) { + if (mod_changed) t4_os_portmod_changed(pi); - } - PORT_LOCK(pi); - if (old_lc->link_ok != lc->link_ok || - old_lc->speed != lc->speed || - old_lc->fec != lc->fec || - old_lc->fc != lc->fc) { + if (link_changed) { + PORT_LOCK(pi); t4_os_link_changed(pi); - *old_lc = *lc; + PORT_UNLOCK(pi); } - PORT_UNLOCK(pi); } else { CH_WARN_RATELIMIT(adap, "Unknown firmware reply %d\n", opcode); return -EINVAL; @@ -8595,6 +8827,11 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) } while ((adap->params.portvec & (1 << j)) == 0); } + p->tx_chan = j; + p->mps_bg_map = t4_get_mps_bg_map(adap, j); + p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); + p->lport = j; + if (!(adap->flags & IS_VF) || adap->params.vfres.r_caps & FW_CMD_CAP_PORT) { t4_update_port_info(p); @@ -8609,10 +8846,6 @@ int t4_port_init(struct adapter *adap, int mbox, int pf, int vf, int port_id) p->vi[0].smt_idx = (ret & 0x7f) << 1; else p->vi[0].smt_idx = (ret & 0x7f); - p->tx_chan = j; - p->mps_bg_map = t4_get_mps_bg_map(adap, j); - p->rx_e_chan_map = t4_get_rx_e_chan_map(adap, j); - p->lport = j; p->vi[0].rss_size = rss_size; t4_os_set_hw_addr(p, addr); diff --git a/sys/dev/cxgbe/osdep.h b/sys/dev/cxgbe/osdep.h index 5cd3e88803ad..6eec287db1a7 100644 --- a/sys/dev/cxgbe/osdep.h +++ b/sys/dev/cxgbe/osdep.h @@ -108,6 +108,7 @@ typedef boolean_t bool; #define DUPLEX_HALF 0 #define DUPLEX_FULL 1 +#define AUTONEG_AUTO (-1) #define AUTONEG_DISABLE 0 #define AUTONEG_ENABLE 1 diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index d6ad6048973a..3ae560585897 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; @@ -526,9 +528,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 +1022,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, @@ -1885,7 +1897,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); } @@ -2063,8 +2075,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) @@ -2081,8 +2093,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 = @@ -2093,47 +2111,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) { @@ -2142,24 +2138,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: @@ -2170,15 +2166,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; @@ -2196,53 +2194,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: @@ -2284,12 +2288,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; @@ -2300,7 +2304,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); @@ -4135,6 +4139,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 @@ -4217,22 +4227,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; } @@ -4241,16 +4259,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); @@ -4258,18 +4302,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: @@ -4280,9 +4318,9 @@ build_medialist(struct port_info *pi, struct ifmedia *ifm) } unknown = 0; - for (bit = 0; bit < fls(ss); bit++) { + for (bit = S_FW_PORT_CAP32_SPEED; bit < fls(ss); bit++) { speed = 1 << bit; - MPASS(speed & M_FW_PORT_CAP_SPEED); + MPASS(speed & M_FW_PORT_CAP32_SPEED); if (ss & speed) { mword = port_mword(pi, speed); if (mword == IFM_NONE) { @@ -4295,86 +4333,134 @@ build_medialist(struct port_info *pi, struct ifmedia *ifm) } if (unknown > 0) /* Add one unknown for all unknown media types. */ ifmedia_add4(ifm, IFM_ETHER | IFM_FDX | IFM_UNKNOWN); - if (lc->supported & FW_PORT_CAP_ANEG) + if (lc->supported & FW_PORT_CAP32_ANEG) ifmedia_add(ifm, IFM_ETHER | IFM_AUTO, 0, NULL); - set_current_media(pi, ifm); + set_current_media(pi); } /* - * Update all the requested_* fields in the link config to something valid (and - * reasonable). + * Initialize the requested fields in the link config based on driver tunables. */ static void -init_l1cfg(struct port_info *pi) +init_link_config(struct port_info *pi) { struct link_config *lc = &pi->link_cfg; PORT_LOCK_ASSERT_OWNED(pi); - /* Gbps -> Mbps */ - lc->requested_speed = port_top_speed(pi) * 1000; + lc->requested_speed = 0; - if (t4_autoneg != 0 && lc->supported & FW_PORT_CAP_ANEG) { - lc->requested_aneg = AUTONEG_ENABLE; - } else { + if (t4_autoneg == 0) lc->requested_aneg = AUTONEG_DISABLE; - } + else if (t4_autoneg == 1) + lc->requested_aneg = AUTONEG_ENABLE; + else + lc->requested_aneg = AUTONEG_AUTO; - lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX); + lc->requested_fc = t4_pause_settings & (PAUSE_TX | PAUSE_RX | + PAUSE_AUTONEG); - if (t4_fec != -1) { - if (t4_fec & FEC_RS && lc->supported & FW_PORT_CAP_FEC_RS) { - lc->requested_fec = FEC_RS; - } else if (t4_fec & FEC_BASER_RS && - lc->supported & FW_PORT_CAP_FEC_BASER_RS) { - lc->requested_fec = FEC_BASER_RS; - } else { - lc->requested_fec = 0; - } - } else { - /* Use the suggested value provided by the firmware in acaps */ - if (lc->advertising & FW_PORT_CAP_FEC_RS && - lc->supported & FW_PORT_CAP_FEC_RS) { - lc->requested_fec = FEC_RS; - } else if (lc->advertising & FW_PORT_CAP_FEC_BASER_RS && - lc->supported & FW_PORT_CAP_FEC_BASER_RS) { - lc->requested_fec = FEC_BASER_RS; - } else { - lc->requested_fec = 0; - } + if (t4_fec == -1 || t4_fec & FEC_AUTO) + lc->requested_fec = FEC_AUTO; + else { + lc->requested_fec = FEC_NONE; + if (t4_fec & FEC_RS) + lc->requested_fec |= FEC_RS; + if (t4_fec & FEC_BASER_RS) + lc->requested_fec |= FEC_BASER_RS; } } /* - * Apply the settings in requested_* to the hardware. The parameters are - * expected to be sane. + * Makes sure that all requested settings comply with what's supported by the + * port. Returns the number of settings that were invalid and had to be fixed. */ static int -apply_l1cfg(struct port_info *pi) +fixup_link_config(struct port_info *pi) +{ + int n = 0; + struct link_config *lc = &pi->link_cfg; + uint32_t fwspeed; + + PORT_LOCK_ASSERT_OWNED(pi); + + /* Speed (when not autonegotiating) */ + if (lc->requested_speed != 0) { + fwspeed = speed_to_fwcap(lc->requested_speed); + if ((fwspeed & lc->supported) == 0) { + n++; + lc->requested_speed = 0; + } + } + + /* Link autonegotiation */ + MPASS(lc->requested_aneg == AUTONEG_ENABLE || + lc->requested_aneg == AUTONEG_DISABLE || + lc->requested_aneg == AUTONEG_AUTO); + if (lc->requested_aneg == AUTONEG_ENABLE && + !(lc->supported & FW_PORT_CAP32_ANEG)) { + n++; + lc->requested_aneg = AUTONEG_AUTO; + } + + /* Flow control */ + MPASS((lc->requested_fc & ~(PAUSE_TX | PAUSE_RX | PAUSE_AUTONEG)) == 0); + if (lc->requested_fc & PAUSE_TX && + !(lc->supported & FW_PORT_CAP32_FC_TX)) { + n++; + lc->requested_fc &= ~PAUSE_TX; + } + if (lc->requested_fc & PAUSE_RX && + !(lc->supported & FW_PORT_CAP32_FC_RX)) { + n++; + lc->requested_fc &= ~PAUSE_RX; + } + if (!(lc->requested_fc & PAUSE_AUTONEG) && + !(lc->supported & FW_PORT_CAP32_FORCE_PAUSE)) { + n++; + lc->requested_fc |= PAUSE_AUTONEG; + } + + /* FEC */ + if ((lc->requested_fec & FEC_RS && + !(lc->supported & FW_PORT_CAP32_FEC_RS)) || + (lc->requested_fec & FEC_BASER_RS && + !(lc->supported & FW_PORT_CAP32_FEC_BASER_RS))) { + n++; + lc->requested_fec = FEC_AUTO; + } + + return (n); +} + +/* + * Apply the requested L1 settings, which are expected to be valid, to the + * hardware. + */ +static int +apply_link_config(struct port_info *pi) { struct adapter *sc = pi->adapter; struct link_config *lc = &pi->link_cfg; int rc; -#ifdef INVARIANTS - uint16_t fwspeed; +#ifdef INVARIANTS ASSERT_SYNCHRONIZED_OP(sc); PORT_LOCK_ASSERT_OWNED(pi); if (lc->requested_aneg == AUTONEG_ENABLE) - MPASS(lc->supported & FW_PORT_CAP_ANEG); + MPASS(lc->supported & FW_PORT_CAP32_ANEG); + if (!(lc->requested_fc & PAUSE_AUTONEG)) + MPASS(lc->supported & FW_PORT_CAP32_FORCE_PAUSE); if (lc->requested_fc & PAUSE_TX) - MPASS(lc->supported & FW_PORT_CAP_FC_TX); + MPASS(lc->supported & FW_PORT_CAP32_FC_TX); if (lc->requested_fc & PAUSE_RX) - MPASS(lc->supported & FW_PORT_CAP_FC_RX); - if (lc->requested_fec == FEC_RS) - MPASS(lc->supported & FW_PORT_CAP_FEC_RS); - if (lc->requested_fec == FEC_BASER_RS) - MPASS(lc->supported & FW_PORT_CAP_FEC_BASER_RS); - fwspeed = speed_to_fwspeed(lc->requested_speed); - MPASS(fwspeed != 0); - MPASS(lc->supported & fwspeed); + MPASS(lc->supported & FW_PORT_CAP32_FC_RX); + if (lc->requested_fec & FEC_RS) + MPASS(lc->supported & FW_PORT_CAP32_FEC_RS); + if (lc->requested_fec & FEC_BASER_RS) + MPASS(lc->supported & FW_PORT_CAP32_FEC_BASER_RS); #endif rc = -t4_link_l1cfg(sc, sc->mbox, pi->tx_chan, lc); if (rc != 0) { @@ -4382,8 +4468,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); } @@ -4637,9 +4732,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; } @@ -4666,12 +4770,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) @@ -4746,11 +4845,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); @@ -6514,7 +6612,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) @@ -6524,14 +6622,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); @@ -6543,7 +6648,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, @@ -6551,15 +6656,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); } @@ -6574,10 +6675,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) @@ -6587,43 +6689,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); } @@ -6637,10 +6764,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); @@ -6651,28 +6778,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); @@ -9409,13 +9530,17 @@ t4_os_portmod_changed(struct port_info *pi) NULL, "LR", "SR", "ER", "TWINAX", "active TWINAX", "LRM" }; - MPASS((pi->flags & FIXED_IFMEDIA) == 0); + KASSERT((pi->flags & FIXED_IFMEDIA) == 0, + ("%s: port_type %u", __func__, pi->port_type)); vi = &pi->vi[0]; if (begin_synchronized_op(sc, vi, HOLD_LOCK, "t4mod") == 0) { PORT_LOCK(pi); - build_medialist(pi, &pi->media); - apply_l1cfg(pi); + build_medialist(pi); + if (pi->mod_type != FW_PORT_MOD_TYPE_NONE) { + fixup_link_config(pi); + apply_link_config(pi); + } PORT_UNLOCK(pi); end_synchronized_op(sc, LOCK_HELD); } diff --git a/sys/dev/cxgbe/tom/t4_cpl_io.c b/sys/dev/cxgbe/tom/t4_cpl_io.c index 4a6ac900962b..684606a8d5b5 100644 --- a/sys/dev/cxgbe/tom/t4_cpl_io.c +++ b/sys/dev/cxgbe/tom/t4_cpl_io.c @@ -634,7 +634,7 @@ write_tx_wr(void *dst, struct toepcb *toep, unsigned int immdlen, if (txalign > 0) { struct tcpcb *tp = intotcpcb(toep->inp); - if (plen < 2 * tp->t_maxseg || is_10G_port(toep->vi->pi)) + if (plen < 2 * tp->t_maxseg) txwr->lsodisable_to_flags |= htobe32(F_FW_OFLD_TX_DATA_WR_LSODISABLE); else From a78849183cb91537da6fb60c055d97611475918d Mon Sep 17 00:00:00 2001 From: Brooks Davis <brooks@FreeBSD.org> Date: Tue, 25 Sep 2018 15:25:42 +0000 Subject: [PATCH 101/139] Don't override LDFLAGS set in bsd.cpu.mk. This is a direct commit to a generated file. Simon plans to fix this upstream before the next import. PR: 231557 Approved by: re (gjb) Obtained from: CheriBSD Sponsored by: DARPA, AFRL --- usr.bin/bmake/Makefile.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/bmake/Makefile.config b/usr.bin/bmake/Makefile.config index a8d35ea3112f..1b4fa796e722 100644 --- a/usr.bin/bmake/Makefile.config +++ b/usr.bin/bmake/Makefile.config @@ -16,7 +16,7 @@ DEFAULT_SYS_PATH?= .../share/mk:/usr/share/mk CPPFLAGS+= CFLAGS+= ${CPPFLAGS} -DHAVE_CONFIG_H -LDFLAGS= +LDFLAGS+= LIBOBJS= ${LIBOBJDIR}stresep$U.o LDADD= USE_META= yes From af534f8d99b2d1b2cef5804bd4947c33646bf417 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Tue, 25 Sep 2018 17:58:06 +0000 Subject: [PATCH 102/139] zfs: depessimize zfs_root with rmlocks Currently vfs calls the root method on each absolute lookup and when crossing mount points. zfs_root ends up looking up the inode internally as if it was not instantianted which results in significant lock contention on systems like EPYC. Store the vnode in the mount point and protect the access with rmlocks. This is a temporary hack for 12.0. Sample result: before: make -s -j 128 buildkernel 2778.09s user 3319.45s system 8370% cpu 1:12.85 total after: make -s -j 128 buildkernel 3199.57s user 1772.78s system 8232% cpu 1:00.40 total Tested by: pho (zfs mount/unmount tests) Reviewed by: kib, mav, sef (different parts) Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17233 --- .../uts/common/fs/zfs/sys/zfs_vfsops.h | 2 + .../uts/common/fs/zfs/zfs_vfsops.c | 68 ++++++++++++++++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h index 8cd6360e4cf5..bbfb79ce24d3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h @@ -46,6 +46,8 @@ struct zfsvfs { zfsvfs_t *z_parent; /* parent fs */ objset_t *z_os; /* objset reference */ uint64_t z_root; /* id of root znode */ + struct vnode *z_rootvnode; /* root vnode */ + struct rmlock z_rootvnodelock;/* protection for root vnode */ uint64_t z_unlinkedobj; /* id of unlinked zapobj */ uint64_t z_max_blksz; /* maximum block size for files */ uint64_t z_fuid_obj; /* fuid table object number */ diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 8e421132b10e..1ab51ba77a1f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -65,6 +65,7 @@ #include <sys/spa_boot.h> #include <sys/jail.h> #include <ufs/ufs/quota.h> +#include <sys/rmlock.h> #include "zfs_comutil.h" @@ -92,6 +93,9 @@ static int zfs_version_zpl = ZPL_VERSION; SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0, "ZPL_VERSION"); +static int zfs_root_setvnode(zfsvfs_t *zfsvfs); +static void zfs_root_dropvnode(zfsvfs_t *zfsvfs); + static int zfs_quotactl(vfs_t *vfsp, int cmds, uid_t id, void *arg); static int zfs_mount(vfs_t *vfsp); static int zfs_umount(vfs_t *vfsp, int fflag); @@ -1209,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; @@ -1315,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); @@ -1921,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 @@ -1993,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); @@ -2008,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); @@ -2126,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), From cbe100dfca7b4d8412aaa90845980853771a8a24 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Tue, 25 Sep 2018 18:24:25 +0000 Subject: [PATCH 103/139] Fix an issue in r338862. For pmap_invalidate_all_pcid(), only reset pm_gen for non-kernel pmaps, as it was done before the conversion to ifuncs. The reset is useless but innocent for kernel_pmap. Coverity reported that cpuid is used uninitialized in this case. Reported by: cem Reviewed by: alc, cem, markj CID: 1395807 Sponsored by: The FreeBSD Foundation Approved by: re (gjb) Differential revision: https://reviews.freebsd.org/D17314 --- sys/amd64/amd64/pmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index ab8cc7d1b6f8..d91906a10508 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1966,10 +1966,10 @@ pmap_invalidate_all_pcid(pmap_t pmap, bool invpcid_works1) critical_exit(); } else pmap->pm_pcids[cpuid].pm_gen = 0; - } - CPU_FOREACH(i) { - if (cpuid != i) - pmap->pm_pcids[i].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(); From 25569cea2b73e0a1e91a36807ffa2c053e5cf6b3 Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Tue, 25 Sep 2018 18:54:18 +0000 Subject: [PATCH 104/139] Do not remove ld man page if lld is enabled and binutils is not Reported by: Mark Millard Approved by: re (gjb) Sponsored by: The FreeBSD Foundation --- tools/build/mk/OptionalObsoleteFiles.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index 0de449a50fab..ee8d3552ecb0 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -206,6 +206,7 @@ OLD_DIRS+=usr/share/examples/bhyve OLD_FILES+=usr/bin/as .if ${MK_LLD_IS_LD} == no OLD_FILES+=usr/bin/ld +OLD_FILES+=usr/share/man/man1/ld.1.gz .endif OLD_FILES+=usr/bin/ld.bfd OLD_FILES+=usr/bin/objdump @@ -405,7 +406,6 @@ OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xsw OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xu OLD_FILES+=usr/libdata/ldscripts/elf_x86_64_fbsd.xw OLD_FILES+=usr/share/man/man1/as.1.gz -OLD_FILES+=usr/share/man/man1/ld.1.gz OLD_FILES+=usr/share/man/man1/objdump.1.gz OLD_FILES+=usr/share/man/man7/as.7.gz OLD_FILES+=usr/share/man/man7/ld.7.gz From 28337eb676fa0e7bd24d28d249e4907ab05a7756 Mon Sep 17 00:00:00 2001 From: Andreas Tobler <andreast@FreeBSD.org> Date: Tue, 25 Sep 2018 19:29:35 +0000 Subject: [PATCH 105/139] Bring the 32-bit powerpc (PowerMac) back to live. The commit 338486 reworked some TLS bits. This broke operation on the PowerMac. Namely one could not login. At login the screen/shell was giving back lots of backslashes and the login shell dumped core. The fix to this issue is to revert the powerpc commit from 338486 and to increase the TLS_TCB_SIZE to 16. Reverting only did not help, login was possible but userland applications aborted with strange messages. I tested this patch with world/kernel builds and with port upgrades. Additionally a full gcc8 bootstrap was successfully completed. Reviewed by: jhibbits@ Approved by: re (Glen) --- libexec/rtld-elf/powerpc/rtld_machdep.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libexec/rtld-elf/powerpc/rtld_machdep.h b/libexec/rtld-elf/powerpc/rtld_machdep.h index c89ec4817401..4e7854d34661 100644 --- a/libexec/rtld-elf/powerpc/rtld_machdep.h +++ b/libexec/rtld-elf/powerpc/rtld_machdep.h @@ -69,12 +69,12 @@ void _rtld_powerpc_pltcall(void); #define TLS_TP_OFFSET 0x7000 #define TLS_DTV_OFFSET 0x8000 -#define TLS_TCB_SIZE 8 +#define TLS_TCB_SIZE 16 #define round(size, align) \ (((size) + (align) - 1) & ~((align) - 1)) #define calculate_first_tls_offset(size, align) \ - TLS_TCB_SIZE + round(8, align) #define calculate_tls_offset(prev_offset, prev_size, size, align) \ round(prev_offset + prev_size, align) #define calculate_tls_end(off, size) ((off) + (size)) From 05e1cca97a180df482a89e3bb382cf695cac31da Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Tue, 25 Sep 2018 20:07:58 +0000 Subject: [PATCH 106/139] Fix some uses of dmaplimit. dmaplimit is the first byte after the end of DMAP. Reported by: "Johnson, Archna" <Archna.Johnson@netapp.com> Reviewed by: alc, markj Approved by: re (gjb) MFC after: 1 week Differential revision: https://reviews.freebsd.org/D17318 --- sys/amd64/amd64/pmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index d91906a10508..61dfd2607b40 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -1422,7 +1422,7 @@ pmap_init(void) if (ppim->va == 0) continue; /* Make the direct map consistent */ - if (ppim->pa < dmaplimit && ppim->pa + ppim->sz < dmaplimit) { + if (ppim->pa < dmaplimit && ppim->pa + ppim->sz <= dmaplimit) { (void)pmap_change_attr(PHYS_TO_DMAP(ppim->pa), ppim->sz, ppim->mode); } @@ -7055,7 +7055,7 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) * If the specified range of physical addresses fits within * the direct map window, use the direct map. */ - if (pa < dmaplimit && pa + size < dmaplimit) { + if (pa < dmaplimit && pa + size <= dmaplimit) { va = PHYS_TO_DMAP(pa); if (!pmap_change_attr(va, size, mode)) return ((void *)(va + offset)); From cb8dedc76ef2290559c0e9e95621bf3729b990a3 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar <np@FreeBSD.org> Date: Wed, 26 Sep 2018 02:27:37 +0000 Subject: [PATCH 107/139] cxgbe(4): Treat base/end of firmware parameters as signed integers when figuring out whether the range is valid or not. Approved by: re@ (rgrimes@) MFC after: 1 week Sponsored by: Chelsio Communications --- sys/dev/cxgbe/t4_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index 3ae560585897..dc491fd1d7d3 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -3851,7 +3851,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; @@ -3986,7 +3986,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; @@ -4016,7 +4016,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; } From 0277ec9c43aef2eeb5af9f1f8814001bb512ea0e Mon Sep 17 00:00:00 2001 From: Michael Tuexen <tuexen@FreeBSD.org> Date: Wed, 26 Sep 2018 10:24:50 +0000 Subject: [PATCH 108/139] Whitespace changes and fixing a typo. No functional change. Approved by: re (kib@) MFC after: 1 week --- sys/netinet/sctp_input.c | 1 - sys/netinet/sctp_output.c | 2 +- sys/netinet/sctputil.c | 16 ++++++++-------- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c index b77abf4768ce..3a7d93833a0a 100644 --- a/sys/netinet/sctp_input.c +++ b/sys/netinet/sctp_input.c @@ -5669,7 +5669,6 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt vrf_id, port); goto out; } - } if (IS_SCTP_CONTROL(ch)) { /* process the control portion of the SCTP packet */ diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index e7807b331629..a0b09ddd3336 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -7210,7 +7210,7 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, if ((sp->msg_is_complete) && (sp->length == 0)) { if (sp->sender_all_done) { /* - * We are doing differed cleanup. Last time through + * We are doing defered cleanup. Last time through * when we took all the data the sender_all_done was * not set. */ diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 12047ad91293..5fc57fe139ea 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3700,7 +3700,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, return; } if ((SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_WAIT) || - (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { + (SCTP_GET_STATE(stcb) == SCTP_STATE_COOKIE_ECHOED)) { if ((notification == SCTP_NOTIFY_INTERFACE_DOWN) || (notification == SCTP_NOTIFY_INTERFACE_UP) || (notification == SCTP_NOTIFY_INTERFACE_CONFIRMED)) { @@ -7391,8 +7391,8 @@ sctp_set_state(struct sctp_tcb *stcb, int new_state) #endif KASSERT((new_state & ~SCTP_STATE_MASK) == 0, - ("sctp_set_state: Can't set substate (new_state = %x)", - new_state)); + ("sctp_set_state: Can't set substate (new_state = %x)", + new_state)); stcb->asoc.state = (stcb->asoc.state & ~SCTP_STATE_MASK) | new_state; if ((new_state == SCTP_STATE_SHUTDOWN_RECEIVED) || (new_state == SCTP_STATE_SHUTDOWN_SENT) || @@ -7402,7 +7402,7 @@ sctp_set_state(struct sctp_tcb *stcb, int new_state) #if defined(KDTRACE_HOOKS) if (((old_state & SCTP_STATE_MASK) != new_state) && !(((old_state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY) && - (new_state == SCTP_STATE_INUSE))) { + (new_state == SCTP_STATE_INUSE))) { SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state); } #endif @@ -7416,14 +7416,14 @@ sctp_add_substate(struct sctp_tcb *stcb, int substate) #endif KASSERT((substate & SCTP_STATE_MASK) == 0, - ("sctp_add_substate: Can't set state (substate = %x)", - substate)); + ("sctp_add_substate: Can't set state (substate = %x)", + substate)); stcb->asoc.state |= substate; #if defined(KDTRACE_HOOKS) if (((substate & SCTP_STATE_ABOUT_TO_BE_FREED) && - ((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) || + ((old_state & SCTP_STATE_ABOUT_TO_BE_FREED) == 0)) || ((substate & SCTP_STATE_SHUTDOWN_PENDING) && - ((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) { + ((old_state & SCTP_STATE_SHUTDOWN_PENDING) == 0))) { SCTP_PROBE6(state__change, NULL, stcb, NULL, stcb, NULL, old_state); } #endif From a4ea412d4ff4de61f72d3b4b8b4cefa62b991f53 Mon Sep 17 00:00:00 2001 From: Slava Shwartsman <slavash@FreeBSD.org> Date: Wed, 26 Sep 2018 13:16:55 +0000 Subject: [PATCH 109/139] Add PCIV_INVALID definition From PCI Spec rev 2.2, 6.2.1. Device Identification: Vendor ID This field identifies the manufacturer of the device. Valid vendor identifiers are allocated by the PCI SIG to ensure uniqueness. 0FFFFh is an invalid value for Vendor ID. MFC after: 3 days Approved by: re (Glen), hselasky (mentor), kib (mentor) Sponsored by: Mellanox Technologies --- sys/dev/pci/pcireg.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/dev/pci/pcireg.h b/sys/dev/pci/pcireg.h index 00589c4b83da..edec95c8e67f 100644 --- a/sys/dev/pci/pcireg.h +++ b/sys/dev/pci/pcireg.h @@ -122,6 +122,9 @@ #define PCIM_MFDEV 0x80 #define PCIR_BIST 0x0f +/* PCI Spec rev 2.2: 0FFFFh is an invalid value for Vendor ID. */ +#define PCIV_INVALID 0xffff + /* Capability Register Offsets */ #define PCICAP_ID 0x0 From 6f282e722e55331768778fc5fe255bd71880e588 Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Wed, 26 Sep 2018 14:32:36 +0000 Subject: [PATCH 110/139] Clarify UPDATING entry about lld The workaround described in the 20180530 entry is no longer required. Amend that entry and add a new 20180530 entry noting lld is the default amd64 linker. Reviewed by: imp Approved by: re (kib) --- UPDATING | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/UPDATING b/UPDATING index 122b0600e827..94fd1d1cb332 100644 --- a/UPDATING +++ b/UPDATING @@ -169,6 +169,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 +201,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 From 0ddfd867ed9a3818266e786b0aa453d8544b0669 Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" <ae@FreeBSD.org> Date: Wed, 26 Sep 2018 14:47:51 +0000 Subject: [PATCH 111/139] Fix witness warning in xform_init(). Do not call crypto_newsession() while holding xforms_lock mutex. Release mutex before invoking crypto_newsession(), and use ipsec_kmod_enter()/ipsec_kmod_exit() functions to protect from doing access to unloaded kernel module memory. Move xform-releated functions into subr_ipsec.c to be able use ipsec_kmod_* functions. Also unconditionally build ipsec_kmod_* functions, since now they are always used by IPSec code. Add xf_cntr field to struct xformsw, it is used by ipsec_kmod_* functions. Also constify xf_name field, since it is not expected to be modified. Approved by: re (kib) Differential Revision: https://reviews.freebsd.org/D17302 --- sys/netipsec/key.c | 81 +----------------------------------- sys/netipsec/key.h | 3 ++ sys/netipsec/subr_ipsec.c | 86 +++++++++++++++++++++++++++++++++++---- sys/netipsec/xform.h | 7 +++- 4 files changed, 87 insertions(+), 90 deletions(-) diff --git a/sys/netipsec/key.c b/sys/netipsec/key.c index 8f5004a0613c..1e027bf6076e 100644 --- a/sys/netipsec/key.c +++ b/sys/netipsec/key.c @@ -534,14 +534,6 @@ MALLOC_DEFINE(M_IPSEC_SPDCACHE, "ipsec-spdcache", "ipsec SPD cache"); VNET_DEFINE_STATIC(uma_zone_t, key_lft_zone); #define V_key_lft_zone VNET(key_lft_zone) -static LIST_HEAD(xforms_list, xformsw) xforms = LIST_HEAD_INITIALIZER(); -static struct mtx xforms_lock; -#define XFORMS_LOCK_INIT() \ - mtx_init(&xforms_lock, "xforms_list", "IPsec transforms list", MTX_DEF) -#define XFORMS_LOCK_DESTROY() mtx_destroy(&xforms_lock) -#define XFORMS_LOCK() mtx_lock(&xforms_lock) -#define XFORMS_UNLOCK() mtx_unlock(&xforms_lock) - /* * set parameters into secpolicyindex buffer. * Must allocate secpolicyindex buffer passed to this function. @@ -717,7 +709,6 @@ static int key_delete(struct socket *, struct mbuf *, const struct sadb_msghdr *); static int key_delete_all(struct socket *, struct mbuf *, const struct sadb_msghdr *, struct secasindex *); -static void key_delete_xform(const struct xformsw *); static int key_get(struct socket *, struct mbuf *, const struct sadb_msghdr *); @@ -750,7 +741,6 @@ static int key_validate_ext(const struct sadb_ext *, int); static int key_align(struct mbuf *, struct sadb_msghdr *); static struct mbuf *key_setlifetime(struct seclifetime *, uint16_t); static struct mbuf *key_setkey(struct seckey *, uint16_t); -static int xform_init(struct secasvar *, u_short); static void spdcache_init(void); static void spdcache_clear(void); @@ -6167,7 +6157,7 @@ key_delete_all(struct socket *so, struct mbuf *m, * Larval SAs have not initialized tdb_xform, so it is safe to leave them * here when xform disappears. */ -static void +void key_delete_xform(const struct xformsw *xsp) { struct secasvar_queue drainq; @@ -8335,7 +8325,6 @@ key_init(void) if (!IS_DEFAULT_VNET(curvnet)) return; - XFORMS_LOCK_INIT(); SPTREE_LOCK_INIT(); REGTREE_LOCK_INIT(); SAHTREE_LOCK_INIT(); @@ -8458,7 +8447,6 @@ key_destroy(void) #ifndef IPSEC_DEBUG2 callout_drain(&key_timer); #endif - XFORMS_LOCK_DESTROY(); SPTREE_LOCK_DESTROY(); REGTREE_LOCK_DESTROY(); SAHTREE_LOCK_DESTROY(); @@ -8617,70 +8605,3 @@ comp_algorithm_lookup(int alg) return (NULL); } -/* - * Register a transform. - */ -static int -xform_register(struct xformsw* xsp) -{ - struct xformsw *entry; - - XFORMS_LOCK(); - LIST_FOREACH(entry, &xforms, chain) { - if (entry->xf_type == xsp->xf_type) { - XFORMS_UNLOCK(); - return (EEXIST); - } - } - LIST_INSERT_HEAD(&xforms, xsp, chain); - XFORMS_UNLOCK(); - return (0); -} - -void -xform_attach(void *data) -{ - struct xformsw *xsp = (struct xformsw *)data; - - if (xform_register(xsp) != 0) - printf("%s: failed to register %s xform\n", __func__, - xsp->xf_name); -} - -void -xform_detach(void *data) -{ - struct xformsw *xsp = (struct xformsw *)data; - - XFORMS_LOCK(); - LIST_REMOVE(xsp, chain); - XFORMS_UNLOCK(); - - /* Delete all SAs related to this xform. */ - key_delete_xform(xsp); -} - -/* - * Initialize transform support in an sav. - */ -static int -xform_init(struct secasvar *sav, u_short xftype) -{ - struct xformsw *entry; - int ret; - - IPSEC_ASSERT(sav->tdb_xform == NULL, - ("tdb_xform is already initialized")); - - ret = EINVAL; - XFORMS_LOCK(); - LIST_FOREACH(entry, &xforms, chain) { - if (entry->xf_type == xftype) { - ret = (*entry->xf_init)(sav, entry); - break; - } - } - XFORMS_UNLOCK(); - return (ret); -} - diff --git a/sys/netipsec/key.h b/sys/netipsec/key.h index 6c3e05c039e8..7d7ae69f379d 100644 --- a/sys/netipsec/key.h +++ b/sys/netipsec/key.h @@ -46,6 +46,7 @@ struct sadb_msg; struct sadb_x_policy; struct secasindex; union sockaddr_union; +struct xformsw; struct secpolicy *key_newsp(void); struct secpolicy *key_allocsp(struct secpolicyindex *, u_int); @@ -74,6 +75,8 @@ int key_sockaddrcmp_withmask(const struct sockaddr *, const struct sockaddr *, int key_register_ifnet(struct secpolicy **, u_int); void key_unregister_ifnet(struct secpolicy **, u_int); +void key_delete_xform(const struct xformsw *); + extern u_long key_random(void); extern void key_randomfill(void *, size_t); extern void key_freereg(struct socket *); diff --git a/sys/netipsec/subr_ipsec.c b/sys/netipsec/subr_ipsec.c index acfe66acf458..37b686a7e91e 100644 --- a/sys/netipsec/subr_ipsec.c +++ b/sys/netipsec/subr_ipsec.c @@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$"); #include <netipsec/ipsec6.h> #include <netipsec/key.h> #include <netipsec/key_debug.h> +#include <netipsec/xform.h> #include <machine/atomic.h> /* @@ -124,14 +125,6 @@ ipsec6_setsockaddrs(const struct mbuf *m, union sockaddr_union *src, } #endif -#ifdef IPSEC_SUPPORT -/* - * IPSEC_SUPPORT - loading of ipsec.ko and tcpmd5.ko is supported. - * IPSEC + IPSEC_SUPPORT - loading tcpmd5.ko is supported. - * IPSEC + TCP_SIGNATURE - all is build in the kernel, do not build - * IPSEC_SUPPORT. - */ -#if !defined(IPSEC) || !defined(TCP_SIGNATURE) #define IPSEC_MODULE_INCR 2 static int ipsec_kmod_enter(volatile u_int *cntr) @@ -171,6 +164,83 @@ ipsec_kmod_drain(volatile u_int *cntr) pause("ipsecd", hz/2); } +static LIST_HEAD(xforms_list, xformsw) xforms = LIST_HEAD_INITIALIZER(); +static struct mtx xforms_lock; +MTX_SYSINIT(xfroms_list, &xforms_lock, "IPsec transforms list", MTX_DEF); +#define XFORMS_LOCK() mtx_lock(&xforms_lock) +#define XFORMS_UNLOCK() mtx_unlock(&xforms_lock) + +void +xform_attach(void *data) +{ + struct xformsw *xsp, *entry; + + xsp = (struct xformsw *)data; + XFORMS_LOCK(); + LIST_FOREACH(entry, &xforms, chain) { + if (entry->xf_type == xsp->xf_type) { + XFORMS_UNLOCK(); + printf("%s: failed to register %s xform\n", + __func__, xsp->xf_name); + return; + } + } + LIST_INSERT_HEAD(&xforms, xsp, chain); + xsp->xf_cntr = IPSEC_MODULE_ENABLED; + XFORMS_UNLOCK(); +} + +void +xform_detach(void *data) +{ + struct xformsw *xsp = (struct xformsw *)data; + + XFORMS_LOCK(); + LIST_REMOVE(xsp, chain); + XFORMS_UNLOCK(); + + /* Delete all SAs related to this xform. */ + key_delete_xform(xsp); + if (xsp->xf_cntr & IPSEC_MODULE_ENABLED) + ipsec_kmod_drain(&xsp->xf_cntr); +} + +/* + * Initialize transform support in an sav. + */ +int +xform_init(struct secasvar *sav, u_short xftype) +{ + struct xformsw *entry; + int ret; + + IPSEC_ASSERT(sav->tdb_xform == NULL, + ("tdb_xform is already initialized")); + + XFORMS_LOCK(); + LIST_FOREACH(entry, &xforms, chain) { + if (entry->xf_type == xftype) { + ret = ipsec_kmod_enter(&entry->xf_cntr); + XFORMS_UNLOCK(); + if (ret != 0) + return (ret); + ret = (*entry->xf_init)(sav, entry); + ipsec_kmod_exit(&entry->xf_cntr); + return (ret); + } + } + XFORMS_UNLOCK(); + return (EINVAL); +} + +#ifdef IPSEC_SUPPORT +/* + * IPSEC_SUPPORT - loading of ipsec.ko and tcpmd5.ko is supported. + * IPSEC + IPSEC_SUPPORT - loading tcpmd5.ko is supported. + * IPSEC + TCP_SIGNATURE - all is build in the kernel, do not build + * IPSEC_SUPPORT. + */ +#if !defined(IPSEC) || !defined(TCP_SIGNATURE) #define METHOD_DECL(...) __VA_ARGS__ #define METHOD_ARGS(...) __VA_ARGS__ #define IPSEC_KMOD_METHOD(type, name, sc, method, decl, args) \ diff --git a/sys/netipsec/xform.h b/sys/netipsec/xform.h index 389d0b66850b..910a88a706f3 100644 --- a/sys/netipsec/xform.h +++ b/sys/netipsec/xform.h @@ -86,14 +86,16 @@ struct xform_data { #define XF_IPCOMP 6 /* IPCOMP */ struct xformsw { - u_short xf_type; /* xform ID */ - char *xf_name; /* human-readable name */ + u_short xf_type; /* xform ID */ + const char *xf_name; /* human-readable name */ int (*xf_init)(struct secasvar*, struct xformsw*); /* setup */ int (*xf_zeroize)(struct secasvar*); /* cleanup */ int (*xf_input)(struct mbuf*, struct secasvar*, /* input */ int, int); int (*xf_output)(struct mbuf*, /* output */ struct secpolicy *, struct secasvar *, u_int, int, int); + + volatile u_int xf_cntr; LIST_ENTRY(xformsw) chain; }; @@ -103,6 +105,7 @@ const struct comp_algo * comp_algorithm_lookup(int); void xform_attach(void *); void xform_detach(void *); +int xform_init(struct secasvar *, u_short); struct cryptoini; /* XF_AH */ From 8d66f7bee69639071ec87be4d1c5ab4097d161ed Mon Sep 17 00:00:00 2001 From: Ed Maste <emaste@FreeBSD.org> Date: Wed, 26 Sep 2018 15:07:06 +0000 Subject: [PATCH 112/139] add REPRODUCIBLE_BUILD note to UPDATING Reported by: bz Approved by: re (gjb) --- UPDATING | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/UPDATING b/UPDATING index 94fd1d1cb332..ce79b09f0c6c 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: disable the most expensive debugging functionality run "ln -s 'abort:false,junk:false' /etc/malloc.conf".) +20180913: + Reproducible build mode is now on by default, in preparation for + FreeBSD 12.0. This eliminates build metadata such as the user, + host, and time from the kernel (and uname), unless the working tree + corresponds to a modified checkout from a version control system. + The previous behavior can be obtained by setting the /etc/src.conf + knob WITHOUT_REPRODUCIBLE_BUILD. + 20180826: The Yarrow CSPRNG has been removed from the kernel as it has not been supported by its designers since at least 2003. Fortuna has been the From c5bf4b1bc690dc122ed4a472672d97af64baab5f Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" <ae@FreeBSD.org> Date: Wed, 26 Sep 2018 15:37:48 +0000 Subject: [PATCH 113/139] Add "src-ip" or "dst-ip" keyword to the output, when we are printing the rest of rule options. Reported by: lev Approved by: re (gjb) MFC after: 1 week --- sbin/ipfw/ipfw2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 32a94edf7c42..203c852b372f 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -1466,19 +1466,31 @@ print_instruction(struct buf_pr *bp, const struct format_opts *fo, case O_IP_SRC_MASK: case O_IP_SRC_ME: case O_IP_SRC_SET: + if (state->flags & HAVE_SRCIP) + bprintf(bp, " src-ip"); + print_ip(bp, fo, insntod(cmd, ip)); + break; case O_IP_DST: case O_IP_DST_LOOKUP: case O_IP_DST_MASK: case O_IP_DST_ME: case O_IP_DST_SET: + if (state->flags & HAVE_DSTIP) + bprintf(bp, " dst-ip"); print_ip(bp, fo, insntod(cmd, ip)); break; case O_IP6_SRC: case O_IP6_SRC_MASK: case O_IP6_SRC_ME: + if (state->flags & HAVE_SRCIP) + bprintf(bp, " src-ip6"); + print_ip6(bp, insntod(cmd, ip6)); + break; case O_IP6_DST: case O_IP6_DST_MASK: case O_IP6_DST_ME: + if (state->flags & HAVE_DSTIP) + bprintf(bp, " dst-ip6"); print_ip6(bp, insntod(cmd, ip6)); break; case O_FLOW6ID: From 329e817fcc97aa847765c5171cc89a81a0b25527 Mon Sep 17 00:00:00 2001 From: Warner Losh <imp@FreeBSD.org> Date: Wed, 26 Sep 2018 17:12:14 +0000 Subject: [PATCH 114/139] Reapply, with minor tweaks, r338025, from the original commit: Remove unused and easy to misuse PNP macro parameter Inspired by r338025, just remove the element size parameter to the MODULE_PNP_INFO macro entirely. The 'table' parameter is now required to have correct pointer (or array) type. Since all invocations of the macro already had this property and the emitted PNP data continues to include the element size, there is no functional change. Mostly done with the coccinelle 'spatch' tool: $ cat modpnpsize0.cocci @normaltables@ identifier b,c; expression a,d,e; declarer MODULE_PNP_INFO; @@ MODULE_PNP_INFO(a,b,c,d, -sizeof(d[0]), e); @singletons@ identifier b,c,d; expression a; declarer MODULE_PNP_INFO; @@ MODULE_PNP_INFO(a,b,c,&d, -sizeof(d), 1); $ rg -l MODULE_PNP_INFO -- sys | \ xargs spatch --in-place --sp-file modpnpsize0.cocci (Note that coccinelle invokes diff(1) via a PATH search and expects diff to tolerate the -B flag, which BSD diff does not. So I had to link gdiff into PATH as diff to use spatch.) Tinderbox'd (-DMAKE_JUST_KERNELS). Approved by: re (glen) --- sys/crypto/ccp/ccp.c | 2 +- sys/dev/aac/aac_pci.c | 2 +- sys/dev/aacraid/aacraid_pci.c | 2 +- sys/dev/adlink/adlink.c | 2 +- sys/dev/ae/if_ae.c | 2 +- sys/dev/age/if_age.c | 2 +- sys/dev/ahci/ahci_pci.c | 2 +- sys/dev/alc/if_alc.c | 2 +- sys/dev/ale/if_ale.c | 2 +- sys/dev/amdsmn/amdsmn.c | 2 +- sys/dev/amdtemp/amdtemp.c | 2 +- sys/dev/amr/amr_pci.c | 2 +- sys/dev/an/if_an_pci.c | 2 +- sys/dev/bce/if_bce.c | 2 +- sys/dev/bfe/if_bfe.c | 2 +- sys/dev/bge/if_bge.c | 2 +- sys/dev/bwi/if_bwi_pci.c | 2 +- sys/dev/bwn/if_bwn_pci.c | 4 ++-- sys/dev/cas/if_cas.c | 2 +- sys/dev/ciss/ciss.c | 2 +- sys/dev/dc/if_dc.c | 2 +- sys/dev/drm2/i915/i915_drv.c | 2 +- sys/dev/drm2/radeon/radeon_drv.c | 2 +- sys/dev/ed/if_ed_pci.c | 2 +- sys/dev/ena/ena.c | 2 +- sys/dev/et/if_et.c | 2 +- sys/dev/fxp/if_fxp.c | 2 +- sys/dev/gem/if_gem_pci.c | 2 +- sys/dev/intpm/intpm.c | 2 +- sys/dev/ioat/ioat.c | 2 +- sys/dev/ipw/if_ipw.c | 2 +- sys/dev/ixgbe/if_ix.c | 2 +- sys/dev/ixgbe/if_ixv.c | 2 +- sys/dev/ncr/ncr.c | 2 +- sys/dev/ntb/ntb_hw/ntb_hw_intel.c | 2 +- sys/dev/ofw/ofw_bus_subr.h | 2 +- sys/dev/pccard/pccardvar.h | 2 +- sys/dev/pci/pcivar.h | 2 +- sys/dev/puc/puc_pci.c | 2 +- sys/dev/spibus/spi.h | 2 +- sys/dev/uart/uart_bus_pccard.c | 2 +- sys/dev/usb/usbdi.h | 6 +++--- sys/dev/xl/if_xl.c | 2 +- sys/isa/isavar.h | 2 +- sys/net/iflib.h | 2 +- sys/sys/module.h | 4 ++-- 46 files changed, 50 insertions(+), 50 deletions(-) diff --git a/sys/crypto/ccp/ccp.c b/sys/crypto/ccp/ccp.c index 163fa748b2ef..1983eac79444 100644 --- a/sys/crypto/ccp/ccp.c +++ b/sys/crypto/ccp/ccp.c @@ -735,7 +735,7 @@ MODULE_VERSION(ccp, 1); MODULE_DEPEND(ccp, crypto, 1, 1, 1); MODULE_DEPEND(ccp, random_device, 1, 1, 1); #if 0 /* There are enough known issues that we shouldn't load automatically */ -MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, sizeof(ccp_ids[0]), +MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, nitems(ccp_ids)); #endif diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c index 399e55a9a47f..738bfbf79167 100644 --- a/sys/dev/aac/aac_pci.c +++ b/sys/dev/aac/aac_pci.c @@ -494,7 +494,7 @@ static driver_t aacch_driver = { static devclass_t aacch_devclass; DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;", pci, aac, - aac_identifiers, sizeof(aac_identifiers[0]), nitems(aac_identifiers) - 1); + aac_identifiers, nitems(aac_identifiers) - 1); static int aacch_probe(device_t dev) diff --git a/sys/dev/aacraid/aacraid_pci.c b/sys/dev/aacraid/aacraid_pci.c index 74ac0ee23312..f445a073b6d5 100644 --- a/sys/dev/aacraid/aacraid_pci.c +++ b/sys/dev/aacraid/aacraid_pci.c @@ -106,7 +106,7 @@ struct aac_ident DRIVER_MODULE(aacraid, pci, aacraid_pci_driver, aacraid_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, aacraid, - aacraid_family_identifiers, sizeof(aacraid_family_identifiers[0]), + aacraid_family_identifiers, nitems(aacraid_family_identifiers) - 1); MODULE_DEPEND(aacraid, pci, 1, 1, 1); diff --git a/sys/dev/adlink/adlink.c b/sys/dev/adlink/adlink.c index 2ae3d768c2fd..19b2f9388c6f 100644 --- a/sys/dev/adlink/adlink.c +++ b/sys/dev/adlink/adlink.c @@ -438,6 +438,6 @@ static driver_t adlink_driver = { }; DRIVER_MODULE(adlink, pci, adlink_driver, adlink_devclass, 0, 0); -MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, adlink, adlink_id, sizeof(adlink_id[0]), +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, adlink, adlink_id, nitems(adlink_id)); #endif /* _KERNEL */ diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c index f70afb27fa56..cb9474db8553 100644 --- a/sys/dev/ae/if_ae.c +++ b/sys/dev/ae/if_ae.c @@ -178,7 +178,7 @@ static devclass_t ae_devclass; DRIVER_MODULE(ae, pci, ae_driver, ae_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ae, ae_devs, - sizeof(ae_devs[0]), nitems(ae_devs)); + nitems(ae_devs)); DRIVER_MODULE(miibus, ae, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(ae, pci, 1, 1, 1); MODULE_DEPEND(ae, ether, 1, 1, 1); diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c index 764363f19856..ee52564d7cc8 100644 --- a/sys/dev/age/if_age.c +++ b/sys/dev/age/if_age.c @@ -184,7 +184,7 @@ static devclass_t age_devclass; DRIVER_MODULE(age, pci, age_driver, age_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, age, age_devs, - sizeof(age_devs[0]), nitems(age_devs)); + nitems(age_devs)); DRIVER_MODULE(miibus, age, miibus_driver, miibus_devclass, 0, 0); static struct resource_spec age_res_spec_mem[] = { diff --git a/sys/dev/ahci/ahci_pci.c b/sys/dev/ahci/ahci_pci.c index a117a5720c86..2bc2a243837b 100644 --- a/sys/dev/ahci/ahci_pci.c +++ b/sys/dev/ahci/ahci_pci.c @@ -667,7 +667,7 @@ static driver_t ahci_driver = { DRIVER_MODULE(ahci, pci, ahci_driver, ahci_devclass, NULL, NULL); /* Also matches class / subclass / progid XXX need to add when we have masking support */ MODULE_PNP_INFO("W32:vendor/device", pci, ahci, ahci_ids, - sizeof(ahci_ids[0]), nitems(ahci_ids) - 1); + nitems(ahci_ids) - 1); static device_method_t ahci_ata_methods[] = { DEVMETHOD(device_probe, ahci_ata_probe), DEVMETHOD(device_attach, ahci_pci_attach), diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c index ede7bd49c193..1bafdab235d0 100644 --- a/sys/dev/alc/if_alc.c +++ b/sys/dev/alc/if_alc.c @@ -244,7 +244,7 @@ static devclass_t alc_devclass; DRIVER_MODULE(alc, pci, alc_driver, alc_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, alc, alc_ident_table, - sizeof(alc_ident_table[0]), nitems(alc_ident_table) - 1); + nitems(alc_ident_table) - 1); DRIVER_MODULE(miibus, alc, miibus_driver, miibus_devclass, 0, 0); static struct resource_spec alc_res_spec_mem[] = { diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c index 987bd2db7421..802fdafd63cf 100644 --- a/sys/dev/ale/if_ale.c +++ b/sys/dev/ale/if_ale.c @@ -179,7 +179,7 @@ static devclass_t ale_devclass; DRIVER_MODULE(ale, pci, ale_driver, ale_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ale, ale_devs, - sizeof(ale_devs[0]), nitems(ale_devs)); + nitems(ale_devs)); DRIVER_MODULE(miibus, ale, miibus_driver, miibus_devclass, NULL, NULL); static struct resource_spec ale_res_spec_mem[] = { diff --git a/sys/dev/amdsmn/amdsmn.c b/sys/dev/amdsmn/amdsmn.c index fb2c8b17328c..17792dd922cd 100644 --- a/sys/dev/amdsmn/amdsmn.c +++ b/sys/dev/amdsmn/amdsmn.c @@ -90,7 +90,7 @@ static devclass_t amdsmn_devclass; DRIVER_MODULE(amdsmn, hostb, amdsmn_driver, amdsmn_devclass, NULL, NULL); MODULE_VERSION(amdsmn, 1); MODULE_PNP_INFO("W32:vendor/device", pci, amdsmn, amdsmn_ids, - sizeof(amdsmn_ids[0]), nitems(amdsmn_ids)); + nitems(amdsmn_ids)); static bool amdsmn_match(device_t parent) diff --git a/sys/dev/amdtemp/amdtemp.c b/sys/dev/amdtemp/amdtemp.c index 45f8d6397ed0..2463212c25f5 100644 --- a/sys/dev/amdtemp/amdtemp.c +++ b/sys/dev/amdtemp/amdtemp.c @@ -167,7 +167,7 @@ DRIVER_MODULE(amdtemp, hostb, amdtemp_driver, amdtemp_devclass, NULL, NULL); MODULE_VERSION(amdtemp, 1); MODULE_DEPEND(amdtemp, amdsmn, 1, 1, 1); MODULE_PNP_INFO("U16:vendor;U16:device", pci, amdtemp, amdtemp_products, - sizeof(amdtemp_products[0]), nitems(amdtemp_products)); + nitems(amdtemp_products)); static int amdtemp_match(device_t dev) diff --git a/sys/dev/amr/amr_pci.c b/sys/dev/amr/amr_pci.c index 80cd58b5ccd3..25b37eda3895 100644 --- a/sys/dev/amr/amr_pci.c +++ b/sys/dev/amr/amr_pci.c @@ -142,7 +142,7 @@ static struct amr_ident static devclass_t amr_devclass; DRIVER_MODULE(amr, pci, amr_pci_driver, amr_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, amr, amr_device_ids, - sizeof(amr_device_ids[0]), nitems(amr_device_ids) - 1); + nitems(amr_device_ids) - 1); MODULE_DEPEND(amr, pci, 1, 1, 1); MODULE_DEPEND(amr, cam, 1, 1, 1); diff --git a/sys/dev/an/if_an_pci.c b/sys/dev/an/if_an_pci.c index 1105a963128e..15ae3e320e54 100644 --- a/sys/dev/an/if_an_pci.c +++ b/sys/dev/an/if_an_pci.c @@ -274,6 +274,6 @@ static devclass_t an_devclass; DRIVER_MODULE(an, pci, an_pci_driver, an_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, an, - an_devs, sizeof(an_devs[0]), nitems(an_devs) - 1); + an_devs, nitems(an_devs) - 1); MODULE_DEPEND(an, pci, 1, 1, 1); MODULE_DEPEND(an, wlan, 1, 1, 1); diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c index 37eed4abcbc0..3d5c0742580c 100644 --- a/sys/dev/bce/if_bce.c +++ b/sys/dev/bce/if_bce.c @@ -530,7 +530,7 @@ MODULE_DEPEND(bce, miibus, 1, 1, 1); DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL); DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce, - bce_devs, sizeof(bce_devs[0]), nitems(bce_devs) - 1); + bce_devs, nitems(bce_devs) - 1); /****************************************************************************/ /* Tunable device values */ diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c index fb0c2949c82d..6a86f3488b4c 100644 --- a/sys/dev/bfe/if_bfe.c +++ b/sys/dev/bfe/if_bfe.c @@ -158,7 +158,7 @@ static devclass_t bfe_devclass; DRIVER_MODULE(bfe, pci, bfe_driver, bfe_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bfe, bfe_devs, - sizeof(bfe_devs[0]), nitems(bfe_devs) - 1); + nitems(bfe_devs) - 1); DRIVER_MODULE(miibus, bfe, miibus_driver, miibus_devclass, 0, 0); /* diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index c7134b9a2abd..193116e10681 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -548,7 +548,7 @@ static devclass_t bge_devclass; DRIVER_MODULE(bge, pci, bge_driver, bge_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, bge, bge_devs, - sizeof(bge_devs[0]), nitems(bge_devs) - 1); + nitems(bge_devs) - 1); DRIVER_MODULE(miibus, bge, miibus_driver, miibus_devclass, 0, 0); static int bge_allow_asf = 1; diff --git a/sys/dev/bwi/if_bwi_pci.c b/sys/dev/bwi/if_bwi_pci.c index 63378be0452d..f95ef854ceaa 100644 --- a/sys/dev/bwi/if_bwi_pci.c +++ b/sys/dev/bwi/if_bwi_pci.c @@ -257,7 +257,7 @@ static driver_t bwi_driver = { static devclass_t bwi_devclass; DRIVER_MODULE(bwi, pci, bwi_driver, bwi_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwi, bwi_devices, - sizeof(bwi_devices[0]), nitems(bwi_devices) - 1); + nitems(bwi_devices) - 1); MODULE_DEPEND(bwi, wlan, 1, 1, 1); /* 802.11 media layer */ MODULE_DEPEND(bwi, firmware, 1, 1, 1); /* firmware support */ MODULE_DEPEND(bwi, wlan_amrr, 1, 1, 1); diff --git a/sys/dev/bwn/if_bwn_pci.c b/sys/dev/bwn/if_bwn_pci.c index dfe7b50e7bc0..610f8bdeb823 100644 --- a/sys/dev/bwn/if_bwn_pci.c +++ b/sys/dev/bwn/if_bwn_pci.c @@ -296,9 +296,9 @@ DEFINE_CLASS_0(bwn_pci, bwn_pci_driver, bwn_pci_methods, DRIVER_MODULE_ORDERED(bwn_pci, pci, bwn_pci_driver, bwn_pci_devclass, NULL, NULL, SI_ORDER_ANY); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwn_siba, - siba_devices, sizeof(siba_devices[0]), nitems(siba_devices) - 1); + siba_devices, nitems(siba_devices) - 1); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwn_bcma, - bcma_devices, sizeof(bcma_devices[0]), nitems(bcma_devices) - 1); + bcma_devices, nitems(bcma_devices) - 1); DRIVER_MODULE(bhndb, bwn_pci, bhndb_pci_driver, bhndb_devclass, NULL, NULL); MODULE_DEPEND(bwn_pci, bwn, 1, 1, 1); diff --git a/sys/dev/cas/if_cas.c b/sys/dev/cas/if_cas.c index 3e6dbfe7b463..d1b3761302a1 100644 --- a/sys/dev/cas/if_cas.c +++ b/sys/dev/cas/if_cas.c @@ -2617,7 +2617,7 @@ static const struct cas_pci_dev { DRIVER_MODULE(cas, pci, cas_pci_driver, cas_devclass, 0, 0); MODULE_PNP_INFO("W32:vendor/device", pci, cas, cas_pci_devlist, - sizeof(cas_pci_devlist[0]), nitems(cas_pci_devlist) - 1); + nitems(cas_pci_devlist) - 1); DRIVER_MODULE(miibus, cas, miibus_driver, miibus_devclass, 0, 0); MODULE_DEPEND(cas, pci, 1, 1, 1); diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index 94bd9c69e1c5..e4b887a38e60 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -365,7 +365,7 @@ static struct static devclass_t ciss_devclass; DRIVER_MODULE(ciss, pci, ciss_pci_driver, ciss_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;", pci, ciss, ciss_vendor_data, - sizeof(ciss_vendor_data[0]), nitems(ciss_vendor_data) - 1); + nitems(ciss_vendor_data) - 1); MODULE_DEPEND(ciss, cam, 1, 1, 1); MODULE_DEPEND(ciss, pci, 1, 1, 1); diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index e1593b02db25..a4394de9c552 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -360,7 +360,7 @@ static devclass_t dc_devclass; DRIVER_MODULE_ORDERED(dc, pci, dc_driver, dc_devclass, NULL, NULL, SI_ORDER_ANY); MODULE_PNP_INFO("W32:vendor/device;U8:revision;D:#", pci, dc, dc_devs, - sizeof(dc_devs[0]), nitems(dc_devs) - 1); + nitems(dc_devs) - 1); DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, NULL, NULL); #define DC_SETBIT(sc, reg, x) \ diff --git a/sys/dev/drm2/i915/i915_drv.c b/sys/dev/drm2/i915/i915_drv.c index f0c8867501b3..8a7168861aca 100644 --- a/sys/dev/drm2/i915/i915_drv.c +++ b/sys/dev/drm2/i915/i915_drv.c @@ -1237,7 +1237,7 @@ MODULE_DEPEND(i915kms, iicbus, 1, 1, 1); MODULE_DEPEND(i915kms, iic, 1, 1, 1); MODULE_DEPEND(i915kms, iicbb, 1, 1, 1); MODULE_PNP_INFO("U32:vendor;U32:device;P:#;D:#", vgapci, i915, pciidlist, - sizeof(pciidlist[0]), nitems(pciidlist) - 1); + nitems(pciidlist) - 1); /* We give fast paths for the really cool registers */ #define NEEDS_FORCE_WAKE(dev_priv, reg) \ diff --git a/sys/dev/drm2/radeon/radeon_drv.c b/sys/dev/drm2/radeon/radeon_drv.c index bf3dd063c178..73f83ccef0cb 100644 --- a/sys/dev/drm2/radeon/radeon_drv.c +++ b/sys/dev/drm2/radeon/radeon_drv.c @@ -402,4 +402,4 @@ MODULE_DEPEND(radeonkms, iic, 1, 1, 1); MODULE_DEPEND(radeonkms, iicbb, 1, 1, 1); MODULE_DEPEND(radeonkms, firmware, 1, 1, 1); MODULE_PNP_INFO("U32:vendor;U32:device;P:#;D:#", vgapci, radeonkms, - pciidlist, sizeof(pciidlist[0]), nitems(pciidlist) - 1); + pciidlist, nitems(pciidlist) - 1); diff --git a/sys/dev/ed/if_ed_pci.c b/sys/dev/ed/if_ed_pci.c index b487b97de820..8ada958abcbe 100644 --- a/sys/dev/ed/if_ed_pci.c +++ b/sys/dev/ed/if_ed_pci.c @@ -145,5 +145,5 @@ static driver_t ed_pci_driver = { DRIVER_MODULE(ed, pci, ed_pci_driver, ed_devclass, 0, 0); MODULE_DEPEND(ed, pci, 1, 1, 1); MODULE_DEPEND(ed, ether, 1, 1, 1); -MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ed, pci_ids, sizeof(pci_ids[0]), +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ed, pci_ids, nitems(pci_ids) - 1); diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c index cadc8bdbf677..a27de7db593f 100644 --- a/sys/dev/ena/ena.c +++ b/sys/dev/ena/ena.c @@ -3948,7 +3948,7 @@ static driver_t ena_driver = { devclass_t ena_devclass; DRIVER_MODULE(ena, pci, ena_driver, ena_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, ena, ena_vendor_info_array, - sizeof(ena_vendor_info_array[0]), nitems(ena_vendor_info_array) - 1); + nitems(ena_vendor_info_array) - 1); MODULE_DEPEND(ena, pci, 1, 1, 1); MODULE_DEPEND(ena, ether, 1, 1, 1); diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c index a5ce9e452872..294d9d5e55aa 100644 --- a/sys/dev/et/if_et.c +++ b/sys/dev/et/if_et.c @@ -189,7 +189,7 @@ static devclass_t et_devclass; DRIVER_MODULE(et, pci, et_driver, et_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, et, et_devices, - sizeof(et_devices[0]), nitems(et_devices) - 1); + nitems(et_devices) - 1); DRIVER_MODULE(miibus, et, miibus_driver, miibus_devclass, 0, 0); static int et_rx_intr_npkts = 32; diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index b89f8329a4f2..2c3297a05bea 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -308,7 +308,7 @@ static devclass_t fxp_devclass; DRIVER_MODULE_ORDERED(fxp, pci, fxp_driver, fxp_devclass, NULL, NULL, SI_ORDER_ANY); MODULE_PNP_INFO("U16:vendor;U16:device", pci, fxp, fxp_ident_table, - sizeof(fxp_ident_table[0]), nitems(fxp_ident_table) - 1); + nitems(fxp_ident_table) - 1); DRIVER_MODULE(miibus, fxp, miibus_driver, miibus_devclass, NULL, NULL); static struct resource_spec fxp_res_spec_mem[] = { diff --git a/sys/dev/gem/if_gem_pci.c b/sys/dev/gem/if_gem_pci.c index af9db3da9c3e..ce3027fb3441 100644 --- a/sys/dev/gem/if_gem_pci.c +++ b/sys/dev/gem/if_gem_pci.c @@ -116,7 +116,7 @@ static driver_t gem_pci_driver = { DRIVER_MODULE(gem, pci, gem_pci_driver, gem_devclass, 0, 0); MODULE_PNP_INFO("W32:vendor/device", pci, gem, gem_pci_devlist, - sizeof(gem_pci_devlist[0]), nitems(gem_pci_devlist) - 1); + nitems(gem_pci_devlist) - 1); MODULE_DEPEND(gem, pci, 1, 1, 1); MODULE_DEPEND(gem, ether, 1, 1, 1); diff --git a/sys/dev/intpm/intpm.c b/sys/dev/intpm/intpm.c index 4b4cf9ab10c8..15da5e861a07 100644 --- a/sys/dev/intpm/intpm.c +++ b/sys/dev/intpm/intpm.c @@ -896,4 +896,4 @@ DRIVER_MODULE(smbus, intsmb, smbus_driver, smbus_devclass, 0, 0); MODULE_DEPEND(intsmb, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); MODULE_VERSION(intsmb, 1); MODULE_PNP_INFO("W32:vendor/device;D:#", pci, intpm, intsmb_products, - sizeof(intsmb_products[0]), nitems(intsmb_products)); + nitems(intsmb_products)); diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 744c26dfafdc..b03de58fcb55 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -241,7 +241,7 @@ static struct _pcsid }; MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ioat, pci_ids, - sizeof(pci_ids[0]), nitems(pci_ids)); + nitems(pci_ids)); /* * OS <-> Driver linkage functions diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 1da31934f738..e99d5aedc714 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -203,7 +203,7 @@ static devclass_t ipw_devclass; DRIVER_MODULE(ipw, pci, ipw_driver, ipw_devclass, NULL, NULL); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ipw, ipw_ident_table, - sizeof(ipw_ident_table[0]), nitems(ipw_ident_table) - 1); + nitems(ipw_ident_table) - 1); MODULE_VERSION(ipw, 1); diff --git a/sys/dev/ixgbe/if_ix.c b/sys/dev/ixgbe/if_ix.c index cca610664065..44843ff3fc98 100644 --- a/sys/dev/ixgbe/if_ix.c +++ b/sys/dev/ixgbe/if_ix.c @@ -238,7 +238,7 @@ static driver_t ix_driver = { devclass_t ix_devclass; DRIVER_MODULE(ix, pci, ix_driver, ix_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, ix, ixgbe_vendor_info_array, - sizeof(ixgbe_vendor_info_array[0]), nitems(ixgbe_vendor_info_array) - 1); + nitems(ixgbe_vendor_info_array) - 1); MODULE_DEPEND(ix, pci, 1, 1, 1); MODULE_DEPEND(ix, ether, 1, 1, 1); diff --git a/sys/dev/ixgbe/if_ixv.c b/sys/dev/ixgbe/if_ixv.c index a6a3465b60d7..91f2f8ef755e 100644 --- a/sys/dev/ixgbe/if_ixv.c +++ b/sys/dev/ixgbe/if_ixv.c @@ -144,7 +144,7 @@ static driver_t ixv_driver = { devclass_t ixv_devclass; DRIVER_MODULE(ixv, pci, ixv_driver, ixv_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device", pci, ixv, ixv_vendor_info_array, - sizeof(ixv_vendor_info_array[0]), nitems(ixv_vendor_info_array) - 1); + nitems(ixv_vendor_info_array) - 1); MODULE_DEPEND(ixv, pci, 1, 1, 1); MODULE_DEPEND(ixv, ether, 1, 1, 1); #ifdef DEV_NETMAP diff --git a/sys/dev/ncr/ncr.c b/sys/dev/ncr/ncr.c index 5cfb413731c2..58bc2a6af01c 100644 --- a/sys/dev/ncr/ncr.c +++ b/sys/dev/ncr/ncr.c @@ -7109,7 +7109,7 @@ static devclass_t ncr_devclass; DRIVER_MODULE(ncr, pci, ncr_driver, ncr_devclass, 0, 0); MODULE_PNP_INFO("W32:vendor/device;U16:#;D:#", pci, ncr, ncr_chip_table, - sizeof(ncr_chip_table[0]), nitems(ncr_chip_table)); + nitems(ncr_chip_table)); MODULE_DEPEND(ncr, cam, 1, 1, 1); MODULE_DEPEND(ncr, pci, 1, 1, 1); diff --git a/sys/dev/ntb/ntb_hw/ntb_hw_intel.c b/sys/dev/ntb/ntb_hw/ntb_hw_intel.c index 3bb57fcb71d0..d61f664d8cff 100644 --- a/sys/dev/ntb/ntb_hw/ntb_hw_intel.c +++ b/sys/dev/ntb/ntb_hw/ntb_hw_intel.c @@ -3120,4 +3120,4 @@ DRIVER_MODULE(ntb_hw_intel, pci, ntb_intel_driver, ntb_hw_devclass, NULL, NULL); MODULE_DEPEND(ntb_hw_intel, ntb, 1, 1, 1); MODULE_VERSION(ntb_hw_intel, 1); MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ntb_hw_intel, pci_ids, - sizeof(pci_ids[0]), nitems(pci_ids)); + nitems(pci_ids)); diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h index 537856b97ef7..edc90ed7bf3c 100644 --- a/sys/dev/ofw/ofw_bus_subr.h +++ b/sys/dev/ofw/ofw_bus_subr.h @@ -67,7 +67,7 @@ struct intr_map_data_fdt { #define SIMPLEBUS_PNP_DESCR "Z:compat;P:#;" #define SIMPLEBUS_PNP_INFO(t) \ - MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); + MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t) / sizeof(t[0])); /* Generic implementation of ofw_bus_if.m methods and helper routines */ int ofw_bus_gen_setup_devinfo(struct ofw_bus_devinfo *, phandle_t); diff --git a/sys/dev/pccard/pccardvar.h b/sys/dev/pccard/pccardvar.h index 5138c243f5b7..87f41850ec5c 100644 --- a/sys/dev/pccard/pccardvar.h +++ b/sys/dev/pccard/pccardvar.h @@ -102,7 +102,7 @@ struct pccard_product { */ #define PCCARD_PNP_DESCR "D:#;V32:manufacturer;V32:product;Z:cisvendor;Z:cisproduct;" #define PCCARD_PNP_INFO(t) \ - MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), nitems(t) - 1); \ + MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, nitems(t) - 1) typedef int (*pccard_product_match_fn) (device_t dev, const struct pccard_product *ent, int vpfmatch); diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h index c5a8afb4ed23..376fb96594ce 100644 --- a/sys/dev/pci/pcivar.h +++ b/sys/dev/pci/pcivar.h @@ -311,7 +311,7 @@ struct pci_device_table { "M16:mask;U16:vendor;U16:device;U16:subvendor;U16:subdevice;" \ "U16:class;U16:subclass;U16:revid;" #define PCI_PNP_INFO(table) \ - MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, \ sizeof(table) / sizeof(table[0])) const struct pci_device_table *pci_match_device(device_t child, diff --git a/sys/dev/puc/puc_pci.c b/sys/dev/puc/puc_pci.c index f0c6aa81dde4..012a16dc9e9b 100644 --- a/sys/dev/puc/puc_pci.c +++ b/sys/dev/puc/puc_pci.c @@ -200,4 +200,4 @@ static driver_t puc_pci_driver = { DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0); MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, puc, - puc_pci_devices, sizeof(puc_pci_devices[0]), nitems(puc_pci_devices) - 1); + puc_pci_devices, nitems(puc_pci_devices) - 1); diff --git a/sys/dev/spibus/spi.h b/sys/dev/spibus/spi.h index 1a9c1496a77d..0c12929bee15 100644 --- a/sys/dev/spibus/spi.h +++ b/sys/dev/spibus/spi.h @@ -43,4 +43,4 @@ struct spi_command { #define SPIBUS_PNP_DESCR "Z:compat;P:#;" #define SPIBUS_PNP_INFO(t) \ - MODULE_PNP_INFO(SPIBUS_PNP_DESCR, spibus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); + MODULE_PNP_INFO(SPIBUS_PNP_DESCR, spibus, t, t, sizeof(t) / sizeof(t[0])); diff --git a/sys/dev/uart/uart_bus_pccard.c b/sys/dev/uart/uart_bus_pccard.c index 3a8446a871f6..8b672ebeadb0 100644 --- a/sys/dev/uart/uart_bus_pccard.c +++ b/sys/dev/uart/uart_bus_pccard.c @@ -103,4 +103,4 @@ uart_pccard_attach(device_t dev) DRIVER_MODULE(uart, pccard, uart_pccard_driver, uart_devclass, 0, 0); MODULE_PNP_INFO("U32:function_type;", pccard, uart, &uart_pccard_function, - sizeof(uart_pccard_function), 1); + 1); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 147b5d5e71b8..d5648c0301ea 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -342,13 +342,13 @@ struct usb_device_id { #define USB_STD_PNP_HOST_INFO USB_STD_PNP_INFO "T:mode=host;" #define USB_STD_PNP_DEVICE_INFO USB_STD_PNP_INFO "T:mode=device;" #define USB_PNP_HOST_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_HOST_INFO, uhub, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(USB_STD_PNP_HOST_INFO, uhub, table, table, \ sizeof(table) / sizeof(table[0])) #define USB_PNP_DEVICE_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, uhub, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, uhub, table, table, \ sizeof(table) / sizeof(table[0])) #define USB_PNP_DUAL_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_INFO, uhub, table, table, sizeof(table[0]), \ + MODULE_PNP_INFO(USB_STD_PNP_INFO, uhub, table, table, \ sizeof(table) / sizeof(table[0])) /* check that the size of the structure above is correct */ diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 0afe62a522de..29d323399894 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -334,7 +334,7 @@ static devclass_t xl_devclass; DRIVER_MODULE_ORDERED(xl, pci, xl_driver, xl_devclass, NULL, NULL, SI_ORDER_ANY); DRIVER_MODULE(miibus, xl, miibus_driver, miibus_devclass, NULL, NULL); -MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, xl, xl_devs, sizeof(xl_devs[0]), +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, xl, xl_devs, nitems(xl_devs) - 1); static void diff --git a/sys/isa/isavar.h b/sys/isa/isavar.h index 1a3e661b67a4..d95a9c1ab3f2 100644 --- a/sys/isa/isavar.h +++ b/sys/isa/isavar.h @@ -142,7 +142,7 @@ enum isa_device_ivars { #define ISA_PNP_DESCR "E:pnpid;D:#" #define ISA_PNP_INFO(t) \ - MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, sizeof(t[0]), nitems(t) - 1); \ + MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, nitems(t) - 1); \ /* * Simplified accessors for isa devices diff --git a/sys/net/iflib.h b/sys/net/iflib.h index 6e1eee633a2c..bda5ad45dfc8 100644 --- a/sys/net/iflib.h +++ b/sys/net/iflib.h @@ -173,7 +173,7 @@ typedef struct pci_vendor_info { #define IFLIB_PNP_DESCR "U32:vendor;U32:device;U32:subvendor;U32:subdevice;" \ "U32:revision;U32:class;D:#" #define IFLIB_PNP_INFO(b, u, t) \ - MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), nitems(t) - 1) + MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, nitems(t) - 1) typedef struct if_txrx { int (*ift_txd_encap) (void *, if_pkt_info_t); diff --git a/sys/sys/module.h b/sys/sys/module.h index b40870d32941..89377df401a8 100644 --- a/sys/sys/module.h +++ b/sys/sys/module.h @@ -178,12 +178,12 @@ struct mod_pnp_match_info * to allow external tools to parse their internal device tables * to make an informed guess about what driver(s) to load. */ -#define MODULE_PNP_INFO(d, b, unique, t, l, n) \ +#define MODULE_PNP_INFO(d, b, unique, t, n) \ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \ .descr = d, \ .bus = #b, \ .table = t, \ - .entry_len = l, \ + .entry_len = sizeof((t)[0]), \ .num_entry = n \ }; \ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \ From 0dc34160f3241087ca7d0485f0ba3813406d04ca Mon Sep 17 00:00:00 2001 From: Warner Losh <imp@FreeBSD.org> Date: Wed, 26 Sep 2018 17:12:30 +0000 Subject: [PATCH 115/139] Add PNP info to PCI attachments of cbb, cxgb, ida, iwn, ixl, ixlv, mfi, mps, mpr, mvs, my, oce, pcn, ral, rl. This only labels existing pci device tables, and has no probe / attach code changes. Reviewed by: imp, chuck Submitted by: Lakhan Shiva Kamireddy <lakhanshiva@gmail.com> Sponsored by: Google, Inc. (GSoC 2018) Approved by: re (glen) --- sys/dev/cxgb/cxgb_main.c | 49 +++++++++++++++++++++------------------ sys/dev/ida/ida_pci.c | 2 ++ sys/dev/iwn/if_iwn.c | 3 ++- sys/dev/ixl/if_ixl.c | 1 + sys/dev/ixl/if_ixlv.c | 4 +++- sys/dev/mfi/mfi_pci.c | 7 ++++-- sys/dev/mpr/mpr_pci.c | 11 ++++++--- sys/dev/mps/mps_pci.c | 8 +++---- sys/dev/mvs/mvs_pci.c | 2 ++ sys/dev/my/if_my.c | 2 ++ sys/dev/oce/oce_if.c | 15 +++++++----- sys/dev/pccbb/pccbb_pci.c | 2 ++ sys/dev/pcn/if_pcn.c | 2 ++ sys/dev/ral/if_ral_pci.c | 2 ++ sys/dev/rl/if_rl.c | 2 ++ 15 files changed, 72 insertions(+), 40 deletions(-) diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 127a61d61c21..a47aa909c237 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -133,6 +133,30 @@ static void cxgb_update_mac_settings(struct port_info *p); static int toe_capability(struct port_info *, int); #endif +/* Table for probing the cards. The desc field isn't actually used */ +struct cxgb_ident { + uint16_t vendor; + uint16_t device; + int index; + char *desc; +} cxgb_identifiers[] = { + {PCI_VENDOR_ID_CHELSIO, 0x0020, 0, "PE9000"}, + {PCI_VENDOR_ID_CHELSIO, 0x0021, 1, "T302E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0022, 2, "T310E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0023, 3, "T320X"}, + {PCI_VENDOR_ID_CHELSIO, 0x0024, 1, "T302X"}, + {PCI_VENDOR_ID_CHELSIO, 0x0025, 3, "T320E"}, + {PCI_VENDOR_ID_CHELSIO, 0x0026, 2, "T310X"}, + {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"}, + {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"}, + {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"}, + {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"}, + {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "T3C10"}, + {PCI_VENDOR_ID_CHELSIO, 0x0036, 3, "S320E-CR"}, + {PCI_VENDOR_ID_CHELSIO, 0x0037, 7, "N320E-G2"}, + {0, 0, 0, NULL} +}; + static device_method_t cxgb_controller_methods[] = { DEVMETHOD(device_probe, cxgb_controller_probe), DEVMETHOD(device_attach, cxgb_controller_attach), @@ -151,6 +175,8 @@ static int cxgbc_mod_event(module_t, int, void *); static devclass_t cxgb_controller_devclass; DRIVER_MODULE(cxgbc, pci, cxgb_controller_driver, cxgb_controller_devclass, cxgbc_mod_event, 0); +MODULE_PNP_INFO("U16:vendor;U16:device", pci, cxgbc, cxgb_identifiers, + nitems(cxgb_identifiers) - 1); MODULE_VERSION(cxgbc, 1); MODULE_DEPEND(cxgbc, firmware, 1, 1, 1); @@ -280,29 +306,6 @@ enum { FILTER_NO_VLAN_PRI = 7 }; #define PORT_MASK ((1 << MAX_NPORTS) - 1) -/* Table for probing the cards. The desc field isn't actually used */ -struct cxgb_ident { - uint16_t vendor; - uint16_t device; - int index; - char *desc; -} cxgb_identifiers[] = { - {PCI_VENDOR_ID_CHELSIO, 0x0020, 0, "PE9000"}, - {PCI_VENDOR_ID_CHELSIO, 0x0021, 1, "T302E"}, - {PCI_VENDOR_ID_CHELSIO, 0x0022, 2, "T310E"}, - {PCI_VENDOR_ID_CHELSIO, 0x0023, 3, "T320X"}, - {PCI_VENDOR_ID_CHELSIO, 0x0024, 1, "T302X"}, - {PCI_VENDOR_ID_CHELSIO, 0x0025, 3, "T320E"}, - {PCI_VENDOR_ID_CHELSIO, 0x0026, 2, "T310X"}, - {PCI_VENDOR_ID_CHELSIO, 0x0030, 2, "T3B10"}, - {PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"}, - {PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"}, - {PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"}, - {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "T3C10"}, - {PCI_VENDOR_ID_CHELSIO, 0x0036, 3, "S320E-CR"}, - {PCI_VENDOR_ID_CHELSIO, 0x0037, 7, "N320E-G2"}, - {0, 0, 0, NULL} -}; static int set_eeprom(struct port_info *pi, const uint8_t *data, int len, int offset); diff --git a/sys/dev/ida/ida_pci.c b/sys/dev/ida/ida_pci.c index 63a18ecf0259..3911a70c0b46 100644 --- a/sys/dev/ida/ida_pci.c +++ b/sys/dev/ida/ida_pci.c @@ -306,3 +306,5 @@ ida_pci_attach(device_t dev) } DRIVER_MODULE(ida, pci, ida_pci_driver, ida_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ida, board_id, + nitems(board_id) - 1); diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index e46082c0b3b8..3e79f4b400c0 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -372,7 +372,8 @@ static driver_t iwn_driver = { static devclass_t iwn_devclass; DRIVER_MODULE(iwn, pci, iwn_driver, iwn_devclass, NULL, NULL); - +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, iwn, iwn_ident_table, + nitems(iwn_ident_table) - 1); MODULE_VERSION(iwn, 1); MODULE_DEPEND(iwn, firmware, 1, 1, 1); diff --git a/sys/dev/ixl/if_ixl.c b/sys/dev/ixl/if_ixl.c index 6d83545ae941..23c9d13c695d 100644 --- a/sys/dev/ixl/if_ixl.c +++ b/sys/dev/ixl/if_ixl.c @@ -150,6 +150,7 @@ static driver_t ixl_driver = { devclass_t ixl_devclass; DRIVER_MODULE(ixl, pci, ixl_driver, ixl_devclass, 0, 0); +IFLIB_PNP_INFO(pci, ixl, ixl_vendor_info_array); MODULE_VERSION(ixl, 3); MODULE_DEPEND(ixl, pci, 1, 1, 1); diff --git a/sys/dev/ixl/if_ixlv.c b/sys/dev/ixl/if_ixlv.c index f0a91b761f87..dd72d52ab187 100644 --- a/sys/dev/ixl/if_ixlv.c +++ b/sys/dev/ixl/if_ixlv.c @@ -149,7 +149,9 @@ static driver_t ixlv_driver = { devclass_t ixlv_devclass; DRIVER_MODULE(ixlv, pci, ixlv_driver, ixlv_devclass, 0, 0); - +MODULE_PNP_INFO("U32:vendor;U32:device;U32:subvendor;U32:subdevice;U32:revision", + pci, ixlv, ixlv_vendor_info_array, + nitems(ixlv_vendor_info_array) - 1); MODULE_DEPEND(ixlv, pci, 1, 1, 1); MODULE_DEPEND(ixlv, ether, 1, 1, 1); MODULE_DEPEND(ixlv, iflib, 1, 1, 1); diff --git a/sys/dev/mfi/mfi_pci.c b/sys/dev/mfi/mfi_pci.c index d63c5ae6435f..ee609b328990 100644 --- a/sys/dev/mfi/mfi_pci.c +++ b/sys/dev/mfi/mfi_pci.c @@ -106,8 +106,6 @@ static driver_t mfi_pci_driver = { }; static devclass_t mfi_devclass; -DRIVER_MODULE(mfi, pci, mfi_pci_driver, mfi_devclass, 0, 0); -MODULE_VERSION(mfi, 1); static int mfi_msi = 1; SYSCTL_INT(_hw_mfi, OID_AUTO, msi, CTLFLAG_RDTUN, &mfi_msi, 0, @@ -159,6 +157,11 @@ struct mfi_ident { {0, 0, 0, 0, 0, NULL} }; +DRIVER_MODULE(mfi, pci, mfi_pci_driver, mfi_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;U16:subvendor;U16:subdevice", pci, mfi, + mfi_identifiers, nitems(mfi_identifiers) - 1); +MODULE_VERSION(mfi, 1); + static struct mfi_ident * mfi_find_ident(device_t dev) { diff --git a/sys/dev/mpr/mpr_pci.c b/sys/dev/mpr/mpr_pci.c index 03f3143040c2..e86bd9e102ba 100644 --- a/sys/dev/mpr/mpr_pci.c +++ b/sys/dev/mpr/mpr_pci.c @@ -88,9 +88,6 @@ static driver_t mpr_pci_driver = { sizeof(struct mpr_softc) }; -static devclass_t mpr_devclass; -DRIVER_MODULE(mpr, pci, mpr_pci_driver, mpr_devclass, 0, 0); -MODULE_DEPEND(mpr, cam, 1, 1, 1); struct mpr_ident { uint16_t vendor; @@ -154,6 +151,14 @@ struct mpr_ident { { 0, 0, 0, 0, 0, NULL } }; + +static devclass_t mpr_devclass; +DRIVER_MODULE(mpr, pci, mpr_pci_driver, mpr_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;U16:subvendor;U16:subdevice;D:#", pci, + mpr, mpr_identifiers, nitems(mpr_identifiers) - 1); + +MODULE_DEPEND(mpr, cam, 1, 1, 1); + static struct mpr_ident * mpr_find_ident(device_t dev) { diff --git a/sys/dev/mps/mps_pci.c b/sys/dev/mps/mps_pci.c index a81fe8a7300f..1e12c9a6906a 100644 --- a/sys/dev/mps/mps_pci.c +++ b/sys/dev/mps/mps_pci.c @@ -88,10 +88,6 @@ static driver_t mps_pci_driver = { sizeof(struct mps_softc) }; -static devclass_t mps_devclass; -DRIVER_MODULE(mps, pci, mps_pci_driver, mps_devclass, 0, 0); -MODULE_DEPEND(mps, cam, 1, 1, 1); - struct mps_ident { uint16_t vendor; uint16_t device; @@ -147,6 +143,10 @@ struct mps_ident { { 0, 0, 0, 0, 0, NULL } }; +static devclass_t mps_devclass; +DRIVER_MODULE(mps, pci, mps_pci_driver, mps_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;U16:subvendor;U16:subdevice", pci, mps, + mps_identifiers, nitems(mps_identifiers) - 1); static struct mps_ident * mps_find_ident(device_t dev) { diff --git a/sys/dev/mvs/mvs_pci.c b/sys/dev/mvs/mvs_pci.c index cd6afce40f5c..4774390b272c 100644 --- a/sys/dev/mvs/mvs_pci.c +++ b/sys/dev/mvs/mvs_pci.c @@ -521,6 +521,8 @@ static driver_t mvs_driver = { sizeof(struct mvs_controller) }; DRIVER_MODULE(mvs, pci, mvs_driver, mvs_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device", pci, mvs, mvs_ids, + nitems(mvs_ids) - 1); MODULE_VERSION(mvs, 1); MODULE_DEPEND(mvs, cam, 1, 1, 1); diff --git a/sys/dev/my/if_my.c b/sys/dev/my/if_my.c index b1d5e3586c9d..ef5ef7613b99 100644 --- a/sys/dev/my/if_my.c +++ b/sys/dev/my/if_my.c @@ -163,6 +163,8 @@ static driver_t my_driver = { static devclass_t my_devclass; DRIVER_MODULE(my, pci, my_driver, my_devclass, 0, 0); +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, my, my_devs, + nitems(my_devs) - 1); MODULE_DEPEND(my, pci, 1, 1, 1); MODULE_DEPEND(my, ether, 1, 1, 1); diff --git a/sys/dev/oce/oce_if.c b/sys/dev/oce/oce_if.c index 23e32a59de49..0b7aa4da2372 100644 --- a/sys/dev/oce/oce_if.c +++ b/sys/dev/oce/oce_if.c @@ -214,12 +214,6 @@ static driver_t oce_driver = { static devclass_t oce_devclass; -DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, 0, 0); -MODULE_DEPEND(oce, pci, 1, 1, 1); -MODULE_DEPEND(oce, ether, 1, 1, 1); -MODULE_VERSION(oce, 1); - - /* global vars */ const char component_revision[32] = {"///" COMPONENT_REVISION "///"}; @@ -242,6 +236,15 @@ static uint32_t supportedDevices[] = { (PCI_VENDOR_EMULEX << 16) | PCI_PRODUCT_SH }; + +DRIVER_MODULE(oce, pci, oce_driver, oce_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device", pci, oce, supportedDevices, + nitems(supportedDevices)); +MODULE_DEPEND(oce, pci, 1, 1, 1); +MODULE_DEPEND(oce, ether, 1, 1, 1); +MODULE_VERSION(oce, 1); + + POCE_SOFTC softc_head = NULL; POCE_SOFTC softc_tail = NULL; diff --git a/sys/dev/pccbb/pccbb_pci.c b/sys/dev/pccbb/pccbb_pci.c index bbffb8b53200..f2f6387c8aaa 100644 --- a/sys/dev/pccbb/pccbb_pci.c +++ b/sys/dev/pccbb/pccbb_pci.c @@ -983,4 +983,6 @@ static driver_t cbb_driver = { }; DRIVER_MODULE(cbb, pci, cbb_driver, cbb_devclass, 0, 0); +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, cbb, yc_chipsets, + nitems(yc_chipsets) - 1); MODULE_DEPEND(cbb, exca, 1, 1, 1); diff --git a/sys/dev/pcn/if_pcn.c b/sys/dev/pcn/if_pcn.c index 6073310b2ac9..81fb763c18b6 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/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c index 6d9de66e53c8..bcf9df033289 100644 --- a/sys/dev/ral/if_ral_pci.c +++ b/sys/dev/ral/if_ral_pci.c @@ -178,6 +178,8 @@ static driver_t ral_pci_driver = { static devclass_t ral_devclass; DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, NULL, NULL); +MODULE_PNP_INFO("U16:vendor; U16:device; D:#", pci, ral, ral_pci_ids, + nitems(ral_pci_ids) - 1); static int ral_pci_probe(device_t dev) diff --git a/sys/dev/rl/if_rl.c b/sys/dev/rl/if_rl.c index 7e8c63131607..622ad5b16813 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); From d51abd5fe12cb7a345ea94bd70f38be24f655d90 Mon Sep 17 00:00:00 2001 From: Bryan Drewery <bdrewery@FreeBSD.org> Date: Wed, 26 Sep 2018 18:40:57 +0000 Subject: [PATCH 116/139] Handle overflow of uid or gid in arguments for chown chown incorrectly allows a uid or gid greater than UID_MAX/GID_MAX respectively. Using such an argument rolls over to accounts such as root, operator, etc. Approved by: re (gjb) Relnotes: yes Reviewed by: cem, kib Submitted by: Don Morris <dgmorris@earthlink.net> Sponsored by: Dell EMC Differential Revision: https://reviews.freebsd.org/D15119 --- usr.sbin/chown/chown.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c index e568fe8acc13..8f09b62d10ca 100644 --- a/usr.sbin/chown/chown.c +++ b/usr.sbin/chown/chown.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <libgen.h> #include <pwd.h> #include <signal.h> +#include <stddef.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -246,16 +247,13 @@ a_uid(const char *s) static uid_t id(const char *name, const char *type) { - uid_t val; + unsigned long val; char *ep; - /* - * XXX - * We know that uid_t's and gid_t's are unsigned longs. - */ errno = 0; val = strtoul(name, &ep, 10); - if (errno || *ep != '\0') + _Static_assert(UID_MAX >= GID_MAX, "UID MAX less than GID MAX"); + if (errno || *ep != '\0' || val > UID_MAX) errx(1, "%s: illegal %s name", name, type); return (val); } From b28589287b04bc1003c5ec70336a5d5f90736001 Mon Sep 17 00:00:00 2001 From: Warner Losh <imp@FreeBSD.org> Date: Wed, 26 Sep 2018 19:41:00 +0000 Subject: [PATCH 117/139] Remove bogus spaces. Spaces aren't allowed in these strings. Approved by: re@ (glen) --- sys/dev/pcn/if_pcn.c | 2 +- sys/dev/ral/if_ral_pci.c | 2 +- sys/dev/rl/if_rl.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/pcn/if_pcn.c b/sys/dev/pcn/if_pcn.c index 81fb763c18b6..0e91df03ea18 100644 --- a/sys/dev/pcn/if_pcn.c +++ b/sys/dev/pcn/if_pcn.c @@ -193,7 +193,7 @@ 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, +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); diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c index bcf9df033289..41e81d573536 100644 --- a/sys/dev/ral/if_ral_pci.c +++ b/sys/dev/ral/if_ral_pci.c @@ -178,7 +178,7 @@ 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, +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, ral, ral_pci_ids, nitems(ral_pci_ids) - 1); static int diff --git a/sys/dev/rl/if_rl.c b/sys/dev/rl/if_rl.c index 622ad5b16813..e5d4787ebbe9 100644 --- a/sys/dev/rl/if_rl.c +++ b/sys/dev/rl/if_rl.c @@ -259,7 +259,7 @@ 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, +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); From 517a1827f76fc70099d79b4019505e67b1772d72 Mon Sep 17 00:00:00 2001 From: Warner Losh <imp@FreeBSD.org> Date: Wed, 26 Sep 2018 19:41:06 +0000 Subject: [PATCH 118/139] Relax syntax requirements of source string The original spec for the strings describing the PNP info didn't allow spaces. Several times now people have broken the install by including them. Relax the syntax to allow them after the ; which is where people's muscle memory tends to put them. Approved by: re@ (gjb) --- usr.sbin/kldxref/kldxref.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/usr.sbin/kldxref/kldxref.c b/usr.sbin/kldxref/kldxref.c index f0d699369dbd..4e456a05c25b 100644 --- a/usr.sbin/kldxref/kldxref.c +++ b/usr.sbin/kldxref/kldxref.c @@ -46,6 +46,7 @@ #include <sys/module.h> #define FREEBSD_ELF +#include <ctype.h> #include <err.h> #include <errno.h> #include <fts.h> @@ -259,6 +260,9 @@ parse_pnp_list(const char *desc, char **new_desc, pnp_list *list) strncpy(key, colon + 1, semi - colon - 1); key[semi - colon - 1] = '\0'; walker = semi + 1; + /* Fail safe if we have spaces after ; */ + while (walker < ep && isspace(*walker)) + walker++; } else { if (strlen(colon + 1) >= sizeof(key)) goto err; From a7fcb1afcb6b798fc6c504449ac8ad4b16951dc8 Mon Sep 17 00:00:00 2001 From: Sean Eric Fagan <sef@FreeBSD.org> Date: Wed, 26 Sep 2018 20:23:12 +0000 Subject: [PATCH 119/139] Add per-session locking to cryptosoft (swcr). As part of ZFS Crypto, I started getting a series of panics when I did not have AESNI loaded. Adding locking fixed it, and I concluded that the Reinit function altered the AES key schedule. This locking is not as fine-grained as it could be (AESNI uses per-cpu locking), but it's minimally invasive. Sponsored by: iXsystems Inc Reviewed by: cem, mav Approved by: re (gjb), mav (mentor) Differential Revision: https://reviews.freebsd.org/D17307 --- sys/opencrypto/cryptosoft.c | 8 +++++++- sys/opencrypto/cryptosoft.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/opencrypto/cryptosoft.c b/sys/opencrypto/cryptosoft.c index a4a719b5fbed..0a5a20640a66 100644 --- a/sys/opencrypto/cryptosoft.c +++ b/sys/opencrypto/cryptosoft.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rwlock.h> #include <sys/endian.h> #include <sys/limits.h> +#include <sys/mutex.h> #include <crypto/blowfish/blowfish.h> #include <crypto/sha1.h> @@ -765,6 +766,7 @@ swcr_newsession(device_t dev, crypto_session_t cses, struct cryptoini *cri) return EINVAL; ses = crypto_get_driver_session(cses); + mtx_init(&ses->swcr_lock, "swcr session lock", NULL, MTX_DEF); for (i = 0; cri != NULL && i < nitems(ses->swcr_algorithms); i++) { swd = &ses->swcr_algorithms[i]; @@ -1022,6 +1024,7 @@ swcr_freesession(device_t dev, crypto_session_t cses) ses = crypto_get_driver_session(cses); + mtx_destroy(&ses->swcr_lock); for (i = 0; i < nitems(ses->swcr_algorithms); i++) { swd = &ses->swcr_algorithms[i]; @@ -1109,7 +1112,7 @@ swcr_freesession(device_t dev, crypto_session_t cses) static int swcr_process(device_t dev, struct cryptop *crp, int hint) { - struct swcr_session *ses; + struct swcr_session *ses = NULL; struct cryptodesc *crd; struct swcr_data *sw; size_t i; @@ -1124,6 +1127,7 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) } ses = crypto_get_driver_session(crp->crp_session); + mtx_lock(&ses->swcr_lock); /* Go through crypto descriptors, processing as we go */ for (crd = crp->crp_desc; crd; crd = crd->crd_next) { @@ -1213,6 +1217,8 @@ swcr_process(device_t dev, struct cryptop *crp, int hint) } done: + if (ses) + mtx_unlock(&ses->swcr_lock); crypto_done(crp); return 0; } diff --git a/sys/opencrypto/cryptosoft.h b/sys/opencrypto/cryptosoft.h index d88b09d4e1c0..d787dc243ae6 100644 --- a/sys/opencrypto/cryptosoft.h +++ b/sys/opencrypto/cryptosoft.h @@ -58,6 +58,7 @@ struct swcr_data { }; struct swcr_session { + struct mtx swcr_lock; struct swcr_data swcr_algorithms[2]; unsigned swcr_nalgs; }; From ac4031d8056a1abd8f1cda7e9a6ddb50287eb83b Mon Sep 17 00:00:00 2001 From: Navdeep Parhar <np@FreeBSD.org> Date: Wed, 26 Sep 2018 21:16:07 +0000 Subject: [PATCH 120/139] cxgbe(4): Enable support for per-connection rate limiting in the default firmware configuration files. Approved by: re@ (gjb@) Sponsored by: Chelsio Communications --- sys/dev/cxgbe/firmware/t4fw_cfg.txt | 3 ++- sys/dev/cxgbe/firmware/t5fw_cfg.txt | 3 ++- sys/dev/cxgbe/firmware/t6fw_cfg.txt | 3 ++- sys/dev/cxgbe/t4_main.c | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/sys/dev/cxgbe/firmware/t4fw_cfg.txt b/sys/dev/cxgbe/firmware/t4fw_cfg.txt index 43820a0b44cb..11721a1ed648 100644 --- a/sys/dev/cxgbe/firmware/t4fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t4fw_cfg.txt @@ -110,6 +110,7 @@ nexactf = 280 cmask = all pmask = all + nethofld = 2048 # driver will mask off features it won't use protocol = ofld, rddp, rdmac, iscsi_initiator_pdu, iscsi_target_pdu @@ -245,7 +246,7 @@ [fini] version = 0x1 - checksum = 0xbec0621 + checksum = 0x159b9295 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t5fw_cfg.txt b/sys/dev/cxgbe/firmware/t5fw_cfg.txt index 721ff372ef80..f42966c62e49 100644 --- a/sys/dev/cxgbe/firmware/t5fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t5fw_cfg.txt @@ -155,6 +155,7 @@ nexactf = 456 cmask = all pmask = all + nethofld = 8192 # driver will mask off features it won't use protocol = ofld, rddp, rdmac, iscsi_initiator_pdu, iscsi_target_pdu, iscsi_t10dif @@ -290,7 +291,7 @@ [fini] version = 0x1 - checksum = 0x89c83d98 + checksum = 0x30b6a157 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/firmware/t6fw_cfg.txt b/sys/dev/cxgbe/firmware/t6fw_cfg.txt index 3b62ed83b344..c542cfcadf5e 100644 --- a/sys/dev/cxgbe/firmware/t6fw_cfg.txt +++ b/sys/dev/cxgbe/firmware/t6fw_cfg.txt @@ -155,6 +155,7 @@ pmask = all ncrypto_lookaside = 16 nclip = 320 + nethofld = 8192 # TCAM has 6K cells; each region must start at a multiple of 128 cell. # Each entry in these categories takes 2 cells each. nhash will use the @@ -275,7 +276,7 @@ [fini] version = 0x1 - checksum = 0x9e8952d2 + checksum = 0xf3e93001 # # $FreeBSD$ # diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c index dc491fd1d7d3..898cbf4db465 100644 --- a/sys/dev/cxgbe/t4_main.c +++ b/sys/dev/cxgbe/t4_main.c @@ -439,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; From 6c30676522be1ee98e5331dcab10288ba8d37f09 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Wed, 26 Sep 2018 21:27:08 +0000 Subject: [PATCH 121/139] When doing lm_add(), check for duplicates. This is useful when lm_find() moves the match to the global mapping, since lm_find() could be called with a same path more than once. Reported and tested by: Andreas Longwitz <longwitz@incore.de> Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week --- libexec/rtld-elf/libmap.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libexec/rtld-elf/libmap.c b/libexec/rtld-elf/libmap.c index 592b7664eea1..33c824a65aff 100644 --- a/libexec/rtld-elf/libmap.c +++ b/libexec/rtld-elf/libmap.c @@ -353,6 +353,7 @@ lm_add(const char *p, const char *f, const char *t) { struct lm_list *lml; struct lm *lm; + const char *t1; if (p == NULL) p = "$DEFAULT$"; @@ -362,11 +363,14 @@ lm_add(const char *p, const char *f, const char *t) if ((lml = lmp_find(p)) == NULL) lml = lmp_init(xstrdup(p)); - lm = xmalloc(sizeof(struct lm)); - lm->f = xstrdup(f); - lm->t = xstrdup(t); - TAILQ_INSERT_HEAD(lml, lm, lm_link); - lm_count++; + t1 = lml_find(lml, f); + if (t1 == NULL || strcmp(t1, t) != 0) { + lm = xmalloc(sizeof(struct lm)); + lm->f = xstrdup(f); + lm->t = xstrdup(t); + TAILQ_INSERT_HEAD(lml, lm, lm_link); + lm_count++; + } } char * From d2f2e4c02d0f3e45a708ba01e9ca4fb8f7f25e31 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Wed, 26 Sep 2018 21:28:14 +0000 Subject: [PATCH 122/139] Provide refobj context when doing libmap substitution inside search_library_path(). This corrects the scope of libmap matches. Reported and tested by: Andreas Longwitz <longwitz@incore.de> Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week --- libexec/rtld-elf/rtld.c | 80 ++++++++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 33 deletions(-) diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c index dfd0388478f9..83d5e28e287b 100644 --- a/libexec/rtld-elf/rtld.c +++ b/libexec/rtld-elf/rtld.c @@ -125,7 +125,7 @@ static void objlist_remove(Objlist *, Obj_Entry *); static int open_binary_fd(const char *argv0, bool search_in_path); static int parse_args(char* argv[], int argc, bool *use_pathp, int *fdp); static int parse_integer(const char *); -static void *path_enumerate(const char *, path_enum_proc, void *); +static void *path_enumerate(const char *, path_enum_proc, const char *, void *); static void print_usage(const char *argv0); static void release_object(Obj_Entry *); static int relocate_object_dag(Obj_Entry *root, bool bind_now, @@ -140,7 +140,8 @@ static int rtld_dirname(const char *, char *); static int rtld_dirname_abs(const char *, char *); static void *rtld_dlopen(const char *name, int fd, int mode); static void rtld_exit(void); -static char *search_library_path(const char *, const char *, int *); +static char *search_library_path(const char *, const char *, const char *, + int *); static char *search_library_pathfds(const char *, const char *, int *); static const void **get_program_var_addr(const char *, RtldLockState *); static void set_program_var(const char *, const void *); @@ -1576,8 +1577,7 @@ gnu_hash(const char *s) static char * find_library(const char *xname, const Obj_Entry *refobj, int *fdp) { - char *pathname; - char *name; + char *name, *pathname, *refobj_path; bool nodeflib, objgiven; objgiven = refobj != NULL; @@ -1597,6 +1597,7 @@ find_library(const char *xname, const Obj_Entry *refobj, int *fdp) } dbg(" Searching for \"%s\"", name); + refobj_path = objgiven ? refobj->path : NULL; /* * If refobj->rpath != NULL, then refobj->runpath is NULL. Fall @@ -1605,52 +1606,61 @@ find_library(const char *xname, const Obj_Entry *refobj, int *fdp) * nodeflib. */ if (objgiven && refobj->rpath != NULL && ld_library_path_rpath) { - pathname = search_library_path(name, ld_library_path, fdp); + pathname = search_library_path(name, ld_library_path, + refobj_path, fdp); if (pathname != NULL) return (pathname); if (refobj != NULL) { - pathname = search_library_path(name, refobj->rpath, fdp); + pathname = search_library_path(name, refobj->rpath, + refobj_path, fdp); if (pathname != NULL) return (pathname); } pathname = search_library_pathfds(name, ld_library_dirs, fdp); if (pathname != NULL) return (pathname); - pathname = search_library_path(name, gethints(false), fdp); + pathname = search_library_path(name, gethints(false), + refobj_path, fdp); if (pathname != NULL) return (pathname); - pathname = search_library_path(name, ld_standard_library_path, fdp); + pathname = search_library_path(name, ld_standard_library_path, + refobj_path, fdp); if (pathname != NULL) return (pathname); } else { nodeflib = objgiven ? refobj->z_nodeflib : false; if (objgiven) { - pathname = search_library_path(name, refobj->rpath, fdp); + pathname = search_library_path(name, refobj->rpath, + refobj->path, fdp); if (pathname != NULL) return (pathname); } if (objgiven && refobj->runpath == NULL && refobj != obj_main) { - pathname = search_library_path(name, obj_main->rpath, fdp); + pathname = search_library_path(name, obj_main->rpath, + refobj_path, fdp); if (pathname != NULL) return (pathname); } - pathname = search_library_path(name, ld_library_path, fdp); + pathname = search_library_path(name, ld_library_path, + refobj_path, fdp); if (pathname != NULL) return (pathname); if (objgiven) { - pathname = search_library_path(name, refobj->runpath, fdp); + pathname = search_library_path(name, refobj->runpath, + refobj_path, fdp); if (pathname != NULL) return (pathname); } pathname = search_library_pathfds(name, ld_library_dirs, fdp); if (pathname != NULL) return (pathname); - pathname = search_library_path(name, gethints(nodeflib), fdp); + pathname = search_library_path(name, gethints(nodeflib), + refobj_path, fdp); if (pathname != NULL) return (pathname); if (objgiven && !nodeflib) { pathname = search_library_path(name, - ld_standard_library_path, fdp); + ld_standard_library_path, refobj_path, fdp); if (pathname != NULL) return (pathname); } @@ -1845,8 +1855,9 @@ gethints(bool nostdlib) hargs.request = RTLD_DI_SERINFOSIZE; hargs.serinfo = &hmeta; - path_enumerate(ld_standard_library_path, fill_search_info, &sargs); - path_enumerate(hints, fill_search_info, &hargs); + path_enumerate(ld_standard_library_path, fill_search_info, NULL, + &sargs); + path_enumerate(hints, fill_search_info, NULL, &hargs); SLPinfo = xmalloc(smeta.dls_size); hintinfo = xmalloc(hmeta.dls_size); @@ -1864,8 +1875,9 @@ gethints(bool nostdlib) hargs.serpath = &hintinfo->dls_serpath[0]; hargs.strspace = (char *)&hintinfo->dls_serpath[hmeta.dls_cnt]; - path_enumerate(ld_standard_library_path, fill_search_info, &sargs); - path_enumerate(hints, fill_search_info, &hargs); + path_enumerate(ld_standard_library_path, fill_search_info, NULL, + &sargs); + path_enumerate(hints, fill_search_info, NULL, &hargs); /* * Now calculate the difference between two sets, by excluding @@ -2974,7 +2986,8 @@ rtld_exit(void) * callback on the result. */ static void * -path_enumerate(const char *path, path_enum_proc callback, void *arg) +path_enumerate(const char *path, path_enum_proc callback, + const char *refobj_path, void *arg) { const char *trans; if (path == NULL) @@ -2986,7 +2999,7 @@ path_enumerate(const char *path, path_enum_proc callback, void *arg) char *res; len = strcspn(path, ":;"); - trans = lm_findn(NULL, path, len); + trans = lm_findn(refobj_path, path, len); if (trans) res = callback(trans, strlen(trans), arg); else @@ -3045,7 +3058,8 @@ try_library_path(const char *dir, size_t dirlen, void *param) } static char * -search_library_path(const char *name, const char *path, int *fdp) +search_library_path(const char *name, const char *path, + const char *refobj_path, int *fdp) { char *p; struct try_library_args arg; @@ -3059,7 +3073,7 @@ search_library_path(const char *name, const char *path, int *fdp) arg.buflen = PATH_MAX; arg.fd = -1; - p = path_enumerate(path, try_library_path, &arg); + p = path_enumerate(path, try_library_path, refobj_path, &arg); *fdp = arg.fd; free(arg.buffer); @@ -3776,12 +3790,12 @@ do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info) _info.dls_size = __offsetof(struct dl_serinfo, dls_serpath); _info.dls_cnt = 0; - path_enumerate(obj->rpath, fill_search_info, &args); - path_enumerate(ld_library_path, fill_search_info, &args); - path_enumerate(obj->runpath, fill_search_info, &args); - path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args); + path_enumerate(obj->rpath, fill_search_info, NULL, &args); + path_enumerate(ld_library_path, fill_search_info, NULL, &args); + path_enumerate(obj->runpath, fill_search_info, NULL, &args); + path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL, &args); if (!obj->z_nodeflib) - path_enumerate(ld_standard_library_path, fill_search_info, &args); + path_enumerate(ld_standard_library_path, fill_search_info, NULL, &args); if (request == RTLD_DI_SERINFOSIZE) { @@ -3801,25 +3815,25 @@ do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info) args.strspace = (char *)&info->dls_serpath[_info.dls_cnt]; args.flags = LA_SER_RUNPATH; - if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL) + if (path_enumerate(obj->rpath, fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_LIBPATH; - if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL) + if (path_enumerate(ld_library_path, fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_RUNPATH; - if (path_enumerate(obj->runpath, fill_search_info, &args) != NULL) + if (path_enumerate(obj->runpath, fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_CONFIG; - if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, &args) + if (path_enumerate(gethints(obj->z_nodeflib), fill_search_info, NULL, &args) != NULL) return (-1); args.flags = LA_SER_DEFAULT; - if (!obj->z_nodeflib && - path_enumerate(ld_standard_library_path, fill_search_info, &args) != NULL) + if (!obj->z_nodeflib && path_enumerate(ld_standard_library_path, + fill_search_info, NULL, &args) != NULL) return (-1); return (0); } From 27d2645787b9487e086a4f8a2a403cfa6c192253 Mon Sep 17 00:00:00 2001 From: Andrew Turner <andrew@FreeBSD.org> Date: Thu, 27 Sep 2018 11:16:19 +0000 Subject: [PATCH 123/139] Handle a guest executing a vm instruction by trapping and raising an undefined instruction exception. Previously we would exit the guest, however an unprivileged user could execute these. Found with: syzkaller Reviewed by: araujo, tychon (previous version) Approved by: re (kib) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D17192 --- sys/amd64/include/vmm.h | 1 + sys/amd64/vmm/intel/vmx.c | 16 ++++++++++++++++ sys/amd64/vmm/vmm.c | 1 + 3 files changed, 18 insertions(+) diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h index 6b8a14224874..b66eda0f4768 100644 --- a/sys/amd64/include/vmm.h +++ b/sys/amd64/include/vmm.h @@ -557,6 +557,7 @@ enum vm_exitcode { VM_EXITCODE_SVM, VM_EXITCODE_REQIDLE, VM_EXITCODE_DEBUG, + VM_EXITCODE_VMINSN, VM_EXITCODE_MAX }; diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index b40846cae6e6..61871e9338eb 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -267,6 +267,9 @@ SDT_PROBE_DEFINE3(vmm, vmx, exit, monitor, SDT_PROBE_DEFINE3(vmm, vmx, exit, mwait, "struct vmx *", "int", "struct vm_exit *"); +SDT_PROBE_DEFINE3(vmm, vmx, exit, vminsn, + "struct vmx *", "int", "struct vm_exit *"); + SDT_PROBE_DEFINE4(vmm, vmx, exit, unknown, "struct vmx *", "int", "struct vm_exit *", "uint32_t"); @@ -2638,6 +2641,19 @@ vmx_exit_process(struct vmx *vmx, int vcpu, struct vm_exit *vmexit) SDT_PROBE3(vmm, vmx, exit, mwait, vmx, vcpu, vmexit); vmexit->exitcode = VM_EXITCODE_MWAIT; break; + case EXIT_REASON_VMCALL: + case EXIT_REASON_VMCLEAR: + case EXIT_REASON_VMLAUNCH: + case EXIT_REASON_VMPTRLD: + case EXIT_REASON_VMPTRST: + case EXIT_REASON_VMREAD: + case EXIT_REASON_VMRESUME: + case EXIT_REASON_VMWRITE: + case EXIT_REASON_VMXOFF: + case EXIT_REASON_VMXON: + SDT_PROBE3(vmm, vmx, exit, vminsn, vmx, vcpu, vmexit); + vmexit->exitcode = VM_EXITCODE_VMINSN; + break; default: SDT_PROBE4(vmm, vmx, exit, unknown, vmx, vcpu, vmexit, reason); diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c index 6f0e0b2b9554..aecd21f13b4a 100644 --- a/sys/amd64/vmm/vmm.c +++ b/sys/amd64/vmm/vmm.c @@ -1737,6 +1737,7 @@ vm_run(struct vm *vm, struct vm_run *vmrun) break; case VM_EXITCODE_MONITOR: case VM_EXITCODE_MWAIT: + case VM_EXITCODE_VMINSN: vm_inject_ud(vm, vcpuid); break; default: From e030048010cddb3a79178979b9c9a5ecd25463d5 Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Thu, 27 Sep 2018 12:08:53 +0000 Subject: [PATCH 124/139] msdosfs(5): Explain how to determine version of the FAT file system. While here, remove deprecated Tn macros. Reviewed by: bcr Approved by: re (gjb), krion (mentor) Sponsored by: Bally Wulff Games & Entertainment GmbH Differential Revision: https://reviews.freebsd.org/D17237 --- share/man/man5/msdosfs.5 | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/share/man/man5/msdosfs.5 b/share/man/man5/msdosfs.5 index ff1df4ba525b..7e8d31fa75c5 100644 --- a/share/man/man5/msdosfs.5 +++ b/share/man/man5/msdosfs.5 @@ -2,7 +2,7 @@ .\" Written by Tom Rhodes .\" This file is in the public domain. .\" -.Dd October 1, 2013 +.Dd September 27, 2018 .Dt MSDOSFS 5 .Os .Sh NAME @@ -15,9 +15,7 @@ The .Nm driver will permit the .Fx -kernel to read and write -.Tn MS-DOS -based file systems. +kernel to read and write MS-DOS based file systems. .Pp The most common usage follows: .Pp @@ -43,9 +41,7 @@ that looks similar to: /dev/ada0sN /dos msdosfs rw 0 0 .Ed .Pp -This will mount an -.Tn MS-DOS -based partition at the +This will mount an MS-DOS based partition at the .Pa /dos mount point during system boot. Using @@ -58,6 +54,15 @@ See for more information on .Fx directory layout. +.Sh EXAMPLES +Determine which FAT file system version (e.g, FAT16, FAT32) +is a partition formatted with: +.Bd -literal -offset indent +file -s /dev/da0s1 +.Ed +.Pp +.Xr gpart 8 +may also be used to extract this information. .Sh SEE ALSO .Xr mount 2 , .Xr unmount 2 , From 8385e87c78f1115e198dd57b792f5f6e34d2048d Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Thu, 27 Sep 2018 12:15:31 +0000 Subject: [PATCH 125/139] newvers.sh: Unbreak building in Git repositories. Building the kernel in Git repositories when git-svn is not available and the "help.autocorrect" Git parameter is enabled results in Git trying to replace the "svn" command (it does not know) with "serve". As a result the output of the "git server" command is appended to the value of the environmental variable VERINFO, which causes the auto generated vers.c file to contain invalid C syntax (missing newline escapes): #define "@(#)FreeBSD 12.0-ALPHA7 r000eversion 2 0015agent=git/2.19.0 000cls-refs 0012fetch=shallow 0012server-option 0000=5e2272613fa(splash-vt)" #define VERSTR "FreeBSD 12.0-ALPHA7 r000eversion 2 0015agent=git/2.19.0 000cls-refs 0012fetch=shallow 0012server-option 0000=5e2272613fa(splash-vt)\n" Using `-c help.autocorrect=0` seems to be a good solution as it does not modify user's environment. I am not sure, however, if we should use programs (or Git commands), which we are not sure exist (we never check if git-svn is available on the host), as there may be more unexpected behaviors like this one. Reviewed by: eadler, emaste, krion Approved by: re (gjb), krion (mentor) Sponsored by: Bally Wulff Games & Entertainment GmbH Differential Revision: https://reviews.freebsd.org/D17271 --- sys/conf/newvers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index db6f66d7c52c..e0cf2cfa9c13 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -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 From 3d31df21e785e3c027d9b1aae29abc73f847b7ec Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Thu, 27 Sep 2018 12:20:32 +0000 Subject: [PATCH 126/139] Cross-reference style.Makefile(5) from make(1) and make.conf(5). Reviewed by: krion, mat, sjg Approved by: re (gjb), krion (mentor), mat (mentor) Sponsored by: Bally Wulff Games & Entertainment GmbH Differential Revision: https://reviews.freebsd.org/D17170 --- contrib/bmake/make.1 | 7 ++++--- share/man/man5/make.conf.5 | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/contrib/bmake/make.1 b/contrib/bmake/make.1 index c4479f1b845e..631b17c46f5b 100644 --- a/contrib/bmake/make.1 +++ b/contrib/bmake/make.1 @@ -29,7 +29,7 @@ .\" .\" from: @(#)make.1 8.4 (Berkeley) 3/19/94 .\" -.Dd June 22, 2017 +.Dd September 27, 2018 .Dt MAKE 1 .Os .Sh NAME @@ -796,7 +796,7 @@ Tells whether to pass the descriptors of the job token queue even if the target is not tagged with .Ic .MAKE -The default is +The default is .Ql Pa yes for backwards compatability with .Fx 9.0 @@ -2385,7 +2385,8 @@ Basic use of suffix rules (for files only in the current directory, not trying to chain transformations together, etc.) is also reasonably portable. .Sh SEE ALSO -.Xr mkdep 1 +.Xr mkdep 1 , +.Xr style.Makefile 5 .Sh HISTORY A .Nm diff --git a/share/man/man5/make.conf.5 b/share/man/man5/make.conf.5 index 7517d20db193..f8c148e62ccb 100644 --- a/share/man/man5/make.conf.5 +++ b/share/man/man5/make.conf.5 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 15, 2018 +.Dd September 27, 2018 .Dt MAKE.CONF 5 .Os .Sh NAME @@ -676,6 +676,7 @@ Porter's Handbook. .Xr install 1 , .Xr make 1 , .Xr src.conf 5 , +.Xr style.Makefile 5 , .Xr environ 7 , .Xr ports 7 , .Xr sendmail 8 From c7637c4d19df9a2030fd919f1016303d15284623 Mon Sep 17 00:00:00 2001 From: Andrew Turner <andrew@FreeBSD.org> Date: Thu, 27 Sep 2018 13:50:57 +0000 Subject: [PATCH 127/139] Move the undefined instruction handler to identcpu.c so we have access to the registers from boot. Approved by: re (kib) Sponsored by: ABT Systems Ltd Differential Revision: https://reviews.freebsd.org/D17301 --- sys/arm64/arm64/identcpu.c | 95 +++++++++++++++++++++++++ sys/arm64/arm64/undefined.c | 130 ---------------------------------- sys/arm64/include/undefined.h | 37 ++++++++++ 3 files changed, 132 insertions(+), 130 deletions(-) diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index a79490441e91..5ba4fbc60605 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; @@ -162,6 +163,98 @@ const struct cpu_implementers cpu_implementers[] = { CPU_IMPLEMENTER_NONE, }; +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); +} + static void identify_cpu_sysinit(void *dummy __unused) { @@ -170,6 +263,8 @@ identify_cpu_sysinit(void *dummy __unused) CPU_FOREACH(cpu) { print_cpu_features(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/undefined.c b/sys/arm64/arm64/undefined.c index a96d5f88ddd5..753558a085dd 100644 --- a/sys/arm64/arm64/undefined.c +++ b/sys/arm64/arm64/undefined.c @@ -53,135 +53,6 @@ struct undef_handler { */ LIST_HEAD(, undef_handler) undef_handlers[2]; -#define MRS_MASK 0xfff00000 -#define MRS_VALUE 0xd5300000 -#define MRS_SPECIAL(insn) ((insn) & 0x000fffe0) -#define MRS_REGISTER(insn) ((insn) & 0x0000001f) -#define MRS_Op0_SHIFT 19 -#define MRS_Op0_MASK 0x00080000 -#define MRS_Op1_SHIFT 16 -#define MRS_Op1_MASK 0x00070000 -#define MRS_CRn_SHIFT 12 -#define MRS_CRn_MASK 0x0000f000 -#define MRS_CRm_SHIFT 8 -#define MRS_CRm_MASK 0x00000f00 -#define MRS_Op2_SHIFT 5 -#define MRS_Op2_MASK 0x000000e0 -#define MRS_Rt_SHIFT 0 -#define MRS_Rt_MASK 0x0000001f - -static inline int -mrs_Op0(uint32_t insn) -{ - - /* op0 is encoded without the top bit in a mrs instruction */ - return (2 | ((insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT)); -} - -#define MRS_GET(op) \ -static inline int \ -mrs_##op(uint32_t insn) \ -{ \ - \ - return ((insn & MRS_##op##_MASK) >> MRS_##op##_SHIFT); \ -} -MRS_GET(Op1) -MRS_GET(CRn) -MRS_GET(CRm) -MRS_GET(Op2) - -struct mrs_safe_value { - u_int CRm; - u_int Op2; - uint64_t value; -}; - -static struct mrs_safe_value safe_values[] = { - { /* id_aa64pfr0_el1 */ - .CRm = 4, - .Op2 = 0, - .value = ID_AA64PFR0_ADV_SIMD_NONE | ID_AA64PFR0_FP_NONE | - ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64, - }, - { /* id_aa64dfr0_el1 */ - .CRm = 5, - .Op2 = 0, - .value = ID_AA64DFR0_DEBUG_VER_8, - }, -}; - -static int -user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, - uint32_t esr) -{ - uint64_t value; - int CRm, Op2, i, reg; - - if ((insn & MRS_MASK) != MRS_VALUE) - return (0); - - /* - * We only emulate Op0 == 3, Op1 == 0, CRn == 0, CRm == {0, 4-7}. - * These are in the EL1 CPU identification space. - * CRm == 0 holds MIDR_EL1, MPIDR_EL1, and REVID_EL1. - * CRm == {4-7} holds the ID_AA64 registers. - * - * For full details see the ARMv8 ARM (ARM DDI 0487C.a) - * Table D9-2 System instruction encodings for non-Debug System - * register accesses. - */ - if (mrs_Op0(insn) != 3 || mrs_Op1(insn) != 0 || mrs_CRn(insn) != 0) - return (0); - - CRm = mrs_CRm(insn); - if (CRm > 7 || (CRm < 4 && CRm != 0)) - return (0); - - Op2 = mrs_Op2(insn); - value = 0; - - for (i = 0; i < nitems(safe_values); i++) { - if (safe_values[i].CRm == CRm && safe_values[i].Op2 == Op2) { - value = safe_values[i].value; - break; - } - } - - if (CRm == 0) { - switch (Op2) { - case 0: - value = READ_SPECIALREG(midr_el1); - break; - case 5: - value = READ_SPECIALREG(mpidr_el1); - break; - case 6: - value = READ_SPECIALREG(revidr_el1); - break; - default: - return (0); - } - } - - /* - * We will handle this instruction, move to the next so we - * don't trap here again. - */ - frame->tf_elr += INSN_SIZE; - - reg = MRS_REGISTER(insn); - /* If reg is 31 then write to xzr, i.e. do nothing */ - if (reg == 31) - return (1); - - if (reg < nitems(frame->tf_x)) - frame->tf_x[reg] = value; - else if (reg == 30) - frame->tf_lr = value; - - return (1); -} - /* * Work around a bug in QEMU prior to 2.5.1 where reading unknown ID * registers would raise an exception when they should return 0. @@ -219,7 +90,6 @@ undef_init(void) LIST_INIT(&undef_handlers[0]); LIST_INIT(&undef_handlers[1]); - install_undef_handler(true, user_mrs_handler); install_undef_handler(false, id_aa64mmfr2_handler); } diff --git a/sys/arm64/include/undefined.h b/sys/arm64/include/undefined.h index 7fded28c31f2..ee25af6e3f9c 100644 --- a/sys/arm64/include/undefined.h +++ b/sys/arm64/include/undefined.h @@ -36,6 +36,43 @@ typedef int (*undef_handler_t)(vm_offset_t, uint32_t, struct trapframe *, uint32_t); +#define MRS_MASK 0xfff00000 +#define MRS_VALUE 0xd5300000 +#define MRS_SPECIAL(insn) ((insn) & 0x000fffe0) +#define MRS_REGISTER(insn) ((insn) & 0x0000001f) +#define MRS_Op0_SHIFT 19 +#define MRS_Op0_MASK 0x00080000 +#define MRS_Op1_SHIFT 16 +#define MRS_Op1_MASK 0x00070000 +#define MRS_CRn_SHIFT 12 +#define MRS_CRn_MASK 0x0000f000 +#define MRS_CRm_SHIFT 8 +#define MRS_CRm_MASK 0x00000f00 +#define MRS_Op2_SHIFT 5 +#define MRS_Op2_MASK 0x000000e0 +#define MRS_Rt_SHIFT 0 +#define MRS_Rt_MASK 0x0000001f + +static inline int +mrs_Op0(uint32_t insn) +{ + + /* op0 is encoded without the top bit in a mrs instruction */ + return (2 | ((insn & MRS_Op0_MASK) >> MRS_Op0_SHIFT)); +} + +#define MRS_GET(op) \ +static inline int \ +mrs_##op(uint32_t insn) \ +{ \ + \ + return ((insn & MRS_##op##_MASK) >> MRS_##op##_SHIFT); \ +} +MRS_GET(Op1) +MRS_GET(CRn) +MRS_GET(CRm) +MRS_GET(Op2) + void undef_init(void); void *install_undef_handler(bool, undef_handler_t); void remove_undef_handler(void *); From e3f284eee7af7bcebf4bc96f64a9bc9e8e9d692b Mon Sep 17 00:00:00 2001 From: Andrew Turner <andrew@FreeBSD.org> Date: Thu, 27 Sep 2018 13:54:09 +0000 Subject: [PATCH 128/139] Export ID_AA64PFR0_EL1 to userland Create a user view of the ID_AA64PFR0_EL1 register with values common across all CPUs. Approved by: re (kib) Sponsored by: ABT Systems Ltd Differential Revision: https://reviews.freebsd.org/D17301 --- sys/arm64/arm64/identcpu.c | 126 +++++++++++++++++++++++++++++++++---- 1 file changed, 115 insertions(+), 11 deletions(-) diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index 5ba4fbc60605..286b4358f4a5 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -88,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 @@ -163,26 +164,77 @@ const struct cpu_implementers cpu_implementers[] = { CPU_IMPLEMENTER_NONE, }; -struct mrs_safe_value { - u_int CRm; - u_int Op2; - uint64_t value; +#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; }; -static struct mrs_safe_value safe_values[] = { +#define MRS_FIELD(_sign, _type, _shift) \ + { \ + .sign = (_sign), \ + .type = (_type), \ + .shift = (_shift), \ + } + +#define MRS_FIELD_END { .type = MRS_INVALID, } + +static struct mrs_field id_aa64pfr0_fields[] = { + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_SVE_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_RAS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_GIC_SHIFT), + MRS_FIELD(true, MRS_LOWER, ID_AA64PFR0_ADV_SIMD_SHIFT), + MRS_FIELD(true, MRS_LOWER, ID_AA64PFR0_FP_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_EL3_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64PFR0_EL2_SHIFT), + MRS_FIELD(false, MRS_LOWER, ID_AA64PFR0_EL1_SHIFT), + MRS_FIELD(false, MRS_LOWER, ID_AA64PFR0_EL0_SHIFT), + MRS_FIELD_END, +}; + +static struct mrs_field id_aa64dfr0_fields[] = { + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_PMS_VER_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_CTX_CMPS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_WRPS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_BRPS_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_PMU_VER_SHIFT), + MRS_FIELD(false, MRS_EXACT, ID_AA64DFR0_TRACE_VER_SHIFT), + MRS_FIELD(false, MRS_EXACT_VAL(0x6), ID_AA64DFR0_DEBUG_VER_SHIFT), + MRS_FIELD_END, +}; + +struct mrs_user_reg { + u_int CRm; + u_int Op2; + size_t offset; + struct mrs_field *fields; +}; + +static struct mrs_user_reg user_regs[] = { { /* id_aa64pfr0_el1 */ .CRm = 4, .Op2 = 0, - .value = ID_AA64PFR0_ADV_SIMD_NONE | ID_AA64PFR0_FP_NONE | - ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64, + .offset = __offsetof(struct cpu_desc, id_aa64pfr0), + .fields = id_aa64pfr0_fields, }, { /* id_aa64dfr0_el1 */ .CRm = 5, .Op2 = 0, - .value = ID_AA64DFR0_DEBUG_VER_8, + .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) @@ -213,9 +265,9 @@ user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, 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; + 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; } } @@ -255,13 +307,65 @@ user_mrs_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, 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); From a8e3f99ec190ee5c11413878b7fd75578e542808 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 27 Sep 2018 14:05:44 +0000 Subject: [PATCH 129/139] amd64: implement memcmp in assembly Both the in-kernel C variant and libc asm variant have very poor performance. The former compiles to a single byte comparison loop, which breaks down even for small sizes. The latter uses rep cmpsq/b which turn out to have very poor throughput and are slower than a hand-coded 32-byte comparison loop. Depending on size this is about 3-4 times faster than the current routines. Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17328 --- sys/amd64/amd64/support.S | 94 +++++++++++++++++++++++++++++++++++++++ sys/conf/files | 1 - sys/conf/files.arm | 1 + sys/conf/files.arm64 | 1 + sys/conf/files.i386 | 1 + sys/conf/files.mips | 1 + sys/conf/files.powerpc | 1 + sys/conf/files.riscv | 1 + sys/conf/files.sparc64 | 1 + 9 files changed, 101 insertions(+), 1 deletion(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 7d580b67656a..6bc8c208c751 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -100,6 +100,100 @@ ENTRY(sse2_pagezero) ret END(sse2_pagezero) +/* + * memcmpy(b1, b2, len) + * rdi,rsi,len + */ +ENTRY(memcmp) + PUSH_FRAME_POINTER + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax + POP_FRAME_POINTER + ret +4: + subl %r8d,%eax + POP_FRAME_POINTER + ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 1b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 1b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 1b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b +END(memcmp) + /* * memmove(dst, src, cnt) * rdi, rsi, rdx diff --git a/sys/conf/files b/sys/conf/files index b2fcc65773e0..ee18125a034f 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4041,7 +4041,6 @@ libkern/murmur3_32.c standard libkern/mcount.c optional profiling-routine libkern/memcchr.c standard libkern/memchr.c standard -libkern/memcmp.c standard libkern/memmem.c optional gdb libkern/qsort.c standard libkern/qsort_r.c standard diff --git a/sys/conf/files.arm b/sys/conf/files.arm index 98d452a8f7ab..087f4c695fa1 100644 --- a/sys/conf/files.arm +++ b/sys/conf/files.arm @@ -163,6 +163,7 @@ libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/lshrdi3.c standard +libkern/memcmp.c standard libkern/moddi3.c standard libkern/qdivrem.c standard libkern/ucmpdi2.c standard diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 76e9e8e36479..010fbc7460c7 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -244,6 +244,7 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard +libkern/memcmp.c standard libkern/memset.c standard libkern/arm64/crc32c_armv8.S standard cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S optional zfs | dtrace compile-with "${CDDL_C}" diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index d2591137a990..f7a86cf5ee49 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -548,6 +548,7 @@ kern/subr_sfbuf.c standard libkern/divdi3.c standard libkern/ffsll.c standard libkern/flsll.c standard +libkern/memcmp.c standard libkern/memset.c standard libkern/moddi3.c standard libkern/qdivrem.c standard diff --git a/sys/conf/files.mips b/sys/conf/files.mips index 07448f44497c..1977fb9dcce2 100644 --- a/sys/conf/files.mips +++ b/sys/conf/files.mips @@ -65,6 +65,7 @@ libkern/cmpdi2.c optional mips | mipshf | mipsel | mipselhf libkern/ucmpdi2.c optional mips | mipshf | mipsel | mipselhf libkern/ashldi3.c standard libkern/ashrdi3.c standard +libkern/memcmp.c standard # cfe support dev/cfe/cfe_api.c optional cfe diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index d6df0c878641..faa057bfc882 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -98,6 +98,7 @@ libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard libkern/lshrdi3.c optional powerpc | powerpcspe +libkern/memcmp.c standard libkern/memset.c standard libkern/moddi3.c optional powerpc | powerpcspe libkern/qdivrem.c optional powerpc | powerpcspe diff --git a/sys/conf/files.riscv b/sys/conf/files.riscv index daba1826331b..8a70023eb91a 100644 --- a/sys/conf/files.riscv +++ b/sys/conf/files.riscv @@ -22,6 +22,7 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard +libkern/memcmp.c standard libkern/memset.c standard riscv/riscv/autoconf.c standard riscv/riscv/bus_machdep.c standard diff --git a/sys/conf/files.sparc64 b/sys/conf/files.sparc64 index 7d8cc3c5cb88..ed61aa49648e 100644 --- a/sys/conf/files.sparc64 +++ b/sys/conf/files.sparc64 @@ -71,6 +71,7 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard +libkern/memcmp.c standard sparc64/central/central.c optional central sparc64/ebus/ebus.c optional ebus sparc64/ebus/epic.c optional epic ebus From dcf55de22a9f2b6cd074c3c44915ff5c0b906dbb Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kib@FreeBSD.org> Date: Thu, 27 Sep 2018 14:31:41 +0000 Subject: [PATCH 130/139] Remove -m (update) from ldconfig -32 & -soft invocation on startup. Since r154114 which introduced ldconfig_local32_dirs, ldconfig -32 was called with -m. This means that ld-elf32.so.hints paths set is not cleared for compat32 on boot, unlike ld,so,hints. Same -m was used in r294295 for ld-elf-soft.so.hints on arm. The patch fixes the asymmetry. Noted by: Andreas Longwitz <longwitz@incore.de> Reviewed by: brooks, emaste, imp Discussed with: bdrewery Sponsored by: The FreeBSD Foundation Approved by: re (gjb) MFC after: 1 week Differential revision: https://reviews.freebsd.org/D17331 --- sbin/init/rc.d/ldconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbin/init/rc.d/ldconfig b/sbin/init/rc.d/ldconfig index 3af9562d3bfa..2d2bd143de73 100755 --- a/sbin/init/rc.d/ldconfig +++ b/sbin/init/rc.d/ldconfig @@ -58,7 +58,7 @@ ldconfig_start() done check_startmsgs && echo '32-bit compatibility ldconfig path:' ${_LDC} - ${ldconfig} -32 -m ${_ins} ${_LDC} + ${ldconfig} -32 ${_ins} ${_LDC} ;; esac @@ -80,7 +80,7 @@ ldconfig_start() done check_startmsgs && echo 'Soft Float compatibility ldconfig path:' ${_LDC} - ${ldconfig} -soft -m ${_ins} ${_LDC} + ${ldconfig} -soft ${_ins} ${_LDC} ;; esac From 9872237d214d880f07791656c0e0109155d32cce Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Thu, 27 Sep 2018 14:52:42 +0000 Subject: [PATCH 131/139] lib(4): Fix mdoc issues. - Fix "mandoc -Tlint" warnings. - Use the "Er" macro for errors. - Add an extra newline for readability. - Reference m_pullup(9) and m_defrag(9). - Use the "Fx" macro when talking about FreeBSD versions. Reviewed by: bcr Approved by: re (gjb), krion (mentor) Differential Revision: https://reviews.freebsd.org/D17270 --- share/man/man4/iflib.4 | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/share/man/man4/iflib.4 b/share/man/man4/iflib.4 index 2e99787b9cfd..ffd7c1153f59 100644 --- a/share/man/man4/iflib.4 +++ b/share/man/man4/iflib.4 @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd September 20, 2018 +.Dd September 27, 2018 .Dt IFLIB 4 .Os .Sh NAME @@ -24,7 +24,7 @@ These variables must be set before loading the driver, either via or through the use of .Xr kenv 1 . They are all prefixed by -.Va dev.X.Y.iflib. +.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 @@ -153,7 +153,8 @@ The transmit queue consumer index of the oldest descriptor to reclaim. 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 EFBIG. +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. @@ -168,12 +169,18 @@ Number of times both .Xr m_collapse 9 and .Xr m_defrag 9 -failed after an EFBIG error +failed after an +.Er EFBIG +error result from DMA mapping a transmit mbuf. .It Va m_pullups -Number of times m_pullup was called attempting to parse a header. +Number of times +.Xr m_pullup 9 +was called attempting to parse a header. .It Va mbuf_defrag -Number of times m_defrag was called. +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 @@ -187,9 +194,11 @@ Current receive ring consumer index. 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 11.0. +This framework was introduced in +.Fx 11.0 . From 0e59ecce47caa309cf35a0f8eb528931a124ec5c Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 27 Sep 2018 15:24:16 +0000 Subject: [PATCH 132/139] amd64: clean up copyin/copyout - move the PSL.AC comment to the fault handler - stop testing for zero-sized ops. after several minutes of package building there were no copyin calls with zero bytes and very few copyout. the semantic of returning 0 in this case is preserved - shorten exit paths by clearing %eax earlier - replace xchg with 3 movs. this is what compilers do. a naive benchmark on EPYC suggests about 1% increase in thoughput thanks to this change. - remove the useless movb %cl,%al from copyout. it looks like a leftover from many years ago Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17286 --- sys/amd64/amd64/support.S | 41 ++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 6bc8c208c751..7c52421dd847 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -404,10 +404,7 @@ END(fillw) .macro COPYOUT smap erms PUSH_FRAME_POINTER movq PCPU(CURPCB),%r9 - /* Trap entry clears PSL.AC */ movq $copy_fault,PCB_ONFAULT(%r9) - testq %rdx,%rdx /* anything to do? */ - jz 2f /* * Check explicitly for non-user addresses. If 486 write protection @@ -432,10 +429,20 @@ END(fillw) cmpq %rcx,%rax 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 @@ -447,17 +454,16 @@ END(fillw) andb $7,%cl jne 1f SMAP_ENABLE \smap - xorl %eax,%eax movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret .endif + ALIGN_TEXT 1: rep movsb + SMAP_ENABLE \smap -2: - xorl %eax,%eax movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret @@ -487,8 +493,6 @@ END(copyout_smap_erms) PUSH_FRAME_POINTER movq PCPU(CURPCB),%r9 movq $copy_fault,PCB_ONFAULT(%r9) - testq %rdx,%rdx /* anything to do? */ - jz 2f /* * make sure address is valid @@ -500,9 +504,12 @@ END(copyout_smap_erms) cmpq %rcx,%rax ja copy_fault - xchgq %rdi,%rsi + movq %rdi,%r8 + movq %rsi,%rdi + movq %r8,%rsi movq %rdx,%rcx - movb %cl,%al + + xorl %eax,%eax SMAP_DISABLE \smap .if \erms == 0 @@ -511,22 +518,20 @@ END(copyout_smap_erms) shrq $3,%rcx /* copy longword-wise */ rep movsq - movb %al,%cl + movb %dl,%cl andb $7,%cl /* copy remaining bytes */ jne 1f SMAP_ENABLE \smap - xorl %eax,%eax movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret .endif + ALIGN_TEXT 1: rep movsb SMAP_ENABLE \smap -2: - xorl %eax,%eax movq %rax,PCB_ONFAULT(%r9) POP_FRAME_POINTER ret @@ -549,9 +554,9 @@ ENTRY(copyin_smap_erms) END(copyin_smap_erms) ALIGN_TEXT + /* Trap entry clears PSL.AC */ copy_fault: - movq PCPU(CURPCB),%rdx - movq $0,PCB_ONFAULT(%rdx) + movq $0,PCB_ONFAULT(%r9) movl $EFAULT,%eax POP_FRAME_POINTER ret From 3d95cc51bbac0db3b512baba91c8cb75f409cfaf Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 27 Sep 2018 15:27:53 +0000 Subject: [PATCH 133/139] amd64: mostly depessimize copystr - remove a forward branch in the common case - replace xchg + lodsb/stosb loop with simple movs A simple test on Intel(R) Core(TM) i7-4600U CPU @ 2.10GH copying /foo/bar/baz in a loop goes from 295715863 ops/s to 465807408. Further changes are pending. Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17281 --- sys/amd64/amd64/support.S | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 7c52421dd847..9aeef2b0ebb3 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -1122,34 +1122,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) /* From e15e0e3e4db57e719c91b67180035f0bfc679d67 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" <bz@FreeBSD.org> Date: Thu, 27 Sep 2018 15:32:37 +0000 Subject: [PATCH 134/139] In in6_pcbpurgeif0() called, e.g., from if_clone_destroy(), once we have a lock, make sure the inp is not marked freed. This can happen since the list traversal and locking was converted to epoch(9). If the inp is marked "freed", skip it. This prevents a NULL pointer deref panic later on. Reported by: slavash (Mellanox) Tested by: slavash (Mellanox) Reviewed by: markj (no formal review but caught my unlock mistake) Approved by: re (kib) --- sys/netinet6/in6_pcb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index a9c73798b18c..b9d8e9e3187a 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -809,6 +809,10 @@ in6_pcbpurgeif0(struct inpcbinfo *pcbinfo, struct ifnet *ifp) INP_INFO_WLOCK(pcbinfo); CK_LIST_FOREACH(in6p, pcbinfo->ipi_listhead, inp_list) { INP_WLOCK(in6p); + if (__predict_false(in6p->inp_flags2 & INP_FREED)) { + INP_WUNLOCK(in6p); + continue; + } im6o = in6p->in6p_moptions; if ((in6p->inp_vflag & INP_IPV6) && im6o != NULL) { /* From 5910b876054c965c6e6ea9d8585721d5869cd9e5 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 27 Sep 2018 15:53:36 +0000 Subject: [PATCH 135/139] amd64: macroify and mostly depessimize copyinstr See r338968 for details. Reviewed by: kib Approved by: re (gjb) Differential Revision: https://reviews.freebsd.org/D17288 --- sys/amd64/amd64/support.S | 110 +++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 61 deletions(-) diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index 9aeef2b0ebb3..be92ff2d7234 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -1011,96 +1011,86 @@ fusufault: * 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 @@ -1109,11 +1099,9 @@ copyinstr_toolong: movq $VM_MAXUSER_ADDRESS,%rax cmpq %rax,%rsi jae cpystrflt - movq $ENAMETOOLONG,%rax + movl $ENAMETOOLONG,%eax jmp cpystrflt_x -END(copyinstr_smap) - /* * copystr(from, to, maxlen, int *lencopied) * %rdi, %rsi, %rdx, %rcx From 5bbde333cdbd9054fd9b4257a2a3e51d4a819ab4 Mon Sep 17 00:00:00 2001 From: Mateusz Guzik <mjg@FreeBSD.org> Date: Thu, 27 Sep 2018 17:08:29 +0000 Subject: [PATCH 136/139] amd64: reimplement libc memcmp and bcmp with kernel memcmp Both are significantly slower than hand-coded loops. See r338963 for kernel commit. bcmp differs from memcmp by always returning 1 when a difference is found, as opposed to going for a value bigger or lower than 0 depending on what it is. This means it can do less work. For now the code is duplicated and modified. This will get deduplicated after another round of optimization when memcmp will get a longer-term form. Both tested with the glibc suite. While the suite does not have a test for bcmp, I created a wrapper routine which verified that values match (0 vs 0, 1 vs non-zero). Reviewed by: kib Approved by: re (gjb) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D17336 --- lib/libc/amd64/string/bcmp.S | 132 +++++++++++++++++++++++++----- lib/libc/amd64/string/memcmp.S | 143 +++++++++++++++++++++++++-------- 2 files changed, 223 insertions(+), 52 deletions(-) diff --git a/lib/libc/amd64/string/bcmp.S b/lib/libc/amd64/string/bcmp.S index d01b76bc10e5..efdc6d33e4dd 100644 --- a/lib/libc/amd64/string/bcmp.S +++ b/lib/libc/amd64/string/bcmp.S @@ -1,27 +1,121 @@ +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Mateusz Guzik <mjg@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + #include <machine/asm.h> __FBSDID("$FreeBSD$"); -#if 0 - RCSID("$NetBSD: bcmp.S,v 1.1 2001/06/19 00:25:04 fvdl Exp $") -#endif - ENTRY(bcmp) - cld /* set compare direction forward */ - - movq %rdx,%rcx /* compare by words */ - shrq $3,%rcx - repe - cmpsq - jne L1 - - movq %rdx,%rcx /* compare remainder by bytes */ - andq $7,%rcx - repe - cmpsb -L1: - setne %al - movsbl %al,%eax + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax ret +4: + movl $1,%eax + ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 4b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 4b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 4b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b END(bcmp) .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/amd64/string/memcmp.S b/lib/libc/amd64/string/memcmp.S index 66d64a0b5a48..3012ffa688c2 100644 --- a/lib/libc/amd64/string/memcmp.S +++ b/lib/libc/amd64/string/memcmp.S @@ -1,44 +1,121 @@ -/* - * Written by J.T. Conklin <jtc@NetBSD.org>. - * Public domain. - * Adapted for NetBSD/x86_64 by Frank van der Linden <fvdl@wasabisystems.com> +/*- + * Copyright (c) 2018 The FreeBSD Foundation + * + * This software was developed by Mateusz Guzik <mjg@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ */ #include <machine/asm.h> __FBSDID("$FreeBSD$"); -#if 0 - RCSID("$NetBSD: memcmp.S,v 1.2 2003/07/26 19:24:39 salo Exp $") -#endif - ENTRY(memcmp) - cld /* set compare direction forward */ - movq %rdx,%rcx /* compare by longs */ - shrq $3,%rcx - repe - cmpsq - jne L5 /* do we match so far? */ - - movq %rdx,%rcx /* compare remainder by bytes */ - andq $7,%rcx - repe - cmpsb - jne L6 /* do we match? */ - - xorl %eax,%eax /* we match, return zero */ + cmpq $16,%rdx + jae 5f +1: + testq %rdx,%rdx + je 3f + xorl %ecx,%ecx +2: + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jz 3f + movzbl (%rdi,%rcx,1),%eax + movzbl (%rsi,%rcx,1),%r8d + cmpb %r8b,%al + jne 4f + addq $1,%rcx + cmpq %rcx,%rdx + jne 2b +3: + xorl %eax,%eax ret - -L5: movl $8,%ecx /* We know that one of the next */ - subq %rcx,%rdi /* eight pairs of bytes do not */ - subq %rcx,%rsi /* match. */ - repe - cmpsb -L6: xorl %eax,%eax /* Perform unsigned comparison */ - movb -1(%rdi),%al - xorl %edx,%edx - movb -1(%rsi),%dl - subl %edx,%eax +4: + subl %r8d,%eax ret +5: + cmpq $32,%rdx + jae 7f +6: + /* + * 8 bytes + */ + movq (%rdi),%r8 + movq (%rsi),%r9 + cmpq %r8,%r9 + jne 1b + leaq 8(%rdi),%rdi + leaq 8(%rsi),%rsi + subq $8,%rdx + cmpq $8,%rdx + jae 6b + jl 1b + jmp 3b +7: + /* + * 32 bytes + */ + movq (%rsi),%r8 + movq 8(%rsi),%r9 + subq (%rdi),%r8 + subq 8(%rdi),%r9 + or %r8,%r9 + jnz 1b + + movq 16(%rsi),%r8 + movq 24(%rsi),%r9 + subq 16(%rdi),%r8 + subq 24(%rdi),%r9 + or %r8,%r9 + jnz 1b + + leaq 32(%rdi),%rdi + leaq 32(%rsi),%rsi + subq $32,%rdx + cmpq $32,%rdx + jae 7b + jnz 1b + jmp 3b END(memcmp) .section .note.GNU-stack,"",%progbits From 83382d027f64411dc5ac57d25496e8c63d106297 Mon Sep 17 00:00:00 2001 From: John Baldwin <jhb@FreeBSD.org> Date: Thu, 27 Sep 2018 17:33:59 +0000 Subject: [PATCH 137/139] Don't clear DR6 for debug exceptions from userland. This reverts part of r333368. The attempt to clear DR6 was occuring too soon as trapsignal() does not pause to let the debugger notice the SIGTRAP and query DR6. The signal exchange does not occur until much later during ast(). As a result, GDB was no longer recognizing hardware breakpoints and watchpoints on x86. In addition, any userland programs that want to inspect DR6 in a SIGTRAP handler don't have a way to do this if we clear DR6 in the exception handler. Instead of relying on the kernel to clear DR6, debuggers will have to explicitly clear it after a trace trap (which they needed to do on older kernels anyway). Reviewed by: kib Approved by: re (delphij) MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D17319 --- sys/amd64/amd64/trap.c | 6 ------ sys/i386/i386/trap.c | 6 ------ 2 files changed, 12 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 72b9b3e78d96..1a8e5d23ff3a 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -659,12 +659,6 @@ trap(struct trapframe *frame) KASSERT((read_rflags() & PSL_I) != 0, ("interrupts disabled")); trapsignal(td, &ksi); - /* - * Clear any pending debug exceptions after allowing a - * debugger to read DR6 while stopped in trapsignal(). - */ - if (type == T_TRCTRAP) - load_dr6(0); userret: userret(td, frame); KASSERT(PCB_USER_FPU(td->td_pcb), diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 19086221b11b..4b62484533c4 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -762,12 +762,6 @@ trap(struct trapframe *frame) KASSERT((read_eflags() & PSL_I) != 0, ("interrupts disabled")); trapsignal(td, &ksi); - /* - * Clear any pending debug exceptions after allowing a - * debugger to read DR6 while stopped in trapsignal(). - */ - if (type == T_TRCTRAP) - load_dr6(0); user: userret(td, frame); KASSERT(PCB_USER_FPU(td->td_pcb), From c049e7c4481dd1b69ee481535fd992bdb329551c Mon Sep 17 00:00:00 2001 From: Guangyuan Yang <ygy@FreeBSD.org> Date: Thu, 27 Sep 2018 18:14:01 +0000 Subject: [PATCH 138/139] Add description, parameters, options, sysctl and examples of using AQMs to ipfw man page. CoDel, PIE, FQ-CoDel and FQ-PIE AQM for Dummynet exist in FreeBSD 11 and 10.3. Submitted by: ralsaadi@swin.edu.au Reviewed by: AllanJude Approved by: re (gjb) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D12507 --- sbin/ipfw/ipfw.8 | 429 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 426 insertions(+), 3 deletions(-) diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index 8364de827787..acb4d347644d 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 10, 2018 +.Dd September 27, 2018 .Dt IPFW 8 .Os .Sh NAME @@ -2711,7 +2711,7 @@ The following case-insensitive parameters can be configured for a scheduler: .Pp .Bl -tag -width indent -compact -.It Cm type Ar {fifo | wf2q+ | rr | qfq} +.It Cm type Ar {fifo | wf2q+ | rr | qfq | fq_codel | fq_pie} specifies the scheduling algorithm to use. .Bl -tag -width indent -compact .It Cm fifo @@ -2738,7 +2738,68 @@ with poor service guarantees. implements the QFQ algorithm, which is a very fast variant of WF2Q+, with similar service guarantees and O(1) processing costs (roughly, 200-250ns per packet). +.It Cm fq_codel +implements the FQ-CoDel (FlowQueue-CoDel) scheduler/AQM algorithm, which +uses a modified Deficit Round Robin scheduler to manage two lists of sub-queues +(old sub-queues and new sub-queues) for providing brief periods of priority to +lightweight or short burst flows. +By default, the total number of sub-queues is 1024. +FQ-CoDel's internal, dynamically +created sub-queues are controlled by separate instances of CoDel AQM. +.It Cm fq_pie +implements the FQ-PIE (FlowQueue-PIE) scheduler/AQM algorithm, which similar to +.Cm fq_codel +but uses per sub-queue PIE AQM instance to control the queue delay. .El +.Pp +.Cm fq_codel +inherits AQM parameters and options from +.Cm codel +(see below), and +.Cm fq_pie +inherits AQM parameters and options from +.Cm pie +(see below). +Additionally, both of +.Cm fq_codel +and +.Cm fq_pie +have shared scheduler parameters which are: +.Bl -tag -width indent +.It Cm quantum +.Ar m +specifies the quantum (credit) of the scheduler. +.Ar m +is the number of bytes a queue can serve before being moved to the tail +of old queues list. +The default is 1514 bytes, and the maximum accepable value +is 9000 bytes. +.It Cm limit +.Ar m +specifies the hard size limit (in unit of packets) of all queues managed by an +instance of the scheduler. +The default value of +.Ar m +is 10240 packets, and the maximum accepable value is 20480 packets. +.It Cm flows +.Ar m +specifies the total number of flow queues (sub-queues) that fq_* +creates and manages. +By default, 1024 sub-queues are created when an instance +of the fq_{codel/pie} scheduler is created. +The maximum accepable value is +65536. +.El +.Pp +Note that any token after +.Cm fq_codel +or +.Cm fq_pie +is considered a parameter for fq_{codel/pie}. +So, ensure all scheduler +configuration options not related to fq_{codel/pie} are written before +.Cm fq_codel/fq_pie +tokens. .El .Pp In addition to the type, all parameters allowed for a pipe can also @@ -2869,6 +2930,135 @@ greater than zero) specifies the expected maximum packet size, only used when queue thresholds are in bytes (defaults to 1500, must be greater than zero). .El +.Pp +.It Cm codel Oo Cm target Ar time Oc Oo Cm interval Ar time Oc Oo Cm ecn | +.Cm noecn Oc +Make use of the CoDel (Controlled-Delay) queue management algorithm. +.Ar time +is interpreted as milliseconds by default but seconds (s), milliseconds (ms) or +microseconds (us) can be specified instead. +CoDel drops or marks (ECN) packets +depending on packet sojourn time in the queue. +.Cm target +.Ar time +(5ms by default) is the minimum acceptable persistent queue delay that CoDel +allows. +CoDel does not drop packets directly after packets sojourn time becomes +higher than +.Cm target +.Ar time +but waits for +.Cm interval +.Ar time +(100ms default) before dropping. +.Cm interval +.Ar time +should be set to maximum RTT for all expected connections. +.Cm ecn +enables (disabled by default) packet marking (instead of dropping) for +ECN-enabled TCP flows when queue delay becomes high. +.Pp +Note that any token after +.Cm codel +is considered a parameter for CoDel. +So, ensure all pipe/queue +configuration options are written before +.Cm codel +token. +.Pp +The +.Xr sysctl 8 +variables +.Va net.inet.ip.dummynet.codel.target +and +.Va net.inet.ip.dummynet.codel.interval +can be used to set CoDel default parameters. +.Pp +.It Cm pie Oo Cm target Ar time Oc Oo Cm tupdate Ar time Oc Oo +.Cm alpha Ar n Oc Oo Cm beta Ar n Oc Oo Cm max_burst Ar time Oc Oo +.Cm max_ecnth Ar n Oc Oo Cm ecn | Cm noecn Oc Oo Cm capdrop | +.Cm nocapdrop Oc Oo Cm drand | Cm nodrand Oc Oo Cm onoff +.Oc Oo Cm dre | Cm ts Oc +Make use of the PIE (Proportional Integral controller Enhanced) queue management +algorithm. +PIE drops or marks packets depending on a calculated drop probability during +en-queue process, with the aim of achieving high throughput while keeping queue +delay low. +At regular time intervals of +.Cm tupdate +.Ar time +(15ms by default) a background process (re)calculates the probability based on queue delay +deviations from +.Cm target +.Ar time +(15ms by default) and queue delay trends. +PIE approximates current queue +delay by using a departure rate estimation method, or (optionally) by using a +packet timestamp method similar to CoDel. +.Ar time +is interpreted as milliseconds by default but seconds (s), milliseconds (ms) or +microseconds (us) can be specified instead. +The other PIE parameters and options are as follows: +.Bl -tag -width indent +.It Cm alpha Ar n +.Ar n +is a floating point number between 0 and 7 which specifies the weight of queue +delay deviations that is used in drop probability calculation. +0.125 is the default. +.It Cm beta Ar n +.Ar n +is a floating point number between 0 and 7 which specifies is the weight of queue +delay trend that is used in drop probability calculation. +1.25 is the default. +.It Cm max_burst Ar time +The maximum period of time that PIE does not drop/mark packets. +150ms is the +default and 10s is the maximum value. +.It Cm max_ecnth Ar n +Even when ECN is enabled, PIE drops packets instead of marking them when drop +probability becomes higher than ECN probability threshold +.Cm max_ecnth Ar n +, the default is 0.1 (i.e 10%) and 1 is the maximum value. +.It Cm ecn | noecn +enable or disable ECN marking for ECN-enabled TCP flows. +Disabled by default. +.It Cm capdrop | nocapdrop +enable or disable cap drop adjustment. +Cap drop adjustment is enabled by default. +.It Cm drand | nodrand +enable or disable drop probability de-randomisation. +De-randomisation eliminates +the problem of dropping packets too close or too far. +De-randomisation is enabled by default. +.It Cm onoff +enable turning PIE on and off depending on queue load. +If this option is enabled, +PIE turnes on when over 1/3 of queue becomes full. +This option is disabled by +default. +.It Cm dre | ts +Calculate queue delay using departure rate estimation +.Cm dre +or timestamps +.Cm ts . +.Cm dre +is used by default. +.El +.Pp +Note that any token after +.Cm pie +is considered a parameter for PIE. +So ensure all pipe/queue +the configuration options are written before +.Cm pie +token. +.Xr sysctl 8 +variables can be used to control the +.Cm pie +default parameters. +See the +.Sx SYSCTL VARIABLES +section for more details. .El .Pp When used with IPv6 data, @@ -3461,10 +3651,102 @@ global IP addresses, this will still result in a fully functional .It Va net.inet.ip.alias.sctp.up_timer: No 300 Timeout value to keep an association up with no traffic. This value cannot be 0. +.It Va net.inet.ip.dummynet.codel.interval : No 100000 +Default +.Cm codel +AQM interval in microseconds. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.codel.target : No 5000 +Default +.Cm codel +AQM target delay time in microseconds (the minimum acceptable persistent queue +delay). +The value must be in the range 1..5000000. .It Va net.inet.ip.dummynet.expire : No 1 Lazily delete dynamic pipes/queue once they have no pending traffic. You can disable this by setting the variable to 0, in which case the pipes/queues will only be deleted when the threshold is reached. +.It Va net.inet.ip.dummynet.fqcodel.flows : No 1024 +Defines the default total number of flow queues (sub-queues) that +.Cm fq_codel +creates and manages. +The value must be in the range 1..65536. +.It Va net.inet.ip.dummynet.fqcodel.interval : No 100000 +Default +.Cm fq_codel +scheduler/AQM interval in microseconds. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.fqcodel.limit : No 10240 +The default hard size limit (in unit of packet) of all queues managed by an +instance of the +.Cm fq_codel +scheduler. +The value must be in the range 1..20480. +.It Va net.inet.ip.dummynet.fqcodel.quantum : No 1514 +The default quantum (credit) of the +.Cm fq_codel +in unit of byte. +The value must be in the range 1..9000. +.It Va net.inet.ip.dummynet.fqcodel.target : No 5000 +Default +.Cm fq_codel +scheduler/AQM target delay time in microseconds (the minimum acceptable +persistent queue delay). +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.fqpie.alpha : No 125 +The default +.Ar alpha +parameter (scaled by 1000) for +.Cm fq_pie +scheduler/AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.fqpie.beta : No 1250 +The default +.Ar beta +parameter (scaled by 1000) for +.Cm fq_pie +scheduler/AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.fqpie.flows : No 1024 +Defines the default total number of flow queues (sub-queues) that +.Cm fq_pie +creates and manages. +The value must be in the range 1..65536. +.It Va net.inet.ip.dummynet.fqpie.limit : No 10240 +The default hard size limit (in unit of packet) of all queues managed by an +instance of the +.Cm fq_pie +scheduler. +The value must be in the range 1..20480. +.It Va net.inet.ip.dummynet.fqpie.max_burst : No 150000 +The default maximum period of microseconds that +.Cm fq_pie +scheduler/AQM does not drop/mark packets. +The value must be in the range 1..10000000. +.It Va net.inet.ip.dummynet.fqpie.max_ecnth : No 99 +The default maximum ECN probability threshold (scaled by 1000) for +.Cm fq_pie +scheduler/AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.fqpie.quantum : No 1514 +The default quantum (credit) of the +.Cm fq_pie +in unit of byte. +The value must be in the range 1..9000. +.It Va net.inet.ip.dummynet.fqpie.target : No 15000 +The default +.Cm target +delay of the +.Cm fq_pie +in unit of microsecond. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.fqpie.tupdate : No 15000 +The default +.Cm tupdate +of the +.Cm fq_pie +in unit of microsecond. +The value must be in the range 1..5000000. .It Va net.inet.ip.dummynet.hash_size : No 64 Default size of the hash table used for dynamic pipes/queues. This value is used when no @@ -3499,6 +3781,44 @@ will be expired even when .It Va net.inet.ip.dummynet.red_max_pkt_size : No 1500 Parameters used in the computations of the drop probability for the RED algorithm. +.It Va net.inet.ip.dummynet.pie.alpha : No 125 +The default +.Ar alpha +parameter (scaled by 1000) for +.Cm pie +AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.pie.beta : No 1250 +The default +.Ar beta +parameter (scaled by 1000) for +.Cm pie +AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.pie.max_burst : No 150000 +The default maximum period of microseconds that +.Cm pie +AQM does not drop/mark packets. +The value must be in the range 1..10000000. +.It Va net.inet.ip.dummynet.pie.max_ecnth : No 99 +The default maximum ECN probability threshold (scaled by 1000) for +.Cm pie +AQM. +The value must be in the range 1..7000. +.It Va net.inet.ip.dummynet.pie.target : No 15000 +The default +.Cm target +delay of +.Cm pie +AQM in unit of microsecond. +The value must be in the range 1..5000000. +.It Va net.inet.ip.dummynet.pie.tupdate : No 15000 +The default +.Cm tupdate +of +.Cm pie +AQM in unit of microsecond. +The value must be in the range 1..5000000. .It Va net.inet.ip.dummynet.pipe_byte_limit : No 1048576 .It Va net.inet.ip.dummynet.pipe_slot_limit : No 100 The maximum queue size that can be specified in bytes or packets. @@ -4029,6 +4349,102 @@ action, if it is not created yet. Later, this dynamic rule is used on way in by .Cm check-state rule. +.Ss CONFIGURING CODEL, PIE, FQ-CODEL and FQ-PIE AQM +.Cm codel +and +.Cm pie +AQM can be configured for +.Nm dummynet +.Cm pipe +or +.Cm queue. +.Pp +To configure a +.Cm pipe +with +.Cm codel +AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s +rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s codel" +.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any" +.Pp +To configure a +.Cm queue +with +.Cm codel +AQM using different configurations parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw queue 1 config pipe 1 codel target 8ms interval 160ms ecn" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +To configure a +.Cm pipe +with +.Cm pie +AQM using default configuration for traffic from 192.168.0.0/24 and 1Mbits/s +rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s pie" +.Dl "ipfw add 100 pipe 1 ip from 192.168.0.0/24 to any" +.Pp +To configure a +.Cm queue +with +.Cm pie +AQM using different configuration parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw queue 1 config pipe 1 pie target 20ms tupdate 30ms ecn" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +.Cm fq_codel +and +.Cm fq_pie +AQM can be configured for +.Nm dummynet +schedulers. +.Pp +To configure +.Cm fq_codel +scheduler using different configurations parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw sched 1 config pipe 1 type fq_codel" +.Dl "ipfw queue 1 config sched 1" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +To change +.Cm fq_codel +default configuration for a +.Cm sched +such as disable ECN and change the +.Ar target +to 10ms, we do: +.Pp +.Dl "ipfw sched 1 config pipe 1 type fq_codel target 10ms noecn" +.Pp +Similar to +.Cm fq_codel, +to configure +.Cm fq_pie +scheduler using different configurations parameters for traffic from +192.168.0.0/24 and 1Mbits/s rate limit, we do: +.Pp +.Dl "ipfw pipe 1 config bw 1mbits/s" +.Dl "ipfw sched 1 config pipe 1 type fq_pie" +.Dl "ipfw queue 1 config sched 1" +.Dl "ipfw add 100 queue 1 ip from 192.168.0.0/24 to any" +.Pp +The configurations of +.Cm fq_pie +.Cm sched +can be changed in a similar way as for +.Cm fq_codel .Sh SEE ALSO .Xr cpp 1 , .Xr m4 1 , @@ -4063,7 +4479,8 @@ was introduced in Summer 2002. .An Poul-Henning Kamp , .An Alex Nash , .An Archie Cobbs , -.An Luigi Rizzo . +.An Luigi Rizzo , +.An Rasool Al-Saadi . .Pp .An -nosplit API based upon code written by @@ -4098,6 +4515,12 @@ For further information visit: Delay profiles have been developed by Alessandro Cerri and Luigi Rizzo, supported by the European Commission within Projects Onelab and Onelab2. +.Pp +CoDel, PIE, FQ-CoDel and FQ-PIE AQM for Dummynet have been implemented by +.An The Centre for Advanced Internet Architectures (CAIA) +in 2016, supported by The Comcast Innovation Fund. +The primary developer is +Rasool Al-Saadi. .Sh BUGS The syntax has grown over the years and sometimes it might be confusing. Unfortunately, backward compatibility prevents cleaning up mistakes From 89f652d14937ac249cd3d79c0d3db49810a20d25 Mon Sep 17 00:00:00 2001 From: Gordon Tetlow <gordon@FreeBSD.org> Date: Thu, 27 Sep 2018 18:39:54 +0000 Subject: [PATCH 139/139] Clear stack allocated data structure to prevent kernel memory leak. Reported by: Thomas Barabosch, Fraunhofer FKIE Reviewed by: wes@ Approved by: re (implicit) Approved by: so Security: FreeBSD-EN-18:12.mem Security: CVE-2018-17155 --- sys/kern/kern_context.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/kern/kern_context.c b/sys/kern/kern_context.c index 5afb371bfb27..3bd5f31082ac 100644 --- a/sys/kern/kern_context.c +++ b/sys/kern/kern_context.c @@ -70,6 +70,7 @@ sys_getcontext(struct thread *td, struct getcontext_args *uap) if (uap->ucp == NULL) ret = EINVAL; else { + bzero(&uc, sizeof(ucontext_t)); get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); PROC_LOCK(td->td_proc); uc.uc_sigmask = td->td_sigmask; @@ -110,6 +111,7 @@ sys_swapcontext(struct thread *td, struct swapcontext_args *uap) if (uap->oucp == NULL || uap->ucp == NULL) ret = EINVAL; else { + bzero(&uc, sizeof(ucontext_t)); get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); bzero(uc.__spare__, sizeof(uc.__spare__)); PROC_LOCK(td->td_proc);