From 041e6eb1c5c9c50ec82679cd3e04d028997ecc4f Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sat, 18 Aug 2018 20:55:20 +0000 Subject: [PATCH 001/222] ls(1): Support other aliases for --color arguments used by GNU ls(1) These aliases are supported and documented in the man page. For now, they will not be mentioned in the error when an invalid argument is encountered, instead keeping that list to the shorter 'preferred' names of each argument. Reported by: rgrimes --- bin/ls/ls.1 | 22 +++++++++++++++++++++- bin/ls/ls.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/bin/ls/ls.1 b/bin/ls/ls.1 index 6f4303a349a1..dde947be9875 100644 --- a/bin/ls/ls.1 +++ b/bin/ls/ls.1 @@ -32,7 +32,7 @@ .\" @(#)ls.1 8.7 (Berkeley) 7/29/94 .\" $FreeBSD$ .\" -.Dd August 16, 2018 +.Dd August 18, 2018 .Dt LS 1 .Os .Sh NAME @@ -252,6 +252,26 @@ environment variable is set and not empty. .Pp .Cm never will disable color regardless of environment variables. +.Pp +For compatibility with GNU coreutils, +.Nm +supports +.Cm yes +or +.Cm force +as equivalent to +.Cm always , +.Cm no +or +.Cm none +as equivalent to +.Cm never , +and +.Cm tty +or +.Cm if-tty +as equivalent to +.Cm auto . .It Fl d Directories are listed as plain files (not searched recursively). .It Fl f diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 9a8e855176eb..19effce3d195 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -200,6 +200,30 @@ do_color(void) return (do_color_from_env()); } +static bool +do_color_always(const char *term) +{ + + return (strcmp(term, "always") == 0 || strcmp(term, "yes") == 0 || + strcmp(term, "force") == 0); +} + +static bool +do_color_never(const char *term) +{ + + return (strcmp(term, "never") == 0 || strcmp(term, "no") == 0 || + strcmp(term, "none") == 0); +} + +static bool +do_color_auto(const char *term) +{ + + return (strcmp(term, "auto") == 0 || strcmp(term, "tty") == 0 || + strcmp(term, "if-tty") == 0); +} + int main(int argc, char *argv[]) { @@ -406,11 +430,11 @@ main(int argc, char *argv[]) break; #ifdef COLORLS case COLOR_OPT: - if (optarg == NULL || strcmp(optarg, "always") == 0) + if (optarg == NULL || do_color_always(optarg)) colorflag = COLORFLAG_ALWAYS; - else if (strcmp(optarg, "auto") == 0) + else if (do_color_auto(optarg)) colorflag = COLORFLAG_AUTO; - else if (strcmp(optarg, "never") == 0) + else if (do_color_never(optarg)) colorflag = COLORFLAG_NEVER; else errx(2, "unsupported --color value '%s' (must be always, auto, or never)", From 517d0a9043bef8d4a4f1e69ca87465a2b7a0378e Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sat, 18 Aug 2018 21:03:19 +0000 Subject: [PATCH 002/222] ls(1): Gate the do_color_* definitions behind COLORLS Pointy hat to: me --- bin/ls/ls.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bin/ls/ls.c b/bin/ls/ls.c index 19effce3d195..3929dd47be5a 100644 --- a/bin/ls/ls.c +++ b/bin/ls/ls.c @@ -200,6 +200,7 @@ do_color(void) return (do_color_from_env()); } +#ifdef COLORLS static bool do_color_always(const char *term) { @@ -223,6 +224,7 @@ do_color_auto(const char *term) return (strcmp(term, "auto") == 0 || strcmp(term, "tty") == 0 || strcmp(term, "if-tty") == 0); } +#endif /* COLORLS */ int main(int argc, char *argv[]) From cc91864c26f6f024111a3d236a6fe7c8e85355ac Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sat, 18 Aug 2018 21:21:06 +0000 Subject: [PATCH 003/222] Revert -r337396. It is being replaced with a revised interface that resulted from testing and further reviews. --- sys/ufs/ffs/ffs_alloc.c | 112 +++++++++--------------------------- sys/ufs/ffs/ffs_balloc.c | 4 +- sys/ufs/ffs/ffs_extern.h | 19 +------ sys/ufs/ffs/ffs_inode.c | 47 +++------------ sys/ufs/ffs/ffs_snapshot.c | 6 +- sys/ufs/ffs/ffs_softdep.c | 113 +++++++++---------------------------- sys/ufs/ffs/ffs_vfsops.c | 3 - sys/ufs/ffs/softdep.h | 1 - sys/ufs/ufs/ufsmount.h | 4 -- 9 files changed, 67 insertions(+), 242 deletions(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 3101f618b059..1e1b4f1350a1 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -110,6 +110,8 @@ static ufs2_daddr_t static void ffs_blkfree_cg(struct ufsmount *, struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t, struct workhead *); +static void ffs_blkfree_trim_completed(struct buf *); +static void ffs_blkfree_trim_task(void *ctx, int pending __unused); #ifdef INVARIANTS static int ffs_checkblk(struct inode *, ufs2_daddr_t, long); #endif @@ -393,23 +395,8 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp) if (bno > 0) { bp->b_blkno = fsbtodb(fs, bno); if (!DOINGSOFTDEP(vp)) - /* - * The usual case is that a smaller fragment that - * was just allocated has been replaced with a bigger - * fragment or a full-size block. If it is marked as - * B_DELWRI, the current contents have not been written - * to disk. It is possible that the block was written - * earlier, but very uncommon. If the block has never - * been written, there is no need to send a BIO_DELETE - * for it when it is freed. The gain from avoiding the - * TRIMs for the common case of unwritten blocks far - * exceeds the cost of the write amplification for the - * uncommon case of failing to send a TRIM for a block - * that had been written. - */ ffs_blkfree(ump, fs, ump->um_devvp, bprev, (long)osize, - ip->i_number, vp->v_type, NULL, - (bp->b_flags & B_DELWRI) != 0 ? NOTRIM : SINGLETON); + ip->i_number, vp->v_type, NULL); delta = btodb(nsize - osize); DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta); if (flags & IO_EXT) @@ -534,7 +521,7 @@ ffs_reallocblks_ufs1(ap) struct fs *fs; struct inode *ip; struct vnode *vp; - struct buf *sbp, *ebp, *bp; + struct buf *sbp, *ebp; ufs1_daddr_t *bap, *sbap, *ebap; struct cluster_save *buflist; struct ufsmount *ump; @@ -743,29 +730,14 @@ ffs_reallocblks_ufs1(ap) printf("\n\tnew:"); #endif for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) { - bp = buflist->bs_children[i]; if (!DOINGSOFTDEP(vp)) - /* - * The usual case is that a set of N-contiguous blocks - * that was just allocated has been replaced with a - * set of N+1-contiguous blocks. If they are marked as - * B_DELWRI, the current contents have not been written - * to disk. It is possible that the blocks were written - * earlier, but very uncommon. If the blocks have never - * been written, there is no need to send a BIO_DELETE - * for them when they are freed. The gain from avoiding - * the TRIMs for the common case of unwritten blocks - * far exceeds the cost of the write amplification for - * the uncommon case of failing to send a TRIM for the - * blocks that had been written. - */ ffs_blkfree(ump, fs, ump->um_devvp, - dbtofsb(fs, bp->b_blkno), - fs->fs_bsize, ip->i_number, vp->v_type, NULL, - (bp->b_flags & B_DELWRI) != 0 ? NOTRIM : SINGLETON); - bp->b_blkno = fsbtodb(fs, blkno); + dbtofsb(fs, buflist->bs_children[i]->b_blkno), + fs->fs_bsize, ip->i_number, vp->v_type, NULL); + buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); #ifdef INVARIANTS - if (!ffs_checkblk(ip, dbtofsb(fs, bp->b_blkno), fs->fs_bsize)) + if (!ffs_checkblk(ip, + dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 3"); #endif #ifdef DEBUG @@ -799,7 +771,7 @@ ffs_reallocblks_ufs2(ap) struct fs *fs; struct inode *ip; struct vnode *vp; - struct buf *sbp, *ebp, *bp; + struct buf *sbp, *ebp; ufs2_daddr_t *bap, *sbap, *ebap; struct cluster_save *buflist; struct ufsmount *ump; @@ -1006,29 +978,14 @@ ffs_reallocblks_ufs2(ap) printf("\n\tnew:"); #endif for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) { - bp = buflist->bs_children[i]; if (!DOINGSOFTDEP(vp)) - /* - * The usual case is that a set of N-contiguous blocks - * that was just allocated has been replaced with a - * set of N+1-contiguous blocks. If they are marked as - * B_DELWRI, the current contents have not been written - * to disk. It is possible that the blocks were written - * earlier, but very uncommon. If the blocks have never - * been written, there is no need to send a BIO_DELETE - * for them when they are freed. The gain from avoiding - * the TRIMs for the common case of unwritten blocks - * far exceeds the cost of the write amplification for - * the uncommon case of failing to send a TRIM for the - * blocks that had been written. - */ ffs_blkfree(ump, fs, ump->um_devvp, - dbtofsb(fs, bp->b_blkno), - fs->fs_bsize, ip->i_number, vp->v_type, NULL, - (bp->b_flags & B_DELWRI) != 0 ? NOTRIM : SINGLETON); - bp->b_blkno = fsbtodb(fs, blkno); + dbtofsb(fs, buflist->bs_children[i]->b_blkno), + fs->fs_bsize, ip->i_number, vp->v_type, NULL); + buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); #ifdef INVARIANTS - if (!ffs_checkblk(ip, dbtofsb(fs, bp->b_blkno), fs->fs_bsize)) + if (!ffs_checkblk(ip, + dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 3"); #endif #ifdef DEBUG @@ -1866,7 +1823,8 @@ ffs_alloccgblk(ip, bp, bpref, size) /* XXX Fixme. */ UFS_UNLOCK(ump); if (DOINGSOFTDEP(ITOV(ip))) - softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno, size, 0); + softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno, + size, 0); UFS_LOCK(ump); return (blkno); } @@ -2296,17 +2254,6 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd) bdwrite(bp); } -/* - * Structures and routines associated with trim management. - */ -MALLOC_DEFINE(M_TRIM, "ufs_trim", "UFS trim structures"); - -#define TRIMLIST_HASH(ump, inum) \ - (&(ump)->um_trimhash[(inum) & (ump)->um_trimlisthashsize]) - -static void ffs_blkfree_trim_completed(struct buf *); -static void ffs_blkfree_trim_task(void *ctx, int pending __unused); - struct ffs_blkfree_trim_params { struct task task; struct ufsmount *ump; @@ -2330,7 +2277,7 @@ ffs_blkfree_trim_task(ctx, pending) tp->inum, tp->pdephd); vn_finished_secondary_write(UFSTOVFS(tp->ump)); atomic_add_int(&tp->ump->um_trim_inflight, -1); - free(tp, M_TRIM); + free(tp, M_TEMP); } static void @@ -2340,13 +2287,13 @@ ffs_blkfree_trim_completed(bp) struct ffs_blkfree_trim_params *tp; tp = bp->b_fsprivate1; - free(bp, M_TRIM); + free(bp, M_TEMP); TASK_INIT(&tp->task, 0, ffs_blkfree_trim_task, tp); taskqueue_enqueue(tp->ump->um_trim_tq, &tp->task); } void -ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, trimtype) +ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd) struct ufsmount *ump; struct fs *fs; struct vnode *devvp; @@ -2355,7 +2302,6 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, trimtype) ino_t inum; enum vtype vtype; struct workhead *dephd; - int trimtype; { struct mount *mp; struct buf *bp; @@ -2373,11 +2319,10 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, trimtype) return; } /* - * Nothing to delay if TRIM is not required for this block or TRIM - * is disabled or the operation is performed on a snapshot. + * Nothing to delay if TRIM is disabled, or the operation is + * performed on the snapshot. */ - if (trimtype == NOTRIM || ((ump->um_flags & UM_CANDELETE) == 0) || - devvp->v_type == VREG) { + if (((ump->um_flags) & UM_CANDELETE) == 0 || devvp->v_type == VREG) { ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd); return; } @@ -2389,7 +2334,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, trimtype) * and write some new data into it. */ atomic_add_int(&ump->um_trim_inflight, 1); - tp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TRIM, M_WAITOK); + tp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TEMP, M_WAITOK); tp->ump = ump; tp->devvp = devvp; tp->bno = bno; @@ -2402,7 +2347,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, trimtype) } else tp->pdephd = NULL; - bp = malloc(sizeof(*bp), M_TRIM, M_WAITOK | M_ZERO); + bp = malloc(sizeof(*bp), M_TEMP, M_WAITOK | M_ZERO); bp->b_iocmd = BIO_DELETE; bp->b_iooffset = dbtob(fsbtodb(fs, bno)); bp->b_iodone = ffs_blkfree_trim_completed; @@ -2879,7 +2824,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) long blkcnt, blksize; struct file *fp, *vfp; cap_rights_t rights; - int filetype, trimtype, error; + int filetype, error; static struct fileops *origops, bufferedops; if (req->newlen > sizeof cmd) @@ -3011,17 +2956,14 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) blkno = cmd.value; blkcnt = cmd.size; blksize = fs->fs_frag - (blkno % fs->fs_frag); - trimtype = (blksize < blkcnt) ? STARTFREE : SINGLETON; while (blkcnt > 0) { if (blksize > blkcnt) blksize = blkcnt; ffs_blkfree(ump, fs, ump->um_devvp, blkno, - blksize * fs->fs_fsize, UFS_ROOTINO, - VDIR, NULL, trimtype); + blksize * fs->fs_fsize, UFS_ROOTINO, VDIR, NULL); blkno += blksize; blkcnt -= blksize; blksize = fs->fs_frag; - trimtype = (blksize < blkcnt) ? CONTINUEFREE : ENDFREE; } break; diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index 552c295753d7..6143b4fca8c0 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -553,7 +553,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, lbns_remfree++; #endif ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize, - ip->i_number, vp->v_type, NULL, SINGLETON); + ip->i_number, vp->v_type, NULL); } return (error); } @@ -1147,7 +1147,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, lbns_remfree++; #endif ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize, - ip->i_number, vp->v_type, NULL, SINGLETON); + ip->i_number, vp->v_type, NULL); } return (error); } diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index e0a1a13c274f..2df48ec91de9 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -63,7 +63,7 @@ int ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size, struct ucred *a_cred, int a_flags, struct buf **a_bpp); int ffs_blkatoff(struct vnode *, off_t, char **, struct buf **); void ffs_blkfree(struct ufsmount *, struct fs *, struct vnode *, - ufs2_daddr_t, long, ino_t, enum vtype, struct workhead *, int); + ufs2_daddr_t, long, ino_t, enum vtype, struct workhead *); ufs2_daddr_t ffs_blkpref_ufs1(struct inode *, ufs_lbn_t, int, ufs1_daddr_t *); ufs2_daddr_t ffs_blkpref_ufs2(struct inode *, ufs_lbn_t, int, ufs2_daddr_t *); int ffs_checkfreefile(struct fs *, struct vnode *, ino_t); @@ -111,28 +111,11 @@ vfs_vget_t ffs_vget; int ffs_vgetf(struct mount *, ino_t, int, struct vnode **, int); void process_deferred_inactive(struct mount *mp); -/* - * Flags to ffs_vgetf - */ #define FFSV_FORCEINSMQ 0x0001 -/* - * Flags to ffs_reload - */ #define FFSR_FORCE 0x0001 #define FFSR_UNSUSPEND 0x0002 -/* - * Trim type to ffs_blkfree - used to help with BIO_DELETE (trim) requests - */ -#define NOTRIM 1 /* never written, so don't call trim for it */ -#define SINGLETON 2 /* only block being freed, so trim it now */ -#define STARTFREE 3 /* beginning to free for this inum */ -#define CONTINUEFREE 4 /* additional block free for this inum */ -#define ENDFREE 5 /* last block to free for this inum */ - -#define MAXTRIMIO 1024 /* maximum expected outstanding trim requests */ - extern struct vop_vector ffs_vnodeops1; extern struct vop_vector ffs_fifoops1; extern struct vop_vector ffs_vnodeops2; diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index 3cf58558c185..6a26ef97189a 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -195,7 +195,7 @@ ffs_truncate(vp, length, flags, cred) struct ufsmount *ump; int softdeptrunc, journaltrunc; int needextclean, extblocks; - int trimtype, firstfree, offset, size, level, nblocks; + int offset, size, level, nblocks; int i, error, allerror, indiroff, waitforupdate; off_t osize; @@ -275,7 +275,7 @@ ffs_truncate(vp, length, flags, cred) continue; ffs_blkfree(ump, fs, ITODEVVP(ip), oldblks[i], sblksize(fs, osize, i), ip->i_number, - vp->v_type, NULL, SINGLETON); + vp->v_type, NULL); } } } @@ -523,7 +523,7 @@ ffs_truncate(vp, length, flags, cred) DIP_SET(ip, i_ib[level], 0); ffs_blkfree(ump, fs, ump->um_devvp, bn, fs->fs_bsize, ip->i_number, - vp->v_type, NULL, SINGLETON); + vp->v_type, NULL); blocksreleased += nblocks; } } @@ -534,7 +534,6 @@ ffs_truncate(vp, length, flags, cred) /* * All whole direct blocks or frags. */ - firstfree = 1; for (i = UFS_NDADDR - 1; i > lastblock; i--) { long bsize; @@ -543,23 +542,8 @@ ffs_truncate(vp, length, flags, cred) continue; DIP_SET(ip, i_db[i], 0); bsize = blksize(fs, ip, i); - if (firstfree) { - if (i - 1 == lastblock || DIP(ip, i_db[i - 1]) == 0) { - trimtype = SINGLETON; - } else { - trimtype = STARTFREE; - firstfree = 0; - } - } else { - if (i - 1 == lastblock || DIP(ip, i_db[i - 1]) == 0) { - trimtype = ENDFREE; - firstfree = 1; - } else { - trimtype = CONTINUEFREE; - } - } ffs_blkfree(ump, fs, ump->um_devvp, bn, bsize, ip->i_number, - vp->v_type, NULL, trimtype); + vp->v_type, NULL); blocksreleased += btodb(bsize); } if (lastblock < 0) @@ -591,8 +575,7 @@ ffs_truncate(vp, length, flags, cred) */ bn += numfrags(fs, newspace); ffs_blkfree(ump, fs, ump->um_devvp, bn, - oldspace - newspace, ip->i_number, vp->v_type, - NULL, SINGLETON); + oldspace - newspace, ip->i_number, vp->v_type, NULL); blocksreleased += btodb(oldspace - newspace); } } @@ -653,7 +636,7 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) struct fs *fs; struct vnode *vp; caddr_t copy = NULL; - int i, trimtype, nblocks, firstfree, error = 0, allerror = 0; + int i, nblocks, error = 0, allerror = 0; ufs2_daddr_t nb, nlbn, last; ufs2_daddr_t blkcount, factor, blocksreleased = 0; ufs1_daddr_t *bap1 = NULL; @@ -736,7 +719,6 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) /* * Recursively free totally unused blocks. */ - firstfree = 1; for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; i--, nlbn += factor) { nb = BAP(ip, i); @@ -748,23 +730,8 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) allerror = error; blocksreleased += blkcount; } - if (firstfree) { - if (i - 1 == last || BAP(ip, i - 1) == 0) { - trimtype = SINGLETON; - } else { - trimtype = STARTFREE; - firstfree = 0; - } - } else { - if (i - 1 == last || BAP(ip, i - 1) == 0) { - trimtype = ENDFREE; - firstfree = 1; - } else { - trimtype = CONTINUEFREE; - } - } ffs_blkfree(ITOUMP(ip), fs, ITODEVVP(ip), nb, fs->fs_bsize, - ip->i_number, vp->v_type, NULL, trimtype); + ip->i_number, vp->v_type, NULL); blocksreleased += nblocks; } diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index e87e097177aa..fed0456b13cb 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -583,7 +583,7 @@ ffs_snapshot(mp, snapfile) if (len != 0 && len < fs->fs_bsize) { ffs_blkfree(ump, copy_fs, vp, DIP(xp, i_db[loc]), len, xp->i_number, - xvp->v_type, NULL, SINGLETON); + xvp->v_type, NULL); blkno = DIP(xp, i_db[loc]); DIP_SET(xp, i_db[loc], 0); } @@ -1265,7 +1265,7 @@ mapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (blkno == BLK_SNAP) blkno = blkstofrags(fs, lblkno); ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum, - vp->v_type, NULL, SINGLETON); + vp->v_type, NULL); } return (0); } @@ -1549,7 +1549,7 @@ mapacct_ufs2(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (blkno == BLK_SNAP) blkno = blkstofrags(fs, lblkno); ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum, - vp->v_type, NULL, SINGLETON); + vp->v_type, NULL); } return (0); } diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 6ddb8db12451..4943555198db 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -869,7 +869,7 @@ static void cancel_allocdirect(struct allocdirectlst *, struct allocdirect *, struct freeblks *); static int check_inode_unwritten(struct inodedep *); static int free_inodedep(struct inodedep *); -static void freework_freeblock(struct freework *, int); +static void freework_freeblock(struct freework *); static void freework_enqueue(struct freework *); static int handle_workitem_freeblocks(struct freeblks *, int); static int handle_complete_freeblocks(struct freeblks *, int); @@ -884,7 +884,7 @@ static struct allocindir *newallocindir(struct inode *, int, ufs2_daddr_t, ufs2_daddr_t, ufs_lbn_t); static void handle_workitem_freefrag(struct freefrag *); static struct freefrag *newfreefrag(struct inode *, ufs2_daddr_t, long, - ufs_lbn_t, int); + ufs_lbn_t); static void allocdirect_merge(struct allocdirectlst *, struct allocdirect *, struct allocdirect *); static struct freefrag *allocindir_merge(struct allocindir *, @@ -5289,22 +5289,7 @@ softdep_setup_allocdirect(ip, off, newblkno, oldblkno, newsize, oldsize, bp) KASSERT(MOUNTEDSOFTDEP(mp) != 0, ("softdep_setup_allocdirect called on non-softdep filesystem")); if (oldblkno && oldblkno != newblkno) - /* - * The usual case is that a smaller fragment that - * was just allocated has been replaced with a bigger - * fragment or a full-size block. If it is marked as - * B_DELWRI, the current contents have not been written - * to disk. It is possible that the block was written - * earlier, but very uncommon. If the block has never - * been written, there is no need to send a BIO_DELETE - * for it when it is freed. The gain from avoiding the - * TRIMs for the common case of unwritten blocks far - * exceeds the cost of the write amplification for the - * uncommon case of failing to send a TRIM for a block - * that had been written. - */ - freefrag = newfreefrag(ip, oldblkno, oldsize, lbn, - (bp->b_flags & B_DELWRI) != 0 ? NOTRIM : SINGLETON); + freefrag = newfreefrag(ip, oldblkno, oldsize, lbn); else freefrag = NULL; @@ -5581,12 +5566,11 @@ newjfreefrag(freefrag, ip, blkno, size, lbn) * Allocate a new freefrag structure. */ static struct freefrag * -newfreefrag(ip, blkno, size, lbn, trimtype) +newfreefrag(ip, blkno, size, lbn) struct inode *ip; ufs2_daddr_t blkno; long size; ufs_lbn_t lbn; - int trimtype; { struct freefrag *freefrag; struct ufsmount *ump; @@ -5607,7 +5591,6 @@ newfreefrag(ip, blkno, size, lbn, trimtype) freefrag->ff_vtype = ITOV(ip)->v_type; freefrag->ff_blkno = blkno; freefrag->ff_fragsize = size; - freefrag->ff_trimtype = trimtype; if (MOUNTEDSUJ(UFSTOVFS(ump))) { freefrag->ff_jdep = (struct worklist *) @@ -5653,8 +5636,7 @@ handle_workitem_freefrag(freefrag) } FREE_LOCK(ump); ffs_blkfree(ump, ump->um_fs, ump->um_devvp, freefrag->ff_blkno, - freefrag->ff_fragsize, freefrag->ff_inum, freefrag->ff_vtype, &wkhd, - freefrag->ff_trimtype); + freefrag->ff_fragsize, freefrag->ff_inum, freefrag->ff_vtype, &wkhd); ACQUIRE_LOCK(ump); WORKITEM_FREE(freefrag, D_FREEFRAG); FREE_LOCK(ump); @@ -5694,22 +5676,7 @@ softdep_setup_allocext(ip, off, newblkno, oldblkno, newsize, oldsize, bp) lbn = bp->b_lblkno; if (oldblkno && oldblkno != newblkno) - /* - * The usual case is that a smaller fragment that - * was just allocated has been replaced with a bigger - * fragment or a full-size block. If it is marked as - * B_DELWRI, the current contents have not been written - * to disk. It is possible that the block was written - * earlier, but very uncommon. If the block has never - * been written, there is no need to send a BIO_DELETE - * for it when it is freed. The gain from avoiding the - * TRIMs for the common case of unwritten blocks far - * exceeds the cost of the write amplification for the - * uncommon case of failing to send a TRIM for a block - * that had been written. - */ - freefrag = newfreefrag(ip, oldblkno, oldsize, lbn, - (bp->b_flags & B_DELWRI) != 0 ? NOTRIM : SINGLETON); + freefrag = newfreefrag(ip, oldblkno, oldsize, lbn); else freefrag = NULL; @@ -5822,8 +5789,7 @@ newallocindir(ip, ptrno, newblkno, oldblkno, lbn) struct jnewblk *jnewblk; if (oldblkno) - freefrag = newfreefrag(ip, oldblkno, ITOFS(ip)->fs_bsize, lbn, - SINGLETON); + freefrag = newfreefrag(ip, oldblkno, ITOFS(ip)->fs_bsize, lbn); else freefrag = NULL; ACQUIRE_LOCK(ITOUMP(ip)); @@ -7758,9 +7724,8 @@ free_inodedep(inodedep) * in memory immediately. */ static void -freework_freeblock(freework, trimtype) +freework_freeblock(freework) struct freework *freework; - int trimtype; { struct freeblks *freeblks; struct jnewblk *jnewblk; @@ -7814,10 +7779,10 @@ freework_freeblock(freework, trimtype) FREE_LOCK(ump); freeblks_free(ump, freeblks, btodb(bsize)); CTR4(KTR_SUJ, - "freework_freeblock: ino %jd blkno %jd lbn %jd size %d", + "freework_freeblock: ino %d blkno %jd lbn %jd size %ld", freeblks->fb_inum, freework->fw_blkno, freework->fw_lbn, bsize); ffs_blkfree(ump, fs, freeblks->fb_devvp, freework->fw_blkno, bsize, - freeblks->fb_inum, freeblks->fb_vtype, &wkhd, trimtype); + freeblks->fb_inum, freeblks->fb_vtype, &wkhd); ACQUIRE_LOCK(ump); /* * The jnewblk will be discarded and the bits in the map never @@ -7870,7 +7835,7 @@ handle_workitem_indirblk(freework) return; } if (freework->fw_off == NINDIR(fs)) { - freework_freeblock(freework, SINGLETON); + freework_freeblock(freework); return; } freework->fw_state |= INPROGRESS; @@ -7924,19 +7889,16 @@ handle_workitem_freeblocks(freeblks, flags) struct freeblks *freeblks; int flags; { - struct freework *freework, *prevfreework; + struct freework *freework; struct newblk *newblk; struct allocindir *aip; struct ufsmount *ump; struct worklist *wk; - int trimtype; KASSERT(LIST_EMPTY(&freeblks->fb_jblkdephd), ("handle_workitem_freeblocks: Journal entries not written.")); ump = VFSTOUFS(freeblks->fb_list.wk_mp); ACQUIRE_LOCK(ump); - prevfreework = NULL; - trimtype = 0; while ((wk = LIST_FIRST(&freeblks->fb_freeworkhd)) != NULL) { WORKLIST_REMOVE(wk); switch (wk->wk_type) { @@ -7970,26 +7932,16 @@ handle_workitem_freeblocks(freeblks, flags) case D_FREEWORK: freework = WK_FREEWORK(wk); - if (freework->fw_lbn <= -UFS_NDADDR) { + if (freework->fw_lbn <= -UFS_NDADDR) handle_workitem_indirblk(freework); - continue; - } else if (prevfreework == NULL) { - trimtype = SINGLETON; - } else if (trimtype == SINGLETON) { - freework_freeblock(prevfreework, STARTFREE); - trimtype = ENDFREE; - } else { - freework_freeblock(prevfreework, CONTINUEFREE); - } - prevfreework = freework; + else + freework_freeblock(freework); continue; default: panic("handle_workitem_freeblocks: Unknown type %s", TYPENAME(wk->wk_type)); } } - if (prevfreework != NULL) - freework_freeblock(prevfreework, trimtype); if (freeblks->fb_ref != 0) { freeblks->fb_state &= ~INPROGRESS; wake_worklist(&freeblks->fb_list); @@ -8128,8 +8080,13 @@ indir_trunc(freework, dbn, lbn) ufs1_daddr_t *bap1; ufs2_daddr_t nb, nnb, *bap2; ufs_lbn_t lbnadd, nlbn; - int nblocks, ufs1fmt, firstfree, trimtype, freedblocks; - int goingaway, freedeps, needj, level, cnt, i; + int i, nblocks, ufs1fmt; + int freedblocks; + int goingaway; + int freedeps; + int needj; + int level; + int cnt; freeblks = freework->fw_freeblks; ump = VFSTOUFS(freeblks->fb_list.wk_mp); @@ -8223,7 +8180,6 @@ indir_trunc(freework, dbn, lbn) * arranges for the current level to be freed when subordinates * are free when journaling. */ - firstfree = 1; for (i = freework->fw_off; i < NINDIR(fs); i++, nb = nnb) { if (i != NINDIR(fs) - 1) { if (ufs1fmt) @@ -8259,26 +8215,11 @@ indir_trunc(freework, dbn, lbn) freedeps++; } CTR3(KTR_SUJ, - "indir_trunc: ino %jd blkno %jd size %d", + "indir_trunc: ino %d blkno %jd size %ld", freeblks->fb_inum, nb, fs->fs_bsize); - if (firstfree) { - if (i == NINDIR(fs) - 1 || nnb == 0) { - trimtype = SINGLETON; - } else { - trimtype = STARTFREE; - firstfree = 0; - } - } else { - if (i == NINDIR(fs) - 1 || nnb == 0) { - trimtype = ENDFREE; - firstfree = 1; - } else { - trimtype = CONTINUEFREE; - } - } ffs_blkfree(ump, fs, freeblks->fb_devvp, nb, fs->fs_bsize, freeblks->fb_inum, - freeblks->fb_vtype, &wkhd, trimtype); + freeblks->fb_vtype, &wkhd); } } if (goingaway) { @@ -8303,7 +8244,7 @@ indir_trunc(freework, dbn, lbn) if (level == 0) freeblks->fb_cgwait += freedeps; if (freework->fw_ref == 0) - freework_freeblock(freework, SINGLETON); + freework_freeblock(freework); FREE_LOCK(ump); return; } @@ -8312,10 +8253,10 @@ indir_trunc(freework, dbn, lbn) */ dbn = dbtofsb(fs, dbn); CTR3(KTR_SUJ, - "indir_trunc 2: ino %jd blkno %jd size %d", + "indir_trunc 2: ino %d blkno %jd size %ld", freeblks->fb_inum, dbn, fs->fs_bsize); ffs_blkfree(ump, fs, freeblks->fb_devvp, dbn, fs->fs_bsize, - freeblks->fb_inum, freeblks->fb_vtype, NULL, SINGLETON); + freeblks->fb_inum, freeblks->fb_vtype, NULL); /* Non SUJ softdep does single-threaded truncations. */ if (freework->fw_blkno == dbn) { freework->fw_state |= ALLCOMPLETE; diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index e3927327c79c..9ed5c58f7b0e 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -978,8 +978,6 @@ ffs_mountfs(devvp, mp, td) taskqueue_thread_enqueue, &ump->um_trim_tq); taskqueue_start_threads(&ump->um_trim_tq, 1, PVFS, "%s trim", mp->mnt_stat.f_mntonname); - ump->um_trimhash = hashinit(MAXTRIMIO, M_TRIM, - &ump->um_trimlisthashsize); } } @@ -1258,7 +1256,6 @@ ffs_unmount(mp, mntflags) pause("ufsutr", hz); taskqueue_drain_all(ump->um_trim_tq); taskqueue_free(ump->um_trim_tq); - free (ump->um_trimhash, M_TRIM); } g_topology_lock(); if (ump->um_fsckpid > 0) { diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h index 5e1fa4ff3680..707429fe68c6 100644 --- a/sys/ufs/ffs/softdep.h +++ b/sys/ufs/ffs/softdep.h @@ -557,7 +557,6 @@ struct freefrag { long ff_fragsize; /* size of fragment being deleted */ ino_t ff_inum; /* owning inode number */ enum vtype ff_vtype; /* owning inode's file type */ - int ff_trimtype; /* trim status when deleted */ }; /* diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h index 2b6896013bd2..1958b02f6abb 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -47,7 +47,6 @@ struct ufs_args { #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_UFSMNT); -MALLOC_DECLARE(M_TRIM); #endif struct buf; @@ -64,7 +63,6 @@ struct inodedep; TAILQ_HEAD(inodedeplst, inodedep); LIST_HEAD(bmsafemaphd, bmsafemap); -LIST_HEAD(trimlist_hashhead, ffs_blkfree_trim_params); /* * This structure describes the UFS specific mount structure data. @@ -103,8 +101,6 @@ struct ufsmount { u_int um_flags; /* (i) filesystem flags */ u_int um_trim_inflight; /* (a) outstanding trim count */ struct taskqueue *um_trim_tq; /* (c) trim request queue */ - struct trimlist_hashhead *um_trimhash; /* (i) trimlist hash table */ - u_long um_trimlisthashsize; /* (i) trim hash table size-1 */ /* (c) - below function ptrs */ int (*um_balloc)(struct vnode *, off_t, int, struct ucred *, int, struct buf **); From db7c2a482248b83d7e325ffa36ce14d93ab78ad2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 18 Aug 2018 22:07:48 +0000 Subject: [PATCH 004/222] Eliminate the unused arena parameter from kmem_alloc_attr(). Reviewed by: kib, markj Differential Revision: https://reviews.freebsd.org/D16793 --- sys/dev/amd_ecc_inject/ecc_inject.c | 2 +- sys/dev/drm/drm_scatter.c | 4 ++-- sys/dev/drm2/drm_scatter.c | 4 ++-- sys/vm/vm_extern.h | 2 +- sys/vm/vm_init.c | 5 ++--- sys/vm/vm_kern.c | 7 ++----- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/sys/dev/amd_ecc_inject/ecc_inject.c b/sys/dev/amd_ecc_inject/ecc_inject.c index 0f7346e84103..a682115b08ae 100644 --- a/sys/dev/amd_ecc_inject/ecc_inject.c +++ b/sys/dev/amd_ecc_inject/ecc_inject.c @@ -186,7 +186,7 @@ ecc_ei_inject(int count) KASSERT(bit_mask != 0 && (bit_mask & ~INJ_VECTOR_MASK) == 0, ("bit mask value is outside of range: 0x%x", bit_mask)); - memory = kmem_alloc_attr(kernel_arena, PAGE_SIZE, M_WAITOK, 0, ~0, + memory = kmem_alloc_attr(PAGE_SIZE, M_WAITOK, 0, ~0, VM_MEMATTR_UNCACHEABLE); for (injected = 0; injected < count; injected++) { diff --git a/sys/dev/drm/drm_scatter.c b/sys/dev/drm/drm_scatter.c index c202475f3a88..163634878d93 100644 --- a/sys/dev/drm/drm_scatter.c +++ b/sys/dev/drm/drm_scatter.c @@ -52,8 +52,8 @@ drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather *request) entry->busaddr = malloc(entry->pages * sizeof(*entry->busaddr), DRM_MEM_SGLISTS, M_WAITOK | M_ZERO); - entry->vaddr = kmem_alloc_attr(kernel_arena, size, M_WAITOK | M_ZERO, - 0, BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); + entry->vaddr = kmem_alloc_attr(size, M_WAITOK | M_ZERO, 0, + BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); if (entry->vaddr == 0) { drm_sg_cleanup(entry); return (ENOMEM); diff --git a/sys/dev/drm2/drm_scatter.c b/sys/dev/drm2/drm_scatter.c index 6e69f0cdd727..510fce4cd6a4 100644 --- a/sys/dev/drm2/drm_scatter.c +++ b/sys/dev/drm2/drm_scatter.c @@ -37,8 +37,8 @@ __FBSDID("$FreeBSD$"); static inline vm_offset_t drm_vmalloc_dma(vm_size_t size) { - return kmem_alloc_attr(kernel_arena, size, M_NOWAIT | M_ZERO, - 0, BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); + return kmem_alloc_attr(size, M_NOWAIT | M_ZERO, 0, + BUS_SPACE_MAXADDR_32BIT, VM_MEMATTR_WRITE_COMBINING); } void drm_sg_cleanup(struct drm_sg_mem * entry) diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h index 60dd72af5e30..8de581b7e6df 100644 --- a/sys/vm/vm_extern.h +++ b/sys/vm/vm_extern.h @@ -54,7 +54,7 @@ vm_offset_t kmap_alloc_wait(vm_map_t, vm_size_t); void kmap_free_wakeup(vm_map_t, vm_offset_t, vm_size_t); /* These operate on virtual addresses backed by memory. */ -vm_offset_t kmem_alloc_attr(struct vmem *, vm_size_t size, int flags, +vm_offset_t kmem_alloc_attr(vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr); vm_offset_t kmem_alloc_attr_domain(int domain, vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, vm_memattr_t memattr); diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c index 0a1af123ddbc..00a7d9287413 100644 --- a/sys/vm/vm_init.c +++ b/sys/vm/vm_init.c @@ -274,9 +274,8 @@ vm_ksubmap_init(struct kva_md_info *kmi) * Try to protect 32-bit DMAable memory from the largest * early alloc of wired mem. */ - firstaddr = kmem_alloc_attr(kernel_arena, size, - M_ZERO | M_NOWAIT, (vm_paddr_t)1 << 32, - ~(vm_paddr_t)0, VM_MEMATTR_DEFAULT); + firstaddr = kmem_alloc_attr(size, M_ZERO | M_NOWAIT, + (vm_paddr_t)1 << 32, ~(vm_paddr_t)0, VM_MEMATTR_DEFAULT); if (firstaddr == 0) #endif firstaddr = kmem_malloc(kernel_arena, size, diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c index 73c23b805daa..17c681451612 100644 --- a/sys/vm/vm_kern.c +++ b/sys/vm/vm_kern.c @@ -220,16 +220,13 @@ kmem_alloc_attr_domain(int domain, vm_size_t size, int flags, vm_paddr_t low, } vm_offset_t -kmem_alloc_attr(vmem_t *vmem, vm_size_t size, int flags, vm_paddr_t low, - vm_paddr_t high, vm_memattr_t memattr) +kmem_alloc_attr(vm_size_t size, int flags, vm_paddr_t low, vm_paddr_t high, + vm_memattr_t memattr) { struct vm_domainset_iter di; vm_offset_t addr; int domain; - KASSERT(vmem == kernel_arena, - ("kmem_alloc_attr: Only kernel_arena is supported.")); - vm_domainset_iter_malloc_init(&di, kernel_object, &domain, &flags); do { addr = kmem_alloc_attr_domain(domain, size, flags, low, high, From 7e038bc257e9c5f7563695b88b481e493a33576f Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sat, 18 Aug 2018 22:21:59 +0000 Subject: [PATCH 005/222] Replace the TRIM consolodation framework originally added in -r337396 driven by problems found with the algorithms being tested for TRIM consolodation. Reported by: Peter Holm Suggested by: kib Reviewed by: kib Sponsored by: Netflix --- sys/ufs/ffs/ffs_alloc.c | 148 ++++++++++++++++++++++++++++++------- sys/ufs/ffs/ffs_balloc.c | 4 +- sys/ufs/ffs/ffs_extern.h | 20 ++++- sys/ufs/ffs/ffs_inode.c | 21 ++++-- sys/ufs/ffs/ffs_snapshot.c | 6 +- sys/ufs/ffs/ffs_softdep.c | 84 +++++++++++++++------ sys/ufs/ffs/ffs_vfsops.c | 3 + sys/ufs/ffs/softdep.h | 1 + sys/ufs/ufs/ufsmount.h | 10 ++- 9 files changed, 232 insertions(+), 65 deletions(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 1e1b4f1350a1..1267de701dec 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -110,8 +110,6 @@ static ufs2_daddr_t static void ffs_blkfree_cg(struct ufsmount *, struct fs *, struct vnode *, ufs2_daddr_t, long, ino_t, struct workhead *); -static void ffs_blkfree_trim_completed(struct buf *); -static void ffs_blkfree_trim_task(void *ctx, int pending __unused); #ifdef INVARIANTS static int ffs_checkblk(struct inode *, ufs2_daddr_t, long); #endif @@ -395,8 +393,24 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp) if (bno > 0) { bp->b_blkno = fsbtodb(fs, bno); if (!DOINGSOFTDEP(vp)) + /* + * The usual case is that a smaller fragment that + * was just allocated has been replaced with a bigger + * fragment or a full-size block. If it is marked as + * B_DELWRI, the current contents have not been written + * to disk. It is possible that the block was written + * earlier, but very uncommon. If the block has never + * been written, there is no need to send a BIO_DELETE + * for it when it is freed. The gain from avoiding the + * TRIMs for the common case of unwritten blocks far + * exceeds the cost of the write amplification for the + * uncommon case of failing to send a TRIM for a block + * that had been written. + */ ffs_blkfree(ump, fs, ump->um_devvp, bprev, (long)osize, - ip->i_number, vp->v_type, NULL); + ip->i_number, vp->v_type, NULL, + (bp->b_flags & B_DELWRI) != 0 ? + NOTRIM_KEY : SINGLETON_KEY); delta = btodb(nsize - osize); DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta); if (flags & IO_EXT) @@ -521,7 +535,7 @@ ffs_reallocblks_ufs1(ap) struct fs *fs; struct inode *ip; struct vnode *vp; - struct buf *sbp, *ebp; + struct buf *sbp, *ebp, *bp; ufs1_daddr_t *bap, *sbap, *ebap; struct cluster_save *buflist; struct ufsmount *ump; @@ -730,14 +744,30 @@ ffs_reallocblks_ufs1(ap) printf("\n\tnew:"); #endif for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) { + bp = buflist->bs_children[i]; if (!DOINGSOFTDEP(vp)) + /* + * The usual case is that a set of N-contiguous blocks + * that was just allocated has been replaced with a + * set of N+1-contiguous blocks. If they are marked as + * B_DELWRI, the current contents have not been written + * to disk. It is possible that the blocks were written + * earlier, but very uncommon. If the blocks have never + * been written, there is no need to send a BIO_DELETE + * for them when they are freed. The gain from avoiding + * the TRIMs for the common case of unwritten blocks + * far exceeds the cost of the write amplification for + * the uncommon case of failing to send a TRIM for the + * blocks that had been written. + */ ffs_blkfree(ump, fs, ump->um_devvp, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), - fs->fs_bsize, ip->i_number, vp->v_type, NULL); - buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); + dbtofsb(fs, bp->b_blkno), + fs->fs_bsize, ip->i_number, vp->v_type, NULL, + (bp->b_flags & B_DELWRI) != 0 ? + NOTRIM_KEY : SINGLETON_KEY); + bp->b_blkno = fsbtodb(fs, blkno); #ifdef INVARIANTS - if (!ffs_checkblk(ip, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) + if (!ffs_checkblk(ip, dbtofsb(fs, bp->b_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 3"); #endif #ifdef DEBUG @@ -771,7 +801,7 @@ ffs_reallocblks_ufs2(ap) struct fs *fs; struct inode *ip; struct vnode *vp; - struct buf *sbp, *ebp; + struct buf *sbp, *ebp, *bp; ufs2_daddr_t *bap, *sbap, *ebap; struct cluster_save *buflist; struct ufsmount *ump; @@ -978,14 +1008,30 @@ ffs_reallocblks_ufs2(ap) printf("\n\tnew:"); #endif for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) { + bp = buflist->bs_children[i]; if (!DOINGSOFTDEP(vp)) + /* + * The usual case is that a set of N-contiguous blocks + * that was just allocated has been replaced with a + * set of N+1-contiguous blocks. If they are marked as + * B_DELWRI, the current contents have not been written + * to disk. It is possible that the blocks were written + * earlier, but very uncommon. If the blocks have never + * been written, there is no need to send a BIO_DELETE + * for them when they are freed. The gain from avoiding + * the TRIMs for the common case of unwritten blocks + * far exceeds the cost of the write amplification for + * the uncommon case of failing to send a TRIM for the + * blocks that had been written. + */ ffs_blkfree(ump, fs, ump->um_devvp, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), - fs->fs_bsize, ip->i_number, vp->v_type, NULL); - buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno); + dbtofsb(fs, bp->b_blkno), + fs->fs_bsize, ip->i_number, vp->v_type, NULL, + (bp->b_flags & B_DELWRI) != 0 ? + NOTRIM_KEY : SINGLETON_KEY); + bp->b_blkno = fsbtodb(fs, blkno); #ifdef INVARIANTS - if (!ffs_checkblk(ip, - dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize)) + if (!ffs_checkblk(ip, dbtofsb(fs, bp->b_blkno), fs->fs_bsize)) panic("ffs_reallocblks: unallocated block 3"); #endif #ifdef DEBUG @@ -1823,8 +1869,7 @@ ffs_alloccgblk(ip, bp, bpref, size) /* XXX Fixme. */ UFS_UNLOCK(ump); if (DOINGSOFTDEP(ITOV(ip))) - softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno, - size, 0); + softdep_setup_blkmapdep(bp, UFSTOVFS(ump), blkno, size, 0); UFS_LOCK(ump); return (blkno); } @@ -2254,6 +2299,17 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd) bdwrite(bp); } +/* + * Structures and routines associated with trim management. + */ +MALLOC_DEFINE(M_TRIM, "ufs_trim", "UFS trim structures"); + +#define TRIMLIST_HASH(ump, key) \ + (&(ump)->um_trimhash[(key) & (ump)->um_trimlisthashsize]) + +static void ffs_blkfree_trim_completed(struct buf *); +static void ffs_blkfree_trim_task(void *ctx, int pending __unused); + struct ffs_blkfree_trim_params { struct task task; struct ufsmount *ump; @@ -2277,7 +2333,7 @@ ffs_blkfree_trim_task(ctx, pending) tp->inum, tp->pdephd); vn_finished_secondary_write(UFSTOVFS(tp->ump)); atomic_add_int(&tp->ump->um_trim_inflight, -1); - free(tp, M_TEMP); + free(tp, M_TRIM); } static void @@ -2287,13 +2343,45 @@ ffs_blkfree_trim_completed(bp) struct ffs_blkfree_trim_params *tp; tp = bp->b_fsprivate1; - free(bp, M_TEMP); + free(bp, M_TRIM); TASK_INIT(&tp->task, 0, ffs_blkfree_trim_task, tp); taskqueue_enqueue(tp->ump->um_trim_tq, &tp->task); } +/* + * Allocate a new key to use to identify a range of blocks. + */ +u_long +ffs_blkrelease_start(ump, devvp, inum) + struct ufsmount *ump; + struct vnode *devvp; + ino_t inum; +{ + static u_long masterkey; + u_long key; + + if ((ump->um_flags & UM_CANDELETE) == 0) + return (SINGLETON_KEY); + do { + key = atomic_fetchadd_long(&masterkey, 1); + } while (key < FIRST_VALID_KEY); + return (key); +} + +/* + * Deallocate a key that has been used to identify a range of blocks. + */ void -ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd) +ffs_blkrelease_finish(ump, key) + struct ufsmount *ump; + u_long key; +{ + + return; +} + +void +ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, key) struct ufsmount *ump; struct fs *fs; struct vnode *devvp; @@ -2302,6 +2390,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd) ino_t inum; enum vtype vtype; struct workhead *dephd; + u_long key; { struct mount *mp; struct buf *bp; @@ -2319,10 +2408,11 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd) return; } /* - * Nothing to delay if TRIM is disabled, or the operation is - * performed on the snapshot. + * Nothing to delay if TRIM is not required for this block or TRIM + * is disabled or the operation is performed on a snapshot. */ - if (((ump->um_flags) & UM_CANDELETE) == 0 || devvp->v_type == VREG) { + if (key == NOTRIM_KEY || ((ump->um_flags & UM_CANDELETE) == 0) || + devvp->v_type == VREG) { ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd); return; } @@ -2334,7 +2424,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd) * and write some new data into it. */ atomic_add_int(&ump->um_trim_inflight, 1); - tp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TEMP, M_WAITOK); + tp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TRIM, M_WAITOK); tp->ump = ump; tp->devvp = devvp; tp->bno = bno; @@ -2347,7 +2437,7 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd) } else tp->pdephd = NULL; - bp = malloc(sizeof(*bp), M_TEMP, M_WAITOK | M_ZERO); + bp = malloc(sizeof(*bp), M_TRIM, M_WAITOK | M_ZERO); bp->b_iocmd = BIO_DELETE; bp->b_iooffset = dbtob(fsbtodb(fs, bno)); bp->b_iodone = ffs_blkfree_trim_completed; @@ -2822,6 +2912,7 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) struct fs *fs; ufs2_daddr_t blkno; long blkcnt, blksize; + u_long key; struct file *fp, *vfp; cap_rights_t rights; int filetype, error; @@ -2956,15 +3047,18 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) blkno = cmd.value; blkcnt = cmd.size; blksize = fs->fs_frag - (blkno % fs->fs_frag); + key = ffs_blkrelease_start(ump, ump->um_devvp, UFS_ROOTINO); while (blkcnt > 0) { - if (blksize > blkcnt) + if (blkcnt < blksize) blksize = blkcnt; ffs_blkfree(ump, fs, ump->um_devvp, blkno, - blksize * fs->fs_fsize, UFS_ROOTINO, VDIR, NULL); + blksize * fs->fs_fsize, UFS_ROOTINO, + VDIR, NULL, key); blkno += blksize; blkcnt -= blksize; blksize = fs->fs_frag; } + ffs_blkrelease_finish(ump, key); break; /* diff --git a/sys/ufs/ffs/ffs_balloc.c b/sys/ufs/ffs/ffs_balloc.c index 6143b4fca8c0..ad41f316000a 100644 --- a/sys/ufs/ffs/ffs_balloc.c +++ b/sys/ufs/ffs/ffs_balloc.c @@ -553,7 +553,7 @@ ffs_balloc_ufs1(struct vnode *vp, off_t startoffset, int size, lbns_remfree++; #endif ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize, - ip->i_number, vp->v_type, NULL); + ip->i_number, vp->v_type, NULL, SINGLETON_KEY); } return (error); } @@ -1147,7 +1147,7 @@ ffs_balloc_ufs2(struct vnode *vp, off_t startoffset, int size, lbns_remfree++; #endif ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize, - ip->i_number, vp->v_type, NULL); + ip->i_number, vp->v_type, NULL, SINGLETON_KEY); } return (error); } diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index 2df48ec91de9..6b8e708f7371 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -63,9 +63,11 @@ int ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size, struct ucred *a_cred, int a_flags, struct buf **a_bpp); int ffs_blkatoff(struct vnode *, off_t, char **, struct buf **); void ffs_blkfree(struct ufsmount *, struct fs *, struct vnode *, - ufs2_daddr_t, long, ino_t, enum vtype, struct workhead *); + ufs2_daddr_t, long, ino_t, enum vtype, struct workhead *, u_long); ufs2_daddr_t ffs_blkpref_ufs1(struct inode *, ufs_lbn_t, int, ufs1_daddr_t *); ufs2_daddr_t ffs_blkpref_ufs2(struct inode *, ufs_lbn_t, int, ufs2_daddr_t *); +void ffs_blkrelease_finish(struct ufsmount *, u_long); +u_long ffs_blkrelease_start(struct ufsmount *, struct vnode *, ino_t); int ffs_checkfreefile(struct fs *, struct vnode *, ino_t); void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t); void ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int); @@ -111,11 +113,27 @@ vfs_vget_t ffs_vget; int ffs_vgetf(struct mount *, ino_t, int, struct vnode **, int); void process_deferred_inactive(struct mount *mp); +/* + * Flags to ffs_vgetf + */ #define FFSV_FORCEINSMQ 0x0001 +/* + * Flags to ffs_reload + */ #define FFSR_FORCE 0x0001 #define FFSR_UNSUSPEND 0x0002 +/* + * Definitions for TRIM interface + * + * Special keys and recommended hash table size + */ +#define NOTRIM_KEY 1 /* never written, so don't call trim for it */ +#define SINGLETON_KEY 2 /* only block being freed, so trim it now */ +#define FIRST_VALID_KEY 3 /* first valid key describing a block range */ +#define MAXTRIMIO 1024 /* maximum expected outstanding trim requests */ + extern struct vop_vector ffs_vnodeops1; extern struct vop_vector ffs_fifoops1; extern struct vop_vector ffs_vnodeops2; diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index 6a26ef97189a..0ec662179880 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -197,6 +197,7 @@ ffs_truncate(vp, length, flags, cred) int needextclean, extblocks; int offset, size, level, nblocks; int i, error, allerror, indiroff, waitforupdate; + u_long key; off_t osize; ip = VTOI(vp); @@ -275,7 +276,7 @@ ffs_truncate(vp, length, flags, cred) continue; ffs_blkfree(ump, fs, ITODEVVP(ip), oldblks[i], sblksize(fs, osize, i), ip->i_number, - vp->v_type, NULL); + vp->v_type, NULL, SINGLETON_KEY); } } } @@ -523,7 +524,7 @@ ffs_truncate(vp, length, flags, cred) DIP_SET(ip, i_ib[level], 0); ffs_blkfree(ump, fs, ump->um_devvp, bn, fs->fs_bsize, ip->i_number, - vp->v_type, NULL); + vp->v_type, NULL, SINGLETON_KEY); blocksreleased += nblocks; } } @@ -534,6 +535,7 @@ ffs_truncate(vp, length, flags, cred) /* * All whole direct blocks or frags. */ + key = ffs_blkrelease_start(ump, ump->um_devvp, ip->i_number); for (i = UFS_NDADDR - 1; i > lastblock; i--) { long bsize; @@ -543,9 +545,10 @@ ffs_truncate(vp, length, flags, cred) DIP_SET(ip, i_db[i], 0); bsize = blksize(fs, ip, i); ffs_blkfree(ump, fs, ump->um_devvp, bn, bsize, ip->i_number, - vp->v_type, NULL); + vp->v_type, NULL, key); blocksreleased += btodb(bsize); } + ffs_blkrelease_finish(ump, key); if (lastblock < 0) goto done; @@ -575,7 +578,8 @@ ffs_truncate(vp, length, flags, cred) */ bn += numfrags(fs, newspace); ffs_blkfree(ump, fs, ump->um_devvp, bn, - oldspace - newspace, ip->i_number, vp->v_type, NULL); + oldspace - newspace, ip->i_number, vp->v_type, + NULL, SINGLETON_KEY); blocksreleased += btodb(oldspace - newspace); } } @@ -634,8 +638,10 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) { struct buf *bp; struct fs *fs; + struct ufsmount *ump; struct vnode *vp; caddr_t copy = NULL; + u_long key; int i, nblocks, error = 0, allerror = 0; ufs2_daddr_t nb, nlbn, last; ufs2_daddr_t blkcount, factor, blocksreleased = 0; @@ -644,6 +650,7 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) #define BAP(ip, i) (I_IS_UFS1(ip) ? bap1[i] : bap2[i]) fs = ITOFS(ip); + ump = ITOUMP(ip); /* * Calculate index in current block of last @@ -719,6 +726,7 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) /* * Recursively free totally unused blocks. */ + key = ffs_blkrelease_start(ump, ITODEVVP(ip), ip->i_number); for (i = NINDIR(fs) - 1, nlbn = lbn + 1 - i * factor; i > last; i--, nlbn += factor) { nb = BAP(ip, i); @@ -730,10 +738,11 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp) allerror = error; blocksreleased += blkcount; } - ffs_blkfree(ITOUMP(ip), fs, ITODEVVP(ip), nb, fs->fs_bsize, - ip->i_number, vp->v_type, NULL); + ffs_blkfree(ump, fs, ITODEVVP(ip), nb, fs->fs_bsize, + ip->i_number, vp->v_type, NULL, key); blocksreleased += nblocks; } + ffs_blkrelease_finish(ump, key); /* * Recursively free last partial block. diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c index fed0456b13cb..4453c59517df 100644 --- a/sys/ufs/ffs/ffs_snapshot.c +++ b/sys/ufs/ffs/ffs_snapshot.c @@ -583,7 +583,7 @@ ffs_snapshot(mp, snapfile) if (len != 0 && len < fs->fs_bsize) { ffs_blkfree(ump, copy_fs, vp, DIP(xp, i_db[loc]), len, xp->i_number, - xvp->v_type, NULL); + xvp->v_type, NULL, SINGLETON_KEY); blkno = DIP(xp, i_db[loc]); DIP_SET(xp, i_db[loc], 0); } @@ -1265,7 +1265,7 @@ mapacct_ufs1(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (blkno == BLK_SNAP) blkno = blkstofrags(fs, lblkno); ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum, - vp->v_type, NULL); + vp->v_type, NULL, SINGLETON_KEY); } return (0); } @@ -1549,7 +1549,7 @@ mapacct_ufs2(vp, oldblkp, lastblkp, fs, lblkno, expungetype) if (blkno == BLK_SNAP) blkno = blkstofrags(fs, lblkno); ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum, - vp->v_type, NULL); + vp->v_type, NULL, SINGLETON_KEY); } return (0); } diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 4943555198db..89d0b7382e4d 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -869,7 +869,7 @@ static void cancel_allocdirect(struct allocdirectlst *, struct allocdirect *, struct freeblks *); static int check_inode_unwritten(struct inodedep *); static int free_inodedep(struct inodedep *); -static void freework_freeblock(struct freework *); +static void freework_freeblock(struct freework *, u_long); static void freework_enqueue(struct freework *); static int handle_workitem_freeblocks(struct freeblks *, int); static int handle_complete_freeblocks(struct freeblks *, int); @@ -884,7 +884,7 @@ static struct allocindir *newallocindir(struct inode *, int, ufs2_daddr_t, ufs2_daddr_t, ufs_lbn_t); static void handle_workitem_freefrag(struct freefrag *); static struct freefrag *newfreefrag(struct inode *, ufs2_daddr_t, long, - ufs_lbn_t); + ufs_lbn_t, u_long); static void allocdirect_merge(struct allocdirectlst *, struct allocdirect *, struct allocdirect *); static struct freefrag *allocindir_merge(struct allocindir *, @@ -5289,7 +5289,22 @@ softdep_setup_allocdirect(ip, off, newblkno, oldblkno, newsize, oldsize, bp) KASSERT(MOUNTEDSOFTDEP(mp) != 0, ("softdep_setup_allocdirect called on non-softdep filesystem")); if (oldblkno && oldblkno != newblkno) - freefrag = newfreefrag(ip, oldblkno, oldsize, lbn); + /* + * The usual case is that a smaller fragment that + * was just allocated has been replaced with a bigger + * fragment or a full-size block. If it is marked as + * B_DELWRI, the current contents have not been written + * to disk. It is possible that the block was written + * earlier, but very uncommon. If the block has never + * been written, there is no need to send a BIO_DELETE + * for it when it is freed. The gain from avoiding the + * TRIMs for the common case of unwritten blocks far + * exceeds the cost of the write amplification for the + * uncommon case of failing to send a TRIM for a block + * that had been written. + */ + freefrag = newfreefrag(ip, oldblkno, oldsize, lbn, + (bp->b_flags & B_DELWRI) != 0 ? NOTRIM_KEY : SINGLETON_KEY); else freefrag = NULL; @@ -5566,11 +5581,12 @@ newjfreefrag(freefrag, ip, blkno, size, lbn) * Allocate a new freefrag structure. */ static struct freefrag * -newfreefrag(ip, blkno, size, lbn) +newfreefrag(ip, blkno, size, lbn, key) struct inode *ip; ufs2_daddr_t blkno; long size; ufs_lbn_t lbn; + u_long key; { struct freefrag *freefrag; struct ufsmount *ump; @@ -5591,6 +5607,7 @@ newfreefrag(ip, blkno, size, lbn) freefrag->ff_vtype = ITOV(ip)->v_type; freefrag->ff_blkno = blkno; freefrag->ff_fragsize = size; + freefrag->ff_key = key; if (MOUNTEDSUJ(UFSTOVFS(ump))) { freefrag->ff_jdep = (struct worklist *) @@ -5636,7 +5653,8 @@ handle_workitem_freefrag(freefrag) } FREE_LOCK(ump); ffs_blkfree(ump, ump->um_fs, ump->um_devvp, freefrag->ff_blkno, - freefrag->ff_fragsize, freefrag->ff_inum, freefrag->ff_vtype, &wkhd); + freefrag->ff_fragsize, freefrag->ff_inum, freefrag->ff_vtype, + &wkhd, freefrag->ff_key); ACQUIRE_LOCK(ump); WORKITEM_FREE(freefrag, D_FREEFRAG); FREE_LOCK(ump); @@ -5676,7 +5694,22 @@ softdep_setup_allocext(ip, off, newblkno, oldblkno, newsize, oldsize, bp) lbn = bp->b_lblkno; if (oldblkno && oldblkno != newblkno) - freefrag = newfreefrag(ip, oldblkno, oldsize, lbn); + /* + * The usual case is that a smaller fragment that + * was just allocated has been replaced with a bigger + * fragment or a full-size block. If it is marked as + * B_DELWRI, the current contents have not been written + * to disk. It is possible that the block was written + * earlier, but very uncommon. If the block has never + * been written, there is no need to send a BIO_DELETE + * for it when it is freed. The gain from avoiding the + * TRIMs for the common case of unwritten blocks far + * exceeds the cost of the write amplification for the + * uncommon case of failing to send a TRIM for a block + * that had been written. + */ + freefrag = newfreefrag(ip, oldblkno, oldsize, lbn, + (bp->b_flags & B_DELWRI) != 0 ? NOTRIM_KEY : SINGLETON_KEY); else freefrag = NULL; @@ -5789,7 +5822,8 @@ newallocindir(ip, ptrno, newblkno, oldblkno, lbn) struct jnewblk *jnewblk; if (oldblkno) - freefrag = newfreefrag(ip, oldblkno, ITOFS(ip)->fs_bsize, lbn); + freefrag = newfreefrag(ip, oldblkno, ITOFS(ip)->fs_bsize, lbn, + SINGLETON_KEY); else freefrag = NULL; ACQUIRE_LOCK(ITOUMP(ip)); @@ -7724,8 +7758,9 @@ free_inodedep(inodedep) * in memory immediately. */ static void -freework_freeblock(freework) +freework_freeblock(freework, key) struct freework *freework; + u_long key; { struct freeblks *freeblks; struct jnewblk *jnewblk; @@ -7779,10 +7814,10 @@ freework_freeblock(freework) FREE_LOCK(ump); freeblks_free(ump, freeblks, btodb(bsize)); CTR4(KTR_SUJ, - "freework_freeblock: ino %d blkno %jd lbn %jd size %ld", + "freework_freeblock: ino %jd blkno %jd lbn %jd size %d", freeblks->fb_inum, freework->fw_blkno, freework->fw_lbn, bsize); ffs_blkfree(ump, fs, freeblks->fb_devvp, freework->fw_blkno, bsize, - freeblks->fb_inum, freeblks->fb_vtype, &wkhd); + freeblks->fb_inum, freeblks->fb_vtype, &wkhd, key); ACQUIRE_LOCK(ump); /* * The jnewblk will be discarded and the bits in the map never @@ -7835,7 +7870,7 @@ handle_workitem_indirblk(freework) return; } if (freework->fw_off == NINDIR(fs)) { - freework_freeblock(freework); + freework_freeblock(freework, SINGLETON_KEY); return; } freework->fw_state |= INPROGRESS; @@ -7894,10 +7929,12 @@ handle_workitem_freeblocks(freeblks, flags) struct allocindir *aip; struct ufsmount *ump; struct worklist *wk; + u_long key; KASSERT(LIST_EMPTY(&freeblks->fb_jblkdephd), ("handle_workitem_freeblocks: Journal entries not written.")); ump = VFSTOUFS(freeblks->fb_list.wk_mp); + key = ffs_blkrelease_start(ump, freeblks->fb_devvp, freeblks->fb_inum); ACQUIRE_LOCK(ump); while ((wk = LIST_FIRST(&freeblks->fb_freeworkhd)) != NULL) { WORKLIST_REMOVE(wk); @@ -7935,7 +7972,7 @@ handle_workitem_freeblocks(freeblks, flags) if (freework->fw_lbn <= -UFS_NDADDR) handle_workitem_indirblk(freework); else - freework_freeblock(freework); + freework_freeblock(freework, key); continue; default: panic("handle_workitem_freeblocks: Unknown type %s", @@ -7948,6 +7985,7 @@ handle_workitem_freeblocks(freeblks, flags) freeblks = NULL; } FREE_LOCK(ump); + ffs_blkrelease_finish(ump, key); if (freeblks) return handle_complete_freeblocks(freeblks, flags); return (0); @@ -8080,13 +8118,9 @@ indir_trunc(freework, dbn, lbn) ufs1_daddr_t *bap1; ufs2_daddr_t nb, nnb, *bap2; ufs_lbn_t lbnadd, nlbn; - int i, nblocks, ufs1fmt; - int freedblocks; - int goingaway; - int freedeps; - int needj; - int level; - int cnt; + u_long key; + int nblocks, ufs1fmt, freedblocks; + int goingaway, freedeps, needj, level, cnt, i; freeblks = freework->fw_freeblks; ump = VFSTOUFS(freeblks->fb_list.wk_mp); @@ -8180,6 +8214,7 @@ indir_trunc(freework, dbn, lbn) * arranges for the current level to be freed when subordinates * are free when journaling. */ + key = ffs_blkrelease_start(ump, freeblks->fb_devvp, freeblks->fb_inum); for (i = freework->fw_off; i < NINDIR(fs); i++, nb = nnb) { if (i != NINDIR(fs) - 1) { if (ufs1fmt) @@ -8215,13 +8250,14 @@ indir_trunc(freework, dbn, lbn) freedeps++; } CTR3(KTR_SUJ, - "indir_trunc: ino %d blkno %jd size %ld", + "indir_trunc: ino %jd blkno %jd size %d", freeblks->fb_inum, nb, fs->fs_bsize); ffs_blkfree(ump, fs, freeblks->fb_devvp, nb, fs->fs_bsize, freeblks->fb_inum, - freeblks->fb_vtype, &wkhd); + freeblks->fb_vtype, &wkhd, key); } } + ffs_blkrelease_finish(ump, key); if (goingaway) { bp->b_flags |= B_INVAL | B_NOCACHE; brelse(bp); @@ -8244,7 +8280,7 @@ indir_trunc(freework, dbn, lbn) if (level == 0) freeblks->fb_cgwait += freedeps; if (freework->fw_ref == 0) - freework_freeblock(freework); + freework_freeblock(freework, SINGLETON_KEY); FREE_LOCK(ump); return; } @@ -8253,10 +8289,10 @@ indir_trunc(freework, dbn, lbn) */ dbn = dbtofsb(fs, dbn); CTR3(KTR_SUJ, - "indir_trunc 2: ino %d blkno %jd size %ld", + "indir_trunc 2: ino %jd blkno %jd size %d", freeblks->fb_inum, dbn, fs->fs_bsize); ffs_blkfree(ump, fs, freeblks->fb_devvp, dbn, fs->fs_bsize, - freeblks->fb_inum, freeblks->fb_vtype, NULL); + freeblks->fb_inum, freeblks->fb_vtype, NULL, SINGLETON_KEY); /* Non SUJ softdep does single-threaded truncations. */ if (freework->fw_blkno == dbn) { freework->fw_state |= ALLCOMPLETE; diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 9ed5c58f7b0e..e3927327c79c 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -978,6 +978,8 @@ ffs_mountfs(devvp, mp, td) taskqueue_thread_enqueue, &ump->um_trim_tq); taskqueue_start_threads(&ump->um_trim_tq, 1, PVFS, "%s trim", mp->mnt_stat.f_mntonname); + ump->um_trimhash = hashinit(MAXTRIMIO, M_TRIM, + &ump->um_trimlisthashsize); } } @@ -1256,6 +1258,7 @@ ffs_unmount(mp, mntflags) pause("ufsutr", hz); taskqueue_drain_all(ump->um_trim_tq); taskqueue_free(ump->um_trim_tq); + free (ump->um_trimhash, M_TRIM); } g_topology_lock(); if (ump->um_fsckpid > 0) { diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h index 707429fe68c6..1e2946ab9fb9 100644 --- a/sys/ufs/ffs/softdep.h +++ b/sys/ufs/ffs/softdep.h @@ -557,6 +557,7 @@ struct freefrag { long ff_fragsize; /* size of fragment being deleted */ ino_t ff_inum; /* owning inode number */ enum vtype ff_vtype; /* owning inode's file type */ + int ff_key; /* trim key when deleted */ }; /* diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h index 1958b02f6abb..0652e6a72930 100644 --- a/sys/ufs/ufs/ufsmount.h +++ b/sys/ufs/ufs/ufsmount.h @@ -47,6 +47,7 @@ struct ufs_args { #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_UFSMNT); +MALLOC_DECLARE(M_TRIM); #endif struct buf; @@ -63,6 +64,7 @@ struct inodedep; TAILQ_HEAD(inodedeplst, inodedep); LIST_HEAD(bmsafemaphd, bmsafemap); +LIST_HEAD(trimlist_hashhead, ffs_blkfree_trim_params); /* * This structure describes the UFS specific mount structure data. @@ -70,7 +72,6 @@ LIST_HEAD(bmsafemaphd, bmsafemap); * UFS (UFS1, UFS2, etc). * * Lock reference: - * a - atomic operations * c - set at allocation then constant until freed * i - ufsmount interlock (UFS_LOCK / UFS_UNLOCK) * q - associated quota file is locked @@ -99,8 +100,13 @@ struct ufsmount { char um_qflags[MAXQUOTAS]; /* (i) quota specific flags */ int64_t um_savedmaxfilesize; /* (c) track maxfilesize */ u_int um_flags; /* (i) filesystem flags */ - u_int um_trim_inflight; /* (a) outstanding trim count */ + u_int um_trim_inflight; /* (i) outstanding trim count */ + u_int um_trim_inflight_blks; /* (i) outstanding trim blks */ + u_long um_trim_total; /* (i) total trim count */ + u_long um_trim_total_blks; /* (i) total trim block count */ struct taskqueue *um_trim_tq; /* (c) trim request queue */ + struct trimlist_hashhead *um_trimhash; /* (i) trimlist hash table */ + u_long um_trimlisthashsize; /* (i) trim hash table size-1 */ /* (c) - below function ptrs */ int (*um_balloc)(struct vnode *, off_t, int, struct ucred *, int, struct buf **); From 94d0f0877db6bf0511dc0198e78b870618f42d3e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 18 Aug 2018 22:35:19 +0000 Subject: [PATCH 006/222] Oops. r338030 didn't eliminate the unused arena argument from all of kmem_alloc_attr()'s callers. Correct that mistake. --- sys/arm/arm/busdma_machdep-v4.c | 4 ++-- sys/arm/arm/busdma_machdep-v6.c | 4 ++-- sys/arm/arm/pmap-v6.c | 4 ++-- sys/arm64/arm64/busdma_bounce.c | 5 ++--- sys/dev/agp/agp_amd.c | 9 ++++----- sys/dev/agp/agp_ati.c | 9 ++++----- sys/mips/mips/busdma_machdep.c | 4 ++-- 7 files changed, 18 insertions(+), 21 deletions(-) diff --git a/sys/arm/arm/busdma_machdep-v4.c b/sys/arm/arm/busdma_machdep-v4.c index 32d38557d246..be1d0b78d0a7 100644 --- a/sys/arm/arm/busdma_machdep-v4.c +++ b/sys/arm/arm/busdma_machdep-v4.c @@ -747,8 +747,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, howmany(dmat->maxsize, MIN(dmat->maxsegsz, PAGE_SIZE)) && dmat->alignment <= PAGE_SIZE && (dmat->boundary % PAGE_SIZE) == 0) { - *vaddr = (void *)kmem_alloc_attr(kernel_arena, dmat->maxsize, - mflags, 0, dmat->lowaddr, memattr); + *vaddr = (void *)kmem_alloc_attr(dmat->maxsize, mflags, 0, + dmat->lowaddr, memattr); } else { *vaddr = (void *)kmem_alloc_contig(kernel_arena, dmat->maxsize, mflags, 0, dmat->lowaddr, dmat->alignment, dmat->boundary, diff --git a/sys/arm/arm/busdma_machdep-v6.c b/sys/arm/arm/busdma_machdep-v6.c index e451e6796b67..3eb31b959f21 100644 --- a/sys/arm/arm/busdma_machdep-v6.c +++ b/sys/arm/arm/busdma_machdep-v6.c @@ -812,8 +812,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags, howmany(dmat->maxsize, MIN(dmat->maxsegsz, PAGE_SIZE)) && dmat->alignment <= PAGE_SIZE && (dmat->boundary % PAGE_SIZE) == 0) { - *vaddr = (void *)kmem_alloc_attr(kernel_arena, dmat->maxsize, - mflags, 0, dmat->lowaddr, memattr); + *vaddr = (void *)kmem_alloc_attr(dmat->maxsize, mflags, 0, + dmat->lowaddr, memattr); } else { *vaddr = (void *)kmem_alloc_contig(kernel_arena, dmat->maxsize, mflags, 0, dmat->lowaddr, dmat->alignment, dmat->boundary, diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c index 6d7c8607d8f4..2d3c4f534faa 100644 --- a/sys/arm/arm/pmap-v6.c +++ b/sys/arm/arm/pmap-v6.c @@ -2236,8 +2236,8 @@ pmap_pinit(pmap_t pmap) * be used no matter which process is current. Its mapping * in PT2MAP can be used only for current process. */ - pmap->pm_pt2tab = (pt2_entry_t *)kmem_alloc_attr(kernel_arena, - NB_IN_PT2TAB, M_NOWAIT | M_ZERO, 0, -1UL, pt_memattr); + pmap->pm_pt2tab = (pt2_entry_t *)kmem_alloc_attr(NB_IN_PT2TAB, + M_NOWAIT | M_ZERO, 0, -1UL, pt_memattr); if (pmap->pm_pt2tab == NULL) { /* * QQQ: As struct pmap is allocated from UMA with diff --git a/sys/arm64/arm64/busdma_bounce.c b/sys/arm64/arm64/busdma_bounce.c index 31eaf05370b6..c6561e43c084 100644 --- a/sys/arm64/arm64/busdma_bounce.c +++ b/sys/arm64/arm64/busdma_bounce.c @@ -491,9 +491,8 @@ bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, dmat->common.alignment <= PAGE_SIZE && (dmat->common.boundary % PAGE_SIZE) == 0) { /* Page-based multi-segment allocations allowed */ - *vaddr = (void *)kmem_alloc_attr(kernel_arena, - dmat->common.maxsize, mflags, 0ul, dmat->common.lowaddr, - attr); + *vaddr = (void *)kmem_alloc_attr(dmat->common.maxsize, mflags, + 0ul, dmat->common.lowaddr, attr); dmat->bounce_flags |= BF_KMEM_ALLOC; } else { *vaddr = (void *)kmem_alloc_contig(kernel_arena, diff --git a/sys/dev/agp/agp_amd.c b/sys/dev/agp/agp_amd.c index d80ed1783488..1648f41ac4a0 100644 --- a/sys/dev/agp/agp_amd.c +++ b/sys/dev/agp/agp_amd.c @@ -101,9 +101,8 @@ agp_amd_alloc_gatt(device_t dev) * directory. */ gatt->ag_entries = entries; - gatt->ag_virtual = (void *)kmem_alloc_attr(kernel_arena, - entries * sizeof(u_int32_t), M_NOWAIT | M_ZERO, 0, ~0, - VM_MEMATTR_WRITE_COMBINING); + gatt->ag_virtual = (void *)kmem_alloc_attr(entries * sizeof(u_int32_t), + M_NOWAIT | M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); if (!gatt->ag_virtual) { if (bootverbose) device_printf(dev, "allocation failed\n"); @@ -114,8 +113,8 @@ agp_amd_alloc_gatt(device_t dev) /* * Allocate the page directory. */ - gatt->ag_vdir = (void *)kmem_alloc_attr(kernel_arena, AGP_PAGE_SIZE, - M_NOWAIT | M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); + gatt->ag_vdir = (void *)kmem_alloc_attr(AGP_PAGE_SIZE, M_NOWAIT | + M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); if (!gatt->ag_vdir) { if (bootverbose) device_printf(dev, diff --git a/sys/dev/agp/agp_ati.c b/sys/dev/agp/agp_ati.c index ee31fdbb4cee..d6c10dc66349 100644 --- a/sys/dev/agp/agp_ati.c +++ b/sys/dev/agp/agp_ati.c @@ -133,9 +133,8 @@ agp_ati_alloc_gatt(device_t dev) /* Alloc the GATT -- pointers to pages of AGP memory */ sc->ag_entries = entries; - sc->ag_virtual = (void *)kmem_alloc_attr(kernel_arena, - entries * sizeof(u_int32_t), M_NOWAIT | M_ZERO, 0, ~0, - VM_MEMATTR_WRITE_COMBINING); + sc->ag_virtual = (void *)kmem_alloc_attr(entries * sizeof(u_int32_t), + M_NOWAIT | M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); if (sc->ag_virtual == NULL) { if (bootverbose) device_printf(dev, "GATT allocation failed\n"); @@ -143,8 +142,8 @@ agp_ati_alloc_gatt(device_t dev) } /* Alloc the page directory -- pointers to each page of the GATT */ - sc->ag_vdir = (void *)kmem_alloc_attr(kernel_arena, AGP_PAGE_SIZE, - M_NOWAIT | M_ZERO, 0, ~0, VM_MEMATTR_WRITE_COMBINING); + sc->ag_vdir = (void *)kmem_alloc_attr(AGP_PAGE_SIZE, M_NOWAIT | M_ZERO, + 0, ~0, VM_MEMATTR_WRITE_COMBINING); if (sc->ag_vdir == NULL) { if (bootverbose) device_printf(dev, "pagedir allocation failed\n"); diff --git a/sys/mips/mips/busdma_machdep.c b/sys/mips/mips/busdma_machdep.c index 2cbcb10f8fe0..4d62a586cb98 100644 --- a/sys/mips/mips/busdma_machdep.c +++ b/sys/mips/mips/busdma_machdep.c @@ -714,8 +714,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddrp, int flags, howmany(dmat->maxsize, MIN(dmat->maxsegsz, PAGE_SIZE)) && dmat->alignment <= PAGE_SIZE && (dmat->boundary % PAGE_SIZE) == 0) { - vaddr = (void *)kmem_alloc_attr(kernel_arena, dmat->maxsize, - mflags, 0, dmat->lowaddr, memattr); + vaddr = (void *)kmem_alloc_attr(dmat->maxsize, mflags, 0, + dmat->lowaddr, memattr); } else { vaddr = (void *)kmem_alloc_contig(kernel_arena, dmat->maxsize, mflags, 0, dmat->lowaddr, dmat->alignment, dmat->boundary, From faa319436f0d548cff97c2c8c763538997b63f34 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 19 Aug 2018 00:22:21 +0000 Subject: [PATCH 007/222] 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). --- 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 f6235bc1610b..45b4eb55ebea 100644 --- a/sys/crypto/ccp/ccp.c +++ b/sys/crypto/ccp/ccp.c @@ -734,7 +734,7 @@ DRIVER_MODULE(ccp, pci, ccp_driver, ccp_devclass, NULL, NULL); MODULE_VERSION(ccp, 1); MODULE_DEPEND(ccp, crypto, 1, 1, 1); MODULE_DEPEND(ccp, random_device, 1, 1, 1); -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)); static int 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 e1fb720511fb..02585cafa47c 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 894240ee344b..a00d69de8024 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 b8e771e97a39a88bbf6ebf8f31dcc820c91fe355 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sun, 19 Aug 2018 00:46:22 +0000 Subject: [PATCH 008/222] Back out r338035 until Warner is finished churning GSoC PNP patches I was not aware Warner was making or planning to make forward progress in this area and have since been informed of that. It's easy to apply/reapply when churn dies down. --- 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 45b4eb55ebea..f6235bc1610b 100644 --- a/sys/crypto/ccp/ccp.c +++ b/sys/crypto/ccp/ccp.c @@ -734,7 +734,7 @@ DRIVER_MODULE(ccp, pci, ccp_driver, ccp_devclass, NULL, NULL); MODULE_VERSION(ccp, 1); MODULE_DEPEND(ccp, crypto, 1, 1, 1); MODULE_DEPEND(ccp, random_device, 1, 1, 1); -MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, +MODULE_PNP_INFO("W32:vendor/device", pci, ccp, ccp_ids, sizeof(ccp_ids[0]), nitems(ccp_ids)); static int diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c index 738bfbf79167..399e55a9a47f 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, nitems(aac_identifiers) - 1); + aac_identifiers, sizeof(aac_identifiers[0]), 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 f445a073b6d5..74ac0ee23312 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, + aacraid_family_identifiers, sizeof(aacraid_family_identifiers[0]), 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 19b2f9388c6f..2ae3d768c2fd 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, +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, adlink, adlink_id, sizeof(adlink_id[0]), nitems(adlink_id)); #endif /* _KERNEL */ diff --git a/sys/dev/ae/if_ae.c b/sys/dev/ae/if_ae.c index cb9474db8553..f70afb27fa56 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, - nitems(ae_devs)); + sizeof(ae_devs[0]), 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 ee52564d7cc8..764363f19856 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, - nitems(age_devs)); + sizeof(age_devs[0]), 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 2bc2a243837b..a117a5720c86 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, - nitems(ahci_ids) - 1); + sizeof(ahci_ids[0]), 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 1bafdab235d0..ede7bd49c193 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, - nitems(alc_ident_table) - 1); + sizeof(alc_ident_table[0]), 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 802fdafd63cf..987bd2db7421 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, - nitems(ale_devs)); + sizeof(ale_devs[0]), 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 17792dd922cd..fb2c8b17328c 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, - nitems(amdsmn_ids)); + sizeof(amdsmn_ids[0]), 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 2463212c25f5..45f8d6397ed0 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, - nitems(amdtemp_products)); + sizeof(amdtemp_products[0]), 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 25b37eda3895..80cd58b5ccd3 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, - nitems(amr_device_ids) - 1); + sizeof(amr_device_ids[0]), 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 15ae3e320e54..1105a963128e 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, nitems(an_devs) - 1); + an_devs, sizeof(an_devs[0]), 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 3d5c0742580c..37eed4abcbc0 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, nitems(bce_devs) - 1); + bce_devs, sizeof(bce_devs[0]), nitems(bce_devs) - 1); /****************************************************************************/ /* Tunable device values */ diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c index 6a86f3488b4c..fb0c2949c82d 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, - nitems(bfe_devs) - 1); + sizeof(bfe_devs[0]), 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 193116e10681..c7134b9a2abd 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, - nitems(bge_devs) - 1); + sizeof(bge_devs[0]), 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 f95ef854ceaa..63378be0452d 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, - nitems(bwi_devices) - 1); + sizeof(bwi_devices[0]), 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 610f8bdeb823..dfe7b50e7bc0 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, nitems(siba_devices) - 1); + siba_devices, sizeof(siba_devices[0]), nitems(siba_devices) - 1); MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, bwn_bcma, - bcma_devices, nitems(bcma_devices) - 1); + bcma_devices, sizeof(bcma_devices[0]), 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 d1b3761302a1..3e6dbfe7b463 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, - nitems(cas_pci_devlist) - 1); + sizeof(cas_pci_devlist[0]), 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 e4b887a38e60..94bd9c69e1c5 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, - nitems(ciss_vendor_data) - 1); + sizeof(ciss_vendor_data[0]), 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 a4394de9c552..e1593b02db25 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, - nitems(dc_devs) - 1); + sizeof(dc_devs[0]), 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 8a7168861aca..f0c8867501b3 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, - nitems(pciidlist) - 1); + sizeof(pciidlist[0]), 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 73f83ccef0cb..bf3dd063c178 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, nitems(pciidlist) - 1); + pciidlist, sizeof(pciidlist[0]), nitems(pciidlist) - 1); diff --git a/sys/dev/ed/if_ed_pci.c b/sys/dev/ed/if_ed_pci.c index 8ada958abcbe..b487b97de820 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, +MODULE_PNP_INFO("W32:vendor/device;D:#", pci, ed, pci_ids, sizeof(pci_ids[0]), nitems(pci_ids) - 1); diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c index a27de7db593f..cadc8bdbf677 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, - nitems(ena_vendor_info_array) - 1); + sizeof(ena_vendor_info_array[0]), 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 294d9d5e55aa..a5ce9e452872 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, - nitems(et_devices) - 1); + sizeof(et_devices[0]), 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 2c3297a05bea..b89f8329a4f2 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, - nitems(fxp_ident_table) - 1); + sizeof(fxp_ident_table[0]), 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 ce3027fb3441..af9db3da9c3e 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, - nitems(gem_pci_devlist) - 1); + sizeof(gem_pci_devlist[0]), 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 15da5e861a07..4b4cf9ab10c8 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, - nitems(intsmb_products)); + sizeof(intsmb_products[0]), nitems(intsmb_products)); diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index b03de58fcb55..744c26dfafdc 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, - nitems(pci_ids)); + sizeof(pci_ids[0]), nitems(pci_ids)); /* * OS <-> Driver linkage functions diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index e99d5aedc714..1da31934f738 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, - nitems(ipw_ident_table) - 1); + sizeof(ipw_ident_table[0]), 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 44843ff3fc98..cca610664065 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, - nitems(ixgbe_vendor_info_array) - 1); + sizeof(ixgbe_vendor_info_array[0]), 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 02585cafa47c..e1fb720511fb 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, - nitems(ixv_vendor_info_array) - 1); + sizeof(ixv_vendor_info_array[0]), 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 58bc2a6af01c..5cfb413731c2 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, - nitems(ncr_chip_table)); + sizeof(ncr_chip_table[0]), 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 d61f664d8cff..3bb57fcb71d0 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, - nitems(pci_ids)); + sizeof(pci_ids[0]), nitems(pci_ids)); diff --git a/sys/dev/ofw/ofw_bus_subr.h b/sys/dev/ofw/ofw_bus_subr.h index edc90ed7bf3c..537856b97ef7 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) / sizeof(t[0])); + MODULE_PNP_INFO(SIMPLEBUS_PNP_DESCR, simplebus, t, t, sizeof(t[0]), 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 87f41850ec5c..5138c243f5b7 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, nitems(t) - 1) + MODULE_PNP_INFO(PCCARD_PNP_DESCR, pccard, t, t, sizeof(t[0]), 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 376fb96594ce..c5a8afb4ed23 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, \ + MODULE_PNP_INFO(PCI_PNP_STR, pci, table, table, sizeof(table[0]), \ 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 012a16dc9e9b..f0c6aa81dde4 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, nitems(puc_pci_devices) - 1); + puc_pci_devices, sizeof(puc_pci_devices[0]), nitems(puc_pci_devices) - 1); diff --git a/sys/dev/spibus/spi.h b/sys/dev/spibus/spi.h index 0c12929bee15..1a9c1496a77d 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) / sizeof(t[0])); + MODULE_PNP_INFO(SPIBUS_PNP_DESCR, spibus, t, t, sizeof(t[0]), sizeof(t) / sizeof(t[0])); diff --git a/sys/dev/uart/uart_bus_pccard.c b/sys/dev/uart/uart_bus_pccard.c index a00d69de8024..894240ee344b 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, - 1); + sizeof(uart_pccard_function), 1); diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index d5648c0301ea..147b5d5e71b8 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, \ + MODULE_PNP_INFO(USB_STD_PNP_HOST_INFO, uhub, table, table, sizeof(table[0]), \ sizeof(table) / sizeof(table[0])) #define USB_PNP_DEVICE_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, uhub, table, table, \ + MODULE_PNP_INFO(USB_STD_PNP_DEVICE_INFO, uhub, table, table, sizeof(table[0]), \ sizeof(table) / sizeof(table[0])) #define USB_PNP_DUAL_INFO(table) \ - MODULE_PNP_INFO(USB_STD_PNP_INFO, uhub, table, table, \ + MODULE_PNP_INFO(USB_STD_PNP_INFO, uhub, table, table, sizeof(table[0]), \ 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 29d323399894..0afe62a522de 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, +MODULE_PNP_INFO("U16:vendor;U16:device;D:#", pci, xl, xl_devs, sizeof(xl_devs[0]), nitems(xl_devs) - 1); static void diff --git a/sys/isa/isavar.h b/sys/isa/isavar.h index d95a9c1ab3f2..1a3e661b67a4 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, nitems(t) - 1); \ + MODULE_PNP_INFO(ISA_PNP_DESCR, isa, t, t, sizeof(t[0]), nitems(t) - 1); \ /* * Simplified accessors for isa devices diff --git a/sys/net/iflib.h b/sys/net/iflib.h index bda5ad45dfc8..6e1eee633a2c 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, nitems(t) - 1) + MODULE_PNP_INFO(IFLIB_PNP_DESCR, b, u, t, sizeof(t[0]), 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 89377df401a8..b40870d32941 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, n) \ +#define MODULE_PNP_INFO(d, b, unique, t, l, n) \ static const struct mod_pnp_match_info _module_pnp_##b##_##unique = { \ .descr = d, \ .bus = #b, \ .table = t, \ - .entry_len = sizeof((t)[0]), \ + .entry_len = l, \ .num_entry = n \ }; \ MODULE_METADATA(_md_##b##_pnpinfo_##unique, MDT_PNP_INFO, \ From d17f8070a1341a2f35a1f25d85dbe98abddf2033 Mon Sep 17 00:00:00 2001 From: Tai-hwa Liang Date: Sun, 19 Aug 2018 01:14:46 +0000 Subject: [PATCH 009/222] Extending the delay cycles to give the codec more time to pump ADC data across the AC-link. Without this patch, some CS4614 cards will need users to reload the driver manually or the hardware won't be initialised properly. Something like: # kldload snd_csa # kldunload snd_csa # kldload snd_csa Tested with: Terratec SiXPack 5.1+ --- sys/dev/sound/pci/csa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sound/pci/csa.c b/sys/dev/sound/pci/csa.c index 6b074018727d..84e0cabcd503 100644 --- a/sys/dev/sound/pci/csa.c +++ b/sys/dev/sound/pci/csa.c @@ -710,7 +710,7 @@ csa_initialize(sc_p scp) * the codec is pumping ADC data across the AC-link. */ acisv = 0; - for (i = 0 ; i < 1000 ; i++) { + for (i = 0 ; i < 2000 ; i++) { /* * First, lets wait a short while to let things settle out a bit, * and to prevent retrying the read too quickly. From e68edb8cf06a796453378b98d963692c838c400f Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 03:57:20 +0000 Subject: [PATCH 010/222] diff(1): Implement -B/--ignore-blank-lines As noted by cem in r338035, coccinelle invokes diff(1) with the -B flag. This was not previously implemented here, so one was forced to create a link for GNU diff to /usr/local/bin/diff Implement the -B flag and add some primitive tests for it. It is implemented in the same fashion that -I is implemented; each chunk's lines are scanned, and if a non-blank line is encountered then the chunk will be output. Otherwise, it's skipped. MFC after: 2 weeks --- usr.bin/diff/TODO | 1 - usr.bin/diff/diff.1 | 14 ++++++++------ usr.bin/diff/diff.c | 14 +++++++++----- usr.bin/diff/diff.h | 1 + usr.bin/diff/diffreg.c | 26 ++++++++++++++++++++++++++ usr.bin/diff/tests/Bflag_C.out | 2 ++ usr.bin/diff/tests/Bflag_D.out | 2 ++ usr.bin/diff/tests/Bflag_F.out | 4 ++++ usr.bin/diff/tests/Makefile | 3 +++ usr.bin/diff/tests/diff_test.sh | 17 +++++++++++++++++ 10 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 usr.bin/diff/tests/Bflag_C.out create mode 100644 usr.bin/diff/tests/Bflag_D.out create mode 100644 usr.bin/diff/tests/Bflag_F.out diff --git a/usr.bin/diff/TODO b/usr.bin/diff/TODO index 537643dd8903..fd58d64ace51 100644 --- a/usr.bin/diff/TODO +++ b/usr.bin/diff/TODO @@ -5,7 +5,6 @@ * make a libsdiff and use that directly to avoid duplicating the code to be implemented: ---ignore-blank-lines --horizon-lines --ignore-tab-expansion --line-format diff --git a/usr.bin/diff/diff.1 b/usr.bin/diff/diff.1 index 0618756aefb0..2ceb273ead1d 100644 --- a/usr.bin/diff/diff.1 +++ b/usr.bin/diff/diff.1 @@ -30,7 +30,7 @@ .\" @(#)diff.1 8.1 (Berkeley) 6/30/93 .\" $FreeBSD$ .\" -.Dd April 20, 2017 +.Dd August 18, 2018 .Dt DIFF 1 .Os .Sh NAME @@ -38,7 +38,7 @@ .Nd differential file and directory comparator .Sh SYNOPSIS .Nm diff -.Op Fl abdipTtw +.Op Fl aBbdipTtw .Oo .Fl c | e | f | .Fl n | q | u @@ -67,7 +67,7 @@ .Op Fl L Ar label | Fl -label Ar label .Ar file1 file2 .Nm diff -.Op Fl abdilpTtw +.Op Fl aBbdilpTtw .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Op Fl L Ar label | Fl -label Ar label .Op Fl -brief @@ -93,7 +93,7 @@ .Fl C Ar number | -context Ar number .Ar file1 file2 .Nm diff -.Op Fl abdiltw +.Op Fl aBbdiltw .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Op Fl -brief .Op Fl -changed-group-format Ar GFMT @@ -118,7 +118,7 @@ .Fl D Ar string | Fl -ifdef Ar string .Ar file1 file2 .Nm diff -.Op Fl abdilpTtw +.Op Fl aBbdilpTtw .Op Fl I Ar pattern | Fl -ignore-matching-lines Ar pattern .Op Fl L Ar label | Fl -label Ar label .Op Fl -brief @@ -144,7 +144,7 @@ .Fl U Ar number | Fl -unified Ar number .Ar file1 file2 .Nm diff -.Op Fl abdilNPprsTtw +.Op Fl aBbdilNPprsTtw .Oo .Fl c | e | f | .Fl n | q | u @@ -300,6 +300,8 @@ if files contain binary characters. Use of this option forces .Nm to produce a diff. +.It Fl B Fl -ignore-blank-lines +Causes chunks that include only blank lines to be ignored. .It Fl b Causes trailing blanks (spaces and tabs) to be ignored, and other strings of blanks to compare equal. diff --git a/usr.bin/diff/diff.c b/usr.bin/diff/diff.c index e12697c4e89e..dbb6528c254f 100644 --- a/usr.bin/diff/diff.c +++ b/usr.bin/diff/diff.c @@ -66,6 +66,7 @@ static struct option longopts[] = { { "ed", no_argument, 0, 'e' }, { "forward-ed", no_argument, 0, 'f' }, { "speed-large-files", no_argument, NULL, 'H' }, + { "ignore-blank-lines", no_argument, 0, 'B' }, { "ignore-matching-lines", required_argument, 0, 'I' }, { "ignore-case", no_argument, 0, 'i' }, { "paginate", no_argument, NULL, 'l' }, @@ -164,6 +165,9 @@ main(int argc, char **argv) case 'h': /* silently ignore for backwards compatibility */ break; + case 'B': + dflags |= D_SKIPBLANKLINES; + break; case 'I': push_ignore_pats(optarg); break; @@ -447,18 +451,18 @@ void usage(void) { (void)fprintf(stderr, - "usage: diff [-abdilpTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" + "usage: diff [-aBbdilpTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" " [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n" " [-I pattern] [-L label] file1 file2\n" - " diff [-abdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" + " diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" " [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n" " -C number file1 file2\n" - " diff [-abdiltw] [-I pattern] [--ignore-case] [--no-ignore-case]\n" + " diff [-aBbdiltw] [-I pattern] [--ignore-case] [--no-ignore-case]\n" " [--normal] [--strip-trailing-cr] [--tabsize] -D string file1 file2\n" - " diff [-abdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" + " diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" " [--no-ignore-case] [--normal] [--tabsize] [--strip-trailing-cr]\n" " -U number file1 file2\n" - " diff [-abdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" + " diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" " [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n" " [-S name] [-X file] [-x pattern] dir1 dir2\n"); diff --git a/usr.bin/diff/diff.h b/usr.bin/diff/diff.h index 87452058220f..1801587f9e68 100644 --- a/usr.bin/diff/diff.h +++ b/usr.bin/diff/diff.h @@ -67,6 +67,7 @@ #define D_EXPANDTABS 0x100 /* Expand tabs to spaces */ #define D_IGNOREBLANKS 0x200 /* Ignore white space changes */ #define D_STRIPCR 0x400 /* Strip trailing cr */ +#define D_SKIPBLANKLINES 0x800 /* Skip blank lines */ /* * Status values for print_status() and diffreg() return values diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c index 47825e1daf46..b872badbc599 100644 --- a/usr.bin/diff/diffreg.c +++ b/usr.bin/diff/diffreg.c @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -1000,6 +1001,31 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d, } return; } + if (*pflags & D_SKIPBLANKLINES) { + char *line; + /* + * All lines in the change, insert, or delete must not be + * empty for the change to be ignored. + */ + if (a <= b) { /* Changes and deletes. */ + for (i = a; i <= b; i++) { + line = preadline(fileno(f1), + ixold[i] - ixold[i - 1], ixold[i - 1]); + if (*line != '\0') + goto proceed; + } + } + if (a > b || c <= d) { /* Changes and inserts. */ + for (i = c; i <= d; i++) { + line = preadline(fileno(f2), + ixnew[i] - ixnew[i - 1], ixnew[i - 1]); + if (*line != '\0') + goto proceed; + } + } + return; + + } proceed: if (*pflags & D_HEADER && diff_format != D_BRIEF) { diff_output("%s %s %s\n", diffargs, file1, file2); diff --git a/usr.bin/diff/tests/Bflag_C.out b/usr.bin/diff/tests/Bflag_C.out new file mode 100644 index 000000000000..c7f130aff396 --- /dev/null +++ b/usr.bin/diff/tests/Bflag_C.out @@ -0,0 +1,2 @@ +1a2 +> diff --git a/usr.bin/diff/tests/Bflag_D.out b/usr.bin/diff/tests/Bflag_D.out new file mode 100644 index 000000000000..4c1170334935 --- /dev/null +++ b/usr.bin/diff/tests/Bflag_D.out @@ -0,0 +1,2 @@ +1a2 +> C diff --git a/usr.bin/diff/tests/Bflag_F.out b/usr.bin/diff/tests/Bflag_F.out new file mode 100644 index 000000000000..9dc5e5694048 --- /dev/null +++ b/usr.bin/diff/tests/Bflag_F.out @@ -0,0 +1,4 @@ +7c8 +< G +--- +> X diff --git a/usr.bin/diff/tests/Makefile b/usr.bin/diff/tests/Makefile index 62a0ab5c6188..78744d3bed8e 100644 --- a/usr.bin/diff/tests/Makefile +++ b/usr.bin/diff/tests/Makefile @@ -5,6 +5,9 @@ PACKAGE= tests ATF_TESTS_SH= diff_test ${PACKAGE}FILES+= \ + Bflag_C.out \ + Bflag_D.out \ + Bflag_F.out \ input1.in \ input2.in \ input_c1.in \ diff --git a/usr.bin/diff/tests/diff_test.sh b/usr.bin/diff/tests/diff_test.sh index 557eea049d4e..01942192e504 100755 --- a/usr.bin/diff/tests/diff_test.sh +++ b/usr.bin/diff/tests/diff_test.sh @@ -9,6 +9,7 @@ atf_test_case group_format atf_test_case side_by_side atf_test_case brief_format atf_test_case b230049 +atf_test_case Bflag simple_body() { @@ -150,6 +151,21 @@ brief_format_body() diff -Nrq A D } +Bflag_body() +{ + atf_check -x 'printf "A\nB\n" > A' + atf_check -x 'printf "A\n\nB\n" > B' + atf_check -x 'printf "A\n \nB\n" > C' + atf_check -x 'printf "A\nC\nB\n" > D' + atf_check -x 'printf "A\nB\nC\nD\nE\nF\nG\nH" > E' + atf_check -x 'printf "A\n\nB\nC\nD\nE\nF\nX\nH" > F' + + atf_check -s exit:0 -o inline:"" diff -B A B + atf_check -s exit:1 -o file:"$(atf_get_srcdir)/Bflag_C.out" diff -B A C + atf_check -s exit:1 -o file:"$(atf_get_srcdir)/Bflag_D.out" diff -B A D + atf_check -s exit:1 -o file:"$(atf_get_srcdir)/Bflag_F.out" diff -B E F +} + atf_init_test_cases() { atf_add_test_case simple @@ -161,4 +177,5 @@ atf_init_test_cases() atf_add_test_case side_by_side atf_add_test_case brief_format atf_add_test_case b230049 + atf_add_test_case Bflag } From 9488de009c0903f02a2d3ae76b737af1ae1f41fc Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 04:15:38 +0000 Subject: [PATCH 011/222] diff(1): Refactor -B a little bit Instead of doing a second pass to skip empty lines if we've specified -I, go ahead and check both at once. Ignore critera has been split out into its own function to try and keep the logic cleaner. --- usr.bin/diff/diffreg.c | 54 ++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 31 deletions(-) diff --git a/usr.bin/diff/diffreg.c b/usr.bin/diff/diffreg.c index b872badbc599..56e126a58414 100644 --- a/usr.bin/diff/diffreg.c +++ b/usr.bin/diff/diffreg.c @@ -196,7 +196,8 @@ static void unsort(struct line *, int, int *); static void change(char *, FILE *, char *, FILE *, int, int, int, int, int *); static void sort(struct line *, int); static void print_header(const char *, const char *); -static int ignoreline(char *); +static bool ignoreline_pattern(char *); +static bool ignoreline(char *, bool); static int asciifile(FILE *); static int fetch(long *, int, int, FILE *, int, int, int); static int newcand(int, int, int); @@ -946,8 +947,8 @@ preadline(int fd, size_t rlen, off_t off) return (line); } -static int -ignoreline(char *line) +static bool +ignoreline_pattern(char *line) { int ret; @@ -956,6 +957,20 @@ ignoreline(char *line) return (ret == 0); /* if it matched, it should be ignored. */ } +static bool +ignoreline(char *line, bool skip_blanks) +{ + + if (ignore_pats != NULL && skip_blanks) + return (ignoreline_pattern(line) || *line == '\0'); + if (ignore_pats != NULL) + return (ignoreline_pattern(line)); + if (skip_blanks) + return (*line == '\0'); + /* No ignore criteria specified */ + return (false); +} + /* * Indicate that there is a difference between lines a and b of the from file * to get to lines c to d of the to file. If a is greater then b then there @@ -971,12 +986,14 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d, long curpos; int i, nc, f; const char *walk; + bool skip_blanks; + skip_blanks = (*pflags & D_SKIPBLANKLINES); restart: if ((diff_format != D_IFDEF || diff_format == D_GFORMAT) && a > b && c > d) return; - if (ignore_pats != NULL) { + if (ignore_pats != NULL || skip_blanks) { char *line; /* * All lines in the change, insert, or delete must @@ -987,7 +1004,7 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d, for (i = a; i <= b; i++) { line = preadline(fileno(f1), ixold[i] - ixold[i - 1], ixold[i - 1]); - if (!ignoreline(line)) + if (!ignoreline(line, skip_blanks)) goto proceed; } } @@ -995,37 +1012,12 @@ change(char *file1, FILE *f1, char *file2, FILE *f2, int a, int b, int c, int d, for (i = c; i <= d; i++) { line = preadline(fileno(f2), ixnew[i] - ixnew[i - 1], ixnew[i - 1]); - if (!ignoreline(line)) + if (!ignoreline(line, skip_blanks)) goto proceed; } } return; } - if (*pflags & D_SKIPBLANKLINES) { - char *line; - /* - * All lines in the change, insert, or delete must not be - * empty for the change to be ignored. - */ - if (a <= b) { /* Changes and deletes. */ - for (i = a; i <= b; i++) { - line = preadline(fileno(f1), - ixold[i] - ixold[i - 1], ixold[i - 1]); - if (*line != '\0') - goto proceed; - } - } - if (a > b || c <= d) { /* Changes and inserts. */ - for (i = c; i <= d; i++) { - line = preadline(fileno(f2), - ixnew[i] - ixnew[i - 1], ixnew[i - 1]); - if (*line != '\0') - goto proceed; - } - } - return; - - } proceed: if (*pflags & D_HEADER && diff_format != D_BRIEF) { diff_output("%s %s %s\n", diffargs, file1, file2); From 36c855b9c0050566dc9864145e1a5c1262e9681d Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sun, 19 Aug 2018 07:05:33 +0000 Subject: [PATCH 012/222] build: remove reference to some dead utilities --- targets/pseudo/userland/Makefile.depend | 4 ---- 1 file changed, 4 deletions(-) diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 685e603c5c4b..63b5797e7140 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -286,9 +286,6 @@ DIRDEPS+= \ usr.bin/nice \ usr.bin/nl \ usr.bin/nohup \ - usr.bin/nslookup \ - usr.bin/nsupdate \ - usr.bin/numactl \ usr.bin/opieinfo \ usr.bin/opiekey \ usr.bin/opiepasswd \ @@ -761,7 +758,6 @@ DIRDEPS+= \ usr.sbin/zic/zic \ usr.sbin/zonectl \ ${DEP_RELDIR}/cddl \ - ${DEP_RELDIR}/games \ ${DEP_RELDIR}/gnu \ ${DEP_RELDIR}/include \ ${DEP_RELDIR}/kerberos5 \ From 4750b59acaa6ecb80d06880809fe609e9d28ddc3 Mon Sep 17 00:00:00 2001 From: Eitan Adler Date: Sun, 19 Aug 2018 07:12:35 +0000 Subject: [PATCH 013/222] send-pr: wave goodbye Entering into the world of 12.x we no longer need even the placeholder for send-pr. It has not done anything for some time. With Hat: bugmeister --- ObsoleteFiles.inc | 2 ++ targets/pseudo/userland/Makefile.depend | 1 - usr.bin/Makefile | 1 - usr.bin/send-pr/Makefile | 5 ----- usr.bin/send-pr/Makefile.depend | 11 ----------- usr.bin/send-pr/send-pr.sh | 11 ----------- usr.sbin/crunch/examples/really-big.conf | 1 - 7 files changed, 2 insertions(+), 30 deletions(-) delete mode 100644 usr.bin/send-pr/Makefile delete mode 100644 usr.bin/send-pr/Makefile.depend delete mode 100755 usr.bin/send-pr/send-pr.sh diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 88baf45ed007..1493f1c9899a 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,8 @@ # xargs -n1 | sort | uniq -d; # done +# 20180819: send-pr(1) placeholder removal +OLD_FILES+=usr/bin/send-pr # 20180725: Cleanup old libcasper.so.0 OLD_LIBS+=lib/libcasper.so.0 # 20180722: indent(1) option renamed, test files follow diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 63b5797e7140..941b943a3983 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -320,7 +320,6 @@ DIRDEPS+= \ usr.bin/script \ usr.bin/sdiff \ usr.bin/sed \ - usr.bin/send-pr \ usr.bin/seq \ usr.bin/shar \ usr.bin/showmount \ diff --git a/usr.bin/Makefile b/usr.bin/Makefile index 48c1d6af91f0..c9620c7b87a1 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -135,7 +135,6 @@ SUBDIR= alias \ script \ sdiff \ sed \ - send-pr \ seq \ shar \ showmount \ diff --git a/usr.bin/send-pr/Makefile b/usr.bin/send-pr/Makefile deleted file mode 100644 index 2b422bf315a8..000000000000 --- a/usr.bin/send-pr/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# $FreeBSD$ - -SCRIPTS= send-pr.sh - -.include diff --git a/usr.bin/send-pr/Makefile.depend b/usr.bin/send-pr/Makefile.depend deleted file mode 100644 index f80275d86ab1..000000000000 --- a/usr.bin/send-pr/Makefile.depend +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - - -.include - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/usr.bin/send-pr/send-pr.sh b/usr.bin/send-pr/send-pr.sh deleted file mode 100755 index ab59040dd6ef..000000000000 --- a/usr.bin/send-pr/send-pr.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -echo -echo "FreeBSD has migrated away from GNATS for tracking bugs, and so send-pr" -echo "is no longer used for submitting bug reports." -echo "Please see https://www.freebsd.org/support.html for more information." -echo -exit 1 diff --git a/usr.sbin/crunch/examples/really-big.conf b/usr.sbin/crunch/examples/really-big.conf index 696fc7b811a1..e83680fcd556 100644 --- a/usr.sbin/crunch/examples/really-big.conf +++ b/usr.sbin/crunch/examples/really-big.conf @@ -110,7 +110,6 @@ progs ypbind ypwhich ypcat ypmatch ypset yppoll srcdirs /usr/src/gnu/usr.bin progs bc cpio diff diff3 gas gawk grep gzip sdiff sort tar -# shell scripts: send-pr srcdirs /usr/src/gnu/usr.bin/ld # ldd and ldconfig progs ld ldd ldconfig From 01012c6442d3daf088db8bbfa43ec1e01f709f6a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 19 Aug 2018 10:15:28 +0000 Subject: [PATCH 014/222] Document LOADER_DEFAULT_INTERP. This controls what interpreter the default boot loader in /boot/loader{,.efi} is, and which one we compile into userboot by default. --- share/man/man7/build.7 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/share/man/man7/build.7 b/share/man/man7/build.7 index 181932add1fe..4c89b9a9b7c0 100644 --- a/share/man/man7/build.7 +++ b/share/man/man7/build.7 @@ -652,6 +652,18 @@ using the option of .Xr make 1 : .Bl -tag -width ".Va -DNO_KERNELCONFIG" +.It Va LOADER_DEFAULT_INTERP +Defines what interpreter the default loader program will have. +Valid values include +.Dq 4th , +.Dq lua , +and +.Dq simp . +This creates the default link for +.Pa /boot/loader +to the loader with that interpreter. +It also determines what interpreter is compiled into +.Pa userboot . .It Va NO_CLEANDIR If set, the build targets that clean parts of the object tree use the equivalent of From 74b7f25ef392065fe31ccd6fd289b9c6365a39eb Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 19 Aug 2018 13:23:46 +0000 Subject: [PATCH 015/222] Fix typo. Noted by: Yuri Pankov MFC after: 12 days --- share/man/man3/pthread_set_name_np.3 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man3/pthread_set_name_np.3 b/share/man/man3/pthread_set_name_np.3 index 814661c01991..3c7ddff56dd5 100644 --- a/share/man/man3/pthread_set_name_np.3 +++ b/share/man/man3/pthread_set_name_np.3 @@ -74,4 +74,4 @@ are non-standard extensions. This manual page was written by .An Alexey Zelkin Aq Mt phantom@FreeBSD.org and -An Yuri Pankov Aq Mt yuripv@yuripv.net . +.An Yuri Pankov Aq Mt yuripv@yuripv.net . From 1d6e9fe75ceb954e045efb8558a7f943161ba0f6 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Sun, 19 Aug 2018 13:44:56 +0000 Subject: [PATCH 016/222] Expose np (nat_t - an entry in the nat table structure) in the DTrace probe when nat fails (label badnat). This is useful in diagnosing failed NAT issues and was used in PR/208566. PR: 208566 MFC after: 3 days --- sys/contrib/ipfilter/netinet/ip_nat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index 598f945c8a77..c95c2d0a66cf 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -3259,7 +3259,7 @@ ipf_nat_add(fin, np, natsave, flags, direction) goto done; badnat: - DT2(ns_badnatnew, fr_info_t *, fin, nat_t *, nat); + DT3(ns_badnatnew, fr_info_t *, fin, nat_t *, nat, ipnat_t *, np); NBUMPSIDE(fin->fin_out, ns_badnatnew); if ((hm = nat->nat_hm) != NULL) ipf_nat_hostmapdel(softc, &hm); From 58a290b9f49a6dc71495894b76a06a211ea8be4a Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Sun, 19 Aug 2018 13:44:59 +0000 Subject: [PATCH 017/222] Add handy DTrace probes useful in diagnosing NAT issues. DTrace probes are situated next to error counters and/or in one instance prior to the -1 return from various functions. This was useful in diagnosis of PR/208566 and will be handy in the future diagnosing NAT failures. PR: 208566 MFC after: 3 days --- sys/contrib/ipfilter/netinet/ip_nat.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index c95c2d0a66cf..815182607f8c 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -2676,6 +2676,7 @@ ipf_nat_newmap(fin, nat, ni) if ((np->in_nsrcmsk == 0xffffffff) && (np->in_spnext == 0)) { if (l > 0) { NBUMPSIDEX(1, ns_exhausted, ns_exhausted_1); + DT4(ns_exhausted_1, fr_info_t *, fin, nat_t *, nat, natinfo_t *, ni, ipnat_t *, np); return -1; } } @@ -2693,6 +2694,7 @@ ipf_nat_newmap(fin, nat, ni) if ((l >= np->in_ppip) || ((l > 0) && !(flags & IPN_TCPUDP))) { NBUMPSIDEX(1, ns_exhausted, ns_exhausted_2); + DT4(ns_exhausted_2, fr_info_t *, fin, nat_t *, nat, natinfo_t *, ni, ipnat_t *, np); return -1; } /* @@ -2728,6 +2730,7 @@ ipf_nat_newmap(fin, nat, ni) ipf_ifpaddr(softc, 4, FRI_NORMAL, fin->fin_ifp, &in6, NULL) == -1) { NBUMPSIDEX(1, ns_new_ifpaddr, ns_new_ifpaddr_1); + DT4(ns_new_ifpaddr_1, fr_info_t *, fin, nat_t *, nat, natinfo_t *, ni, ipnat_t *, np); return -1; } in.s_addr = ntohl(in6.in4.s_addr); @@ -2738,6 +2741,7 @@ ipf_nat_newmap(fin, nat, ni) */ if (l > 0) { NBUMPSIDEX(1, ns_exhausted, ns_exhausted_3); + DT4(ns_exhausted_3, fr_info_t *, fin, nat_t *, nat, natinfo_t *, ni, ipnat_t *, np); return -1; } in.s_addr = ntohl(fin->fin_saddr); @@ -2833,6 +2837,7 @@ ipf_nat_newmap(fin, nat, ni) (np->in_spnext != 0) && (st_port == np->in_spnext) && (np->in_snip != 0) && (st_ip == np->in_snip)) { NBUMPSIDED(1, ns_wrap); + DT4(ns_wrap, fr_info_t *, fin, nat_t *, nat, natinfo_t *, ni, ipnat_t *, np); return -1; } l++; @@ -2968,6 +2973,7 @@ ipf_nat_newrdr(fin, nat, ni) if (ipf_ifpaddr(softc, 4, FRI_NORMAL, fin->fin_ifp, &in6, NULL) == -1) { NBUMPSIDEX(0, ns_new_ifpaddr, ns_new_ifpaddr_2); + DT3(ns_new_ifpaddr_2, fr_info_t *, fin, nat_t *, nat, natinfo_t, ni); return -1; } in.s_addr = ntohl(in6.in4.s_addr); @@ -3114,6 +3120,7 @@ ipf_nat_add(fin, np, natsave, flags, direction) if (nsp->ns_active >= softn->ipf_nat_table_max) { NBUMPSIDED(fin->fin_out, ns_table_max); + DT2(ns_table_max, nat_stat_t *, nsp, ipf_nat_softc_t *, softn); return NULL; } @@ -3128,6 +3135,7 @@ ipf_nat_add(fin, np, natsave, flags, direction) /* Give me a new nat */ KMALLOC(nat, nat_t *); if (nat == NULL) { + DT(ns_memfail); NBUMPSIDED(fin->fin_out, ns_memfail); /* * Try to automatically tune the max # of entries in the @@ -3223,6 +3231,7 @@ ipf_nat_add(fin, np, natsave, flags, direction) if ((np->in_apr != NULL) && ((nat->nat_flags & NAT_SLAVE) == 0)) { if (ipf_proxy_new(fin, nat) == -1) { NBUMPSIDED(fin->fin_out, ns_appr_fail); + DT3(ns_appr_fail, fr_info_t *, fin, nat_t *, nat, ipnat_t *, np); goto badnat; } } @@ -3380,6 +3389,7 @@ ipf_nat_finalise(fin, nat) } NBUMPSIDED(fin->fin_out, ns_unfinalised); + DT2(ns_unfinalised, fr_info_t *, fin, nat_t *, nat); /* * nat_insert failed, so cleanup time... */ @@ -7065,6 +7075,7 @@ ipf_nat_newrewrite(fin, nat, nai) do { changed = -1; /* TRACE (l, src_search, dst_search, np) */ + DT4(ipf_nat_rewrite_1, int, l, int, src_search, int, dst_search, ipnat_t *, np); if ((src_search == 0) && (np->in_spnext == 0) && (dst_search == 0) && (np->in_dpnext == 0)) { @@ -7129,6 +7140,7 @@ ipf_nat_newrewrite(fin, nat, nai) * Find a new destination address */ /* TRACE (fin, np, l, frnat) */ + DT4(ipf_nat_rewrite_2, frinfo_t *, fin, ipnat_t *, np, int, l, frinfo_t *, &frnat); if (ipf_nat_nextaddr(fin, &np->in_ndst, &frnat.fin_daddr, &frnat.fin_daddr) == -1) @@ -7179,6 +7191,7 @@ ipf_nat_newrewrite(fin, nat, nai) } /* TRACE (frnat) */ + DT1(ipf_nat_rewrite_3, frinfo_t *, &frnat); /* * Here we do a lookup of the connection as seen from @@ -7218,6 +7231,7 @@ ipf_nat_newrewrite(fin, nat, nai) } /* TRACE natl, in_stepnext, l */ + DT3(ipf_nat_rewrite_2, nat_t *, natl, ipnat_t *, np , int, l); if ((natl != NULL) && (l > 8)) /* XXX 8 is arbitrary */ return -1; @@ -7310,6 +7324,7 @@ ipf_nat_newdivert(fin, nat, nai) if (natl != NULL) { NBUMPSIDED(fin->fin_out, ns_divert_exist); + DT3(ns_divert_exist, fr_info_t *, fin, nat_t *, nat, natinfo_t, nai); return -1; } @@ -7562,6 +7577,7 @@ ipf_nat_nextaddr(fin, na, old, dst) case FRI_PEERADDR : case FRI_NETWORK : default : + DT4(ns_na_atype, fr_info_t *, fin, nat_addr_t *, na, u_32_t *, old, u_32_t *, new); return -1; } @@ -7573,6 +7589,7 @@ ipf_nat_nextaddr(fin, na, old, dst) NULL); } else { NBUMPSIDE(fin->fin_out, ns_badnextaddr); + DT4(ns_badnextaddr_1, fr_info_t *, fin, nat_addr_t *, na, u_32_t *, old, u_32_t *, new); } } else if (na->na_atype == IPLT_NONE) { @@ -7591,6 +7608,7 @@ ipf_nat_nextaddr(fin, na, old, dst) if (ipf_ifpaddr(softc, 4, na->na_atype, fin->fin_ifp, &newip, NULL) == -1) { NBUMPSIDED(fin->fin_out, ns_ifpaddrfail); + DT4(ns_ifpaddrfail, fr_info_t *, fin, nat_addr_t *, na, u_32_t *, old, u_32_t *, new); return -1; } new = newip.in4.s_addr; @@ -7602,6 +7620,7 @@ ipf_nat_nextaddr(fin, na, old, dst) } else { NBUMPSIDE(fin->fin_out, ns_badnextaddr); + DT4(ns_badnextaddr_2, fr_info_t *, fin, nat_addr_t *, na, u_32_t *, old, u_32_t *, new); } return error; From 683a58eeb9ce3dcfbaa613f85e36687d11e75d26 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Sun, 19 Aug 2018 13:45:03 +0000 Subject: [PATCH 018/222] The bucket index is subtracted by one at lines 2304 and 2314. When 0 it becomes -1, except these are unsigned integers, so they become very large numbers. Thus are always larger than the maximum bucket; the hash table insertion fails causing NAT to fail. This commit ensures that if the index is already zero it is not reduced prior to insertion into the hash table. PR: 208566 --- sys/contrib/ipfilter/netinet/ip_nat.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/contrib/ipfilter/netinet/ip_nat.c b/sys/contrib/ipfilter/netinet/ip_nat.c index 815182607f8c..7c3e0c9fcee4 100644 --- a/sys/contrib/ipfilter/netinet/ip_nat.c +++ b/sys/contrib/ipfilter/netinet/ip_nat.c @@ -2304,14 +2304,16 @@ ipf_nat_delete(softc, nat, logtype) bkt = nat->nat_hv[0] % softn->ipf_nat_table_sz; nss = &softn->ipf_nat_stats.ns_side[0]; - nss->ns_bucketlen[bkt]--; + if (nss->ns_bucketlen[bkt] > 0) + nss->ns_bucketlen[bkt]--; if (nss->ns_bucketlen[bkt] == 0) { nss->ns_inuse--; } bkt = nat->nat_hv[1] % softn->ipf_nat_table_sz; nss = &softn->ipf_nat_stats.ns_side[1]; - nss->ns_bucketlen[bkt]--; + if (nss->ns_bucketlen[bkt] > 0) + nss->ns_bucketlen[bkt]--; if (nss->ns_bucketlen[bkt] == 0) { nss->ns_inuse--; } From d3ee476315631aa7e437f30dde0643c584cca375 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 19 Aug 2018 14:22:45 +0000 Subject: [PATCH 019/222] Use tab for indent. Submitted by: Yuri Pankov MFC after: 3 days --- lib/libc/stdlib/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index d20008f1c810..3994ea3453be 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -16,7 +16,7 @@ MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ random.c reallocarray.c reallocf.c realpath.c remque.c \ set_constraint_handler_s.c strfmon.c strtoimax.c \ strtol.c strtold.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \ - strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c + strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c # Work around an issue on case-insensitive file systems. # libc has both _Exit.c and _exit.s and they both yield From 759a4bc697b6cb264fbd2521470357aa0bb69e1a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 19 Aug 2018 14:25:28 +0000 Subject: [PATCH 020/222] Clarify that memset_s(3) requires __STDC_WANT_LIB_EXT1__ for visibility. Fix typos and other nits. Submitted by: Yuri Pankov MFC after: 3 days Differential revision: https://reviews.freebsd.org/D16797 --- lib/libc/string/memset.3 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/libc/string/memset.3 b/lib/libc/string/memset.3 index 9ab521401317..3f4b777a9e86 100644 --- a/lib/libc/string/memset.3 +++ b/lib/libc/string/memset.3 @@ -32,7 +32,7 @@ .\" @(#)memset.3 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd February 15, 2018 +.Dd August 19, 2018 .Dt MEMSET 3 .Os .Sh NAME @@ -44,6 +44,7 @@ .In string.h .Ft void * .Fn memset "void *dest" "int c" "size_t len" +.Fd #define __STDC_WANT_LIB_EXT1__ 1 .Ft errno_t .Fn memset_s "void *dest" "rsize_t destsz" "int c" "rsize_t len" .Sh DESCRIPTION @@ -82,7 +83,6 @@ or is greater than .Dv RSIZE_MAX , or -.Sp .Fa len is greater than .Fa destsz @@ -93,10 +93,10 @@ Like .Xr explicit_bzero 3 , .Fn memset_s is not removed through Dead Store Elimination (DSE), making it useful for -clearing sensitve data. +clearing sensitive data. In contrast .Fn memset -function +function may be optimized away if the object modified by the function is not accessed again. To clear memory that will not subsequently be accessed it is advised to use @@ -126,6 +126,6 @@ function conforms to .St -isoC . .Fn memset_s -conforms to: +conforms to .St -isoC-2011 K.3.7.4.1. From f9f8ac94cd4d6d357784bb1c0bfdc2906608e123 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 14:26:33 +0000 Subject: [PATCH 021/222] stand: Flip the default interpreter to Lua After years in the making, lualoader is ready to make its debut. Both flavors of loader are still built by default, and may be installed as /boot/loader or /boot/loader.efi as appropriate either by manually creating hard links or using LOADER_DEFAULT_INTERP as documented in build(7). Discussed with: imp Relnotes: yes Differential Revision: https://reviews.freebsd.org/D16795 --- UPDATING | 9 +++++++++ stand/defs.mk | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/UPDATING b/UPDATING index 327bbecd7aa2..990937d547ee 100644 --- a/UPDATING +++ b/UPDATING @@ -31,6 +31,15 @@ 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".) +20180818: + The default interpreter has been switched from 4th to Lua. + LOADER_DEFAULT_INTERP, documented in build(7), will override the default + interpreter. If you have custom FORTH code you will need to set + LOADER_DEFAULT_INTERP=4th (valid values are 4th, lua or simp) in + src.conf for the build. This will create default hard links between + loader and loader_4th instead of loader and loader_lua, the new default. + If you are using UEFI it will create the proper hard link to loader.efi. + 20180815: ls(1) now respects the COLORTERM environment variable used in other systems and software to indicate that a colored terminal is both diff --git a/stand/defs.mk b/stand/defs.mk index e446fd0f6c94..87fb20880462 100644 --- a/stand/defs.mk +++ b/stand/defs.mk @@ -154,10 +154,10 @@ CFLAGS+= -mlittle-endian # # Have a sensible default # -.if ${MK_FORTH} == "yes" -LOADER_DEFAULT_INTERP?=4th -.elif ${MK_LOADER_LUA} == "yes" +.if ${MK_LOADER_LUA} == "yes" LOADER_DEFAULT_INTERP?=lua +.elif ${MK_FORTH} == "yes" +LOADER_DEFAULT_INTERP?=4th .else LOADER_DEFAULT_INTERP?=simp .endif From 540cc17f7b96475db0c4c59741639b041cc77007 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 19 Aug 2018 14:39:57 +0000 Subject: [PATCH 022/222] Provide set_constraint_handler_s(3) man page. Mention abort_handler_s(3) and ignore_handler_s(3), provide cross-reference from memset(3). Submitted by: Yuri Pankov MFC after: 3 days Differential revision: https://reviews.freebsd.org/D16797 --- lib/libc/stdlib/Makefile.inc | 7 +- lib/libc/stdlib/set_constraint_handler_s.3 | 149 +++++++++++++++++++++ lib/libc/string/memset.3 | 1 + 3 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 lib/libc/stdlib/set_constraint_handler_s.3 diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index 3994ea3453be..ee6d98e9cf6a 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -36,8 +36,9 @@ MAN+= a64l.3 abort.3 abs.3 alloca.3 atexit.3 atof.3 \ hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \ lsearch.3 memory.3 ptsname.3 qsort.3 \ quick_exit.3 \ - radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 \ - realpath.3 strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \ + radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 realpath.3 \ + set_constraint_handler_s.3 \ + strfmon.3 strtod.3 strtol.3 strtonum.3 strtoul.3 system.3 \ tsearch.3 MLINKS+=a64l.3 l64a.3 a64l.3 l64a_r.3 @@ -55,6 +56,8 @@ MLINKS+=rand.3 rand_r.3 rand.3 srand.3 rand.3 sranddev.3 MLINKS+=random.3 initstate.3 random.3 setstate.3 random.3 srandom.3 \ random.3 srandomdev.3 MLINKS+=radixsort.3 sradixsort.3 +MLINKS+=set_constraint_handler_s.3 abort_handler_s.3 +MLINKS+=set_constraint_handler_s.3 ignore_handler_s.3 MLINKS+=strfmon.3 strfmon_l.3 MLINKS+=strtod.3 strtof.3 strtod.3 strtold.3 MLINKS+=strtol.3 strtoll.3 strtol.3 strtoq.3 strtol.3 strtoimax.3 diff --git a/lib/libc/stdlib/set_constraint_handler_s.3 b/lib/libc/stdlib/set_constraint_handler_s.3 new file mode 100644 index 000000000000..85956d2a9997 --- /dev/null +++ b/lib/libc/stdlib/set_constraint_handler_s.3 @@ -0,0 +1,149 @@ +.\" Copyright 2018 Yuri Pankov +.\" +.\" 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 REGENTS 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 REGENTS 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$ +.\" +.Dd August 18, 2018 +.Dt SET_CONSTRAINT_HANDLER_S 3 +.Os +.Sh NAME +.Nm set_constraint_handler_s , +.Nm abort_handler_s , +.Nm ignore_handler_s +.Nd runtime-constraint violation handling +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.Fd #define __STDC_WANT_LIB_EXT1__ 1 +.In stdlib.h +.Ft constraint_handler_t +.Fo set_constraint_handler_s +.Fa "constraint_handler_t handler" +.Fc +.Ss Handler Prototype +.Ft typedef void +.Fo (*constraint_handler_t) +.Fa "const char * restrict msg" +.Fa "void * restrict ptr" +.Fa "errno_t error" +.Fc +.Ss Predefined Handlers +.Ft void +.Fo abort_handler_s +.Fa "const char * restrict msg" +.Fa "void * restrict ptr" +.Fa "errno_t error" +.Fc +.Ft void +.Fo ignore_handler_s +.Fa "const char * restrict msg" +.Fa "void * restrict ptr" +.Fa "errno_t error" +.Fc +.Sh DESCRIPTION +The +.Fn set_constraint_handler_s +function sets the runtime-constraint violation handler to be +.Fa handler . +.Pp +The runtime-constraint handler is the callback function invoked when a library +function detects a runtime-constraint violation. +.Pp +The arguments are as follows: +.Bl -tag -width "error" +.It Fa msg +A pointer to a character string describing the runtime-constraint violation. +.It Fa ptr +A +.Dv NULL +pointer. +.It Fa error +If the function calling the handler has a return type declared as +.Vt errno_t , +the return value of the function is passed. +Otherwise, a positive value of type +.Vt errno_t +is passed. +.El +.Pp +Only the most recent handler registered with +.Fn set_constraint_handler_s +is called when a runtime-constraint violation occurs. +.Pp +The implementation has a default constraint handler that is used if no calls to +the +.Fn set_constraint_handler_s +function have been made. +If the +.Fa handler +argument to +.Fn set_constraint_handler_s +is a +.Dv NULL +pointer, the default handler becomes the current constraint handler. +.Pp +The +.Fn abort_handler_s +and +.Fn ignore_handler_s +are the standard-defined runtime-constraint handlers provided by the C library. +.Pp +The +.Fn abort_handler_s +function writes the error message including the +.Fa msg +to +.Dv stderr +and calls the +.Xr abort 3 +function. +The +.Fn abort_handler_s +is currently the default runtime-constraint handler. +.Pp +The +.Fn ignore_handler_s +simply returns to its caller. +.Sh RETURN VALUES +The +.Fn set_constraint_handler_s +function returns a pointer to the previously registered handler, or +.Dv NULL +if none was previously registered. +.Pp +The +.Fn abort_handler_s +function does not return to its caller. +.Pp +The +.Fn ignore_handler_s +function returns no value. +.Sh STANDARDS +The +.Fn set_constraint_handler_s +function conforms to +.St -isoC-2011 +K.3.6.1.1. +.Sh AUTHORS +This manual page was written by +.An Yuri Pankov Aq Mt yuripv@yuripv.net . diff --git a/lib/libc/string/memset.3 b/lib/libc/string/memset.3 index 3f4b777a9e86..590bc08531b9 100644 --- a/lib/libc/string/memset.3 +++ b/lib/libc/string/memset.3 @@ -117,6 +117,7 @@ function returns zero on success, non-zero on error. .Sh SEE ALSO .Xr bzero 3 , .Xr explicit_bzero 3 , +.Xr set_constraint_handler_s 3 , .Xr swab 3 , .Xr wmemset 3 .Sh STANDARDS From 63d8b6ea21d8a40fcc8416ef03ecc4aed1fe4c77 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 14:48:32 +0000 Subject: [PATCH 023/222] libsa: Add lshrdi3.c for powerpc* and mips --- stand/libsa/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stand/libsa/Makefile b/stand/libsa/Makefile index 2158a5447454..69df6be894ad 100644 --- a/stand/libsa/Makefile +++ b/stand/libsa/Makefile @@ -73,13 +73,13 @@ SRCS+= aeabi_memcmp.S aeabi_memcpy.S aeabi_memmove.S aeabi_memset.S .if ${MACHINE_CPUARCH} == "powerpc" .PATH: ${LIBC_SRC}/quad -SRCS+= ashldi3.c ashrdi3.c +SRCS+= ashldi3.c ashrdi3.c lshrdi3.c SRCS+= syncicache.c .endif .if ${MACHINE_CPUARCH} == "mips" .PATH: ${LIBC_SRC}/quad -SRCS+= ashldi3.c ashrdi3.c +SRCS+= ashldi3.c ashrdi3.c lshrdi3.c .endif # uuid functions from libc From 8e02b4e00cc590bdd018b9c7cf08f5f5fd4f0e47 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sun, 19 Aug 2018 14:56:10 +0000 Subject: [PATCH 024/222] Don't expose the uptime via the TCP timestamps. The TCP client side or the TCP server side when not using SYN-cookies used the uptime as the TCP timestamp value. This patch uses in all cases an offset, which is the result of a keyed hash function taking the source and destination addresses and port numbers into account. The keyed hash function is the same a used for the initial TSN. Reviewed by: rrs@ MFC after: 1 month Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D16636 --- sys/netinet/tcp_subr.c | 67 +++++++++++++++++++++++--------------- sys/netinet/tcp_syncache.c | 8 ++--- sys/netinet/tcp_usrreq.c | 8 +++-- sys/netinet/tcp_var.h | 4 ++- 4 files changed, 52 insertions(+), 35 deletions(-) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 5a1731321217..5e8aa9bb104d 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -233,6 +233,9 @@ VNET_DEFINE(uma_zone_t, sack_hole_zone); VNET_DEFINE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]); #endif +VNET_DEFINE_STATIC(u_char, ts_offset_secret[32]); +#define V_ts_offset_secret VNET(ts_offset_secret) + static int tcp_default_fb_init(struct tcpcb *tp); static void tcp_default_fb_fini(struct tcpcb *tp, int tcb_is_purged); static int tcp_default_handoff_ok(struct tcpcb *tp); @@ -1092,6 +1095,7 @@ tcp_init(void) /* Initialize the TCP logging data. */ tcp_log_init(); #endif + read_random(&V_ts_offset_secret, sizeof(V_ts_offset_secret)); if (tcp_soreceive_stream) { #ifdef INET @@ -2603,6 +2607,40 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d) } #endif /* INET6 */ +static uint32_t +tcp_keyed_hash(struct in_conninfo *inc, u_char *key) +{ + MD5_CTX ctx; + uint32_t hash[4]; + + MD5Init(&ctx); + MD5Update(&ctx, &inc->inc_fport, sizeof(uint16_t)); + MD5Update(&ctx, &inc->inc_lport, sizeof(uint16_t)); + switch (inc->inc_flags & INC_ISIPV6) { +#ifdef INET + case 0: + MD5Update(&ctx, &inc->inc_faddr, sizeof(struct in_addr)); + MD5Update(&ctx, &inc->inc_laddr, sizeof(struct in_addr)); + break; +#endif +#ifdef INET6 + case INC_ISIPV6: + MD5Update(&ctx, &inc->inc6_faddr, sizeof(struct in6_addr)); + MD5Update(&ctx, &inc->inc6_laddr, sizeof(struct in6_addr)); + break; +#endif + } + MD5Update(&ctx, key, 32); + MD5Final((unsigned char *)hash, &ctx); + + return (hash[0]); +} + +uint32_t +tcp_new_ts_offset(struct in_conninfo *inc) +{ + return (tcp_keyed_hash(inc, V_ts_offset_secret)); +} /* * Following is where TCP initial sequence number generation occurs. @@ -2644,7 +2682,7 @@ tcp6_ctlinput(int cmd, struct sockaddr *sa, void *d) * as reseeding should not be necessary. * * Locking of the global variables isn_secret, isn_last_reseed, isn_offset, - * isn_offset_old, and isn_ctx is performed using the TCP pcbinfo lock. In + * isn_offset_old, and isn_ctx is performed using the ISN lock. In * general, this means holding an exclusive (write) lock. */ @@ -2665,15 +2703,11 @@ VNET_DEFINE_STATIC(u_int32_t, isn_offset_old); #define V_isn_offset_old VNET(isn_offset_old) tcp_seq -tcp_new_isn(struct tcpcb *tp) +tcp_new_isn(struct in_conninfo *inc) { - MD5_CTX isn_ctx; - u_int32_t md5_buffer[4]; tcp_seq new_isn; u_int32_t projected_offset; - INP_WLOCK_ASSERT(tp->t_inpcb); - ISN_LOCK(); /* Seed if this is the first use, reseed if requested. */ if ((V_isn_last_reseed == 0) || ((V_tcp_isn_reseed_interval > 0) && @@ -2684,26 +2718,7 @@ tcp_new_isn(struct tcpcb *tp) } /* Compute the md5 hash and return the ISN. */ - MD5Init(&isn_ctx); - MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_fport, sizeof(u_short)); - MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_lport, sizeof(u_short)); -#ifdef INET6 - if ((tp->t_inpcb->inp_vflag & INP_IPV6) != 0) { - MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_faddr, - sizeof(struct in6_addr)); - MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->in6p_laddr, - sizeof(struct in6_addr)); - } else -#endif - { - MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_faddr, - sizeof(struct in_addr)); - MD5Update(&isn_ctx, (u_char *) &tp->t_inpcb->inp_laddr, - sizeof(struct in_addr)); - } - MD5Update(&isn_ctx, (u_char *) &V_isn_secret, sizeof(V_isn_secret)); - MD5Final((u_char *) &md5_buffer, &isn_ctx); - new_isn = (tcp_seq) md5_buffer[0]; + new_isn = (tcp_seq)tcp_keyed_hash(inc, V_isn_secret); V_isn_offset += ISN_STATIC_INCREMENT + (arc4random() & ISN_RANDOM_INCREMENT); if (ticks != V_isn_last) { diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index d6174221cc7d..6b477d3af9c8 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -1497,6 +1497,7 @@ syncache_add(struct in_conninfo *inc, struct tcpopt *to, struct tcphdr *th, if (to->to_flags & TOF_TS) { sc->sc_tsreflect = to->to_tsval; sc->sc_flags |= SCF_TIMESTAMP; + sc->sc_tsoff = tcp_new_ts_offset(inc); } if (to->to_flags & TOF_SCALE) { int wscale = 0; @@ -2035,11 +2036,6 @@ syncookie_generate(struct syncache_head *sch, struct syncache *sc) iss = hash & ~0xff; iss |= cookie.cookie ^ (hash >> 24); - /* Randomize the timestamp. */ - if (sc->sc_flags & SCF_TIMESTAMP) { - sc->sc_tsoff = arc4random() - tcp_ts_getticks(); - } - TCPSTAT_INC(tcps_sc_sendcookie); return (iss); } @@ -2126,7 +2122,7 @@ syncookie_lookup(struct in_conninfo *inc, struct syncache_head *sch, if (to->to_flags & TOF_TS) { sc->sc_flags |= SCF_TIMESTAMP; sc->sc_tsreflect = to->to_tsval; - sc->sc_tsoff = to->to_tsecr - tcp_ts_getticks(); + sc->sc_tsoff = tcp_new_ts_offset(inc); } if (to->to_flags & TOF_SIGNATURE) diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 12011928a90b..75ffe968858a 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1439,7 +1439,9 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) soisconnecting(so); TCPSTAT_INC(tcps_connattempt); tcp_state_change(tp, TCPS_SYN_SENT); - tp->iss = tcp_new_isn(tp); + tp->iss = tcp_new_isn(&inp->inp_inc); + if (tp->t_flags & TF_REQ_TSTMP) + tp->ts_offset = tcp_new_ts_offset(&inp->inp_inc); tcp_sendseqinit(tp); return 0; @@ -1478,7 +1480,9 @@ tcp6_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) soisconnecting(inp->inp_socket); TCPSTAT_INC(tcps_connattempt); tcp_state_change(tp, TCPS_SYN_SENT); - tp->iss = tcp_new_isn(tp); + tp->iss = tcp_new_isn(&inp->inp_inc); + if (tp->t_flags & TF_REQ_TSTMP) + tp->ts_offset = tcp_new_ts_offset(&inp->inp_inc); tcp_sendseqinit(tp); return 0; diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h index c0f870ad6e10..5f8c0ade6700 100644 --- a/sys/netinet/tcp_var.h +++ b/sys/netinet/tcp_var.h @@ -923,7 +923,9 @@ void tcp_hc_updatemtu(struct in_conninfo *, uint32_t); void tcp_hc_update(struct in_conninfo *, struct hc_metrics_lite *); extern struct pr_usrreqs tcp_usrreqs; -tcp_seq tcp_new_isn(struct tcpcb *); + +uint32_t tcp_new_ts_offset(struct in_conninfo *); +tcp_seq tcp_new_isn(struct in_conninfo *); int tcp_sack_doack(struct tcpcb *, struct tcpopt *, tcp_seq); void tcp_update_sack_list(struct tcpcb *tp, tcp_seq rcv_laststart, tcp_seq rcv_lastend); From 088b5ad33962fd6f9b682ad31417b4cd14518c27 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 15:07:39 +0000 Subject: [PATCH 025/222] Add config.lua(8) to the tree Reviewed by: 0mp, rpokala (earlier version) Differential Revision: https://reviews.freebsd.org/D14819 --- stand/lua/config.lua.8 | 188 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 stand/lua/config.lua.8 diff --git a/stand/lua/config.lua.8 b/stand/lua/config.lua.8 new file mode 100644 index 000000000000..9d2f545819b4 --- /dev/null +++ b/stand/lua/config.lua.8 @@ -0,0 +1,188 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2018 Kyle Evans +.\" +.\" 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$ +.\" +.Dd June 9, 2018 +.Dt CONFIG.LUA 8 +.Os +.Sh NAME +.Nm config.lua +.Nd FreeBSD config module +.Sh DESCRIPTION +.Nm +contains configuration and module loading functionality. +.Pp +Before hooking into or using the functionality provided by +.Nm , +it must be included with a statement such as the following: +.Pp +.Dl local config = require("config") +.Ss Exported functions +The following functions are exported from +.Nm : +.Bl -tag -width "config.setCarouselIndex(id, idx)" -offset indent +.It Fn config.getCarouselIndex id +Returns the currently chosen index in the carousel menu entry described by +.Ev id . +See the definition of +.Xr menu.lua 8 +for a more in-depth explanation of carousels. +.It Fn config.setCarouselIndex id idx +Set the chosen index for the carousel menu entry described by +.Ev id +to +.Ev idx . +A lookup will be done as needed to determine what value +.Ev idx +actually corresponds to. +.It Fn config.processFile name silent +Process and parse +.Ev name +as a configuration file. +Returns true if +.Ev name +exists and parses without error, false otherwise. +If +.Ev silent +is true, +.Fn config.processFile +will not consider a failure to read the file as a failure. +.It Fn config.parse text +Parse +.Ev text +as a configuration file. +This is used internally by +.Fn config.processFile +to parse the contents of a configuration file. +Returns true if parsing succeeds without error, false if an error occurred. +A message is also printed to the console if an error is encountered. +.It Fn config.loadKernel other_kernel +Attempts to load +.Ev other_kernel +as a kernel. +If +.Ev other_kernel +is unset +.Fn config.loadKernel +will attempt to load +.Dq kernel . +Otherwise, it will try to load +.Dq kernel +first from +.Pa /boot/{other_kernel} , +then from +.Pa {other_kernel} . +.Pp +The latter is tried in case an absolute path has been specified to the kernel +to use. +.Ev module_path +is amended to include the directory the kernel was found in if either of these +paths result in a loaded kernel. +.Pp +If no kernel was loaded from either of these paths, +.Fn config.loadKernel +will attempt to load a kernel named +.Dq {other_kernel} +from +.Ev module_path +instead of attempting to load a kernel named +.Dq kernel . +.Pp +Returns true if a kernel was loaded, false if no kernel was loaded. +.It Fn config.selectKernel kernel +Set +.Ev kernel +to the kernel that will be loaded when either +.Ic autoboot +or +.Ic boot +are invoked. +This is usually called by the menu system as the kernel selector carousel is +toggled through. +.It Fn config.load file reload +Loads +.Ev file +as a configuration file. +If +.Ev file +is not specified, +.Pa /boot/defaults/loader.conf +is used. +.Fn config.load +will then silently attempt to process any files specified in +.Ev loader_conf_files +after +.Ev file +has been processed. +.Xr nextboot 8 +configuration will also be checked as part of +.Fn config.load . +Before returning, all +.Dq config.loaded +hooks will be run if +.Ev reload +is not set to true. +.It Fn config.reload file +Reloads +.Ev file +as a configuration file. +.Fn config.reload +will restore the environment to how it existed before the last config was +loaded, then it will invoke +.Fn config.load file . +Before returning, all +.Dq config.reloaded +hooks will be run. +.It Fn config.loadelf +Loads all ELF objects, the selected kernel as well as any modules configured to +be preloaded in +.Xr loader.conf 5 . +This will be called by the Lua intercepted +.Ic autoboot +and +.Ic boot +commands. +.El +.Ss Defined Hooks +The following hooks are defined in +.Nm : +.Bl -tag -width "config.reloaded" -offset indent +.It config.loaded +.It config.reloaded +.El +.Sh SEE ALSO +.Xr loader.conf 5 , +.Xr loader 8 , +.Xr menu.lua 8 , +.Xr nextboot 8 +.Sh AUTHORS +The +.Nm +file was originally written by +.An Pedro Souza Aq Mt pedrosouza@FreeBSD.org . +Later work and this manual page was done by +.An Kyle Evans Aq Mt kevans@FreeBSD.org . From a5688189135dcef18c138ca7fecd0c82ce12884c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sun, 19 Aug 2018 16:14:59 +0000 Subject: [PATCH 026/222] Remove some vestiges of IPI_LAZYPMAP on i386. The support for lazy pmap invalidations on i386 was removed in r281707. This removes the constant for the IPI and stops accounting for it when sizing the interrupt count arrays. Reviewed by: kib MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D16801 --- sys/i386/include/intr_machdep.h | 4 ++-- sys/x86/include/apicvar.h | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/sys/i386/include/intr_machdep.h b/sys/i386/include/intr_machdep.h index 1ac8f489fd1c..e755baa6ad46 100644 --- a/sys/i386/include/intr_machdep.h +++ b/sys/i386/include/intr_machdep.h @@ -75,10 +75,10 @@ * - 1 ??? dummy counter. * - 2 counters for each I/O interrupt. * - 1 counter for each CPU for lapic timer. - * - 9 counters for each CPU for IPI counters for SMP. + * - 8 counters for each CPU for IPI counters for SMP. */ #ifdef SMP -#define INTRCNT_COUNT (1 + NUM_IO_INTS * 2 + (1 + 9) * MAXCPU) +#define INTRCNT_COUNT (1 + NUM_IO_INTS * 2 + (1 + 8) * MAXCPU) #else #define INTRCNT_COUNT (1 + NUM_IO_INTS * 2 + 1) #endif diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h index f49415a000f1..aecae5467309 100644 --- a/sys/x86/include/apicvar.h +++ b/sys/x86/include/apicvar.h @@ -129,12 +129,7 @@ #define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */ #define IPI_SUSPEND (APIC_IPI_INTS + 7) /* Suspend CPU until restarted. */ -#ifdef __i386__ -#define IPI_LAZYPMAP (APIC_IPI_INTS + 8) /* Lazy pmap release. */ -#define IPI_DYN_FIRST (APIC_IPI_INTS + 9) -#else #define IPI_DYN_FIRST (APIC_IPI_INTS + 8) -#endif #define IPI_DYN_LAST (253) /* IPIs allocated at runtime */ /* From fc6e17153554bbbdb7cf47aa014cdbc03b1bc45f Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sun, 19 Aug 2018 16:56:42 +0000 Subject: [PATCH 027/222] Add consolodation of TRIM / BIO_DELETE commands to the UFS/FFS filesystem. When deleting files on filesystems that are stored on flash-memory (solid-state) disk drives, the filesystem notifies the underlying disk of the blocks that it is no longer using. The notification allows the drive to avoid saving these blocks when it needs to flash (zero out) one of its flash pages. These notifications of no-longer-being-used blocks are referred to as TRIM notifications. In FreeBSD these TRIM notifications are sent from the filesystem to the drive using the BIO_DELETE command. Until now, the filesystem would send a separate message to the drive for each block of the file that was deleted. Each Gigabyte of file size resulted in over 3000 TRIM messages being sent to the drive. This burst of messages can overwhelm the drive's task queue causing multiple second delays for read and write requests. This implementation collects runs of contiguous blocks in the file and then consolodates them into a single BIO_DELETE command to the drive. The BIO_DELETE command describes the run of blocks as a single large block being deleted. Each Gigabyte of file size can result in as few as two BIO_DELETE commands and is typically less than ten. Though these larger BIO_DELETE commands take longer to run, they do not clog the drive task queue, so read and write commands can intersperse effectively with them. Though this new feature has been throughly reviewed and tested, it is being added disabled by default so as to minimize the possibility of disrupting the upcoming 12.0 release. It can be enabled by running ``sysctl vfs.ffs.dotrimcons=1''. Users are encouraged to test it. If no problems arise, we will consider requesting that it be enabled by default for 12.0. Reviewed by: kib Tested by: Peter Holm Sponsored by: Netflix --- sys/ufs/ffs/ffs_alloc.c | 313 +++++++++++++++++++++++++++++++++------- 1 file changed, 258 insertions(+), 55 deletions(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 1267de701dec..dbbb32f2dd93 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -484,6 +484,10 @@ static int doreallocblks = 1; SYSCTL_INT(_vfs_ffs, OID_AUTO, doreallocblks, CTLFLAG_RW, &doreallocblks, 0, "enable block reallocation"); +static int dotrimcons = 1; +SYSCTL_INT(_vfs_ffs, OID_AUTO, dotrimcons, CTLFLAG_RW, &dotrimcons, 0, +"enable BIO_DELETE / TRIM consolodation"); + static int maxclustersearch = 10; SYSCTL_INT(_vfs_ffs, OID_AUTO, maxclustersearch, CTLFLAG_RW, &maxclustersearch, 0, "max number of cylinder group to search for contigous blocks"); @@ -2301,41 +2305,57 @@ ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd) /* * Structures and routines associated with trim management. + * + * The following requests are passed to trim_lookup to indicate + * the actions that should be taken. */ +#define NEW 1 /* if found, error else allocate and hash it */ +#define OLD 2 /* if not found, error, else return it */ +#define REPLACE 3 /* if not found, error else unhash and reallocate it */ +#define DONE 4 /* if not found, error else unhash and return it */ +#define SINGLE 5 /* don't look up, just allocate it and don't hash it */ + MALLOC_DEFINE(M_TRIM, "ufs_trim", "UFS trim structures"); #define TRIMLIST_HASH(ump, key) \ (&(ump)->um_trimhash[(key) & (ump)->um_trimlisthashsize]) -static void ffs_blkfree_trim_completed(struct buf *); -static void ffs_blkfree_trim_task(void *ctx, int pending __unused); - -struct ffs_blkfree_trim_params { - struct task task; - struct ufsmount *ump; - struct vnode *devvp; +/* + * These structures describe each of the block free requests aggregated + * together to make up a trim request. + */ +struct trim_blkreq { + TAILQ_ENTRY(trim_blkreq) blkreqlist; ufs2_daddr_t bno; long size; - ino_t inum; struct workhead *pdephd; struct workhead dephd; }; -static void -ffs_blkfree_trim_task(ctx, pending) - void *ctx; - int pending; -{ - struct ffs_blkfree_trim_params *tp; +/* + * Description of a trim request. + */ +struct ffs_blkfree_trim_params { + TAILQ_HEAD(, trim_blkreq) blklist; + LIST_ENTRY(ffs_blkfree_trim_params) hashlist; + struct task task; + struct ufsmount *ump; + struct vnode *devvp; + ino_t inum; + ufs2_daddr_t bno; + long size; + long key; +}; - tp = ctx; - ffs_blkfree_cg(tp->ump, tp->ump->um_fs, tp->devvp, tp->bno, tp->size, - tp->inum, tp->pdephd); - vn_finished_secondary_write(UFSTOVFS(tp->ump)); - atomic_add_int(&tp->ump->um_trim_inflight, -1); - free(tp, M_TRIM); -} +static void ffs_blkfree_trim_completed(struct buf *); +static void ffs_blkfree_trim_task(void *ctx, int pending __unused); +static struct ffs_blkfree_trim_params *trim_lookup(struct ufsmount *, + struct vnode *, ufs2_daddr_t, long, ino_t, u_long, int); +static void ffs_blkfree_sendtrim(struct ffs_blkfree_trim_params *); +/* + * Called on trim completion to start a task to free the associated block(s). + */ static void ffs_blkfree_trim_completed(bp) struct buf *bp; @@ -2348,6 +2368,132 @@ ffs_blkfree_trim_completed(bp) taskqueue_enqueue(tp->ump->um_trim_tq, &tp->task); } +/* + * Trim completion task that free associated block(s). + */ +static void +ffs_blkfree_trim_task(ctx, pending) + void *ctx; + int pending; +{ + struct ffs_blkfree_trim_params *tp; + struct trim_blkreq *blkelm; + struct ufsmount *ump; + + tp = ctx; + ump = tp->ump; + while ((blkelm = TAILQ_FIRST(&tp->blklist)) != NULL) { + ffs_blkfree_cg(ump, ump->um_fs, tp->devvp, blkelm->bno, + blkelm->size, tp->inum, blkelm->pdephd); + TAILQ_REMOVE(&tp->blklist, blkelm, blkreqlist); + free(blkelm, M_TRIM); + } + vn_finished_secondary_write(UFSTOVFS(ump)); + UFS_LOCK(ump); + ump->um_trim_inflight -= 1; + ump->um_trim_inflight_blks -= numfrags(ump->um_fs, tp->size); + UFS_UNLOCK(ump); + free(tp, M_TRIM); +} + +/* + * Lookup a trim request by inode number. + * Allocate if requested (NEW, REPLACE, SINGLE). + */ +static struct ffs_blkfree_trim_params * +trim_lookup(ump, devvp, bno, size, inum, key, alloctype) + struct ufsmount *ump; + struct vnode *devvp; + ufs2_daddr_t bno; + long size; + ino_t inum; + u_long key; + int alloctype; +{ + struct trimlist_hashhead *tphashhead; + struct ffs_blkfree_trim_params *tp, *ntp; + + ntp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TRIM, M_WAITOK); + if (alloctype != SINGLE) { + KASSERT(key >= FIRST_VALID_KEY, ("trim_lookup: invalid key")); + UFS_LOCK(ump); + tphashhead = TRIMLIST_HASH(ump, key); + LIST_FOREACH(tp, tphashhead, hashlist) + if (key == tp->key) + break; + } + switch (alloctype) { + case NEW: + KASSERT(tp == NULL, ("trim_lookup: found trim")); + break; + case OLD: + KASSERT(tp != NULL, + ("trim_lookup: missing call to ffs_blkrelease_start()")); + UFS_UNLOCK(ump); + free(ntp, M_TRIM); + return (tp); + case REPLACE: + KASSERT(tp != NULL, ("trim_lookup: missing REPLACE trim")); + LIST_REMOVE(tp, hashlist); + /* tp will be freed by caller */ + break; + case DONE: + KASSERT(tp != NULL, ("trim_lookup: missing DONE trim")); + LIST_REMOVE(tp, hashlist); + UFS_UNLOCK(ump); + free(ntp, M_TRIM); + return (tp); + } + TAILQ_INIT(&ntp->blklist); + ntp->ump = ump; + ntp->devvp = devvp; + ntp->bno = bno; + ntp->size = size; + ntp->inum = inum; + ntp->key = key; + if (alloctype != SINGLE) { + LIST_INSERT_HEAD(tphashhead, ntp, hashlist); + UFS_UNLOCK(ump); + } + return (ntp); +} + +/* + * Dispatch a trim request. + */ +static void +ffs_blkfree_sendtrim(tp) + struct ffs_blkfree_trim_params *tp; +{ + struct ufsmount *ump; + struct mount *mp; + struct buf *bp; + + /* + * Postpone the set of the free bit in the cg bitmap until the + * BIO_DELETE is completed. Otherwise, due to disk queue + * reordering, TRIM might be issued after we reuse the block + * and write some new data into it. + */ + ump = tp->ump; + bp = malloc(sizeof(*bp), M_TRIM, M_WAITOK | M_ZERO); + bp->b_iocmd = BIO_DELETE; + bp->b_iooffset = dbtob(fsbtodb(ump->um_fs, tp->bno)); + bp->b_iodone = ffs_blkfree_trim_completed; + bp->b_bcount = tp->size; + bp->b_fsprivate1 = tp; + UFS_LOCK(ump); + ump->um_trim_total += 1; + ump->um_trim_inflight += 1; + ump->um_trim_inflight_blks += numfrags(ump->um_fs, tp->size); + ump->um_trim_total_blks += numfrags(ump->um_fs, tp->size); + UFS_UNLOCK(ump); + + mp = UFSTOVFS(ump); + vn_start_secondary_write(NULL, &mp, 0); + g_vfs_strategy(ump->um_bo, bp); +} + /* * Allocate a new key to use to identify a range of blocks. */ @@ -2360,11 +2506,12 @@ ffs_blkrelease_start(ump, devvp, inum) static u_long masterkey; u_long key; - if ((ump->um_flags & UM_CANDELETE) == 0) + if (((ump->um_flags & UM_CANDELETE) == 0) || dotrimcons == 0) return (SINGLETON_KEY); do { key = atomic_fetchadd_long(&masterkey, 1); } while (key < FIRST_VALID_KEY); + (void) trim_lookup(ump, devvp, 0, 0, inum, key, NEW); return (key); } @@ -2376,10 +2523,32 @@ ffs_blkrelease_finish(ump, key) struct ufsmount *ump; u_long key; { + struct ffs_blkfree_trim_params *tp; - return; + if (((ump->um_flags & UM_CANDELETE) == 0) || dotrimcons == 0) + return; + /* + * We are done with sending blocks using this key. Look up the key + * using the DONE alloctype (in tp) to request that it be unhashed + * as we will not be adding to it. If the key has never been used, + * tp->size will be zero, so we can just free tp. Otherwise the call + * to ffs_blkfree_sendtrim(tp) causes the block range described by + * tp to be issued (and then tp to be freed). + */ + tp = trim_lookup(ump, NULL, 0, 0, 0, key, DONE); + if (tp->size == 0) + free(tp, M_TRIM); + else + ffs_blkfree_sendtrim(tp); } +/* + * Setup to free a block or fragment. + * + * Check for snapshots that might want to claim the block. + * If trims are requested, prepare a trim request. Attempt to + * aggregate consecutive blocks into a single trim request. + */ void ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, key) struct ufsmount *ump; @@ -2392,9 +2561,8 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, key) struct workhead *dephd; u_long key; { - struct mount *mp; - struct buf *bp; - struct ffs_blkfree_trim_params *tp; + struct ffs_blkfree_trim_params *tp, *ntp; + struct trim_blkreq *blkelm; /* * Check to see if a snapshot wants to claim the block. @@ -2416,37 +2584,72 @@ ffs_blkfree(ump, fs, devvp, bno, size, inum, vtype, dephd, key) ffs_blkfree_cg(ump, fs, devvp, bno, size, inum, dephd); return; } - + blkelm = malloc(sizeof(struct trim_blkreq), M_TRIM, M_WAITOK); + blkelm->bno = bno; + blkelm->size = size; + if (dephd == NULL) { + blkelm->pdephd = NULL; + } else { + LIST_INIT(&blkelm->dephd); + LIST_SWAP(dephd, &blkelm->dephd, worklist, wk_list); + blkelm->pdephd = &blkelm->dephd; + } + if (key == SINGLETON_KEY) { + /* + * Just a single non-contiguous piece. Use the SINGLE + * alloctype to return a trim request that will not be + * hashed for future lookup. + */ + tp = trim_lookup(ump, devvp, bno, size, inum, key, SINGLE); + TAILQ_INSERT_HEAD(&tp->blklist, blkelm, blkreqlist); + ffs_blkfree_sendtrim(tp); + return; + } /* - * Postpone the set of the free bit in the cg bitmap until the - * BIO_DELETE is completed. Otherwise, due to disk queue - * reordering, TRIM might be issued after we reuse the block - * and write some new data into it. + * The callers of this function are not tracking whether or not + * the blocks are contiguous. They are just saying that they + * are freeing a set of blocks. It is this code that determines + * the pieces of that range that are actually contiguous. + * + * Calling ffs_blkrelease_start() will have created an entry + * that we will use. */ - atomic_add_int(&ump->um_trim_inflight, 1); - tp = malloc(sizeof(struct ffs_blkfree_trim_params), M_TRIM, M_WAITOK); - tp->ump = ump; - tp->devvp = devvp; - tp->bno = bno; - tp->size = size; - tp->inum = inum; - if (dephd != NULL) { - LIST_INIT(&tp->dephd); - LIST_SWAP(dephd, &tp->dephd, worklist, wk_list); - tp->pdephd = &tp->dephd; - } else - tp->pdephd = NULL; - - bp = malloc(sizeof(*bp), M_TRIM, M_WAITOK | M_ZERO); - bp->b_iocmd = BIO_DELETE; - bp->b_iooffset = dbtob(fsbtodb(fs, bno)); - bp->b_iodone = ffs_blkfree_trim_completed; - bp->b_bcount = size; - bp->b_fsprivate1 = tp; - - mp = UFSTOVFS(ump); - vn_start_secondary_write(NULL, &mp, 0); - g_vfs_strategy(ump->um_bo, bp); + tp = trim_lookup(ump, devvp, bno, size, inum, key, OLD); + if (tp->size == 0) { + /* + * First block of a potential range, set block and size + * for the trim block. + */ + tp->bno = bno; + tp->size = size; + TAILQ_INSERT_HEAD(&tp->blklist, blkelm, blkreqlist); + return; + } + /* + * If this block is a continuation of the range (either + * follows at the end or preceeds in the front) then we + * add it to the front or back of the list and return. + * + * If it is not a continuation of the trim that we were + * building, using the REPLACE alloctype, we request that + * the old trim request (still in tp) be unhashed and a + * new range started (in ntp). The ffs_blkfree_sendtrim(tp) + * call causes the block range described by tp to be issued + * (and then tp to be freed). + */ + if (bno + numfrags(fs, size) == tp->bno) { + TAILQ_INSERT_HEAD(&tp->blklist, blkelm, blkreqlist); + tp->bno = bno; + tp->size += size; + return; + } else if (bno == tp->bno + numfrags(fs, tp->size)) { + TAILQ_INSERT_TAIL(&tp->blklist, blkelm, blkreqlist); + tp->size += size; + return; + } + ntp = trim_lookup(ump, devvp, bno, size, inum, key, REPLACE); + TAILQ_INSERT_HEAD(&ntp->blklist, blkelm, blkreqlist); + ffs_blkfree_sendtrim(tp); } #ifdef INVARIANTS From 4de0d16b8cd8ea0b266cc2f46d0b0fb55f5e2cc9 Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Sun, 19 Aug 2018 17:19:20 +0000 Subject: [PATCH 028/222] For traditional disks, the filesystem attempts to allocate the blocks of a file as contiguously as possible. Since the filesystem does not know how large a file will grow when it is first being written, it initially places the file in a set of blocks in which it currently fits. As it grows, it is relocated to areas with larger contiguous blocks. In this way it saves its large contiguous sets of blocks for the files that need them and thus avoids unnecessaily fragmenting its disk space. We used to skip reallocating the blocks of a file into a contiguous sequence if the underlying flash device requested BIO_DELETE notifications, because devices that benefit from BIO_DELETE also benefit from not moving the data. However, in the algorithm described above that reallocates the blocks, the destination for the data is usually moved before the data is written to the initially allocated location. So we rarely suffer the penalty of extra writes. With the addition of the consolodation of contiguous blocks into single BIO_DELETE operations, having fewer but larger contiguous blocks reduces the number of (slow and expensive) BIO_DELETE operations. So when doing BIO_DELETE consolodation, we do block reallocation. Reviewed by: kib Tested by: Peter Holm Sponsored by: Netflix --- sys/ufs/ffs/ffs_alloc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index dbbb32f2dd93..ed8275e20982 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -506,14 +506,23 @@ ffs_reallocblks(ap) struct ufsmount *ump; /* - * If the underlying device can do deletes, then skip reallocating - * the blocks of this file into contiguous sequences. Devices that - * benefit from BIO_DELETE also benefit from not moving the data. - * These devices are flash and therefore work less well with this - * optimization. Also skip if reallocblks has been disabled globally. + * We used to skip reallocating the blocks of a file into a + * contiguous sequence if the underlying flash device requested + * BIO_DELETE notifications, because devices that benefit from + * BIO_DELETE also benefit from not moving the data. However, + * the destination for the data is usually moved before the data + * is written to the initially allocated location, so we rarely + * suffer the penalty of extra writes. With the addition of the + * consolodation of contiguous blocks into single BIO_DELETE + * operations, having fewer but larger contiguous blocks reduces + * the number of (slow and expensive) BIO_DELETE operations. So + * when doing BIO_DELETE consolodation, we do block reallocation. + * + * Skip if reallocblks has been disabled globally. */ ump = ap->a_vp->v_mount->mnt_data; - if (((ump->um_flags) & UM_CANDELETE) != 0 || doreallocblks == 0) + if ((((ump->um_flags) & UM_CANDELETE) != 0 && dotrimcons == 0) || + doreallocblks == 0) return (ENOSPC); /* From 38a13e9002540152964435700f0f2a73ad5e2e62 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sun, 19 Aug 2018 17:36:50 +0000 Subject: [PATCH 029/222] Fix the MPTable probe code after the 4:4 changes on i386. The MPTable probe code was using PMAP_MAP_LOW as the PA -> VA offset when searching for the table signature but still using KERNBASE once it had found the table. As a result, the mpfps table pointed into a random part of the kernel text instead of the actual MP Table. Rather than adding more #ifdef's, use BIOS_PADDRTOVADDR from which already uses PMAP_MAP_LOW on i386 and KERNBASE on amd64. Reviewed by: kib MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D16802 --- sys/x86/x86/mptable.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/sys/x86/x86/mptable.c b/sys/x86/x86/mptable.c index fca234a5c9e7..3172b7751da5 100644 --- a/sys/x86/x86/mptable.c +++ b/sys/x86/x86/mptable.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef NEW_PCIB #include #endif @@ -223,11 +224,7 @@ search_for_sig(u_int32_t target, int count) int x; u_int32_t *addr; -#ifdef __amd64__ - addr = (u_int32_t *) (KERNBASE + target); -#else /* __i386__ */ - addr = (u_int32_t *) (PMAP_MAP_LOW + target); -#endif + addr = (u_int32_t *)BIOS_PADDRTOVADDR(target); for (x = 0; x < count; x += 4) if (addr[x] == MP_SIG) /* make array index a byte index */ @@ -258,13 +255,7 @@ mptable_probe(void) u_int32_t target; /* see if EBDA exists */ - if ((segment = (u_long) * (u_short *) ( -#ifdef __amd64__ - KERNBASE -#else /* __i386__ */ - PMAP_MAP_LOW -#endif - + 0x40e)) != 0) { + if ((segment = *(u_short *)BIOS_PADDRTOVADDR(0x40e)) != 0) { /* search first 1K of EBDA */ target = (u_int32_t) (segment << 4); if ((x = search_for_sig(target, 1024 / 4)) >= 0) @@ -285,7 +276,7 @@ mptable_probe(void) return (ENXIO); found: - mpfps = (mpfps_t)(KERNBASE + x); + mpfps = (mpfps_t)BIOS_PADDRTOVADDR(x); /* Map in the configuration table if it exists. */ if (mpfps->config_type != 0) { @@ -306,7 +297,7 @@ mptable_probe(void) __func__); return (ENXIO); } - mpct = (mpcth_t)(KERNBASE + (uintptr_t)mpfps->pap); + mpct = (mpcth_t)BIOS_PADDRTOVADDR((uintptr_t)mpfps->pap); if (mpct->base_table_length + (uintptr_t)mpfps->pap >= 1024 * 1024) { printf("%s: Unable to map end of MP Config Table\n", From c1e80940f3b4030df0aaed73028053af057e476d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sun, 19 Aug 2018 17:40:50 +0000 Subject: [PATCH 030/222] Update userland arc4random() with OpenBSD's Chacha20 based arc4random(). ObsoleteFiles.inc: Remove manual pages for arc4random_addrandom(3) and arc4random_stir(3). contrib/ntp/lib/isc/random.c: contrib/ntp/sntp/libevent/evutil_rand.c: Eliminate in-tree usage of arc4random_addrandom(). crypto/heimdal/lib/roken/rand.c: crypto/openssh/config.h: Eliminate in-tree usage of arc4random_stir(). include/stdlib.h: Remove arc4random_stir() and arc4random_addrandom() prototypes, provide temporary shims for transistion period. lib/libc/gen/Makefile.inc: Hook arc4random-compat.c to build, add hint for Chacha20 source for kernel, and remove arc4random_addrandom(3) and arc4random_stir(3) links. lib/libc/gen/arc4random.c: Adopt OpenBSD arc4random.c,v 1.54 with bare minimum changes, use the sys/crypto/chacha20 implementation of keystream. lib/libc/gen/Symbol.map: Remove arc4random_stir and arc4random_addrandom interfaces. lib/libc/gen/arc4random.h: Adopt OpenBSD arc4random.h,v 1.4 but provide _ARC4_LOCK of our own. lib/libc/gen/arc4random.3: Adopt OpenBSD arc4random.3,v 1.35 but keep FreeBSD r114444 and r118247. lib/libc/gen/arc4random-compat.c: Compatibility shims for arc4random_stir and arc4random_addrandom functions to preserve ABI. Log once when called but do nothing otherwise. lib/libc/gen/getentropy.c: lib/libc/include/libc_private.h: Fold __arc4_sysctl into getentropy.c (renamed to arnd_sysctl). Remove from libc_private.h as a result. sys/crypto/chacha20/chacha.c: sys/crypto/chacha20/chacha.h: Make it possible to use the kernel implementation in libc. PR: 182610 Reviewed by: cem, markm Obtained from: OpenBSD Relnotes: yes Differential Revision: https://reviews.freebsd.org/D16760 --- ObsoleteFiles.inc | 3 + contrib/ntp/lib/isc/random.c | 2 - contrib/ntp/sntp/libevent/evutil_rand.c | 2 - crypto/heimdal/lib/roken/rand.c | 1 - crypto/openssh/config.h | 2 +- include/stdlib.h | 9 +- lib/libc/gen/Makefile.inc | 7 +- lib/libc/gen/Symbol.map | 2 - lib/libc/gen/arc4random-compat.c | 72 +++++ lib/libc/gen/arc4random.3 | 110 ++++---- lib/libc/gen/arc4random.c | 356 ++++++++++-------------- lib/libc/gen/arc4random.h | 74 +++++ lib/libc/gen/getentropy.c | 27 +- lib/libc/include/libc_private.h | 2 - sys/crypto/chacha20/chacha.c | 11 +- sys/crypto/chacha20/chacha.h | 12 +- 16 files changed, 413 insertions(+), 279 deletions(-) create mode 100644 lib/libc/gen/arc4random-compat.c create mode 100644 lib/libc/gen/arc4random.h diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index 1493f1c9899a..414be14d1fe7 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,9 @@ # xargs -n1 | sort | uniq -d; # done +# 20180819: Remove deprecated arc4random(3) stir/addrandom interfaces +OLD_FILES+=usr/share/man/man3/arc4random_addrandom.3.gz +OLD_FILES+=usr/share/man/man3/arc4random_stir.3.gz # 20180819: send-pr(1) placeholder removal OLD_FILES+=usr/bin/send-pr # 20180725: Cleanup old libcasper.so.0 diff --git a/contrib/ntp/lib/isc/random.c b/contrib/ntp/lib/isc/random.c index 8b73ed56927d..c433f478a837 100644 --- a/contrib/ntp/lib/isc/random.c +++ b/contrib/ntp/lib/isc/random.c @@ -67,8 +67,6 @@ isc_random_seed(isc_uint32_t seed) #ifndef HAVE_ARC4RANDOM srand(seed); -#else - arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t)); #endif } diff --git a/contrib/ntp/sntp/libevent/evutil_rand.c b/contrib/ntp/sntp/libevent/evutil_rand.c index 046a14b07a9a..24efa69288da 100644 --- a/contrib/ntp/sntp/libevent/evutil_rand.c +++ b/contrib/ntp/sntp/libevent/evutil_rand.c @@ -195,8 +195,6 @@ evutil_secure_rng_get_bytes(void *buf, size_t n) void evutil_secure_rng_add_bytes(const char *buf, size_t n) { - arc4random_addrandom((unsigned char*)buf, - n>(size_t)INT_MAX ? INT_MAX : (int)n); } void diff --git a/crypto/heimdal/lib/roken/rand.c b/crypto/heimdal/lib/roken/rand.c index ef92c2052b78..3172756daf79 100644 --- a/crypto/heimdal/lib/roken/rand.c +++ b/crypto/heimdal/lib/roken/rand.c @@ -37,7 +37,6 @@ void ROKEN_LIB_FUNCTION rk_random_init(void) { #if defined(HAVE_ARC4RANDOM) - arc4random_stir(); #elif defined(HAVE_SRANDOMDEV) srandomdev(); #elif defined(HAVE_RANDOM) diff --git a/crypto/openssh/config.h b/crypto/openssh/config.h index 2dc0c296d447..f76727418c61 100644 --- a/crypto/openssh/config.h +++ b/crypto/openssh/config.h @@ -191,7 +191,7 @@ #define HAVE_ARC4RANDOM_BUF 1 /* Define to 1 if you have the `arc4random_stir' function. */ -#define HAVE_ARC4RANDOM_STIR 1 +/* #undef HAVE_ARC4RANDOM_STIR */ /* Define to 1 if you have the `arc4random_uniform' function. */ #define HAVE_ARC4RANDOM_UNIFORM 1 diff --git a/include/stdlib.h b/include/stdlib.h index d38952e15629..51f003171451 100644 --- a/include/stdlib.h +++ b/include/stdlib.h @@ -250,11 +250,16 @@ extern void (*malloc_message)(void *, const char *); void abort2(const char *, int, void **) __dead2; __uint32_t arc4random(void); -void arc4random_addrandom(unsigned char *, int); void arc4random_buf(void *, size_t); -void arc4random_stir(void); __uint32_t arc4random_uniform(__uint32_t); + +#if !defined(BURN_BRIDGES) +/* Deprecated arc4random() functions */ +#define arc4random_stir() +#define arc4random_addrandom(a,b) +#endif + #ifdef __BLOCKS__ int atexit_b(void (^ _Nonnull)(void)); void *bsearch_b(const void *, const void *, size_t, diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index c6defe88cc96..d6eb1075dbfa 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -16,6 +16,7 @@ SRCS+= __getosreldate.c \ _thread_init.c \ alarm.c \ arc4random.c \ + arc4random-compat.c \ arc4random_uniform.c \ assert.c \ auxv.c \ @@ -166,6 +167,8 @@ SRCS+= devname-compat11.c \ unvis-compat.c .endif +CFLAGS.arc4random.c= -I${SRCTOP}/sys -I${SRCTOP}/sys/crypto/chacha20 + .PATH: ${SRCTOP}/contrib/libc-pwcache SRCS+= pwcache.c pwcache.h @@ -316,9 +319,7 @@ MAN+= alarm.3 \ vis.3 \ wordexp.3 -MLINKS+=arc4random.3 arc4random_addrandom.3 \ - arc4random.3 arc4random_stir.3 \ - arc4random.3 arc4random_buf.3 \ +MLINKS+=arc4random.3 arc4random_buf.3 \ arc4random.3 arc4random_uniform.3 MLINKS+=ctermid.3 ctermid_r.3 MLINKS+=devname.3 devname_r.3 diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index cd81e96eeb5c..010358ba9bc5 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -65,8 +65,6 @@ FBSD_1.0 { pthread_testcancel; alarm; arc4random; - arc4random_addrandom; - arc4random_stir; __assert; check_utility_compat; clock; diff --git a/lib/libc/gen/arc4random-compat.c b/lib/libc/gen/arc4random-compat.c new file mode 100644 index 000000000000..065998e80553 --- /dev/null +++ b/lib/libc/gen/arc4random-compat.c @@ -0,0 +1,72 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2018 Google LLC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +/* + * The following functions were removed from OpenBSD for good reasons: + * + * - arc4random_stir() + * - arc4random_addrandom() + * + * On FreeBSD, for backward ABI compatibility, we provide two wrapper which + * logs this event and returns. + */ + +void __arc4random_stir_fbsd11(void); +void __arc4random_addrandom_fbsd11(u_char *, int); + +void +__arc4random_stir_fbsd11(void) +{ + static bool warned = false; + + if (!warned) + syslog(LOG_DEBUG, "Deprecated function arc4random_stir() called"); + warned = true; +} + +void +__arc4random_addrandom_fbsd11(u_char * dummy1 __unused, int dummy2 __unused) +{ + static bool warned = false; + + if (!warned) + syslog(LOG_DEBUG, "Deprecated function arc4random_addrandom() called"); + warned = true; +} + +__sym_compat(arc4random_stir, __arc4random_stir_fbsd11, FBSD_1.0); +__sym_compat(arc4random_addrandom, __arc4random_addrandom_fbsd11, FBSD_1.0); diff --git a/lib/libc/gen/arc4random.3 b/lib/libc/gen/arc4random.3 index e1124c622e77..77ad24f9a570 100644 --- a/lib/libc/gen/arc4random.3 +++ b/lib/libc/gen/arc4random.3 @@ -1,4 +1,5 @@ -.\" $OpenBSD: arc4random.3,v 1.2 1997/04/27 22:40:25 angelos Exp $ +.\" $OpenBSD: arc4random.3,v 1.35 2014/11/25 16:45:24 millert Exp $ +.\" .\" Copyright 1997 Niels Provos .\" All rights reserved. .\" @@ -30,16 +31,14 @@ .\" Manual page, using -mandoc macros .\" $FreeBSD$ .\" -.Dd April 15, 1997 +.Dd July 19, 2014 .Dt ARC4RANDOM 3 .Os .Sh NAME .Nm arc4random , .Nm arc4random_buf , -.Nm arc4random_uniform , -.Nm arc4random_stir , -.Nm arc4random_addrandom -.Nd arc4 random number generator +.Nm arc4random_uniform +.Nd random number generator .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -50,20 +49,36 @@ .Fn arc4random_buf "void *buf" "size_t nbytes" .Ft uint32_t .Fn arc4random_uniform "uint32_t upper_bound" -.Ft void -.Fn arc4random_stir "void" -.Ft void -.Fn arc4random_addrandom "unsigned char *dat" "int datlen" .Sh DESCRIPTION +This family of functions provides higher quality data than those +described in +.Xr rand 3 , +.Xr random 3 , +and +.Xr rand48 3 . +.Pp +Use of these functions is encouraged for almost all random number +consumption because the other interfaces are deficient in either +quality, portability, standardization, or availability. +These functions can be called in almost all coding environments, +including +.Xr pthreads 3 +and +.Xr chroot 2 . +.Pp +High quality 32-bit pseudo-random numbers are generated very quickly. +On each call, a cryptographic pseudo-random number generator is used +to generate a new result. +One data pool is used for all consumers in a process, so that consumption +under program flow can act as additional stirring. +The subsystem is re-seeded from the kernel random number subsystem using +.Xr getentropy 2 +on a regular basis, and also upon +.Xr fork 2 . +.Pp The .Fn arc4random -function uses the key stream generator employed by the -arc4 cipher, which uses 8*8 8 bit S-Boxes. -The S-Boxes -can be in about -.if t 2\u\s71700\s10\d -.if n (2**1700) -states. +function returns a single 32-bit value. The .Fn arc4random function returns pseudo-random numbers in the range of 0 to @@ -75,33 +90,24 @@ and .Xr random 3 . .Pp .Fn arc4random_buf -function fills the region +fills the region .Fa buf of length .Fa nbytes -with ARC4-derived random data. +with random data. .Pp .Fn arc4random_uniform -will return a uniformly distributed random number less than +will return a single 32-bit value, uniformly distributed but less than .Fa upper_bound . -.Fn arc4random_uniform -is recommended over constructions like +This is recommended over constructions like .Dq Li arc4random() % upper_bound as it avoids "modulo bias" when the upper bound is not a power of two. -.Pp -The -.Fn arc4random_stir -function reads data from -.Pa /dev/urandom -and uses it to permute the S-Boxes via -.Fn arc4random_addrandom . -.Pp -There is no need to call -.Fn arc4random_stir -before using -.Fn arc4random -functions family, since -they automatically initialize themselves. +In the worst case, this function may consume multiple iterations +to ensure uniformity; see the source code to understand the problem +and solution. +.Sh RETURN VALUES +These functions are always successful, and no return value is +reserved to indicate an error. .Sh EXAMPLES The following produces a drop-in replacement for the traditional .Fn rand @@ -113,15 +119,25 @@ functions using .Dl "#define foo4random() (arc4random() % ((unsigned)RAND_MAX + 1))" .Sh SEE ALSO .Xr rand 3 , -.Xr random 3 , -.Xr srandomdev 3 +.Xr rand48 3 , +.Xr random 3 .Sh HISTORY -.Pa RC4 -has been designed by RSA Data Security, Inc. -It was posted anonymously -to the USENET and was confirmed to be equivalent by several sources who -had access to the original cipher. -Since -.Pa RC4 -used to be a trade secret, the cipher is now referred to as -.Pa ARC4 . +These functions first appeared in +.Ox 2.1 . +.Pp +The original version of this random number generator used the +RC4 (also known as ARC4) algorithm. +In +.Ox 5.5 +it was replaced with the ChaCha20 cipher, and it may be replaced +again in the future as cryptographic techniques advance. +A good mnemonic is +.Dq A Replacement Call for Random . +.Pp +The +.Fn arc4random +random number generator was first introduced in +.Fx 2.2.6 . +The ChaCha20 based implementation was introduced in +.Fx 12.0 , +with obsolete stir and addrandom interfaces removed at the same time. diff --git a/lib/libc/gen/arc4random.c b/lib/libc/gen/arc4random.c index 4c20680d305c..3a884fa8ace4 100644 --- a/lib/libc/gen/arc4random.c +++ b/lib/libc/gen/arc4random.c @@ -1,8 +1,10 @@ -/* $OpenBSD: arc4random.c,v 1.24 2013/06/11 16:59:50 deraadt Exp $ */ +/* $OpenBSD: arc4random.c,v 1.54 2015/09/13 08:31:47 guenther Exp $ */ /* * Copyright (c) 1996, David Mazieres * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -18,15 +20,7 @@ */ /* - * Arc4 random number generator for OpenBSD. - * - * This code is derived from section 17.1 of Applied Cryptography, - * second edition, which describes a stream cipher allegedly - * compatible with RSA Labs "RC4" cipher (the actual description of - * which is a trade secret). The same algorithm is used as a stream - * cipher called "arcfour" in Tatu Ylonen's ssh package. - * - * RC4 is a registered trademark of RSA Laboratories. + * ChaCha based random number generator for OpenBSD. */ #include @@ -35,232 +29,176 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include #include -#include -#include -#include -#include -#include #include - +#include +#include +#include +#include +#include +#include +#include + #include "libc_private.h" #include "un-namespace.h" -#ifdef __GNUC__ +#define KEYSTREAM_ONLY +#include "chacha.c" + +#define minimum(a, b) ((a) < (b) ? (a) : (b)) + +#if defined(__GNUC__) || defined(_MSC_VER) #define inline __inline -#else /* !__GNUC__ */ +#else /* __GNUC__ || _MSC_VER */ #define inline -#endif /* !__GNUC__ */ +#endif /* !__GNUC__ && !_MSC_VER */ -struct arc4_stream { - u_int8_t i; - u_int8_t j; - u_int8_t s[256]; -}; +#define KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) -static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +/* Marked INHERIT_ZERO, so zero'd out in fork children. */ +static struct _rs { + size_t rs_have; /* valid bytes at end of rs_buf */ + size_t rs_count; /* bytes till reseed */ +} *rs; -#define KEYSIZE 128 -#define _ARC4_LOCK() \ - do { \ - if (__isthreaded) \ - _pthread_mutex_lock(&arc4random_mtx); \ - } while (0) +/* Maybe be preserved in fork children, if _rs_allocate() decides. */ +static struct _rsx { + chacha_ctx rs_chacha; /* chacha context for random keystream */ + u_char rs_buf[RSBUFSZ]; /* keystream blocks */ +} *rsx; -#define _ARC4_UNLOCK() \ - do { \ - if (__isthreaded) \ - _pthread_mutex_unlock(&arc4random_mtx); \ - } while (0) +static inline int _rs_allocate(struct _rs **, struct _rsx **); +static inline void _rs_forkdetect(void); +#include "arc4random.h" -static int rs_initialized; -static struct arc4_stream rs; -static pid_t arc4_stir_pid; -static int arc4_count; - -extern int __sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, - void *newp, size_t newlen); - -static inline u_int8_t arc4_getbyte(void); -static void arc4_stir(void); +static inline void _rs_rekey(u_char *dat, size_t datlen); static inline void -arc4_init(void) +_rs_init(u_char *buf, size_t n) { - int n; + if (n < KEYSZ + IVSZ) + return; - for (n = 0; n < 256; n++) - rs.s[n] = n; - rs.i = 0; - rs.j = 0; -} - -static inline void -arc4_addrandom(u_char *dat, int datlen) -{ - int n; - u_int8_t si; - - rs.i--; - for (n = 0; n < 256; n++) { - rs.i = (rs.i + 1); - si = rs.s[rs.i]; - rs.j = (rs.j + si + dat[n % datlen]); - rs.s[rs.i] = rs.s[rs.j]; - rs.s[rs.j] = si; + if (rs == NULL) { + if (_rs_allocate(&rs, &rsx) == -1) + abort(); } - rs.j = rs.i; -} -size_t -__arc4_sysctl(u_char *buf, size_t size) -{ - int mib[2]; - size_t len, done; - - mib[0] = CTL_KERN; - mib[1] = KERN_ARND; - done = 0; - - do { - len = size; - if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1) - return (done); - done += len; - buf += len; - size -= len; - } while (size > 0); - - return (done); + chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8); + chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ, NULL); } static void -arc4_stir(void) +_rs_stir(void) { - u_char rdat[KEYSIZE]; - int i; + u_char rnd[KEYSZ + IVSZ]; - if (!rs_initialized) { - arc4_init(); - rs_initialized = 1; + if (getentropy(rnd, sizeof rnd) == -1) + _getentropy_fail(); + + if (!rs) + _rs_init(rnd, sizeof(rnd)); + else + _rs_rekey(rnd, sizeof(rnd)); + explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */ + + /* invalidate rs_buf */ + rs->rs_have = 0; + memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); + + rs->rs_count = 1600000; +} + +static inline void +_rs_stir_if_needed(size_t len) +{ + _rs_forkdetect(); + if (!rs || rs->rs_count <= len) + _rs_stir(); + if (rs->rs_count <= len) + rs->rs_count = 0; + else + rs->rs_count -= len; +} + +static inline void +_rs_rekey(u_char *dat, size_t datlen) +{ +#ifndef KEYSTREAM_ONLY + memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); +#endif + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf, + rsx->rs_buf, sizeof(rsx->rs_buf)); + /* mix in optional user provided data */ + if (dat) { + size_t i, m; + + m = minimum(datlen, KEYSZ + IVSZ); + for (i = 0; i < m; i++) + rsx->rs_buf[i] ^= dat[i]; } - if (__arc4_sysctl(rdat, KEYSIZE) != KEYSIZE) { - /* - * The sysctl cannot fail. If it does fail on some FreeBSD - * derivative or after some future change, just abort so that - * the problem will be found and fixed. abort is not normally - * suitable for a library but makes sense here. - */ - abort(); - } - - arc4_addrandom(rdat, KEYSIZE); - - /* - * Discard early keystream, as per recommendations in: - * "(Not So) Random Shuffles of RC4" by Ilya Mironov. - */ - for (i = 0; i < 3072; i++) - (void)arc4_getbyte(); - arc4_count = 1600000; + /* immediately reinit for backtracking resistance */ + _rs_init(rsx->rs_buf, KEYSZ + IVSZ); + memset(rsx->rs_buf, 0, KEYSZ + IVSZ); + rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ; } -static void -arc4_stir_if_needed(void) -{ - pid_t pid = getpid(); - - if (arc4_count <= 0 || !rs_initialized || arc4_stir_pid != pid) { - arc4_stir_pid = pid; - arc4_stir(); - } -} - -static inline u_int8_t -arc4_getbyte(void) -{ - u_int8_t si, sj; - - rs.i = (rs.i + 1); - si = rs.s[rs.i]; - rs.j = (rs.j + si); - sj = rs.s[rs.j]; - rs.s[rs.i] = sj; - rs.s[rs.j] = si; - return (rs.s[(si + sj) & 0xff]); -} - -static inline u_int32_t -arc4_getword(void) -{ - u_int32_t val; - val = arc4_getbyte() << 24; - val |= arc4_getbyte() << 16; - val |= arc4_getbyte() << 8; - val |= arc4_getbyte(); - return val; -} - -void -arc4random_stir(void) -{ - _ARC4_LOCK(); - arc4_stir(); - _ARC4_UNLOCK(); -} - -void -arc4random_addrandom(u_char *dat, int datlen) -{ - _ARC4_LOCK(); - if (!rs_initialized) - arc4_stir(); - arc4_addrandom(dat, datlen); - _ARC4_UNLOCK(); -} - -u_int32_t -arc4random(void) -{ - u_int32_t val; - _ARC4_LOCK(); - arc4_count -= 4; - arc4_stir_if_needed(); - val = arc4_getword(); - _ARC4_UNLOCK(); - return val; -} - -void -arc4random_buf(void *_buf, size_t n) +static inline void +_rs_random_buf(void *_buf, size_t n) { u_char *buf = (u_char *)_buf; - _ARC4_LOCK(); - arc4_stir_if_needed(); - while (n--) { - if (--arc4_count <= 0) - arc4_stir(); - buf[n] = arc4_getbyte(); + u_char *keystream; + size_t m; + + _rs_stir_if_needed(n); + while (n > 0) { + if (rs->rs_have > 0) { + m = minimum(n, rs->rs_have); + keystream = rsx->rs_buf + sizeof(rsx->rs_buf) + - rs->rs_have; + memcpy(buf, keystream, m); + memset(keystream, 0, m); + buf += m; + n -= m; + rs->rs_have -= m; + } + if (rs->rs_have == 0) + _rs_rekey(NULL, 0); } +} + +static inline void +_rs_random_u32(uint32_t *val) +{ + u_char *keystream; + + _rs_stir_if_needed(sizeof(*val)); + if (rs->rs_have < sizeof(*val)) + _rs_rekey(NULL, 0); + keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have; + memcpy(val, keystream, sizeof(*val)); + memset(keystream, 0, sizeof(*val)); + rs->rs_have -= sizeof(*val); +} + +uint32_t +arc4random(void) +{ + uint32_t val; + + _ARC4_LOCK(); + _rs_random_u32(&val); + _ARC4_UNLOCK(); + return val; +} + +void +arc4random_buf(void *buf, size_t n) +{ + _ARC4_LOCK(); + _rs_random_buf(buf, n); _ARC4_UNLOCK(); } - -#if 0 -/*-------- Test code for i386 --------*/ -#include -#include -int -main(int argc, char **argv) -{ - const int iter = 1000000; - int i; - pctrval v; - - v = rdtsc(); - for (i = 0; i < iter; i++) - arc4random(); - v = rdtsc() - v; - v /= iter; - - printf("%qd cycles\n", v); -} -#endif diff --git a/lib/libc/gen/arc4random.h b/lib/libc/gen/arc4random.h new file mode 100644 index 000000000000..a83b7a2e8861 --- /dev/null +++ b/lib/libc/gen/arc4random.h @@ -0,0 +1,74 @@ +/* $OpenBSD: arc4random.h,v 1.4 2015/01/15 06:57:18 deraadt Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +/* + * Stub functions for portability. + */ +#include + +#include + +static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER; +#define _ARC4_LOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_lock(&arc4random_mtx); \ + } while (0) + +#define _ARC4_UNLOCK() \ + do { \ + if (__isthreaded) \ + _pthread_mutex_unlock(&arc4random_mtx); \ + } while (0) + +static inline void +_getentropy_fail(void) +{ + raise(SIGKILL); +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ + struct { + struct _rs rs; + struct _rsx rsx; + } *p; + + if ((p = mmap(NULL, sizeof(*p), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + if (minherit(p, sizeof(*p), INHERIT_ZERO) == -1) { + munmap(p, sizeof(*p)); + return (-1); + } + + *rsp = &p->rs; + *rsxp = &p->rsx; + return (0); +} + +static inline void +_rs_forkdetect(void) +{ +} diff --git a/lib/libc/gen/getentropy.c b/lib/libc/gen/getentropy.c index bf7f18b3fd52..2e0f649a15be 100644 --- a/lib/libc/gen/getentropy.c +++ b/lib/libc/gen/getentropy.c @@ -31,12 +31,37 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include "libc_private.h" +extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t); + +static size_t +arnd_sysctl(u_char *buf, size_t size) +{ + int mib[2]; + size_t len, done; + + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + done = 0; + + do { + len = size; + if (__sysctl(mib, 2, buf, &len, NULL, 0) == -1) + return (done); + done += len; + buf += len; + size -= len; + } while (size > 0); + + return (done); +} + /* * If a newer libc is accidentally installed on an older kernel, provide high * quality random data anyway. The sysctl interface is not as fast and does @@ -54,7 +79,7 @@ getentropy_fallback(void *buf, size_t buflen) errno = EFAULT; return (-1); } - if (__arc4_sysctl(buf, buflen) != buflen) { + if (arnd_sysctl(buf, buflen) != buflen) { if (errno == EFAULT) return (-1); /* diff --git a/lib/libc/include/libc_private.h b/lib/libc/include/libc_private.h index 0985b5ed8741..aaa40deeb083 100644 --- a/lib/libc/include/libc_private.h +++ b/lib/libc/include/libc_private.h @@ -405,8 +405,6 @@ int __sys_futimens(int fd, const struct timespec *times) __hidden; int __sys_utimensat(int fd, const char *path, const struct timespec *times, int flag) __hidden; -__size_t __arc4_sysctl(unsigned char *, __size_t); - /* execve() with PATH processing to implement posix_spawnp() */ int _execvpe(const char *, char * const *, char * const *); diff --git a/sys/crypto/chacha20/chacha.c b/sys/crypto/chacha20/chacha.c index b3566087aee6..ac4eef222115 100644 --- a/sys/crypto/chacha20/chacha.c +++ b/sys/crypto/chacha20/chacha.c @@ -14,7 +14,6 @@ __FBSDID("$FreeBSD$"); #include - typedef uint8_t u8; typedef uint32_t u32; @@ -57,7 +56,7 @@ typedef struct chacha_ctx chacha_ctx; static const char sigma[16] = "expand 32-byte k"; static const char tau[16] = "expand 16-byte k"; -void +LOCAL void chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) { const char *constants; @@ -82,7 +81,7 @@ chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) x->input[3] = U8TO32_LITTLE(constants + 12); } -void +LOCAL void chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) { x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0); @@ -91,7 +90,7 @@ chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter) x->input[15] = U8TO32_LITTLE(iv + 4); } -void +LOCAL void chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) { u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; @@ -169,6 +168,7 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) x14 = PLUS(x14,j14); x15 = PLUS(x15,j15); +#ifndef KEYSTREAM_ONLY x0 = XOR(x0,U8TO32_LITTLE(m + 0)); x1 = XOR(x1,U8TO32_LITTLE(m + 4)); x2 = XOR(x2,U8TO32_LITTLE(m + 8)); @@ -185,6 +185,7 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) x13 = XOR(x13,U8TO32_LITTLE(m + 52)); x14 = XOR(x14,U8TO32_LITTLE(m + 56)); x15 = XOR(x15,U8TO32_LITTLE(m + 60)); +#endif j12 = PLUSONE(j12); if (!j12) { @@ -219,6 +220,8 @@ chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) } bytes -= 64; c += 64; +#ifndef KEYSTREAM_ONLY m += 64; +#endif } } diff --git a/sys/crypto/chacha20/chacha.h b/sys/crypto/chacha20/chacha.h index 02106eaa250d..e67cc81264cd 100644 --- a/sys/crypto/chacha20/chacha.h +++ b/sys/crypto/chacha20/chacha.h @@ -23,9 +23,15 @@ struct chacha_ctx { #define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN) #define CHACHA_BLOCKLEN 64 -void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits); -void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr); -void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m, +#ifdef _KERNEL +#define LOCAL +#else +#define LOCAL static +#endif + +LOCAL void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits); +LOCAL void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr); +LOCAL void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m, u_char *c, u_int bytes); #endif /* CHACHA_H */ From c8b8b38e5f605f3c85bd7c8723b147734905565a Mon Sep 17 00:00:00 2001 From: Mateusz Piotrowski <0mp@FreeBSD.org> Date: Sun, 19 Aug 2018 17:42:49 +0000 Subject: [PATCH 031/222] Document socket control message routines for ancillary data access (CMSG_DATA). PR: 227777 Reviewed by: bcr, eadler Approved by: mat (mentor), manpages (bcr) Obtained from: OpenBSD Differential Revision: https://reviews.freebsd.org/D15215 --- lib/libc/sys/recv.2 | 3 +- lib/libc/sys/send.2 | 5 +- lib/libc/sys/socket.2 | 3 +- share/man/man3/CMSG_DATA.3 | 214 +++++++++++++++++++++++++++++++++++++ share/man/man3/Makefile | 5 + share/man/man4/ip.4 | 3 +- share/man/man4/ip6.4 | 3 +- share/man/man4/unix.4 | 3 +- 8 files changed, 232 insertions(+), 7 deletions(-) create mode 100644 share/man/man3/CMSG_DATA.3 diff --git a/lib/libc/sys/recv.2 b/lib/libc/sys/recv.2 index 899f2cd1d968..354ba90ebfc6 100644 --- a/lib/libc/sys/recv.2 +++ b/lib/libc/sys/recv.2 @@ -28,7 +28,7 @@ .\" @(#)recv.2 8.3 (Berkeley) 2/21/94 .\" $FreeBSD$ .\" -.Dd May 20, 2018 +.Dd August 19, 2018 .Dt RECV 2 .Os .Sh NAME @@ -366,6 +366,7 @@ address space. .Xr read 2 , .Xr select 2 , .Xr socket 2 , +.Xr CMSG_DATA 3 , .Xr unix 4 .Sh HISTORY The diff --git a/lib/libc/sys/send.2 b/lib/libc/sys/send.2 index 2e3916c8793e..c5a04f1d8bba 100644 --- a/lib/libc/sys/send.2 +++ b/lib/libc/sys/send.2 @@ -28,7 +28,7 @@ .\" From: @(#)send.2 8.2 (Berkeley) 2/21/94 .\" $FreeBSD$ .\" -.Dd August 18, 2016 +.Dd August 19, 2018 .Dt SEND 2 .Os .Sh NAME @@ -242,7 +242,8 @@ is not connected. .Xr recv 2 , .Xr select 2 , .Xr socket 2 , -.Xr write 2 +.Xr write 2 , +.Xr CMSG_DATA 3 .Sh HISTORY The .Fn send diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2 index 55298531c70e..b23d207c9730 100644 --- a/lib/libc/sys/socket.2 +++ b/lib/libc/sys/socket.2 @@ -28,7 +28,7 @@ .\" From: @(#)socket.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd June 10, 2017 +.Dd August 19, 2018 .Dt SOCKET 2 .Os .Sh NAME @@ -299,6 +299,7 @@ The socket type is not supported by the protocol. .Xr shutdown 2 , .Xr socketpair 2 , .Xr write 2 , +.Xr CMSG_DATA 3 , .Xr getprotoent 3 , .Xr netgraph 4 , .Xr protocols 5 diff --git a/share/man/man3/CMSG_DATA.3 b/share/man/man3/CMSG_DATA.3 new file mode 100644 index 000000000000..7654ac153944 --- /dev/null +++ b/share/man/man3/CMSG_DATA.3 @@ -0,0 +1,214 @@ +.\" Written by Jared Yanovich +.\" Public domain, July 3, 2005 +.\" +.\" $FreeBSD$ +.Dd August 19, 2018 +.Dt CMSG_DATA 3 +.Os +.Sh NAME +.Nm CMSG_DATA , +.Nm CMSG_FIRSTHDR , +.Nm CMSG_LEN , +.Nm CMSG_NXTHDR , +.Nm CMSG_SPACE +.Nd socket control message routines for ancillary data access +.Sh SYNOPSIS +.In sys/socket.h +.Ft unsigned char * +.Fn CMSG_DATA "struct cmsghdr *" +.Ft struct cmsghdr * +.Fn CMSG_FIRSTHDR "struct msghdr *" +.Ft size_t +.Fn CMSG_LEN "size_t" +.Ft struct cmsghdr * +.Fn CMSG_NXTHDR "struct msghdr *" "struct cmsghdr *" +.Ft size_t +.Fn CMSG_SPACE "size_t" +.Sh DESCRIPTION +The control message API is used to construct ancillary data objects for +use in control messages sent and received across sockets. +.Pp +Control messages are passed around by the +.Xr recvmsg 2 +and +.Xr sendmsg 2 +system calls. +The +.Vt cmsghdr +structure, described in +.Xr recvmsg 2 , +is used to specify a chain of control messages. +.Pp +These routines should be used instead of directly accessing the control +message header members and data buffers as they ensure that necessary +alignment constraints are met. +.Pp +The following routines are provided: +.Bl -tag -width Ds +.It Fn CMSG_DATA cmsg +This routine accesses the data portion of the control message header +.Fa cmsg . +It ensures proper alignment constraints on the beginning of ancillary +data are met. +.It Fn CMSG_FIRSTHDR mhdr +This routine accesses the first control message attached to the +message +.Fa msg . +If no control messages are attached to the message, this routine +returns +.Dv NULL . +.It Fn CMSG_LEN len +This routine determines the size in bytes of a control message, +which includes the control message header. +.Fa len +specifies the length of the data held by the control message. +This value is what is normally stored in the +.Fa cmsg_len +of each control message. +This routine accounts for any alignment constraints on the beginning of +ancillary data. +.It Fn CMSG_NXTHDR mhdr cmsg +This routine returns the location of the control message following +.Fa cmsg +in the message +.Fa mhdr . +If +.Fa cmsg +is the last control message in the chain, this routine returns +.Dv NULL . +.It Fn CMSG_SPACE len +This routine determines the size in bytes needed to hold a control +message and its contents of length +.Fa len , +which includes the control message header. +This value is what is normally stored in +.Fa msg_msgcontrollen . +This routine accounts for any alignment constraints on the beginning of +ancillary data as well as any needed to pad the next control message. +.El +.Sh EXAMPLES +The following example constructs a control message containing a file descriptor +in the parent process and passes it over a pre-shared socket over the child +process. +Then the child process sends a "hello" string to the parent process using the +received file descriptor. +.Bd -literal +#include + +#include +#include +#include +#include +#include + +#define HELLOLEN sizeof("hello") + +int +main() +{ + struct msghdr msg; + union { + struct cmsghdr hdr; + unsigned char buf[CMSG_SPACE(sizeof(int))]; + } cmsgbuf; + char buf[HELLOLEN]; + int hellofd[2]; + int presharedfd[2]; + struct cmsghdr *cmsg; + + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, presharedfd) == -1) + err(EX_OSERR, "failed to create a pre-shared socket pair"); + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = &cmsgbuf.buf; + msg.msg_controllen = sizeof(cmsgbuf.buf); + msg.msg_iov = NULL; + msg.msg_iovlen = 0; + + switch (fork()) { + case -1: + err(EX_OSERR, "fork"); + case 0: + close(presharedfd[0]); + strlcpy(buf, "hello", HELLOLEN); + + if (recvmsg(presharedfd[1], &msg, 0) == -1) + err(EX_IOERR, "failed to receive a message"); + if (msg.msg_flags & (MSG_CTRUNC | MSG_TRUNC)) + errx(EX_IOERR, "control message truncated"); + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && + cmsg->cmsg_level == SOL_SOCKET && + cmsg->cmsg_type == SCM_RIGHTS) { + hellofd[1] = *(int *)CMSG_DATA(cmsg); + printf("child: sending '%s'\n", buf); + if (write(hellofd[1], buf, HELLOLEN) == -1) + err(EX_IOERR, "failed to send 'hello'"); + } + } + break; + default: + close(presharedfd[1]); + + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, hellofd) == -1) + err(EX_OSERR, "failed to create a 'hello' socket pair"); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *(int *)CMSG_DATA(cmsg) = hellofd[1]; + + if (sendmsg(presharedfd[0], &msg, 0) == -1) + err(EX_IOERR, "sendmsg"); + close(hellofd[1]); + + if (read(hellofd[0], buf, HELLOLEN) == -1) + err(EX_IOERR, "faild to receive 'hello'"); + printf("parent: received '%s'\n", buf); + break; + } + + return (0); +} +.Ed +.Sh SEE ALSO +.Xr recvmsg 2 , +.Xr sendmsg 2 , +.Xr socket 2 , +.Xr ip 4 , +.Xr ip6 4 , +.Xr unix 4 +.Sh STANDARDS +.Bl -item +.It +.Rs +.%A W. Stevens +.%A M. Thomas +.%T "Advanced Sockets API for IPv6" +.%R RFC 2292 +.%D February 1998 +.Re +.It +.Rs +.%A W. Stevens +.%A M. Thomas +.%A E. Nordmark +.%A T. Jinmei +.%T "Advanced Sockets Application Program Interface (API) for IPv6" +.%R RFC 3542 +.%D May 2003 +.Re +.El +.Sh HISTORY +The control message API first appeared in +.Bx 4.2 . +This manual page was originally written by +.An Jared Yanovich Aq Mt jaredy@OpenBSD.org +for +.Ox 3.8 +and eventually brought to +.Fx 12.0 +by +.An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org . diff --git a/share/man/man3/Makefile b/share/man/man3/Makefile index ff2cb02827d4..8267f9f24e40 100644 --- a/share/man/man3/Makefile +++ b/share/man/man3/Makefile @@ -8,6 +8,7 @@ PACKAGE=runtime-manuals MAN= assert.3 \ ATOMIC_VAR_INIT.3 \ bitstring.3 \ + CMSG_DATA.3 \ end.3 \ fpgetround.3 \ intro.3 \ @@ -57,6 +58,10 @@ MLINKS+= bitstring.3 bit_alloc.3 \ bitstring.3 bit_set.3 \ bitstring.3 bitstr_size.3 \ bitstring.3 bit_test.3 +MLINKS+= CMSG_DATA.3 CMSG_FIRSTHDR.3 \ + CMSG_DATA.3 CMSG_LEN.3 \ + CMSG_DATA.3 CMSG_NEXTHDR.3 \ + CMSG_DATA.3 CMSG_SPACE.3 MLINKS+= end.3 edata.3 \ end.3 etext.3 MLINKS+= fpgetround.3 fpgetmask.3 \ diff --git a/share/man/man4/ip.4 b/share/man/man4/ip.4 index d9ee8175ac3a..555aca1e36df 100644 --- a/share/man/man4/ip.4 +++ b/share/man/man4/ip.4 @@ -28,7 +28,7 @@ .\" @(#)ip.4 8.2 (Berkeley) 11/30/93 .\" $FreeBSD$ .\" -.Dd September 1, 2014 +.Dd August 19, 2018 .Dt IP 4 .Os .Sh NAME @@ -888,6 +888,7 @@ field was not equal to the length of the datagram written to the socket. .Xr recv 2 , .Xr send 2 , .Xr byteorder 3 , +.Xr CMSG_DATA 3 , .Xr sourcefilter 3 , .Xr icmp 4 , .Xr igmp 4 , diff --git a/share/man/man4/ip6.4 b/share/man/man4/ip6.4 index a1b06fe8cab7..9828510922e1 100644 --- a/share/man/man4/ip6.4 +++ b/share/man/man4/ip6.4 @@ -30,7 +30,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 13, 2011 +.Dd August 19, 2018 .Dt IP6 4 .Os .Sh NAME @@ -651,6 +651,7 @@ An ancillary data object was improperly formed. .Xr send 2 , .Xr setsockopt 2 , .Xr socket 2 , +.Xr CMSG_DATA 3 , .\" .Xr inet6_option_space 3 , .\" .Xr inet6_rthdr_space 3 , .Xr if_nametoindex 3 , diff --git a/share/man/man4/unix.4 b/share/man/man4/unix.4 index 86b291ed29db..c63ef8eaa531 100644 --- a/share/man/man4/unix.4 +++ b/share/man/man4/unix.4 @@ -28,7 +28,7 @@ .\" @(#)unix.4 8.1 (Berkeley) 6/9/93 .\" $FreeBSD$ .\" -.Dd February 3, 2017 +.Dd August 19, 2018 .Dt UNIX 4 .Os .Sh NAME @@ -350,6 +350,7 @@ socket option. .Xr sendto 2 , .Xr setsockopt 2 , .Xr socket 2 , +.Xr CMSG_DATA 3 , .Xr intro 4 .Rs .%T "An Introductory 4.3 BSD Interprocess Communication Tutorial" From 56019a539f11a1f5d7783ea25c9ae165842ec6d7 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sun, 19 Aug 2018 17:47:30 +0000 Subject: [PATCH 032/222] Bump __FreeBSD_version after r338059 (Chacha20 based arc4random(3) and deprecation of arc4random_stir and arc4random_addrandom). --- sys/sys/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sys/param.h b/sys/sys/param.h index d9ea39a31a93..60f3cb9aa6a6 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -60,7 +60,7 @@ * in the range 5 to 9. */ #undef __FreeBSD_version -#define __FreeBSD_version 1200078 /* Master, propagated to newvers */ +#define __FreeBSD_version 1200079 /* Master, propagated to newvers */ /* * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD, From 2734fedc4e55ff6000174dd324f874e9b74cb2be Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sun, 19 Aug 2018 17:57:51 +0000 Subject: [PATCH 033/222] Fix a couple of comment nits. --- sys/x86/x86/local_apic.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index aed5d2947a29..7e3fcac1e78e 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -1925,8 +1925,8 @@ apic_setup_io(void *dummy __unused) /* * Finish setting up the local APIC on the BSP once we know * how to properly program the LINT pins. In particular, this - * enables the EOI suppression mode, if LAPIC support it and - * user did not disabled the mode. + * enables the EOI suppression mode, if LAPIC supports it and + * user did not disable the mode. */ lapic_setup(1); if (bootverbose) From 6112ee09cb8dd2f6734fb3d73c1ccb13d4cef4d5 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 18:12:11 +0000 Subject: [PATCH 034/222] lualoader: Stop exporting drawer.draw drawer.draw is the back-end for drawlogo and drawbrand and should not be used directly. --- stand/lua/drawer.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/stand/lua/drawer.lua b/stand/lua/drawer.lua index 5f0b020cef11..2d24a95393a6 100644 --- a/stand/lua/drawer.lua +++ b/stand/lua/drawer.lua @@ -83,6 +83,13 @@ local function getLogodef(logo) return logodef end +local function draw(x, y, logo) + for i = 1, #logo do + screen.setcursor(x, y + i - 1) + printc(logo[i]) + end +end + fbsd_brand = { " ______ ____ _____ _____ ", " | ____| | _ \\ / ____| __ \\ ", @@ -320,13 +327,6 @@ function drawer.drawbox() printc(menu_header) end -function drawer.draw(x, y, logo) - for i = 1, #logo do - screen.setcursor(x, y + i - 1) - printc(logo[i]) - end -end - function drawer.drawbrand() local x = tonumber(loader.getenv("loader_brand_x")) or drawer.brand_position.x @@ -343,7 +343,7 @@ function drawer.drawbrand() x = x + drawer.shift.x y = y + drawer.shift.y - drawer.draw(x, y, graphic) + draw(x, y, graphic) end function drawer.drawlogo() @@ -381,7 +381,7 @@ function drawer.drawlogo() y = y + logodef.shift.y end - drawer.draw(x, y, logodef.graphic) + draw(x, y, logodef.graphic) end return drawer From 295506bf9c871f873978f79ff282d63e0f2e347b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 19 Aug 2018 18:18:19 +0000 Subject: [PATCH 035/222] Turn back the clock just a little: make userboot.so always be 4th Turns out there was a hidden dependency we hasn't counted upon. The host load /boot/userboot.so to boot the VMs it runs. This means that the change to lua meant suddently that nobody could run their older VMs because LUA wasn't in 10.0, last month's HardenedBSD, 11.2 or whatever. Even more than for the /boot/loader* binaries, we need a good coexistance strategy for this. While that's being designed and implemented, drop back to always 4th for userboot.so. This will fail safe in all but the most extreme environments (but lua-only hacks to .lua files won't be processes in VMs until we fix it). Differential Review: https://reviews.freebsd.org/D16805 --- UPDATING | 3 +++ stand/userboot/userboot/Makefile | 1 + 2 files changed, 4 insertions(+) diff --git a/UPDATING b/UPDATING index 990937d547ee..f1478d8fb789 100644 --- a/UPDATING +++ b/UPDATING @@ -40,6 +40,9 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: loader and loader_4th instead of loader and loader_lua, the new default. If you are using UEFI it will create the proper hard link to loader.efi. + bhyve uses userboot.so. It remains 4th-only until some issues are solved + regarding coexisting with multiple versions of FreeBSD are resolved. + 20180815: ls(1) now respects the COLORTERM environment variable used in other systems and software to indicate that a colored terminal is both diff --git a/stand/userboot/userboot/Makefile b/stand/userboot/userboot/Makefile index 1fc71782dfdf..b375083917f1 100644 --- a/stand/userboot/userboot/Makefile +++ b/stand/userboot/userboot/Makefile @@ -5,6 +5,7 @@ LOADER_UFS_SUPPORT?= yes LOADER_CD9660_SUPPORT?= no LOADER_EXT2FS_SUPPORT?= no PIC=yes +LOADER_INTERP=4th .include From 12eaa305dd50059af1410c1a897c968ae5d2fa78 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 18:22:01 +0000 Subject: [PATCH 036/222] lualoader: Hide most of the internal drawing functions Ideally, all of the functionality to revamp the loader screen has associated APIs that are flexible enough that third-party scripts wouldn't need to override these. --- stand/lua/drawer.lua | 350 +++++++++++++++++++++---------------------- 1 file changed, 175 insertions(+), 175 deletions(-) diff --git a/stand/lua/drawer.lua b/stand/lua/drawer.lua index 2d24a95393a6..4b8b9a3706c6 100644 --- a/stand/lua/drawer.lua +++ b/stand/lua/drawer.lua @@ -90,6 +90,176 @@ local function draw(x, y, logo) end end +local function drawmenu(menudef) + local x = drawer.menu_position.x + local y = drawer.menu_position.y + + x = x + drawer.shift.x + y = y + drawer.shift.y + + -- print the menu and build the alias table + local alias_table = {} + local entry_num = 0 + local menu_entries = menudef.entries + local effective_line_num = 0 + if type(menu_entries) == "function" then + menu_entries = menu_entries() + end + for _, e in ipairs(menu_entries) do + -- Allow menu items to be conditionally visible by specifying + -- a visible function. + if e.visible ~= nil and not e.visible() then + goto continue + end + effective_line_num = effective_line_num + 1 + if e.entry_type ~= core.MENU_SEPARATOR then + entry_num = entry_num + 1 + screen.setcursor(x, y + effective_line_num) + + printc(entry_num .. ". " .. menuEntryName(menudef, e)) + + -- fill the alias table + alias_table[tostring(entry_num)] = e + if e.alias ~= nil then + for _, a in ipairs(e.alias) do + alias_table[a] = e + end + end + else + screen.setcursor(x, y + effective_line_num) + printc(menuEntryName(menudef, e)) + end + ::continue:: + end + return alias_table +end + +local function drawbox() + local x = drawer.menu_position.x - 3 + local y = drawer.menu_position.y - 1 + local w = drawer.frame_size.w + local h = drawer.frame_size.h + + local framestyle = loader.getenv("loader_menu_frame") or "double" + local framespec = drawer.frame_styles[framestyle] + -- If we don't have a framespec for the current frame style, just don't + -- draw a box. + if framespec == nil then + return + end + + local hl = framespec.horizontal + local vl = framespec.vertical + + local tl = framespec.top_left + local bl = framespec.bottom_left + local tr = framespec.top_right + local br = framespec.bottom_right + + x = x + drawer.shift.x + y = y + drawer.shift.y + + screen.setcursor(x, y); printc(tl) + screen.setcursor(x, y + h); printc(bl) + screen.setcursor(x + w, y); printc(tr) + screen.setcursor(x + w, y + h); printc(br) + + screen.setcursor(x + 1, y) + for _ = 1, w - 1 do + printc(hl) + end + + screen.setcursor(x + 1, y + h) + for _ = 1, w - 1 do + printc(hl) + end + + for i = 1, h - 1 do + screen.setcursor(x, y + i) + printc(vl) + screen.setcursor(x + w, y + i) + printc(vl) + end + + local menu_header = loader.getenv("loader_menu_title") or + "Welcome to FreeBSD" + local menu_header_align = loader.getenv("loader_menu_title_align") + local menu_header_x + + if menu_header_align ~= nil then + menu_header_align = menu_header_align:lower() + if menu_header_align == "left" then + -- Just inside the left border on top + menu_header_x = x + 1 + elseif menu_header_align == "right" then + -- Just inside the right border on top + menu_header_x = x + w - #menu_header + end + end + if menu_header_x == nil then + menu_header_x = x + (w / 2) - (#menu_header / 2) + end + screen.setcursor(menu_header_x, y) + printc(menu_header) +end + +local function drawbrand() + local x = tonumber(loader.getenv("loader_brand_x")) or + drawer.brand_position.x + local y = tonumber(loader.getenv("loader_brand_y")) or + drawer.brand_position.y + + local branddef = getBranddef(loader.getenv("loader_brand")) + + if branddef == nil then + branddef = getBranddef(drawer.default_brand) + end + + local graphic = branddef.graphic + + x = x + drawer.shift.x + y = y + drawer.shift.y + draw(x, y, graphic) +end + +local function drawlogo() + local x = tonumber(loader.getenv("loader_logo_x")) or + drawer.logo_position.x + local y = tonumber(loader.getenv("loader_logo_y")) or + drawer.logo_position.y + + local logo = loader.getenv("loader_logo") + local colored = color.isEnabled() + + local logodef = getLogodef(logo) + + if logodef == nil or logodef.graphic == nil or + (not colored and logodef.requires_color) then + -- Choose a sensible default + if colored then + logodef = getLogodef("orb") + else + logodef = getLogodef("orbbw") + end + end + + if logodef ~= nil and logodef.graphic == none then + drawer.shift = logodef.shift + else + drawer.shift = drawer.default_shift + end + + x = x + drawer.shift.x + y = y + drawer.shift.y + + if logodef ~= nil and logodef.shift ~= nil then + x = x + logodef.shift.x + y = y + logodef.shift.y + end + + draw(x, y, logodef.graphic) +end + fbsd_brand = { " ______ ____ _____ _____ ", " | ____| | _ \\ / ____| __ \\ ", @@ -205,183 +375,13 @@ drawer.frame_styles = { }, } -function drawer.drawscreen(menu_opts) +function drawer.drawscreen(menudef) -- drawlogo() must go first. -- it determines the positions of other elements - drawer.drawlogo() - drawer.drawbrand() - drawer.drawbox() - return drawer.drawmenu(menu_opts) -end - -function drawer.drawmenu(menudef) - local x = drawer.menu_position.x - local y = drawer.menu_position.y - - x = x + drawer.shift.x - y = y + drawer.shift.y - - -- print the menu and build the alias table - local alias_table = {} - local entry_num = 0 - local menu_entries = menudef.entries - local effective_line_num = 0 - if type(menu_entries) == "function" then - menu_entries = menu_entries() - end - for _, e in ipairs(menu_entries) do - -- Allow menu items to be conditionally visible by specifying - -- a visible function. - if e.visible ~= nil and not e.visible() then - goto continue - end - effective_line_num = effective_line_num + 1 - if e.entry_type ~= core.MENU_SEPARATOR then - entry_num = entry_num + 1 - screen.setcursor(x, y + effective_line_num) - - printc(entry_num .. ". " .. menuEntryName(menudef, e)) - - -- fill the alias table - alias_table[tostring(entry_num)] = e - if e.alias ~= nil then - for _, a in ipairs(e.alias) do - alias_table[a] = e - end - end - else - screen.setcursor(x, y + effective_line_num) - printc(menuEntryName(menudef, e)) - end - ::continue:: - end - return alias_table -end - -function drawer.drawbox() - local x = drawer.menu_position.x - 3 - local y = drawer.menu_position.y - 1 - local w = drawer.frame_size.w - local h = drawer.frame_size.h - - local framestyle = loader.getenv("loader_menu_frame") or "double" - local framespec = drawer.frame_styles[framestyle] - -- If we don't have a framespec for the current frame style, just don't - -- draw a box. - if framespec == nil then - return - end - - local hl = framespec.horizontal - local vl = framespec.vertical - - local tl = framespec.top_left - local bl = framespec.bottom_left - local tr = framespec.top_right - local br = framespec.bottom_right - - x = x + drawer.shift.x - y = y + drawer.shift.y - - screen.setcursor(x, y); printc(tl) - screen.setcursor(x, y + h); printc(bl) - screen.setcursor(x + w, y); printc(tr) - screen.setcursor(x + w, y + h); printc(br) - - screen.setcursor(x + 1, y) - for _ = 1, w - 1 do - printc(hl) - end - - screen.setcursor(x + 1, y + h) - for _ = 1, w - 1 do - printc(hl) - end - - for i = 1, h - 1 do - screen.setcursor(x, y + i) - printc(vl) - screen.setcursor(x + w, y + i) - printc(vl) - end - - local menu_header = loader.getenv("loader_menu_title") or - "Welcome to FreeBSD" - local menu_header_align = loader.getenv("loader_menu_title_align") - local menu_header_x - - if menu_header_align ~= nil then - menu_header_align = menu_header_align:lower() - if menu_header_align == "left" then - -- Just inside the left border on top - menu_header_x = x + 1 - elseif menu_header_align == "right" then - -- Just inside the right border on top - menu_header_x = x + w - #menu_header - end - end - if menu_header_x == nil then - menu_header_x = x + (w / 2) - (#menu_header / 2) - end - screen.setcursor(menu_header_x, y) - printc(menu_header) -end - -function drawer.drawbrand() - local x = tonumber(loader.getenv("loader_brand_x")) or - drawer.brand_position.x - local y = tonumber(loader.getenv("loader_brand_y")) or - drawer.brand_position.y - - local branddef = getBranddef(loader.getenv("loader_brand")) - - if branddef == nil then - branddef = getBranddef(drawer.default_brand) - end - - local graphic = branddef.graphic - - x = x + drawer.shift.x - y = y + drawer.shift.y - draw(x, y, graphic) -end - -function drawer.drawlogo() - local x = tonumber(loader.getenv("loader_logo_x")) or - drawer.logo_position.x - local y = tonumber(loader.getenv("loader_logo_y")) or - drawer.logo_position.y - - local logo = loader.getenv("loader_logo") - local colored = color.isEnabled() - - local logodef = getLogodef(logo) - - if logodef == nil or logodef.graphic == nil or - (not colored and logodef.requires_color) then - -- Choose a sensible default - if colored then - logodef = getLogodef("orb") - else - logodef = getLogodef("orbbw") - end - end - - if logodef ~= nil and logodef.graphic == none then - drawer.shift = logodef.shift - else - drawer.shift = drawer.default_shift - end - - x = x + drawer.shift.x - y = y + drawer.shift.y - - if logodef ~= nil and logodef.shift ~= nil then - x = x + logodef.shift.x - y = y + logodef.shift.y - end - - draw(x, y, logodef.graphic) + drawlogo() + drawbrand() + drawbox() + return drawmenu(menudef) end return drawer From a9edc01b20017cfca934b574bca2699be4cf728b Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 18:37:33 +0000 Subject: [PATCH 037/222] lualoader: Hide the rest of the private interfaces These are less controversial than the others, thus done in a separate commit. These are all used internally and ways to override are provided via soon-to-be-documented API or loader.conf(5) variables. --- stand/lua/drawer.lua | 102 ++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 46 deletions(-) diff --git a/stand/lua/drawer.lua b/stand/lua/drawer.lua index 4b8b9a3706c6..ae83f012e287 100644 --- a/stand/lua/drawer.lua +++ b/stand/lua/drawer.lua @@ -39,8 +39,18 @@ local drawer = {} local fbsd_brand local none +local menu_name_handlers +local branddefs +local logodefs +local brand_position +local logo_position +local menu_position +local frame_size +local default_shift +local shift + local function menuEntryName(drawing_menu, entry) - local name_handler = drawer.menu_name_handlers[entry.entry_type] + local name_handler = menu_name_handlers[entry.entry_type] if name_handler ~= nil then return name_handler(drawing_menu, entry) @@ -56,12 +66,12 @@ local function getBranddef(brand) return nil end -- Look it up - local branddef = drawer.branddefs[brand] + local branddef = branddefs[brand] -- Try to pull it in if branddef == nil then try_include('brand-' .. brand) - branddef = drawer.branddefs[brand] + branddef = branddefs[brand] end return branddef @@ -72,12 +82,12 @@ local function getLogodef(logo) return nil end -- Look it up - local logodef = drawer.logodefs[logo] + local logodef = logodefs[logo] -- Try to pull it in if logodef == nil then try_include('logo-' .. logo) - logodef = drawer.logodefs[logo] + logodef = logodefs[logo] end return logodef @@ -91,11 +101,11 @@ local function draw(x, y, logo) end local function drawmenu(menudef) - local x = drawer.menu_position.x - local y = drawer.menu_position.y + local x = menu_position.x + local y = menu_position.y - x = x + drawer.shift.x - y = y + drawer.shift.y + x = x + shift.x + y = y + shift.y -- print the menu and build the alias table local alias_table = {} @@ -135,10 +145,10 @@ local function drawmenu(menudef) end local function drawbox() - local x = drawer.menu_position.x - 3 - local y = drawer.menu_position.y - 1 - local w = drawer.frame_size.w - local h = drawer.frame_size.h + local x = menu_position.x - 3 + local y = menu_position.y - 1 + local w = frame_size.w + local h = frame_size.h local framestyle = loader.getenv("loader_menu_frame") or "double" local framespec = drawer.frame_styles[framestyle] @@ -156,8 +166,8 @@ local function drawbox() local tr = framespec.top_right local br = framespec.bottom_right - x = x + drawer.shift.x - y = y + drawer.shift.y + x = x + shift.x + y = y + shift.y screen.setcursor(x, y); printc(tl) screen.setcursor(x, y + h); printc(bl) @@ -205,9 +215,9 @@ end local function drawbrand() local x = tonumber(loader.getenv("loader_brand_x")) or - drawer.brand_position.x + brand_position.x local y = tonumber(loader.getenv("loader_brand_y")) or - drawer.brand_position.y + brand_position.y local branddef = getBranddef(loader.getenv("loader_brand")) @@ -217,16 +227,16 @@ local function drawbrand() local graphic = branddef.graphic - x = x + drawer.shift.x - y = y + drawer.shift.y + x = x + shift.x + y = y + shift.y draw(x, y, graphic) end local function drawlogo() local x = tonumber(loader.getenv("loader_logo_x")) or - drawer.logo_position.x + logo_position.x local y = tonumber(loader.getenv("loader_logo_y")) or - drawer.logo_position.y + logo_position.y local logo = loader.getenv("loader_logo") local colored = color.isEnabled() @@ -244,13 +254,13 @@ local function drawlogo() end if logodef ~= nil and logodef.graphic == none then - drawer.shift = logodef.shift + shift = logodef.shift else - drawer.shift = drawer.default_shift + shift = default_shift end - x = x + drawer.shift.x - y = y + drawer.shift.y + x = x + shift.x + y = y + shift.y if logodef ~= nil and logodef.shift ~= nil then x = x + logodef.shift.x @@ -271,10 +281,7 @@ fbsd_brand = { } none = {""} --- Module exports -drawer.default_brand = 'fbsd' - -drawer.menu_name_handlers = { +menu_name_handlers = { -- Menu name handlers should take the menu being drawn and entry being -- drawn as parameters, and return the name of the item. -- This is designed so that everything, including menu separators, may @@ -303,14 +310,7 @@ drawer.menu_name_handlers = { end, } -drawer.brand_position = {x = 2, y = 1} -drawer.logo_position = {x = 46, y = 4} -drawer.menu_position = {x = 5, y = 10} -drawer.frame_size = {w = 42, h = 13} -drawer.default_shift = {x = 0, y = 0} -drawer.shift = drawer.default_shift - -drawer.branddefs = { +branddefs = { -- Indexed by valid values for loader_brand in loader.conf(5). Valid -- keys are: graphic (table depicting graphic) ["fbsd"] = { @@ -321,15 +321,7 @@ drawer.branddefs = { }, } -function drawer.addBrand(name, def) - drawer.branddefs[name] = def -end - -function drawer.addLogo(name, def) - drawer.logodefs[name] = def -end - -drawer.logodefs = { +logodefs = { -- Indexed by valid values for loader_logo in loader.conf(5). Valid keys -- are: requires_color (boolean), graphic (table depicting graphic), and -- shift (table containing x and y). @@ -345,6 +337,24 @@ drawer.logodefs = { }, } +brand_position = {x = 2, y = 1} +logo_position = {x = 46, y = 4} +menu_position = {x = 5, y = 10} +frame_size = {w = 42, h = 13} +default_shift = {x = 0, y = 0} +shift = default_shift + +-- Module exports +drawer.default_brand = 'fbsd' + +function drawer.addBrand(name, def) + branddefs[name] = def +end + +function drawer.addLogo(name, def) + logodefs[name] = def +end + drawer.frame_styles = { -- Indexed by valid values for loader_menu_frame in loader.conf(5). -- All of the keys appearing below must be set for any menu frame style From 2c690e2a40fd4213366ae7ee7734cbe82d1d218a Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Sun, 19 Aug 2018 18:43:10 +0000 Subject: [PATCH 038/222] lualoader: Add drawer-exported variables for default logodefs Uncovered while writing the documentation from this, we previously explicitly fell back to orb or orbbw if an invalid or incompatible logodef was selected -- in contrast to branddefs, which have an exported variable that one can whip up a quick local.lua to override in a safe manner that works regardless of whether or not loader.conf(5) successfully loads. --- stand/lua/drawer.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stand/lua/drawer.lua b/stand/lua/drawer.lua index ae83f012e287..ee788919d4a3 100644 --- a/stand/lua/drawer.lua +++ b/stand/lua/drawer.lua @@ -247,9 +247,9 @@ local function drawlogo() (not colored and logodef.requires_color) then -- Choose a sensible default if colored then - logodef = getLogodef("orb") + logodef = getLogodef(drawer.default_color_logodef) else - logodef = getLogodef("orbbw") + logodef = getLogodef(drawer.default_bw_logodef) end end @@ -346,6 +346,8 @@ shift = default_shift -- Module exports drawer.default_brand = 'fbsd' +drawer.default_color_logodef = 'orb' +drawer.default_bw_logodef = 'orbbw' function drawer.addBrand(name, def) branddefs[name] = def From c1141fba00786e8c3536dcef6cb88dd6b354052a Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 19 Aug 2018 18:47:16 +0000 Subject: [PATCH 039/222] Update L1TF workaround to sustain L1D pollution from NMI. Current mitigation for L1TF in bhyve flushes L1D either by an explicit WRMSR command, or by software reading enough uninteresting data to fully populate all lines of L1D. If NMI occurs after either of methods is completed, but before VM entry, L1D becomes polluted with the cache lines touched by NMI handlers. There is no interesting data which NMI accesses, but something sensitive might be co-located on the same cache line, and then L1TF exposes that to a rogue guest. Use VM entry MSR load list to ensure atomicity of L1D cache and VM entry if updated microcode was loaded. If only software flush method is available, try to help the bhyve sw flusher by also flushing L1D on NMI exit to kernel mode. Suggested by and discussed with: Andrew Cooper Reviewed by: jhb Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D16790 --- sys/amd64/amd64/exception.S | 5 +++- sys/amd64/amd64/support.S | 33 ++++++++++++++++++++++++ sys/amd64/amd64/trap.c | 14 +++++++++++ sys/amd64/include/md_var.h | 1 + sys/amd64/vmm/intel/vmx.c | 42 ++++++++++++++++++++++++++++--- sys/amd64/vmm/intel/vmx_support.S | 38 ++-------------------------- 6 files changed, 92 insertions(+), 41 deletions(-) diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S index 543d9f72b131..91767094954b 100644 --- a/sys/amd64/amd64/exception.S +++ b/sys/amd64/amd64/exception.S @@ -864,7 +864,10 @@ nocallchain: movl %edx,%eax shrq $32,%rdx wrmsr - movq %r13,%cr3 + cmpb $0, nmi_flush_l1d_sw(%rip) + je 2f + call flush_l1d_sw /* bhyve L1TF assist */ +2: movq %r13,%cr3 RESTORE_REGS addq $TF_RIP,%rsp jmp doreti_iret diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index e95ffff5cc44..0547bbeabc0b 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -1225,3 +1225,36 @@ ENTRY(handle_ibrs_exit_rs) END(handle_ibrs_exit_rs) .noaltmacro + +/* + * Flush L1D cache. Load enough of the data from the kernel text + * to flush existing L1D content. + * + * N.B. The function follows ABI calling conventions, but the vmm.ko + * caller expects that only %rax, %rcx, %r9, and %rflags registers + * are clobbered. + */ +ENTRY(flush_l1d_sw) +#define L1D_FLUSH_SIZE (64 * 1024) + movq $KERNBASE, %r9 + movq $-L1D_FLUSH_SIZE, %rcx + /* + * pass 1: Preload TLB. + * Kernel text is mapped using superpages. TLB preload is + * done for the benefit of older CPUs which split 2M page + * into 4k TLB entries. + */ +1: movb L1D_FLUSH_SIZE(%r9, %rcx), %al + addq $PAGE_SIZE, %rcx + jne 1b + xorl %eax, %eax + cpuid + movq $-L1D_FLUSH_SIZE, %rcx + /* pass 2: Read each cache line. */ +2: movb L1D_FLUSH_SIZE(%r9, %rcx), %al + addq $64, %rcx + jne 2b + lfence + ret +#undef L1D_FLUSH_SIZE +END(flush_l1d_sw) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index e9dafbd8fe3a..019decb837ac 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -160,6 +160,20 @@ SYSCTL_INT(_machdep, OID_AUTO, uprintf_signal, CTLFLAG_RWTUN, &uprintf_signal, 0, "Print debugging information on trap signal to ctty"); +/* + * Control L1D flush on return from NMI. + * + * Tunable can be set to the following values: + * 0 - only enable flush on return from NMI if required by vmm.ko (default) + * >1 - always flush on return from NMI. + * + * Post-boot, the sysctl indicates if flushing is currently enabled. + */ +int nmi_flush_l1d_sw; +SYSCTL_INT(_machdep, OID_AUTO, nmi_flush_l1d_sw, CTLFLAG_RWTUN, + &nmi_flush_l1d_sw, 0, + "Flush L1 Data Cache on NMI exit, software bhyve L1TF mitigation assist"); + /* * Exception, fault, and trap interface to the FreeBSD kernel. * This common code is called from assembly language IDT gate entry diff --git a/sys/amd64/include/md_var.h b/sys/amd64/include/md_var.h index b2a987417282..0c17842a8e65 100644 --- a/sys/amd64/include/md_var.h +++ b/sys/amd64/include/md_var.h @@ -40,6 +40,7 @@ extern uint64_t *vm_page_dump; extern int hw_lower_amd64_sharedpage; extern int hw_ibrs_disable; extern int hw_ssb_disable; +extern int nmi_flush_l1d_sw; /* * The file "conf/ldscript.amd64" defines the symbol "kernphys". Its diff --git a/sys/amd64/vmm/intel/vmx.c b/sys/amd64/vmm/intel/vmx.c index ce8fc331747e..b40846cae6e6 100644 --- a/sys/amd64/vmm/intel/vmx.c +++ b/sys/amd64/vmm/intel/vmx.c @@ -191,8 +191,11 @@ SYSCTL_UINT(_hw_vmm_vmx, OID_AUTO, vpid_alloc_failed, CTLFLAG_RD, static int guest_l1d_flush; SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, l1d_flush, CTLFLAG_RD, &guest_l1d_flush, 0, NULL); +static int guest_l1d_flush_sw; +SYSCTL_INT(_hw_vmm_vmx, OID_AUTO, l1d_flush_sw, CTLFLAG_RD, + &guest_l1d_flush_sw, 0, NULL); -uint64_t vmx_msr_flush_cmd; +static struct msr_entry msr_load_list[1] __aligned(16); /* * The definitions of SDT probes for VMX. @@ -579,6 +582,9 @@ vmx_cleanup(void) vpid_unr = NULL; } + if (nmi_flush_l1d_sw == 1) + nmi_flush_l1d_sw = 0; + smp_rendezvous(NULL, vmx_disable, NULL, NULL); return (0); @@ -807,9 +813,28 @@ vmx_init(int ipinum) guest_l1d_flush = (cpu_ia32_arch_caps & IA32_ARCH_CAP_RDCL_NO) == 0; TUNABLE_INT_FETCH("hw.vmm.l1d_flush", &guest_l1d_flush); - if (guest_l1d_flush && - (cpu_stdext_feature3 & CPUID_STDEXT3_L1D_FLUSH) != 0) - vmx_msr_flush_cmd = IA32_FLUSH_CMD_L1D; + + /* + * L1D cache flush is enabled. Use IA32_FLUSH_CMD MSR when + * available. Otherwise fall back to the software flush + * method which loads enough data from the kernel text to + * flush existing L1D content, both on VMX entry and on NMI + * return. + */ + if (guest_l1d_flush) { + if ((cpu_stdext_feature3 & CPUID_STDEXT3_L1D_FLUSH) == 0) { + guest_l1d_flush_sw = 1; + TUNABLE_INT_FETCH("hw.vmm.l1d_flush_sw", + &guest_l1d_flush_sw); + } + if (guest_l1d_flush_sw) { + if (nmi_flush_l1d_sw <= 1) + nmi_flush_l1d_sw = 1; + } else { + msr_load_list[0].index = MSR_IA32_FLUSH_CMD; + msr_load_list[0].val = IA32_FLUSH_CMD_L1D; + } + } /* * Stash the cr0 and cr4 bits that must be fixed to 0 or 1 @@ -1000,6 +1025,15 @@ vmx_vminit(struct vm *vm, pmap_t pmap) error += vmwrite(VMCS_MSR_BITMAP, vtophys(vmx->msr_bitmap)); error += vmwrite(VMCS_VPID, vpid[i]); + if (guest_l1d_flush && !guest_l1d_flush_sw) { + vmcs_write(VMCS_ENTRY_MSR_LOAD, pmap_kextract( + (vm_offset_t)&msr_load_list[0])); + vmcs_write(VMCS_ENTRY_MSR_LOAD_COUNT, + nitems(msr_load_list)); + vmcs_write(VMCS_EXIT_MSR_STORE, 0); + vmcs_write(VMCS_EXIT_MSR_STORE_COUNT, 0); + } + /* exception bitmap */ if (vcpu_trace_exceptions(vm, i)) exc_bitmap = 0xffffffff; diff --git a/sys/amd64/vmm/intel/vmx_support.S b/sys/amd64/vmm/intel/vmx_support.S index c34210722a76..1652abac2134 100644 --- a/sys/amd64/vmm/intel/vmx_support.S +++ b/sys/amd64/vmm/intel/vmx_support.S @@ -176,44 +176,10 @@ ENTRY(vmx_enter_guest) jbe invept_error /* Check invept instruction error */ guest_restore: - - /* - * Flush L1D cache if requested. Use IA32_FLUSH_CMD MSR if available, - * otherwise load enough of the data from the zero_region to flush - * existing L1D content. - */ -#define L1D_FLUSH_SIZE (64 * 1024) movl %edx, %r8d - cmpb $0, guest_l1d_flush(%rip) + cmpb $0, guest_l1d_flush_sw(%rip) je after_l1d - movq vmx_msr_flush_cmd(%rip), %rax - testq %rax, %rax - jz 1f - movq %rax, %rdx - shrq $32, %rdx - movl $MSR_IA32_FLUSH_CMD, %ecx - wrmsr - jmp after_l1d -1: movq $KERNBASE, %r9 - movq $-L1D_FLUSH_SIZE, %rcx - /* - * pass 1: Preload TLB. - * Kernel text is mapped using superpages. TLB preload is - * done for the benefit of older CPUs which split 2M page - * into 4k TLB entries. - */ -2: movb L1D_FLUSH_SIZE(%r9, %rcx), %al - addq $PAGE_SIZE, %rcx - jne 2b - xorl %eax, %eax - cpuid - movq $-L1D_FLUSH_SIZE, %rcx - /* pass 2: Read each cache line */ -3: movb L1D_FLUSH_SIZE(%r9, %rcx), %al - addq $64, %rcx - jne 3b - lfence -#undef L1D_FLUSH_SIZE + call flush_l1d_sw after_l1d: cmpl $0, %r8d je do_launch From 340a810bf00928a0367eea0c1da83c2466d9b2eb Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 19 Aug 2018 18:54:43 +0000 Subject: [PATCH 040/222] booke pmap: hide debug-ish printf behind bootverbose It's not necessary during normal operation to know the mapped region size and wasted space. --- sys/powerpc/booke/pmap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 67a5ea21f7e5..7f439814e5f0 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -4177,8 +4177,9 @@ tlb1_mapin_region(vm_offset_t va, vm_paddr_t pa, vm_size_t size) } mapped = (va - base); - printf("mapped size 0x%"PRI0ptrX" (wasted space 0x%"PRIxPTR")\n", - mapped, mapped - size); + if (bootverbose) + printf("mapped size 0x%"PRIxPTR" (wasted space 0x%"PRIxPTR")\n", + mapped, mapped - size); return (mapped); } From 65aee3a872706517bd32ce3b4608704d7fddadd1 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Sun, 19 Aug 2018 18:55:33 +0000 Subject: [PATCH 041/222] arm64: allwinner: Add aw_syscon driver to GENERIC Recent DTS use the syscon for the emac controller. We support this but since U-Boot is still using old DTS it was never needed for us to add this support, but this is a problem when using upstream recent DTS and will be when U-Boot will catch up. While here add a new compatible to the aw_syscon driver as Linux changed it ... --- sys/arm/allwinner/aw_syscon.c | 1 + sys/arm64/conf/GENERIC | 1 + sys/conf/files.arm64 | 1 + 3 files changed, 3 insertions(+) diff --git a/sys/arm/allwinner/aw_syscon.c b/sys/arm/allwinner/aw_syscon.c index da36d0f6b938..122ab2283fe2 100644 --- a/sys/arm/allwinner/aw_syscon.c +++ b/sys/arm/allwinner/aw_syscon.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); static struct ofw_compat_data compat_data[] = { {"allwinner,sun50i-a64-system-controller", 1}, + {"allwinner,sun50i-a64-system-control", 1}, {"allwinner,sun8i-a83t-system-controller", 1}, {"allwinner,sun8i-h3-system-controller", 1}, {NULL, 0} diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index 3e2618ed4a7e..e09dc61083c0 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -256,6 +256,7 @@ device hwreset device nvmem device regulator device syscon +device aw_syscon # The `bpf' device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 8b845cc88fec..64e8e1c7aa8b 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -34,6 +34,7 @@ arm/allwinner/aw_rsb.c optional aw_rsb fdt arm/allwinner/aw_rtc.c optional aw_rtc fdt arm/allwinner/aw_sid.c optional aw_sid fdt arm/allwinner/aw_spi.c optional aw_spi fdt +arm/allwinner/aw_syscon.c optional aw_syscon ext_resources syscon fdt arm/allwinner/aw_thermal.c optional aw_thermal fdt arm/allwinner/aw_usbphy.c optional ehci aw_usbphy fdt arm/allwinner/aw_wdog.c optional aw_wdog fdt From 290646564b65de9b7dc46eb7d6c06001e1fc6d09 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 19 Aug 2018 19:00:44 +0000 Subject: [PATCH 042/222] powerpc64: Align frequently used/exclusive data on cacheline boundaries This is effectively a merge from amd64 of r312888, r323235, and r333486. I've been running this on my POWER9 Talos for some time now with no ill effects. Suggested by: mjg --- sys/conf/ldscript.powerpc64 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/conf/ldscript.powerpc64 b/sys/conf/ldscript.powerpc64 index 025c65451972..866bc05e622a 100644 --- a/sys/conf/ldscript.powerpc64 +++ b/sys/conf/ldscript.powerpc64 @@ -69,6 +69,20 @@ SECTIONS .sbss2 : { *(.sbss2) } /* Adjust the address for the data segment to the next page up. */ . = ALIGN(4096); + .data.read_frequently : + { + *(SORT_BY_ALIGNMENT(.data.read_frequently)) + } + .data.read_mostly : + { + *(.data.read_mostly) + } + . = ALIGN(128); + .data.exclusive_cache_line : + { + *(.data.exclusive_cache_line) + } + . = ALIGN(128); .data : { *(.data) From b793c8ab284561b34972848b5b3f79aedea42200 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 19 Aug 2018 19:03:43 +0000 Subject: [PATCH 043/222] Sort SPR_SPEFSCR in the SPR list Also remove duplicate definition of SPR_IBAT0U. --- sys/powerpc/include/spr.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h index 0c709ee336f4..ce7289606552 100644 --- a/sys/powerpc/include/spr.h +++ b/sys/powerpc/include/spr.h @@ -229,7 +229,6 @@ #define EPCR_DGTMI 0x00800000 #define EPCR_DMIUH 0x00400000 #define EPCR_PMGS 0x00200000 -#define SPR_SPEFSCR 0x200 /* ..8 Signal Processing Engine FSCR. */ #define SPR_HSRR0 0x13a #define SPR_HSRR1 0x13b @@ -245,7 +244,7 @@ #define SPR_LPID 0x13f /* Logical Partitioning Control */ #define SPR_PTCR 0x1d0 /* Partition Table Control Register */ -#define SPR_IBAT0U 0x210 /* .68 Instruction BAT Reg 0 Upper */ +#define SPR_SPEFSCR 0x200 /* ..8 Signal Processing Engine FSCR. */ #define SPR_IBAT0U 0x210 /* .6. Instruction BAT Reg 0 Upper */ #define SPR_IBAT0L 0x211 /* .6. Instruction BAT Reg 0 Lower */ #define SPR_IBAT1U 0x212 /* .6. Instruction BAT Reg 1 Upper */ From 8d67357c5c5896446984f206fec86f818aa1c22c Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 19 Aug 2018 19:07:59 +0000 Subject: [PATCH 044/222] powerpc conf: Add PRINTF_BUFR_SIZE option to Book-E configs Without this, printf is very hard to follow at times on multicore systems. --- sys/powerpc/conf/MPC85XX | 1 + sys/powerpc/conf/MPC85XXSPE | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX index e350507a6a00..cdf48ddbb6f4 100644 --- a/sys/powerpc/conf/MPC85XX +++ b/sys/powerpc/conf/MPC85XX @@ -47,6 +47,7 @@ options MSDOSFS options NFS_ROOT options NFSCL options NFSLOCKD +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options PROCFS options PSEUDOFS options SCHED_ULE diff --git a/sys/powerpc/conf/MPC85XXSPE b/sys/powerpc/conf/MPC85XXSPE index 0aca61c59041..5d7dc3d5fd4e 100644 --- a/sys/powerpc/conf/MPC85XXSPE +++ b/sys/powerpc/conf/MPC85XXSPE @@ -47,6 +47,7 @@ options MSDOSFS options NFS_ROOT options NFSCL options NFSLOCKD +options PRINTF_BUFR_SIZE=128 # Prevent printf output being interspersed. options PROCFS options PSEUDOFS options SCHED_ULE From 381388b9c48b07b08199b07b7657d46e8fcb59b0 Mon Sep 17 00:00:00 2001 From: Matt Macy Date: Sun, 19 Aug 2018 21:10:21 +0000 Subject: [PATCH 045/222] add snps IP uart support / genaralize UART This is an amalgam of a patch by Doug Ambrisko to generalize uart_acpi_find_device, imp moving the ACPI table to uart_dev_ns8250.c and advice by jhb to work around a bug in the EPYC 3151 BIOS (the BIOS incorrectly marks the serial ports as disabled) Reviewed by: imp MFC after: 8 weeks Differential Revision: https://reviews.freebsd.org/D16432 --- sys/arm/nvidia/tegra_uart.c | 2 +- sys/dev/acpica/acpi.c | 9 +++++ sys/dev/uart/uart_bus.h | 5 ++- sys/dev/uart/uart_bus_acpi.c | 49 ++++++----------------- sys/dev/uart/uart_bus_ebus.c | 2 +- sys/dev/uart/uart_bus_fdt.c | 2 +- sys/dev/uart/uart_bus_isa.c | 2 +- sys/dev/uart/uart_bus_pccard.c | 2 +- sys/dev/uart/uart_bus_pci.c | 2 +- sys/dev/uart/uart_bus_puc.c | 2 +- sys/dev/uart/uart_bus_scc.c | 2 +- sys/dev/uart/uart_core.c | 3 +- sys/dev/uart/uart_cpu_acpi.h | 12 ++++-- sys/dev/uart/uart_cpu_arm64.c | 10 ++--- sys/dev/uart/uart_dev_ns8250.c | 24 +++++++++++ sys/dev/uart/uart_dev_pl011.c | 6 +-- sys/dev/uart/uart_dev_snps.c | 17 +------- sys/mips/atheros/ar531x/uart_bus_ar5315.c | 2 +- sys/mips/atheros/uart_bus_ar71xx.c | 2 +- sys/mips/atheros/uart_bus_ar933x.c | 2 +- sys/mips/broadcom/uart_bus_chipc.c | 2 +- sys/mips/cavium/uart_bus_octeonusart.c | 2 +- sys/mips/ingenic/jz4780_uart.c | 2 +- sys/mips/malta/uart_bus_maltausart.c | 2 +- sys/modules/uart/Makefile | 9 ++++- sys/powerpc/psim/uart_iobus.c | 2 +- sys/sparc64/pci/sbbc.c | 2 +- 27 files changed, 95 insertions(+), 83 deletions(-) diff --git a/sys/arm/nvidia/tegra_uart.c b/sys/arm/nvidia/tegra_uart.c index 1bc81fdb99cf..fc4e722824ea 100644 --- a/sys/arm/nvidia/tegra_uart.c +++ b/sys/arm/nvidia/tegra_uart.c @@ -216,7 +216,7 @@ tegra_uart_probe(device_t dev) device_printf(dev, "Cannot enable UART clock: %d\n", rv); return (ENXIO); } - return (uart_bus_probe(dev, shift, 0, (int)freq, 0, 0)); + return (uart_bus_probe(dev, shift, 0, (int)freq, 0, 0, 0)); } static int diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index c1bfd880c896..f55a0048e4b6 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -2221,6 +2221,15 @@ acpi_DeviceIsPresent(device_t dev) return (FALSE); status = acpi_GetInteger(h, "_STA", &s); + /* + * Onboard serial ports on certain AMD motherboards have an invalid _STA + * method that always returns 0. Force them to always be treated as present. + * + * This may solely be a quirk of a preproduction BIOS. + */ + if (acpi_MatchHid(h, "AMDI0020") || acpi_MatchHid(h, "AMDI0010")) + return (TRUE); + /* If no _STA method, must be present */ if (ACPI_FAILURE(status)) return (status == AE_NOT_FOUND ? TRUE : FALSE); diff --git a/sys/dev/uart/uart_bus.h b/sys/dev/uart/uart_bus.h index 556a9228493c..2bc33734cfb5 100644 --- a/sys/dev/uart/uart_bus.h +++ b/sys/dev/uart/uart_bus.h @@ -56,6 +56,9 @@ #define UART_IOCTL_OFLOW 3 #define UART_IOCTL_BAUD 4 +/* UART quirk flags */ +#define UART_F_BUSY_DETECT 0x1 + /* * UART class & instance (=softc) */ @@ -140,7 +143,7 @@ int uart_bus_detach(device_t dev); int uart_bus_resume(device_t dev); serdev_intr_t *uart_bus_ihand(device_t dev, int ipend); int uart_bus_ipend(device_t dev); -int uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan); +int uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan, int quirks); int uart_bus_sysdev(device_t dev); void uart_sched_softih(struct uart_softc *, uint32_t); diff --git a/sys/dev/uart/uart_bus_acpi.c b/sys/dev/uart/uart_bus_acpi.c index 88b1480064f4..a711c0c6a675 100644 --- a/sys/dev/uart/uart_bus_acpi.c +++ b/sys/dev/uart/uart_bus_acpi.c @@ -37,17 +37,13 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include - -#ifdef __aarch64__ #include #include #include -#endif + static int uart_acpi_probe(device_t dev); @@ -66,59 +62,40 @@ static driver_t uart_acpi_driver = { sizeof(struct uart_softc), }; -#if defined(__i386__) || defined(__amd64__) -static struct isa_pnp_id acpi_ns8250_ids[] = { - {0x0005d041, "Standard PC COM port"}, /* PNP0500 */ - {0x0105d041, "16550A-compatible COM port"}, /* PNP0501 */ - {0x0205d041, "Multiport serial device (non-intelligent 16550)"}, /* PNP0502 */ - {0x1005d041, "Generic IRDA-compatible device"}, /* PNP0510 */ - {0x1105d041, "Generic IRDA-compatible device"}, /* PNP0511 */ - {0x04f0235c, "Wacom Tablet PC Screen"}, /* WACF004 */ - {0x0ef0235c, "Wacom Tablet PC Screen 00e"}, /* WACF00e */ - {0xe502aa1a, "Wacom Tablet at FuS Lifebook T"}, /* FUJ02E5 */ - {0} -}; -#endif - -#ifdef __aarch64__ -static struct uart_class * +static struct acpi_uart_compat_data * uart_acpi_find_device(device_t dev) { - struct acpi_uart_compat_data **cd; + struct acpi_uart_compat_data **cd, *cd_it; ACPI_HANDLE h; if ((h = acpi_get_handle(dev)) == NULL) return (NULL); SET_FOREACH(cd, uart_acpi_class_and_device_set) { - if (acpi_MatchHid(h, (*cd)->hid)) { - return ((*cd)->clas); + for (cd_it = *cd; cd_it->cd_hid != NULL; cd_it++) { + if (acpi_MatchHid(h, cd_it->cd_hid)) + return (cd_it); } } return (NULL); } -#endif static int uart_acpi_probe(device_t dev) { struct uart_softc *sc; + struct acpi_uart_compat_data *cd; sc = device_get_softc(dev); -#if defined(__i386__) || defined(__amd64__) - if (!ISA_PNP_PROBE(device_get_parent(dev), dev, acpi_ns8250_ids)) { - sc->sc_class = &uart_ns8250_class; - return (uart_bus_probe(dev, 0, 0, 0, 0, 0)); + if ((cd = uart_acpi_find_device(dev)) != NULL) { + sc->sc_class = cd->cd_class; + if (cd->cd_desc != NULL) + device_set_desc(dev, cd->cd_desc); + return (uart_bus_probe(dev, cd->cd_regshft, cd->cd_regiowidth, + cd->cd_rclk, 0, 0, cd->cd_quirks)); } - - /* Add checks for non-ns8250 IDs here. */ -#elif defined(__aarch64__) - if ((sc->sc_class = uart_acpi_find_device(dev)) != NULL) - return (uart_bus_probe(dev, 2, 0, 0, 0, 0)); -#endif - return (ENXIO); } diff --git a/sys/dev/uart/uart_bus_ebus.c b/sys/dev/uart/uart_bus_ebus.c index dead7733d0cf..dd50ff83596f 100644 --- a/sys/dev/uart/uart_bus_ebus.c +++ b/sys/dev/uart/uart_bus_ebus.c @@ -99,7 +99,7 @@ uart_ebus_probe(device_t dev) return (ENXIO); } sc->sc_class = &uart_ns8250_class; - return (uart_bus_probe(dev, 0, 0, 0, 0, 0)); + return (uart_bus_probe(dev, 0, 0, 0, 0, 0, 0)); } return (ENXIO); diff --git a/sys/dev/uart/uart_bus_fdt.c b/sys/dev/uart/uart_bus_fdt.c index 8efb7d7b2290..34c600301e64 100644 --- a/sys/dev/uart/uart_bus_fdt.c +++ b/sys/dev/uart/uart_bus_fdt.c @@ -278,7 +278,7 @@ uart_fdt_probe(device_t dev) if (uart_fdt_get_io_width(node, &iowidth) != 0) iowidth = uart_getregiowidth(sc->sc_class); - return (uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0)); + return (uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0, 0)); } DRIVER_MODULE(uart, simplebus, uart_fdt_driver, uart_devclass, 0, 0); diff --git a/sys/dev/uart/uart_bus_isa.c b/sys/dev/uart/uart_bus_isa.c index 759d4f92a9a9..5085ff66fe10 100644 --- a/sys/dev/uart/uart_bus_isa.c +++ b/sys/dev/uart/uart_bus_isa.c @@ -168,7 +168,7 @@ uart_isa_probe(device_t dev) /* Probe PnP _and_ non-PnP ns8250 here. */ sc->sc_class = &uart_ns8250_class; - return (uart_bus_probe(dev, 0, 0, 0, 0, 0)); + return (uart_bus_probe(dev, 0, 0, 0, 0, 0, 0)); } DRIVER_MODULE(uart, isa, uart_isa_driver, uart_devclass, 0, 0); diff --git a/sys/dev/uart/uart_bus_pccard.c b/sys/dev/uart/uart_bus_pccard.c index 894240ee344b..3a8446a871f6 100644 --- a/sys/dev/uart/uart_bus_pccard.c +++ b/sys/dev/uart/uart_bus_pccard.c @@ -95,7 +95,7 @@ uart_pccard_attach(device_t dev) sc = device_get_softc(dev); sc->sc_class = &uart_ns8250_class; - error = uart_bus_probe(dev, 0, 0, 0, 0, 0); + error = uart_bus_probe(dev, 0, 0, 0, 0, 0, 0); if (error > 0) return (error); return (uart_bus_attach(dev)); diff --git a/sys/dev/uart/uart_bus_pci.c b/sys/dev/uart/uart_bus_pci.c index a8b8a7ec9ae1..f4be108ab7b2 100644 --- a/sys/dev/uart/uart_bus_pci.c +++ b/sys/dev/uart/uart_bus_pci.c @@ -206,7 +206,7 @@ uart_pci_probe(device_t dev) return (ENXIO); match: - result = uart_bus_probe(dev, id->regshft, 0, id->rclk, id->rid, 0); + result = uart_bus_probe(dev, id->regshft, 0, id->rclk, id->rid, 0, 0); /* Bail out on error. */ if (result > 0) return (result); diff --git a/sys/dev/uart/uart_bus_puc.c b/sys/dev/uart/uart_bus_puc.c index 36419d43f355..a90e01628f40 100644 --- a/sys/dev/uart/uart_bus_puc.c +++ b/sys/dev/uart/uart_bus_puc.c @@ -83,7 +83,7 @@ uart_puc_probe(device_t dev) if (BUS_READ_IVAR(parent, dev, PUC_IVAR_CLOCK, &rclk)) rclk = 0; - return (uart_bus_probe(dev, 0, 0, rclk, 0, 0)); + return (uart_bus_probe(dev, 0, 0, rclk, 0, 0, 0)); } DRIVER_MODULE(uart, puc, uart_puc_driver, uart_devclass, 0, 0); diff --git a/sys/dev/uart/uart_bus_scc.c b/sys/dev/uart/uart_bus_scc.c index 80f590610d9d..6666a35e272e 100644 --- a/sys/dev/uart/uart_bus_scc.c +++ b/sys/dev/uart/uart_bus_scc.c @@ -114,7 +114,7 @@ uart_scc_probe(device_t dev) BUS_READ_IVAR(parent, dev, SCC_IVAR_REGSHFT, &rs)) return (ENXIO); - return (uart_bus_probe(dev, rs, 0, cl, 0, ch)); + return (uart_bus_probe(dev, rs, 0, cl, 0, ch, 0)); } DRIVER_MODULE(uart, scc, uart_scc_driver, uart_devclass, 0, 0); diff --git a/sys/dev/uart/uart_core.c b/sys/dev/uart/uart_core.c index fe722cb3eb2d..87874e4d11d0 100644 --- a/sys/dev/uart/uart_core.c +++ b/sys/dev/uart/uart_core.c @@ -493,7 +493,7 @@ uart_bus_sysdev(device_t dev) } int -uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan) +uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int chan, int quirks) { struct uart_softc *sc; struct uart_devinfo *sysdev; @@ -553,6 +553,7 @@ uart_bus_probe(device_t dev, int regshft, int regiowidth, int rclk, int rid, int sc->sc_bas.regshft = regshft; sc->sc_bas.regiowidth = regiowidth; sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk; + sc->sc_bas.busy_detect = !!(quirks & UART_F_BUSY_DETECT); SLIST_FOREACH(sysdev, &uart_sysdevs, next) { if (chan == sysdev->bas.chan && diff --git a/sys/dev/uart/uart_cpu_acpi.h b/sys/dev/uart/uart_cpu_acpi.h index 30cfa4e19388..416ff48f9266 100644 --- a/sys/dev/uart/uart_cpu_acpi.h +++ b/sys/dev/uart/uart_cpu_acpi.h @@ -38,9 +38,15 @@ struct uart_class; struct acpi_uart_compat_data { - const char *hid; - struct uart_class *clas; - uint16_t port_subtype; + const char *cd_hid; + struct uart_class *cd_class; + + uint16_t cd_port_subtype; + int cd_regshft; + int cd_regiowidth; + int cd_rclk; + int cd_quirks; + const char *cd_desc; }; /* diff --git a/sys/dev/uart/uart_cpu_arm64.c b/sys/dev/uart/uart_cpu_arm64.c index 56a88f73b2bf..5a323a38ac4e 100644 --- a/sys/dev/uart/uart_cpu_arm64.c +++ b/sys/dev/uart/uart_cpu_arm64.c @@ -88,16 +88,16 @@ uart_cpu_acpi_scan(uint8_t interface_type) SET_FOREACH(cd, uart_acpi_class_and_device_set) { curcd = *cd; - for (i = 0; curcd[i].hid != NULL; i++) { - if (curcd[i].port_subtype == interface_type) + for (i = 0; curcd[i].cd_hid != NULL; i++) { + if (curcd[i].cd_port_subtype == interface_type) return (&curcd[i]); } } SET_FOREACH(cd, uart_acpi_class_set) { curcd = *cd; - for (i = 0; curcd[i].hid != NULL; i++) { - if (curcd[i].port_subtype == interface_type) + for (i = 0; curcd[i].cd_hid != NULL; i++) { + if (curcd[i].cd_port_subtype == interface_type) return (&curcd[i]); } } @@ -147,7 +147,7 @@ uart_cpu_acpi_probe(struct uart_class **classp, bus_space_tag_t *bst, if (err != 0) goto out; - *classp = cd->clas; + *classp = cd->cd_class; *rclk = 0; *shiftp = 2; *iowidthp = spcr->SerialPort.BitWidth / 8; diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index 03792f8f6598..7f87b111f502 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -26,6 +26,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "opt_acpi.h" #include "opt_platform.h" #include "opt_uart.h" @@ -54,6 +55,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef DEV_ACPI +#include +#endif #include @@ -404,6 +408,26 @@ struct uart_class uart_ns8250_class = { .uc_rshift = 0 }; +/* + * XXX -- refactor out ACPI and FDT ifdefs + */ +#ifdef DEV_ACPI +static struct acpi_uart_compat_data acpi_compat_data[] = { + {"AMD0020", &uart_ns8250_class, 0, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"}, + {"AMDI0020", &uart_ns8250_class, 0, 2, 0, 48000000, UART_F_BUSY_DETECT, "AMD / Synopsys Designware UART"}, + {"PNP0500", &uart_ns8250_class, 0, 0, 0, 0, 0, "Standard PC COM port"}, + {"PNP0501", &uart_ns8250_class, 0, 0, 0, 0, 0, "16550A-compatible COM port"}, + {"PNP0502", &uart_ns8250_class, 0, 0, 0, 0, 0, "Multiport serial device (non-intelligent 16550)"}, + {"PNP0510", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"}, + {"PNP0511", &uart_ns8250_class, 0, 0, 0, 0, 0, "Generic IRDA-compatible device"}, + {"WACF004", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet PC Screen"}, + {"WACF00E", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet PC Screen 00e"}, + {"FUJ02E5", &uart_ns8250_class, 0, 0, 0, 0, 0, "Wacom Tablet at FuS Lifebook T"}, + {NULL, NULL, 0, 0 , 0, 0, 0, NULL}, +}; +UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data); +#endif + #ifdef FDT static struct ofw_compat_data compat_data[] = { {"ns16550", (uintptr_t)&uart_ns8250_class}, diff --git a/sys/dev/uart/uart_dev_pl011.c b/sys/dev/uart/uart_dev_pl011.c index 0b55b6a217db..08905d13c1e6 100644 --- a/sys/dev/uart/uart_dev_pl011.c +++ b/sys/dev/uart/uart_dev_pl011.c @@ -342,9 +342,9 @@ UART_FDT_CLASS_AND_DEVICE(fdt_compat_data); #ifdef DEV_ACPI static struct acpi_uart_compat_data acpi_compat_data[] = { - {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_PL011}, - {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_SBSA_GENERIC}, - {NULL, NULL, 0}, + {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_PL011, 2, 0, 0, 0, "uart plo11"}, + {"ARMH0011", &uart_pl011_class, ACPI_DBG2_ARM_SBSA_GENERIC, 2, 0, 0, 0, "uart plo11"}, + {NULL, NULL, 0, 0, 0, 0, 0, NULL}, }; UART_ACPI_CLASS_AND_DEVICE(acpi_compat_data); #endif diff --git a/sys/dev/uart/uart_dev_snps.c b/sys/dev/uart/uart_dev_snps.c index 26696621c7d2..d8fc114824f8 100644 --- a/sys/dev/uart/uart_dev_snps.c +++ b/sys/dev/uart/uart_dev_snps.c @@ -99,22 +99,9 @@ early_putc_t *early_putc = uart_snps_early_putc; #endif /* EARLY_PRINTF */ #endif -static int -snps_uart_attach(struct uart_softc *uart_sc) -{ - struct snps_softc *sc; - - sc = (struct snps_softc *)uart_sc; - - /* UART requires to read USR reg when IIR_BUSY */ - uart_sc->sc_bas.busy_detect = 1; - - return (ns8250_bus_attach(uart_sc)); -} - static kobj_method_t snps_methods[] = { KOBJMETHOD(uart_probe, ns8250_bus_probe), - KOBJMETHOD(uart_attach, snps_uart_attach), + KOBJMETHOD(uart_attach, ns8250_bus_attach), KOBJMETHOD(uart_detach, ns8250_bus_detach), KOBJMETHOD(uart_flush, ns8250_bus_flush), KOBJMETHOD(uart_getsig, ns8250_bus_getsig), @@ -238,7 +225,7 @@ snps_probe(device_t dev) if (bootverbose && clock == 0) device_printf(dev, "could not determine frequency\n"); - error = uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0); + error = uart_bus_probe(dev, (int)shift, (int)iowidth, (int)clock, 0, 0, UART_F_BUSY_DETECT); if (error != 0) return (error); diff --git a/sys/mips/atheros/ar531x/uart_bus_ar5315.c b/sys/mips/atheros/ar531x/uart_bus_ar5315.c index 823dd863e0b7..425b3849e0dc 100644 --- a/sys/mips/atheros/ar531x/uart_bus_ar5315.c +++ b/sys/mips/atheros/ar531x/uart_bus_ar5315.c @@ -83,7 +83,7 @@ uart_ar5315_probe(device_t dev) sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = ar531x_uart_addr() + 3; - return (uart_bus_probe(dev, 2, 0, freq, 0, 0)); + return (uart_bus_probe(dev, 2, 0, freq, 0, 0, 0)); } DRIVER_MODULE(uart, apb, uart_ar5315_driver, uart_devclass, 0, 0); diff --git a/sys/mips/atheros/uart_bus_ar71xx.c b/sys/mips/atheros/uart_bus_ar71xx.c index b3c098686028..2c38a4dedbe1 100644 --- a/sys/mips/atheros/uart_bus_ar71xx.c +++ b/sys/mips/atheros/uart_bus_ar71xx.c @@ -85,7 +85,7 @@ uart_ar71xx_probe(device_t dev) sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR) + 3; - return (uart_bus_probe(dev, 2, 0, freq, 0, 0)); + return (uart_bus_probe(dev, 2, 0, freq, 0, 0, 0)); } #ifdef EARLY_PRINTF diff --git a/sys/mips/atheros/uart_bus_ar933x.c b/sys/mips/atheros/uart_bus_ar933x.c index c71d47a771b0..3f0314302600 100644 --- a/sys/mips/atheros/uart_bus_ar933x.c +++ b/sys/mips/atheros/uart_bus_ar933x.c @@ -90,7 +90,7 @@ uart_ar933x_probe(device_t dev) sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(AR71XX_UART_ADDR); - return (uart_bus_probe(dev, 2, 0, freq, 0, 0)); + return (uart_bus_probe(dev, 2, 0, freq, 0, 0, 0)); } /* diff --git a/sys/mips/broadcom/uart_bus_chipc.c b/sys/mips/broadcom/uart_bus_chipc.c index 132819846553..b796c371da3d 100644 --- a/sys/mips/broadcom/uart_bus_chipc.c +++ b/sys/mips/broadcom/uart_bus_chipc.c @@ -61,7 +61,7 @@ uart_chipc_probe(device_t dev) sc->sc_class = &uart_ns8250_class; rclk = bcm_get_uart_rclk(bcm_get_platform()); - return (uart_bus_probe(dev, 0, 0, rclk, 0, 0)); + return (uart_bus_probe(dev, 0, 0, rclk, 0, 0, 0)); } static device_method_t uart_chipc_methods[] = { diff --git a/sys/mips/cavium/uart_bus_octeonusart.c b/sys/mips/cavium/uart_bus_octeonusart.c index 4d50f91fdac6..8569f4fdc03d 100644 --- a/sys/mips/cavium/uart_bus_octeonusart.c +++ b/sys/mips/cavium/uart_bus_octeonusart.c @@ -107,7 +107,7 @@ uart_octeon_probe(device_t dev) if (bus_space_map(sc->sc_bas.bst, CVMX_MIO_UARTX_RBR(0), uart_getrange(sc->sc_class), 0, &sc->sc_bas.bsh) != 0) return (ENXIO); - return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, 0, unit)); + return (uart_bus_probe(dev, sc->sc_bas.regshft, 0, 0, 0, unit, 0)); } DRIVER_MODULE(uart, obio, uart_octeon_driver, uart_devclass, 0, 0); diff --git a/sys/mips/ingenic/jz4780_uart.c b/sys/mips/ingenic/jz4780_uart.c index ccc8137c04db..38d15493c155 100644 --- a/sys/mips/ingenic/jz4780_uart.c +++ b/sys/mips/ingenic/jz4780_uart.c @@ -179,7 +179,7 @@ jz4780_uart_probe(device_t dev) device_printf(dev, "got UART clock: %lld\n", freq); sc->ns8250_base.base.sc_class = (struct uart_class *)cd->ocd_data; shift = jz4780_uart_get_shift(dev); - return (uart_bus_probe(dev, shift, 0, (int)freq, 0, 0)); + return (uart_bus_probe(dev, shift, 0, (int)freq, 0, 0, 0)); } static int diff --git a/sys/mips/malta/uart_bus_maltausart.c b/sys/mips/malta/uart_bus_maltausart.c index 0bd11282cea4..a3fdf77f879c 100644 --- a/sys/mips/malta/uart_bus_maltausart.c +++ b/sys/mips/malta/uart_bus_maltausart.c @@ -87,7 +87,7 @@ uart_malta_probe(device_t dev) sc->sc_sysdev->bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); sc->sc_bas.bst = mips_bus_space_generic; sc->sc_bas.bsh = MIPS_PHYS_TO_KSEG1(MALTA_UART0ADR); - return(uart_bus_probe(dev, 0, 0, 0, 0, 0)); + return(uart_bus_probe(dev, 0, 0, 0, 0, 0, 0)); } DRIVER_MODULE(uart, obio, uart_malta_driver, uart_devclass, 0, 0); diff --git a/sys/modules/uart/Makefile b/sys/modules/uart/Makefile index f16d59aa7f6e..0b878c09187d 100644 --- a/sys/modules/uart/Makefile +++ b/sys/modules/uart/Makefile @@ -2,6 +2,11 @@ .PATH: ${SRCTOP}/sys/dev/uart +.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "amd64" || \ + ${MACHINE_CPUARCH} == "i386" +uart_bus_acpi=uart_bus_acpi.c +.endif + .if ${MACHINE_CPUARCH} == "sparc64" uart_bus_ebus= uart_bus_ebus.c .endif @@ -27,7 +32,7 @@ uart_dev_mu=uart_dev_mu.c .endif KMOD= uart -SRCS= uart_bus_acpi.c ${uart_bus_ebus} uart_bus_isa.c uart_bus_pccard.c \ +SRCS= ${uart_bus_acpi} ${uart_bus_ebus} uart_bus_isa.c uart_bus_pccard.c \ uart_bus_pci.c uart_bus_puc.c uart_bus_scc.c \ uart_core.c ${uart_cpu_machine} uart_dbg.c \ ${uart_dev_mvebu} uart_dev_ns8250.c ${uart_dev_mu} \ @@ -37,6 +42,6 @@ SRCS= uart_bus_acpi.c ${uart_bus_ebus} uart_bus_isa.c uart_bus_pccard.c \ SRCS+= acpi_if.h bus_if.h card_if.h device_if.h isa_if.h ${ofw_bus_if} \ pci_if.h \ power_if.h pccarddevs.h serdev_if.h -SRCS+= opt_platform.h opt_uart.h +SRCS+= opt_acpi.h opt_platform.h opt_uart.h .include diff --git a/sys/powerpc/psim/uart_iobus.c b/sys/powerpc/psim/uart_iobus.c index 5cceef76377f..7da09ebdbf3e 100644 --- a/sys/powerpc/psim/uart_iobus.c +++ b/sys/powerpc/psim/uart_iobus.c @@ -83,7 +83,7 @@ uart_iobus_probe(device_t dev) sc->sc_class = &uart_ns8250_class; device_set_desc(dev, "PSIM serial port"); - return (uart_bus_probe(dev, 0, 0, 0, 0, 0)); + return (uart_bus_probe(dev, 0, 0, 0, 0, 0, 0)); } DRIVER_MODULE(uart, iobus, uart_iobus_driver, uart_devclass, 0, 0); diff --git a/sys/sparc64/pci/sbbc.c b/sys/sparc64/pci/sbbc.c index f4a100ec5621..a5975fff82a3 100644 --- a/sys/sparc64/pci/sbbc.c +++ b/sys/sparc64/pci/sbbc.c @@ -620,7 +620,7 @@ sbbc_uart_sbbc_probe(device_t dev) sc = device_get_softc(dev); sc->sc_class = &uart_sbbc_class; device_set_desc(dev, "Serengeti console"); - return (uart_bus_probe(dev, 0, 0, 0, SBBC_PCI_BAR, 0)); + return (uart_bus_probe(dev, 0, 0, 0, SBBC_PCI_BAR, 0, 0)); } /* From b060c61dfdbe52d2894ae1e9a91b9ef1423f5b45 Mon Sep 17 00:00:00 2001 From: John-Mark Gurney Date: Sun, 19 Aug 2018 21:37:51 +0000 Subject: [PATCH 046/222] use sbuf so that lines are printed together... As aarch64 often has SMP enabled, lines can get intermixed with other console output making these lines hard to read... Reviewed by: manu Differential Revision: https://reviews.freebsd.org/D16689 --- sys/arm64/arm64/identcpu.c | 355 ++++++++++++++++++++----------------- 1 file changed, 188 insertions(+), 167 deletions(-) diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index 2cabd87e2881..a79490441e91 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -175,30 +176,34 @@ SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL); void print_cpu_features(u_int cpu) { + struct sbuf *sb; int printed; - printf("CPU%3d: %s %s r%dp%d", cpu, cpu_desc[cpu].cpu_impl_name, - cpu_desc[cpu].cpu_part_name, cpu_desc[cpu].cpu_variant, - cpu_desc[cpu].cpu_revision); + sb = sbuf_new_auto(); + sbuf_printf(sb, "CPU%3d: %s %s r%dp%d", cpu, + cpu_desc[cpu].cpu_impl_name, cpu_desc[cpu].cpu_part_name, + cpu_desc[cpu].cpu_variant, cpu_desc[cpu].cpu_revision); - printf(" affinity:"); + sbuf_cat(sb, " affinity:"); switch(cpu_aff_levels) { default: case 4: - printf(" %2d", CPU_AFF3(cpu_desc[cpu].mpidr)); + sbuf_printf(sb, " %2d", CPU_AFF3(cpu_desc[cpu].mpidr)); /* FALLTHROUGH */ case 3: - printf(" %2d", CPU_AFF2(cpu_desc[cpu].mpidr)); + sbuf_printf(sb, " %2d", CPU_AFF2(cpu_desc[cpu].mpidr)); /* FALLTHROUGH */ case 2: - printf(" %2d", CPU_AFF1(cpu_desc[cpu].mpidr)); + sbuf_printf(sb, " %2d", CPU_AFF1(cpu_desc[cpu].mpidr)); /* FALLTHROUGH */ case 1: case 0: /* On UP this will be zero */ - printf(" %2d", CPU_AFF0(cpu_desc[cpu].mpidr)); + sbuf_printf(sb, " %2d", CPU_AFF0(cpu_desc[cpu].mpidr)); break; } - printf("\n"); + sbuf_finish(sb); + printf("%s\n", sbuf_data(sb)); + sbuf_clear(sb); /* * There is a hardware errata where, if one CPU is performing a TLB @@ -230,39 +235,39 @@ print_cpu_features(u_int cpu) /* AArch64 Instruction Set Attribute Register 0 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR0) != 0) { printed = 0; - printf(" Instruction Set Attributes 0 = <"); + sbuf_printf(sb, " Instruction Set Attributes 0 = <"); switch (ID_AA64ISAR0_RDM(cpu_desc[cpu].id_aa64isar0)) { case ID_AA64ISAR0_RDM_NONE: break; case ID_AA64ISAR0_RDM_IMPL: - printf("%sRDM", SEP_STR); + sbuf_printf(sb, "%sRDM", SEP_STR); break; default: - printf("%sUnknown RDM", SEP_STR); + sbuf_printf(sb, "%sUnknown RDM", SEP_STR); } switch (ID_AA64ISAR0_ATOMIC(cpu_desc[cpu].id_aa64isar0)) { case ID_AA64ISAR0_ATOMIC_NONE: break; case ID_AA64ISAR0_ATOMIC_IMPL: - printf("%sAtomic", SEP_STR); + sbuf_printf(sb, "%sAtomic", SEP_STR); break; default: - printf("%sUnknown Atomic", SEP_STR); + sbuf_printf(sb, "%sUnknown Atomic", SEP_STR); } switch (ID_AA64ISAR0_AES(cpu_desc[cpu].id_aa64isar0)) { case ID_AA64ISAR0_AES_NONE: break; case ID_AA64ISAR0_AES_BASE: - printf("%sAES", SEP_STR); + sbuf_printf(sb, "%sAES", SEP_STR); break; case ID_AA64ISAR0_AES_PMULL: - printf("%sAES+PMULL", SEP_STR); + sbuf_printf(sb, "%sAES+PMULL", SEP_STR); break; default: - printf("%sUnknown AES", SEP_STR); + sbuf_printf(sb, "%sUnknown AES", SEP_STR); break; } @@ -270,10 +275,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_SHA1_NONE: break; case ID_AA64ISAR0_SHA1_BASE: - printf("%sSHA1", SEP_STR); + sbuf_printf(sb, "%sSHA1", SEP_STR); break; default: - printf("%sUnknown SHA1", SEP_STR); + sbuf_printf(sb, "%sUnknown SHA1", SEP_STR); break; } @@ -281,13 +286,13 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_SHA2_NONE: break; case ID_AA64ISAR0_SHA2_BASE: - printf("%sSHA2", SEP_STR); + sbuf_printf(sb, "%sSHA2", SEP_STR); break; case ID_AA64ISAR0_SHA2_512: - printf("%sSHA2+SHA512", SEP_STR); + sbuf_printf(sb, "%sSHA2+SHA512", SEP_STR); break; default: - printf("%sUnknown SHA2", SEP_STR); + sbuf_printf(sb, "%sUnknown SHA2", SEP_STR); break; } @@ -295,10 +300,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_CRC32_NONE: break; case ID_AA64ISAR0_CRC32_BASE: - printf("%sCRC32", SEP_STR); + sbuf_printf(sb, "%sCRC32", SEP_STR); break; default: - printf("%sUnknown CRC32", SEP_STR); + sbuf_printf(sb, "%sUnknown CRC32", SEP_STR); break; } @@ -306,10 +311,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_SHA3_NONE: break; case ID_AA64ISAR0_SHA3_IMPL: - printf("%sSHA3", SEP_STR); + sbuf_printf(sb, "%sSHA3", SEP_STR); break; default: - printf("%sUnknown SHA3", SEP_STR); + sbuf_printf(sb, "%sUnknown SHA3", SEP_STR); break; } @@ -317,10 +322,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_SM3_NONE: break; case ID_AA64ISAR0_SM3_IMPL: - printf("%sSM3", SEP_STR); + sbuf_printf(sb, "%sSM3", SEP_STR); break; default: - printf("%sUnknown SM3", SEP_STR); + sbuf_printf(sb, "%sUnknown SM3", SEP_STR); break; } @@ -328,10 +333,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_SM4_NONE: break; case ID_AA64ISAR0_SM4_IMPL: - printf("%sSM4", SEP_STR); + sbuf_printf(sb, "%sSM4", SEP_STR); break; default: - printf("%sUnknown SM4", SEP_STR); + sbuf_printf(sb, "%sUnknown SM4", SEP_STR); break; } @@ -339,33 +344,35 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR0_DP_NONE: break; case ID_AA64ISAR0_DP_IMPL: - printf("%sDotProd", SEP_STR); + sbuf_printf(sb, "%sDotProd", SEP_STR); break; default: - printf("%sUnknown DP", SEP_STR); + sbuf_printf(sb, "%sUnknown DP", SEP_STR); break; } if ((cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK) != 0) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64isar0 & ~ID_AA64ISAR0_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Instruction Set Attribute Register 1 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_ISAR1) != 0) { printed = 0; - printf(" Instruction Set Attributes 1 = <"); + sbuf_printf(sb, " Instruction Set Attributes 1 = <"); switch (ID_AA64ISAR1_GPI(cpu_desc[cpu].id_aa64isar1)) { case ID_AA64ISAR1_GPI_NONE: break; case ID_AA64ISAR1_GPI_IMPL: - printf("%sImpl GenericAuth", SEP_STR); + sbuf_printf(sb, "%sImpl GenericAuth", SEP_STR); break; default: - printf("%sUnknown GenericAuth", SEP_STR); + sbuf_printf(sb, "%sUnknown GenericAuth", SEP_STR); break; } @@ -373,10 +380,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_GPA_NONE: break; case ID_AA64ISAR1_GPA_IMPL: - printf("%sPrince GenericAuth", SEP_STR); + sbuf_printf(sb, "%sPrince GenericAuth", SEP_STR); break; default: - printf("%sUnknown GenericAuth", SEP_STR); + sbuf_printf(sb, "%sUnknown GenericAuth", SEP_STR); break; } @@ -384,10 +391,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_LRCPC_NONE: break; case ID_AA64ISAR1_LRCPC_IMPL: - printf("%sRCpc", SEP_STR); + sbuf_printf(sb, "%sRCpc", SEP_STR); break; default: - printf("%sUnknown RCpc", SEP_STR); + sbuf_printf(sb, "%sUnknown RCpc", SEP_STR); break; } @@ -395,10 +402,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_FCMA_NONE: break; case ID_AA64ISAR1_FCMA_IMPL: - printf("%sFCMA", SEP_STR); + sbuf_printf(sb, "%sFCMA", SEP_STR); break; default: - printf("%sUnknown FCMA", SEP_STR); + sbuf_printf(sb, "%sUnknown FCMA", SEP_STR); break; } @@ -406,10 +413,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_JSCVT_NONE: break; case ID_AA64ISAR1_JSCVT_IMPL: - printf("%sJS Conv", SEP_STR); + sbuf_printf(sb, "%sJS Conv", SEP_STR); break; default: - printf("%sUnknown JS Conv", SEP_STR); + sbuf_printf(sb, "%sUnknown JS Conv", SEP_STR); break; } @@ -417,10 +424,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_API_NONE: break; case ID_AA64ISAR1_API_IMPL: - printf("%sImpl AddrAuth", SEP_STR); + sbuf_printf(sb, "%sImpl AddrAuth", SEP_STR); break; default: - printf("%sUnknown Impl AddrAuth", SEP_STR); + sbuf_printf(sb, "%sUnknown Impl AddrAuth", SEP_STR); break; } @@ -428,10 +435,10 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_APA_NONE: break; case ID_AA64ISAR1_APA_IMPL: - printf("%sPrince AddrAuth", SEP_STR); + sbuf_printf(sb, "%sPrince AddrAuth", SEP_STR); break; default: - printf("%sUnknown Prince AddrAuth", SEP_STR); + sbuf_printf(sb, "%sUnknown Prince AddrAuth", SEP_STR); break; } @@ -439,32 +446,34 @@ print_cpu_features(u_int cpu) case ID_AA64ISAR1_DPB_NONE: break; case ID_AA64ISAR1_DPB_IMPL: - printf("%sDC CVAP", SEP_STR); + sbuf_printf(sb, "%sDC CVAP", SEP_STR); break; default: - printf("%sUnknown DC CVAP", SEP_STR); + sbuf_printf(sb, "%sUnknown DC CVAP", SEP_STR); break; } if ((cpu_desc[cpu].id_aa64isar1 & ~ID_AA64ISAR1_MASK) != 0) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64isar1 & ~ID_AA64ISAR1_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Processor Feature Register 0 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_PFR0) != 0) { printed = 0; - printf(" Processor Features 0 = <"); + sbuf_printf(sb, " Processor Features 0 = <"); switch (ID_AA64PFR0_SVE(cpu_desc[cpu].id_aa64pfr0)) { case ID_AA64PFR0_SVE_NONE: break; case ID_AA64PFR0_SVE_IMPL: - printf("%sSVE", SEP_STR); + sbuf_printf(sb, "%sSVE", SEP_STR); break; default: - printf("%sUnknown SVE", SEP_STR); + sbuf_printf(sb, "%sUnknown SVE", SEP_STR); break; } @@ -472,10 +481,10 @@ print_cpu_features(u_int cpu) case ID_AA64PFR0_RAS_NONE: break; case ID_AA64PFR0_RAS_V1: - printf("%sRASv1", SEP_STR); + sbuf_printf(sb, "%sRASv1", SEP_STR); break; default: - printf("%sUnknown RAS", SEP_STR); + sbuf_printf(sb, "%sUnknown RAS", SEP_STR); break; } @@ -483,10 +492,10 @@ print_cpu_features(u_int cpu) case ID_AA64PFR0_GIC_CPUIF_NONE: break; case ID_AA64PFR0_GIC_CPUIF_EN: - printf("%sGIC", SEP_STR); + sbuf_printf(sb, "%sGIC", SEP_STR); break; default: - printf("%sUnknown GIC interface", SEP_STR); + sbuf_printf(sb, "%sUnknown GIC interface", SEP_STR); break; } @@ -494,13 +503,13 @@ print_cpu_features(u_int cpu) case ID_AA64PFR0_ADV_SIMD_NONE: break; case ID_AA64PFR0_ADV_SIMD_IMPL: - printf("%sAdvSIMD", SEP_STR); + sbuf_printf(sb, "%sAdvSIMD", SEP_STR); break; case ID_AA64PFR0_ADV_SIMD_HP: - printf("%sAdvSIMD+HP", SEP_STR); + sbuf_printf(sb, "%sAdvSIMD+HP", SEP_STR); break; default: - printf("%sUnknown AdvSIMD", SEP_STR); + sbuf_printf(sb, "%sUnknown AdvSIMD", SEP_STR); break; } @@ -508,75 +517,77 @@ print_cpu_features(u_int cpu) case ID_AA64PFR0_FP_NONE: break; case ID_AA64PFR0_FP_IMPL: - printf("%sFloat", SEP_STR); + sbuf_printf(sb, "%sFloat", SEP_STR); break; case ID_AA64PFR0_FP_HP: - printf("%sFloat+HP", SEP_STR); + sbuf_printf(sb, "%sFloat+HP", SEP_STR); break; default: - printf("%sUnknown Float", SEP_STR); + sbuf_printf(sb, "%sUnknown Float", SEP_STR); break; } switch (ID_AA64PFR0_EL3(cpu_desc[cpu].id_aa64pfr0)) { case ID_AA64PFR0_EL3_NONE: - printf("%sNo EL3", SEP_STR); + sbuf_printf(sb, "%sNo EL3", SEP_STR); break; case ID_AA64PFR0_EL3_64: - printf("%sEL3", SEP_STR); + sbuf_printf(sb, "%sEL3", SEP_STR); break; case ID_AA64PFR0_EL3_64_32: - printf("%sEL3 32", SEP_STR); + sbuf_printf(sb, "%sEL3 32", SEP_STR); break; default: - printf("%sUnknown EL3", SEP_STR); + sbuf_printf(sb, "%sUnknown EL3", SEP_STR); break; } switch (ID_AA64PFR0_EL2(cpu_desc[cpu].id_aa64pfr0)) { case ID_AA64PFR0_EL2_NONE: - printf("%sNo EL2", SEP_STR); + sbuf_printf(sb, "%sNo EL2", SEP_STR); break; case ID_AA64PFR0_EL2_64: - printf("%sEL2", SEP_STR); + sbuf_printf(sb, "%sEL2", SEP_STR); break; case ID_AA64PFR0_EL2_64_32: - printf("%sEL2 32", SEP_STR); + sbuf_printf(sb, "%sEL2 32", SEP_STR); break; default: - printf("%sUnknown EL2", SEP_STR); + sbuf_printf(sb, "%sUnknown EL2", SEP_STR); break; } switch (ID_AA64PFR0_EL1(cpu_desc[cpu].id_aa64pfr0)) { case ID_AA64PFR0_EL1_64: - printf("%sEL1", SEP_STR); + sbuf_printf(sb, "%sEL1", SEP_STR); break; case ID_AA64PFR0_EL1_64_32: - printf("%sEL1 32", SEP_STR); + sbuf_printf(sb, "%sEL1 32", SEP_STR); break; default: - printf("%sUnknown EL1", SEP_STR); + sbuf_printf(sb, "%sUnknown EL1", SEP_STR); break; } switch (ID_AA64PFR0_EL0(cpu_desc[cpu].id_aa64pfr0)) { case ID_AA64PFR0_EL0_64: - printf("%sEL0", SEP_STR); + sbuf_printf(sb, "%sEL0", SEP_STR); break; case ID_AA64PFR0_EL0_64_32: - printf("%sEL0 32", SEP_STR); + sbuf_printf(sb, "%sEL0 32", SEP_STR); break; default: - printf("%sUnknown EL0", SEP_STR); + sbuf_printf(sb, "%sUnknown EL0", SEP_STR); break; } if ((cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK) != 0) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64pfr0 & ~ID_AA64PFR0_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Processor Feature Register 1 */ @@ -588,15 +599,15 @@ print_cpu_features(u_int cpu) /* AArch64 Memory Model Feature Register 0 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR0) != 0) { printed = 0; - printf(" Memory Model Features 0 = <"); + sbuf_printf(sb, " Memory Model Features 0 = <"); switch (ID_AA64MMFR0_TGRAN4(cpu_desc[cpu].id_aa64mmfr0)) { case ID_AA64MMFR0_TGRAN4_NONE: break; case ID_AA64MMFR0_TGRAN4_IMPL: - printf("%s4k Granule", SEP_STR); + sbuf_printf(sb, "%s4k Granule", SEP_STR); break; default: - printf("%sUnknown 4k Granule", SEP_STR); + sbuf_printf(sb, "%sUnknown 4k Granule", SEP_STR); break; } @@ -604,10 +615,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR0_TGRAN16_NONE: break; case ID_AA64MMFR0_TGRAN16_IMPL: - printf("%s16k Granule", SEP_STR); + sbuf_printf(sb, "%s16k Granule", SEP_STR); break; default: - printf("%sUnknown 16k Granule", SEP_STR); + sbuf_printf(sb, "%sUnknown 16k Granule", SEP_STR); break; } @@ -615,10 +626,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR0_TGRAN64_NONE: break; case ID_AA64MMFR0_TGRAN64_IMPL: - printf("%s64k Granule", SEP_STR); + sbuf_printf(sb, "%s64k Granule", SEP_STR); break; default: - printf("%sUnknown 64k Granule", SEP_STR); + sbuf_printf(sb, "%sUnknown 64k Granule", SEP_STR); break; } @@ -626,10 +637,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR0_BIGEND_FIXED: break; case ID_AA64MMFR0_BIGEND_MIXED: - printf("%sMixedEndian", SEP_STR); + sbuf_printf(sb, "%sMixedEndian", SEP_STR); break; default: - printf("%sUnknown Endian switching", SEP_STR); + sbuf_printf(sb, "%sUnknown Endian switching", SEP_STR); break; } @@ -637,10 +648,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR0_BIGEND_EL0_FIXED: break; case ID_AA64MMFR0_BIGEND_EL0_MIXED: - printf("%sEL0 MixEndian", SEP_STR); + sbuf_printf(sb, "%sEL0 MixEndian", SEP_STR); break; default: - printf("%sUnknown EL0 Endian switching", SEP_STR); + sbuf_printf(sb, "%sUnknown EL0 Endian switching", SEP_STR); break; } @@ -648,71 +659,73 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR0_S_NS_MEM_NONE: break; case ID_AA64MMFR0_S_NS_MEM_DISTINCT: - printf("%sS/NS Mem", SEP_STR); + sbuf_printf(sb, "%sS/NS Mem", SEP_STR); break; default: - printf("%sUnknown S/NS Mem", SEP_STR); + sbuf_printf(sb, "%sUnknown S/NS Mem", SEP_STR); break; } switch (ID_AA64MMFR0_ASID_BITS(cpu_desc[cpu].id_aa64mmfr0)) { case ID_AA64MMFR0_ASID_BITS_8: - printf("%s8bit ASID", SEP_STR); + sbuf_printf(sb, "%s8bit ASID", SEP_STR); break; case ID_AA64MMFR0_ASID_BITS_16: - printf("%s16bit ASID", SEP_STR); + sbuf_printf(sb, "%s16bit ASID", SEP_STR); break; default: - printf("%sUnknown ASID", SEP_STR); + sbuf_printf(sb, "%sUnknown ASID", SEP_STR); break; } switch (ID_AA64MMFR0_PA_RANGE(cpu_desc[cpu].id_aa64mmfr0)) { case ID_AA64MMFR0_PA_RANGE_4G: - printf("%s4GB PA", SEP_STR); + sbuf_printf(sb, "%s4GB PA", SEP_STR); break; case ID_AA64MMFR0_PA_RANGE_64G: - printf("%s64GB PA", SEP_STR); + sbuf_printf(sb, "%s64GB PA", SEP_STR); break; case ID_AA64MMFR0_PA_RANGE_1T: - printf("%s1TB PA", SEP_STR); + sbuf_printf(sb, "%s1TB PA", SEP_STR); break; case ID_AA64MMFR0_PA_RANGE_4T: - printf("%s4TB PA", SEP_STR); + sbuf_printf(sb, "%s4TB PA", SEP_STR); break; case ID_AA64MMFR0_PA_RANGE_16T: - printf("%s16TB PA", SEP_STR); + sbuf_printf(sb, "%s16TB PA", SEP_STR); break; case ID_AA64MMFR0_PA_RANGE_256T: - printf("%s256TB PA", SEP_STR); + sbuf_printf(sb, "%s256TB PA", SEP_STR); break; case ID_AA64MMFR0_PA_RANGE_4P: - printf("%s4PB PA", SEP_STR); + sbuf_printf(sb, "%s4PB PA", SEP_STR); break; default: - printf("%sUnknown PA Range", SEP_STR); + sbuf_printf(sb, "%sUnknown PA Range", SEP_STR); break; } if ((cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK) != 0) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64mmfr0 & ~ID_AA64MMFR0_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Memory Model Feature Register 1 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR1) != 0) { printed = 0; - printf(" Memory Model Features 1 = <"); + sbuf_printf(sb, " Memory Model Features 1 = <"); switch (ID_AA64MMFR1_XNX(cpu_desc[cpu].id_aa64mmfr1)) { case ID_AA64MMFR1_XNX_NONE: break; case ID_AA64MMFR1_XNX_IMPL: - printf("%sEL2 XN", SEP_STR); + sbuf_printf(sb, "%sEL2 XN", SEP_STR); break; default: - printf("%sUnknown XNX", SEP_STR); + sbuf_printf(sb, "%sUnknown XNX", SEP_STR); break; } @@ -720,10 +733,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_SPEC_SEI_NONE: break; case ID_AA64MMFR1_SPEC_SEI_IMPL: - printf("%sSpecSEI", SEP_STR); + sbuf_printf(sb, "%sSpecSEI", SEP_STR); break; default: - printf("%sUnknown SpecSEI", SEP_STR); + sbuf_printf(sb, "%sUnknown SpecSEI", SEP_STR); break; } @@ -731,13 +744,13 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_PAN_NONE: break; case ID_AA64MMFR1_PAN_IMPL: - printf("%sPAN", SEP_STR); + sbuf_printf(sb, "%sPAN", SEP_STR); break; case ID_AA64MMFR1_PAN_ATS1E1: - printf("%sPAN+AT", SEP_STR); + sbuf_printf(sb, "%sPAN+AT", SEP_STR); break; default: - printf("%sUnknown PAN", SEP_STR); + sbuf_printf(sb, "%sUnknown PAN", SEP_STR); break; } @@ -745,10 +758,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_LO_NONE: break; case ID_AA64MMFR1_LO_IMPL: - printf("%sLO", SEP_STR); + sbuf_printf(sb, "%sLO", SEP_STR); break; default: - printf("%sUnknown LO", SEP_STR); + sbuf_printf(sb, "%sUnknown LO", SEP_STR); break; } @@ -756,13 +769,13 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_HPDS_NONE: break; case ID_AA64MMFR1_HPDS_HPD: - printf("%sHPDS", SEP_STR); + sbuf_printf(sb, "%sHPDS", SEP_STR); break; case ID_AA64MMFR1_HPDS_TTPBHA: - printf("%sTTPBHA", SEP_STR); + sbuf_printf(sb, "%sTTPBHA", SEP_STR); break; default: - printf("%sUnknown HPDS", SEP_STR); + sbuf_printf(sb, "%sUnknown HPDS", SEP_STR); break; } @@ -770,10 +783,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_VH_NONE: break; case ID_AA64MMFR1_VH_IMPL: - printf("%sVHE", SEP_STR); + sbuf_printf(sb, "%sVHE", SEP_STR); break; default: - printf("%sUnknown VHE", SEP_STR); + sbuf_printf(sb, "%sUnknown VHE", SEP_STR); break; } @@ -781,10 +794,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_VMIDBITS_8: break; case ID_AA64MMFR1_VMIDBITS_16: - printf("%s16 VMID bits", SEP_STR); + sbuf_printf(sb, "%s16 VMID bits", SEP_STR); break; default: - printf("%sUnknown VMID bits", SEP_STR); + sbuf_printf(sb, "%sUnknown VMID bits", SEP_STR); break; } @@ -792,59 +805,61 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR1_HAFDBS_NONE: break; case ID_AA64MMFR1_HAFDBS_AF: - printf("%sAF", SEP_STR); + sbuf_printf(sb, "%sAF", SEP_STR); break; case ID_AA64MMFR1_HAFDBS_AF_DBS: - printf("%sAF+DBS", SEP_STR); + sbuf_printf(sb, "%sAF+DBS", SEP_STR); break; default: - printf("%sUnknown Hardware update AF/DBS", SEP_STR); + sbuf_printf(sb, "%sUnknown Hardware update AF/DBS", SEP_STR); break; } if ((cpu_desc[cpu].id_aa64mmfr1 & ~ID_AA64MMFR1_MASK) != 0) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64mmfr1 & ~ID_AA64MMFR1_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Memory Model Feature Register 2 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_MMFR2) != 0) { printed = 0; - printf(" Memory Model Features 2 = <"); + sbuf_printf(sb, " Memory Model Features 2 = <"); switch (ID_AA64MMFR2_NV(cpu_desc[cpu].id_aa64mmfr2)) { case ID_AA64MMFR2_NV_NONE: break; case ID_AA64MMFR2_NV_IMPL: - printf("%sNestedVirt", SEP_STR); + sbuf_printf(sb, "%sNestedVirt", SEP_STR); break; default: - printf("%sUnknown NestedVirt", SEP_STR); + sbuf_printf(sb, "%sUnknown NestedVirt", SEP_STR); break; } switch (ID_AA64MMFR2_CCIDX(cpu_desc[cpu].id_aa64mmfr2)) { case ID_AA64MMFR2_CCIDX_32: - printf("%s32b CCIDX", SEP_STR); + sbuf_printf(sb, "%s32b CCIDX", SEP_STR); break; case ID_AA64MMFR2_CCIDX_64: - printf("%s64b CCIDX", SEP_STR); + sbuf_printf(sb, "%s64b CCIDX", SEP_STR); break; default: - printf("%sUnknown CCIDX", SEP_STR); + sbuf_printf(sb, "%sUnknown CCIDX", SEP_STR); break; } switch (ID_AA64MMFR2_VA_RANGE(cpu_desc[cpu].id_aa64mmfr2)) { case ID_AA64MMFR2_VA_RANGE_48: - printf("%s48b VA", SEP_STR); + sbuf_printf(sb, "%s48b VA", SEP_STR); break; case ID_AA64MMFR2_VA_RANGE_52: - printf("%s52b VA", SEP_STR); + sbuf_printf(sb, "%s52b VA", SEP_STR); break; default: - printf("%sUnknown VA Range", SEP_STR); + sbuf_printf(sb, "%sUnknown VA Range", SEP_STR); break; } @@ -852,10 +867,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR2_IESB_NONE: break; case ID_AA64MMFR2_IESB_IMPL: - printf("%sIESB", SEP_STR); + sbuf_printf(sb, "%sIESB", SEP_STR); break; default: - printf("%sUnknown IESB", SEP_STR); + sbuf_printf(sb, "%sUnknown IESB", SEP_STR); break; } @@ -863,10 +878,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR2_LSM_NONE: break; case ID_AA64MMFR2_LSM_IMPL: - printf("%sLSM", SEP_STR); + sbuf_printf(sb, "%sLSM", SEP_STR); break; default: - printf("%sUnknown LSM", SEP_STR); + sbuf_printf(sb, "%sUnknown LSM", SEP_STR); break; } @@ -874,10 +889,10 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR2_UAO_NONE: break; case ID_AA64MMFR2_UAO_IMPL: - printf("%sUAO", SEP_STR); + sbuf_printf(sb, "%sUAO", SEP_STR); break; default: - printf("%sUnknown UAO", SEP_STR); + sbuf_printf(sb, "%sUnknown UAO", SEP_STR); break; } @@ -885,57 +900,59 @@ print_cpu_features(u_int cpu) case ID_AA64MMFR2_CNP_NONE: break; case ID_AA64MMFR2_CNP_IMPL: - printf("%sCnP", SEP_STR); + sbuf_printf(sb, "%sCnP", SEP_STR); break; default: - printf("%sUnknown CnP", SEP_STR); + sbuf_printf(sb, "%sUnknown CnP", SEP_STR); break; } if ((cpu_desc[cpu].id_aa64mmfr2 & ~ID_AA64MMFR2_MASK) != 0) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64mmfr2 & ~ID_AA64MMFR2_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Debug Feature Register 0 */ if (cpu == 0 || (cpu_print_regs & PRINT_ID_AA64_DFR0) != 0) { printed = 0; - printf(" Debug Features 0 = <"); + sbuf_printf(sb, " Debug Features 0 = <"); switch(ID_AA64DFR0_PMS_VER(cpu_desc[cpu].id_aa64dfr0)) { case ID_AA64DFR0_PMS_VER_NONE: break; case ID_AA64DFR0_PMS_VER_V1: - printf("%sSPE v1", SEP_STR); + sbuf_printf(sb, "%sSPE v1", SEP_STR); break; default: - printf("%sUnknown SPE", SEP_STR); + sbuf_printf(sb, "%sUnknown SPE", SEP_STR); break; } - printf("%s%lu CTX Breakpoints", SEP_STR, + sbuf_printf(sb, "%s%lu CTX Breakpoints", SEP_STR, ID_AA64DFR0_CTX_CMPS(cpu_desc[cpu].id_aa64dfr0)); - printf("%s%lu Watchpoints", SEP_STR, + sbuf_printf(sb, "%s%lu Watchpoints", SEP_STR, ID_AA64DFR0_WRPS(cpu_desc[cpu].id_aa64dfr0)); - printf("%s%lu Breakpoints", SEP_STR, + sbuf_printf(sb, "%s%lu Breakpoints", SEP_STR, ID_AA64DFR0_BRPS(cpu_desc[cpu].id_aa64dfr0)); switch (ID_AA64DFR0_PMU_VER(cpu_desc[cpu].id_aa64dfr0)) { case ID_AA64DFR0_PMU_VER_NONE: break; case ID_AA64DFR0_PMU_VER_3: - printf("%sPMUv3", SEP_STR); + sbuf_printf(sb, "%sPMUv3", SEP_STR); break; case ID_AA64DFR0_PMU_VER_3_1: - printf("%sPMUv3+16 bit evtCount", SEP_STR); + sbuf_printf(sb, "%sPMUv3+16 bit evtCount", SEP_STR); break; case ID_AA64DFR0_PMU_VER_IMPL: - printf("%sImplementation defined PMU", SEP_STR); + sbuf_printf(sb, "%sImplementation defined PMU", SEP_STR); break; default: - printf("%sUnknown PMU", SEP_STR); + sbuf_printf(sb, "%sUnknown PMU", SEP_STR); break; } @@ -943,32 +960,34 @@ print_cpu_features(u_int cpu) case ID_AA64DFR0_TRACE_VER_NONE: break; case ID_AA64DFR0_TRACE_VER_IMPL: - printf("%sTrace", SEP_STR); + sbuf_printf(sb, "%sTrace", SEP_STR); break; default: - printf("%sUnknown Trace", SEP_STR); + sbuf_printf(sb, "%sUnknown Trace", SEP_STR); break; } switch (ID_AA64DFR0_DEBUG_VER(cpu_desc[cpu].id_aa64dfr0)) { case ID_AA64DFR0_DEBUG_VER_8: - printf("%sDebug v8", SEP_STR); + sbuf_printf(sb, "%sDebug v8", SEP_STR); break; case ID_AA64DFR0_DEBUG_VER_8_VHE: - printf("%sDebug v8+VHE", SEP_STR); + sbuf_printf(sb, "%sDebug v8+VHE", SEP_STR); break; case ID_AA64DFR0_DEBUG_VER_8_2: - printf("%sDebug v8.2", SEP_STR); + sbuf_printf(sb, "%sDebug v8.2", SEP_STR); break; default: - printf("%sUnknown Debug", SEP_STR); + sbuf_printf(sb, "%sUnknown Debug", SEP_STR); break; } if (cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK) - printf("%s%#lx", SEP_STR, + sbuf_printf(sb, "%s%#lx", SEP_STR, cpu_desc[cpu].id_aa64dfr0 & ~ID_AA64DFR0_MASK); - printf(">\n"); + sbuf_finish(sb); + printf("%s>\n", sbuf_data(sb)); + sbuf_clear(sb); } /* AArch64 Memory Model Feature Register 1 */ @@ -989,6 +1008,8 @@ print_cpu_features(u_int cpu) cpu_desc[cpu].id_aa64afr1); } + sbuf_delete(sb); + sb = NULL; #undef SEP_STR } From beacffb30d89c29505f2303d91396e3603f54dd9 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Mon, 20 Aug 2018 02:08:39 +0000 Subject: [PATCH 047/222] Add drawer.lua(8) --- stand/lua/drawer.lua.8 | 179 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) create mode 100644 stand/lua/drawer.lua.8 diff --git a/stand/lua/drawer.lua.8 b/stand/lua/drawer.lua.8 new file mode 100644 index 000000000000..4a76895bdddb --- /dev/null +++ b/stand/lua/drawer.lua.8 @@ -0,0 +1,179 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2018 Kyle Evans +.\" +.\" 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$ +.\" +.Dd August 19, 2018 +.Dt DRAWER.LUA 8 +.Os +.Sh NAME +.Nm drawer.lua +.Nd FreeBSD menu/screen drawer module +.Sh DESCRIPTION +.Nm +contains functionality for drawing and manipulating the menu, logo, and brand +to the screen. +.Pp +Before using the functionality provided by +.Nm , +it must be included with a statement such as the following: +.Pp +.Dl local drawer = require("drawer") +.Ss BRAND DEFINITIONS +Brand definitions describe a +.Dq brand , +traditionally drawn above the menu. +The exact position may be controlled by using the +.Xr loader.conf 5 +variables +.Va loader_brand_x +and +.Va loader_brand_y . +The following keys may be defined for a brand definition: +.Bl -tag -width ".Ic Graphic" -offset indent +.It Ic graphic +A table of strings containing rows of text to be drawn to the screen. +.El +.Ss LOGO DEFINITIONS +Logo definitions describe a +.Dq logo , +traditionally to the right of the menu. +The exact position may be controlled by using the +.Xr loader.conf 5 +variables +.Va loader_logo_x +and +.Va loader_logo_y . +The following keys may be defined for a logo definition: +.Bl -tag -width ".Ic requires_color" -offset indent +.It Ic requires_color +A boolean describing whether or not this logo definition requires color. +If it is chosen to be drawn and it requires color on a color-disabled boot, +.Nm +will elect to use the default +.Dq orbbw +logo rather than the chosen logo. +.It Ic graphic +A table of strings containing rows of text to be drawn to the screen. +.It Ic shift +A table describing the +.Va x +and +.Va y +shift that should be applied to all elements should this logo be selected. +This is typically used for shifting the menu and brand if an empty or minimal +logo are selected. +.El +.Ss CUSTOM BRANDS AND LOGOS +The brand and logo system is designed to allow brands and logos to be easily +plugged in. +When an unrecognized +.Ev loader_brand +or +.Ev loader_logo +are encountered, +.Nm +will attempt to include +.Pa brand-${loader_brand}.lua +or +.Pa logo-${loader_logo}.lua +respectively. +These files are expected to call either +.Fn drawer.addBrand +or +.Fn drawer.addLogo +to add the requested branddef or logodef. +.Nm +will attempt to do another lookup for the requested brand or logo before falling +back to one of the following: +.Bl -tag -width ".Ic drawer.default_color_logodef" -offset indent +.It Ic drawer.default_brand +The default brand to be used if the requested brand cannot be located. +.It Ic drawer.default_color_logodef +The default logodef to be used if an invalid logodef is requested and +.Xr loader 8 +has been configured to allow output of color. +.It Ic drawer.default_bw_logodef +The default logodef to be used if either an invalid logodef has been requested, +or a logodef has been requested that requires color and +.Xr loader 8 +has been configured to not output color. +.El +.Ss FRAME STYLES +.Nm +contains the definitions for the different frame styles that may be drawn around +the menu. +Frame styles define the characters drawn for horizontal lines, vertical aligns, +and each of the four corner styles. +The following keys may be defined for a frame style: +.Bl -bullet -width "" +.It +horizontal +.It +vertical +.It +top_left +.It +bottom_left +.It +top_right +.It +bottom_right +.El +Frame styles are currently defined in the table +.Ic drawer.frame_styles +indexed by the name used for +.Ev loader_menu_frame . +No API currently exists for manipulating this table indirectly. +.Ss Exported functions +The following functions are exported from +.Nm : +.Bl -tag -width hook.registerType -offset indent +.It Fn drawer.addBrand name def +Add the brand definition described by +.Fa def +to the table of known brand definitions, indexed by +.Fa name . +.It Fn drawer.addLogo name def +Add the logo definition described by +.Fa def +to the table of known logo definitions, indexed by +.Fa name . +.It Fn drawer.drawscreen menudef +Draws the logo, brand, menu frame, and the current menu as described in +.Fa menudef , +formatted as defined by +.Xr menu.lua 8 . +.El +.Sh SEE ALSO +.Xr menu.lua 8 +.Sh AUTHORS +The +.Nm +file was originally written by +.An Pedro Souza Aq Mt pedrosouza@FreeBSD.org . +Later work and this manual page was done by +.An Kyle Evans Aq Mt kevans@FreeBSD.org . From 59488f25ad9d2e804f85a48d38e38df9e94ae61d Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 20 Aug 2018 02:17:55 +0000 Subject: [PATCH 048/222] In r331279 the code used ENOSYS to check the existence of getrandom(2). This will only work if the caller already handles SIGSYS, which is not always the case. Address this by checking osreldate instead. Note that because there was not __FreeBSD_version bump when the system call was added, use 1200061 (r332100) which is the first bump after the introduction of the system call. PR: 230762 Reported by: Jenkins via Mark Millard Reviewed by: cem Differential Revision: https://reviews.freebsd.org/D16807 --- lib/libc/gen/getentropy.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/lib/libc/gen/getentropy.c b/lib/libc/gen/getentropy.c index 2e0f649a15be..4e91afc6a6a1 100644 --- a/lib/libc/gen/getentropy.c +++ b/lib/libc/gen/getentropy.c @@ -34,10 +34,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include "libc_private.h" +/* First __FreeBSD_version bump after introduction of getrandom(2) (r331279) */ +#define GETRANDOM_FIRST 1200061 + extern int __sysctl(int *, u_int, void *, size_t *, void *, size_t); static size_t @@ -99,21 +103,38 @@ int getentropy(void *buf, size_t buflen) { ssize_t rd; + bool have_getrandom; if (buflen > 256) { errno = EIO; return (-1); } + have_getrandom = (__getosreldate() >= GETRANDOM_FIRST); + while (buflen > 0) { - rd = getrandom(buf, buflen, 0); - if (rd == -1) { - if (errno == EINTR) - continue; - else if (errno == ENOSYS || errno == ECAPMODE) - return (getentropy_fallback(buf, buflen)); - else - return (-1); + if (have_getrandom) { + rd = getrandom(buf, buflen, 0); + if (rd == -1) { + switch (errno) { + case ECAPMODE: + /* + * Kernel >= r331280 and < r337999 + * will return ECAPMODE when the + * caller is already in capability + * mode, fallback to traditional + * method in this case. + */ + have_getrandom = false; + continue; + case EINTR: + continue; + default: + return (-1); + } + } + } else { + return (getentropy_fallback(buf, buflen)); } /* This cannot happen. */ From 75658c965ce860beb7bed9b0afa003df93bba877 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Mon, 20 Aug 2018 02:37:24 +0000 Subject: [PATCH 049/222] Add color.lua(8), password.lua(8), and screen.lua(8) --- stand/lua/color.lua.8 | 132 +++++++++++++++++++++++++++++++++++++++ stand/lua/password.lua.8 | 74 ++++++++++++++++++++++ stand/lua/screen.lua.8 | 102 ++++++++++++++++++++++++++++++ 3 files changed, 308 insertions(+) create mode 100644 stand/lua/color.lua.8 create mode 100644 stand/lua/password.lua.8 create mode 100644 stand/lua/screen.lua.8 diff --git a/stand/lua/color.lua.8 b/stand/lua/color.lua.8 new file mode 100644 index 000000000000..d32f702c0daa --- /dev/null +++ b/stand/lua/color.lua.8 @@ -0,0 +1,132 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2018 Kyle Evans +.\" +.\" 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$ +.\" +.Dd August 19, 2018 +.Dt COLOR.LUA 8 +.Os +.Sh NAME +.Nm color.lua +.Nd FreeBSD color module +.Sh DESCRIPTION +.Nm +contains functionality for working with colors. +.Pp +Before using the functionality provided by +.Nm , +it must be included with a statement such as the following: +.Pp +.Dl local color = require("color") +.Pp +The following color constants are exported from +.Nm : +.Bl -tag -width "Ic color.MAGENTA" -offset indent +.It Ic color.BLACK +.It Ic color.RED +.It Ic color.GREEN +.It Ic color.YELLOW +.It Ic color.BLUE +.It Ic color.MAGENTA +.It Ic color.CYAN +.It Ic color.WHITE +.El +.Pp +The following attribute constants are exported from +.Nm : +.Bl -tag -width "Ic color.DEFAULT" -offset indent +.It Ic color.DEFAULT +.It Ic color.BRIGHT +.It Ic color.DIM +.El +.Pp +The following functions are exported from +.Nm : +.Bl -tag -width "Fn color.isEnabled" -offset indent +.It Fn color.isEnabled +Returns True if +.Xr loader 8 +has been configured to not allow color, False otherwise. +This checks the +.Ev loader_color +.Xr loader.conf 5 +variable, along with +.Fn core.isSerialBoot . +.It Fn color.escapefg color_value +Returns the escape sequence that encodes +.Fa color_value +as a foreground color. +.Fn color.escapefg +returns an empty string if color is disabled. +.It Fn color.resetfg +Returns the escape sequence for the default foreground color. +.Fn color.resetfg +returns an empty string if color is disabled. +.It Fn color.escapebg color_value +Returns the escape sequence that encodes +.Fa color_value +as a background color. +.Fn color.escapebg +returns an empty string if color is disabled. +.It Fn color.resetbg +Returns the escape sequence for the default background color. +.Fn color.resetbg +returns an empty string if color is disabled. +.It Fn color.escape fg_color bg_color attribute +Returns an escape sequence that encodes +.Fa fg_color +as the foreground color, +.Fa bg_color +as the background color, and +.Fa attribute +applied. +.Fn color.escape +returns an empty string if color is disabled. +.It Fn color.default +Returns the escape sequence for the default color scheme, white on black with +no attributes applied. +.Fn color.default +returns an empty string if color is disabled. +.It Fn color.highlight str +Returns +.Fa str +with the +.Ic color.BRIGHT +attribute applied before it and reset after it. +.Fn color.highlight +returns +.Fa str +if color is disabled. +.El +.Sh SEE ALSO +.Xr screen.lua 8 +.Sh AUTHORS +The +.Nm +file was originally written by +.An Pedro Souza Aq Mt pedrosouza@FreeBSD.org . +Later work and this manual page was done by +.An Kyle Evans Aq Mt kevans@FreeBSD.org . diff --git a/stand/lua/password.lua.8 b/stand/lua/password.lua.8 new file mode 100644 index 000000000000..db235aadec8d --- /dev/null +++ b/stand/lua/password.lua.8 @@ -0,0 +1,74 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2018 Kyle Evans +.\" +.\" 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$ +.\" +.Dd August 19, 2018 +.Dt PASSWORD.LUA 8 +.Os +.Sh NAME +.Nm password.lua +.Nd FreeBSD password module +.Sh DESCRIPTION +.Nm +contains functionality for prompting for and checking passwords. +.Pp +Before using the functionality provided by +.Nm , +it must be included with a statement such as the following: +.Pp +.Dl local password = require("password") +.Pp +The following functions are exported from +.Nm : +.Bl -tag -width "Fn password.read prompt_length" -offset indent +.It Fn password.read prompt_length +Read a password following a prompt. +.Fa prompt_length +is required so that the twiddle may be properly drawn as the user is typing. +.It Fn password.check +Drives the primary password checks done by the loader. +The +.Fn password.check +function will check +.Ev bootlock_password , +.Ev geom_eli_passphrase_prompt , +and +.Ev password +and prompt the user for passwords as-needed. +If +.Ev password +is set, the autoboot sequence will begin as the user is prompted for a password. +.El +.Sh SEE ALSO +.Xr screen.lua 8 +.Sh AUTHORS +The +.Nm +file was originally written by +.An Pedro Souza Aq Mt pedrosouza@FreeBSD.org . +Later work and this manual page was done by +.An Kyle Evans Aq Mt kevans@FreeBSD.org . diff --git a/stand/lua/screen.lua.8 b/stand/lua/screen.lua.8 new file mode 100644 index 000000000000..d272f3ca8028 --- /dev/null +++ b/stand/lua/screen.lua.8 @@ -0,0 +1,102 @@ +.\" +.\" SPDX-License-Identifier: BSD-2-Clause-FreeBSD +.\" +.\" Copyright (c) 2018 Kyle Evans +.\" +.\" 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$ +.\" +.Dd August 19, 2018 +.Dt SCREEN.LUA 8 +.Os +.Sh NAME +.Nm screen.lua +.Nd FreeBSD screen manipulation module +.Sh DESCRIPTION +.Nm +contains functionality for manipulating the screen. +This includes functionality such as clearing the screen, moving the cursor, and +setting foreground/background colors using sequences provided by +.Xr color.lua 8 . +.Pp +Before using the functionality provided by +.Nm , +it must be included with a statement such as the following: +.Pp +.Dl local screen = require("screen") +.Pp +The following variables are exported from +.Nm : +.Bl -tag -width "Ic screen.default_x" -offset indent +.It Ic screen.default_x +The x component of the default cursor position. +.It Ic screen.default_y +The y component of the default cursor position. +.El +.Pp +The following functions are exported from +.Nm : +.Bl -tag -width "Fn screen.clear" -offset indent +.It Fn screen.clear +Clears the screen. +.Fn screen.clear +will do nothing if a serial boot is detected. +.It Fn screen.setcursor x y +Sets the cursor position to +.Fa x , +.Fa y . +.Fn screen.setcursor +will do nothing if a serial boot is detected. +.It Fn screen.setforeground color_value +Sets the foreground color to +.Fa color_value , +which should be a constant defined in +.Xr color.lua 8 . +.Fn screen.setforeground +will do nothing if color is disabled. +.It Fn screen.setbackground color_value +Sets the background color to +.Fa color_value , +which should be a constant defined in +.Xr color.lua 8 . +.Fn screen.setbackground +will do nothing if color is disabled. +.It Fn screen.defcolor +Sets the default color scheme, as defined by +.Fn color.default . +.Fn screen.defcolor +will do nothing if color is disabled. +.It Fn screen.defcursor +Sets the default cursor position to that defined by +.Ic screen.default_x , +.Ic screen.default_y . +.El +.Sh SEE ALSO +.Xr color.lua 8 +.Sh AUTHORS +The +.Nm +file was originally written by +.An Pedro Souza Aq Mt pedrosouza@FreeBSD.org . +Later work and this manual page was done by +.An Kyle Evans Aq Mt kevans@FreeBSD.org . From b991b318d40c221f39b54333f0725900c48f9020 Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Mon, 20 Aug 2018 02:40:10 +0000 Subject: [PATCH 050/222] lualoader: Install all manpages Now that a complete set is written, save for one describing loader.lua, install all of them. This was not previously done as they were written to hopefully avoid confusion as bits and pieces of the overall system were undocumented. --- stand/lua/Makefile | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stand/lua/Makefile b/stand/lua/Makefile index d48cccca8979..6e7019603ae4 100644 --- a/stand/lua/Makefile +++ b/stand/lua/Makefile @@ -2,6 +2,16 @@ .include +MAN= cli.lua.8 \ + color.lua.8 \ + config.lua.8 \ + core.lua.8 \ + drawer.lua.8 \ + hook.lua.8 \ + menu.lua.8 \ + password.lua.8 \ + screen.lua.8 + FILESDIR= /boot/lua FILES= cli.lua \ color.lua \ From df90fce298821ae3bff305b42d35ea8a3c037d20 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Mon, 20 Aug 2018 04:44:29 +0000 Subject: [PATCH 051/222] Fix double mutex lock. Reported by: Coverity CID: 1394833 Discussed with: Leon Dang Sponsored by: iXsystems Inc. --- usr.sbin/bhyve/pci_nvme.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index 5fc4c2af705a..3671db162752 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -358,7 +358,7 @@ pci_nvme_init_nsdata(struct pci_nvme_softc *sc) } static void -pci_nvme_reset(struct pci_nvme_softc *sc) +pci_nvme_reset_locked(struct pci_nvme_softc *sc) { DPRINTF(("%s\r\n", __func__)); @@ -374,7 +374,6 @@ pci_nvme_reset(struct pci_nvme_softc *sc) sc->regs.csts = 0; if (sc->submit_queues != NULL) { - pthread_mutex_lock(&sc->mtx); sc->num_cqueues = sc->num_squeues = sc->max_queues; for (int i = 0; i <= sc->max_queues; i++) { @@ -398,8 +397,6 @@ pci_nvme_reset(struct pci_nvme_softc *sc) sc->compl_queues[i].tail = 0; sc->compl_queues[i].head = 0; } - - pthread_mutex_unlock(&sc->mtx); } else sc->submit_queues = calloc(sc->max_queues + 1, sizeof(struct nvme_submission_queue)); @@ -413,6 +410,14 @@ pci_nvme_reset(struct pci_nvme_softc *sc) } } +static void +pci_nvme_reset(struct pci_nvme_softc *sc) +{ + pthread_mutex_lock(&sc->mtx); + pci_nvme_reset_locked(sc); + pthread_mutex_unlock(&sc->mtx); +} + static void pci_nvme_init_controller(struct vmctx *ctx, struct pci_nvme_softc *sc) { @@ -1537,7 +1542,7 @@ pci_nvme_write_bar_0(struct vmctx *ctx, struct pci_nvme_softc* sc, if (NVME_CC_GET_EN(ccreg) != NVME_CC_GET_EN(sc->regs.cc)) { if (NVME_CC_GET_EN(ccreg) == 0) /* transition 1-> causes controller reset */ - pci_nvme_reset(sc); + pci_nvme_reset_locked(sc); else pci_nvme_init_controller(ctx, sc); } From b018ea0174b80175cac60717f2b0432d67de35a8 Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Mon, 20 Aug 2018 04:50:11 +0000 Subject: [PATCH 052/222] Users must set the number of queues from 1 to maximum 16 queues. Sponsored by: iXsystems Inc. --- usr.sbin/bhyve/pci_nvme.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index 3671db162752..35e07eb49529 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -373,9 +373,8 @@ pci_nvme_reset_locked(struct pci_nvme_softc *sc) sc->regs.cc = 0; sc->regs.csts = 0; + sc->num_cqueues = sc->num_squeues = sc->max_queues; if (sc->submit_queues != NULL) { - sc->num_cqueues = sc->num_squeues = sc->max_queues; - for (int i = 0; i <= sc->max_queues; i++) { /* * The Admin Submission Queue is at index 0. @@ -1765,10 +1764,9 @@ pci_nvme_parse_opts(struct pci_nvme_softc *sc, char *opts) (1 << sc->nvstore.sectsz_bits) < sc->nvstore.sectsz; sc->nvstore.sectsz_bits++); - if (sc->max_queues == 0) { - fprintf(stderr, "Invalid maxq option\n"); - return (-1); - } + if (sc->max_queues <= 0 || sc->max_queues > NVME_QUEUES) + sc->max_queues = NVME_QUEUES; + if (sc->max_qentries <= 0) { fprintf(stderr, "Invalid qsz option\n"); return (-1); From 6b2c20cd98598a1c5001acaedf8b2219ca0ff7eb Mon Sep 17 00:00:00 2001 From: Marcelo Araujo Date: Mon, 20 Aug 2018 04:56:37 +0000 Subject: [PATCH 053/222] NVMe spec version 1.3c says that "serial number" field must be 7-bit ASCII, with unused bytes padded by space characters. Same for firmware number and namespace number. Discussed with: imp@ Sponsored by: iXsystems Inc. --- usr.sbin/bhyve/pci_nvme.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index 35e07eb49529..e99566cf29e0 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -253,6 +253,14 @@ static void pci_nvme_io_partial(struct blockif_req *br, int err); ((NVME_STATUS_SCT_MASK << NVME_STATUS_SCT_SHIFT) |\ (NVME_STATUS_SC_MASK << NVME_STATUS_SC_SHIFT)) +static __inline void +cpywithpad(char *dst, int dst_size, const char *src, char pad) +{ + int len = strnlen(src, dst_size); + memcpy(dst, src, len); + memset(dst + len, pad, dst_size - len); +} + static __inline void pci_nvme_status_tc(uint16_t *status, uint16_t type, uint16_t code) { @@ -287,20 +295,8 @@ pci_nvme_init_ctrldata(struct pci_nvme_softc *sc) cd->vid = 0xFB5D; cd->ssvid = 0x0000; - cd->mn[0] = 'b'; - cd->mn[1] = 'h'; - cd->mn[2] = 'y'; - cd->mn[3] = 'v'; - cd->mn[4] = 'e'; - cd->mn[5] = '-'; - cd->mn[6] = 'N'; - cd->mn[7] = 'V'; - cd->mn[8] = 'M'; - cd->mn[9] = 'e'; - - cd->fr[0] = '1'; - cd->fr[1] = '.'; - cd->fr[2] = '0'; + cpywithpad((char *)cd->mn, sizeof(cd->mn), "bhyve-NVMe", ' '); + cpywithpad((char *)cd->fr, sizeof(cd->fr), "1.0", ' '); /* Num of submission commands that we can handle at a time (2^rab) */ cd->rab = 4; @@ -1715,12 +1711,11 @@ pci_nvme_parse_opts(struct pci_nvme_softc *sc, char *opts) } else if (!strcmp("ser", xopts)) { /* * This field indicates the Product Serial Number in - * 8-bit ASCII, unused bytes should be NULL characters. - * Ref: NVM Express Management Interface 1.0a. + * 7-bit ASCII, unused bytes should be space characters. + * Ref: NVMe v1.3c. */ - memset(sc->ctrldata.sn, 0, sizeof(sc->ctrldata.sn)); - strncpy(sc->ctrldata.sn, config, - sizeof(sc->ctrldata.sn)); + cpywithpad((char *)sc->ctrldata.sn, + sizeof(sc->ctrldata.sn), config, ' '); } else if (!strcmp("ram", xopts)) { uint64_t sz = strtoull(&xopts[4], NULL, 10); From c7f4d2332394d5600fe4e14c530ede36b0ff29b0 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 20 Aug 2018 06:07:33 +0000 Subject: [PATCH 054/222] Vendor import of ntp-4.2.8p12. --- ChangeLog | 72 +- NEWS | 73 +- config.h.in | 23 + configure | 112 ++- configure.ac | 15 + html/authentic.html | 306 ++++-- html/authopt.html | 49 +- html/confopt.html | 4 +- html/keygen.html | 4 +- html/ntpdate.html | 4 +- include/ntp.h | 12 + include/ntp_md5.h | 7 +- libntp/a_md5encrypt.c | 17 +- libntp/ntp_calendar.c | 2 +- libntp/prettydate.c | 5 + libntp/ssl_init.c | 27 +- libntp/syssignal.c | 9 +- libntp/work_fork.c | 4 + libntp/work_thread.c | 17 +- ntpd/complete.conf.in | 2 +- ntpd/invoke-ntp.conf.texi | 12 +- ntpd/invoke-ntp.keys.texi | 6 +- ntpd/invoke-ntpd.texi | 4 +- ntpd/ntp.conf.5man | 16 +- ntpd/ntp.conf.5mdoc | 14 +- ntpd/ntp.conf.def | 10 +- ntpd/ntp.conf.html | 12 +- ntpd/ntp.conf.man.in | 16 +- ntpd/ntp.conf.mdoc.in | 14 +- ntpd/ntp.keys.5man | 8 +- ntpd/ntp.keys.5mdoc | 8 +- ntpd/ntp.keys.def | 4 +- ntpd/ntp.keys.html | 6 +- ntpd/ntp.keys.man.in | 8 +- ntpd/ntp.keys.mdoc.in | 8 +- ntpd/ntp_config.c | 39 +- ntpd/ntp_control.c | 97 +- ntpd/ntp_io.c | 55 +- ntpd/ntp_loopfilter.c | 12 +- ntpd/ntp_parser.c | 677 ++++++------- ntpd/ntp_parser.h | 2 +- ntpd/ntp_parser.y | 1 + ntpd/ntp_proto.c | 145 +-- ntpd/ntp_refclock.c | 2 +- ntpd/ntp_request.c | 1 + ntpd/ntpd-opts.c | 14 +- ntpd/ntpd-opts.h | 6 +- ntpd/ntpd.1ntpdman | 6 +- ntpd/ntpd.1ntpdmdoc | 4 +- ntpd/ntpd.c | 400 +++++--- ntpd/ntpd.html | 4 +- ntpd/ntpd.man.in | 6 +- ntpd/ntpd.mdoc.in | 4 +- ntpd/rc_cmdlength.c | 2 + ntpd/refclock_datum.c | 3 +- ntpd/refclock_gpsdjson.c | 4 +- ntpd/refclock_jupiter.c | 3 +- ntpd/refclock_shm.c | 1 + ntpd/refclock_true.c | 2 +- ntpdate/ntpdate.c | 187 ++-- ntpdc/invoke-ntpdc.texi | 4 +- ntpdc/ntpdc-opts.c | 14 +- ntpdc/ntpdc-opts.h | 6 +- ntpdc/ntpdc.1ntpdcman | 6 +- ntpdc/ntpdc.1ntpdcmdoc | 4 +- ntpdc/ntpdc.c | 80 +- ntpdc/ntpdc.html | 4 +- ntpdc/ntpdc.man.in | 6 +- ntpdc/ntpdc.mdoc.in | 4 +- ntpq/invoke-ntpq.texi | 4 +- ntpq/ntpq-opts.c | 14 +- ntpq/ntpq-opts.h | 6 +- ntpq/ntpq-subs.c | 59 +- ntpq/ntpq.1ntpqman | 6 +- ntpq/ntpq.1ntpqmdoc | 4 +- ntpq/ntpq.c | 890 +++++++++++------- ntpq/ntpq.html | 6 +- ntpq/ntpq.man.in | 6 +- ntpq/ntpq.mdoc.in | 4 +- ntpq/ntpq.texi | 2 +- ntpsnmpd/invoke-ntpsnmpd.texi | 2 +- ntpsnmpd/ntpsnmpd-opts.c | 14 +- ntpsnmpd/ntpsnmpd-opts.h | 6 +- ntpsnmpd/ntpsnmpd.1ntpsnmpdman | 6 +- ntpsnmpd/ntpsnmpd.1ntpsnmpdmdoc | 4 +- ntpsnmpd/ntpsnmpd.html | 2 +- ntpsnmpd/ntpsnmpd.man.in | 6 +- ntpsnmpd/ntpsnmpd.mdoc.in | 4 +- packageinfo.sh | 2 +- ports/winnt/include/ntservice.h | 1 + ports/winnt/ntpd/nt_clockstuff.c | 6 - ports/winnt/ntpd/ntservice.c | 69 +- .../calc_tickadj.1calc_tickadjman | 6 +- .../calc_tickadj.1calc_tickadjmdoc | 4 +- scripts/calc_tickadj/calc_tickadj.html | 2 +- scripts/calc_tickadj/calc_tickadj.man.in | 6 +- scripts/calc_tickadj/calc_tickadj.mdoc.in | 4 +- scripts/calc_tickadj/invoke-calc_tickadj.texi | 2 +- scripts/invoke-plot_summary.texi | 4 +- scripts/invoke-summary.texi | 4 +- scripts/ntp-wait/invoke-ntp-wait.texi | 4 +- scripts/ntp-wait/ntp-wait-opts | 4 +- scripts/ntp-wait/ntp-wait.1ntp-waitman | 6 +- scripts/ntp-wait/ntp-wait.1ntp-waitmdoc | 4 +- scripts/ntp-wait/ntp-wait.html | 4 +- scripts/ntp-wait/ntp-wait.man.in | 6 +- scripts/ntp-wait/ntp-wait.mdoc.in | 4 +- scripts/ntpsweep/invoke-ntpsweep.texi | 4 +- scripts/ntpsweep/ntpsweep-opts | 4 +- scripts/ntpsweep/ntpsweep.1ntpsweepman | 6 +- scripts/ntpsweep/ntpsweep.1ntpsweepmdoc | 4 +- scripts/ntpsweep/ntpsweep.html | 4 +- scripts/ntpsweep/ntpsweep.man.in | 6 +- scripts/ntpsweep/ntpsweep.mdoc.in | 4 +- scripts/ntptrace/invoke-ntptrace.texi | 4 +- scripts/ntptrace/ntptrace-opts | 4 +- scripts/ntptrace/ntptrace.1ntptraceman | 6 +- scripts/ntptrace/ntptrace.1ntptracemdoc | 4 +- scripts/ntptrace/ntptrace.html | 4 +- scripts/ntptrace/ntptrace.man.in | 6 +- scripts/ntptrace/ntptrace.mdoc.in | 4 +- scripts/plot_summary-opts | 4 +- scripts/plot_summary.1plot_summaryman | 6 +- scripts/plot_summary.1plot_summarymdoc | 4 +- scripts/plot_summary.html | 4 +- scripts/plot_summary.man.in | 6 +- scripts/plot_summary.mdoc.in | 4 +- scripts/summary-opts | 4 +- scripts/summary.1summaryman | 6 +- scripts/summary.1summarymdoc | 4 +- scripts/summary.html | 4 +- scripts/summary.man.in | 6 +- scripts/summary.mdoc.in | 4 +- scripts/update-leap/invoke-update-leap.texi | 2 +- scripts/update-leap/update-leap-opts | 4 +- .../update-leap/update-leap.1update-leapman | 6 +- .../update-leap/update-leap.1update-leapmdoc | 4 +- scripts/update-leap/update-leap.html | 76 +- scripts/update-leap/update-leap.man.in | 6 +- scripts/update-leap/update-leap.mdoc.in | 4 +- sntp/config.h.in | 12 + sntp/configure | 71 +- sntp/crypto.c | 9 +- sntp/include/version.def | 2 +- sntp/include/version.texi | 6 +- sntp/invoke-sntp.texi | 50 +- sntp/m4/ntp_libntp.m4 | 23 +- sntp/m4/ntp_openssl.m4 | 1 + sntp/m4/version.m4 | 2 +- sntp/main.c | 7 + sntp/sntp-opts.c | 14 +- sntp/sntp-opts.h | 6 +- sntp/sntp.1sntpman | 6 +- sntp/sntp.1sntpmdoc | 4 +- sntp/sntp.html | 50 +- sntp/sntp.man.in | 6 +- sntp/sntp.mdoc.in | 4 +- sntp/tests/crypto.c | 4 +- sntp/tests/packetProcessing.c | 8 + sntp/version.c | 2 +- tests/libntp/ssl_init.c | 8 +- util/invoke-ntp-keygen.texi | 40 +- util/ntp-keygen-opts.c | 14 +- util/ntp-keygen-opts.def | 2 +- util/ntp-keygen-opts.h | 6 +- util/ntp-keygen.1ntp-keygenman | 8 +- util/ntp-keygen.1ntp-keygenmdoc | 6 +- util/ntp-keygen.html | 8 +- util/ntp-keygen.man.in | 8 +- util/ntp-keygen.mdoc.in | 6 +- util/ntp-keygen.texi | 2 +- util/sht.c | 8 +- 172 files changed, 2808 insertions(+), 1719 deletions(-) diff --git a/ChangeLog b/ChangeLog index b4ee4247a8d6..f381a093cf94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,68 @@ --- +(4.2.8p12) 2018/08/14 Released by Harlan Stenn + +* [Sec 3505] CVE-2018-12327 - Arbitrary Code Execution Vulnerability + - fixed stack buffer overflow in the openhost() command-line call + of NTPQ/NTPDC +* [Sec 3012] noepeer tweaks. +* [Bug 3521] Fix a logic bug in the INVALIDNAK checks. +* [Bug 3509] Add support for running as non-root on FreeBSD, Darwin, + other TrustedBSD platforms + - applied patch by Ian Lepore +* [Bug 3506] Service Control Manager interacts poorly with NTPD + - changed interaction with SCM to signal pending startup +* [Bug 3486] Buffer overflow in ntpq/ntpq.c:tstflags() + - applied patch by Gerry Garvey +* [Bug 3485] Undefined sockaddr used in error messages in ntp_config.c + - applied patch by Gerry Garvey +* [Bug 3484] ntpq response from ntpd is incorrect when REFID is null + - rework of ntpq 'nextvar()' key/value parsing +* [Bug 3482] Fixes for compilation warnings (ntp_io.c & ntpq-subs.c) + - applied patch by Gerry Garvey (with mods) +* [Bug 3480] Refclock sample filter not cleared on clock STEP + - applied patch by Gerry Garvey +* [Bug 3479] ctl_putrefid() allows unsafe characters through to ntpq + - applied patch by Gerry Garvey (with mods) +* [Bug 3476]ctl_putstr() sends empty unquoted string [...] + - applied patch by Gerry Garvey (with mods); not sure if that's bug or feature, though +* [Bug 3475] modify prettydate() to suppress output of zero time + - applied patch by Gerry Garvey +* [Bug 3474] Missing pmode in mode7 peer info response + - applied patch by Gerry Garvey +* [Bug 3471] Check for openssl/[ch]mac.h. HStenn. + - add #define ENABLE_CMAC support in configure. HStenn. +* [Bug 3470] ntpd4.2.8p11 fails to compile without OpenSSL +* [Bug 3469] Incomplete string compare [...] in is_refclk_addr + - patch by Stephen Friedl +* [Bug 3467] Potential memory fault in ntpq [...] + - fixed IO redirection and CTRL-C handling in ntq and ntpdc +* [Bug 3465] Default TTL values cannot be used +* [Bug 3461] refclock_shm.c: clear error status on clock recovery + - initial patch by Hal Murray; also fixed refclock_report() trouble +* [Bug 3460] Fix typo in ntpq.texi, reported by Kenyon Ralph. +* [Bug 3456] Use uintptr_t rather than size_t to store an integer in a pointer + - According to Brooks Davis, there was only one location +* [Bug 3449] ntpq - display "loop" instead of refid [...] + - applied patch by Gerry Garvey +* [Bug 3445] Symmetric peer won't sync on startup + - applied patch by Gerry Garvey +* [Bug 3442] Fixes for ntpdate as suggested by Gerry Garvey, + with modifications + New macro REFID_ISTEXT() which is also used in ntpd/ntp_control.c. +* [Bug 3434] ntpd clears STA_UNSYNC on start + - applied patch by Miroslav Lichvar +* [Bug 3426] ntpdate.html -t default is 2 seconds. Leonid Evdokimov. +* [Bug 3121] Drop root privileges for the forked DNS worker + - integrated patch by Reinhard Max +* [Bug 2821] minor build issues + - applied patches by Christos Zoulas, including real bug fixes +* html/authopt.html: cleanup, from +* ntpd/ntpd.c: DROPROOT cleanup. +* Symmetric key range is 1-65535. Update docs. +* html/authentic.html: cleanup, from + +--- +(4.2.8p11) 2018/02/27 Released by Harlan Stenn * [Sec 3454] Unauthenticated packet can reset authenticated interleave associations. HStenn. @@ -14,16 +78,16 @@ - applied patch by Sean Haugh * [Bug 3452] PARSE driver prints uninitialized memory. * [Bug 3450] Dubious error messages from plausibility checks in get_systime() - - removed error log caused by rounding/slew, ensured postcondition + - removed error log caused by rounding/slew, ensured postcondition * [Bug 3447] AES-128-CMAC (fixes) - refactoring the MAC code, too * [Bug 3441] Validate the assumption that AF_UNSPEC is 0. stenn@ntp.org * [Bug 3439] When running multiple commands / hosts in ntpq... - - applied patch by ggarvey + - applied patch by ggarvey * [Bug 3438] Negative values and values > 999 days in... - - applied patch by ggarvey (with minor mods) + - applied patch by ggarvey (with minor mods) * [Bug 3437] ntpd tries to open socket with AF_UNSPEC domain - - applied patch (with mods) by Miroslav Lichvar + - applied patch (with mods) by Miroslav Lichvar * [Bug 3435] anchor NTP era alignment * [Bug 3433] sntp crashes when run with -a. * [Bug 3430] ntpq dumps core (SIGSEGV) for "keytype md2" diff --git a/NEWS b/NEWS index b30f187cbceb..8dc0f0f728a6 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,5 @@ -- -NTP 4.2.8p11 (Harlan Stenn , 2018/02/27) +NTP 4.2.8p12 (Harlan Stenn , 2018/14/09) NOTE: this NEWS file will be undergoing more revisions. @@ -7,6 +7,77 @@ Focus: Security, Bug fixes, enhancements. Severity: MEDIUM +This release fixes a "hole" in the noepeer capability introduced to ntpd +in ntp-4.2.8p11, and a buffer overflow in the openhost() function used by +ntpq and ntpdc. It also provides 26 other bugfixes, and 4 other improvements: + +* [Sec 3505] Buffer overflow in the openhost() call of ntpq and ntpdc. + +* [Sec 3012] Fix a hole in the new "noepeer" processing. + +* Bug Fixes: + [Bug 3521] Fix a logic bug in the INVALIDNAK checks. + [Bug 3509] Add support for running as non-root on FreeBSD, Darwin, + other TrustedBSD platforms + - applied patch by Ian Lepore + [Bug 3506] Service Control Manager interacts poorly with NTPD + - changed interaction with SCM to signal pending startup + [Bug 3486] Buffer overflow in ntpq/ntpq.c:tstflags() + - applied patch by Gerry Garvey + [Bug 3485] Undefined sockaddr used in error messages in ntp_config.c + - applied patch by Gerry Garvey + [Bug 3484] ntpq response from ntpd is incorrect when REFID is null + - rework of ntpq 'nextvar()' key/value parsing + [Bug 3482] Fixes for compilation warnings (ntp_io.c & ntpq-subs.c) + - applied patch by Gerry Garvey (with mods) + [Bug 3480] Refclock sample filter not cleared on clock STEP + - applied patch by Gerry Garvey + [Bug 3479] ctl_putrefid() allows unsafe characters through to ntpq + - applied patch by Gerry Garvey (with mods) + [Bug 3476]ctl_putstr() sends empty unquoted string [...] + - applied patch by Gerry Garvey (with mods); not sure if that's bug or feature, though + [Bug 3475] modify prettydate() to suppress output of zero time + - applied patch by Gerry Garvey + [Bug 3474] Missing pmode in mode7 peer info response + - applied patch by Gerry Garvey + [Bug 3471] Check for openssl/[ch]mac.h. HStenn. + - add #define ENABLE_CMAC support in configure. HStenn. + [Bug 3470] ntpd4.2.8p11 fails to compile without OpenSSL + [Bug 3469] Incomplete string compare [...] in is_refclk_addr + - patch by Stephen Friedl + [Bug 3467] Potential memory fault in ntpq [...] + - fixed IO redirection and CTRL-C handling in ntq and ntpdc + [Bug 3465] Default TTL values cannot be used + [Bug 3461] refclock_shm.c: clear error status on clock recovery + - initial patch by Hal Murray; also fixed refclock_report() trouble + [Bug 3460] Fix typo in ntpq.texi, reported by Kenyon Ralph. + [Bug 3456] Use uintptr_t rather than size_t to store an integer in a pointer + - According to Brooks Davis, there was only one location + [Bug 3449] ntpq - display "loop" instead of refid [...] + - applied patch by Gerry Garvey + [Bug 3445] Symmetric peer won't sync on startup + - applied patch by Gerry Garvey + [Bug 3442] Fixes for ntpdate as suggested by Gerry Garvey, + with modifications + New macro REFID_ISTEXT() which is also used in ntpd/ntp_control.c. + [Bug 3434] ntpd clears STA_UNSYNC on start + - applied patch by Miroslav Lichvar + [Bug 3426] ntpdate.html -t default is 2 seconds. Leonid Evdokimov. + [Bug 3121] Drop root privileges for the forked DNS worker + - integrated patch by Reinhard Max + [Bug 2821] minor build issues + - applied patches by Christos Zoulas, including real bug fixes + html/authopt.html: cleanup, from + ntpd/ntpd.c: DROPROOT cleanup. + Symmetric key range is 1-65535. Update docs. + +-- +NTP 4.2.8p11 (Harlan Stenn , 2018/02/27) + +Focus: Security, Bug fixes, enhancements. + +Severity: MEDIUM + This release fixes 2 low-/medium-, 1 informational/medum-, and 2 low-severity vulnerabilities in ntpd, one medium-severity vulernability in ntpq, and provides 65 other non-security fixes and improvements: diff --git a/config.h.in b/config.h.in index 13f9bc838f15..e91f86b1f93a 100644 --- a/config.h.in +++ b/config.h.in @@ -311,6 +311,9 @@ /* Provide the explicit 127.0.0.0/8 martian filter? */ #undef ENABLE_BUG3020_FIX +/* Enable CMAC support? */ +#undef ENABLE_CMAC + /* nls support in libopts */ #undef ENABLE_NLS @@ -372,6 +375,14 @@ /* Define to 1 if you have the `daemon' function. */ #undef HAVE_DAEMON +/* Define to 1 if you have the declaration of `siglongjmp', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGLONGJMP + +/* Define to 1 if you have the declaration of `sigsetjmp', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGSETJMP + /* Define to 1 if you have the declaration of `strerror_r', and to 0 if you don't. */ #undef HAVE_DECL_STRERROR_R @@ -653,6 +664,12 @@ /* if you have NT Threads */ #undef HAVE_NT_THREADS +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_CMAC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_OPENSSL_HMAC_H + /* Define to 1 if the system has the type `pid_t'. */ #undef HAVE_PID_T @@ -957,6 +974,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_LOCK_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MAC_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H @@ -1117,6 +1137,9 @@ /* Do we have the TIO serial stuff? */ #undef HAVE_TIO_SERIAL_STUFF +/* Are TrustedBSD MAC policy privileges available? */ +#undef HAVE_TRUSTEDBSD_MAC + /* Define to 1 if the system has the type `uint16_t'. */ #undef HAVE_UINT16_T diff --git a/configure b/configure index 1ab45bc43888..0ba239416fac 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for ntp 4.2.8p11. +# Generated by GNU Autoconf 2.69 for ntp 4.2.8p12. # # Report bugs to . # @@ -590,8 +590,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ntp' PACKAGE_TARNAME='ntp' -PACKAGE_VERSION='4.2.8p11' -PACKAGE_STRING='ntp 4.2.8p11' +PACKAGE_VERSION='4.2.8p12' +PACKAGE_STRING='ntp 4.2.8p12' PACKAGE_BUGREPORT='http://bugs.ntp.org./' PACKAGE_URL='http://www.ntp.org./' @@ -968,6 +968,7 @@ enable_c99_snprintf enable_clockctl enable_linuxcaps enable_solarisprivs +enable_trustedbsd_mac with_arlib with_net_snmp_config enable_libseccomp @@ -1614,7 +1615,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures ntp 4.2.8p11 to adapt to many kinds of systems. +\`configure' configures ntp 4.2.8p12 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1684,7 +1685,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ntp 4.2.8p11:";; + short | recursive ) echo "Configuration of ntp 4.2.8p12:";; esac cat <<\_ACEOF @@ -1731,6 +1732,8 @@ Optional Features and Packages: --enable-clockctl s Use /dev/clockctl for non-root clock control --enable-linuxcaps + Use Linux capabilities for non-root clock control --enable-solarisprivs + Use Solaris privileges for non-root clock control + --enable-trustedbsd-mac s Use TrustedBSD MAC policy for non-root clock + control --with-arlib - deprecated, arlib not distributed --with-net-snmp-config + =net-snmp-config --enable-libseccomp EXPERIMENTAL: enable support for libseccomp @@ -1923,7 +1926,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ntp configure 4.2.8p11 +ntp configure 4.2.8p12 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2632,7 +2635,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ntp $as_me 4.2.8p11, which was +It was created by ntp $as_me 4.2.8p12, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3633,7 +3636,7 @@ fi # Define the identity of the package. PACKAGE='ntp' - VERSION='4.2.8p11' + VERSION='4.2.8p12' cat >>confdefs.h <<_ACEOF @@ -24026,7 +24029,40 @@ esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ntp_have_solarisprivs" >&5 $as_echo "$ntp_have_solarisprivs" >&6; } -case "$ntp_use_dev_clockctl$ntp_have_linuxcaps$ntp_have_solarisprivs" in +for ac_header in sys/mac.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "sys/mac.h" "ac_cv_header_sys_mac_h" "$ac_includes_default" +if test "x$ac_cv_header_sys_mac_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SYS_MAC_H 1 +_ACEOF + +fi + +done + + +# Check whether --enable-trustedbsd_mac was given. +if test "${enable_trustedbsd_mac+set}" = set; then : + enableval=$enable_trustedbsd_mac; ntp_use_trustedbsd_mac=$enableval + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we should use TrustedBSD MAC privileges" >&5 +$as_echo_n "checking if we should use TrustedBSD MAC privileges... " >&6; } + +case "$ntp_use_trustedbsd_mac$ac_cv_header_sys_mac_h" in + yesyes) + +$as_echo "#define HAVE_TRUSTEDBSD_MAC 1" >>confdefs.h + +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ntp_use_trustedbsd_mac" >&5 +$as_echo "$ntp_use_trustedbsd_mac" >&6; } + +case "$ntp_use_dev_clockctl$ntp_have_linuxcaps$ntp_have_solarisprivs$ntp_use_trustedbsd_mac" in *yes*) $as_echo "#define HAVE_DROPROOT 1" >>confdefs.h @@ -30311,6 +30347,19 @@ $as_echo "$ntp_openssl" >&6; } case "$ntp_openssl" in yes) + for ac_header in openssl/cmac.h openssl/hmac.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + $as_echo "#define OPENSSL /**/" >>confdefs.h @@ -30534,6 +30583,21 @@ LIBS="$NTPO_SAVED_LIBS" { ntp_openssl_from_pkg_config=; unset ntp_openssl_from_pkg_config;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we want to enable CMAC support" >&5 +$as_echo_n "checking if we want to enable CMAC support... " >&6; } +case "$ac_cv_header_openssl_cmac_h" in + yes) + +$as_echo "#define ENABLE_CMAC 1" >>confdefs.h + + ans="yes" + ;; + *) ans="no" + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ans" >&5 +$as_echo "$ans" >&6; } + @@ -33221,6 +33285,32 @@ fi +### + +ac_fn_c_check_decl "$LINENO" "sigsetjmp" "ac_cv_have_decl_sigsetjmp" "#include +" +if test "x$ac_cv_have_decl_sigsetjmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGSETJMP $ac_have_decl +_ACEOF +ac_fn_c_check_decl "$LINENO" "siglongjmp" "ac_cv_have_decl_siglongjmp" "#include +" +if test "x$ac_cv_have_decl_siglongjmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGLONGJMP $ac_have_decl +_ACEOF + + ### @@ -33964,7 +34054,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ntp $as_me 4.2.8p11, which was +This file was extended by ntp $as_me 4.2.8p12, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -34031,7 +34121,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -ntp config.status 4.2.8p11 +ntp config.status 4.2.8p12 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 4e7e06af6167..1f477c514188 100644 --- a/configure.ac +++ b/configure.ac @@ -3014,6 +3014,17 @@ AC_MSG_RESULT([$ans]) NTP_OPENSSL +AC_MSG_CHECKING([if we want to enable CMAC support]) +case "$ac_cv_header_openssl_cmac_h" in + yes) + AC_DEFINE([ENABLE_CMAC], [1], [Enable CMAC support?]) + ans="yes" + ;; + *) ans="no" + ;; +esac +AC_MSG_RESULT([$ans]) + NTP_CRYPTO_RAND # if we are using OpenSSL (--with-crypto), by default Autokey is enabled @@ -4380,6 +4391,10 @@ NTP_PROBLEM_TESTS ### +AC_CHECK_DECLS([sigsetjmp,siglongjmp], [], [], [[#include ]]) + +### + AC_DEFINE_DIR([NTP_KEYSDIR], [sysconfdir], [Default location of crypto key info]) diff --git a/html/authentic.html b/html/authentic.html index 06bb67bc727a..52703e4566e5 100644 --- a/html/authentic.html +++ b/html/authentic.html @@ -1,91 +1,223 @@ - - - -Authentication Support - - - - -

Authentication Support

-giffrom Alice's Adventures in Wonderland, Lewis Carroll -

Our resident cryptographer; now you see him, now you don't.

-

Last update: - 5-Feb-2016 09:13 - UTC

-
-

Related Links

- - -

Table of Contents

- -
-

Introduction

-

This page describes the various cryptographic authentication provisions in NTPv4. Authentication support allows the NTP client to verify that servers are in fact known and trusted and not intruders intending accidentally or intentionally to masquerade as a legitimate server. A detailed discussion of the NTP multi-layer security model and vulnerability analysis is in the white paper NTP Security Analysis.

-

The NTPv3 specification (RFC-1305) defined an authentication scheme properly described as symmetric key cryptography. It used the Data Encryption Standard (DES) algorithm operating in cipher-block chaining (CBC) mode. Subsequently, this algorithm was replaced by the RSA Message Digest 5 (MD5) algorithm commonly called keyed-MD5. Either algorithm computes a message digest or one-way hash which can be used to verify the client has the same message digest as the server. The MD5 message digest algorithm is included in the distribution, so without further cryptographic support, the distribution can be freely exported.

-

If the OpenSSL cryptographic library is installed prior to building the distribution, all message digest algorithms included in the library may be used, including SHA and SHA1. However, if conformance to FIPS 140-2 is required, only a limited subset of these algorithms can be used. This library is available from http://www.openssl.org and can be installed using the procedures outlined in the Building and Installing the Distribution page. Once installed, the configure and build process automatically detects the library and links the library routines -required.

-

In addition to the symmetric key algorithms, this distribution includes support for the Autokey public key algorithms and protocol specified in RFC-5906 "Network Time Protocol Version 4: Autokey Specification". This support is available only if the OpenSSL library has been installed and the --enable-autokey option is used when the distribution is built.

-

Public key cryptography is generally considered more secure than symmetric key cryptography, since the security is based on private and public values which are generated by each participant and where the private value is never revealed. Autokey uses X.509 public certificates, which can be produced by commercial services, the OpenSSL application program, or the ntp-keygen utility program in the NTP software distribution.

-

Note that according to US law, NTP binaries including OpenSSL library components, including the OpenSSL library itself, cannot be exported outside the US without license from the US Department of Commerce. Builders outside the US are advised to obtain the OpenSSL library directly from OpenSSL, which is outside the US, and build outside the US.

-

Authentication is configured separately for each association using the key or autokey option of the server configuration command, as described in the Server Options page. The ntp-keygen page describes the files required for the various authentication schemes. Further details are in the briefings, papers and reports at the NTP project page linked from www.ntp.org.

-

By default, the client sends non-authenticated packets and the server responds with non-authenticated packets. If the client sends authenticated packets, the server responds with authenticated packets if correct, or a crypto-NAK packet if not. In the case of unsolicited packets which might consume significant resources, such as broadcast or symmetric mode packets, authentication is required, unless overridden by a disable auth command. In the current climate of targeted broadcast or "letterbomb" attacks, defeating this requirement would be decidedly dangerous. In any case, the notrust flag, described on the Access Control Options page, can be used to disable access to all but correctly authenticated clients.

-

Symmetric Key Cryptography

-

The original NTPv3 specification (RFC-1305), as well as the current NTPv4 specification (RFC-5905), allows any one of possibly 65,534 message digest keys (excluding zero), each distinguished by a 32-bit key ID, to authenticate an association. The servers and clients involved must agree on the key ID, key type and key to authenticate NTP packets.

-

The message digest is a cryptographic hash computed by an algorithm such as MD5, SHA, or AES-128 CMAC. When authentication is specified, a message authentication code (MAC) is appended to the NTP packet header. The MAC consists of a 32-bit key identifier (key ID) followed by a 128- or 160-bit message digest. The algorithm computes the digest as the hash of a 128- or 160- bit message digest key concatenated with the NTP packet header fields with the exception of the MAC. On transmit, the message digest is computed and inserted in the MAC. On receive, the message digest is computed and compared with the MAC. The packet is accepted only if the two MACs are identical. If a discrepancy is found by the client, the client ignores the packet, but raises an alarm. If this happens at the server, the server returns a special message called a crypto-NAK. Since the crypto-NAK is protected by the loopback test, an intruder cannot disrupt the protocol by sending a bogus crypto-NAK.

-

Keys and related information are specified in a keys file, which must be distributed and stored using secure means beyond the scope of the NTP protocol itself. Besides the keys used for ordinary NTP associations, additional keys can be used as passwords for the ntpq and ntpdc utility programs. Ordinarily, the ntp.keys file is generated by the ntp-keygen program, but it can be constructed and edited using an ordinary text editor.

-

Each line of the keys file consists of three or four fields: a key ID in the range 1 to 65,534, inclusive, a key type, a message digest key consisting of a printable ASCII string less than 40 characters or a 40-character hex digit string, and an optional comma-separated list of IPs that are allowed to serve time. If the OpenSSL library is installed, the key type can be any message digest algorithm supported by the library. If the OpenSSL library is not installed, the only permitted key type is MD5.

- - -
- Figure 1. Typical Symmetric Key File -
-
-# ntpkey_MD5key_bk.ntp.org.3595864945
-# Thu Dec 12 19:22:25 2013
+  
+    
+    
+    Authentication Support
+    
+    
+    
+  
+  
+    

Authentication Support

+ giffrom Alice's Adventures in Wonderland, Lewis Carroll +

Our resident cryptographer; now you see him, now you don't.

+

Last update: + 24-Jul-2018 09:12 + UTC

+
+

Related Links

+ + +

Table of Contents

+ +
+

Introduction

+

This page describes the various cryptographic authentication + provisions in NTPv4. Authentication support allows the NTP client to + verify that servers are in fact known and trusted and not intruders + intending accidentally or intentionally to masquerade as a legitimate + server. A detailed discussion of the NTP multi-layer security model + and vulnerability analysis is in the white + paper NTP + Security Analysis.

+

The NTPv3 specification (RFC-1305) defined an authentication scheme + properly described as symmetric key cryptography. It used + the Data Encryption Standard (DES) algorithm operating in cipher-block + chaining (CBC) mode. Subsequently, this algorithm was replaced by the + RSA Message Digest 5 (MD5) algorithm commonly called keyed-MD5. + Either algorithm computes a message digest or one-way hash which can + be used to verify the client has the same message digest as the + server. The MD5 message digest algorithm is included in the + distribution, so without further cryptographic support, the + distribution can be freely exported.

+

If the OpenSSL cryptographic library is installed prior to building + the distribution, all message digest algorithms included in the + library may be used, including SHA and SHA1. However, if conformance + to FIPS 140-2 is required, only a limited subset of these algorithms + can be used. This library is available + from http://www.openssl.org and + can be installed using the procedures outlined in + the Building and Installing the Distribution + page. Once installed, the configure and build process automatically + detects the library and links the library routines required.

+

In addition to the symmetric key algorithms, this distribution + includes support for the Autokey public key algorithms and protocol + specified in RFC-5906 "Network Time Protocol Version 4: Autokey + Specification". This support is available only if the OpenSSL + library has been installed and the --enable-autokey option is + used when the distribution is built.

+

Public key cryptography is generally considered more secure than + symmetric key cryptography, since the security is based on private and + public values which are generated by each participant and where the + private value is never revealed. Autokey uses X.509 public + certificates, which can be produced by commercial services, the + OpenSSL application program, or + the ntp-keygen utility program in + the NTP software distribution.

+

Note that according to US law, NTP binaries including OpenSSL library + components, including the OpenSSL library itself, cannot be exported + outside the US without license from the US Department of Commerce. + Builders outside the US are advised to obtain the OpenSSL library + directly from OpenSSL, which is outside the US, and build outside the + US.

+

Authentication is configured separately for each association using + the key or autokey option of the server + configuration command, as described in + the Server Options page. + The ntp-keygen page describes the files + required for the various authentication schemes. Further details are + in the briefings, papers and reports at the NTP project page linked + from www.ntp.org.

+

By default, the client sends non-authenticated packets and the server + responds with non-authenticated packets. If the client sends + authenticated packets, the server responds with authenticated packets + if correct, or a crypto-NAK packet if not. In the case of unsolicited + packets which might consume significant resources, such as broadcast + or symmetric mode packets, authentication is required, unless + overridden by a disable auth command. In the current climate + of targeted broadcast or "letterbomb" attacks, defeating + this requirement would be decidedly dangerous. In any case, + the notrust flag, described on + the Access Control Options page, can be + used to disable access to all but correctly authenticated clients.

+

Symmetric Key Cryptography

+

The original NTPv3 specification (RFC-1305), as well as the current + NTPv4 specification (RFC-5905), allows any one of possibly 65,535 + message digest keys (excluding zero), each distinguished by a 32-bit + key ID, to authenticate an association. The servers and clients + involved must agree on the key ID, key type and key to authenticate + NTP packets.

+

The message digest is a cryptographic hash computed by an algorithm + such as MD5, SHA, or AES-128 CMAC. When authentication is specified, + a message authentication code (MAC) is appended to the NTP packet + header. The MAC consists of a 32-bit key identifier (key ID) followed + by a 128- or 160-bit message digest. The algorithm computes the + digest as the hash of a 128- or 160- bit message digest key + concatenated with the NTP packet header fields with the exception of + the MAC. On transmit, the message digest is computed and inserted in + the MAC. On receive, the message digest is computed and compared with + the MAC. The packet is accepted only if the two MACs are identical. + If a discrepancy is found by the client, the client ignores the + packet, but raises an alarm. If this happens at the server, the + server returns a special message called a crypto-NAK. Since + the crypto-NAK is protected by the loopback test, an intruder cannot + disrupt the protocol by sending a bogus crypto-NAK.

+

Keys and related information are specified in a keys file, which must + be distributed and stored using secure means beyond the scope of the + NTP protocol itself. Besides the keys used for ordinary NTP + associations, additional keys can be used as passwords for + the ntpq + and ntpdc utility programs. + Ordinarily, the ntp.keys file is generated by + the ntp-keygen program, but it can + be constructed and edited using an ordinary text editor.

+

Each line of the keys file consists of three or four fields: a key + ID in the range 1 to 65,535, inclusive, a key type, a message digest + key consisting of a printable ASCII string less than 40 characters or + a 40-character hex digit string, and an optional comma-separated list + of IPs that are allowed to serve time. If the OpenSSL library is + installed, the key type can be any message digest algorithm supported + by the library. If the OpenSSL library is not installed, the only + permitted key type is MD5.

+ + +
+ Figure 1. Typical Symmetric Key File +
+
+	    # ntpkey_MD5key_bk.ntp.org.3595864945
+	    # Thu Dec 12 19:22:25 2013
 
-1  MD5 L";Nw<`.I<f4U0)247"i  # MD5 key
-2  MD5 &>l0%XXK9O'51VwV<xq~  # MD5 key
-3  MD5 lb4zLW~d^!K:]RsD'qb6  # MD5 key
-4  MD5 Yue:tL[+vR)M`n~bY,'?  # MD5 key
-5  MD5 B;fxlKgr/&4ZTbL6=RxA  # MD5 key
-6  MD5 4eYwa`o}3i@@V@..R9!l  # MD5 key
-7  MD5 `A.([h+;wTQ|xfi%Sn_!  # MD5 key
-8  MD5 45:V,r4]l6y^JH6"Sh?F  # MD5 key
-9  MD5 3-5vcn*6l29DS?Xdsg)*  # MD5 key
-10 MD5 2late4Me              # MD5 key
-11 SHA1 a27872d3030a9025b8446c751b4551a7629af65c  # SHA1 key
-12 SHA1 21bc3b4865dbb9e920902abdccb3e04ff97a5e74  # SHA1 key
-13 SHA1 2b7736fe24fef5ba85ae11594132ab5d6f6daba9  # SHA1 key
-14 SHA  a5332809c8878dd3a5b918819108a111509aeceb  # SHA  key
-15 MD2  2fe16c88c760ff2f16d4267e36c1aa6c926e6964  # MD2  key
-16 MD4  b2691811dc19cfc0e2f9bcacd74213f29812183d  # MD4  key
-17 MD5  e4d6735b8bdad58ec5ffcb087300a17f7fef1f7c  # MD5  key
-18 MDC2 a8d5e2315c025bf3a79174c87fbd10477de2eabc  # MDC2 key
-19 RIPEMD160 77ca332cafb30e3cafb174dcd5b80ded7ba9b3d2  # RIPEMD160 key
-20 AES128CMAC f92ff73eee86c1e7dc638d6489a04e4e555af878  # AES128CMAC key
-  
-

Figure 1 shows a typical keys file used by the reference implementation when the OpenSSL library is installed. In this figure, for key IDs in he range 1-10, the key is interpreted as a printable ASCII string. For key IDs in the range 11-20, the key is a 40-character hex digit string. The key is truncated or zero-filled internally to either 128 or 160 bits, depending on the key type. The line can be edited later or new lines can be added to change any field. The key can be changed to a password, such as 2late4Me for key ID 10. Note that two or more keys files can be combined in any order as long as the key IDs are distinct.

-

When ntpd is started, it reads the keys file specified by the keys command and installs the keys in the key cache. However, individual keys must be activated with the trustedkey configuration command before use. This allows, for instance, the installation of possibly several batches of keys and then activating a key remotely using ntpq or ntpdc. The requestkey command selects the key ID used as the password for the ntpdc utility, while the controlkey command selects the key ID used as the password for the ntpq utility.

-

Microsoft Windows Authentication

-

In addition to the above means, ntpd now supports Microsoft Windows MS-SNTP authentication using Active Directory services. This support was contributed by the Samba Team and is still in development. It is enabled using the mssntp flag of the restrict command described on the Access Control Options page. Note: Potential users should be aware that these services involve a TCP connection to another process that could potentially block, denying services to other users. Therefore, this flag should be used only for a dedicated server with no clients other than MS-SNTP.

-

Public Key Cryptography

-

See the Autokey Public-Key Authentication page.

-
- - + 1 MD5 L";Nw<`.I<f4U0)247"i # MD5 key + 2 MD5 &>l0%XXK9O'51VwV<xq~ # MD5 key + 3 MD5 lb4zLW~d^!K:]RsD'qb6 # MD5 key + 4 MD5 Yue:tL[+vR)M`n~bY,'? # MD5 key + 5 MD5 B;fxlKgr/&4ZTbL6=RxA # MD5 key + 6 MD5 4eYwa`o}3i@@V@..R9!l # MD5 key + 7 MD5 `A.([h+;wTQ|xfi%Sn_! # MD5 key + 8 MD5 45:V,r4]l6y^JH6"Sh?F # MD5 key + 9 MD5 3-5vcn*6l29DS?Xdsg)* # MD5 key + 10 MD5 2late4Me # MD5 key + 11 SHA1 a27872d3030a9025b8446c751b4551a7629af65c # SHA1 key + 12 SHA1 21bc3b4865dbb9e920902abdccb3e04ff97a5e74 # SHA1 key + 13 SHA1 2b7736fe24fef5ba85ae11594132ab5d6f6daba9 # SHA1 key + 14 SHA a5332809c8878dd3a5b918819108a111509aeceb # SHA key + 15 MD2 2fe16c88c760ff2f16d4267e36c1aa6c926e6964 # MD2 key + 16 MD4 b2691811dc19cfc0e2f9bcacd74213f29812183d # MD4 key + 17 MD5 e4d6735b8bdad58ec5ffcb087300a17f7fef1f7c # MD5 key + 18 MDC2 a8d5e2315c025bf3a79174c87fbd10477de2eabc # MDC2 key + 19 RIPEMD160 77ca332cafb30e3cafb174dcd5b80ded7ba9b3d2 # RIPEMD160 key + 20 AES128CMAC f92ff73eee86c1e7dc638d6489a04e4e555af878 # AES128CMAC key + 21 MD5 sampo 10.1.2.3/24 +
+

Figure 1 shows a typical symmetric keys file used by the reference + implementation when the OpenSSL library is installed. Each line of + the file contains three or four fields. The first field is an integer + between 1 and 65535, inclusive, representing the key identifier. The + second field is the digest algorithm, which in the absence of the + OpenSSL library must be MD5, which designates the MD5 message + digest algorithm. The third field is the key. The optional fourth + field is one or more comma-separated IPs. An IP may end with an + optional /subnetbits suffix, which limits the acceptance of + the key identifier to packets claiming to be from the described IP + space. In this example, for the key IDs in the range 1-10 the key is + interpreted as a printable ASCII string. For the key IDs in the range + 11-20, the key is a 40-character hex digit string. In either case, + the key is truncated or zero-filled internally to either 128 or 160 + bits, depending on the key type. The line can be edited later or new + lines can be added to change any field. The key can be changed to a + password, such as 2late4Me for key ID 10. Note that two or + more keys files can be combined in any order as long as the key IDs + are distinct.

+

When ntpd is started, it reads the keys file specified by + the keys command and installs the keys in the key cache. + However, individual keys must be activated with + the trustedkey configuration command before use. This + allows, for instance, the installation of possibly several batches of + keys and then activating a key remotely using ntpq + or ntpdc. The requestkey command selects the key ID + used as the password for the ntpdc utility, while + the controlkey command selects the key ID used as the + password for the ntpq utility.

+

Microsoft Windows Authentication

+

In addition to the above means, ntpd now supports Microsoft + Windows MS-SNTP authentication using Active Directory services. This + support was contributed by the Samba Team and is still in development. + It is enabled using the mssntp flag of the restrict + command described on the Access Control + Options page. Note: Potential users should + be aware that these services involve a TCP connection to another + process that could potentially block, denying services to other users. + Therefore, this flag should be used only for a dedicated server with + no clients other than MS-SNTP.

+

Public Key Cryptography

+

See the Autokey Public-Key Authentication + page.

+
+ + diff --git a/html/authopt.html b/html/authopt.html index 9504deb8ad69..c9484ef9ad5c 100644 --- a/html/authopt.html +++ b/html/authopt.html @@ -4,6 +4,7 @@ Authentication Commands and Options +