From 760c70cd25a8077e78162eba259005895631ac13 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 14 Oct 2016 11:49:36 +0000 Subject: [PATCH 001/235] 7301 zpool export -f should be able to interrupt file freeing Reviewed by: Matthew Ahrens Reviewed by: Sanjay Nadkarni Reviewed by: Saso Kiselkov Reviewed by: John Kennedy Author: Alek Pinchuk Closes #175 --- uts/common/fs/zfs/dmu.c | 21 ++++++++++++++++++++- uts/common/fs/zfs/sys/zfs_znode.h | 2 ++ uts/common/fs/zfs/zfs_dir.c | 4 ++-- uts/common/fs/zfs/zfs_vfsops.c | 28 ++++++++++++++++++++++++++-- 4 files changed, 50 insertions(+), 5 deletions(-) diff --git a/uts/common/fs/zfs/dmu.c b/uts/common/fs/zfs/dmu.c index 0fe695c41728..4212addbefbd 100644 --- a/uts/common/fs/zfs/dmu.c +++ b/uts/common/fs/zfs/dmu.c @@ -24,7 +24,7 @@ */ /* Copyright (c) 2013 by Saso Kiselkov. All rights reserved. */ /* Copyright (c) 2013, Joyent, Inc. All rights reserved. */ -/* Copyright (c) 2014, Nexenta Systems, Inc. All rights reserved. */ +/* Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ #include #include @@ -695,6 +695,22 @@ get_next_chunk(dnode_t *dn, uint64_t *start, uint64_t minimum) return (0); } +/* + * If this objset is of type OST_ZFS return true if vfs's unmounted flag is set, + * otherwise return false. + * Used below in dmu_free_long_range_impl() to enable abort when unmounting + */ +/*ARGSUSED*/ +static boolean_t +dmu_objset_zfs_unmounting(objset_t *os) +{ +#ifdef _KERNEL + if (dmu_objset_type(os) == DMU_OST_ZFS) + return (zfs_get_vfs_flag_unmounted(os)); +#endif + return (B_FALSE); +} + static int dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset, uint64_t length) @@ -711,6 +727,9 @@ dmu_free_long_range_impl(objset_t *os, dnode_t *dn, uint64_t offset, while (length != 0) { uint64_t chunk_end, chunk_begin; + if (dmu_objset_zfs_unmounting(dn->dn_objset)) + return (SET_ERROR(EINTR)); + chunk_end = chunk_begin = offset + length; /* move chunk_begin backwards to the beginning of this chunk */ diff --git a/uts/common/fs/zfs/sys/zfs_znode.h b/uts/common/fs/zfs/sys/zfs_znode.h index 9a611c024e40..bebe577d3f08 100644 --- a/uts/common/fs/zfs/sys/zfs_znode.h +++ b/uts/common/fs/zfs/sys/zfs_znode.h @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SYS_FS_ZFS_ZNODE_H @@ -302,6 +303,7 @@ extern int zfs_sync(vfs_t *vfsp, short flag, cred_t *cr); extern dev_t zfs_cmpldev(uint64_t); extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value); extern int zfs_get_stats(objset_t *os, nvlist_t *nv); +extern boolean_t zfs_get_vfs_flag_unmounted(objset_t *os); extern void zfs_znode_dmu_fini(znode_t *); extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, diff --git a/uts/common/fs/zfs/zfs_dir.c b/uts/common/fs/zfs/zfs_dir.c index 2b18ecb01c6d..10cf087a290a 100644 --- a/uts/common/fs/zfs/zfs_dir.c +++ b/uts/common/fs/zfs/zfs_dir.c @@ -618,8 +618,8 @@ zfs_rmnode(znode_t *zp) error = dmu_free_long_range(os, zp->z_id, 0, DMU_OBJECT_END); if (error) { /* - * Not enough space. Leave the file in the unlinked - * set. + * Not enough space or we were interrupted by unmount. + * Leave the file in the unlinked set. */ zfs_znode_dmu_fini(zp); zfs_znode_free(zp); diff --git a/uts/common/fs/zfs/zfs_vfsops.c b/uts/common/fs/zfs/zfs_vfsops.c index 71df239ac95b..7b5d87d6ae50 100644 --- a/uts/common/fs/zfs/zfs_vfsops.c +++ b/uts/common/fs/zfs/zfs_vfsops.c @@ -22,6 +22,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2014 Integros [integros.com] + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. */ /* Portions Copyright 2010 Robert Milkowski */ @@ -1728,7 +1729,7 @@ zfs_root(vfs_t *vfsp, vnode_t **vpp) /* * Teardown the zfsvfs::z_os. * - * Note, if 'unmounting' if FALSE, we return with the 'z_teardown_lock' + * Note, if 'unmounting' is FALSE, we return with the 'z_teardown_lock' * and 'z_teardown_inactive_lock' held. */ static int @@ -1793,8 +1794,8 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) */ if (unmounting) { zfsvfs->z_unmounted = B_TRUE; - rrm_exit(&zfsvfs->z_teardown_lock, FTAG); rw_exit(&zfsvfs->z_teardown_inactive_lock); + rrm_exit(&zfsvfs->z_teardown_lock, FTAG); } /* @@ -2272,6 +2273,29 @@ zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value) return (error); } +/* + * Return true if the coresponding vfs's unmounted flag is set. + * Otherwise return false. + * If this function returns true we know VFS unmount has been initiated. + */ +boolean_t +zfs_get_vfs_flag_unmounted(objset_t *os) +{ + zfsvfs_t *zfvp; + boolean_t unmounted = B_FALSE; + + ASSERT(dmu_objset_type(os) == DMU_OST_ZFS); + + mutex_enter(&os->os_user_ptr_lock); + zfvp = dmu_objset_get_user(os); + if (zfvp != NULL && zfvp->z_vfs != NULL && + (zfvp->z_vfs->vfs_flag & VFS_UNMOUNTED)) + unmounted = B_TRUE; + mutex_exit(&os->os_user_ptr_lock); + + return (unmounted); +} + static vfsdef_t vfw = { VFSDEF_VERSION, MNTTYPE_ZFS, From afc7ee85ef3f0057e2d74990f2599860efe3362a Mon Sep 17 00:00:00 2001 From: Mariusz Zaborski Date: Fri, 21 Oct 2016 16:31:58 +0000 Subject: [PATCH 002/235] Fix few sentence in the man page. Pointed out by: wblock --- lib/libcapsicum/capsicum_helpers.3 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/libcapsicum/capsicum_helpers.3 b/lib/libcapsicum/capsicum_helpers.3 index fe2e0e7d0876..98ea1dc64179 100644 --- a/lib/libcapsicum/capsicum_helpers.3 +++ b/lib/libcapsicum/capsicum_helpers.3 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd October 5, 2016 +.Dd October 21, 2016 .Dt CAPSICUM_HELPERS 3 .Os .Sh NAME @@ -57,7 +57,8 @@ .Sh DESCRIPTION The .Nm capsicum helpers -are a set of a inline functions which simplify Capsicumizing programs. +are a set of a inline functions which simplify modifying programs to use +Capsicum. The goal is to reduce duplicated code patterns. The .Nm capsicum helpers @@ -70,7 +71,7 @@ restricts capabilities on .Fa fd to only those needed by POSIX stream objects (that is, FILEs). .Pp -The following flags can be provided: +These flags can be provided: .Pp .Bl -tag -width "CAPH_IGNORE_EBADF" -compact -offset indent .It Dv CAPH_IGNORE_EBADF From 1c32eff59bbe4757d96c0ddbe003f8cd074de2a4 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 21 Oct 2016 17:25:19 +0000 Subject: [PATCH 003/235] Allow all subdirectories to be optional via SUBDIR.${MK_*} Reviewed by: br, imp Tested by: br Pointy hat to: emaste Differential Revision: https://reviews.freebsd.org/D8317 --- share/mk/bsd.subdir.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/mk/bsd.subdir.mk b/share/mk/bsd.subdir.mk index 34fc8325ae3f..9d1fed72073d 100644 --- a/share/mk/bsd.subdir.mk +++ b/share/mk/bsd.subdir.mk @@ -110,7 +110,7 @@ install: beforeinstall realinstall afterinstall # SUBDIR recursing may be disabled for MK_DIRDEPS_BUILD .if !target(_SUBDIR) -.if defined(SUBDIR) +.if defined(SUBDIR) || defined(SUBDIR.yes) SUBDIR:=${SUBDIR} ${SUBDIR.yes} SUBDIR:=${SUBDIR:u} .endif From 9d71a3975e55e1fbc9ec7c09bdabc9e496c638a9 Mon Sep 17 00:00:00 2001 From: Hiren Panchasara Date: Fri, 21 Oct 2016 18:27:30 +0000 Subject: [PATCH 004/235] Rework r306337. In sendit(), if mp->msg_control is present, then in sockargs() we are allocating mbuf to store mp->msg_control. Later in kern_sendit(), call to getsock_cap(), will check validity of file pointer passed, if this fails EBADF is returned but mbuf allocated in sockargs() is not freed. Made code changes to free the same. Since freeing control mbuf in sendit() after checking (control != NULL) may lead to double freeing of control mbuf in sendit(), we can free control mbuf in kern_sendit() if there are any errors in the routine. Submitted by: Lohith Bellad Reviewed by: glebius MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D8152 --- sys/kern/uipc_syscalls.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index e282665f75e5..98f6957e0ae6 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -762,8 +762,10 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, cap_rights_set(&rights, CAP_CONNECT); } error = getsock_cap(td, s, &rights, &fp, NULL, NULL); - if (error != 0) + if (error != 0) { + m_freem(control); return (error); + } so = (struct socket *)fp->f_data; #ifdef KTRACE @@ -774,12 +776,16 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, if (mp->msg_name != NULL) { error = mac_socket_check_connect(td->td_ucred, so, mp->msg_name); - if (error != 0) + if (error != 0) { + m_freem(control); goto bad; + } } error = mac_socket_check_send(td->td_ucred, so); - if (error != 0) + if (error != 0) { + m_freem(control); goto bad; + } #endif auio.uio_iov = mp->msg_iov; @@ -793,6 +799,7 @@ kern_sendit(struct thread *td, int s, struct msghdr *mp, int flags, for (i = 0; i < mp->msg_iovlen; i++, iov++) { if ((auio.uio_resid += iov->iov_len) < 0) { error = EINVAL; + m_freem(control); goto bad; } } From 202a205fc200ffbf77c8168f2700ec822485ada8 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Fri, 21 Oct 2016 18:45:09 +0000 Subject: [PATCH 005/235] Fix a grammar error. Reported by:i hiren, vangyzen MFC after: 1 month X-MFC: r307727 Sponsored by: Netflix --- share/man/man4/tcp.4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/tcp.4 b/share/man/man4/tcp.4 index 4d1473082b36..49fe2afaee95 100644 --- a/share/man/man4/tcp.4 +++ b/share/man/man4/tcp.4 @@ -587,10 +587,10 @@ List of available TCP function blocks (TCP stacks). .It Va functions_default The default TCP function block (TCP stack). .It Va insecure_rst -Use criterias defined in RFC793 instead of RFC5961 for accepting RST segments. +Use criteria defined in RFC793 instead of RFC5961 for accepting RST segments. Default is false. .It Va insecure_syn -Use criterias defined in RFC793 instead of RFC5961 for accepting SYN segments. +Use criteria defined in RFC793 instead of RFC5961 for accepting SYN segments. Default is false. .El .Sh ERRORS From 38fb20e2ac94170d97d621255a5ac526ec749105 Mon Sep 17 00:00:00 2001 From: "Kenneth D. Merry" Date: Fri, 21 Oct 2016 18:54:56 +0000 Subject: [PATCH 006/235] Fix a problem in camcontrol(8) that cropped up with r307684. In r307684, I changed rescan_or_reset_bus() to bzero stack-allocated CCBs before sending them to the kernel because there was stack garbage in there that wound up meaning that bogus CCB flags were set. While this fixed the 'camcontrol rescan all' case (XPT_DEV_MATCH CCBs were failing previously), it broke the 'camcontrol rescan 0' (or any other number) case when INVARIANTS are turned on. Rescanning a single bus reliably produced an assert in cam_periph_runccb(): panic: cam_periph_runccb: ccb=0xfffff80044ffe000, func_code=0x708, flags=0xffffdde0 The flags values don't make sense from the code. Changing the CCBs in rescan_or_reset_bus() from stack to heap allocated avoids the problem. It would be better to understand why userland stack allocated CCBs don't work properly, since there may be other code that breaks if stack allocated CCBs don't work. sbin/camcontrol/camcontrol.c: In rescan_or_reset_bus(), allocate the CCBs using malloc(3) instead of on the stack to avoid an assertion in cam_periph_runccb(). MFC after: 3 days Sponsored by: Spectra Logic --- sbin/camcontrol/camcontrol.c | 120 +++++++++++++++++++---------------- 1 file changed, 66 insertions(+), 54 deletions(-) diff --git a/sbin/camcontrol/camcontrol.c b/sbin/camcontrol/camcontrol.c index aebb90371436..3a443a9c1f3e 100644 --- a/sbin/camcontrol/camcontrol.c +++ b/sbin/camcontrol/camcontrol.c @@ -3127,8 +3127,8 @@ dorescan_or_reset(int argc, char **argv, int rescan) static int rescan_or_reset_bus(path_id_t bus, int rescan) { - union ccb ccb, matchccb; - int fd, retval; + union ccb *ccb = NULL, *matchccb = NULL; + int fd = -1, retval; int bufsize; retval = 0; @@ -3139,37 +3139,41 @@ rescan_or_reset_bus(path_id_t bus, int rescan) return(1); } - bzero(&ccb, sizeof(ccb)); + ccb = malloc(sizeof(*ccb)); + if (ccb == NULL) { + warn("failed to allocate CCB"); + retval = 1; + goto bailout; + } + bzero(ccb, sizeof(*ccb)); if (bus != CAM_BUS_WILDCARD) { - ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; - ccb.ccb_h.path_id = bus; - ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; - ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; - ccb.crcn.flags = CAM_FLAG_NONE; + ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; + ccb->ccb_h.path_id = bus; + ccb->ccb_h.target_id = CAM_TARGET_WILDCARD; + ccb->ccb_h.target_lun = CAM_LUN_WILDCARD; + ccb->crcn.flags = CAM_FLAG_NONE; /* run this at a low priority */ - ccb.ccb_h.pinfo.priority = 5; + ccb->ccb_h.pinfo.priority = 5; - if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { + if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); - close(fd); - return(1); + retval = 1; + goto bailout; } - if ((ccb.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { + if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { fprintf(stdout, "%s of bus %d was successful\n", rescan ? "Re-scan" : "Reset", bus); } else { fprintf(stdout, "%s of bus %d returned error %#x\n", rescan ? "Re-scan" : "Reset", bus, - ccb.ccb_h.status & CAM_STATUS_MASK); + ccb->ccb_h.status & CAM_STATUS_MASK); retval = 1; } - close(fd); - return(retval); - + goto bailout; } @@ -3183,58 +3187,64 @@ rescan_or_reset_bus(path_id_t bus, int rescan) * no-op, sending a rescan to the xpt bus would result in a status of * CAM_REQ_INVALID. */ - bzero(&matchccb, sizeof(matchccb)); - matchccb.ccb_h.func_code = XPT_DEV_MATCH; - matchccb.ccb_h.path_id = CAM_BUS_WILDCARD; + matchccb = malloc(sizeof(*matchccb)); + if (matchccb == NULL) { + warn("failed to allocate CCB"); + retval = 1; + goto bailout; + } + bzero(matchccb, sizeof(*matchccb)); + matchccb->ccb_h.func_code = XPT_DEV_MATCH; + matchccb->ccb_h.path_id = CAM_BUS_WILDCARD; bufsize = sizeof(struct dev_match_result) * 20; - matchccb.cdm.match_buf_len = bufsize; - matchccb.cdm.matches=(struct dev_match_result *)malloc(bufsize); - if (matchccb.cdm.matches == NULL) { + matchccb->cdm.match_buf_len = bufsize; + matchccb->cdm.matches=(struct dev_match_result *)malloc(bufsize); + if (matchccb->cdm.matches == NULL) { warnx("can't malloc memory for matches"); retval = 1; goto bailout; } - matchccb.cdm.num_matches = 0; + matchccb->cdm.num_matches = 0; - matchccb.cdm.num_patterns = 1; - matchccb.cdm.pattern_buf_len = sizeof(struct dev_match_pattern); + matchccb->cdm.num_patterns = 1; + matchccb->cdm.pattern_buf_len = sizeof(struct dev_match_pattern); - matchccb.cdm.patterns = (struct dev_match_pattern *)malloc( - matchccb.cdm.pattern_buf_len); - if (matchccb.cdm.patterns == NULL) { + matchccb->cdm.patterns = (struct dev_match_pattern *)malloc( + matchccb->cdm.pattern_buf_len); + if (matchccb->cdm.patterns == NULL) { warnx("can't malloc memory for patterns"); retval = 1; goto bailout; } - matchccb.cdm.patterns[0].type = DEV_MATCH_BUS; - matchccb.cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY; + matchccb->cdm.patterns[0].type = DEV_MATCH_BUS; + matchccb->cdm.patterns[0].pattern.bus_pattern.flags = BUS_MATCH_ANY; do { unsigned int i; - if (ioctl(fd, CAMIOCOMMAND, &matchccb) == -1) { + if (ioctl(fd, CAMIOCOMMAND, matchccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); retval = 1; goto bailout; } - if ((matchccb.ccb_h.status != CAM_REQ_CMP) - || ((matchccb.cdm.status != CAM_DEV_MATCH_LAST) - && (matchccb.cdm.status != CAM_DEV_MATCH_MORE))) { + if ((matchccb->ccb_h.status != CAM_REQ_CMP) + || ((matchccb->cdm.status != CAM_DEV_MATCH_LAST) + && (matchccb->cdm.status != CAM_DEV_MATCH_MORE))) { warnx("got CAM error %#x, CDM error %d\n", - matchccb.ccb_h.status, matchccb.cdm.status); + matchccb->ccb_h.status, matchccb->cdm.status); retval = 1; goto bailout; } - for (i = 0; i < matchccb.cdm.num_matches; i++) { + for (i = 0; i < matchccb->cdm.num_matches; i++) { struct bus_match_result *bus_result; /* This shouldn't happen. */ - if (matchccb.cdm.matches[i].type != DEV_MATCH_BUS) + if (matchccb->cdm.matches[i].type != DEV_MATCH_BUS) continue; - bus_result = &matchccb.cdm.matches[i].result.bus_result; + bus_result =&matchccb->cdm.matches[i].result.bus_result; /* * We don't want to rescan or reset the xpt bus. @@ -3243,23 +3253,23 @@ rescan_or_reset_bus(path_id_t bus, int rescan) if (bus_result->path_id == CAM_XPT_PATH_ID) continue; - ccb.ccb_h.func_code = rescan ? XPT_SCAN_BUS : + ccb->ccb_h.func_code = rescan ? XPT_SCAN_BUS : XPT_RESET_BUS; - ccb.ccb_h.path_id = bus_result->path_id; - ccb.ccb_h.target_id = CAM_TARGET_WILDCARD; - ccb.ccb_h.target_lun = CAM_LUN_WILDCARD; - ccb.crcn.flags = CAM_FLAG_NONE; + ccb->ccb_h.path_id = bus_result->path_id; + ccb->ccb_h.target_id = CAM_TARGET_WILDCARD; + ccb->ccb_h.target_lun = CAM_LUN_WILDCARD; + ccb->crcn.flags = CAM_FLAG_NONE; /* run this at a low priority */ - ccb.ccb_h.pinfo.priority = 5; + ccb->ccb_h.pinfo.priority = 5; - if (ioctl(fd, CAMIOCOMMAND, &ccb) == -1) { + if (ioctl(fd, CAMIOCOMMAND, ccb) == -1) { warn("CAMIOCOMMAND ioctl failed"); retval = 1; goto bailout; } - if ((ccb.ccb_h.status & CAM_STATUS_MASK) ==CAM_REQ_CMP){ + if ((ccb->ccb_h.status & CAM_STATUS_MASK)==CAM_REQ_CMP){ fprintf(stdout, "%s of bus %d was successful\n", rescan? "Re-scan" : "Reset", bus_result->path_id); @@ -3272,22 +3282,24 @@ rescan_or_reset_bus(path_id_t bus, int rescan) fprintf(stderr, "%s of bus %d returned error " "%#x\n", rescan? "Re-scan" : "Reset", bus_result->path_id, - ccb.ccb_h.status & CAM_STATUS_MASK); + ccb->ccb_h.status & CAM_STATUS_MASK); retval = 1; } } - } while ((matchccb.ccb_h.status == CAM_REQ_CMP) - && (matchccb.cdm.status == CAM_DEV_MATCH_MORE)); + } while ((matchccb->ccb_h.status == CAM_REQ_CMP) + && (matchccb->cdm.status == CAM_DEV_MATCH_MORE)); bailout: if (fd != -1) close(fd); - if (matchccb.cdm.patterns != NULL) - free(matchccb.cdm.patterns); - if (matchccb.cdm.matches != NULL) - free(matchccb.cdm.matches); + if (matchccb != NULL) { + free(matchccb->cdm.patterns); + free(matchccb->cdm.matches); + free(matchccb); + } + free(ccb); return(retval); } From 07c4accca887ca0d3ea817b59e03725a56964661 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Fri, 21 Oct 2016 20:17:19 +0000 Subject: [PATCH 007/235] Close some file descriptor leaks in pw MFC after: 4 weeks Sponsored by: Spectra Logic Corp Differential Revision: https://reviews.freebsd.org/D8245 --- usr.sbin/pw/grupd.c | 3 +++ usr.sbin/pw/pw_nis.c | 3 +++ usr.sbin/pw/pwupd.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/usr.sbin/pw/grupd.c b/usr.sbin/pw/grupd.c index 9cbe0cb0b345..38d5e5bc956c 100644 --- a/usr.sbin/pw/grupd.c +++ b/usr.sbin/pw/grupd.c @@ -34,6 +34,7 @@ static const char rcsid[] = #include #include #include +#include #include "pwupd.h" @@ -73,8 +74,10 @@ gr_update(struct group * grp, char const * group) } if (gr_copy(pfd, tfd, gr, old_gr) == -1) { gr_fini(); + close(tfd); err(1, "gr_copy()"); } + close(tfd); if (gr_mkdb() == -1) { gr_fini(); err(1, "gr_mkdb()"); diff --git a/usr.sbin/pw/pw_nis.c b/usr.sbin/pw/pw_nis.c index 6cc361b7a25c..35b26ea5224b 100644 --- a/usr.sbin/pw/pw_nis.c +++ b/usr.sbin/pw/pw_nis.c @@ -34,6 +34,7 @@ static const char rcsid[] = #include #include #include +#include #include "pw.h" @@ -63,8 +64,10 @@ pw_nisupdate(const char * path, struct passwd * pwd, char const * user) } if (pw_copy(pfd, tfd, pw, old_pw) == -1) { pw_fini(); + close(tfd); err(1, "pw_copy()"); } + close(tfd); if (chmod(pw_tempname(), 0644) == -1) err(1, "chmod()"); if (rename(pw_tempname(), path) == -1) diff --git a/usr.sbin/pw/pwupd.c b/usr.sbin/pw/pwupd.c index ee23952e090f..3bcb95f8c465 100644 --- a/usr.sbin/pw/pwupd.c +++ b/usr.sbin/pw/pwupd.c @@ -111,8 +111,10 @@ pw_update(struct passwd * pwd, char const * user) } if (pw_copy(pfd, tfd, pw, old_pw) == -1) { pw_fini(); + close(tfd); err(1, "pw_copy()"); } + close(tfd); /* * in case of deletion of a user, the whole database * needs to be regenerated From e5e40621d1af7007fb0c7646dd93e3233c66eefc Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 21 Oct 2016 21:52:22 +0000 Subject: [PATCH 008/235] Fix building of many ports that use make from base, such as devel/apr1, after r307676, which added transformation rules for .llo and .bco files. These suffixes also have to be added the the global .SUFFIXES target, otherwise the various suffix-transformation rules would be interpreted as literal targets. E.g., .c.bco: ... commands ... would actually to build a file named ".c.bco". --- share/mk/sys.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 3f768844794c..28387f61bc49 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -121,7 +121,7 @@ META_MODE?= normal .if defined(%POSIX) .SUFFIXES: .o .c .y .l .a .sh .f .else -.SUFFIXES: .out .a .ln .o .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh +.SUFFIXES: .out .a .ln .o .bco .llo .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh .endif AR ?= ar From 7627b33010f0907e2bfc9e6b826d102eb05f6b33 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 21 Oct 2016 21:55:50 +0000 Subject: [PATCH 009/235] swapoff: Remove only late devices with -aL. Currently, '/etc/rc.d/swaplate stop' removes all swap devices. This can be very slow and may not even be possible if there is a lot of swap space in use. However, removing swap devices is only needed for late swap devices that may depend on daemons that subsequent shutdown steps stop. Normal swap devices such as hard disk partitions will remain available throughout the shutdown process and need not be removed. In swapoff, interpret -aL to remove late swap devices only, and use this in etc/rc.d/swaplate. The meaning of -aL in swapon remains unchanged (add all swap devices, both normal and late). PR: 187081 Reviewed by: wblock (man page only), ngie MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D8126 --- etc/rc.d/swaplate | 2 +- sbin/swapon/swapon.8 | 8 +++++++- sbin/swapon/swapon.c | 4 ++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/etc/rc.d/swaplate b/etc/rc.d/swaplate index f335481b6e47..fbfae2ad9bfe 100755 --- a/etc/rc.d/swaplate +++ b/etc/rc.d/swaplate @@ -12,7 +12,7 @@ name="swaplate" desc="Setup late swap space" start_cmd='/sbin/swapon -aLq' -stop_cmd='/sbin/swapoff -aq' +stop_cmd='/sbin/swapoff -aLq' load_rc_config swap run_rc_command "$1" diff --git a/sbin/swapon/swapon.8 b/sbin/swapon/swapon.8 index ffce7d9db46e..51bee68346b6 100644 --- a/sbin/swapon/swapon.8 +++ b/sbin/swapon/swapon.8 @@ -28,7 +28,7 @@ .\" @(#)swapon.8 8.1 (Berkeley) 6/5/93 .\" $FreeBSD$ .\" -.Dd October 2, 2016 +.Dd October 21, 2016 .Dt SWAPON 8 .Os .Sh NAME @@ -98,6 +98,12 @@ will be removed, unless their .Dq noauto option is also set. If the +.Fl L +option is specified, +only swap devices with the +.Dq late +option will be removed. +If the .Fl q option is used, informational messages will not be diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c index e34cfcf171bf..052fbc734afb 100644 --- a/sbin/swapon/swapon.c +++ b/sbin/swapon/swapon.c @@ -176,6 +176,10 @@ main(int argc, char **argv) strstr(fsp->fs_mntops, "late") && late == 0) continue; + if (which_prog == SWAPOFF && + strstr(fsp->fs_mntops, "late") == NULL && + late != 0) + continue; swfile = swap_on_off(fsp->fs_spec, 1, fsp->fs_mntops); if (swfile == NULL) { From 5dd723425ee0bbe05c08d2c2272be9fc34695886 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 21 Oct 2016 23:50:02 +0000 Subject: [PATCH 010/235] Define max_align_t for C11. libc++'s stddef.h includes an existing definition of max_align_t for C++11, but it is only defined for C++, not for C. In addition, GCC and clang both define an alternate version of max_align_t that uses a union of multiple types rather than a plain long double as in libc++. This adds a __max_align_t to that matches the GCC and clang definition that is mapped to max_align_t in . PR: 210890 Reviewed by: dim MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D8194 --- include/stddef.h | 8 ++++++++ sys/sys/_types.h | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/include/stddef.h b/include/stddef.h index 7898da251a6e..7f2d2f0cd4bd 100644 --- a/include/stddef.h +++ b/include/stddef.h @@ -62,6 +62,14 @@ typedef ___wchar_t wchar_t; #endif #endif +#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L +#ifndef __CLANG_MAX_ALIGN_T_DEFINED +typedef __max_align_t max_align_t; +#define __CLANG_MAX_ALIGN_T_DEFINED +#define __GCC_MAX_ALIGN_T +#endif +#endif + #define offsetof(type, member) __offsetof(type, member) #endif /* _STDDEF_H_ */ diff --git a/sys/sys/_types.h b/sys/sys/_types.h index ecc1c7e05e4c..8736651ba6f0 100644 --- a/sys/sys/_types.h +++ b/sys/sys/_types.h @@ -100,6 +100,11 @@ typedef __uint_least32_t __char32_t; #define _CHAR32_T_DECLARED #endif +typedef struct { + long long __max_align1 __aligned(_Alignof(long long)); + long double __max_align2 __aligned(_Alignof(long double)); +} __max_align_t; + typedef __uint32_t __dev_t; /* device number */ typedef __uint32_t __fixpt_t; /* fixed point number */ From aaa4ddd9d084859c0680ed93de6bf44eaf57276e Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Sat, 22 Oct 2016 00:48:58 +0000 Subject: [PATCH 011/235] cxgbe(4): Dump any mailbox command that times out. --- sys/dev/cxgbe/common/t4_hw.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 553993a66f2b..4a52139ac98c 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -432,6 +432,21 @@ int t4_wr_mbox_meat_timeout(struct adapter *adap, int mbox, const void *cmd, CH_ERR(adap, "command %#x in mailbox %d timed out\n", *(const u8 *)cmd, mbox); + /* If DUMP_MBOX is set the mbox has already been dumped */ + if ((adap->debug_flags & DF_DUMP_MBOX) == 0) { + p = cmd; + CH_ERR(adap, "mbox: %016llx %016llx %016llx %016llx " + "%016llx %016llx %016llx %016llx\n", + (unsigned long long)be64_to_cpu(p[0]), + (unsigned long long)be64_to_cpu(p[1]), + (unsigned long long)be64_to_cpu(p[2]), + (unsigned long long)be64_to_cpu(p[3]), + (unsigned long long)be64_to_cpu(p[4]), + (unsigned long long)be64_to_cpu(p[5]), + (unsigned long long)be64_to_cpu(p[6]), + (unsigned long long)be64_to_cpu(p[7])); + } + t4_report_fw_error(adap); t4_fatal_err(adap); return ret; From dc9b124d6668d984b8a012e21fef6a0fe585faef Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 22 Oct 2016 01:57:15 +0000 Subject: [PATCH 012/235] Create a new MACHINE_ARCH for Freescale PowerPC e500v2 Summary: The Freescale e500v2 PowerPC core does not use a standard FPU. Instead, it uses a Signal Processing Engine (SPE)--a DSP-style vector processor unit, which doubles as a FPU. The PowerPC SPE ABI is incompatible with the stock powerpc ABI, so a new MACHINE_ARCH was created to deal with this. Additionaly, the SPE opcodes overlap with Altivec, so these are mutually exclusive. Taking advantage of this fact, a new file, powerpc/booke/spe.c, was created with the same function set as in powerpc/powerpc/altivec.c, so it becomes effectively a drop-in replacement. setjmp/longjmp were modified to save the upper 32-bits of the now-64-bit GPRs (upper 32-bits are only accessible by the SPE). Note: This does _not_ support the SPE in the e500v1, as the e500v1 SPE does not support double-precision floating point. Also, without a new MACHINE_ARCH it would be impossible to provide binary packages which utilize the SPE. Additionally, no work has been done to support ports, work is needed for this. This also means no newer gcc can yet be used. However, gcc's powerpc support has been refactored which would make adding a powerpcspe-freebsd target very easy. Test Plan: This was lightly tested on a RouterBoard RB800 and an AmigaOne A1222 (P1022-based) board, compiled against the new ABI. Base system utilities (/bin/sh, /bin/ls, etc) still function appropriately, the system is able to boot multiuser. Reviewed By: bdrewery, imp Relnotes: yes Differential Revision: https://reviews.freebsd.org/D5683 --- Makefile | 4 +- Makefile.inc1 | 1 + contrib/binutils/bfd/config.bfd | 2 +- contrib/gcc/config/rs6000/freebsdspe.h | 77 +++++ gnu/lib/libgcc/Makefile | 2 +- gnu/lib/libgomp/Makefile | 2 +- gnu/usr.bin/binutils/Makefile.inc0 | 4 +- gnu/usr.bin/cc/Makefile.tgt | 2 +- gnu/usr.bin/cc/cc_tools/Makefile.hdrs | 4 + gnu/usr.bin/cc/include/Makefile | 3 +- gnu/usr.bin/gdb/Makefile.inc | 2 +- gnu/usr.bin/gdb/libgdb/Makefile | 2 +- lib/libarchive/Makefile | 2 +- lib/libc/powerpcspe/Makefile.inc | 7 + lib/libc/powerpcspe/SYS.h | 70 +++++ lib/libc/powerpcspe/Symbol.map | 59 ++++ lib/libc/powerpcspe/_fpmath.h | 49 ++++ lib/libc/powerpcspe/arith.h | 16 + lib/libc/powerpcspe/gd_qnan.h | 21 ++ lib/libc/powerpcspe/gen/Makefile.inc | 11 + lib/libc/powerpcspe/gen/_ctx_start.S | 46 +++ lib/libc/powerpcspe/gen/_set_tp.c | 35 +++ lib/libc/powerpcspe/gen/_setjmp.S | 117 ++++++++ lib/libc/powerpcspe/gen/eabi.S | 34 +++ lib/libc/powerpcspe/gen/fabs.S | 38 +++ lib/libc/powerpcspe/gen/flt_rounds.c | 57 ++++ lib/libc/powerpcspe/gen/fpgetmask.c | 49 ++++ lib/libc/powerpcspe/gen/fpgetround.c | 49 ++++ lib/libc/powerpcspe/gen/fpgetsticky.c | 55 ++++ lib/libc/powerpcspe/gen/fpsetmask.c | 53 ++++ lib/libc/powerpcspe/gen/fpsetround.c | 53 ++++ lib/libc/powerpcspe/gen/infinity.c | 17 ++ lib/libc/powerpcspe/gen/makecontext.c | 120 ++++++++ lib/libc/powerpcspe/gen/setjmp.S | 138 +++++++++ lib/libc/powerpcspe/gen/signalcontext.c | 103 +++++++ lib/libc/powerpcspe/gen/sigsetjmp.S | 150 ++++++++++ lib/libc/powerpcspe/gen/syncicache.c | 103 +++++++ lib/libc/powerpcspe/softfloat/milieu.h | 49 ++++ lib/libc/powerpcspe/softfloat/powerpc-gcc.h | 92 ++++++ lib/libc/powerpcspe/softfloat/softfloat.h | 307 ++++++++++++++++++++ lib/libc/powerpcspe/sys/Makefile.inc | 8 + lib/libc/powerpcspe/sys/brk.S | 76 +++++ lib/libc/powerpcspe/sys/cerror.S | 58 ++++ lib/libc/powerpcspe/sys/exect.S | 42 +++ lib/libc/powerpcspe/sys/ptrace.S | 61 ++++ lib/libc/powerpcspe/sys/sbrk.S | 73 +++++ lib/libc/powerpcspe/sys/setlogin.S | 51 ++++ lib/msun/powerpc/fenv.h | 5 + share/mk/bsd.cpu.mk | 6 + share/mk/bsd.endian.mk | 1 + share/mk/local.meta.sys.mk | 2 +- share/mk/sys.mk | 2 +- sys/boot/powerpc/Makefile | 5 +- sys/conf/Makefile.powerpc | 4 + sys/conf/files.powerpc | 29 +- sys/conf/kern.mk | 5 + sys/conf/ldscript.powerpcspe | 144 +++++++++ sys/conf/options.powerpc | 1 + sys/modules/Makefile | 8 +- sys/powerpc/booke/booke_machdep.c | 5 + sys/powerpc/booke/spe.c | 183 ++++++++++++ sys/powerpc/conf/MPC85XXSPE | 100 +++++++ sys/powerpc/include/param.h | 4 + sys/powerpc/include/spr.h | 1 + sys/powerpc/include/trap.h | 1 + sys/powerpc/powerpc/trap.c | 39 +++ usr.sbin/Makefile.powerpc | 2 + 67 files changed, 2890 insertions(+), 31 deletions(-) create mode 100644 contrib/gcc/config/rs6000/freebsdspe.h create mode 100644 lib/libc/powerpcspe/Makefile.inc create mode 100644 lib/libc/powerpcspe/SYS.h create mode 100644 lib/libc/powerpcspe/Symbol.map create mode 100644 lib/libc/powerpcspe/_fpmath.h create mode 100644 lib/libc/powerpcspe/arith.h create mode 100644 lib/libc/powerpcspe/gd_qnan.h create mode 100644 lib/libc/powerpcspe/gen/Makefile.inc create mode 100644 lib/libc/powerpcspe/gen/_ctx_start.S create mode 100644 lib/libc/powerpcspe/gen/_set_tp.c create mode 100644 lib/libc/powerpcspe/gen/_setjmp.S create mode 100644 lib/libc/powerpcspe/gen/eabi.S create mode 100644 lib/libc/powerpcspe/gen/fabs.S create mode 100644 lib/libc/powerpcspe/gen/flt_rounds.c create mode 100644 lib/libc/powerpcspe/gen/fpgetmask.c create mode 100644 lib/libc/powerpcspe/gen/fpgetround.c create mode 100644 lib/libc/powerpcspe/gen/fpgetsticky.c create mode 100644 lib/libc/powerpcspe/gen/fpsetmask.c create mode 100644 lib/libc/powerpcspe/gen/fpsetround.c create mode 100644 lib/libc/powerpcspe/gen/infinity.c create mode 100644 lib/libc/powerpcspe/gen/makecontext.c create mode 100644 lib/libc/powerpcspe/gen/setjmp.S create mode 100644 lib/libc/powerpcspe/gen/signalcontext.c create mode 100644 lib/libc/powerpcspe/gen/sigsetjmp.S create mode 100644 lib/libc/powerpcspe/gen/syncicache.c create mode 100644 lib/libc/powerpcspe/softfloat/milieu.h create mode 100644 lib/libc/powerpcspe/softfloat/powerpc-gcc.h create mode 100644 lib/libc/powerpcspe/softfloat/softfloat.h create mode 100644 lib/libc/powerpcspe/sys/Makefile.inc create mode 100644 lib/libc/powerpcspe/sys/brk.S create mode 100644 lib/libc/powerpcspe/sys/cerror.S create mode 100644 lib/libc/powerpcspe/sys/exect.S create mode 100644 lib/libc/powerpcspe/sys/ptrace.S create mode 100644 lib/libc/powerpcspe/sys/sbrk.S create mode 100644 lib/libc/powerpcspe/sys/setlogin.S create mode 100644 sys/conf/ldscript.powerpcspe create mode 100644 sys/powerpc/booke/spe.c create mode 100644 sys/powerpc/conf/MPC85XXSPE diff --git a/Makefile b/Makefile index 00dbc23bb79c..b5d51341135e 100644 --- a/Makefile +++ b/Makefile @@ -239,7 +239,7 @@ _MAKE+= MK_META_MODE=no _TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/} .elif !defined(TARGET) && defined(TARGET_ARCH) && \ ${TARGET_ARCH} != ${MACHINE_ARCH} -_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/riscv64/riscv/} +_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64/riscv/} .endif .if defined(TARGET) && !defined(_TARGET) _TARGET=${TARGET} @@ -422,7 +422,7 @@ _UNIVERSE_TARGETS= ${TARGETS} TARGET_ARCHES_arm?= arm armeb armv6 TARGET_ARCHES_arm64?= aarch64 TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 -TARGET_ARCHES_powerpc?= powerpc powerpc64 +TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe TARGET_ARCHES_pc98?= i386 .for target in ${TARGETS} TARGET_ARCHES_${target}?= ${target} diff --git a/Makefile.inc1 b/Makefile.inc1 index a89a893a9eec..99918b3703e8 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -358,6 +358,7 @@ KNOWN_ARCHES?= aarch64/arm64 \ mipsn32/mips \ powerpc \ powerpc64/powerpc \ + powerpcspe/powerpc \ riscv64/riscv \ sparc64 diff --git a/contrib/binutils/bfd/config.bfd b/contrib/binutils/bfd/config.bfd index 6b108c0b8fdb..1365ac12f8a5 100755 --- a/contrib/binutils/bfd/config.bfd +++ b/contrib/binutils/bfd/config.bfd @@ -1103,7 +1103,7 @@ case "${targ}" in want64=true ;; #endif - powerpc-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \ + powerpc-*-*bsd* | powerpcspe-*-*bsd* | powerpc-*-elf* | powerpc-*-sysv4* | powerpc-*-eabi* | \ powerpc-*-solaris2* | powerpc-*-linux-* | powerpc-*-rtems* | \ powerpc-*-chorus*) targ_defvec=bfd_elf32_powerpc_vec diff --git a/contrib/gcc/config/rs6000/freebsdspe.h b/contrib/gcc/config/rs6000/freebsdspe.h new file mode 100644 index 000000000000..9c960298f6ef --- /dev/null +++ b/contrib/gcc/config/rs6000/freebsdspe.h @@ -0,0 +1,77 @@ +/* Definitions of target machine for GNU compiler, + for PowerPC e500 machines running FreeBSD. + Based on linuxspe.h + Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Contributed by Aldy Hernandez (aldy@quesejoda.com). + + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2, or (at your + option) any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING. If not, write to the + Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#undef TARGET_VERSION +#define TARGET_VERSION fprintf (stderr, " (PowerPC E500 FreeBSD)"); + +/* Override rs6000.h and sysv4.h definition. */ +#undef TARGET_DEFAULT +#define TARGET_DEFAULT (MASK_POWERPC | MASK_NEW_MNEMONICS | MASK_STRICT_ALIGN) + +#undef TARGET_SPE_ABI +#undef TARGET_SPE +#undef TARGET_E500 +#undef TARGET_ISEL +#undef TARGET_FPRS +#undef TARGET_E500_SINGLE +#undef TARGET_E500_DOUBLE + +#define TARGET_SPE_ABI rs6000_spe_abi +#define TARGET_SPE rs6000_spe +#define TARGET_E500 (rs6000_cpu == PROCESSOR_PPC8540) +#define TARGET_ISEL rs6000_isel +#define TARGET_FPRS (rs6000_float_gprs == 0) +#define TARGET_E500_SINGLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 1) +#define TARGET_E500_DOUBLE (TARGET_HARD_FLOAT && rs6000_float_gprs == 2) + +#undef SUBSUBTARGET_OVERRIDE_OPTIONS +#define SUBSUBTARGET_OVERRIDE_OPTIONS \ + if (rs6000_select[1].string == NULL) \ + rs6000_cpu = PROCESSOR_PPC8540; \ + if (!rs6000_explicit_options.abi) \ + rs6000_spe_abi = 1; \ + if (!rs6000_explicit_options.float_gprs) \ + rs6000_float_gprs = 1; \ + /* See note below. */ \ + /*if (!rs6000_explicit_options.long_double)*/ \ + /* rs6000_long_double_type_size = 128;*/ \ + if (!rs6000_explicit_options.spe) \ + rs6000_spe = 1; \ + if (!rs6000_explicit_options.isel) \ + rs6000_isel = 1; \ + if (target_flags & MASK_64BIT) \ + error ("-m64 not supported in this configuration") + +/* The e500 ABI says that either long doubles are 128 bits, or if + implemented in any other size, the compiler/linker should error out. + We have no emulation libraries for 128 bit long doubles, and I hate + the dozens of failures on the regression suite. So I'm breaking ABI + specifications, until I properly fix the emulation. + + Enable these later. +#undef CPP_LONGDOUBLE_DEFAULT_SPEC +#define CPP_LONGDOUBLE_DEFAULT_SPEC "-D__LONG_DOUBLE_128__=1" +*/ + +#undef ASM_DEFAULT_SPEC +#define ASM_DEFAULT_SPEC "-mppc -mspe -me500" diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile index b101b4f2ea91..3186458f0866 100644 --- a/gnu/lib/libgcc/Makefile +++ b/gnu/lib/libgcc/Makefile @@ -173,7 +173,7 @@ LIB2FUNCS_EXTRA+= fixdfdi.c fixunssfsi.c .endif .endif -.if ${TARGET_ARCH} == "powerpc" +.if ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpcspe" # from config/rs6000/t-ppccomm LIB2FUNCS_EXTRA = tramp.asm LIB2FUNCS_STATIC_EXTRA = eabi.asm diff --git a/gnu/lib/libgomp/Makefile b/gnu/lib/libgomp/Makefile index d428bd3f24c6..b4abf7958bcc 100644 --- a/gnu/lib/libgomp/Makefile +++ b/gnu/lib/libgomp/Makefile @@ -24,7 +24,7 @@ VERSION_MAP= ${SRCDIR}/libgomp.map # Target-specific OpenMP configuration .if ${MACHINE_CPUARCH} == arm || ${MACHINE_CPUARCH} == i386 || \ - ${MACHINE_ARCH} == powerpc || \ + ${MACHINE_ARCH} == powerpc || ${MACHINE_ARCH} == powerpcspe || \ (${MACHINE_CPUARCH} == mips && ${MACHINE_ARCH:Mmips64*} == "") OMP_LOCK_ALIGN = 4 OMP_LOCK_KIND= 4 diff --git a/gnu/usr.bin/binutils/Makefile.inc0 b/gnu/usr.bin/binutils/Makefile.inc0 index 28062d587393..597d451c8a10 100644 --- a/gnu/usr.bin/binutils/Makefile.inc0 +++ b/gnu/usr.bin/binutils/Makefile.inc0 @@ -7,7 +7,7 @@ VERSION= "2.17.50 [FreeBSD] 2007-07-03" .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif @@ -30,7 +30,7 @@ RELSRC= ${RELTOP}/../../../contrib/binutils SRCDIR= ${.CURDIR}/${RELSRC} .if ${TARGET_CPUARCH} == "arm" || ${TARGET_CPUARCH} == "i386" || \ - ${TARGET_ARCH} == "powerpc" || \ + ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpcspe" || \ (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips64*} == "") CFLAGS+= -DBFD_DEFAULT_TARGET_SIZE=32 .else diff --git a/gnu/usr.bin/cc/Makefile.tgt b/gnu/usr.bin/cc/Makefile.tgt index 63be261ff48d..0337ecf2bfcb 100644 --- a/gnu/usr.bin/cc/Makefile.tgt +++ b/gnu/usr.bin/cc/Makefile.tgt @@ -4,7 +4,7 @@ # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif diff --git a/gnu/usr.bin/cc/cc_tools/Makefile.hdrs b/gnu/usr.bin/cc/cc_tools/Makefile.hdrs index 959d7a73e985..f2576f7fdf0a 100644 --- a/gnu/usr.bin/cc/cc_tools/Makefile.hdrs +++ b/gnu/usr.bin/cc/cc_tools/Makefile.hdrs @@ -46,6 +46,10 @@ TARGET_INC+= ${GCC_CPU}/bpabi.h TARGET_INC+= ${GCC_CPU}/biarch64.h TARGET_INC+= ${GCC_CPU}/default64.h .endif +.if ${TARGET_ARCH} == "powerpcspe" +TARGET_INC+= ${GCC_CPU}/freebsdspe.h +TARGET_INC+= ${GCC_CPU}/e500-double.h +.endif TARGET_INC+= ${GCC_CPU}/freebsd.h .if ${TARGET_CPUARCH} == "amd64" TARGET_INC+= ${GCC_CPU}/freebsd64.h diff --git a/gnu/usr.bin/cc/include/Makefile b/gnu/usr.bin/cc/include/Makefile index 48060ecc7750..bcca48a7a722 100644 --- a/gnu/usr.bin/cc/include/Makefile +++ b/gnu/usr.bin/cc/include/Makefile @@ -14,7 +14,8 @@ INCS= ammintrin.h emmintrin.h mmintrin.h mm3dnow.h pmmintrin.h \ INCS+= wmmintrin.h __wmmintrin_aes.h __wmmintrin_pclmul.h .elif ${TARGET_ARCH} == "arm" INCS= mmintrin.h -.elif ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpc64" +.elif ${TARGET_ARCH} == "powerpc" || ${TARGET_ARCH} == "powerpc64" || \ + ${TARGET_ARCH} == "powerpcspe" INCS= ppc-asm.h altivec.h spe.h .endif diff --git a/gnu/usr.bin/gdb/Makefile.inc b/gnu/usr.bin/gdb/Makefile.inc index 34dc90797d08..5bce6a91f01e 100644 --- a/gnu/usr.bin/gdb/Makefile.inc +++ b/gnu/usr.bin/gdb/Makefile.inc @@ -23,7 +23,7 @@ OBJ_RL= ${OBJ_ROOT}/../lib/libreadline/readline # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif diff --git a/gnu/usr.bin/gdb/libgdb/Makefile b/gnu/usr.bin/gdb/libgdb/Makefile index ed00525fad3f..71bb9ff494da 100644 --- a/gnu/usr.bin/gdb/libgdb/Makefile +++ b/gnu/usr.bin/gdb/libgdb/Makefile @@ -4,7 +4,7 @@ # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc64/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index ce390f8372eb..67aff5cecb26 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -30,7 +30,7 @@ SHARED_CFLAGS+= -DHAVE_ICONV=1 -DHAVE_ICONV_H=1 -DICONV_CONST= .endif .if ${MACHINE_ARCH:Marm*} != "" || ${MACHINE_ARCH:Mmips*} != "" || \ - ${MACHINE_ARCH:Msparc64*} != "" + ${MACHINE_ARCH:Msparc64*} != "" || ${MACHINE_ARCH:Mpowerpc*} != "" NO_WCAST_ALIGN= yes .if ${MACHINE_ARCH:M*64*} == "" CFLAGS+= -DPPMD_32BIT diff --git a/lib/libc/powerpcspe/Makefile.inc b/lib/libc/powerpcspe/Makefile.inc new file mode 100644 index 000000000000..05d1e44f8b82 --- /dev/null +++ b/lib/libc/powerpcspe/Makefile.inc @@ -0,0 +1,7 @@ +# $FreeBSD$ + +SRCS+= trivial-vdso_tc.c + +# Long double is 64-bits +MDSRCS+=machdep_ldisd.c +SYM_MAPS+=${LIBC_SRCTOP}/powerpcspe/Symbol.map diff --git a/lib/libc/powerpcspe/SYS.h b/lib/libc/powerpcspe/SYS.h new file mode 100644 index 000000000000..f0665c09c144 --- /dev/null +++ b/lib/libc/powerpcspe/SYS.h @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2002 Benno Rice. All rights reserved. + * Copyright (c) 2002 David E. O'Brien. 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. + * 3. Neither the name of the author nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 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. + * + * $NetBSD: SYS.h,v 1.8 2002/01/14 00:55:56 thorpej Exp $ + * $FreeBSD$ + */ + +#include +#include + +#define _SYSCALL(name) \ + .text; \ + .align 2; \ + li 0,(SYS_##name); \ + sc + +#define SYSCALL(name) \ + .text; \ + .align 2; \ +2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bso 2b + +#define PSEUDO(name) \ + .text; \ + .align 2; \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnslr; \ + b PIC_PLT(CNAME(HIDENAME(cerror))) + +#define RSYSCALL(name) \ + .text; \ + .align 2; \ +2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ +ENTRY(__sys_##name); \ + WEAK_REFERENCE(__sys_##name, name); \ + WEAK_REFERENCE(__sys_##name, _##name); \ + _SYSCALL(name); \ + bnslr; \ + b PIC_PLT(CNAME(HIDENAME(cerror))) diff --git a/lib/libc/powerpcspe/Symbol.map b/lib/libc/powerpcspe/Symbol.map new file mode 100644 index 000000000000..f695c81bb27f --- /dev/null +++ b/lib/libc/powerpcspe/Symbol.map @@ -0,0 +1,59 @@ +/* + * $FreeBSD$ + */ + +/* + * This only needs to contain symbols that are not listed in + * symbol maps from other parts of libc (i.e., not found in + * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). + */ +FBSD_1.0 { + /* PSEUDO syscalls */ + _exit; + + _mcount; + _setjmp; + _longjmp; + fabs; + __flt_rounds; + fpgetmask; + fpgetround; + fpgetsticky; + fpsetmask; + fpsetround; + __infinity; + __nan; + makecontext; + setjmp; + longjmp; + sigsetjmp; + siglongjmp; + htonl; + htons; + ntohl; + ntohs; + brk; + exect; + sbrk; + vfork; +}; + +FBSD_1.3 { + __eabi; +}; + +FBSDprivate_1.0 { + /* PSEUDO syscalls */ + __sys_getlogin; + _getlogin; + __sys_exit; + + _set_tp; + _fpgetsticky; + __makecontext; + __longjmp; + signalcontext; + __signalcontext; + __syncicache; + _end; +}; diff --git a/lib/libc/powerpcspe/_fpmath.h b/lib/libc/powerpcspe/_fpmath.h new file mode 100644 index 000000000000..6d80eb4bdf4e --- /dev/null +++ b/lib/libc/powerpcspe/_fpmath.h @@ -0,0 +1,49 @@ +/*- + * Copyright (c) 2003 David Schultz + * 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$ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; + } bits; +}; + +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/lib/libc/powerpcspe/arith.h b/lib/libc/powerpcspe/arith.h new file mode 100644 index 000000000000..8e2c9ec597b3 --- /dev/null +++ b/lib/libc/powerpcspe/arith.h @@ -0,0 +1,16 @@ +/* + * MD header for contrib/gdtoa + * + * $FreeBSD$ + */ + +/* + * NOTE: The definitions in this file must be correct or strtod(3) and + * floating point formats in printf(3) will break! The file can be + * generated by running contrib/gdtoa/arithchk.c on the target + * architecture. See contrib/gdtoa/gdtoaimp.h for details. + */ + +#define IEEE_MC68k +#define Arith_Kind_ASL 2 +#define Double_Align diff --git a/lib/libc/powerpcspe/gd_qnan.h b/lib/libc/powerpcspe/gd_qnan.h new file mode 100644 index 000000000000..d70d8c318c4c --- /dev/null +++ b/lib/libc/powerpcspe/gd_qnan.h @@ -0,0 +1,21 @@ +/* + * MD header for contrib/gdtoa + * + * This file can be generated by compiling and running contrib/gdtoa/qnan.c + * on the target architecture after arith.h has been generated. + * + * $FreeBSD$ + */ + +#define f_QNAN 0x7fc00000 +#define d_QNAN0 0x7ff80000 +#define d_QNAN1 0x0 +#define ld_QNAN0 0x7ff80000 +#define ld_QNAN1 0x0 +#define ld_QNAN2 0x0 +#define ld_QNAN3 0x0 +#define ldus_QNAN0 0x7ff8 +#define ldus_QNAN1 0x0 +#define ldus_QNAN2 0x0 +#define ldus_QNAN3 0x0 +#define ldus_QNAN4 0x0 diff --git a/lib/libc/powerpcspe/gen/Makefile.inc b/lib/libc/powerpcspe/gen/Makefile.inc new file mode 100644 index 000000000000..2a00ba332b94 --- /dev/null +++ b/lib/libc/powerpcspe/gen/Makefile.inc @@ -0,0 +1,11 @@ +# $FreeBSD$ + +SRCS += _ctx_start.S eabi.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ + fpgetsticky.c fpsetmask.c fpsetround.c \ + infinity.c ldexp.c makecontext.c _setjmp.S \ + setjmp.S sigsetjmp.S signalcontext.c syncicache.c \ + _set_tp.c \ + trivial-getcontextx.c + + + diff --git a/lib/libc/powerpcspe/gen/_ctx_start.S b/lib/libc/powerpcspe/gen/_ctx_start.S new file mode 100644 index 000000000000..4b9fc1d53ae0 --- /dev/null +++ b/lib/libc/powerpcspe/gen/_ctx_start.S @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + */ + + #include + + __FBSDID("$FreeBSD$"); + + .globl CNAME(_ctx_done) + .globl CNAME(abort) + + ENTRY(_ctx_start) + mtlr %r14 + blrl /* branch to start function */ + mr %r3,%r15 /* pass pointer to ucontext as argument */ + bl PIC_PLT(CNAME(_ctx_done)) /* branch to ctxt completion func */ + /* + * we should never return from the + * above branch. + */ + bl PIC_PLT(CNAME(abort)) /* abort */ + END(_cts_start) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/_set_tp.c b/lib/libc/powerpcspe/gen/_set_tp.c new file mode 100644 index 000000000000..eeb062f30217 --- /dev/null +++ b/lib/libc/powerpcspe/gen/_set_tp.c @@ -0,0 +1,35 @@ +/*- + * Copyright (c) 2004 Doug Rabson + * 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 "libc_private.h" + +void +_set_tp(void *tpval) +{ + + __asm __volatile("mr 2,%0" :: "r"((char*)tpval + 0x7008)); +} diff --git a/lib/libc/powerpcspe/gen/_setjmp.S b/lib/libc/powerpcspe/gen/_setjmp.S new file mode 100644 index 000000000000..0dd28fa2deb4 --- /dev/null +++ b/lib/libc/powerpcspe/gen/_setjmp.S @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2016 Justin Hibbits + * 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. + */ +/* $NetBSD: _setjmp.S,v 1.1 1997/03/29 20:55:53 thorpej Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * C library -- _setjmp, _longjmp + * + * _longjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * _setjmp(a) + * by restoring registers from the stack. + * The previous signal state is NOT restored. + * + * jmpbuf layout: + * +------------+ + * | unused | + * +------------+ + * | unused | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + +ENTRY(_setjmp) + mflr %r11 + mfcr %r12 + evstdd %r1,24+0*8(%r3) + evstdd %r2,24+1*8(%r3) + evstdd %r11,24+2*8(%r3) + evstdd %r12,24+3*8(%r3) + evstdd %r13,24+4*8(%r3) + evstdd %r14,24+5*8(%r3) + evstdd %r15,24+6*8(%r3) + evstdd %r16,24+7*8(%r3) + evstdd %r17,24+8*8(%r3) + evstdd %r18,24+9*8(%r3) + evstdd %r19,24+10*8(%r3) + evstdd %r20,24+11*8(%r3) + evstdd %r21,24+12*8(%r3) + evstdd %r22,24+13*8(%r3) + evstdd %r23,24+14*8(%r3) + evstdd %r24,24+15*8(%r3) + evstdd %r25,24+16*8(%r3) + evstdd %r26,24+17*8(%r3) + evstdd %r27,24+18*8(%r3) + evstdd %r28,24+19*8(%r3) + evstdd %r29,24+20*8(%r3) + evstdd %r30,24+21*8(%r3) + evstdd %r31,24+22*8(%r3) + + li %r3,0 + blr +END(_setjmp) + +ENTRY(_longjmp) + evldd %r1,24+0*8(%r3) + evldd %r2,24+1*8(%r3) + evldd %r11,24+2*8(%r3) + evldd %r12,24+3*8(%r3) + evldd %r13,24+4*8(%r3) + evldd %r14,24+5*8(%r3) + evldd %r15,24+6*8(%r3) + evldd %r16,24+7*8(%r3) + evldd %r17,24+8*8(%r3) + evldd %r18,24+9*8(%r3) + evldd %r19,24+10*8(%r3) + evldd %r20,24+11*8(%r3) + evldd %r21,24+12*8(%r3) + evldd %r22,24+13*8(%r3) + evldd %r23,24+14*8(%r3) + evldd %r24,24+15*8(%r3) + evldd %r25,24+16*8(%r3) + evldd %r26,24+17*8(%r3) + evldd %r27,24+18*8(%r3) + evldd %r28,24+19*8(%r3) + evldd %r29,24+20*8(%r3) + evldd %r30,24+21*8(%r3) + evldd %r31,24+22*8(%r3) + + mtlr %r11 + mtcr %r12 + or. %r3,%r4,%r4 + bnelr + li %r3,1 + blr +END(_longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/eabi.S b/lib/libc/powerpcspe/gen/eabi.S new file mode 100644 index 000000000000..3296af88a4d1 --- /dev/null +++ b/lib/libc/powerpcspe/gen/eabi.S @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Marcel Moolenaar + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +ENTRY(__eabi) + blr +END(__eabi) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/fabs.S b/lib/libc/powerpcspe/gen/fabs.S new file mode 100644 index 000000000000..da806f025394 --- /dev/null +++ b/lib/libc/powerpcspe/gen/fabs.S @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Justin Hibbits + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * double fabs(double) + */ +ENTRY(fabs) + efdabs %f1,%f1 + blr +END(fabs) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/flt_rounds.c b/lib/libc/powerpcspe/gen/flt_rounds.c new file mode 100644 index 000000000000..1334021fb7fa --- /dev/null +++ b/lib/libc/powerpcspe/gen/flt_rounds.c @@ -0,0 +1,57 @@ +/* $NetBSD: flt_rounds.c,v 1.4.10.3 2002/03/22 20:41:53 nathanw Exp $ */ + +/* + * Copyright (c) 2016 Justin Hibbits + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Mark Brinicombe + * for the NetBSD Project. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#ifndef _SOFT_FLOAT +static const int map[] = { + 1, /* round to nearest */ + 0, /* round to zero */ + 2, /* round to positive infinity */ + 3 /* round to negative infinity */ +}; + +int +__flt_rounds() +{ + uint32_t fpscr; + + __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); + return map[(fpscr & 0x03)]; +} +#endif diff --git a/lib/libc/powerpcspe/gen/fpgetmask.c b/lib/libc/powerpcspe/gen/fpgetmask.c new file mode 100644 index 000000000000..3103e05ba41d --- /dev/null +++ b/lib/libc/powerpcspe/gen/fpgetmask.c @@ -0,0 +1,49 @@ +/* $NetBSD: fpgetmask.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ + +/* + * Copyright (c) 2016 Justin Hibbits + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#ifndef _SOFT_FLOAT +fp_except_t +fpgetmask() +{ + uint32_t fpscr; + + __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); + return ((fp_except_t)((fpscr >> 3) & 0x1f)); +} +#endif diff --git a/lib/libc/powerpcspe/gen/fpgetround.c b/lib/libc/powerpcspe/gen/fpgetround.c new file mode 100644 index 000000000000..7815559f7b5a --- /dev/null +++ b/lib/libc/powerpcspe/gen/fpgetround.c @@ -0,0 +1,49 @@ +/* $NetBSD: fpgetround.c,v 1.3 2002/01/13 21:45:47 thorpej Exp $ */ + +/* + * Copyright (c) 2016 Justin Hibbits + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#ifndef _SOFT_FLOAT +fp_rnd_t +fpgetround() +{ + uint32_t fpscr; + + __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); + return ((fp_rnd_t)(fpscr & 0x3)); +} +#endif diff --git a/lib/libc/powerpcspe/gen/fpgetsticky.c b/lib/libc/powerpcspe/gen/fpgetsticky.c new file mode 100644 index 000000000000..87962637bc3c --- /dev/null +++ b/lib/libc/powerpcspe/gen/fpgetsticky.c @@ -0,0 +1,55 @@ +/* $NetBSD: fpgetsticky.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 2016 Justin Hibbits + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 + +#include "namespace.h" + +#include +#include +#include + +#ifndef _SOFT_FLOAT +#ifdef __weak_alias +__weak_alias(fpgetsticky,_fpgetsticky) +#endif + +fp_except_t +fpgetsticky() +{ + uint32_t fpscr; + + __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); + return ((fp_except_t)((fpscr >> 25) & 0x1f)); +} +#endif diff --git a/lib/libc/powerpcspe/gen/fpsetmask.c b/lib/libc/powerpcspe/gen/fpsetmask.c new file mode 100644 index 000000000000..24c0b3828b7f --- /dev/null +++ b/lib/libc/powerpcspe/gen/fpsetmask.c @@ -0,0 +1,53 @@ +/* $NetBSD: fpsetmask.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 2016 Justin Hibbits + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#ifndef _SOFT_FLOAT +fp_except_t +fpsetmask(fp_except_t mask) +{ + uint32_t fpscr; + fp_rnd_t old; + + __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR)); + old = (fp_rnd_t)((fpscr >> 3) & 0x1f); + fpscr = (fpscr & 0xffffff07) | (mask << 3); + __asm__ __volatile("mtspr %1,%0" :: "r"(fpscr), "K"(SPR_SPEFSCR)); + return (old); +} +#endif diff --git a/lib/libc/powerpcspe/gen/fpsetround.c b/lib/libc/powerpcspe/gen/fpsetround.c new file mode 100644 index 000000000000..b5340a6d9ea2 --- /dev/null +++ b/lib/libc/powerpcspe/gen/fpsetround.c @@ -0,0 +1,53 @@ +/* $NetBSD: fpsetround.c,v 1.3 2002/01/13 21:45:48 thorpej Exp $ */ + +/* + * Copyright (c) 2016 Justin Hibbits + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dan Winship. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#ifndef _SOFT_FLOAT +fp_rnd_t +fpsetround(fp_rnd_t rnd_dir) +{ + uint32_t fpscr; + fp_rnd_t old; + + __asm__ __volatile("mfspr %0, %1" : "=r"(fpscr) : "K"(SPR_SPEFSCR) ); + old = (fp_rnd_t)(fpscr & 0x3); + fpscr = (fpscr & 0xfffffffc) | rnd_dir; + __asm__ __volatile("mtspr %1, %0" :: "r"(fpscr), "K"(SPR_SPEFSCR)); + return (old); +} +#endif diff --git a/lib/libc/powerpcspe/gen/infinity.c b/lib/libc/powerpcspe/gen/infinity.c new file mode 100644 index 000000000000..cf1695e68028 --- /dev/null +++ b/lib/libc/powerpcspe/gen/infinity.c @@ -0,0 +1,17 @@ +#include +#if 0 +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: infinity.c,v 1.2 1998/11/14 19:31:02 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ +#endif +__FBSDID("$FreeBSD$"); + +/* infinity.c */ + +#include + +/* bytes for +Infinity on powerpc */ +const union __infinity_un __infinity = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; + +/* bytes for NaN */ +const union __nan_un __nan = { { 0xff, 0xc0, 0, 0 } }; diff --git a/lib/libc/powerpcspe/gen/makecontext.c b/lib/libc/powerpcspe/gen/makecontext.c new file mode 100644 index 000000000000..d66e82457a4e --- /dev/null +++ b/lib/libc/powerpcspe/gen/makecontext.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2004 Suleiman Souhlal + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +#include +#include +#include +#include +#include + +__weak_reference(__makecontext, makecontext); + +void _ctx_done(ucontext_t *ucp); +void _ctx_start(void); + +void +_ctx_done(ucontext_t *ucp) +{ + if (ucp->uc_link == NULL) + exit(0); + else { + /* invalidate context */ + ucp->uc_mcontext.mc_len = 0; + + setcontext((const ucontext_t *)ucp->uc_link); + + abort(); /* should never return from above call */ + } +} + +void +__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) +{ + mcontext_t *mc; + char *sp; + va_list ap; + int i, regargs, stackargs; + + /* Sanity checks */ + if ((ucp == NULL) || (argc < 0) || (argc > NCARGS) + || (ucp->uc_stack.ss_sp == NULL) + || (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { + /* invalidate context */ + ucp->uc_mcontext.mc_len = 0; + return; + } + + /* + * The stack must have space for the frame pointer, saved + * link register, overflow arguments, and be 16-byte + * aligned. + */ + stackargs = (argc > 8) ? argc - 8 : 0; + sp = (char *) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size + - sizeof(uint32_t)*(stackargs + 2); + sp = (char *)((uint32_t)sp & ~0x1f); + + mc = &ucp->uc_mcontext; + + /* + * Up to 8 register args. Assumes all args are 32-bit and + * integer only. Not sure how to cater for floating point, + * although 64-bit args will work if aligned correctly + * in the arg list. + */ + regargs = (argc > 8) ? 8 : argc; + va_start(ap, argc); + for (i = 0; i < regargs; i++) + mc->mc_gpr[3 + i] = va_arg(ap, uint32_t); + + /* + * Overflow args go onto the stack + */ + if (argc > 8) { + uint32_t *argp; + + /* Skip past frame pointer and saved LR */ + argp = (uint32_t *)sp + 2; + + for (i = 0; i < stackargs; i++) + *argp++ = va_arg(ap, uint32_t); + } + va_end(ap); + + /* + * Use caller-saved regs 14/15 to hold params that _ctx_start + * will use to invoke the user-supplied func + */ + mc->mc_srr0 = (uint32_t) _ctx_start; + mc->mc_gpr[1] = (uint32_t) sp; /* new stack pointer */ + mc->mc_gpr[14] = (uint32_t) start; /* r14 <- start */ + mc->mc_gpr[15] = (uint32_t) ucp; /* r15 <- ucp */ +} diff --git a/lib/libc/powerpcspe/gen/setjmp.S b/lib/libc/powerpcspe/gen/setjmp.S new file mode 100644 index 000000000000..3d70b5b4a419 --- /dev/null +++ b/lib/libc/powerpcspe/gen/setjmp.S @@ -0,0 +1,138 @@ +/*- + * Copyright (c) 2016 Justin Hibbits + * 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. + */ +/* $NetBSD: setjmp.S,v 1.3 1998/10/03 12:30:38 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * setjmp(a) + * by restoring registers from the stack. + * The previous signal state is restored. + * + * jmpbuf layout: + * +------------+ + * | unused | + * +------------+ + * | sig state | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + +ENTRY(setjmp) + mr %r6,%r3 + li %r3,1 /* SIG_BLOCK, but doesn't matter */ + /* since set == NULL */ + li %r4,0 /* set = NULL */ + mr %r5,%r6 /* &oset */ + addi %r5,%r5,4 + li %r0, SYS_sigprocmask /*sigprocmask(SIG_BLOCK, NULL, &oset)*/ + sc /*assume no error XXX */ + mflr %r11 /* r11 <- link reg */ + mfcr %r12 /* r12 <- condition reg */ + mr %r10,%r1 /* r10 <- stackptr */ + mr %r9,%r2 /* r9 <- global ptr */ + evstdd %r9,24+0*8(%r6) + evstdd %r10,24+1*8(%r6) + evstdd %r11,24+2*8(%r6) + evstdd %r12,24+3*8(%r6) + evstdd %r13,24+4*8(%r6) + evstdd %r14,24+5*8(%r6) + evstdd %r15,24+6*8(%r6) + evstdd %r16,24+7*8(%r6) + evstdd %r17,24+8*8(%r6) + evstdd %r18,24+9*8(%r6) + evstdd %r19,24+10*8(%r6) + evstdd %r20,24+11*8(%r6) + evstdd %r21,24+12*8(%r6) + evstdd %r22,24+13*8(%r6) + evstdd %r23,24+14*8(%r6) + evstdd %r24,24+15*8(%r6) + evstdd %r25,24+16*8(%r6) + evstdd %r26,24+17*8(%r6) + evstdd %r27,24+18*8(%r6) + evstdd %r28,24+19*8(%r6) + evstdd %r29,24+20*8(%r6) + evstdd %r30,24+21*8(%r6) + evstdd %r31,24+22*8(%r6) + + li %r3,0 /* return (0) */ + blr +END(setjmp) + + WEAK_REFERENCE(CNAME(__longjmp), longjmp) +ENTRY(__longjmp) + evldd %r9,24+0*8(%r6) + evldd %r10,24+1*8(%r6) + evldd %r11,24+2*8(%r6) + evldd %r12,24+3*8(%r6) + evldd %r13,24+4*8(%r6) + evldd %r14,24+5*8(%r6) + evldd %r15,24+6*8(%r6) + evldd %r16,24+7*8(%r6) + evldd %r17,24+8*8(%r6) + evldd %r18,24+9*8(%r6) + evldd %r19,24+10*8(%r6) + evldd %r20,24+11*8(%r6) + evldd %r21,24+12*8(%r6) + evldd %r22,24+13*8(%r6) + evldd %r23,24+14*8(%r6) + evldd %r24,24+15*8(%r6) + evldd %r25,24+16*8(%r6) + evldd %r26,24+17*8(%r6) + evldd %r27,24+18*8(%r6) + evldd %r28,24+19*8(%r6) + evldd %r29,24+20*8(%r6) + evldd %r30,24+21*8(%r6) + evldd %r31,24+22*8(%r6) + + mr %r6,%r4 /* save val param */ + mtlr %r11 /* r11 -> link reg */ + mtcr %r12 /* r12 -> condition reg */ + mr %r1,%r10 /* r10 -> stackptr */ + mr %r4,%r3 + li %r3,3 /* SIG_SETMASK */ + addi %r4,%r4,4 /* &set */ + li %r5,0 /* oset = NULL */ + li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ + sc /* assume no error XXX */ + or. %r3,%r6,%r6 + bnelr + li %r3,1 + blr +END(__longjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/signalcontext.c b/lib/libc/powerpcspe/gen/signalcontext.c new file mode 100644 index 000000000000..30e2be848b2b --- /dev/null +++ b/lib/libc/powerpcspe/gen/signalcontext.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2004 Marcel Moolenaar, Peter Grehan + * 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 ``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 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +typedef void (*handler_t)(uint32_t, uint32_t, uint32_t); + +/* Prototypes */ +static void ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, + uint32_t sig_si, uint32_t sig_uc); + +__weak_reference(__signalcontext, signalcontext); + +int +__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) +{ + siginfo_t *sig_si; + ucontext_t *sig_uc; + uint32_t sp; + + /* Bail out if we don't have a valid ucontext pointer. */ + if (ucp == NULL) + abort(); + + /* + * Build a 16-byte-aligned signal frame + */ + sp = (ucp->uc_mcontext.mc_gpr[1] - sizeof(ucontext_t)) & ~15UL; + sig_uc = (ucontext_t *)sp; + bcopy(ucp, sig_uc, sizeof(*sig_uc)); + sp = (sp - sizeof(siginfo_t)) & ~15UL; + sig_si = (siginfo_t *)sp; + bzero(sig_si, sizeof(*sig_si)); + sig_si->si_signo = sig; + + /* + * Subtract 8 bytes from stack to allow for frameptr + */ + sp -= 2*sizeof(uint32_t); + sp &= ~15UL; + + /* + * Setup the ucontext of the signal handler. + */ + bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); + ucp->uc_link = sig_uc; + sigdelset(&ucp->uc_sigmask, sig); + + ucp->uc_mcontext.mc_vers = _MC_VERSION; + ucp->uc_mcontext.mc_len = sizeof(struct __mcontext); + ucp->uc_mcontext.mc_srr0 = (uint32_t) ctx_wrapper; + ucp->uc_mcontext.mc_gpr[1] = (uint32_t) sp; + ucp->uc_mcontext.mc_gpr[3] = (uint32_t) func; + ucp->uc_mcontext.mc_gpr[4] = (uint32_t) sig; + ucp->uc_mcontext.mc_gpr[5] = (uint32_t) sig_si; + ucp->uc_mcontext.mc_gpr[6] = (uint32_t) sig_uc; + + return (0); +} + +static void +ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, uint32_t sig_si, + uint32_t sig_uc) +{ + + (*func)(sig, sig_si, sig_uc); + if (ucp->uc_link == NULL) + exit(0); + setcontext((const ucontext_t *)ucp->uc_link); + /* should never get here */ + abort(); + /* NOTREACHED */ +} diff --git a/lib/libc/powerpcspe/gen/sigsetjmp.S b/lib/libc/powerpcspe/gen/sigsetjmp.S new file mode 100644 index 000000000000..31737e0d8558 --- /dev/null +++ b/lib/libc/powerpcspe/gen/sigsetjmp.S @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 2016 Justin Hibbits + * 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. + */ +/* $NetBSD: sigsetjmp.S,v 1.4 1998/10/03 12:30:38 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * C library -- sigsetjmp, siglongjmp + * + * siglongjmp(a,v) + * will generate a "return(v?v:1)" from the last call to + * sigsetjmp(a, savemask) + * by restoring registers from the stack. + * The previous signal state is restored if savemask is non-zero + * + * jmpbuf layout: + * +------------+ + * | savemask | + * +------------+ + * | sig state | + * | | + * | (4 words) | + * | | + * +------------+ + * | saved regs | + * | ... | + */ + + +#include + +ENTRY(sigsetjmp) + mr %r6,%r3 + stw %r4,0(%r3) + or. %r7,%r4,%r4 + beq 1f + li %r3,1 /* SIG_BLOCK, but doesn't matter */ + /* since set == NULL */ + li %r4,0 /* set = NULL */ + mr %r5,%r6 /* &oset */ + addi %r5,%r5,4 + li %r0, SYS_sigprocmask /* sigprocmask(SIG_BLOCK, NULL, &oset)*/ + sc /* assume no error XXX */ +1: + mflr %r11 + mfcr %r12 + mr %r10,%r1 + mr %r9,%r2 + + /* FPRs */ + evstdd %r9,24+0*8(%r6) + evstdd %r10,24+1*8(%r6) + evstdd %r11,24+2*8(%r6) + evstdd %r12,24+3*8(%r6) + evstdd %r13,24+4*8(%r6) + evstdd %r14,24+5*8(%r6) + evstdd %r15,24+6*8(%r6) + evstdd %r16,24+7*8(%r6) + evstdd %r17,24+8*8(%r6) + evstdd %r18,24+9*8(%r6) + evstdd %r19,24+10*8(%r6) + evstdd %r20,24+11*8(%r6) + evstdd %r21,24+12*8(%r6) + evstdd %r22,24+13*8(%r6) + evstdd %r23,24+14*8(%r6) + evstdd %r24,24+15*8(%r6) + evstdd %r25,24+16*8(%r6) + evstdd %r26,24+17*8(%r6) + evstdd %r27,24+18*8(%r6) + evstdd %r28,24+19*8(%r6) + evstdd %r29,24+20*8(%r6) + evstdd %r30,24+21*8(%r6) + evstdd %r31,24+22*8(%r6) + + li %r3,0 + blr +END(sigsetjmp) + +ENTRY(siglongjmp) + + /* FPRs */ + evldd %r9,24+0*8(%r6) + evldd %r10,24+1*8(%r6) + evldd %r11,24+2*8(%r6) + evldd %r12,24+3*8(%r6) + evldd %r13,24+4*8(%r6) + evldd %r14,24+5*8(%r6) + evldd %r15,24+6*8(%r6) + evldd %r16,24+7*8(%r6) + evldd %r17,24+8*8(%r6) + evldd %r18,24+9*8(%r6) + evldd %r19,24+10*8(%r6) + evldd %r20,24+11*8(%r6) + evldd %r21,24+12*8(%r6) + evldd %r22,24+13*8(%r6) + evldd %r23,24+14*8(%r6) + evldd %r24,24+15*8(%r6) + evldd %r25,24+16*8(%r6) + evldd %r26,24+17*8(%r6) + evldd %r27,24+18*8(%r6) + evldd %r28,24+19*8(%r6) + evldd %r29,24+20*8(%r6) + evldd %r30,24+21*8(%r6) + evldd %r31,24+22*8(%r6) + + lwz %r7,0(%r3) + mr %r6,%r4 + mtlr %r11 + mtcr %r12 + mr %r1,%r10 + or. %r7,%r7,%r7 + beq 1f + mr %r4,%r3 + li %r3,3 /* SIG_SETMASK */ + addi %r4,%r4,4 /* &set */ + li %r5,0 /* oset = NULL */ + li %r0,SYS_sigprocmask /* sigprocmask(SIG_SET, &set, NULL) */ + sc /* assume no error XXX */ +1: + or. %r3,%r6,%r6 + bnelr + li %r3,1 + blr +END(siglongjmp) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/syncicache.c b/lib/libc/powerpcspe/gen/syncicache.c new file mode 100644 index 000000000000..aa025cca8bc6 --- /dev/null +++ b/lib/libc/powerpcspe/gen/syncicache.c @@ -0,0 +1,103 @@ +/*- + * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank. + * Copyright (C) 1995-1997, 1999 TooLs GmbH. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + * + * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $ + */ + +#ifndef lint +static const char rcsid[] = + "$FreeBSD$"; +#endif /* not lint */ + +#include +#if defined(_KERNEL) || defined(_STANDALONE) +#include +#include +#include +#endif +#include + +#include +#include + +#ifdef _STANDALONE +int cacheline_size = 32; +#endif + +#if !defined(_KERNEL) && !defined(_STANDALONE) +#include + +int cacheline_size = 0; + +static void getcachelinesize(void); + +static void +getcachelinesize() +{ + static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE }; + int clen; + + clen = sizeof(cacheline_size); + + if (sysctl(cachemib, nitems(cachemib), &cacheline_size, &clen, + NULL, 0) < 0 || !cacheline_size) { + abort(); + } +} +#endif + +void +__syncicache(void *from, int len) +{ + int l, off; + char *p; + +#if !defined(_KERNEL) && !defined(_STANDALONE) + if (!cacheline_size) + getcachelinesize(); +#endif + + off = (u_int)from & (cacheline_size - 1); + l = len += off; + p = (char *)from - off; + + do { + __asm __volatile ("dcbst 0,%0" :: "r"(p)); + p += cacheline_size; + } while ((l -= cacheline_size) > 0); + __asm __volatile ("sync"); + p = (char *)from - off; + do { + __asm __volatile ("icbi 0,%0" :: "r"(p)); + p += cacheline_size; + } while ((len -= cacheline_size) > 0); + __asm __volatile ("sync; isync"); +} + diff --git a/lib/libc/powerpcspe/softfloat/milieu.h b/lib/libc/powerpcspe/softfloat/milieu.h new file mode 100644 index 000000000000..e2e43b150073 --- /dev/null +++ b/lib/libc/powerpcspe/softfloat/milieu.h @@ -0,0 +1,49 @@ +/* $NetBSD: milieu.h,v 1.1 2000/12/29 20:13:54 bjh21 Exp $ */ +/* $FreeBSD$ */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +Include common integer types and flags. +------------------------------------------------------------------------------- +*/ +#include "powerpc-gcc.h" + +/* +------------------------------------------------------------------------------- +Symbolic Boolean literals. +------------------------------------------------------------------------------- +*/ +enum { + FALSE = 0, + TRUE = 1 +}; diff --git a/lib/libc/powerpcspe/softfloat/powerpc-gcc.h b/lib/libc/powerpcspe/softfloat/powerpc-gcc.h new file mode 100644 index 000000000000..e2f8680dd74e --- /dev/null +++ b/lib/libc/powerpcspe/softfloat/powerpc-gcc.h @@ -0,0 +1,92 @@ +/* $NetBSD: arm-gcc.h,v 1.2 2001/02/21 18:09:25 bjh21 Exp $ */ +/* $FreeBSD$ */ + +/* +------------------------------------------------------------------------------- +One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined. +------------------------------------------------------------------------------- +*/ +#define BIGENDIAN + +/* +------------------------------------------------------------------------------- +The macro `BITS64' can be defined to indicate that 64-bit integer types are +supported by the compiler. +------------------------------------------------------------------------------- +*/ +#define BITS64 + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines the most convenient type that holds +integers of at least as many bits as specified. For example, `uint8' should +be the most convenient type that can hold unsigned integers of as many as +8 bits. The `flag' type must be able to hold either a 0 or 1. For most +implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed +to the same as `int'. +------------------------------------------------------------------------------- +*/ +typedef int flag; +typedef unsigned int uint8; +typedef int int8; +typedef unsigned int uint16; +typedef int int16; +typedef unsigned int uint32; +typedef signed int int32; +#ifdef BITS64 +typedef unsigned long long int uint64; +typedef signed long long int int64; +#endif + +/* +------------------------------------------------------------------------------- +Each of the following `typedef's defines a type that holds integers +of _exactly_ the number of bits specified. For instance, for most +implementation of C, `bits16' and `sbits16' should be `typedef'ed to +`unsigned short int' and `signed short int' (or `short int'), respectively. +------------------------------------------------------------------------------- +*/ +typedef unsigned char bits8; +typedef signed char sbits8; +typedef unsigned short int bits16; +typedef signed short int sbits16; +typedef unsigned int bits32; +typedef signed int sbits32; +#ifdef BITS64 +typedef unsigned long long int bits64; +typedef signed long long int sbits64; +#endif + +#ifdef BITS64 +/* +------------------------------------------------------------------------------- +The `LIT64' macro takes as its argument a textual integer literal and +if necessary ``marks'' the literal as having a 64-bit integer type. +For example, the GNU C Compiler (`gcc') requires that 64-bit literals be +appended with the letters `LL' standing for `long long', which is `gcc's +name for the 64-bit integer type. Some compilers may allow `LIT64' to be +defined as the identity macro: `#define LIT64( a ) a'. +------------------------------------------------------------------------------- +*/ +#define LIT64( a ) a##LL +#endif + +/* +------------------------------------------------------------------------------- +The macro `INLINE' can be used before functions that should be inlined. If +a compiler does not support explicit inlining, this macro should be defined +to be `static'. +------------------------------------------------------------------------------- +*/ +#define INLINE static __inline + +/* +------------------------------------------------------------------------------- +The ARM FPA is odd in that it stores doubles high-order word first, no matter +what the endianness of the CPU. VFP is sane. +------------------------------------------------------------------------------- +*/ +#if defined(SOFTFLOAT_FOR_GCC) +#define FLOAT64_DEMANGLE(a) (a) +#define FLOAT64_MANGLE(a) (a) +#endif diff --git a/lib/libc/powerpcspe/softfloat/softfloat.h b/lib/libc/powerpcspe/softfloat/softfloat.h new file mode 100644 index 000000000000..6b9c9b06956d --- /dev/null +++ b/lib/libc/powerpcspe/softfloat/softfloat.h @@ -0,0 +1,307 @@ +/* $NetBSD: softfloat.h,v 1.6 2002/05/12 13:12:46 bjh21 Exp $ */ +/* $FreeBSD$ */ + +/* This is a derivative work. */ + +/* +=============================================================================== + +This C header file is part of the SoftFloat IEC/IEEE Floating-point +Arithmetic Package, Release 2a. + +Written by John R. Hauser. This work was made possible in part by the +International Computer Science Institute, located at Suite 600, 1947 Center +Street, Berkeley, California 94704. Funding was partially provided by the +National Science Foundation under grant MIP-9311980. The original version +of this code was written as part of a project to build a fixed-point vector +processor in collaboration with the University of California at Berkeley, +overseen by Profs. Nelson Morgan and John Wawrzynek. More information +is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ +arithmetic/SoftFloat.html'. + +THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort +has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT +TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO +PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY +AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. + +Derivative works are acceptable, even for commercial purposes, so long as +(1) they include prominent notice that the work is derivative, and (2) they +include prominent notice akin to these four paragraphs for those parts of +this code that are retained. + +=============================================================================== +*/ + +/* +------------------------------------------------------------------------------- +The macro `FLOATX80' must be defined to enable the extended double-precision +floating-point format `floatx80'. If this macro is not defined, the +`floatx80' type will not be defined, and none of the functions that either +input or output the `floatx80' type will be defined. The same applies to +the `FLOAT128' macro and the quadruple-precision format `float128'. +------------------------------------------------------------------------------- +*/ +/* #define FLOATX80 */ +/* #define FLOAT128 */ + +#include + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point types. +------------------------------------------------------------------------------- +*/ +typedef unsigned int float32; +typedef unsigned long long float64; +#ifdef FLOATX80 +typedef struct { + unsigned short high; + unsigned long long low; +} floatx80; +#endif +#ifdef FLOAT128 +typedef struct { + unsigned long long high, low; +} float128; +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point underflow tininess-detection mode. +------------------------------------------------------------------------------- +*/ +#ifndef SOFTFLOAT_FOR_GCC +extern int8 float_detect_tininess; +#endif +enum { + float_tininess_after_rounding = 0, + float_tininess_before_rounding = 1 +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point rounding mode. +------------------------------------------------------------------------------- +*/ +extern fp_rnd_t float_rounding_mode; +enum { + float_round_nearest_even = FP_RN, + float_round_to_zero = FP_RZ, + float_round_down = FP_RM, + float_round_up = FP_RP +}; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE floating-point exception flags. +------------------------------------------------------------------------------- +*/ +typedef fp_except_t fp_except; + +extern fp_except float_exception_flags; +extern fp_except float_exception_mask; +enum { + float_flag_inexact = FP_X_IMP, + float_flag_underflow = FP_X_UFL, + float_flag_overflow = FP_X_OFL, + float_flag_divbyzero = FP_X_DZ, + float_flag_invalid = FP_X_INV +}; + +/* +------------------------------------------------------------------------------- +Routine to raise any or all of the software IEC/IEEE floating-point +exception flags. +------------------------------------------------------------------------------- +*/ +void float_raise( fp_except ); + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE integer-to-floating-point conversion routines. +------------------------------------------------------------------------------- +*/ +float32 int32_to_float32( int ); +float64 int32_to_float64( int ); +#ifdef FLOATX80 +floatx80 int32_to_floatx80( int ); +#endif +#ifdef FLOAT128 +float128 int32_to_float128( int ); +#endif +float32 int64_to_float32( long long ); +float64 int64_to_float64( long long ); +#ifdef FLOATX80 +floatx80 int64_to_floatx80( long long ); +#endif +#ifdef FLOAT128 +float128 int64_to_float128( long long ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float32_to_int32( float32 ); +int float32_to_int32_round_to_zero( float32 ); +unsigned int float32_to_uint32_round_to_zero( float32 ); +long long float32_to_int64( float32 ); +long long float32_to_int64_round_to_zero( float32 ); +float64 float32_to_float64( float32 ); +#ifdef FLOATX80 +floatx80 float32_to_floatx80( float32 ); +#endif +#ifdef FLOAT128 +float128 float32_to_float128( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE single-precision operations. +------------------------------------------------------------------------------- +*/ +float32 float32_round_to_int( float32 ); +float32 float32_add( float32, float32 ); +float32 float32_sub( float32, float32 ); +float32 float32_mul( float32, float32 ); +float32 float32_div( float32, float32 ); +float32 float32_rem( float32, float32 ); +float32 float32_sqrt( float32 ); +int float32_eq( float32, float32 ); +int float32_le( float32, float32 ); +int float32_lt( float32, float32 ); +int float32_eq_signaling( float32, float32 ); +int float32_le_quiet( float32, float32 ); +int float32_lt_quiet( float32, float32 ); +#ifndef SOFTFLOAT_FOR_GCC +int float32_is_signaling_nan( float32 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float64_to_int32( float64 ); +int float64_to_int32_round_to_zero( float64 ); +unsigned int float64_to_uint32_round_to_zero( float64 ); +long long float64_to_int64( float64 ); +long long float64_to_int64_round_to_zero( float64 ); +float32 float64_to_float32( float64 ); +#ifdef FLOATX80 +floatx80 float64_to_floatx80( float64 ); +#endif +#ifdef FLOAT128 +float128 float64_to_float128( float64 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE double-precision operations. +------------------------------------------------------------------------------- +*/ +float64 float64_round_to_int( float64 ); +float64 float64_add( float64, float64 ); +float64 float64_sub( float64, float64 ); +float64 float64_mul( float64, float64 ); +float64 float64_div( float64, float64 ); +float64 float64_rem( float64, float64 ); +float64 float64_sqrt( float64 ); +int float64_eq( float64, float64 ); +int float64_le( float64, float64 ); +int float64_lt( float64, float64 ); +int float64_eq_signaling( float64, float64 ); +int float64_le_quiet( float64, float64 ); +int float64_lt_quiet( float64, float64 ); +#ifndef SOFTFLOAT_FOR_GCC +int float64_is_signaling_nan( float64 ); +#endif + +#ifdef FLOATX80 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int floatx80_to_int32( floatx80 ); +int floatx80_to_int32_round_to_zero( floatx80 ); +long long floatx80_to_int64( floatx80 ); +long long floatx80_to_int64_round_to_zero( floatx80 ); +float32 floatx80_to_float32( floatx80 ); +float64 floatx80_to_float64( floatx80 ); +#ifdef FLOAT128 +float128 floatx80_to_float128( floatx80 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision rounding precision. Valid +values are 32, 64, and 80. +------------------------------------------------------------------------------- +*/ +extern int floatx80_rounding_precision; + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE extended double-precision operations. +------------------------------------------------------------------------------- +*/ +floatx80 floatx80_round_to_int( floatx80 ); +floatx80 floatx80_add( floatx80, floatx80 ); +floatx80 floatx80_sub( floatx80, floatx80 ); +floatx80 floatx80_mul( floatx80, floatx80 ); +floatx80 floatx80_div( floatx80, floatx80 ); +floatx80 floatx80_rem( floatx80, floatx80 ); +floatx80 floatx80_sqrt( floatx80 ); +int floatx80_eq( floatx80, floatx80 ); +int floatx80_le( floatx80, floatx80 ); +int floatx80_lt( floatx80, floatx80 ); +int floatx80_eq_signaling( floatx80, floatx80 ); +int floatx80_le_quiet( floatx80, floatx80 ); +int floatx80_lt_quiet( floatx80, floatx80 ); +int floatx80_is_signaling_nan( floatx80 ); + +#endif + +#ifdef FLOAT128 + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision conversion routines. +------------------------------------------------------------------------------- +*/ +int float128_to_int32( float128 ); +int float128_to_int32_round_to_zero( float128 ); +long long float128_to_int64( float128 ); +long long float128_to_int64_round_to_zero( float128 ); +float32 float128_to_float32( float128 ); +float64 float128_to_float64( float128 ); +#ifdef FLOATX80 +floatx80 float128_to_floatx80( float128 ); +#endif + +/* +------------------------------------------------------------------------------- +Software IEC/IEEE quadruple-precision operations. +------------------------------------------------------------------------------- +*/ +float128 float128_round_to_int( float128 ); +float128 float128_add( float128, float128 ); +float128 float128_sub( float128, float128 ); +float128 float128_mul( float128, float128 ); +float128 float128_div( float128, float128 ); +float128 float128_rem( float128, float128 ); +float128 float128_sqrt( float128 ); +int float128_eq( float128, float128 ); +int float128_le( float128, float128 ); +int float128_lt( float128, float128 ); +int float128_eq_signaling( float128, float128 ); +int float128_le_quiet( float128, float128 ); +int float128_lt_quiet( float128, float128 ); +int float128_is_signaling_nan( float128 ); + +#endif + diff --git a/lib/libc/powerpcspe/sys/Makefile.inc b/lib/libc/powerpcspe/sys/Makefile.inc new file mode 100644 index 000000000000..4948f6754c9f --- /dev/null +++ b/lib/libc/powerpcspe/sys/Makefile.inc @@ -0,0 +1,8 @@ +# $FreeBSD$ + +MDASM+= brk.S cerror.S exect.S ptrace.S sbrk.S setlogin.S + +# Don't generate default code for these syscalls: +NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o + +PSEUDO= _getlogin.o _exit.o diff --git a/lib/libc/powerpcspe/sys/brk.S b/lib/libc/powerpcspe/sys/brk.S new file mode 100644 index 000000000000..e14be1058b51 --- /dev/null +++ b/lib/libc/powerpcspe/sys/brk.S @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + */ +/* $NetBSD: brk.S,v 1.9 2000/06/26 06:25:43 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl HIDENAME(minbrk) + .globl CNAME(_end) + + .data +HIDENAME(minbrk): + .long CNAME(_end) + + .text + +ENTRY(brk) +#ifdef PIC + mflr %r10 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r9 + mtlr %r10 + lwz %r5,HIDENAME(minbrk)@got(%r9) + lwz %r6,0(%r5) +#else + lis %r5,HIDENAME(minbrk)@ha + lwz %r6,HIDENAME(minbrk)@l(%r5) +#endif + cmplw %r6,%r3 /* if (minbrk <= r3) */ + bgt 0f + mr %r6,%r3 /* r6 = r3 */ +0: + mr %r3,%r6 /* new break value */ + li %r0,SYS_break + sc /* assume, that r5 is kept */ + bso 1f +#ifdef PIC + lwz %r7,HIDENAME(curbrk)@got(%r9) + stw %r6,0(%r7) +#else + lis %r7,HIDENAME(curbrk)@ha /* record new break */ + stw %r6,HIDENAME(curbrk)@l(%r7) +#endif + blr /* return 0 */ + +1: + b PIC_PLT(HIDENAME(cerror)) +END(brk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/cerror.S b/lib/libc/powerpcspe/sys/cerror.S new file mode 100644 index 000000000000..3ca04fb4a19d --- /dev/null +++ b/lib/libc/powerpcspe/sys/cerror.S @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + */ +/* $NetBSD: cerror.S,v 1.5 2000/01/27 14:58:48 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + + .globl HIDENAME(cerror) + .hidden HIDENAME(cerror) + .globl CNAME(__error) + + /* + * The __error() function is thread aware. For non-threaded + * programs and the initial threaded in threaded programs, + * it returns a pointer to the global errno variable. + */ +HIDENAME(cerror): + mflr %r0 + stwu %r1,-16(%r1) /* allocate new stack frame */ + stw %r0,20(%r1) /* and save lr, r31 */ + stw %r31,8(%r1) + mr %r31,%r3 /* stash errval in callee-saved register */ + bl PIC_PLT(CNAME(__error)) + stw %r31,0(%r3) /* store errval into &errno */ + lwz %r0,20(%r1) + lwz %r31,8(%r1) + mtlr %r0 + la %r1,16(%r1) + li %r3,-1 + li %r4,-1 + blr /* return to callers caller */ + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/exect.S b/lib/libc/powerpcspe/sys/exect.S new file mode 100644 index 000000000000..701f5b00f45c --- /dev/null +++ b/lib/libc/powerpcspe/sys/exect.S @@ -0,0 +1,42 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + */ +/* $NetBSD: exect.S,v 1.3 1998/05/25 15:28:03 ws Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + +ENTRY(exect) + li %r0,SYS_execve + sc + bso 1f + blr +1: + b PIC_PLT(HIDENAME(cerror)) +END(exect) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/ptrace.S b/lib/libc/powerpcspe/sys/ptrace.S new file mode 100644 index 000000000000..cff463dd009c --- /dev/null +++ b/lib/libc/powerpcspe/sys/ptrace.S @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + */ +/* $NetBSD: ptrace.S,v 1.3 2000/02/23 20:16:57 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + +ENTRY(ptrace) + mflr %r0 + stwu %r1,-32(%r1) + stw %r0,36(%r1) + stw %r3,8(%r1) + stw %r4,12(%r1) + stw %r5,16(%r1) + stw %r6,20(%r1) + + bl PIC_PLT(CNAME(__error)) + li %r7,0 + stw %r7,0(%r3) + + lwz %r3,8(%r1) + lwz %r4,12(%r1) + lwz %r5,16(%r1) + lwz %r0,36(%r1) + lwz %r6,20(%r1) + mtlr %r0 + la %r1,32(%r1) + li %r0,SYS_ptrace + sc + bso 1f + blr +1: + b PIC_PLT(HIDENAME(cerror)) +END(ptrace) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/sbrk.S b/lib/libc/powerpcspe/sys/sbrk.S new file mode 100644 index 000000000000..f058d112e863 --- /dev/null +++ b/lib/libc/powerpcspe/sys/sbrk.S @@ -0,0 +1,73 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + */ +/* $NetBSD: sbrk.S,v 1.8 2000/06/26 06:25:44 kleink Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + + .globl HIDENAME(curbrk) + .globl CNAME(_end) + + .data +HIDENAME(curbrk): + .long CNAME(_end) + + .text +ENTRY(sbrk) + +#ifdef PIC + mflr %r10 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r5 + mtlr %r10 + lwz %r5,HIDENAME(curbrk)@got(%r5) + lwz %r6,0(%r5) +#else + lis %r5,HIDENAME(curbrk)@ha + lwz %r6,HIDENAME(curbrk)@l(%r5) /* r6 = old break */ +#endif + cmpwi %r3,0 /* sbrk(0) - return curbrk */ + beq 1f + add %r3,%r3,%r6 + mr %r7,%r3 /* r7 = new break */ + li %r0,SYS_break + sc /* break(new_break) */ + bso 2f +#ifdef PIC + stw %r7,0(%r5) +#else + stw %r7,HIDENAME(curbrk)@l(%r5) /* record new break */ +#endif +1: + mr %r3,%r6 /* set return value */ + blr +2: + b PIC_PLT(HIDENAME(cerror)) +END(sbrk) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/setlogin.S b/lib/libc/powerpcspe/sys/setlogin.S new file mode 100644 index 000000000000..e0d6d3c012ce --- /dev/null +++ b/lib/libc/powerpcspe/sys/setlogin.S @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2002 Peter Grehan. + * 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. + */ +/* $NetBSD: setlogin.S,v 1.3 1998/11/24 11:14:57 tsubai Exp $ */ + +#include +__FBSDID("$FreeBSD$"); + +#include "SYS.h" + + .globl CNAME(_logname_valid) /* in _getlogin() */ + +SYSCALL(setlogin) +#ifdef PIC + mflr %r10 + bl _GLOBAL_OFFSET_TABLE_@local-4 + mflr %r4 + lwz %r4,CNAME(_logname_valid)@got(%r4) + li %r5,%r0 + stw %r5,0(%r4) + mtlr %r10 +#else + lis %r4,CNAME(_logname_valid)@ha + li %r5,0 + stw %r5,CNAME(_logname_valid)@l(%r4) +#endif + blr + + .section .note.GNU-stack,"",%progbits diff --git a/lib/msun/powerpc/fenv.h b/lib/msun/powerpc/fenv.h index 33de3750a93a..8fbecd7c0806 100644 --- a/lib/msun/powerpc/fenv.h +++ b/lib/msun/powerpc/fenv.h @@ -87,8 +87,13 @@ extern const fenv_t __fe_dfl_env; FE_OVERFLOW | FE_UNDERFLOW) >> _FPUSW_SHIFT) #ifndef _SOFT_FLOAT +#ifdef __SPE__ +#define __mffs(__env) __asm __volatile("mfspr %0, 512" : "=r" (*(__env))) +#define __mtfsf(__env) __asm __volatile("mtspr 512,%0" : : "r" (__env)) +#else #define __mffs(__env) __asm __volatile("mffs %0" : "=f" (*(__env))) #define __mtfsf(__env) __asm __volatile("mtfsf 255,%0" : : "f" (__env)) +#endif #else #define __mffs(__env) #define __mtfsf(__env) diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk index a967f892846b..211b6fc87723 100644 --- a/share/mk/bsd.cpu.mk +++ b/share/mk/bsd.cpu.mk @@ -137,6 +137,8 @@ _CPUCFLAGS = -Wa,-me500 -msoft-float . else _CPUCFLAGS = -mcpu=${CPUTYPE} -mno-powerpc64 . endif +. elif ${MACHINE_ARCH} == "powerpcspe" +_CPUCFLAGS = -Wa,-me500 -mspe=yes -mabi=spe -mfloat-gprs=double . elif ${MACHINE_ARCH} == "powerpc64" _CPUCFLAGS = -mcpu=${CPUTYPE} . elif ${MACHINE_CPUARCH} == "mips" @@ -327,6 +329,10 @@ CFLAGS += -mfloat-abi=softfp .endif .endif +.if ${MACHINE_ARCH} == "powerpcspe" +CFLAGS += -mcpu=8540 -Wa,-me500 -mspe=yes -mabi=spe -mfloat-gprs=double +.endif + .if ${MACHINE_CPUARCH} == "riscv" CFLAGS += -msoft-float ACFLAGS += -msoft-float diff --git a/share/mk/bsd.endian.mk b/share/mk/bsd.endian.mk index c7ec42cb2876..a264b67e0407 100644 --- a/share/mk/bsd.endian.mk +++ b/share/mk/bsd.endian.mk @@ -9,6 +9,7 @@ TARGET_ENDIANNESS= 1234 .elif ${MACHINE_ARCH} == "powerpc" || \ ${MACHINE_ARCH} == "powerpc64" || \ + ${MACHINE_ARCH} == "powerpcspe" || \ ${MACHINE_ARCH} == "sparc64" || \ (${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} != "") || \ ${MACHINE_ARCH:Mmips*} != "" diff --git a/share/mk/local.meta.sys.mk b/share/mk/local.meta.sys.mk index 2ac23d613b1f..49f625ccefa9 100644 --- a/share/mk/local.meta.sys.mk +++ b/share/mk/local.meta.sys.mk @@ -46,7 +46,7 @@ OBJROOT:= ${OBJROOT:H:tA}/${OBJROOT:T} TARGET_ARCHES_arm?= arm armeb armv6 TARGET_ARCHES_arm64?= aarch64 TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipsn32el -TARGET_ARCHES_powerpc?= powerpc powerpc64 +TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe TARGET_ARCHES_pc98?= i386 TARGET_ARCHES_riscv?= riscv64 diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 28387f61bc49..6efa99410d0a 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -13,7 +13,7 @@ unix ?= We run FreeBSD, not UNIX. # and/or endian. This is called MACHINE_CPU in NetBSD, but that's used # for something different in FreeBSD. # -MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc64/powerpc/:C/riscv64/riscv/} +MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64/riscv/} .endif diff --git a/sys/boot/powerpc/Makefile b/sys/boot/powerpc/Makefile index 1f3a528b2f08..e3ac008fb799 100644 --- a/sys/boot/powerpc/Makefile +++ b/sys/boot/powerpc/Makefile @@ -1,5 +1,8 @@ # $FreeBSD$ -SUBDIR= boot1.chrp kboot ofw ps3 uboot +SUBDIR= boot1.chrp kboot ofw uboot +.if ${MACHINE_ARCH} != "powerpcspe" +SUBDIR+= ps3 +.endif .include diff --git a/sys/conf/Makefile.powerpc b/sys/conf/Makefile.powerpc index 769b068ed5f2..e529ef7cc11d 100644 --- a/sys/conf/Makefile.powerpc +++ b/sys/conf/Makefile.powerpc @@ -35,6 +35,10 @@ LDSCRIPT_NAME?= ldscript.${MACHINE_ARCH} INCLUDES+= -I$S/contrib/libfdt +.if "${MACHINE_ARCH}" == "powerpcspe" +# Force __SPE__, since the builtin will be removed later with -mno-spe +CFLAGS+= -mabi=spe -D__SPE__ +.endif CFLAGS+= -msoft-float -Wa,-many # Build position-independent kernel diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index aee0a1022b9c..7ccc3a6ae2fb 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -82,25 +82,25 @@ kern/kern_clocksource.c standard kern/subr_dummy_vdso_tc.c standard kern/syscalls.c optional ktr kern/subr_sfbuf.c standard -libkern/ashldi3.c optional powerpc -libkern/ashrdi3.c optional powerpc +libkern/ashldi3.c optional powerpc | powerpcspe +libkern/ashrdi3.c optional powerpc | powerpcspe libkern/bcmp.c standard -libkern/cmpdi2.c optional powerpc -libkern/divdi3.c optional powerpc +libkern/cmpdi2.c optional powerpc | powerpcspe +libkern/divdi3.c optional powerpc | powerpcspe libkern/ffs.c standard libkern/ffsl.c standard libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard -libkern/lshrdi3.c optional powerpc +libkern/lshrdi3.c optional powerpc | powerpcspe libkern/memmove.c standard libkern/memset.c standard -libkern/moddi3.c optional powerpc -libkern/qdivrem.c optional powerpc -libkern/ucmpdi2.c optional powerpc -libkern/udivdi3.c optional powerpc -libkern/umoddi3.c optional powerpc +libkern/moddi3.c optional powerpc | powerpcspe +libkern/qdivrem.c optional powerpc | powerpcspe +libkern/ucmpdi2.c optional powerpc | powerpcspe +libkern/udivdi3.c optional powerpc | powerpcspe +libkern/umoddi3.c optional powerpc | powerpcspe powerpc/aim/locore.S optional aim no-obj powerpc/aim/aim_machdep.c optional aim powerpc/aim/mmu_oea.c optional aim powerpc @@ -115,6 +115,7 @@ powerpc/booke/machdep_e500.c optional booke_e500 powerpc/booke/mp_cpudep.c optional booke smp powerpc/booke/platform_bare.c optional booke powerpc/booke/pmap.c optional booke +powerpc/booke/spe.c optional powerpcspe powerpc/cpufreq/dfs.c optional cpufreq powerpc/cpufreq/pcr.c optional cpufreq aim powerpc/cpufreq/pmufreq.c optional cpufreq aim pmu @@ -179,7 +180,7 @@ powerpc/powermac/smusat.c optional powermac smu powerpc/powermac/uninorth.c optional powermac powerpc/powermac/uninorthpci.c optional powermac pci powerpc/powermac/vcoregpio.c optional powermac -powerpc/powerpc/altivec.c standard +powerpc/powerpc/altivec.c optional powerpc | powerpc64 powerpc/powerpc/autoconf.c standard powerpc/powerpc/bcopy.c standard powerpc/powerpc/bus_machdep.c standard @@ -193,7 +194,7 @@ powerpc/powerpc/db_hwwatch.c optional ddb powerpc/powerpc/db_interface.c optional ddb powerpc/powerpc/db_trace.c optional ddb powerpc/powerpc/dump_machdep.c standard -powerpc/powerpc/elf32_machdep.c optional powerpc | compat_freebsd32 +powerpc/powerpc/elf32_machdep.c optional powerpc | powerpcspe | compat_freebsd32 powerpc/powerpc/elf64_machdep.c optional powerpc64 powerpc/powerpc/exec_machdep.c standard powerpc/powerpc/fpu.c standard @@ -216,9 +217,9 @@ powerpc/powerpc/platform_if.m standard powerpc/powerpc/ptrace_machdep.c standard powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard -powerpc/powerpc/sigcode32.S optional powerpc | compat_freebsd32 +powerpc/powerpc/sigcode32.S optional powerpc | powerpcspe | compat_freebsd32 powerpc/powerpc/sigcode64.S optional powerpc64 -powerpc/powerpc/swtch32.S optional powerpc +powerpc/powerpc/swtch32.S optional powerpc | powerpcspe powerpc/powerpc/swtch64.S optional powerpc64 powerpc/powerpc/stack_machdep.c optional ddb | stack powerpc/powerpc/suswintr.c standard diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index be296f7849ed..15a6bf557013 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -167,6 +167,10 @@ CFLAGS.gcc+= -msoft-float INLINE_LIMIT?= 15000 .endif +.if ${MACHINE_ARCH} == "powerpcspe" +CFLAGS+= -mno-spe +.endif + # # Use dot symbols on powerpc64 to make ddb happy # @@ -261,6 +265,7 @@ LD_EMULATION_mips64el= elf64ltsmip_fbsd LD_EMULATION_mipsn32= elf32btsmipn32_fbsd LD_EMULATION_mipsn32el= elf32btsmipn32_fbsd # I don't think this is a thing that works LD_EMULATION_powerpc= elf32ppc_fbsd +LD_EMULATION_powerpcspe= elf32ppc_fbsd LD_EMULATION_powerpc64= elf64ppc_fbsd LD_EMULATION_riscv= elf64riscv LD_EMULATION_sparc64= elf64_sparc_fbsd diff --git a/sys/conf/ldscript.powerpcspe b/sys/conf/ldscript.powerpcspe new file mode 100644 index 000000000000..b190dc193b02 --- /dev/null +++ b/sys/conf/ldscript.powerpcspe @@ -0,0 +1,144 @@ +/* $FreeBSD$ */ + +OUTPUT_FORMAT("elf32-powerpc-freebsd", "elf32-powerpc-freebsd", + "elf32-powerpc-freebsd") +OUTPUT_ARCH(powerpc) +ENTRY(__start) +SEARCH_DIR(/usr/lib); +PROVIDE (__stack = 0); +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + + . = kernbase + SIZEOF_HEADERS; + PROVIDE (begin = . - SIZEOF_HEADERS); + + .text : + { + *(.text) + *(.stub) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.gnu.linkonce.t*) + } =0 + _etext = .; + PROVIDE (etext = .); + + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rela.text : + { *(.rela.text) *(.rela.gnu.linkonce.t*) } + .rela.data : + { *(.rela.data) *(.rela.gnu.linkonce.d*) } + .rela.rodata : + { *(.rela.rodata) *(.rela.gnu.linkonce.r*) } + .rela.got : { *(.rela.got) } + .rela.got1 : { *(.rela.got1) } + .rela.got2 : { *(.rela.got2) } + .rela.ctors : { *(.rela.ctors) } + .rela.dtors : { *(.rela.dtors) } + .rela.init : { *(.rela.init) } + .rela.fini : { *(.rela.fini) } + .rela.bss : { *(.rela.bss) } + .rela.plt : { *(.rela.plt) } + .rela.sdata : { *(.rela.sdata) } + .rela.sbss : { *(.rela.sbss) } + .rela.sdata2 : { *(.rela.sdata2) } + .rela.sbss2 : { *(.rela.sbss2) } + + .init : { *(.init) } =0 + .fini : { *(.fini) } =0 + .rodata : { *(.rodata) *(.gnu.linkonce.r*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2) } + .sbss2 : { *(.sbss2) } + /* Adjust the address for the data segment to the next page up. */ + . = ((. + 0x1000) & ~(0x1000 - 1)); + .data : + { + *(.data) + *(.gnu.linkonce.d*) + CONSTRUCTORS + } + .data1 : { *(.data1) } + .got1 : { *(.got1) } + .dynamic : { *(.dynamic) } + /* Put .ctors and .dtors next to the .got2 section, so that the pointers + get relocated with -mrelocatable. Also put in the .fixup pointers. + The current compiler no longer needs this, but keep it around for 2.7.2 */ + PROVIDE (_GOT2_START_ = .); + .got2 : { *(.got2) } + PROVIDE (__CTOR_LIST__ = .); + .ctors : { *(.ctors) } + PROVIDE (__CTOR_END__ = .); + PROVIDE (__DTOR_LIST__ = .); + .dtors : { *(.dtors) } + PROVIDE (__DTOR_END__ = .); + PROVIDE (_FIXUP_START_ = .); + .fixup : { *(.fixup) } + PROVIDE (_FIXUP_END_ = .); + PROVIDE (_GOT2_END_ = .); + PROVIDE (_GOT_START_ = .); + .got : { *(.got) } + .got.plt : { *(.got.plt) } + PROVIDE (_GOT_END_ = .); + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + .sbss : + { + PROVIDE (__sbss_start = .); + *(.sbss) + *(.scommon) + *(.dynsbss) + PROVIDE (__sbss_end = .); + } + .plt : { *(.plt) } + .bss : + { + PROVIDE (__bss_start = .); + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* These must appear regardless of . */ +} + diff --git a/sys/conf/options.powerpc b/sys/conf/options.powerpc index 4926947c7da7..3e82696983dd 100644 --- a/sys/conf/options.powerpc +++ b/sys/conf/options.powerpc @@ -9,6 +9,7 @@ CELL POWERPC POWERPC64 +POWERPCSPE FPU_EMU diff --git a/sys/modules/Makefile b/sys/modules/Makefile index fbaefc3ebe9a..dc8a7cf36961 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -510,7 +510,8 @@ _txp= txp .if ${MK_SOURCELESS_UCODE} != "no" && ${MACHINE_CPUARCH} != "arm" && \ ${MACHINE_CPUARCH} != "mips" && \ - ${MACHINE_ARCH} != "powerpc" && ${MACHINE_CPUARCH} != "riscv" + ${MACHINE_ARCH} != "powerpc" && ${MACHINE_ARCH} != "powerpcspe" && \ + ${MACHINE_CPUARCH} != "riscv" _cxgbe= cxgbe .endif @@ -753,7 +754,6 @@ _cfi= cfi _cpufreq= cpufreq _drm= drm _exca= exca -_nvram= powermac_nvram _pccard= pccard _wi= wi .endif @@ -761,6 +761,10 @@ _wi= wi .if ${MACHINE_ARCH} == "powerpc64" _drm2= drm2 .endif +.if ${MACHINE_ARCH} == "powerpc64" || ${MACHINE_ARCH} == "powerpc" +# Don't build powermac_nvram for powerpcspe, it's never supported. +_nvram= powermac_nvram +.endif .if ${MACHINE_CPUARCH} == "sparc64" _auxio= auxio diff --git a/sys/powerpc/booke/booke_machdep.c b/sys/powerpc/booke/booke_machdep.c index 8d04f7ee1133..cbd7fc403cfb 100644 --- a/sys/powerpc/booke/booke_machdep.c +++ b/sys/powerpc/booke/booke_machdep.c @@ -242,6 +242,11 @@ ivor_setup(void) case FSL_E500mc: case FSL_E5500: SET_TRAP(SPR_IVOR7, int_fpu); + break; + case FSL_E500v1: + case FSL_E500v2: + SET_TRAP(SPR_IVOR32, int_vec); + break; } } diff --git a/sys/powerpc/booke/spe.c b/sys/powerpc/booke/spe.c new file mode 100644 index 000000000000..45eb7798b2c4 --- /dev/null +++ b/sys/powerpc/booke/spe.c @@ -0,0 +1,183 @@ +/*- + * Copyright (C) 1996 Wolfgang Solfrank. + * Copyright (C) 1996 TooLs GmbH. + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by TooLs GmbH. + * 4. The name of TooLs GmbH may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. + * + * $NetBSD: fpu.c,v 1.5 2001/07/22 11:29:46 wiz Exp $ + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include +#include + +static void +save_vec_int(struct thread *td) +{ + int msr; + struct pcb *pcb; + + pcb = td->td_pcb; + + /* + * Temporarily re-enable the vector unit during the save + */ + msr = mfmsr(); + mtmsr(msr | PSL_VEC); + isync(); + + /* + * Save the vector registers and SPEFSCR to the PCB + */ +#define EVSTDW(n) __asm ("evstdw %1,0(%0)" \ + :: "b"(pcb->pcb_vec.vr[n]), "n"(n)); + EVSTDW(0); EVSTDW(1); EVSTDW(2); EVSTDW(3); + EVSTDW(4); EVSTDW(5); EVSTDW(6); EVSTDW(7); + EVSTDW(8); EVSTDW(9); EVSTDW(10); EVSTDW(11); + EVSTDW(12); EVSTDW(13); EVSTDW(14); EVSTDW(15); + EVSTDW(16); EVSTDW(17); EVSTDW(18); EVSTDW(19); + EVSTDW(20); EVSTDW(21); EVSTDW(22); EVSTDW(23); + EVSTDW(24); EVSTDW(25); EVSTDW(26); EVSTDW(27); + EVSTDW(28); EVSTDW(29); EVSTDW(30); EVSTDW(31); +#undef EVSTDW + + __asm ( "evxor 0,0,0\n" + "evaddumiaaw 0,0\n" + "evstdd 0,0(%0)" :: "b"(&pcb->pcb_vec.vr[17][0])); + pcb->pcb_vec.vscr = mfspr(SPR_SPEFSCR); + + /* + * Disable vector unit again + */ + isync(); + mtmsr(msr); + +} + +void +enable_vec(struct thread *td) +{ + int msr; + struct pcb *pcb; + struct trapframe *tf; + + pcb = td->td_pcb; + tf = trapframe(td); + + /* + * Save the thread's SPE CPU number, and set the CPU's current + * vector thread + */ + td->td_pcb->pcb_veccpu = PCPU_GET(cpuid); + PCPU_SET(vecthread, td); + + /* + * Enable the vector unit for when the thread returns from the + * exception. If this is the first time the unit has been used by + * the thread, initialise the vector registers and VSCR to 0, and + * set the flag to indicate that the vector unit is in use. + */ + tf->srr1 |= PSL_VEC; + if (!(pcb->pcb_flags & PCB_VEC)) { + memset(&pcb->pcb_vec, 0, sizeof pcb->pcb_vec); + pcb->pcb_flags |= PCB_VEC; + } + + /* + * Temporarily enable the vector unit so the registers + * can be restored. + */ + msr = mfmsr(); + mtmsr(msr | PSL_VEC); + isync(); + + /* Restore SPEFSCR and ACC. Use %r0 as the scratch for ACC. */ + mtspr(SPR_SPEFSCR, pcb->pcb_vec.vscr); + __asm __volatile("evldd 0, 0(%0); evmra 0,0\n" + :: "b"(&pcb->pcb_vec.vr[17][0])); + + /* + * The lower half of each register will be restored on trap return. Use + * %r0 as a scratch register, and restore it last. + */ +#define EVLDW(n) __asm __volatile("evldw 0, 0(%0); evmergehilo "#n",0,"#n \ + :: "b"(&pcb->pcb_vec.vr[n])); + EVLDW(1); EVLDW(2); EVLDW(3); EVLDW(4); + EVLDW(5); EVLDW(6); EVLDW(7); EVLDW(8); + EVLDW(9); EVLDW(10); EVLDW(11); EVLDW(12); + EVLDW(13); EVLDW(14); EVLDW(15); EVLDW(16); + EVLDW(17); EVLDW(18); EVLDW(19); EVLDW(20); + EVLDW(21); EVLDW(22); EVLDW(23); EVLDW(24); + EVLDW(25); EVLDW(26); EVLDW(27); EVLDW(28); + EVLDW(29); EVLDW(30); EVLDW(31); EVLDW(0); +#undef EVLDW + + isync(); + mtmsr(msr); +} + +void +save_vec(struct thread *td) +{ + struct pcb *pcb; + + pcb = td->td_pcb; + + save_vec_int(td); + + /* + * Clear the current vec thread and pcb's CPU id + * XXX should this be left clear to allow lazy save/restore ? + */ + pcb->pcb_veccpu = INT_MAX; + PCPU_SET(vecthread, NULL); +} + +/* + * Save SPE state without dropping ownership. This will only save state if + * the current vector-thread is `td'. + */ +void +save_vec_nodrop(struct thread *td) +{ + struct thread *vtd; + + vtd = PCPU_GET(vecthread); + if (td != vtd) { + return; + } + + save_vec_int(td); +} diff --git a/sys/powerpc/conf/MPC85XXSPE b/sys/powerpc/conf/MPC85XXSPE new file mode 100644 index 000000000000..781d6899d316 --- /dev/null +++ b/sys/powerpc/conf/MPC85XXSPE @@ -0,0 +1,100 @@ +# +# Custom kernel for Freescale MPC85XX development boards like the CDS etc. +# +# $FreeBSD$ +# + +cpu BOOKE +cpu BOOKE_E500 +ident MPC85XX + +machine powerpc powerpcspe + +include "dpaa/config.dpaa" +makeoptions DEBUG="-Wa,-me500 -g" +makeoptions WERROR="-Werror -Wno-format -Wno-redundant-decls" +makeoptions NO_MODULES=yes + +options FPU_EMU + +options _KPOSIX_PRIORITY_SCHEDULING +options ALT_BREAK_TO_DEBUGGER +options BREAK_TO_DEBUGGER +options BOOTP +options BOOTP_NFSROOT +#options BOOTP_NFSV3 +options CD9660 +options COMPAT_43 +options DDB +#options DEADLKRES +options DEVICE_POLLING +#options DIAGNOSTIC +options FDT +#makeoptions FDT_DTS_FILE=mpc8555cds.dts +options FFS +options GDB +options GEOM_PART_GPT +options INET +options INET6 +options TCP_HHOOK # hhook(9) framework for TCP +options INVARIANTS +options INVARIANT_SUPPORT +options KDB +options KTRACE +options MD_ROOT +options MPC85XX +options MSDOSFS +options NFS_ROOT +options NFSCL +options NFSLOCKD +options PROCFS +options PSEUDOFS +options SCHED_ULE +options CAPABILITIES +options CAPABILITY_MODE +options SMP +options SYSVMSG +options SYSVSEM +options SYSVSHM +options WITNESS +options WITNESS_SKIPSPIN + +device ata +device bpf +device cfi +device crypto +device cryptodev +device da +device ds1553 +device em +device alc +device ether +device fxp +device gpio +device iic +device iicbus +#device isa +device loop +device md +device miibus +device pass +device pci +device quicc +device random +#device rl +device scbus +device scc +device sec +device tsec +device tun +device uart +options USB_DEBUG # enable debug msgs +#device uhci +device ehci +device umass +device usb +device vlan + +# P1022 DIU +device diu +device videomode diff --git a/sys/powerpc/include/param.h b/sys/powerpc/include/param.h index 453915cba4df..a74ccf212a8f 100644 --- a/sys/powerpc/include/param.h +++ b/sys/powerpc/include/param.h @@ -57,9 +57,13 @@ #ifdef __powerpc64__ #define MACHINE_ARCH "powerpc64" #else +#ifdef __SPE__ +#define MACHINE_ARCH "powerpcspe" +#else #define MACHINE_ARCH "powerpc" #endif #endif +#endif #define MID_MACHINE MID_POWERPC #ifdef __powerpc64__ #ifndef MACHINE_ARCH32 diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h index 86dac97bc01c..bfd205fb2002 100644 --- a/sys/powerpc/include/spr.h +++ b/sys/powerpc/include/spr.h @@ -192,6 +192,7 @@ #define FSL_E5500 0x8024 #define FSL_E6500 0x8040 +#define SPR_SPEFSCR 0x200 /* ..8 Signal Processing Engine FSCR. */ #define SPR_IBAT0U 0x210 /* .68 Instruction BAT Reg 0 Upper */ #define SPR_IBAT0U 0x210 /* .6. Instruction BAT Reg 0 Upper */ #define SPR_IBAT0L 0x211 /* .6. Instruction BAT Reg 0 Lower */ diff --git a/sys/powerpc/include/trap.h b/sys/powerpc/include/trap.h index 81c40c9bffaf..34cd98dabab9 100644 --- a/sys/powerpc/include/trap.h +++ b/sys/powerpc/include/trap.h @@ -112,6 +112,7 @@ /* Macros to extract register information */ #define EXC_ALI_RST(dsisr) ((dsisr >> 5) & 0x1f) /* source or target */ #define EXC_ALI_RA(dsisr) (dsisr & 0x1f) +#define EXC_ALI_SPE_REG(instr) ((instr >> 21) & 0x1f) /* * SRR1 bits for program exception traps. These identify what caused diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c index d1860513fe45..b0a86701ac47 100644 --- a/sys/powerpc/powerpc/trap.c +++ b/sys/powerpc/powerpc/trap.c @@ -750,9 +750,47 @@ static int fix_unaligned(struct thread *td, struct trapframe *frame) { struct thread *fputhread; +#ifdef __SPE__ + uint32_t inst; +#endif int indicator, reg; double *fpr; +#ifdef __SPE__ + indicator = (frame->cpu.booke.esr & (ESR_ST|ESR_SPE)); + if (indicator & ESR_SPE) { + if (copyin((void *)frame->srr0, &inst, sizeof(inst)) != 0) + return (-1); + reg = EXC_ALI_SPE_REG(inst); + fpr = (double *)td->td_pcb->pcb_vec.vr[reg]; + fputhread = PCPU_GET(vecthread); + + /* Juggle the FPU to ensure that we've initialized + * the FPRs, and that their current state is in + * the PCB. + */ + if (fputhread != td) { + if (fputhread) + save_vec(fputhread); + enable_vec(td); + } + save_vec(td); + + if (!(indicator & ESR_ST)) { + if (copyin((void *)frame->dar, fpr, + sizeof(double)) != 0) + return (-1); + frame->fixreg[reg] = td->td_pcb->pcb_vec.vr[reg][1]; + enable_vec(td); + } else { + td->td_pcb->pcb_vec.vr[reg][1] = frame->fixreg[reg]; + if (copyout(fpr, (void *)frame->dar, + sizeof(double)) != 0) + return (-1); + } + return (0); + } +#else indicator = EXC_ALI_OPCODE_INDICATOR(frame->cpu.aim.dsisr); switch (indicator) { @@ -786,6 +824,7 @@ fix_unaligned(struct thread *td, struct trapframe *frame) return (0); break; } +#endif return (-1); } diff --git a/usr.sbin/Makefile.powerpc b/usr.sbin/Makefile.powerpc index 131eb571cdc4..4e234ab8dce9 100644 --- a/usr.sbin/Makefile.powerpc +++ b/usr.sbin/Makefile.powerpc @@ -1,4 +1,6 @@ # $FreeBSD$ +.if ${MACHINE_ARCH} != "powerpcspe" SUBDIR+= nvram +.endif SUBDIR+= ofwdump From 3413fe97706221447c6348d7e6558e7dea1d2a80 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 22 Oct 2016 02:11:53 +0000 Subject: [PATCH 013/235] Initialize the ofw_bus_devinfo on the portals to prevent a crash. If the device tree doesn't contain a cpu-handle field in any bman-portal or qman-portal, it will exit without setting up the devinfo, leaving it uninitialized. This will lead to attempts to free random memory, and ultimately panic. --- sys/dev/dpaa/bman_fdt.c | 2 +- sys/dev/dpaa/qman_fdt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/dpaa/bman_fdt.c b/sys/dev/dpaa/bman_fdt.c index 691a8dea9538..c7950270e34d 100644 --- a/sys/dev/dpaa/bman_fdt.c +++ b/sys/dev/dpaa/bman_fdt.c @@ -143,7 +143,7 @@ bman_portals_fdt_attach(device_t dev) ihandle_t cpu; int cpu_num, cpus, intr_rid; struct dpaa_portals_devinfo di; - struct ofw_bus_devinfo ofw_di; + struct ofw_bus_devinfo ofw_di = {}; cpus = 0; sc = device_get_softc(dev); diff --git a/sys/dev/dpaa/qman_fdt.c b/sys/dev/dpaa/qman_fdt.c index 4df8c05b84e0..cdcaa654ea5e 100644 --- a/sys/dev/dpaa/qman_fdt.c +++ b/sys/dev/dpaa/qman_fdt.c @@ -143,7 +143,7 @@ qman_portals_fdt_attach(device_t dev) ihandle_t cpu; int cpu_num, cpus, intr_rid; struct dpaa_portals_devinfo di; - struct ofw_bus_devinfo ofw_di; + struct ofw_bus_devinfo ofw_di = {}; cpus = 0; sc = device_get_softc(dev); From 4afdfe9761ab66dda41826aa8befe1d9530d08a2 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 22 Oct 2016 08:00:46 +0000 Subject: [PATCH 014/235] jedec_ts: a driver for thermal sensors on memory modules The driver currently supports chips that are fully compliant with the JEDEC SPD / EEPROM / TS standard (JEDEC Standard 21-C, TSE2002 Specification, frequenlty referred to as JEDEC JC 42.4). Additionally some chips from STMicroelectronics are supported as well. They are compliant except for their Device ID pattern. Given the continued lack of any common sensor infrastructure, the driver uses an ad-hoc sysctl to report the temperature. Reviewed by: wblock (documentation) MFC after: 2 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D8174 --- share/man/man4/jedec_ts.4 | 130 ++++++++++++++++++++++ sys/conf/NOTES | 5 + sys/conf/files | 1 + sys/dev/jedec_ts/jedec_ts.c | 179 ++++++++++++++++++++++++++++++ sys/modules/i2c/Makefile | 2 +- sys/modules/i2c/jedec_ts/Makefile | 7 ++ 6 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 share/man/man4/jedec_ts.4 create mode 100644 sys/dev/jedec_ts/jedec_ts.c create mode 100644 sys/modules/i2c/jedec_ts/Makefile diff --git a/share/man/man4/jedec_ts.4 b/share/man/man4/jedec_ts.4 new file mode 100644 index 000000000000..567beb66b58b --- /dev/null +++ b/share/man/man4/jedec_ts.4 @@ -0,0 +1,130 @@ +.\" +.\" Copyright (c) 2016 Andriy Gapon +.\" 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 ``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 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 October 13, 2016 +.Dt JEDEC_TS 4 +.Os +.Sh NAME +.Nm jedec_ts +.Nd driver for temperature sensors on memory modules +.Sh SYNOPSIS +.Bd -ragged -offset indent +.Cd "device jedec_ts" +.Cd "device smbus" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +jedec_ts_load="YES" +.Ed +.Pp +In +.Pa /boot/device.hints : +.Bd -literal -offset indent +.Cd hint.jedec_ts.0.at="smbus0" +.Cd hint.jedec_ts.0.addr="0x30" +.Cd hint.jedec_ts.1.at="smbus0" +.Cd hint.jedec_ts.1.addr="0x32" +.Cd hint.jedec_ts.2.at="smbus0" +.Cd hint.jedec_ts.2.addr="0x34" +.Cd hint.jedec_ts.3.at="smbus0" +.Cd hint.jedec_ts.3.addr="0x36" +.Cd hint.jedec_ts.4.at="smbus0" +.Cd hint.jedec_ts.4.addr="0x38" +.Cd hint.jedec_ts.5.at="smbus0" +.Cd hint.jedec_ts.5.addr="0x3A" +.Cd hint.jedec_ts.6.at="smbus0" +.Cd hint.jedec_ts.6.addr="0x3C" +.Cd hint.jedec_ts.7.at="smbus0" +.Cd hint.jedec_ts.7.addr="0x3E" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides access to sensor data over the +.Xr smbus 4 . +The driver supports temperature sensors on memory modules that conform +to JEDEC Standard 21-C, TSE2002 Specification. +.Pp +The access to +.Nm +data is made via the +.Xr sysctl 8 +interface: +.Bl -tag -width "dev.jedec_ts.%d.temp" +.It Va dev.jedec_ts.%d.temp +read-only value of the current temperature read by the sensor. +.El +.Pp +On a system using +.Xr device.hints 5 , +these values are configurable for +.Nm : +.Bl -tag -width "hint.jedec_ts.%d.addr" +.It Va hint.jedec_ts.%d.at +target +.Xr smbus 4 . +.It Va hint.jedec_ts.%d.addr +.Nm +SMBus address on the +.Xr smbus 4 . +.El +.Pp +.Nm +temperature sensors can be wired to eight different addresses, +allowing up to eight sensors on the same +.Xr smbus 4 . +.Pp +If the sensors are on an I2C bus behind an +.Xr iicbus 4 +controller, then the +.Xr iicsmb 4 +bridge driver can be used to attach the +.Xr smbus 4 . +.Sh EXAMPLES +.Ss Sensor read out for two memory modules: +.Bd -literal +dev.jedec_ts.0.temp: 40.2500C +dev.jedec_ts.1.temp: 40.7500C +.Ed +.Sh SEE ALSO +.Xr iicbus 4 , +.Xr iicsmb 4 , +.Xr smbus 4 , +.Xr sysctl 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 12.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver and this manual page were written by +.An Andriy Gapon Aq Mt avg@FreeBSD.org . diff --git a/sys/conf/NOTES b/sys/conf/NOTES index afc521518978..af8bf72cabb8 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2527,7 +2527,12 @@ device ismt device smb +# SMBus peripheral devices # +# jedec_ts Temperature Sensor compliant with JEDEC Standard 21-C +# +device jedec_ts + # I2C Bus # # Philips i2c bus support is provided by the `iicbus' device. diff --git a/sys/conf/files b/sys/conf/files index ef6ac4b6de5d..a430fb4ca308 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2062,6 +2062,7 @@ dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" +dev/jedec_ts/jedec_ts.c optional jedec_ts smbus dev/jme/if_jme.c optional jme pci dev/joy/joy.c optional joy dev/joy/joy_isa.c optional joy isa diff --git a/sys/dev/jedec_ts/jedec_ts.c b/sys/dev/jedec_ts/jedec_ts.c new file mode 100644 index 000000000000..b65ef789173f --- /dev/null +++ b/sys/dev/jedec_ts/jedec_ts.c @@ -0,0 +1,179 @@ +/*- + * Copyright (c) 2016 Andriy Gapon + * 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 ``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 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "smbus_if.h" + + +/* + * SMBus specification defines little-endian byte order, + * but it seems that the JEDEC devices expect it to + * be big-endian. + */ +static int +ts_readw_be(device_t dev, uint8_t reg, uint16_t *val) +{ + device_t bus = device_get_parent(dev); + uint8_t addr = smbus_get_addr(dev); + int err; + + err = smbus_readw(bus, addr, reg, val); + if (err != 0) + return (err); + *val = be16toh(*val); + return (0); +} + +static int +ts_temp_sysctl(SYSCTL_HANDLER_ARGS) +{ + device_t dev = arg1; + int err; + int temp; + uint16_t val; + + err = ts_readw_be(dev, 5, &val); + if (err != 0) + return (EIO); + + /* + * Convert the reading to temperature in 0.0001 Kelvins. + * Three most significant bits are flags, the next + * most significant bit is a sign bit. + * Each step is 0.0625 degrees. + */ + temp = val & 0xfff; + if ((val & 0x1000) != 0) + temp = -temp; + temp = temp * 625 + 2731500; + err = sysctl_handle_int(oidp, &temp, 0, req); + return (err); +} + +static int +ts_probe(device_t dev) +{ + device_set_desc(dev, "DIMM memory sensor"); + return (BUS_PROBE_DEFAULT); +} + +static int +ts_attach(device_t dev) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid_list *tree; + int err; + uint16_t vendorid; + uint16_t devid; + uint8_t addr; + + addr = smbus_get_addr(dev); + if ((addr & 0x30) != 0x30) { + /* Up to 8 slave devices starting at 0x30. */ + return (ENXIO); + } + + err = ts_readw_be(dev, 6, &vendorid); + if (err != 0) { + device_printf(dev, "failed to read Manufacturer ID\n"); + return (ENXIO); + } + err = ts_readw_be(dev, 6, &devid); + if (err != 0) { + device_printf(dev, "failed to read Device ID\n"); + return (ENXIO); + } + if ((devid & 0xff00) == 0x2200) { + /* + * Defined by JEDEC Standard No. 21-C, Release 26, + * Page 4.1.6 – 24 + */ + } else if (vendorid == 0x104a) { + /* + * STMicroelectronics datasheets say that + * device ID and revision can vary. + * E.g. STT424E02, Doc ID 13448 Rev 8, + * section 4.6, page 26. + */ + } else { + if (bootverbose) { + device_printf(dev, "Unknown Manufacturer and Device IDs" + ", 0x%x and 0x%x\n", vendorid, devid); + } + return (ENXIO); + } + + ctx = device_get_sysctl_ctx(dev); + tree = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); + + SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temp", + CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, dev, 0, + ts_temp_sysctl, "IK4", "Current temperature"); + + return (0); +} + +static int +ts_detach(device_t dev) +{ + return (0); +} + + +static device_method_t jedec_ts_methods[] = { + /* Methods from the device interface */ + DEVMETHOD(device_probe, ts_probe), + DEVMETHOD(device_attach, ts_attach), + DEVMETHOD(device_detach, ts_detach), + + /* Terminate method list */ + { 0, 0 } +}; + +static driver_t jedec_ts_driver = { + "jedec_ts", + jedec_ts_methods, + 0 /* no softc */ +}; + +static devclass_t jedec_ts_devclass; + +DRIVER_MODULE(jedec_ts, smbus, jedec_ts_driver, jedec_ts_devclass, 0, 0); +MODULE_DEPEND(jedec_ts, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); +MODULE_VERSION(jedec_ts, 1); diff --git a/sys/modules/i2c/Makefile b/sys/modules/i2c/Makefile index a2199f561051..8e9bdf982cb6 100644 --- a/sys/modules/i2c/Makefile +++ b/sys/modules/i2c/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ SUBDIR = -SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic cyapa smb isl +SUBDIR += controllers if_ic smbus iicbus iicbb iicsmb iic cyapa smb isl jedec_ts .include diff --git a/sys/modules/i2c/jedec_ts/Makefile b/sys/modules/i2c/jedec_ts/Makefile new file mode 100644 index 000000000000..66e620619fd5 --- /dev/null +++ b/sys/modules/i2c/jedec_ts/Makefile @@ -0,0 +1,7 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../dev/jedec_ts +KMOD = jedec_ts +SRCS = jedec_ts.c bus_if.h device_if.h smbus_if.h + +.include From 53d49b370a1777185491252c492d6c7288ba83d4 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sat, 22 Oct 2016 11:26:22 +0000 Subject: [PATCH 015/235] daemon: Allow logging daemon stdout/stderr to file or syslog. There are various new options, documented in the man page, to send the daemon's standard output and/or standard error to a file or to syslog. Submitted by: ank at iki.fi Reviewed by: wblock (man page only) Relnotes: yes Differential Revision: https://reviews.freebsd.org/D7993 --- usr.sbin/daemon/daemon.8 | 78 ++++++- usr.sbin/daemon/daemon.c | 486 ++++++++++++++++++++++++++++++--------- 2 files changed, 449 insertions(+), 115 deletions(-) diff --git a/usr.sbin/daemon/daemon.8 b/usr.sbin/daemon/daemon.8 index dab9e3f2ab9c..d8fd43f89bca 100644 --- a/usr.sbin/daemon/daemon.8 +++ b/usr.sbin/daemon/daemon.8 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 2, 2016 +.Dd October 22, 2016 .Dt DAEMON 8 .Os .Sh NAME @@ -34,11 +34,16 @@ .Nd run detached from the controlling terminal .Sh SYNOPSIS .Nm -.Op Fl cfr +.Op Fl cfrS .Op Fl p Ar child_pidfile .Op Fl P Ar supervisor_pidfile .Op Fl t Ar title .Op Fl u Ar user +.Op Fl m Ar output_mask +.Op Fl o Ar output_file +.Op Fl s Ar syslog_priority +.Op Fl T Ar syslog_tag +.Op Fl s Ar syslog_facility .Ar command arguments ... .Sh DESCRIPTION The @@ -46,6 +51,8 @@ The utility detaches itself from the controlling terminal and executes the program specified by its arguments. Privileges may be lowered to the specified user. +The output of the daemonized process may be redirected to syslog and to a +log file. .Pp The options are as follows: .Bl -tag -width indent @@ -55,6 +62,19 @@ Change the current working directory to the root .It Fl f Redirect standard input, standard output and standard error to .Pa /dev/null . +.It Fl S +Enable syslog output. +This is implicitly applied if other syslog parameters are provided. +The default values are daemon, notice, and daemon for facility, priority, and +tag, respectively. +.It Fl o Ar output_file +Append output from the daemonized process to +.Pa output_file . +If the file does not exist, it is created with permissions 0600. +.It Fl m Ar output_mask +Redirect output from the child process stdout (1), stderr (2), or both (3). +This value specifies what is sent to syslog and the log file. +The default is 3. .It Fl p Ar child_pidfile Write the ID of the created process into the .Ar child_pidfile @@ -96,18 +116,37 @@ option is used or not. .It Fl r Supervise and restart the program if it has been terminated. .It Fl t Ar title -Process title for the daemon to make it easily identifiable. +Set the title for the daemon process. +The default is the daemonized invocation. .It Fl u Ar user Login name of the user to execute the program under. Requires adequate superuser privileges. +.It Fl s Ar syslog_priority +These priorities are accepted: emerg, alert, crit, err, warning, +notice, info, and debug. +The default is info. +.It Fl l Ar syslog_facility +These facilities are accepted: auth, authpriv, console, cron, daemon, +ftp, kern, lpr, mail, news, ntp, security, syslog, user, uucp, and +local0, ..., local7. +The default is daemon. +.It Fl T Ar syslog_tag +Set the tag which is appended to all syslog messages. +The default is daemon. .El .Pp -If the +If any of the options .Fl p , -.Fl P +.Fl P , +.Fl r , +.Fl o , +.Fl s , +.Fl T , +.Fl m , +.Fl S , or -.Fl r -option is specified the program is executed in a spawned child process. +.Fl l +are specified, the program is executed in a spawned child process. The .Nm waits until it terminates to keep the pid file(s) locked and removes them @@ -119,6 +158,13 @@ spawned process. Normally it will cause the child to exit, remove the pidfile(s) and then terminate. .Pp +If neither file or syslog output are selected, all output is redirected to the +.Nm +process and written to stdout. +The +.Fl f +option may be used to suppress the stdout output completely. +.Pp The .Fl P option is useful combined with the @@ -145,13 +191,21 @@ library routine, 2 if or .Ar supervisor_pidfile is requested, but cannot be opened, 3 if process is already running (pidfile -exists and is locked), -otherwise 0. +exists and is locked), 4 if +.Ar syslog_priority +is not accepted, 5 if +.Ar syslog_facility +is not accepted, 6 if +.Ar output_mask +is not within the accepted range, 7 if +.Ar output_file +cannot be opened for appending, and otherwise 0. .Sh DIAGNOSTICS -If the command cannot be executed, an error message is displayed on -standard error unless the +If the command cannot be executed, an error message is printed to +standard error. +The exact behavior depends on the logging parameters and the .Fl f -flag is specified. +flag. .Sh SEE ALSO .Xr setregid 2 , .Xr setreuid 2 , diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c index 0ba7b06ee00a..e09315fa852a 100644 --- a/usr.sbin/daemon/daemon.c +++ b/usr.sbin/daemon/daemon.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -44,25 +45,59 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include +#define SYSLOG_NAMES +#include +#include +#include + +#define LBUF_SIZE 4096 + +struct log_params { + int dosyslog; + int logpri; + int noclose; + int outfd; +}; -static void dummy_sighandler(int); static void restrict_process(const char *); -static int wait_child(pid_t pid, sigset_t *mask); +static void handle_term(int); +static void handle_chld(int); +static int listen_child(int, struct log_params *); +static int get_log_mapping(const char *, const CODE *); +static void open_pid_files(const char *, const char *, struct pidfh **, + struct pidfh **); +static void do_output(const unsigned char *, size_t, struct log_params *); +static void daemon_sleep(time_t, long); static void usage(void); +static volatile sig_atomic_t terminate = 0, child_gone = 0, pid = 0; + int main(int argc, char *argv[]) { - struct pidfh *ppfh, *pfh; - sigset_t mask, oldmask; - int ch, nochdir, noclose, restart, serrno; - const char *pidfile, *ppidfile, *title, *user; - pid_t otherpid, pid; + const char *pidfile, *ppidfile, *title, *user, *outfn, *logtag; + int ch, nochdir, noclose, restart, dosyslog, child_eof; + sigset_t mask_susp, mask_orig, mask_read, mask_term; + struct log_params logpar; + int pfd[2] = { -1, -1 }, outfd = -1; + int stdmask, logpri, logfac; + struct pidfh *ppfh, *pfh; + char *p; + memset(&logpar, 0, sizeof(logpar)); + stdmask = STDOUT_FILENO | STDERR_FILENO; + ppidfile = pidfile = user = NULL; nochdir = noclose = 1; + logpri = LOG_NOTICE; + logfac = LOG_DAEMON; + logtag = "daemon"; restart = 0; - ppidfile = pidfile = title = user = NULL; - while ((ch = getopt(argc, argv, "cfp:P:rt:u:")) != -1) { + dosyslog = 0; + outfn = NULL; + title = NULL; + while ((ch = getopt(argc, argv, "cfSp:P:ru:o:s:l:t:l:m:T:")) != -1) { switch (ch) { case 'c': nochdir = 0; @@ -70,6 +105,20 @@ main(int argc, char *argv[]) case 'f': noclose = 0; break; + case 'l': + logfac = get_log_mapping(optarg, facilitynames); + if (logfac == -1) + errx(5, "unrecognized syslog facility"); + dosyslog = 1; + break; + case 'm': + stdmask = strtol(optarg, &p, 10); + if (p == optarg || stdmask < 0 || stdmask > 3) + errx(6, "unrecognized listening mask"); + break; + case 'o': + outfn = optarg; + break; case 'p': pidfile = optarg; break; @@ -79,9 +128,22 @@ main(int argc, char *argv[]) case 'r': restart = 1; break; + case 's': + logpri = get_log_mapping(optarg, prioritynames); + if (logpri == -1) + errx(4, "unrecognized syslog priority"); + dosyslog = 1; + break; + case 'S': + dosyslog = 1; + break; case 't': title = optarg; break; + case 'T': + logtag = optarg; + dosyslog = 1; + break; case 'u': user = optarg; break; @@ -95,43 +157,30 @@ main(int argc, char *argv[]) if (argc == 0) usage(); + if (!title) + title = argv[0]; + + if (outfn) { + outfd = open(outfn, O_CREAT | O_WRONLY | O_APPEND | O_CLOEXEC, 0600); + if (outfd == -1) + err(7, "open"); + } + + if (dosyslog) + openlog(logtag, LOG_PID | LOG_NDELAY, logfac); + ppfh = pfh = NULL; /* * Try to open the pidfile before calling daemon(3), * to be able to report the error intelligently */ - if (pidfile != NULL) { - pfh = pidfile_open(pidfile, 0600, &otherpid); - if (pfh == NULL) { - if (errno == EEXIST) { - errx(3, "process already running, pid: %d", - otherpid); - } - err(2, "pidfile ``%s''", pidfile); - } - } - /* Do the same for actual daemon process. */ - if (ppidfile != NULL) { - ppfh = pidfile_open(ppidfile, 0600, &otherpid); - if (ppfh == NULL) { - serrno = errno; - pidfile_remove(pfh); - errno = serrno; - if (errno == EEXIST) { - errx(3, "process already running, pid: %d", - otherpid); - } - err(2, "ppidfile ``%s''", ppidfile); - } - } - + open_pid_files(pidfile, ppidfile, &pfh, &ppfh); if (daemon(nochdir, noclose) == -1) { warn("daemon"); goto exit; } /* Write out parent pidfile if needed. */ pidfile_write(ppfh); - /* * If the pidfile or restart option is specified the daemon * executes the command in a forked process and wait on child @@ -139,92 +188,242 @@ main(int argc, char *argv[]) * we don't want the monitoring daemon to be terminated * leaving the running process and the stale pidfile, so we * catch SIGTERM and forward it to the children expecting to - * get SIGCHLD eventually. + * get SIGCHLD eventually. We also must fork() to obtain a + * readable pipe with the child for writing to a log file + * and syslog. */ pid = -1; - if (pidfile != NULL || ppidfile != NULL || restart) { + if (pidfile || ppidfile || restart || outfd != -1 || dosyslog) { + struct sigaction act_term, act_chld; + + /* Avoid PID racing with SIGCHLD and SIGTERM. */ + memset(&act_term, 0, sizeof(act_term)); + act_term.sa_handler = handle_term; + sigemptyset(&act_term.sa_mask); + sigaddset(&act_term.sa_mask, SIGCHLD); + + memset(&act_chld, 0, sizeof(act_chld)); + act_chld.sa_handler = handle_chld; + sigemptyset(&act_chld.sa_mask); + sigaddset(&act_chld.sa_mask, SIGTERM); + + /* Block these when avoiding racing before sigsuspend(). */ + sigemptyset(&mask_susp); + sigaddset(&mask_susp, SIGTERM); + sigaddset(&mask_susp, SIGCHLD); + /* Block SIGTERM when we lack a valid child PID. */ + sigemptyset(&mask_term); + sigaddset(&mask_term, SIGTERM); /* - * Restore default action for SIGTERM in case the - * parent process decided to ignore it. + * When reading, we wish to avoid SIGCHLD. SIGTERM + * has to be caught, otherwise we'll be stuck until + * the read() returns - if it returns. */ - if (signal(SIGTERM, SIG_DFL) == SIG_ERR) { - warn("signal"); - goto exit; - } - /* - * Because SIGCHLD is ignored by default, setup dummy handler - * for it, so we can mask it. - */ - if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) { - warn("signal"); - goto exit; - } - /* - * Block interesting signals. - */ - sigemptyset(&mask); - sigaddset(&mask, SIGTERM); - sigaddset(&mask, SIGCHLD); - if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) { + sigemptyset(&mask_read); + sigaddset(&mask_read, SIGCHLD); + /* Block SIGTERM to avoid racing until we have forked. */ + if (sigprocmask(SIG_BLOCK, &mask_term, &mask_orig)) { warn("sigprocmask"); goto exit; } + if (sigaction(SIGTERM, &act_term, NULL) == -1) { + warn("sigaction"); + goto exit; + } + if (sigaction(SIGCHLD, &act_chld, NULL) == -1) { + warn("sigaction"); + goto exit; + } /* * Try to protect against pageout kill. Ignore the * error, madvise(2) will fail only if a process does * not have superuser privileges. */ (void)madvise(NULL, 0, MADV_PROTECT); + logpar.outfd = outfd; + logpar.dosyslog = dosyslog; + logpar.logpri = logpri; + logpar.noclose = noclose; restart: + if (pipe(pfd)) + err(1, "pipe"); /* - * Spawn a child to exec the command, so in the parent - * we could wait for it to exit and remove pidfile. + * Spawn a child to exec the command. */ + child_gone = 0; pid = fork(); if (pid == -1) { warn("fork"); goto exit; + } else if (pid > 0) { + /* + * Unblock SIGTERM after we know we have a valid + * child PID to signal. + */ + if (sigprocmask(SIG_UNBLOCK, &mask_term, NULL)) { + warn("sigprocmask"); + goto exit; + } + close(pfd[1]); + pfd[1] = -1; } } if (pid <= 0) { - if (pid == 0) { - /* Restore old sigmask in the child. */ - if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1) - err(1, "sigprocmask"); - } /* Now that we are the child, write out the pid. */ pidfile_write(pfh); if (user != NULL) restrict_process(user); - + /* + * When forking, the child gets the original sigmask, + * and dup'd pipes. + */ + if (pid == 0) { + close(pfd[0]); + if (sigprocmask(SIG_SETMASK, &mask_orig, NULL)) + err(1, "sigprogmask"); + if (stdmask & STDERR_FILENO) { + if (dup2(pfd[1], STDERR_FILENO) == -1) + err(1, "dup2"); + } + if (stdmask & STDOUT_FILENO) { + if (dup2(pfd[1], STDOUT_FILENO) == -1) + err(1, "dup2"); + } + if (pfd[1] != STDERR_FILENO && + pfd[1] != STDOUT_FILENO) + close(pfd[1]); + } execvp(argv[0], argv); - /* * execvp() failed -- report the error. The child is * now running, so the exit status doesn't matter. */ err(1, "%s", argv[0]); } - - if (title != NULL) - setproctitle("%s[%d]", title, pid); - else - setproctitle("%s[%d]", argv[0], pid); - if (wait_child(pid, &mask) == 0 && restart) { - sleep(1); + setproctitle("%s[%d]", title, (int)pid); + /* + * As we have closed the write end of pipe for parent process, + * we might detect the child's exit by reading EOF. The child + * might have closed its stdout and stderr, so we must wait for + * the SIGCHLD to ensure that the process is actually gone. + */ + child_eof = 0; + for (;;) { + /* + * We block SIGCHLD when listening, but SIGTERM we accept + * so the read() won't block if we wish to depart. + * + * Upon receiving SIGTERM, we have several options after + * sending the SIGTERM to our child: + * - read until EOF + * - read until EOF but only for a while + * - bail immediately + * + * We go for the third, as otherwise we have no guarantee + * that we won't block indefinitely if the child refuses + * to depart. To handle the second option, a different + * approach would be needed (procctl()?) + */ + if (child_gone && child_eof) { + break; + } else if (terminate) { + goto exit; + } else if (!child_eof) { + if (sigprocmask(SIG_BLOCK, &mask_read, NULL)) { + warn("sigprocmask"); + goto exit; + } + child_eof = !listen_child(pfd[0], &logpar); + if (sigprocmask(SIG_UNBLOCK, &mask_read, NULL)) { + warn("sigprocmask"); + goto exit; + } + } else { + if (sigprocmask(SIG_BLOCK, &mask_susp, NULL)) { + warn("sigprocmask"); + goto exit; + } + while (!terminate && !child_gone) + sigsuspend(&mask_orig); + if (sigprocmask(SIG_UNBLOCK, &mask_susp, NULL)) { + warn("sigprocmask"); + goto exit; + } + } + } + if (sigprocmask(SIG_BLOCK, &mask_term, NULL)) { + warn("sigprocmask"); + goto exit; + } + if (restart && !terminate) { + daemon_sleep(1, 0); + close(pfd[0]); + pfd[0] = -1; goto restart; } exit: + close(outfd); + close(pfd[0]); + close(pfd[1]); + if (dosyslog) + closelog(); pidfile_remove(pfh); pidfile_remove(ppfh); exit(1); /* If daemon(3) succeeded exit status does not matter. */ } static void -dummy_sighandler(int sig __unused) +daemon_sleep(time_t secs, long nsecs) { - /* Nothing to do. */ + struct timespec ts = { secs, nsecs }; + while (nanosleep(&ts, &ts) == -1) { + if (errno != EINTR) + err(1, "nanosleep"); + } +} + +static void +open_pid_files(const char *pidfile, const char *ppidfile, + struct pidfh **pfh, struct pidfh **ppfh) +{ + pid_t fpid; + int serrno; + + if (pidfile) { + *pfh = pidfile_open(pidfile, 0600, &fpid); + if (*pfh == NULL) { + if (errno == EEXIST) { + errx(3, "process already running, pid: %d", + fpid); + } + err(2, "pidfile ``%s''", pidfile); + } + } + /* Do the same for the actual daemon process. */ + if (ppidfile) { + *ppfh = pidfile_open(ppidfile, 0600, &fpid); + if (*ppfh == NULL) { + serrno = errno; + pidfile_remove(*pfh); + errno = serrno; + if (errno == EEXIST) { + errx(3, "process already running, pid: %d", + fpid); + } + err(2, "ppidfile ``%s''", ppidfile); + } + } +} + +static int +get_log_mapping(const char *str, const CODE *c) +{ + const CODE *cp; + for (cp = c; cp->c_name; cp++) + if (strcmp(cp->c_name, str) == 0) + return cp->c_val; + return -1; } static void @@ -240,34 +439,112 @@ restrict_process(const char *user) errx(1, "failed to set user environment"); } +/* + * We try to collect whole lines terminated by '\n'. Otherwise we collect a + * full buffer, and then output it. + * + * Return value of 0 is assumed to mean EOF or error, and 1 indicates to + * continue reading. + */ static int -wait_child(pid_t pid, sigset_t *mask) +listen_child(int fd, struct log_params *logpar) { - int terminate, signo; + static unsigned char buf[LBUF_SIZE]; + static size_t bytes_read = 0; + int rv; - terminate = 0; - for (;;) { - if (sigwait(mask, &signo) == -1) { - warn("sigwaitinfo"); - return (-1); + assert(logpar); + assert(bytes_read < LBUF_SIZE - 1); + + rv = read(fd, buf + bytes_read, LBUF_SIZE - bytes_read - 1); + if (rv > 0) { + unsigned char *cp; + + bytes_read += rv; + assert(bytes_read <= LBUF_SIZE - 1); + /* Always NUL-terminate just in case. */ + buf[LBUF_SIZE - 1] = '\0'; + /* + * Chomp line by line until we run out of buffer. + * This does not take NUL characters into account. + */ + while ((cp = memchr(buf, '\n', bytes_read)) != NULL) { + size_t bytes_line = cp - buf + 1; + assert(bytes_line <= bytes_read); + do_output(buf, bytes_line, logpar); + bytes_read -= bytes_line; + memmove(buf, cp + 1, bytes_read); } - switch (signo) { - case SIGCHLD: - if (waitpid(pid, NULL, WNOHANG) == -1) { - warn("waitpid"); - return (-1); - } - return (terminate); - case SIGTERM: - terminate = 1; - if (kill(pid, signo) == -1) { - warn("kill"); - return (-1); - } - continue; - default: - warnx("sigwaitinfo: invalid signal: %d", signo); - return (-1); + /* Wait until the buffer is full. */ + if (bytes_read < LBUF_SIZE - 1) + return 1; + do_output(buf, bytes_read, logpar); + bytes_read = 0; + return 1; + } else if (rv == -1) { + /* EINTR should trigger another read. */ + if (errno == EINTR) { + return 1; + } else { + warn("read"); + return 0; + } + } + /* Upon EOF, we have to flush what's left of the buffer. */ + if (bytes_read > 0) { + do_output(buf, bytes_read, logpar); + bytes_read = 0; + } + return 0; +} + +/* + * The default behavior is to stay silent if the user wants to redirect + * output to a file and/or syslog. If neither are provided, then we bounce + * everything back to parent's stdout. + */ +static void +do_output(const unsigned char *buf, size_t len, struct log_params *logpar) +{ + assert(len <= LBUF_SIZE); + assert(logpar); + + if (len < 1) + return; + if (logpar->dosyslog) + syslog(logpar->logpri, "%.*s", (int)len, buf); + if (logpar->outfd != -1) { + if (write(logpar->outfd, buf, len) == -1) + warn("write"); + } + if (logpar->noclose && !logpar->dosyslog && logpar->outfd == -1) + printf("%.*s", (int)len, buf); +} + +/* + * We use the global PID acquired directly from fork. If there is no valid + * child pid, the handler should be blocked and/or child_gone == 1. + */ +static void +handle_term(int signo) +{ + if (pid > 0 && !child_gone) + kill(pid, signo); + terminate = 1; +} + +static void +handle_chld(int signo) +{ + (void)signo; + for (;;) { + int rv = waitpid(-1, NULL, WNOHANG); + if (pid == rv) { + child_gone = 1; + break; + } else if (rv == -1 && errno != EINTR) { + warn("waitpid"); + return; } } } @@ -275,8 +552,11 @@ wait_child(pid_t pid, sigset_t *mask) static void usage(void) { - (void)fprintf(stderr, "%s\n\t%s\n", - "usage: daemon [-cfr] [-p child_pidfile] [-P supervisor_pidfile]", - "[-t title] [-u user] command arguments ..."); + (void)fprintf(stderr, + "usage: daemon [-cfrS] [-p child_pidfile] [-P supervisor_pidfile]\n" + " [-u user] [-o output_file] [-t title]\n" + " [-l syslog_facility] [-s syslog_priority]\n" + " [-T syslog_tag] [-m output_mask]\n" + "command arguments ...\n"); exit(1); } From 8f34671a5e3aa4c7b98f4140255735e4360038f1 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 22 Oct 2016 13:11:09 +0000 Subject: [PATCH 016/235] ptrace.S is not needed, libc/sys/ptrace.c exists already. This was leftovers from the initial branch work. Reported by: kib --- lib/libc/powerpcspe/sys/Makefile.inc | 2 +- lib/libc/powerpcspe/sys/ptrace.S | 61 ---------------------------- 2 files changed, 1 insertion(+), 62 deletions(-) delete mode 100644 lib/libc/powerpcspe/sys/ptrace.S diff --git a/lib/libc/powerpcspe/sys/Makefile.inc b/lib/libc/powerpcspe/sys/Makefile.inc index 4948f6754c9f..6451d821b99c 100644 --- a/lib/libc/powerpcspe/sys/Makefile.inc +++ b/lib/libc/powerpcspe/sys/Makefile.inc @@ -1,6 +1,6 @@ # $FreeBSD$ -MDASM+= brk.S cerror.S exect.S ptrace.S sbrk.S setlogin.S +MDASM+= brk.S cerror.S exect.S sbrk.S setlogin.S # Don't generate default code for these syscalls: NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o diff --git a/lib/libc/powerpcspe/sys/ptrace.S b/lib/libc/powerpcspe/sys/ptrace.S deleted file mode 100644 index cff463dd009c..000000000000 --- a/lib/libc/powerpcspe/sys/ptrace.S +++ /dev/null @@ -1,61 +0,0 @@ -/*- - * Copyright (c) 2002 Peter Grehan. - * 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. - */ -/* $NetBSD: ptrace.S,v 1.3 2000/02/23 20:16:57 kleink Exp $ */ - -#include -__FBSDID("$FreeBSD$"); - -#include "SYS.h" - -ENTRY(ptrace) - mflr %r0 - stwu %r1,-32(%r1) - stw %r0,36(%r1) - stw %r3,8(%r1) - stw %r4,12(%r1) - stw %r5,16(%r1) - stw %r6,20(%r1) - - bl PIC_PLT(CNAME(__error)) - li %r7,0 - stw %r7,0(%r3) - - lwz %r3,8(%r1) - lwz %r4,12(%r1) - lwz %r5,16(%r1) - lwz %r0,36(%r1) - lwz %r6,20(%r1) - mtlr %r0 - la %r1,32(%r1) - li %r0,SYS_ptrace - sc - bso 1f - blr -1: - b PIC_PLT(HIDENAME(cerror)) -END(ptrace) - - .section .note.GNU-stack,"",%progbits From 0b9cf9729be515a1188d595d1251e8fb59c61ea3 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 22 Oct 2016 14:37:13 +0000 Subject: [PATCH 017/235] Fix libusb20_dev_get_desc(3) to use the "vendor product" order, not "product vendor". This is consistent with how it's generally done. The ordering is visible eg in usbconfig(8) output. Note to self: MFC this to 9 and 8. Reviewed by: hselasky@ MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D8258 --- lib/libusb/libusb20_ugen20.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c index e40bc07e61e0..be2acee7e9e0 100644 --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -214,8 +214,8 @@ ugen20_enumerate(struct libusb20_device *pdev, const char *id) snprintf(pdev->usb_desc, sizeof(pdev->usb_desc), USB_GENERIC_NAME "%u.%u: <%s %s> at usbus%u", pdev->bus_number, - pdev->device_address, devinfo.udi_product, - devinfo.udi_vendor, pdev->bus_number); + pdev->device_address, devinfo.udi_vendor, + devinfo.udi_product, pdev->bus_number); error = 0; done: From 38d3251c3d048164804fe097b5fe9c4554bbdab4 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Sat, 22 Oct 2016 17:21:21 +0000 Subject: [PATCH 018/235] No functional changes, mostly getting the whitespace changes resulting from an updated formatting tool chain. MFC after: 1 month --- sys/netinet/sctp_bsd_addr.c | 3 - sys/netinet/sctp_output.c | 247 +++++++++++------------------------- 2 files changed, 76 insertions(+), 174 deletions(-) diff --git a/sys/netinet/sctp_bsd_addr.c b/sys/netinet/sctp_bsd_addr.c index 9276a20990c6..6c0f6e171508 100644 --- a/sys/netinet/sctp_bsd_addr.c +++ b/sys/netinet/sctp_bsd_addr.c @@ -140,7 +140,6 @@ sctp_gather_internal_ifa_flags(struct sctp_ifa *ifa) ifa->localifa_flags &= ~SCTP_ADDR_IFA_UNUSEABLE; } } - #endif /* INET6 */ @@ -201,10 +200,8 @@ sctp_init_ifns_for_vrf(int vrfid) struct ifaddr *ifa; struct sctp_ifa *sctp_ifa; uint32_t ifa_flags; - #ifdef INET6 struct in6_ifaddr *ifa6; - #endif IFNET_RLOCK(); diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c index 2749a0849933..6db73812ccb2 100644 --- a/sys/netinet/sctp_output.c +++ b/sys/netinet/sctp_output.c @@ -1943,7 +1943,6 @@ sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t * len) struct sctp_paramhdr *parmh; struct mbuf *mret; uint16_t plen; - #endif switch (ifa->address.sa.sa_family) { @@ -2139,10 +2138,8 @@ sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb, cnt++; total_count++; if (cnt >= 2) { - /* - * two from each - * address - */ + /* two from each + * address */ break; } if (total_count > SCTP_ADDRESS_LIMIT) { @@ -2784,7 +2781,6 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, { struct sctp_ifa *ifa, *sifa; int num_eligible_addr = 0; - #ifdef INET6 struct sockaddr_in6 sin6, lsa6; @@ -2829,10 +2825,8 @@ sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, if (fam == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&sifa->address.sin6.sin6_addr) && IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) { - /* - * link-local <-> link-local must belong to the same - * scope. - */ + /* link-local <-> link-local must belong to the same + * scope. */ memcpy(&lsa6, &sifa->address.sin6, sizeof(struct sockaddr_in6)); (void)sa6_recoverscope(&lsa6); if (sin6.sin6_scope_id != lsa6.sin6_scope_id) { @@ -2966,10 +2960,8 @@ sctp_choose_boundall(struct sctp_inpcb *inp, struct sctp_ifa *sctp_ifa, *sifa; uint32_t ifn_index; struct sctp_vrf *vrf; - #ifdef INET int retried = 0; - #endif /*- @@ -3315,14 +3307,11 @@ sctp_source_address_selection(struct sctp_inpcb *inp, struct sctp_ifa *answer; uint8_t dest_is_priv, dest_is_loop; sa_family_t fam; - #ifdef INET struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst; - #endif #ifdef INET6 struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst; - #endif /** @@ -3570,14 +3559,11 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er struct cmsghdr cmh; int tlen, at; struct sctp_initmsg initmsg; - #ifdef INET struct sockaddr_in sin; - #endif #ifdef INET6 struct sockaddr_in6 sin6; - #endif tlen = SCTP_BUF_LEN(control); @@ -3618,10 +3604,8 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) { struct sctp_stream_out *tmp_str; unsigned int i; - #if defined(SCTP_DETAILED_STR_STATS) int j; - #endif /* Default is NOT correct */ @@ -3744,14 +3728,11 @@ sctp_findassociation_cmsgs(struct sctp_inpcb **inp_p, int tlen, at; struct sctp_tcb *stcb; struct sockaddr *addr; - #ifdef INET struct sockaddr_in sin; - #endif #ifdef INET6 struct sockaddr_in6 sin6; - #endif tlen = SCTP_BUF_LEN(control); @@ -3970,7 +3951,6 @@ sctp_handle_no_route(struct sctp_tcb *stcb, } } } - #endif static int @@ -4016,22 +3996,17 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, struct sctphdr *sctphdr; int packet_length; int ret; - #if defined(INET) || defined(INET6) uint32_t vrf_id; - #endif #if defined(INET) || defined(INET6) struct mbuf *o_pak; sctp_route_t *ro = NULL; struct udphdr *udp = NULL; - #endif uint8_t tos_value; - #if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) struct socket *so = NULL; - #endif if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) { @@ -4289,10 +4264,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, /* free tempy routes */ RO_RTFREE(ro); } else { - /* - * PMTU check versus smallest asoc MTU goes - * here - */ + /* PMTU check versus smallest asoc MTU goes + * here */ if ((ro->ro_rt != NULL) && (net->ro._s_addr)) { uint32_t mtu; @@ -4567,10 +4540,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT3, (struct sockaddr *)sin6); if (net) { sin6 = (struct sockaddr_in6 *)&net->ro._l_addr; - /* - * preserve the port and scope for link - * local send - */ + /* preserve the port and scope for link + * local send */ prev_scope = sin6->sin6_scope_id; prev_port = sin6->sin6_port; } @@ -4636,10 +4607,8 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, /* Now if we had a temp route free it */ RO_RTFREE(ro); } else { - /* - * PMTU check versus smallest asoc MTU goes - * here - */ + /* PMTU check versus smallest asoc MTU goes + * here */ if (ro->ro_rt == NULL) { /* Route was freed */ if (net->ro._s_addr && @@ -4969,11 +4938,11 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, * being equal to the beginning of the params i.e. (iphlen + * sizeof(struct sctp_init_msg) parse through the parameters to the * end of the mbuf verifying that all parameters are known. - * + * * For unknown parameters build and return a mbuf with * UNRECOGNIZED_PARAMETER errors. If the flags indicate to stop * processing this chunk stop, and set *abort_processing to 1. - * + * * By having param_offset be pre-set to where parameters begin it is * hoped that this routine may be reused in the future by new * features. @@ -5260,7 +5229,6 @@ sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, *abort_processing = 1; if ((op_err == NULL) && phdr) { int l_len; - #ifdef INET6 l_len = SCTP_MIN_OVERHEAD; #else @@ -5318,14 +5286,11 @@ sctp_are_there_new_addresses(struct sctp_association *asoc, uint8_t fnd; struct sctp_nets *net; int check_src; - #ifdef INET struct sockaddr_in sin4, *sa4; - #endif #ifdef INET6 struct sockaddr_in6 sin6, *sa6; - #endif #ifdef INET @@ -5509,18 +5474,15 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_paramhdr *ph; union sctp_sockstore *over_addr; struct sctp_scoping scp; - #ifdef INET struct sockaddr_in *dst4 = (struct sockaddr_in *)dst; struct sockaddr_in *src4 = (struct sockaddr_in *)src; struct sockaddr_in *sin; - #endif #ifdef INET6 struct sockaddr_in6 *dst6 = (struct sockaddr_in6 *)dst; struct sockaddr_in6 *src6 = (struct sockaddr_in6 *)src; struct sockaddr_in6 *sin6; - #endif struct sockaddr *to; struct sctp_state_cookie stc; @@ -5544,10 +5506,10 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* * new addresses, out of here in non-cookie-wait * states - * - * Send an ABORT, without the new address error cause. - * This looks no different than if no listener was - * present. + * + * Send an ABORT, without the new address error + * cause. This looks no different than if no + * listener was present. */ op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), "Address added"); @@ -5560,9 +5522,9 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, /* * change of remote encapsulation port, out of here * in non-cookie-wait states - * - * Send an ABORT, without an specific error cause. This - * looks no different than if no listener was + * + * Send an ABORT, without an specific error cause. + * This looks no different than if no listener was * present. */ op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code), @@ -5716,10 +5678,8 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * show up in our scoped count. */ cnt_inits_to = 1; - /* - * pull out the scope_id from - * incoming pkt - */ + /* pull out the scope_id from + * incoming pkt */ } else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr) || IN6_IS_ADDR_SITELOCAL(&dst6->sin6_addr)) { /* @@ -5744,7 +5704,6 @@ sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, #ifdef INET6 struct sctp_nets *lnet; - #endif stc.loopback_scope = asoc->scope.loopback_scope; @@ -6206,9 +6165,9 @@ sctp_prune_prsctp(struct sctp_tcb *stcb, if (freed_spc >= dataout) { return; } - } /* if chunk was present */ - } /* if of sufficient priority */ - } /* if chunk has enabled */ + } /* if chunk was present */ + } /* if of sufficient priority */ + } /* if chunk has enabled */ } /* tailqforeach */ TAILQ_FOREACH_SAFE(chk, &asoc->send_queue, sctp_next, nchk) { @@ -6229,11 +6188,11 @@ sctp_prune_prsctp(struct sctp_tcb *stcb, if (freed_spc >= dataout) { return; } - } /* end if chk->data */ - } /* end if right class */ - } /* end if chk pr-sctp */ + } /* end if chk->data */ + } /* end if right class */ + } /* end if chk pr-sctp */ } /* tailqforeachsafe (chk) */ - } /* if enabled in asoc */ + } /* if enabled in asoc */ } int @@ -6476,10 +6435,8 @@ sctp_copy_mbufchain(struct mbuf *clonechain, /* get the prepend space */ SCTP_BUF_RESV_UF(outchain, (SCTP_FIRST_MBUF_RESV + 4)); } else { - /* - * We really should not get a NULL - * in endofchain - */ + /* We really should not get a NULL + * in endofchain */ /* find end */ m = outchain; while (m) { @@ -6491,10 +6448,8 @@ sctp_copy_mbufchain(struct mbuf *clonechain, } /* sanity */ if (*endofchain == NULL) { - /* - * huh, TSNH XXX maybe we - * should panic - */ + /* huh, TSNH XXX maybe we + * should panic */ sctp_m_freem(outchain); goto new_mbuf; } @@ -6693,17 +6648,13 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, if ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc)) { goto abort_anyway; } - /* - * there is nothing queued to send, so I'm - * done... - */ + /* there is nothing queued to send, so I'm + * done... */ if ((SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_SENT) && (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_RECEIVED) && (SCTP_GET_STATE(asoc) != SCTP_STATE_SHUTDOWN_ACK_SENT)) { - /* - * only send SHUTDOWN the first time - * through - */ + /* only send SHUTDOWN the first time + * through */ if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) { SCTP_STAT_DECR_GAUGE32(sctps_currestab); } @@ -7334,10 +7285,8 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb, SCTP_TCB_SEND_LOCK(stcb); send_lock_up = 1; if (sp->msg_is_complete) { - /* - * the sender finished the - * msg - */ + /* the sender finished the + * msg */ goto re_look; } } @@ -7955,9 +7904,9 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, * (when CMT is off) then it calls * sctp_fill_outqueue for the net. This gets data on * the send queue for that network. - * - * In sctp_fill_outqueue TSN's are assigned and data is - * copied out of the stream buffers. Note mostly + * + * In sctp_fill_outqueue TSN's are assigned and data + * is copied out of the stream buffers. Note mostly * copy by reference (we hope). */ net->window_probe = 0; @@ -8226,10 +8175,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, net->port, NULL, 0, 0, so_locked))) { - /* - * error, we could not - * output - */ + /* error, we could not + * output */ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error); if (from_where == 0) { SCTP_STAT_INCR(sctps_lowlevelerrusr); @@ -8302,16 +8249,12 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, * to where the sack is going.. */ if (chk->whoTo == net) { - /* - * Don't transmit it to where its - * going (current net) - */ + /* Don't transmit it to where its + * going (current net) */ continue; } else if (sack_goes_to == net) { - /* - * But do transmit it to this - * address - */ + /* But do transmit it to this + * address */ goto skip_net_check; } } @@ -8504,10 +8447,8 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, net->port, NULL, 0, 0, so_locked))) { - /* - * error, we could not - * output - */ + /* error, we could not + * output */ SCTPDBG(SCTP_DEBUG_OUTPUT3, "Gak send error %d\n", error); if (from_where == 0) { SCTP_STAT_INCR(sctps_lowlevelerrusr); @@ -8704,17 +8645,13 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, override_ok = 0; SCTP_STAT_INCR_COUNTER64(sctps_outcontrolchunks); } else if (override_ok) { - /* - * use this data's - * keyid - */ + /* use this data's + * keyid */ auth_keyid = chk->auth_keyid; override_ok = 0; } else if (auth_keyid != chk->auth_keyid) { - /* - * different keyid, - * so done bundling - */ + /* different keyid, + * so done bundling */ break; } } @@ -8793,8 +8730,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp, break; } } /* for (chunk gather loop for this net) */ - } /* if asoc.state OPEN */ -no_data_fill: +} /* if asoc.state OPEN */ no_data_fill: /* Is there something to send for this destination? */ if (outchain) { /* We may need to start a control timer or two */ @@ -9734,10 +9670,8 @@ sctp_chunk_retransmission(struct sctp_inpcb *inp, auth_keyid = fwd->auth_keyid; override_ok = 0; } else if (fwd->auth_keyid != auth_keyid) { - /* - * different keyid, - * so done bundling - */ + /* different keyid, + * so done bundling */ break; } } @@ -10113,11 +10047,9 @@ sctp_chunk_output(struct sctp_inpcb *inp, if (asoc->max_burst > 0) { if (SCTP_BASE_SYSCTL(sctp_use_cwnd_based_maxburst)) { if ((net->flight_size + (asoc->max_burst * net->mtu)) < net->cwnd) { - /* - * JRS - Use the congestion + /* JRS - Use the congestion * control given in the - * congestion control module - */ + * congestion control module */ asoc->cc_functions.sctp_cwnd_update_after_output(stcb, net, asoc->max_burst); if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_MAXBURST_ENABLE) { sctp_log_maxburst(stcb, net, 0, asoc->max_burst, SCTP_MAX_BURST_APPLIED); @@ -10127,10 +10059,8 @@ sctp_chunk_output(struct sctp_inpcb *inp, net->fast_retran_ip = 0; } else { if (net->flight_size == 0) { - /* - * Should be decaying the - * cwnd here - */ + /* Should be decaying the + * cwnd here */ ; } } @@ -11017,23 +10947,18 @@ sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, struct mbuf *mout; struct sctphdr *shout; struct sctp_chunkhdr *ch; - #if defined(INET) || defined(INET6) struct udphdr *udp; int ret; - #endif int len, cause_len, padding_len; - #ifdef INET struct sockaddr_in *src_sin, *dst_sin; struct ip *ip; - #endif #ifdef INET6 struct sockaddr_in6 *src_sin6, *dst_sin6; struct ip6_hdr *ip6; - #endif /* Compute the length of the cause and add final padding. */ @@ -11622,10 +11547,8 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u asoc = &stcb->asoc; TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) { if ((chk->rec.chunk_id.id == SCTP_ECN_CWR) && (net == chk->whoTo)) { - /* - * found a previous CWR queued to same destination - * update it if needed - */ + /* found a previous CWR queued to same destination + * update it if needed */ uint32_t ctsn; cwr = mtod(chk->data, struct sctp_cwr_chunk *); @@ -12169,10 +12092,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, struct sctp_stream_out *oldstream; struct sctp_stream_queue_pending *sp, *nsp; int i; - #if defined(SCTP_DETAILED_STR_STATS) int j; - #endif oldstream = stcb->asoc.strmout; @@ -12204,10 +12125,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, stcb->asoc.strmout[i].stream_no = i; stcb->asoc.strmout[i].state = oldstream[i].state; /* FIX ME FIX ME */ - /* - * This should be a SS_COPY operation FIX ME STREAM - * SCHEDULER EXPERT - */ + /* This should be a SS_COPY operation FIX ME STREAM + * SCHEDULER EXPERT */ stcb->asoc.ss_functions.sctp_ss_init_stream(stcb, &stcb->asoc.strmout[i], &oldstream[i]); /* now anything on those queues? */ TAILQ_FOREACH_SAFE(sp, &oldstream[i].outqueue, next, nsp) { @@ -12451,10 +12370,8 @@ sctp_sosend(struct socket *so, int error, use_sndinfo = 0; struct sctp_sndrcvinfo sndrcvninfo; struct sockaddr *addr_to_use; - #if defined(INET) && defined(INET6) struct sockaddr_in sin; - #endif if (control) { @@ -12739,10 +12656,8 @@ sctp_lower_sosend(struct socket *so, } if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) { stcb->sctp_ep->sctp_flags |= SCTP_PCB_FLAGS_CONNECTED; - /* - * Set the connected flag so we can queue - * data - */ + /* Set the connected flag so we can queue + * data */ soisconnecting(so); } hold_tcblock = 1; @@ -12752,10 +12667,8 @@ sctp_lower_sosend(struct socket *so, } else { SCTP_PRINTF("Huh-3? create lock should have been on??\n"); } - /* - * Turn on queue only flag to prevent data from - * being sent - */ + /* Turn on queue only flag to prevent data from + * being sent */ queue_only = 1; asoc = &stcb->asoc; SCTP_SET_STATE(asoc, SCTP_STATE_COOKIE_WAIT); @@ -13248,10 +13161,8 @@ sctp_lower_sosend(struct socket *so, } /* PR-SCTP? */ if ((asoc->prsctp_supported) && (asoc->sent_queue_cnt_removeable > 0)) { - /* - * This is ugly but we must assure locking - * order - */ + /* This is ugly but we must assure locking + * order */ if (hold_tcblock == 0) { SCTP_TCB_LOCK(stcb); hold_tcblock = 1; @@ -13528,10 +13439,8 @@ sctp_lower_sosend(struct socket *so, msg); sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_LOCKED); - /* - * now relock the stcb so everything - * is sane - */ + /* now relock the stcb so everything + * is sane */ hold_tcblock = 0; stcb = NULL; goto out; @@ -13605,10 +13514,8 @@ sctp_lower_sosend(struct socket *so, if ((queue_only == 0) && (nagle_applies == 0) && (stcb->asoc.peers_rwnd && un_sent)) { /* we can attempt to send too. */ if (hold_tcblock == 0) { - /* - * If there is activity recv'ing sacks no need to - * send - */ + /* If there is activity recv'ing sacks no need to + * send */ if (SCTP_TCB_TRYLOCK(stcb)) { sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_LOCKED); hold_tcblock = 1; @@ -13776,10 +13683,9 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro) SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, (struct sockaddr *)&gw6); SCTPDBG(SCTP_DEBUG_OUTPUT2, "installed router is "); SCTPDBG_ADDR(SCTP_DEBUG_OUTPUT2, ro->ro_rt->rt_gateway); - if (sctp_cmpaddr((struct sockaddr *)&gw6, - ro->ro_rt->rt_gateway)) { - SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is installed\n"); + if (sctp_cmpaddr((struct sockaddr *)&gw6, ro->ro_rt->rt_gateway)) { ND6_RUNLOCK(); + SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is installed\n"); return (1); } } @@ -13787,7 +13693,6 @@ sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t * ro) SCTPDBG(SCTP_DEBUG_OUTPUT2, "pfxrouter is not installed\n"); return (0); } - #endif int From 8798ef0679c07421dd7827acf3e7e9f08d610f48 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Sat, 22 Oct 2016 18:02:20 +0000 Subject: [PATCH 019/235] ddb(4): Add sleepchains to "show allchains" Reported by: markj Reviewed by: markj Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D8320 --- sys/kern/subr_turnstile.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/kern/subr_turnstile.c b/sys/kern/subr_turnstile.c index 57d9f0975d14..dd39835d0dc2 100644 --- a/sys/kern/subr_turnstile.c +++ b/sys/kern/subr_turnstile.c @@ -157,6 +157,9 @@ static void init_turnstile0(void *dummy); #ifdef TURNSTILE_PROFILING static void init_turnstile_profiling(void *arg); #endif +#ifdef DDB +static void print_sleepchain(struct thread *td, const char *prefix); +#endif static void propagate_priority(struct thread *td); static int turnstile_adjust_thread(struct turnstile *ts, struct thread *td); @@ -1169,6 +1172,10 @@ DB_SHOW_ALL_COMMAND(chains, db_show_allchains) db_printf("chain %d:\n", i++); print_lockchain(td, " "); } + if (TD_IS_INHIBITED(td) && TD_ON_SLEEPQ(td)) { + db_printf("chain %d:\n", i++); + print_sleepchain(td, " "); + } if (db_pager_quit) return; } From 4dddcb12459a28675cc6bae4758d89cd76064d4c Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 19:18:59 +0000 Subject: [PATCH 020/235] Import tzdata 2016h --- asia | 78 +++++++++++++++++++++++++--------------------------- australasia | 8 +++++- europe | 44 +++++++++++++++-------------- northamerica | 28 +++++++++++++++++-- 4 files changed, 93 insertions(+), 65 deletions(-) diff --git a/asia b/asia index 71ef8787b508..b2c993085319 100644 --- a/asia +++ b/asia @@ -2544,11 +2544,6 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # From Paul Eggert (2015-03-03): # http://www.timeanddate.com/time/change/west-bank/ramallah?year=2014 # says that the fall 2014 transition was Oct 23 at 24:00. -# For future dates, guess the last Friday in March at 24:00 through -# the first Friday on or after October 21 at 00:00. This is consistent with -# the predictions in today's editions of the following URLs: -# http://www.timeanddate.com/time/change/gaza-strip/gaza -# http://www.timeanddate.com/time/change/west-bank/hebron # From Hannah Kreitem (2016-03-09): # http://www.palestinecabinet.gov.ps/WebSite/ar/ViewDetails?ID=31728 @@ -2558,7 +2553,21 @@ Zone Asia/Karachi 4:28:12 - LMT 1907 # # From Paul Eggert (2016-03-12): # Predict spring transitions on March's last Saturday at 01:00 from now on. -# Leave fall predictions alone for now. + +# From Sharef Mustafa (2016-10-19): +# [T]he Palestinian cabinet decision (Mar 8th 2016) published on +# http://www.palestinecabinet.gov.ps/WebSite/Upload/Decree/GOV_17/16032016134830.pdf +# states that summer time will end on Oct 29th at 01:00. +# +# From Tim Parenti (2016-10-19): +# Predict fall transitions on October's last Saturday at 01:00 from now on. +# This is consistent with the 2016 transition as well as our spring +# predictions. +# +# From Paul Eggert (2016-10-19): +# It's also consistent with predictions in the following URLs today: +# http://www.timeanddate.com/time/change/gaza-strip/gaza +# http://www.timeanddate.com/time/change/west-bank/hebron # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule EgyptAsia 1957 only - May 10 0:00 1:00 S @@ -2587,9 +2596,10 @@ Rule Palestine 2011 only - Sep 30 0:00 0 - Rule Palestine 2012 2014 - Mar lastThu 24:00 1:00 S Rule Palestine 2012 only - Sep 21 1:00 0 - Rule Palestine 2013 only - Sep Fri>=21 0:00 0 - -Rule Palestine 2014 max - Oct Fri>=21 0:00 0 - +Rule Palestine 2014 2015 - Oct Fri>=21 0:00 0 - Rule Palestine 2015 only - Mar lastFri 24:00 1:00 S Rule Palestine 2016 max - Mar lastSat 1:00 1:00 S +Rule Palestine 2016 max - Oct lastSat 1:00 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Gaza 2:17:52 - LMT 1900 Oct @@ -2739,45 +2749,31 @@ Zone Asia/Singapore 6:55:25 - LMT 1901 Jan 1 # People who live in regions under Tamil control can use [TZ='Asia/Kolkata'], # as that zone has agreed with the Tamil areas since our cutoff date of 1970. -# From K Sethu (2006-04-25): -# I think the abbreviation LKT originated from the world of computers at -# the time of or subsequent to the time zone changes by SL Government -# twice in 1996 and probably SL Government or its standardization -# agencies never declared an abbreviation as a national standard. +# From Sadika Sumanapala (2016-10-19): +# According to http://www.sltime.org (maintained by Measurement Units, +# Standards & Services Department, Sri Lanka) abbreviation for Sri Lanka +# standard time is SLST. # -# I recollect before the recent change the government announcements -# mentioning it as simply changing Sri Lanka Standard Time or Sri Lanka -# Time and no mention was made about the abbreviation. -# -# If we look at Sri Lanka Department of Government's "Official News -# Website of Sri Lanka" ... http://www.news.lk/ we can see that they -# use SLT as abbreviation in time stamp at the beginning of each news -# item.... -# -# Within Sri Lanka I think LKT is well known among computer users and -# administrators. In my opinion SLT may not be a good choice because the -# nation's largest telcom / internet operator Sri Lanka Telcom is well -# known by that abbreviation - simply as SLT (there IP domains are -# slt.lk and sltnet.lk). -# -# But if indeed our government has adopted SLT as standard abbreviation -# (that we have not known so far) then it is better that it be used for -# all computers. - -# From Paul Eggert (2006-04-25): -# One possibility is that we wait for a bit for the dust to settle down -# and then see what people actually say in practice. +# From Paul Eggert (2016-10-18): +# "SLST" seems to be reasonably recent and rarely-used outside time +# zone nerd sources. I searched Google News and found three uses of +# it in the International Business Times of India in February and +# March of this year when discussing cricket match times, but nothing +# since then (though there has been a lot of cricket) and nothing in +# other English-language news sources. Our old abbreviation "LKT" is +# even worse. For now, let's use a numeric abbreviation; we can +# switch to "SLST" if it catches on. # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Asia/Colombo 5:19:24 - LMT 1880 5:19:32 - MMT 1906 # Moratuwa Mean Time - 5:30 - IST 1942 Jan 5 - 5:30 0:30 IHST 1942 Sep - 5:30 1:00 IST 1945 Oct 16 2:00 - 5:30 - IST 1996 May 25 0:00 - 6:30 - LKT 1996 Oct 26 0:30 - 6:00 - LKT 2006 Apr 15 0:30 - 5:30 - IST + 5:30 - +0530 1942 Jan 5 + 5:30 0:30 +0530/+06 1942 Sep + 5:30 1:00 +0530/+0630 1945 Oct 16 2:00 + 5:30 - +0530 1996 May 25 0:00 + 6:30 - +0630 1996 Oct 26 0:30 + 6:00 - +06 2006 Apr 15 0:30 + 5:30 - +0530 # Syria # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S diff --git a/australasia b/australasia index f49df1d6e107..85d363295b88 100644 --- a/australasia +++ b/australasia @@ -350,7 +350,13 @@ Zone Indian/Cocos 6:27:40 - LMT 1900 # commencing at 2.00 am on Sunday 1st November, 2015 and ending at # 3.00 am on Sunday 17th January, 2016. -# From Paul Eggert (2015-09-01): +# From Raymond Kumar (2016-10-04): +# http://www.fiji.gov.fj/Media-Center/Press-Releases/DAYLIGHT-SAVING-STARTS-ON-6th-NOVEMBER,-2016.aspx +# "Fiji's daylight savings will begin on Sunday, 6 November 2016, when +# clocks go forward an hour at 2am to 3am.... Daylight Saving will +# end at 3.00am on Sunday 15th January 2017." + +# From Paul Eggert (2016-10-03): # For now, guess DST from 02:00 the first Sunday in November to # 03:00 the third Sunday in January. Although ad hoc, it matches # transitions since late 2014 and seems more likely to match future diff --git a/europe b/europe index 6020059f696b..a7dc350d1ebf 100644 --- a/europe +++ b/europe @@ -1908,7 +1908,7 @@ Zone Europe/Monaco 0:29:32 - LMT 1891 Mar 15 # Amsterdam mean time. # The data entries before 1945 are taken from -# http://www.phys.uu.nl/~vgent/wettijd/wettijd.htm +# http://www.staff.science.uu.nl/~gent0113/idl/idl.htm # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Neth 1916 only - May 1 0:00 1:00 NST # Netherlands Summer Time @@ -3427,22 +3427,24 @@ Zone Europe/Zurich 0:34:08 - LMT 1853 Jul 16 # See above comment. # Turkey -# From Amar Devegowda (2007-01-03): -# The time zone rules for Istanbul, Turkey have not been changed for years now. -# ... The latest rules are available at: -# http://www.timeanddate.com/worldclock/timezone.html?n=107 -# From Steffen Thorsen (2007-01-03): -# I have been able to find press records back to 1996 which all say that -# DST started 01:00 local time and end at 02:00 local time. I am not sure -# what happened before that. One example for each year from 1996 to 2001: -# http://newspot.byegm.gov.tr/arsiv/1996/21/N4.htm -# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING97/03/97X03X25.TXT -# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING98/03/98X03X02.HTM -# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING99/10/99X10X26.HTM#%2016 -# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2000/03/00X03X06.HTM#%2021 -# http://www.byegm.gov.tr/YAYINLARIMIZ/CHR/ING2001/03/23x03x01.HTM#%2027 -# From Paul Eggert (2007-01-03): -# Prefer the above source to Shanks & Pottenger for time stamps after 1990. +# From Kıvanç Yazan (2016-09-25): +# 1) For 1986-2006, DST started at 01:00 local and ended at 02:00 local, with +# no exceptions. +# 2) 1994's lastSun was overridden with Mar 20 ... +# Here are official papers: +# http://www.resmigazete.gov.tr/arsiv/19032.pdf - page 2 for 1986 +# http://www.resmigazete.gov.tr/arsiv/19400.pdf - page 4 for 1987 +# http://www.resmigazete.gov.tr/arsiv/19752.pdf - page 15 for 1988 +# http://www.resmigazete.gov.tr/arsiv/20102.pdf - page 6 for 1989 +# http://www.resmigazete.gov.tr/arsiv/20464.pdf - page 1 for 1990 - 1992 +# http://www.resmigazete.gov.tr/arsiv/21531.pdf - page 15 for 1993 - 1995 +# http://www.resmigazete.gov.tr/arsiv/21879.pdf - page 1 for overriding 1994 +# http://www.resmigazete.gov.tr/arsiv/22588.pdf - page 1 for 1996, 1997 +# http://www.resmigazete.gov.tr/arsiv/23286.pdf - page 10 for 1998 - 2000 +# http://www.resmigazete.gov.tr/eskiler/2001/03/20010324.htm#2 - for 2001 +# http://www.resmigazete.gov.tr/eskiler/2002/03/20020316.htm#2 - for 2002-2006 +# From Paul Eggert (2016-09-25): +# Prefer the above sources to Shanks & Pottenger for time stamps after 1985. # From Steffen Thorsen (2007-03-09): # Starting 2007 though, it seems that they are adopting EU's 1:00 UTC @@ -3551,10 +3553,10 @@ Rule Turkey 1983 only - Jul 31 0:00 1:00 S Rule Turkey 1983 only - Oct 2 0:00 0 - Rule Turkey 1985 only - Apr 20 0:00 1:00 S Rule Turkey 1985 only - Sep 28 0:00 0 - -Rule Turkey 1986 1990 - Mar lastSun 2:00s 1:00 S -Rule Turkey 1986 1990 - Sep lastSun 2:00s 0 - -Rule Turkey 1991 2006 - Mar lastSun 1:00s 1:00 S -Rule Turkey 1991 1995 - Sep lastSun 1:00s 0 - +Rule Turkey 1986 1993 - Mar lastSun 1:00s 1:00 S +Rule Turkey 1986 1995 - Sep lastSun 1:00s 0 - +Rule Turkey 1994 only - Mar 20 1:00s 1:00 S +Rule Turkey 1995 2006 - Mar lastSun 1:00s 1:00 S Rule Turkey 1996 2006 - Oct lastSun 1:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Europe/Istanbul 1:55:52 - LMT 1880 diff --git a/northamerica b/northamerica index 0bafb00a22c3..e1ed9e4a8720 100644 --- a/northamerica +++ b/northamerica @@ -24,8 +24,32 @@ # was the result of his proposals at the Convention of Railroad Trunk Lines # in New York City (1869-10). His 1870 proposal was based on Washington, DC, # but in 1872-05 he moved the proposed origin to Greenwich. -# His proposal was adopted by the railroads on 1883-11-18 at 12:00, -# and the most of the country soon followed suit. + +# From Paul Eggert (2016-09-21): +# Dowd's proposal left many details unresolved, such as where to draw +# lines between time zones. The key individual who made time zones +# work in the US was William Frederick Allen - railway engineer, +# managing editor of the Travelers' Guide, and secretary of the +# General Time Convention, a railway standardization group. Allen +# spent months in dialogs with scientific and railway leaders, +# developed a workable plan to institute time zones, and presented it +# to the General Time Convention on 1883-04-11, saying that his plan +# meant "local time would be practically abolished" - a plus for +# railway scheduling. By the next convention on 1883-10-11 nearly all +# railroads had agreed and it took effect on 1883-11-18 at 12:00. +# That Sunday was called the "day of two noons", as the eastern parts +# of the new zones observed noon twice. Allen witnessed the +# transition in New York City, writing: +# +# I heard the bells of St. Paul's strike on the old time. Four +# minutes later, obedient to the electrical signal from the Naval +# Observatory ... the time-ball made its rapid descent, the chimes +# of old Trinity rang twelve measured strokes, and local time was +# abandoned, probably forever. +# +# Most of the US soon followed suit. See: +# Bartky IR. The adoption of standard time. Technol Cult 1989 Jan;30(1):25-56. +# http://dx.doi.org/10.2307/3105430 # From Paul Eggert (2005-04-16): # That 1883 transition occurred at 12:00 new time, not at 12:00 old time. From e58d31ade5a76c689424819f1f2e8a6fcb01ffaf Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 22 Oct 2016 19:27:49 +0000 Subject: [PATCH 021/235] Fix a typo from a manual merge. --- gnu/usr.bin/cc/Makefile.tgt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gnu/usr.bin/cc/Makefile.tgt b/gnu/usr.bin/cc/Makefile.tgt index 0337ecf2bfcb..ca2d2ed43e26 100644 --- a/gnu/usr.bin/cc/Makefile.tgt +++ b/gnu/usr.bin/cc/Makefile.tgt @@ -4,7 +4,7 @@ # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64spe)/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif From a358681e90be015178e98c11049f662397c750af Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 19:36:12 +0000 Subject: [PATCH 022/235] Import pci_vendors 2016.10.20 --- share/misc/pci_vendors | 88 ++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 21 deletions(-) diff --git a/share/misc/pci_vendors b/share/misc/pci_vendors index 2bc34d3c42d1..3d9c83c3e2d4 100644 --- a/share/misc/pci_vendors +++ b/share/misc/pci_vendors @@ -3,8 +3,8 @@ # # List of PCI ID's # -# Version: 2016.10.03 -# Date: 2016-10-03 03:15:01 +# Version: 2016.10.20 +# Date: 2016-10-20 03:15:02 # # Maintained by Albert Pool, Martin Mares, and other volunteers from # the PCI ID Project at http://pci-ids.ucw.cz/. @@ -245,8 +245,13 @@ 0013 53c875a 1000 1000 LSI53C875A PCI to Ultra SCSI Controller 0014 MegaRAID Tri-Mode SAS3516 + 1028 1fd4 PERC H745P MX 1d49 0602 ThinkSystem RAID 930-16i 4GB Flash PCIe 12Gb Adapter 0016 MegaRAID Tri-Mode SAS3508 + 1028 1fc9 PERC H840 Adapter + 1028 1fcb PERC H740P Adapter + 1028 1fcd PERC H740P Mini + 1028 1fcf PERC H740P Mini 1d49 0601 ThinkSystem RAID 930-8i 2GB Flash PCIe 12Gb Adapter 1d49 0603 ThinkSystem RAID 930-24i 4GB Flash PCIe 12Gb Adapter 1d49 0604 ThinkSystem RAID 930-8e 4GB Flash PCIe 12Gb Adapter @@ -376,6 +381,7 @@ 1028 1f4d PERC FD33xS 1028 1f4f PERC H730P Slim 1028 1f54 PERC FD33xD + 1028 1fd1 PERC H730P MX 17aa 1052 ThinkServer RAID 720i 17aa 1053 ThinkServer RAID 720ix 1d49 0600 ThinkSystem RAID 730-8i 1GB Cache PCIe 12Gb Adapter @@ -535,8 +541,11 @@ 0097 SAS3008 PCI-Express Fusion-MPT SAS-3 1000 3090 SAS9311-8i 1000 30e0 SAS9300-8i - 1028 1f45 12GB/s HBA internal + 1028 1f45 HBA330 Adapter 1028 1f46 12Gbps HBA + 1028 1f53 HBA330 Mini + 1028 1fd2 HBA330 MX + 1028 1fd3 HBA330 MMZ 00ab SAS3516 Fusion-MPT Tri-Mode RAID On Chip (ROC) 00ac SAS3416 Fusion-MPT Tri-Mode I/O Controller Chip (IOC) 1d49 0201 ThinkSystem 9400-16i PCIe 12Gb HBA @@ -1588,7 +1597,7 @@ 1462 2938 Radeon R9 360 OEM 1462 3271 Radeon R9 360 OEM 1682 7360 Radeon R7 360 - 6660 Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330] + 6660 Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330 / M430] 1028 05ea Radeon HD 8670M 1028 06bf Radeon R5 M335 103c 1970 Radeon HD 8670M @@ -1596,6 +1605,7 @@ 103c 8136 Radeon R5 M330 17aa 3804 Radeon R5 M330 17aa 3809 Radeon R5 M330 + 17aa 381a Radeon R5 M430 17aa 390c Radeon R5 M330 6663 Sun PRO [Radeon HD 8570A/8570M] 1025 0846 Radeon HD 8570A @@ -2866,11 +2876,12 @@ 174b e180 Radeon HD 7350 17af 3015 Radeon HD 7350 68fe Cedar LE - 6900 Topaz XT [Radeon R7 M260/M265 / M340/M360] + 6900 Topaz XT [Radeon R7 M260/M265 / M340/M360 / M440/M445] 1025 1056 Radeon R7 M360 / R8 M365DX 1028 0640 Radeon R7 M260/M265 1028 0643 Radeon R7 M260/M265 1028 067f Radeon R7 M260 + 1028 0767 Radeon R7 M445 1028 130a Radeon R7 M260 103c 2263 Radeon R7 M260 103c 2269 Radeon R7 M260 @@ -2881,6 +2892,7 @@ 103c 80b5 Radeon R7 M360 103c 80b9 Radeon R7 M360 103c 811c Radeon R7 M340 + 103c 8226 Radeon R7 M440 10cf 1906 Radeon R7 M260 1170 9979 Radeon R7 M360 1179 f903 Radeon R7 M260 @@ -2892,6 +2904,7 @@ 17aa 5021 Radeon R7 M260 6901 Topaz PRO [Radeon R5 M255] 103c 1318 Radeon R6 M255DX + 6907 Meso XT [Radeon R5 M315] 6921 Amethyst XT [Radeon R9 M295X] 6929 Tonga XT GL [FirePro S7150] 692b Tonga PRO GL [FirePro W7100] @@ -3349,7 +3362,7 @@ 99a4 Trinity [Radeon HD 7400G] aa00 R600 HDMI Audio [Radeon HD 2900 GT/PRO/XT] aa01 RV635 HDMI Audio [Radeon HD 3650/3730/3750] - aa08 RV630 HDMI Audio [Radeon HD 2600 Series] + aa08 RV630 HDMI Audio [Radeon HD 2600 PRO/XT / HD 3610] aa10 RV610 HDMI Audio [Radeon HD 2350 PRO / 2400 PRO/XT / HD 3410] 174b aa10 Radeon HD 2400 PRO 18bc aa10 Radeon HD 2400 PRO @@ -3369,10 +3382,10 @@ aa68 Cedar HDMI Audio [Radeon HD 5400/6300/7300 Series] 1028 aa68 XPS 8300 aa80 Cayman/Antilles HDMI Audio [Radeon HD 6930/6950/6970/6990] - aa88 Barts HDMI Audio [Radeon HD 6800 Series] + aa88 Barts HDMI Audio [Radeon HD 6790/6850/6870 / 7720 OEM] aa90 Turks HDMI Audio [Radeon HD 6500/6600 / 6700M Series] 1028 04a3 Precision M4600 - aa98 Caicos HDMI Audio [Radeon HD 6400 Series] + aa98 Caicos HDMI Audio [Radeon HD 6450 / 7450/8450/8490 OEM / R5 230/235/235X OEM] 174b aa98 Radeon HD 6450 1GB DDR3 aaa0 Tahiti HDMI Audio [Radeon HD 7870 XT / 7950/7970] aab0 Cape Verde/Pitcairn HDMI Audio [Radeon HD 7700/7800 Series] @@ -7347,6 +7360,7 @@ 8533 PEX 8533 32-lane, 6-port PCI Express Switch 8547 PEX 8547 48-lane, 3-port PCI Express Switch 8548 PEX 8548 48-lane, 9-port PCI Express Switch + 8603 PEX 8603 3-lane, 3-Port PCI Express Gen 2 (5.0 GT/s) Switch 8604 PEX 8604 4-lane, 4-Port PCI Express Gen 2 (5.0 GT/s) Switch 8605 PEX 8605 PCI Express 4-port Gen2 Switch 8606 PEX 8606 6 Lane, 6 Port PCI Express Gen 2 (5.0 GT/s) Switch @@ -17921,7 +17935,7 @@ 1015 MT27710 Family [ConnectX-4 Lx] 1016 MT27710 Family [ConnectX-4 Lx Virtual Function] 1017 MT27800 Family [ConnectX-5] - 1018 MT28800 Family [ConnectX-5 Virtual Function] + 1018 MT27800 Family [ConnectX-5 Virtual Function] 1019 MT28800 Family [ConnectX-5 Ex] 101a MT28800 Family [ConnectX-5 Ex Virtual Function] 101b MT28831 @@ -17932,6 +17946,7 @@ 1020 MT28860 1021 MT28861 1974 MT28800 Family [ConnectX-5 PCIe Bridge] + 1975 MT416842 Family [BlueField SoC PCIe Bridge] 5274 MT21108 InfiniBridge 5a44 MT23108 InfiniHost 5a45 MT23108 [Infinihost HCA Flash Recovery] @@ -17966,6 +17981,9 @@ 7121 NPS-600 configuration and management interface 7122 NPS-600 network interface PF 7123 NPS-600 network interface VF + a2d0 MT416842 + a2d1 MT416842 + a2d3 MT416842 BlueField multicore SoC family VF # SwitchX-2, 40GbE switch c738 MT51136 c739 MT51136 GW @@ -18638,7 +18656,12 @@ 7018 AP408: 32-Channel Digital I/O Module 701a AP220-16 12-Bit, 16-Channel Analog Output Module 701b AP231-16 16-Bit, 16-Channel Analog Output Module + 7021 APA7-201 Reconfigurable Artix-7 FPGA module 48 TTL channels + 7022 APA7-202 Reconfigurable Artix-7 FPGA module 24 RS485 channels + 7023 APA7-203 Reconfigurable Artix-7 FPGA module 24 TTL & 12 RS485 channels + 7024 APA7-204 Reconfigurable Artix-7 FPGA module 24 LVDS channels 7042 AP482 Counter Timer Module with TTL Level Input/Output + 7043 AP483 Counter Timer Module with TTL Level and RS422 Input/Output 7044 AP484 Counter Timer Module with RS422 Input/Output 16da Advantech Co., Ltd. 0011 INES GPIB-PCI @@ -18881,6 +18904,7 @@ 0401 Datacenter Technologies QDF2400 PCI Express Root Port 17cc NetChip Technology, Inc 2280 USB 2.0 +17cd Cadence Design Systems, Inc. 17cf Z-Com, Inc. 17d3 Areca Technology Corp. 1110 ARC-1110 4-Port PCI-X to SATA RAID Controller @@ -20290,7 +20314,8 @@ 1432 8102 EN-8102P 10GbE Ethernet Adapter 1fc9 3015 Ethernet Adapter 4026 TN9610 10GbE SFP+ Ethernet Adapter - 4027 TN9710 10GBase-T/NBASE-T Ethernet Adapter + 4027 TN9710P 10GBase-T/NBASE-T Ethernet Adapter + 4527 TN9710Q 5GBase-T/NBASE-T Ethernet Adapter 1fcc StreamLabs f416 MS416 fb01 MH4LM @@ -22295,6 +22320,7 @@ 17aa 4007 82599ES 10-Gigabit SFI/SFP+ Network Connection 17aa 402b 82599ES 10Gb 2-port Server Adapter X520-DA2 17aa 402f FPGA Card XC7VX690T-3FFG1157E + 18d4 0c09 82599ES 10Gb 2-port SFP+ OCP Mezz Card MOP81-I-10GS2 1bd4 001b 10G SFP+ DP ER102Fi4 Rack Adapter 1bd4 002f 10G SFP+ DP EP102Fi4A Adapter 1bd4 0032 10G SFP+ DP EP102Fi4 Adapter @@ -22570,8 +22596,15 @@ 1520 I350 Ethernet Controller Virtual Function 1521 I350 Gigabit Network Connection 1028 0602 Gigabit 2P I350-t LOM + 1028 0693 Gigabit 2P I350-t LOM + 1028 06e2 Gigabit 2P I350-t LOM + 1028 0757 Gigabit I350-t LOM + 1028 075a Gigabit I350-t LOM 1028 1f60 Gigabit 4P I350-t rNDC 1028 1f62 Gigabit 4P X540/I350 rNDC + 1028 1fa8 Ethernet 10G 4P X550/I350 rNDC + 1028 1fa9 Ethernet 10G 4P X550 rNDC + 1028 1faa Gigabit 4P X550/I350 rNDC 1028 ff9a Gigabit 4P X710/I350 rNDC 103c 17d1 Ethernet 1Gb 4-port 366FLR Adapter 103c 2003 Ethernet 1Gb 2-port 367i Adapter @@ -22590,6 +22623,7 @@ 15d9 0652 Dual Port i350 GbE MicroLP [AOC-CGP-i2] 17aa 1074 ThinkServer I350-T4 AnyFabric 17aa 4005 I350 Gigabit Network Connection + 18d4 0c07 I350 1Gb 2-port RJ45 OCP Mezz Card MOP41-I-1GT2 1bd4 001d 1G base-T QP EP014Ti1 Adapter 1bd4 0035 1G base-T QP EP014Ti1 Adapter 8086 0001 Ethernet Server Adapter I350-T4 @@ -22698,6 +22732,7 @@ 1028 1fa9 Ethernet 10G 4P X550 rNDC 1590 00d1 Ethernet 10Gb 2-port 562T Adapter 1590 00d2 Ethernet 10Gb 2-port 562FLR-T Adapter + 18d4 0c08 X550 10Gb 2-port RJ45 OCP Mezz Card MOP81-I-10GT2 8086 0001 Ethernet Converged Network Adapter X550-T2 8086 001a Ethernet Converged Network Adapter X550-T2 8086 0022 Ethernet Converged Network Adapter X550-T2 @@ -22782,11 +22817,11 @@ 108e 0000 Ethernet Controller X710 for 10GBASE-T 108e 4857 Ethernet Controller X710 for 10GBASE-T 1587 Ethernet Controller XL710 for 20GbE backplane - 103c 0000 HP Flex-20 20Gb 2-port 660FLB Adapter - 103c 22fe HP Flex-20 20Gb 2-port 660FLB Adapter + 103c 0000 HPE Ethernet 10/20Gb 2-port 660FLB Adapter + 103c 22fe HPE Ethernet 10/20Gb 2-port 660FLB Adapter 1588 Ethernet Controller XL710 for 20GbE backplane - 103c 0000 HP Flex-20 20Gb 2-port 660M Adapter - 103c 22ff HP Flex-20 20Gb 2-port 660M Adapter + 103c 0000 HPE Ethernet 10/20Gb 2-port 660M Adapter + 103c 22ff HPE Ethernet 10/20Gb 2-port 660M Adapter 1589 Ethernet Controller X710/X557-AT 10GBASE-T 108e 0000 Quad Port 10GBase-T Adapter 108e 7b1c Quad Port 10GBase-T Adapter @@ -23169,7 +23204,7 @@ 1e09 7 Series Chipset Family 2-port SATA Controller [IDE mode] 144d c652 NP300E5C series laptop 1e0e 7 Series/C210 Series Chipset Family SATA Controller [RAID mode] - 1e10 7 Series/C210 Series Chipset Family PCI Express Root Port 1 + 1e10 7 Series/C216 Chipset Family PCI Express Root Port 1 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A @@ -23181,7 +23216,7 @@ 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1e14 7 Series/C210 Series Chipset Family PCI Express Root Port 3 - 1e16 7 Series/C210 Series Chipset Family PCI Express Root Port 4 + 1e16 7 Series/C216 Chipset Family PCI Express Root Port 4 1043 108d VivoBook X202EV 1043 1477 N56VZ 144d c652 NP300E5C series laptop @@ -23194,7 +23229,7 @@ 1e1c 7 Series/C210 Series Chipset Family PCI Express Root Port 7 1e1e 7 Series/C210 Series Chipset Family PCI Express Root Port 8 1849 1e1e Motherboard - 1e20 7 Series/C210 Series Chipset Family High Definition Audio Controller + 1e20 7 Series/C216 Chipset Family High Definition Audio Controller 1028 054b Dell XPS One 2710 1043 108d VivoBook X202EV 1043 1477 N56VZ @@ -23203,7 +23238,7 @@ 1043 8445 ASUS P8Z77-V LX Motherboard 144d c652 NP300E5C series laptop 1849 1898 Z77 Extreme4 motherboard - 1e22 7 Series/C210 Series Chipset Family SMBus Controller + 1e22 7 Series/C216 Chipset Family SMBus Controller 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A @@ -23213,14 +23248,14 @@ 1e24 7 Series/C210 Series Chipset Family Thermal Management Controller 1043 1517 Zenbook Prime UX31A 1e25 7 Series/C210 Series Chipset Family DMI to PCI Bridge - 1e26 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #1 + 1e26 7 Series/C216 Chipset Family USB Enhanced Host Controller #1 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A 1043 84ca P8 series motherboard 144d c652 NP300E5C series laptop 1849 1e26 Motherboard - 1e2d 7 Series/C210 Series Chipset Family USB Enhanced Host Controller #2 + 1e2d 7 Series/C216 Chipset Family USB Enhanced Host Controller #2 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A @@ -23235,7 +23270,7 @@ 1043 84ca P8 series motherboard 1849 1e31 Motherboard 1e33 7 Series/C210 Series Chipset Family LAN Controller - 1e3a 7 Series/C210 Series Chipset Family MEI Controller #1 + 1e3a 7 Series/C216 Chipset Family MEI Controller #1 1043 108d VivoBook X202EV 1043 1477 N56VZ 1043 1517 Zenbook Prime UX31A @@ -26234,10 +26269,21 @@ 37cd X722 Virtual Function 37ce Ethernet Connection X722 for 10GbE backplane 1590 0215 Ethernet 10Gb 2-port 568i Adapter + 17aa 4023 Intel Ethernet Connection X722 for 10GbE backplane 37cf Ethernet Connection X722 for 10GbE QSFP+ 37d0 Ethernet Connection X722 for 10GbE SFP+ 37d1 Ethernet Connection X722 for 1GbE + 17aa 4020 Intel Ethernet Connection X722 for 1GbE + 17aa 4021 Intel Ethernet Connection X722 for 1GbE + 17aa 4022 Intel Ethernet Connection X722 for 1GbE + 8086 4020 Ethernet Connection X722 for 1GbE + 8086 4021 Ethernet Connection X722 for 1GbE + 8086 4022 Ethernet Connection X722 for 1GbE 37d2 Ethernet Connection X722 for 10GBASE-T + 17aa 4020 Intel Ethernet Connection X722 for 10GBASE + 17aa 4021 Intel Ethernet Connection X722 for 10GBASE + 8086 4020 Ethernet Connection X722 for 10GBASE + 8086 4021 Ethernet Connection X722 for 10GBASE 37d3 Ethernet Connection X722 for 10GbE SFP+ 37d4 Ethernet Connection X722 for 10GbE QSFP+ 37d9 X722 Hyper-V Virtual Function From 62352309a86bfc581195af028dddd4fcdd15f3ef Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 19:51:32 +0000 Subject: [PATCH 023/235] Do not install NIS program rc script if WITHOUT_NIS is set PR: 213375 Submitted by: sergey@akhmatov.ru MFC after: 3 days --- etc/rc.d/Makefile | 7 +++++-- tools/build/mk/OptionalObsoleteFiles.inc | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index ad43a20a268f..320e550aeb8a 100644 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -118,14 +118,17 @@ FILES= DAEMON \ ugidfw \ ${_utx} \ var \ - watchdogd \ - ypbind \ + watchdogd + +.if ${MK_NIS} != "no" +FILES+= ypbind \ ypldap \ yppasswdd \ ypserv \ ypset \ ypupdated \ ypxfrd +.endif .if ${MK_ACCT} != "no" FILESGROUPS+= ACCT diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index b4b7a26a7521..cb17b4f029a9 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -6113,6 +6113,13 @@ OLD_FILES+=usr/share/snmp/mibs/BEGEMOT-NETGRAPH.txt .endif .if ${MK_NIS} == no +OLD_FILES+=etc/rc.d/ypbind +OLD_FILES+=etc/rc.d/ypldap +OLD_FILES+=etc/rc.d/yppasswdd +OLD_FILES+=etc/rc.d/ypserv +OLD_FILES+=etc/rc.d/ypset +OLD_FILES+=etc/rc.d/ypupdated +OLD_FILES+=etc/rc.d/ypxfrd OLD_FILES+=usr/bin/ypcat OLD_FILES+=usr/bin/ypchfn OLD_FILES+=usr/bin/ypchpass From 7652bc12babc530b86c0503ab2ba0e07cd01bba9 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 20:00:39 +0000 Subject: [PATCH 024/235] Fix typo in the COMPILER_VERSION check PR: 213120 Submitted by: Yuta Satoh MFC after: 3 days --- sys/boot/efi/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/efi/Makefile b/sys/boot/efi/Makefile index 21da86f3aaa2..66481f8513fc 100644 --- a/sys/boot/efi/Makefile +++ b/sys/boot/efi/Makefile @@ -4,7 +4,7 @@ # In-tree GCC does not support __attribute__((ms_abi)), but gcc newer # than 4.5 supports it. -.if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 404500 +.if ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500 .if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" .if ${MK_FDT} != "no" @@ -18,6 +18,6 @@ SUBDIR+= fdt SUBDIR+= libefi loader boot1 .endif -.endif # ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 404500 +.endif # ${COMPILER_TYPE} != "gcc" || ${COMPILER_VERSION} >= 40500 .include From 54360de77b19d4dffd77c181f2ce2846f79edad4 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 22 Oct 2016 21:51:58 +0000 Subject: [PATCH 025/235] Reduce code duplication between powerpc and powerpcspe They're nearly identical except for a few files. Reported by: kib --- lib/libc/powerpc/gen/Makefile.common | 6 ++ lib/libc/powerpc/gen/Makefile.inc | 12 +-- lib/libc/powerpcspe/Makefile.inc | 1 + lib/libc/powerpcspe/SYS.h | 70 -------------- lib/libc/powerpcspe/_fpmath.h | 49 ---------- lib/libc/powerpcspe/arith.h | 16 ---- lib/libc/powerpcspe/gd_qnan.h | 21 ----- lib/libc/powerpcspe/gen/Makefile.inc | 12 +-- lib/libc/powerpcspe/gen/_ctx_start.S | 46 --------- lib/libc/powerpcspe/gen/_set_tp.c | 35 ------- lib/libc/powerpcspe/gen/eabi.S | 34 ------- lib/libc/powerpcspe/gen/infinity.c | 17 ---- lib/libc/powerpcspe/gen/makecontext.c | 120 ------------------------ lib/libc/powerpcspe/gen/signalcontext.c | 103 -------------------- lib/libc/powerpcspe/gen/syncicache.c | 103 -------------------- lib/libc/powerpcspe/sys/Makefile.inc | 8 +- lib/libc/powerpcspe/sys/brk.S | 76 --------------- lib/libc/powerpcspe/sys/cerror.S | 58 ------------ lib/libc/powerpcspe/sys/exect.S | 42 --------- lib/libc/powerpcspe/sys/sbrk.S | 73 -------------- lib/libc/powerpcspe/sys/setlogin.S | 51 ---------- 21 files changed, 17 insertions(+), 936 deletions(-) create mode 100644 lib/libc/powerpc/gen/Makefile.common delete mode 100644 lib/libc/powerpcspe/SYS.h delete mode 100644 lib/libc/powerpcspe/_fpmath.h delete mode 100644 lib/libc/powerpcspe/arith.h delete mode 100644 lib/libc/powerpcspe/gd_qnan.h delete mode 100644 lib/libc/powerpcspe/gen/_ctx_start.S delete mode 100644 lib/libc/powerpcspe/gen/_set_tp.c delete mode 100644 lib/libc/powerpcspe/gen/eabi.S delete mode 100644 lib/libc/powerpcspe/gen/infinity.c delete mode 100644 lib/libc/powerpcspe/gen/makecontext.c delete mode 100644 lib/libc/powerpcspe/gen/signalcontext.c delete mode 100644 lib/libc/powerpcspe/gen/syncicache.c delete mode 100644 lib/libc/powerpcspe/sys/brk.S delete mode 100644 lib/libc/powerpcspe/sys/cerror.S delete mode 100644 lib/libc/powerpcspe/sys/exect.S delete mode 100644 lib/libc/powerpcspe/sys/sbrk.S delete mode 100644 lib/libc/powerpcspe/sys/setlogin.S diff --git a/lib/libc/powerpc/gen/Makefile.common b/lib/libc/powerpc/gen/Makefile.common new file mode 100644 index 000000000000..4ba72799a5cf --- /dev/null +++ b/lib/libc/powerpc/gen/Makefile.common @@ -0,0 +1,6 @@ +# $FreeBSD$ + +.PATH: ${LIBC_SRCTOP}/powerpc/gen + +SRCS += _ctx_start.S eabi.S infinity.c ldexp.c makecontext.c \ + signalcontext.c syncicache.c _set_tp.c trivial-getcontextx.c diff --git a/lib/libc/powerpc/gen/Makefile.inc b/lib/libc/powerpc/gen/Makefile.inc index 2a00ba332b94..368887e1ac9e 100644 --- a/lib/libc/powerpc/gen/Makefile.inc +++ b/lib/libc/powerpc/gen/Makefile.inc @@ -1,11 +1,7 @@ # $FreeBSD$ -SRCS += _ctx_start.S eabi.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ +.include "${LIBC_SRC}/powerpc/gen/Makefile.common" + +SRCS += fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ fpgetsticky.c fpsetmask.c fpsetround.c \ - infinity.c ldexp.c makecontext.c _setjmp.S \ - setjmp.S sigsetjmp.S signalcontext.c syncicache.c \ - _set_tp.c \ - trivial-getcontextx.c - - - + _setjmp.S setjmp.S sigsetjmp.S diff --git a/lib/libc/powerpcspe/Makefile.inc b/lib/libc/powerpcspe/Makefile.inc index 05d1e44f8b82..c5cb1ba47245 100644 --- a/lib/libc/powerpcspe/Makefile.inc +++ b/lib/libc/powerpcspe/Makefile.inc @@ -1,5 +1,6 @@ # $FreeBSD$ +CFLAGS+= -I${LIBC_SRCTOP}/powerpc SRCS+= trivial-vdso_tc.c # Long double is 64-bits diff --git a/lib/libc/powerpcspe/SYS.h b/lib/libc/powerpcspe/SYS.h deleted file mode 100644 index f0665c09c144..000000000000 --- a/lib/libc/powerpcspe/SYS.h +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * Copyright (c) 2002 Benno Rice. All rights reserved. - * Copyright (c) 2002 David E. O'Brien. 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. - * 3. Neither the name of the author nor the names of any contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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 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. - * - * $NetBSD: SYS.h,v 1.8 2002/01/14 00:55:56 thorpej Exp $ - * $FreeBSD$ - */ - -#include -#include - -#define _SYSCALL(name) \ - .text; \ - .align 2; \ - li 0,(SYS_##name); \ - sc - -#define SYSCALL(name) \ - .text; \ - .align 2; \ -2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ -ENTRY(__sys_##name); \ - WEAK_REFERENCE(__sys_##name, name); \ - WEAK_REFERENCE(__sys_##name, _##name); \ - _SYSCALL(name); \ - bso 2b - -#define PSEUDO(name) \ - .text; \ - .align 2; \ -ENTRY(__sys_##name); \ - WEAK_REFERENCE(__sys_##name, _##name); \ - _SYSCALL(name); \ - bnslr; \ - b PIC_PLT(CNAME(HIDENAME(cerror))) - -#define RSYSCALL(name) \ - .text; \ - .align 2; \ -2: b PIC_PLT(CNAME(HIDENAME(cerror))); \ -ENTRY(__sys_##name); \ - WEAK_REFERENCE(__sys_##name, name); \ - WEAK_REFERENCE(__sys_##name, _##name); \ - _SYSCALL(name); \ - bnslr; \ - b PIC_PLT(CNAME(HIDENAME(cerror))) diff --git a/lib/libc/powerpcspe/_fpmath.h b/lib/libc/powerpcspe/_fpmath.h deleted file mode 100644 index 6d80eb4bdf4e..000000000000 --- a/lib/libc/powerpcspe/_fpmath.h +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright (c) 2003 David Schultz - * 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$ - */ - -union IEEEl2bits { - long double e; - struct { - unsigned int sign :1; - unsigned int exp :11; - unsigned int manh :20; - unsigned int manl :32; - } bits; -}; - -#define mask_nbit_l(u) ((void)0) -#define LDBL_IMPLICIT_NBIT -#define LDBL_NBIT 0 - -#define LDBL_MANH_SIZE 20 -#define LDBL_MANL_SIZE 32 - -#define LDBL_TO_ARRAY32(u, a) do { \ - (a)[0] = (uint32_t)(u).bits.manl; \ - (a)[1] = (uint32_t)(u).bits.manh; \ -} while(0) diff --git a/lib/libc/powerpcspe/arith.h b/lib/libc/powerpcspe/arith.h deleted file mode 100644 index 8e2c9ec597b3..000000000000 --- a/lib/libc/powerpcspe/arith.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * MD header for contrib/gdtoa - * - * $FreeBSD$ - */ - -/* - * NOTE: The definitions in this file must be correct or strtod(3) and - * floating point formats in printf(3) will break! The file can be - * generated by running contrib/gdtoa/arithchk.c on the target - * architecture. See contrib/gdtoa/gdtoaimp.h for details. - */ - -#define IEEE_MC68k -#define Arith_Kind_ASL 2 -#define Double_Align diff --git a/lib/libc/powerpcspe/gd_qnan.h b/lib/libc/powerpcspe/gd_qnan.h deleted file mode 100644 index d70d8c318c4c..000000000000 --- a/lib/libc/powerpcspe/gd_qnan.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * MD header for contrib/gdtoa - * - * This file can be generated by compiling and running contrib/gdtoa/qnan.c - * on the target architecture after arith.h has been generated. - * - * $FreeBSD$ - */ - -#define f_QNAN 0x7fc00000 -#define d_QNAN0 0x7ff80000 -#define d_QNAN1 0x0 -#define ld_QNAN0 0x7ff80000 -#define ld_QNAN1 0x0 -#define ld_QNAN2 0x0 -#define ld_QNAN3 0x0 -#define ldus_QNAN0 0x7ff8 -#define ldus_QNAN1 0x0 -#define ldus_QNAN2 0x0 -#define ldus_QNAN3 0x0 -#define ldus_QNAN4 0x0 diff --git a/lib/libc/powerpcspe/gen/Makefile.inc b/lib/libc/powerpcspe/gen/Makefile.inc index 2a00ba332b94..f96ad9fb0a6f 100644 --- a/lib/libc/powerpcspe/gen/Makefile.inc +++ b/lib/libc/powerpcspe/gen/Makefile.inc @@ -1,11 +1,7 @@ # $FreeBSD$ -SRCS += _ctx_start.S eabi.S fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ +.include "${LIBC_SRCTOP}/powerpc/gen/Makefile.common" + +SRCS += fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ fpgetsticky.c fpsetmask.c fpsetround.c \ - infinity.c ldexp.c makecontext.c _setjmp.S \ - setjmp.S sigsetjmp.S signalcontext.c syncicache.c \ - _set_tp.c \ - trivial-getcontextx.c - - - + _setjmp.S setjmp.S sigsetjmp.S diff --git a/lib/libc/powerpcspe/gen/_ctx_start.S b/lib/libc/powerpcspe/gen/_ctx_start.S deleted file mode 100644 index 4b9fc1d53ae0..000000000000 --- a/lib/libc/powerpcspe/gen/_ctx_start.S +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004 Suleiman Souhlal - * 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. - */ - - #include - - __FBSDID("$FreeBSD$"); - - .globl CNAME(_ctx_done) - .globl CNAME(abort) - - ENTRY(_ctx_start) - mtlr %r14 - blrl /* branch to start function */ - mr %r3,%r15 /* pass pointer to ucontext as argument */ - bl PIC_PLT(CNAME(_ctx_done)) /* branch to ctxt completion func */ - /* - * we should never return from the - * above branch. - */ - bl PIC_PLT(CNAME(abort)) /* abort */ - END(_cts_start) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/_set_tp.c b/lib/libc/powerpcspe/gen/_set_tp.c deleted file mode 100644 index eeb062f30217..000000000000 --- a/lib/libc/powerpcspe/gen/_set_tp.c +++ /dev/null @@ -1,35 +0,0 @@ -/*- - * Copyright (c) 2004 Doug Rabson - * 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 "libc_private.h" - -void -_set_tp(void *tpval) -{ - - __asm __volatile("mr 2,%0" :: "r"((char*)tpval + 0x7008)); -} diff --git a/lib/libc/powerpcspe/gen/eabi.S b/lib/libc/powerpcspe/gen/eabi.S deleted file mode 100644 index 3296af88a4d1..000000000000 --- a/lib/libc/powerpcspe/gen/eabi.S +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2011 Marcel Moolenaar - * 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -ENTRY(__eabi) - blr -END(__eabi) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/gen/infinity.c b/lib/libc/powerpcspe/gen/infinity.c deleted file mode 100644 index cf1695e68028..000000000000 --- a/lib/libc/powerpcspe/gen/infinity.c +++ /dev/null @@ -1,17 +0,0 @@ -#include -#if 0 -#if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: infinity.c,v 1.2 1998/11/14 19:31:02 christos Exp $"); -#endif /* LIBC_SCCS and not lint */ -#endif -__FBSDID("$FreeBSD$"); - -/* infinity.c */ - -#include - -/* bytes for +Infinity on powerpc */ -const union __infinity_un __infinity = { { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 } }; - -/* bytes for NaN */ -const union __nan_un __nan = { { 0xff, 0xc0, 0, 0 } }; diff --git a/lib/libc/powerpcspe/gen/makecontext.c b/lib/libc/powerpcspe/gen/makecontext.c deleted file mode 100644 index d66e82457a4e..000000000000 --- a/lib/libc/powerpcspe/gen/makecontext.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2004 Suleiman Souhlal - * 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include - -#include -#include -#include -#include -#include - -__weak_reference(__makecontext, makecontext); - -void _ctx_done(ucontext_t *ucp); -void _ctx_start(void); - -void -_ctx_done(ucontext_t *ucp) -{ - if (ucp->uc_link == NULL) - exit(0); - else { - /* invalidate context */ - ucp->uc_mcontext.mc_len = 0; - - setcontext((const ucontext_t *)ucp->uc_link); - - abort(); /* should never return from above call */ - } -} - -void -__makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) -{ - mcontext_t *mc; - char *sp; - va_list ap; - int i, regargs, stackargs; - - /* Sanity checks */ - if ((ucp == NULL) || (argc < 0) || (argc > NCARGS) - || (ucp->uc_stack.ss_sp == NULL) - || (ucp->uc_stack.ss_size < MINSIGSTKSZ)) { - /* invalidate context */ - ucp->uc_mcontext.mc_len = 0; - return; - } - - /* - * The stack must have space for the frame pointer, saved - * link register, overflow arguments, and be 16-byte - * aligned. - */ - stackargs = (argc > 8) ? argc - 8 : 0; - sp = (char *) ucp->uc_stack.ss_sp + ucp->uc_stack.ss_size - - sizeof(uint32_t)*(stackargs + 2); - sp = (char *)((uint32_t)sp & ~0x1f); - - mc = &ucp->uc_mcontext; - - /* - * Up to 8 register args. Assumes all args are 32-bit and - * integer only. Not sure how to cater for floating point, - * although 64-bit args will work if aligned correctly - * in the arg list. - */ - regargs = (argc > 8) ? 8 : argc; - va_start(ap, argc); - for (i = 0; i < regargs; i++) - mc->mc_gpr[3 + i] = va_arg(ap, uint32_t); - - /* - * Overflow args go onto the stack - */ - if (argc > 8) { - uint32_t *argp; - - /* Skip past frame pointer and saved LR */ - argp = (uint32_t *)sp + 2; - - for (i = 0; i < stackargs; i++) - *argp++ = va_arg(ap, uint32_t); - } - va_end(ap); - - /* - * Use caller-saved regs 14/15 to hold params that _ctx_start - * will use to invoke the user-supplied func - */ - mc->mc_srr0 = (uint32_t) _ctx_start; - mc->mc_gpr[1] = (uint32_t) sp; /* new stack pointer */ - mc->mc_gpr[14] = (uint32_t) start; /* r14 <- start */ - mc->mc_gpr[15] = (uint32_t) ucp; /* r15 <- ucp */ -} diff --git a/lib/libc/powerpcspe/gen/signalcontext.c b/lib/libc/powerpcspe/gen/signalcontext.c deleted file mode 100644 index 30e2be848b2b..000000000000 --- a/lib/libc/powerpcspe/gen/signalcontext.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2004 Marcel Moolenaar, Peter Grehan - * 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 ``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 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. - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include - -typedef void (*handler_t)(uint32_t, uint32_t, uint32_t); - -/* Prototypes */ -static void ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, - uint32_t sig_si, uint32_t sig_uc); - -__weak_reference(__signalcontext, signalcontext); - -int -__signalcontext(ucontext_t *ucp, int sig, __sighandler_t *func) -{ - siginfo_t *sig_si; - ucontext_t *sig_uc; - uint32_t sp; - - /* Bail out if we don't have a valid ucontext pointer. */ - if (ucp == NULL) - abort(); - - /* - * Build a 16-byte-aligned signal frame - */ - sp = (ucp->uc_mcontext.mc_gpr[1] - sizeof(ucontext_t)) & ~15UL; - sig_uc = (ucontext_t *)sp; - bcopy(ucp, sig_uc, sizeof(*sig_uc)); - sp = (sp - sizeof(siginfo_t)) & ~15UL; - sig_si = (siginfo_t *)sp; - bzero(sig_si, sizeof(*sig_si)); - sig_si->si_signo = sig; - - /* - * Subtract 8 bytes from stack to allow for frameptr - */ - sp -= 2*sizeof(uint32_t); - sp &= ~15UL; - - /* - * Setup the ucontext of the signal handler. - */ - bzero(&ucp->uc_mcontext, sizeof(ucp->uc_mcontext)); - ucp->uc_link = sig_uc; - sigdelset(&ucp->uc_sigmask, sig); - - ucp->uc_mcontext.mc_vers = _MC_VERSION; - ucp->uc_mcontext.mc_len = sizeof(struct __mcontext); - ucp->uc_mcontext.mc_srr0 = (uint32_t) ctx_wrapper; - ucp->uc_mcontext.mc_gpr[1] = (uint32_t) sp; - ucp->uc_mcontext.mc_gpr[3] = (uint32_t) func; - ucp->uc_mcontext.mc_gpr[4] = (uint32_t) sig; - ucp->uc_mcontext.mc_gpr[5] = (uint32_t) sig_si; - ucp->uc_mcontext.mc_gpr[6] = (uint32_t) sig_uc; - - return (0); -} - -static void -ctx_wrapper(ucontext_t *ucp, handler_t func, uint32_t sig, uint32_t sig_si, - uint32_t sig_uc) -{ - - (*func)(sig, sig_si, sig_uc); - if (ucp->uc_link == NULL) - exit(0); - setcontext((const ucontext_t *)ucp->uc_link); - /* should never get here */ - abort(); - /* NOTREACHED */ -} diff --git a/lib/libc/powerpcspe/gen/syncicache.c b/lib/libc/powerpcspe/gen/syncicache.c deleted file mode 100644 index aa025cca8bc6..000000000000 --- a/lib/libc/powerpcspe/gen/syncicache.c +++ /dev/null @@ -1,103 +0,0 @@ -/*- - * Copyright (C) 1995-1997, 1999 Wolfgang Solfrank. - * Copyright (C) 1995-1997, 1999 TooLs GmbH. - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by TooLs GmbH. - * 4. The name of TooLs GmbH may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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. - * - * $NetBSD: syncicache.c,v 1.2 1999/05/05 12:36:40 tsubai Exp $ - */ - -#ifndef lint -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include -#if defined(_KERNEL) || defined(_STANDALONE) -#include -#include -#include -#endif -#include - -#include -#include - -#ifdef _STANDALONE -int cacheline_size = 32; -#endif - -#if !defined(_KERNEL) && !defined(_STANDALONE) -#include - -int cacheline_size = 0; - -static void getcachelinesize(void); - -static void -getcachelinesize() -{ - static int cachemib[] = { CTL_MACHDEP, CPU_CACHELINE }; - int clen; - - clen = sizeof(cacheline_size); - - if (sysctl(cachemib, nitems(cachemib), &cacheline_size, &clen, - NULL, 0) < 0 || !cacheline_size) { - abort(); - } -} -#endif - -void -__syncicache(void *from, int len) -{ - int l, off; - char *p; - -#if !defined(_KERNEL) && !defined(_STANDALONE) - if (!cacheline_size) - getcachelinesize(); -#endif - - off = (u_int)from & (cacheline_size - 1); - l = len += off; - p = (char *)from - off; - - do { - __asm __volatile ("dcbst 0,%0" :: "r"(p)); - p += cacheline_size; - } while ((l -= cacheline_size) > 0); - __asm __volatile ("sync"); - p = (char *)from - off; - do { - __asm __volatile ("icbi 0,%0" :: "r"(p)); - p += cacheline_size; - } while ((len -= cacheline_size) > 0); - __asm __volatile ("sync; isync"); -} - diff --git a/lib/libc/powerpcspe/sys/Makefile.inc b/lib/libc/powerpcspe/sys/Makefile.inc index 6451d821b99c..7ddf4f89f05b 100644 --- a/lib/libc/powerpcspe/sys/Makefile.inc +++ b/lib/libc/powerpcspe/sys/Makefile.inc @@ -1,8 +1,4 @@ # $FreeBSD$ -MDASM+= brk.S cerror.S exect.S sbrk.S setlogin.S - -# Don't generate default code for these syscalls: -NOASM= break.o exit.o getlogin.o openbsd_poll.o sstk.o yield.o - -PSEUDO= _getlogin.o _exit.o +.PATH: ${LIBC_SRCTOP}/powerpc/sys +.sinclude "${LIBC_SRCTOP}/powerpc/sys/Makefile.inc" diff --git a/lib/libc/powerpcspe/sys/brk.S b/lib/libc/powerpcspe/sys/brk.S deleted file mode 100644 index e14be1058b51..000000000000 --- a/lib/libc/powerpcspe/sys/brk.S +++ /dev/null @@ -1,76 +0,0 @@ -/*- - * Copyright (c) 2002 Peter Grehan. - * 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. - */ -/* $NetBSD: brk.S,v 1.9 2000/06/26 06:25:43 kleink Exp $ */ - -#include -__FBSDID("$FreeBSD$"); - -#include "SYS.h" - - .globl HIDENAME(curbrk) - .globl HIDENAME(minbrk) - .globl CNAME(_end) - - .data -HIDENAME(minbrk): - .long CNAME(_end) - - .text - -ENTRY(brk) -#ifdef PIC - mflr %r10 - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr %r9 - mtlr %r10 - lwz %r5,HIDENAME(minbrk)@got(%r9) - lwz %r6,0(%r5) -#else - lis %r5,HIDENAME(minbrk)@ha - lwz %r6,HIDENAME(minbrk)@l(%r5) -#endif - cmplw %r6,%r3 /* if (minbrk <= r3) */ - bgt 0f - mr %r6,%r3 /* r6 = r3 */ -0: - mr %r3,%r6 /* new break value */ - li %r0,SYS_break - sc /* assume, that r5 is kept */ - bso 1f -#ifdef PIC - lwz %r7,HIDENAME(curbrk)@got(%r9) - stw %r6,0(%r7) -#else - lis %r7,HIDENAME(curbrk)@ha /* record new break */ - stw %r6,HIDENAME(curbrk)@l(%r7) -#endif - blr /* return 0 */ - -1: - b PIC_PLT(HIDENAME(cerror)) -END(brk) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/cerror.S b/lib/libc/powerpcspe/sys/cerror.S deleted file mode 100644 index 3ca04fb4a19d..000000000000 --- a/lib/libc/powerpcspe/sys/cerror.S +++ /dev/null @@ -1,58 +0,0 @@ -/*- - * Copyright (c) 2002 Peter Grehan. - * 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. - */ -/* $NetBSD: cerror.S,v 1.5 2000/01/27 14:58:48 kleink Exp $ */ - -#include -__FBSDID("$FreeBSD$"); - -#include "SYS.h" - - .globl HIDENAME(cerror) - .hidden HIDENAME(cerror) - .globl CNAME(__error) - - /* - * The __error() function is thread aware. For non-threaded - * programs and the initial threaded in threaded programs, - * it returns a pointer to the global errno variable. - */ -HIDENAME(cerror): - mflr %r0 - stwu %r1,-16(%r1) /* allocate new stack frame */ - stw %r0,20(%r1) /* and save lr, r31 */ - stw %r31,8(%r1) - mr %r31,%r3 /* stash errval in callee-saved register */ - bl PIC_PLT(CNAME(__error)) - stw %r31,0(%r3) /* store errval into &errno */ - lwz %r0,20(%r1) - lwz %r31,8(%r1) - mtlr %r0 - la %r1,16(%r1) - li %r3,-1 - li %r4,-1 - blr /* return to callers caller */ - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/exect.S b/lib/libc/powerpcspe/sys/exect.S deleted file mode 100644 index 701f5b00f45c..000000000000 --- a/lib/libc/powerpcspe/sys/exect.S +++ /dev/null @@ -1,42 +0,0 @@ -/*- - * Copyright (c) 2002 Peter Grehan. - * 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. - */ -/* $NetBSD: exect.S,v 1.3 1998/05/25 15:28:03 ws Exp $ */ - -#include -__FBSDID("$FreeBSD$"); - -#include "SYS.h" - -ENTRY(exect) - li %r0,SYS_execve - sc - bso 1f - blr -1: - b PIC_PLT(HIDENAME(cerror)) -END(exect) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/sbrk.S b/lib/libc/powerpcspe/sys/sbrk.S deleted file mode 100644 index f058d112e863..000000000000 --- a/lib/libc/powerpcspe/sys/sbrk.S +++ /dev/null @@ -1,73 +0,0 @@ -/*- - * Copyright (c) 2002 Peter Grehan. - * 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. - */ -/* $NetBSD: sbrk.S,v 1.8 2000/06/26 06:25:44 kleink Exp $ */ - -#include -__FBSDID("$FreeBSD$"); - -#include "SYS.h" - - .globl HIDENAME(curbrk) - .globl CNAME(_end) - - .data -HIDENAME(curbrk): - .long CNAME(_end) - - .text -ENTRY(sbrk) - -#ifdef PIC - mflr %r10 - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr %r5 - mtlr %r10 - lwz %r5,HIDENAME(curbrk)@got(%r5) - lwz %r6,0(%r5) -#else - lis %r5,HIDENAME(curbrk)@ha - lwz %r6,HIDENAME(curbrk)@l(%r5) /* r6 = old break */ -#endif - cmpwi %r3,0 /* sbrk(0) - return curbrk */ - beq 1f - add %r3,%r3,%r6 - mr %r7,%r3 /* r7 = new break */ - li %r0,SYS_break - sc /* break(new_break) */ - bso 2f -#ifdef PIC - stw %r7,0(%r5) -#else - stw %r7,HIDENAME(curbrk)@l(%r5) /* record new break */ -#endif -1: - mr %r3,%r6 /* set return value */ - blr -2: - b PIC_PLT(HIDENAME(cerror)) -END(sbrk) - - .section .note.GNU-stack,"",%progbits diff --git a/lib/libc/powerpcspe/sys/setlogin.S b/lib/libc/powerpcspe/sys/setlogin.S deleted file mode 100644 index e0d6d3c012ce..000000000000 --- a/lib/libc/powerpcspe/sys/setlogin.S +++ /dev/null @@ -1,51 +0,0 @@ -/*- - * Copyright (c) 2002 Peter Grehan. - * 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. - */ -/* $NetBSD: setlogin.S,v 1.3 1998/11/24 11:14:57 tsubai Exp $ */ - -#include -__FBSDID("$FreeBSD$"); - -#include "SYS.h" - - .globl CNAME(_logname_valid) /* in _getlogin() */ - -SYSCALL(setlogin) -#ifdef PIC - mflr %r10 - bl _GLOBAL_OFFSET_TABLE_@local-4 - mflr %r4 - lwz %r4,CNAME(_logname_valid)@got(%r4) - li %r5,%r0 - stw %r5,0(%r4) - mtlr %r10 -#else - lis %r4,CNAME(_logname_valid)@ha - li %r5,0 - stw %r5,CNAME(_logname_valid)@l(%r4) -#endif - blr - - .section .note.GNU-stack,"",%progbits From fcdaff2cd129aff33458b55b3099f1ea28ecfee2 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Sat, 22 Oct 2016 22:27:51 +0000 Subject: [PATCH 026/235] Sources from the "current" build tree and generated sources in the object tree should be used instead of sources and headers from the already installed source tree on the build host. This was noticed while addressing issues in the upcoming amd update. MFC after: 2 weeks --- usr.sbin/amd/Makefile.inc | 4 ++-- usr.sbin/amd/amd/Makefile | 2 +- usr.sbin/amd/libamu/Makefile | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/usr.sbin/amd/Makefile.inc b/usr.sbin/amd/Makefile.inc index 1b19acd90415..d558fa412b1e 100644 --- a/usr.sbin/amd/Makefile.inc +++ b/usr.sbin/amd/Makefile.inc @@ -32,8 +32,8 @@ CFLAGS+= -DYES_HESIOD CFLAGS+= -DHOST_CPU=\"${MACHINE_CPUARCH}\" -DHOST_ARCH=\"${MACHINE_ARCH}\" RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen -MOUNT_X= ${DESTDIR}/usr/include/rpcsvc/mount.x -NFS_PROT_X= ${DESTDIR}/usr/include/rpcsvc/nfs_prot.x +MOUNT_X= ${SRCTOP}/include/rpcsvc/mount.x +NFS_PROT_X= ${SRCTOP}/include/rpcsvc/nfs_prot.x WARNS?= 1 diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile index 1ebd9b71c000..9811f88930f5 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -25,7 +25,7 @@ SRCS+= ops_unionfs.c opts.c readdir.c restart.c rpc_fwd.c sched.c SRCS+= srvr_amfs_auto.c srvr_nfs.c CFLAGS+= -I${SRCTOP}/contrib/amd/amd \ - -I${DESTDIR}/usr/include/rpcsvc + -I${.OBJDIR}/../../../include/rpcsvc LIBADD= amu wrap diff --git a/usr.sbin/amd/libamu/Makefile b/usr.sbin/amd/libamu/Makefile index 4621f3e93344..850183d43dab 100644 --- a/usr.sbin/amd/libamu/Makefile +++ b/usr.sbin/amd/libamu/Makefile @@ -23,7 +23,7 @@ SRCS+= nfs_prot_x.c xdr_func_%undef.c CLEANFILES+= nfs_prot_x.c xdr_func_%undef.c CFLAGS+= -I${SRCTOP}/contrib/amd/libamu \ - -I${DESTDIR}/usr/include/rpcsvc + -I${.OBJDIR}/../../../include/rpcsvc nfs_prot_x.c: ${NFS_PROT_X} ${RPCCOM} -c -C -DWANT_NFS3 ${NFS_PROT_X} -o ${.TARGET} From d1c0e47537fafe22cb22291f5f3a703c613c2107 Mon Sep 17 00:00:00 2001 From: Cy Schubert Date: Sat, 22 Oct 2016 22:29:03 +0000 Subject: [PATCH 027/235] Align whitespace. MFC after: 2 weeks X-MFC with: r307800 --- usr.sbin/amd/amd/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/amd/amd/Makefile b/usr.sbin/amd/amd/Makefile index 9811f88930f5..8f14259fca5c 100644 --- a/usr.sbin/amd/amd/Makefile +++ b/usr.sbin/amd/amd/Makefile @@ -31,7 +31,7 @@ LIBADD= amu wrap CLEANFILES+= conf_parse.c conf_parse.h conf_tok.c -conf_tok.o: conf_parse.h +conf_tok.o: conf_parse.h # These are generated at compile time SRCS+= mount_xdr.c From 4fe54d42791722b93f4c3f9b57fb09a15c3faaaa Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 22:35:39 +0000 Subject: [PATCH 028/235] Fix build of tzsetup when WITHOUT_DIALOG is set Hide dialog specific code behind HAVE_DIALOG. It allows to build a stripped down version (missing the dialog UI) but perfectly function tzsetup when world is built WITHOUT_DIALOG Reorganise a bit the code to limit the number of blocks under HAVE_DIALOG Reviewed by: emaste Sponsored by: https://reviews.freebsd.org/D8325 --- tools/build/mk/OptionalObsoleteFiles.inc | 2 - usr.sbin/Makefile | 2 +- usr.sbin/tzsetup/Makefile | 8 +- usr.sbin/tzsetup/tzsetup.c | 488 ++++++++++++----------- 4 files changed, 272 insertions(+), 228 deletions(-) diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index cb17b4f029a9..bc2092d64204 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1348,12 +1348,10 @@ OLD_FILES+=usr/lib/libdpv.so OLD_FILES+=usr/lib/libdpv.so.1 OLD_FILES+=usr/lib/libdpv_p.a OLD_FILES+=usr/sbin/bsdconfig -OLD_FILES+=usr/sbin/tzsetup OLD_FILES+=usr/share/man/man1/dialog.1.gz OLD_FILES+=usr/share/man/man1/dpv.1.gz OLD_FILES+=usr/share/man/man3/dialog.3.gz OLD_FILES+=usr/share/man/man3/dpv.3.gz -OLD_FILES+=usr/share/man/man8/tzsetup.8.gz OLD_FILES+=usr/share/man/man8/bsdconfig.8.gz .endif diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 1a1d0ced868c..71e39f731f02 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -88,6 +88,7 @@ SUBDIR= adduser \ tcpdump \ traceroute \ trpt \ + tzsetup \ uefisign \ ugidfw \ vigr \ @@ -121,7 +122,6 @@ SUBDIR.${MK_BOOTPARAMD}+= bootparamd SUBDIR.${MK_BSDINSTALL}+= bsdinstall SUBDIR.${MK_BSNMP}+= bsnmpd SUBDIR.${MK_CTM}+= ctm -SUBDIR.${MK_DIALOG}+= tzsetup SUBDIR.${MK_DIALOG}+= bsdconfig SUBDIR.${MK_EFI}+= efivar SUBDIR.${MK_FLOPPY}+= fdcontrol diff --git a/usr.sbin/tzsetup/Makefile b/usr.sbin/tzsetup/Makefile index de7375f0002e..d6867a8a7e4f 100644 --- a/usr.sbin/tzsetup/Makefile +++ b/usr.sbin/tzsetup/Makefile @@ -1,12 +1,16 @@ # $FreeBSD$ +.include + PROG= tzsetup MAN= tzsetup.8 -CFLAGS+= -I${.CURDIR}/../../contrib/dialog -I. +CFLAGS+= -I. +.if ${MK_DIALOG} != no WARNS?= 3 - +CFLAGS+= -I${.CURDIR}/../../contrib/dialog -DHAVE_DIALOG LIBADD= dialog ncursesw +.endif .include diff --git a/usr.sbin/tzsetup/tzsetup.c b/usr.sbin/tzsetup/tzsetup.c index 4f0f2d081bf8..2637924f24c0 100644 --- a/usr.sbin/tzsetup/tzsetup.c +++ b/usr.sbin/tzsetup/tzsetup.c @@ -49,7 +49,9 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef HAVE_DIALOG #include +#endif #define _PATH_ZONETAB "/usr/share/zoneinfo/zone.tab" #define _PATH_ISO3166 "/usr/share/misc/iso3166" @@ -72,6 +74,19 @@ __FBSDID("$FreeBSD$"); #define DITEM_LEAVE_MENU (1 << 16) #define DITEM_RECREATE (1 << 18) +static char path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN], + path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN], + path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN]; + +static int reallydoit = 1; +static int reinstall = 0; +static char *chrootenv = NULL; + +static void usage(void); +static int install_zoneinfo(const char *zoneinfo); +static int install_zoneinfo_file(const char *zoneinfo_file); + +#ifdef HAVE_DIALOG /* for use in describing more exotic behaviors */ typedef struct dialogMenuItem { char *prompt; @@ -187,20 +202,10 @@ xdialog_menu(const char *title, const char *cprompt, int height, int width, return result; } -static char path_zonetab[MAXPATHLEN], path_iso3166[MAXPATHLEN], - path_zoneinfo[MAXPATHLEN], path_localtime[MAXPATHLEN], - path_db[MAXPATHLEN], path_wall_cmos_clock[MAXPATHLEN]; - -static int reallydoit = 1; -static int reinstall = 0; static int usedialog = 1; -static char *chrootenv = NULL; -static void usage(void); static int confirm_zone(const char *filename); static int continent_country_menu(dialogMenuItem *); -static int install_zoneinfo(const char *zoneinfo); -static int install_zoneinfo_file(const char *zoneinfo_file); static int set_zone_multi(dialogMenuItem *); static int set_zone_whole_country(dialogMenuItem *); static int set_zone_menu(dialogMenuItem *); @@ -643,218 +648,6 @@ set_zone_utc(void) return (install_zoneinfo("UTC")); } -static int -install_zoneinfo_file(const char *zoneinfo_file) -{ - char buf[1024]; - char title[64], prompt[SILLY_BUFFER_SIZE]; - struct stat sb; - ssize_t len; - int fd1, fd2, copymode; - - if (lstat(path_localtime, &sb) < 0) { - /* Nothing there yet... */ - copymode = 1; - } else if (S_ISLNK(sb.st_mode)) - copymode = 0; - else - copymode = 1; - -#ifdef VERBOSE - snprintf(title, sizeof(title), "Info"); - if (zoneinfo_file == NULL) - snprintf(prompt, sizeof(prompt), - "Removing %s", path_localtime); - else if (copymode) - snprintf(prompt, sizeof(prompt), - "Copying %s to %s", zoneinfo_file, path_localtime); - else - snprintf(prompt, sizeof(prompt), - "Creating symbolic link %s to %s", - path_localtime, zoneinfo_file); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); -#endif - - if (reallydoit) { - if (zoneinfo_file == NULL) { - if (unlink(path_localtime) < 0 && errno != ENOENT) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Could not delete %s: %s", path_localtime, - strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - - return (DITEM_FAILURE | DITEM_RECREATE); - } - if (unlink(path_db) < 0 && errno != ENOENT) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Could not delete %s: %s", path_db, - strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - - return (DITEM_FAILURE | DITEM_RECREATE); - } -#ifdef VERBOSE - snprintf(title, sizeof(title), "Done"); - snprintf(prompt, sizeof(prompt), - "Removed %s", path_localtime); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); -#endif - return (DITEM_LEAVE_MENU); - } - - if (copymode) { - fd1 = open(zoneinfo_file, O_RDONLY, 0); - if (fd1 < 0) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Could not open %s: %s", zoneinfo_file, - strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - - if (unlink(path_localtime) < 0 && errno != ENOENT) { - snprintf(prompt, sizeof(prompt), - "Could not unlink %s: %s", - path_localtime, strerror(errno)); - if (usedialog) { - snprintf(title, sizeof(title), "Error"); - dialog_msgbox(title, prompt, 8, 72, 1); - } else - fprintf(stderr, "%s\n", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - - fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY, - S_IRUSR | S_IRGRP | S_IROTH); - if (fd2 < 0) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Could not open %s: %s", - path_localtime, strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - - while ((len = read(fd1, buf, sizeof(buf))) > 0) - if ((len = write(fd2, buf, len)) < 0) - break; - - if (len == -1) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Error copying %s to %s %s", zoneinfo_file, - path_localtime, strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - /* Better to leave none than a corrupt one. */ - unlink(path_localtime); - return (DITEM_FAILURE | DITEM_RECREATE); - } - close(fd1); - close(fd2); - } else { - if (access(zoneinfo_file, R_OK) != 0) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Cannot access %s: %s", zoneinfo_file, - strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - if (unlink(path_localtime) < 0 && errno != ENOENT) { - snprintf(prompt, sizeof(prompt), - "Could not unlink %s: %s", - path_localtime, strerror(errno)); - if (usedialog) { - snprintf(title, sizeof(title), "Error"); - dialog_msgbox(title, prompt, 8, 72, 1); - } else - fprintf(stderr, "%s\n", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - if (symlink(zoneinfo_file, path_localtime) < 0) { - snprintf(title, sizeof(title), "Error"); - snprintf(prompt, sizeof(prompt), - "Cannot create symbolic link %s to %s: %s", - path_localtime, zoneinfo_file, - strerror(errno)); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); - return (DITEM_FAILURE | DITEM_RECREATE); - } - } - -#ifdef VERBOSE - snprintf(title, sizeof(title), "Done"); - if (copymode) - snprintf(prompt, sizeof(prompt), - "Copied timezone file from %s to %s", - zoneinfo_file, path_localtime); - else - snprintf(prompt, sizeof(prompt), - "Created symbolic link from %s to %s", - zoneinfo_file, path_localtime); - if (usedialog) - dialog_msgbox(title, prompt, 8, 72, 1); - else - fprintf(stderr, "%s\n", prompt); -#endif - } /* reallydoit */ - - return (DITEM_LEAVE_MENU); -} - -static int -install_zoneinfo(const char *zoneinfo) -{ - int rv; - FILE *f; - char path_zoneinfo_file[MAXPATHLEN]; - - if ((size_t)snprintf(path_zoneinfo_file, sizeof(path_zoneinfo_file), - "%s/%s", path_zoneinfo, zoneinfo) >= sizeof(path_zoneinfo_file)) - errx(1, "%s/%s name too long", path_zoneinfo, zoneinfo); - rv = install_zoneinfo_file(path_zoneinfo_file); - - /* Save knowledge for later */ - if (reallydoit && (rv & DITEM_FAILURE) == 0) { - if ((f = fopen(path_db, "w")) != NULL) { - fprintf(f, "%s\n", zoneinfo); - fclose(f); - } - } - - return (rv); -} - static int confirm_zone(const char *filename) { @@ -900,6 +693,244 @@ set_zone_whole_country(dialogMenuItem *dmi) return (rv); } +#endif + +static int +install_zoneinfo_file(const char *zoneinfo_file) +{ + char buf[1024]; + char title[64], prompt[SILLY_BUFFER_SIZE]; + struct stat sb; + ssize_t len; + int fd1, fd2, copymode; + + if (lstat(path_localtime, &sb) < 0) { + /* Nothing there yet... */ + copymode = 1; + } else if (S_ISLNK(sb.st_mode)) + copymode = 0; + else + copymode = 1; + +#ifdef VERBOSE + snprintf(title, sizeof(title), "Info"); + if (zoneinfo_file == NULL) + snprintf(prompt, sizeof(prompt), + "Removing %s", path_localtime); + else if (copymode) + snprintf(prompt, sizeof(prompt), + "Copying %s to %s", zoneinfo_file, path_localtime); + else + snprintf(prompt, sizeof(prompt), + "Creating symbolic link %s to %s", + path_localtime, zoneinfo_file); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); +#endif + + if (reallydoit) { + if (zoneinfo_file == NULL) { + if (unlink(path_localtime) < 0 && errno != ENOENT) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not delete %s: %s", path_localtime, + strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + + return (DITEM_FAILURE | DITEM_RECREATE); + } + if (unlink(path_db) < 0 && errno != ENOENT) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not delete %s: %s", path_db, + strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + + return (DITEM_FAILURE | DITEM_RECREATE); + } +#ifdef VERBOSE + snprintf(title, sizeof(title), "Done"); + snprintf(prompt, sizeof(prompt), + "Removed %s", path_localtime); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); +#endif + return (DITEM_LEAVE_MENU); + } + + if (copymode) { + fd1 = open(zoneinfo_file, O_RDONLY, 0); + if (fd1 < 0) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not open %s: %s", zoneinfo_file, + strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + + if (unlink(path_localtime) < 0 && errno != ENOENT) { + snprintf(prompt, sizeof(prompt), + "Could not unlink %s: %s", + path_localtime, strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) { + snprintf(title, sizeof(title), "Error"); + dialog_msgbox(title, prompt, 8, 72, 1); + } else +#endif + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + + fd2 = open(path_localtime, O_CREAT | O_EXCL | O_WRONLY, + S_IRUSR | S_IRGRP | S_IROTH); + if (fd2 < 0) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Could not open %s: %s", + path_localtime, strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + + while ((len = read(fd1, buf, sizeof(buf))) > 0) + if ((len = write(fd2, buf, len)) < 0) + break; + + if (len == -1) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Error copying %s to %s %s", zoneinfo_file, + path_localtime, strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + /* Better to leave none than a corrupt one. */ + unlink(path_localtime); + return (DITEM_FAILURE | DITEM_RECREATE); + } + close(fd1); + close(fd2); + } else { + if (access(zoneinfo_file, R_OK) != 0) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Cannot access %s: %s", zoneinfo_file, + strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + if (unlink(path_localtime) < 0 && errno != ENOENT) { + snprintf(prompt, sizeof(prompt), + "Could not unlink %s: %s", + path_localtime, strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) { + snprintf(title, sizeof(title), "Error"); + dialog_msgbox(title, prompt, 8, 72, 1); + } else +#endif + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + if (symlink(zoneinfo_file, path_localtime) < 0) { + snprintf(title, sizeof(title), "Error"); + snprintf(prompt, sizeof(prompt), + "Cannot create symbolic link %s to %s: %s", + path_localtime, zoneinfo_file, + strerror(errno)); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); + return (DITEM_FAILURE | DITEM_RECREATE); + } + } + +#ifdef VERBOSE + snprintf(title, sizeof(title), "Done"); + if (copymode) + snprintf(prompt, sizeof(prompt), + "Copied timezone file from %s to %s", + zoneinfo_file, path_localtime); + else + snprintf(prompt, sizeof(prompt), + "Created symbolic link from %s to %s", + zoneinfo_file, path_localtime); +#ifdef HAVE_DIALOG + if (usedialog) + dialog_msgbox(title, prompt, 8, 72, 1); + else +#endif + fprintf(stderr, "%s\n", prompt); +#endif + } /* reallydoit */ + + return (DITEM_LEAVE_MENU); +} + +static int +install_zoneinfo(const char *zoneinfo) +{ + int rv; + FILE *f; + char path_zoneinfo_file[MAXPATHLEN]; + + if ((size_t)snprintf(path_zoneinfo_file, sizeof(path_zoneinfo_file), + "%s/%s", path_zoneinfo, zoneinfo) >= sizeof(path_zoneinfo_file)) + errx(1, "%s/%s name too long", path_zoneinfo, zoneinfo); + rv = install_zoneinfo_file(path_zoneinfo_file); + + /* Save knowledge for later */ + if (reallydoit && (rv & DITEM_FAILURE) == 0) { + if ((f = fopen(path_db, "w")) != NULL) { + fprintf(f, "%s\n", zoneinfo); + fclose(f); + } + } + + return (rv); +} + static void usage(void) { @@ -912,8 +943,11 @@ usage(void) int main(int argc, char **argv) { +#ifdef HAVE_DIALOG char title[64], prompt[128]; - int c, fd, rv, skiputc; + int fd; +#endif + int c, rv, skiputc; char vm_guest[16] = ""; size_t len = sizeof(vm_guest); @@ -934,7 +968,9 @@ main(int argc, char **argv) break; case 'r': reinstall = 1; +#ifdef HAVE_DIALOG usedialog = 0; +#endif break; case 's': skiputc = 1; @@ -998,12 +1034,15 @@ main(int argc, char **argv) struct stat sb; if (stat(argv[optind], &sb) != 0) { +#ifdef HAVE_DIALOG usedialog = 0; +#endif rv = install_zoneinfo(argv[optind]); exit(rv & ~DITEM_LEAVE_MENU); } /* FALLTHROUGH */ } +#ifdef HAVE_DIALOG read_iso3166_table(); read_zones(); @@ -1064,5 +1103,8 @@ main(int argc, char **argv) dlg_clear(); end_dialog(); +#else + usage(); +#endif return (0); } From 73362d0e56ee37c67efe03ab5f087b6ad78757da Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 22 Oct 2016 22:52:50 +0000 Subject: [PATCH 029/235] EVDEV: Add shortcut functions for event types Add wrappers around generic evdev_push_event for specific event types: EV_KEY/EV_REL/EV_ABS etc... Submitted by: Vladimir Kondratiev --- sys/dev/evdev/evdev.c | 15 --------- sys/dev/evdev/evdev.h | 66 +++++++++++++++++++++++++++++++++++-- sys/dev/evdev/evdev_utils.c | 7 ++-- 3 files changed, 67 insertions(+), 21 deletions(-) diff --git a/sys/dev/evdev/evdev.c b/sys/dev/evdev/evdev.c index 63e04966fec9..4de5dee8db04 100644 --- a/sys/dev/evdev/evdev.c +++ b/sys/dev/evdev/evdev.c @@ -822,21 +822,6 @@ evdev_inject_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, return (ret); } -inline int -evdev_sync(struct evdev_dev *evdev) -{ - - return (evdev_push_event(evdev, EV_SYN, SYN_REPORT, 1)); -} - - -inline int -evdev_mt_sync(struct evdev_dev *evdev) -{ - - return (evdev_push_event(evdev, EV_SYN, SYN_MT_REPORT, 1)); -} - int evdev_register_client(struct evdev_dev *evdev, struct evdev_client *client) { diff --git a/sys/dev/evdev/evdev.h b/sys/dev/evdev/evdev.h index 7287e739e832..34808b4b563c 100644 --- a/sys/dev/evdev/evdev.h +++ b/sys/dev/evdev/evdev.h @@ -97,8 +97,6 @@ int evdev_register(struct evdev_dev *); int evdev_register_mtx(struct evdev_dev *, struct mtx *); int evdev_unregister(struct evdev_dev *); int evdev_push_event(struct evdev_dev *, uint16_t, uint16_t, int32_t); -int evdev_sync(struct evdev_dev *); -int evdev_mt_sync(struct evdev_dev *); void evdev_support_prop(struct evdev_dev *, uint16_t); void evdev_support_event(struct evdev_dev *, uint16_t); void evdev_support_key(struct evdev_dev *, uint16_t); @@ -129,4 +127,68 @@ void evdev_push_leds(struct evdev_dev *, int); void evdev_push_repeats(struct evdev_dev *, keyboard_t *); evdev_event_t evdev_ev_kbd_event; +/* Event reporting shortcuts: */ +static __inline int +evdev_sync(struct evdev_dev *evdev) +{ + + return (evdev_push_event(evdev, EV_SYN, SYN_REPORT, 1)); +} + +static __inline int +evdev_mt_sync(struct evdev_dev *evdev) +{ + + return (evdev_push_event(evdev, EV_SYN, SYN_MT_REPORT, 1)); +} + +static __inline int +evdev_push_key(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_KEY, code, value != 0)); +} + +static __inline int +evdev_push_rel(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_REL, code, value)); +} + +static __inline int +evdev_push_abs(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_ABS, code, value)); +} + +static __inline int +evdev_push_msc(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_MSC, code, value)); +} + +static __inline int +evdev_push_led(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_LED, code, value != 0)); +} + +static __inline int +evdev_push_snd(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_SND, code, value != 0)); +} + +static __inline int +evdev_push_sw(struct evdev_dev *evdev, uint16_t code, int32_t value) +{ + + return (evdev_push_event(evdev, EV_SW, code, value != 0)); +} + #endif /* _DEV_EVDEV_EVDEV_H */ diff --git a/sys/dev/evdev/evdev_utils.c b/sys/dev/evdev/evdev_utils.c index 47e5e64a3c42..860634299270 100644 --- a/sys/dev/evdev/evdev_utils.c +++ b/sys/dev/evdev/evdev_utils.c @@ -271,8 +271,8 @@ evdev_push_mouse_btn(struct evdev_dev *evdev, int buttons) size_t i; for (i = 0; i < nitems(evdev_mouse_button_codes); i++) - evdev_push_event(evdev, EV_KEY, evdev_mouse_button_codes[i], - (buttons & (1 << i)) != 0); + evdev_push_key(evdev, evdev_mouse_button_codes[i], + buttons & (1 << i)); } void @@ -285,8 +285,7 @@ evdev_push_leds(struct evdev_dev *evdev, int leds) return; for (i = 0; i < nitems(evdev_led_codes); i++) - evdev_push_event(evdev, EV_LED, evdev_led_codes[i], - (leds & (1 << i)) != 0); + evdev_push_led(evdev, evdev_led_codes[i], leds & (1 << i)); } void From e012a280a584a65378d103296be67a83dd50440f Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Sat, 22 Oct 2016 22:55:10 +0000 Subject: [PATCH 030/235] EVDEV: ums evdev support improvements: locking and event reporting - Use ums lock as evdev lock - Do not cap axes values to sysmouse limits for evdev reports - Do not map T-axis events to buttons for evdev reports - Use shortcuts for event reporting Submitted by: Vladimir Kondratiev MFC after: 1 week --- sys/dev/usb/input/ums.c | 63 ++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c index 4d60517e1b50..6679ea31734a 100644 --- a/sys/dev/usb/input/ums.c +++ b/sys/dev/usb/input/ums.c @@ -173,6 +173,8 @@ static usb_fifo_ioctl_t ums_fifo_ioctl; #ifdef EVDEV_SUPPORT static evdev_open_t ums_ev_open; static evdev_close_t ums_ev_close; +static void ums_evdev_push(struct ums_softc *, int32_t, int32_t, + int32_t, int32_t, int32_t); #endif static void ums_start_rx(struct ums_softc *); @@ -205,6 +207,9 @@ ums_put_queue_timeout(void *__sc) mtx_assert(&sc->sc_mtx, MA_OWNED); ums_put_queue(sc, 0, 0, 0, 0, 0); +#ifdef EVDEV_SUPPORT + ums_evdev_push(sc, 0, 0, 0, 0, 0); +#endif } static void @@ -216,6 +221,9 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) uint8_t *buf = sc->sc_temp; int32_t buttons = 0; int32_t buttons_found = 0; +#ifdef EVDEV_SUPPORT + int32_t buttons_reported = 0; +#endif int32_t dw = 0; int32_t dx = 0; int32_t dy = 0; @@ -306,6 +314,9 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) if (++info != &sc->sc_info[UMS_INFO_MAX]) goto repeat; +#ifdef EVDEV_SUPPORT + buttons_reported = buttons; +#endif /* keep old button value(s) for non-detected buttons */ buttons |= sc->sc_status.button & ~buttons_found; @@ -351,6 +362,11 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) usb_callout_stop(&sc->sc_callout); ums_put_queue(sc, dx, dy, dz, dt, buttons); +#ifdef EVDEV_SUPPORT + ums_evdev_push(sc, dx, dy, dz, dt, + buttons_reported); +#endif + } } case USB_ST_SETUP: @@ -720,7 +736,7 @@ ums_attach(device_t dev) for (i = 0; i < info->sc_buttons; i++) evdev_support_key(sc->sc_evdev, BTN_MOUSE + i); - err = evdev_register(sc->sc_evdev); + err = evdev_register_mtx(sc->sc_evdev, &sc->sc_mtx); if (err) goto detach; #endif @@ -891,27 +907,32 @@ ums_put_queue(struct ums_softc *sc, int32_t dx, int32_t dy, } usb_fifo_put_data_linear(sc->sc_fifo.fp[USB_FIFO_RX], buf, sc->sc_mode.packetsize, 1); - -#ifdef EVDEV_SUPPORT - if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) { - /* Push evdev event */ - evdev_push_event(sc->sc_evdev, EV_REL, REL_X, dx); - evdev_push_event(sc->sc_evdev, EV_REL, REL_Y, -dy); - evdev_push_event(sc->sc_evdev, EV_REL, REL_WHEEL, -dz); - evdev_push_event(sc->sc_evdev, EV_REL, REL_HWHEEL, dt); - evdev_push_mouse_btn(sc->sc_evdev, - (buttons & ~MOUSE_STDBUTTONS) | - (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) | - (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) | - (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0)); - evdev_sync(sc->sc_evdev); - } -#endif } else { DPRINTF("Buffer full, discarded packet\n"); } } +#ifdef EVDEV_SUPPORT +static void +ums_evdev_push(struct ums_softc *sc, int32_t dx, int32_t dy, + int32_t dz, int32_t dt, int32_t buttons) +{ + if (evdev_rcpt_mask & EVDEV_RCPT_HW_MOUSE) { + /* Push evdev event */ + evdev_push_rel(sc->sc_evdev, REL_X, dx); + evdev_push_rel(sc->sc_evdev, REL_Y, -dy); + evdev_push_rel(sc->sc_evdev, REL_WHEEL, -dz); + evdev_push_rel(sc->sc_evdev, REL_HWHEEL, dt); + evdev_push_mouse_btn(sc->sc_evdev, + (buttons & ~MOUSE_STDBUTTONS) | + (buttons & (1 << 2) ? MOUSE_BUTTON1DOWN : 0) | + (buttons & (1 << 1) ? MOUSE_BUTTON2DOWN : 0) | + (buttons & (1 << 0) ? MOUSE_BUTTON3DOWN : 0)); + evdev_sync(sc->sc_evdev); + } +} +#endif + static void ums_reset_buf(struct ums_softc *sc) { @@ -925,7 +946,7 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc) { struct ums_softc *sc = (struct ums_softc *)ev_softc; - mtx_lock(&sc->sc_mtx); + mtx_assert(&sc->sc_mtx, MA_OWNED); sc->sc_evflags = UMS_EVDEV_OPENED; @@ -934,8 +955,6 @@ ums_ev_open(struct evdev_dev *evdev, void *ev_softc) ums_start_rx(sc); } - mtx_unlock(&sc->sc_mtx); - return (0); } @@ -944,14 +963,12 @@ ums_ev_close(struct evdev_dev *evdev, void *ev_softc) { struct ums_softc *sc = (struct ums_softc *)ev_softc; - mtx_lock(&sc->sc_mtx); + mtx_assert(&sc->sc_mtx, MA_OWNED); sc->sc_evflags = 0; if (sc->sc_fflags == 0) ums_stop_rx(sc); - - mtx_unlock(&sc->sc_mtx); } #endif From f8e856f8bd0b5cd769b186b09113e77a1636ad6d Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 23:05:44 +0000 Subject: [PATCH 031/235] Remove RCS entry from PSD content file, it is gone along with GNU RCS --- share/doc/psd/contents/contents.ms | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/share/doc/psd/contents/contents.ms b/share/doc/psd/contents/contents.ms index 4a222460600a..989fb16ce6c1 100644 --- a/share/doc/psd/contents/contents.ms +++ b/share/doc/psd/contents/contents.ms @@ -145,17 +145,6 @@ Indispensable tool for making sure large programs are properly compiled with minimal effort. .sp .IP -.tl 'An Introduction to the Revision Control System''PSD:13' -.if \n(.U \{\ -.br -.>> 13.rcs/paper.html -.\} -.QP -RCS is a user-contributed tool for working together with other people -without stepping on each other's toes. -An alternative to \fIsccs\fR for controlling software changes. -.sp -.IP .tl 'An Introduction to the Source Code Control System''PSD:14' .QP A useful introductory article for those users with From 439df1f0d43a9e92ea02a4162c7f119bdce16f93 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Sat, 22 Oct 2016 23:09:06 +0000 Subject: [PATCH 032/235] Remove reference to RCS from PSD titles --- share/doc/psd/title/Title | 6 ------ 1 file changed, 6 deletions(-) diff --git a/share/doc/psd/title/Title b/share/doc/psd/title/Title index eb1ad942274f..1cdf9b4751f4 100644 --- a/share/doc/psd/title/Title +++ b/share/doc/psd/title/Title @@ -117,12 +117,6 @@ Permission is granted to make and distribute verbatim copies of this document provided the copyright notice and this permission notice are preserved on all copies. .sp 2 -Document PSD:13 is part of the user contributed software and is -copyright 1983 by Walter F. Tichy. -Permission to copy the RCS documentation or any portion thereof as -necessary for licensed use of the software is granted to licensees -of this software, provided this copyright notice is included. -.sp 2 The views and conclusions contained in this manual are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the Regents of the University of California. From d2972ce0cbda43115d1d499d367a18b43640abf0 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sat, 22 Oct 2016 23:49:06 +0000 Subject: [PATCH 033/235] elfcopy: select mode by the end of the program name The mode of operation (elfcopy, mcs, or strip) is chosen based on the program name. Broaden this to allow a substring match at the end of the name to allow prefixes - for example, bsdstrip or aarch64-freebsd-strip. This improves use of these tools as drop-in replacements for GNU objcopy and strip, which are often built with a limited set of supported targets and installed with a target prefix for cross tools. Reviewed by: dim Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D1663 --- contrib/elftoolchain/elfcopy/main.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/contrib/elftoolchain/elfcopy/main.c b/contrib/elftoolchain/elfcopy/main.c index ebc0c92a1c01..1917c646c887 100644 --- a/contrib/elftoolchain/elfcopy/main.c +++ b/contrib/elftoolchain/elfcopy/main.c @@ -1529,6 +1529,22 @@ print_version(void) exit(EXIT_SUCCESS); } +/* + * Compare the ending of s with end. + */ +static int +strrcmp(const char *s, const char *end) +{ + size_t endlen, slen; + + slen = strlen(s); + endlen = strlen(end); + + if (slen >= endlen) + s += slen - endlen; + return (strcmp(s, end)); +} + int main(int argc, char **argv) { @@ -1562,12 +1578,16 @@ main(int argc, char **argv) if ((ecp->progname = ELFTC_GETPROGNAME()) == NULL) ecp->progname = "elfcopy"; - if (strcmp(ecp->progname, "strip") == 0) + if (strrcmp(ecp->progname, "strip") == 0) strip_main(ecp, argc, argv); - else if (strcmp(ecp->progname, "mcs") == 0) + else if (strrcmp(ecp->progname, "mcs") == 0) mcs_main(ecp, argc, argv); - else + else { + if (strrcmp(ecp->progname, "elfcopy") != 0 && + strrcmp(ecp->progname, "objcopy") != 0) + warnx("program mode not known, defaulting to elfcopy"); elfcopy_main(ecp, argc, argv); + } free_sec_add(ecp); free_sec_act(ecp); From 89965e701119f918e235be24c5c1e2e45b014e6e Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 23 Oct 2016 01:01:08 +0000 Subject: [PATCH 034/235] Use the right thread pointer for SPE alignment exceptions. --- sys/powerpc/powerpc/trap.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c index b0a86701ac47..702b48942da8 100644 --- a/sys/powerpc/powerpc/trap.c +++ b/sys/powerpc/powerpc/trap.c @@ -765,13 +765,13 @@ fix_unaligned(struct thread *td, struct trapframe *frame) fpr = (double *)td->td_pcb->pcb_vec.vr[reg]; fputhread = PCPU_GET(vecthread); - /* Juggle the FPU to ensure that we've initialized - * the FPRs, and that their current state is in + /* Juggle the SPE to ensure that we've initialized + * the registers, and that their current state is in * the PCB. */ - if (fputhread != td) { - if (fputhread) - save_vec(fputhread); + if (vecthread != td) { + if (vecthread) + save_vec(vecthread); enable_vec(td); } save_vec(td); From eaa5e39660d3d9150a2fd63384ac5d62eae11f27 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 23 Oct 2016 01:03:17 +0000 Subject: [PATCH 035/235] Revert r307813. I misread the code, and it shouldn't have compiled (fputhread is just a variable name). --- sys/powerpc/powerpc/trap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/powerpc/powerpc/trap.c b/sys/powerpc/powerpc/trap.c index 702b48942da8..b3217628943a 100644 --- a/sys/powerpc/powerpc/trap.c +++ b/sys/powerpc/powerpc/trap.c @@ -769,9 +769,9 @@ fix_unaligned(struct thread *td, struct trapframe *frame) * the registers, and that their current state is in * the PCB. */ - if (vecthread != td) { - if (vecthread) - save_vec(vecthread); + if (fputhread != td) { + if (fputhread) + save_vec(fputhread); enable_vec(td); } save_vec(td); From 561da369d766800787f49909755277657b6e6404 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 23 Oct 2016 08:19:43 +0000 Subject: [PATCH 036/235] [net80211] Add a macro to see if a frame is a management frame or not. --- sys/net80211/ieee80211.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index 28f1ffed81f7..a9a82c3fea19 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -162,6 +162,10 @@ struct ieee80211_qosframe_addr4 { #define IEEE80211_FC0_SUBTYPE_QOS_CFACKPOLL 0xb0 #define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 +#define IEEE80211_IS_MGMT(wh) \ + (!! (((wh)->i_fc[0] & IEEE80211_FC0_TYPE_MASK) \ + == IEEE80211_FC0_TYPE_MGT)) + #define IEEE80211_FC0_QOSDATA \ (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_VERSION_0) From d24ac5fb28cfd201ce1e701bbb511e1c277b5a98 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 23 Oct 2016 08:21:35 +0000 Subject: [PATCH 037/235] [net80211] Add a variant on ieee80211_get_rx_params() that returns a pointer. Be careful when calling this, as the underlying mbuf may change afterwards - common in the RX path. --- sys/net80211/ieee80211_freebsd.c | 15 +++++++++++++++ sys/net80211/ieee80211_freebsd.h | 1 + 2 files changed, 16 insertions(+) diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index e685e1d37d60..bf0407c0b840 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -529,6 +529,21 @@ ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs) return (0); } +const struct ieee80211_rx_stats * +ieee80211_get_rx_params_ptr(struct mbuf *m) +{ + struct m_tag *mtag; + struct ieee80211_rx_params *rx; + + mtag = m_tag_locate(m, MTAG_ABI_NET80211, NET80211_TAG_RECV_PARAMS, + NULL); + if (mtag == NULL) + return (NULL); + rx = (struct ieee80211_rx_params *)(mtag + 1); + return (&rx->params); +} + + /* * Add TOA parameters to the given mbuf. */ diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index f21423c3e375..cbacc08b51cf 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -713,6 +713,7 @@ int ieee80211_add_rx_params(struct mbuf *m, const struct ieee80211_rx_stats *rxs); int ieee80211_get_rx_params(struct mbuf *m, struct ieee80211_rx_stats *rxs); +const struct ieee80211_rx_stats * ieee80211_get_rx_params_ptr(struct mbuf *m); struct ieee80211_toa_params { int request_id; From 55ee7a4c5fcab265b2fb9555e853ed0aae458ec0 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 23 Oct 2016 11:23:17 +0000 Subject: [PATCH 038/235] In the fueword64(9) wrapper for architectures which do not implemented native fueword64(9) still, use proper type for local where fuword64() result is stored. Note that fueword64() is unused in the tree. Submitted by: Chunhui He PR: 212520 MFC after: 1 week --- sys/kern/subr_uio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index 0e85c92c4980..7e4f1b81949b 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -532,7 +532,7 @@ fueword32(volatile const void *base, int32_t *val) int fueword64(volatile const void *base, int64_t *val) { - int32_t res; + int64_t res; res = fuword64(base); if (res == -1) From 0b194aca210b65861422121ac9011b73c35f0dd5 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Sun, 23 Oct 2016 12:48:09 +0000 Subject: [PATCH 039/235] allwinner: Add support for P2WI bus P2WI (Push-Pull Two Wire Interface) is an I2C-like bus used in sun6i SoC for talking to power management unit IC. --- sys/arm/allwinner/aw_p2wi.c | 277 ++++++++++++++++++++++++++++++ sys/arm/allwinner/aw_p2wi.h | 79 +++++++++ sys/arm/allwinner/files.allwinner | 1 + sys/arm/conf/GENERIC | 1 + 4 files changed, 358 insertions(+) create mode 100644 sys/arm/allwinner/aw_p2wi.c create mode 100644 sys/arm/allwinner/aw_p2wi.h diff --git a/sys/arm/allwinner/aw_p2wi.c b/sys/arm/allwinner/aw_p2wi.c new file mode 100644 index 000000000000..6feb732e5305 --- /dev/null +++ b/sys/arm/allwinner/aw_p2wi.c @@ -0,0 +1,277 @@ +/*- + * Copyright (c) 2016 Emmanuel Vadot + * 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 ``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 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$ + */ + +/* + * Allwinner P2WI (Push-Pull Two Wire Interface) + * P2WI is a iic-like interface used on sun6i hardware + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include "iicbus_if.h" + +static struct ofw_compat_data compat_data[] = { + { "allwinner,sun6i-a31-p2wi", 1 }, + { NULL, 0 } +}; + +static struct resource_spec p2wi_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +struct p2wi_softc { + struct resource *res; + struct mtx mtx; + clk_t clk; + hwreset_t rst; + device_t iicbus; +}; + +#define P2WI_LOCK(sc) mtx_lock(&(sc)->mtx) +#define P2WI_UNLOCK(sc) mtx_unlock(&(sc)->mtx) +#define P2WI_READ(sc, reg) bus_read_4((sc)->res, (reg)) +#define P2WI_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) + +#define P2WI_RETRY 1000 + +static phandle_t +p2wi_get_node(device_t bus, device_t dev) +{ + return (ofw_bus_get_node(bus)); +} + +static int +p2wi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) +{ + struct p2wi_softc *sc; + int retry; + + sc = device_get_softc(dev); + + P2WI_LOCK(sc); + + P2WI_WRITE(sc, P2WI_CTRL, P2WI_CTRL_SOFT_RESET); + for (retry = P2WI_RETRY; retry > 0; retry--) + if ((P2WI_READ(sc, P2WI_CTRL) & P2WI_CTRL_SOFT_RESET) == 0) + break; + + P2WI_UNLOCK(sc); + + if (retry == 0) { + device_printf(dev, "soft reset timeout\n"); + return (ETIMEDOUT); + } + + return (IIC_ENOADDR); +} + +static int +p2wi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) +{ + struct p2wi_softc *sc; + int retry, error; + uint8_t data_len; + + sc = device_get_softc(dev); + + /* + * Since P2WI is only used for AXP22x PMIC we only support + * two messages of one byte length + */ + if (nmsgs != 2 || (msgs[0].flags & IIC_M_RD) == IIC_M_RD || + msgs[0].len != 1 || msgs[1].len != 1) + return (EINVAL); + + P2WI_LOCK(sc); + + /* Write address */ + P2WI_WRITE(sc, P2WI_DADDR0, msgs[0].buf[0]); + + /* Write Data length/Direction */ + data_len = P2WI_DLEN_LEN(msgs[1].len); + if ((msgs[1].flags & IIC_M_RD) == 0) + P2WI_WRITE(sc, P2WI_DATA0, msgs[1].buf[0]); + else + data_len |= P2WI_DLEN_READ; + P2WI_WRITE(sc, P2WI_DLEN, data_len); + + /* Start transfer */ + P2WI_WRITE(sc, P2WI_CTRL, P2WI_CTRL_START_TRANS); + + /* Wait for transfer to complete */ + for (retry = P2WI_RETRY; retry > 0; retry--) + if ((P2WI_READ(sc, P2WI_CTRL) & P2WI_CTRL_START_TRANS) == 0) + break; + + if (retry == 0) { + error = ETIMEDOUT; + goto done; + } + + /* Read data if needed */ + if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD) { + msgs[1].buf[0] = P2WI_READ(sc, P2WI_DATA0) & 0xff; + msgs[1].len = 1; + } + + error = 0; + +done: + P2WI_UNLOCK(sc); + + return (error); +} + +static int +p2wi_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "Allwinner P2WI"); + return (BUS_PROBE_DEFAULT); +} + +static int +p2wi_attach(device_t dev) +{ + struct p2wi_softc *sc; + int error; + + sc = device_get_softc(dev); + mtx_init(&sc->mtx, device_get_nameunit(dev), "p2wi", MTX_DEF); + + if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) { + error = clk_enable(sc->clk); + if (error != 0) { + device_printf(dev, "cannot enable clock\n"); + goto fail; + } + } + if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) { + error = hwreset_deassert(sc->rst); + if (error != 0) { + device_printf(dev, "cannot de-assert reset\n"); + goto fail; + } + } + + if (bus_alloc_resources(dev, p2wi_spec, &sc->res) != 0) { + device_printf(dev, "cannot allocate resources for device\n"); + error = ENXIO; + goto fail; + } + + sc->iicbus = device_add_child(dev, "iicbus", -1); + if (sc->iicbus == NULL) { + device_printf(dev, "cannot add iicbus child device\n"); + error = ENXIO; + goto fail; + } + + /* Disable interrupts */ + P2WI_WRITE(sc, P2WI_INTE, 0x0); + + bus_generic_attach(dev); + + return (0); + +fail: + bus_release_resources(dev, p2wi_spec, &sc->res); + if (sc->rst != NULL) + hwreset_release(sc->rst); + if (sc->clk != NULL) + clk_release(sc->clk); + mtx_destroy(&sc->mtx); + return (error); +} + +static device_method_t p2wi_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, p2wi_probe), + DEVMETHOD(device_attach, p2wi_attach), + + /* Bus interface */ + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), + DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), + DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), + + /* OFW methods */ + DEVMETHOD(ofw_bus_get_node, p2wi_get_node), + + /* iicbus interface */ + DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD(iicbus_reset, p2wi_reset), + DEVMETHOD(iicbus_transfer, p2wi_transfer), + + DEVMETHOD_END +}; + +static driver_t p2wi_driver = { + "iichb", + p2wi_methods, + sizeof(struct p2wi_softc), +}; + +static devclass_t p2wi_devclass; + +EARLY_DRIVER_MODULE(iicbus, p2wi, iicbus_driver, iicbus_devclass, 0, 0, + BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); +EARLY_DRIVER_MODULE(p2wi, simplebus, p2wi_driver, p2wi_devclass, 0, 0, + BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); +MODULE_VERSION(p2wi, 1); diff --git a/sys/arm/allwinner/aw_p2wi.h b/sys/arm/allwinner/aw_p2wi.h new file mode 100644 index 000000000000..a6b18208486a --- /dev/null +++ b/sys/arm/allwinner/aw_p2wi.h @@ -0,0 +1,79 @@ +/*- + * Copyright (c) 2016 Emmanuel Vadot + * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __AW_P2WI_H__ +#define __AW_P2WI_H__ + +#define P2WI_CTRL 0x00 +#define P2WI_CTRL_SOFT_RESET (1 << 0) +#define P2WI_CTRL_GLOBAL_INT_ENB (1 << 1) +#define P2WI_CTRL_ABORT_TRANS (1 << 6) +#define P2WI_CTRL_START_TRANS (1 << 7) + +#define P2WI_CCR 0x04 +#define P2WI_CCR_CLK_DIV_SHIFT 0 +#define P2WI_CCR_CLK_DIV_MASK 0xFF +#define P2WI_CCR_SDA_ODLY_SHIFT 7 +#define P2WI_CCR_SDA_ODLY_MASK 0x700 + +#define P2WI_INTE 0x08 +#define P2WI_INTE_TRANS_OVER_ENB +#define P2WI_INTE_TRANS_ERR_ENB +#define P2WI_INTE_LOAD_BSY_ENB + +#define P2WI_STAT 0x0C +#define P2WI_STAT_TRANS_OVER (1 << 0) +#define P2WI_STAT_TRANS_ERR (1 << 1) +#define P2WI_STAT_LOAD_BSY (1 << 2) +#define P2WI_STAT_TRANS_ERR_ID_SHIFT 7 +#define P2WI_STAT_TRANS_ERR_ID_MASK 0xFF00 + +#define P2WI_DADDR0 0x10 + +#define P2WI_DADDR1 0x14 + +#define P2WI_DLEN 0x18 +#define P2WI_DLEN_LEN(x) ((x - 1) & 0x7) +#define P2WI_DLEN_READ (1 << 4) + +#define P2WI_DATA0 0x1C + +#define P2WI_DATA1 0x20 + +#define P2WI_LCR 0x24 +#define P2WI_LCR_SDA_CTL_EN (1 << 0) +#define P2WI_LCR_SDA_CTL (1 << 1) +#define P2WI_LCR_SCL_CTL_EN (1 << 2) +#define P2WI_LCR_SCL_CTL (1 << 3) +#define P2WI_LCR_SDA_STATE (1 << 4) +#define P2WI_LCR_SCL_STATE (1 << 5) + + +#define P2WI_PMCR 0x28 + +#endif /* __AW_P2WI_H__ */ diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index d06f6aebbe8f..5ada7549355e 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -12,6 +12,7 @@ arm/allwinner/a10_mmc.c optional mmc arm/allwinner/a10_sramc.c standard arm/allwinner/aw_nmi.c optional intrng arm/allwinner/aw_if_dwc.c optional dwc +arm/allwinner/aw_p2wi.c optional p2wi arm/allwinner/aw_rsb.c optional rsb arm/allwinner/aw_rtc.c standard arm/allwinner/aw_ts.c standard diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 61b53ec35e18..0d7bf7ad1a39 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -104,6 +104,7 @@ device iicbus device iic device twsi device rsb +device p2wi # Allwinner Push-Pull Two Wire interface device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc From ce1e4668defe6a9d7677038ed98931a0d8850d1f Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 23 Oct 2016 14:28:29 +0000 Subject: [PATCH 040/235] Use upstream suffixes for LLVM IR In r307676, several make rules were added for LLVM IR files, both in text and binary format. Unfortunately these use different suffixes from what upstream uses: * Text IR has upstream suffix ".ll", while r307676 uses ".llo" * Binary IR has upstream suffix ".bc", while r307676 uses ".bco" Change these to what upstream uses instead. Reviewed by: emaste Differential Revision: https://reviews.freebsd.org/D8326 --- share/mk/bsd.suffixes.mk | 8 ++++---- share/mk/sys.mk | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/share/mk/bsd.suffixes.mk b/share/mk/bsd.suffixes.mk index 9ca583b0b952..21668ede069a 100644 --- a/share/mk/bsd.suffixes.mk +++ b/share/mk/bsd.suffixes.mk @@ -20,10 +20,10 @@ ${CC} ${STATIC_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CTFCONVERT_CMD} -.c.bco: +.c.bc: ${CC} -emit-llvm ${IR_CFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.c.llo: +.c.ll: ${CC} -emit-llvm ${IR_CFLAGS} -S ${.IMPSRC} -o ${.TARGET} .cc .cpp .cxx .C: @@ -32,10 +32,10 @@ .cc.o .cpp.o .cxx.o .C.o: ${CXX} ${STATIC_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.cc.bco .cpp.bco .cxx.bco .C.bco: +.cc.bc .cpp.bc .cxx.bc .C.bc: ${CXX} -emit-llvm ${IR_CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.cc.llo .cpp.llo .cxx.llo .C.llo: +.cc.ll .cpp.ll .cxx.ll .C.ll: ${CXX} -emit-llvm ${IR_CXXFLAGS} -S ${.IMPSRC} -o ${.TARGET} .m.o: diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 6efa99410d0a..eeb3f979f5f8 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -121,7 +121,7 @@ META_MODE?= normal .if defined(%POSIX) .SUFFIXES: .o .c .y .l .a .sh .f .else -.SUFFIXES: .out .a .ln .o .bco .llo .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh +.SUFFIXES: .out .a .ln .o .bc .ll .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh .endif AR ?= ar From 3c2b90f1d14c395722b9a7cd9881655d36dc747e Mon Sep 17 00:00:00 2001 From: Jared McNeill Date: Sun, 23 Oct 2016 17:48:34 +0000 Subject: [PATCH 041/235] Throttle CPU frequency when hot temperature threshold has been reached to prevent overheating. When sensor 0's alarm interrupt is fired, set a throttle flag. Further requests to set CPU frequency will be rejected until sensor 0's temperature returns to a level below the hot temperature threshold. Relnotes: yes --- sys/arm/allwinner/aw_thermal.c | 195 ++++++++++++++++++++++++++++----- 1 file changed, 168 insertions(+), 27 deletions(-) diff --git a/sys/arm/allwinner/aw_thermal.c b/sys/arm/allwinner/aw_thermal.c index c8bbe3edef9c..509a69444224 100644 --- a/sys/arm/allwinner/aw_thermal.c +++ b/sys/arm/allwinner/aw_thermal.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -51,6 +52,8 @@ __FBSDID("$FreeBSD$"); #include +#include "cpufreq_if.h" + #define THS_CTRL0 0x00 #define THS_CTRL1 0x04 #define ADC_CALI_EN (1 << 17) @@ -70,6 +73,14 @@ __FBSDID("$FreeBSD$"); #define ALARM_INT2_STS (1 << 2) #define ALARM_INT1_STS (1 << 1) #define ALARM_INT0_STS (1 << 0) +#define THS_ALARM0_CTRL 0x50 +#define ALARM_T_HOT_MASK 0xfff +#define ALARM_T_HOT_SHIFT 16 +#define ALARM_T_HYST_MASK 0xfff +#define ALARM_T_HYST_SHIFT 0 +#define THS_SHUTDOWN0_CTRL 0x60 +#define SHUT_T_HOT_MASK 0xfff +#define SHUT_T_HOT_SHIFT 16 #define THS_FILTER 0x70 #define THS_CALIB0 0x74 #define THS_CALIB1 0x78 @@ -97,16 +108,24 @@ __FBSDID("$FreeBSD$"); #define H3_ADC_ACQUIRE_TIME 0x3f #define H3_FILTER 0x6 #define H3_INTC 0x191000 -#define H3_TEMP_BASE 217000000 -#define H3_TEMP_MUL 121168 -#define H3_TEMP_DIV 1000000 +#define H3_TEMP_BASE 2794000 +#define H3_TEMP_MUL 1000 +#define H3_TEMP_DIV -14882 #define H3_CLK_RATE 4000000 #define TEMP_C_TO_K 273 #define SENSOR_ENABLE_ALL (SENSOR0_EN|SENSOR1_EN|SENSOR2_EN) #define SHUT_INT_ALL (SHUT_INT0_STS|SHUT_INT1_STS|SHUT_INT2_STS) +#define ALARM_INT_ALL (ALARM_INT0_STS) #define MAX_SENSORS 3 +#define MAX_CF_LEVELS 64 + +#define THROTTLE_ENABLE_DEFAULT 1 + +/* Enable thermal throttling */ +static int aw_thermal_throttle_enable = THROTTLE_ENABLE_DEFAULT; +TUNABLE_INT("hw.aw_thermal.throttle_enable", &aw_thermal_throttle_enable); struct aw_thermal_sensor { const char *name; @@ -118,14 +137,23 @@ struct aw_thermal_config { int nsensors; uint64_t clk_rate; uint32_t adc_acquire_time; + int adc_cali_en; uint32_t filter; uint32_t intc; + int (*to_temp)(uint32_t); int temp_base; int temp_mul; int temp_div; - int calib; + int calib0, calib1; + uint32_t calib0_mask, calib1_mask; }; +static int +a83t_to_temp(uint32_t val) +{ + return ((A83T_TEMP_BASE - (val * A83T_TEMP_MUL)) / A83T_TEMP_DIV); +} + static const struct aw_thermal_config a83t_config = { .nsensors = 3, .sensors = { @@ -144,14 +172,22 @@ static const struct aw_thermal_config a83t_config = { }, .clk_rate = A83T_CLK_RATE, .adc_acquire_time = A83T_ADC_ACQUIRE_TIME, + .adc_cali_en = 1, .filter = A83T_FILTER, .intc = A83T_INTC, - .temp_base = A83T_TEMP_BASE, - .temp_mul = A83T_TEMP_MUL, - .temp_div = A83T_TEMP_DIV, - .calib = 1, + .to_temp = a83t_to_temp, + .calib0 = 1, + .calib0_mask = 0xffffffff, + .calib1 = 1, + .calib1_mask = 0xffffffff, }; +static int +a64_to_temp(uint32_t val) +{ + return ((A64_TEMP_BASE - (val * A64_TEMP_MUL)) / A64_TEMP_DIV); +} + static const struct aw_thermal_config a64_config = { .nsensors = 3, .sensors = { @@ -172,11 +208,15 @@ static const struct aw_thermal_config a64_config = { .adc_acquire_time = A64_ADC_ACQUIRE_TIME, .filter = A64_FILTER, .intc = A64_INTC, - .temp_base = A64_TEMP_BASE, - .temp_mul = A64_TEMP_MUL, - .temp_div = A64_TEMP_DIV, + .to_temp = a64_to_temp, }; +static int +h3_to_temp(uint32_t val) +{ + return (((int)(val * H3_TEMP_MUL) - H3_TEMP_BASE) / H3_TEMP_DIV); +} + static const struct aw_thermal_config h3_config = { .nsensors = 1, .sensors = { @@ -189,9 +229,9 @@ static const struct aw_thermal_config h3_config = { .adc_acquire_time = H3_ADC_ACQUIRE_TIME, .filter = H3_FILTER, .intc = H3_INTC, - .temp_base = H3_TEMP_BASE, - .temp_mul = H3_TEMP_MUL, - .temp_div = H3_TEMP_DIV, + .to_temp = h3_to_temp, + .calib0 = 1, + .calib0_mask = 0xfff, }; static struct ofw_compat_data compat_data[] = { @@ -205,8 +245,14 @@ static struct ofw_compat_data compat_data[] = { (void *)ofw_bus_search_compatible((d), compat_data)->ocd_data struct aw_thermal_softc { + device_t dev; struct resource *res[2]; struct aw_thermal_config *conf; + + int throttle; + int min_freq; + struct cf_level levels[MAX_CF_LEVELS]; + eventhandler_tag cf_pre_tag; }; static struct resource_spec aw_thermal_spec[] = { @@ -224,15 +270,20 @@ aw_thermal_init(struct aw_thermal_softc *sc) uint32_t calib0, calib1; int error; - if (sc->conf->calib) { + if (sc->conf->calib0 != 0 || sc->conf->calib1 != 0) { /* Read calibration settings from SRAM */ error = aw_sid_read_tscalib(&calib0, &calib1); if (error != 0) return (error); + calib0 &= sc->conf->calib0_mask; + calib1 &= sc->conf->calib1_mask; + /* Write calibration settings to thermal controller */ - WR4(sc, THS_CALIB0, calib0); - WR4(sc, THS_CALIB1, calib1); + if (sc->conf->calib0 != 0 && calib0 != 0) + WR4(sc, THS_CALIB0, calib0); + if (sc->conf->calib1 != 0 && calib1 != 0) + WR4(sc, THS_CALIB1, calib1); } /* Configure ADC acquire time (CLK_IN/(N+1)) and enable sensors */ @@ -245,7 +296,7 @@ aw_thermal_init(struct aw_thermal_softc *sc) /* Enable interrupts */ WR4(sc, THS_INTS, RD4(sc, THS_INTS)); - WR4(sc, THS_INTC, sc->conf->intc | SHUT_INT_ALL); + WR4(sc, THS_INTC, sc->conf->intc | SHUT_INT_ALL | ALARM_INT_ALL); /* Enable sensors */ WR4(sc, THS_CTRL2, RD4(sc, THS_CTRL2) | SENSOR_ENABLE_ALL); @@ -253,13 +304,6 @@ aw_thermal_init(struct aw_thermal_softc *sc) return (0); } -static int -aw_thermal_reg_to_temp(struct aw_thermal_softc *sc, uint32_t val) -{ - return ((sc->conf->temp_base - (val * sc->conf->temp_mul)) / - sc->conf->temp_div); -} - static int aw_thermal_gettemp(struct aw_thermal_softc *sc, int sensor) { @@ -267,7 +311,40 @@ aw_thermal_gettemp(struct aw_thermal_softc *sc, int sensor) val = RD4(sc, THS_DATA0 + (sensor * 4)); - return (aw_thermal_reg_to_temp(sc, val) + TEMP_C_TO_K); + return (sc->conf->to_temp(val) + TEMP_C_TO_K); +} + +static int +aw_thermal_getshut(struct aw_thermal_softc *sc, int sensor) +{ + uint32_t val; + + val = RD4(sc, THS_SHUTDOWN0_CTRL + (sensor * 4)); + val = (val >> SHUT_T_HOT_SHIFT) & SHUT_T_HOT_MASK; + + return (sc->conf->to_temp(val) + TEMP_C_TO_K); +} + +static int +aw_thermal_gethyst(struct aw_thermal_softc *sc, int sensor) +{ + uint32_t val; + + val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4)); + val = (val >> ALARM_T_HYST_SHIFT) & ALARM_T_HYST_MASK; + + return (sc->conf->to_temp(val) + TEMP_C_TO_K); +} + +static int +aw_thermal_getalarm(struct aw_thermal_softc *sc, int sensor) +{ + uint32_t val; + + val = RD4(sc, THS_ALARM0_CTRL + (sensor * 4)); + val = (val >> ALARM_T_HOT_SHIFT) & ALARM_T_HOT_MASK; + + return (sc->conf->to_temp(val) + TEMP_C_TO_K); } static int @@ -284,6 +361,55 @@ aw_thermal_sysctl(SYSCTL_HANDLER_ARGS) return sysctl_handle_opaque(oidp, &val, sizeof(val), req); } +static void +aw_thermal_throttle(struct aw_thermal_softc *sc, int enable) +{ + device_t cf_dev; + int count, error; + + if (enable == sc->throttle) + return; + + if (enable != 0) { + /* Set the lowest available frequency */ + cf_dev = devclass_get_device(devclass_find("cpufreq"), 0); + if (cf_dev == NULL) + return; + count = MAX_CF_LEVELS; + error = CPUFREQ_LEVELS(cf_dev, sc->levels, &count); + if (error != 0 || count == 0) + return; + sc->min_freq = sc->levels[count - 1].total_set.freq; + error = CPUFREQ_SET(cf_dev, &sc->levels[count - 1], + CPUFREQ_PRIO_USER); + if (error != 0) + return; + } + + sc->throttle = enable; +} + +static void +aw_thermal_cf_pre_change(void *arg, const struct cf_level *level, int *status) +{ + struct aw_thermal_softc *sc; + int temp_cur, temp_alarm; + + sc = arg; + + if (aw_thermal_throttle_enable == 0 || sc->throttle == 0 || + level->total_set.freq == sc->min_freq) + return; + + temp_cur = aw_thermal_gettemp(sc, 0); + temp_alarm = aw_thermal_getalarm(sc, 0); + + if (temp_cur < temp_alarm) + aw_thermal_throttle(sc, 0); + else + *status = ENXIO; +} + static void aw_thermal_intr(void *arg) { @@ -299,9 +425,12 @@ aw_thermal_intr(void *arg) if ((ints & SHUT_INT_ALL) != 0) { device_printf(dev, - "WARNING - current temperature exceeds safe limits\n"); + "WARNING - current temperature exceeds safe limits\n"); shutdown_nice(RB_POWEROFF); } + + if ((ints & ALARM_INT_ALL) != 0) + aw_thermal_throttle(sc, 1); } static int @@ -383,6 +512,18 @@ aw_thermal_attach(device_t dev) sc, i, aw_thermal_sysctl, "IK0", sc->conf->sensors[i].desc); + if (bootverbose) + for (i = 0; i < sc->conf->nsensors; i++) { + device_printf(dev, + "#%d: alarm %dC hyst %dC shut %dC\n", i, + aw_thermal_getalarm(sc, i) - TEMP_C_TO_K, + aw_thermal_gethyst(sc, i) - TEMP_C_TO_K, + aw_thermal_getshut(sc, i) - TEMP_C_TO_K); + } + + sc->cf_pre_tag = EVENTHANDLER_REGISTER(cpufreq_pre_change, + aw_thermal_cf_pre_change, sc, EVENTHANDLER_PRI_FIRST); + return (0); fail: From 90136961949dd6ac01e8905dbfae00835b2b1bea Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 23 Oct 2016 18:00:08 +0000 Subject: [PATCH 042/235] Tweak the UPDATING message a bit about the upgrade path. Add some automation into Makefile.inc1 to to enforce known good upgrade from source paths. --- Makefile.inc1 | 15 ++++++++++++++- UPDATING | 11 +++++++---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Makefile.inc1 b/Makefile.inc1 index 99918b3703e8..476c05431d2a 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -453,7 +453,7 @@ PACKAGE= kernel # BOOTSTRAPPING?= 0 -# Keep these in sync +# Keep these in sync -- see below for special case exception MINIMUM_SUPPORTED_OSREL?= 900044 MINIMUM_SUPPORTED_REL?= 9.1 @@ -1557,10 +1557,23 @@ _elftoolchain_libs= lib/libelf lib/libdwarf .endif legacy: .PHONY +# Temporary special case for automatically detecting the clang compiler issue +# Note: 9.x didn't have FreeBSD_version bumps often enough, so you may need to +# set BOOTSTRAPPING to 0 if you're stable/9 tree post-dates r286035 but is before +# the version bump in r296219 (from July 29, 2015 -> Feb 29, 2016). +.if ${BOOTSTRAPPING} != 0 && \ + ${WANT_COMPILER_TYPE} == "clang" && ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} < 30601 +.if ${BOOTSTRAPPING} > 10000000 && ${BOOTSTRAPPING} < 1002501 + @echo "ERROR: Source upgrades from stable/10 prior to r286033 are not supported."; false +.elif ${BOOTSTRAPPING} > 9000000 && ${BOOTSTRAPPING} < 903509 + @echo "ERROR: Source upgrades from stable/9 prior to r286035 are not supported."; false +.endif +.endif .if ${BOOTSTRAPPING} < ${MINIMUM_SUPPORTED_OSREL} && ${BOOTSTRAPPING} != 0 @echo "ERROR: Source upgrades from versions prior to ${MINIMUM_SUPPORTED_REL} are not supported."; \ false .endif + .for _tool in tools/build ${_elftoolchain_libs} ${_+_}@${ECHODIR} "===> ${_tool} (obj,includes,all,install)"; \ cd ${.CURDIR}/${_tool}; \ diff --git a/UPDATING b/UPDATING index 20a82940a5c8..71a952aff9ab 100644 --- a/UPDATING +++ b/UPDATING @@ -41,10 +41,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: 11.0-RELEASE). These revisions post-date the 10.2 and 9.3 releases, so you'll need to take the unusual step of upgrading to the tip of the stable branch before moving to 11 or -current via a source upgrade. - stable/11 and 11.0-RELEASE post-date the fix so you can move from them - to -current. This differs from the historical situation where one could - upgrade from anywhere on the last couple of stable branches, so be - careful. + stable/11 and 11.0-RELEASE have working newer compiler. This differs + from the historical situation where one could upgrade from anywhere on + the last couple of stable branches, so be careful. + + If you're running a hybrid system on 9.x or 10.x with an updated clang + compiler or are using an supported external toolchain, the build system + will allow the upgrade. Otherwise it will print a reminder. ****************************** SPECIAL WARNING: ****************************** From 40adda8665bbcda1bad7e3a6a3c1031027faf39a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sun, 23 Oct 2016 18:00:09 +0000 Subject: [PATCH 043/235] Use checkyesno instead of rolling my own.. --- etc/rc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/rc b/etc/rc index 278c9de494c3..b2ffe0f7a04c 100644 --- a/etc/rc +++ b/etc/rc @@ -135,16 +135,16 @@ done # Note: this assumes firstboot_sentinel is on / when we have # a read-only /, or that it is on media that's writable. if [ -e ${firstboot_sentinel} ]; then - [ ${root_rw_mount#[Yy][Ee][Ss]} = "" ] || mount -uw / + checkyesno root_rw_mount && mount -uw / chflags -R 0 ${firstboot_sentinel} rm -rf ${firstboot_sentinel} if [ -e ${firstboot_sentinel}-reboot ]; then chflags -R 0 ${firstboot_sentinel}-reboot rm -rf ${firstboot_sentinel}-reboot - [ ${root_rw_mount#[Yy][Ee][Ss]} = "" ] || mount -ur / + checkyesno root_rw_mount && mount -ur / kill -INT 1 fi - [ ${root_rw_mount#[Yy][Ee][Ss]} = "" ] || mount -ur / + checkyesno root_rw_mount && mount -ur / fi echo '' From 3bf61aa48d5f378aecaf377cfa8a8ecbe96671a5 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 23 Oct 2016 18:08:34 +0000 Subject: [PATCH 044/235] Remove the powerpcspe Symbol.map, it's identical to powerpc's. Reported by: kib --- lib/libc/powerpcspe/Makefile.inc | 2 +- lib/libc/powerpcspe/Symbol.map | 59 -------------------------------- 2 files changed, 1 insertion(+), 60 deletions(-) delete mode 100644 lib/libc/powerpcspe/Symbol.map diff --git a/lib/libc/powerpcspe/Makefile.inc b/lib/libc/powerpcspe/Makefile.inc index c5cb1ba47245..3a7960ab378c 100644 --- a/lib/libc/powerpcspe/Makefile.inc +++ b/lib/libc/powerpcspe/Makefile.inc @@ -5,4 +5,4 @@ SRCS+= trivial-vdso_tc.c # Long double is 64-bits MDSRCS+=machdep_ldisd.c -SYM_MAPS+=${LIBC_SRCTOP}/powerpcspe/Symbol.map +SYM_MAPS+=${LIBC_SRCTOP}/powerpc/Symbol.map diff --git a/lib/libc/powerpcspe/Symbol.map b/lib/libc/powerpcspe/Symbol.map deleted file mode 100644 index f695c81bb27f..000000000000 --- a/lib/libc/powerpcspe/Symbol.map +++ /dev/null @@ -1,59 +0,0 @@ -/* - * $FreeBSD$ - */ - -/* - * This only needs to contain symbols that are not listed in - * symbol maps from other parts of libc (i.e., not found in - * stdlib/Symbol.map, string/Symbol.map, sys/Symbol.map, ...). - */ -FBSD_1.0 { - /* PSEUDO syscalls */ - _exit; - - _mcount; - _setjmp; - _longjmp; - fabs; - __flt_rounds; - fpgetmask; - fpgetround; - fpgetsticky; - fpsetmask; - fpsetround; - __infinity; - __nan; - makecontext; - setjmp; - longjmp; - sigsetjmp; - siglongjmp; - htonl; - htons; - ntohl; - ntohs; - brk; - exect; - sbrk; - vfork; -}; - -FBSD_1.3 { - __eabi; -}; - -FBSDprivate_1.0 { - /* PSEUDO syscalls */ - __sys_getlogin; - _getlogin; - __sys_exit; - - _set_tp; - _fpgetsticky; - __makecontext; - __longjmp; - signalcontext; - __signalcontext; - __syncicache; - _end; -}; From 5a7f20b4d0b953902b74423dc5b15d04ddb8515b Mon Sep 17 00:00:00 2001 From: Jared McNeill Date: Sun, 23 Oct 2016 19:02:19 +0000 Subject: [PATCH 045/235] Add device cpufreq. --- sys/arm/conf/GENERIC | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 0d7bf7ad1a39..22c69db1de9b 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -59,6 +59,9 @@ device phy device hwreset device regulator +# CPU frequency control +device cpufreq + # Interrupt controller options INTRNG device gic From b474a0278424b9ae4191a6a5bbcac358c9996472 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sun, 23 Oct 2016 19:59:56 +0000 Subject: [PATCH 046/235] Use the correct name for the qm_portals class. This file was copy&pasted from bman_fdt, and it still shows. --- sys/dev/dpaa/qman_fdt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/dev/dpaa/qman_fdt.c b/sys/dev/dpaa/qman_fdt.c index cdcaa654ea5e..69f128cf649f 100644 --- a/sys/dev/dpaa/qman_fdt.c +++ b/sys/dev/dpaa/qman_fdt.c @@ -91,7 +91,7 @@ qman_fdt_probe(device_t dev) static device_probe_t qman_portals_fdt_probe; static device_attach_t qman_portals_fdt_attach; -static device_method_t bm_portals_methods[] = { +static device_method_t qm_portals_methods[] = { /* Device interface */ DEVMETHOD(device_probe, qman_portals_fdt_probe), DEVMETHOD(device_attach, qman_portals_fdt_attach), @@ -100,14 +100,14 @@ static device_method_t bm_portals_methods[] = { { 0, 0 } }; -static driver_t bm_portals_driver = { +static driver_t qm_portals_driver = { "qman-portals", - bm_portals_methods, + qm_portals_methods, sizeof(struct dpaa_portals_softc), }; -static devclass_t bm_portals_devclass; -DRIVER_MODULE(qman_portals, ofwbus, bm_portals_driver, bm_portals_devclass, 0, 0); +static devclass_t qm_portals_devclass; +DRIVER_MODULE(qman_portals, ofwbus, qm_portals_driver, qm_portals_devclass, 0, 0); static void get_addr_props(phandle_t node, uint32_t *addrp, uint32_t *sizep) From 3b46b94b58681c67d65456b003bca19b9a4074df Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 23 Oct 2016 20:41:25 +0000 Subject: [PATCH 047/235] [rss] install the header file. Submitted by: gallatin --- lib/librss/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/librss/Makefile b/lib/librss/Makefile index 384a205d85bd..51be6d91936b 100644 --- a/lib/librss/Makefile +++ b/lib/librss/Makefile @@ -5,6 +5,7 @@ SHLIBDIR?= /lib .include +INCS= librss.h LIB= rss SHLIB_MAJOR= 1 From 94dab02d885da6518c627244baebef24a8cd38ec Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sun, 23 Oct 2016 20:42:32 +0000 Subject: [PATCH 048/235] [rss] manpage improvements. Submitted by: gallatin --- lib/librss/librss.3 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/librss/librss.3 b/lib/librss/librss.3 index 02a50f89eed7..2ac5804746b2 100644 --- a/lib/librss/librss.3 +++ b/lib/librss/librss.3 @@ -1,6 +1,6 @@ .\" $FreeBSD$ .\" -.Dd September 29, 2016 +.Dd October 23, 2016 .Dt LIBRSS 3 .Os .Sh NAME @@ -9,6 +9,8 @@ .Sh LIBRARY .Lb librss .Sh SYNOPSIS +.In sys/param.h +.In sys/cpuset.h .In librss.h .Ft struct rss_config * .Fn rss_config_get "void" @@ -17,6 +19,8 @@ .Ft int .Fn rss_config_get_bucket_count "struct rss_config *cfg" .Ft int +.Fn rss_get_bucket_cpuset "struct rss_config *rc" "rss_bucket_type_t btype" "int bucket" "cpuset_t *cs" +.Ft int .Fn rss_set_bucket_rebalance_cb "rss_bucket_rebalance_cb_t *cb" "void *cbdata" .Ft int .Fn rss_sock_set_bindmulti "int fd" "int af" "int val" From b7009d53923a8bf6deb0720c3a07afb09fb3c520 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 03:26:34 +0000 Subject: [PATCH 049/235] hyperv/hn: Move chimney buffer index and size to txdesc. All RNDIS control messages have used SG list for a while. This makes the send context suitable for further refactoring. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8308 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 30 +------ sys/dev/hyperv/netvsc/hv_net_vsc.h | 11 +-- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 82 +++++++++++++++---- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 5 +- sys/dev/hyperv/netvsc/if_hnvar.h | 28 ++----- 5 files changed, 81 insertions(+), 75 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 2676222541e3..a14faffbe991 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -117,7 +117,7 @@ hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, /* * Execute the xact setup by the caller. */ - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact); vmbus_xact_activate(xact); error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, @@ -669,34 +669,6 @@ hn_chim_free(struct hn_softc *sc, uint32_t chim_idx) atomic_clear_long(&sc->hn_chim_bmap[idx], mask); } -/* - * Net VSC on send - * Sends a packet on the specified Hyper-V device. - * Returns 0 on success, non-zero on failure. - */ -int -hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, - struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) -{ - struct hn_nvs_rndis rndis; - int ret; - - rndis.nvs_type = HN_NVS_TYPE_RNDIS; - rndis.nvs_rndis_mtype = rndis_mtype; - rndis.nvs_chim_idx = sndc->hn_chim_idx; - rndis.nvs_chim_sz = sndc->hn_chim_sz; - - if (gpa_cnt) { - ret = hn_nvs_send_sglist(chan, gpa, gpa_cnt, - &rndis, sizeof(rndis), sndc); - } else { - ret = hn_nvs_send(chan, VMBUS_CHANPKT_FLAG_RC, - &rndis, sizeof(rndis), sndc); - } - - return (ret); -} - int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch0) { diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 06a6dfe8c98b..2e3e2aacc1e3 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -104,8 +104,8 @@ struct vmbus_channel; #define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE) #define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE) -#ifndef HN_USE_TXDESC_BUFRING struct hn_txdesc; +#ifndef HN_USE_TXDESC_BUFRING SLIST_HEAD(hn_txdesc_list, hn_txdesc); #else struct buf_ring; @@ -179,6 +179,7 @@ struct hn_tx_ring { bus_dma_tag_t hn_tx_data_dtag; uint64_t hn_csum_assist; + int (*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *); int hn_suspended; int hn_gpa_cnt; struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE]; @@ -276,13 +277,5 @@ struct hn_softc { #define HN_LINK_FLAG_LINKUP 0x0001 #define HN_LINK_FLAG_NETCHG 0x0002 -/* - * Externs - */ -struct hn_send_ctx; - -int hv_nv_on_send(struct vmbus_channel *chan, uint32_t rndis_mtype, - struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt); - #endif /* __HV_NET_VSC_H__ */ diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 336fee8b3b4e..b29f3270ccc1 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -169,6 +169,8 @@ struct hn_txdesc { int refs; uint32_t flags; /* HN_TXD_FLAG_ */ struct hn_send_ctx send_ctx; + uint32_t chim_index; + int chim_size; bus_dmamap_t data_dmap; @@ -363,6 +365,8 @@ static void hn_tx_resume(struct hn_softc *, int); static void hn_tx_ring_qflush(struct hn_tx_ring *); static int netvsc_detach(device_t dev); static void hn_link_status(struct hn_softc *); +static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *, struct hn_txdesc *); +static int hn_sendpkt_rndis_chim(struct hn_tx_ring *, struct hn_txdesc *); static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt); @@ -399,6 +403,57 @@ hn_set_lro_lenlim(struct hn_softc *sc, int lenlim) } #endif +static __inline int +hn_nvs_send_rndis_sglist1(struct vmbus_channel *chan, uint32_t rndis_mtype, + struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) +{ + struct hn_nvs_rndis rndis; + + rndis.nvs_type = HN_NVS_TYPE_RNDIS; + rndis.nvs_rndis_mtype = rndis_mtype; + rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID; + rndis.nvs_chim_sz = 0; + + return (hn_nvs_send_sglist(chan, gpa, gpa_cnt, + &rndis, sizeof(rndis), sndc)); +} + +int +hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, + struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) +{ + + return hn_nvs_send_rndis_sglist1(chan, HN_NVS_RNDIS_MTYPE_CTRL, + sndc, gpa, gpa_cnt); +} + +static int +hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd) +{ + + KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID && + txd->chim_size == 0, ("invalid rndis sglist txd")); + return (hn_nvs_send_rndis_sglist1(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA, + &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt)); +} + +static int +hn_sendpkt_rndis_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd) +{ + struct hn_nvs_rndis rndis; + + KASSERT(txd->chim_index != HN_NVS_CHIM_IDX_INVALID && + txd->chim_size > 0, ("invalid rndis chim txd")); + + rndis.nvs_type = HN_NVS_TYPE_RNDIS; + rndis.nvs_rndis_mtype = HN_NVS_RNDIS_MTYPE_DATA; + rndis.nvs_chim_idx = txd->chim_index; + rndis.nvs_chim_sz = txd->chim_size; + + return (hn_nvs_send(txr->hn_chan, VMBUS_CHANPKT_FLAG_RC, + &rndis, sizeof(rndis), &txd->send_ctx)); +} + static int hn_get_txswq_depth(const struct hn_tx_ring *txr) { @@ -1038,8 +1093,8 @@ hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc, struct hn_txdesc *txd = sndc->hn_cbarg; struct hn_tx_ring *txr; - if (sndc->hn_chim_idx != HN_NVS_CHIM_IDX_INVALID) - hn_chim_free(sc, sndc->hn_chim_idx); + if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) + hn_chim_free(sc, txd->chim_index); txr = txd->txr; KASSERT(txr->hn_chan == chan, @@ -1096,9 +1151,8 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) int error, nsegs, i; struct mbuf *m_head = *m_head0; struct rndis_packet_msg *pkt; - uint32_t send_buf_section_idx; - int send_buf_section_size, pktlen; uint32_t *pi_data; + int pktlen; /* * extension points to the area reserved for the @@ -1211,18 +1265,19 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) */ if (pkt->rm_len < txr->hn_chim_size) { txr->hn_tx_chimney_tried++; - send_buf_section_idx = hn_chim_alloc(txr->hn_sc); - if (send_buf_section_idx != HN_NVS_CHIM_IDX_INVALID) { + txd->chim_index = hn_chim_alloc(txr->hn_sc); + if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) { uint8_t *dest = txr->hn_sc->hn_chim + - (send_buf_section_idx * txr->hn_sc->hn_chim_szmax); + (txd->chim_index * txr->hn_sc->hn_chim_szmax); memcpy(dest, pkt, pktlen); dest += pktlen; m_copydata(m_head, 0, m_head->m_pkthdr.len, dest); - send_buf_section_size = pkt->rm_len; + txd->chim_size = pkt->rm_len; txr->hn_gpa_cnt = 0; txr->hn_tx_chimney++; + txr->hn_sendpkt = hn_sendpkt_rndis_chim; goto done; } } @@ -1267,14 +1322,14 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) gpa->gpa_len = segs[i].ds_len; } - send_buf_section_idx = HN_NVS_CHIM_IDX_INVALID; - send_buf_section_size = 0; + txd->chim_index = HN_NVS_CHIM_IDX_INVALID; + txd->chim_size = 0; + txr->hn_sendpkt = hn_sendpkt_rndis_sglist; done: txd->m = m_head; /* Set the completion routine */ - hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd, - send_buf_section_idx, send_buf_section_size); + hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd); return 0; } @@ -1294,8 +1349,7 @@ hn_send_pkt(struct ifnet *ifp, struct hn_tx_ring *txr, struct hn_txdesc *txd) * Make sure that txd is not freed before ETHER_BPF_MTAP. */ hn_txdesc_hold(txd); - error = hv_nv_on_send(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA, - &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt); + error = txr->hn_sendpkt(txr, txd); if (!error) { ETHER_BPF_MTAP(ifp, txd->m); if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index 16f292a22bba..623aad00ed31 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -585,8 +585,7 @@ hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen, * message. */ vmbus_xact_activate(xact); - error = hv_nv_on_send(sc->hn_prichan, HN_NVS_RNDIS_MTYPE_CTRL, sndc, - gpa, gpa_cnt); + error = hn_nvs_send_rndis_ctrl(sc->hn_prichan, sndc, gpa, gpa_cnt); if (error) { vmbus_xact_deactivate(xact); if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error); @@ -1165,7 +1164,7 @@ hn_rndis_halt(struct hn_softc *sc) halt->rm_rid = hn_rndis_rid(sc); /* No RNDIS completion; rely on NVS message send completion */ - hn_send_ctx_init_simple(&sndc, hn_nvs_sent_xact, xact); + hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact); hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len); vmbus_xact_put(xact); diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index d25d5f2b7d53..9e73a2d5782d 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -46,8 +46,6 @@ typedef void (*hn_sent_callback_t) struct hn_send_ctx { hn_sent_callback_t hn_cb; void *hn_cbarg; - uint32_t hn_chim_idx; - int hn_chim_sz; }; struct rndis_hash_info; @@ -66,31 +64,18 @@ struct hn_recvinfo { uint32_t hash_value; }; -#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ -{ \ - .hn_cb = cb, \ - .hn_cbarg = cbarg, \ - .hn_chim_idx = HN_NVS_CHIM_IDX_INVALID, \ - .hn_chim_sz = 0 \ +#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ +{ \ + .hn_cb = cb, \ + .hn_cbarg = cbarg \ } static __inline void -hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, - void *cbarg, uint32_t chim_idx, int chim_sz) +hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, void *cbarg) { sndc->hn_cb = cb; sndc->hn_cbarg = cbarg; - sndc->hn_chim_idx = chim_idx; - sndc->hn_chim_sz = chim_sz; -} - -static __inline void -hn_send_ctx_init_simple(struct hn_send_ctx *sndc, hn_sent_callback_t cb, - void *cbarg) -{ - - hn_send_ctx_init(sndc, cb, cbarg, HN_NVS_CHIM_IDX_INVALID, 0); } static __inline int @@ -134,6 +119,9 @@ void hn_nvs_detach(struct hn_softc *sc); int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch); void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, struct vmbus_channel *chan, const void *data, int dlen); +int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, + struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, + int gpa_cnt); int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_recvinfo *info); From 6aa8c9a4e098dba396474638c98333ab404ad9e4 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 03:34:19 +0000 Subject: [PATCH 050/235] hyperv/hn: Fix chimney sending buffer leakage upon NVS sending failure. This will not happen in real world, since TX consumption of the vmbus TX bufring is limitted. Better safe than sorry. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8309 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index b29f3270ccc1..acb7eb1528e2 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -951,6 +951,8 @@ hn_txdesc_dmamap_load(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf *m = *m_head; int error; + KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID, ("txd uses chim")); + error = bus_dmamap_load_mbuf_sg(txr->hn_tx_data_dtag, txd->data_dmap, m, segs, nsegs, BUS_DMA_NOWAIT); if (error == EFBIG) { @@ -974,19 +976,6 @@ hn_txdesc_dmamap_load(struct hn_tx_ring *txr, struct hn_txdesc *txd, return error; } -static __inline void -hn_txdesc_dmamap_unload(struct hn_tx_ring *txr, struct hn_txdesc *txd) -{ - - if (txd->flags & HN_TXD_FLAG_DMAMAP) { - bus_dmamap_sync(txr->hn_tx_data_dtag, - txd->data_dmap, BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(txr->hn_tx_data_dtag, - txd->data_dmap); - txd->flags &= ~HN_TXD_FLAG_DMAMAP; - } -} - static __inline int hn_txdesc_put(struct hn_tx_ring *txr, struct hn_txdesc *txd) { @@ -998,14 +987,25 @@ hn_txdesc_put(struct hn_tx_ring *txr, struct hn_txdesc *txd) if (atomic_fetchadd_int(&txd->refs, -1) != 1) return 0; - hn_txdesc_dmamap_unload(txr, txd); + if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) { + KASSERT((txd->flags & HN_TXD_FLAG_DMAMAP) == 0, + ("chim txd uses dmamap")); + hn_chim_free(txr->hn_sc, txd->chim_index); + txd->chim_index = HN_NVS_CHIM_IDX_INVALID; + } else if (txd->flags & HN_TXD_FLAG_DMAMAP) { + bus_dmamap_sync(txr->hn_tx_data_dtag, + txd->data_dmap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(txr->hn_tx_data_dtag, + txd->data_dmap); + txd->flags &= ~HN_TXD_FLAG_DMAMAP; + } + if (txd->m != NULL) { m_freem(txd->m); txd->m = NULL; } txd->flags |= HN_TXD_FLAG_ONLIST; - #ifndef HN_USE_TXDESC_BUFRING mtx_lock_spin(&txr->hn_txlist_spin); KASSERT(txr->hn_txdesc_avail >= 0 && @@ -1046,7 +1046,9 @@ hn_txdesc_get(struct hn_tx_ring *txr) atomic_subtract_int(&txr->hn_txdesc_avail, 1); #endif KASSERT(txd->m == NULL && txd->refs == 0 && - (txd->flags & HN_TXD_FLAG_ONLIST), ("invalid txd")); + txd->chim_index == HN_NVS_CHIM_IDX_INVALID && + (txd->flags & HN_TXD_FLAG_ONLIST) && + (txd->flags & HN_TXD_FLAG_DMAMAP) == 0, ("invalid txd")); txd->flags &= ~HN_TXD_FLAG_ONLIST; txd->refs = 1; } @@ -1093,9 +1095,6 @@ hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc, struct hn_txdesc *txd = sndc->hn_cbarg; struct hn_tx_ring *txr; - if (txd->chim_index != HN_NVS_CHIM_IDX_INVALID) - hn_chim_free(sc, txd->chim_index); - txr = txd->txr; KASSERT(txr->hn_chan == chan, ("channel mismatch, on chan%u, should be chan%u", @@ -2820,6 +2819,7 @@ hn_create_tx_ring(struct hn_softc *sc, int id) struct hn_txdesc *txd = &txr->hn_txdesc[i]; txd->txr = txr; + txd->chim_index = HN_NVS_CHIM_IDX_INVALID; /* * Allocate and load RNDIS packet message. From 6827d9497ac05a0eeb3c0dc6146cd73b9a789926 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 03:42:34 +0000 Subject: [PATCH 051/235] hyperv/hn: Properly handle synthetic parts reattach failure. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8310 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index acb7eb1528e2..b475c23beb16 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -1783,19 +1783,6 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; } - /* Obtain and record requested MTU */ - ifp->if_mtu = ifr->ifr_mtu; - -#if __FreeBSD_version >= 1100099 - /* - * Make sure that LRO aggregation length limit is still - * valid, after the MTU change. - */ - if (sc->hn_rx_ring[0].hn_lro.lro_length_lim < - HN_LRO_LENLIM_MIN(ifp)) - hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp)); -#endif - /* * Suspend this interface before the synthetic parts * are ripped. @@ -1810,13 +1797,31 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* * Reattach the synthetic parts, i.e. NVS and RNDIS, * with the new MTU setting. - * XXX check error. */ - hn_synth_attach(sc, ifr->ifr_mtu); + error = hn_synth_attach(sc, ifr->ifr_mtu); + if (error) { + HN_UNLOCK(sc); + break; + } + /* + * Commit the requested MTU, after the synthetic parts + * have been successfully attached. + */ + ifp->if_mtu = ifr->ifr_mtu; + + /* + * Make sure that various parameters based on MTU are + * still valid, after the MTU change. + */ if (sc->hn_tx_ring[0].hn_chim_size > sc->hn_chim_szmax) hn_set_chim_size(sc, sc->hn_chim_szmax); - hn_set_tso_maxsize(sc, hn_tso_maxlen, ifr->ifr_mtu); + hn_set_tso_maxsize(sc, hn_tso_maxlen, ifp->if_mtu); +#if __FreeBSD_version >= 1100099 + if (sc->hn_rx_ring[0].hn_lro.lro_length_lim < + HN_LRO_LENLIM_MIN(ifp)) + hn_set_lro_lenlim(sc, HN_LRO_LENLIM_MIN(ifp)); +#endif /* * All done! Resume the interface now. From e7c4ddf5ba06c7055798efaebf42aa12b77af2ae Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Mon, 24 Oct 2016 04:21:06 +0000 Subject: [PATCH 052/235] Add a bunch of new default options to MPC85XX* configs These were tested at various points but never merged into the configs at the time. --- sys/powerpc/conf/MPC85XX | 7 +++++++ sys/powerpc/conf/MPC85XXSPE | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX index 0e60ceb24e55..b26340fe5397 100644 --- a/sys/powerpc/conf/MPC85XX +++ b/sys/powerpc/conf/MPC85XX @@ -58,6 +58,10 @@ options SYSVSEM options SYSVSHM options WITNESS options WITNESS_SKIPSPIN +options COMPAT_FREEBSD10 +options HWPMC_HOOKS +options KDTRACE_HOOKS # Kernel DTrace hooks +options DDB_CTF # Kernel ELF linker loads CTF data device ata device bpf @@ -86,6 +90,7 @@ device scbus device scc device sec device tsec +device dpaa device tun device uart options USB_DEBUG # enable debug msgs @@ -98,3 +103,5 @@ device vlan # P1022 DIU device diu device videomode +device vt +device fbd diff --git a/sys/powerpc/conf/MPC85XXSPE b/sys/powerpc/conf/MPC85XXSPE index 781d6899d316..15470d578bef 100644 --- a/sys/powerpc/conf/MPC85XXSPE +++ b/sys/powerpc/conf/MPC85XXSPE @@ -58,6 +58,10 @@ options SYSVSEM options SYSVSHM options WITNESS options WITNESS_SKIPSPIN +options COMPAT_FREEBSD10 +options HWPMC_HOOKS +options KDTRACE_HOOKS # Kernel DTrace hooks +options DDB_CTF # Kernel ELF linker loads CTF data device ata device bpf @@ -86,6 +90,7 @@ device scbus device scc device sec device tsec +device dpaa device tun device uart options USB_DEBUG # enable debug msgs @@ -98,3 +103,5 @@ device vlan # P1022 DIU device diu device videomode +device vt +device fbd From 665bc5ff49c8842c4b1a9915ad1fab9b78a63c55 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 05:01:34 +0000 Subject: [PATCH 053/235] hyperv/hn: Start link status check, if no network changes were pending. Link status check is much more lightweight than network change detection. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8311 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index b475c23beb16..c4315166bdaa 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -3908,12 +3908,18 @@ static void hn_resume_mgmt(struct hn_softc *sc) { - /* - * Kick off network change detection, which will - * do link status check too. - */ sc->hn_mgmt_taskq = sc->hn_mgmt_taskq0; - hn_network_change(sc); + + /* + * Kick off network change detection, if it was pending. + * If no network change was pending, start link status + * checks, which is more lightweight than network change + * detection. + */ + if (sc->hn_link_flags & HN_LINK_FLAG_NETCHG) + hn_network_change(sc); + else + hn_link_status_update(sc); } static void From 121e98e697eadf913c6df600960a3308ebb36193 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 05:10:35 +0000 Subject: [PATCH 054/235] hyperv/hn: Fix RX filter settings. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8313 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 1 + sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 114 +++++++++++++----- sys/net/rndis.h | 10 +- 3 files changed, 94 insertions(+), 31 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 2e3e2aacc1e3..014f823d8846 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -232,6 +232,7 @@ struct hn_softc { struct sysctl_oid *hn_rx_sysctl_tree; struct vmbus_xact_ctx *hn_xact; uint32_t hn_nvs_ver; + uint32_t hn_rx_filter; struct taskqueue *hn_mgmt_taskq; struct taskqueue *hn_mgmt_taskq0; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index c4315166bdaa..5bd46e8e8273 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -326,6 +326,7 @@ static int hn_tx_conf_int_sysctl(SYSCTL_HANDLER_ARGS); static int hn_ndis_version_sysctl(SYSCTL_HANDLER_ARGS); static int hn_caps_sysctl(SYSCTL_HANDLER_ARGS); static int hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); @@ -367,6 +368,7 @@ static int netvsc_detach(device_t dev); static void hn_link_status(struct hn_softc *); static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *, struct hn_txdesc *); static int hn_sendpkt_rndis_chim(struct hn_tx_ring *, struct hn_txdesc *); +static int hn_set_rxfilter(struct hn_softc *); static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt); @@ -454,6 +456,43 @@ hn_sendpkt_rndis_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd) &rndis, sizeof(rndis), &txd->send_ctx)); } +static int +hn_set_rxfilter(struct hn_softc *sc) +{ + struct ifnet *ifp = sc->hn_ifp; + uint32_t filter; + int error = 0; + + HN_LOCK_ASSERT(sc); + + if (ifp->if_flags & IFF_PROMISC) { + filter = NDIS_PACKET_TYPE_PROMISCUOUS; + } else { + filter = NDIS_PACKET_TYPE_DIRECTED; + if (ifp->if_flags & IFF_BROADCAST) + filter |= NDIS_PACKET_TYPE_BROADCAST; +#ifdef notyet + /* + * See the comment in SIOCADDMULTI/SIOCDELMULTI. + */ + /* TODO: support multicast list */ + if ((ifp->if_flags & IFF_ALLMULTI) || + !TAILQ_EMPTY(&ifp->if_multiaddrs)) + filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; +#else + /* Always enable ALLMULTI */ + filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; +#endif + } + + if (sc->hn_rx_filter != filter) { + error = hn_rndis_set_rxfilter(sc, filter); + if (!error) + sc->hn_rx_filter = filter; + } + return (error); +} + static int hn_get_txswq_depth(const struct hn_tx_ring *txr) { @@ -728,6 +767,9 @@ netvsc_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "hwassist", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_hwassist_sysctl, "A", "hwassist"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxfilter", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_rxfilter_sysctl, "A", "rxfilter"); SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key", CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, hn_rss_key_sysctl, "IU", "RSS key"); @@ -1840,31 +1882,13 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) } if (ifp->if_flags & IFF_UP) { - /* - * If only the state of the PROMISC flag changed, - * then just use the 'set promisc mode' command - * instead of reinitializing the entire NIC. Doing - * a full re-init means reloading the firmware and - * waiting for it to start up, which may take a - * second or two. - */ -#ifdef notyet - /* Fixme: Promiscuous mode? */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->hn_if_flags & IFF_PROMISC)) { - /* do something here for Hyper-V */ - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->hn_if_flags & IFF_PROMISC) { - /* do something here for Hyper-V */ - } else -#endif + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_set_rxfilter(sc); + else hn_init_locked(sc); } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) hn_stop(sc); - } } sc->hn_if_flags = ifp->if_flags; @@ -1922,12 +1946,27 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCADDMULTI: case SIOCDELMULTI: - /* Always all-multi */ +#ifdef notyet /* - * TODO: - * Enable/disable all-multi according to the emptiness of - * the mcast address list. + * XXX + * Multicast uses mutex, while RNDIS RX filter setting + * sleeps. We workaround this by always enabling + * ALLMULTI. ALLMULTI would actually always be on, even + * if we supported the SIOCADDMULTI/SIOCDELMULTI, since + * we don't support multicast address list configuration + * for this driver. */ + HN_LOCK(sc); + + if ((sc->hn_flags & HN_FLAG_SYNTH_ATTACHED) == 0) { + HN_UNLOCK(sc); + break; + } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + hn_set_rxfilter(sc); + + HN_UNLOCK(sc); +#endif break; case SIOCSIFMEDIA: @@ -2035,8 +2074,8 @@ hn_init_locked(struct hn_softc *sc) if (ifp->if_drv_flags & IFF_DRV_RUNNING) return; - /* TODO: add hn_rx_filter */ - hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS); + /* Configure RX filter */ + hn_set_rxfilter(sc); /* Clear OACTIVE bit. */ atomic_clear_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); @@ -2362,6 +2401,21 @@ hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS) return sysctl_handle_string(oidp, assist_str, sizeof(assist_str), req); } +static int +hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char filter_str[128]; + uint32_t filter; + + HN_LOCK(sc); + filter = sc->hn_rx_filter; + HN_UNLOCK(sc); + snprintf(filter_str, sizeof(filter_str), "%b", filter, + NDIS_PACKET_TYPES); + return sysctl_handle_string(oidp, filter_str, sizeof(filter_str), req); +} + static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS) { @@ -3783,6 +3837,7 @@ hn_suspend_data(struct hn_softc *sc) * Disable RX by clearing RX filter. */ hn_rndis_set_rxfilter(sc, 0); + sc->hn_rx_filter = 0; /* * Give RNDIS enough time to flush all pending data packets. @@ -3870,9 +3925,8 @@ hn_resume_data(struct hn_softc *sc) /* * Re-enable RX. - * TODO: add hn_rx_filter. */ - hn_rndis_set_rxfilter(sc, NDIS_PACKET_TYPE_PROMISCUOUS); + hn_set_rxfilter(sc); /* * Make sure to clear suspend status on "all" TX rings, diff --git a/sys/net/rndis.h b/sys/net/rndis.h index 95edb1c5d7e4..12385e35ca24 100644 --- a/sys/net/rndis.h +++ b/sys/net/rndis.h @@ -351,7 +351,7 @@ struct rndis_keepalive_comp { uint32_t rm_status; }; -/* packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ +/* Packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ #define NDIS_PACKET_TYPE_DIRECTED 0x00000001 #define NDIS_PACKET_TYPE_MULTICAST 0x00000002 #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 @@ -365,6 +365,14 @@ struct rndis_keepalive_comp { #define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 #define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000 +/* + * Packet filter description for use with printf(9) %b identifier. + */ +#define NDIS_PACKET_TYPES \ + "\20\1DIRECT\2MULTICAST\3ALLMULTI\4BROADCAST" \ + "\5SRCROUTE\6PROMISC\7SMT\10ALLLOCAL" \ + "\11GROUP\12ALLFUNC\13FUNC\14MACFRAME" + /* RNDIS offsets */ #define RNDIS_HEADER_OFFSET ((uint32_t)sizeof(struct rndis_msghdr)) #define RNDIS_DATA_OFFSET \ From f0dcc3114c74a8f6e6dabce3297d924223e0dc9b Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 05:20:02 +0000 Subject: [PATCH 055/235] hyperv/hn: Nuke unused forward declaration. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8314 --- sys/dev/hyperv/netvsc/if_hnvar.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 9e73a2d5782d..0b37cf3c819b 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -48,11 +48,6 @@ struct hn_send_ctx { void *hn_cbarg; }; -struct rndis_hash_info; -struct rndix_hash_value; -struct ndis_8021q_info_; -struct rndis_tcp_ip_csum_info_; - #define HN_NDIS_VLAN_INFO_INVALID 0xffffffff #define HN_NDIS_RXCSUM_INFO_INVALID 0 #define HN_NDIS_HASH_INFO_INVALID 0 From 5bf51473c0e065c9f7bc2a53efdd70cd7a6f2b91 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 24 Oct 2016 05:36:19 +0000 Subject: [PATCH 056/235] hyperv/ic: Rework framework/message version negotiation. Submitted by: Hongjiang Zhang Modified by: sephe MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8280 --- sys/dev/hyperv/utilities/hv_heartbeat.c | 11 +- sys/dev/hyperv/utilities/hv_kvp.c | 70 +++------- sys/dev/hyperv/utilities/hv_kvp.h | 7 +- sys/dev/hyperv/utilities/hv_shutdown.c | 11 +- sys/dev/hyperv/utilities/hv_timesync.c | 11 +- sys/dev/hyperv/utilities/hv_util.c | 162 +++++++++++++++++++++--- sys/dev/hyperv/utilities/hv_util.h | 5 +- sys/dev/hyperv/utilities/hv_utilreg.h | 12 -- sys/dev/hyperv/utilities/vmbus_icreg.h | 6 + 9 files changed, 207 insertions(+), 88 deletions(-) diff --git a/sys/dev/hyperv/utilities/hv_heartbeat.c b/sys/dev/hyperv/utilities/hv_heartbeat.c index 37867148b538..8fc7a0944eaf 100644 --- a/sys/dev/hyperv/utilities/hv_heartbeat.c +++ b/sys/dev/hyperv/utilities/hv_heartbeat.c @@ -40,6 +40,14 @@ __FBSDID("$FreeBSD$"); #include "vmbus_if.h" +#define VMBUS_HEARTBEAT_FWVER_MAJOR 3 +#define VMBUS_HEARTBEAT_FWVER \ + VMBUS_IC_VERSION(VMBUS_HEARTBEAT_FWVER_MAJOR, 0) + +#define VMBUS_HEARTBEAT_MSGVER_MAJOR 3 +#define VMBUS_HEARTBEAT_MSGVER \ + VMBUS_IC_VERSION(VMBUS_HEARTBEAT_MSGVER_MAJOR, 0) + static const struct vmbus_ic_desc vmbus_heartbeat_descs[] = { { .ic_guid = { .hv_guid = { @@ -80,7 +88,8 @@ vmbus_heartbeat_cb(struct vmbus_channel *chan, void *xsc) */ switch (hdr->ic_type) { case VMBUS_ICMSG_TYPE_NEGOTIATE: - error = vmbus_ic_negomsg(sc, data, &dlen); + error = vmbus_ic_negomsg(sc, data, &dlen, + VMBUS_HEARTBEAT_FWVER, VMBUS_HEARTBEAT_MSGVER); if (error) return; break; diff --git a/sys/dev/hyperv/utilities/hv_kvp.c b/sys/dev/hyperv/utilities/hv_kvp.c index 9d1abb4c42b9..593b4226bc52 100644 --- a/sys/dev/hyperv/utilities/hv_kvp.c +++ b/sys/dev/hyperv/utilities/hv_kvp.c @@ -61,7 +61,9 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include #include "hv_util.h" #include "unicode.h" @@ -74,6 +76,12 @@ __FBSDID("$FreeBSD$"); #define KVP_ERROR 1 #define kvp_hdr hdr.kvp_hdr +#define KVP_FWVER_MAJOR 3 +#define KVP_FWVER VMBUS_IC_VERSION(KVP_FWVER_MAJOR, 0) + +#define KVP_MSGVER_MAJOR 4 +#define KVP_MSGVER VMBUS_IC_VERSION(KVP_MSGVER_MAJOR, 0) + /* hv_kvp debug control */ static int hv_kvp_log = 0; @@ -208,52 +216,10 @@ hv_kvp_transaction_init(hv_kvp_sc *sc, uint32_t rcv_len, sc->host_msg_id = request_id; sc->rcv_buf = rcv_buf; sc->host_kvp_msg = (struct hv_kvp_msg *)&rcv_buf[ - sizeof(struct hv_vmbus_pipe_hdr) + - sizeof(struct hv_vmbus_icmsg_hdr)]; + sizeof(struct hv_vmbus_pipe_hdr) + + sizeof(struct hv_vmbus_icmsg_hdr)]; } - -/* - * hv_kvp - version neogtiation function - */ -static void -hv_kvp_negotiate_version(struct hv_vmbus_icmsg_hdr *icmsghdrp, uint8_t *buf) -{ - struct hv_vmbus_icmsg_negotiate *negop; - int icframe_vercnt; - int icmsg_vercnt; - - icmsghdrp->icmsgsize = 0x10; - - negop = (struct hv_vmbus_icmsg_negotiate *)&buf[ - sizeof(struct hv_vmbus_pipe_hdr) + - sizeof(struct hv_vmbus_icmsg_hdr)]; - icframe_vercnt = negop->icframe_vercnt; - icmsg_vercnt = negop->icmsg_vercnt; - - /* - * Select the framework version number we will support - */ - if ((icframe_vercnt >= 2) && (negop->icversion_data[1].major == 3)) { - icframe_vercnt = 3; - if (icmsg_vercnt > 2) - icmsg_vercnt = 4; - else - icmsg_vercnt = 3; - } else { - icframe_vercnt = 1; - icmsg_vercnt = 1; - } - - negop->icframe_vercnt = 1; - negop->icmsg_vercnt = 1; - negop->icversion_data[0].major = icframe_vercnt; - negop->icversion_data[0].minor = 0; - negop->icversion_data[1].major = icmsg_vercnt; - negop->icversion_data[1].minor = 0; -} - - /* * Convert ip related info in umsg from utf8 to utf16 and store in hmsg */ @@ -578,7 +544,8 @@ hv_kvp_respond_host(hv_kvp_sc *sc, int error) error = HV_KVP_E_FAIL; hv_icmsg_hdrp->status = error; - hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | HV_ICMSGHDRFLAG_RESPONSE; + hv_icmsg_hdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION | + HV_ICMSGHDRFLAG_RESPONSE; error = vmbus_chan_send(vmbus_get_channel(sc->dev), VMBUS_CHANPKT_TYPE_INBAND, 0, sc->rcv_buf, sc->host_msg_len, @@ -622,8 +589,8 @@ hv_kvp_process_request(void *context, int pending) uint32_t recvlen = 0; uint64_t requestid; struct hv_vmbus_icmsg_hdr *icmsghdrp; - int ret = 0; - hv_kvp_sc *sc; + int ret = 0, error; + hv_kvp_sc *sc; hv_kvp_log_info("%s: entering hv_kvp_process_request\n", __func__); @@ -637,14 +604,15 @@ hv_kvp_process_request(void *context, int pending) /* XXX check recvlen to make sure that it contains enough data */ while ((ret == 0) && (recvlen > 0)) { - icmsghdrp = (struct hv_vmbus_icmsg_hdr *) - &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)]; + &kvp_buf[sizeof(struct hv_vmbus_pipe_hdr)]; hv_kvp_transaction_init(sc, recvlen, requestid, kvp_buf); if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) { - hv_kvp_negotiate_version(icmsghdrp, kvp_buf); - hv_kvp_respond_host(sc, ret); + error = vmbus_ic_negomsg(&sc->util_sc, + kvp_buf, &recvlen, KVP_FWVER, KVP_MSGVER); + /* XXX handle vmbus_ic_negomsg failure. */ + hv_kvp_respond_host(sc, error); /* * It is ok to not acquire the mutex before setting diff --git a/sys/dev/hyperv/utilities/hv_kvp.h b/sys/dev/hyperv/utilities/hv_kvp.h index 6474e1825677..c391da0d5a5d 100644 --- a/sys/dev/hyperv/utilities/hv_kvp.h +++ b/sys/dev/hyperv/utilities/hv_kvp.h @@ -28,7 +28,6 @@ #ifndef _KVP_H #define _KVP_H - /* * An implementation of HyperV key value pair (KVP) functionality for FreeBSD * @@ -178,9 +177,9 @@ struct hv_kvp_ipaddr_value { }__attribute__((packed)); struct hv_kvp_hdr { - uint8_t operation; - uint8_t pool; - uint16_t pad; + uint8_t operation; + uint8_t pool; + uint16_t pad; } __attribute__((packed)); struct hv_kvp_exchg_msg_value { diff --git a/sys/dev/hyperv/utilities/hv_shutdown.c b/sys/dev/hyperv/utilities/hv_shutdown.c index 458009381b27..e511b21a070c 100644 --- a/sys/dev/hyperv/utilities/hv_shutdown.c +++ b/sys/dev/hyperv/utilities/hv_shutdown.c @@ -41,6 +41,14 @@ __FBSDID("$FreeBSD$"); #include "vmbus_if.h" +#define VMBUS_SHUTDOWN_FWVER_MAJOR 3 +#define VMBUS_SHUTDOWN_FWVER \ + VMBUS_IC_VERSION(VMBUS_SHUTDOWN_FWVER_MAJOR, 0) + +#define VMBUS_SHUTDOWN_MSGVER_MAJOR 3 +#define VMBUS_SHUTDOWN_MSGVER \ + VMBUS_IC_VERSION(VMBUS_SHUTDOWN_MSGVER_MAJOR, 0) + static const struct vmbus_ic_desc vmbus_shutdown_descs[] = { { .ic_guid = { .hv_guid = { @@ -82,7 +90,8 @@ vmbus_shutdown_cb(struct vmbus_channel *chan, void *xsc) */ switch (hdr->ic_type) { case VMBUS_ICMSG_TYPE_NEGOTIATE: - error = vmbus_ic_negomsg(sc, data, &dlen); + error = vmbus_ic_negomsg(sc, data, &dlen, + VMBUS_SHUTDOWN_FWVER, VMBUS_SHUTDOWN_MSGVER); if (error) return; break; diff --git a/sys/dev/hyperv/utilities/hv_timesync.c b/sys/dev/hyperv/utilities/hv_timesync.c index 2d440263ec0c..5bd51b08a91f 100644 --- a/sys/dev/hyperv/utilities/hv_timesync.c +++ b/sys/dev/hyperv/utilities/hv_timesync.c @@ -42,6 +42,14 @@ __FBSDID("$FreeBSD$"); #include "vmbus_if.h" +#define VMBUS_TIMESYNC_FWVER_MAJOR 3 +#define VMBUS_TIMESYNC_FWVER \ + VMBUS_IC_VERSION(VMBUS_TIMESYNC_FWVER_MAJOR, 0) + +#define VMBUS_TIMESYNC_MSGVER_MAJOR 3 +#define VMBUS_TIMESYNC_MSGVER \ + VMBUS_IC_VERSION(VMBUS_TIMESYNC_MSGVER_MAJOR, 0) + static const struct vmbus_ic_desc vmbus_timesync_descs[] = { { .ic_guid = { .hv_guid = { @@ -162,7 +170,8 @@ vmbus_timesync_cb(struct vmbus_channel *chan, void *xsc) */ switch (hdr->ic_type) { case VMBUS_ICMSG_TYPE_NEGOTIATE: - error = vmbus_ic_negomsg(sc, data, &dlen); + error = vmbus_ic_negomsg(sc, data, &dlen, + VMBUS_TIMESYNC_FWVER, VMBUS_TIMESYNC_MSGVER); if (error) return; break; diff --git a/sys/dev/hyperv/utilities/hv_util.c b/sys/dev/hyperv/utilities/hv_util.c index 3fc16c951d4a..20b8f84da94f 100644 --- a/sys/dev/hyperv/utilities/hv_util.c +++ b/sys/dev/hyperv/utilities/hv_util.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -53,52 +54,145 @@ __offsetof(struct vmbus_icmsg_negotiate, ic_ver[VMBUS_IC_VERCNT]) CTASSERT(VMBUS_IC_NEGOSZ < VMBUS_IC_BRSIZE); +static int vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS); +static int vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS); + int -vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0) +vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen0, + uint32_t fw_ver, uint32_t msg_ver) { struct vmbus_icmsg_negotiate *nego; - int cnt, major, dlen = *dlen0; + int i, cnt, dlen = *dlen0, error; + uint32_t sel_fw_ver, sel_msg_ver; + bool has_fw_ver, has_msg_ver; /* - * Preliminary message size verification + * Preliminary message verification. */ if (dlen < sizeof(*nego)) { device_printf(sc->ic_dev, "truncated ic negotiate, len %d\n", dlen); - return EINVAL; + return (EINVAL); } nego = data; + if (nego->ic_fwver_cnt == 0) { + device_printf(sc->ic_dev, "ic negotiate does not contain " + "framework version %u\n", nego->ic_fwver_cnt); + return (EINVAL); + } + if (nego->ic_msgver_cnt == 0) { + device_printf(sc->ic_dev, "ic negotiate does not contain " + "message version %u\n", nego->ic_msgver_cnt); + return (EINVAL); + } + cnt = nego->ic_fwver_cnt + nego->ic_msgver_cnt; if (dlen < __offsetof(struct vmbus_icmsg_negotiate, ic_ver[cnt])) { device_printf(sc->ic_dev, "ic negotiate does not contain " "versions %d\n", dlen); - return EINVAL; + return (EINVAL); } - /* Select major version; XXX looks wrong. */ - if (nego->ic_fwver_cnt >= 2 && VMBUS_ICVER_MAJOR(nego->ic_ver[1]) == 3) - major = 3; - else - major = 1; + error = EOPNOTSUPP; - /* One framework version */ + /* + * Find the best match framework version. + */ + has_fw_ver = false; + for (i = 0; i < nego->ic_fwver_cnt; ++i) { + if (VMBUS_ICVER_LE(nego->ic_ver[i], fw_ver)) { + if (!has_fw_ver) { + sel_fw_ver = nego->ic_ver[i]; + has_fw_ver = true; + } else if (VMBUS_ICVER_GT(nego->ic_ver[i], + sel_fw_ver)) { + sel_fw_ver = nego->ic_ver[i]; + } + } + } + if (!has_fw_ver) { + device_printf(sc->ic_dev, "failed to select framework " + "version\n"); + goto done; + } + + /* + * Fine the best match message version. + */ + has_msg_ver = false; + for (i = nego->ic_fwver_cnt; + i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; ++i) { + if (VMBUS_ICVER_LE(nego->ic_ver[i], msg_ver)) { + if (!has_msg_ver) { + sel_msg_ver = nego->ic_ver[i]; + has_msg_ver = true; + } else if (VMBUS_ICVER_GT(nego->ic_ver[i], + sel_msg_ver)) { + sel_msg_ver = nego->ic_ver[i]; + } + } + } + if (!has_msg_ver) { + device_printf(sc->ic_dev, "failed to select message " + "version\n"); + goto done; + } + + error = 0; +done: + if (bootverbose || !has_fw_ver || !has_msg_ver) { + if (has_fw_ver) { + device_printf(sc->ic_dev, "sel framework version: " + "%u.%u\n", + VMBUS_ICVER_MAJOR(sel_fw_ver), + VMBUS_ICVER_MINOR(sel_fw_ver)); + } + for (i = 0; i < nego->ic_fwver_cnt; i++) { + device_printf(sc->ic_dev, "supp framework version: " + "%u.%u\n", + VMBUS_ICVER_MAJOR(nego->ic_ver[i]), + VMBUS_ICVER_MINOR(nego->ic_ver[i])); + } + + if (has_msg_ver) { + device_printf(sc->ic_dev, "sel message version: " + "%u.%u\n", + VMBUS_ICVER_MAJOR(sel_msg_ver), + VMBUS_ICVER_MINOR(sel_msg_ver)); + } + for (i = nego->ic_fwver_cnt; + i < nego->ic_fwver_cnt + nego->ic_msgver_cnt; i++) { + device_printf(sc->ic_dev, "supp message version: " + "%u.%u\n", + VMBUS_ICVER_MAJOR(nego->ic_ver[i]), + VMBUS_ICVER_MINOR(nego->ic_ver[i])); + } + } + if (error) + return (error); + + /* Record the selected versions. */ + sc->ic_fwver = sel_fw_ver; + sc->ic_msgver = sel_msg_ver; + + /* One framework version. */ nego->ic_fwver_cnt = 1; - nego->ic_ver[0] = VMBUS_IC_VERSION(major, 0); + nego->ic_ver[0] = sel_fw_ver; - /* One message version */ + /* One message version. */ nego->ic_msgver_cnt = 1; - nego->ic_ver[1] = VMBUS_IC_VERSION(major, 0); + nego->ic_ver[1] = sel_msg_ver; - /* Update data size */ + /* Update data size. */ nego->ic_hdr.ic_dsize = VMBUS_IC_NEGOSZ - sizeof(struct vmbus_icmsg_hdr); - /* Update total size, if necessary */ + /* Update total size, if necessary. */ if (dlen < VMBUS_IC_NEGOSZ) *dlen0 = VMBUS_IC_NEGOSZ; - return 0; + return (0); } int @@ -124,6 +218,8 @@ hv_util_attach(device_t dev, vmbus_chan_callback_t cb) { struct hv_util_sc *sc = device_get_softc(dev); struct vmbus_channel *chan = vmbus_get_channel(dev); + struct sysctl_oid_list *child; + struct sysctl_ctx_list *ctx; int error; sc->ic_dev = dev; @@ -146,9 +242,41 @@ hv_util_attach(device_t dev, vmbus_chan_callback_t cb) free(sc->receive_buffer, M_DEVBUF); return (error); } + + ctx = device_get_sysctl_ctx(dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(dev)); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "fw_version", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + vmbus_ic_fwver_sysctl, "A", "framework version"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "msg_version", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + vmbus_ic_msgver_sysctl, "A", "message version"); + return (0); } +static int +vmbus_ic_fwver_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hv_util_sc *sc = arg1; + char verstr[16]; + + snprintf(verstr, sizeof(verstr), "%u.%u", + VMBUS_ICVER_MAJOR(sc->ic_fwver), VMBUS_ICVER_MINOR(sc->ic_fwver)); + return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); +} + +static int +vmbus_ic_msgver_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hv_util_sc *sc = arg1; + char verstr[16]; + + snprintf(verstr, sizeof(verstr), "%u.%u", + VMBUS_ICVER_MAJOR(sc->ic_msgver), VMBUS_ICVER_MINOR(sc->ic_msgver)); + return sysctl_handle_string(oidp, verstr, sizeof(verstr), req); +} + int hv_util_detach(device_t dev) { diff --git a/sys/dev/hyperv/utilities/hv_util.h b/sys/dev/hyperv/utilities/hv_util.h index 012cdeec3ed6..7cf8d3171826 100644 --- a/sys/dev/hyperv/utilities/hv_util.h +++ b/sys/dev/hyperv/utilities/hv_util.h @@ -42,6 +42,8 @@ typedef struct hv_util_sc { device_t ic_dev; uint8_t *receive_buffer; int ic_buflen; + uint32_t ic_fwver; /* framework version */ + uint32_t ic_msgver; /* message version */ } hv_util_sc; struct vmbus_ic_desc { @@ -54,6 +56,7 @@ struct vmbus_ic_desc { int hv_util_attach(device_t dev, vmbus_chan_callback_t cb); int hv_util_detach(device_t dev); int vmbus_ic_probe(device_t dev, const struct vmbus_ic_desc descs[]); -int vmbus_ic_negomsg(struct hv_util_sc *, void *data, int *dlen); +int vmbus_ic_negomsg(struct hv_util_sc *sc, void *data, int *dlen, + uint32_t fw_ver, uint32_t msg_ver); #endif diff --git a/sys/dev/hyperv/utilities/hv_utilreg.h b/sys/dev/hyperv/utilities/hv_utilreg.h index 124de412e95f..9358776409ee 100644 --- a/sys/dev/hyperv/utilities/hv_utilreg.h +++ b/sys/dev/hyperv/utilities/hv_utilreg.h @@ -76,16 +76,4 @@ typedef struct hv_vmbus_icmsg_negotiate { hv_vmbus_ic_version icversion_data[1]; /* any size array */ } __packed hv_vmbus_icmsg_negotiate; -typedef struct hv_vmbus_shutdown_msg_data { - uint32_t reason_code; - uint32_t timeout_seconds; - uint32_t flags; - uint8_t display_message[2048]; -} __packed hv_vmbus_shutdown_msg_data; - -typedef struct hv_vmbus_heartbeat_msg_data { - uint64_t seq_num; - uint32_t reserved[8]; -} __packed hv_vmbus_heartbeat_msg_data; - #endif /* !_HV_UTILREG_H_ */ diff --git a/sys/dev/hyperv/utilities/vmbus_icreg.h b/sys/dev/hyperv/utilities/vmbus_icreg.h index 683e2f83b591..34359622b6c2 100644 --- a/sys/dev/hyperv/utilities/vmbus_icreg.h +++ b/sys/dev/hyperv/utilities/vmbus_icreg.h @@ -42,6 +42,12 @@ #define VMBUS_IC_VERSION(major, minor) ((major) | (((uint32_t)(minor)) << 16)) #define VMBUS_ICVER_MAJOR(ver) ((ver) & 0xffff) #define VMBUS_ICVER_MINOR(ver) (((ver) & 0xffff0000) >> 16) +#define VMBUS_ICVER_SWAP(ver) \ + ((VMBUS_ICVER_MAJOR((ver)) << 16) | VMBUS_ICVER_MINOR((ver))) +#define VMBUS_ICVER_LE(v1, v2) \ + (VMBUS_ICVER_SWAP((v1)) <= VMBUS_ICVER_SWAP((v2))) +#define VMBUS_ICVER_GT(v1, v2) \ + (VMBUS_ICVER_SWAP((v1)) > VMBUS_ICVER_SWAP((v2))) struct vmbus_pipe_hdr { uint32_t ph_flags; From f0cbbdecbcb82a6f6f9d63b13af5fddb6ce005e6 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 24 Oct 2016 12:24:24 +0000 Subject: [PATCH 057/235] Fix panic after ZVOL renamed to name invalid for DEVFS. MFC after: 2 weeks --- .../opensolaris/uts/common/fs/zfs/zvol.c | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index d0c7a74c6dd7..832847e30258 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -782,8 +782,10 @@ zvol_remove_zv(zvol_state_t *zv) g_topology_lock(); zvol_geom_destroy(zv); g_topology_unlock(); - } else if (zv->zv_volmode == ZFS_VOLMODE_DEV) - destroy_dev(zv->zv_dev); + } else if (zv->zv_volmode == ZFS_VOLMODE_DEV) { + if (zv->zv_dev != NULL) + destroy_dev(zv->zv_dev); + } #endif avl_destroy(&zv->zv_znode.z_range_avl); @@ -2973,14 +2975,14 @@ zvol_rename_minor(zvol_state_t *zv, const char *newname) } else if (zv->zv_volmode == ZFS_VOLMODE_DEV) { struct make_dev_args args; - dev = zv->zv_dev; - ASSERT(dev != NULL); - zv->zv_dev = NULL; - destroy_dev(dev); - if (zv->zv_total_opens > 0) { - zv->zv_flags &= ~ZVOL_EXCL; - zv->zv_total_opens = 0; - zvol_last_close(zv); + if ((dev = zv->zv_dev) != NULL) { + zv->zv_dev = NULL; + destroy_dev(dev); + if (zv->zv_total_opens > 0) { + zv->zv_flags &= ~ZVOL_EXCL; + zv->zv_total_opens = 0; + zvol_last_close(zv); + } } make_dev_args_init(&args); From 9eb0ccbb54a2c9c924a696935993278635815c86 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 24 Oct 2016 13:44:24 +0000 Subject: [PATCH 058/235] Increase CACHE_LINE_SHIFT to 7 as cache lines are 128 bytes on ThunderX. MFC after: 1 week Sponsored by: ABT Systems Ltd --- sys/arm64/include/param.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm64/include/param.h b/sys/arm64/include/param.h index d4d49554ebdf..69e2c0817911 100644 --- a/sys/arm64/include/param.h +++ b/sys/arm64/include/param.h @@ -77,7 +77,7 @@ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an * architecture. It should be used with appropriate caution. */ -#define CACHE_LINE_SHIFT 6 +#define CACHE_LINE_SHIFT 7 #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) #define PAGE_SHIFT 12 From 930550a55e28eda815a869274e1f152d8a408d44 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Mon, 24 Oct 2016 13:51:45 +0000 Subject: [PATCH 059/235] Update vendor/libarchive to git 629358182b04d7de2316bbd29708c58ddf797fd2 Libarchive 3.2.2 --- .travis.yml | 19 +- Makefile.am | 4 +- NEWS | 3 + build/ci_build.sh | 103 ++++++++ build/version | 2 +- cat/test/CMakeLists.txt | 3 +- cat/test/main.c | 47 +++- cat/test/test.h | 9 + configure.ac | 4 +- cpio/test/CMakeLists.txt | 3 +- cpio/test/main.c | 31 +++ cpio/test/test.h | 4 + libarchive/archive.h | 4 +- libarchive/archive_entry.h | 2 +- libarchive/test/CMakeLists.txt | 2 +- libarchive/test/main.c | 31 +++ libarchive/test/test.h | 4 + .../test/test_read_format_mtree_crash747.c | 5 + .../test_read_format_zip_high_compression.c | 10 + libarchive/test/test_read_set_format.c | 29 ++- libarchive/test/test_write_format_iso9660.c | 221 ++++++++++++++++-- tar/test/CMakeLists.txt | 3 +- tar/test/main.c | 4 +- tar/test/test.h | 2 +- tar/test/test_option_b.c | 2 +- tar/test/test_symlink_dir.c | 2 +- 26 files changed, 490 insertions(+), 63 deletions(-) create mode 100755 build/ci_build.sh diff --git a/.travis.yml b/.travis.yml index c9323986a92d..3a7aae334b61 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,13 @@ language: C -sudo: true +sudo: required +dist: trusty compiler: - gcc - clang -before_install: - - sudo add-apt-repository ppa:kubuntu-ppa/backports -y - - sudo apt-get update -qq +env: + - BUILD_SYSTEM=cmake + - BUILD_SYSTEM=autotools install: - - sudo apt-get install -y cmake=2.8.12.2-0ubuntu1~ubuntu12.04.1~ppa2 - sudo apt-get install -y libbz2-dev libzip-dev liblzma-dev -before_script: - - BUILD_DIR=`pwd`/BUILD - - mkdir -p ${BUILD_DIR} - - cd ${BUILD_DIR} - - cmake .. script: - - cd ${BUILD_DIR} - - make - - make test + - build/ci_build.sh diff --git a/Makefile.am b/Makefile.am index 90c9ae10546f..5fe2d4947e64 100644 --- a/Makefile.am +++ b/Makefile.am @@ -23,7 +23,7 @@ TESTS_ENVIRONMENT= $(libarchive_TESTS_ENVIRONMENT) $(bsdtar_TESTS_ENVIRONMENT) $ DISTCHECK_CONFIGURE_FLAGS = --enable-bsdtar --enable-bsdcpio # The next line is commented out by default in shipping libarchive releases. # It is uncommented by default in trunk. -DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g +# DEV_CFLAGS=-Werror -Wextra -Wunused -Wshadow -Wmissing-prototypes -Wcast-qual -g AM_CFLAGS=$(DEV_CFLAGS) PLATFORMCPPFLAGS = @PLATFORMCPPFLAGS@ AM_CPPFLAGS=$(PLATFORMCPPFLAGS) @@ -662,6 +662,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_filter_lrzip.tar.lrz.uu \ libarchive/test/test_read_filter_lzop.tar.lzo.uu \ libarchive/test/test_read_filter_lzop_multiple_parts.tar.lzo.uu \ + libarchive/test/test_read_format_mtree_crash747.mtree.bz2.uu \ libarchive/test/test_read_format_7zip_bcj2_bzip2.7z.uu \ libarchive/test/test_read_format_7zip_bcj2_copy_1.7z.uu \ libarchive/test/test_read_format_7zip_bcj2_copy_2.7z.uu \ @@ -787,6 +788,7 @@ libarchive_test_EXTRA_DIST=\ libarchive/test/test_read_format_zip_filename_utf8_jp.zip.uu \ libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \ libarchive/test/test_read_format_zip_filename_utf8_ru2.zip.uu \ + libarchive/test/test_read_format_zip_high_compression.zip.uu \ libarchive/test/test_read_format_zip_length_at_end.zip.uu \ libarchive/test/test_read_format_zip_mac_metadata.zip.uu \ libarchive/test/test_read_format_zip_malformed1.zip.uu \ diff --git a/NEWS b/NEWS index f672d3dfe3cb..dd4cfd59fb0c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,6 @@ +Oct 23, 2016: libarchive 3.2.2 released + Security release + Jun 20, 2016: libarchive 3.2.1 released This fixes a handful of security and other critical issues with 3.2.0 diff --git a/build/ci_build.sh b/build/ci_build.sh new file mode 100755 index 000000000000..624e09cde31d --- /dev/null +++ b/build/ci_build.sh @@ -0,0 +1,103 @@ +#!/bin/sh +# +# Automated build and test of libarchive on CI systems +# +# Variables that can be passed via environment: +# BUILD_SYSTEM= +# BUILDDIR= +# SRCDIR= +# CONFIGURE_ARGS= +# MAKE_ARGS= +# + +ACTIONS= +BUILD_SYSTEM="${BUILD_SYSTEM:-autotools}" +CURDIR=`pwd` +SRCDIR="${SRCDIR:-`pwd`}" +RET=0 + +usage () { + echo "Usage: $0 [-b autotools|cmake] [-a autogen|configure|build|test ] [ -a ... ] [ -d builddir ] [-s srcdir ]" +} +inputerror () { + echo $1 + usage + exit 1 +} +while getopts a:b:d:s: opt; do + case ${opt} in + a) + case "${OPTARG}" in + autogen) ;; + configure) ;; + build) ;; + test) ;; + *) inputerror "Invalid action (-a)" ;; + esac + ACTIONS="${ACTIONS} ${OPTARG}" + ;; + b) BUILD_SYSTEM="${OPTARG}" + case "${BUILD_SYSTEM}" in + autotools) ;; + cmake) ;; + *) inputerror "Invalid build system (-b)" ;; + esac + ;; + d) + BUILDDIR="${OPTARG}" + ;; + s) + SRCDIR="${OPTARG}" + if [ ! -f "${SRCDIR}/build/version" ]; then + inputerror "Missing file: ${SRCDIR}/build/version" + fi + ;; + esac +done +if [ -z "${ACTIONS}" ]; then + ACTIONS="autogen configure build test" +fi +if [ -z "${BUILD_SYSTEM}" ]; then + inputerror "Missing type (-t) parameter" +fi +if [ -z "${BUILDDIR}" ]; then + BUILDDIR="${CURDIR}/BUILD/${BUILD_SYSTEM}" +fi +mkdir -p "${BUILDDIR}" +for action in ${ACTIONS}; do + cd "${BUILDDIR}" + case "${action}" in + autogen) + case "${BUILD_SYSTEM}" in + autotools) + cd "${SRCDIR}" + sh build/autogen.sh + RET="$?" + ;; + esac + ;; + configure) + case "${BUILD_SYSTEM}" in + autotools) "${SRCDIR}/configure" ${CONFIGURE_ARGS} ;; + cmake) cmake ${CONFIGURE_ARGS} "${SRCDIR}" ;; + esac + RET="$?" + ;; + build) + make ${MAKE_ARGS} + RET="$?" + ;; + test) + case "${BUILD_SYSTEM}" in + autotools) make ${MAKE_ARGS} check ;; + cmake) make ${MAKE_ARGS} test ;; + esac + RET="$?" + ;; + esac + if [ "${RET}" != "0" ]; then + exit "${RET}" + fi + cd "${CURDIR}" +done +exit "${RET}" diff --git a/build/version b/build/version index f293156370c5..f54ddaaefc3d 100644 --- a/build/version +++ b/build/version @@ -1 +1 @@ -3002001 +3002002 diff --git a/cat/test/CMakeLists.txt b/cat/test/CMakeLists.txt index 0990bcf272a7..c4642aea4794 100644 --- a/cat/test/CMakeLists.txt +++ b/cat/test/CMakeLists.txt @@ -58,7 +58,8 @@ IF(ENABLE_CAT AND ENABLE_TEST) # Experimental new test handling ADD_CUSTOM_TARGET(run_bsdcat_test COMMAND bsdcat_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR}) + -r ${CMAKE_CURRENT_SOURCE_DIR} + -vv) ADD_DEPENDENCIES(run_bsdcat_test bsdcat) ADD_DEPENDENCIES(run_all_tests run_bsdcat_test) diff --git a/cat/test/main.c b/cat/test/main.c index 29f7b14b1849..a57984294fe4 100644 --- a/cat/test/main.c +++ b/cat/test/main.c @@ -129,6 +129,13 @@ # include #endif +mode_t umasked(mode_t expected_mode) +{ + mode_t mode = umask(0); + umask(mode); + return expected_mode & ~mode; +} + /* Path to working directory for current test */ const char *testworkdir; #ifdef PROGRAM @@ -1156,6 +1163,35 @@ assertion_file_contains_lines_any_order(const char *file, int line, return (0); } +/* Verify that a text file does not contains the specified strings */ +int +assertion_file_contains_no_invalid_strings(const char *file, int line, + const char *pathname, const char *strings[]) +{ + char *buff; + int i; + + buff = slurpfile(NULL, "%s", pathname); + if (buff == NULL) { + failure_start(file, line, "Can't read file: %s", pathname); + failure_finish(NULL); + return (0); + } + + for (i = 0; strings[i] != NULL; ++i) { + if (strstr(buff, strings[i]) != NULL) { + failure_start(file, line, "Invalid string in %s: %s", pathname, + strings[i]); + failure_finish(NULL); + free(buff); + return(0); + } + } + + free(buff); + return (0); +} + /* Test that two paths point to the same file. */ /* As a side-effect, asserts that both files exist. */ static int @@ -1293,6 +1329,11 @@ assertion_file_time(const char *file, int line, switch (type) { case 'a': filet_nsec = st.st_atimespec.tv_nsec; break; case 'b': filet = st.st_birthtime; + /* FreeBSD filesystems that don't support birthtime + * (e.g., UFS1) always return -1 here. */ + if (filet == -1) { + return (1); + } filet_nsec = st.st_birthtimespec.tv_nsec; break; case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break; default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); @@ -1370,6 +1411,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect assertion_count(file, line); #if defined(_WIN32) && !defined(__CYGWIN__) failure_start(file, line, "assertFileMode not yet implemented for Windows"); + (void)mode; /* UNUSED */ + (void)r; /* UNUSED */ #else { struct stat st; @@ -1424,7 +1467,7 @@ assertion_file_nlinks(const char *file, int line, assertion_count(file, line); r = lstat(pathname, &st); if (r == 0 && (int)st.st_nlink == nlinks) - return (1); + return (1); failure_start(file, line, "File %s has %d links, expected %d", pathname, st.st_nlink, nlinks); failure_finish(NULL); @@ -1660,6 +1703,7 @@ assertion_make_file(const char *file, int line, if (0 != chmod(path, mode)) { failure_start(file, line, "Could not chmod %s", path); failure_finish(NULL); + close(fd); return (0); } if (contents != NULL) { @@ -1674,6 +1718,7 @@ assertion_make_file(const char *file, int line, failure_start(file, line, "Could not write to %s", path); failure_finish(NULL); + close(fd); return (0); } } diff --git a/cat/test/test.h b/cat/test/test.h index 1d219647560f..c002a2c27eee 100644 --- a/cat/test/test.h +++ b/cat/test/test.h @@ -174,6 +174,9 @@ /* Assert that file contents match a string. */ #define assertFileContents(data, data_size, pathname) \ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname) +/* Verify that a file does not contain invalid strings */ +#define assertFileContainsNoInvalidStrings(pathname, strings) \ + assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings) #define assertFileMtime(pathname, sec, nsec) \ assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec) #define assertFileMtimeRecent(pathname) \ @@ -182,6 +185,8 @@ assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks) #define assertFileSize(pathname, size) \ assertion_file_size(__FILE__, __LINE__, pathname, size) +#define assertFileMode(pathname, mode) \ + assertion_file_mode(__FILE__, __LINE__, pathname, mode) #define assertTextFileContents(text, pathname) \ assertion_text_file_contents(__FILE__, __LINE__, text, pathname) #define assertFileContainsLinesAnyOrder(pathname, lines) \ @@ -239,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *); int assertion_file_birthtime(const char *, int, const char *, long, long); int assertion_file_birthtime_recent(const char *, int, const char *); int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); +int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); int assertion_file_mode(const char *, int, const char *, int); @@ -327,6 +333,9 @@ void copy_reference_file(const char *); */ void extract_reference_files(const char **); +/* Subtract umask from mode */ +mode_t umasked(mode_t expected_mode); + /* Path to working directory for current test */ extern const char *testworkdir; diff --git a/configure.ac b/configure.ac index fc82b0ef9d5f..008b04de0b5c 100644 --- a/configure.ac +++ b/configure.ac @@ -4,8 +4,8 @@ dnl First, define all of the version numbers up front. dnl In particular, this allows the version macro to be used in AC_INIT dnl These first two version numbers are updated automatically on each release. -m4_define([LIBARCHIVE_VERSION_S],[3.2.1]) -m4_define([LIBARCHIVE_VERSION_N],[3002001]) +m4_define([LIBARCHIVE_VERSION_S],[3.2.2]) +m4_define([LIBARCHIVE_VERSION_N],[3002002]) dnl bsdtar and bsdcpio versioning tracks libarchive m4_define([BSDTAR_VERSION_S],LIBARCHIVE_VERSION_S()) diff --git a/cpio/test/CMakeLists.txt b/cpio/test/CMakeLists.txt index e3063ee9be58..8ffb54276967 100644 --- a/cpio/test/CMakeLists.txt +++ b/cpio/test/CMakeLists.txt @@ -91,7 +91,8 @@ IF(ENABLE_CPIO AND ENABLE_TEST) # Experimental new test handling ADD_CUSTOM_TARGET(run_bsdcpio_test COMMAND bsdcpio_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR}) + -r ${CMAKE_CURRENT_SOURCE_DIR} + -vv) ADD_DEPENDENCIES(run_bsdcpio_test bsdcpio) ADD_DEPENDENCIES(run_all_tests run_bsdcpio_test) ENDIF(ENABLE_CPIO AND ENABLE_TEST) diff --git a/cpio/test/main.c b/cpio/test/main.c index f3b431d0a6df..6e6b5ab435d0 100644 --- a/cpio/test/main.c +++ b/cpio/test/main.c @@ -1164,6 +1164,35 @@ assertion_file_contains_lines_any_order(const char *file, int line, return (0); } +/* Verify that a text file does not contains the specified strings */ +int +assertion_file_contains_no_invalid_strings(const char *file, int line, + const char *pathname, const char *strings[]) +{ + char *buff; + int i; + + buff = slurpfile(NULL, "%s", pathname); + if (buff == NULL) { + failure_start(file, line, "Can't read file: %s", pathname); + failure_finish(NULL); + return (0); + } + + for (i = 0; strings[i] != NULL; ++i) { + if (strstr(buff, strings[i]) != NULL) { + failure_start(file, line, "Invalid string in %s: %s", pathname, + strings[i]); + failure_finish(NULL); + free(buff); + return(0); + } + } + + free(buff); + return (0); +} + /* Test that two paths point to the same file. */ /* As a side-effect, asserts that both files exist. */ static int @@ -1383,6 +1412,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect assertion_count(file, line); #if defined(_WIN32) && !defined(__CYGWIN__) failure_start(file, line, "assertFileMode not yet implemented for Windows"); + (void)mode; /* UNUSED */ + (void)r; /* UNUSED */ #else { struct stat st; diff --git a/cpio/test/test.h b/cpio/test/test.h index 0a8b31e1c864..49fa32c99e25 100644 --- a/cpio/test/test.h +++ b/cpio/test/test.h @@ -174,6 +174,9 @@ /* Assert that file contents match a string. */ #define assertFileContents(data, data_size, pathname) \ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname) +/* Verify that a file does not contain invalid strings */ +#define assertFileContainsNoInvalidStrings(pathname, strings) \ + assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings) #define assertFileMtime(pathname, sec, nsec) \ assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec) #define assertFileMtimeRecent(pathname) \ @@ -241,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *); int assertion_file_birthtime(const char *, int, const char *, long, long); int assertion_file_birthtime_recent(const char *, int, const char *); int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); +int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); int assertion_file_mode(const char *, int, const char *, int); diff --git a/libarchive/archive.h b/libarchive/archive.h index 1794dd34fc56..ff401e94fa66 100644 --- a/libarchive/archive.h +++ b/libarchive/archive.h @@ -36,7 +36,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */ -#define ARCHIVE_VERSION_NUMBER 3002001 +#define ARCHIVE_VERSION_NUMBER 3002002 #include #include /* for wchar_t */ @@ -155,7 +155,7 @@ __LA_DECL int archive_version_number(void); /* * Textual name/version of the library, useful for version displays. */ -#define ARCHIVE_VERSION_ONLY_STRING "3.2.1" +#define ARCHIVE_VERSION_ONLY_STRING "3.2.2" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void); diff --git a/libarchive/archive_entry.h b/libarchive/archive_entry.h index dab2c9d82878..71b1e87e8d57 100644 --- a/libarchive/archive_entry.h +++ b/libarchive/archive_entry.h @@ -29,7 +29,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */ -#define ARCHIVE_VERSION_NUMBER 3002001 +#define ARCHIVE_VERSION_NUMBER 3002002 /* * Note: archive_entry.h is for use outside of libarchive; the diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt index 0cb5966df35c..1cb21f9c6b71 100644 --- a/libarchive/test/CMakeLists.txt +++ b/libarchive/test/CMakeLists.txt @@ -300,7 +300,7 @@ IF(ENABLE_TEST) # Experimental new test handling ADD_CUSTOM_TARGET(run_libarchive_test - COMMAND libarchive_test -r ${CMAKE_CURRENT_SOURCE_DIR}) + COMMAND libarchive_test -r ${CMAKE_CURRENT_SOURCE_DIR} -vv) ADD_DEPENDENCIES(run_all_tests run_libarchive_test) ENDIF(ENABLE_TEST) diff --git a/libarchive/test/main.c b/libarchive/test/main.c index aaa5cfa5d4b6..32a1f78b9cf2 100644 --- a/libarchive/test/main.c +++ b/libarchive/test/main.c @@ -1162,6 +1162,35 @@ assertion_file_contains_lines_any_order(const char *file, int line, return (0); } +/* Verify that a text file does not contains the specified strings */ +int +assertion_file_contains_no_invalid_strings(const char *file, int line, + const char *pathname, const char *strings[]) +{ + char *buff; + int i; + + buff = slurpfile(NULL, "%s", pathname); + if (buff == NULL) { + failure_start(file, line, "Can't read file: %s", pathname); + failure_finish(NULL); + return (0); + } + + for (i = 0; strings[i] != NULL; ++i) { + if (strstr(buff, strings[i]) != NULL) { + failure_start(file, line, "Invalid string in %s: %s", pathname, + strings[i]); + failure_finish(NULL); + free(buff); + return(0); + } + } + + free(buff); + return (0); +} + /* Test that two paths point to the same file. */ /* As a side-effect, asserts that both files exist. */ static int @@ -1381,6 +1410,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect assertion_count(file, line); #if defined(_WIN32) && !defined(__CYGWIN__) failure_start(file, line, "assertFileMode not yet implemented for Windows"); + (void)mode; /* UNUSED */ + (void)r; /* UNUSED */ #else { struct stat st; diff --git a/libarchive/test/test.h b/libarchive/test/test.h index 4d5030329d53..a48c42641e89 100644 --- a/libarchive/test/test.h +++ b/libarchive/test/test.h @@ -174,6 +174,9 @@ /* Assert that file contents match a string. */ #define assertFileContents(data, data_size, pathname) \ assertion_file_contents(__FILE__, __LINE__, data, data_size, pathname) +/* Verify that a file does not contain invalid strings */ +#define assertFileContainsNoInvalidStrings(pathname, strings) \ + assertion_file_contains_no_invalid_strings(__FILE__, __LINE__, pathname, strings) #define assertFileMtime(pathname, sec, nsec) \ assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec) #define assertFileMtimeRecent(pathname) \ @@ -241,6 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *); int assertion_file_birthtime(const char *, int, const char *, long, long); int assertion_file_birthtime_recent(const char *, int, const char *); int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); +int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); int assertion_file_mode(const char *, int, const char *, int); diff --git a/libarchive/test/test_read_format_mtree_crash747.c b/libarchive/test/test_read_format_mtree_crash747.c index c08284552131..9500bba2cdb4 100644 --- a/libarchive/test/test_read_format_mtree_crash747.c +++ b/libarchive/test/test_read_format_mtree_crash747.c @@ -33,6 +33,11 @@ DEFINE_TEST(test_read_format_mtree_crash747) const char *reffile = "test_read_format_mtree_crash747.mtree.bz2"; struct archive *a; + if (archive_bzlib_version() == NULL) { + skipping("This test requires bzlib"); + return; + } + extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); diff --git a/libarchive/test/test_read_format_zip_high_compression.c b/libarchive/test/test_read_format_zip_high_compression.c index 6c8aa8eee1b2..42faed378f6d 100644 --- a/libarchive/test/test_read_format_zip_high_compression.c +++ b/libarchive/test/test_read_format_zip_high_compression.c @@ -50,6 +50,11 @@ DEFINE_TEST(test_read_format_zip_high_compression) size_t s; int64_t o; + if (archive_zlib_version() == NULL) { + skipping("Zip compression test requires zlib"); + return; + } + extract_reference_file(refname); p = slurpfile(&archive_size, refname); @@ -82,6 +87,11 @@ DEFINE_TEST(test_read_format_zip_high_compression2) char *body, *body_read, *buff; int n; + if (archive_zlib_version() == NULL) { + skipping("Zip compression test requires zlib"); + return; + } + assert((body = malloc(body_size)) != NULL); assert((body_read = malloc(body_size)) != NULL); assert((buff = malloc(buff_size)) != NULL); diff --git a/libarchive/test/test_read_set_format.c b/libarchive/test/test_read_set_format.c index d333269c2ee9..fb5e0047443a 100644 --- a/libarchive/test/test_read_set_format.c +++ b/libarchive/test/test_read_set_format.c @@ -133,11 +133,12 @@ DEFINE_TEST(test_read_append_filter) assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); r = archive_read_append_filter(a, ARCHIVE_FILTER_GZIP); - if (r == ARCHIVE_WARN && !canGzip()) { - skipping("gzip reading not fully supported on this platform"); + if (r != ARCHIVE_OK && archive_zlib_version() == NULL && !canGzip()) { + skipping("gzip tests require zlib or working gzip command"); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); return; } + assertEqualIntA(a, ARCHIVE_OK, r); assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); @@ -200,8 +201,11 @@ DEFINE_TEST(test_read_append_filter_wrong_program) { struct archive_entry *ae; struct archive *a; +#if !defined(_WIN32) || defined(__CYGWIN__) + FILE * fp; int fd; fpos_t pos; +#endif /* * If we have "bunzip2 -q", try using that. @@ -211,11 +215,13 @@ DEFINE_TEST(test_read_append_filter_wrong_program) return; } +#if !defined(_WIN32) || defined(__CYGWIN__) /* bunzip2 will write to stderr, redirect it to a file */ fflush(stderr); fgetpos(stderr, &pos); fd = dup(fileno(stderr)); - freopen("stderr1", "w", stderr); + fp = freopen("stderr1", "w", stderr); +#endif assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); @@ -227,12 +233,15 @@ DEFINE_TEST(test_read_append_filter_wrong_program) assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); - /* restore stderr */ - fflush(stderr); - dup2(fd, fileno(stderr)); - close(fd); - clearerr(stderr); - fsetpos(stderr, &pos); - +#if !defined(_WIN32) || defined(__CYGWIN__) + /* restore stderr and verify results */ + if (fp != NULL) { + fflush(stderr); + dup2(fd, fileno(stderr)); + close(fd); + clearerr(stderr); + fsetpos(stderr, &pos); + } assertTextFileContents("bunzip2: (stdin) is not a bzip2 file.\n", "stderr1"); +#endif } diff --git a/libarchive/test/test_write_format_iso9660.c b/libarchive/test/test_write_format_iso9660.c index 1ea69a183595..ee6db6fed3b2 100644 --- a/libarchive/test/test_write_format_iso9660.c +++ b/libarchive/test/test_write_format_iso9660.c @@ -117,8 +117,8 @@ DEFINE_TEST(test_write_format_iso9660) */ dirname[0] = '\0'; strcpy(dir, "/dir0"); - for (i = 0; i < 10; i++) { - dir[4] = '0' + i; + for (i = 0; i < 13; i++) { + dir[4] = "0123456789ABCDEF"[i]; if (i == 0) strcat(dirname, dir+1); else @@ -134,6 +134,19 @@ DEFINE_TEST(test_write_format_iso9660) archive_entry_free(ae); } + strcat(dirname, "/file"); + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_atime(ae, 2, 20); + archive_entry_set_birthtime(ae, 3, 30); + archive_entry_set_ctime(ae, 4, 40); + archive_entry_set_mtime(ae, 5, 50); + archive_entry_copy_pathname(ae, dirname); + archive_entry_set_mode(ae, S_IFREG | 0755); + archive_entry_set_size(ae, 8); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, 8, archive_write_data(a, "12345678", 9)); + /* * "dir0/dir1/file1" has 8 bytes of data. */ @@ -332,6 +345,45 @@ DEFINE_TEST(test_write_format_iso9660) assert((S_IFDIR | 0555) == archive_entry_mode(ae)); assertEqualInt(2048, archive_entry_size(ae)); + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(2, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_birthtime(ae)); + assertEqualInt(4, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0555) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(2, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_birthtime(ae)); + assertEqualInt(4, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0555) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(2, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_birthtime(ae)); + assertEqualInt(4, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0555) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* * Read "hardlnk" */ @@ -385,6 +437,21 @@ DEFINE_TEST(test_write_format_iso9660) assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); assertEqualMem(buff2, "12345678", 8); + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(2, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_birthtime(ae)); + assertEqualInt(4, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file", archive_entry_pathname(ae)); + assert((AE_IFREG | 0555) == archive_entry_mode(ae)); + assertEqualInt(1, archive_entry_nlink(ae)); + assertEqualInt(8, archive_entry_size(ae)); + assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); + assertEqualMem(buff2, "12345678", 8); + /* * Read "dir0/dir1/file1" */ @@ -580,18 +647,40 @@ DEFINE_TEST(test_write_format_iso9660) assertEqualInt(2048, archive_entry_size(ae)); /* - * Read "hardlnk" + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA" */ assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); assertEqualInt(5, archive_entry_atime(ae)); assertEqualInt(5, archive_entry_ctime(ae)); assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("hardlnk", archive_entry_pathname(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0700) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0700) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0700) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); /* * Read "file" @@ -601,8 +690,22 @@ DEFINE_TEST(test_write_format_iso9660) assertEqualInt(5, archive_entry_ctime(ae)); assertEqualInt(5, archive_entry_mtime(ae)); assertEqualString("file", archive_entry_pathname(ae)); - assertEqualString("hardlnk", archive_entry_hardlink(ae)); assert((AE_IFREG | 0400) == archive_entry_mode(ae)); + assertEqualInt(8, archive_entry_size(ae)); + assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); + assertEqualMem(buff2, "12345678", 8); + + /* + * Read "hardlnk" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("hardlnk", archive_entry_pathname(ae)); + assertEqualString("file", archive_entry_hardlink(ae)); + assert((AE_IFREG | 0400) == archive_entry_mode(ae)); + assertEqualInt(2, archive_entry_nlink(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualIntA(a, 0, archive_read_data(a, buff2, 10)); @@ -624,6 +727,22 @@ DEFINE_TEST(test_write_format_iso9660) assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); assertEqualMem(buff2, "12345678", 8); + /* + * Read "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString( + "dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dirA/dirB/dirC/file", + archive_entry_pathname(ae)); + assert((AE_IFREG | 0400) == archive_entry_mode(ae)); + assertEqualInt(1, archive_entry_nlink(ae)); + assertEqualInt(8, archive_entry_size(ae)); + assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); + assertEqualMem(buff2, "12345678", 8); + /* * Read "dir0/dir1/file1" */ @@ -745,6 +864,42 @@ DEFINE_TEST(test_write_format_iso9660) assert((S_IFDIR | 0700) == archive_entry_mode(ae)); assertEqualInt(2048, archive_entry_size(ae)); + /* + * Read "rr_moved/dir7/dir8/dir9/dira" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0700) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + + /* + * Read "rr_moved/dir7/dir8/dir9/dira/dirB" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0700) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + + /* + * Read "rr_moved/dir7/dir8/dir9/dirA/dirB/dirC" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB/DIRC", + archive_entry_pathname(ae)); + assert((S_IFDIR | 0700) == archive_entry_mode(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* * Read "dir0" */ @@ -826,6 +981,20 @@ DEFINE_TEST(test_write_format_iso9660) assert((S_IFDIR | 0700) == archive_entry_mode(ae)); assertEqualInt(2048, archive_entry_size(ae)); + /* + * Read "hardlink" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString("HARDLNK", archive_entry_pathname(ae)); + assertEqualString(NULL, archive_entry_hardlink(ae)); + assert((AE_IFREG | 0400) == archive_entry_mode(ae)); + assertEqualInt(8, archive_entry_size(ae)); + assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); + assertEqualMem(buff2, "12345678", 8); + /* * Read "file" */ @@ -835,25 +1004,13 @@ DEFINE_TEST(test_write_format_iso9660) assertEqualInt(5, archive_entry_ctime(ae)); assertEqualInt(5, archive_entry_mtime(ae)); assertEqualString("FILE", archive_entry_pathname(ae)); + assertEqualString("HARDLNK", archive_entry_hardlink(ae)); assert((AE_IFREG | 0400) == archive_entry_mode(ae)); assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(8, archive_entry_size(ae)); - assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); - assertEqualMem(buff2, "12345678", 8); - - /* - * Read "hardlink" - */ - assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_entry_atime(ae)); - assertEqualInt(5, archive_entry_ctime(ae)); - assertEqualInt(5, archive_entry_mtime(ae)); - assertEqualString("HARDLNK", archive_entry_pathname(ae)); - assertEqualString("FILE", archive_entry_hardlink(ae)); - assert((AE_IFREG | 0400) == archive_entry_mode(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualIntA(a, 0, archive_read_data(a, buff2, 10)); + /* * Read longname */ @@ -870,6 +1027,22 @@ DEFINE_TEST(test_write_format_iso9660) assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); assertEqualMem(buff2, "12345678", 8); + /* + * Read "rr_moved/dir7/dir8/dir9/dirA/dirB/dirC/file" + */ + assertEqualIntA(a, 0, archive_read_next_header(a, &ae)); + assertEqualInt(5, archive_entry_atime(ae)); + assertEqualInt(5, archive_entry_ctime(ae)); + assertEqualInt(5, archive_entry_mtime(ae)); + assertEqualString( + "RR_MOVED/DIR7/DIR8/DIR9/DIRA/DIRB/DIRC/FILE", + archive_entry_pathname(ae)); + assert((AE_IFREG | 0400) == archive_entry_mode(ae)); + assertEqualInt(1, archive_entry_nlink(ae)); + assertEqualInt(8, archive_entry_size(ae)); + assertEqualIntA(a, 8, archive_read_data(a, buff2, 10)); + assertEqualMem(buff2, "12345678", 8); + /* * Read "dir0/dir1/file1" */ diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt index f19a5f69c504..0d2da365087d 100644 --- a/tar/test/CMakeLists.txt +++ b/tar/test/CMakeLists.txt @@ -100,7 +100,8 @@ IF(ENABLE_TAR AND ENABLE_TEST) # Experimental new test handling ADD_CUSTOM_TARGET(run_bsdtar_test COMMAND bsdtar_test -p $ - -r ${CMAKE_CURRENT_SOURCE_DIR}) + -r ${CMAKE_CURRENT_SOURCE_DIR} + -vv) ADD_DEPENDENCIES(run_bsdtar_test bsdtar) ADD_DEPENDENCIES(run_all_tests run_bsdtar_test) diff --git a/tar/test/main.c b/tar/test/main.c index d847964f75e9..d35d33565449 100644 --- a/tar/test/main.c +++ b/tar/test/main.c @@ -1188,7 +1188,7 @@ assertion_file_contains_no_invalid_strings(const char *file, int line, return(0); } } - + free(buff); return (0); } @@ -1412,6 +1412,8 @@ assertion_file_mode(const char *file, int line, const char *pathname, int expect assertion_count(file, line); #if defined(_WIN32) && !defined(__CYGWIN__) failure_start(file, line, "assertFileMode not yet implemented for Windows"); + (void)mode; /* UNUSED */ + (void)r; /* UNUSED */ #else { struct stat st; diff --git a/tar/test/test.h b/tar/test/test.h index 98415f8538d8..3a23a05a67ec 100644 --- a/tar/test/test.h +++ b/tar/test/test.h @@ -244,7 +244,7 @@ int assertion_file_atime_recent(const char *, int, const char *); int assertion_file_birthtime(const char *, int, const char *, long, long); int assertion_file_birthtime_recent(const char *, int, const char *); int assertion_file_contains_lines_any_order(const char *, int, const char *, const char **); -int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); +int assertion_file_contains_no_invalid_strings(const char *, int, const char *, const char **); int assertion_file_contents(const char *, int, const void *, int, const char *); int assertion_file_exists(const char *, int, const char *); int assertion_file_mode(const char *, int, const char *, int); diff --git a/tar/test/test_option_b.c b/tar/test/test_option_b.c index 81f50be8355e..7c2f60476c55 100644 --- a/tar/test/test_option_b.c +++ b/tar/test/test_option_b.c @@ -33,7 +33,7 @@ DEFINE_TEST(test_option_b) assertMakeFile("file1", 0644, "file1"); if (systemf("cat file1 > test_cat.out 2> test_cat.err") != 0) { - skipping("Platform doesn't have cat"); + skipping("This test requires a `cat` program"); return; } testprog_ustar = malloc(strlen(testprog) + sizeof(USTAR_OPT) + 1); diff --git a/tar/test/test_symlink_dir.c b/tar/test/test_symlink_dir.c index f6e99662bf11..25bd8b162a16 100644 --- a/tar/test/test_symlink_dir.c +++ b/tar/test/test_symlink_dir.c @@ -63,7 +63,7 @@ DEFINE_TEST(test_symlink_dir) /* "dir2" is a symlink to a non-existing "real_dir2" */ assertMakeSymlink("dest1/dir2", "real_dir2"); } else { - skipping("some symlink checks"); + skipping("Symlinks are not supported on this platform"); } /* "dir3" is a symlink to an existing "non_dir3" */ assertMakeFile("dest1/non_dir3", 0755, "abcdef"); From 2c3b1e3c42a39f56ffdfc62130ef1882759c620b Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Mon, 24 Oct 2016 14:24:12 +0000 Subject: [PATCH 060/235] Revert 307822 P2WI is almost compatible with RSB which we already support. I'll add support for P2WI in aw_rsb instead. Discussed with: jmcneill --- sys/arm/allwinner/aw_p2wi.c | 277 ------------------------------ sys/arm/allwinner/aw_p2wi.h | 79 --------- sys/arm/allwinner/files.allwinner | 1 - sys/arm/conf/GENERIC | 1 - 4 files changed, 358 deletions(-) delete mode 100644 sys/arm/allwinner/aw_p2wi.c delete mode 100644 sys/arm/allwinner/aw_p2wi.h diff --git a/sys/arm/allwinner/aw_p2wi.c b/sys/arm/allwinner/aw_p2wi.c deleted file mode 100644 index 6feb732e5305..000000000000 --- a/sys/arm/allwinner/aw_p2wi.c +++ /dev/null @@ -1,277 +0,0 @@ -/*- - * Copyright (c) 2016 Emmanuel Vadot - * 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 ``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 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$ - */ - -/* - * Allwinner P2WI (Push-Pull Two Wire Interface) - * P2WI is a iic-like interface used on sun6i hardware - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include - -#include "iicbus_if.h" - -static struct ofw_compat_data compat_data[] = { - { "allwinner,sun6i-a31-p2wi", 1 }, - { NULL, 0 } -}; - -static struct resource_spec p2wi_spec[] = { - { SYS_RES_MEMORY, 0, RF_ACTIVE }, - { -1, 0 } -}; - -struct p2wi_softc { - struct resource *res; - struct mtx mtx; - clk_t clk; - hwreset_t rst; - device_t iicbus; -}; - -#define P2WI_LOCK(sc) mtx_lock(&(sc)->mtx) -#define P2WI_UNLOCK(sc) mtx_unlock(&(sc)->mtx) -#define P2WI_READ(sc, reg) bus_read_4((sc)->res, (reg)) -#define P2WI_WRITE(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) - -#define P2WI_RETRY 1000 - -static phandle_t -p2wi_get_node(device_t bus, device_t dev) -{ - return (ofw_bus_get_node(bus)); -} - -static int -p2wi_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) -{ - struct p2wi_softc *sc; - int retry; - - sc = device_get_softc(dev); - - P2WI_LOCK(sc); - - P2WI_WRITE(sc, P2WI_CTRL, P2WI_CTRL_SOFT_RESET); - for (retry = P2WI_RETRY; retry > 0; retry--) - if ((P2WI_READ(sc, P2WI_CTRL) & P2WI_CTRL_SOFT_RESET) == 0) - break; - - P2WI_UNLOCK(sc); - - if (retry == 0) { - device_printf(dev, "soft reset timeout\n"); - return (ETIMEDOUT); - } - - return (IIC_ENOADDR); -} - -static int -p2wi_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) -{ - struct p2wi_softc *sc; - int retry, error; - uint8_t data_len; - - sc = device_get_softc(dev); - - /* - * Since P2WI is only used for AXP22x PMIC we only support - * two messages of one byte length - */ - if (nmsgs != 2 || (msgs[0].flags & IIC_M_RD) == IIC_M_RD || - msgs[0].len != 1 || msgs[1].len != 1) - return (EINVAL); - - P2WI_LOCK(sc); - - /* Write address */ - P2WI_WRITE(sc, P2WI_DADDR0, msgs[0].buf[0]); - - /* Write Data length/Direction */ - data_len = P2WI_DLEN_LEN(msgs[1].len); - if ((msgs[1].flags & IIC_M_RD) == 0) - P2WI_WRITE(sc, P2WI_DATA0, msgs[1].buf[0]); - else - data_len |= P2WI_DLEN_READ; - P2WI_WRITE(sc, P2WI_DLEN, data_len); - - /* Start transfer */ - P2WI_WRITE(sc, P2WI_CTRL, P2WI_CTRL_START_TRANS); - - /* Wait for transfer to complete */ - for (retry = P2WI_RETRY; retry > 0; retry--) - if ((P2WI_READ(sc, P2WI_CTRL) & P2WI_CTRL_START_TRANS) == 0) - break; - - if (retry == 0) { - error = ETIMEDOUT; - goto done; - } - - /* Read data if needed */ - if ((msgs[1].flags & IIC_M_RD) == IIC_M_RD) { - msgs[1].buf[0] = P2WI_READ(sc, P2WI_DATA0) & 0xff; - msgs[1].len = 1; - } - - error = 0; - -done: - P2WI_UNLOCK(sc); - - return (error); -} - -static int -p2wi_probe(device_t dev) -{ - if (!ofw_bus_status_okay(dev)) - return (ENXIO); - - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) - return (ENXIO); - - device_set_desc(dev, "Allwinner P2WI"); - return (BUS_PROBE_DEFAULT); -} - -static int -p2wi_attach(device_t dev) -{ - struct p2wi_softc *sc; - int error; - - sc = device_get_softc(dev); - mtx_init(&sc->mtx, device_get_nameunit(dev), "p2wi", MTX_DEF); - - if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) { - error = clk_enable(sc->clk); - if (error != 0) { - device_printf(dev, "cannot enable clock\n"); - goto fail; - } - } - if (hwreset_get_by_ofw_idx(dev, 0, 0, &sc->rst) == 0) { - error = hwreset_deassert(sc->rst); - if (error != 0) { - device_printf(dev, "cannot de-assert reset\n"); - goto fail; - } - } - - if (bus_alloc_resources(dev, p2wi_spec, &sc->res) != 0) { - device_printf(dev, "cannot allocate resources for device\n"); - error = ENXIO; - goto fail; - } - - sc->iicbus = device_add_child(dev, "iicbus", -1); - if (sc->iicbus == NULL) { - device_printf(dev, "cannot add iicbus child device\n"); - error = ENXIO; - goto fail; - } - - /* Disable interrupts */ - P2WI_WRITE(sc, P2WI_INTE, 0x0); - - bus_generic_attach(dev); - - return (0); - -fail: - bus_release_resources(dev, p2wi_spec, &sc->res); - if (sc->rst != NULL) - hwreset_release(sc->rst); - if (sc->clk != NULL) - clk_release(sc->clk); - mtx_destroy(&sc->mtx); - return (error); -} - -static device_method_t p2wi_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, p2wi_probe), - DEVMETHOD(device_attach, p2wi_attach), - - /* Bus interface */ - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), - DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), - DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), - - /* OFW methods */ - DEVMETHOD(ofw_bus_get_node, p2wi_get_node), - - /* iicbus interface */ - DEVMETHOD(iicbus_callback, iicbus_null_callback), - DEVMETHOD(iicbus_reset, p2wi_reset), - DEVMETHOD(iicbus_transfer, p2wi_transfer), - - DEVMETHOD_END -}; - -static driver_t p2wi_driver = { - "iichb", - p2wi_methods, - sizeof(struct p2wi_softc), -}; - -static devclass_t p2wi_devclass; - -EARLY_DRIVER_MODULE(iicbus, p2wi, iicbus_driver, iicbus_devclass, 0, 0, - BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); -EARLY_DRIVER_MODULE(p2wi, simplebus, p2wi_driver, p2wi_devclass, 0, 0, - BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE); -MODULE_VERSION(p2wi, 1); diff --git a/sys/arm/allwinner/aw_p2wi.h b/sys/arm/allwinner/aw_p2wi.h deleted file mode 100644 index a6b18208486a..000000000000 --- a/sys/arm/allwinner/aw_p2wi.h +++ /dev/null @@ -1,79 +0,0 @@ -/*- - * Copyright (c) 2016 Emmanuel Vadot - * 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 ``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 BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef __AW_P2WI_H__ -#define __AW_P2WI_H__ - -#define P2WI_CTRL 0x00 -#define P2WI_CTRL_SOFT_RESET (1 << 0) -#define P2WI_CTRL_GLOBAL_INT_ENB (1 << 1) -#define P2WI_CTRL_ABORT_TRANS (1 << 6) -#define P2WI_CTRL_START_TRANS (1 << 7) - -#define P2WI_CCR 0x04 -#define P2WI_CCR_CLK_DIV_SHIFT 0 -#define P2WI_CCR_CLK_DIV_MASK 0xFF -#define P2WI_CCR_SDA_ODLY_SHIFT 7 -#define P2WI_CCR_SDA_ODLY_MASK 0x700 - -#define P2WI_INTE 0x08 -#define P2WI_INTE_TRANS_OVER_ENB -#define P2WI_INTE_TRANS_ERR_ENB -#define P2WI_INTE_LOAD_BSY_ENB - -#define P2WI_STAT 0x0C -#define P2WI_STAT_TRANS_OVER (1 << 0) -#define P2WI_STAT_TRANS_ERR (1 << 1) -#define P2WI_STAT_LOAD_BSY (1 << 2) -#define P2WI_STAT_TRANS_ERR_ID_SHIFT 7 -#define P2WI_STAT_TRANS_ERR_ID_MASK 0xFF00 - -#define P2WI_DADDR0 0x10 - -#define P2WI_DADDR1 0x14 - -#define P2WI_DLEN 0x18 -#define P2WI_DLEN_LEN(x) ((x - 1) & 0x7) -#define P2WI_DLEN_READ (1 << 4) - -#define P2WI_DATA0 0x1C - -#define P2WI_DATA1 0x20 - -#define P2WI_LCR 0x24 -#define P2WI_LCR_SDA_CTL_EN (1 << 0) -#define P2WI_LCR_SDA_CTL (1 << 1) -#define P2WI_LCR_SCL_CTL_EN (1 << 2) -#define P2WI_LCR_SCL_CTL (1 << 3) -#define P2WI_LCR_SDA_STATE (1 << 4) -#define P2WI_LCR_SCL_STATE (1 << 5) - - -#define P2WI_PMCR 0x28 - -#endif /* __AW_P2WI_H__ */ diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index 5ada7549355e..d06f6aebbe8f 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -12,7 +12,6 @@ arm/allwinner/a10_mmc.c optional mmc arm/allwinner/a10_sramc.c standard arm/allwinner/aw_nmi.c optional intrng arm/allwinner/aw_if_dwc.c optional dwc -arm/allwinner/aw_p2wi.c optional p2wi arm/allwinner/aw_rsb.c optional rsb arm/allwinner/aw_rtc.c standard arm/allwinner/aw_ts.c standard diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 22c69db1de9b..148d20746898 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -107,7 +107,6 @@ device iicbus device iic device twsi device rsb -device p2wi # Allwinner Push-Pull Two Wire interface device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc From aa09009340785eeb67f2e50ef8dc57af9a366297 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 24 Oct 2016 14:37:18 +0000 Subject: [PATCH 061/235] Set SHLIBDIR before .including src.opts.mk in libcapser services bsd.own.mk (included from src.opts.mk) sets SHLIBDIR?=${LIBDIR}, so SHLIBDIR must be set before including either one of them. MFC with: 305626 Sponsored by: The FreeBSD Foundation --- lib/libcasper/services/cap_dns/Makefile | 3 ++- lib/libcasper/services/cap_grp/Makefile | 3 ++- lib/libcasper/services/cap_pwd/Makefile | 3 ++- lib/libcasper/services/cap_sysctl/Makefile | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/libcasper/services/cap_dns/Makefile b/lib/libcasper/services/cap_dns/Makefile index 6f7dbd580201..4a36da134b3a 100644 --- a/lib/libcasper/services/cap_dns/Makefile +++ b/lib/libcasper/services/cap_dns/Makefile @@ -1,12 +1,13 @@ # $FreeBSD$ +SHLIBDIR?= /lib/casper + .include PACKAGE=libcasper LIB= cap_dns SHLIB_MAJOR= 0 -SHLIBDIR?= /lib/casper INCSDIR?= ${INCLUDEDIR}/casper SRCS= cap_dns.c diff --git a/lib/libcasper/services/cap_grp/Makefile b/lib/libcasper/services/cap_grp/Makefile index a620be11b814..c2cc4b1a0b9f 100644 --- a/lib/libcasper/services/cap_grp/Makefile +++ b/lib/libcasper/services/cap_grp/Makefile @@ -1,12 +1,13 @@ # $FreeBSD$ +SHLIBDIR?= /lib/casper + .include PACKAGE=libcasper LIB= cap_grp SHLIB_MAJOR= 0 -SHLIBDIR?= /lib/casper INCSDIR?= ${INCLUDEDIR}/casper SRCS= cap_grp.c diff --git a/lib/libcasper/services/cap_pwd/Makefile b/lib/libcasper/services/cap_pwd/Makefile index 57876115db0b..ab4be4bacd14 100644 --- a/lib/libcasper/services/cap_pwd/Makefile +++ b/lib/libcasper/services/cap_pwd/Makefile @@ -1,12 +1,13 @@ # $FreeBSD$ +SHLIBDIR?= /lib/casper + .include PACKAGE=libcasper LIB= cap_pwd SHLIB_MAJOR= 0 -SHLIBDIR?= /lib/casper INCSDIR?= ${INCLUDEDIR}/casper SRCS= cap_pwd.c diff --git a/lib/libcasper/services/cap_sysctl/Makefile b/lib/libcasper/services/cap_sysctl/Makefile index d37b5dc461de..446ec5236e0b 100644 --- a/lib/libcasper/services/cap_sysctl/Makefile +++ b/lib/libcasper/services/cap_sysctl/Makefile @@ -1,12 +1,13 @@ # $FreeBSD$ +SHLIBDIR?= /lib/casper + .include PACKAGE=libcasper LIB= cap_sysctl SHLIB_MAJOR= 0 -SHLIBDIR?= /lib/casper INCSDIR?= ${INCLUDEDIR}/casper SRCS= cap_sysctl.c From 6430a5fde0861bfda88e5049213a668ea087c937 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Mon, 24 Oct 2016 14:56:13 +0000 Subject: [PATCH 062/235] Move the LLVM-based libgcc_s to /lib When enabled, it should install in the same location as the existing library. Reported by: antoine --- lib/libgcc_s/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libgcc_s/Makefile b/lib/libgcc_s/Makefile index 92fb8c3fb22d..6c57741e4d0a 100644 --- a/lib/libgcc_s/Makefile +++ b/lib/libgcc_s/Makefile @@ -2,6 +2,7 @@ PKG= clibs SHLIB_NAME= libgcc_s.so.1 +SHLIBDIR?= /lib WARNS?= 2 From 1d1140af580219d33a04ec84536caa6ef3e3d264 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Mon, 24 Oct 2016 16:28:54 +0000 Subject: [PATCH 063/235] loader should boot pre-feature flags pools. The feature flags chek is missing the corner case where we have valid pool version, but feature flags are not enabled - as for example plain v28 pool. This update does fix the boot support for such pools. Reviewed by: avg, allanjude Approved by: allanjude (mentor) Differential Revision: https://reviews.freebsd.org/D8331 --- sys/boot/zfs/zfsimpl.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index 85aeb765172b..c9f8bbf43314 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -2122,8 +2122,13 @@ check_mos_features(const spa_t *spa) &dir)) != 0) return (rc); if ((rc = zap_lookup(spa, &dir, DMU_POOL_FEATURES_FOR_READ, - sizeof (objnum), 1, &objnum)) != 0) - return (rc); + sizeof (objnum), 1, &objnum)) != 0) { + /* + * It is older pool without features. As we have already + * tested the label, just return without raising the error. + */ + return (0); + } if ((rc = objset_get_dnode(spa, &spa->spa_mos, objnum, &dir)) != 0) return (rc); From 835c2787bed752ffeeaeceae9f01839db0f18dff Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 24 Oct 2016 16:40:27 +0000 Subject: [PATCH 064/235] Handle broadcast NMIs. On several Intel chipsets, diagnostic NMIs sent from BMC or NMIs reporting hardware errors are broadcasted to all CPUs. When kernel is configured to enter kdb on NMI, the outcome is problematic, because each CPU tries to enter kdb. All CPUs are executing NMI handlers, which set the latches disabling the nested NMI delivery; this means that stop_cpus_hard(), used by kdb_enter() to stop other cpus by broadcasting IPI_STOP_HARD NMI, cannot work. One indication of this is the harmless but annoying diagnostic "timeout stopping cpus". Much more harming behaviour is that because all CPUs try to enter kdb, and if ddb is used as debugger, all CPUs issue prompt on console and race for the input, not to mention the simultaneous use of the ddb shared state. Try to fix this by introducing a pseudo-lock for simultaneous attempts to handle NMIs. If one core happens to enter NMI trap handler, other cores see it and simulate reception of the IPI_STOP_HARD. More, generic_stop_cpus() avoids sending IPI_STOP_HARD and avoids waiting for the acknowledgement, relying on the nmi handler on other cores suspending and then restarting the CPU. Since it is impossible to detect at runtime whether some stray NMI is broadcast or unicast, add a knob for administrator (really developer) to configure debugging NMI handling mode. The updated patch was debugged with the help from Andrey Gapon (avg) and discussed with him. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D8249 --- sys/amd64/amd64/trap.c | 37 +++------------------------ sys/i386/i386/trap.c | 32 +++-------------------- sys/kern/subr_smp.c | 53 +++++++++++++++++++++++++-------------- sys/x86/include/x86_smp.h | 3 +++ sys/x86/include/x86_var.h | 5 ++++ sys/x86/x86/cpu_machdep.c | 50 ++++++++++++++++++++++++++++++++++++ sys/x86/x86/mp_x86.c | 37 +++++++++++++++++++++++++++ 7 files changed, 135 insertions(+), 82 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 8d2b3990f019..85cab5fae324 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -144,11 +144,6 @@ static char *trap_msg[] = { "DTrace pid return trap", /* 32 T_DTRACE_RET */ }; -#ifdef KDB -static int kdb_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN, - &kdb_on_nmi, 0, "Go to KDB on NMI"); -#endif static int panic_on_nmi = 1; SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN, &panic_on_nmi, 0, "Panic on NMI"); @@ -377,21 +372,7 @@ trap(struct trapframe *frame) #ifdef DEV_ISA case T_NMI: - /* machine/parity/power fail/"kitchen sink" faults */ - if (isa_nmi(frame->tf_err) == 0) { -#ifdef KDB - /* - * NMI can be hooked up to a pushbutton - * for debugging. - */ - if (kdb_on_nmi) { - printf ("NMI ... going to debugger\n"); - kdb_trap(type, 0, frame); - } -#endif /* KDB */ - goto userout; - } else if (panic_on_nmi) - panic("NMI indicates hardware failure"); + nmi_handle_intr(type, frame, true); break; #endif /* DEV_ISA */ @@ -563,20 +544,8 @@ trap(struct trapframe *frame) #ifdef DEV_ISA case T_NMI: - /* machine/parity/power fail/"kitchen sink" faults */ - if (isa_nmi(frame->tf_err) == 0) { -#ifdef KDB - /* - * NMI can be hooked up to a pushbutton - * for debugging. - */ - if (kdb_on_nmi) { - printf ("NMI ... going to debugger\n"); - kdb_trap(type, 0, frame); - } -#endif /* KDB */ - goto out; - } else if (panic_on_nmi == 0) + if (nmi_handle_intr(type, frame, false) || + !panic_on_nmi) goto out; /* FALLTHROUGH */ #endif /* DEV_ISA */ diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 3decfd43be24..ff59be0accd1 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -467,21 +467,7 @@ trap(struct trapframe *frame) } goto userout; #else /* !POWERFAIL_NMI */ - /* machine/parity/power fail/"kitchen sink" faults */ - if (isa_nmi(frame->tf_err) == 0) { -#ifdef KDB - /* - * NMI can be hooked up to a pushbutton - * for debugging. - */ - if (kdb_on_nmi) { - printf ("NMI ... going to debugger\n"); - kdb_trap(type, 0, frame); - } -#endif /* KDB */ - goto userout; - } else if (panic_on_nmi) - panic("NMI indicates hardware failure"); + nmi_handle_intr(type, frame, true); break; #endif /* POWERFAIL_NMI */ #endif /* DEV_ISA */ @@ -730,20 +716,8 @@ trap(struct trapframe *frame) } goto out; #else /* !POWERFAIL_NMI */ - /* machine/parity/power fail/"kitchen sink" faults */ - if (isa_nmi(frame->tf_err) == 0) { -#ifdef KDB - /* - * NMI can be hooked up to a pushbutton - * for debugging. - */ - if (kdb_on_nmi) { - printf ("NMI ... going to debugger\n"); - kdb_trap(type, 0, frame); - } -#endif /* KDB */ - goto out; - } else if (panic_on_nmi == 0) + if (nmi_handle_intr(type, frame, false) || + !panic_on_nmi) goto out; /* FALLTHROUGH */ #endif /* POWERFAIL_NMI */ diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c index d98b1b7212ea..0ab5a9afc743 100644 --- a/sys/kern/subr_smp.c +++ b/sys/kern/subr_smp.c @@ -209,6 +209,11 @@ forward_signal(struct thread *td) * 1: ok * */ +#if defined(__amd64__) || defined(__i386__) +#define X86 1 +#else +#define X86 0 +#endif static int generic_stop_cpus(cpuset_t map, u_int type) { @@ -220,12 +225,11 @@ generic_stop_cpus(cpuset_t map, u_int type) volatile cpuset_t *cpus; KASSERT( -#if defined(__amd64__) || defined(__i386__) - type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND, -#else - type == IPI_STOP || type == IPI_STOP_HARD, + type == IPI_STOP || type == IPI_STOP_HARD +#if X86 + || type == IPI_SUSPEND #endif - ("%s: invalid stop type", __func__)); + , ("%s: invalid stop type", __func__)); if (!smp_started) return (0); @@ -233,7 +237,7 @@ generic_stop_cpus(cpuset_t map, u_int type) CTR2(KTR_SMP, "stop_cpus(%s) with %u type", cpusetobj_strprint(cpusetbuf, &map), type); -#if defined(__amd64__) || defined(__i386__) +#if X86 /* * When suspending, ensure there are are no IPIs in progress. * IPIs that have been issued, but not yet delivered (e.g. @@ -245,6 +249,9 @@ generic_stop_cpus(cpuset_t map, u_int type) mtx_lock_spin(&smp_ipi_mtx); #endif +#if X86 + if (!nmi_is_broadcast || nmi_kdb_lock == 0) { +#endif if (stopping_cpu != PCPU_GET(cpuid)) while (atomic_cmpset_int(&stopping_cpu, NOCPU, PCPU_GET(cpuid)) == 0) @@ -253,8 +260,11 @@ generic_stop_cpus(cpuset_t map, u_int type) /* send the stop IPI to all CPUs in map */ ipi_selected(map, type); +#if X86 + } +#endif -#if defined(__amd64__) || defined(__i386__) +#if X86 if (type == IPI_SUSPEND) cpus = &suspended_cpus; else @@ -272,7 +282,7 @@ generic_stop_cpus(cpuset_t map, u_int type) } } -#if defined(__amd64__) || defined(__i386__) +#if X86 if (type == IPI_SUSPEND) mtx_unlock_spin(&smp_ipi_mtx); #endif @@ -295,7 +305,7 @@ stop_cpus_hard(cpuset_t map) return (generic_stop_cpus(map, IPI_STOP_HARD)); } -#if defined(__amd64__) || defined(__i386__) +#if X86 int suspend_cpus(cpuset_t map) { @@ -325,20 +335,18 @@ generic_restart_cpus(cpuset_t map, u_int type) #endif volatile cpuset_t *cpus; - KASSERT( -#if defined(__amd64__) || defined(__i386__) - type == IPI_STOP || type == IPI_STOP_HARD || type == IPI_SUSPEND, -#else - type == IPI_STOP || type == IPI_STOP_HARD, + KASSERT(type == IPI_STOP || type == IPI_STOP_HARD +#if X86 + || type == IPI_SUSPEND #endif - ("%s: invalid stop type", __func__)); + , ("%s: invalid stop type", __func__)); if (!smp_started) - return 0; + return (0); CTR1(KTR_SMP, "restart_cpus(%s)", cpusetobj_strprint(cpusetbuf, &map)); -#if defined(__amd64__) || defined(__i386__) +#if X86 if (type == IPI_SUSPEND) cpus = &suspended_cpus; else @@ -348,11 +356,17 @@ generic_restart_cpus(cpuset_t map, u_int type) /* signal other cpus to restart */ CPU_COPY_STORE_REL(&map, &started_cpus); +#if X86 + if (!nmi_is_broadcast || nmi_kdb_lock == 0) { +#endif /* wait for each to clear its bit */ while (CPU_OVERLAP(cpus, &map)) cpu_spinwait(); +#if X86 + } +#endif - return 1; + return (1); } int @@ -362,7 +376,7 @@ restart_cpus(cpuset_t map) return (generic_restart_cpus(map, IPI_STOP)); } -#if defined(__amd64__) || defined(__i386__) +#if X86 int resume_cpus(cpuset_t map) { @@ -370,6 +384,7 @@ resume_cpus(cpuset_t map) return (generic_restart_cpus(map, IPI_SUSPEND)); } #endif +#undef X86 /* * All-CPU rendezvous. CPUs are signalled, all execute the setup function diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h index 7c906dd6ad08..84a0eba25bc7 100644 --- a/sys/x86/include/x86_smp.h +++ b/sys/x86/include/x86_smp.h @@ -45,6 +45,9 @@ extern u_int ipi_page; extern u_int ipi_range; extern u_int ipi_range_size; +extern int nmi_kdb_lock; +extern int nmi_is_broadcast; + struct cpu_info { int cpu_present:1; int cpu_bsp:1; diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h index d04ab9b8a5fa..1ea2f36f1616 100644 --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -85,6 +85,7 @@ struct reg; struct fpreg; struct dbreg; struct dumperinfo; +struct trapframe; /* * The interface type of the interrupt handler entry point cannot be @@ -107,6 +108,10 @@ bool fix_cpuid(void); void fillw(int /*u_short*/ pat, void *base, size_t cnt); int is_physical_memory(vm_paddr_t addr); int isa_nmi(int cd); +bool nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame, + bool panic); +bool nmi_call_kdb_smp(u_int type, struct trapframe *frame, bool panic); +int nmi_handle_intr(u_int type, struct trapframe *frame, bool panic); void pagecopy(void *from, void *to); void printcpuinfo(void); int user_dbreg_trap(void); diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c index 551a514e1f4e..bd3cf967112a 100644 --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include "opt_ddb.h" #include "opt_inet.h" #include "opt_isa.h" +#include "opt_kdb.h" #include "opt_kstack_pages.h" #include "opt_maxmem.h" #include "opt_mp_watchdog.h" @@ -522,3 +523,52 @@ idle_sysctl(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0, idle_sysctl, "A", "currently selected idle function"); + +int nmi_is_broadcast = 1; +SYSCTL_INT(_machdep, OID_AUTO, nmi_is_broadcast, CTLFLAG_RWTUN, + &nmi_is_broadcast, 0, + "Chipset NMI is broadcast"); +#ifdef KDB +int kdb_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN, + &kdb_on_nmi, 0, + "Go to KDB on NMI"); +#endif + +#ifdef DEV_ISA +bool +nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame, bool do_panic) +{ + + /* machine/parity/power fail/"kitchen sink" faults */ + if (isa_nmi(frame->tf_err) == 0) { +#ifdef KDB + /* + * NMI can be hooked up to a pushbutton for debugging. + */ + if (kdb_on_nmi) { + printf ("NMI/cpu%d ... going to debugger\n", cpu); + kdb_trap(type, 0, frame); + return (true); + } + } else +#endif /* KDB */ + if (do_panic) + panic("NMI indicates hardware failure"); + return (false); +} +#endif + +int +nmi_handle_intr(u_int type, struct trapframe *frame, bool panic) +{ + +#ifdef DEV_ISA +#ifdef SMP + if (nmi_is_broadcast) + return (nmi_call_kdb_smp(type, frame, panic)); + else +#endif + return (nmi_call_kdb(0, type, frame, panic)); +#endif +} diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c index 19071f60061b..44a6acf869f0 100644 --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_apic.h" #endif #include "opt_cpu.h" +#include "opt_isa.h" #include "opt_kstack_pages.h" #include "opt_pmap.h" #include "opt_sched.h" @@ -140,6 +141,7 @@ int cpu_apic_ids[MAXCPU]; volatile u_int cpu_ipi_pending[MAXCPU]; static void release_aps(void *dummy); +static void cpustop_handler_post(u_int cpu); static int hyperthreading_allowed = 1; SYSCTL_INT(_machdep, OID_AUTO, hyperthreading_allowed, CTLFLAG_RDTUN, @@ -1211,6 +1213,34 @@ ipi_nmi_handler(void) return (0); } +#ifdef DEV_ISA +int nmi_kdb_lock; + +bool +nmi_call_kdb_smp(u_int type, struct trapframe *frame, bool do_panic) +{ + int cpu; + bool call_post, ret; + + cpu = PCPU_GET(cpuid); + if (atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) { + ret = nmi_call_kdb(cpu, type, frame, do_panic); + call_post = false; + } else { + ret = true; + savectx(&stoppcbs[cpu]); + CPU_SET_ATOMIC(cpu, &stopped_cpus); + while (!atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) + ia32_pause(); + call_post = true; + } + atomic_store_rel_int(&nmi_kdb_lock, 0); + if (call_post) + cpustop_handler_post(cpu); + return (ret); +} +#endif + /* * Handle an IPI_STOP by saving our current context and spinning until we * are resumed. @@ -1231,6 +1261,13 @@ cpustop_handler(void) while (!CPU_ISSET(cpu, &started_cpus)) ia32_pause(); + cpustop_handler_post(cpu); +} + +static void +cpustop_handler_post(u_int cpu) +{ + CPU_CLR_ATOMIC(cpu, &started_cpus); CPU_CLR_ATOMIC(cpu, &stopped_cpus); From a57d70325e922cc3f5a0684295ace4309a0732bf Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 24 Oct 2016 17:37:21 +0000 Subject: [PATCH 065/235] Fix typo. Submitted by: alc MFC after: 3 days --- sys/x86/x86/mp_x86.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c index 44a6acf869f0..16dd3392d462 100644 --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -1351,7 +1351,7 @@ invlcache_handler(void) * Reading the generation here allows greater parallelism * since wbinvd is a serializing instruction. Without the * temporary, we'd wait for wbinvd to complete, then the read - * would execute, then the dependent write, whuch must then + * would execute, then the dependent write, which must then * complete before return from interrupt. */ generation = smp_tlb_generation; From b0928c0dbb1cd67b61defa4af494db44c52d9ca0 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 24 Oct 2016 17:56:08 +0000 Subject: [PATCH 066/235] When compiling on macOS or Linux, __dead can be defined already. Conditionally define __dead. --- lib/libnetbsd/sys/cdefs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/libnetbsd/sys/cdefs.h b/lib/libnetbsd/sys/cdefs.h index 051959f53132..46372f368afd 100644 --- a/lib/libnetbsd/sys/cdefs.h +++ b/lib/libnetbsd/sys/cdefs.h @@ -35,11 +35,13 @@ #include_next +#ifndef __dead #ifdef __dead2 #define __dead __dead2 #else #define __dead #endif +#endif /* !__dead */ /* * The __CONCAT macro is used to concatenate parts of symbol names, e.g. From 871afaefab95343d61a163b185824d9e9dd60088 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 24 Oct 2016 17:57:46 +0000 Subject: [PATCH 067/235] Include "util.h", not . The header is in the same directory as the C file. There may be a on the host when compiling on macOS or Linux, causing conflicts. --- lib/libnetbsd/util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/libnetbsd/util.c b/lib/libnetbsd/util.c index 36b9421efc39..4f922dc2c41d 100644 --- a/lib/libnetbsd/util.c +++ b/lib/libnetbsd/util.c @@ -36,7 +36,8 @@ #include #include #include -#include + +#include "util.h" char * flags_to_string(u_long flags, const char *def) From 5b424cba0ac5a4716d4182aabfd4fb1c1b9707a1 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 24 Oct 2016 17:59:25 +0000 Subject: [PATCH 068/235] Detect clang on macOS. The version string is slightly different. --- share/mk/bsd.compiler.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/mk/bsd.compiler.mk b/share/mk/bsd.compiler.mk index 38c4f5f24600..954ba5e572e2 100644 --- a/share/mk/bsd.compiler.mk +++ b/share/mk/bsd.compiler.mk @@ -147,7 +147,7 @@ ${X_}COMPILER_TYPE:= clang ${X_}COMPILER_TYPE:= gcc . elif ${_v:M\(GCC\)} ${X_}COMPILER_TYPE:= gcc -. elif ${_v:Mclang} +. elif ${_v:Mclang} || ${_v:M(clang-*.*.*)} ${X_}COMPILER_TYPE:= clang . else .error Unable to determine compiler type for ${cc}=${${cc}}. Consider setting ${X_}COMPILER_TYPE. From 07f862a76947ec6d3c9941fe7815b6c81e8cd03a Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 24 Oct 2016 18:03:04 +0000 Subject: [PATCH 069/235] Include instead of when compiled as part of libsbuf. The former is the standard header, and allows us to compile libsbuf on macOS/linux. --- sys/kern/subr_prf.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index 5886438fc48c..e78863830c7b 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -72,7 +72,11 @@ __FBSDID("$FreeBSD$"); * Note that stdarg.h and the ANSI style va_start macro is used for both * ANSI and traditional C compilers. */ +#ifdef _KERNEL #include +#else +#include +#endif #ifdef _KERNEL From d67ec19c3ec022f4bfcb084f299eb99025906c33 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 24 Oct 2016 18:12:57 +0000 Subject: [PATCH 070/235] Include explicitly instead of depending on that header being included by . When compiled as part of makefs(8) and on macOS or Linux, is not our own. --- sys/ufs/ffs/ffs_tables.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/ufs/ffs/ffs_tables.c b/sys/ufs/ffs/ffs_tables.c index 848d47805c31..c124893eb344 100644 --- a/sys/ufs/ffs/ffs_tables.c +++ b/sys/ufs/ffs/ffs_tables.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include From 77e9044c471abd1fe55d91fb5c6bd6a7960860c8 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Mon, 24 Oct 2016 19:09:56 +0000 Subject: [PATCH 071/235] cxgbe(4): Fix bug in the calculation of the number of physically contiguous regions in an mbuf chain. If the payload of an mbuf ends at a page boundary count_mbuf_nsegs would incorrectly consider the next mbuf's payload physically contiguous based solely on a KVA comparison. MFC after: 1 week Sponsored by: Chelsio Communications --- sys/dev/cxgbe/t4_sge.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/sys/dev/cxgbe/t4_sge.c b/sys/dev/cxgbe/t4_sge.c index 3748b2bc80f7..88c2e91bc7ae 100644 --- a/sys/dev/cxgbe/t4_sge.c +++ b/sys/dev/cxgbe/t4_sge.c @@ -2110,24 +2110,6 @@ m_advance(struct mbuf **pm, int *poffset, int len) return ((void *)p); } -static inline int -same_paddr(char *a, char *b) -{ - - if (a == b) - return (1); - else if (a != NULL && b != NULL) { - vm_offset_t x = (vm_offset_t)a; - vm_offset_t y = (vm_offset_t)b; - - if ((x & PAGE_MASK) == (y & PAGE_MASK) && - pmap_kextract(x) == pmap_kextract(y)) - return (1); - } - - return (0); -} - /* * Can deal with empty mbufs in the chain that have m_len = 0, but the chain * must have at least one mbuf that's not empty. @@ -2135,24 +2117,25 @@ same_paddr(char *a, char *b) static inline int count_mbuf_nsegs(struct mbuf *m) { - char *prev_end, *start; + vm_paddr_t lastb, next; + vm_offset_t va; int len, nsegs; MPASS(m != NULL); nsegs = 0; - prev_end = NULL; + lastb = 0; for (; m; m = m->m_next) { len = m->m_len; if (__predict_false(len == 0)) continue; - start = mtod(m, char *); - - nsegs += sglist_count(start, len); - if (same_paddr(prev_end, start)) + va = mtod(m, vm_offset_t); + next = pmap_kextract(va); + nsegs += sglist_count(m->m_data, len); + if (lastb + 1 == next) nsegs--; - prev_end = start + len; + lastb = pmap_kextract(va + len - 1); } MPASS(nsegs > 0); From cd2b868b5defeef34623aed5ab03165dd85f9b39 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Mon, 24 Oct 2016 20:33:42 +0000 Subject: [PATCH 072/235] allwinner: Add support for P2WI in RSB driver Push-Pull Two Wire interface is a almost compatible iic like bus used in sun6i SoC. It's only use is to communicate with the power management IC. Reviewed by: jmcneill MFC after: 1 week Relnotes: yes --- sys/arm/allwinner/aw_rsb.c | 105 ++++++++++++++++++------------ sys/arm/allwinner/files.allwinner | 2 +- sys/arm/conf/GENERIC | 3 +- 3 files changed, 65 insertions(+), 45 deletions(-) diff --git a/sys/arm/allwinner/aw_rsb.c b/sys/arm/allwinner/aw_rsb.c index 073479420a26..9ea9294ba9c1 100644 --- a/sys/arm/allwinner/aw_rsb.c +++ b/sys/arm/allwinner/aw_rsb.c @@ -27,7 +27,7 @@ */ /* - * Allwinner RSB (Reduced Serial Bus) + * Allwinner RSB (Reduced Serial Bus) and P2WI (Push-Pull Two Wire Interface) */ #include @@ -92,8 +92,12 @@ __FBSDID("$FreeBSD$"); #define RSB_ADDR_PMIC_SECONDARY 0x745 #define RSB_ADDR_PERIPH_IC 0xe89 +#define A31_P2WI 1 +#define A23_RSB 2 + static struct ofw_compat_data compat_data[] = { - { "allwinner,sun8i-a23-rsb", 1 }, + { "allwinner,sun6i-a31-p2wi", A31_P2WI }, + { "allwinner,sun8i-a23-rsb", A23_RSB }, { NULL, 0 } }; @@ -131,6 +135,7 @@ struct rsb_softc { int busy; uint32_t status; uint16_t cur_addr; + int type; struct iic_msg *msg; }; @@ -270,8 +275,8 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) sc = device_get_softc(dev); /* - * RSB is not really an I2C or SMBus controller, so there are some - * restrictions imposed by the driver. + * P2WI and RSB are not really I2C or SMBus controllers, so there are + * some restrictions imposed by the driver. * * Transfers must contain exactly two messages. The first is always * a write, containing a single data byte offset. Data will either @@ -284,34 +289,36 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) msgs[0].len != 1 || msgs[1].len > RSB_MAXLEN) return (EINVAL); - /* The controller can read or write 1, 2, or 4 bytes at a time. */ - if ((msgs[1].flags & IIC_M_RD) != 0) { - switch (msgs[1].len) { - case 1: - cmd = CMD_RD8; - break; - case 2: - cmd = CMD_RD16; - break; - case 4: - cmd = CMD_RD32; - break; - default: - return (EINVAL); - } - } else { - switch (msgs[1].len) { - case 1: - cmd = CMD_WR8; - break; - case 2: - cmd = CMD_WR16; - break; - case 4: - cmd = CMD_WR32; - break; - default: - return (EINVAL); + /* The RSB controller can read or write 1, 2, or 4 bytes at a time. */ + if (sc->type == A23_RSB) { + if ((msgs[1].flags & IIC_M_RD) != 0) { + switch (msgs[1].len) { + case 1: + cmd = CMD_RD8; + break; + case 2: + cmd = CMD_RD16; + break; + case 4: + cmd = CMD_RD32; + break; + default: + return (EINVAL); + } + } else { + switch (msgs[1].len) { + case 1: + cmd = CMD_WR8; + break; + case 2: + cmd = CMD_WR16; + break; + case 4: + cmd = CMD_WR32; + break; + default: + return (EINVAL); + } } } @@ -322,13 +329,15 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) sc->status = 0; /* Select current run-time address if necessary */ - device_addr = msgs[0].slave >> 1; - if (sc->cur_addr != device_addr) { - error = rsb_set_rta(dev, device_addr); - if (error != 0) - goto done; - sc->cur_addr = device_addr; - sc->status = 0; + if (sc->type == A23_RSB) { + device_addr = msgs[0].slave >> 1; + if (sc->cur_addr != device_addr) { + error = rsb_set_rta(dev, device_addr); + if (error != 0) + goto done; + sc->cur_addr = device_addr; + sc->status = 0; + } } /* Clear interrupt status */ @@ -344,8 +353,9 @@ rsb_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) RSB_WRITE(sc, RSB_DATA0, data[0]); } - /* Set command type */ - RSB_WRITE(sc, RSB_CMD, cmd); + /* Set command type for RSB */ + if (sc->type == A23_RSB) + RSB_WRITE(sc, RSB_CMD, cmd); /* Program data length register and transfer direction */ dlen = msgs[0].len - 1; @@ -379,10 +389,17 @@ rsb_probe(device_t dev) if (!ofw_bus_status_okay(dev)) return (ENXIO); - if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { + case A23_RSB: + device_set_desc(dev, "Allwinner RSB"); + break; + case A31_P2WI: + device_set_desc(dev, "Allwinner P2WI"); + break; + default: return (ENXIO); + } - device_set_desc(dev, "Allwinner RSB"); return (BUS_PROBE_DEFAULT); } @@ -395,6 +412,8 @@ rsb_attach(device_t dev) sc = device_get_softc(dev); mtx_init(&sc->mtx, device_get_nameunit(dev), "rsb", MTX_DEF); + sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; + if (clk_get_by_ofw_index(dev, 0, 0, &sc->clk) == 0) { error = clk_enable(sc->clk); if (error != 0) { diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index d06f6aebbe8f..4e04902268be 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -12,7 +12,7 @@ arm/allwinner/a10_mmc.c optional mmc arm/allwinner/a10_sramc.c standard arm/allwinner/aw_nmi.c optional intrng arm/allwinner/aw_if_dwc.c optional dwc -arm/allwinner/aw_rsb.c optional rsb +arm/allwinner/aw_rsb.c optional rsb | p2wi arm/allwinner/aw_rtc.c standard arm/allwinner/aw_ts.c standard arm/allwinner/aw_wdog.c standard diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 148d20746898..d8fa9dd41e71 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -106,7 +106,8 @@ device psci device iicbus device iic device twsi -device rsb +device rsb # Allwinner Reduced Serial Bus +device p2wi # Allwinner Push-Pull Two Wire device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc From b6110871b5d91aa9c1805d9384e66d0950bc747e Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 24 Oct 2016 20:36:54 +0000 Subject: [PATCH 073/235] Preliminary support for EFI in boot loader. Define efi-boot forth environment variable to allow conditional compilation based on EFI being present or not. Provide efi-setenv, efi-getenv, and efi-unsetenv, though those need improvement. Move the efi definition to libefi (but include a reference so they get included). --- sys/boot/efi/libefi/Makefile | 1 + sys/boot/efi/libefi/env.c | 179 ++++++++++++++++++++++++++++++ sys/boot/efi/loader/main.c | 8 +- sys/boot/ficl/efi.c | 207 ----------------------------------- sys/boot/ficl/loader.c | 3 +- sys/boot/forth/Makefile.inc | 1 + sys/boot/forth/efi.4th | 30 +++++ sys/boot/forth/loader.4th | 3 + 8 files changed, 221 insertions(+), 211 deletions(-) delete mode 100644 sys/boot/ficl/efi.c create mode 100644 sys/boot/forth/efi.4th diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile index 9ea2c3333366..5fda2eaf0c87 100644 --- a/sys/boot/efi/libefi/Makefile +++ b/sys/boot/efi/libefi/Makefile @@ -26,6 +26,7 @@ CFLAGS+= -msoft-float -mgeneral-regs-only .if ${MACHINE_ARCH} == "amd64" CFLAGS+= -fPIC -mno-red-zone .endif +CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE} CFLAGS+= -I${.CURDIR}/../include CFLAGS+= -I${.CURDIR}/../include/${MACHINE} CFLAGS+= -I${.CURDIR}/../../../../lib/libstand diff --git a/sys/boot/efi/libefi/env.c b/sys/boot/efi/libefi/env.c index 6cfe491cd1b7..a26eb725fd03 100644 --- a/sys/boot/efi/libefi/env.c +++ b/sys/boot/efi/libefi/env.c @@ -26,8 +26,15 @@ #include __FBSDID("$FreeBSD$"); +#include +#include #include #include +#include +#include "bootstrap.h" +#include "ficl.h" + +int efi_variable_support = 1; /* * Simple wrappers to the underlying UEFI functions. @@ -53,3 +60,175 @@ efi_set_variable(CHAR16 *variable_name, EFI_GUID *vendor_guid, UINT32 attributes { return RS->SetVariable(variable_name, vendor_guid, attributes, data_size, data); } + +/* + * FreeBSD's loader interaction words and extras + * + * efi-setenv ( value n name n guid n attr -- 0 | -1) + * efi-getenv ( guid n addr n -- addr' n' | -1 ) + * efi-unsetenv ( name n guid n'' -- ) + */ + +/* + * efi-setenv + * efi-setenv ( value n name n guid n attr -- 0 | -1) + * + * Set environment variables using the SetVariable EFI runtime service. + * + * Value and guid are passed through in binary form (so guid needs to be + * converted to binary form from its string form). Name is converted from + * ASCII to CHAR16. Since ficl doesn't have support for internationalization, + * there's no native CHAR16 interface provided. + * + * attr is an int in the bitmask of the following attributes for this variable. + * + * 1 Non volatile + * 2 Boot service access + * 4 Run time access + * (corresponding to the same bits in the UEFI spec). + */ +void +ficlEfiSetenv(FICL_VM *pVM) +{ +#ifndef TESTMAIN + char *value = NULL, *guid = NULL; + CHAR16 *name = NULL; + int i; +#endif + char *namep, *valuep, *guidp; + int names, values, guids, attr; + int status; + uuid_t u; + uint32_t ustatus; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 6, 0); +#endif + attr = stackPopINT(pVM->pStack); + guids = stackPopINT(pVM->pStack); + guidp = (char*)stackPopPtr(pVM->pStack); + names = stackPopINT(pVM->pStack); + namep = (char*)stackPopPtr(pVM->pStack); + values = stackPopINT(pVM->pStack); + valuep = (char*)stackPopPtr(pVM->pStack); + +#ifndef TESTMAIN + guid = (char*)ficlMalloc(guids); + if (guid != NULL) + vmThrowErr(pVM, "Error: out of memory"); + memcpy(guid, guidp, guids); + uuid_from_string(guid, &u, &ustatus); + if (ustatus != uuid_s_ok) { + stackPushINT(pVM->pStack, -1); + goto out; + } + + name = (CHAR16 *)ficlMalloc((names + 1) * sizeof(CHAR16)); + if (name == NULL) + vmThrowErr(pVM, "Error: out of memory"); + for (i = 0; i < names; i++) + name[i] = namep[i]; + name[names] = (CHAR16)0; + + value = (char*)ficlMalloc(values + 1); + if (value != NULL) + vmThrowErr(pVM, "Error: out of memory"); + memcpy(value, valuep, values); + + status = efi_set_variable(name, (EFI_GUID *)&u, attr, values, value); + if (status == EFI_SUCCESS) + stackPushINT(pVM->pStack, 0); + else + stackPushINT(pVM->pStack, -1); +out: + ficlFree(name); + ficlFree(value); + ficlFree(guid); +#endif + + return; +} + +void +ficlEfiGetenv(FICL_VM *pVM) +{ +#ifndef TESTMAIN + char *name, *value; +#endif + char *namep; + int names; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 2, 2); +#endif + names = stackPopINT(pVM->pStack); + namep = (char*) stackPopPtr(pVM->pStack); + +#ifndef TESTMAIN + name = (char*) ficlMalloc(names+1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + strncpy(name, namep, names); + name[names] = '\0'; + + value = getenv(name); + ficlFree(name); + + if(value != NULL) { + stackPushPtr(pVM->pStack, value); + stackPushINT(pVM->pStack, strlen(value)); + } else +#endif + stackPushINT(pVM->pStack, -1); + + return; +} + +void +ficlEfiUnsetenv(FICL_VM *pVM) +{ +#ifndef TESTMAIN + char *name; +#endif + char *namep; + int names; + +#if FICL_ROBUST > 1 + vmCheckStack(pVM, 2, 0); +#endif + names = stackPopINT(pVM->pStack); + namep = (char*) stackPopPtr(pVM->pStack); + +#ifndef TESTMAIN + name = (char*) ficlMalloc(names+1); + if (!name) + vmThrowErr(pVM, "Error: out of memory"); + strncpy(name, namep, names); + name[names] = '\0'; + + unsetenv(name); + ficlFree(name); +#endif + + return; +} + +/************************************************************************** +** Add FreeBSD UEFI platform extensions into the system dictionary +**************************************************************************/ +void ficlEfiCompilePlatform(FICL_SYSTEM *pSys) +{ + FICL_DICT *dp = pSys->dp; + assert (dp); + + dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT); + dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT); + dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT); + + /* Would like to export the EFI version, but this will do for now */ + ficlSetEnv(pSys, "efi-boot", 1); + + return; +} + +FICL_COMPILE_SET(ficlEfiCompilePlatform); diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index b5f2fd6bcca1..e1d0b64f95d6 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -55,6 +55,10 @@ extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; +/* Force a reference to bring in EFI support from the library */ +extern int efi_variable_support; +int *dummy1 = &efi_variable_support; + struct arch_switch archsw; /* MI/MD interface boundary */ EFI_GUID acpi = ACPI_TABLE_GUID; @@ -906,8 +910,8 @@ command_efi_show(int argc, char *argv[]) return (rv); } - if (argc != 0) { - printf("Too many args\n"); + if (argc > 0) { + printf("Too many args %d\n", argc); pager_close(); return (CMD_ERROR); } diff --git a/sys/boot/ficl/efi.c b/sys/boot/ficl/efi.c deleted file mode 100644 index 8a08f7059977..000000000000 --- a/sys/boot/ficl/efi.c +++ /dev/null @@ -1,207 +0,0 @@ -/*- - * Copyright (c) 2014 Netflix, Inc - * 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$ - */ - -/******************************************************************* -** e f i . c -** Additional words for EFI -** -*******************************************************************/ - -#ifdef TESTMAIN -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif -#include "bootstrap.h" -#include -#include "ficl.h" - -/* - * FreeBSD's loader interaction words and extras - * - * efi-setenv ( value n name n guid n attr -- 0 | -1) - * efi-getenv ( guid n addr n -- addr' n' | -1 ) - * efi-unsetenv ( name n guid n'' -- ) - */ - -/* - * efi-setenv - * efi-setenv ( value n name n guid n attr -- 0 | -1) - * - * Set environment variables using the SetVariable EFI runtime service. - * - * Value and guid are passed through in binary form (so guid needs to be - * converted to binary form from its string form). Name is converted from - * ASCII to CHAR16. Since ficl doesn't have support for internationalization, - * there's no native CHAR16 interface provided. - * - * attr is an int in the bitmask of the following attributes for this variable. - * - * 1 Non volatile - * 2 Boot service access - * 4 Run time access - * (corresponding to the same bits in the UEFI spec). - */ -void -ficlEfiSetenv(FICL_VM *pVM) -{ -#ifndef TESTMAIN - char *value, *guid; - CHAR16 *name - int i; -#endif - char *namep, *valuep, *guidp; - int names, values, guids, attr; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 6, 0); -#endif - attr = stackPopINT(pVM->pStack); - guids = stackPopINT(pVM->pStack); - guidp = (char*)stackPopPtr(pVM->pStack); - names = stackPopINT(pVM->pStack); - namep = (char*)stackPopPtr(pVM->pStack); - values = stackPopINT(pVM->pStack); - valuep = (char*)stackPopPtr(pVM->pStack); - -#ifndef TESTMAIN - guid = (char*)ficlMalloc(guids); - if (guid != NULL) - vmThrowErr(pVM, "Error: out of memory"); - memcpy(guid, guidp, guids); - - name = (char*)ficlMalloc((names + 1) * sizeof(CHAR16)); - if (name == NULL) - vmThrowErr(pVM, "Error: out of memory"); - for (i = 0; i < names; i++) - name[i] = namep[i]; - name[names] = (CHAR16)0; - - value = (char*)ficlMalloc(values + 1); - if (value != NULL) - vmThrowErr(pVM, "Error: out of memory"); - memcpy(value, valuep, values); - - status = efi_set_variable(name, guid, attr, value); - if (status == EFI_SUCCESS) - stackPushINT(pVM->pStack, 0); - else - stackPushINT(pVM->pStack, -1); - - ficlFree(name); - ficlFree(value); - ficlFree(guid); -#endif - - return; -} - -void -ficlEfiGetenv(FICL_VM *pVM) -{ -#ifndef TESTMAIN - char *name, *value; -#endif - char *namep; - int names; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 2, 2); -#endif - names = stackPopINT(pVM->pStack); - namep = (char*) stackPopPtr(pVM->pStack); - -#ifndef TESTMAIN - name = (char*) ficlMalloc(names+1); - if (!name) - vmThrowErr(pVM, "Error: out of memory"); - strncpy(name, namep, names); - name[names] = '\0'; - - value = getenv(name); - ficlFree(name); - - if(value != NULL) { - stackPushPtr(pVM->pStack, value); - stackPushINT(pVM->pStack, strlen(value)); - } else -#endif - stackPushINT(pVM->pStack, -1); - - return; -} - -void -ficlEfiUnsetenv(FICL_VM *pVM) -{ -#ifndef TESTMAIN - char *name; -#endif - char *namep; - int names; - -#if FICL_ROBUST > 1 - vmCheckStack(pVM, 2, 0); -#endif - names = stackPopINT(pVM->pStack); - namep = (char*) stackPopPtr(pVM->pStack); - -#ifndef TESTMAIN - name = (char*) ficlMalloc(names+1); - if (!name) - vmThrowErr(pVM, "Error: out of memory"); - strncpy(name, namep, names); - name[names] = '\0'; - - unsetenv(name); - ficlFree(name); -#endif - - return; -} -/************************************************************************** - -** Build FreeBSD platform extensions into the system dictionary -**************************************************************************/ -void ficlEfiCompilePlatform(FICL_SYSTEM *pSys) -{ - FICL_DICT *dp = pSys->dp; - assert (dp); - - dictAppendWord(dp, "efi-setenv", ficlEfiSetenv, FW_DEFAULT); - dictAppendWord(dp, "efi-getenv", ficlEfiGetenv, FW_DEFAULT); - dictAppendWord(dp, "efi-unsetenv", ficlEfiUnsetenv, FW_DEFAULT); - - return; -} diff --git a/sys/boot/ficl/loader.c b/sys/boot/ficl/loader.c index 197f15bf38c3..224619065790 100644 --- a/sys/boot/ficl/loader.c +++ b/sys/boot/ficl/loader.c @@ -824,9 +824,8 @@ void ficlCompilePlatform(FICL_SYSTEM *pSys) dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT); dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT); - SET_FOREACH(fnpp, Xficl_compile_set) { + SET_FOREACH(fnpp, Xficl_compile_set) (*fnpp)(pSys); - } #if defined(PC98) ficlSetEnv(pSys, "arch-pc98", FICL_TRUE); diff --git a/sys/boot/forth/Makefile.inc b/sys/boot/forth/Makefile.inc index 97ab433a1b28..d31ff3f26291 100644 --- a/sys/boot/forth/Makefile.inc +++ b/sys/boot/forth/Makefile.inc @@ -6,6 +6,7 @@ FILES+= brand-fbsd.4th FILES+= check-password.4th FILES+= color.4th FILES+= delay.4th +FILES+= efi.4th FILES+= frames.4th FILES+= loader.4th FILES+= loader.conf diff --git a/sys/boot/forth/efi.4th b/sys/boot/forth/efi.4th new file mode 100644 index 000000000000..7c1bdf30b8e1 --- /dev/null +++ b/sys/boot/forth/efi.4th @@ -0,0 +1,30 @@ +\ Copyright (c) 2016 Netflix, Inc +\ 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$ + +only forth definitions + +\ Place holder for more functions +.( EFI boot environment) cr diff --git a/sys/boot/forth/loader.4th b/sys/boot/forth/loader.4th index 6c2f7b378f6b..013a033b1fcd 100644 --- a/sys/boot/forth/loader.4th +++ b/sys/boot/forth/loader.4th @@ -46,6 +46,9 @@ include /boot/support.4th include /boot/color.4th include /boot/delay.4th include /boot/check-password.4th +s" efi-boot" environment? [if] [if] + include /boot/efi.4th +[then] [then] only forth definitions From 295f4b6cfec069476c648f929cb70e33eabee4d0 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 24 Oct 2016 20:47:46 +0000 Subject: [PATCH 074/235] Follow-up to r307866: - Make !KDB config buildable. - Simplify interface to nmi_handle_intr() by evaluating panic_on_nmi in one place, namely nmi_call_kdb(). This allows to remove do_panic argument from the functions, and to remove i386/amd64 duplication of the variable and sysctl definitions. Note that now NMI causes panic(9) instead of trap_fatal() reporting and then panic(9), consistently for NMIs delivered while CPU operated in ring 0 and 3. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/amd64/amd64/trap.c | 11 +++-------- sys/i386/i386/trap.c | 16 +++------------- sys/x86/include/x86_var.h | 7 +++---- sys/x86/x86/cpu_machdep.c | 27 +++++++++++++++------------ sys/x86/x86/mp_x86.c | 10 ++++------ 5 files changed, 28 insertions(+), 43 deletions(-) diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 85cab5fae324..024c1b34a6cc 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -144,9 +144,6 @@ static char *trap_msg[] = { "DTrace pid return trap", /* 32 T_DTRACE_RET */ }; -static int panic_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN, - &panic_on_nmi, 0, "Panic on NMI"); static int prot_fault_translation; SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RWTUN, &prot_fault_translation, 0, @@ -372,7 +369,7 @@ trap(struct trapframe *frame) #ifdef DEV_ISA case T_NMI: - nmi_handle_intr(type, frame, true); + nmi_handle_intr(type, frame); break; #endif /* DEV_ISA */ @@ -544,10 +541,8 @@ trap(struct trapframe *frame) #ifdef DEV_ISA case T_NMI: - if (nmi_handle_intr(type, frame, false) || - !panic_on_nmi) - goto out; - /* FALLTHROUGH */ + nmi_handle_intr(type, frame); + goto out; #endif /* DEV_ISA */ } diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index ff59be0accd1..3cf0c5a66589 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -158,14 +158,6 @@ static char *trap_msg[] = { int has_f00f_bug = 0; /* Initialized so that it can be patched. */ #endif -#ifdef KDB -static int kdb_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN, - &kdb_on_nmi, 0, "Go to KDB on NMI"); -#endif -static int panic_on_nmi = 1; -SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN, - &panic_on_nmi, 0, "Panic on NMI"); static int prot_fault_translation = 0; SYSCTL_INT(_machdep, OID_AUTO, prot_fault_translation, CTLFLAG_RW, &prot_fault_translation, 0, "Select signal to deliver on protection fault"); @@ -467,7 +459,7 @@ trap(struct trapframe *frame) } goto userout; #else /* !POWERFAIL_NMI */ - nmi_handle_intr(type, frame, true); + nmi_handle_intr(type, frame); break; #endif /* POWERFAIL_NMI */ #endif /* DEV_ISA */ @@ -716,10 +708,8 @@ trap(struct trapframe *frame) } goto out; #else /* !POWERFAIL_NMI */ - if (nmi_handle_intr(type, frame, false) || - !panic_on_nmi) - goto out; - /* FALLTHROUGH */ + nmi_handle_intr(type, frame); + goto out; #endif /* POWERFAIL_NMI */ #endif /* DEV_ISA */ } diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h index 1ea2f36f1616..12bc1e07d4c0 100644 --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -108,10 +108,9 @@ bool fix_cpuid(void); void fillw(int /*u_short*/ pat, void *base, size_t cnt); int is_physical_memory(vm_paddr_t addr); int isa_nmi(int cd); -bool nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame, - bool panic); -bool nmi_call_kdb_smp(u_int type, struct trapframe *frame, bool panic); -int nmi_handle_intr(u_int type, struct trapframe *frame, bool panic); +void nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame); +void nmi_call_kdb_smp(u_int type, struct trapframe *frame); +void nmi_handle_intr(u_int type, struct trapframe *frame); void pagecopy(void *from, void *to); void printcpuinfo(void); int user_dbreg_trap(void); diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c index bd3cf967112a..c1740ee8dfb3 100644 --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -524,6 +524,10 @@ idle_sysctl(SYSCTL_HANDLER_ARGS) SYSCTL_PROC(_machdep, OID_AUTO, idle, CTLTYPE_STRING | CTLFLAG_RW, 0, 0, idle_sysctl, "A", "currently selected idle function"); +static int panic_on_nmi = 1; +SYSCTL_INT(_machdep, OID_AUTO, panic_on_nmi, CTLFLAG_RWTUN, + &panic_on_nmi, 0, + "Panic on NMI"); int nmi_is_broadcast = 1; SYSCTL_INT(_machdep, OID_AUTO, nmi_is_broadcast, CTLFLAG_RWTUN, &nmi_is_broadcast, 0, @@ -536,8 +540,8 @@ SYSCTL_INT(_machdep, OID_AUTO, kdb_on_nmi, CTLFLAG_RWTUN, #endif #ifdef DEV_ISA -bool -nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame, bool do_panic) +void +nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame) { /* machine/parity/power fail/"kitchen sink" faults */ @@ -549,26 +553,25 @@ nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame, bool do_panic) if (kdb_on_nmi) { printf ("NMI/cpu%d ... going to debugger\n", cpu); kdb_trap(type, 0, frame); - return (true); } - } else #endif /* KDB */ - if (do_panic) + } else if (panic_on_nmi) { panic("NMI indicates hardware failure"); - return (false); + } } #endif -int -nmi_handle_intr(u_int type, struct trapframe *frame, bool panic) +void +nmi_handle_intr(u_int type, struct trapframe *frame) { #ifdef DEV_ISA #ifdef SMP - if (nmi_is_broadcast) - return (nmi_call_kdb_smp(type, frame, panic)); - else + if (nmi_is_broadcast) { + nmi_call_kdb_smp(type, frame); + return; + } #endif - return (nmi_call_kdb(0, type, frame, panic)); + nmi_call_kdb(0, type, frame); #endif } diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c index 16dd3392d462..56653ee74706 100644 --- a/sys/x86/x86/mp_x86.c +++ b/sys/x86/x86/mp_x86.c @@ -1216,18 +1216,17 @@ ipi_nmi_handler(void) #ifdef DEV_ISA int nmi_kdb_lock; -bool -nmi_call_kdb_smp(u_int type, struct trapframe *frame, bool do_panic) +void +nmi_call_kdb_smp(u_int type, struct trapframe *frame) { int cpu; - bool call_post, ret; + bool call_post; cpu = PCPU_GET(cpuid); if (atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) { - ret = nmi_call_kdb(cpu, type, frame, do_panic); + nmi_call_kdb(cpu, type, frame); call_post = false; } else { - ret = true; savectx(&stoppcbs[cpu]); CPU_SET_ATOMIC(cpu, &stopped_cpus); while (!atomic_cmpset_acq_int(&nmi_kdb_lock, 0, 1)) @@ -1237,7 +1236,6 @@ nmi_call_kdb_smp(u_int type, struct trapframe *frame, bool do_panic) atomic_store_rel_int(&nmi_kdb_lock, 0); if (call_post) cpustop_handler_post(cpu); - return (ret); } #endif From 5df976f79ec239734376357a1090c0f0e1750597 Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Mon, 24 Oct 2016 20:53:44 +0000 Subject: [PATCH 075/235] krping: Allow the underlying ib_device to handle DMA mappings. Submitted by: Vijay Singh @ Netapp --- sys/contrib/rdma/krping/krping.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/contrib/rdma/krping/krping.c b/sys/contrib/rdma/krping/krping.c index 3392c204b29d..8a89f80e3ea3 100644 --- a/sys/contrib/rdma/krping/krping.c +++ b/sys/contrib/rdma/krping/krping.c @@ -548,11 +548,11 @@ static int krping_setup_buffers(struct krping_cb *cb) DEBUG_LOG(cb, "krping_setup_buffers called on cb %p\n", cb); - cb->recv_dma_addr = dma_map_single(cb->pd->device->dma_device, + cb->recv_dma_addr = ib_dma_map_single(cb->pd->device, &cb->recv_buf, sizeof(cb->recv_buf), DMA_BIDIRECTIONAL); pci_unmap_addr_set(cb, recv_mapping, cb->recv_dma_addr); - cb->send_dma_addr = dma_map_single(cb->pd->device->dma_device, + cb->send_dma_addr = ib_dma_map_single(cb->pd->device, &cb->send_buf, sizeof(cb->send_buf), DMA_BIDIRECTIONAL); pci_unmap_addr_set(cb, send_mapping, cb->send_dma_addr); @@ -606,7 +606,7 @@ static int krping_setup_buffers(struct krping_cb *cb) goto bail; } - cb->rdma_dma_addr = dma_map_single(cb->pd->device->dma_device, + cb->rdma_dma_addr = ib_dma_map_single(cb->pd->device, cb->rdma_buf, cb->size, DMA_BIDIRECTIONAL); pci_unmap_addr_set(cb, rdma_mapping, cb->rdma_dma_addr); @@ -676,7 +676,7 @@ static int krping_setup_buffers(struct krping_cb *cb) goto bail; } - cb->start_dma_addr = dma_map_single(cb->pd->device->dma_device, + cb->start_dma_addr = ib_dma_map_single(cb->pd->device, cb->start_buf, cb->size, DMA_BIDIRECTIONAL); pci_unmap_addr_set(cb, start_mapping, cb->start_dma_addr); @@ -1707,7 +1707,7 @@ static void krping_fr_test5(struct krping_cb *cb) goto err2; } DEBUG_LOG(cb, "%s buf[%u] %p\n", __func__, scnt, buf[scnt]); - dma_addr[scnt] = dma_map_single(cb->pd->device->dma_device, + dma_addr[scnt] = ib_dma_map_single(cb->pd->device, buf[scnt], cb->size, DMA_BIDIRECTIONAL); if (dma_mapping_error(cb->pd->device->dma_device, @@ -2032,7 +2032,7 @@ static void krping_fr_test6(struct krping_cb *cb) goto err2; } DEBUG_LOG(cb, "%s buf[%u] %p\n", __func__, scnt, buf[scnt]); - dma_addr[scnt] = dma_map_single(cb->pd->device->dma_device, + dma_addr[scnt] = ib_dma_map_single(cb->pd->device, buf[scnt], cb->size, DMA_BIDIRECTIONAL); if (dma_mapping_error(cb->pd->device->dma_device, From 1108712cb5b14130380c93b00f4e9ef2a797a07d Mon Sep 17 00:00:00 2001 From: Shteryana Shopova Date: Mon, 24 Oct 2016 21:05:23 +0000 Subject: [PATCH 076/235] Fix a regression introduced in SVN r256678 that breaks USM header parsing Reviewed by: bz@ --- contrib/bsnmp/lib/snmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/bsnmp/lib/snmp.c b/contrib/bsnmp/lib/snmp.c index 6b9e3e87aaaa..a91be77e081c 100644 --- a/contrib/bsnmp/lib/snmp.c +++ b/contrib/bsnmp/lib/snmp.c @@ -288,7 +288,7 @@ parse_secparams(struct asn_buf *b, struct snmp_pdu *pdu) memset(buf, 0, 256); tb.asn_ptr = buf; tb.asn_len = 256; - u_int len; + u_int len = 256; if (asn_get_octetstring(b, buf, &len) != ASN_ERR_OK) { snmp_error("cannot parse usm header"); From 3a140f67b4c4ae443eb4849ecb1f84e07998096e Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Mon, 24 Oct 2016 21:09:48 +0000 Subject: [PATCH 077/235] Add needed cpu-supply property for cpufreq. Patch is merged upstream, in the meantime add it in our DTS. --- sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts b/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts index e937a93f7c00..6773792a0f2a 100644 --- a/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts +++ b/sys/boot/fdt/dts/arm/olimex-a20-som-evb.dts @@ -41,3 +41,7 @@ }; }; }; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; From f5355fadf7600da7d73162365bc8c97f24cfbb6d Mon Sep 17 00:00:00 2001 From: Glen Barber Date: Mon, 24 Oct 2016 21:16:21 +0000 Subject: [PATCH 078/235] Belatedly revert r303119, which was determined to not be needed. Sponsored by: The FreeBSD Foundation --- release/tools/arm.subr | 1 - 1 file changed, 1 deletion(-) diff --git a/release/tools/arm.subr b/release/tools/arm.subr index bc516eb4d744..97326c4d1fb7 100644 --- a/release/tools/arm.subr +++ b/release/tools/arm.subr @@ -88,7 +88,6 @@ arm_create_user() { -c 'FreeBSD User' -d '/home/freebsd' -s '/bin/csh' chroot ${CHROOTDIR} /usr/sbin/pw -R ${DESTDIR} \ usermod root -w yes - chroot ${CHROOTDIR} ln -s /home ${DESTDIR}/usr/home return 0 } From 6c1bd5587596e8cfd1939f88c47033d79de72883 Mon Sep 17 00:00:00 2001 From: Ryan Stone Date: Mon, 24 Oct 2016 22:11:33 +0000 Subject: [PATCH 079/235] Fix ip_output() on point-to-point links In r304435, ip_output() was changed to use the result of the route lookup to decide whether the outgoing packet was a broadcast or not. This introduced a regression on interfaces where IFF_BROADCAST was not set (e.g. point-to-point links), as the algorithm could incorrectly treat the destination address as a broadcast address, and ip_output() would subsequently drop the packet as broadcasting on a non-IFF_BROADCAST interface is not allowed. Differential Revision: https://reviews.freebsd.org/D8303 Reviewed by: jtl Reported by: ambrisko MFC after: 2 weeks X-MFC-With: r304435 Sponsored by: Dell EMC Isilon --- sys/netinet/ip_output.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 04fa7256b002..352aa375c770 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -350,7 +350,8 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, have_ia_ref = 1; ifp = ia->ia_ifp; ip->ip_ttl = 1; - isbroadcast = in_ifaddr_broadcast(dst->sin_addr, ia); + isbroadcast = ifp->if_flags & IFF_BROADCAST ? + in_ifaddr_broadcast(dst->sin_addr, ia) : 0; } else if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) && imo != NULL && imo->imo_multicast_ifp != NULL) { /* @@ -403,8 +404,10 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, gw = (struct sockaddr_in *)rte->rt_gateway; if (rte->rt_flags & RTF_HOST) isbroadcast = (rte->rt_flags & RTF_BROADCAST); - else + else if (ifp->if_flags & IFF_BROADCAST) isbroadcast = in_ifaddr_broadcast(gw->sin_addr, ia); + else + isbroadcast = 0; } /* From 2e4f934752afae0493742bcfd65831a903eb2102 Mon Sep 17 00:00:00 2001 From: Jared McNeill Date: Mon, 24 Oct 2016 22:35:12 +0000 Subject: [PATCH 080/235] Defer cpufreq updates from intr handler to the taskqueue_thread queue. --- sys/arm/allwinner/aw_thermal.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/sys/arm/allwinner/aw_thermal.c b/sys/arm/allwinner/aw_thermal.c index 509a69444224..c4c8bc1035ce 100644 --- a/sys/arm/allwinner/aw_thermal.c +++ b/sys/arm/allwinner/aw_thermal.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -249,6 +250,7 @@ struct aw_thermal_softc { struct resource *res[2]; struct aw_thermal_config *conf; + struct task cf_task; int throttle; int min_freq; struct cf_level levels[MAX_CF_LEVELS]; @@ -389,6 +391,16 @@ aw_thermal_throttle(struct aw_thermal_softc *sc, int enable) sc->throttle = enable; } +static void +aw_thermal_cf_task(void *arg, int pending) +{ + struct aw_thermal_softc *sc; + + sc = arg; + + aw_thermal_throttle(sc, 1); +} + static void aw_thermal_cf_pre_change(void *arg, const struct cf_level *level, int *status) { @@ -430,7 +442,7 @@ aw_thermal_intr(void *arg) } if ((ints & ALARM_INT_ALL) != 0) - aw_thermal_throttle(sc, 1); + taskqueue_enqueue(taskqueue_thread, &sc->cf_task); } static int @@ -461,6 +473,7 @@ aw_thermal_attach(device_t dev) ih = NULL; sc->conf = THS_CONF(dev); + TASK_INIT(&sc->cf_task, 0, aw_thermal_cf_task, sc); if (bus_alloc_resources(dev, aw_thermal_spec, sc->res) != 0) { device_printf(dev, "cannot allocate resources for device\n"); From 51fefb04189840cf844cfc3522aa6d67b8a0482f Mon Sep 17 00:00:00 2001 From: Jared McNeill Date: Mon, 24 Oct 2016 22:35:45 +0000 Subject: [PATCH 081/235] Enable driver for SY8106A Buck Regulator. --- sys/arm/conf/GENERIC | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index d8fa9dd41e71..8e3169ca7266 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -112,6 +112,7 @@ device axp209 # AXP209 Power Management Unit device axp81x # AXP813/818 Power Management Unit device bcm2835_bsc device icee +device sy8106a # SY8106A Buck Regulator # GPIO device gpio From 5ebee88d80bc3979a847362f020f9921141b72b7 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 25 Oct 2016 00:52:42 +0000 Subject: [PATCH 082/235] mountd(8) was erroneously setting the sysctl for the old NFS server when the new/default NFS server was running, for the "-n" option. This patch fixes the problem for head and stable/11. For stable/10 the patch will need to be modified when MFC'd, since the stable/10 mountd.c handles both old and new NFS servers. Since the new NFS server uses vfs.nfsd.nfs_privport == 0 by default, there wouldn't have been many users affected by the code not setting it to 0 when the "-n" option was specified. PR: 213450 Submitted by: rs@bytecamp.net MFC after: 2 weeks --- usr.sbin/mountd/mountd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c index e4b04b0d3e0b..d893387028be 100644 --- a/usr.sbin/mountd/mountd.c +++ b/usr.sbin/mountd/mountd.c @@ -476,7 +476,7 @@ main(int argc, char **argv) rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); if (!resvport_only) { - if (sysctlbyname("vfs.nfsrv.nfs_privport", NULL, NULL, + if (sysctlbyname("vfs.nfsd.nfs_privport", NULL, NULL, &resvport_only, sizeof(resvport_only)) != 0 && errno != ENOENT) { syslog(LOG_ERR, "sysctl: %m"); From a4a17097288ea421337d0debb9d7728863554368 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 25 Oct 2016 00:59:23 +0000 Subject: [PATCH 083/235] Fix the man page to reflect the change done by r307890 to mountd.c so that the "-n" option uses the sysctl for the new NFS server. This is a content change. PR: 213450 Submitted by: rs@bytecamp.net MFC after: 2 weeks --- usr.sbin/mountd/mountd.8 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/usr.sbin/mountd/mountd.8 b/usr.sbin/mountd/mountd.8 index 4dbf5ff2328e..ac0a3a23ebdf 100644 --- a/usr.sbin/mountd/mountd.8 +++ b/usr.sbin/mountd/mountd.8 @@ -28,7 +28,7 @@ .\" @(#)mountd.8 8.4 (Berkeley) 4/28/95 .\" $FreeBSD$ .\" -.Dd October 14, 2012 +.Dd October 24, 2016 .Dt MOUNTD 8 .Os .Sh NAME @@ -95,7 +95,7 @@ requests to be logged. Allow non-root mount requests to be served. This should only be specified if there are clients such as PC's, that require it. -It will automatically clear the vfs.nfsrv.nfs_privport sysctl flag, which +It will automatically clear the vfs.nfsd.nfs_privport sysctl flag, which controls if the kernel will accept NFS requests from reserved ports only. .It Fl p Ar port Force From 80d2e10c9b6b27e228502c0bcee06133e7b44405 Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Tue, 25 Oct 2016 01:32:35 +0000 Subject: [PATCH 084/235] Fix a typo which broke the build for powerpc. It's spelled LIBC_SRCTOP not LIBC_SRC. Pointy-hat to: jhibbits Reported by: kib --- lib/libc/powerpc/gen/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/powerpc/gen/Makefile.inc b/lib/libc/powerpc/gen/Makefile.inc index 368887e1ac9e..f96ad9fb0a6f 100644 --- a/lib/libc/powerpc/gen/Makefile.inc +++ b/lib/libc/powerpc/gen/Makefile.inc @@ -1,6 +1,6 @@ # $FreeBSD$ -.include "${LIBC_SRC}/powerpc/gen/Makefile.common" +.include "${LIBC_SRCTOP}/powerpc/gen/Makefile.common" SRCS += fabs.S flt_rounds.c fpgetmask.c fpgetround.c \ fpgetsticky.c fpsetmask.c fpsetround.c \ From 7888d6422d916370f09e2b9e4474a880f780c65b Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Tue, 25 Oct 2016 01:41:39 +0000 Subject: [PATCH 085/235] hyperv/hn: Set baudrate properly PR: 208931 Submitted by: Eugene Grosbein Reported by: Eugene Grosbein MFC after: 1 week Sponsored by: Microsoft --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 5bd46e8e8273..744d1790da34 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -789,6 +789,7 @@ netvsc_attach(device_t dev) * Setup the ifnet for this interface. */ + ifp->if_baudrate = IF_Gbps(10); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = hn_ioctl; ifp->if_init = hn_init; From 1648616981ad00457c943269f99d8a7f6d58c560 Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Tue, 25 Oct 2016 03:55:56 +0000 Subject: [PATCH 086/235] Use proper if_getdrvflags() API. This is a NOP. Sponsored by: Dell EMC Isilon --- sys/dev/bxe/bxe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/bxe/bxe.c b/sys/dev/bxe/bxe.c index c5daac58da56..98978da9a53f 100644 --- a/sys/dev/bxe/bxe.c +++ b/sys/dev/bxe/bxe.c @@ -5603,7 +5603,7 @@ bxe_tx_start(if_t ifp) fp = &sc->fp[0]; - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) { + if (if_getdrvflags(ifp) & IFF_DRV_OACTIVE) { fp->eth_q_stats.tx_queue_full_return++; return; } @@ -5643,7 +5643,7 @@ bxe_tx_mq_start_locked(struct bxe_softc *sc, } } - if (!sc->link_vars.link_up || !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!sc->link_vars.link_up || !(if_getdrvflags(ifp) & IFF_DRV_RUNNING)) { fp->eth_q_stats.tx_request_link_down_failures++; goto bxe_tx_mq_start_locked_exit; } From 95d82360113ffbcc1fce3cf26cc92b00f2ab869b Mon Sep 17 00:00:00 2001 From: Hiren Panchasara Date: Tue, 25 Oct 2016 05:03:33 +0000 Subject: [PATCH 087/235] In Collaboration with: Matt Macy Reviewed by: jtl Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D8225 --- sys/netinet/cc/cc_cdg.c | 15 ++++++++++++--- sys/netinet/cc/cc_chd.c | 8 ++++++++ sys/netinet/cc/cc_cubic.c | 15 ++++++++++++--- sys/netinet/cc/cc_dctcp.c | 19 +++++++++++-------- sys/netinet/cc/cc_htcp.c | 11 +++++++++-- sys/netinet/cc/cc_newreno.c | 23 ++++++++++++++++------- sys/netinet/tcp_input.c | 34 ++++++++++++++++++++++++++-------- 7 files changed, 94 insertions(+), 31 deletions(-) diff --git a/sys/netinet/cc/cc_cdg.c b/sys/netinet/cc/cc_cdg.c index 04e2f7be5145..b9049fb7222b 100644 --- a/sys/netinet/cc/cc_cdg.c +++ b/sys/netinet/cc/cc_cdg.c @@ -431,6 +431,11 @@ static void cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) { struct cdg *cdg_data = ccv->cc_data; + uint32_t cwin; + u_int mss; + + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch(signal_type) { case CC_CDG_DELAY: @@ -448,7 +453,7 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) */ if (IN_CONGRECOVERY(CCV(ccv, t_flags)) || cdg_data->queue_state < CDG_Q_FULL) { - CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); + CCV(ccv, snd_ssthresh) = cwin; CCV(ccv, snd_recover) = CCV(ccv, snd_max); } else { /* @@ -461,13 +466,17 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) cdg_data->shadow_w, RENO_BETA); CCV(ccv, snd_ssthresh) = max(cdg_data->shadow_w, - cdg_window_decrease(ccv, CCV(ccv, snd_cwnd), - V_cdg_beta_loss)); + cdg_window_decrease(ccv, cwin, V_cdg_beta_loss)); + CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); cdg_data->window_incr = cdg_data->rtt_count = 0; } ENTER_RECOVERY(CCV(ccv, t_flags)); break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2); + CCV(ccv, snd_cwnd) = mss; + break; default: newreno_cc_algo.cong_signal(ccv, signal_type); break; diff --git a/sys/netinet/cc/cc_chd.c b/sys/netinet/cc/cc_chd.c index d7b53fec4d6a..fd2f6b8ec1b6 100644 --- a/sys/netinet/cc/cc_chd.c +++ b/sys/netinet/cc/cc_chd.c @@ -330,10 +330,14 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type) struct ertt *e_t; struct chd *chd_data; int qdly; + uint32_t cwin; + u_int mss; e_t = khelp_get_osd(CCV(ccv, osd), ertt_id); chd_data = ccv->cc_data; qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt; + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch(signal_type) { case CC_CHD_DELAY: @@ -373,6 +377,10 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type) } ENTER_FASTRECOVERY(CCV(ccv, t_flags)); break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2); + CCV(ccv, snd_cwnd) = mss; + break; default: newreno_cc_algo.cong_signal(ccv, signal_type); diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index 64398faa929b..d2304d227487 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -225,8 +225,12 @@ static void cubic_cong_signal(struct cc_var *ccv, uint32_t type) { struct cubic *cubic_data; + uint32_t cwin; + u_int mss; cubic_data = ccv->cc_data; + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: @@ -235,7 +239,8 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_ssthresh_update(ccv); cubic_data->num_cong_events++; cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = CCV(ccv, snd_cwnd); + cubic_data->max_cwnd = cwin; + CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -246,7 +251,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_ssthresh_update(ccv); cubic_data->num_cong_events++; cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = CCV(ccv, snd_cwnd); + cubic_data->max_cwnd = cwin; cubic_data->t_last_cong = ticks; CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); @@ -261,9 +266,13 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) * chance the first one is a false alarm and may not indicate * congestion. */ - if (CCV(ccv, t_rxtshift) >= 2) + if (CCV(ccv, t_rxtshift) >= 2) { cubic_data->num_cong_events++; cubic_data->t_last_cong = ticks; + cubic_ssthresh_update(ccv); + cubic_data->max_cwnd = cwin; + CCV(ccv, snd_cwnd) = mss; + } break; } } diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c index ce75750fef8b..e79fb19d96da 100644 --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -230,10 +230,11 @@ static void dctcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct dctcp *dctcp_data; - u_int win, mss; + uint32_t cwin; + u_int mss; dctcp_data = ccv->cc_data; - win = CCV(ccv, snd_cwnd); + cwin = CCV(ccv, snd_cwnd); mss = CCV(ccv, t_maxseg); switch (type) { @@ -241,16 +242,16 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { CCV(ccv, snd_ssthresh) = mss * - max(win / 2 / mss, 2); + max(cwin / 2 / mss, 2); dctcp_data->num_cong_events++; } else { /* cwnd has already updated as congestion * recovery. Reverse cwnd value using * snd_cwnd_prev and recalculate snd_ssthresh */ - win = CCV(ccv, snd_cwnd_prev); + cwin = CCV(ccv, snd_cwnd_prev); CCV(ccv, snd_ssthresh) = - max(win / 2 / mss, 2) * mss; + max(cwin / 2 / mss, 2) * mss; } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -260,18 +261,18 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) * Save current snd_cwnd when the host encounters both * congestion recovery and fast recovery. */ - CCV(ccv, snd_cwnd_prev) = win; + CCV(ccv, snd_cwnd_prev) = cwin; if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { if (V_dctcp_slowstart && dctcp_data->num_cong_events++ == 0) { CCV(ccv, snd_ssthresh) = - mss * max(win / 2 / mss, 2); + mss * max(cwin / 2 / mss, 2); dctcp_data->alpha = MAX_ALPHA_VALUE; dctcp_data->bytes_ecn = 0; dctcp_data->bytes_total = 0; dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); } else - CCV(ccv, snd_ssthresh) = max((win - ((win * + CCV(ccv, snd_ssthresh) = max((cwin - ((cwin * dctcp_data->alpha) >> 11)) / mss, 2) * mss; CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); @@ -284,6 +285,8 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) dctcp_update_alpha(ccv); dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); dctcp_data->num_cong_events++; + CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2); + CCV(ccv, snd_cwnd) = mss; } break; } diff --git a/sys/netinet/cc/cc_htcp.c b/sys/netinet/cc/cc_htcp.c index 92820f56de8c..8842648435c0 100644 --- a/sys/netinet/cc/cc_htcp.c +++ b/sys/netinet/cc/cc_htcp.c @@ -271,8 +271,12 @@ static void htcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct htcp *htcp_data; + uint32_t cwin; + u_int mss; htcp_data = ccv->cc_data; + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: @@ -287,8 +291,9 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) (htcp_data->maxrtt - htcp_data->minrtt) * 95) / 100; htcp_ssthresh_update(ccv); + CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); htcp_data->t_last_cong = ticks; - htcp_data->prev_cwnd = CCV(ccv, snd_cwnd); + htcp_data->prev_cwnd = cwin; } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -305,7 +310,7 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) htcp_ssthresh_update(ccv); CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); htcp_data->t_last_cong = ticks; - htcp_data->prev_cwnd = CCV(ccv, snd_cwnd); + htcp_data->prev_cwnd = cwin; ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } break; @@ -320,6 +325,8 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) */ if (CCV(ccv, t_rxtshift) >= 2) htcp_data->t_last_cong = ticks; + CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2); + CCV(ccv, snd_cwnd) = mss; break; } } diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c index b2c72fe9fcb1..3aa16019657d 100644 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -182,30 +182,39 @@ newreno_after_idle(struct cc_var *ccv) static void newreno_cong_signal(struct cc_var *ccv, uint32_t type) { - u_int win; + uint32_t cwin; + u_int mss; + + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); /* Catch algos which mistakenly leak private signal types. */ KASSERT((type & CC_SIGPRIVMASK) == 0, ("%s: congestion signal type 0x%08x is private\n", __func__, type)); - win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) * - CCV(ccv, t_maxseg); + cwin = max(2*mss, cwin/2); switch (type) { case CC_NDUPACK: if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { - if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) - CCV(ccv, snd_ssthresh) = win; + if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { + CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_cwnd) = cwin; + } ENTER_RECOVERY(CCV(ccv, t_flags)); } break; case CC_ECN: if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { - CCV(ccv, snd_ssthresh) = win; - CCV(ccv, snd_cwnd) = win; + CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_cwnd) = cwin; ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_cwnd) = mss; + break; } } diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index ed61e64a0ede..792818a9231d 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -438,9 +438,15 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) tp->t_dupacks = 0; tp->t_bytes_acked = 0; EXIT_RECOVERY(tp->t_flags); - tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 / - maxseg) * maxseg; - tp->snd_cwnd = maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) { + /* + * RFC5681 Section 3.1 + * ssthresh = max (FlightSize / 2, 2*SMSS) eq (4) + */ + tp->snd_ssthresh = + max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg); + tp->snd_cwnd = maxseg; + } break; case CC_RTO_ERR: TCPSTAT_INC(tcps_sndrexmitbad); @@ -2613,6 +2619,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += maxseg; + /* + * RFC5681 Section 3.2 talks about cwnd + * inflation on additional dupacks and + * deflation on recovering from loss. + * + * We keep cwnd into check so that + * we don't have to 'deflate' it when we + * get out of recovery. + */ if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; } @@ -2652,19 +2667,22 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, TCPSTAT_INC( tcps_sack_recovery_episode); tp->sack_newdata = tp->snd_nxt; - tp->snd_cwnd = maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = maxseg; (void) tp->t_fb->tfb_tcp_output(tp); goto drop; } tp->snd_nxt = th->th_ack; - tp->snd_cwnd = maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = maxseg; (void) tp->t_fb->tfb_tcp_output(tp); KASSERT(tp->snd_limited <= 2, ("%s: tp->snd_limited too big", __func__)); - tp->snd_cwnd = tp->snd_ssthresh + - maxseg * - (tp->t_dupacks - tp->snd_limited); + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = tp->snd_ssthresh + + maxseg * + (tp->t_dupacks - tp->snd_limited); if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; From dd13b7d3877a4613ff5b786e991bc4fb1f33ebf0 Mon Sep 17 00:00:00 2001 From: Hiren Panchasara Date: Tue, 25 Oct 2016 05:07:51 +0000 Subject: [PATCH 088/235] Undo r307899. It needs a bit more work and proper commit log. --- sys/netinet/cc/cc_cdg.c | 15 +++------------ sys/netinet/cc/cc_chd.c | 8 -------- sys/netinet/cc/cc_cubic.c | 15 +++------------ sys/netinet/cc/cc_dctcp.c | 19 ++++++++----------- sys/netinet/cc/cc_htcp.c | 11 ++--------- sys/netinet/cc/cc_newreno.c | 23 +++++++---------------- sys/netinet/tcp_input.c | 34 ++++++++-------------------------- 7 files changed, 31 insertions(+), 94 deletions(-) diff --git a/sys/netinet/cc/cc_cdg.c b/sys/netinet/cc/cc_cdg.c index b9049fb7222b..04e2f7be5145 100644 --- a/sys/netinet/cc/cc_cdg.c +++ b/sys/netinet/cc/cc_cdg.c @@ -431,11 +431,6 @@ static void cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) { struct cdg *cdg_data = ccv->cc_data; - uint32_t cwin; - u_int mss; - - cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); switch(signal_type) { case CC_CDG_DELAY: @@ -453,7 +448,7 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) */ if (IN_CONGRECOVERY(CCV(ccv, t_flags)) || cdg_data->queue_state < CDG_Q_FULL) { - CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); CCV(ccv, snd_recover) = CCV(ccv, snd_max); } else { /* @@ -466,17 +461,13 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) cdg_data->shadow_w, RENO_BETA); CCV(ccv, snd_ssthresh) = max(cdg_data->shadow_w, - cdg_window_decrease(ccv, cwin, V_cdg_beta_loss)); - CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); + cdg_window_decrease(ccv, CCV(ccv, snd_cwnd), + V_cdg_beta_loss)); cdg_data->window_incr = cdg_data->rtt_count = 0; } ENTER_RECOVERY(CCV(ccv, t_flags)); break; - case CC_RTO: - CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2); - CCV(ccv, snd_cwnd) = mss; - break; default: newreno_cc_algo.cong_signal(ccv, signal_type); break; diff --git a/sys/netinet/cc/cc_chd.c b/sys/netinet/cc/cc_chd.c index fd2f6b8ec1b6..d7b53fec4d6a 100644 --- a/sys/netinet/cc/cc_chd.c +++ b/sys/netinet/cc/cc_chd.c @@ -330,14 +330,10 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type) struct ertt *e_t; struct chd *chd_data; int qdly; - uint32_t cwin; - u_int mss; e_t = khelp_get_osd(CCV(ccv, osd), ertt_id); chd_data = ccv->cc_data; qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt; - cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); switch(signal_type) { case CC_CHD_DELAY: @@ -377,10 +373,6 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type) } ENTER_FASTRECOVERY(CCV(ccv, t_flags)); break; - case CC_RTO: - CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2); - CCV(ccv, snd_cwnd) = mss; - break; default: newreno_cc_algo.cong_signal(ccv, signal_type); diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index d2304d227487..64398faa929b 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -225,12 +225,8 @@ static void cubic_cong_signal(struct cc_var *ccv, uint32_t type) { struct cubic *cubic_data; - uint32_t cwin; - u_int mss; cubic_data = ccv->cc_data; - cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: @@ -239,8 +235,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_ssthresh_update(ccv); cubic_data->num_cong_events++; cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = cwin; - CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); + cubic_data->max_cwnd = CCV(ccv, snd_cwnd); } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -251,7 +246,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_ssthresh_update(ccv); cubic_data->num_cong_events++; cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = cwin; + cubic_data->max_cwnd = CCV(ccv, snd_cwnd); cubic_data->t_last_cong = ticks; CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); @@ -266,13 +261,9 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) * chance the first one is a false alarm and may not indicate * congestion. */ - if (CCV(ccv, t_rxtshift) >= 2) { + if (CCV(ccv, t_rxtshift) >= 2) cubic_data->num_cong_events++; cubic_data->t_last_cong = ticks; - cubic_ssthresh_update(ccv); - cubic_data->max_cwnd = cwin; - CCV(ccv, snd_cwnd) = mss; - } break; } } diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c index e79fb19d96da..ce75750fef8b 100644 --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -230,11 +230,10 @@ static void dctcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct dctcp *dctcp_data; - uint32_t cwin; - u_int mss; + u_int win, mss; dctcp_data = ccv->cc_data; - cwin = CCV(ccv, snd_cwnd); + win = CCV(ccv, snd_cwnd); mss = CCV(ccv, t_maxseg); switch (type) { @@ -242,16 +241,16 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { CCV(ccv, snd_ssthresh) = mss * - max(cwin / 2 / mss, 2); + max(win / 2 / mss, 2); dctcp_data->num_cong_events++; } else { /* cwnd has already updated as congestion * recovery. Reverse cwnd value using * snd_cwnd_prev and recalculate snd_ssthresh */ - cwin = CCV(ccv, snd_cwnd_prev); + win = CCV(ccv, snd_cwnd_prev); CCV(ccv, snd_ssthresh) = - max(cwin / 2 / mss, 2) * mss; + max(win / 2 / mss, 2) * mss; } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -261,18 +260,18 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) * Save current snd_cwnd when the host encounters both * congestion recovery and fast recovery. */ - CCV(ccv, snd_cwnd_prev) = cwin; + CCV(ccv, snd_cwnd_prev) = win; if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { if (V_dctcp_slowstart && dctcp_data->num_cong_events++ == 0) { CCV(ccv, snd_ssthresh) = - mss * max(cwin / 2 / mss, 2); + mss * max(win / 2 / mss, 2); dctcp_data->alpha = MAX_ALPHA_VALUE; dctcp_data->bytes_ecn = 0; dctcp_data->bytes_total = 0; dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); } else - CCV(ccv, snd_ssthresh) = max((cwin - ((cwin * + CCV(ccv, snd_ssthresh) = max((win - ((win * dctcp_data->alpha) >> 11)) / mss, 2) * mss; CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); @@ -285,8 +284,6 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) dctcp_update_alpha(ccv); dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); dctcp_data->num_cong_events++; - CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2); - CCV(ccv, snd_cwnd) = mss; } break; } diff --git a/sys/netinet/cc/cc_htcp.c b/sys/netinet/cc/cc_htcp.c index 8842648435c0..92820f56de8c 100644 --- a/sys/netinet/cc/cc_htcp.c +++ b/sys/netinet/cc/cc_htcp.c @@ -271,12 +271,8 @@ static void htcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct htcp *htcp_data; - uint32_t cwin; - u_int mss; htcp_data = ccv->cc_data; - cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: @@ -291,9 +287,8 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) (htcp_data->maxrtt - htcp_data->minrtt) * 95) / 100; htcp_ssthresh_update(ccv); - CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); htcp_data->t_last_cong = ticks; - htcp_data->prev_cwnd = cwin; + htcp_data->prev_cwnd = CCV(ccv, snd_cwnd); } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -310,7 +305,7 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) htcp_ssthresh_update(ccv); CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); htcp_data->t_last_cong = ticks; - htcp_data->prev_cwnd = cwin; + htcp_data->prev_cwnd = CCV(ccv, snd_cwnd); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } break; @@ -325,8 +320,6 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) */ if (CCV(ccv, t_rxtshift) >= 2) htcp_data->t_last_cong = ticks; - CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2); - CCV(ccv, snd_cwnd) = mss; break; } } diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c index 3aa16019657d..b2c72fe9fcb1 100644 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -182,39 +182,30 @@ newreno_after_idle(struct cc_var *ccv) static void newreno_cong_signal(struct cc_var *ccv, uint32_t type) { - uint32_t cwin; - u_int mss; - - cwin = CCV(ccv, snd_cwnd); - mss = CCV(ccv, t_maxseg); + u_int win; /* Catch algos which mistakenly leak private signal types. */ KASSERT((type & CC_SIGPRIVMASK) == 0, ("%s: congestion signal type 0x%08x is private\n", __func__, type)); - cwin = max(2*mss, cwin/2); + win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) * + CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { - if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { - CCV(ccv, snd_ssthresh) = cwin; - CCV(ccv, snd_cwnd) = cwin; - } + if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) + CCV(ccv, snd_ssthresh) = win; ENTER_RECOVERY(CCV(ccv, t_flags)); } break; case CC_ECN: if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { - CCV(ccv, snd_ssthresh) = cwin; - CCV(ccv, snd_cwnd) = cwin; + CCV(ccv, snd_ssthresh) = win; + CCV(ccv, snd_cwnd) = win; ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } break; - case CC_RTO: - CCV(ccv, snd_ssthresh) = cwin; - CCV(ccv, snd_cwnd) = mss; - break; } } diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 792818a9231d..ed61e64a0ede 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -438,15 +438,9 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) tp->t_dupacks = 0; tp->t_bytes_acked = 0; EXIT_RECOVERY(tp->t_flags); - if (CC_ALGO(tp)->cong_signal == NULL) { - /* - * RFC5681 Section 3.1 - * ssthresh = max (FlightSize / 2, 2*SMSS) eq (4) - */ - tp->snd_ssthresh = - max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg); - tp->snd_cwnd = maxseg; - } + tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 / + maxseg) * maxseg; + tp->snd_cwnd = maxseg; break; case CC_RTO_ERR: TCPSTAT_INC(tcps_sndrexmitbad); @@ -2619,15 +2613,6 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += maxseg; - /* - * RFC5681 Section 3.2 talks about cwnd - * inflation on additional dupacks and - * deflation on recovering from loss. - * - * We keep cwnd into check so that - * we don't have to 'deflate' it when we - * get out of recovery. - */ if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; } @@ -2667,22 +2652,19 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, TCPSTAT_INC( tcps_sack_recovery_episode); tp->sack_newdata = tp->snd_nxt; - if (CC_ALGO(tp)->cong_signal == NULL) - tp->snd_cwnd = maxseg; + tp->snd_cwnd = maxseg; (void) tp->t_fb->tfb_tcp_output(tp); goto drop; } tp->snd_nxt = th->th_ack; - if (CC_ALGO(tp)->cong_signal == NULL) - tp->snd_cwnd = maxseg; + tp->snd_cwnd = maxseg; (void) tp->t_fb->tfb_tcp_output(tp); KASSERT(tp->snd_limited <= 2, ("%s: tp->snd_limited too big", __func__)); - if (CC_ALGO(tp)->cong_signal == NULL) - tp->snd_cwnd = tp->snd_ssthresh + - maxseg * - (tp->t_dupacks - tp->snd_limited); + tp->snd_cwnd = tp->snd_ssthresh + + maxseg * + (tp->t_dupacks - tp->snd_limited); if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; From 4e7f755377b2cc827bd63cfcbb67797c8928b249 Mon Sep 17 00:00:00 2001 From: Hiren Panchasara Date: Tue, 25 Oct 2016 05:45:47 +0000 Subject: [PATCH 089/235] FreeBSD tcp stack used to inform respective congestion control module about the loss event but not use or obay the recommendations i.e. values set by it in some cases. Here is an attempt to solve that confusion by following relevant RFCs/drafts. Stack only sets congestion window/slow start threshold values when there is no CC module availalbe to take that action. All CC modules are inspected and updated when needed to take appropriate action on loss. tcp_stacks/fastpath module has been updated to adapt these changes. Note: Probably, the most significant change would be to not bring congestion window down to 1MSS on a loss signaled by 3-duplicate acks and letting respective CC decide that value. In collaboration with: Matt Macy Discussed on: transport@ mailing list Reviewed by: jtl MFC after: 1 month Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D8225 --- sys/netinet/cc/cc_cdg.c | 15 +++++++++++--- sys/netinet/cc/cc_chd.c | 8 ++++++++ sys/netinet/cc/cc_cubic.c | 15 +++++++++++--- sys/netinet/cc/cc_dctcp.c | 19 +++++++++-------- sys/netinet/cc/cc_htcp.c | 11 ++++++++-- sys/netinet/cc/cc_newreno.c | 23 ++++++++++++++------- sys/netinet/tcp_input.c | 34 +++++++++++++++++++++++-------- sys/netinet/tcp_stacks/fastpath.c | 22 +++++++++++++++----- 8 files changed, 111 insertions(+), 36 deletions(-) diff --git a/sys/netinet/cc/cc_cdg.c b/sys/netinet/cc/cc_cdg.c index 04e2f7be5145..b9049fb7222b 100644 --- a/sys/netinet/cc/cc_cdg.c +++ b/sys/netinet/cc/cc_cdg.c @@ -431,6 +431,11 @@ static void cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) { struct cdg *cdg_data = ccv->cc_data; + uint32_t cwin; + u_int mss; + + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch(signal_type) { case CC_CDG_DELAY: @@ -448,7 +453,7 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) */ if (IN_CONGRECOVERY(CCV(ccv, t_flags)) || cdg_data->queue_state < CDG_Q_FULL) { - CCV(ccv, snd_ssthresh) = CCV(ccv, snd_cwnd); + CCV(ccv, snd_ssthresh) = cwin; CCV(ccv, snd_recover) = CCV(ccv, snd_max); } else { /* @@ -461,13 +466,17 @@ cdg_cong_signal(struct cc_var *ccv, uint32_t signal_type) cdg_data->shadow_w, RENO_BETA); CCV(ccv, snd_ssthresh) = max(cdg_data->shadow_w, - cdg_window_decrease(ccv, CCV(ccv, snd_cwnd), - V_cdg_beta_loss)); + cdg_window_decrease(ccv, cwin, V_cdg_beta_loss)); + CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); cdg_data->window_incr = cdg_data->rtt_count = 0; } ENTER_RECOVERY(CCV(ccv, t_flags)); break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2); + CCV(ccv, snd_cwnd) = mss; + break; default: newreno_cc_algo.cong_signal(ccv, signal_type); break; diff --git a/sys/netinet/cc/cc_chd.c b/sys/netinet/cc/cc_chd.c index d7b53fec4d6a..fd2f6b8ec1b6 100644 --- a/sys/netinet/cc/cc_chd.c +++ b/sys/netinet/cc/cc_chd.c @@ -330,10 +330,14 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type) struct ertt *e_t; struct chd *chd_data; int qdly; + uint32_t cwin; + u_int mss; e_t = khelp_get_osd(CCV(ccv, osd), ertt_id); chd_data = ccv->cc_data; qdly = imax(e_t->rtt, chd_data->maxrtt_in_rtt) - e_t->minrtt; + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch(signal_type) { case CC_CHD_DELAY: @@ -373,6 +377,10 @@ chd_cong_signal(struct cc_var *ccv, uint32_t signal_type) } ENTER_FASTRECOVERY(CCV(ccv, t_flags)); break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = max(2*mss, cwin/2); + CCV(ccv, snd_cwnd) = mss; + break; default: newreno_cc_algo.cong_signal(ccv, signal_type); diff --git a/sys/netinet/cc/cc_cubic.c b/sys/netinet/cc/cc_cubic.c index 64398faa929b..d2304d227487 100644 --- a/sys/netinet/cc/cc_cubic.c +++ b/sys/netinet/cc/cc_cubic.c @@ -225,8 +225,12 @@ static void cubic_cong_signal(struct cc_var *ccv, uint32_t type) { struct cubic *cubic_data; + uint32_t cwin; + u_int mss; cubic_data = ccv->cc_data; + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: @@ -235,7 +239,8 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_ssthresh_update(ccv); cubic_data->num_cong_events++; cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = CCV(ccv, snd_cwnd); + cubic_data->max_cwnd = cwin; + CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -246,7 +251,7 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) cubic_ssthresh_update(ccv); cubic_data->num_cong_events++; cubic_data->prev_max_cwnd = cubic_data->max_cwnd; - cubic_data->max_cwnd = CCV(ccv, snd_cwnd); + cubic_data->max_cwnd = cwin; cubic_data->t_last_cong = ticks; CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); @@ -261,9 +266,13 @@ cubic_cong_signal(struct cc_var *ccv, uint32_t type) * chance the first one is a false alarm and may not indicate * congestion. */ - if (CCV(ccv, t_rxtshift) >= 2) + if (CCV(ccv, t_rxtshift) >= 2) { cubic_data->num_cong_events++; cubic_data->t_last_cong = ticks; + cubic_ssthresh_update(ccv); + cubic_data->max_cwnd = cwin; + CCV(ccv, snd_cwnd) = mss; + } break; } } diff --git a/sys/netinet/cc/cc_dctcp.c b/sys/netinet/cc/cc_dctcp.c index ce75750fef8b..e79fb19d96da 100644 --- a/sys/netinet/cc/cc_dctcp.c +++ b/sys/netinet/cc/cc_dctcp.c @@ -230,10 +230,11 @@ static void dctcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct dctcp *dctcp_data; - u_int win, mss; + uint32_t cwin; + u_int mss; dctcp_data = ccv->cc_data; - win = CCV(ccv, snd_cwnd); + cwin = CCV(ccv, snd_cwnd); mss = CCV(ccv, t_maxseg); switch (type) { @@ -241,16 +242,16 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { CCV(ccv, snd_ssthresh) = mss * - max(win / 2 / mss, 2); + max(cwin / 2 / mss, 2); dctcp_data->num_cong_events++; } else { /* cwnd has already updated as congestion * recovery. Reverse cwnd value using * snd_cwnd_prev and recalculate snd_ssthresh */ - win = CCV(ccv, snd_cwnd_prev); + cwin = CCV(ccv, snd_cwnd_prev); CCV(ccv, snd_ssthresh) = - max(win / 2 / mss, 2) * mss; + max(cwin / 2 / mss, 2) * mss; } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -260,18 +261,18 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) * Save current snd_cwnd when the host encounters both * congestion recovery and fast recovery. */ - CCV(ccv, snd_cwnd_prev) = win; + CCV(ccv, snd_cwnd_prev) = cwin; if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { if (V_dctcp_slowstart && dctcp_data->num_cong_events++ == 0) { CCV(ccv, snd_ssthresh) = - mss * max(win / 2 / mss, 2); + mss * max(cwin / 2 / mss, 2); dctcp_data->alpha = MAX_ALPHA_VALUE; dctcp_data->bytes_ecn = 0; dctcp_data->bytes_total = 0; dctcp_data->save_sndnxt = CCV(ccv, snd_nxt); } else - CCV(ccv, snd_ssthresh) = max((win - ((win * + CCV(ccv, snd_ssthresh) = max((cwin - ((cwin * dctcp_data->alpha) >> 11)) / mss, 2) * mss; CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); ENTER_CONGRECOVERY(CCV(ccv, t_flags)); @@ -284,6 +285,8 @@ dctcp_cong_signal(struct cc_var *ccv, uint32_t type) dctcp_update_alpha(ccv); dctcp_data->save_sndnxt += CCV(ccv, t_maxseg); dctcp_data->num_cong_events++; + CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2); + CCV(ccv, snd_cwnd) = mss; } break; } diff --git a/sys/netinet/cc/cc_htcp.c b/sys/netinet/cc/cc_htcp.c index 92820f56de8c..8842648435c0 100644 --- a/sys/netinet/cc/cc_htcp.c +++ b/sys/netinet/cc/cc_htcp.c @@ -271,8 +271,12 @@ static void htcp_cong_signal(struct cc_var *ccv, uint32_t type) { struct htcp *htcp_data; + uint32_t cwin; + u_int mss; htcp_data = ccv->cc_data; + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); switch (type) { case CC_NDUPACK: @@ -287,8 +291,9 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) (htcp_data->maxrtt - htcp_data->minrtt) * 95) / 100; htcp_ssthresh_update(ccv); + CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); htcp_data->t_last_cong = ticks; - htcp_data->prev_cwnd = CCV(ccv, snd_cwnd); + htcp_data->prev_cwnd = cwin; } ENTER_RECOVERY(CCV(ccv, t_flags)); } @@ -305,7 +310,7 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) htcp_ssthresh_update(ccv); CCV(ccv, snd_cwnd) = CCV(ccv, snd_ssthresh); htcp_data->t_last_cong = ticks; - htcp_data->prev_cwnd = CCV(ccv, snd_cwnd); + htcp_data->prev_cwnd = cwin; ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } break; @@ -320,6 +325,8 @@ htcp_cong_signal(struct cc_var *ccv, uint32_t type) */ if (CCV(ccv, t_rxtshift) >= 2) htcp_data->t_last_cong = ticks; + CCV(ccv, snd_ssthresh) = max(2 * mss, cwin / 2); + CCV(ccv, snd_cwnd) = mss; break; } } diff --git a/sys/netinet/cc/cc_newreno.c b/sys/netinet/cc/cc_newreno.c index b2c72fe9fcb1..3aa16019657d 100644 --- a/sys/netinet/cc/cc_newreno.c +++ b/sys/netinet/cc/cc_newreno.c @@ -182,30 +182,39 @@ newreno_after_idle(struct cc_var *ccv) static void newreno_cong_signal(struct cc_var *ccv, uint32_t type) { - u_int win; + uint32_t cwin; + u_int mss; + + cwin = CCV(ccv, snd_cwnd); + mss = CCV(ccv, t_maxseg); /* Catch algos which mistakenly leak private signal types. */ KASSERT((type & CC_SIGPRIVMASK) == 0, ("%s: congestion signal type 0x%08x is private\n", __func__, type)); - win = max(CCV(ccv, snd_cwnd) / 2 / CCV(ccv, t_maxseg), 2) * - CCV(ccv, t_maxseg); + cwin = max(2*mss, cwin/2); switch (type) { case CC_NDUPACK: if (!IN_FASTRECOVERY(CCV(ccv, t_flags))) { - if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) - CCV(ccv, snd_ssthresh) = win; + if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { + CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_cwnd) = cwin; + } ENTER_RECOVERY(CCV(ccv, t_flags)); } break; case CC_ECN: if (!IN_CONGRECOVERY(CCV(ccv, t_flags))) { - CCV(ccv, snd_ssthresh) = win; - CCV(ccv, snd_cwnd) = win; + CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_cwnd) = cwin; ENTER_CONGRECOVERY(CCV(ccv, t_flags)); } break; + case CC_RTO: + CCV(ccv, snd_ssthresh) = cwin; + CCV(ccv, snd_cwnd) = mss; + break; } } diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index ed61e64a0ede..792818a9231d 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -438,9 +438,15 @@ cc_cong_signal(struct tcpcb *tp, struct tcphdr *th, uint32_t type) tp->t_dupacks = 0; tp->t_bytes_acked = 0; EXIT_RECOVERY(tp->t_flags); - tp->snd_ssthresh = max(2, min(tp->snd_wnd, tp->snd_cwnd) / 2 / - maxseg) * maxseg; - tp->snd_cwnd = maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) { + /* + * RFC5681 Section 3.1 + * ssthresh = max (FlightSize / 2, 2*SMSS) eq (4) + */ + tp->snd_ssthresh = + max((tp->snd_max - tp->snd_una) / 2, 2 * maxseg); + tp->snd_cwnd = maxseg; + } break; case CC_RTO_ERR: TCPSTAT_INC(tcps_sndrexmitbad); @@ -2613,6 +2619,15 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += maxseg; + /* + * RFC5681 Section 3.2 talks about cwnd + * inflation on additional dupacks and + * deflation on recovering from loss. + * + * We keep cwnd into check so that + * we don't have to 'deflate' it when we + * get out of recovery. + */ if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; } @@ -2652,19 +2667,22 @@ tcp_do_segment(struct mbuf *m, struct tcphdr *th, struct socket *so, TCPSTAT_INC( tcps_sack_recovery_episode); tp->sack_newdata = tp->snd_nxt; - tp->snd_cwnd = maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = maxseg; (void) tp->t_fb->tfb_tcp_output(tp); goto drop; } tp->snd_nxt = th->th_ack; - tp->snd_cwnd = maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = maxseg; (void) tp->t_fb->tfb_tcp_output(tp); KASSERT(tp->snd_limited <= 2, ("%s: tp->snd_limited too big", __func__)); - tp->snd_cwnd = tp->snd_ssthresh + - maxseg * - (tp->t_dupacks - tp->snd_limited); + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = tp->snd_ssthresh + + maxseg * + (tp->t_dupacks - tp->snd_limited); if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; diff --git a/sys/netinet/tcp_stacks/fastpath.c b/sys/netinet/tcp_stacks/fastpath.c index a31a28e70f69..2d7db04fbc1e 100644 --- a/sys/netinet/tcp_stacks/fastpath.c +++ b/sys/netinet/tcp_stacks/fastpath.c @@ -1119,6 +1119,15 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, struct socket *so, if (awnd < tp->snd_ssthresh) { tp->snd_cwnd += tp->t_maxseg; + /* + * RFC5681 Section 3.2 talks about cwnd + * inflation on additional dupacks and + * deflation on recovering from loss. + * + * We keep cwnd into check so that + * we don't have to 'deflate' it when we + * get out of recovery. + */ if (tp->snd_cwnd > tp->snd_ssthresh) tp->snd_cwnd = tp->snd_ssthresh; } @@ -1158,19 +1167,22 @@ tcp_do_slowpath(struct mbuf *m, struct tcphdr *th, struct socket *so, TCPSTAT_INC( tcps_sack_recovery_episode); tp->sack_newdata = tp->snd_nxt; - tp->snd_cwnd = tp->t_maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = tp->t_maxseg; (void) tp->t_fb->tfb_tcp_output(tp); goto drop; } tp->snd_nxt = th->th_ack; - tp->snd_cwnd = tp->t_maxseg; + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = tp->t_maxseg; (void) tp->t_fb->tfb_tcp_output(tp); KASSERT(tp->snd_limited <= 2, ("%s: tp->snd_limited too big", __func__)); - tp->snd_cwnd = tp->snd_ssthresh + - tp->t_maxseg * - (tp->t_dupacks - tp->snd_limited); + if (CC_ALGO(tp)->cong_signal == NULL) + tp->snd_cwnd = tp->snd_ssthresh + + tp->t_maxseg * + (tp->t_dupacks - tp->snd_limited); if (SEQ_GT(onxt, tp->snd_nxt)) tp->snd_nxt = onxt; goto drop; From 88f9a4ff7582ce2283e746e7ea3f56ccd3270543 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 25 Oct 2016 07:48:19 +0000 Subject: [PATCH 090/235] Make the USB attach strings in dmesg include product name. Note to self: MFC this to 9 and 8. Reviewed by: hselasky@, imp@ MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D8259 --- sys/dev/usb/usb_device.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index bc0f50e5ead3..56a6095a16e9 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -1938,8 +1938,8 @@ usb_alloc_device(device_t parent_dev, struct usb_bus *bus, udev->ugen_symlink = usb_alloc_symlink(udev->ugen_name); /* Announce device */ - printf("%s: <%s> at %s\n", udev->ugen_name, - usb_get_manufacturer(udev), + printf("%s: <%s %s> at %s\n", udev->ugen_name, + usb_get_manufacturer(udev), usb_get_product(udev), device_get_nameunit(udev->bus->bdev)); #endif @@ -2148,8 +2148,9 @@ usb_free_device(struct usb_device *udev, uint8_t flag) #if USB_HAVE_UGEN if (!rebooting) { - printf("%s: <%s> at %s (disconnected)\n", udev->ugen_name, - usb_get_manufacturer(udev), device_get_nameunit(bus->bdev)); + printf("%s: <%s %s> at %s (disconnected)\n", udev->ugen_name, + usb_get_manufacturer(udev), usb_get_product(udev), + device_get_nameunit(bus->bdev)); } /* Destroy UGEN symlink, if any */ From 3387e8743edb38ddc2d5715d167166cd6624e78d Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 25 Oct 2016 10:34:14 +0000 Subject: [PATCH 091/235] vmm/svm: iopm_bitmap and msr_bitmap must be contiguous in physical memory To achieve that the whole svm_softc is allocated with contigmalloc now. It would be more effient to de-embed those arrays and allocate only them with contigmalloc. Previously, if malloc(9) used non-contiguous pages for the arrays, then random bits in physical pages next to the first page would be used to determine permissions for I/O port and MSR accesses. That could result in a guest dangerously modifying the host hardware configuration. One example is that sometimes NMI watchdog driver in a Linux guest would be able to configure a performance counter on a host system. The counter would generate an interrupt and if hwpmc(4) driver is loaded on the host, then the interrupt would be delivered as an NMI. Discussed with: jhb Reviewed by: grehan MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D8321 --- sys/amd64/vmm/amd/svm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index bd70d1135b44..6826cd802e88 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -517,7 +517,8 @@ svm_vminit(struct vm *vm, pmap_t pmap) vm_paddr_t msrpm_pa, iopm_pa, pml4_pa; int i; - svm_sc = malloc(sizeof (struct svm_softc), M_SVM, M_WAITOK | M_ZERO); + svm_sc = contigmalloc(sizeof (*svm_sc), M_SVM, M_WAITOK | M_ZERO, + 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); svm_sc->vm = vm; svm_sc->nptp = (vm_offset_t)vtophys(pmap->pm_pml4); @@ -2042,7 +2043,7 @@ svm_vmcleanup(void *arg) { struct svm_softc *sc = arg; - free(sc, M_SVM); + contigfree(sc, sizeof (*sc), M_SVM); } static register_t * From 1ea776522672566cb51d44d7e65c52add7c523a9 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 25 Oct 2016 10:59:21 +0000 Subject: [PATCH 092/235] fix up r307903, use correct max address definition MFC after: 1 week X-MFC with: r307903 --- sys/amd64/vmm/amd/svm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index 6826cd802e88..2b29d061e020 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "vmm_lapic.h" #include "vmm_stat.h" @@ -518,7 +519,7 @@ svm_vminit(struct vm *vm, pmap_t pmap) int i; svm_sc = contigmalloc(sizeof (*svm_sc), M_SVM, M_WAITOK | M_ZERO, - 0, BUS_SPACE_MAXADDR, PAGE_SIZE, 0); + 0, VM_MAX_ADDRESS, PAGE_SIZE, 0); svm_sc->vm = vm; svm_sc->nptp = (vm_offset_t)vtophys(pmap->pm_pml4); From ce9fa35b3507673fcc1fb00753736fe1102bc4cb Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 13:45:59 +0000 Subject: [PATCH 093/235] Update the armv6 tlb handling functions to detect if it is running on hardware that supports the mp extensions. If so it should use the broadcast tlb invalidate instructions as other CPUs or devices may need to know about the invalidation. To simplify the code have the compiler optimise out the else case when not builing for Cortex-A8. Sponsored by: ABT Systems Ltd Differential Revision: https://reviews.freebsd.org/D8092 --- sys/arm/include/cpu-v6.h | 73 ++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 22 deletions(-) diff --git a/sys/arm/include/cpu-v6.h b/sys/arm/include/cpu-v6.h index aa2ec2618164..e11e0f766fbb 100644 --- a/sys/arm/include/cpu-v6.h +++ b/sys/arm/include/cpu-v6.h @@ -347,12 +347,21 @@ tlb_flush_range_local(vm_offset_t va, vm_size_t size) /* Broadcasting operations. */ #if __ARM_ARCH >= 7 && defined SMP +#if defined(CPU_CORTEXA8) +#define ARM_HAVE_MP_EXTENSIONS (cpuinfo.mp_ext != 0) +#else +#define ARM_HAVE_MP_EXTENSIONS 1 +#endif + static __inline void tlb_flush_all(void) { dsb(); - _CP15_TLBIALLIS(); + if (ARM_HAVE_MP_EXTENSIONS) + _CP15_TLBIALLIS(); + else + _CP15_TLBIALL(); dsb(); } @@ -361,7 +370,10 @@ tlb_flush_all_ng(void) { dsb(); - _CP15_TLBIASIDIS(CPU_ASID_KERNEL); + if (ARM_HAVE_MP_EXTENSIONS) + _CP15_TLBIASIDIS(CPU_ASID_KERNEL); + else + _CP15_TLBIASID(CPU_ASID_KERNEL); dsb(); } @@ -372,7 +384,10 @@ tlb_flush(vm_offset_t va) KASSERT((va & PAGE_MASK) == 0, ("%s: va %#x not aligned", __func__, va)); dsb(); - _CP15_TLBIMVAAIS(va); + if (ARM_HAVE_MP_EXTENSIONS) + _CP15_TLBIMVAAIS(va); + else + _CP15_TLBIMVA(va | CPU_ASID_KERNEL); dsb(); } @@ -386,8 +401,13 @@ tlb_flush_range(vm_offset_t va, vm_size_t size) size)); dsb(); - for (; va < eva; va += PAGE_SIZE) - _CP15_TLBIMVAAIS(va); + if (ARM_HAVE_MP_EXTENSIONS) { + for (; va < eva; va += PAGE_SIZE) + _CP15_TLBIMVAAIS(va); + } else { + for (; va < eva; va += PAGE_SIZE) + _CP15_TLBIMVA(va | CPU_ASID_KERNEL); + } dsb(); } #else /* SMP */ @@ -411,19 +431,23 @@ icache_sync(vm_offset_t va, vm_size_t size) dsb(); va &= ~cpuinfo.dcache_line_mask; - for ( ; va < eva; va += cpuinfo.dcache_line_size) { #if __ARM_ARCH >= 7 && defined SMP - _CP15_DCCMVAU(va); -#else - _CP15_DCCMVAC(va); + if (ARM_HAVE_MP_EXTENSIONS) { + for ( ; va < eva; va += cpuinfo.dcache_line_size) + _CP15_DCCMVAU(va); + } else #endif + { + for ( ; va < eva; va += cpuinfo.dcache_line_size) + _CP15_DCCMVAC(va); } dsb(); #if __ARM_ARCH >= 7 && defined SMP - _CP15_ICIALLUIS(); -#else - _CP15_ICIALLU(); + if (ARM_HAVE_MP_EXTENSIONS) + _CP15_ICIALLUIS(); + else #endif + _CP15_ICIALLU(); dsb(); isb(); } @@ -433,10 +457,11 @@ static __inline void icache_inv_all(void) { #if __ARM_ARCH >= 7 && defined SMP - _CP15_ICIALLUIS(); -#else - _CP15_ICIALLU(); + if (ARM_HAVE_MP_EXTENSIONS) + _CP15_ICIALLUIS(); + else #endif + _CP15_ICIALLU(); dsb(); isb(); } @@ -446,10 +471,11 @@ static __inline void bpb_inv_all(void) { #if __ARM_ARCH >= 7 && defined SMP - _CP15_BPIALLIS(); -#else - _CP15_BPIALL(); + if (ARM_HAVE_MP_EXTENSIONS) + _CP15_BPIALLIS(); + else #endif + _CP15_BPIALL(); dsb(); isb(); } @@ -462,12 +488,15 @@ dcache_wb_pou(vm_offset_t va, vm_size_t size) dsb(); va &= ~cpuinfo.dcache_line_mask; - for ( ; va < eva; va += cpuinfo.dcache_line_size) { #if __ARM_ARCH >= 7 && defined SMP - _CP15_DCCMVAU(va); -#else - _CP15_DCCMVAC(va); + if (ARM_HAVE_MP_EXTENSIONS) { + for ( ; va < eva; va += cpuinfo.dcache_line_size) + _CP15_DCCMVAU(va); + } else #endif + { + for ( ; va < eva; va += cpuinfo.dcache_line_size) + _CP15_DCCMVAC(va); } dsb(); } From 3ad9f8d0247210e8ab1324cb289a354ed9b16bc6 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 14:01:13 +0000 Subject: [PATCH 094/235] Fix the build on both arm64 and when WITHOUT_FORTH is defined. * On arm64 we need to use the ${MACHINE_CPUARCH} subdirectory. * env.c is only needed when using forth so only build it there. Sponsored by: ABT Systems Ltd --- sys/boot/efi/libefi/Makefile | 10 ++++++++-- sys/boot/efi/loader/main.c | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile index 5fda2eaf0c87..a1d55fd9403c 100644 --- a/sys/boot/efi/libefi/Makefile +++ b/sys/boot/efi/libefi/Makefile @@ -1,10 +1,12 @@ # $FreeBSD$ +.include + LIB= efi INTERNALLIB= WARNS?= 2 -SRCS= delay.c devpath.c efi_console.c efinet.c efipart.c env.c errno.c \ +SRCS= delay.c devpath.c efi_console.c efinet.c efipart.c errno.c \ handles.c libefi.c .if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" @@ -12,6 +14,11 @@ SRCS+= time.c .elif ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" SRCS+= time_event.c .endif +.if ${MK_FORTH} != "no" +SRCS+= env.c +CFLAGS+= -I${.CURDIR}/../../ficl +CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH} +.endif # We implement a slightly non-standard %S in that it always takes a # CHAR16 that's common in UEFI-land instead of a wchar_t. This only @@ -26,7 +33,6 @@ CFLAGS+= -msoft-float -mgeneral-regs-only .if ${MACHINE_ARCH} == "amd64" CFLAGS+= -fPIC -mno-red-zone .endif -CFLAGS+= -I${.CURDIR}/../../ficl -I${.CURDIR}/../../ficl/${MACHINE} CFLAGS+= -I${.CURDIR}/../include CFLAGS+= -I${.CURDIR}/../include/${MACHINE} CFLAGS+= -I${.CURDIR}/../../../../lib/libstand diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index e1d0b64f95d6..3e48cf361095 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -55,9 +55,11 @@ extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; +#ifdef BOOT_FORTH /* Force a reference to bring in EFI support from the library */ extern int efi_variable_support; int *dummy1 = &efi_variable_support; +#endif struct arch_switch archsw; /* MI/MD interface boundary */ From 02e1c9861d9037f5ca8a880de763dd9673b6bece Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 14:04:35 +0000 Subject: [PATCH 095/235] Import the Cortex String memcpy and memmove into the kernel. On ThunderX these show a 9-10% reduction in user and system time for a buildworld -j48. Obtained from: ABT Systems Ltd MFC after: 1 week Sponsored by: The FreeBSD Foundation --- sys/arm64/arm64/bcopy.c | 139 ------------------------ sys/arm64/arm64/memcpy.S | 219 ++++++++++++++++++++++++++++++++++++++ sys/arm64/arm64/memmove.S | 150 ++++++++++++++++++++++++++ sys/conf/files.arm64 | 4 +- 4 files changed, 371 insertions(+), 141 deletions(-) delete mode 100644 sys/arm64/arm64/bcopy.c create mode 100644 sys/arm64/arm64/memcpy.S create mode 100644 sys/arm64/arm64/memmove.S diff --git a/sys/arm64/arm64/bcopy.c b/sys/arm64/arm64/bcopy.c deleted file mode 100644 index 613ca97e5430..000000000000 --- a/sys/arm64/arm64/bcopy.c +++ /dev/null @@ -1,139 +0,0 @@ -/*- - * Copyright (c) 1990 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * 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. - * - * From: sys/powerpc/powerpc/bcopy.c - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include - -/* - * sizeof(word) MUST BE A POWER OF TWO - * SO THAT wmask BELOW IS ALL ONES - */ -typedef long word; /* "word" used for optimal copy speed */ - -#define wsize sizeof(word) -#define wmask (wsize - 1) - -/* - * Copy a block of memory, handling overlap. - * This is the routine that actually implements - * (the portable versions of) bcopy, memcpy, and memmove. - */ -void * -memcpy(void *dst0, const void *src0, size_t length) -{ - char *dst; - const char *src; - size_t t; - - dst = dst0; - src = src0; - - if (length == 0 || dst == src) { /* nothing to do */ - goto done; - } - - /* - * Macros: loop-t-times; and loop-t-times, t>0 - */ -#define TLOOP(s) if (t) TLOOP1(s) -#define TLOOP1(s) do { s; } while (--t) - - if ((unsigned long)dst < (unsigned long)src) { - /* - * Copy forward. - */ - t = (size_t)src; /* only need low bits */ - - if ((t | (uintptr_t)dst) & wmask) { - /* - * Try to align operands. This cannot be done - * unless the low bits match. - */ - if ((t ^ (uintptr_t)dst) & wmask || length < wsize) { - t = length; - } else { - t = wsize - (t & wmask); - } - - length -= t; - TLOOP1(*dst++ = *src++); - } - /* - * Copy whole words, then mop up any trailing bytes. - */ - t = length / wsize; - TLOOP(*(word *)dst = *(const word *)src; src += wsize; - dst += wsize); - t = length & wmask; - TLOOP(*dst++ = *src++); - } else { - /* - * Copy backwards. Otherwise essentially the same. - * Alignment works as before, except that it takes - * (t&wmask) bytes to align, not wsize-(t&wmask). - */ - src += length; - dst += length; - t = (uintptr_t)src; - - if ((t | (uintptr_t)dst) & wmask) { - if ((t ^ (uintptr_t)dst) & wmask || length <= wsize) { - t = length; - } else { - t &= wmask; - } - - length -= t; - TLOOP1(*--dst = *--src); - } - t = length / wsize; - TLOOP(src -= wsize; dst -= wsize; - *(word *)dst = *(const word *)src); - t = length & wmask; - TLOOP(*--dst = *--src); - } -done: - return (dst0); -} - -void -bcopy(const void *src0, void *dst0, size_t length) -{ - - memcpy(dst0, src0, length); -} - diff --git a/sys/arm64/arm64/memcpy.S b/sys/arm64/arm64/memcpy.S new file mode 100644 index 000000000000..f98c2513fa58 --- /dev/null +++ b/sys/arm64/arm64/memcpy.S @@ -0,0 +1,219 @@ +/* Copyright (c) 2012, Linaro Limited + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the Linaro nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT + HOLDER 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. */ + +/* + * Copyright (c) 2015 ARM Ltd + * 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. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* Assumptions: + * + * ARMv8-a, AArch64, unaligned accesses. + * + */ + +#define dstin x0 +#define src x1 +#define count x2 +#define dst x3 +#define srcend x4 +#define dstend x5 +#define A_l x6 +#define A_lw w6 +#define A_h x7 +#define A_hw w7 +#define B_l x8 +#define B_lw w8 +#define B_h x9 +#define C_l x10 +#define C_h x11 +#define D_l x12 +#define D_h x13 +#define E_l src +#define E_h count +#define F_l srcend +#define F_h dst +#define tmp1 x9 + +#define L(l) .L ## l + +/* Copies are split into 3 main cases: small copies of up to 16 bytes, + medium copies of 17..96 bytes which are fully unrolled. Large copies + of more than 96 bytes align the destination and use an unrolled loop + processing 64 bytes per iteration. + Small and medium copies read all data before writing, allowing any + kind of overlap, and memmove tailcalls memcpy for these cases as + well as non-overlapping copies. +*/ + +ENTRY(memcpy) + prfm PLDL1KEEP, [src] + add srcend, src, count + add dstend, dstin, count + cmp count, 16 + b.ls L(copy16) + cmp count, 96 + b.hi L(copy_long) + + /* Medium copies: 17..96 bytes. */ + sub tmp1, count, 1 + ldp A_l, A_h, [src] + tbnz tmp1, 6, L(copy96) + ldp D_l, D_h, [srcend, -16] + tbz tmp1, 5, 1f + ldp B_l, B_h, [src, 16] + ldp C_l, C_h, [srcend, -32] + stp B_l, B_h, [dstin, 16] + stp C_l, C_h, [dstend, -32] +1: + stp A_l, A_h, [dstin] + stp D_l, D_h, [dstend, -16] + ret + + .p2align 4 + /* Small copies: 0..16 bytes. */ +L(copy16): + cmp count, 8 + b.lo 1f + ldr A_l, [src] + ldr A_h, [srcend, -8] + str A_l, [dstin] + str A_h, [dstend, -8] + ret + .p2align 4 +1: + tbz count, 2, 1f + ldr A_lw, [src] + ldr A_hw, [srcend, -4] + str A_lw, [dstin] + str A_hw, [dstend, -4] + ret + + /* Copy 0..3 bytes. Use a branchless sequence that copies the same + byte 3 times if count==1, or the 2nd byte twice if count==2. */ +1: + cbz count, 2f + lsr tmp1, count, 1 + ldrb A_lw, [src] + ldrb A_hw, [srcend, -1] + ldrb B_lw, [src, tmp1] + strb A_lw, [dstin] + strb B_lw, [dstin, tmp1] + strb A_hw, [dstend, -1] +2: ret + + .p2align 4 + /* Copy 64..96 bytes. Copy 64 bytes from the start and + 32 bytes from the end. */ +L(copy96): + ldp B_l, B_h, [src, 16] + ldp C_l, C_h, [src, 32] + ldp D_l, D_h, [src, 48] + ldp E_l, E_h, [srcend, -32] + ldp F_l, F_h, [srcend, -16] + stp A_l, A_h, [dstin] + stp B_l, B_h, [dstin, 16] + stp C_l, C_h, [dstin, 32] + stp D_l, D_h, [dstin, 48] + stp E_l, E_h, [dstend, -32] + stp F_l, F_h, [dstend, -16] + ret + + /* Align DST to 16 byte alignment so that we don't cross cache line + boundaries on both loads and stores. There are at least 96 bytes + to copy, so copy 16 bytes unaligned and then align. The loop + copies 64 bytes per iteration and prefetches one iteration ahead. */ + + .p2align 4 +L(copy_long): + and tmp1, dstin, 15 + bic dst, dstin, 15 + ldp D_l, D_h, [src] + sub src, src, tmp1 + add count, count, tmp1 /* Count is now 16 too large. */ + ldp A_l, A_h, [src, 16] + stp D_l, D_h, [dstin] + ldp B_l, B_h, [src, 32] + ldp C_l, C_h, [src, 48] + ldp D_l, D_h, [src, 64]! + subs count, count, 128 + 16 /* Test and readjust count. */ + b.ls 2f +1: + stp A_l, A_h, [dst, 16] + ldp A_l, A_h, [src, 16] + stp B_l, B_h, [dst, 32] + ldp B_l, B_h, [src, 32] + stp C_l, C_h, [dst, 48] + ldp C_l, C_h, [src, 48] + stp D_l, D_h, [dst, 64]! + ldp D_l, D_h, [src, 64]! + subs count, count, 64 + b.hi 1b + + /* Write the last full set of 64 bytes. The remainder is at most 64 + bytes, so it is safe to always copy 64 bytes from the end even if + there is just 1 byte left. */ +2: + ldp E_l, E_h, [srcend, -64] + stp A_l, A_h, [dst, 16] + ldp A_l, A_h, [srcend, -48] + stp B_l, B_h, [dst, 32] + ldp B_l, B_h, [srcend, -32] + stp C_l, C_h, [dst, 48] + ldp C_l, C_h, [srcend, -16] + stp D_l, D_h, [dst, 64] + stp E_l, E_h, [dstend, -64] + stp A_l, A_h, [dstend, -48] + stp B_l, B_h, [dstend, -32] + stp C_l, C_h, [dstend, -16] + ret +END(memcpy) diff --git a/sys/arm64/arm64/memmove.S b/sys/arm64/arm64/memmove.S new file mode 100644 index 000000000000..4b99dccc536e --- /dev/null +++ b/sys/arm64/arm64/memmove.S @@ -0,0 +1,150 @@ +/* Copyright (c) 2013, Linaro Limited + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the Linaro nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT + HOLDER 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. */ + +/* + * Copyright (c) 2015 ARM Ltd + * 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. + * 3. The name of the company may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY ARM LTD ``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 ARM LTD 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* Assumptions: + * + * ARMv8-a, AArch64, unaligned accesses + */ + +/* Parameters and result. */ +#define dstin x0 +#define src x1 +#define count x2 +#define srcend x3 +#define dstend x4 +#define tmp1 x5 +#define A_l x6 +#define A_h x7 +#define B_l x8 +#define B_h x9 +#define C_l x10 +#define C_h x11 +#define D_l x12 +#define D_h x13 +#define E_l count +#define E_h tmp1 + +/* All memmoves up to 96 bytes are done by memcpy as it supports overlaps. + Larger backwards copies are also handled by memcpy. The only remaining + case is forward large copies. The destination is aligned, and an + unrolled loop processes 64 bytes per iteration. +*/ + +ENTRY(bcopy) + /* Switch the input pointers when called as bcopy */ + mov x3, x1 + mov x1, x0 + mov x0, x3 +EENTRY(memmove) + sub tmp1, dstin, src + cmp count, 96 + ccmp tmp1, count, 2, hi + b.hs memcpy + + cbz tmp1, 3f + add dstend, dstin, count + add srcend, src, count + + /* Align dstend to 16 byte alignment so that we don't cross cache line + boundaries on both loads and stores. There are at least 96 bytes + to copy, so copy 16 bytes unaligned and then align. The loop + copies 64 bytes per iteration and prefetches one iteration ahead. */ + + and tmp1, dstend, 15 + ldp D_l, D_h, [srcend, -16] + sub srcend, srcend, tmp1 + sub count, count, tmp1 + ldp A_l, A_h, [srcend, -16] + stp D_l, D_h, [dstend, -16] + ldp B_l, B_h, [srcend, -32] + ldp C_l, C_h, [srcend, -48] + ldp D_l, D_h, [srcend, -64]! + sub dstend, dstend, tmp1 + subs count, count, 128 + b.ls 2f + nop +1: + stp A_l, A_h, [dstend, -16] + ldp A_l, A_h, [srcend, -16] + stp B_l, B_h, [dstend, -32] + ldp B_l, B_h, [srcend, -32] + stp C_l, C_h, [dstend, -48] + ldp C_l, C_h, [srcend, -48] + stp D_l, D_h, [dstend, -64]! + ldp D_l, D_h, [srcend, -64]! + subs count, count, 64 + b.hi 1b + + /* Write the last full set of 64 bytes. The remainder is at most 64 + bytes, so it is safe to always copy 64 bytes from the start even if + there is just 1 byte left. */ +2: + ldp E_l, E_h, [src, 48] + stp A_l, A_h, [dstend, -16] + ldp A_l, A_h, [src, 32] + stp B_l, B_h, [dstend, -32] + ldp B_l, B_h, [src, 16] + stp C_l, C_h, [dstend, -48] + ldp C_l, C_h, [src] + stp D_l, D_h, [dstend, -64] + stp E_l, E_h, [dstin, 48] + stp A_l, A_h, [dstin, 32] + stp B_l, B_h, [dstin, 16] + stp C_l, C_h, [dstin] +3: ret +EEND(memmove) +END(bcopy) diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 2feac5041985..ea7b7d4b4431 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -72,7 +72,6 @@ arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi arm64/acpica/pci_cfgreg.c optional acpi pci arm64/arm64/autoconf.c standard -arm64/arm64/bcopy.c standard arm64/arm64/bus_machdep.c standard arm64/arm64/bus_space_asm.S standard arm64/arm64/busdma_bounce.c standard @@ -98,6 +97,8 @@ arm64/arm64/in_cksum.c optional inet | inet6 arm64/arm64/locore.S standard no-obj arm64/arm64/machdep.c standard arm64/arm64/mem.c standard +arm64/arm64/memcpy.S standard +arm64/arm64/memmove.S standard arm64/arm64/minidump_machdep.c standard arm64/arm64/mp_machdep.c optional smp arm64/arm64/nexus.c standard @@ -178,7 +179,6 @@ libkern/ffsll.c standard libkern/fls.c standard libkern/flsl.c standard libkern/flsll.c standard -libkern/memmove.c standard libkern/memset.c standard cddl/contrib/opensolaris/common/atomic/aarch64/opensolaris_atomic.S optional zfs | dtrace compile-with "${CDDL_C}" cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" From c2dd354bf4d3f8256d9e35d184369f939db96b96 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 14:18:27 +0000 Subject: [PATCH 096/235] Create a new PSCI error code and use it to signal that starting the CPU is impossible as the PSCI firmware is missing. Sponsored by: ABT Systmes Ltd --- sys/arm64/arm64/mp_machdep.c | 10 +++++++--- sys/dev/psci/psci.c | 4 ++-- sys/dev/psci/psci.h | 4 ++++ 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index 6fbb610dd6c0..4361cef888a1 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -461,9 +461,13 @@ cpu_init_fdt(u_int id, phandle_t node, u_int addr_size, pcell_t *reg) err = psci_cpu_on(target_cpu, pa, cpuid); if (err != PSCI_RETVAL_SUCCESS) { - /* Panic here if INVARIANTS are enabled */ - KASSERT(0, ("Failed to start CPU %u (%lx)\n", id, - target_cpu)); + /* + * Panic here if INVARIANTS are enabled and PSCI failed to + * start the requested CPU. If psci_cpu_on returns PSCI_MISSING + * to indicate we are unable to use it to start the given CPU. + */ + KASSERT(err == PSCI_MISSING, + ("Failed to start CPU %u (%lx)\n", id, target_cpu)); pcpu_destroy(pcpup); kmem_free(kernel_arena, (vm_offset_t)dpcpu[cpuid - 1], diff --git a/sys/dev/psci/psci.c b/sys/dev/psci/psci.c index c5fe0fbc443e..f7050976c8c6 100644 --- a/sys/dev/psci/psci.c +++ b/sys/dev/psci/psci.c @@ -189,12 +189,12 @@ psci_cpu_on(unsigned long cpu, unsigned long entry, unsigned long context_id) node = ofw_bus_find_compatible(OF_peer(0), "arm,psci-0.2"); if (node == 0) /* TODO: Handle psci 0.1 */ - return (PSCI_RETVAL_INTERNAL_FAILURE); + return (PSCI_MISSING); fnid = PSCI_FNID_CPU_ON; callfn = psci_get_callfn(node); if (callfn == NULL) - return (PSCI_RETVAL_INTERNAL_FAILURE); + return (PSCI_MISSING); } else { callfn = psci_softc->psci_call; fnid = psci_softc->psci_fnids[PSCI_FN_CPU_ON]; diff --git a/sys/dev/psci/psci.h b/sys/dev/psci/psci.h index 58f1e791d0c0..7f447abaf444 100644 --- a/sys/dev/psci/psci.h +++ b/sys/dev/psci/psci.h @@ -54,6 +54,10 @@ int psci_smc_despatch(register_t, register_t, register_t, register_t); #define PSCI_RETVAL_INTERNAL_FAILURE -6 #define PSCI_RETVAL_NOT_PRESENT -7 #define PSCI_RETVAL_DISABLED -8 +/* + * Used to signal PSCI is not available, e.g. to start a CPU. + */ +#define PSCI_MISSING 1 /* * PSCI function codes (as per PSCI v0.2). From 405804dd312ee1dd5cd60ab527ddc3a964338322 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 25 Oct 2016 14:42:09 +0000 Subject: [PATCH 097/235] Add better comment... --- sys/boot/efi/loader/main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index 3e48cf361095..c6f30a9e4229 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -56,7 +56,17 @@ extern char bootprog_date[]; extern char bootprog_maker[]; #ifdef BOOT_FORTH -/* Force a reference to bring in EFI support from the library */ +/* + * Normally, efi.o from libefi.a would be brought in due to a function we call + * there that's defined there. However, none of its functions are callable from + * here since it just adds words to the FORTH environment or implement those + * words. So, add a reference to a symbol in efi.o to force it to be be brought + * in so the init function there gets added to the "compile" linker set happens + * correctly. + * + * This assumes there's no global analysys that notices dummy1 isn't used + * anywhere and tries to eliminate it. + */ extern int efi_variable_support; int *dummy1 = &efi_variable_support; #endif From a146e36c02b36050a59febfa6550ee42bbf62a16 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Tue, 25 Oct 2016 15:20:06 +0000 Subject: [PATCH 098/235] accept4 actually expect SOCK_NONBLOCK and not O_NONBLOCK Reported by: jhb Pointyhat to: bapt --- usr.sbin/bhyve/dbgport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/bhyve/dbgport.c b/usr.sbin/bhyve/dbgport.c index 6e6c83f0408a..14214027d883 100644 --- a/usr.sbin/bhyve/dbgport.c +++ b/usr.sbin/bhyve/dbgport.c @@ -73,7 +73,7 @@ dbg_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes, printf("Waiting for connection from gdb\r\n"); printonce = 1; } - conn_fd = accept4(listen_fd, NULL, NULL, O_NONBLOCK); + conn_fd = accept4(listen_fd, NULL, NULL, SOCK_NONBLOCK); if (conn_fd < 0 && errno != EINTR) perror("accept"); } From 6a9f23793df57c211bedc670e96a52e71fab97e2 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Tue, 25 Oct 2016 15:21:08 +0000 Subject: [PATCH 099/235] allwinner A10 Pll1 allow changing freq PLL1 is used by the cpu core, allowing changing freq is needed for cpufreq. The factors table contains all the frequencies in the operating point table present in the DTS. MFC after: 1 week --- sys/arm/allwinner/clk/aw_pll.c | 53 +++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c index b5ee409c95d3..2629d2330ee5 100644 --- a/sys/arm/allwinner/clk/aw_pll.c +++ b/sys/arm/allwinner/clk/aw_pll.c @@ -192,6 +192,16 @@ struct aw_pll_factor { #define PLLFACTOR(_n, _k, _m, _p, _freq) \ { .n = (_n), .k = (_k), .m = (_m), .p = (_p), .freq = (_freq) } +static struct aw_pll_factor aw_a10_pll1_factors[] = { + PLLFACTOR(6, 0, 0, 0, 144000000), + PLLFACTOR(12, 0, 0, 0, 312000000), + PLLFACTOR(21, 0, 0, 0, 528000000), + PLLFACTOR(29, 0, 0, 0, 720000000), + PLLFACTOR(18, 1, 0, 0, 864000000), + PLLFACTOR(19, 1, 0, 0, 912000000), + PLLFACTOR(20, 1, 0, 0, 960000000), +}; + static struct aw_pll_factor aw_a23_pll1_factors[] = { PLLFACTOR(9, 0, 0, 2, 60000000), PLLFACTOR(10, 0, 0, 2, 66000000), @@ -299,6 +309,47 @@ struct aw_pll_funcs { #define DEVICE_LOCK(sc) CLKDEV_DEVICE_LOCK((sc)->clkdev) #define DEVICE_UNLOCK(sc) CLKDEV_DEVICE_UNLOCK((sc)->clkdev) +static int +a10_pll1_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def) +{ + /* Allow changing PLL frequency while enabled */ + def->flags = CLK_NODE_GLITCH_FREE; + + return (0); +} + +static int +a10_pll1_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout, + int flags) +{ + struct aw_pll_factor *f; + uint32_t val; + int n; + + f = NULL; + for (n = 0; n < nitems(aw_a10_pll1_factors); n++) { + if (aw_a10_pll1_factors[n].freq == *fout) { + f = &aw_a10_pll1_factors[n]; + break; + } + } + if (f == NULL) + return (EINVAL); + + DEVICE_LOCK(sc); + PLL_READ(sc, &val); + val &= ~(A10_PLL1_FACTOR_N|A10_PLL1_FACTOR_K|A10_PLL1_FACTOR_M| + A10_PLL1_OUT_EXT_DIVP); + val |= (f->p << A10_PLL1_OUT_EXT_DIVP_SHIFT); + val |= (f->n << A10_PLL1_FACTOR_N_SHIFT); + val |= (f->k << A10_PLL1_FACTOR_K_SHIFT); + val |= (f->m << A10_PLL1_FACTOR_M_SHIFT); + PLL_WRITE(sc, val); + DEVICE_UNLOCK(sc); + + return (0); +} + static int a10_pll1_recalc(struct aw_pll_sc *sc, uint64_t *freq) { @@ -948,7 +999,7 @@ a83t_pllcpux_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout, } static struct aw_pll_funcs aw_pll_func[] = { - PLL(AWPLL_A10_PLL1, a10_pll1_recalc, NULL, NULL), + PLL(AWPLL_A10_PLL1, a10_pll1_recalc, a10_pll1_set_freq, a10_pll1_init), PLL(AWPLL_A10_PLL2, a10_pll2_recalc, a10_pll2_set_freq, NULL), PLL(AWPLL_A10_PLL3, a10_pll3_recalc, a10_pll3_set_freq, a10_pll3_init), PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL), From 46783b12e38e8c81ed2dea94a925ada0b8f58e6c Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Tue, 25 Oct 2016 16:21:38 +0000 Subject: [PATCH 100/235] Allow building makefs(8) from another Makefile (such as one in a seperate directory hierarchy used to build tools). This boils down to replacing the use of ${.CURDIR} with either ${SRCDIR} or ${SRCTOP}. SRCDIR is defined as the directory in which the Makefile lives that bmake(1) is currently reading. Use SRCTOP when reaching outside of makefs's directory. --- usr.sbin/makefs/Makefile | 20 +++++++++++--------- usr.sbin/makefs/cd9660/Makefile.inc | 4 ++-- usr.sbin/makefs/ffs/Makefile.inc | 4 ++-- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/usr.sbin/makefs/Makefile b/usr.sbin/makefs/Makefile index 7a0ebf0d0cbb..a02458044d25 100644 --- a/usr.sbin/makefs/Makefile +++ b/usr.sbin/makefs/Makefile @@ -1,10 +1,12 @@ # $FreeBSD$ +SRCDIR:=${.PARSEDIR:tA} + .include PROG= makefs -CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${SRCDIR} SRCS= cd9660.c ffs.c \ makefs.c \ @@ -14,24 +16,24 @@ MAN= makefs.8 WARNS?= 2 -.include "${.CURDIR}/cd9660/Makefile.inc" -.include "${.CURDIR}/ffs/Makefile.inc" +.include "${SRCDIR}/cd9660/Makefile.inc" +.include "${SRCDIR}/ffs/Makefile.inc" CFLAGS+=-DHAVE_STRUCT_STAT_ST_FLAGS=1 CFLAGS+=-DHAVE_STRUCT_STAT_ST_GEN=1 -.PATH: ${.CURDIR}/../../contrib/mtree -CFLAGS+=-I${.CURDIR}/../../contrib/mtree +.PATH: ${SRCTOP}/contrib/mtree +CFLAGS+=-I${SRCTOP}/contrib/mtree SRCS+= getid.c misc.c spec.c -.PATH: ${.CURDIR}/../../contrib/mknod -CFLAGS+=-I${.CURDIR}/../../contrib/mknod +.PATH: ${SRCTOP}/contrib/mknod +CFLAGS+=-I${SRCTOP}/contrib/mknod SRCS+= pack_dev.c -.PATH: ${.CURDIR}/../../sys/ufs/ffs +.PATH: ${SRCTOP}/sys/ufs/ffs SRCS+= ffs_tables.c -CFLAGS+= -I${.CURDIR}/../../lib/libnetbsd +CFLAGS+= -I${SRCTOP}/lib/libnetbsd LIBADD= netbsd util sbuf .if ${MK_TESTS} != "no" diff --git a/usr.sbin/makefs/cd9660/Makefile.inc b/usr.sbin/makefs/cd9660/Makefile.inc index 1455fcddaca6..a04664ed4928 100644 --- a/usr.sbin/makefs/cd9660/Makefile.inc +++ b/usr.sbin/makefs/cd9660/Makefile.inc @@ -1,9 +1,9 @@ # $FreeBSD$ # -.PATH: ${.CURDIR}/cd9660 ${.CURDIR}/../../sys/fs/cd9660/ +.PATH: ${SRCDIR}/cd9660 ${SRCTOP}/sys/fs/cd9660/ -CFLAGS+=-I${.CURDIR}/../../sys/fs/cd9660/ +CFLAGS+=-I${SRCTOP}/sys/fs/cd9660/ SRCS+= cd9660_strings.c cd9660_debug.c cd9660_eltorito.c \ cd9660_write.c cd9660_conversion.c iso9660_rrip.c cd9660_archimedes.c diff --git a/usr.sbin/makefs/ffs/Makefile.inc b/usr.sbin/makefs/ffs/Makefile.inc index d681c4eff773..2e9f1921b43f 100644 --- a/usr.sbin/makefs/ffs/Makefile.inc +++ b/usr.sbin/makefs/ffs/Makefile.inc @@ -1,9 +1,9 @@ # $FreeBSD$ # -.PATH: ${.CURDIR}/ffs ${.CURDIR}/../../sys/ufs/ffs +.PATH: ${SRCDIR}/ffs ${SRCTOP}/sys/ufs/ffs -CFLAGS+= -I${.CURDIR}/../../sys/ufs/ffs +CFLAGS+= -I${SRCTOP}/sys/ufs/ffs SRCS+= ffs_alloc.c ffs_balloc.c ffs_bswap.c ffs_subr.c ufs_bmap.c SRCS+= buf.c mkfs.c From ff300d23166aac356f4cf9f960d02ff7a3ba753e Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 16:25:06 +0000 Subject: [PATCH 101/235] Remove arm11x6_setttb and armv7_setttb as they are unused. While here remove unneeded code from the ARMv7 cpu assembly code. Sponsored by: ABT Systems Ltd --- sys/arm/arm/cpufunc_asm_arm11x6.S | 8 ------ sys/arm/arm/cpufunc_asm_armv7.S | 42 +------------------------------ sys/arm/include/cpufunc.h | 2 -- 3 files changed, 1 insertion(+), 51 deletions(-) diff --git a/sys/arm/arm/cpufunc_asm_arm11x6.S b/sys/arm/arm/cpufunc_asm_arm11x6.S index 02a698e650cd..8346211ec21e 100644 --- a/sys/arm/arm/cpufunc_asm_arm11x6.S +++ b/sys/arm/arm/cpufunc_asm_arm11x6.S @@ -64,14 +64,6 @@ __FBSDID("$FreeBSD$"); .cpu arm1176jz-s -ENTRY(arm11x6_setttb) - mov r1, #0 - mcr p15, 0, r0, c2, c0, 0 /* load new TTB */ - mcr p15, 0, r1, c8, c7, 0 /* invalidate I+D TLBs */ - mcr p15, 0, r1, c7, c10, 4 /* drain write buffer */ - RET -END(arm11x6_setttb) - /* * Preload the cache before issuing the WFI by conditionally disabling the * mcr intstructions the first time around the loop. Ensure the function is diff --git a/sys/arm/arm/cpufunc_asm_armv7.S b/sys/arm/arm/cpufunc_asm_armv7.S index d086fa893ea2..c6f14fe78da8 100644 --- a/sys/arm/arm/cpufunc_asm_armv7.S +++ b/sys/arm/arm/cpufunc_asm_armv7.S @@ -37,56 +37,16 @@ __FBSDID("$FreeBSD$"); .cpu cortex-a8 +#ifdef ELF_TRAMPOLINE .Lcoherency_level: .word _C_LABEL(arm_cache_loc) .Lcache_type: .word _C_LABEL(arm_cache_type) -.Larmv7_dcache_line_size: - .word _C_LABEL(arm_dcache_min_line_size) -.Larmv7_icache_line_size: - .word _C_LABEL(arm_icache_min_line_size) -.Larmv7_idcache_line_size: - .word _C_LABEL(arm_idcache_min_line_size) .Lway_mask: .word 0x3ff .Lmax_index: .word 0x7fff -.Lpage_mask: - .word 0xfff -#define PT_NOS (1 << 5) -#define PT_S (1 << 1) -#define PT_INNER_NC 0 -#define PT_INNER_WT (1 << 0) -#define PT_INNER_WB ((1 << 0) | (1 << 6)) -#define PT_INNER_WBWA (1 << 6) -#define PT_OUTER_NC 0 -#define PT_OUTER_WT (2 << 3) -#define PT_OUTER_WB (3 << 3) -#define PT_OUTER_WBWA (1 << 3) - -#ifdef SMP -#define PT_ATTR (PT_S|PT_INNER_WBWA|PT_OUTER_WBWA|PT_NOS) -#else -#define PT_ATTR (PT_INNER_WBWA|PT_OUTER_WBWA) -#endif - -ENTRY(armv7_setttb) - dsb - orr r0, r0, #PT_ATTR - mcr CP15_TTBR0(r0) - isb -#ifdef SMP - mcr CP15_TLBIALLIS -#else - mcr CP15_TLBIALL -#endif - dsb - isb - RET -END(armv7_setttb) - -#ifdef ELF_TRAMPOLINE /* Based on algorithm from ARM Architecture Reference Manual */ ENTRY(armv7_dcache_wbinv_all) stmdb sp!, {r4, r5, r6, r7, r8, r9} diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h index 7a007284a48b..dfe4b5dfc9f6 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -279,7 +279,6 @@ void armv6_idcache_wbinv_all (void); #endif #if defined(CPU_CORTEXA8) || defined(CPU_CORTEXA_MP) || \ defined(CPU_MV_PJ4B) || defined(CPU_KRAIT) -void armv7_setttb (u_int); void armv7_idcache_wbinv_all (void); void armv7_cpu_sleep (int); void armv7_setup (void); @@ -297,7 +296,6 @@ void pj4bv7_setup (void); #if defined(CPU_ARM1176) void arm11_drain_writebuf (void); -void arm11x6_setttb (u_int); void arm11x6_setup (void); void arm11x6_sleep (int); /* no ref. for errata */ #endif From 72b09927ed3ce7255a6a69c5cb15643cf24fb317 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 25 Oct 2016 16:28:30 +0000 Subject: [PATCH 102/235] Check m_getcl() return value. CID: 611376 --- sys/dev/bfe/if_bfe.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/bfe/if_bfe.c b/sys/dev/bfe/if_bfe.c index eaad8f0b5981..50cb173f8e73 100644 --- a/sys/dev/bfe/if_bfe.c +++ b/sys/dev/bfe/if_bfe.c @@ -793,6 +793,8 @@ bfe_list_newbuf(struct bfe_softc *sc, int c) int nsegs; m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); m->m_len = m->m_pkthdr.len = MCLBYTES; if (bus_dmamap_load_mbuf_sg(sc->bfe_rxmbuf_tag, sc->bfe_rx_sparemap, From 5d71efbecd873e18f487db1d88d9adb345963e95 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Tue, 25 Oct 2016 16:29:15 +0000 Subject: [PATCH 103/235] Be more precise when including headers so that we're less likely to depend on namespace pollution and as such become more portable. This means including headers like or , but also making sure we include system/host headers before local headers. While here: define ENOATTR as ENOMSG in mtree.c. There is no ENOATTR on Linux. With this, makefs is ready for compilation on macOS and Linux. --- usr.sbin/makefs/cd9660.c | 5 +++-- usr.sbin/makefs/cd9660/cd9660_archimedes.c | 2 ++ usr.sbin/makefs/cd9660/iso9660_rrip.c | 12 +++++++----- usr.sbin/makefs/ffs/ffs_bswap.c | 9 +++++---- usr.sbin/makefs/ffs/ffs_subr.c | 1 + usr.sbin/makefs/mtree.c | 5 +++++ usr.sbin/makefs/walk.c | 1 + 7 files changed, 24 insertions(+), 11 deletions(-) diff --git a/usr.sbin/makefs/cd9660.c b/usr.sbin/makefs/cd9660.c index 63d07736f425..0a1156de3627 100644 --- a/usr.sbin/makefs/cd9660.c +++ b/usr.sbin/makefs/cd9660.c @@ -98,10 +98,11 @@ #include __FBSDID("$FreeBSD$"); -#include -#include #include #include +#include +#include +#include #include "makefs.h" #include "cd9660.h" diff --git a/usr.sbin/makefs/cd9660/cd9660_archimedes.c b/usr.sbin/makefs/cd9660/cd9660_archimedes.c index d18a0f7b51c0..7a23e245ed8f 100644 --- a/usr.sbin/makefs/cd9660/cd9660_archimedes.c +++ b/usr.sbin/makefs/cd9660/cd9660_archimedes.c @@ -40,9 +40,11 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include +#include #include #include "makefs.h" diff --git a/usr.sbin/makefs/cd9660/iso9660_rrip.c b/usr.sbin/makefs/cd9660/iso9660_rrip.c index 749747ba5bd1..1d7539997971 100644 --- a/usr.sbin/makefs/cd9660/iso9660_rrip.c +++ b/usr.sbin/makefs/cd9660/iso9660_rrip.c @@ -35,14 +35,16 @@ * defined in iso9660_rrip.h */ +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + #include "makefs.h" #include "cd9660.h" #include "iso9660_rrip.h" -#include -#include - -#include -__FBSDID("$FreeBSD$"); static void cd9660_rrip_initialize_inode(cd9660node *); static int cd9660_susp_handle_continuation(cd9660node *); diff --git a/usr.sbin/makefs/ffs/ffs_bswap.c b/usr.sbin/makefs/ffs/ffs_bswap.c index d2a3781b3823..d2f9fb16e5ba 100644 --- a/usr.sbin/makefs/ffs/ffs_bswap.c +++ b/usr.sbin/makefs/ffs/ffs_bswap.c @@ -38,18 +38,19 @@ __FBSDID("$FreeBSD$"); #include #endif -#include -#include "ffs/ufs_bswap.h" -#include - #if !defined(_KERNEL) #include +#include #include #include #include #define panic(x) printf("%s\n", (x)), abort() #endif +#include +#include "ffs/ufs_bswap.h" +#include + #define fs_old_postbloff fs_spare5[0] #define fs_old_rotbloff fs_spare5[1] #define fs_old_postbl_start fs_maxbsize diff --git a/usr.sbin/makefs/ffs/ffs_subr.c b/usr.sbin/makefs/ffs/ffs_subr.c index b55174db0ba3..ddf4d2efc245 100644 --- a/usr.sbin/makefs/ffs/ffs_subr.c +++ b/usr.sbin/makefs/ffs/ffs_subr.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include diff --git a/usr.sbin/makefs/mtree.c b/usr.sbin/makefs/mtree.c index 532b9e41f7a8..e711933f2f89 100644 --- a/usr.sbin/makefs/mtree.c +++ b/usr.sbin/makefs/mtree.c @@ -44,10 +44,15 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "makefs.h" +#ifndef ENOATTR +#define ENOATTR ENOMSG +#endif + #define IS_DOT(nm) ((nm)[0] == '.' && (nm)[1] == '\0') #define IS_DOTDOT(nm) ((nm)[0] == '.' && (nm)[1] == '.' && (nm)[2] == '\0') diff --git a/usr.sbin/makefs/walk.c b/usr.sbin/makefs/walk.c index 711017044d45..2c15d6a4b6d1 100644 --- a/usr.sbin/makefs/walk.c +++ b/usr.sbin/makefs/walk.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include From bf715082c3291991044ffd886886721da51abfff Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 16:33:05 +0000 Subject: [PATCH 104/235] Remove armadaxp_idcache_wbinv_all, it's a static function in the ELF trampoline and not used outside this. Sponsored by: ABT Systems Ltd --- sys/arm/include/cpufunc.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/arm/include/cpufunc.h b/sys/arm/include/cpufunc.h index dfe4b5dfc9f6..a4039258455b 100644 --- a/sys/arm/include/cpufunc.h +++ b/sys/arm/include/cpufunc.h @@ -284,8 +284,6 @@ void armv7_cpu_sleep (int); void armv7_setup (void); void armv7_drain_writebuf (void); -void armadaxp_idcache_wbinv_all (void); - void cortexa_setup (void); #endif #if defined(CPU_MV_PJ4B) From ccd08e4d99fa607d7ad8fc0dc02329850ce24244 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 25 Oct 2016 17:13:46 +0000 Subject: [PATCH 105/235] The argument validation in r296956 was not enough to close all possible overflows in sysarch(2). Submitted by: Kun Yang Patch by: kib Security: SA-16:15 --- sys/amd64/amd64/sys_machdep.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/amd64/amd64/sys_machdep.c b/sys/amd64/amd64/sys_machdep.c index 4f85e1f03174..24009dbaed5e 100644 --- a/sys/amd64/amd64/sys_machdep.c +++ b/sys/amd64/amd64/sys_machdep.c @@ -608,6 +608,8 @@ amd64_set_ldt(td, uap, descs) largest_ld = uap->start + uap->num; if (largest_ld > max_ldt_segment) largest_ld = max_ldt_segment; + if (largest_ld < uap->start) + return (EINVAL); i = largest_ld - uap->start; mtx_lock(&dt_lock); bzero(&((struct user_segment_descriptor *)(pldt->ldt_base)) @@ -620,7 +622,8 @@ amd64_set_ldt(td, uap, descs) /* verify range of descriptors to modify */ largest_ld = uap->start + uap->num; if (uap->start >= max_ldt_segment || - largest_ld > max_ldt_segment) + largest_ld > max_ldt_segment || + largest_ld < uap->start) return (EINVAL); } From 42854d99e8da99ad11ede13c598887673d8c3338 Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Tue, 25 Oct 2016 17:13:58 +0000 Subject: [PATCH 106/235] Fix unchecked array reference in the VGA device emulation code. Submitted by: Ilja Van Sprundel Patch by: tychon Security: SA-16:32 --- usr.sbin/bhyve/vga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/usr.sbin/bhyve/vga.c b/usr.sbin/bhyve/vga.c index 208064b3b2ff..57dc26eae412 100644 --- a/usr.sbin/bhyve/vga.c +++ b/usr.sbin/bhyve/vga.c @@ -161,10 +161,10 @@ struct vga_softc { */ struct { uint8_t dac_state; - int dac_rd_index; - int dac_rd_subindex; - int dac_wr_index; - int dac_wr_subindex; + uint8_t dac_rd_index; + uint8_t dac_rd_subindex; + uint8_t dac_wr_index; + uint8_t dac_wr_subindex; uint8_t dac_palette[3 * 256]; uint32_t dac_palette_rgb[256]; } vga_dac; From 75a63b2de3424ec1afd155163e504e3ade717ff1 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 25 Oct 2016 17:31:57 +0000 Subject: [PATCH 107/235] Really make WITHOUT_FORTH (MK_FORTH==no) work. The recent inclusion of FICL definitions not in ficl/ficl32 files broke this generally. This makes that stuff conditional on BOOT_FORTH. Also, move definitions related to the architecture (FICL_CPUARCH and friends) into Makefile.ficl that all parts of the tree that include files with ficl need to include (but only if MK_FORTH == yes). In addition, had to fix library ordering issue with LIBSTAND to keep it last. Without boot forth, there's no references to memset to bring in memset.o from libstand.a to satisfy libgeliboot.a's use of it. Listing libstand last solves this issue (and it's the proper place for libstand to boot). --- sys/boot/common/Makefile.inc | 1 + sys/boot/common/pnp.c | 4 +++ sys/boot/efi/libefi/Makefile | 6 +++-- sys/boot/ficl/Makefile | 45 +-------------------------------- sys/boot/ficl32/Makefile | 5 +--- sys/boot/i386/libi386/biospci.c | 4 +++ sys/boot/i386/loader/Makefile | 4 +-- 7 files changed, 17 insertions(+), 52 deletions(-) diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 480279d7c21e..6086a3b22fa0 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -60,6 +60,7 @@ SRCS+= pnp.c # Forth interpreter .if defined(BOOT_FORTH) SRCS+= interp_forth.c +.include "${SRCTOP}/sys/boot/Makefile.ficl" .endif .if defined(BOOT_PROMPT_123) diff --git a/sys/boot/common/pnp.c b/sys/boot/common/pnp.c index f7e1c23e5dfc..6197776a1d7d 100644 --- a/sys/boot/common/pnp.c +++ b/sys/boot/common/pnp.c @@ -17,7 +17,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef BOOT_FORTH #include "ficl.h" +#endif static struct pnpinfo_stql pnp_devices; static int pnp_devices_initted = 0; @@ -186,6 +188,7 @@ pnp_eisaformat(u_int8_t *data) return(idbuf); } +#ifdef BOOT_FORTH void ficlPnpdevices(FICL_VM *pVM) { @@ -230,3 +233,4 @@ static void ficlCompilePnp(FICL_SYSTEM *pSys) } FICL_COMPILE_SET(ficlCompilePnp); +#endif diff --git a/sys/boot/efi/libefi/Makefile b/sys/boot/efi/libefi/Makefile index a1d55fd9403c..d9619bef89db 100644 --- a/sys/boot/efi/libefi/Makefile +++ b/sys/boot/efi/libefi/Makefile @@ -2,6 +2,10 @@ .include +.if ${MK_FORTH} != "no" +.include "${.CURDIR}/../../Makefile.ficl" +.endif + LIB= efi INTERNALLIB= WARNS?= 2 @@ -16,8 +20,6 @@ SRCS+= time_event.c .endif .if ${MK_FORTH} != "no" SRCS+= env.c -CFLAGS+= -I${.CURDIR}/../../ficl -CFLAGS+= -I${.CURDIR}/../../ficl/${MACHINE_CPUARCH} .endif # We implement a slightly non-standard %S in that it always takes a diff --git a/sys/boot/ficl/Makefile b/sys/boot/ficl/Makefile index bce9ffa78870..c16b25d8fc90 100644 --- a/sys/boot/ficl/Makefile +++ b/sys/boot/ficl/Makefile @@ -1,15 +1,8 @@ # $FreeBSD$ # -FICLDIR?= ${.CURDIR} +.include "${.CURDIR}/../Makefile.ficl" -.if defined(FICL32) -.PATH: ${FICLDIR}/${MACHINE_CPUARCH:S/amd64/i386/} -.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" -.PATH: ${FICLDIR}/mips64 -.else -.PATH: ${FICLDIR}/${MACHINE_CPUARCH} -.endif BASE_SRCS= dict.c ficl.c fileaccess.c float.c loader.c math64.c \ prefix.c search.c stack.c tools.c vm.c words.c @@ -41,42 +34,6 @@ SOFTWORDS= softcore.fr jhlocal.fr marker.fr freebsd.fr ficllocal.fr \ # Optional OO extension softwords #SOFTWORDS+= oo.fr classes.fr -.if ${MACHINE_CPUARCH} == "amd64" -.if defined(FICL32) -CFLAGS+= -m32 -I. -.else -CFLAGS+= -fPIC -.endif -.endif - -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -I. -.endif - -.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) -FICL_CPUARCH= i386 -.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" -FICL_CPUARCH= mips64 -.else -FICL_CPUARCH= ${MACHINE_CPUARCH} -.endif - -CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \ - -I${FICLDIR}/../common - softcore.c: ${SOFTWORDS} softcore.awk (cd ${FICLDIR}/softwords; cat ${SOFTWORDS} \ | awk -f softcore.awk -v datestamp="`LC_ALL=C date`") > ${.TARGET} - -.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) -.if !exists(machine) -${SRCS:M*.c:R:S/$/.o/g}: machine - -beforedepend ${OBJS}: machine -.endif - -machine: .NOMETA - ln -sf ${.CURDIR}/../../i386/include machine - -CLEANFILES+= machine -.endif diff --git a/sys/boot/ficl32/Makefile b/sys/boot/ficl32/Makefile index 57c44cad90af..b27a339bc2ab 100644 --- a/sys/boot/ficl32/Makefile +++ b/sys/boot/ficl32/Makefile @@ -1,8 +1,5 @@ # $FreeBSD$ FICL32= -FICLDIR= ${.CURDIR}/../ficl -.PATH: ${FICLDIR} - -.include "${FICLDIR}/Makefile" +.include "${.CURDIR}/../ficl/Makefile" diff --git a/sys/boot/i386/libi386/biospci.c b/sys/boot/i386/libi386/biospci.c index 331f1526617e..098e30caa5f1 100644 --- a/sys/boot/i386/libi386/biospci.c +++ b/sys/boot/i386/libi386/biospci.c @@ -38,7 +38,9 @@ __FBSDID("$FreeBSD$"); #include #include #include "libi386.h" +#ifdef BOOT_FORTH #include "ficl.h" +#endif /* * Stupid PCI BIOS interface doesn't let you simply enumerate everything @@ -429,6 +431,7 @@ biospci_count_device_type(uint32_t devid) return i; } +#ifdef BOOT_FORTH /* * pcibios-device-count (devid -- count) * @@ -582,3 +585,4 @@ static void ficlCompilePciBios(FICL_SYSTEM *pSys) } FICL_COMPILE_SET(ficlCompilePciBios); +#endif diff --git a/sys/boot/i386/loader/Makefile b/sys/boot/i386/loader/Makefile index 233876a52687..7c6397cf5099 100644 --- a/sys/boot/i386/loader/Makefile +++ b/sys/boot/i386/loader/Makefile @@ -123,8 +123,8 @@ FILES+= loader.rc menu.rc # XXX crt0.o needs to be first for pxeboot(8) to work OBJS= ${BTXCRT} -DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND} ${LIBGELIBOOT} -LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBSTAND} ${LIBGELIBOOT} +DPADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSTAND} +LDADD= ${LIBFICL} ${LIBFIREWIRE} ${LIBZFSBOOT} ${LIBI386} ${LIBGELIBOOT} ${LIBSTAND} .include From 12f7add9f7309d332f377ddf65047c0c5f216bb9 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 17:57:31 +0000 Subject: [PATCH 108/235] Remove the need for the delay to be zero when MULTIDELAY is undefined, it may be useful to only enable this in some configs. Sponsored by: ABT Systems Ltd --- sys/arm/include/platformvar.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/include/platformvar.h b/sys/arm/include/platformvar.h index 607e00f99aa8..a80f628c6d5c 100644 --- a/sys/arm/include/platformvar.h +++ b/sys/arm/include/platformvar.h @@ -93,7 +93,7 @@ extern platform_method_t fdt_platform_methods[]; #ifdef MULTIDELAY #define FDT_PLATFORM_CTASSERT(delay) CTASSERT(delay > 0) #else -#define FDT_PLATFORM_CTASSERT(delay) CTASSERT(delay == 0) +#define FDT_PLATFORM_CTASSERT(delay) #endif #define FDT_PLATFORM_DEF2(NAME, VAR_NAME, NAME_STR, size, compatible, \ From 8fcbb32311a1d520d64072ecf5fceb922a4fdbda Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Tue, 25 Oct 2016 18:01:19 +0000 Subject: [PATCH 109/235] Add MULTIDELAY support to the am335x dmtimer. This will be useful for testing Cortex-A8 support in GENERIC. Sponsored by: ABT Systems Ltd --- sys/arm/ti/am335x/am335x_dmtimer.c | 42 +++++++++++++++++++++--------- sys/arm/ti/ti_machdep.c | 2 +- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/sys/arm/ti/am335x/am335x_dmtimer.c b/sys/arm/ti/am335x/am335x_dmtimer.c index dd286cfb68c3..9d28565fa1f3 100644 --- a/sys/arm/ti/am335x/am335x_dmtimer.c +++ b/sys/arm/ti/am335x/am335x_dmtimer.c @@ -38,6 +38,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef MULTIDELAY +#include /* For arm_set_delay */ +#endif + #include #include #include @@ -67,6 +71,8 @@ struct am335x_dmtimer_softc { static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL; static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL; +static void am335x_dmtimer_delay(int, void *); + /* * We use dmtimer2 for eventtimer and dmtimer3 for timecounter. */ @@ -235,6 +241,10 @@ am335x_dmtimer_tc_init(struct am335x_dmtimer_softc *sc) am335x_dmtimer_tc_sc = sc; tc_init(&sc->func.tc); +#ifdef MULTIDELAY + arm_set_delay(am335x_dmtimer_delay, sc); +#endif + return (0); } @@ -328,23 +338,13 @@ static devclass_t am335x_dmtimer_devclass; DRIVER_MODULE(am335x_dmtimer, simplebus, am335x_dmtimer_driver, am335x_dmtimer_devclass, 0, 0); MODULE_DEPEND(am335x_dmtimer, am335x_prcm, 1, 1, 1); -void -DELAY(int usec) +static void +am335x_dmtimer_delay(int usec, void *arg) { - struct am335x_dmtimer_softc *sc; + struct am335x_dmtimer_softc *sc = arg; int32_t counts; uint32_t first, last; - sc = am335x_dmtimer_tc_sc; - - if (sc == NULL) { - for (; usec > 0; usec--) - for (counts = 200; counts > 0; counts--) - /* Prevent gcc from optimizing out the loop */ - cpufunc_nullop(); - return; - } - /* Get the number of times to count */ counts = (usec + 1) * (sc->sysclk_freq / 1000000); @@ -361,3 +361,19 @@ DELAY(int usec) } } +#ifndef MULTIDELAY +void +DELAY(int usec) +{ + int32_t counts; + + if (am335x_dmtimer_tc_sc == NULL) { + for (; usec > 0; usec--) + for (counts = 200; counts > 0; counts--) + /* Prevent gcc from optimizing out the loop */ + cpufunc_nullop(); + return; + } else + am335x_dmtimer_delay(usec, am335x_dmtimer_tc_sc); +} +#endif diff --git a/sys/arm/ti/ti_machdep.c b/sys/arm/ti/ti_machdep.c index 0e10f765ff15..f9d83890ba86 100644 --- a/sys/arm/ti/ti_machdep.c +++ b/sys/arm/ti/ti_machdep.c @@ -124,5 +124,5 @@ static platform_method_t am335x_methods[] = { PLATFORMMETHOD_END, }; -FDT_PLATFORM_DEF(am335x, "am335x", 0, "ti,am335x", 0); +FDT_PLATFORM_DEF(am335x, "am335x", 0, "ti,am335x", 200); #endif From b8acc2d67edaa1a348e47c6f2929e0595e7182f5 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Tue, 25 Oct 2016 18:36:15 +0000 Subject: [PATCH 110/235] uhso(4): Fix a null pointer dereference The directly following m_defrag() call can wait, so there is no reason this call can't as well. Reported by: Coverity CID: 1353551 Sponsored by: Dell EMC Isilon --- sys/dev/usb/net/uhso.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/net/uhso.c b/sys/dev/usb/net/uhso.c index c94e67625a94..d8db44986b53 100644 --- a/sys/dev/usb/net/uhso.c +++ b/sys/dev/usb/net/uhso.c @@ -1752,7 +1752,7 @@ uhso_if_rxflush(void *arg) * Allocate a new mbuf for this IP packet and * copy the IP-packet into it. */ - m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); + m = m_getcl(M_WAITOK, MT_DATA, M_PKTHDR); memcpy(mtod(m, uint8_t *), mtod(m0, uint8_t *), iplen); m->m_pkthdr.len = m->m_len = iplen; From 0a33140d0697deac2fb0af3fb92c6b9b72d049c7 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Tue, 25 Oct 2016 18:43:36 +0000 Subject: [PATCH 111/235] Change fs image name so it will not be regenerated (we have both big and little-endian images in tree). Also we don't known the endianness of the platform the image was generated on. Sponsored by: DARPA, AFRL Sponsored by: HEIF5 --- tests/sys/geom/class/uzip/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/sys/geom/class/uzip/Makefile b/tests/sys/geom/class/uzip/Makefile index 1f73edf61e32..88f9e47ccced 100644 --- a/tests/sys/geom/class/uzip/Makefile +++ b/tests/sys/geom/class/uzip/Makefile @@ -8,7 +8,7 @@ PACKAGE= tests TESTSDIR= ${TESTSBASE}/sys/geom/class/${.CURDIR:T} -IMAGE= 1_endian_little.img +IMAGE= 1_endian_unknown_autogenerated.img ZIMAGE= ${IMAGE}.uzip UZIMAGE= ${ZIMAGE}.uue @@ -26,7 +26,7 @@ ${UZIMAGE}: ${IMAGE} ${ZIMAGE} uuencode ${ZIMAGE} ${ZIMAGE} >>${.TARGET} ${PACKAGE}FILES+= conf.sh 1_endian_big.img.uzip.uue \ - ${UZIMAGE} + 1_endian_little.img.uzip.uue FILESGROUPS+= etalon etalon+= etalon/etalon.txt From 8368d90bfceb421309fb8a0db0f588e7193ee6ba Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 25 Oct 2016 18:45:14 +0000 Subject: [PATCH 112/235] Use binary and (&) instead of logical to extract the mask of a capability. CID: 1365227 Submitted by: cem --- lib/libsysdecode/flags.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libsysdecode/flags.c b/lib/libsysdecode/flags.c index 3a705c7e9c5f..653b522b3c08 100644 --- a/lib/libsysdecode/flags.c +++ b/lib/libsysdecode/flags.c @@ -959,7 +959,7 @@ sysdecode_umtx_rwlock_flags(FILE *fp, u_long flags, u_long *rem) } /* XXX: This should be in */ -#define CAPMASK(right) ((right) && (((uint64_t)1 << 57) - 1)) +#define CAPMASK(right) ((right) & (((uint64_t)1 << 57) - 1)) void sysdecode_cap_rights(FILE *fp, cap_rights_t *rightsp) From 014b0299e96e6f88df66cd1058c2a61782b3ea2a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 25 Oct 2016 18:57:25 +0000 Subject: [PATCH 113/235] Add missing file --- Makefile.ficl | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 Makefile.ficl diff --git a/Makefile.ficl b/Makefile.ficl new file mode 100644 index 000000000000..de1427aa4285 --- /dev/null +++ b/Makefile.ficl @@ -0,0 +1,43 @@ +# $FreeBSD$ + +# Common flags to build FICL related files + +FICLDIR?= ${SRCTOP}/sys/boot/ficl + +.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) +FICL_CPUARCH= i386 +.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" +FICL_CPUARCH= mips64 +.else +FICL_CPUARCH= ${MACHINE_CPUARCH} +.endif + +.PATH: ${FICLDIR} ${FICLDIR}/${FICL_CPUARCH} + +.if ${MACHINE_CPUARCH} == "amd64" +.if defined(FICL32) +CFLAGS+= -m32 -I. +.else +CFLAGS+= -fPIC +.endif +.endif + +.if ${MACHINE_ARCH} == "powerpc64" +CFLAGS+= -m32 -mcpu=powerpc -I. +.endif + +CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \ + -I${FICLDIR}/../common + +.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) +.if !exists(machine) +${SRCS:M*.c:R:S/$/.o/g}: machine + +beforedepend ${OBJS}: machine +.endif + +machine: .NOMETA + ln -sf ${.CURDIR}/../../i386/include machine + +CLEANFILES+= machine +.endif From c1e27128f8a2a34f23eedab0292032448ac72cf2 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 25 Oct 2016 19:04:42 +0000 Subject: [PATCH 114/235] Add it to the right place --- sys/boot/Makefile.ficl | 43 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 sys/boot/Makefile.ficl diff --git a/sys/boot/Makefile.ficl b/sys/boot/Makefile.ficl new file mode 100644 index 000000000000..de1427aa4285 --- /dev/null +++ b/sys/boot/Makefile.ficl @@ -0,0 +1,43 @@ +# $FreeBSD$ + +# Common flags to build FICL related files + +FICLDIR?= ${SRCTOP}/sys/boot/ficl + +.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) +FICL_CPUARCH= i386 +.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" +FICL_CPUARCH= mips64 +.else +FICL_CPUARCH= ${MACHINE_CPUARCH} +.endif + +.PATH: ${FICLDIR} ${FICLDIR}/${FICL_CPUARCH} + +.if ${MACHINE_CPUARCH} == "amd64" +.if defined(FICL32) +CFLAGS+= -m32 -I. +.else +CFLAGS+= -fPIC +.endif +.endif + +.if ${MACHINE_ARCH} == "powerpc64" +CFLAGS+= -m32 -mcpu=powerpc -I. +.endif + +CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \ + -I${FICLDIR}/../common + +.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) +.if !exists(machine) +${SRCS:M*.c:R:S/$/.o/g}: machine + +beforedepend ${OBJS}: machine +.endif + +machine: .NOMETA + ln -sf ${.CURDIR}/../../i386/include machine + +CLEANFILES+= machine +.endif From dbef2d49411aa3e49a7df88bc2c30f396b64502b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Tue, 25 Oct 2016 19:04:44 +0000 Subject: [PATCH 115/235] Fix two backwards tests. CID: 1365227, 1365228 --- Makefile.ficl | 43 --------------------------------------- sys/boot/efi/libefi/env.c | 8 ++++---- 2 files changed, 4 insertions(+), 47 deletions(-) delete mode 100644 Makefile.ficl diff --git a/Makefile.ficl b/Makefile.ficl deleted file mode 100644 index de1427aa4285..000000000000 --- a/Makefile.ficl +++ /dev/null @@ -1,43 +0,0 @@ -# $FreeBSD$ - -# Common flags to build FICL related files - -FICLDIR?= ${SRCTOP}/sys/boot/ficl - -.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) -FICL_CPUARCH= i386 -.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" -FICL_CPUARCH= mips64 -.else -FICL_CPUARCH= ${MACHINE_CPUARCH} -.endif - -.PATH: ${FICLDIR} ${FICLDIR}/${FICL_CPUARCH} - -.if ${MACHINE_CPUARCH} == "amd64" -.if defined(FICL32) -CFLAGS+= -m32 -I. -.else -CFLAGS+= -fPIC -.endif -.endif - -.if ${MACHINE_ARCH} == "powerpc64" -CFLAGS+= -m32 -mcpu=powerpc -I. -.endif - -CFLAGS+= -I${FICLDIR} -I${FICLDIR}/${FICL_CPUARCH} \ - -I${FICLDIR}/../common - -.if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) -.if !exists(machine) -${SRCS:M*.c:R:S/$/.o/g}: machine - -beforedepend ${OBJS}: machine -.endif - -machine: .NOMETA - ln -sf ${.CURDIR}/../../i386/include machine - -CLEANFILES+= machine -.endif diff --git a/sys/boot/efi/libefi/env.c b/sys/boot/efi/libefi/env.c index a26eb725fd03..66b947d9b06d 100644 --- a/sys/boot/efi/libefi/env.c +++ b/sys/boot/efi/libefi/env.c @@ -114,7 +114,7 @@ ficlEfiSetenv(FICL_VM *pVM) #ifndef TESTMAIN guid = (char*)ficlMalloc(guids); - if (guid != NULL) + if (guid == NULL) vmThrowErr(pVM, "Error: out of memory"); memcpy(guid, guidp, guids); uuid_from_string(guid, &u, &ustatus); @@ -131,7 +131,7 @@ ficlEfiSetenv(FICL_VM *pVM) name[names] = (CHAR16)0; value = (char*)ficlMalloc(values + 1); - if (value != NULL) + if (value == NULL) vmThrowErr(pVM, "Error: out of memory"); memcpy(value, valuep, values); @@ -166,7 +166,7 @@ ficlEfiGetenv(FICL_VM *pVM) #ifndef TESTMAIN name = (char*) ficlMalloc(names+1); - if (!name) + if (name == NULL) vmThrowErr(pVM, "Error: out of memory"); strncpy(name, namep, names); name[names] = '\0'; @@ -201,7 +201,7 @@ ficlEfiUnsetenv(FICL_VM *pVM) #ifndef TESTMAIN name = (char*) ficlMalloc(names+1); - if (!name) + if (name == NULL) vmThrowErr(pVM, "Error: out of memory"); strncpy(name, namep, names); name[names] = '\0'; From 91833b0f3c5952e189cbfc35739a938a5952a99c Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 26 Oct 2016 04:26:17 +0000 Subject: [PATCH 116/235] hyperv/vmbus: Add missing white space. Submitted by: QianYue You MFC after: 1 week Sponsored by: Microsoft --- sys/dev/hyperv/vmbus/vmbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/hyperv/vmbus/vmbus.c b/sys/dev/hyperv/vmbus/vmbus.c index d9cb81ba3f66..6c153335c57c 100644 --- a/sys/dev/hyperv/vmbus/vmbus.c +++ b/sys/dev/hyperv/vmbus/vmbus.c @@ -863,7 +863,7 @@ vmbus_intr_setup(struct vmbus_softc *sc) device_printf(sc->vmbus_dev, "cannot find free IDT vector\n"); return ENXIO; } - if(bootverbose) { + if (bootverbose) { device_printf(sc->vmbus_dev, "vmbus IDT vector %d\n", sc->vmbus_idtvec); } From eaaa9935d46eb906c9ba1cbb07794438b4ef904b Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 26 Oct 2016 05:06:23 +0000 Subject: [PATCH 117/235] hyperv/vmbus: Implement vmbus_chan_printf. And use it for vmbus channel logging, which can log the channel owner's name properly, instead of vmbus0. Submitted by: QianYue You MFC after: 1 week Sponsored by: Microsoft --- sys/dev/hyperv/vmbus/vmbus_chan.c | 136 +++++++++++++++++------------- 1 file changed, 79 insertions(+), 57 deletions(-) diff --git a/sys/dev/hyperv/vmbus/vmbus_chan.c b/sys/dev/hyperv/vmbus/vmbus_chan.c index a889962b0b49..1a86efdaf09e 100644 --- a/sys/dev/hyperv/vmbus/vmbus_chan.c +++ b/sys/dev/hyperv/vmbus/vmbus_chan.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -39,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -90,6 +92,9 @@ static void vmbus_chan_msgproc_chrescind( struct vmbus_softc *, const struct vmbus_message *); +static int vmbus_chan_printf(const struct vmbus_channel *, + const char *, ...) __printflike(2, 3); + /* * Vmbus channel message processing. */ @@ -304,7 +309,7 @@ vmbus_chan_open(struct vmbus_channel *chan, int txbr_size, int rxbr_size, PAGE_SIZE, 0, txbr_size + rxbr_size, &chan->ch_bufring_dma, BUS_DMA_WAITOK); if (chan->ch_bufring == NULL) { - device_printf(chan->ch_dev, "bufring allocation failed\n"); + vmbus_chan_printf(chan, "bufring allocation failed\n"); return (ENOMEM); } @@ -336,7 +341,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, uint8_t *br; if (udlen > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { - device_printf(sc->vmbus_dev, + vmbus_chan_printf(chan, "invalid udata len %d for chan%u\n", udlen, chan->ch_id); return EINVAL; } @@ -386,7 +391,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, error = vmbus_chan_gpadl_connect(chan, cbr->cbr_paddr, txbr_size + rxbr_size, &chan->ch_bufring_gpadl); if (error) { - device_printf(sc->vmbus_dev, + vmbus_chan_printf(chan, "failed to connect bufring GPADL to chan%u\n", chan->ch_id); goto failed; } @@ -402,7 +407,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, */ mh = vmbus_msghc_get(sc, sizeof(*req)); if (mh == NULL) { - device_printf(sc->vmbus_dev, + vmbus_chan_printf(chan, "can not get msg hypercall for chopen(chan%u)\n", chan->ch_id); error = ENXIO; @@ -421,7 +426,7 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, error = vmbus_msghc_exec(sc, mh); if (error) { - device_printf(sc->vmbus_dev, + vmbus_chan_printf(chan, "chopen(chan%u) msg hypercall exec failed: %d\n", chan->ch_id, error); vmbus_msghc_put(sc, mh); @@ -436,13 +441,12 @@ vmbus_chan_open_br(struct vmbus_channel *chan, const struct vmbus_chan_br *cbr, if (status == 0) { if (bootverbose) { - device_printf(sc->vmbus_dev, "chan%u opened\n", - chan->ch_id); + vmbus_chan_printf(chan, "chan%u opened\n", chan->ch_id); } return 0; } - device_printf(sc->vmbus_dev, "failed to open chan%u\n", chan->ch_id); + vmbus_chan_printf(chan, "failed to open chan%u\n", chan->ch_id); error = ENXIO; failed: @@ -485,7 +489,7 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, * We don't support multiple GPA ranges. */ if (range_len > UINT16_MAX) { - device_printf(sc->vmbus_dev, "GPA too large, %d pages\n", + vmbus_chan_printf(chan, "GPA too large, %d pages\n", page_count); return EOPNOTSUPP; } @@ -514,8 +518,8 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, chm_range.gpa_page[cnt]); mh = vmbus_msghc_get(sc, reqsz); if (mh == NULL) { - device_printf(sc->vmbus_dev, - "can not get msg hypercall for gpadl->chan%u\n", + vmbus_chan_printf(chan, + "can not get msg hypercall for gpadl_conn(chan%u)\n", chan->ch_id); return EIO; } @@ -533,8 +537,8 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, error = vmbus_msghc_exec(sc, mh); if (error) { - device_printf(sc->vmbus_dev, - "gpadl->chan%u msg hypercall exec failed: %d\n", + vmbus_chan_printf(chan, + "gpadl_conn(chan%u) msg hypercall exec failed: %d\n", chan->ch_id, error); vmbus_msghc_put(sc, mh); return error; @@ -570,13 +574,13 @@ vmbus_chan_gpadl_connect(struct vmbus_channel *chan, bus_addr_t paddr, vmbus_msghc_put(sc, mh); if (status != 0) { - device_printf(sc->vmbus_dev, "gpadl->chan%u failed: " - "status %u\n", chan->ch_id, status); + vmbus_chan_printf(chan, "gpadl_conn(chan%u) failed: %u\n", + chan->ch_id, status); return EIO; } else { if (bootverbose) { - device_printf(sc->vmbus_dev, "gpadl->chan%u " - "succeeded\n", chan->ch_id); + vmbus_chan_printf(chan, + "gpadl_conn(chan%u) succeeded\n", chan->ch_id); } } return 0; @@ -595,8 +599,8 @@ vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, uint32_t gpadl) mh = vmbus_msghc_get(sc, sizeof(*req)); if (mh == NULL) { - device_printf(sc->vmbus_dev, - "can not get msg hypercall for gpa x->chan%u\n", + vmbus_chan_printf(chan, + "can not get msg hypercall for gpadl_disconn(chan%u)\n", chan->ch_id); return EBUSY; } @@ -608,8 +612,8 @@ vmbus_chan_gpadl_disconnect(struct vmbus_channel *chan, uint32_t gpadl) error = vmbus_msghc_exec(sc, mh); if (error) { - device_printf(sc->vmbus_dev, - "gpa x->chan%u msg hypercall exec failed: %d\n", + vmbus_chan_printf(chan, + "gpadl_disconn(chan%u) msg hypercall exec failed: %d\n", chan->ch_id, error); vmbus_msghc_put(sc, mh); return error; @@ -681,7 +685,7 @@ vmbus_chan_close_internal(struct vmbus_channel *chan) */ mh = vmbus_msghc_get(sc, sizeof(*req)); if (mh == NULL) { - device_printf(sc->vmbus_dev, + vmbus_chan_printf(chan, "can not get msg hypercall for chclose(chan%u)\n", chan->ch_id); return; @@ -695,12 +699,12 @@ vmbus_chan_close_internal(struct vmbus_channel *chan) vmbus_msghc_put(sc, mh); if (error) { - device_printf(sc->vmbus_dev, + vmbus_chan_printf(chan, "chclose(chan%u) msg hypercall exec failed: %d\n", chan->ch_id, error); return; } else if (bootverbose) { - device_printf(sc->vmbus_dev, "close chan%u\n", chan->ch_id); + vmbus_chan_printf(chan, "close chan%u\n", chan->ch_id); } /* @@ -890,13 +894,12 @@ vmbus_chan_recv(struct vmbus_channel *chan, void *data, int *dlen0, return (error); if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) { - device_printf(chan->ch_dev, "invalid hlen %u\n", - pkt.cph_hlen); + vmbus_chan_printf(chan, "invalid hlen %u\n", pkt.cph_hlen); /* XXX this channel is dead actually. */ return (EIO); } if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) { - device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n", + vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n", pkt.cph_hlen, pkt.cph_tlen); /* XXX this channel is dead actually. */ return (EIO); @@ -933,13 +936,12 @@ vmbus_chan_recv_pkt(struct vmbus_channel *chan, return (error); if (__predict_false(pkt.cph_hlen < VMBUS_CHANPKT_HLEN_MIN)) { - device_printf(chan->ch_dev, "invalid hlen %u\n", - pkt.cph_hlen); + vmbus_chan_printf(chan, "invalid hlen %u\n", pkt.cph_hlen); /* XXX this channel is dead actually. */ return (EIO); } if (__predict_false(pkt.cph_hlen > pkt.cph_tlen)) { - device_printf(chan->ch_dev, "invalid hlen %u and tlen %u\n", + vmbus_chan_printf(chan, "invalid hlen %u and tlen %u\n", pkt.cph_hlen, pkt.cph_tlen); /* XXX this channel is dead actually. */ return (EIO); @@ -1082,8 +1084,8 @@ vmbus_chan_update_evtflagcnt(struct vmbus_softc *sc, break; if (atomic_cmpset_int(flag_cnt_ptr, old_flag_cnt, flag_cnt)) { if (bootverbose) { - device_printf(sc->vmbus_dev, - "channel%u update cpu%d flag_cnt to %d\n", + vmbus_chan_printf(chan, + "chan%u update cpu%d flag_cnt to %d\n", chan->ch_id, chan->ch_cpuid, flag_cnt); } break; @@ -1154,11 +1156,6 @@ vmbus_chan_add(struct vmbus_channel *newchan) return EINVAL; } - if (bootverbose) { - device_printf(sc->vmbus_dev, "chan%u subidx%u offer\n", - newchan->ch_id, newchan->ch_subidx); - } - mtx_lock(&sc->vmbus_prichan_lock); TAILQ_FOREACH(prichan, &sc->vmbus_prichans, ch_prilink) { /* @@ -1179,15 +1176,15 @@ vmbus_chan_add(struct vmbus_channel *newchan) goto done; } else { mtx_unlock(&sc->vmbus_prichan_lock); - device_printf(sc->vmbus_dev, "duplicated primary " - "chan%u\n", newchan->ch_id); + device_printf(sc->vmbus_dev, + "duplicated primary chan%u\n", newchan->ch_id); return EINVAL; } } else { /* Sub-channel */ if (prichan == NULL) { mtx_unlock(&sc->vmbus_prichan_lock); - device_printf(sc->vmbus_dev, "no primary chan for " - "chan%u\n", newchan->ch_id); + device_printf(sc->vmbus_dev, + "no primary chan for chan%u\n", newchan->ch_id); return EINVAL; } /* @@ -1224,6 +1221,15 @@ vmbus_chan_add(struct vmbus_channel *newchan) mtx_lock(&sc->vmbus_chan_lock); vmbus_chan_ins_list(sc, newchan); mtx_unlock(&sc->vmbus_chan_lock); + + if (bootverbose) { + vmbus_chan_printf(newchan, "chan%u subidx%u offer\n", + newchan->ch_id, newchan->ch_subidx); + } + + /* Select default cpu for this channel. */ + vmbus_chan_cpu_default(newchan); + return 0; } @@ -1242,7 +1248,8 @@ vmbus_chan_cpu_set(struct vmbus_channel *chan, int cpu) chan->ch_vcpuid = VMBUS_PCPU_GET(chan->ch_vmbus, vcpuid, cpu); if (bootverbose) { - printf("vmbus_chan%u: assigned to cpu%u [vcpu%u]\n", + vmbus_chan_printf(chan, + "chan%u assigned to cpu%u [vcpu%u]\n", chan->ch_id, chan->ch_cpuid, chan->ch_vcpuid); } } @@ -1338,9 +1345,6 @@ vmbus_chan_msgproc_choffer(struct vmbus_softc *sc, TASK_INIT(&chan->ch_attach_task, 0, attach_fn, chan); TASK_INIT(&chan->ch_detach_task, 0, detach_fn, chan); - /* Select default cpu for this channel. */ - vmbus_chan_cpu_default(chan); - error = vmbus_chan_add(chan); if (error) { device_printf(sc->vmbus_dev, "add chan%u failed: %d\n", @@ -1365,11 +1369,6 @@ vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc, return; } - if (bootverbose) { - device_printf(sc->vmbus_dev, "chan%u rescinded\n", - note->chm_chanid); - } - /* * Find and remove the target channel from the channel list. */ @@ -1400,6 +1399,9 @@ vmbus_chan_msgproc_chrescind(struct vmbus_softc *sc, mtx_unlock(&sc->vmbus_prichan_lock); } + if (bootverbose) + vmbus_chan_printf(chan, "chan%u rescinded\n", note->chm_chanid); + /* Detach the target channel. */ taskqueue_enqueue(chan->ch_mgmt_tq, &chan->ch_detach_task); } @@ -1414,8 +1416,9 @@ vmbus_chan_release(struct vmbus_channel *chan) mh = vmbus_msghc_get(sc, sizeof(*req)); if (mh == NULL) { - device_printf(sc->vmbus_dev, "can not get msg hypercall for " - "chfree(chan%u)\n", chan->ch_id); + vmbus_chan_printf(chan, + "can not get msg hypercall for chfree(chan%u)\n", + chan->ch_id); return (ENXIO); } @@ -1427,13 +1430,12 @@ vmbus_chan_release(struct vmbus_channel *chan) vmbus_msghc_put(sc, mh); if (error) { - device_printf(sc->vmbus_dev, "chfree(chan%u) failed: %d", + vmbus_chan_printf(chan, + "chfree(chan%u) msg hypercall exec failed: %d\n", chan->ch_id, error); } else { - if (bootverbose) { - device_printf(sc->vmbus_dev, "chan%u freed\n", - chan->ch_id); - } + if (bootverbose) + vmbus_chan_printf(chan, "chan%u freed\n", chan->ch_id); } return (error); } @@ -1714,6 +1716,26 @@ vmbus_chan_rx_empty(const struct vmbus_channel *chan) return (vmbus_rxbr_empty(&chan->ch_rxbr)); } +static int +vmbus_chan_printf(const struct vmbus_channel *chan, const char *fmt, ...) +{ + va_list ap; + device_t dev; + int retval; + + if (chan->ch_dev == NULL || !device_is_alive(chan->ch_dev)) + dev = chan->ch_vmbus->vmbus_dev; + else + dev = chan->ch_dev; + + retval = device_print_prettyname(dev); + va_start(ap, fmt); + retval += vprintf(fmt, ap); + va_end(ap); + + return (retval); +} + void vmbus_chan_run_task(struct vmbus_channel *chan, struct task *task) { From a07692527da09e9ee0e368e968c17931dd07c1bc Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 26 Oct 2016 05:26:58 +0000 Subject: [PATCH 118/235] Back out the move to the loader script from -N. This should fix the crypto-using boot problems. --- sys/boot/i386/Makefile.inc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/boot/i386/Makefile.inc b/sys/boot/i386/Makefile.inc index 312a374b9b9b..ac413b27d93d 100644 --- a/sys/boot/i386/Makefile.inc +++ b/sys/boot/i386/Makefile.inc @@ -30,7 +30,9 @@ BTXCRT= ${BTXDIR}/lib/crt0.o # compact binary with no padding between text, data, bss LDSCRIPT= ${SRCTOP}/sys/boot/i386/boot.ldscript -LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary -LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections +# LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-T,${LDSCRIPT},-S,--oformat,binary +# LD_FLAGS_BIN=-static -T ${LDSCRIPT} --gc-sections +LDFLAGS_BIN=-e start -Ttext ${ORG} -Wl,-N,-S,--oformat,binary +LD_FLAGS_BIN=-static -N --gc-sections .include "../Makefile.inc" From 5e102beb437edf7e91c1696fce91d3f78c38cee5 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 26 Oct 2016 05:26:59 +0000 Subject: [PATCH 119/235] LIBSTAND goes last, so put it last here too. --- sys/boot/i386/gptboot/Makefile | 2 +- sys/boot/i386/gptzfsboot/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/boot/i386/gptboot/Makefile b/sys/boot/i386/gptboot/Makefile index 626a42a7bd81..dc447c2b9246 100644 --- a/sys/boot/i386/gptboot/Makefile +++ b/sys/boot/i386/gptboot/Makefile @@ -75,7 +75,7 @@ gptboot.bin: gptboot.out ${OBJCOPY} -S -O binary gptboot.out ${.TARGET} gptboot.out: ${BTXCRT} gptboot.o sio.o crc32.o drv.o cons.o util.o ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND} ${LIBGELIBOOT} + ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSTAND} gptboot.o: ${.CURDIR}/../../common/ufsread.c diff --git a/sys/boot/i386/gptzfsboot/Makefile b/sys/boot/i386/gptzfsboot/Makefile index 793eeff30e70..bef6c62f7c7d 100644 --- a/sys/boot/i386/gptzfsboot/Makefile +++ b/sys/boot/i386/gptzfsboot/Makefile @@ -78,7 +78,7 @@ gptzfsboot.bin: gptzfsboot.out gptzfsboot.out: ${BTXCRT} zfsboot.o sio.o gpt.o drv.o cons.o util.o \ skein.o skein_block.o ${OPENCRYPTO_XTS} - ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBSTAND} ${LIBGELIBOOT} + ${LD} ${LD_FLAGS} -Ttext ${ORG2} -o ${.TARGET} ${.ALLSRC} ${LIBGELIBOOT} ${LIBSTAND} zfsboot.o: ${.CURDIR}/../../zfs/zfsimpl.c From 1535414c2511bdf71782d22cae049c64d3dc3a09 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Wed, 26 Oct 2016 08:47:35 +0000 Subject: [PATCH 120/235] The only consumer of pll1 is the CPU clock, we don't need to set it glitch free. Reported by: jmcneill MFC after: 1 week --- sys/arm/allwinner/clk/aw_pll.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c index 2629d2330ee5..6632934f51a1 100644 --- a/sys/arm/allwinner/clk/aw_pll.c +++ b/sys/arm/allwinner/clk/aw_pll.c @@ -309,15 +309,6 @@ struct aw_pll_funcs { #define DEVICE_LOCK(sc) CLKDEV_DEVICE_LOCK((sc)->clkdev) #define DEVICE_UNLOCK(sc) CLKDEV_DEVICE_UNLOCK((sc)->clkdev) -static int -a10_pll1_init(device_t dev, bus_addr_t reg, struct clknode_init_def *def) -{ - /* Allow changing PLL frequency while enabled */ - def->flags = CLK_NODE_GLITCH_FREE; - - return (0); -} - static int a10_pll1_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout, int flags) @@ -999,7 +990,7 @@ a83t_pllcpux_set_freq(struct aw_pll_sc *sc, uint64_t fin, uint64_t *fout, } static struct aw_pll_funcs aw_pll_func[] = { - PLL(AWPLL_A10_PLL1, a10_pll1_recalc, a10_pll1_set_freq, a10_pll1_init), + PLL(AWPLL_A10_PLL1, a10_pll1_recalc, a10_pll1_set_freq, NULL), PLL(AWPLL_A10_PLL2, a10_pll2_recalc, a10_pll2_set_freq, NULL), PLL(AWPLL_A10_PLL3, a10_pll3_recalc, a10_pll3_set_freq, a10_pll3_init), PLL(AWPLL_A10_PLL5, a10_pll5_recalc, NULL, NULL), From 2e620e70f9abf20cb17ff707f16db4e65fea0541 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 26 Oct 2016 12:29:56 +0000 Subject: [PATCH 121/235] Use nitems to get the correct number of registers to read when dumping them. Previously this would walk past the end of the array and print whatever happened to be after the trapframe struct. MFC after: 1 week Sponsored by: DARPA, AFRL --- sys/arm64/arm64/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 07752a90e036..6ae347ef4343 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -250,7 +250,7 @@ print_registers(struct trapframe *frame) { u_int reg; - for (reg = 0; reg < 31; reg++) { + for (reg = 0; reg < nitems(frame->tf_x); reg++) { printf(" %sx%d: %16lx\n", (reg < 10) ? " " : "", reg, frame->tf_x[reg]); } From 2eb8079722516c37c1e8d9f2a75c38d33f966959 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 26 Oct 2016 12:30:53 +0000 Subject: [PATCH 122/235] Only release CPUs when they exist. MFC after: 1 week Sponsored by: DARPA, AFRL --- sys/arm64/arm64/mp_machdep.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index 4361cef888a1..4904e6b6a4a1 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -203,6 +203,10 @@ release_aps(void *dummy __unused) { int i; + /* Only release CPUs if they exist */ + if (mp_ncpus == 1) + return; + intr_pic_ipi_setup(IPI_AST, "ast", ipi_ast, NULL); intr_pic_ipi_setup(IPI_PREEMPT, "preempt", ipi_preempt, NULL); intr_pic_ipi_setup(IPI_RENDEZVOUS, "rendezvous", ipi_rendezvous, NULL); From 1fb2428f1c3d68fabf73b661d82e8f998adf46d0 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 26 Oct 2016 12:41:44 +0000 Subject: [PATCH 123/235] Stop including a possibly GPLd header from the GPIO code. Add the only needed macro to ofw_gpiobus.c. Reported by: emaste Sponsored by: DARPA, AFRL --- sys/dev/gpio/gpiobusvar.h | 1 - sys/dev/gpio/ofw_gpiobus.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/gpio/gpiobusvar.h b/sys/dev/gpio/gpiobusvar.h index 4717bf3fa32e..b6fb44cf5866 100644 --- a/sys/dev/gpio/gpiobusvar.h +++ b/sys/dev/gpio/gpiobusvar.h @@ -38,7 +38,6 @@ #ifdef FDT #include -#include #endif #ifdef INTRNG diff --git a/sys/dev/gpio/ofw_gpiobus.c b/sys/dev/gpio/ofw_gpiobus.c index 96775dc0eb00..f8fcbea95078 100644 --- a/sys/dev/gpio/ofw_gpiobus.c +++ b/sys/dev/gpio/ofw_gpiobus.c @@ -41,6 +41,8 @@ __FBSDID("$FreeBSD$"); #include "gpiobus_if.h" +#define GPIO_ACTIVE_LOW 1 + static struct ofw_gpiobus_devinfo *ofw_gpiobus_setup_devinfo(device_t, device_t, phandle_t); static void ofw_gpiobus_destroy_devinfo(device_t, struct ofw_gpiobus_devinfo *); From 87e1355ba56252739df77a1247624088980220c1 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 26 Oct 2016 14:09:30 +0000 Subject: [PATCH 124/235] Define the Allwinner PLL FDT constants in the file that uses them rather than including a file from under sys/gnu. Sponsored by: DARPA, AFRL --- sys/arm/allwinner/clk/aw_pll.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c index 6632934f51a1..6d159c8eaa0d 100644 --- a/sys/arm/allwinner/clk/aw_pll.c +++ b/sys/arm/allwinner/clk/aw_pll.c @@ -47,12 +47,15 @@ __FBSDID("$FreeBSD$"); #include -#include - #include #include "clkdev_if.h" +#define SUN4I_A10_PLL2_1X 0 +#define SUN4I_A10_PLL2_2X 1 +#define SUN4I_A10_PLL2_4X 2 +#define SUN4I_A10_PLL2_8X 3 + #define AW_PLL_ENABLE (1 << 31) #define A10_PLL1_OUT_EXT_DIVP (0x3 << 16) From 1d290950b2172ee76aed87b9ebf6080ee363e7fd Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Wed, 26 Oct 2016 14:26:45 +0000 Subject: [PATCH 125/235] Use uint32_t instead of u_long as a storage for breakpoint instruction to copy. All the platforms breakpoints fits this fine. This fixes operation on big-endian MIPS64 where we were coping zeroes instead of real instruction. Reviewed by: rpaulo Sponsored by: DARPA, AFRL Sponsored by: HEIF5 Differential Revision: https://reviews.freebsd.org/D8250 --- lib/libproc/proc_bkpt.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/libproc/proc_bkpt.c b/lib/libproc/proc_bkpt.c index 4a100cbbd4eb..3167206af204 100644 --- a/lib/libproc/proc_bkpt.c +++ b/lib/libproc/proc_bkpt.c @@ -68,6 +68,14 @@ __FBSDID("$FreeBSD$"); #error "Add support for your architecture" #endif +/* + * Use 4-bytes holder for breakpoint instruction on all the platforms. + * Works for x86 as well until it is endian-little platform. + * (We are coping one byte only on x86 from this 4-bytes piece of + * memory). + */ +typedef uint32_t instr_t; + static int proc_stop(struct proc_handle *phdl) { @@ -92,8 +100,9 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, unsigned long *saved) { struct ptrace_io_desc piod; - unsigned long paddr, caddr; + unsigned long caddr; int ret = 0, stopped; + instr_t instr; *saved = 0; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || @@ -115,10 +124,10 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, * Read the original instruction. */ caddr = address; - paddr = 0; + instr = 0; piod.piod_op = PIOD_READ_I; piod.piod_offs = (void *)caddr; - piod.piod_addr = &paddr; + piod.piod_addr = &instr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { DPRINTF("ERROR: couldn't read instruction at address 0x%" @@ -126,15 +135,15 @@ proc_bkptset(struct proc_handle *phdl, uintptr_t address, ret = -1; goto done; } - *saved = paddr; + *saved = instr; /* * Write a breakpoint instruction to that address. */ caddr = address; - paddr = BREAKPOINT_INSTR; + instr = BREAKPOINT_INSTR; piod.piod_op = PIOD_WRITE_I; piod.piod_offs = (void *)caddr; - piod.piod_addr = &paddr; + piod.piod_addr = &instr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { DPRINTF("ERROR: couldn't write instruction at address 0x%" @@ -156,8 +165,9 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, unsigned long saved) { struct ptrace_io_desc piod; - unsigned long paddr, caddr; + unsigned long caddr; int ret = 0, stopped; + instr_t instr; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || phdl->status == PS_IDLE) { @@ -178,10 +188,10 @@ proc_bkptdel(struct proc_handle *phdl, uintptr_t address, * Overwrite the breakpoint instruction that we setup previously. */ caddr = address; - paddr = saved; + instr = saved; piod.piod_op = PIOD_WRITE_I; piod.piod_offs = (void *)caddr; - piod.piod_addr = &paddr; + piod.piod_addr = &instr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { DPRINTF("ERROR: couldn't write instruction at address 0x%" From 0c5434ae584257cee3e32e3ab6211cf427eab15b Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 26 Oct 2016 15:18:08 +0000 Subject: [PATCH 126/235] Pull the common FDT interrupt values into a new header rather than be magic numbers. Sponsored by: DARPA, AFRL --- sys/arm/arm/gic.c | 7 +++++-- sys/arm64/arm64/gic_v3.c | 11 +++++----- sys/dev/fdt/fdt_intr.h | 44 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 sys/dev/fdt/fdt_intr.h diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c index d67f9c6ced68..91ccf31635f5 100644 --- a/sys/arm/arm/gic.c +++ b/sys/arm/arm/gic.c @@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -821,13 +822,15 @@ gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp, } tripol = cells[2] & 0xff; - if (tripol & 0xf0 || (tripol & 0x0a && cells[0] == 0)) + if (tripol & 0xf0 || (tripol & FDT_INTR_LOW_MASK && + cells[0] == 0)) device_printf(dev, "unsupported trigger/polarity " "configuration 0x%02x\n", tripol); *irqp = irq; *polp = INTR_POLARITY_CONFORM; - *trigp = tripol & 0x03 ? INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL; + *trigp = tripol & FDT_INTR_EDGE_MASK ? + INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL; return (0); } return (EINVAL); diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index 0110ebd734f2..fea4b2d42820 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include #ifdef FDT +#include #include #endif @@ -470,20 +471,20 @@ gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp, return (EINVAL); } - switch (cells[2] & 0xf) { - case 1: + switch (cells[2] & FDT_INTR_MASK) { + case FDT_INTR_EDGE_RISING: *trigp = INTR_TRIGGER_EDGE; *polp = INTR_POLARITY_HIGH; break; - case 2: + case FDT_INTR_EDGE_FALLING: *trigp = INTR_TRIGGER_EDGE; *polp = INTR_POLARITY_LOW; break; - case 4: + case FDT_INTR_LEVEL_HIGH: *trigp = INTR_TRIGGER_LEVEL; *polp = INTR_POLARITY_HIGH; break; - case 8: + case FDT_INTR_LEVEL_LOW: *trigp = INTR_TRIGGER_LEVEL; *polp = INTR_POLARITY_LOW; break; diff --git a/sys/dev/fdt/fdt_intr.h b/sys/dev/fdt/fdt_intr.h new file mode 100644 index 000000000000..b8568e1399f0 --- /dev/null +++ b/sys/dev/fdt/fdt_intr.h @@ -0,0 +1,44 @@ +/*- + * Copyright (c) 2016 Andrew Turner + * All rights reserved. + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237 + * ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FDT_INTR_H_ +#define _FDT_INTR_H_ + +#define FDT_INTR_EDGE_RISING 1 +#define FDT_INTR_EDGE_FALLING 2 +#define FDT_INTR_LEVEL_HIGH 4 +#define FDT_INTR_LEVEL_LOW 8 +#define FDT_INTR_LOW_MASK (FDT_INTR_EDGE_FALLING | FDT_INTR_LEVEL_LOW) +#define FDT_INTR_EDGE_MASK (FDT_INTR_EDGE_RISING | FDT_INTR_EDGE_FALLING) +#define FDT_INTR_MASK 0xf + +#endif /* _FDT_INTR_H_ */ From f1ee30ccd60533bff96c04735850578ab1b16630 Mon Sep 17 00:00:00 2001 From: Julien Charbon Date: Wed, 26 Oct 2016 15:19:18 +0000 Subject: [PATCH 127/235] Remove an extraneous call to soisconnected() in syncache_socket(), introduced with r261242. The useful and expected soisconnected() call is done in tcp_do_segment(). Has been found as part of unrelated PR:212920 investigation. Improve slightly (~2%) the maximum number of TCP accept per second. Tested by: kevin.bowling_kev009.com, jch Approved by: gnn, hiren MFC after: 1 week Sponsored by: Verisign, Inc Differential Revision: https://reviews.freebsd.org/D8072 --- sys/netinet/tcp_syncache.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/netinet/tcp_syncache.c b/sys/netinet/tcp_syncache.c index 33e5df782d69..6dc02ef85930 100644 --- a/sys/netinet/tcp_syncache.c +++ b/sys/netinet/tcp_syncache.c @@ -918,10 +918,6 @@ syncache_socket(struct syncache *sc, struct socket *lso, struct mbuf *m) tp->t_keepcnt = sototcpcb(lso)->t_keepcnt; tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); - if ((so->so_options & SO_ACCEPTFILTER) == 0) { - soisconnected(so); - } - TCPSTAT_INC(tcps_accepts); return (so); From 5bdda834d5b0dbfdc6178f648ce0bdfbc0973151 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 26 Oct 2016 15:58:41 +0000 Subject: [PATCH 128/235] Allow config to be compiled from another source directory, such as one for building tools. This boils down to replacing ${.CURDIR} with ${SRCDIR}, where the latter is the directory in which this makefile lives. Also allow overriding where file2c comes from using ${FILE2C}. --- usr.sbin/config/Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/usr.sbin/config/Makefile b/usr.sbin/config/Makefile index 76712d2861e1..845a3263dfc5 100644 --- a/usr.sbin/config/Makefile +++ b/usr.sbin/config/Makefile @@ -1,15 +1,20 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +SRCDIR:=${.PARSEDIR:tA} + PROG= config MAN= config.5 config.8 SRCS= config.y main.c lang.l mkmakefile.c mkheaders.c \ mkoptions.c y.tab.h kernconf.c -kernconf.c: kernconf.tmpl - file2c 'char kernconfstr[] = {' ',0};' < ${.CURDIR}/kernconf.tmpl > kernconf.c +FILE2C?=file2c -CFLAGS+= -I. -I${.CURDIR} +kernconf.c: kernconf.tmpl + ${FILE2C} 'char kernconfstr[] = {' ',0};' < \ + ${SRCDIR}/kernconf.tmpl > kernconf.c + +CFLAGS+= -I. -I${SRCDIR} NO_WMISSING_VARIABLE_DECLARATIONS= From f1ae17fb50d647e414b31a278837b894750d5a09 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Wed, 26 Oct 2016 16:03:26 +0000 Subject: [PATCH 129/235] Use the new fdt_intr.h constants in the Allwinner NMI driver. Sponsored by: DARPA, AFRL --- sys/arm/allwinner/aw_nmi.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/sys/arm/allwinner/aw_nmi.c b/sys/arm/allwinner/aw_nmi.c index a281a6b0e0ba..67be72d6b056 100644 --- a/sys/arm/allwinner/aw_nmi.c +++ b/sys/arm/allwinner/aw_nmi.c @@ -40,12 +40,11 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include -#include - #include "pic_if.h" #define NMI_IRQ_CTRL_REG 0x0 @@ -155,19 +154,19 @@ aw_nmi_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp, tripol = cells[1]; switch (tripol) { - case IRQ_TYPE_EDGE_RISING: + case FDT_INTR_EDGE_RISING: trig = INTR_TRIGGER_EDGE; pol = INTR_POLARITY_HIGH; break; - case IRQ_TYPE_EDGE_FALLING: + case FDT_INTR_EDGE_FALLING: trig = INTR_TRIGGER_EDGE; pol = INTR_POLARITY_LOW; break; - case IRQ_TYPE_LEVEL_HIGH: + case FDT_INTR_LEVEL_HIGH: trig = INTR_TRIGGER_LEVEL; pol = INTR_POLARITY_HIGH; break; - case IRQ_TYPE_LEVEL_LOW: + case FDT_INTR_LEVEL_LOW: trig = INTR_TRIGGER_LEVEL; pol = INTR_POLARITY_LOW; break; From f8d647b44deb0cdfc857e0fb9a1106f11b6546ee Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Wed, 26 Oct 2016 17:07:53 +0000 Subject: [PATCH 130/235] strings: fix exit status if a file before the last one fails Previously a command like "strings f1 f2 f3" reported the exit status based only on processing the last file. As with GNU strings, report an error exit status if an error was encountered processing any of the files. While here simplify the exit status handling to just success (0) / failure (1). Reviewed by: brooks MFC after: 1 month Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D8334 --- contrib/elftoolchain/strings/strings.c | 27 +++++++++++--------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/contrib/elftoolchain/strings/strings.c b/contrib/elftoolchain/strings/strings.c index 8de29ca7d25b..a936b6be1bbb 100644 --- a/contrib/elftoolchain/strings/strings.c +++ b/contrib/elftoolchain/strings/strings.c @@ -48,12 +48,6 @@ ELFTC_VCSID("$Id: strings.c 3446 2016-05-03 01:31:17Z emaste $"); -enum return_code { - RETURN_OK, - RETURN_NOINPUT, - RETURN_SOFTWARE -}; - enum radix_style { RADIX_DECIMAL, RADIX_HEX, @@ -107,7 +101,7 @@ main(int argc, char **argv) { int ch, rc; - rc = RETURN_OK; + rc = 0; min_len = 0; encoding_size = 1; if (elf_version(EV_CURRENT) == EV_NONE) @@ -197,7 +191,8 @@ main(int argc, char **argv) if (!*argv) rc = handle_file("{standard input}"); else while (*argv) { - rc = handle_file(*argv); + if (handle_file(*argv) != 0) + rc = 1; argv++; } return (rc); @@ -209,11 +204,11 @@ handle_file(const char *name) int fd, rt; if (name == NULL) - return (RETURN_NOINPUT); + return (1); if (strcmp("{standard input}", name) != 0) { if (freopen(name, "rb", stdin) == NULL) { warnx("'%s': %s", name, strerror(errno)); - return (RETURN_NOINPUT); + return (1); } } else { return (find_strings(name, (off_t)0, (off_t)0)); @@ -221,7 +216,7 @@ handle_file(const char *name) fd = fileno(stdin); if (fd < 0) - return (RETURN_NOINPUT); + return (1); rt = handle_elf(name, fd); return (rt); } @@ -239,7 +234,7 @@ handle_binary(const char *name, int fd) (void) lseek(fd, (off_t)0, SEEK_SET); if (!fstat(fd, &buf)) return (find_strings(name, (off_t)0, buf.st_size)); - return (RETURN_SOFTWARE); + return (1); } /* @@ -257,7 +252,7 @@ handle_elf(const char *name, int fd) Elf_Scn *scn; int rc; - rc = RETURN_OK; + rc = 0; /* If entire file is chosen, treat it as a binary file */ if (entire_file) return (handle_binary(name, fd)); @@ -272,7 +267,7 @@ handle_elf(const char *name, int fd) if (gelf_getehdr(elf, &elfhdr) == NULL) { (void) elf_end(elf); warnx("%s: ELF file could not be processed", name); - return (RETURN_SOFTWARE); + return (1); } if (elfhdr.e_shnum == 0 && elfhdr.e_type == ET_CORE) { @@ -352,7 +347,7 @@ find_strings(const char *name, off_t offset, off_t size) if ((obuf = (char*)calloc(1, min_len + 1)) == NULL) { (void) fprintf(stderr, "Unable to allocate memory: %s\n", strerror(errno)); - return (RETURN_SOFTWARE); + return (1); } (void) fseeko(stdin, offset, SEEK_SET); @@ -426,7 +421,7 @@ find_strings(const char *name, off_t offset, off_t size) } _exit1: free(obuf); - return (RETURN_OK); + return (0); } #define USAGE_MESSAGE "\ From ed3abcbb0de655fa883b49af28dceb1945db7a20 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 26 Oct 2016 17:37:08 +0000 Subject: [PATCH 131/235] Correct definition of 'struct sigcontext' on MIPS. Add missing fields ('sr' and 'mc_tls') to 'struct sigcontext'. The kernel doesn't use 'struct sigcontext' but instead uses 'ucontext_t' which includes 'mcontext_t' in 'struct sigframe' to build the signal frame. As a result, this change is not an ABI change but simply making 'struct sigcontext' correct. Note that 'struct sigcontext' is only used for "Traditional BSD style" signal handlers. While here, rename the 'xxx' field to '__spare__' to match 'mcontext_t'. Sponsored by: DARPA, AFRL --- sys/mips/include/signal.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/mips/include/signal.h b/sys/mips/include/signal.h index 5107af05bba2..f808d3ff6e40 100644 --- a/sys/mips/include/signal.h +++ b/sys/mips/include/signal.h @@ -68,11 +68,13 @@ struct sigcontext { int sc_onstack; /* sigstack state to restore */ __register_t sc_pc; /* pc at time of signal */ __register_t sc_regs[32]; /* processor regs 0 to 31 */ + __register_t sr; /* status register */ __register_t mullo, mulhi; /* mullo and mulhi registers... */ int sc_fpused; /* fp has been used */ f_register_t sc_fpregs[33]; /* fp regs 0 to 31 and csr */ __register_t sc_fpc_eir; /* fp exception instruction reg */ - int xxx[8]; /* XXX reserved */ + void *sc_tls; /* pointer to TLS area */ + int __spare__[8]; /* XXX reserved */ }; #endif /* !_ANSI_SOURCE && !_POSIX_SOURCE */ From 726f4773ec261cac63e0c30a7b84059cafcb7511 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 26 Oct 2016 18:47:47 +0000 Subject: [PATCH 132/235] Enable EFER_NXE properly on APs. EFER_NXE is set in the EFER MSR by initializecpu() and must be set on all CPUs in the system. When PG_NX support was added to PAE on i386, the block to enable EFER_NXE was placed in a section of initializecpu() that only runs if 'cpu == CPU_686'. During early boot, locore does an initial pass to set cpu that sets it to CPU_686 on all CPUs later than a Pentium. Later, printcpuinfo() adjusts the 'cpu' variable on PII and later CPUs to one of CPU_PII, CPU_PIII, or CPU_P4. However, printcpuinfo() is called after initializecpu() on the BSP, so the BSP would enable EFER_NXE and pg_nx. The APs execute initializecpu() much later after printcpuinfo() has run. The end result on a modern CPU was that cpu was set to CPU_PIII when the APs invoked initializecpu(), so they did not enable EFER_NXE. As a result, the APs would fault when trying to access any pages marked with PG_NX set. When booting a 2 CPU PAE kernel in bhyve this manifested as a hang before single user mode. The attempt to execute /bin/init tried to copy out the exec strings (argv, etc.) to a non-executable mapping while running on the AP. The instruction kept faulting due to invalid bits in the PTE in an infinite loop. Fix this by moving the code to enable EFER_NXE out of the switch statement on 'cpu' and always doing it if 'amd_feature' supports AMDID_NX. MFC after: 2 weeks --- sys/i386/i386/initcpu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c index 214c6f6d989f..f67593794908 100644 --- a/sys/i386/i386/initcpu.c +++ b/sys/i386/i386/initcpu.c @@ -753,16 +753,6 @@ initializecpu(void) init_transmeta(); break; } -#if defined(PAE) || defined(PAE_TABLES) - if ((amd_feature & AMDID_NX) != 0) { - uint64_t msr; - - msr = rdmsr(MSR_EFER) | EFER_NXE; - wrmsr(MSR_EFER, msr); - pg_nx = PG_NX; - elf32_nxstack = 1; - } -#endif break; #endif default: @@ -774,6 +764,16 @@ initializecpu(void) cpu_fxsr = hw_instruction_sse = 1; } #endif +#if defined(PAE) || defined(PAE_TABLES) + if ((amd_feature & AMDID_NX) != 0) { + uint64_t msr; + + msr = rdmsr(MSR_EFER) | EFER_NXE; + wrmsr(MSR_EFER, msr); + pg_nx = PG_NX; + elf32_nxstack = 1; + } +#endif } void From 7518a9bd2bd4ffc18171625bddede1c5e773f019 Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 26 Oct 2016 20:02:22 +0000 Subject: [PATCH 133/235] Build OpenSSL assembly sources for aarch64. Tested with ThunderX by andrew. --- crypto/openssl/crypto/aes/asm/aesv8-armx.pl | 2 +- crypto/openssl/crypto/arm64cpuid.S | 1 - .../openssl/crypto/modes/asm/ghashv8-armx.pl | 2 +- secure/lib/libcrypto/Makefile | 19 +- secure/lib/libcrypto/Makefile.asm | 39 +- secure/lib/libcrypto/Makefile.inc | 10 +- secure/lib/libcrypto/aarch64/aesv8-armx.S | 748 ++++++++++ secure/lib/libcrypto/aarch64/ghashv8-armx.S | 228 ++++ secure/lib/libcrypto/aarch64/sha1-armv8.S | 1213 +++++++++++++++++ secure/lib/libcrypto/aarch64/sha256-armv8.S | 1143 ++++++++++++++++ secure/lib/libcrypto/aarch64/sha512-armv8.S | 1023 ++++++++++++++ 11 files changed, 4416 insertions(+), 12 deletions(-) create mode 100644 secure/lib/libcrypto/aarch64/aesv8-armx.S create mode 100644 secure/lib/libcrypto/aarch64/ghashv8-armx.S create mode 100644 secure/lib/libcrypto/aarch64/sha1-armv8.S create mode 100644 secure/lib/libcrypto/aarch64/sha256-armv8.S create mode 100644 secure/lib/libcrypto/aarch64/sha512-armv8.S diff --git a/crypto/openssl/crypto/aes/asm/aesv8-armx.pl b/crypto/openssl/crypto/aes/asm/aesv8-armx.pl index 95ebae3beb9b..0ed263fbe2f9 100755 --- a/crypto/openssl/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/openssl/crypto/aes/asm/aesv8-armx.pl @@ -42,7 +42,7 @@ $code=<<___; #if __ARM_MAX_ARCH__>=7 .text ___ -$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); +# $code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); $code.=".arch armv7-a\n.fpu neon\n.code 32\n" if ($flavour !~ /64/); #^^^^^^ this is done to simplify adoption by not depending # on latest binutils. diff --git a/crypto/openssl/crypto/arm64cpuid.S b/crypto/openssl/crypto/arm64cpuid.S index 4778ac1deacc..d16a7b53488e 100644 --- a/crypto/openssl/crypto/arm64cpuid.S +++ b/crypto/openssl/crypto/arm64cpuid.S @@ -1,7 +1,6 @@ #include "arm_arch.h" .text -.arch armv8-a+crypto .align 5 .global _armv7_neon_probe diff --git a/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl b/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl index 0886d2180702..3026b44ab579 100755 --- a/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl +++ b/crypto/openssl/crypto/modes/asm/ghashv8-armx.pl @@ -49,7 +49,7 @@ $code=<<___; .text ___ -$code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); +# $code.=".arch armv8-a+crypto\n" if ($flavour =~ /64/); $code.=".fpu neon\n.code 32\n" if ($flavour !~ /64/); ################################################################################ diff --git a/secure/lib/libcrypto/Makefile b/secure/lib/libcrypto/Makefile index 0bc2fda8c63b..5e9ad2b27540 100644 --- a/secure/lib/libcrypto/Makefile +++ b/secure/lib/libcrypto/Makefile @@ -22,7 +22,10 @@ MAN+= config.5 des_modes.7 # base sources SRCS= cpt_err.c cryptlib.c cversion.c ex_data.c mem.c mem_dbg.c o_dir.c \ o_fips.c o_init.c o_str.c o_time.c uid.c -.if defined(ASM_amd64) +.if defined(ASM_aarch64) +SRCS+= arm64cpuid.S armcap.c mem_clr.c +CFLAGS.arm64cpuid.S= -march=armv8-a+crypto +.elif defined(ASM_amd64) SRCS+= x86_64cpuid.S .elif defined(ASM_arm) SRCS+= armcap.c armv4cpuid.S @@ -35,7 +38,10 @@ INCS+= crypto.h ebcdic.h opensslv.h ossl_typ.h symhacks.h ../e_os2.h # aes SRCS+= aes_cfb.c aes_ctr.c aes_ecb.c aes_ige.c aes_misc.c aes_ofb.c aes_wrap.c -.if defined(ASM_amd64) +.if defined(ASM_aarch64) +SRCS+= aes_cbc.c aes_core.c aesv8-armx.S +CFLAGS.aesv8-armx.S= -march=armv8-a+crypto +.elif defined(ASM_amd64) SRCS+= aes-x86_64.S aesni-mb-x86_64.S aesni-sha1-x86_64.S \ aesni-sha256-x86_64.S aesni-x86_64.S bsaes-x86_64.S vpaes-x86_64.S .elif defined(ASM_arm) @@ -238,7 +244,10 @@ INCS+= mdc2.h # modes SRCS+= cbc128.c ccm128.c cfb128.c ctr128.c cts128.c gcm128.c ofb128.c \ wrap128.c xts128.c -.if defined(ASM_amd64) +.if defined(ASM_aarch64) +SRCS+= ghashv8-armx.S +CFLAGS.ghashv8-armx.S= -march=armv8-a+crypto +.elif defined(ASM_amd64) SRCS+= aesni-gcm-x86_64.S ghash-x86_64.S .elif defined(ASM_arm) SRCS+= ghash-armv4.S ghashv8-armx.S @@ -324,7 +333,9 @@ INCS+= seed.h # sha SRCS+= sha1_one.c sha1dgst.c sha256.c sha512.c sha_dgst.c sha_one.c -.if defined(ASM_amd64) +.if defined(ASM_aarch64) +SRCS+= sha1-armv8.S sha256-armv8.S sha512-armv8.S +.elif defined(ASM_amd64) SRCS+= sha1-mb-x86_64.S sha1-x86_64.S sha256-mb-x86_64.S sha256-x86_64.S \ sha512-x86_64.S .elif defined(ASM_arm) diff --git a/secure/lib/libcrypto/Makefile.asm b/secure/lib/libcrypto/Makefile.asm index a50392003354..076d4c1e69e7 100644 --- a/secure/lib/libcrypto/Makefile.asm +++ b/secure/lib/libcrypto/Makefile.asm @@ -6,7 +6,44 @@ .include "Makefile.inc" -.if defined(ASM_amd64) +.if defined(ASM_aarch64) + +.PATH: ${LCRYPTO_SRC}/crypto \ + ${LCRYPTO_SRC}/crypto/aes/asm \ + ${LCRYPTO_SRC}/crypto/modes/asm \ + ${LCRYPTO_SRC}/crypto/sha/asm + +PERLPATH= -I${LCRYPTO_SRC}/crypto/perlasm + +# aes +SRCS= aesv8-armx.pl + +# modes +SRCS+= ghashv8-armx.pl + +# sha +SRCS+= sha1-armv8.pl sha512-armv8.pl + +ASM= ${SRCS:R:S/$/.S/} sha256-armv8.S + +all: ${ASM} + +CLEANFILES= ${ASM} ${SRCS:R:S/$/.s/} sha256-armv8.s +.SUFFIXES: .pl + +sha256-armv8.S: sha512-armv8.pl + env CC=cc perl ${.ALLSRC} 64 ${.TARGET:R:S/$/.s/} + ( echo '/* $$'FreeBSD'$$ */' ;\ + echo '/* Do not modify. This file is auto-generated from ${.ALLSRC:T:R:S/$/.pl/}. */' ;\ + cat ${.TARGET:R:S/$/.s/}) > ${.TARGET} + +.pl.S: + env CC=cc perl ${.IMPSRC} 64 ${.TARGET:R:S/$/.s/} + ( echo '/* $$'FreeBSD'$$ */' ;\ + echo '/* Do not modify. This file is auto-generated from ${.IMPSRC:T:R:S/$/.pl/}. */' ;\ + cat ${.TARGET:R:S/$/.s/}) > ${.TARGET} + +.elif defined(ASM_amd64) .PATH: ${LCRYPTO_SRC}/crypto \ ${LCRYPTO_SRC}/crypto/aes/asm \ diff --git a/secure/lib/libcrypto/Makefile.inc b/secure/lib/libcrypto/Makefile.inc index 3be4ddc7ea07..257c53402c68 100644 --- a/secure/lib/libcrypto/Makefile.inc +++ b/secure/lib/libcrypto/Makefile.inc @@ -21,7 +21,9 @@ CFLAGS+=-DL_ENDIAN CFLAGS+=-DB_ENDIAN .endif -.if ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" +.if ${MACHINE_CPUARCH} == "aarch64" || ${MACHINE_CPUARCH} == "arm" +ASM_${MACHINE_CPUARCH}= +.elif ${MACHINE_CPUARCH} == "amd64" || ${MACHINE_CPUARCH} == "i386" _ASM_AVX!= { \ echo vzeroall | \ ${CC} -x assembler -o /dev/null -c - 2> /dev/null; \ @@ -29,11 +31,11 @@ _ASM_AVX!= { \ .if ${_ASM_AVX} == yes ASM_${MACHINE_CPUARCH}= .endif -.elif ${MACHINE_CPUARCH} == "arm" -ASM_arm= .endif -.if defined(ASM_amd64) +.if defined(ASM_aarch64) +CFLAGS+=-DSHA1_ASM -DSHA256_ASM -DSHA512_ASM +.elif defined(ASM_amd64) CFLAGS+=-DOPENSSL_IA32_SSE2 CFLAGS+=-DAES_ASM -DBSAES_ASM -DVPAES_ASM CFLAGS+=-DECP_NISTZ256_ASM diff --git a/secure/lib/libcrypto/aarch64/aesv8-armx.S b/secure/lib/libcrypto/aarch64/aesv8-armx.S new file mode 100644 index 000000000000..5c8aa5002e8a --- /dev/null +++ b/secure/lib/libcrypto/aarch64/aesv8-armx.S @@ -0,0 +1,748 @@ +/* $FreeBSD$ */ +/* Do not modify. This file is auto-generated from aesv8-armx.pl. */ +#include "arm_arch.h" + +#if __ARM_MAX_ARCH__>=7 +.text +.align 5 +rcon: +.long 0x01,0x01,0x01,0x01 +.long 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d // rotate-n-splat +.long 0x1b,0x1b,0x1b,0x1b + +.globl aes_v8_set_encrypt_key +.type aes_v8_set_encrypt_key,%function +.align 5 +aes_v8_set_encrypt_key: +.Lenc_key: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + mov x3,#-1 + cmp x0,#0 + b.eq .Lenc_key_abort + cmp x2,#0 + b.eq .Lenc_key_abort + mov x3,#-2 + cmp w1,#128 + b.lt .Lenc_key_abort + cmp w1,#256 + b.gt .Lenc_key_abort + tst w1,#0x3f + b.ne .Lenc_key_abort + + adr x3,rcon + cmp w1,#192 + + eor v0.16b,v0.16b,v0.16b + ld1 {v3.16b},[x0],#16 + mov w1,#8 // reuse w1 + ld1 {v1.4s,v2.4s},[x3],#32 + + b.lt .Loop128 + b.eq .L192 + b .L256 + +.align 4 +.Loop128: + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + b.ne .Loop128 + + ld1 {v1.4s},[x3] + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + + tbl v6.16b,{v3.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v3.4s},[x2],#16 + aese v6.16b,v0.16b + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2] + add x2,x2,#0x50 + + mov w12,#10 + b .Ldone + +.align 4 +.L192: + ld1 {v4.8b},[x0],#8 + movi v6.16b,#8 // borrow v6.16b + st1 {v3.4s},[x2],#16 + sub v2.16b,v2.16b,v6.16b // adjust the mask + +.Loop192: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.8b},[x2],#8 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + + dup v5.4s,v3.s[3] + eor v5.16b,v5.16b,v4.16b + eor v6.16b,v6.16b,v1.16b + ext v4.16b,v0.16b,v4.16b,#12 + shl v1.16b,v1.16b,#1 + eor v4.16b,v4.16b,v5.16b + eor v3.16b,v3.16b,v6.16b + eor v4.16b,v4.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.ne .Loop192 + + mov w12,#12 + add x2,x2,#0x20 + b .Ldone + +.align 4 +.L256: + ld1 {v4.16b},[x0] + mov w1,#7 + mov w12,#14 + st1 {v3.4s},[x2],#16 + +.Loop256: + tbl v6.16b,{v4.16b},v2.16b + ext v5.16b,v0.16b,v3.16b,#12 + st1 {v4.4s},[x2],#16 + aese v6.16b,v0.16b + subs w1,w1,#1 + + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v3.16b,v3.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v6.16b,v6.16b,v1.16b + eor v3.16b,v3.16b,v5.16b + shl v1.16b,v1.16b,#1 + eor v3.16b,v3.16b,v6.16b + st1 {v3.4s},[x2],#16 + b.eq .Ldone + + dup v6.4s,v3.s[3] // just splat + ext v5.16b,v0.16b,v4.16b,#12 + aese v6.16b,v0.16b + + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + ext v5.16b,v0.16b,v5.16b,#12 + eor v4.16b,v4.16b,v5.16b + + eor v4.16b,v4.16b,v6.16b + b .Loop256 + +.Ldone: + str w12,[x2] + mov x3,#0 + +.Lenc_key_abort: + mov x0,x3 // return value + ldr x29,[sp],#16 + ret +.size aes_v8_set_encrypt_key,.-aes_v8_set_encrypt_key + +.globl aes_v8_set_decrypt_key +.type aes_v8_set_decrypt_key,%function +.align 5 +aes_v8_set_decrypt_key: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + bl .Lenc_key + + cmp x0,#0 + b.ne .Ldec_key_abort + + sub x2,x2,#240 // restore original x2 + mov x4,#-16 + add x0,x2,x12,lsl#4 // end of key schedule + + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + +.Loop_imc: + ld1 {v0.4s},[x2] + ld1 {v1.4s},[x0] + aesimc v0.16b,v0.16b + aesimc v1.16b,v1.16b + st1 {v0.4s},[x0],x4 + st1 {v1.4s},[x2],#16 + cmp x0,x2 + b.hi .Loop_imc + + ld1 {v0.4s},[x2] + aesimc v0.16b,v0.16b + st1 {v0.4s},[x0] + + eor x0,x0,x0 // return value +.Ldec_key_abort: + ldp x29,x30,[sp],#16 + ret +.size aes_v8_set_decrypt_key,.-aes_v8_set_decrypt_key +.globl aes_v8_encrypt +.type aes_v8_encrypt,%function +.align 5 +aes_v8_encrypt: + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_enc: + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aese v2.16b,v1.16b + aesmc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_enc + + aese v2.16b,v0.16b + aesmc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aese v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_v8_encrypt,.-aes_v8_encrypt +.globl aes_v8_decrypt +.type aes_v8_decrypt,%function +.align 5 +aes_v8_decrypt: + ldr w3,[x2,#240] + ld1 {v0.4s},[x2],#16 + ld1 {v2.16b},[x0] + sub w3,w3,#2 + ld1 {v1.4s},[x2],#16 + +.Loop_dec: + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2],#16 + subs w3,w3,#2 + aesd v2.16b,v1.16b + aesimc v2.16b,v2.16b + ld1 {v1.4s},[x2],#16 + b.gt .Loop_dec + + aesd v2.16b,v0.16b + aesimc v2.16b,v2.16b + ld1 {v0.4s},[x2] + aesd v2.16b,v1.16b + eor v2.16b,v2.16b,v0.16b + + st1 {v2.16b},[x1] + ret +.size aes_v8_decrypt,.-aes_v8_decrypt +.globl aes_v8_cbc_encrypt +.type aes_v8_cbc_encrypt,%function +.align 5 +aes_v8_cbc_encrypt: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + subs x2,x2,#16 + mov x8,#16 + b.lo .Lcbc_abort + csel x8,xzr,x8,eq + + cmp w5,#0 // en- or decrypting? + ldr w5,[x3,#240] + and x2,x2,#-16 + ld1 {v6.16b},[x4] + ld1 {v0.16b},[x0],x8 + + ld1 {v16.4s-v17.4s},[x3] // load key schedule... + sub w5,w5,#6 + add x7,x3,x5,lsl#4 // pointer to last 7 round keys + sub w5,w5,#2 + ld1 {v18.4s-v19.4s},[x7],#32 + ld1 {v20.4s-v21.4s},[x7],#32 + ld1 {v22.4s-v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + + add x7,x3,#32 + mov w6,w5 + b.eq .Lcbc_dec + + cmp w5,#2 + eor v0.16b,v0.16b,v6.16b + eor v5.16b,v16.16b,v7.16b + b.eq .Lcbc_enc128 + + ld1 {v2.4s-v3.4s},[x7] + add x7,x3,#16 + add x6,x3,#16*4 + add x12,x3,#16*5 + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + add x14,x3,#16*6 + add x3,x3,#16*7 + b .Lenter_cbc_enc + +.align 4 +.Loop_cbc_enc: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x6] + cmp w5,#4 + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x12] + b.eq .Lcbc_enc192 + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + ld1 {v16.4s},[x14] + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x3] + nop + +.Lcbc_enc192: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + ld1 {v17.4s},[x7] // re-pre-load rndkey[1] + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc + + st1 {v6.16b},[x1],#16 + b .Lcbc_done + +.align 5 +.Lcbc_enc128: + ld1 {v2.4s-v3.4s},[x7] + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + b .Lenter_cbc_enc128 +.Loop_cbc_enc128: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + st1 {v6.16b},[x1],#16 +.Lenter_cbc_enc128: + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + subs x2,x2,#16 + aese v0.16b,v2.16b + aesmc v0.16b,v0.16b + csel x8,xzr,x8,eq + aese v0.16b,v3.16b + aesmc v0.16b,v0.16b + aese v0.16b,v18.16b + aesmc v0.16b,v0.16b + aese v0.16b,v19.16b + aesmc v0.16b,v0.16b + ld1 {v16.16b},[x0],x8 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + eor v16.16b,v16.16b,v5.16b + aese v0.16b,v23.16b + eor v6.16b,v0.16b,v7.16b + b.hs .Loop_cbc_enc128 + + st1 {v6.16b},[x1],#16 + b .Lcbc_done +.align 5 +.Lcbc_dec: + ld1 {v18.16b},[x0],#16 + subs x2,x2,#32 // bias + add w6,w5,#2 + orr v3.16b,v0.16b,v0.16b + orr v1.16b,v0.16b,v0.16b + orr v19.16b,v18.16b,v18.16b + b.lo .Lcbc_dec_tail + + orr v1.16b,v18.16b,v18.16b + ld1 {v18.16b},[x0],#16 + orr v2.16b,v0.16b,v0.16b + orr v3.16b,v1.16b,v1.16b + orr v19.16b,v18.16b,v18.16b + +.Loop3x_cbc_dec: + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_cbc_dec + + aesd v0.16b,v16.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + eor v4.16b,v6.16b,v7.16b + subs x2,x2,#0x30 + eor v5.16b,v2.16b,v7.16b + csel x6,x2,x6,lo // x6, w6, is zero at this point + aesd v0.16b,v17.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + eor v17.16b,v3.16b,v7.16b + add x0,x0,x6 // x0 is adjusted in such way that + // at exit from the loop v1.16b-v18.16b + // are loaded with last "words" + orr v6.16b,v19.16b,v19.16b + mov x7,x3 + aesd v0.16b,v20.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v20.16b + aesimc v18.16b,v18.16b + ld1 {v2.16b},[x0],#16 + aesd v0.16b,v21.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v21.16b + aesimc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + aesd v0.16b,v22.16b + aesimc v0.16b,v0.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v22.16b + aesimc v18.16b,v18.16b + ld1 {v19.16b},[x0],#16 + aesd v0.16b,v23.16b + aesd v1.16b,v23.16b + aesd v18.16b,v23.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + add w6,w5,#2 + eor v4.16b,v4.16b,v0.16b + eor v5.16b,v5.16b,v1.16b + eor v18.16b,v18.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v4.16b},[x1],#16 + orr v0.16b,v2.16b,v2.16b + st1 {v5.16b},[x1],#16 + orr v1.16b,v3.16b,v3.16b + st1 {v18.16b},[x1],#16 + orr v18.16b,v19.16b,v19.16b + b.hs .Loop3x_cbc_dec + + cmn x2,#0x30 + b.eq .Lcbc_done + nop + +.Lcbc_dec_tail: + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lcbc_dec_tail + + aesd v1.16b,v16.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v16.16b + aesimc v18.16b,v18.16b + aesd v1.16b,v17.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v17.16b + aesimc v18.16b,v18.16b + aesd v1.16b,v20.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v20.16b + aesimc v18.16b,v18.16b + cmn x2,#0x20 + aesd v1.16b,v21.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v21.16b + aesimc v18.16b,v18.16b + eor v5.16b,v6.16b,v7.16b + aesd v1.16b,v22.16b + aesimc v1.16b,v1.16b + aesd v18.16b,v22.16b + aesimc v18.16b,v18.16b + eor v17.16b,v3.16b,v7.16b + aesd v1.16b,v23.16b + aesd v18.16b,v23.16b + b.eq .Lcbc_dec_one + eor v5.16b,v5.16b,v1.16b + eor v17.16b,v17.16b,v18.16b + orr v6.16b,v19.16b,v19.16b + st1 {v5.16b},[x1],#16 + st1 {v17.16b},[x1],#16 + b .Lcbc_done + +.Lcbc_dec_one: + eor v5.16b,v5.16b,v18.16b + orr v6.16b,v19.16b,v19.16b + st1 {v5.16b},[x1],#16 + +.Lcbc_done: + st1 {v6.16b},[x4] +.Lcbc_abort: + ldr x29,[sp],#16 + ret +.size aes_v8_cbc_encrypt,.-aes_v8_cbc_encrypt +.globl aes_v8_ctr32_encrypt_blocks +.type aes_v8_ctr32_encrypt_blocks,%function +.align 5 +aes_v8_ctr32_encrypt_blocks: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + ldr w5,[x3,#240] + + ldr w8, [x4, #12] + ld1 {v0.4s},[x4] + + ld1 {v16.4s-v17.4s},[x3] // load key schedule... + sub w5,w5,#4 + mov x12,#16 + cmp x2,#2 + add x7,x3,x5,lsl#4 // pointer to last 5 round keys + sub w5,w5,#2 + ld1 {v20.4s-v21.4s},[x7],#32 + ld1 {v22.4s-v23.4s},[x7],#32 + ld1 {v7.4s},[x7] + add x7,x3,#32 + mov w6,w5 + csel x12,xzr,x12,lo +#ifndef __ARMEB__ + rev w8, w8 +#endif + orr v1.16b,v0.16b,v0.16b + add w10, w8, #1 + orr v18.16b,v0.16b,v0.16b + add w8, w8, #2 + orr v6.16b,v0.16b,v0.16b + rev w10, w10 + mov v1.s[3],w10 + b.ls .Lctr32_tail + rev w12, w8 + sub x2,x2,#3 // bias + mov v18.s[3],w12 + b .Loop3x_ctr32 + +.align 4 +.Loop3x_ctr32: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + aese v18.16b,v17.16b + aesmc v18.16b,v18.16b + ld1 {v17.4s},[x7],#16 + b.gt .Loop3x_ctr32 + + aese v0.16b,v16.16b + aesmc v4.16b,v0.16b + aese v1.16b,v16.16b + aesmc v5.16b,v1.16b + ld1 {v2.16b},[x0],#16 + orr v0.16b,v6.16b,v6.16b + aese v18.16b,v16.16b + aesmc v18.16b,v18.16b + ld1 {v3.16b},[x0],#16 + orr v1.16b,v6.16b,v6.16b + aese v4.16b,v17.16b + aesmc v4.16b,v4.16b + aese v5.16b,v17.16b + aesmc v5.16b,v5.16b + ld1 {v19.16b},[x0],#16 + mov x7,x3 + aese v18.16b,v17.16b + aesmc v17.16b,v18.16b + orr v18.16b,v6.16b,v6.16b + add w9,w8,#1 + aese v4.16b,v20.16b + aesmc v4.16b,v4.16b + aese v5.16b,v20.16b + aesmc v5.16b,v5.16b + eor v2.16b,v2.16b,v7.16b + add w10,w8,#2 + aese v17.16b,v20.16b + aesmc v17.16b,v17.16b + eor v3.16b,v3.16b,v7.16b + add w8,w8,#3 + aese v4.16b,v21.16b + aesmc v4.16b,v4.16b + aese v5.16b,v21.16b + aesmc v5.16b,v5.16b + eor v19.16b,v19.16b,v7.16b + rev w9,w9 + aese v17.16b,v21.16b + aesmc v17.16b,v17.16b + mov v0.s[3], w9 + rev w10,w10 + aese v4.16b,v22.16b + aesmc v4.16b,v4.16b + aese v5.16b,v22.16b + aesmc v5.16b,v5.16b + mov v1.s[3], w10 + rev w12,w8 + aese v17.16b,v22.16b + aesmc v17.16b,v17.16b + mov v18.s[3], w12 + subs x2,x2,#3 + aese v4.16b,v23.16b + aese v5.16b,v23.16b + aese v17.16b,v23.16b + + eor v2.16b,v2.16b,v4.16b + ld1 {v16.4s},[x7],#16 // re-pre-load rndkey[0] + st1 {v2.16b},[x1],#16 + eor v3.16b,v3.16b,v5.16b + mov w6,w5 + st1 {v3.16b},[x1],#16 + eor v19.16b,v19.16b,v17.16b + ld1 {v17.4s},[x7],#16 // re-pre-load rndkey[1] + st1 {v19.16b},[x1],#16 + b.hs .Loop3x_ctr32 + + adds x2,x2,#3 + b.eq .Lctr32_done + cmp x2,#1 + mov x12,#16 + csel x12,xzr,x12,eq + +.Lctr32_tail: + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + ld1 {v16.4s},[x7],#16 + subs w6,w6,#2 + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v17.4s},[x7],#16 + b.gt .Lctr32_tail + + aese v0.16b,v16.16b + aesmc v0.16b,v0.16b + aese v1.16b,v16.16b + aesmc v1.16b,v1.16b + aese v0.16b,v17.16b + aesmc v0.16b,v0.16b + aese v1.16b,v17.16b + aesmc v1.16b,v1.16b + ld1 {v2.16b},[x0],x12 + aese v0.16b,v20.16b + aesmc v0.16b,v0.16b + aese v1.16b,v20.16b + aesmc v1.16b,v1.16b + ld1 {v3.16b},[x0] + aese v0.16b,v21.16b + aesmc v0.16b,v0.16b + aese v1.16b,v21.16b + aesmc v1.16b,v1.16b + eor v2.16b,v2.16b,v7.16b + aese v0.16b,v22.16b + aesmc v0.16b,v0.16b + aese v1.16b,v22.16b + aesmc v1.16b,v1.16b + eor v3.16b,v3.16b,v7.16b + aese v0.16b,v23.16b + aese v1.16b,v23.16b + + cmp x2,#1 + eor v2.16b,v2.16b,v0.16b + eor v3.16b,v3.16b,v1.16b + st1 {v2.16b},[x1],#16 + b.eq .Lctr32_done + st1 {v3.16b},[x1] + +.Lctr32_done: + ldr x29,[sp],#16 + ret +.size aes_v8_ctr32_encrypt_blocks,.-aes_v8_ctr32_encrypt_blocks +#endif diff --git a/secure/lib/libcrypto/aarch64/ghashv8-armx.S b/secure/lib/libcrypto/aarch64/ghashv8-armx.S new file mode 100644 index 000000000000..61a4e4488d16 --- /dev/null +++ b/secure/lib/libcrypto/aarch64/ghashv8-armx.S @@ -0,0 +1,228 @@ +/* $FreeBSD$ */ +/* Do not modify. This file is auto-generated from ghashv8-armx.pl. */ +#include "arm_arch.h" + +.text +.global gcm_init_v8 +.type gcm_init_v8,%function +.align 4 +gcm_init_v8: + ld1 {v17.2d},[x1] //load input H + movi v19.16b,#0xe1 + shl v19.2d,v19.2d,#57 //0xc2.0 + ext v3.16b,v17.16b,v17.16b,#8 + ushr v18.2d,v19.2d,#63 + dup v17.4s,v17.s[1] + ext v16.16b,v18.16b,v19.16b,#8 //t0=0xc2....01 + ushr v18.2d,v3.2d,#63 + sshr v17.4s,v17.4s,#31 //broadcast carry bit + and v18.16b,v18.16b,v16.16b + shl v3.2d,v3.2d,#1 + ext v18.16b,v18.16b,v18.16b,#8 + and v16.16b,v16.16b,v17.16b + orr v3.16b,v3.16b,v18.16b //H<<<=1 + eor v20.16b,v3.16b,v16.16b //twisted H + st1 {v20.2d},[x0],#16 //store Htable[0] + + //calculate H^2 + ext v16.16b,v20.16b,v20.16b,#8 //Karatsuba pre-processing + pmull v0.1q,v20.1d,v20.1d + eor v16.16b,v16.16b,v20.16b + pmull2 v2.1q,v20.2d,v20.2d + pmull v1.1q,v16.1d,v16.1d + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v22.16b,v0.16b,v18.16b + + ext v17.16b,v22.16b,v22.16b,#8 //Karatsuba pre-processing + eor v17.16b,v17.16b,v22.16b + ext v21.16b,v16.16b,v17.16b,#8 //pack Karatsuba pre-processed + st1 {v21.2d-v22.2d},[x0] //store Htable[1..2] + + ret +.size gcm_init_v8,.-gcm_init_v8 +.global gcm_gmult_v8 +.type gcm_gmult_v8,%function +.align 4 +gcm_gmult_v8: + ld1 {v17.2d},[x0] //load Xi + movi v19.16b,#0xe1 + ld1 {v20.2d-v21.2d},[x1] //load twisted H, ... + shl v19.2d,v19.2d,#57 +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ext v3.16b,v17.16b,v17.16b,#8 + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_gmult_v8,.-gcm_gmult_v8 +.global gcm_ghash_v8 +.type gcm_ghash_v8,%function +.align 4 +gcm_ghash_v8: + ld1 {v0.2d},[x0] //load [rotated] Xi + //"[rotated]" means that + //loaded value would have + //to be rotated in order to + //make it appear as in + //alorithm specification + subs x3,x3,#32 //see if x3 is 32 or larger + mov x12,#16 //x12 is used as post- + //increment for input pointer; + //as loop is modulo-scheduled + //x12 is zeroed just in time + //to preclude oversteping + //inp[len], which means that + //last block[s] are actually + //loaded twice, but last + //copy is not processed + ld1 {v20.2d-v21.2d},[x1],#32 //load twisted H, ..., H^2 + movi v19.16b,#0xe1 + ld1 {v22.2d},[x1] + csel x12,xzr,x12,eq //is it time to zero x12? + ext v0.16b,v0.16b,v0.16b,#8 //rotate Xi + ld1 {v16.2d},[x2],#16 //load [rotated] I[0] + shl v19.2d,v19.2d,#57 //compose 0xc2.0 constant +#ifndef __ARMEB__ + rev64 v16.16b,v16.16b + rev64 v0.16b,v0.16b +#endif + ext v3.16b,v16.16b,v16.16b,#8 //rotate I[0] + b.lo .Lodd_tail_v8 //x3 was less than 32 + ld1 {v17.2d},[x2],x12 //load [rotated] I[1] +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ext v7.16b,v17.16b,v17.16b,#8 + eor v3.16b,v3.16b,v0.16b //I[i]^=Xi + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + pmull2 v6.1q,v20.2d,v7.2d + b .Loop_mod2x_v8 + +.align 4 +.Loop_mod2x_v8: + ext v18.16b,v3.16b,v3.16b,#8 + subs x3,x3,#32 //is there more data? + pmull v0.1q,v22.1d,v3.1d //H^2.lo·Xi.lo + csel x12,xzr,x12,lo //is it time to zero x12? + + pmull v5.1q,v21.1d,v17.1d + eor v18.16b,v18.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v22.2d,v3.2d //H^2.hi·Xi.hi + eor v0.16b,v0.16b,v4.16b //accumulate + pmull2 v1.1q,v21.2d,v18.2d //(H^2.lo+H^2.hi)·(Xi.lo+Xi.hi) + ld1 {v16.2d},[x2],x12 //load [rotated] I[i+2] + + eor v2.16b,v2.16b,v6.16b + csel x12,xzr,x12,eq //is it time to zero x12? + eor v1.16b,v1.16b,v5.16b + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + ld1 {v17.2d},[x2],x12 //load [rotated] I[i+3] +#ifndef __ARMEB__ + rev64 v16.16b,v16.16b +#endif + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + +#ifndef __ARMEB__ + rev64 v17.16b,v17.16b +#endif + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + ext v7.16b,v17.16b,v17.16b,#8 + ext v3.16b,v16.16b,v16.16b,#8 + eor v0.16b,v1.16b,v18.16b + pmull v4.1q,v20.1d,v7.1d //H·Ii+1 + eor v3.16b,v3.16b,v2.16b //accumulate v3.16b early + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v3.16b,v3.16b,v18.16b + eor v17.16b,v17.16b,v7.16b //Karatsuba pre-processing + eor v3.16b,v3.16b,v0.16b + pmull2 v6.1q,v20.2d,v7.2d + b.hs .Loop_mod2x_v8 //there was at least 32 more bytes + + eor v2.16b,v2.16b,v18.16b + ext v3.16b,v16.16b,v16.16b,#8 //re-construct v3.16b + adds x3,x3,#32 //re-construct x3 + eor v0.16b,v0.16b,v2.16b //re-construct v0.16b + b.eq .Ldone_v8 //is x3 zero? +.Lodd_tail_v8: + ext v18.16b,v0.16b,v0.16b,#8 + eor v3.16b,v3.16b,v0.16b //inp^=Xi + eor v17.16b,v16.16b,v18.16b //v17.16b is rotated inp^Xi + + pmull v0.1q,v20.1d,v3.1d //H.lo·Xi.lo + eor v17.16b,v17.16b,v3.16b //Karatsuba pre-processing + pmull2 v2.1q,v20.2d,v3.2d //H.hi·Xi.hi + pmull v1.1q,v21.1d,v17.1d //(H.lo+H.hi)·(Xi.lo+Xi.hi) + + ext v17.16b,v0.16b,v2.16b,#8 //Karatsuba post-processing + eor v18.16b,v0.16b,v2.16b + eor v1.16b,v1.16b,v17.16b + eor v1.16b,v1.16b,v18.16b + pmull v18.1q,v0.1d,v19.1d //1st phase of reduction + + ins v2.d[0],v1.d[1] + ins v1.d[1],v0.d[0] + eor v0.16b,v1.16b,v18.16b + + ext v18.16b,v0.16b,v0.16b,#8 //2nd phase of reduction + pmull v0.1q,v0.1d,v19.1d + eor v18.16b,v18.16b,v2.16b + eor v0.16b,v0.16b,v18.16b + +.Ldone_v8: +#ifndef __ARMEB__ + rev64 v0.16b,v0.16b +#endif + ext v0.16b,v0.16b,v0.16b,#8 + st1 {v0.2d},[x0] //write out Xi + + ret +.size gcm_ghash_v8,.-gcm_ghash_v8 +.asciz "GHASH for ARMv8, CRYPTOGAMS by " +.align 2 diff --git a/secure/lib/libcrypto/aarch64/sha1-armv8.S b/secure/lib/libcrypto/aarch64/sha1-armv8.S new file mode 100644 index 000000000000..ad5bf932fec9 --- /dev/null +++ b/secure/lib/libcrypto/aarch64/sha1-armv8.S @@ -0,0 +1,1213 @@ +/* $FreeBSD$ */ +/* Do not modify. This file is auto-generated from sha1-armv8.pl. */ +#include "arm_arch.h" + +.text + +.globl sha1_block_data_order +.type sha1_block_data_order,%function +.align 6 +sha1_block_data_order: + ldr x16,.LOPENSSL_armcap_P + adr x17,.LOPENSSL_armcap_P + add x16,x16,x17 + ldr w16,[x16] + tst w16,#ARMV8_SHA1 + b.ne .Lv8_entry + + stp x29,x30,[sp,#-96]! + add x29,sp,#0 + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + + ldp w20,w21,[x0] + ldp w22,w23,[x0,#8] + ldr w24,[x0,#16] + +.Loop: + ldr x3,[x1],#64 + movz w28,#0x7999 + sub x2,x2,#1 + movk w28,#0x5a82,lsl#16 +#ifdef __ARMEB__ + ror x3,x3,#32 +#else + rev32 x3,x3 +#endif + add w24,w24,w28 // warm it up + add w24,w24,w3 + lsr x4,x3,#32 + ldr x5,[x1,#-56] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w4 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x5,x5,#32 +#else + rev32 x5,x5 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w5 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x6,x5,#32 + ldr x7,[x1,#-48] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w6 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x7,x7,#32 +#else + rev32 x7,x7 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w7 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x8,x7,#32 + ldr x9,[x1,#-40] + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w8 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x9,x9,#32 +#else + rev32 x9,x9 +#endif + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w9 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + lsr x10,x9,#32 + ldr x11,[x1,#-32] + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w10 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x11,x11,#32 +#else + rev32 x11,x11 +#endif + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w11 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + lsr x12,x11,#32 + ldr x13,[x1,#-24] + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w12 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x13,x13,#32 +#else + rev32 x13,x13 +#endif + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + add w24,w24,w13 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + lsr x14,x13,#32 + ldr x15,[x1,#-16] + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + add w23,w23,w14 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x15,x15,#32 +#else + rev32 x15,x15 +#endif + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + add w22,w22,w15 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + lsr x16,x15,#32 + ldr x17,[x1,#-8] + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + add w21,w21,w16 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) +#ifdef __ARMEB__ + ror x17,x17,#32 +#else + rev32 x17,x17 +#endif + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w17 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + lsr x19,x17,#32 + eor w3,w3,w5 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w3,w3,w11 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w3,w3,w16 + ror w22,w22,#2 + add w24,w24,w19 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + bic w25,w23,w21 + and w26,w22,w21 + ror w27,w20,#27 + eor w4,w4,w12 + add w23,w23,w28 // future e+=K + orr w25,w25,w26 + add w24,w24,w27 // e+=rot(a,5) + eor w4,w4,w17 + ror w21,w21,#2 + add w23,w23,w3 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + bic w25,w22,w20 + and w26,w21,w20 + ror w27,w24,#27 + eor w5,w5,w13 + add w22,w22,w28 // future e+=K + orr w25,w25,w26 + add w23,w23,w27 // e+=rot(a,5) + eor w5,w5,w19 + ror w20,w20,#2 + add w22,w22,w4 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + bic w25,w21,w24 + and w26,w20,w24 + ror w27,w23,#27 + eor w6,w6,w14 + add w21,w21,w28 // future e+=K + orr w25,w25,w26 + add w22,w22,w27 // e+=rot(a,5) + eor w6,w6,w3 + ror w24,w24,#2 + add w21,w21,w5 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + bic w25,w20,w23 + and w26,w24,w23 + ror w27,w22,#27 + eor w7,w7,w15 + add w20,w20,w28 // future e+=K + orr w25,w25,w26 + add w21,w21,w27 // e+=rot(a,5) + eor w7,w7,w4 + ror w23,w23,#2 + add w20,w20,w6 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w7,w7,#31 + movz w28,#0xeba1 + movk w28,#0x6ed9,lsl#16 + eor w8,w8,w10 + bic w25,w24,w22 + and w26,w23,w22 + ror w27,w21,#27 + eor w8,w8,w16 + add w24,w24,w28 // future e+=K + orr w25,w25,w26 + add w20,w20,w27 // e+=rot(a,5) + eor w8,w8,w5 + ror w22,w22,#2 + add w24,w24,w7 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w9,w9,w6 + add w23,w23,w8 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w10,w10,w7 + add w22,w22,w9 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w11,w11,w8 + add w21,w21,w10 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w12,w12,w9 + add w20,w20,w11 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w13,w13,w10 + add w24,w24,w12 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w14,w14,w11 + add w23,w23,w13 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w15,w15,w12 + add w22,w22,w14 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w16,w16,w13 + add w21,w21,w15 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w17,w17,w14 + add w20,w20,w16 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w19,w19,w15 + add w24,w24,w17 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w3,w3,w16 + add w23,w23,w19 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w4,w4,w17 + add w22,w22,w3 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w5,w5,w19 + add w21,w21,w4 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w6,w6,w3 + add w20,w20,w5 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w7,w7,w4 + add w24,w24,w6 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w8,w8,w5 + add w23,w23,w7 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w9,w9,w6 + add w22,w22,w8 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w10,w10,w7 + add w21,w21,w9 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w11,w11,w8 + add w20,w20,w10 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w11,w11,#31 + movz w28,#0xbcdc + movk w28,#0x8f1b,lsl#16 + eor w12,w12,w14 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w12,w12,w9 + add w24,w24,w11 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w13,w13,w15 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w13,w13,w5 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w13,w13,w10 + add w23,w23,w12 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w14,w14,w16 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w14,w14,w6 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w14,w14,w11 + add w22,w22,w13 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w15,w15,w17 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w15,w15,w7 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w15,w15,w12 + add w21,w21,w14 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w15,w15,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w16,w16,w19 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w16,w16,w8 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w16,w16,w13 + add w20,w20,w15 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w16,w16,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w17,w17,w3 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w17,w17,w9 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w17,w17,w14 + add w24,w24,w16 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w17,w17,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w19,w19,w4 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w19,w19,w10 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w19,w19,w15 + add w23,w23,w17 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w19,w19,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w3,w3,w5 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w3,w3,w11 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w3,w3,w16 + add w22,w22,w19 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w3,w3,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w4,w4,w6 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w4,w4,w12 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w4,w4,w17 + add w21,w21,w3 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w4,w4,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w5,w5,w7 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w5,w5,w13 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w5,w5,w19 + add w20,w20,w4 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w5,w5,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w6,w6,w8 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w6,w6,w14 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w6,w6,w3 + add w24,w24,w5 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w6,w6,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w7,w7,w9 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w7,w7,w15 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w7,w7,w4 + add w23,w23,w6 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w7,w7,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w8,w8,w10 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w8,w8,w16 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w8,w8,w5 + add w22,w22,w7 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w8,w8,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w9,w9,w11 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w9,w9,w17 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w9,w9,w6 + add w21,w21,w8 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w9,w9,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w10,w10,w12 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w10,w10,w19 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w10,w10,w7 + add w20,w20,w9 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w10,w10,#31 + orr w25,w22,w23 + and w26,w22,w23 + eor w11,w11,w13 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w11,w11,w3 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w11,w11,w8 + add w24,w24,w10 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w11,w11,#31 + orr w25,w21,w22 + and w26,w21,w22 + eor w12,w12,w14 + ror w27,w20,#27 + and w25,w25,w23 + add w23,w23,w28 // future e+=K + eor w12,w12,w4 + add w24,w24,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w21,w21,#2 + eor w12,w12,w9 + add w23,w23,w11 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w12,w12,#31 + orr w25,w20,w21 + and w26,w20,w21 + eor w13,w13,w15 + ror w27,w24,#27 + and w25,w25,w22 + add w22,w22,w28 // future e+=K + eor w13,w13,w5 + add w23,w23,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w20,w20,#2 + eor w13,w13,w10 + add w22,w22,w12 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w13,w13,#31 + orr w25,w24,w20 + and w26,w24,w20 + eor w14,w14,w16 + ror w27,w23,#27 + and w25,w25,w21 + add w21,w21,w28 // future e+=K + eor w14,w14,w6 + add w22,w22,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w24,w24,#2 + eor w14,w14,w11 + add w21,w21,w13 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w14,w14,#31 + orr w25,w23,w24 + and w26,w23,w24 + eor w15,w15,w17 + ror w27,w22,#27 + and w25,w25,w20 + add w20,w20,w28 // future e+=K + eor w15,w15,w7 + add w21,w21,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w23,w23,#2 + eor w15,w15,w12 + add w20,w20,w14 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w15,w15,#31 + movz w28,#0xc1d6 + movk w28,#0xca62,lsl#16 + orr w25,w22,w23 + and w26,w22,w23 + eor w16,w16,w19 + ror w27,w21,#27 + and w25,w25,w24 + add w24,w24,w28 // future e+=K + eor w16,w16,w8 + add w20,w20,w27 // e+=rot(a,5) + orr w25,w25,w26 + ror w22,w22,#2 + eor w16,w16,w13 + add w24,w24,w15 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w17,w17,w14 + add w23,w23,w16 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w19,w19,w15 + add w22,w22,w17 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w19,w19,#31 + eor w3,w3,w5 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w3,w3,w11 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w3,w3,w16 + add w21,w21,w19 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w3,w3,#31 + eor w4,w4,w6 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w4,w4,w12 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w4,w4,w17 + add w20,w20,w3 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w4,w4,#31 + eor w5,w5,w7 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w5,w5,w13 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w5,w5,w19 + add w24,w24,w4 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w5,w5,#31 + eor w6,w6,w8 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w6,w6,w14 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w6,w6,w3 + add w23,w23,w5 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w6,w6,#31 + eor w7,w7,w9 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w7,w7,w15 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w7,w7,w4 + add w22,w22,w6 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w7,w7,#31 + eor w8,w8,w10 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w8,w8,w16 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w8,w8,w5 + add w21,w21,w7 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w8,w8,#31 + eor w9,w9,w11 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w9,w9,w17 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w9,w9,w6 + add w20,w20,w8 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w9,w9,#31 + eor w10,w10,w12 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w10,w10,w19 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w10,w10,w7 + add w24,w24,w9 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w10,w10,#31 + eor w11,w11,w13 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w11,w11,w3 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w11,w11,w8 + add w23,w23,w10 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w11,w11,#31 + eor w12,w12,w14 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w12,w12,w4 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w12,w12,w9 + add w22,w22,w11 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w12,w12,#31 + eor w13,w13,w15 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w13,w13,w5 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w13,w13,w10 + add w21,w21,w12 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w13,w13,#31 + eor w14,w14,w16 + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w14,w14,w6 + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + eor w14,w14,w11 + add w20,w20,w13 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ror w14,w14,#31 + eor w15,w15,w17 + eor w25,w24,w22 + ror w27,w21,#27 + add w24,w24,w28 // future e+=K + eor w15,w15,w7 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + eor w15,w15,w12 + add w24,w24,w14 // future e+=X[i] + add w20,w20,w25 // e+=F(b,c,d) + ror w15,w15,#31 + eor w16,w16,w19 + eor w25,w23,w21 + ror w27,w20,#27 + add w23,w23,w28 // future e+=K + eor w16,w16,w8 + eor w25,w25,w22 + add w24,w24,w27 // e+=rot(a,5) + ror w21,w21,#2 + eor w16,w16,w13 + add w23,w23,w15 // future e+=X[i] + add w24,w24,w25 // e+=F(b,c,d) + ror w16,w16,#31 + eor w17,w17,w3 + eor w25,w22,w20 + ror w27,w24,#27 + add w22,w22,w28 // future e+=K + eor w17,w17,w9 + eor w25,w25,w21 + add w23,w23,w27 // e+=rot(a,5) + ror w20,w20,#2 + eor w17,w17,w14 + add w22,w22,w16 // future e+=X[i] + add w23,w23,w25 // e+=F(b,c,d) + ror w17,w17,#31 + eor w19,w19,w4 + eor w25,w21,w24 + ror w27,w23,#27 + add w21,w21,w28 // future e+=K + eor w19,w19,w10 + eor w25,w25,w20 + add w22,w22,w27 // e+=rot(a,5) + ror w24,w24,#2 + eor w19,w19,w15 + add w21,w21,w17 // future e+=X[i] + add w22,w22,w25 // e+=F(b,c,d) + ror w19,w19,#31 + ldp w4,w5,[x0] + eor w25,w20,w23 + ror w27,w22,#27 + add w20,w20,w28 // future e+=K + eor w25,w25,w24 + add w21,w21,w27 // e+=rot(a,5) + ror w23,w23,#2 + add w20,w20,w19 // future e+=X[i] + add w21,w21,w25 // e+=F(b,c,d) + ldp w6,w7,[x0,#8] + eor w25,w24,w22 + ror w27,w21,#27 + eor w25,w25,w23 + add w20,w20,w27 // e+=rot(a,5) + ror w22,w22,#2 + ldr w8,[x0,#16] + add w20,w20,w25 // e+=F(b,c,d) + add w21,w21,w5 + add w22,w22,w6 + add w20,w20,w4 + add w23,w23,w7 + add w24,w24,w8 + stp w20,w21,[x0] + stp w22,w23,[x0,#8] + str w24,[x0,#16] + cbnz x2,.Loop + + ldp x19,x20,[sp,#16] + ldp x21,x22,[sp,#32] + ldp x23,x24,[sp,#48] + ldp x25,x26,[sp,#64] + ldp x27,x28,[sp,#80] + ldr x29,[sp],#96 + ret +.size sha1_block_data_order,.-sha1_block_data_order +.type sha1_block_armv8,%function +.align 6 +sha1_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + adr x4,.Lconst + eor v1.16b,v1.16b,v1.16b + ld1 {v0.4s},[x0],#16 + ld1 {v1.s}[0],[x0] + sub x0,x0,#16 + ld1 {v16.4s-v19.4s},[x4] + +.Loop_hw: + ld1 {v4.16b-v7.16b},[x1],#64 + sub x2,x2,#1 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + + add v20.4s,v16.4s,v4.4s + rev32 v6.16b,v6.16b + orr v22.16b,v0.16b,v0.16b // offload + + add v21.4s,v16.4s,v5.4s + rev32 v7.16b,v7.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b + .inst 0x5e140020 //sha1c v0.16b,v1.16b,v20.4s // 0 + add v20.4s,v16.4s,v6.4s + .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 1 + .inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v16.4s,v7.4s + .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b + .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 2 + .inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v16.4s,v4.4s + .inst 0x5e281885 //sha1su1 v5.16b,v4.16b + .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 3 + .inst 0x5e150060 //sha1c v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s + .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b + .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 4 + .inst 0x5e140040 //sha1c v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v6.4s + .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b + .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 5 + .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v7.4s + .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b + .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 6 + .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v17.4s,v4.4s + .inst 0x5e281885 //sha1su1 v5.16b,v4.16b + .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 7 + .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v17.4s,v5.4s + .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b + .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 8 + .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s + .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b + .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 9 + .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v7.4s + .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b + .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 10 + .inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v4.4s + .inst 0x5e281885 //sha1su1 v5.16b,v4.16b + .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 11 + .inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v18.4s,v5.4s + .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b + .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 12 + .inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v18.4s,v6.4s + .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b + .inst 0x5e0630a4 //sha1su0 v4.16b,v5.16b,v6.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 13 + .inst 0x5e152060 //sha1m v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s + .inst 0x5e2818e4 //sha1su1 v4.16b,v7.16b + .inst 0x5e0730c5 //sha1su0 v5.16b,v6.16b,v7.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 14 + .inst 0x5e142040 //sha1m v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v4.4s + .inst 0x5e281885 //sha1su1 v5.16b,v4.16b + .inst 0x5e0430e6 //sha1su0 v6.16b,v7.16b,v4.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 15 + .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v5.4s + .inst 0x5e2818a6 //sha1su1 v6.16b,v5.16b + .inst 0x5e053087 //sha1su0 v7.16b,v4.16b,v5.16b + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 16 + .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + add v20.4s,v19.4s,v6.4s + .inst 0x5e2818c7 //sha1su1 v7.16b,v6.16b + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 17 + .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + add v21.4s,v19.4s,v7.4s + + .inst 0x5e280803 //sha1h v3.16b,v0.16b // 18 + .inst 0x5e141040 //sha1p v0.16b,v2.16b,v20.4s + + .inst 0x5e280802 //sha1h v2.16b,v0.16b // 19 + .inst 0x5e151060 //sha1p v0.16b,v3.16b,v21.4s + + add v1.4s,v1.4s,v2.4s + add v0.4s,v0.4s,v22.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s},[x0],#16 + st1 {v1.s}[0],[x0] + + ldr x29,[sp],#16 + ret +.size sha1_block_armv8,.-sha1_block_armv8 +.align 6 +.Lconst: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 //K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 //K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc //K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 //K_60_79 +.LOPENSSL_armcap_P: +.quad OPENSSL_armcap_P-. +.asciz "SHA1 block transform for ARMv8, CRYPTOGAMS by " +.align 2 +.comm OPENSSL_armcap_P,4,4 diff --git a/secure/lib/libcrypto/aarch64/sha256-armv8.S b/secure/lib/libcrypto/aarch64/sha256-armv8.S new file mode 100644 index 000000000000..eff9d2433a0b --- /dev/null +++ b/secure/lib/libcrypto/aarch64/sha256-armv8.S @@ -0,0 +1,1143 @@ +/* $FreeBSD$ */ +/* Do not modify. This file is auto-generated from sha512-armv8.pl. */ +#include "arm_arch.h" + +.text + +.globl sha256_block_data_order +.type sha256_block_data_order,%function +.align 6 +sha256_block_data_order: + ldr x16,.LOPENSSL_armcap_P + adr x17,.LOPENSSL_armcap_P + add x16,x16,x17 + ldr w16,[x16] + tst w16,#ARMV8_SHA256 + b.ne .Lv8_entry + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*4 + + ldp w20,w21,[x0] // load context + ldp w22,w23,[x0,#2*4] + ldp w24,w25,[x0,#4*4] + add x2,x1,x2,lsl#6 // end of input + ldp w26,w27,[x0,#6*4] + adr x30,K256 + stp x0,x2,[x29,#96] + +.Loop: + ldp w3,w4,[x1],#2*4 + ldr w19,[x30],#4 // *K++ + eor w28,w21,w22 // magic seed + str x1,[x29,#112] +#ifndef __ARMEB__ + rev w3,w3 // 0 +#endif + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w6,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w3 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w4,w4 // 1 +#endif + ldp w5,w6,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w7,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w4 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w5,w5 // 2 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w8,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w5 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w6,w6 // 3 +#endif + ldp w7,w8,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w9,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w6 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w7,w7 // 4 +#endif + add w24,w24,w17 // h+=Sigma0(a) + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w10,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w7 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w10,ror#11 // Sigma1(e) + ror w10,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w10,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w8,w8 // 5 +#endif + ldp w9,w10,[x1],#2*4 + add w23,w23,w17 // h+=Sigma0(a) + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w11,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w8 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w11,ror#11 // Sigma1(e) + ror w11,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w11,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w9,w9 // 6 +#endif + add w22,w22,w17 // h+=Sigma0(a) + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w12,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w9 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w12,ror#11 // Sigma1(e) + ror w12,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w12,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w10,w10 // 7 +#endif + ldp w11,w12,[x1],#2*4 + add w21,w21,w17 // h+=Sigma0(a) + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + eor w13,w25,w25,ror#14 + and w17,w26,w25 + bic w28,w27,w25 + add w20,w20,w10 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w13,ror#11 // Sigma1(e) + ror w13,w21,#2 + add w20,w20,w17 // h+=Ch(e,f,g) + eor w17,w21,w21,ror#9 + add w20,w20,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w24,w24,w20 // d+=h + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w13,w17,ror#13 // Sigma0(a) + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w20,w20,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w11,w11 // 8 +#endif + add w20,w20,w17 // h+=Sigma0(a) + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + eor w14,w24,w24,ror#14 + and w17,w25,w24 + bic w19,w26,w24 + add w27,w27,w11 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w14,ror#11 // Sigma1(e) + ror w14,w20,#2 + add w27,w27,w17 // h+=Ch(e,f,g) + eor w17,w20,w20,ror#9 + add w27,w27,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w23,w23,w27 // d+=h + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w14,w17,ror#13 // Sigma0(a) + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w27,w27,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w12,w12 // 9 +#endif + ldp w13,w14,[x1],#2*4 + add w27,w27,w17 // h+=Sigma0(a) + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + eor w15,w23,w23,ror#14 + and w17,w24,w23 + bic w28,w25,w23 + add w26,w26,w12 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w15,ror#11 // Sigma1(e) + ror w15,w27,#2 + add w26,w26,w17 // h+=Ch(e,f,g) + eor w17,w27,w27,ror#9 + add w26,w26,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w22,w22,w26 // d+=h + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w15,w17,ror#13 // Sigma0(a) + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w26,w26,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w13,w13 // 10 +#endif + add w26,w26,w17 // h+=Sigma0(a) + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + eor w0,w22,w22,ror#14 + and w17,w23,w22 + bic w19,w24,w22 + add w25,w25,w13 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w0,ror#11 // Sigma1(e) + ror w0,w26,#2 + add w25,w25,w17 // h+=Ch(e,f,g) + eor w17,w26,w26,ror#9 + add w25,w25,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w21,w21,w25 // d+=h + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w0,w17,ror#13 // Sigma0(a) + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w25,w25,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w14,w14 // 11 +#endif + ldp w15,w0,[x1],#2*4 + add w25,w25,w17 // h+=Sigma0(a) + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + eor w6,w21,w21,ror#14 + and w17,w22,w21 + bic w28,w23,w21 + add w24,w24,w14 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w6,ror#11 // Sigma1(e) + ror w6,w25,#2 + add w24,w24,w17 // h+=Ch(e,f,g) + eor w17,w25,w25,ror#9 + add w24,w24,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w20,w20,w24 // d+=h + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w17,ror#13 // Sigma0(a) + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w24,w24,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w15,w15 // 12 +#endif + add w24,w24,w17 // h+=Sigma0(a) + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + eor w7,w20,w20,ror#14 + and w17,w21,w20 + bic w19,w22,w20 + add w23,w23,w15 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w7,ror#11 // Sigma1(e) + ror w7,w24,#2 + add w23,w23,w17 // h+=Ch(e,f,g) + eor w17,w24,w24,ror#9 + add w23,w23,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w27,w27,w23 // d+=h + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w17,ror#13 // Sigma0(a) + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w23,w23,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w0,w0 // 13 +#endif + ldp w1,w2,[x1] + add w23,w23,w17 // h+=Sigma0(a) + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + eor w8,w27,w27,ror#14 + and w17,w20,w27 + bic w28,w21,w27 + add w22,w22,w0 // h+=X[i] + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w8,ror#11 // Sigma1(e) + ror w8,w23,#2 + add w22,w22,w17 // h+=Ch(e,f,g) + eor w17,w23,w23,ror#9 + add w22,w22,w16 // h+=Sigma1(e) + and w19,w19,w28 // (b^c)&=(a^b) + add w26,w26,w22 // d+=h + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w17,ror#13 // Sigma0(a) + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + //add w22,w22,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w1,w1 // 14 +#endif + ldr w6,[sp,#12] + add w22,w22,w17 // h+=Sigma0(a) + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + eor w9,w26,w26,ror#14 + and w17,w27,w26 + bic w19,w20,w26 + add w21,w21,w1 // h+=X[i] + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w9,ror#11 // Sigma1(e) + ror w9,w22,#2 + add w21,w21,w17 // h+=Ch(e,f,g) + eor w17,w22,w22,ror#9 + add w21,w21,w16 // h+=Sigma1(e) + and w28,w28,w19 // (b^c)&=(a^b) + add w25,w25,w21 // d+=h + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w17,ror#13 // Sigma0(a) + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + //add w21,w21,w17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev w2,w2 // 15 +#endif + ldr w7,[sp,#0] + add w21,w21,w17 // h+=Sigma0(a) + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 +.Loop_16_xx: + ldr w8,[sp,#4] + str w11,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w10,w5,#7 + and w17,w25,w24 + ror w9,w2,#17 + bic w19,w26,w24 + ror w11,w20,#2 + add w27,w27,w3 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w10,w10,w5,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w11,w11,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w9,w9,w2,ror#19 + eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w11,w20,ror#22 // Sigma0(a) + eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) + add w4,w4,w13 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w4,w4,w10 + add w27,w27,w17 // h+=Sigma0(a) + add w4,w4,w9 + ldr w9,[sp,#8] + str w12,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w11,w6,#7 + and w17,w24,w23 + ror w10,w3,#17 + bic w28,w25,w23 + ror w12,w27,#2 + add w26,w26,w4 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w11,w11,w6,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w12,w12,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w10,w10,w3,ror#19 + eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w12,w27,ror#22 // Sigma0(a) + eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) + add w5,w5,w14 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w5,w5,w11 + add w26,w26,w17 // h+=Sigma0(a) + add w5,w5,w10 + ldr w10,[sp,#12] + str w13,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w12,w7,#7 + and w17,w23,w22 + ror w11,w4,#17 + bic w19,w24,w22 + ror w13,w26,#2 + add w25,w25,w5 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w12,w12,w7,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w13,w13,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w11,w11,w4,ror#19 + eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w13,w26,ror#22 // Sigma0(a) + eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) + add w6,w6,w15 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w6,w6,w12 + add w25,w25,w17 // h+=Sigma0(a) + add w6,w6,w11 + ldr w11,[sp,#0] + str w14,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w13,w8,#7 + and w17,w22,w21 + ror w12,w5,#17 + bic w28,w23,w21 + ror w14,w25,#2 + add w24,w24,w6 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w13,w13,w8,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w14,w14,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w12,w12,w5,ror#19 + eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w14,w25,ror#22 // Sigma0(a) + eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) + add w7,w7,w0 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w7,w7,w13 + add w24,w24,w17 // h+=Sigma0(a) + add w7,w7,w12 + ldr w12,[sp,#4] + str w15,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w14,w9,#7 + and w17,w21,w20 + ror w13,w6,#17 + bic w19,w22,w20 + ror w15,w24,#2 + add w23,w23,w7 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w14,w14,w9,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w15,w15,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w13,w13,w6,ror#19 + eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w15,w24,ror#22 // Sigma0(a) + eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) + add w8,w8,w1 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w8,w8,w14 + add w23,w23,w17 // h+=Sigma0(a) + add w8,w8,w13 + ldr w13,[sp,#8] + str w0,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w15,w10,#7 + and w17,w20,w27 + ror w14,w7,#17 + bic w28,w21,w27 + ror w0,w23,#2 + add w22,w22,w8 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w15,w15,w10,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w0,w0,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w14,w14,w7,ror#19 + eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w0,w23,ror#22 // Sigma0(a) + eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) + add w9,w9,w2 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w9,w9,w15 + add w22,w22,w17 // h+=Sigma0(a) + add w9,w9,w14 + ldr w14,[sp,#12] + str w1,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w0,w11,#7 + and w17,w27,w26 + ror w15,w8,#17 + bic w19,w20,w26 + ror w1,w22,#2 + add w21,w21,w9 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w0,w0,w11,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w1,w1,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w15,w15,w8,ror#19 + eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w1,w22,ror#22 // Sigma0(a) + eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) + add w10,w10,w3 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w10,w10,w0 + add w21,w21,w17 // h+=Sigma0(a) + add w10,w10,w15 + ldr w15,[sp,#0] + str w2,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w1,w12,#7 + and w17,w26,w25 + ror w0,w9,#17 + bic w28,w27,w25 + ror w2,w21,#2 + add w20,w20,w10 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w1,w1,w12,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w2,w2,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w0,w0,w9,ror#19 + eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w2,w21,ror#22 // Sigma0(a) + eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) + add w11,w11,w4 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w11,w11,w1 + add w20,w20,w17 // h+=Sigma0(a) + add w11,w11,w0 + ldr w0,[sp,#4] + str w3,[sp,#0] + ror w16,w24,#6 + add w27,w27,w19 // h+=K[i] + ror w2,w13,#7 + and w17,w25,w24 + ror w1,w10,#17 + bic w19,w26,w24 + ror w3,w20,#2 + add w27,w27,w11 // h+=X[i] + eor w16,w16,w24,ror#11 + eor w2,w2,w13,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w20,w21 // a^b, b^c in next round + eor w16,w16,w24,ror#25 // Sigma1(e) + eor w3,w3,w20,ror#13 + add w27,w27,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w1,w1,w10,ror#19 + eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) + add w27,w27,w16 // h+=Sigma1(e) + eor w28,w28,w21 // Maj(a,b,c) + eor w17,w3,w20,ror#22 // Sigma0(a) + eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) + add w12,w12,w5 + add w23,w23,w27 // d+=h + add w27,w27,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w12,w12,w2 + add w27,w27,w17 // h+=Sigma0(a) + add w12,w12,w1 + ldr w1,[sp,#8] + str w4,[sp,#4] + ror w16,w23,#6 + add w26,w26,w28 // h+=K[i] + ror w3,w14,#7 + and w17,w24,w23 + ror w2,w11,#17 + bic w28,w25,w23 + ror w4,w27,#2 + add w26,w26,w12 // h+=X[i] + eor w16,w16,w23,ror#11 + eor w3,w3,w14,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w27,w20 // a^b, b^c in next round + eor w16,w16,w23,ror#25 // Sigma1(e) + eor w4,w4,w27,ror#13 + add w26,w26,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w2,w2,w11,ror#19 + eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) + add w26,w26,w16 // h+=Sigma1(e) + eor w19,w19,w20 // Maj(a,b,c) + eor w17,w4,w27,ror#22 // Sigma0(a) + eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) + add w13,w13,w6 + add w22,w22,w26 // d+=h + add w26,w26,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w13,w13,w3 + add w26,w26,w17 // h+=Sigma0(a) + add w13,w13,w2 + ldr w2,[sp,#12] + str w5,[sp,#8] + ror w16,w22,#6 + add w25,w25,w19 // h+=K[i] + ror w4,w15,#7 + and w17,w23,w22 + ror w3,w12,#17 + bic w19,w24,w22 + ror w5,w26,#2 + add w25,w25,w13 // h+=X[i] + eor w16,w16,w22,ror#11 + eor w4,w4,w15,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w26,w27 // a^b, b^c in next round + eor w16,w16,w22,ror#25 // Sigma1(e) + eor w5,w5,w26,ror#13 + add w25,w25,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w3,w3,w12,ror#19 + eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) + add w25,w25,w16 // h+=Sigma1(e) + eor w28,w28,w27 // Maj(a,b,c) + eor w17,w5,w26,ror#22 // Sigma0(a) + eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) + add w14,w14,w7 + add w21,w21,w25 // d+=h + add w25,w25,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w14,w14,w4 + add w25,w25,w17 // h+=Sigma0(a) + add w14,w14,w3 + ldr w3,[sp,#0] + str w6,[sp,#12] + ror w16,w21,#6 + add w24,w24,w28 // h+=K[i] + ror w5,w0,#7 + and w17,w22,w21 + ror w4,w13,#17 + bic w28,w23,w21 + ror w6,w25,#2 + add w24,w24,w14 // h+=X[i] + eor w16,w16,w21,ror#11 + eor w5,w5,w0,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w25,w26 // a^b, b^c in next round + eor w16,w16,w21,ror#25 // Sigma1(e) + eor w6,w6,w25,ror#13 + add w24,w24,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w4,w4,w13,ror#19 + eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) + add w24,w24,w16 // h+=Sigma1(e) + eor w19,w19,w26 // Maj(a,b,c) + eor w17,w6,w25,ror#22 // Sigma0(a) + eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) + add w15,w15,w8 + add w20,w20,w24 // d+=h + add w24,w24,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w15,w15,w5 + add w24,w24,w17 // h+=Sigma0(a) + add w15,w15,w4 + ldr w4,[sp,#4] + str w7,[sp,#0] + ror w16,w20,#6 + add w23,w23,w19 // h+=K[i] + ror w6,w1,#7 + and w17,w21,w20 + ror w5,w14,#17 + bic w19,w22,w20 + ror w7,w24,#2 + add w23,w23,w15 // h+=X[i] + eor w16,w16,w20,ror#11 + eor w6,w6,w1,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w24,w25 // a^b, b^c in next round + eor w16,w16,w20,ror#25 // Sigma1(e) + eor w7,w7,w24,ror#13 + add w23,w23,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w5,w5,w14,ror#19 + eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) + add w23,w23,w16 // h+=Sigma1(e) + eor w28,w28,w25 // Maj(a,b,c) + eor w17,w7,w24,ror#22 // Sigma0(a) + eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) + add w0,w0,w9 + add w27,w27,w23 // d+=h + add w23,w23,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w0,w0,w6 + add w23,w23,w17 // h+=Sigma0(a) + add w0,w0,w5 + ldr w5,[sp,#8] + str w8,[sp,#4] + ror w16,w27,#6 + add w22,w22,w28 // h+=K[i] + ror w7,w2,#7 + and w17,w20,w27 + ror w6,w15,#17 + bic w28,w21,w27 + ror w8,w23,#2 + add w22,w22,w0 // h+=X[i] + eor w16,w16,w27,ror#11 + eor w7,w7,w2,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w23,w24 // a^b, b^c in next round + eor w16,w16,w27,ror#25 // Sigma1(e) + eor w8,w8,w23,ror#13 + add w22,w22,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w6,w6,w15,ror#19 + eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) + add w22,w22,w16 // h+=Sigma1(e) + eor w19,w19,w24 // Maj(a,b,c) + eor w17,w8,w23,ror#22 // Sigma0(a) + eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) + add w1,w1,w10 + add w26,w26,w22 // d+=h + add w22,w22,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w1,w1,w7 + add w22,w22,w17 // h+=Sigma0(a) + add w1,w1,w6 + ldr w6,[sp,#12] + str w9,[sp,#8] + ror w16,w26,#6 + add w21,w21,w19 // h+=K[i] + ror w8,w3,#7 + and w17,w27,w26 + ror w7,w0,#17 + bic w19,w20,w26 + ror w9,w22,#2 + add w21,w21,w1 // h+=X[i] + eor w16,w16,w26,ror#11 + eor w8,w8,w3,ror#18 + orr w17,w17,w19 // Ch(e,f,g) + eor w19,w22,w23 // a^b, b^c in next round + eor w16,w16,w26,ror#25 // Sigma1(e) + eor w9,w9,w22,ror#13 + add w21,w21,w17 // h+=Ch(e,f,g) + and w28,w28,w19 // (b^c)&=(a^b) + eor w7,w7,w0,ror#19 + eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) + add w21,w21,w16 // h+=Sigma1(e) + eor w28,w28,w23 // Maj(a,b,c) + eor w17,w9,w22,ror#22 // Sigma0(a) + eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) + add w2,w2,w11 + add w25,w25,w21 // d+=h + add w21,w21,w28 // h+=Maj(a,b,c) + ldr w28,[x30],#4 // *K++, w19 in next round + add w2,w2,w8 + add w21,w21,w17 // h+=Sigma0(a) + add w2,w2,w7 + ldr w7,[sp,#0] + str w10,[sp,#12] + ror w16,w25,#6 + add w20,w20,w28 // h+=K[i] + ror w9,w4,#7 + and w17,w26,w25 + ror w8,w1,#17 + bic w28,w27,w25 + ror w10,w21,#2 + add w20,w20,w2 // h+=X[i] + eor w16,w16,w25,ror#11 + eor w9,w9,w4,ror#18 + orr w17,w17,w28 // Ch(e,f,g) + eor w28,w21,w22 // a^b, b^c in next round + eor w16,w16,w25,ror#25 // Sigma1(e) + eor w10,w10,w21,ror#13 + add w20,w20,w17 // h+=Ch(e,f,g) + and w19,w19,w28 // (b^c)&=(a^b) + eor w8,w8,w1,ror#19 + eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) + add w20,w20,w16 // h+=Sigma1(e) + eor w19,w19,w22 // Maj(a,b,c) + eor w17,w10,w21,ror#22 // Sigma0(a) + eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) + add w3,w3,w12 + add w24,w24,w20 // d+=h + add w20,w20,w19 // h+=Maj(a,b,c) + ldr w19,[x30],#4 // *K++, w28 in next round + add w3,w3,w9 + add w20,w20,w17 // h+=Sigma0(a) + add w3,w3,w8 + cbnz w19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#260 // rewind + + ldp w3,w4,[x0] + ldp w5,w6,[x0,#2*4] + add x1,x1,#14*4 // advance input pointer + ldp w7,w8,[x0,#4*4] + add w20,w20,w3 + ldp w9,w10,[x0,#6*4] + add w21,w21,w4 + add w22,w22,w5 + add w23,w23,w6 + stp w20,w21,[x0] + add w24,w24,w7 + add w25,w25,w8 + stp w22,w23,[x0,#2*4] + add w26,w26,w9 + add w27,w27,w10 + cmp x1,x2 + stp w24,w25,[x0,#4*4] + stp w26,w27,[x0,#6*4] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*4 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 + ret +.size sha256_block_data_order,.-sha256_block_data_order + +.align 6 +.type K256,%object +K256: + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 + .long 0 //terminator +.size K256,.-K256 +.align 3 +.LOPENSSL_armcap_P: + .quad OPENSSL_armcap_P-. +.asciz "SHA256 block transform for ARMv8, CRYPTOGAMS by " +.align 2 +.type sha256_block_armv8,%function +.align 6 +sha256_block_armv8: +.Lv8_entry: + stp x29,x30,[sp,#-16]! + add x29,sp,#0 + + ld1 {v0.4s,v1.4s},[x0] + adr x3,K256 + +.Loop_hw: + ld1 {v4.16b-v7.16b},[x1],#64 + sub x2,x2,#1 + ld1 {v16.4s},[x3],#16 + rev32 v4.16b,v4.16b + rev32 v5.16b,v5.16b + rev32 v6.16b,v6.16b + rev32 v7.16b,v7.16b + orr v18.16b,v0.16b,v0.16b // offload + orr v19.16b,v1.16b,v1.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s + .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s + .inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s + .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s + .inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v6.4s + .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v7.4s + .inst 0x5e282887 //sha256su0 v7.16b,v4.16b + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b + ld1 {v17.4s},[x3],#16 + add v16.4s,v16.4s,v4.4s + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + ld1 {v16.4s},[x3],#16 + add v17.4s,v17.4s,v5.4s + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + ld1 {v17.4s},[x3] + add v16.4s,v16.4s,v6.4s + sub x3,x3,#64*4-16 // rewind + orr v2.16b,v0.16b,v0.16b + .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s + .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s + + add v17.4s,v17.4s,v7.4s + orr v2.16b,v0.16b,v0.16b + .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s + .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s + + add v0.4s,v0.4s,v18.4s + add v1.4s,v1.4s,v19.4s + + cbnz x2,.Loop_hw + + st1 {v0.4s,v1.4s},[x0] + + ldr x29,[sp],#16 + ret +.size sha256_block_armv8,.-sha256_block_armv8 +.comm OPENSSL_armcap_P,4,4 diff --git a/secure/lib/libcrypto/aarch64/sha512-armv8.S b/secure/lib/libcrypto/aarch64/sha512-armv8.S new file mode 100644 index 000000000000..108e7ed8aeac --- /dev/null +++ b/secure/lib/libcrypto/aarch64/sha512-armv8.S @@ -0,0 +1,1023 @@ +/* $FreeBSD$ */ +/* Do not modify. This file is auto-generated from sha512-armv8.pl. */ +#include "arm_arch.h" + +.text + +.globl sha512_block_data_order +.type sha512_block_data_order,%function +.align 6 +sha512_block_data_order: + stp x29,x30,[sp,#-128]! + add x29,sp,#0 + + stp x19,x20,[sp,#16] + stp x21,x22,[sp,#32] + stp x23,x24,[sp,#48] + stp x25,x26,[sp,#64] + stp x27,x28,[sp,#80] + sub sp,sp,#4*8 + + ldp x20,x21,[x0] // load context + ldp x22,x23,[x0,#2*8] + ldp x24,x25,[x0,#4*8] + add x2,x1,x2,lsl#7 // end of input + ldp x26,x27,[x0,#6*8] + adr x30,K512 + stp x0,x2,[x29,#96] + +.Loop: + ldp x3,x4,[x1],#2*8 + ldr x19,[x30],#8 // *K++ + eor x28,x21,x22 // magic seed + str x1,[x29,#112] +#ifndef __ARMEB__ + rev x3,x3 // 0 +#endif + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x6,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x3 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x4,x4 // 1 +#endif + ldp x5,x6,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x7,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x4 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x5,x5 // 2 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x8,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x5 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x6,x6 // 3 +#endif + ldp x7,x8,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x9,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x6 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x7,x7 // 4 +#endif + add x24,x24,x17 // h+=Sigma0(a) + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x10,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x7 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x10,ror#18 // Sigma1(e) + ror x10,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x10,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x8,x8 // 5 +#endif + ldp x9,x10,[x1],#2*8 + add x23,x23,x17 // h+=Sigma0(a) + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x11,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x8 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x11,ror#18 // Sigma1(e) + ror x11,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x11,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x9,x9 // 6 +#endif + add x22,x22,x17 // h+=Sigma0(a) + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x12,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x9 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x12,ror#18 // Sigma1(e) + ror x12,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x12,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x10,x10 // 7 +#endif + ldp x11,x12,[x1],#2*8 + add x21,x21,x17 // h+=Sigma0(a) + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + eor x13,x25,x25,ror#23 + and x17,x26,x25 + bic x28,x27,x25 + add x20,x20,x10 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x13,ror#18 // Sigma1(e) + ror x13,x21,#28 + add x20,x20,x17 // h+=Ch(e,f,g) + eor x17,x21,x21,ror#5 + add x20,x20,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x24,x24,x20 // d+=h + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x13,x17,ror#34 // Sigma0(a) + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x20,x20,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x11,x11 // 8 +#endif + add x20,x20,x17 // h+=Sigma0(a) + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + eor x14,x24,x24,ror#23 + and x17,x25,x24 + bic x19,x26,x24 + add x27,x27,x11 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x14,ror#18 // Sigma1(e) + ror x14,x20,#28 + add x27,x27,x17 // h+=Ch(e,f,g) + eor x17,x20,x20,ror#5 + add x27,x27,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x23,x23,x27 // d+=h + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x14,x17,ror#34 // Sigma0(a) + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x27,x27,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x12,x12 // 9 +#endif + ldp x13,x14,[x1],#2*8 + add x27,x27,x17 // h+=Sigma0(a) + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + eor x15,x23,x23,ror#23 + and x17,x24,x23 + bic x28,x25,x23 + add x26,x26,x12 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x15,ror#18 // Sigma1(e) + ror x15,x27,#28 + add x26,x26,x17 // h+=Ch(e,f,g) + eor x17,x27,x27,ror#5 + add x26,x26,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x22,x22,x26 // d+=h + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x15,x17,ror#34 // Sigma0(a) + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x26,x26,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x13,x13 // 10 +#endif + add x26,x26,x17 // h+=Sigma0(a) + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + eor x0,x22,x22,ror#23 + and x17,x23,x22 + bic x19,x24,x22 + add x25,x25,x13 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x0,ror#18 // Sigma1(e) + ror x0,x26,#28 + add x25,x25,x17 // h+=Ch(e,f,g) + eor x17,x26,x26,ror#5 + add x25,x25,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x21,x21,x25 // d+=h + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x0,x17,ror#34 // Sigma0(a) + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x25,x25,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x14,x14 // 11 +#endif + ldp x15,x0,[x1],#2*8 + add x25,x25,x17 // h+=Sigma0(a) + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + eor x6,x21,x21,ror#23 + and x17,x22,x21 + bic x28,x23,x21 + add x24,x24,x14 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x6,ror#18 // Sigma1(e) + ror x6,x25,#28 + add x24,x24,x17 // h+=Ch(e,f,g) + eor x17,x25,x25,ror#5 + add x24,x24,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x20,x20,x24 // d+=h + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x17,ror#34 // Sigma0(a) + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x24,x24,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x15,x15 // 12 +#endif + add x24,x24,x17 // h+=Sigma0(a) + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + eor x7,x20,x20,ror#23 + and x17,x21,x20 + bic x19,x22,x20 + add x23,x23,x15 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x7,ror#18 // Sigma1(e) + ror x7,x24,#28 + add x23,x23,x17 // h+=Ch(e,f,g) + eor x17,x24,x24,ror#5 + add x23,x23,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x27,x27,x23 // d+=h + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x17,ror#34 // Sigma0(a) + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x23,x23,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x0,x0 // 13 +#endif + ldp x1,x2,[x1] + add x23,x23,x17 // h+=Sigma0(a) + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + eor x8,x27,x27,ror#23 + and x17,x20,x27 + bic x28,x21,x27 + add x22,x22,x0 // h+=X[i] + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x8,ror#18 // Sigma1(e) + ror x8,x23,#28 + add x22,x22,x17 // h+=Ch(e,f,g) + eor x17,x23,x23,ror#5 + add x22,x22,x16 // h+=Sigma1(e) + and x19,x19,x28 // (b^c)&=(a^b) + add x26,x26,x22 // d+=h + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x17,ror#34 // Sigma0(a) + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + //add x22,x22,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x1,x1 // 14 +#endif + ldr x6,[sp,#24] + add x22,x22,x17 // h+=Sigma0(a) + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + eor x9,x26,x26,ror#23 + and x17,x27,x26 + bic x19,x20,x26 + add x21,x21,x1 // h+=X[i] + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x9,ror#18 // Sigma1(e) + ror x9,x22,#28 + add x21,x21,x17 // h+=Ch(e,f,g) + eor x17,x22,x22,ror#5 + add x21,x21,x16 // h+=Sigma1(e) + and x28,x28,x19 // (b^c)&=(a^b) + add x25,x25,x21 // d+=h + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x17,ror#34 // Sigma0(a) + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + //add x21,x21,x17 // h+=Sigma0(a) +#ifndef __ARMEB__ + rev x2,x2 // 15 +#endif + ldr x7,[sp,#0] + add x21,x21,x17 // h+=Sigma0(a) + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 +.Loop_16_xx: + ldr x8,[sp,#8] + str x11,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x10,x5,#1 + and x17,x25,x24 + ror x9,x2,#19 + bic x19,x26,x24 + ror x11,x20,#28 + add x27,x27,x3 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x10,x10,x5,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x11,x11,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x9,x9,x2,ror#61 + eor x10,x10,x5,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x11,x20,ror#39 // Sigma0(a) + eor x9,x9,x2,lsr#6 // sigma1(X[i+14]) + add x4,x4,x13 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x4,x4,x10 + add x27,x27,x17 // h+=Sigma0(a) + add x4,x4,x9 + ldr x9,[sp,#16] + str x12,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x11,x6,#1 + and x17,x24,x23 + ror x10,x3,#19 + bic x28,x25,x23 + ror x12,x27,#28 + add x26,x26,x4 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x11,x11,x6,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x12,x12,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x10,x10,x3,ror#61 + eor x11,x11,x6,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x12,x27,ror#39 // Sigma0(a) + eor x10,x10,x3,lsr#6 // sigma1(X[i+14]) + add x5,x5,x14 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x5,x5,x11 + add x26,x26,x17 // h+=Sigma0(a) + add x5,x5,x10 + ldr x10,[sp,#24] + str x13,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x12,x7,#1 + and x17,x23,x22 + ror x11,x4,#19 + bic x19,x24,x22 + ror x13,x26,#28 + add x25,x25,x5 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x12,x12,x7,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x13,x13,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x11,x11,x4,ror#61 + eor x12,x12,x7,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x13,x26,ror#39 // Sigma0(a) + eor x11,x11,x4,lsr#6 // sigma1(X[i+14]) + add x6,x6,x15 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x6,x6,x12 + add x25,x25,x17 // h+=Sigma0(a) + add x6,x6,x11 + ldr x11,[sp,#0] + str x14,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x13,x8,#1 + and x17,x22,x21 + ror x12,x5,#19 + bic x28,x23,x21 + ror x14,x25,#28 + add x24,x24,x6 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x13,x13,x8,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x14,x14,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x12,x12,x5,ror#61 + eor x13,x13,x8,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x14,x25,ror#39 // Sigma0(a) + eor x12,x12,x5,lsr#6 // sigma1(X[i+14]) + add x7,x7,x0 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x7,x7,x13 + add x24,x24,x17 // h+=Sigma0(a) + add x7,x7,x12 + ldr x12,[sp,#8] + str x15,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x14,x9,#1 + and x17,x21,x20 + ror x13,x6,#19 + bic x19,x22,x20 + ror x15,x24,#28 + add x23,x23,x7 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x14,x14,x9,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x15,x15,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x13,x13,x6,ror#61 + eor x14,x14,x9,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x15,x24,ror#39 // Sigma0(a) + eor x13,x13,x6,lsr#6 // sigma1(X[i+14]) + add x8,x8,x1 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x8,x8,x14 + add x23,x23,x17 // h+=Sigma0(a) + add x8,x8,x13 + ldr x13,[sp,#16] + str x0,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x15,x10,#1 + and x17,x20,x27 + ror x14,x7,#19 + bic x28,x21,x27 + ror x0,x23,#28 + add x22,x22,x8 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x15,x15,x10,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x0,x0,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x14,x14,x7,ror#61 + eor x15,x15,x10,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x0,x23,ror#39 // Sigma0(a) + eor x14,x14,x7,lsr#6 // sigma1(X[i+14]) + add x9,x9,x2 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x9,x9,x15 + add x22,x22,x17 // h+=Sigma0(a) + add x9,x9,x14 + ldr x14,[sp,#24] + str x1,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x0,x11,#1 + and x17,x27,x26 + ror x15,x8,#19 + bic x19,x20,x26 + ror x1,x22,#28 + add x21,x21,x9 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x0,x0,x11,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x1,x1,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x15,x15,x8,ror#61 + eor x0,x0,x11,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x1,x22,ror#39 // Sigma0(a) + eor x15,x15,x8,lsr#6 // sigma1(X[i+14]) + add x10,x10,x3 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x10,x10,x0 + add x21,x21,x17 // h+=Sigma0(a) + add x10,x10,x15 + ldr x15,[sp,#0] + str x2,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x1,x12,#1 + and x17,x26,x25 + ror x0,x9,#19 + bic x28,x27,x25 + ror x2,x21,#28 + add x20,x20,x10 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x1,x1,x12,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x2,x2,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x0,x0,x9,ror#61 + eor x1,x1,x12,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x2,x21,ror#39 // Sigma0(a) + eor x0,x0,x9,lsr#6 // sigma1(X[i+14]) + add x11,x11,x4 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x11,x11,x1 + add x20,x20,x17 // h+=Sigma0(a) + add x11,x11,x0 + ldr x0,[sp,#8] + str x3,[sp,#0] + ror x16,x24,#14 + add x27,x27,x19 // h+=K[i] + ror x2,x13,#1 + and x17,x25,x24 + ror x1,x10,#19 + bic x19,x26,x24 + ror x3,x20,#28 + add x27,x27,x11 // h+=X[i] + eor x16,x16,x24,ror#18 + eor x2,x2,x13,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x20,x21 // a^b, b^c in next round + eor x16,x16,x24,ror#41 // Sigma1(e) + eor x3,x3,x20,ror#34 + add x27,x27,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x1,x1,x10,ror#61 + eor x2,x2,x13,lsr#7 // sigma0(X[i+1]) + add x27,x27,x16 // h+=Sigma1(e) + eor x28,x28,x21 // Maj(a,b,c) + eor x17,x3,x20,ror#39 // Sigma0(a) + eor x1,x1,x10,lsr#6 // sigma1(X[i+14]) + add x12,x12,x5 + add x23,x23,x27 // d+=h + add x27,x27,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x12,x12,x2 + add x27,x27,x17 // h+=Sigma0(a) + add x12,x12,x1 + ldr x1,[sp,#16] + str x4,[sp,#8] + ror x16,x23,#14 + add x26,x26,x28 // h+=K[i] + ror x3,x14,#1 + and x17,x24,x23 + ror x2,x11,#19 + bic x28,x25,x23 + ror x4,x27,#28 + add x26,x26,x12 // h+=X[i] + eor x16,x16,x23,ror#18 + eor x3,x3,x14,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x27,x20 // a^b, b^c in next round + eor x16,x16,x23,ror#41 // Sigma1(e) + eor x4,x4,x27,ror#34 + add x26,x26,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x2,x2,x11,ror#61 + eor x3,x3,x14,lsr#7 // sigma0(X[i+1]) + add x26,x26,x16 // h+=Sigma1(e) + eor x19,x19,x20 // Maj(a,b,c) + eor x17,x4,x27,ror#39 // Sigma0(a) + eor x2,x2,x11,lsr#6 // sigma1(X[i+14]) + add x13,x13,x6 + add x22,x22,x26 // d+=h + add x26,x26,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x13,x13,x3 + add x26,x26,x17 // h+=Sigma0(a) + add x13,x13,x2 + ldr x2,[sp,#24] + str x5,[sp,#16] + ror x16,x22,#14 + add x25,x25,x19 // h+=K[i] + ror x4,x15,#1 + and x17,x23,x22 + ror x3,x12,#19 + bic x19,x24,x22 + ror x5,x26,#28 + add x25,x25,x13 // h+=X[i] + eor x16,x16,x22,ror#18 + eor x4,x4,x15,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x26,x27 // a^b, b^c in next round + eor x16,x16,x22,ror#41 // Sigma1(e) + eor x5,x5,x26,ror#34 + add x25,x25,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x3,x3,x12,ror#61 + eor x4,x4,x15,lsr#7 // sigma0(X[i+1]) + add x25,x25,x16 // h+=Sigma1(e) + eor x28,x28,x27 // Maj(a,b,c) + eor x17,x5,x26,ror#39 // Sigma0(a) + eor x3,x3,x12,lsr#6 // sigma1(X[i+14]) + add x14,x14,x7 + add x21,x21,x25 // d+=h + add x25,x25,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x14,x14,x4 + add x25,x25,x17 // h+=Sigma0(a) + add x14,x14,x3 + ldr x3,[sp,#0] + str x6,[sp,#24] + ror x16,x21,#14 + add x24,x24,x28 // h+=K[i] + ror x5,x0,#1 + and x17,x22,x21 + ror x4,x13,#19 + bic x28,x23,x21 + ror x6,x25,#28 + add x24,x24,x14 // h+=X[i] + eor x16,x16,x21,ror#18 + eor x5,x5,x0,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x25,x26 // a^b, b^c in next round + eor x16,x16,x21,ror#41 // Sigma1(e) + eor x6,x6,x25,ror#34 + add x24,x24,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x4,x4,x13,ror#61 + eor x5,x5,x0,lsr#7 // sigma0(X[i+1]) + add x24,x24,x16 // h+=Sigma1(e) + eor x19,x19,x26 // Maj(a,b,c) + eor x17,x6,x25,ror#39 // Sigma0(a) + eor x4,x4,x13,lsr#6 // sigma1(X[i+14]) + add x15,x15,x8 + add x20,x20,x24 // d+=h + add x24,x24,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x15,x15,x5 + add x24,x24,x17 // h+=Sigma0(a) + add x15,x15,x4 + ldr x4,[sp,#8] + str x7,[sp,#0] + ror x16,x20,#14 + add x23,x23,x19 // h+=K[i] + ror x6,x1,#1 + and x17,x21,x20 + ror x5,x14,#19 + bic x19,x22,x20 + ror x7,x24,#28 + add x23,x23,x15 // h+=X[i] + eor x16,x16,x20,ror#18 + eor x6,x6,x1,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x24,x25 // a^b, b^c in next round + eor x16,x16,x20,ror#41 // Sigma1(e) + eor x7,x7,x24,ror#34 + add x23,x23,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x5,x5,x14,ror#61 + eor x6,x6,x1,lsr#7 // sigma0(X[i+1]) + add x23,x23,x16 // h+=Sigma1(e) + eor x28,x28,x25 // Maj(a,b,c) + eor x17,x7,x24,ror#39 // Sigma0(a) + eor x5,x5,x14,lsr#6 // sigma1(X[i+14]) + add x0,x0,x9 + add x27,x27,x23 // d+=h + add x23,x23,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x0,x0,x6 + add x23,x23,x17 // h+=Sigma0(a) + add x0,x0,x5 + ldr x5,[sp,#16] + str x8,[sp,#8] + ror x16,x27,#14 + add x22,x22,x28 // h+=K[i] + ror x7,x2,#1 + and x17,x20,x27 + ror x6,x15,#19 + bic x28,x21,x27 + ror x8,x23,#28 + add x22,x22,x0 // h+=X[i] + eor x16,x16,x27,ror#18 + eor x7,x7,x2,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x23,x24 // a^b, b^c in next round + eor x16,x16,x27,ror#41 // Sigma1(e) + eor x8,x8,x23,ror#34 + add x22,x22,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x6,x6,x15,ror#61 + eor x7,x7,x2,lsr#7 // sigma0(X[i+1]) + add x22,x22,x16 // h+=Sigma1(e) + eor x19,x19,x24 // Maj(a,b,c) + eor x17,x8,x23,ror#39 // Sigma0(a) + eor x6,x6,x15,lsr#6 // sigma1(X[i+14]) + add x1,x1,x10 + add x26,x26,x22 // d+=h + add x22,x22,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x1,x1,x7 + add x22,x22,x17 // h+=Sigma0(a) + add x1,x1,x6 + ldr x6,[sp,#24] + str x9,[sp,#16] + ror x16,x26,#14 + add x21,x21,x19 // h+=K[i] + ror x8,x3,#1 + and x17,x27,x26 + ror x7,x0,#19 + bic x19,x20,x26 + ror x9,x22,#28 + add x21,x21,x1 // h+=X[i] + eor x16,x16,x26,ror#18 + eor x8,x8,x3,ror#8 + orr x17,x17,x19 // Ch(e,f,g) + eor x19,x22,x23 // a^b, b^c in next round + eor x16,x16,x26,ror#41 // Sigma1(e) + eor x9,x9,x22,ror#34 + add x21,x21,x17 // h+=Ch(e,f,g) + and x28,x28,x19 // (b^c)&=(a^b) + eor x7,x7,x0,ror#61 + eor x8,x8,x3,lsr#7 // sigma0(X[i+1]) + add x21,x21,x16 // h+=Sigma1(e) + eor x28,x28,x23 // Maj(a,b,c) + eor x17,x9,x22,ror#39 // Sigma0(a) + eor x7,x7,x0,lsr#6 // sigma1(X[i+14]) + add x2,x2,x11 + add x25,x25,x21 // d+=h + add x21,x21,x28 // h+=Maj(a,b,c) + ldr x28,[x30],#8 // *K++, x19 in next round + add x2,x2,x8 + add x21,x21,x17 // h+=Sigma0(a) + add x2,x2,x7 + ldr x7,[sp,#0] + str x10,[sp,#24] + ror x16,x25,#14 + add x20,x20,x28 // h+=K[i] + ror x9,x4,#1 + and x17,x26,x25 + ror x8,x1,#19 + bic x28,x27,x25 + ror x10,x21,#28 + add x20,x20,x2 // h+=X[i] + eor x16,x16,x25,ror#18 + eor x9,x9,x4,ror#8 + orr x17,x17,x28 // Ch(e,f,g) + eor x28,x21,x22 // a^b, b^c in next round + eor x16,x16,x25,ror#41 // Sigma1(e) + eor x10,x10,x21,ror#34 + add x20,x20,x17 // h+=Ch(e,f,g) + and x19,x19,x28 // (b^c)&=(a^b) + eor x8,x8,x1,ror#61 + eor x9,x9,x4,lsr#7 // sigma0(X[i+1]) + add x20,x20,x16 // h+=Sigma1(e) + eor x19,x19,x22 // Maj(a,b,c) + eor x17,x10,x21,ror#39 // Sigma0(a) + eor x8,x8,x1,lsr#6 // sigma1(X[i+14]) + add x3,x3,x12 + add x24,x24,x20 // d+=h + add x20,x20,x19 // h+=Maj(a,b,c) + ldr x19,[x30],#8 // *K++, x28 in next round + add x3,x3,x9 + add x20,x20,x17 // h+=Sigma0(a) + add x3,x3,x8 + cbnz x19,.Loop_16_xx + + ldp x0,x2,[x29,#96] + ldr x1,[x29,#112] + sub x30,x30,#648 // rewind + + ldp x3,x4,[x0] + ldp x5,x6,[x0,#2*8] + add x1,x1,#14*8 // advance input pointer + ldp x7,x8,[x0,#4*8] + add x20,x20,x3 + ldp x9,x10,[x0,#6*8] + add x21,x21,x4 + add x22,x22,x5 + add x23,x23,x6 + stp x20,x21,[x0] + add x24,x24,x7 + add x25,x25,x8 + stp x22,x23,[x0,#2*8] + add x26,x26,x9 + add x27,x27,x10 + cmp x1,x2 + stp x24,x25,[x0,#4*8] + stp x26,x27,[x0,#6*8] + b.ne .Loop + + ldp x19,x20,[x29,#16] + add sp,sp,#4*8 + ldp x21,x22,[x29,#32] + ldp x23,x24,[x29,#48] + ldp x25,x26,[x29,#64] + ldp x27,x28,[x29,#80] + ldp x29,x30,[sp],#128 + ret +.size sha512_block_data_order,.-sha512_block_data_order + +.align 6 +.type K512,%object +K512: + .quad 0x428a2f98d728ae22,0x7137449123ef65cd + .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc + .quad 0x3956c25bf348b538,0x59f111f1b605d019 + .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 + .quad 0xd807aa98a3030242,0x12835b0145706fbe + .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 + .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 + .quad 0x9bdc06a725c71235,0xc19bf174cf692694 + .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 + .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 + .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 + .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 + .quad 0x983e5152ee66dfab,0xa831c66d2db43210 + .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 + .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 + .quad 0x06ca6351e003826f,0x142929670a0e6e70 + .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 + .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df + .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 + .quad 0x81c2c92e47edaee6,0x92722c851482353b + .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 + .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 + .quad 0xd192e819d6ef5218,0xd69906245565a910 + .quad 0xf40e35855771202a,0x106aa07032bbd1b8 + .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 + .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 + .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb + .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 + .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 + .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec + .quad 0x90befffa23631e28,0xa4506cebde82bde9 + .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b + .quad 0xca273eceea26619c,0xd186b8c721c0c207 + .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 + .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 + .quad 0x113f9804bef90dae,0x1b710b35131c471b + .quad 0x28db77f523047d84,0x32caab7b40c72493 + .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c + .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a + .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 + .quad 0 // terminator +.size K512,.-K512 +.align 3 +.LOPENSSL_armcap_P: + .quad OPENSSL_armcap_P-. +.asciz "SHA512 block transform for ARMv8, CRYPTOGAMS by " +.align 2 +.comm OPENSSL_armcap_P,4,4 From 46f6fa3cbab13611ce14e0e6f717286c0239ba9f Mon Sep 17 00:00:00 2001 From: Jung-uk Kim Date: Wed, 26 Oct 2016 20:12:30 +0000 Subject: [PATCH 134/235] Prefer ACFLAGS over CFLAGS for compiling aarch64 assembly files. --- secure/lib/libcrypto/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/secure/lib/libcrypto/Makefile b/secure/lib/libcrypto/Makefile index 5e9ad2b27540..ccc78212ab09 100644 --- a/secure/lib/libcrypto/Makefile +++ b/secure/lib/libcrypto/Makefile @@ -24,7 +24,7 @@ SRCS= cpt_err.c cryptlib.c cversion.c ex_data.c mem.c mem_dbg.c o_dir.c \ o_fips.c o_init.c o_str.c o_time.c uid.c .if defined(ASM_aarch64) SRCS+= arm64cpuid.S armcap.c mem_clr.c -CFLAGS.arm64cpuid.S= -march=armv8-a+crypto +ACFLAGS.arm64cpuid.S= -march=armv8-a+crypto .elif defined(ASM_amd64) SRCS+= x86_64cpuid.S .elif defined(ASM_arm) @@ -40,7 +40,7 @@ INCS+= crypto.h ebcdic.h opensslv.h ossl_typ.h symhacks.h ../e_os2.h SRCS+= aes_cfb.c aes_ctr.c aes_ecb.c aes_ige.c aes_misc.c aes_ofb.c aes_wrap.c .if defined(ASM_aarch64) SRCS+= aes_cbc.c aes_core.c aesv8-armx.S -CFLAGS.aesv8-armx.S= -march=armv8-a+crypto +ACFLAGS.aesv8-armx.S= -march=armv8-a+crypto .elif defined(ASM_amd64) SRCS+= aes-x86_64.S aesni-mb-x86_64.S aesni-sha1-x86_64.S \ aesni-sha256-x86_64.S aesni-x86_64.S bsaes-x86_64.S vpaes-x86_64.S @@ -246,7 +246,7 @@ SRCS+= cbc128.c ccm128.c cfb128.c ctr128.c cts128.c gcm128.c ofb128.c \ wrap128.c xts128.c .if defined(ASM_aarch64) SRCS+= ghashv8-armx.S -CFLAGS.ghashv8-armx.S= -march=armv8-a+crypto +ACFLAGS.ghashv8-armx.S= -march=armv8-a+crypto .elif defined(ASM_amd64) SRCS+= aesni-gcm-x86_64.S ghash-x86_64.S .elif defined(ASM_arm) From 9e7e59125c85904240b4f3f46e404c30aab4fbfb Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Wed, 26 Oct 2016 20:28:23 +0000 Subject: [PATCH 135/235] The UFS/FFS filesystem checks directory link counts when doing directory create and delete operations. If it ever finds a directory with a link count less than 2, it panics. Thus, an rm -rf that encounters a directory with a link count below 2 causes a kernel panic. The proposed fix is to return the error EINVAL rather than panicing. The effect is that the requested operation is not done, but the system continues to run. At a more convenient later time, the filesystem can be unmounted and cleaned (with fsck or journal run). Once cleaned, the operation can be rerun to successful completion. This fix takes that approach. The panic message has been converted into a uprintf(9) to provide the user with the inode number and filesystem mount point of the offending directory and EINVAL is returned for the operation. The long (three year) delay in fixing this problem occurred because the bug was misclassified when originally assigned and only this week was found during a sweep of old unresolved bug reports. PR: 180894 Reviewed by: kib MFC after: 2 weeks --- sys/ufs/ufs/ufs_vnops.c | 59 +++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index b6e3385b81c3..13f0d02ef7ce 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -105,7 +105,7 @@ static vop_create_t ufs_create; static vop_getattr_t ufs_getattr; static vop_ioctl_t ufs_ioctl; static vop_link_t ufs_link; -static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *); +static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *, const char *); static vop_markatime_t ufs_markatime; static vop_mkdir_t ufs_mkdir; static vop_mknod_t ufs_mknod; @@ -204,7 +204,7 @@ ufs_create(ap) error = ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), - ap->a_dvp, ap->a_vpp, ap->a_cnp); + ap->a_dvp, ap->a_vpp, ap->a_cnp, "ufs_create"); if (error != 0) return (error); if ((ap->a_cnp->cn_flags & MAKEENTRY) != 0) @@ -232,7 +232,7 @@ ufs_mknod(ap) int error; error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), - ap->a_dvp, vpp, ap->a_cnp); + ap->a_dvp, vpp, ap->a_cnp, "ufs_mknod"); if (error) return (error); ip = VTOI(*vpp); @@ -942,6 +942,17 @@ ufs_remove(ap) return (error); } +static void +print_bad_link_count(const char *funcname, struct vnode *dvp) +{ + struct inode *dip; + + dip = VTOI(dvp); + uprintf("%s: Bad link count %d on parent inode %d in file system %s\n", + funcname, dip->i_effnlink, dip->i_number, + dvp->v_mount->mnt_stat.f_mntonname); +} + /* * link vnode call */ @@ -964,9 +975,11 @@ ufs_link(ap) if ((cnp->cn_flags & HASBUF) == 0) panic("ufs_link: no name"); #endif - if (VTOI(tdvp)->i_effnlink < 2) - panic("ufs_link: Bad link count %d on parent", - VTOI(tdvp)->i_effnlink); + if (VTOI(tdvp)->i_effnlink < 2) { + print_bad_link_count("ufs_link", tdvp); + error = EINVAL; + goto out; + } ip = VTOI(vp); if ((nlink_t)ip->i_nlink >= LINK_MAX) { error = EMLINK; @@ -1710,10 +1723,10 @@ ufs_do_posix1e_acl_inheritance_file(struct vnode *dvp, struct vnode *tvp, * XXX: This should not happen, as EOPNOTSUPP above was * supposed to free acl. */ - printf("ufs_makeinode: VOP_GETACL() but no " - "VOP_SETACL()\n"); - /* panic("ufs_makeinode: VOP_GETACL() but no " - "VOP_SETACL()"); */ + printf("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() " + "but no VOP_SETACL()\n"); + /* panic("ufs_do_posix1e_acl_inheritance_file: VOP_GETACL() " + "but no VOP_SETACL()"); */ break; default: @@ -1791,6 +1804,11 @@ ufs_mkdir(ap) * but not have it entered in the parent directory. The entry is * made later after writing "." and ".." entries. */ + if (dp->i_effnlink < 2) { + print_bad_link_count("ufs_mkdir", dvp); + error = EINVAL; + goto out; + } error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp); if (error) goto out; @@ -2021,13 +2039,12 @@ ufs_rmdir(ap) * tries to remove a locally mounted on directory). */ error = 0; - if (ip->i_effnlink < 2) { + if (dp->i_effnlink <= 2) { + if (dp->i_effnlink == 2) + print_bad_link_count("ufs_rmdir", dvp); error = EINVAL; goto out; } - if (dp->i_effnlink < 3) - panic("ufs_dirrem: Bad link count %d on parent", - dp->i_effnlink); if (!ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) { error = ENOTEMPTY; goto out; @@ -2106,7 +2123,7 @@ ufs_symlink(ap) int len, error; error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, - vpp, ap->a_cnp); + vpp, ap->a_cnp, "ufs_symlink"); if (error) return (error); vp = *vpp; @@ -2558,11 +2575,12 @@ ufs_vinit(mntp, fifoops, vpp) * Vnode dvp must be locked. */ static int -ufs_makeinode(mode, dvp, vpp, cnp) +ufs_makeinode(mode, dvp, vpp, cnp, callfunc) int mode; struct vnode *dvp; struct vnode **vpp; struct componentname *cnp; + const char *callfunc; { struct inode *ip, *pdir; struct direct newdir; @@ -2572,15 +2590,16 @@ ufs_makeinode(mode, dvp, vpp, cnp) pdir = VTOI(dvp); #ifdef INVARIANTS if ((cnp->cn_flags & HASBUF) == 0) - panic("ufs_makeinode: no name"); + panic("%s: no name", callfunc); #endif *vpp = NULL; if ((mode & IFMT) == 0) mode |= IFREG; - if (VTOI(dvp)->i_effnlink < 2) - panic("ufs_makeinode: Bad link count %d on parent", - VTOI(dvp)->i_effnlink); + if (pdir->i_effnlink < 2) { + print_bad_link_count(callfunc, dvp); + return (EINVAL); + } error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp); if (error) return (error); From 921e5f56752096ebe205be58ccad2b54cbe33f2c Mon Sep 17 00:00:00 2001 From: Bryan Drewery Date: Wed, 26 Oct 2016 23:40:07 +0000 Subject: [PATCH 136/235] Remove excess CTLFLAG_VNET Sponsored by: Dell EMC Isilon --- sys/net/if_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 986639da9ccf..d98e691e58e3 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -408,7 +408,7 @@ SYSCTL_INT(_net_link_bridge, OID_AUTO, inherit_mac, static VNET_DEFINE(int, allow_llz_overlap) = 0; #define V_allow_llz_overlap VNET(allow_llz_overlap) SYSCTL_INT(_net_link_bridge, OID_AUTO, allow_llz_overlap, - CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(allow_llz_overlap), 0, + CTLFLAG_RW | CTLFLAG_VNET, &VNET_NAME(allow_llz_overlap), 0, "Allow overlap of link-local scope " "zones of a bridge interface and the member interfaces"); From 3d8102824b018aebcd8df0a519168c80e9c545ac Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Thu, 27 Oct 2016 02:20:13 +0000 Subject: [PATCH 137/235] Disable CLKREQ for ASPM since re(4) doesn't implement link level power saving. Reviewed by: yongari --- sys/dev/re/if_re.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 071b55b10146..00c27642b568 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -1358,15 +1358,17 @@ re_attach(device_t dev) CSR_WRITE_1(sc, RL_EECMD, RL_EEMODE_OFF); } - /* Disable ASPM L0S/L1. */ + /* Disable ASPM L0S/L1 and CLKREQ. */ if (sc->rl_expcap != 0) { cap = pci_read_config(dev, sc->rl_expcap + PCIER_LINK_CAP, 2); if ((cap & PCIEM_LINK_CAP_ASPM) != 0) { ctl = pci_read_config(dev, sc->rl_expcap + PCIER_LINK_CTL, 2); - if ((ctl & PCIEM_LINK_CTL_ASPMC) != 0) { - ctl &= ~PCIEM_LINK_CTL_ASPMC; + if ((ctl & (PCIEM_LINK_CTL_ECPM | + PCIEM_LINK_CTL_ASPMC))!= 0) { + ctl &= ~(PCIEM_LINK_CTL_ECPM | + PCIEM_LINK_CTL_ASPMC); pci_write_config(dev, sc->rl_expcap + PCIER_LINK_CTL, ctl, 2); device_printf(dev, "ASPM disabled\n"); From 20b3dcf039af8eedde5684b7746960e8447adfda Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 03:43:27 +0000 Subject: [PATCH 138/235] hyperv/hn: Properly configure RSS according to RSS capabilities MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8338 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 2 + sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 25 +++++- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 90 ++++++++++++++++--- sys/dev/hyperv/netvsc/ndis.h | 12 ++- 4 files changed, 113 insertions(+), 16 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 014f823d8846..5f7fea7566a7 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -255,6 +255,8 @@ struct hn_softc { int hn_ndis_tso_szmax; int hn_ndis_tso_sgmin; + int hn_rss_ind_size; + uint32_t hn_rss_hash; /* NDIS_HASH_ */ struct ndis_rssprm_toeplitz hn_rss; }; diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 744d1790da34..7e89cf78d250 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -329,6 +329,7 @@ static int hn_hwassist_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rxfilter_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_key_sysctl(SYSCTL_HANDLER_ARGS); static int hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS); +static int hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS); static int hn_check_iplen(const struct mbuf *, int); static int hn_create_tx_ring(struct hn_softc *, int); static void hn_destroy_tx_ring(struct hn_tx_ring *); @@ -770,6 +771,11 @@ netvsc_attach(device_t dev) SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rxfilter", CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, hn_rxfilter_sysctl, "A", "rxfilter"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_hash", + CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, sc, 0, + hn_rss_hash_sysctl, "A", "RSS hash"); + SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rss_ind_size", + CTLFLAG_RD, &sc->hn_rss_ind_size, 0, "RSS indirect entry count"); SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rss_key", CTLTYPE_OPAQUE | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 0, hn_rss_key_sysctl, "IU", "RSS key"); @@ -2478,6 +2484,20 @@ hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS) return (error); } +static int +hn_rss_hash_sysctl(SYSCTL_HANDLER_ARGS) +{ + struct hn_softc *sc = arg1; + char hash_str[128]; + uint32_t hash; + + HN_LOCK(sc); + hash = sc->hn_rss_hash; + HN_UNLOCK(sc); + snprintf(hash_str, sizeof(hash_str), "%b", hash, NDIS_HASH_BITS); + return sysctl_handle_string(oidp, hash_str, sizeof(hash_str), req); +} + static int hn_check_iplen(const struct mbuf *m, int hoff) { @@ -3642,6 +3662,10 @@ hn_synth_attach(struct hn_softc *sc, int mtu) old_caps = sc->hn_caps; sc->hn_caps = 0; + /* Clear RSS stuffs. */ + sc->hn_rss_ind_size = 0; + sc->hn_rss_hash = 0; + /* * Attach the primary channel _before_ attaching NVS and RNDIS. */ @@ -3716,7 +3740,6 @@ hn_synth_attach(struct hn_softc *sc, int mtu) if_printf(sc->hn_ifp, "setup default RSS indirect " "table\n"); } - /* TODO: Take ndis_rss_caps.ndis_nind into account. */ for (i = 0; i < NDIS_HASH_INDCNT; ++i) rss->rss_ind[i] = i % nchan; sc->hn_flags |= HN_FLAG_HAS_RSSIND; diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index 623aad00ed31..b0bed94289b1 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -747,13 +747,14 @@ hn_rndis_query2(struct hn_softc *sc, uint32_t oid, } int -hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt) +hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt0) { struct ndis_rss_caps in, caps; size_t caps_len; - int error; + int error, indsz, rxr_cnt, hash_fnidx; + uint32_t hash_func = 0, hash_types = 0; - *rxr_cnt = 0; + *rxr_cnt0 = 0; if (sc->hn_ndis_ver < HN_NDIS_VERSION_6_20) return (EOPNOTSUPP); @@ -792,18 +793,73 @@ hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt) return (EINVAL); } + /* + * Save information for later RSS configuration. + */ if (caps.ndis_nrxr == 0) { if_printf(sc->hn_ifp, "0 RX rings!?\n"); return (EINVAL); } - *rxr_cnt = caps.ndis_nrxr; + if (bootverbose) + if_printf(sc->hn_ifp, "%u RX rings\n", caps.ndis_nrxr); + rxr_cnt = caps.ndis_nrxr; + + if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE && + caps.ndis_hdr.ndis_rev >= NDIS_RSS_CAPS_REV_2) { + if (caps.ndis_nind > NDIS_HASH_INDCNT) { + if_printf(sc->hn_ifp, + "too many RSS indirect table entries %u\n", + caps.ndis_nind); + return (EOPNOTSUPP); + } + if (!powerof2(caps.ndis_nind)) { + if_printf(sc->hn_ifp, "RSS indirect table size is not " + "power-of-2 %u\n", caps.ndis_nind); + } - if (caps.ndis_hdr.ndis_size == NDIS_RSS_CAPS_SIZE) { if (bootverbose) { if_printf(sc->hn_ifp, "RSS indirect table size %u\n", caps.ndis_nind); } + indsz = caps.ndis_nind; + } else { + indsz = NDIS_HASH_INDCNT; } + if (indsz < rxr_cnt) { + if_printf(sc->hn_ifp, "# of RX rings (%d) > " + "RSS indirect table size %d\n", rxr_cnt, indsz); + rxr_cnt = indsz; + } + + /* + * NOTE: + * Toeplitz is at the lowest bit, and it is prefered; so ffs(), + * instead of fls(), is used here. + */ + hash_fnidx = ffs(caps.ndis_caps & NDIS_RSS_CAP_HASHFUNC_MASK); + if (hash_fnidx == 0) { + if_printf(sc->hn_ifp, "no hash functions, caps 0x%08x\n", + caps.ndis_caps); + return (EOPNOTSUPP); + } + hash_func = 1 << (hash_fnidx - 1); /* ffs is 1-based */ + + if (caps.ndis_caps & NDIS_RSS_CAP_IPV4) + hash_types |= NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4; + if (caps.ndis_caps & NDIS_RSS_CAP_IPV6) + hash_types |= NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6; + if (caps.ndis_caps & NDIS_RSS_CAP_IPV6_EX) + hash_types |= NDIS_HASH_IPV6_EX | NDIS_HASH_TCP_IPV6_EX; + if (hash_types == 0) { + if_printf(sc->hn_ifp, "no hash types, caps 0x%08x\n", + caps.ndis_caps); + return (EOPNOTSUPP); + } + + /* Commit! */ + sc->hn_rss_ind_size = indsz; + sc->hn_rss_hash = hash_func | hash_types; + *rxr_cnt0 = rxr_cnt; return (0); } @@ -1033,7 +1089,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags) { struct ndis_rssprm_toeplitz *rss = &sc->hn_rss; struct ndis_rss_params *prm = &rss->rss_params; - int error; + int error, rss_size; /* * Only NDIS 6.20+ is supported: @@ -1043,21 +1099,29 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags) KASSERT(sc->hn_ndis_ver >= HN_NDIS_VERSION_6_20, ("NDIS 6.20+ is required, NDIS version 0x%08x", sc->hn_ndis_ver)); + /* XXX only one can be specified through, popcnt? */ + KASSERT((sc->hn_rss_hash & NDIS_HASH_FUNCTION_MASK), ("no hash func")); + KASSERT((sc->hn_rss_hash & NDIS_HASH_TYPE_MASK), ("no hash types")); + KASSERT(sc->hn_rss_ind_size > 0, ("no indirect table size")); + + if (bootverbose) { + if_printf(sc->hn_ifp, "RSS indirect table size %d, " + "hash 0x%08x\n", sc->hn_rss_ind_size, sc->hn_rss_hash); + } + /* * NOTE: * DO NOT whack rss_key and rss_ind, which are setup by the caller. */ memset(prm, 0, sizeof(*prm)); + rss_size = NDIS_RSSPRM_TOEPLITZ_SIZE(sc->hn_rss_ind_size); prm->ndis_hdr.ndis_type = NDIS_OBJTYPE_RSS_PARAMS; prm->ndis_hdr.ndis_rev = NDIS_RSS_PARAMS_REV_2; - prm->ndis_hdr.ndis_size = sizeof(*rss); + prm->ndis_hdr.ndis_size = rss_size; prm->ndis_flags = flags; - prm->ndis_hash = NDIS_HASH_FUNCTION_TOEPLITZ | - NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 | - NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6; - /* TODO: Take ndis_rss_caps.ndis_nind into account */ - prm->ndis_indsize = sizeof(rss->rss_ind); + prm->ndis_hash = sc->hn_rss_hash; + prm->ndis_indsize = sizeof(rss->rss_ind[0]) * sc->hn_rss_ind_size; prm->ndis_indoffset = __offsetof(struct ndis_rssprm_toeplitz, rss_ind[0]); prm->ndis_keysize = sizeof(rss->rss_key); @@ -1065,7 +1129,7 @@ hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags) __offsetof(struct ndis_rssprm_toeplitz, rss_key[0]); error = hn_rndis_set(sc, OID_GEN_RECEIVE_SCALE_PARAMETERS, - rss, sizeof(*rss)); + rss, rss_size); if (error) { if_printf(sc->hn_ifp, "RSS config failed: %d\n", error); } else { diff --git a/sys/dev/hyperv/netvsc/ndis.h b/sys/dev/hyperv/netvsc/ndis.h index 5c741c6db330..9d01471553c6 100644 --- a/sys/dev/hyperv/netvsc/ndis.h +++ b/sys/dev/hyperv/netvsc/ndis.h @@ -57,6 +57,10 @@ #define NDIS_HASH_TCP_IPV6 0x00001000 #define NDIS_HASH_TCP_IPV6_EX 0x00002000 +/* Hash description for use with printf(9) %b identifier. */ +#define NDIS_HASH_BITS \ + "\20\1TOEPLITZ\11IP4\12TCP4\13IP6\14IP6EX\15TCP6\16TCP6EX" + #define NDIS_HASH_KEYSIZE_TOEPLITZ 40 #define NDIS_HASH_INDCNT 128 @@ -142,7 +146,7 @@ struct ndis_offload_params { */ struct ndis_rss_caps { struct ndis_object_hdr ndis_hdr; - uint32_t ndis_flags; /* NDIS_RSS_CAP_ */ + uint32_t ndis_caps; /* NDIS_RSS_CAP_ */ uint32_t ndis_nmsi; /* # of MSIs */ uint32_t ndis_nrxr; /* # of RX rings */ /* NDIS >= 6.30 */ @@ -165,7 +169,8 @@ struct ndis_rss_caps { #define NDIS_RSS_CAP_IPV4 0x00000100 #define NDIS_RSS_CAP_IPV6 0x00000200 #define NDIS_RSS_CAP_IPV6_EX 0x00000400 -#define NDIS_RSS_CAP_HASH_TOEPLITZ 0x00000001 +#define NDIS_RSS_CAP_HASH_TOEPLITZ NDIS_HASH_FUNCTION_TOEPLITZ +#define NDIS_RSS_CAP_HASHFUNC_MASK NDIS_HASH_FUNCTION_MASK /* * OID_GEN_RECEIVE_SCALE_PARAMETERS @@ -209,6 +214,9 @@ struct ndis_rssprm_toeplitz { uint32_t rss_ind[NDIS_HASH_INDCNT]; }; +#define NDIS_RSSPRM_TOEPLITZ_SIZE(nind) \ + __offsetof(struct ndis_rssprm_toeplitz, rss_ind[nind]) + /* * OID_TCP_OFFLOAD_HARDWARE_CAPABILITIES * ndis_type: NDIS_OBJTYPE_OFFLOAD From a6e9118bf43072ef1e0645eb91d4a2f1e4262879 Mon Sep 17 00:00:00 2001 From: Ganbold Tsagaankhuu Date: Thu, 27 Oct 2016 04:26:33 +0000 Subject: [PATCH 139/235] Add support for Allwinner Consumer IR interface. RX is supported now and the driver is using evdev framework. It was tested on Cubieboard2 (A20 SoC) using lirc with dfrobot's IR remote controller. --- sys/arm/allwinner/aw_cir.c | 535 ++++++++++++++++++++++++++++++ sys/arm/allwinner/files.allwinner | 1 + sys/arm/conf/GENERIC | 6 + 3 files changed, 542 insertions(+) create mode 100644 sys/arm/allwinner/aw_cir.c diff --git a/sys/arm/allwinner/aw_cir.c b/sys/arm/allwinner/aw_cir.c new file mode 100644 index 000000000000..19f49fbe7761 --- /dev/null +++ b/sys/arm/allwinner/aw_cir.c @@ -0,0 +1,535 @@ +/*- + * Copyright (c) 2016 Ganbold Tsagaankhuu + * 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. + */ + +/* + * Allwinner Consumer IR controller + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define READ(_sc, _r) bus_read_4((_sc)->res[0], (_r)) +#define WRITE(_sc, _r, _v) bus_write_4((_sc)->res[0], (_r), (_v)) + +/* IR Control */ +#define AW_IR_CTL 0x00 +/* Global Enable */ +#define AW_IR_CTL_GEN (1 << 0) +/* RX enable */ +#define AW_IR_CTL_RXEN (1 << 1) +/* CIR mode enable */ +#define AW_IR_CTL_MD (1 << 4) | (1 << 5) + +/* RX Config Reg */ +#define AW_IR_RXCTL 0x10 +/* Pulse Polarity Invert flag */ +#define AW_IR_RXCTL_RPPI (1 << 2) + +/* RX Data */ +#define AW_IR_RXFIFO 0x20 + +/* RX Interrupt Control */ +#define AW_IR_RXINT 0x2C +/* RX FIFO Overflow */ +#define AW_IR_RXINT_ROI_EN (1 << 0) +/* RX Packet End */ +#define AW_IR_RXINT_RPEI_EN (1 << 1) +/* RX FIFO Data Available */ +#define AW_IR_RXINT_RAI_EN (1 << 4) +/* RX FIFO available byte level */ +#define AW_IR_RXINT_RAL(val) ((val) << 8) + +/* RX Interrupt Status Reg */ +#define AW_IR_RXSTA 0x30 +/* RX FIFO Get Available Counter */ +#define AW_IR_RXSTA_COUNTER(val) (((val) >> 8) & (sc->fifo_size * 2 - 1)) +/* Clear all interrupt status */ +#define AW_IR_RXSTA_CLEARALL 0xff + +/* IR Sample Configure Reg */ +#define AW_IR_CIR 0x34 +/* Filter Threshold = 8 * 21.3 = ~128us < 200us */ +#define AW_IR_RXFILT_VAL (((8) & 0x3f) << 2) +/* Idle Threshold = (2 + 1) * 128 * 42.7 = ~16.4ms > 9ms */ +#define AW_IR_RXIDLE_VAL (((2) & 0xff) << 8) + +/* Bit 15 - value (pulse/space) */ +#define VAL_MASK 0x80 +/* Bits 0:14 - sample duration */ +#define PERIOD_MASK 0x7f + +/* Clock rate for IR0 or IR1 clock in CIR mode */ +#define AW_IR_BASE_CLK 3000000 +/* Frequency sample 3MHz/64 = 46875Hz (21.3us) */ +#define AW_IR_SAMPLE_64 (0 << 0) +/* Frequency sample 3MHz/128 = 23437.5Hz (42.7us) */ +#define AW_IR_SAMPLE_128 (1 << 0) + +#define AW_IR_ERROR_CODE 0xffffffff +#define AW_IR_REPEAT_CODE 0x0 + +/* 80 * 42.7 = ~3.4ms, Lead1(4.5ms) > AW_IR_L1_MIN */ +#define AW_IR_L1_MIN 80 +/* 40 * 42.7 = ~1.7ms, Lead0(4.5ms) Lead0R(2.25ms) > AW_IR_L0_MIN */ +#define AW_IR_L0_MIN 40 +/* 26 * 42.7 = ~1109us ~= 561 * 2, Pulse < AW_IR_PMAX */ +#define AW_IR_PMAX 26 +/* 26 * 42.7 = ~1109us ~= 561 * 2, D1 > AW_IR_DMID, D0 <= AW_IR_DMID */ +#define AW_IR_DMID 26 +/* 53 * 42.7 = ~2263us ~= 561 * 4, D < AW_IR_DMAX */ +#define AW_IR_DMAX 53 + +/* Active Thresholds */ +#define AW_IR_ACTIVE_T ((0 & 0xff) << 16) +#define AW_IR_ACTIVE_T_C ((1 & 0xff) << 23) + +/* Code masks */ +#define CODE_MASK 0x00ff00ff +#define INV_CODE_MASK 0xff00ff00 +#define VALID_CODE_MASK 0x00ff0000 + +#define A10_IR 1 +#define A13_IR 2 + +#define AW_IR_RAW_BUF_SIZE 128 + +struct aw_ir_softc { + device_t dev; + struct resource *res[2]; + void * intrhand; + int fifo_size; + int dcnt; /* Packet Count */ + unsigned char buf[AW_IR_RAW_BUF_SIZE]; + struct evdev_dev *sc_evdev; +}; + +static struct resource_spec aw_ir_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, + { -1, 0 } +}; + +static struct ofw_compat_data compat_data[] = { + { "allwinner,sun4i-a10-ir", A10_IR }, + { "allwinner,sun5i-a13-ir", A13_IR }, + { NULL, 0 } +}; + +static void +aw_ir_buf_reset(struct aw_ir_softc *sc) +{ + + sc->dcnt = 0; +} + +static void +aw_ir_buf_write(struct aw_ir_softc *sc, unsigned char data) +{ + + if (sc->dcnt < AW_IR_RAW_BUF_SIZE) + sc->buf[sc->dcnt++] = data; + else + if (bootverbose) + device_printf(sc->dev, "IR RX Buffer Full!\n"); +} + +static int +aw_ir_buf_full(struct aw_ir_softc *sc) +{ + + return (sc->dcnt >= AW_IR_RAW_BUF_SIZE); +} + +static unsigned char +aw_ir_read_data(struct aw_ir_softc *sc) +{ + + return (unsigned char)(READ(sc, AW_IR_RXFIFO) & 0xff); +} + +static unsigned long +aw_ir_decode_packets(struct aw_ir_softc *sc) +{ + unsigned long len, code; + unsigned char val, last; + unsigned int active_delay; + int i, bitcount; + + if (bootverbose) + device_printf(sc->dev, "sc->dcnt = %d\n", sc->dcnt); + + /* Find Lead 1 (bit separator) */ + active_delay = (AW_IR_ACTIVE_T + 1) * (AW_IR_ACTIVE_T_C ? 128 : 1); + len = 0; + len += (active_delay >> 1); + if (bootverbose) + device_printf(sc->dev, "Initial len: %ld\n", len); + for (i = 0; i < sc->dcnt; i++) { + val = sc->buf[i]; + if (val & VAL_MASK) + len += val & PERIOD_MASK; + else { + if (len > AW_IR_L1_MIN) + break; + len = 0; + } + } + if (bootverbose) + device_printf(sc->dev, "len = %ld\n", len); + if ((val & VAL_MASK) || (len <= AW_IR_L1_MIN)) { + if (bootverbose) + device_printf(sc->dev, "Bit separator error\n"); + goto error_code; + } + + /* Find Lead 0 (bit length) */ + len = 0; + for (; i < sc->dcnt; i++) { + val = sc->buf[i]; + if (val & VAL_MASK) { + if(len > AW_IR_L0_MIN) + break; + len = 0; + } else + len += val & PERIOD_MASK; + } + if ((!(val & VAL_MASK)) || (len <= AW_IR_L0_MIN)) { + if (bootverbose) + device_printf(sc->dev, "Bit length error\n"); + goto error_code; + } + + /* Start decoding */ + code = 0; + bitcount = 0; + last = 1; + len = 0; + for (; i < sc->dcnt; i++) { + val = sc->buf[i]; + if (last) { + if (val & VAL_MASK) + len += val & PERIOD_MASK; + else { + if (len > AW_IR_PMAX) { + if (bootverbose) + device_printf(sc->dev, + "Pulse error\n"); + goto error_code; + } + last = 0; + len = val & PERIOD_MASK; + } + } else { + if (val & VAL_MASK) { + if (len > AW_IR_DMAX) { + if (bootverbose) + device_printf(sc->dev, + "Distant error\n"); + goto error_code; + } else { + if (len > AW_IR_DMID) { + /* Decode */ + code |= 1 << bitcount; + } + bitcount++; + if (bitcount == 32) + break; /* Finish decoding */ + } + last = 1; + len = val & PERIOD_MASK; + } else + len += val & PERIOD_MASK; + } + } + return (code); + +error_code: + + return (AW_IR_ERROR_CODE); +} + +static int +aw_ir_validate_code(unsigned long code) +{ + unsigned long v1, v2; + + /* Don't check address */ + v1 = code & CODE_MASK; + v2 = (code & INV_CODE_MASK) >> 8; + + if (((v1 ^ v2) & VALID_CODE_MASK) == VALID_CODE_MASK) + return (0); /* valid */ + else + return (1); /* invalid */ +} + +static void +aw_ir_intr(void *arg) +{ + struct aw_ir_softc *sc; + uint32_t val; + int i, dcnt; + unsigned long ir_code; + int stat; + + sc = (struct aw_ir_softc *)arg; + + /* Read RX interrupt status */ + val = READ(sc, AW_IR_RXSTA); + + /* Clean all pending interrupt statuses */ + WRITE(sc, AW_IR_RXSTA, val | AW_IR_RXSTA_CLEARALL); + + /* When Rx FIFO Data available or Packet end */ + if (val & (AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RPEI_EN)) { + /* Get available message count in RX FIFO */ + dcnt = AW_IR_RXSTA_COUNTER(val); + /* Read FIFO */ + for (i = 0; i < dcnt; i++) { + if (aw_ir_buf_full(sc)) { + if (bootverbose) + device_printf(sc->dev, + "raw buffer full\n"); + break; + } else + aw_ir_buf_write(sc, aw_ir_read_data(sc)); + } + } + + if (val & AW_IR_RXINT_RPEI_EN) { + /* RX Packet end */ + if (bootverbose) + device_printf(sc->dev, "RX Packet end\n"); + ir_code = aw_ir_decode_packets(sc); + stat = aw_ir_validate_code(ir_code); + if (stat == 0) { + evdev_push_event(sc->sc_evdev, + EV_MSC, MSC_SCAN, ir_code); + evdev_sync(sc->sc_evdev); + } + if (bootverbose) { + device_printf(sc->dev, "Final IR code: %lx\n", + ir_code); + device_printf(sc->dev, "IR code status: %d\n", + stat); + } + sc->dcnt = 0; + } + if (val & AW_IR_RXINT_ROI_EN) { + /* RX FIFO overflow */ + if (bootverbose) + device_printf(sc->dev, "RX FIFO overflow\n"); + /* Flush raw buffer */ + aw_ir_buf_reset(sc); + } +} + +static int +aw_ir_probe(device_t dev) +{ + + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "Allwinner CIR controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +aw_ir_attach(device_t dev) +{ + struct aw_ir_softc *sc; + hwreset_t rst_apb; + clk_t clk_ir, clk_gate; + int err; + uint32_t val = 0; + + clk_ir = clk_gate = NULL; + + sc = device_get_softc(dev); + sc->dev = dev; + + if (bus_alloc_resources(dev, aw_ir_spec, sc->res) != 0) { + device_printf(dev, "could not allocate memory resource\n"); + return (ENXIO); + } + + switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { + case A10_IR: + sc->fifo_size = 16; + break; + case A13_IR: + sc->fifo_size = 64; + break; + } + + /* De-assert reset */ + if (hwreset_get_by_ofw_name(dev, 0, "apb", &rst_apb) == 0) { + err = hwreset_deassert(rst_apb); + if (err != 0) { + device_printf(dev, "cannot de-assert reset\n"); + goto error; + } + } + + /* Reset buffer */ + aw_ir_buf_reset(sc); + + /* Get clocks and enable them */ + err = clk_get_by_ofw_name(dev, 0, "apb", &clk_gate); + if (err != 0) { + device_printf(dev, "Cannot get gate clock\n"); + goto error; + } + err = clk_get_by_ofw_name(dev, 0, "ir", &clk_ir); + if (err != 0) { + device_printf(dev, "Cannot get IR clock\n"); + goto error; + } + /* Set clock rate */ + err = clk_set_freq(clk_ir, AW_IR_BASE_CLK, 0); + if (err != 0) { + device_printf(dev, "cannot set IR clock rate\n"); + goto error; + } + /* Enable clocks */ + err = clk_enable(clk_gate); + if (err != 0) { + device_printf(dev, "Cannot enable clk gate\n"); + goto error; + } + err = clk_enable(clk_ir); + if (err != 0) { + device_printf(dev, "Cannot enable IR clock\n"); + goto error; + } + + if (bus_setup_intr(dev, sc->res[1], + INTR_TYPE_MISC | INTR_MPSAFE, NULL, aw_ir_intr, sc, + &sc->intrhand)) { + bus_release_resources(dev, aw_ir_spec, sc->res); + device_printf(dev, "cannot setup interrupt handler\n"); + return (ENXIO); + } + + /* Enable CIR Mode */ + WRITE(sc, AW_IR_CTL, AW_IR_CTL_MD); + + /* + * Set clock sample, filter, idle thresholds. + * Frequency sample = 3MHz/128 = 23437.5Hz (42.7us) + */ + val = AW_IR_SAMPLE_128; + val |= (AW_IR_RXFILT_VAL | AW_IR_RXIDLE_VAL); + val |= (AW_IR_ACTIVE_T | AW_IR_ACTIVE_T_C); + WRITE(sc, AW_IR_CIR, val); + + /* Invert Input Signal */ + WRITE(sc, AW_IR_RXCTL, AW_IR_RXCTL_RPPI); + + /* Clear All RX Interrupt Status */ + WRITE(sc, AW_IR_RXSTA, AW_IR_RXSTA_CLEARALL); + + /* + * Enable RX interrupt in case of overflow, packet end + * and FIFO available. + * RX FIFO Threshold = FIFO size / 2 + */ + WRITE(sc, AW_IR_RXINT, AW_IR_RXINT_ROI_EN | AW_IR_RXINT_RPEI_EN | + AW_IR_RXINT_RAI_EN | AW_IR_RXINT_RAL((sc->fifo_size >> 1) - 1)); + + /* Enable IR Module */ + val = READ(sc, AW_IR_CTL); + WRITE(sc, AW_IR_CTL, val | AW_IR_CTL_GEN | AW_IR_CTL_RXEN); + + sc->sc_evdev = evdev_alloc(); + evdev_set_name(sc->sc_evdev, device_get_desc(sc->dev)); + evdev_set_phys(sc->sc_evdev, device_get_nameunit(sc->dev)); + evdev_set_id(sc->sc_evdev, BUS_HOST, 0, 0, 0); + evdev_support_event(sc->sc_evdev, EV_SYN); + evdev_support_event(sc->sc_evdev, EV_MSC); + evdev_support_msc(sc->sc_evdev, MSC_SCAN); + + err = evdev_register(sc->sc_evdev); + if (err) { + device_printf(dev, + "failed to register evdev: error=%d\n", err); + goto error; + } + + return (0); +error: + if (clk_gate != NULL) + clk_release(clk_gate); + if (clk_ir != NULL) + clk_release(clk_ir); + if (rst_apb != NULL) + hwreset_release(rst_apb); + evdev_free(sc->sc_evdev); + sc->sc_evdev = NULL; /* Avoid double free */ + + bus_release_resources(dev, aw_ir_spec, sc->res); + return (ENXIO); +} + +static device_method_t aw_ir_methods[] = { + DEVMETHOD(device_probe, aw_ir_probe), + DEVMETHOD(device_attach, aw_ir_attach), + + DEVMETHOD_END +}; + +static driver_t aw_ir_driver = { + "aw_ir", + aw_ir_methods, + sizeof(struct aw_ir_softc), +}; +static devclass_t aw_ir_devclass; + +DRIVER_MODULE(aw_ir, simplebus, aw_ir_driver, aw_ir_devclass, 0, 0); +MODULE_DEPEND(aw_ir, evdev, 1, 1, 1); diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner index 4e04902268be..d4e6a88456c7 100644 --- a/sys/arm/allwinner/files.allwinner +++ b/sys/arm/allwinner/files.allwinner @@ -29,6 +29,7 @@ dev/usb/controller/generic_usb_if.m optional ohci arm/allwinner/aw_sid.c standard arm/allwinner/aw_thermal.c standard dev/iicbus/sy8106a.c optional sy8106a +arm/allwinner/aw_cir.c optional aw_cir evdev #arm/allwinner/console.c standard arm/allwinner/a10_fb.c optional vt diff --git a/sys/arm/conf/GENERIC b/sys/arm/conf/GENERIC index 8e3169ca7266..dfc1b31bd021 100644 --- a/sys/arm/conf/GENERIC +++ b/sys/arm/conf/GENERIC @@ -119,6 +119,12 @@ device gpio device gpioled device gpioregulator +# EVDEV support +device evdev # input event device support +options EVDEV_SUPPORT # evdev support in legacy drivers +device uinput # install /dev/uinput cdev +device aw_cir + # SPI device spibus device bcm2835_spi From 90321eb752644caf7877ed126267dcb752e436d8 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 04:28:01 +0000 Subject: [PATCH 140/235] hyperv/hn: Nuke unnecessary M_NETVSC MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8340 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 6 ++-- sys/dev/hyperv/netvsc/hv_net_vsc.h | 2 -- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 30 +++++++++---------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index a14faffbe991..028042d8f6b1 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -52,8 +52,6 @@ #include #include -MALLOC_DEFINE(M_NETVSC, "netvsc", "Hyper-V netvsc driver"); - /* * Forward declarations */ @@ -308,7 +306,7 @@ hn_nvs_conn_chim(struct hn_softc *sc) sc->hn_chim_bmap_cnt = sc->hn_chim_cnt / LONG_BIT; sc->hn_chim_bmap = malloc(sc->hn_chim_bmap_cnt * sizeof(u_long), - M_NETVSC, M_WAITOK | M_ZERO); + M_DEVBUF, M_WAITOK | M_ZERO); /* Done! */ sc->hn_flags |= HN_FLAG_CHIM_CONNECTED; @@ -427,7 +425,7 @@ hn_nvs_disconn_chim(struct hn_softc *sc) } if (sc->hn_chim_bmap != NULL) { - free(sc->hn_chim_bmap, M_NETVSC); + free(sc->hn_chim_bmap, M_DEVBUF); sc->hn_chim_bmap = NULL; } return (0); diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 5f7fea7566a7..1bddf47afa82 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -66,8 +66,6 @@ #define HN_USE_TXDESC_BUFRING -MALLOC_DECLARE(M_NETVSC); - /* * The following arguably belongs in a separate header file */ diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 7e89cf78d250..e0365bfa9f3b 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -2606,7 +2606,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) sc->hn_rx_ring_inuse = sc->hn_rx_ring_cnt; sc->hn_rx_ring = malloc(sizeof(struct hn_rx_ring) * sc->hn_rx_ring_cnt, - M_NETVSC, M_WAITOK | M_ZERO); + M_DEVBUF, M_WAITOK | M_ZERO); #if defined(INET) || defined(INET6) #if __FreeBSD_version >= 1100095 @@ -2647,7 +2647,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) rxr->hn_ifp = sc->hn_ifp; if (i < sc->hn_tx_ring_cnt) rxr->hn_txr = &sc->hn_tx_ring[i]; - rxr->hn_rdbuf = malloc(NETVSC_PACKET_SIZE, M_NETVSC, M_WAITOK); + rxr->hn_rdbuf = malloc(NETVSC_PACKET_SIZE, M_DEVBUF, M_WAITOK); rxr->hn_rx_idx = i; rxr->hn_rxbuf = sc->hn_rxbuf; @@ -2794,9 +2794,9 @@ hn_destroy_rx_data(struct hn_softc *sc) #if defined(INET) || defined(INET6) tcp_lro_free(&rxr->hn_lro); #endif - free(rxr->hn_rdbuf, M_NETVSC); + free(rxr->hn_rdbuf, M_DEVBUF); } - free(sc->hn_rx_ring, M_NETVSC); + free(sc->hn_rx_ring, M_DEVBUF); sc->hn_rx_ring = NULL; sc->hn_rx_ring_cnt = 0; @@ -2821,11 +2821,11 @@ hn_create_tx_ring(struct hn_softc *sc, int id) txr->hn_txdesc_cnt = HN_TX_DESC_CNT; txr->hn_txdesc = malloc(sizeof(struct hn_txdesc) * txr->hn_txdesc_cnt, - M_NETVSC, M_WAITOK | M_ZERO); + M_DEVBUF, M_WAITOK | M_ZERO); #ifndef HN_USE_TXDESC_BUFRING SLIST_INIT(&txr->hn_txlist); #else - txr->hn_txdesc_br = buf_ring_alloc(txr->hn_txdesc_cnt, M_NETVSC, + txr->hn_txdesc_br = buf_ring_alloc(txr->hn_txdesc_cnt, M_DEVBUF, M_WAITOK, &txr->hn_tx_lock); #endif @@ -2843,7 +2843,7 @@ hn_create_tx_ring(struct hn_softc *sc, int id) TASK_INIT(&txr->hn_txeof_task, 0, hn_xmit_txeof_taskfunc, txr); br_depth = hn_get_txswq_depth(txr); - txr->hn_mbuf_br = buf_ring_alloc(br_depth, M_NETVSC, + txr->hn_mbuf_br = buf_ring_alloc(br_depth, M_DEVBUF, M_WAITOK, &txr->hn_tx_lock); } @@ -3026,14 +3026,14 @@ hn_destroy_tx_ring(struct hn_tx_ring *txr) bus_dma_tag_destroy(txr->hn_tx_rndis_dtag); #ifdef HN_USE_TXDESC_BUFRING - buf_ring_free(txr->hn_txdesc_br, M_NETVSC); + buf_ring_free(txr->hn_txdesc_br, M_DEVBUF); #endif - free(txr->hn_txdesc, M_NETVSC); + free(txr->hn_txdesc, M_DEVBUF); txr->hn_txdesc = NULL; if (txr->hn_mbuf_br != NULL) - buf_ring_free(txr->hn_mbuf_br, M_NETVSC); + buf_ring_free(txr->hn_mbuf_br, M_DEVBUF); #ifndef HN_USE_TXDESC_BUFRING mtx_destroy(&txr->hn_txlist_spin); @@ -3065,7 +3065,7 @@ hn_create_tx_data(struct hn_softc *sc, int ring_cnt) sc->hn_tx_ring_inuse = sc->hn_tx_ring_cnt; sc->hn_tx_ring = malloc(sizeof(struct hn_tx_ring) * sc->hn_tx_ring_cnt, - M_NETVSC, M_WAITOK | M_ZERO); + M_DEVBUF, M_WAITOK | M_ZERO); ctx = device_get_sysctl_ctx(sc->hn_dev); child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->hn_dev)); @@ -3225,7 +3225,7 @@ hn_destroy_tx_data(struct hn_softc *sc) for (i = 0; i < sc->hn_tx_ring_cnt; ++i) hn_destroy_tx_ring(&sc->hn_tx_ring[i]); - free(sc->hn_tx_ring, M_NETVSC); + free(sc->hn_tx_ring, M_DEVBUF); sc->hn_tx_ring = NULL; sc->hn_tx_ring_cnt = 0; @@ -4175,12 +4175,12 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) } else if (ret == ENOBUFS) { /* Handle large packet */ if (bufferlen > NETVSC_PACKET_SIZE) { - free(buffer, M_NETVSC); + free(buffer, M_DEVBUF); buffer = NULL; } /* alloc new buffer */ - buffer = malloc(bytes_rxed, M_NETVSC, M_NOWAIT); + buffer = malloc(bytes_rxed, M_DEVBUF, M_NOWAIT); if (buffer == NULL) { if_printf(rxr->hn_ifp, "hv_cb malloc buffer failed, len=%u\n", @@ -4196,7 +4196,7 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) } while (1); if (bufferlen > NETVSC_PACKET_SIZE) - free(buffer, M_NETVSC); + free(buffer, M_DEVBUF); hv_rf_channel_rollup(rxr, rxr->hn_txr); } From 5341cc1c9116dd7d537c4b0912a58b586d9b45e9 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 04:42:39 +0000 Subject: [PATCH 141/235] hyperv/hn: Move %b format string for capabilities near their definition. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8341 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 5 +++++ sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 13 +------------ 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 1bddf47afa82..ce47a85e1d26 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -275,6 +275,11 @@ struct hn_softc { #define HN_CAP_TSO6 0x0100 #define HN_CAP_HASHVAL 0x0200 +/* Capability description for use with printf(9) %b identifier. */ +#define HN_CAP_BITS \ + "\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS" \ + "\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL" + #define HN_LINK_FLAG_LINKUP 0x0001 #define HN_LINK_FLAG_NETCHG 0x0002 diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index e0365bfa9f3b..821e1373433e 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -2379,18 +2379,7 @@ hn_caps_sysctl(SYSCTL_HANDLER_ARGS) HN_LOCK(sc); caps = sc->hn_caps; HN_UNLOCK(sc); - snprintf(caps_str, sizeof(caps_str), "%b", caps, - "\020" - "\001VLAN" - "\002MTU" - "\003IPCS" - "\004TCP4CS" - "\005TCP6CS" - "\006UDP4CS" - "\007UDP6CS" - "\010TSO4" - "\011TSO6" - "\012HASHVAL"); + snprintf(caps_str, sizeof(caps_str), "%b", caps, HN_CAP_BITS); return sysctl_handle_string(oidp, caps_str, sizeof(caps_str), req); } From 14a31e99d7e7c907d3d16618e08237c59056cc18 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 04:55:19 +0000 Subject: [PATCH 142/235] hyperv/hn: Define empty packet filter. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8342 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 4 ++-- sys/dev/hyperv/netvsc/if_hnvar.h | 2 +- sys/net/rndis.h | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 821e1373433e..551df9f006e4 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -3849,8 +3849,8 @@ hn_suspend_data(struct hn_softc *sc) /* * Disable RX by clearing RX filter. */ - hn_rndis_set_rxfilter(sc, 0); - sc->hn_rx_filter = 0; + sc->hn_rx_filter = NDIS_PACKET_TYPE_NONE; + hn_rndis_set_rxfilter(sc, sc->hn_rx_filter); /* * Give RNDIS enough time to flush all pending data packets. diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 0b37cf3c819b..f6aca1c43bf7 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -106,7 +106,7 @@ int hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt); int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr); int hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status); -/* filter: NDIS_PACKET_TYPE_ or 0. */ +/* filter: NDIS_PACKET_TYPE_. */ int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); int hn_nvs_attach(struct hn_softc *sc, int mtu); diff --git a/sys/net/rndis.h b/sys/net/rndis.h index 12385e35ca24..72548ebf1f11 100644 --- a/sys/net/rndis.h +++ b/sys/net/rndis.h @@ -352,6 +352,7 @@ struct rndis_keepalive_comp { }; /* Packet filter bits used by OID_GEN_CURRENT_PACKET_FILTER */ +#define NDIS_PACKET_TYPE_NONE 0x00000000 #define NDIS_PACKET_TYPE_DIRECTED 0x00000001 #define NDIS_PACKET_TYPE_MULTICAST 0x00000002 #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 From d6e37dc70f00047001b7ae16dfca3e3e795475e6 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 05:04:54 +0000 Subject: [PATCH 143/235] hyperv/hn: Shuffle chimney sending buffer alloc/free around. This paves way for more chimney sending buffer reorganization. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8343 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 46 ------------------ sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 47 +++++++++++++++++++ sys/dev/hyperv/netvsc/if_hnvar.h | 3 -- 3 files changed, 47 insertions(+), 49 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 028042d8f6b1..ad5097724496 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -73,33 +73,6 @@ static const uint32_t hn_nvs_version[] = { HN_NVS_VERSION_1 }; -uint32_t -hn_chim_alloc(struct hn_softc *sc) -{ - int i, bmap_cnt = sc->hn_chim_bmap_cnt; - u_long *bmap = sc->hn_chim_bmap; - uint32_t ret = HN_NVS_CHIM_IDX_INVALID; - - for (i = 0; i < bmap_cnt; ++i) { - int idx; - - idx = ffsl(~bmap[i]); - if (idx == 0) - continue; - - --idx; /* ffsl is 1-based */ - KASSERT(i * LONG_BIT + idx < sc->hn_chim_cnt, - ("invalid i %d and idx %d", i, idx)); - - if (atomic_testandset_long(&bmap[i], idx)) - continue; - - ret = i * LONG_BIT + idx; - break; - } - return (ret); -} - static const void * hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, size_t *resplen0, uint32_t type) @@ -648,25 +621,6 @@ hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, /* EMPTY */ } -void -hn_chim_free(struct hn_softc *sc, uint32_t chim_idx) -{ - u_long mask; - uint32_t idx; - - idx = chim_idx / LONG_BIT; - KASSERT(idx < sc->hn_chim_bmap_cnt, - ("invalid chimney index 0x%x", chim_idx)); - - mask = 1UL << (chim_idx % LONG_BIT); - KASSERT(sc->hn_chim_bmap[idx] & mask, - ("index bitmap 0x%lx, chimney index %u, " - "bitmap idx %d, bitmask 0x%lx", - sc->hn_chim_bmap[idx], chim_idx, idx, mask)); - - atomic_clear_long(&sc->hn_chim_bmap[idx], mask); -} - int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch0) { diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 551df9f006e4..1314f63b9057 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -457,6 +458,52 @@ hn_sendpkt_rndis_chim(struct hn_tx_ring *txr, struct hn_txdesc *txd) &rndis, sizeof(rndis), &txd->send_ctx)); } +static __inline uint32_t +hn_chim_alloc(struct hn_softc *sc) +{ + int i, bmap_cnt = sc->hn_chim_bmap_cnt; + u_long *bmap = sc->hn_chim_bmap; + uint32_t ret = HN_NVS_CHIM_IDX_INVALID; + + for (i = 0; i < bmap_cnt; ++i) { + int idx; + + idx = ffsl(~bmap[i]); + if (idx == 0) + continue; + + --idx; /* ffsl is 1-based */ + KASSERT(i * LONG_BIT + idx < sc->hn_chim_cnt, + ("invalid i %d and idx %d", i, idx)); + + if (atomic_testandset_long(&bmap[i], idx)) + continue; + + ret = i * LONG_BIT + idx; + break; + } + return (ret); +} + +static __inline void +hn_chim_free(struct hn_softc *sc, uint32_t chim_idx) +{ + u_long mask; + uint32_t idx; + + idx = chim_idx / LONG_BIT; + KASSERT(idx < sc->hn_chim_bmap_cnt, + ("invalid chimney index 0x%x", chim_idx)); + + mask = 1UL << (chim_idx % LONG_BIT); + KASSERT(sc->hn_chim_bmap[idx] & mask, + ("index bitmap 0x%lx, chimney index %u, " + "bitmap idx %d, bitmask 0x%lx", + sc->hn_chim_bmap[idx], chim_idx, idx, mask)); + + atomic_clear_long(&sc->hn_chim_bmap[idx], mask); +} + static int hn_set_rxfilter(struct hn_softc *sc) { diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index f6aca1c43bf7..5f01d6c97688 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -94,9 +94,6 @@ hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, struct vmbus_xact; struct rndis_packet_msg; -uint32_t hn_chim_alloc(struct hn_softc *sc); -void hn_chim_free(struct hn_softc *sc, uint32_t chim_idx); - int hn_rndis_attach(struct hn_softc *sc, int mtu); void hn_rndis_detach(struct hn_softc *sc); int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); From 19b2340a769141d704563e19e688a48b21fc49df Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 05:13:00 +0000 Subject: [PATCH 144/235] hyperv/hn: Move hn_softc to if_hnvar.h While I'm here, use consistent macro names. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8345 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 11 +- sys/dev/hyperv/netvsc/hv_net_vsc.h | 226 ------------------ sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 37 +-- sys/dev/hyperv/netvsc/if_hnvar.h | 214 ++++++++++++++++- 4 files changed, 230 insertions(+), 258 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index ad5097724496..0de7901920a6 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -138,9 +138,9 @@ hn_nvs_conn_rxbuf(struct hn_softc *sc) * Limit RXBUF size for old NVS. */ if (sc->hn_nvs_ver <= HN_NVS_VERSION_2) - rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY; + rxbuf_size = HN_RXBUF_SIZE_COMPAT; else - rxbuf_size = NETVSC_RECEIVE_BUFFER_SIZE; + rxbuf_size = HN_RXBUF_SIZE; /* * Connect the RXBUF GPADL to the primary channel. @@ -219,8 +219,7 @@ hn_nvs_conn_chim(struct hn_softc *sc) * Sub-channels just share this chimney sending buffer. */ error = vmbus_chan_gpadl_connect(sc->hn_prichan, - sc->hn_chim_dma.hv_paddr, NETVSC_SEND_BUFFER_SIZE, - &sc->hn_chim_gpadl); + sc->hn_chim_dma.hv_paddr, HN_CHIM_SIZE, &sc->hn_chim_gpadl); if (error) { if_printf(sc->hn_ifp, "chim gpadl conn failed: %d\n", error); goto cleanup; @@ -267,8 +266,8 @@ hn_nvs_conn_chim(struct hn_softc *sc) } sc->hn_chim_szmax = sectsz; - sc->hn_chim_cnt = NETVSC_SEND_BUFFER_SIZE / sc->hn_chim_szmax; - if (NETVSC_SEND_BUFFER_SIZE % sc->hn_chim_szmax != 0) { + sc->hn_chim_cnt = HN_CHIM_SIZE / sc->hn_chim_szmax; + if (HN_CHIM_SIZE % sc->hn_chim_szmax != 0) { if_printf(sc->hn_ifp, "chimney sending sections are " "not properly aligned\n"); } diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index ce47a85e1d26..17d93fa9c202 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -28,13 +28,6 @@ * $FreeBSD$ */ -/* - * HyperV vmbus (virtual machine bus) network VSC (virtual services client) - * header file - * - * (Updated from unencumbered NvspProtocol.h) - */ - #ifndef __HV_NET_VSC_H__ #define __HV_NET_VSC_H__ @@ -64,224 +57,5 @@ #include -#define HN_USE_TXDESC_BUFRING - -/* - * The following arguably belongs in a separate header file - */ - -/* - * Defines - */ - -#define NETVSC_SEND_BUFFER_SIZE (1024*1024*15) /* 15M */ - -#define NETVSC_RECEIVE_BUFFER_SIZE_LEGACY (1024*1024*15) /* 15MB */ -#define NETVSC_RECEIVE_BUFFER_SIZE (1024*1024*16) /* 16MB */ - -/* - * Maximum MTU we permit to be configured for a netvsc interface. - * When the code was developed, a max MTU of 12232 was tested and - * proven to work. 9K is a reasonable maximum for an Ethernet. - */ -#define NETVSC_MAX_CONFIGURABLE_MTU (9 * 1024) - -#define NETVSC_PACKET_SIZE PAGE_SIZE - -/* - * Data types - */ - -struct vmbus_channel; - -#define NETVSC_DEVICE_RING_BUFFER_SIZE (128 * PAGE_SIZE) -#define NETVSC_PACKET_MAXPAGE 32 - -#define HN_XACT_REQ_PGCNT 2 -#define HN_XACT_RESP_PGCNT 2 -#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE) -#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE) - -struct hn_txdesc; -#ifndef HN_USE_TXDESC_BUFRING -SLIST_HEAD(hn_txdesc_list, hn_txdesc); -#else -struct buf_ring; -#endif - -struct hn_tx_ring; - -struct hn_rx_ring { - struct ifnet *hn_ifp; - struct hn_tx_ring *hn_txr; - void *hn_rdbuf; - uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */ - int hn_rx_idx; - - /* Trust csum verification on host side */ - int hn_trust_hcsum; /* HN_TRUST_HCSUM_ */ - struct lro_ctrl hn_lro; - - u_long hn_csum_ip; - u_long hn_csum_tcp; - u_long hn_csum_udp; - u_long hn_csum_trusted; - u_long hn_lro_tried; - u_long hn_small_pkts; - u_long hn_pkts; - u_long hn_rss_pkts; - - /* Rarely used stuffs */ - struct sysctl_oid *hn_rx_sysctl_tree; - int hn_rx_flags; - - void *hn_br; /* TX/RX bufring */ - struct hyperv_dma hn_br_dma; -} __aligned(CACHE_LINE_SIZE); - -#define HN_TRUST_HCSUM_IP 0x0001 -#define HN_TRUST_HCSUM_TCP 0x0002 -#define HN_TRUST_HCSUM_UDP 0x0004 - -#define HN_RX_FLAG_ATTACHED 0x1 - -struct hn_tx_ring { -#ifndef HN_USE_TXDESC_BUFRING - struct mtx hn_txlist_spin; - struct hn_txdesc_list hn_txlist; -#else - struct buf_ring *hn_txdesc_br; -#endif - int hn_txdesc_cnt; - int hn_txdesc_avail; - u_short hn_has_txeof; - u_short hn_txdone_cnt; - - int hn_sched_tx; - void (*hn_txeof)(struct hn_tx_ring *); - struct taskqueue *hn_tx_taskq; - struct task hn_tx_task; - struct task hn_txeof_task; - - struct buf_ring *hn_mbuf_br; - int hn_oactive; - int hn_tx_idx; - int hn_tx_flags; - - struct mtx hn_tx_lock; - struct hn_softc *hn_sc; - struct vmbus_channel *hn_chan; - - int hn_direct_tx_size; - int hn_chim_size; - bus_dma_tag_t hn_tx_data_dtag; - uint64_t hn_csum_assist; - - int (*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *); - int hn_suspended; - int hn_gpa_cnt; - struct vmbus_gpa hn_gpa[NETVSC_PACKET_MAXPAGE]; - - u_long hn_no_txdescs; - u_long hn_send_failed; - u_long hn_txdma_failed; - u_long hn_tx_collapsed; - u_long hn_tx_chimney_tried; - u_long hn_tx_chimney; - u_long hn_pkts; - - /* Rarely used stuffs */ - struct hn_txdesc *hn_txdesc; - bus_dma_tag_t hn_tx_rndis_dtag; - struct sysctl_oid *hn_tx_sysctl_tree; -} __aligned(CACHE_LINE_SIZE); - -#define HN_TX_FLAG_ATTACHED 0x1 -#define HN_TX_FLAG_HASHVAL 0x2 /* support HASHVAL pktinfo */ - -/* - * Device-specific softc structure - */ -struct hn_softc { - struct ifnet *hn_ifp; - struct ifmedia hn_media; - device_t hn_dev; - int hn_if_flags; - struct sx hn_lock; - struct vmbus_channel *hn_prichan; - - int hn_rx_ring_cnt; - int hn_rx_ring_inuse; - struct hn_rx_ring *hn_rx_ring; - - int hn_tx_ring_cnt; - int hn_tx_ring_inuse; - struct hn_tx_ring *hn_tx_ring; - - uint8_t *hn_chim; - u_long *hn_chim_bmap; - int hn_chim_bmap_cnt; - int hn_chim_cnt; - int hn_chim_szmax; - - int hn_cpu; - struct taskqueue *hn_tx_taskq; - struct sysctl_oid *hn_tx_sysctl_tree; - struct sysctl_oid *hn_rx_sysctl_tree; - struct vmbus_xact_ctx *hn_xact; - uint32_t hn_nvs_ver; - uint32_t hn_rx_filter; - - struct taskqueue *hn_mgmt_taskq; - struct taskqueue *hn_mgmt_taskq0; - struct task hn_link_task; - struct task hn_netchg_init; - struct timeout_task hn_netchg_status; - uint32_t hn_link_flags; /* HN_LINK_FLAG_ */ - - uint32_t hn_caps; /* HN_CAP_ */ - uint32_t hn_flags; /* HN_FLAG_ */ - void *hn_rxbuf; - uint32_t hn_rxbuf_gpadl; - struct hyperv_dma hn_rxbuf_dma; - - uint32_t hn_chim_gpadl; - struct hyperv_dma hn_chim_dma; - - uint32_t hn_rndis_rid; - uint32_t hn_ndis_ver; - int hn_ndis_tso_szmax; - int hn_ndis_tso_sgmin; - - int hn_rss_ind_size; - uint32_t hn_rss_hash; /* NDIS_HASH_ */ - struct ndis_rssprm_toeplitz hn_rss; -}; - -#define HN_FLAG_RXBUF_CONNECTED 0x0001 -#define HN_FLAG_CHIM_CONNECTED 0x0002 -#define HN_FLAG_HAS_RSSKEY 0x0004 -#define HN_FLAG_HAS_RSSIND 0x0008 -#define HN_FLAG_SYNTH_ATTACHED 0x0010 - -#define HN_CAP_VLAN 0x0001 -#define HN_CAP_MTU 0x0002 -#define HN_CAP_IPCS 0x0004 -#define HN_CAP_TCP4CS 0x0008 -#define HN_CAP_TCP6CS 0x0010 -#define HN_CAP_UDP4CS 0x0020 -#define HN_CAP_UDP6CS 0x0040 -#define HN_CAP_TSO4 0x0080 -#define HN_CAP_TSO6 0x0100 -#define HN_CAP_HASHVAL 0x0200 - -/* Capability description for use with printf(9) %b identifier. */ -#define HN_CAP_BITS \ - "\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS" \ - "\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL" - -#define HN_LINK_FLAG_LINKUP 0x0001 -#define HN_LINK_FLAG_NETCHG 0x0002 - #endif /* __HV_NET_VSC_H__ */ diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 1314f63b9057..655255982333 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -91,6 +92,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -116,11 +118,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include +#include +#include +#include #include #include -#include #include "vmbus_if.h" @@ -155,7 +160,7 @@ __FBSDID("$FreeBSD$"); #define HN_TX_DATA_MAXSIZE IP_MAXPACKET #define HN_TX_DATA_SEGSIZE PAGE_SIZE /* -1 for RNDIS packet message */ -#define HN_TX_DATA_SEGCNT_MAX (NETVSC_PACKET_MAXPAGE - 1) +#define HN_TX_DATA_SEGCNT_MAX (HN_GPACNT_MAX - 1) #define HN_DIRECT_TX_SIZE_DEF 128 @@ -1855,7 +1860,7 @@ hn_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { case SIOCSIFMTU: - if (ifr->ifr_mtu > NETVSC_MAX_CONFIGURABLE_MTU) { + if (ifr->ifr_mtu > HN_MTU_MAX) { error = EINVAL; break; } @@ -2631,7 +2636,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) * may further limit the usable space. */ sc->hn_rxbuf = hyperv_dmamem_alloc(bus_get_dma_tag(dev), - PAGE_SIZE, 0, NETVSC_RECEIVE_BUFFER_SIZE, &sc->hn_rxbuf_dma, + PAGE_SIZE, 0, HN_RXBUF_SIZE, &sc->hn_rxbuf_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); if (sc->hn_rxbuf == NULL) { device_printf(sc->hn_dev, "allocate rxbuf failed\n"); @@ -2665,9 +2670,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) struct hn_rx_ring *rxr = &sc->hn_rx_ring[i]; rxr->hn_br = hyperv_dmamem_alloc(bus_get_dma_tag(dev), - PAGE_SIZE, 0, - NETVSC_DEVICE_RING_BUFFER_SIZE + - NETVSC_DEVICE_RING_BUFFER_SIZE, + PAGE_SIZE, 0, HN_TXBR_SIZE + HN_RXBR_SIZE, &rxr->hn_br_dma, BUS_DMA_WAITOK); if (rxr->hn_br == NULL) { device_printf(dev, "allocate bufring failed\n"); @@ -2683,7 +2686,7 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) rxr->hn_ifp = sc->hn_ifp; if (i < sc->hn_tx_ring_cnt) rxr->hn_txr = &sc->hn_tx_ring[i]; - rxr->hn_rdbuf = malloc(NETVSC_PACKET_SIZE, M_DEVBUF, M_WAITOK); + rxr->hn_pktbuf = malloc(HN_PKTBUF_LEN, M_DEVBUF, M_WAITOK); rxr->hn_rx_idx = i; rxr->hn_rxbuf = sc->hn_rxbuf; @@ -2830,7 +2833,7 @@ hn_destroy_rx_data(struct hn_softc *sc) #if defined(INET) || defined(INET6) tcp_lro_free(&rxr->hn_lro); #endif - free(rxr->hn_rdbuf, M_DEVBUF); + free(rxr->hn_pktbuf, M_DEVBUF); } free(sc->hn_rx_ring, M_DEVBUF); sc->hn_rx_ring = NULL; @@ -3090,7 +3093,7 @@ hn_create_tx_data(struct hn_softc *sc, int ring_cnt) * NOTE: It is shared by all channels. */ sc->hn_chim = hyperv_dmamem_alloc(bus_get_dma_tag(sc->hn_dev), - PAGE_SIZE, 0, NETVSC_SEND_BUFFER_SIZE, &sc->hn_chim_dma, + PAGE_SIZE, 0, HN_CHIM_SIZE, &sc->hn_chim_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO); if (sc->hn_chim == NULL) { device_printf(sc->hn_dev, "allocate txbuf failed\n"); @@ -3508,8 +3511,8 @@ hn_chan_attach(struct hn_softc *sc, struct vmbus_channel *chan) */ cbr.cbr = rxr->hn_br; cbr.cbr_paddr = rxr->hn_br_dma.hv_paddr; - cbr.cbr_txsz = NETVSC_DEVICE_RING_BUFFER_SIZE; - cbr.cbr_rxsz = NETVSC_DEVICE_RING_BUFFER_SIZE; + cbr.cbr_txsz = HN_TXBR_SIZE; + cbr.cbr_rxsz = HN_RXBR_SIZE; error = vmbus_chan_open_br(chan, &cbr, NULL, 0, hn_chan_callback, rxr); if (error) { if_printf(sc->hn_ifp, "open chan%u failed: %d\n", @@ -4126,7 +4129,7 @@ hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr, ofs = pkt->cp_rxbuf[i].rb_ofs; len = pkt->cp_rxbuf[i].rb_len; - if (__predict_false(ofs + len > NETVSC_RECEIVE_BUFFER_SIZE)) { + if (__predict_false(ofs + len > HN_RXBUF_SIZE)) { if_printf(rxr->hn_ifp, "%dth RNDIS msg overflow rxbuf, " "ofs %d, len %d\n", i, ofs, len); continue; @@ -4181,9 +4184,9 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) struct hn_rx_ring *rxr = xrxr; struct hn_softc *sc = rxr->hn_ifp->if_softc; void *buffer; - int bufferlen = NETVSC_PACKET_SIZE; + int bufferlen = HN_PKTBUF_LEN; - buffer = rxr->hn_rdbuf; + buffer = rxr->hn_pktbuf; do { struct vmbus_chanpkt_hdr *pkt = buffer; uint32_t bytes_rxed; @@ -4210,7 +4213,7 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) } } else if (ret == ENOBUFS) { /* Handle large packet */ - if (bufferlen > NETVSC_PACKET_SIZE) { + if (bufferlen > HN_PKTBUF_LEN) { free(buffer, M_DEVBUF); buffer = NULL; } @@ -4231,7 +4234,7 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) } } while (1); - if (bufferlen > NETVSC_PACKET_SIZE) + if (bufferlen > HN_PKTBUF_LEN) free(buffer, M_DEVBUF); hv_rf_channel_rollup(rxr, rxr->hn_txr); diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 5f01d6c97688..23b126789e52 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -29,14 +29,30 @@ #ifndef _IF_HNVAR_H_ #define _IF_HNVAR_H_ -#include +#define HN_USE_TXDESC_BUFRING -#include -#include +#define HN_CHIM_SIZE (15 * 1024 * 1024) -struct hn_softc; +#define HN_RXBUF_SIZE (16 * 1024 * 1024) +#define HN_RXBUF_SIZE_COMPAT (15 * 1024 * 1024) + +/* Claimed to be 12232B */ +#define HN_MTU_MAX (9 * 1024) + +#define HN_PKTBUF_LEN 4096 + +#define HN_TXBR_SIZE (128 * PAGE_SIZE) +#define HN_RXBR_SIZE (128 * PAGE_SIZE) + +#define HN_XACT_REQ_PGCNT 2 +#define HN_XACT_RESP_PGCNT 2 +#define HN_XACT_REQ_SIZE (HN_XACT_REQ_PGCNT * PAGE_SIZE) +#define HN_XACT_RESP_SIZE (HN_XACT_RESP_PGCNT * PAGE_SIZE) + +#define HN_GPACNT_MAX 32 struct vmbus_channel; +struct hn_softc; struct hn_send_ctx; typedef void (*hn_sent_callback_t) @@ -48,6 +64,12 @@ struct hn_send_ctx { void *hn_cbarg; }; +#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ +{ \ + .hn_cb = cb, \ + .hn_cbarg = cbarg \ +} + #define HN_NDIS_VLAN_INFO_INVALID 0xffffffff #define HN_NDIS_RXCSUM_INFO_INVALID 0 #define HN_NDIS_HASH_INFO_INVALID 0 @@ -59,11 +81,185 @@ struct hn_recvinfo { uint32_t hash_value; }; -#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ -{ \ - .hn_cb = cb, \ - .hn_cbarg = cbarg \ -} +struct hn_txdesc; +#ifndef HN_USE_TXDESC_BUFRING +SLIST_HEAD(hn_txdesc_list, hn_txdesc); +#else +struct buf_ring; +#endif +struct hn_tx_ring; + +struct hn_rx_ring { + struct ifnet *hn_ifp; + struct hn_tx_ring *hn_txr; + void *hn_pktbuf; + uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */ + int hn_rx_idx; + + /* Trust csum verification on host side */ + int hn_trust_hcsum; /* HN_TRUST_HCSUM_ */ + struct lro_ctrl hn_lro; + + u_long hn_csum_ip; + u_long hn_csum_tcp; + u_long hn_csum_udp; + u_long hn_csum_trusted; + u_long hn_lro_tried; + u_long hn_small_pkts; + u_long hn_pkts; + u_long hn_rss_pkts; + + /* Rarely used stuffs */ + struct sysctl_oid *hn_rx_sysctl_tree; + int hn_rx_flags; + + void *hn_br; /* TX/RX bufring */ + struct hyperv_dma hn_br_dma; +} __aligned(CACHE_LINE_SIZE); + +#define HN_TRUST_HCSUM_IP 0x0001 +#define HN_TRUST_HCSUM_TCP 0x0002 +#define HN_TRUST_HCSUM_UDP 0x0004 + +#define HN_RX_FLAG_ATTACHED 0x1 + +struct hn_tx_ring { +#ifndef HN_USE_TXDESC_BUFRING + struct mtx hn_txlist_spin; + struct hn_txdesc_list hn_txlist; +#else + struct buf_ring *hn_txdesc_br; +#endif + int hn_txdesc_cnt; + int hn_txdesc_avail; + u_short hn_has_txeof; + u_short hn_txdone_cnt; + + int hn_sched_tx; + void (*hn_txeof)(struct hn_tx_ring *); + struct taskqueue *hn_tx_taskq; + struct task hn_tx_task; + struct task hn_txeof_task; + + struct buf_ring *hn_mbuf_br; + int hn_oactive; + int hn_tx_idx; + int hn_tx_flags; + + struct mtx hn_tx_lock; + struct hn_softc *hn_sc; + struct vmbus_channel *hn_chan; + + int hn_direct_tx_size; + int hn_chim_size; + bus_dma_tag_t hn_tx_data_dtag; + uint64_t hn_csum_assist; + + int (*hn_sendpkt)(struct hn_tx_ring *, struct hn_txdesc *); + int hn_suspended; + int hn_gpa_cnt; + struct vmbus_gpa hn_gpa[HN_GPACNT_MAX]; + + u_long hn_no_txdescs; + u_long hn_send_failed; + u_long hn_txdma_failed; + u_long hn_tx_collapsed; + u_long hn_tx_chimney_tried; + u_long hn_tx_chimney; + u_long hn_pkts; + + /* Rarely used stuffs */ + struct hn_txdesc *hn_txdesc; + bus_dma_tag_t hn_tx_rndis_dtag; + struct sysctl_oid *hn_tx_sysctl_tree; +} __aligned(CACHE_LINE_SIZE); + +#define HN_TX_FLAG_ATTACHED 0x1 +#define HN_TX_FLAG_HASHVAL 0x2 /* support HASHVAL pktinfo */ + +/* + * Device-specific softc structure + */ +struct hn_softc { + struct ifnet *hn_ifp; + struct ifmedia hn_media; + device_t hn_dev; + int hn_if_flags; + struct sx hn_lock; + struct vmbus_channel *hn_prichan; + + int hn_rx_ring_cnt; + int hn_rx_ring_inuse; + struct hn_rx_ring *hn_rx_ring; + + int hn_tx_ring_cnt; + int hn_tx_ring_inuse; + struct hn_tx_ring *hn_tx_ring; + + uint8_t *hn_chim; + u_long *hn_chim_bmap; + int hn_chim_bmap_cnt; + int hn_chim_cnt; + int hn_chim_szmax; + + int hn_cpu; + struct taskqueue *hn_tx_taskq; + struct sysctl_oid *hn_tx_sysctl_tree; + struct sysctl_oid *hn_rx_sysctl_tree; + struct vmbus_xact_ctx *hn_xact; + uint32_t hn_nvs_ver; + uint32_t hn_rx_filter; + + struct taskqueue *hn_mgmt_taskq; + struct taskqueue *hn_mgmt_taskq0; + struct task hn_link_task; + struct task hn_netchg_init; + struct timeout_task hn_netchg_status; + uint32_t hn_link_flags; /* HN_LINK_FLAG_ */ + + uint32_t hn_caps; /* HN_CAP_ */ + uint32_t hn_flags; /* HN_FLAG_ */ + void *hn_rxbuf; + uint32_t hn_rxbuf_gpadl; + struct hyperv_dma hn_rxbuf_dma; + + uint32_t hn_chim_gpadl; + struct hyperv_dma hn_chim_dma; + + uint32_t hn_rndis_rid; + uint32_t hn_ndis_ver; + int hn_ndis_tso_szmax; + int hn_ndis_tso_sgmin; + + int hn_rss_ind_size; + uint32_t hn_rss_hash; /* NDIS_HASH_ */ + struct ndis_rssprm_toeplitz hn_rss; +}; + +#define HN_FLAG_RXBUF_CONNECTED 0x0001 +#define HN_FLAG_CHIM_CONNECTED 0x0002 +#define HN_FLAG_HAS_RSSKEY 0x0004 +#define HN_FLAG_HAS_RSSIND 0x0008 +#define HN_FLAG_SYNTH_ATTACHED 0x0010 + +#define HN_CAP_VLAN 0x0001 +#define HN_CAP_MTU 0x0002 +#define HN_CAP_IPCS 0x0004 +#define HN_CAP_TCP4CS 0x0008 +#define HN_CAP_TCP6CS 0x0010 +#define HN_CAP_UDP4CS 0x0020 +#define HN_CAP_UDP6CS 0x0040 +#define HN_CAP_TSO4 0x0080 +#define HN_CAP_TSO6 0x0100 +#define HN_CAP_HASHVAL 0x0200 + +/* Capability description for use with printf(9) %b identifier. */ +#define HN_CAP_BITS \ + "\020\1VLAN\2MTU\3IPCS\4TCP4CS\5TCP6CS" \ + "\6UDP4CS\7UDP6CS\10TSO4\11TSO6\12HASHVAL" + +#define HN_LINK_FLAG_LINKUP 0x0001 +#define HN_LINK_FLAG_NETCHG 0x0002 static __inline void hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, void *cbarg) From e3946ae44ada2604841dbf3f686f833b164be2a2 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 05:26:04 +0000 Subject: [PATCH 145/235] hyperv/hn: Move send context to NVS domain. Since all sends are encapsulated in NVS messages. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8346 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 41 ++++++--- sys/dev/hyperv/netvsc/hv_net_vsc.h | 87 ++++++++++++++----- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 36 ++------ sys/dev/hyperv/netvsc/hv_rndis_filter.c | 34 ++++---- sys/dev/hyperv/netvsc/if_hnvar.h | 57 ------------ 5 files changed, 119 insertions(+), 136 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 0de7901920a6..e4570c816c75 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -39,18 +39,24 @@ #include #include #include +#include + #include #include -#include -#include -#include +#include + +#include +#include #include +#include +#include #include -#include -#include + +#include #include #include +#include /* * Forward declarations @@ -59,12 +65,12 @@ static int hn_nvs_conn_chim(struct hn_softc *sc); static int hn_nvs_conn_rxbuf(struct hn_softc *); static int hn_nvs_disconn_chim(struct hn_softc *sc); static int hn_nvs_disconn_rxbuf(struct hn_softc *sc); -static void hn_nvs_sent_none(struct hn_send_ctx *sndc, +static void hn_nvs_sent_none(struct hn_nvs_sendctx *sndc, struct hn_softc *, struct vmbus_channel *chan, const void *, int); -struct hn_send_ctx hn_send_ctx_none = - HN_SEND_CTX_INITIALIZER(hn_nvs_sent_none, NULL); +struct hn_nvs_sendctx hn_nvs_sendctx_none = + HN_NVS_SENDCTX_INITIALIZER(hn_nvs_sent_none, NULL); static const uint32_t hn_nvs_version[] = { HN_NVS_VERSION_5, @@ -77,7 +83,7 @@ static const void * hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, void *req, int reqlen, size_t *resplen0, uint32_t type) { - struct hn_send_ctx sndc; + struct hn_nvs_sendctx sndc; size_t resplen, min_resplen = *resplen0; const struct hn_nvs_hdr *hdr; int error; @@ -88,7 +94,7 @@ hn_nvs_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, /* * Execute the xact setup by the caller. */ - hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact); + hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact); vmbus_xact_activate(xact); error = hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_RC, @@ -121,7 +127,7 @@ hn_nvs_req_send(struct hn_softc *sc, void *req, int reqlen) { return (hn_nvs_send(sc->hn_prichan, VMBUS_CHANPKT_FLAG_NONE, - req, reqlen, &hn_send_ctx_none)); + req, reqlen, &hn_nvs_sendctx_none)); } static int @@ -604,7 +610,7 @@ hn_nvs_detach(struct hn_softc *sc) } void -hn_nvs_sent_xact(struct hn_send_ctx *sndc, +hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc, struct hn_softc *sc __unused, struct vmbus_channel *chan __unused, const void *data, int dlen) { @@ -613,7 +619,7 @@ hn_nvs_sent_xact(struct hn_send_ctx *sndc, } static void -hn_nvs_sent_none(struct hn_send_ctx *sndc __unused, +hn_nvs_sent_none(struct hn_nvs_sendctx *sndc __unused, struct hn_softc *sc __unused, struct vmbus_channel *chan __unused, const void *data __unused, int dlen __unused) { @@ -670,3 +676,12 @@ hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch0) vmbus_xact_put(xact); return (error); } + +int +hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, + struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) +{ + + return hn_nvs_send_rndis_sglist(chan, HN_NVS_RNDIS_MTYPE_CTRL, + sndc, gpa, gpa_cnt); +} diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 17d93fa9c202..037d7f1f0a88 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -31,31 +31,76 @@ #ifndef __HV_NET_VSC_H__ #define __HV_NET_VSC_H__ -#include -#include -#include -#include -#include -#include -#include -#include +struct hn_nvs_sendctx; +struct vmbus_channel; +struct hn_softc; -#include -#include -#include +typedef void (*hn_nvs_sent_t) + (struct hn_nvs_sendctx *, struct hn_softc *, + struct vmbus_channel *, const void *, int); -#include -#include +struct hn_nvs_sendctx { + hn_nvs_sent_t hn_cb; + void *hn_cbarg; +}; -#include -#include -#include +#define HN_NVS_SENDCTX_INITIALIZER(cb, cbarg) \ +{ \ + .hn_cb = cb, \ + .hn_cbarg = cbarg \ +} -#include -#include -#include +static __inline void +hn_nvs_sendctx_init(struct hn_nvs_sendctx *sndc, hn_nvs_sent_t cb, void *cbarg) +{ -#include + sndc->hn_cb = cb; + sndc->hn_cbarg = cbarg; +} + +static __inline int +hn_nvs_send(struct vmbus_channel *chan, uint16_t flags, + void *nvs_msg, int nvs_msglen, struct hn_nvs_sendctx *sndc) +{ + + return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags, + nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc)); +} + +static __inline int +hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, + void *nvs_msg, int nvs_msglen, struct hn_nvs_sendctx *sndc) +{ + + return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen, + (uint64_t)(uintptr_t)sndc)); +} + +static __inline int +hn_nvs_send_rndis_sglist(struct vmbus_channel *chan, uint32_t rndis_mtype, + struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) +{ + struct hn_nvs_rndis rndis; + + rndis.nvs_type = HN_NVS_TYPE_RNDIS; + rndis.nvs_rndis_mtype = rndis_mtype; + rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID; + rndis.nvs_chim_sz = 0; + + return (hn_nvs_send_sglist(chan, gpa, gpa_cnt, + &rndis, sizeof(rndis), sndc)); +} + +int hn_nvs_attach(struct hn_softc *sc, int mtu); +void hn_nvs_detach(struct hn_softc *sc); +int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch); +void hn_nvs_sent_xact(struct hn_nvs_sendctx *sndc, + struct hn_softc *sc, struct vmbus_channel *chan, + const void *data, int dlen); +int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, + struct hn_nvs_sendctx *sndc, struct vmbus_gpa *gpa, + int gpa_cnt); + +extern struct hn_nvs_sendctx hn_nvs_sendctx_none; #endif /* __HV_NET_VSC_H__ */ - diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 655255982333..df3822031a5b 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -174,7 +174,7 @@ struct hn_txdesc { struct hn_tx_ring *txr; int refs; uint32_t flags; /* HN_TXD_FLAG_ */ - struct hn_send_ctx send_ctx; + struct hn_nvs_sendctx send_ctx; uint32_t chim_index; int chim_size; @@ -412,37 +412,13 @@ hn_set_lro_lenlim(struct hn_softc *sc, int lenlim) } #endif -static __inline int -hn_nvs_send_rndis_sglist1(struct vmbus_channel *chan, uint32_t rndis_mtype, - struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) -{ - struct hn_nvs_rndis rndis; - - rndis.nvs_type = HN_NVS_TYPE_RNDIS; - rndis.nvs_rndis_mtype = rndis_mtype; - rndis.nvs_chim_idx = HN_NVS_CHIM_IDX_INVALID; - rndis.nvs_chim_sz = 0; - - return (hn_nvs_send_sglist(chan, gpa, gpa_cnt, - &rndis, sizeof(rndis), sndc)); -} - -int -hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, - struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, int gpa_cnt) -{ - - return hn_nvs_send_rndis_sglist1(chan, HN_NVS_RNDIS_MTYPE_CTRL, - sndc, gpa, gpa_cnt); -} - static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *txr, struct hn_txdesc *txd) { KASSERT(txd->chim_index == HN_NVS_CHIM_IDX_INVALID && txd->chim_size == 0, ("invalid rndis sglist txd")); - return (hn_nvs_send_rndis_sglist1(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA, + return (hn_nvs_send_rndis_sglist(txr->hn_chan, HN_NVS_RNDIS_MTYPE_DATA, &txd->send_ctx, txr->hn_gpa, txr->hn_gpa_cnt)); } @@ -1190,7 +1166,7 @@ hn_txeof(struct hn_tx_ring *txr) } static void -hn_tx_done(struct hn_send_ctx *sndc, struct hn_softc *sc, +hn_tx_done(struct hn_nvs_sendctx *sndc, struct hn_softc *sc, struct vmbus_channel *chan, const void *data __unused, int dlen __unused) { struct hn_txdesc *txd = sndc->hn_cbarg; @@ -1429,7 +1405,7 @@ hn_encap(struct hn_tx_ring *txr, struct hn_txdesc *txd, struct mbuf **m_head0) txd->m = m_head; /* Set the completion routine */ - hn_send_ctx_init(&txd->send_ctx, hn_tx_done, txd); + hn_nvs_sendctx_init(&txd->send_ctx, hn_tx_done, txd); return 0; } @@ -4070,9 +4046,9 @@ static void hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt) { - struct hn_send_ctx *sndc; + struct hn_nvs_sendctx *sndc; - sndc = (struct hn_send_ctx *)(uintptr_t)pkt->cph_xactid; + sndc = (struct hn_nvs_sendctx *)(uintptr_t)pkt->cph_xactid; sndc->hn_cb(sndc, sc, chan, VMBUS_CHANPKT_CONST_DATA(pkt), VMBUS_CHANPKT_DATALEN(pkt)); /* diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index b0bed94289b1..dead3a3f3826 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -34,26 +34,30 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include +#include + +#include + #include +#include +#include +#include #include + #include #include -#include -#include -#include -#include -#include -#include +#include #include +#include +#include #include + +#include +#include +#include #include #include -#include -#include #define HV_RF_RECVINFO_VLAN 0x1 #define HV_RF_RECVINFO_CSUM 0x2 @@ -549,7 +553,7 @@ hn_rndis_get_linkstatus(struct hn_softc *sc, uint32_t *link_status) static const void * hn_rndis_xact_exec1(struct hn_softc *sc, struct vmbus_xact *xact, size_t reqlen, - struct hn_send_ctx *sndc, size_t *comp_len) + struct hn_nvs_sendctx *sndc, size_t *comp_len) { struct vmbus_gpa gpa[HN_XACT_REQ_PGCNT]; int gpa_cnt, error; @@ -608,7 +612,7 @@ hn_rndis_xact_execute(struct hn_softc *sc, struct vmbus_xact *xact, uint32_t rid /* * Execute the xact setup by the caller. */ - comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_send_ctx_none, + comp = hn_rndis_xact_exec1(sc, xact, reqlen, &hn_nvs_sendctx_none, &comp_len); if (comp == NULL) return (NULL); @@ -1214,7 +1218,7 @@ hn_rndis_halt(struct hn_softc *sc) { struct vmbus_xact *xact; struct rndis_halt_req *halt; - struct hn_send_ctx sndc; + struct hn_nvs_sendctx sndc; size_t comp_len; xact = vmbus_xact_get(sc->hn_xact, sizeof(*halt)); @@ -1228,7 +1232,7 @@ hn_rndis_halt(struct hn_softc *sc) halt->rm_rid = hn_rndis_rid(sc); /* No RNDIS completion; rely on NVS message send completion */ - hn_send_ctx_init(&sndc, hn_nvs_sent_xact, xact); + hn_nvs_sendctx_init(&sndc, hn_nvs_sent_xact, xact); hn_rndis_xact_exec1(sc, xact, sizeof(*halt), &sndc, &comp_len); vmbus_xact_put(xact); diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 23b126789e52..a22197a138d1 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -51,25 +51,6 @@ #define HN_GPACNT_MAX 32 -struct vmbus_channel; -struct hn_softc; -struct hn_send_ctx; - -typedef void (*hn_sent_callback_t) - (struct hn_send_ctx *, struct hn_softc *, - struct vmbus_channel *, const void *, int); - -struct hn_send_ctx { - hn_sent_callback_t hn_cb; - void *hn_cbarg; -}; - -#define HN_SEND_CTX_INITIALIZER(cb, cbarg) \ -{ \ - .hn_cb = cb, \ - .hn_cbarg = cbarg \ -} - #define HN_NDIS_VLAN_INFO_INVALID 0xffffffff #define HN_NDIS_RXCSUM_INFO_INVALID 0 #define HN_NDIS_HASH_INFO_INVALID 0 @@ -261,33 +242,6 @@ struct hn_softc { #define HN_LINK_FLAG_LINKUP 0x0001 #define HN_LINK_FLAG_NETCHG 0x0002 -static __inline void -hn_send_ctx_init(struct hn_send_ctx *sndc, hn_sent_callback_t cb, void *cbarg) -{ - - sndc->hn_cb = cb; - sndc->hn_cbarg = cbarg; -} - -static __inline int -hn_nvs_send(struct vmbus_channel *chan, uint16_t flags, - void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc) -{ - - return (vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, flags, - nvs_msg, nvs_msglen, (uint64_t)(uintptr_t)sndc)); -} - -static __inline int -hn_nvs_send_sglist(struct vmbus_channel *chan, struct vmbus_gpa sg[], int sglen, - void *nvs_msg, int nvs_msglen, struct hn_send_ctx *sndc) -{ - - return (vmbus_chan_send_sglist(chan, sg, sglen, nvs_msg, nvs_msglen, - (uint64_t)(uintptr_t)sndc)); -} - -struct vmbus_xact; struct rndis_packet_msg; int hn_rndis_attach(struct hn_softc *sc, int mtu); @@ -302,21 +256,10 @@ int hn_rndis_get_linkstatus(struct hn_softc *sc, /* filter: NDIS_PACKET_TYPE_. */ int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); -int hn_nvs_attach(struct hn_softc *sc, int mtu); -void hn_nvs_detach(struct hn_softc *sc); -int hn_nvs_alloc_subchans(struct hn_softc *sc, int *nsubch); -void hn_nvs_sent_xact(struct hn_send_ctx *sndc, struct hn_softc *sc, - struct vmbus_channel *chan, const void *data, int dlen); -int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, - struct hn_send_ctx *sndc, struct vmbus_gpa *gpa, - int gpa_cnt); - int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_recvinfo *info); void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); void hn_link_status_update(struct hn_softc *sc); void hn_network_change(struct hn_softc *sc); -extern struct hn_send_ctx hn_send_ctx_none; - #endif /* !_IF_HNVAR_H_ */ From 2ae974568d0b7fd41c49bdae76478e983756ad96 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 27 Oct 2016 05:33:48 +0000 Subject: [PATCH 146/235] hyperv/hn: NVS inclusion cleanup and forward declare functions. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8347 --- sys/dev/hyperv/netvsc/hv_net_vsc.c | 42 +++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index e4570c816c75..657c90b61236 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -24,21 +24,23 @@ * 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$ */ -/** - * HyperV vmbus network VSC (virtual services client) module - * +/* + * Network Virtualization Service. */ +#include +__FBSDID("$FreeBSD$"); + +#include "opt_inet6.h" +#include "opt_inet.h" #include #include -#include #include -#include +#include +#include #include #include @@ -58,18 +60,22 @@ #include #include -/* - * Forward declarations - */ -static int hn_nvs_conn_chim(struct hn_softc *sc); -static int hn_nvs_conn_rxbuf(struct hn_softc *); -static int hn_nvs_disconn_chim(struct hn_softc *sc); -static int hn_nvs_disconn_rxbuf(struct hn_softc *sc); -static void hn_nvs_sent_none(struct hn_nvs_sendctx *sndc, - struct hn_softc *, struct vmbus_channel *chan, - const void *, int); +static int hn_nvs_conn_chim(struct hn_softc *); +static int hn_nvs_conn_rxbuf(struct hn_softc *); +static int hn_nvs_disconn_chim(struct hn_softc *); +static int hn_nvs_disconn_rxbuf(struct hn_softc *); +static int hn_nvs_conf_ndis(struct hn_softc *, int); +static int hn_nvs_init_ndis(struct hn_softc *); +static int hn_nvs_doinit(struct hn_softc *, uint32_t); +static int hn_nvs_init(struct hn_softc *); +static const void *hn_nvs_xact_execute(struct hn_softc *, + struct vmbus_xact *, void *, int, + size_t *, uint32_t); +static void hn_nvs_sent_none(struct hn_nvs_sendctx *, + struct hn_softc *, struct vmbus_channel *, + const void *, int); -struct hn_nvs_sendctx hn_nvs_sendctx_none = +struct hn_nvs_sendctx hn_nvs_sendctx_none = HN_NVS_SENDCTX_INITIALIZER(hn_nvs_sent_none, NULL); static const uint32_t hn_nvs_version[] = { From 0a682531f4904fc97d172234557fdd02dd495032 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Thu, 27 Oct 2016 07:11:31 +0000 Subject: [PATCH 147/235] 3746 ZRLs are racy illumos/illumos-gate@260af64db74a52d64de8c6c5f67dd0a71d228ca5 https://github.com/illumos/illumos-gate/commit/260af64db74a52d64de8c6c5f67dd0a71d228ca5 https://www.illumos.org/issues/3746 From the original change log: It was possible for a reference to be added even with the lock held, and for references added just after a lock release to be lost. This bug was also independently found and reported in wesunsolve.net issues 6985013 6995524. In zrl_add(), always use an atomic operation to update the refcount. The mutex in the ZRL only guarantees that wakeups occur for waiters on the lock. It offers no protection against concurrent updates of the refcount. The only refcount transition that is safe to perform without an atomic operation is from ZRL_LOCKED back to 0, since this can only be performed by the thread which has the ZRL locked. Authored by: Will Andrews Reviewed by: Boris Protopopov Reviewed by: Pavel Zakharov Reviewed by: Yuri Pankov Reviewed by: Justin T. Gibbs Approved by: Matt Ahrens Author: Youzhong Yang --- uts/common/fs/zfs/zrlock.c | 48 +++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/uts/common/fs/zfs/zrlock.c b/uts/common/fs/zfs/zrlock.c index 7f6beeed6149..ec333e54d2a8 100644 --- a/uts/common/fs/zfs/zrlock.c +++ b/uts/common/fs/zfs/zrlock.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2015 by Delphix. All rights reserved. + * Copyright 2016 The MathWorks, Inc. All rights reserved. */ /* @@ -71,37 +72,32 @@ zrl_destroy(zrlock_t *zrl) void zrl_add_impl(zrlock_t *zrl, const char *zc) { - uint32_t n = (uint32_t)zrl->zr_refcount; - - while (n != ZRL_LOCKED) { - uint32_t cas = atomic_cas_32( - (uint32_t *)&zrl->zr_refcount, n, n + 1); - if (cas == n) { - ASSERT3S((int32_t)n, >=, 0); + for (;;) { + uint32_t n = (uint32_t)zrl->zr_refcount; + while (n != ZRL_LOCKED) { + uint32_t cas = atomic_cas_32( + (uint32_t *)&zrl->zr_refcount, n, n + 1); + if (cas == n) { + ASSERT3S((int32_t)n, >=, 0); #ifdef ZFS_DEBUG - if (zrl->zr_owner == curthread) { - DTRACE_PROBE2(zrlock__reentry, - zrlock_t *, zrl, uint32_t, n); + if (zrl->zr_owner == curthread) { + DTRACE_PROBE2(zrlock__reentry, + zrlock_t *, zrl, uint32_t, n); + } + zrl->zr_owner = curthread; + zrl->zr_caller = zc; +#endif + return; } - zrl->zr_owner = curthread; - zrl->zr_caller = zc; -#endif - return; + n = cas; } - n = cas; - } - mutex_enter(&zrl->zr_mtx); - while (zrl->zr_refcount == ZRL_LOCKED) { - cv_wait(&zrl->zr_cv, &zrl->zr_mtx); + mutex_enter(&zrl->zr_mtx); + while (zrl->zr_refcount == ZRL_LOCKED) { + cv_wait(&zrl->zr_cv, &zrl->zr_mtx); + } + mutex_exit(&zrl->zr_mtx); } - ASSERT3S(zrl->zr_refcount, >=, 0); - zrl->zr_refcount++; -#ifdef ZFS_DEBUG - zrl->zr_owner = curthread; - zrl->zr_caller = zc; -#endif - mutex_exit(&zrl->zr_mtx); } void From 844a6f0c5308cc9ef487f4c07394c88f3a5f5d4c Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Thu, 27 Oct 2016 09:46:22 +0000 Subject: [PATCH 148/235] Various fixes for ptnet/ptnetmap (passthrough of netmap ports). In detail: - use PCI_VENDOR and PCI_DEVICE ids from a publicly allocated range (thanks to RedHat) - export memory pool information through PCI registers - improve mechanism for configuring passthrough on different hypervisors Code is from Vincenzo Maffione as a follow up to his GSOC work. --- sys/dev/netmap/if_ptnet.c | 29 ++-- sys/dev/netmap/netmap.c | 21 ++- sys/dev/netmap/netmap_freebsd.c | 110 +++++-------- sys/dev/netmap/netmap_kern.h | 11 +- sys/dev/netmap/netmap_mem2.c | 269 +++++++++++++------------------- sys/dev/netmap/netmap_mem2.h | 4 +- sys/dev/netmap/netmap_pt.c | 53 ++++--- sys/dev/netmap/netmap_vale.c | 2 +- sys/net/netmap.h | 26 +-- sys/net/netmap_virt.h | 173 +++++++++++--------- 10 files changed, 314 insertions(+), 384 deletions(-) diff --git a/sys/dev/netmap/if_ptnet.c b/sys/dev/netmap/if_ptnet.c index 90a90e984a5a..4c7072774df4 100644 --- a/sys/dev/netmap/if_ptnet.c +++ b/sys/dev/netmap/if_ptnet.c @@ -291,7 +291,7 @@ static inline void ptnet_kick(struct ptnet_queue *pq) static int ptnet_attach(device_t dev) { - uint32_t ptfeatures = PTNETMAP_F_BASE; + uint32_t ptfeatures = 0; unsigned int num_rx_rings, num_tx_rings; struct netmap_adapter na_arg; unsigned int nifp_offset; @@ -315,19 +315,12 @@ ptnet_attach(device_t dev) return (ENXIO); } - /* Check if we are supported by the hypervisor. If not, - * bail out immediately. */ + /* Negotiate features with the hypervisor. */ if (ptnet_vnet_hdr) { ptfeatures |= PTNETMAP_F_VNET_HDR; } bus_write_4(sc->iomem, PTNET_IO_PTFEAT, ptfeatures); /* wanted */ ptfeatures = bus_read_4(sc->iomem, PTNET_IO_PTFEAT); /* acked */ - if (!(ptfeatures & PTNETMAP_F_BASE)) { - device_printf(dev, "Hypervisor does not support netmap " - "passthorugh\n"); - err = ENXIO; - goto err_path; - } sc->ptfeatures = ptfeatures; /* Allocate CSB and carry out CSB allocation protocol (CSBBAH first, @@ -474,7 +467,8 @@ ptnet_attach(device_t dev) na_arg.nm_txsync = ptnet_nm_txsync; na_arg.nm_rxsync = ptnet_nm_rxsync; - netmap_pt_guest_attach(&na_arg, sc->csb, nifp_offset, ptnet_nm_ptctl); + netmap_pt_guest_attach(&na_arg, sc->csb, nifp_offset, + bus_read_4(sc->iomem, PTNET_IO_HOSTMEMID)); /* Now a netmap adapter for this ifp has been allocated, and it * can be accessed through NA(ifp). We also have to initialize the CSB @@ -1082,13 +1076,12 @@ static uint32_t ptnet_nm_ptctl(if_t ifp, uint32_t cmd) { struct ptnet_softc *sc = if_getsoftc(ifp); - int ret; - + /* + * Write a command and read back error status, + * with zero meaning success. + */ bus_write_4(sc->iomem, PTNET_IO_PTCTL, cmd); - ret = bus_read_4(sc->iomem, PTNET_IO_PTSTS); - device_printf(sc->dev, "PTCTL %u, ret %u\n", cmd, ret); - - return ret; + return bus_read_4(sc->iomem, PTNET_IO_PTCTL); } static int @@ -1196,7 +1189,7 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff) /* Make sure the host adapter passed through is ready * for txsync/rxsync. */ - ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_REGIF); + ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_CREATE); if (ret) { return ret; } @@ -1246,7 +1239,7 @@ ptnet_nm_register(struct netmap_adapter *na, int onoff) } if (sc->ptna->backend_regifs == 0) { - ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_UNREGIF); + ret = ptnet_nm_ptctl(ifp, PTNETMAP_PTCTL_DELETE); } } diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c index 46aca2eab5e2..15e44815accc 100644 --- a/sys/dev/netmap/netmap.c +++ b/sys/dev/netmap/netmap.c @@ -2186,7 +2186,11 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread break; case NIOCREGIF: - /* possibly attach/detach NIC and VALE switch */ + /* + * If nmr->nr_cmd is not zero, this NIOCREGIF is not really + * a regif operation, but a different one, specified by the + * value of nmr->nr_cmd. + */ i = nmr->nr_cmd; if (i == NETMAP_BDG_ATTACH || i == NETMAP_BDG_DETACH || i == NETMAP_BDG_VNET_HDR @@ -2194,12 +2198,15 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread || i == NETMAP_BDG_DELIF || i == NETMAP_BDG_POLLING_ON || i == NETMAP_BDG_POLLING_OFF) { + /* possibly attach/detach NIC and VALE switch */ error = netmap_bdg_ctl(nmr, NULL); break; } else if (i == NETMAP_PT_HOST_CREATE || i == NETMAP_PT_HOST_DELETE) { + /* forward the command to the ptnetmap subsystem */ error = ptnetmap_ctl(nmr, priv->np_na); break; } else if (i == NETMAP_VNET_HDR_GET) { + /* get vnet-header length for this netmap port */ struct ifnet *ifp; NMG_LOCK(); @@ -2210,6 +2217,10 @@ netmap_ioctl(struct netmap_priv_d *priv, u_long cmd, caddr_t data, struct thread netmap_unget_na(na, ifp); NMG_UNLOCK(); break; + } else if (i == NETMAP_POOLS_INFO_GET) { + /* get information from the memory allocator */ + error = netmap_mem_pools_info_get(nmr, priv->np_na); + break; } else if (i != 0) { D("nr_cmd must be 0 not %d", i); error = EINVAL; @@ -2873,17 +2884,15 @@ netmap_attach(struct netmap_adapter *arg) #ifdef WITH_PTNETMAP_GUEST int -netmap_pt_guest_attach(struct netmap_adapter *arg, - void *csb, - unsigned int nifp_offset, - nm_pt_guest_ptctl_t ptctl) +netmap_pt_guest_attach(struct netmap_adapter *arg, void *csb, + unsigned int nifp_offset, unsigned int memid) { struct netmap_pt_guest_adapter *ptna; struct ifnet *ifp = arg ? arg->ifp : NULL; int error; /* get allocator */ - arg->nm_mem = netmap_mem_pt_guest_new(ifp, nifp_offset, ptctl); + arg->nm_mem = netmap_mem_pt_guest_new(ifp, nifp_offset, memid); if (arg->nm_mem == NULL) return ENOMEM; arg->na_flags |= NAF_MEM_OWNER; diff --git a/sys/dev/netmap/netmap_freebsd.c b/sys/dev/netmap/netmap_freebsd.c index d83f21e255ec..2aecb53b47e4 100644 --- a/sys/dev/netmap/netmap_freebsd.c +++ b/sys/dev/netmap/netmap_freebsd.c @@ -625,19 +625,6 @@ static devclass_t ptnetmap_devclass; DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass, NULL, NULL, SI_ORDER_MIDDLE + 1); -/* - * I/O port read/write wrappers. - * Some are not used, so we keep them commented out until needed - */ -#define ptn_ioread16(ptn_dev, reg) bus_read_2((ptn_dev)->pci_io, (reg)) -#define ptn_ioread32(ptn_dev, reg) bus_read_4((ptn_dev)->pci_io, (reg)) -#if 0 -#define ptn_ioread8(ptn_dev, reg) bus_read_1((ptn_dev)->pci_io, (reg)) -#define ptn_iowrite8(ptn_dev, reg, val) bus_write_1((ptn_dev)->pci_io, (reg), (val)) -#define ptn_iowrite16(ptn_dev, reg, val) bus_write_2((ptn_dev)->pci_io, (reg), (val)) -#define ptn_iowrite32(ptn_dev, reg, val) bus_write_4((ptn_dev)->pci_io, (reg), (val)) -#endif /* unused */ - /* * Map host netmap memory through PCI-BAR in the guest OS, * returning physical (nm_paddr) and virtual (nm_addr) addresses @@ -645,19 +632,20 @@ DRIVER_MODULE_ORDERED(ptn_memdev, pci, ptn_memdev_driver, ptnetmap_devclass, */ int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr, - void **nm_addr) + void **nm_addr, uint64_t *mem_size) { - uint32_t mem_size; int rid; D("ptn_memdev_driver iomap"); rid = PCIR_BAR(PTNETMAP_MEM_PCI_BAR); - mem_size = ptn_ioread32(ptn_dev, PTNETMAP_IO_PCI_MEMSIZE); + *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_HI); + *mem_size = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMSIZE_LO) | + (*mem_size << 32); /* map memory allocator */ ptn_dev->pci_mem = bus_alloc_resource(ptn_dev->dev, SYS_RES_MEMORY, - &rid, 0, ~0, mem_size, RF_ACTIVE); + &rid, 0, ~0, *mem_size, RF_ACTIVE); if (ptn_dev->pci_mem == NULL) { *nm_paddr = 0; *nm_addr = 0; @@ -667,14 +655,20 @@ nm_os_pt_memdev_iomap(struct ptnetmap_memdev *ptn_dev, vm_paddr_t *nm_paddr, *nm_paddr = rman_get_start(ptn_dev->pci_mem); *nm_addr = rman_get_virtual(ptn_dev->pci_mem); - D("=== BAR %d start %lx len %lx mem_size %x ===", + D("=== BAR %d start %lx len %lx mem_size %lx ===", PTNETMAP_MEM_PCI_BAR, (unsigned long)(*nm_paddr), (unsigned long)rman_get_size(ptn_dev->pci_mem), - mem_size); + (unsigned long)*mem_size); return (0); } +uint32_t +nm_os_pt_memdev_ioread(struct ptnetmap_memdev *ptn_dev, unsigned int reg) +{ + return bus_read_4(ptn_dev->pci_io, reg); +} + /* Unmap host netmap memory. */ void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *ptn_dev) @@ -730,7 +724,7 @@ ptn_memdev_attach(device_t dev) return (ENXIO); } - mem_id = ptn_ioread16(ptn_dev, PTNETMAP_IO_PCI_HOSTID); + mem_id = bus_read_4(ptn_dev->pci_io, PTNET_MDEV_IO_MEMID); /* create guest allocator */ ptn_dev->nm_mem = netmap_mem_pt_guest_attach(ptn_dev, mem_id); @@ -740,7 +734,7 @@ ptn_memdev_attach(device_t dev) } netmap_mem_get(ptn_dev->nm_mem); - D("ptn_memdev_driver probe OK - host_id: %d", mem_id); + D("ptn_memdev_driver probe OK - host_mem_id: %d", mem_id); return (0); } @@ -993,12 +987,7 @@ nm_os_ncpus(void) struct nm_kthread_ctx { struct thread *user_td; /* thread user-space (kthread creator) to send ioctl */ - /* notification to guest (interrupt) */ - int irq_fd; /* ioctl fd */ - struct nm_kth_ioctl irq_ioctl; /* ioctl arguments */ - - /* notification from guest */ - void *ioevent_file; /* tsleep() argument */ + struct ptnetmap_cfgentry_bhyve cfg; /* worker function and parameter */ nm_kthread_worker_fn_t worker_fn; @@ -1034,8 +1023,8 @@ nm_os_kthread_wakeup_worker(struct nm_kthread *nmk) */ mtx_lock(&nmk->worker_lock); nmk->scheduled++; - if (nmk->worker_ctx.ioevent_file) { - wakeup(nmk->worker_ctx.ioevent_file); + if (nmk->worker_ctx.cfg.wchan) { + wakeup((void *)nmk->worker_ctx.cfg.wchan); } mtx_unlock(&nmk->worker_lock); } @@ -1046,11 +1035,13 @@ nm_os_kthread_send_irq(struct nm_kthread *nmk) struct nm_kthread_ctx *ctx = &nmk->worker_ctx; int err; - if (ctx->user_td && ctx->irq_fd > 0) { - err = kern_ioctl(ctx->user_td, ctx->irq_fd, ctx->irq_ioctl.com, (caddr_t)&ctx->irq_ioctl.data.msix); + if (ctx->user_td && ctx->cfg.ioctl_fd > 0) { + err = kern_ioctl(ctx->user_td, ctx->cfg.ioctl_fd, ctx->cfg.ioctl_cmd, + (caddr_t)&ctx->cfg.ioctl_data); if (err) { - D("kern_ioctl error: %d ioctl parameters: fd %d com %ju data %p", - err, ctx->irq_fd, (uintmax_t)ctx->irq_ioctl.com, &ctx->irq_ioctl.data); + D("kern_ioctl error: %d ioctl parameters: fd %d com %lu data %p", + err, ctx->cfg.ioctl_fd, (unsigned long)ctx->cfg.ioctl_cmd, + &ctx->cfg.ioctl_data); } } } @@ -1082,10 +1073,10 @@ nm_kthread_worker(void *data) } /* - * if ioevent_file is not defined, we don't have notification + * if wchan is not defined, we don't have notification * mechanism and we continually execute worker_fn() */ - if (!ctx->ioevent_file) { + if (!ctx->cfg.wchan) { ctx->worker_fn(ctx->worker_private); /* worker body */ } else { /* checks if there is a pending notification */ @@ -1099,7 +1090,7 @@ nm_kthread_worker(void *data) continue; } else if (nmk->run) { /* wait on event with one second timeout */ - msleep_spin(ctx->ioevent_file, &nmk->worker_lock, + msleep_spin((void *)ctx->cfg.wchan, &nmk->worker_lock, "nmk_ev", hz); nmk->scheduled++; } @@ -1110,29 +1101,6 @@ nm_kthread_worker(void *data) kthread_exit(); } -static int -nm_kthread_open_files(struct nm_kthread *nmk, struct nm_kthread_cfg *cfg) -{ - /* send irq through ioctl to bhyve (vmm.ko) */ - if (cfg->event.irqfd) { - nmk->worker_ctx.irq_fd = cfg->event.irqfd; - nmk->worker_ctx.irq_ioctl = cfg->event.ioctl; - } - /* ring.ioeventfd contains the chan where do tsleep to wait events */ - if (cfg->event.ioeventfd) { - nmk->worker_ctx.ioevent_file = (void *)cfg->event.ioeventfd; - } - - return 0; -} - -static void -nm_kthread_close_files(struct nm_kthread *nmk) -{ - nmk->worker_ctx.irq_fd = 0; - nmk->worker_ctx.ioevent_file = NULL; -} - void nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity) { @@ -1140,10 +1108,15 @@ nm_os_kthread_set_affinity(struct nm_kthread *nmk, int affinity) } struct nm_kthread * -nm_os_kthread_create(struct nm_kthread_cfg *cfg) +nm_os_kthread_create(struct nm_kthread_cfg *cfg, unsigned int cfgtype, + void *opaque) { struct nm_kthread *nmk = NULL; - int error; + + if (cfgtype != PTNETMAP_CFGTYPE_BHYVE) { + D("Unsupported cfgtype %u", cfgtype); + return NULL; + } nmk = malloc(sizeof(*nmk), M_DEVBUF, M_NOWAIT | M_ZERO); if (!nmk) @@ -1158,15 +1131,12 @@ nm_os_kthread_create(struct nm_kthread_cfg *cfg) /* attach kthread to user process (ptnetmap) */ nmk->attach_user = cfg->attach_user; - /* open event fd */ - error = nm_kthread_open_files(nmk, cfg); - if (error) - goto err; + /* store kick/interrupt configuration */ + if (opaque) { + nmk->worker_ctx.cfg = *((struct ptnetmap_cfgentry_bhyve *)opaque); + } return nmk; -err: - free(nmk, M_DEVBUF); - return NULL; } int @@ -1194,7 +1164,7 @@ nm_os_kthread_start(struct nm_kthread *nmk) goto err; } - D("nm_kthread started td 0x%p", nmk->worker); + D("nm_kthread started td %p", nmk->worker); return 0; err: @@ -1228,7 +1198,7 @@ nm_os_kthread_delete(struct nm_kthread *nmk) nm_os_kthread_stop(nmk); } - nm_kthread_close_files(nmk); + memset(&nmk->worker_ctx.cfg, 0, sizeof(nmk->worker_ctx.cfg)); free(nmk, M_DEVBUF); } diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h index 28e69d7ab093..f904476721ba 100644 --- a/sys/dev/netmap/netmap_kern.h +++ b/sys/dev/netmap/netmap_kern.h @@ -2009,13 +2009,14 @@ typedef void (*nm_kthread_worker_fn_t)(void *data); /* kthread configuration */ struct nm_kthread_cfg { long type; /* kthread type/identifier */ - struct ptnet_ring_cfg event; /* event/ioctl fd */ nm_kthread_worker_fn_t worker_fn; /* worker function */ void *worker_private;/* worker parameter */ int attach_user; /* attach kthread to user process */ }; /* kthread configuration */ -struct nm_kthread *nm_os_kthread_create(struct nm_kthread_cfg *cfg); +struct nm_kthread *nm_os_kthread_create(struct nm_kthread_cfg *cfg, + unsigned int cfgtype, + void *opaque); int nm_os_kthread_start(struct nm_kthread *); void nm_os_kthread_stop(struct nm_kthread *); void nm_os_kthread_delete(struct nm_kthread *); @@ -2053,8 +2054,6 @@ nm_ptnetmap_host_on(struct netmap_adapter *na) #ifdef WITH_PTNETMAP_GUEST /* ptnetmap GUEST routines */ -typedef uint32_t (*nm_pt_guest_ptctl_t)(struct ifnet *, uint32_t); - /* * netmap adapter for guest ptnetmap ports */ @@ -2076,8 +2075,8 @@ struct netmap_pt_guest_adapter { }; -int netmap_pt_guest_attach(struct netmap_adapter *, void *, - unsigned int, nm_pt_guest_ptctl_t); +int netmap_pt_guest_attach(struct netmap_adapter *na, void *csb, + unsigned int nifp_offset, unsigned int memid); struct ptnet_ring; bool netmap_pt_guest_txsync(struct ptnet_ring *ptring, struct netmap_kring *kring, int flags); diff --git a/sys/dev/netmap/netmap_mem2.c b/sys/dev/netmap/netmap_mem2.c index bb0f9c8b6f39..ab89d3af65a5 100644 --- a/sys/dev/netmap/netmap_mem2.c +++ b/sys/dev/netmap/netmap_mem2.c @@ -147,39 +147,6 @@ struct netmap_mem_ops { typedef uint16_t nm_memid_t; -/* - * Shared info for netmap allocator - * - * Each allocator contains this structur as first netmap_if. - * In this way, we can share same details about allocator - * to the VM. - * Used in ptnetmap. - */ -struct netmap_mem_shared_info { -#ifndef _WIN32 - struct netmap_if up; /* ends with a 0-sized array, which VSC does not like */ -#else /* !_WIN32 */ - char up[sizeof(struct netmap_if)]; -#endif /* !_WIN32 */ - uint64_t features; -#define NMS_FEAT_BUF_POOL 0x0001 -#define NMS_FEAT_MEMSIZE 0x0002 - - uint32_t buf_pool_offset; - uint32_t buf_pool_objtotal; - uint32_t buf_pool_objsize; - uint32_t totalsize; -}; - -#define NMS_NAME "nms_info" -#define NMS_VERSION 1 -static const struct netmap_if nms_if_blueprint = { - .ni_name = NMS_NAME, - .ni_version = NMS_VERSION, - .ni_tx_rings = 0, - .ni_rx_rings = 0 -}; - struct netmap_mem_d { NMA_LOCK_T nm_mtx; /* protect the allocator */ u_int nm_totalsize; /* shorthand */ @@ -312,8 +279,6 @@ netmap_mem_finalize(struct netmap_mem_d *nmd, struct netmap_adapter *na) return nmd->lasterr; } -static int netmap_mem_init_shared_info(struct netmap_mem_d *nmd); - void netmap_mem_deref(struct netmap_mem_d *nmd, struct netmap_adapter *na) { @@ -362,13 +327,9 @@ netmap_mem_deref(struct netmap_mem_d *nmd, struct netmap_adapter *na) if (nmd->pools[NETMAP_BUF_POOL].bitmap) { /* XXX This check is a workaround that prevents a * NULL pointer crash which currently happens only - * with ptnetmap guests. Also, - * netmap_mem_init_shared_info must not be called - * by ptnetmap guest. */ + * with ptnetmap guests. + * Removed shared-info --> is the bug still there? */ nmd->pools[NETMAP_BUF_POOL].bitmap[0] = ~3; - - /* expose info to the ptnetmap guest */ - netmap_mem_init_shared_info(nmd); } } nmd->ops->nmd_deref(nmd); @@ -1390,30 +1351,6 @@ netmap_mem_map(struct netmap_obj_pool *p, struct netmap_adapter *na) return 0; } -static int -netmap_mem_init_shared_info(struct netmap_mem_d *nmd) -{ - struct netmap_mem_shared_info *nms_info; - ssize_t base; - - /* Use the first slot in IF_POOL */ - nms_info = netmap_if_malloc(nmd, sizeof(*nms_info)); - if (nms_info == NULL) { - return ENOMEM; - } - - base = netmap_if_offset(nmd, nms_info); - - memcpy(&nms_info->up, &nms_if_blueprint, sizeof(nms_if_blueprint)); - nms_info->buf_pool_offset = nmd->pools[NETMAP_IF_POOL].memtotal + nmd->pools[NETMAP_RING_POOL].memtotal; - nms_info->buf_pool_objtotal = nmd->pools[NETMAP_BUF_POOL].objtotal; - nms_info->buf_pool_objsize = nmd->pools[NETMAP_BUF_POOL]._objsize; - nms_info->totalsize = nmd->nm_totalsize; - nms_info->features = NMS_FEAT_BUF_POOL | NMS_FEAT_MEMSIZE; - - return 0; -} - static int netmap_mem_finalize_all(struct netmap_mem_d *nmd) { @@ -1433,11 +1370,6 @@ netmap_mem_finalize_all(struct netmap_mem_d *nmd) nmd->pools[NETMAP_BUF_POOL].bitmap[0] = ~3; nmd->flags |= NETMAP_MEM_FINALIZED; - /* expose info to the ptnetmap guest */ - nmd->lasterr = netmap_mem_init_shared_info(nmd); - if (nmd->lasterr) - goto error; - if (netmap_verbose) D("interfaces %d KB, rings %d KB, buffers %d MB", nmd->pools[NETMAP_IF_POOL].memtotal >> 10, @@ -1929,12 +1861,54 @@ struct netmap_mem_ops netmap_mem_private_ops = { .nmd_rings_delete = netmap_mem2_rings_delete }; +int +netmap_mem_pools_info_get(struct nmreq *nmr, struct netmap_adapter *na) +{ + uintptr_t *pp = (uintptr_t *)&nmr->nr_arg1; + struct netmap_pools_info *upi = (struct netmap_pools_info *)(*pp); + struct netmap_mem_d *nmd = na->nm_mem; + struct netmap_pools_info pi; + unsigned int memsize; + uint16_t memid; + int ret; + + if (!nmd) { + return -1; + } + + ret = netmap_mem_get_info(nmd, &memsize, NULL, &memid); + if (ret) { + return ret; + } + + pi.memsize = memsize; + pi.memid = memid; + pi.if_pool_offset = 0; + pi.if_pool_objtotal = nmd->pools[NETMAP_IF_POOL].objtotal; + pi.if_pool_objsize = nmd->pools[NETMAP_IF_POOL]._objsize; + + pi.ring_pool_offset = nmd->pools[NETMAP_IF_POOL].memtotal; + pi.ring_pool_objtotal = nmd->pools[NETMAP_RING_POOL].objtotal; + pi.ring_pool_objsize = nmd->pools[NETMAP_RING_POOL]._objsize; + + pi.buf_pool_offset = nmd->pools[NETMAP_IF_POOL].memtotal + + nmd->pools[NETMAP_RING_POOL].memtotal; + pi.buf_pool_objtotal = nmd->pools[NETMAP_BUF_POOL].objtotal; + pi.buf_pool_objsize = nmd->pools[NETMAP_BUF_POOL]._objsize; + + ret = copyout(&pi, upi, sizeof(pi)); + if (ret) { + return ret; + } + + return 0; +} + #ifdef WITH_PTNETMAP_GUEST struct mem_pt_if { struct mem_pt_if *next; struct ifnet *ifp; unsigned int nifp_offset; - nm_pt_guest_ptctl_t ptctl; }; /* Netmap allocator for ptnetmap guests. */ @@ -1944,16 +1918,15 @@ struct netmap_mem_ptg { vm_paddr_t nm_paddr; /* physical address in the guest */ void *nm_addr; /* virtual address in the guest */ struct netmap_lut buf_lut; /* lookup table for BUF pool in the guest */ - nm_memid_t nm_host_id; /* allocator identifier in the host */ - struct ptnetmap_memdev *ptn_dev; + nm_memid_t host_mem_id; /* allocator identifier in the host */ + struct ptnetmap_memdev *ptn_dev;/* ptnetmap memdev */ struct mem_pt_if *pt_ifs; /* list of interfaces in passthrough */ }; /* Link a passthrough interface to a passthrough netmap allocator. */ static int netmap_mem_pt_guest_ifp_add(struct netmap_mem_d *nmd, struct ifnet *ifp, - unsigned int nifp_offset, - nm_pt_guest_ptctl_t ptctl) + unsigned int nifp_offset) { struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)nmd; struct mem_pt_if *ptif = malloc(sizeof(*ptif), M_NETMAP, @@ -1967,7 +1940,6 @@ netmap_mem_pt_guest_ifp_add(struct netmap_mem_d *nmd, struct ifnet *ifp, ptif->ifp = ifp; ptif->nifp_offset = nifp_offset; - ptif->ptctl = ptctl; if (ptnmd->pt_ifs) { ptif->next = ptnmd->pt_ifs; @@ -2029,62 +2001,6 @@ netmap_mem_pt_guest_ifp_del(struct netmap_mem_d *nmd, struct ifnet *ifp) return ret; } -/* Read allocator info from the first netmap_if (only on finalize) */ -static int -netmap_mem_pt_guest_read_shared_info(struct netmap_mem_d *nmd) -{ - struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)nmd; - struct netmap_mem_shared_info *nms_info; - uint32_t bufsize; - uint32_t nbuffers; - char *vaddr; - vm_paddr_t paddr; - int i; - - nms_info = (struct netmap_mem_shared_info *)ptnmd->nm_addr; - if (strncmp(nms_info->up.ni_name, NMS_NAME, sizeof(NMS_NAME)) != 0) { - D("error, the first slot does not contain shared info"); - return EINVAL; - } - /* check features mem_shared info */ - if ((nms_info->features & (NMS_FEAT_BUF_POOL | NMS_FEAT_MEMSIZE)) != - (NMS_FEAT_BUF_POOL | NMS_FEAT_MEMSIZE)) { - D("error, the shared info does not contain BUF_POOL and MEMSIZE"); - return EINVAL; - } - - bufsize = nms_info->buf_pool_objsize; - nbuffers = nms_info->buf_pool_objtotal; - - /* allocate the lut */ - if (ptnmd->buf_lut.lut == NULL) { - D("allocating lut"); - ptnmd->buf_lut.lut = nm_alloc_lut(nbuffers); - if (ptnmd->buf_lut.lut == NULL) { - D("lut allocation failed"); - return ENOMEM; - } - } - - /* we have physically contiguous memory mapped through PCI BAR */ - vaddr = (char *)(ptnmd->nm_addr) + nms_info->buf_pool_offset; - paddr = ptnmd->nm_paddr + nms_info->buf_pool_offset; - - for (i = 0; i < nbuffers; i++) { - ptnmd->buf_lut.lut[i].vaddr = vaddr; - ptnmd->buf_lut.lut[i].paddr = paddr; - vaddr += bufsize; - paddr += bufsize; - } - - ptnmd->buf_lut.objtotal = nbuffers; - ptnmd->buf_lut.objsize = bufsize; - - nmd->nm_totalsize = nms_info->totalsize; - - return 0; -} - static int netmap_mem_pt_guest_get_lut(struct netmap_mem_d *nmd, struct netmap_lut *lut) { @@ -2147,6 +2063,13 @@ static int netmap_mem_pt_guest_finalize(struct netmap_mem_d *nmd) { struct netmap_mem_ptg *ptnmd = (struct netmap_mem_ptg *)nmd; + uint64_t mem_size; + uint32_t bufsize; + uint32_t nbuffers; + uint32_t poolofs; + vm_paddr_t paddr; + char *vaddr; + int i; int error = 0; nmd->active++; @@ -2159,16 +2082,45 @@ netmap_mem_pt_guest_finalize(struct netmap_mem_d *nmd) error = ENOMEM; goto err; } - /* map memory through ptnetmap-memdev BAR */ + /* Map memory through ptnetmap-memdev BAR. */ error = nm_os_pt_memdev_iomap(ptnmd->ptn_dev, &ptnmd->nm_paddr, - &ptnmd->nm_addr); + &ptnmd->nm_addr, &mem_size); if (error) goto err; - /* read allcator info and create lut */ - error = netmap_mem_pt_guest_read_shared_info(nmd); - if (error) - goto err; + /* Initialize the lut using the information contained in the + * ptnetmap memory device. */ + bufsize = nm_os_pt_memdev_ioread(ptnmd->ptn_dev, + PTNET_MDEV_IO_BUF_POOL_OBJSZ); + nbuffers = nm_os_pt_memdev_ioread(ptnmd->ptn_dev, + PTNET_MDEV_IO_BUF_POOL_OBJNUM); + + /* allocate the lut */ + if (ptnmd->buf_lut.lut == NULL) { + D("allocating lut"); + ptnmd->buf_lut.lut = nm_alloc_lut(nbuffers); + if (ptnmd->buf_lut.lut == NULL) { + D("lut allocation failed"); + return ENOMEM; + } + } + + /* we have physically contiguous memory mapped through PCI BAR */ + poolofs = nm_os_pt_memdev_ioread(ptnmd->ptn_dev, + PTNET_MDEV_IO_BUF_POOL_OFS); + vaddr = (char *)(ptnmd->nm_addr) + poolofs; + paddr = ptnmd->nm_paddr + poolofs; + + for (i = 0; i < nbuffers; i++) { + ptnmd->buf_lut.lut[i].vaddr = vaddr; + ptnmd->buf_lut.lut[i].paddr = paddr; + vaddr += bufsize; + paddr += bufsize; + } + + ptnmd->buf_lut.objtotal = nbuffers; + ptnmd->buf_lut.objsize = bufsize; + nmd->nm_totalsize = (unsigned int)mem_size; nmd->flags |= NETMAP_MEM_FINALIZED; out: @@ -2248,15 +2200,10 @@ netmap_mem_pt_guest_if_delete(struct netmap_adapter *na, struct netmap_if *nifp) struct mem_pt_if *ptif; NMA_LOCK(na->nm_mem); - ptif = netmap_mem_pt_guest_ifp_lookup(na->nm_mem, na->ifp); if (ptif == NULL) { D("Error: interface %p is not in passthrough", na->ifp); - goto out; } - - ptif->ptctl(na->ifp, PTNETMAP_PTCTL_IFDELETE); -out: NMA_UNLOCK(na->nm_mem); } @@ -2295,7 +2242,6 @@ netmap_mem_pt_guest_rings_create(struct netmap_adapter *na) nifp->ring_ofs[i + na->num_tx_rings + 1]); } - //error = ptif->ptctl->nm_ptctl(ifp, PTNETMAP_PTCTL_RINGSCREATE); error = 0; out: NMA_UNLOCK(na->nm_mem); @@ -2331,7 +2277,7 @@ static struct netmap_mem_ops netmap_mem_pt_guest_ops = { /* Called with NMA_LOCK(&nm_mem) held. */ static struct netmap_mem_d * -netmap_mem_pt_guest_find_hostid(nm_memid_t host_id) +netmap_mem_pt_guest_find_memid(nm_memid_t mem_id) { struct netmap_mem_d *mem = NULL; struct netmap_mem_d *scan = netmap_last_mem_d; @@ -2339,7 +2285,7 @@ netmap_mem_pt_guest_find_hostid(nm_memid_t host_id) do { /* find ptnetmap allocator through host ID */ if (scan->ops->nmd_deref == netmap_mem_pt_guest_deref && - ((struct netmap_mem_ptg *)(scan))->nm_host_id == host_id) { + ((struct netmap_mem_ptg *)(scan))->host_mem_id == mem_id) { mem = scan; break; } @@ -2351,7 +2297,7 @@ netmap_mem_pt_guest_find_hostid(nm_memid_t host_id) /* Called with NMA_LOCK(&nm_mem) held. */ static struct netmap_mem_d * -netmap_mem_pt_guest_create(nm_memid_t host_id) +netmap_mem_pt_guest_create(nm_memid_t mem_id) { struct netmap_mem_ptg *ptnmd; int err = 0; @@ -2364,7 +2310,7 @@ netmap_mem_pt_guest_create(nm_memid_t host_id) } ptnmd->up.ops = &netmap_mem_pt_guest_ops; - ptnmd->nm_host_id = host_id; + ptnmd->host_mem_id = mem_id; ptnmd->pt_ifs = NULL; /* Assign new id in the guest (We have the lock) */ @@ -2388,14 +2334,14 @@ netmap_mem_pt_guest_create(nm_memid_t host_id) * if it is not there */ static struct netmap_mem_d * -netmap_mem_pt_guest_get(nm_memid_t host_id) +netmap_mem_pt_guest_get(nm_memid_t mem_id) { struct netmap_mem_d *nmd; NMA_LOCK(&nm_mem); - nmd = netmap_mem_pt_guest_find_hostid(host_id); + nmd = netmap_mem_pt_guest_find_memid(mem_id); if (nmd == NULL) { - nmd = netmap_mem_pt_guest_create(host_id); + nmd = netmap_mem_pt_guest_create(mem_id); } NMA_UNLOCK(&nm_mem); @@ -2404,7 +2350,7 @@ netmap_mem_pt_guest_get(nm_memid_t host_id) /* * The guest allocator can be created by ptnetmap_memdev (during the device - * attach) or by ptnetmap device (e1000/virtio), during the netmap_attach. + * attach) or by ptnetmap device (ptnet), during the netmap_attach. * * The order is not important (we have different order in LINUX and FreeBSD). * The first one, creates the device, and the second one simply attaches it. @@ -2413,12 +2359,12 @@ netmap_mem_pt_guest_get(nm_memid_t host_id) /* Called when ptnetmap_memdev is attaching, to attach a new allocator in * the guest */ struct netmap_mem_d * -netmap_mem_pt_guest_attach(struct ptnetmap_memdev *ptn_dev, nm_memid_t host_id) +netmap_mem_pt_guest_attach(struct ptnetmap_memdev *ptn_dev, nm_memid_t mem_id) { struct netmap_mem_d *nmd; struct netmap_mem_ptg *ptnmd; - nmd = netmap_mem_pt_guest_get(host_id); + nmd = netmap_mem_pt_guest_get(mem_id); /* assign this device to the guest allocator */ if (nmd) { @@ -2429,27 +2375,22 @@ netmap_mem_pt_guest_attach(struct ptnetmap_memdev *ptn_dev, nm_memid_t host_id) return nmd; } -/* Called when ptnetmap device (virtio/e1000) is attaching */ +/* Called when ptnet device is attaching */ struct netmap_mem_d * netmap_mem_pt_guest_new(struct ifnet *ifp, unsigned int nifp_offset, - nm_pt_guest_ptctl_t ptctl) + unsigned int memid) { struct netmap_mem_d *nmd; - nm_memid_t host_id; - if (ifp == NULL || ptctl == NULL) { + if (ifp == NULL) { return NULL; } - /* Get the host id allocator. */ - host_id = ptctl(ifp, PTNETMAP_PTCTL_HOSTMEMID); - - nmd = netmap_mem_pt_guest_get(host_id); + nmd = netmap_mem_pt_guest_get((nm_memid_t)memid); if (nmd) { - netmap_mem_pt_guest_ifp_add(nmd, ifp, nifp_offset, - ptctl); + netmap_mem_pt_guest_ifp_add(nmd, ifp, nifp_offset); } return nmd; diff --git a/sys/dev/netmap/netmap_mem2.h b/sys/dev/netmap/netmap_mem2.h index 7f4c5e9e9624..f170df9d5490 100644 --- a/sys/dev/netmap/netmap_mem2.h +++ b/sys/dev/netmap/netmap_mem2.h @@ -167,12 +167,14 @@ void netmap_mem_put(struct netmap_mem_d *); #ifdef WITH_PTNETMAP_GUEST struct netmap_mem_d* netmap_mem_pt_guest_new(struct ifnet *, unsigned int nifp_offset, - nm_pt_guest_ptctl_t); + unsigned int memid); struct ptnetmap_memdev; struct netmap_mem_d* netmap_mem_pt_guest_attach(struct ptnetmap_memdev *, uint16_t); int netmap_mem_pt_guest_ifp_del(struct netmap_mem_d *, struct ifnet *); #endif /* WITH_PTNETMAP_GUEST */ +int netmap_mem_pools_info_get(struct nmreq *, struct netmap_adapter *); + #define NETMAP_MEM_PRIVATE 0x2 /* allocator uses private address space */ #define NETMAP_MEM_IO 0x4 /* the underlying memory is mmapped I/O */ diff --git a/sys/dev/netmap/netmap_pt.c b/sys/dev/netmap/netmap_pt.c index 56434a236145..3913f4b957fd 100644 --- a/sys/dev/netmap/netmap_pt.c +++ b/sys/dev/netmap/netmap_pt.c @@ -560,13 +560,34 @@ ptnetmap_print_configuration(struct ptnetmap_cfg *cfg) { int k; - D("[PTN] configuration:"); - D(" CSB ptrings @%p, num_rings=%u, features %08x", cfg->ptrings, - cfg->num_rings, cfg->features); + D("ptnetmap configuration:"); + D(" CSB ptrings @%p, num_rings=%u, cfgtype %08x", cfg->ptrings, + cfg->num_rings, cfg->cfgtype); for (k = 0; k < cfg->num_rings; k++) { - D(" ring #%d: iofd=%llu, irqfd=%llu", k, - (unsigned long long)cfg->entries[k].ioeventfd, - (unsigned long long)cfg->entries[k].irqfd); + switch (cfg->cfgtype) { + case PTNETMAP_CFGTYPE_QEMU: { + struct ptnetmap_cfgentry_qemu *e = + (struct ptnetmap_cfgentry_qemu *)(cfg+1) + k; + D(" ring #%d: ioeventfd=%lu, irqfd=%lu", k, + (unsigned long)e->ioeventfd, + (unsigned long)e->irqfd); + break; + } + + case PTNETMAP_CFGTYPE_BHYVE: + { + struct ptnetmap_cfgentry_bhyve *e = + (struct ptnetmap_cfgentry_bhyve *)(cfg+1) + k; + D(" ring #%d: wchan=%lu, ioctl_fd=%lu, " + "ioctl_cmd=%lu, msix_msg_data=%lu, msix_addr=%lu", + k, (unsigned long)e->wchan, + (unsigned long)e->ioctl_fd, + (unsigned long)e->ioctl_cmd, + (unsigned long)e->ioctl_data.msg_data, + (unsigned long)e->ioctl_data.addr); + break; + } + } } } @@ -632,6 +653,7 @@ ptnetmap_create_kthreads(struct netmap_pt_host_adapter *pth_na, struct ptnetmap_state *ptns = pth_na->ptns; struct nm_kthread_cfg nmk_cfg; unsigned int num_rings; + uint8_t *cfg_entries = (uint8_t *)(cfg + 1); int k; num_rings = pth_na->up.num_tx_rings + @@ -640,7 +662,6 @@ ptnetmap_create_kthreads(struct netmap_pt_host_adapter *pth_na, for (k = 0; k < num_rings; k++) { nmk_cfg.attach_user = 1; /* attach kthread to user process */ nmk_cfg.worker_private = ptnetmap_kring(pth_na, k); - nmk_cfg.event = *(cfg->entries + k); nmk_cfg.type = k; if (k < pth_na->up.num_tx_rings) { nmk_cfg.worker_fn = ptnetmap_tx_handler; @@ -648,7 +669,8 @@ ptnetmap_create_kthreads(struct netmap_pt_host_adapter *pth_na, nmk_cfg.worker_fn = ptnetmap_rx_handler; } - ptns->kthreads[k] = nm_os_kthread_create(&nmk_cfg); + ptns->kthreads[k] = nm_os_kthread_create(&nmk_cfg, + cfg->cfgtype, cfg_entries + k * cfg->entry_size); if (ptns->kthreads[k] == NULL) { goto err; } @@ -727,7 +749,7 @@ ptnetmap_read_cfg(struct nmreq *nmr) return NULL; } - cfglen = sizeof(tmp) + tmp.num_rings * sizeof(struct ptnet_ring_cfg); + cfglen = sizeof(tmp) + tmp.num_rings * tmp.entry_size; cfg = malloc(cfglen, M_DEVBUF, M_NOWAIT | M_ZERO); if (!cfg) { return NULL; @@ -750,7 +772,6 @@ static int ptnetmap_create(struct netmap_pt_host_adapter *pth_na, struct ptnetmap_cfg *cfg) { - unsigned ft_mask = (PTNETMAP_CFG_FEAT_CSB | PTNETMAP_CFG_FEAT_EVENTFD); struct ptnetmap_state *ptns; unsigned int num_rings; int ret, i; @@ -761,12 +782,6 @@ ptnetmap_create(struct netmap_pt_host_adapter *pth_na, return EINVAL; } - if ((cfg->features & ft_mask) != ft_mask) { - D("ERROR ptnetmap_cfg(%x) does not contain CSB and EVENTFD", - cfg->features); - return EINVAL; - } - num_rings = pth_na->up.num_tx_rings + pth_na->up.num_rx_rings; if (num_rings != cfg->num_rings) { @@ -1240,9 +1255,9 @@ netmap_get_pt_host_na(struct nmreq *nmr, struct netmap_adapter **na, int create) #ifdef WITH_PTNETMAP_GUEST /* - * GUEST ptnetmap generic txsync()/rxsync() used in e1000/virtio-net device - * driver notify is set when we need to send notification to the host - * (driver-specific) + * Guest ptnetmap txsync()/rxsync() routines, used in ptnet device drivers. + * These routines are reused across the different operating systems supported + * by netmap. */ /* diff --git a/sys/dev/netmap/netmap_vale.c b/sys/dev/netmap/netmap_vale.c index 78c53409c0b3..71b3aedddd46 100644 --- a/sys/dev/netmap/netmap_vale.c +++ b/sys/dev/netmap/netmap_vale.c @@ -913,7 +913,7 @@ nm_bdg_create_kthreads(struct nm_bdg_polling_state *bps) kcfg.type = i; kcfg.worker_private = t; - t->nmk = nm_os_kthread_create(&kcfg); + t->nmk = nm_os_kthread_create(&kcfg, 0, NULL); if (t->nmk == NULL) { goto cleanup; } diff --git a/sys/net/netmap.h b/sys/net/netmap.h index 14b5e2b32128..3e0cdab42489 100644 --- a/sys/net/netmap.h +++ b/sys/net/netmap.h @@ -525,6 +525,7 @@ struct nmreq { #define NETMAP_BDG_POLLING_ON 10 /* delete polling kthread */ #define NETMAP_BDG_POLLING_OFF 11 /* delete polling kthread */ #define NETMAP_VNET_HDR_GET 12 /* get the port virtio-net-hdr length */ +#define NETMAP_POOLS_INFO_GET 13 /* get memory allocator pools info */ uint16_t nr_arg1; /* reserve extra rings in NIOCREGIF */ #define NETMAP_BDG_HOST 1 /* attach the host stack on ATTACH */ @@ -644,29 +645,4 @@ struct nm_ifreq { char data[NM_IFRDATA_LEN]; }; -/* - * netmap kernel thread configuration - */ -/* bhyve/vmm.ko MSIX parameters for IOCTL */ -struct ptn_vmm_ioctl_msix { - uint64_t msg; - uint64_t addr; -}; - -/* IOCTL parameters */ -struct nm_kth_ioctl { - uint64_t com; - /* We use union to support more ioctl commands. */ - union { - struct ptn_vmm_ioctl_msix msix; - } data; -}; - -/* Configuration of a ptnetmap ring */ -struct ptnet_ring_cfg { - uint64_t ioeventfd; /* eventfd in linux, tsleep() parameter in FreeBSD */ - uint64_t irqfd; /* eventfd in linux, ioctl fd in FreeBSD */ - struct nm_kth_ioctl ioctl; /* ioctl parameter to send irq (only used in bhyve/FreeBSD) */ - uint64_t reserved[4]; /* reserved to support of more hypervisors */ -}; #endif /* _NET_NETMAP_H_ */ diff --git a/sys/net/netmap_virt.h b/sys/net/netmap_virt.h index e17dcf854a99..e5c823ea2f28 100644 --- a/sys/net/netmap_virt.h +++ b/sys/net/netmap_virt.h @@ -32,13 +32,6 @@ #ifndef NETMAP_VIRT_H #define NETMAP_VIRT_H -#define NETMAP_VIRT_CSB_SIZE 4096 - -/* ptnetmap features */ -#define PTNETMAP_F_BASE 1 -#define PTNETMAP_F_FULL 2 /* not used */ -#define PTNETMAP_F_VNET_HDR 4 - /* * ptnetmap_memdev: device used to expose memory into the guest VM * @@ -49,83 +42,126 @@ /* PCI identifiers and PCI BARs for the ptnetmap memdev * and ptnetmap network interface. */ #define PTNETMAP_MEMDEV_NAME "ptnetmap-memdev" -#define PTNETMAP_PCI_VENDOR_ID 0x3333 /* TODO change vendor_id */ -#define PTNETMAP_PCI_DEVICE_ID 0x0001 /* memory device */ -#define PTNETMAP_PCI_NETIF_ID 0x0002 /* ptnet network interface */ +#define PTNETMAP_PCI_VENDOR_ID 0x1b36 /* QEMU virtual devices */ +#define PTNETMAP_PCI_DEVICE_ID 0x000c /* memory device */ +#define PTNETMAP_PCI_NETIF_ID 0x000d /* ptnet network interface */ #define PTNETMAP_IO_PCI_BAR 0 #define PTNETMAP_MEM_PCI_BAR 1 #define PTNETMAP_MSIX_PCI_BAR 2 /* Registers for the ptnetmap memdev */ -/* 32 bit r/o */ -#define PTNETMAP_IO_PCI_MEMSIZE 0 /* size of the netmap memory shared - * between guest and host */ -/* 16 bit r/o */ -#define PTNETMAP_IO_PCI_HOSTID 4 /* memory allocator ID in netmap host */ -#define PTNETMAP_IO_SIZE 6 +#define PTNET_MDEV_IO_MEMSIZE_LO 0 /* netmap memory size (low) */ +#define PTNET_MDEV_IO_MEMSIZE_HI 4 /* netmap_memory_size (high) */ +#define PTNET_MDEV_IO_MEMID 8 /* memory allocator ID in the host */ +#define PTNET_MDEV_IO_IF_POOL_OFS 64 +#define PTNET_MDEV_IO_IF_POOL_OBJNUM 68 +#define PTNET_MDEV_IO_IF_POOL_OBJSZ 72 +#define PTNET_MDEV_IO_RING_POOL_OFS 76 +#define PTNET_MDEV_IO_RING_POOL_OBJNUM 80 +#define PTNET_MDEV_IO_RING_POOL_OBJSZ 84 +#define PTNET_MDEV_IO_BUF_POOL_OFS 88 +#define PTNET_MDEV_IO_BUF_POOL_OBJNUM 92 +#define PTNET_MDEV_IO_BUF_POOL_OBJSZ 96 +#define PTNET_MDEV_IO_END 100 /* * ptnetmap configuration * - * The hypervisor (QEMU or bhyve) sends this struct to the host netmap - * module through an ioctl() command when it wants to start the ptnetmap - * kthreads. + * The ptnet kthreads (running in host kernel-space) need to be configured + * in order to know how to intercept guest kicks (I/O register writes) and + * how to inject MSI-X interrupts to the guest. The configuration may vary + * depending on the hypervisor. Currently, we support QEMU/KVM on Linux and + * and bhyve on FreeBSD. + * The configuration is passed by the hypervisor to the host netmap module + * by means of an ioctl() with nr_cmd=NETMAP_PT_HOST_CREATE, and it is + * specified by the ptnetmap_cfg struct. This struct contains an header + * with general informations and an array of entries whose size depends + * on the hypervisor. The NETMAP_PT_HOST_CREATE command is issued every + * time the kthreads are started. */ struct ptnetmap_cfg { -#define PTNETMAP_CFG_FEAT_CSB 0x0001 -#define PTNETMAP_CFG_FEAT_EVENTFD 0x0002 -#define PTNETMAP_CFG_FEAT_IOCTL 0x0004 - uint32_t features; - void *ptrings; /* ptrings inside CSB */ - uint32_t num_rings; /* number of entries */ - struct ptnet_ring_cfg entries[0]; /* per-ptring configuration */ +#define PTNETMAP_CFGTYPE_QEMU 0x1 +#define PTNETMAP_CFGTYPE_BHYVE 0x2 + uint16_t cfgtype; /* how to interpret the cfg entries */ + uint16_t entry_size; /* size of a config entry */ + uint32_t num_rings; /* number of config entries */ + void *ptrings; /* ptrings inside CSB */ + /* Configuration entries are allocated right after the struct. */ +}; + +/* Configuration of a ptnetmap ring for QEMU. */ +struct ptnetmap_cfgentry_qemu { + uint32_t ioeventfd; /* to intercept guest register access */ + uint32_t irqfd; /* to inject guest interrupts */ +}; + +/* Configuration of a ptnetmap ring for bhyve. */ +struct ptnetmap_cfgentry_bhyve { + uint64_t wchan; /* tsleep() parameter, to wake up kthread */ + uint32_t ioctl_fd; /* ioctl fd */ + /* ioctl parameters to send irq */ + uint32_t ioctl_cmd; + /* vmm.ko MSIX parameters for IOCTL */ + struct { + uint64_t msg_data; + uint64_t addr; + } ioctl_data; }; /* - * Functions used to write ptnetmap_cfg from/to the nmreq. - * The user-space application writes the pointer of ptnetmap_cfg - * (user-space buffer) starting from nr_arg1 field, so that the kernel - * can read it with copyin (copy_from_user). + * Structure filled-in by the kernel when asked for allocator info + * through NETMAP_POOLS_INFO_GET. Used by hypervisors supporting + * ptnetmap. + */ +struct netmap_pools_info { + uint64_t memsize; /* same as nmr->nr_memsize */ + uint32_t memid; /* same as nmr->nr_arg2 */ + uint32_t if_pool_offset; + uint32_t if_pool_objtotal; + uint32_t if_pool_objsize; + uint32_t ring_pool_offset; + uint32_t ring_pool_objtotal; + uint32_t ring_pool_objsize; + uint32_t buf_pool_offset; + uint32_t buf_pool_objtotal; + uint32_t buf_pool_objsize; +}; + +/* + * Pass a pointer to a userspace buffer to be passed to kernelspace for write + * or read. Used by NETMAP_PT_HOST_CREATE and NETMAP_POOLS_INFO_GET. */ static inline void -ptnetmap_write_cfg(struct nmreq *nmr, struct ptnetmap_cfg *cfg) +nmreq_pointer_put(struct nmreq *nmr, void *userptr) { - uintptr_t *nmr_ptncfg = (uintptr_t *)&nmr->nr_arg1; - *nmr_ptncfg = (uintptr_t)cfg; + uintptr_t *pp = (uintptr_t *)&nmr->nr_arg1; + *pp = (uintptr_t)userptr; } -/* ptnetmap control commands */ -#define PTNETMAP_PTCTL_CONFIG 1 -#define PTNETMAP_PTCTL_FINALIZE 2 -#define PTNETMAP_PTCTL_IFNEW 3 -#define PTNETMAP_PTCTL_IFDELETE 4 -#define PTNETMAP_PTCTL_RINGSCREATE 5 -#define PTNETMAP_PTCTL_RINGSDELETE 6 -#define PTNETMAP_PTCTL_DEREF 7 -#define PTNETMAP_PTCTL_TXSYNC 8 -#define PTNETMAP_PTCTL_RXSYNC 9 -#define PTNETMAP_PTCTL_REGIF 10 -#define PTNETMAP_PTCTL_UNREGIF 11 -#define PTNETMAP_PTCTL_HOSTMEMID 12 - +/* ptnetmap features */ +#define PTNETMAP_F_VNET_HDR 1 /* I/O registers for the ptnet device. */ #define PTNET_IO_PTFEAT 0 #define PTNET_IO_PTCTL 4 -#define PTNET_IO_PTSTS 8 -#define PTNET_IO_MAC_LO 12 -#define PTNET_IO_MAC_HI 16 -#define PTNET_IO_CSBBAH 20 -#define PTNET_IO_CSBBAL 24 -#define PTNET_IO_NIFP_OFS 28 -#define PTNET_IO_NUM_TX_RINGS 32 -#define PTNET_IO_NUM_RX_RINGS 36 -#define PTNET_IO_NUM_TX_SLOTS 40 -#define PTNET_IO_NUM_RX_SLOTS 44 -#define PTNET_IO_VNET_HDR_LEN 48 +#define PTNET_IO_MAC_LO 8 +#define PTNET_IO_MAC_HI 12 +#define PTNET_IO_CSBBAH 16 +#define PTNET_IO_CSBBAL 20 +#define PTNET_IO_NIFP_OFS 24 +#define PTNET_IO_NUM_TX_RINGS 28 +#define PTNET_IO_NUM_RX_RINGS 32 +#define PTNET_IO_NUM_TX_SLOTS 36 +#define PTNET_IO_NUM_RX_SLOTS 40 +#define PTNET_IO_VNET_HDR_LEN 44 +#define PTNET_IO_HOSTMEMID 48 #define PTNET_IO_END 52 #define PTNET_IO_KICK_BASE 128 -#define PTNET_IO_MASK 0xff +#define PTNET_IO_MASK 0xff + +/* ptnetmap control commands (values for PTCTL register) */ +#define PTNETMAP_PTCTL_CREATE 1 +#define PTNETMAP_PTCTL_DELETE 2 /* If defined, CSB is allocated by the guest, not by the host. */ #define PTNET_CSB_ALLOC @@ -145,29 +181,18 @@ struct ptnet_ring { /* CSB for the ptnet device. */ struct ptnet_csb { +#define NETMAP_VIRT_CSB_SIZE 4096 struct ptnet_ring rings[NETMAP_VIRT_CSB_SIZE/sizeof(struct ptnet_ring)]; }; -#if defined (WITH_PTNETMAP_HOST) || defined (WITH_PTNETMAP_GUEST) - -/* return l_elem - r_elem with wraparound */ -static inline uint32_t -ptn_sub(uint32_t l_elem, uint32_t r_elem, uint32_t num_slots) -{ - int64_t res; - - res = (int64_t)(l_elem) - r_elem; - - return (res < 0) ? res + num_slots : res; -} -#endif /* WITH_PTNETMAP_HOST || WITH_PTNETMAP_GUEST */ - #ifdef WITH_PTNETMAP_GUEST /* ptnetmap_memdev routines used to talk with ptnetmap_memdev device driver */ struct ptnetmap_memdev; -int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **); +int nm_os_pt_memdev_iomap(struct ptnetmap_memdev *, vm_paddr_t *, void **, + uint64_t *); void nm_os_pt_memdev_iounmap(struct ptnetmap_memdev *); +uint32_t nm_os_pt_memdev_ioread(struct ptnetmap_memdev *, unsigned int); /* Guest driver: Write kring pointers (cur, head) to the CSB. * This routine is coupled with ptnetmap_host_read_kring_csb(). */ From e301826d4c835cccd3b51197ef74800c841d4445 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 27 Oct 2016 14:21:54 +0000 Subject: [PATCH 149/235] libgcc_eh/libgcc_s: apply hidden visibility only to static libs --- lib/libgcc_eh/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libgcc_eh/Makefile.inc b/lib/libgcc_eh/Makefile.inc index 7321fbea78f9..85c77aae5d7b 100644 --- a/lib/libgcc_eh/Makefile.inc +++ b/lib/libgcc_eh/Makefile.inc @@ -4,7 +4,7 @@ COMPILERRTDIR= ${SRCTOP}/contrib/compiler-rt UNWINDINCDIR= ${SRCTOP}/contrib/llvm/projects/libunwind/include UNWINDSRCDIR= ${SRCTOP}/contrib/llvm/projects/libunwind/src -CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN +STATIC_CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN .PATH: ${COMPILERRTDIR}/lib/builtins .PATH: ${UNWINDSRCDIR} From c4e24caf4ec787d4092a953f535021682744f3ba Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Thu, 27 Oct 2016 18:46:52 +0000 Subject: [PATCH 150/235] Revert r307823 (Use upstream suffixes for LLVM IR) for now. It causes a number of ports to fail, which use bmake, and use .ll file extensions (usually for for C++-based lex input). Reported by: antoine --- share/mk/bsd.suffixes.mk | 8 ++++---- share/mk/sys.mk | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/share/mk/bsd.suffixes.mk b/share/mk/bsd.suffixes.mk index 21668ede069a..9ca583b0b952 100644 --- a/share/mk/bsd.suffixes.mk +++ b/share/mk/bsd.suffixes.mk @@ -20,10 +20,10 @@ ${CC} ${STATIC_CFLAGS} ${CFLAGS} -c ${.IMPSRC} -o ${.TARGET} ${CTFCONVERT_CMD} -.c.bc: +.c.bco: ${CC} -emit-llvm ${IR_CFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.c.ll: +.c.llo: ${CC} -emit-llvm ${IR_CFLAGS} -S ${.IMPSRC} -o ${.TARGET} .cc .cpp .cxx .C: @@ -32,10 +32,10 @@ .cc.o .cpp.o .cxx.o .C.o: ${CXX} ${STATIC_CXXFLAGS} ${CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.cc.bc .cpp.bc .cxx.bc .C.bc: +.cc.bco .cpp.bco .cxx.bco .C.bco: ${CXX} -emit-llvm ${IR_CXXFLAGS} -c ${.IMPSRC} -o ${.TARGET} -.cc.ll .cpp.ll .cxx.ll .C.ll: +.cc.llo .cpp.llo .cxx.llo .C.llo: ${CXX} -emit-llvm ${IR_CXXFLAGS} -S ${.IMPSRC} -o ${.TARGET} .m.o: diff --git a/share/mk/sys.mk b/share/mk/sys.mk index eeb3f979f5f8..6efa99410d0a 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -121,7 +121,7 @@ META_MODE?= normal .if defined(%POSIX) .SUFFIXES: .o .c .y .l .a .sh .f .else -.SUFFIXES: .out .a .ln .o .bc .ll .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh +.SUFFIXES: .out .a .ln .o .bco .llo .c .cc .cpp .cxx .C .m .F .f .e .r .y .l .S .asm .s .cl .p .h .sh .endif AR ?= ar From 16dcd7734fa83ba7bd7daf822e2b7fa4fa2cba5a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 27 Oct 2016 21:23:14 +0000 Subject: [PATCH 151/235] MFamd64: Add bounds checks on addresses used with /dev/mem. Reject attempts to read from or memory map offsets in /dev/mem that are beyond the maximum-supported physical address of the current CPU. Reviewed by: kib MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D7408 --- sys/amd64/amd64/mem.c | 4 ++-- sys/i386/i386/mem.c | 9 +++++++-- sys/x86/include/x86_var.h | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c index 51f465074363..c2e74ff63b06 100644 --- a/sys/amd64/amd64/mem.c +++ b/sys/amd64/amd64/mem.c @@ -140,7 +140,7 @@ memrw(struct cdev *dev, struct uio *uio, int flags) error = uiomove((void *)vd, c, uio); break; } - if (v >= (1ULL << cpu_maxphyaddr)) { + if (v > cpu_getmaxphyaddr()) { error = EFAULT; break; } @@ -169,7 +169,7 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot __unused, vm_memattr_t *memattr __unused) { if (dev2unit(dev) == CDEV_MINOR_MEM) { - if (offset >= (1ULL << cpu_maxphyaddr)) + if (offset > cpu_getmaxphyaddr()) return (-1); *paddr = offset; return (0); diff --git a/sys/i386/i386/mem.c b/sys/i386/i386/mem.c index 43fb99451f76..accd092f1c57 100644 --- a/sys/i386/i386/mem.c +++ b/sys/i386/i386/mem.c @@ -108,8 +108,11 @@ memrw(struct cdev *dev, struct uio *uio, int flags) continue; } if (dev2unit(dev) == CDEV_MINOR_MEM) { - pa = uio->uio_offset; - pa &= ~PAGE_MASK; + if (uio->uio_offset > cpu_getmaxphyaddr()) { + error = EFAULT; + break; + } + pa = trunc_page(uio->uio_offset); } else { /* * Extract the physical page since the mapping may @@ -162,6 +165,8 @@ memmmap(struct cdev *dev, vm_ooffset_t offset, vm_paddr_t *paddr, int prot __unused, vm_memattr_t *memattr __unused) { if (dev2unit(dev) == CDEV_MINOR_MEM) { + if (offset > cpu_getmaxphyaddr()) + return (-1); *paddr = offset; return (0); } diff --git a/sys/x86/include/x86_var.h b/sys/x86/include/x86_var.h index 12bc1e07d4c0..92c9f1dafa21 100644 --- a/sys/x86/include/x86_var.h +++ b/sys/x86/include/x86_var.h @@ -94,6 +94,20 @@ struct trapframe; */ typedef void alias_for_inthand_t(void); +/* + * Returns the maximum physical address that can be used with the + * current system. + */ +static __inline vm_paddr_t +cpu_getmaxphyaddr(void) +{ +#if defined(__i386__) && !defined(PAE) + return (0xffffffff); +#else + return ((1ULL << cpu_maxphyaddr) - 1); +#endif +} + void *alloc_fpusave(int flags); void busdma_swi(void); bool cpu_mwait_usable(void); From 7b64a80b55ad3035c6cc5b4460241955d67d9f60 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 27 Oct 2016 21:31:56 +0000 Subject: [PATCH 152/235] Add powerd(8) support for several families of AMD CPUs. Use the same logic to calculate the nominal CPU frequency from the P-state MSRs on family 0x12, 0x15, and 0x16 CPUs as is used for family 0x10. Family 0x14 was included in the original patch in the PR but I left that out as the BIOS writer's guide for family 0x14 CPUs show a different layout for the relevant MSR and include a different formulate for calculating the frequency. While here, simplify a few expressions and print out the family of unsupported CPUs in hex rather than decimal. PR: 212020 Submitted by: Anthony Jenkins MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D7587 --- sys/x86/cpufreq/hwpstate.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/sys/x86/cpufreq/hwpstate.c b/sys/x86/cpufreq/hwpstate.c index d4c70b773c70..97762dcf48b9 100644 --- a/sys/x86/cpufreq/hwpstate.c +++ b/sys/x86/cpufreq/hwpstate.c @@ -408,25 +408,27 @@ hwpstate_get_info_from_msr(device_t dev) hwpstate_set = sc->hwpstate_settings; for (i = 0; i < sc->cfnum; i++) { msr = rdmsr(MSR_AMD_10H_11H_CONFIG + i); - if ((msr & ((uint64_t)1 << 63)) != ((uint64_t)1 << 63)) { + if ((msr & ((uint64_t)1 << 63)) == 0) { HWPSTATE_DEBUG(dev, "msr is not valid.\n"); return (ENXIO); } did = AMD_10H_11H_CUR_DID(msr); fid = AMD_10H_11H_CUR_FID(msr); + + /* Convert fid/did to frequency. */ switch(family) { case 0x11: - /* fid/did to frequency */ - hwpstate_set[i].freq = 100 * (fid + 0x08) / (1 << did); + hwpstate_set[i].freq = (100 * (fid + 0x08)) >> did; break; case 0x10: - /* fid/did to frequency */ - hwpstate_set[i].freq = 100 * (fid + 0x10) / (1 << did); + case 0x12: + case 0x15: + case 0x16: + hwpstate_set[i].freq = (100 * (fid + 0x10)) >> did; break; default: - HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family %d CPU's are not implemented yet. sorry.\n", family); + HWPSTATE_DEBUG(dev, "get_info_from_msr: AMD family 0x%02x CPU's are not implemented yet. sorry.\n", family); return (ENXIO); - break; } hwpstate_set[i].pstate_id = i; /* There was volts calculation, but deleted it. */ From 0656bb22c07d985876781a6be511ab3a1279a599 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Fri, 28 Oct 2016 00:04:04 +0000 Subject: [PATCH 153/235] libunwind: consistently add \n to log and trace messages Previously most messages included a newline in the string, but a few of them were missing. Fix these and simplify by just adding the newline in the _LIBUNWIND_LOG macro itself. While here correct 'libuwind' typo (missing 'n'). Upstream LLVM libunwind commits r280086 and r280103. --- .../projects/libunwind/include/libunwind.h | 4 +- .../projects/libunwind/src/AddressSpace.hpp | 2 +- .../libunwind/src/CompactUnwinder.hpp | 8 +- .../projects/libunwind/src/EHHeaderParser.hpp | 2 +- .../projects/libunwind/src/Unwind-EHABI.cpp | 44 +++++------ .../llvm/projects/libunwind/src/Unwind-sjlj.c | 68 ++++++++--------- .../projects/libunwind/src/UnwindCursor.hpp | 14 ++-- .../libunwind/src/UnwindLevel1-gcc-ext.c | 44 +++++------ .../projects/libunwind/src/UnwindLevel1.c | 76 +++++++++---------- contrib/llvm/projects/libunwind/src/config.h | 4 +- .../llvm/projects/libunwind/src/libunwind.cpp | 32 ++++---- 11 files changed, 149 insertions(+), 149 deletions(-) diff --git a/contrib/llvm/projects/libunwind/include/libunwind.h b/contrib/llvm/projects/libunwind/include/libunwind.h index 64534b135f82..f583f530fac9 100644 --- a/contrib/llvm/projects/libunwind/include/libunwind.h +++ b/contrib/llvm/projects/libunwind/include/libunwind.h @@ -6,7 +6,7 @@ // Source Licenses. See LICENSE.TXT for details. // // -// Compatible with libuwind API documented at: +// Compatible with libunwind API documented at: // http://www.nongnu.org/libunwind/man/libunwind(3).html // //===----------------------------------------------------------------------===// @@ -120,7 +120,7 @@ extern int unw_init_remote_thread(unw_cursor_t *, unw_addr_space_t, thread_t *); #endif /* UNW_REMOTE */ /* - * traditional libuwind "remote" API + * traditional libunwind "remote" API * NOT IMPLEMENTED on Mac OS X * * extern int unw_init_remote(unw_cursor_t*, unw_addr_space_t, diff --git a/contrib/llvm/projects/libunwind/src/AddressSpace.hpp b/contrib/llvm/projects/libunwind/src/AddressSpace.hpp index 74294a33bfa3..d9ea3db36c26 100644 --- a/contrib/llvm/projects/libunwind/src/AddressSpace.hpp +++ b/contrib/llvm/projects/libunwind/src/AddressSpace.hpp @@ -374,7 +374,7 @@ inline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, (_Unwind_Ptr) targetAddr, &length); info.arm_section_length = (uintptr_t)length; #endif - _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n", + _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x", info.arm_section, info.arm_section_length); if (info.arm_section && info.arm_section_length) return true; diff --git a/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp b/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp index f528fba984db..1be1b0be1292 100644 --- a/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp +++ b/contrib/llvm/projects/libunwind/src/CompactUnwinder.hpp @@ -105,7 +105,7 @@ int CompactUnwinder_x86::stepWithCompactEncodingEBPFrame( default: (void)functionStart; _LIBUNWIND_DEBUG_LOG("bad register for EBP frame, encoding=%08X for " - "function starting at 0x%X\n", + "function starting at 0x%X", compactEncoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -224,7 +224,7 @@ int CompactUnwinder_x86::stepWithCompactEncodingFrameless( break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " - "function starting at 0x%X\n", + "function starting at 0x%X", encoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -336,7 +336,7 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingRBPFrame( default: (void)functionStart; _LIBUNWIND_DEBUG_LOG("bad register for RBP frame, encoding=%08X for " - "function starting at 0x%llX\n", + "function starting at 0x%llX", compactEncoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } @@ -455,7 +455,7 @@ int CompactUnwinder_x86_64::stepWithCompactEncodingFrameless( break; default: _LIBUNWIND_DEBUG_LOG("bad register for frameless, encoding=%08X for " - "function starting at 0x%llX\n", + "function starting at 0x%llX", encoding, functionStart); _LIBUNWIND_ABORT("invalid compact unwind encoding"); } diff --git a/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp b/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp index 7945c7ba2fb0..6c3ccc863172 100644 --- a/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp +++ b/contrib/llvm/projects/libunwind/src/EHHeaderParser.hpp @@ -85,7 +85,7 @@ bool EHHeaderParser::decodeTableEntry( const char *message = CFI_Parser::decodeFDE(addressSpace, fde, fdeInfo, cieInfo); if (message != NULL) { - _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s\n", + _LIBUNWIND_DEBUG_LOG("EHHeaderParser::decodeTableEntry: bad fde: %s", message); return false; } diff --git a/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp b/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp index ca7b43e113a7..719bde166959 100644 --- a/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp +++ b/contrib/llvm/projects/libunwind/src/Unwind-EHABI.cpp @@ -454,7 +454,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_proc_info_t frameInfo; if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info " - "failed => _URC_FATAL_PHASE1_ERROR\n", + "failed => _URC_FATAL_PHASE1_ERROR", static_cast(exception_object)); return _URC_FATAL_PHASE1_ERROR; } @@ -472,7 +472,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_get_reg(cursor, UNW_REG_IP, &pc); _LIBUNWIND_TRACE_UNWINDING( "unwind_phase1(ex_ojb=%p): pc=0x%llX, start_ip=0x%llX, func=%s, " - "lsda=0x%llX, personality=0x%llX\n", + "lsda=0x%llX, personality=0x%llX", static_cast(exception_object), (long long)pc, (long long)frameInfo.start_ip, functionName, (long long)frameInfo.lsda, (long long)frameInfo.handler); @@ -484,7 +484,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except __personality_routine p = (__personality_routine)(long)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): calling personality function %p\n", + "unwind_phase1(ex_ojb=%p): calling personality function %p", static_cast(exception_object), reinterpret_cast(reinterpret_cast(p))); struct _Unwind_Context *context = (struct _Unwind_Context *)(cursor); @@ -496,7 +496,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except (*p)(_US_VIRTUAL_UNWIND_FRAME, exception_object, context); _LIBUNWIND_TRACE_UNWINDING( "unwind_phase1(ex_ojb=%p): personality result %d start_ip %x ehtp %p " - "additional %x\n", + "additional %x", static_cast(exception_object), personalityResult, exception_object->pr_cache.fnstart, static_cast(exception_object->pr_cache.ehtp), @@ -508,13 +508,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except handlerNotFound = false; // p should have initialized barrier_cache. EHABI #7.3.5 _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n", + "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND", static_cast(exception_object)); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", + "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", static_cast(exception_object)); // continue unwinding break; @@ -526,7 +526,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n", + "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", static_cast(exception_object)); return _URC_FATAL_PHASE1_ERROR; } @@ -541,13 +541,13 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor // See comment at the start of unwind_phase1 regarding VRS integrity. unw_init_local(cursor, uc); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", static_cast(exception_object)); int frame_count = 0; // Walk each frame until we reach where search phase said to stop. while (true) { - // Ask libuwind to get next frame (skip over first which is + // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException or _Unwind_Resume). // // Resume only ever makes sense for 1 frame. @@ -572,7 +572,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor unw_get_reg(cursor, UNW_REG_SP, &sp); if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info " - "failed => _URC_FATAL_PHASE2_ERROR\n", + "failed => _URC_FATAL_PHASE2_ERROR", static_cast(exception_object)); return _URC_FATAL_PHASE2_ERROR; } @@ -588,7 +588,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING( "unwind_phase2(ex_ojb=%p): start_ip=0x%llX, func=%s, sp=0x%llX, " - "lsda=0x%llX, personality=0x%llX\n", + "lsda=0x%llX, personality=0x%llX", static_cast(exception_object), (long long)frameInfo.start_ip, functionName, (long long)sp, (long long)frameInfo.lsda, (long long)frameInfo.handler); @@ -610,7 +610,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor case _URC_CONTINUE_UNWIND: // Continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", + "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", static_cast(exception_object)); // EHABI #7.2 if (sp == exception_object->barrier_cache.sp) { @@ -621,7 +621,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n", + "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", static_cast(exception_object)); // Personality routine says to transfer control to landing pad. // We may get control back if landing pad calls _Unwind_Resume(). @@ -630,7 +630,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor unw_get_reg(cursor, UNW_REG_IP, &pc); unw_get_reg(cursor, UNW_REG_SP, &sp); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering " - "user code with ip=0x%llX, sp=0x%llX\n", + "user code with ip=0x%llX, sp=0x%llX", static_cast(exception_object), (long long)pc, (long long)sp); } @@ -668,7 +668,7 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor /// Called by __cxa_throw. Only returns if there is a fatal error. _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", static_cast(exception_object)); unw_context_t uc; unw_cursor_t cursor; @@ -706,7 +706,7 @@ _LIBUNWIND_EXPORT void _Unwind_Complete(_Unwind_Exception* exception_object) { /// in turn calls _Unwind_Resume_or_Rethrow(). _LIBUNWIND_EXPORT void _Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", static_cast(exception_object)); unw_context_t uc; unw_cursor_t cursor; @@ -730,7 +730,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.lsda; _LIBUNWIND_TRACE_API( - "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx\n", + "_Unwind_GetLanguageSpecificData(context=%p) => 0x%llx", static_cast(context), (long long)result); return result; } @@ -758,7 +758,7 @@ _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t regno, _Unwind_VRS_DataRepresentation representation, void *valuep) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Set(context=%p, regclass=%d, reg=%d, " - "rep=%d, value=0x%llX)\n", + "rep=%d, value=0x%llX)", static_cast(context), regclass, regno, representation, ValueAsBitPattern(representation, valuep)); @@ -863,7 +863,7 @@ _Unwind_VRS_Result _Unwind_VRS_Get( _Unwind_VRS_Get_Internal(context, regclass, regno, representation, valuep); _LIBUNWIND_TRACE_API("_Unwind_VRS_Get(context=%p, regclass=%d, reg=%d, " - "rep=%d, value=0x%llX, result = %d)\n", + "rep=%d, value=0x%llX, result = %d)", static_cast(context), regclass, regno, representation, ValueAsBitPattern(representation, valuep), result); @@ -875,7 +875,7 @@ _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, uint32_t discriminator, _Unwind_VRS_DataRepresentation representation) { _LIBUNWIND_TRACE_API("_Unwind_VRS_Pop(context=%p, regclass=%d, " - "discriminator=%d, representation=%d)\n", + "discriminator=%d, representation=%d)", static_cast(context), regclass, discriminator, representation); switch (regclass) { @@ -948,7 +948,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { uintptr_t result = 0; if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.start_ip; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX\n", + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%llX", static_cast(context), (long long)result); return result; } @@ -958,7 +958,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { // is caught. _LIBUNWIND_EXPORT void _Unwind_DeleteException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", static_cast(exception_object)); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, diff --git a/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c b/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c index f9256b5a9260..89944a283cfb 100644 --- a/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c +++ b/contrib/llvm/projects/libunwind/src/Unwind-sjlj.c @@ -72,7 +72,7 @@ _Unwind_SjLj_Unregister(struct _Unwind_FunctionContext *fc) { static _Unwind_Reason_Code unwind_phase1(struct _Unwind_Exception *exception_object) { _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack(); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p\n", c); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: initial function-context=%p", c); // walk each frame looking for a place to stop for (bool handlerNotFound = true; handlerNotFound; c = c->prev) { @@ -80,17 +80,17 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { // check for no more frames if (c == NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): reached " - "bottom => _URC_END_OF_STACK\n", + "bottom => _URC_END_OF_STACK", exception_object); return _URC_END_OF_STACK; } - _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p\n", c); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase1: function-context=%p", c); // if there is a personality routine, ask it if it will want to stop at this // frame if (c->personality != NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): calling " - "personality function %p\n", + "personality function %p", exception_object, c->personality); _Unwind_Reason_Code personalityResult = (*c->personality)( 1, _UA_SEARCH_PHASE, exception_object->exception_class, @@ -102,19 +102,19 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { handlerNotFound = false; exception_object->private_2 = (uintptr_t) c; _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): " - "_URC_HANDLER_FOUND\n", exception_object); + "_URC_HANDLER_FOUND", exception_object); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): " - "_URC_CONTINUE_UNWIND\n", exception_object); + "_URC_CONTINUE_UNWIND", exception_object); // continue unwinding break; default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n", + "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -126,18 +126,18 @@ unwind_phase1(struct _Unwind_Exception *exception_object) { static _Unwind_Reason_Code unwind_phase2(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", exception_object); + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", exception_object); // walk each frame until we reach where search phase said to stop _Unwind_FunctionContext_t c = __Unwind_SjLj_GetTopOfFunctionStack(); while (true) { - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p\n", + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2s(ex_ojb=%p): context=%p", exception_object, c); // check for no more frames if (c == NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached " - "bottom => _URC_END_OF_STACK\n", + "bottom => _URC_END_OF_STACK", exception_object); return _URC_END_OF_STACK; } @@ -157,7 +157,7 @@ unwind_phase2(struct _Unwind_Exception *exception_object) { case _URC_CONTINUE_UNWIND: // continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", + "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", exception_object); if ((uintptr_t) c == exception_object->private_2) { // phase 1 said we would stop at this frame, but we did not... @@ -168,7 +168,7 @@ unwind_phase2(struct _Unwind_Exception *exception_object) { case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): " "_URC_INSTALL_CONTEXT, will resume at " - "landing pad %p\n", + "landing pad %p", exception_object, c->jbuf[1]); // personality routine says to transfer control to landing pad // we may get control back if landing pad calls _Unwind_Resume() @@ -202,7 +202,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, // get next frame (skip over first which is _Unwind_RaiseException) if (c == NULL) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached " - "bottom => _URC_END_OF_STACK\n", + "bottom => _URC_END_OF_STACK", exception_object); return _URC_END_OF_STACK; } @@ -214,11 +214,11 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, (*stop)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)c, stop_parameter); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "stop function returned %d\n", + "stop function returned %d", exception_object, stopResult); if (stopResult != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "stopped by stop function\n", + "stopped by stop function", exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -227,7 +227,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, if (c->personality != NULL) { __personality_routine p = (__personality_routine) c->personality; _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "calling personality function %p\n", + "calling personality function %p", exception_object, p); _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, @@ -235,13 +235,13 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, switch (personalityResult) { case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned _URC_CONTINUE_UNWIND\n", + "personality returned _URC_CONTINUE_UNWIND", exception_object); // destructors called, continue unwinding break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " - "personality returned _URC_INSTALL_CONTEXT\n", + "personality returned _URC_INSTALL_CONTEXT", exception_object); // we may get control back if landing pad calls _Unwind_Resume() __Unwind_SjLj_SetTopOfFunctionStack(c); @@ -251,7 +251,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, // something went wrong _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned %d, " - "_URC_FATAL_PHASE2_ERROR\n", + "_URC_FATAL_PHASE2_ERROR", exception_object, personalityResult); return _URC_FATAL_PHASE2_ERROR; } @@ -262,7 +262,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, // call stop function one last time and tell it we've reached the end of the // stack _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " - "function with _UA_END_OF_STACK\n", + "function with _UA_END_OF_STACK", exception_object); _Unwind_Action lastAction = (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK); @@ -278,7 +278,7 @@ unwind_phase2_forced(struct _Unwind_Exception *exception_object, /// Called by __cxa_throw. Only returns if there is a fatal error _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)\n", exception_object); + _LIBUNWIND_TRACE_API("_Unwind_SjLj_RaiseException(ex_obj=%p)", exception_object); // mark that this is a non-forced unwind, so _Unwind_Resume() can do the right // thing @@ -308,7 +308,7 @@ _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object) { /// __cxa_rethrow() which in turn calls _Unwind_Resume_or_Rethrow() _LIBUNWIND_EXPORT void _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)\n", exception_object); + _LIBUNWIND_TRACE_API("_Unwind_SjLj_Resume(ex_obj=%p)", exception_object); if (exception_object->private_1 != 0) unwind_phase2_forced(exception_object, @@ -326,7 +326,7 @@ _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object) { _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object) { _LIBUNWIND_TRACE_API("__Unwind_SjLj_Resume_or_Rethrow(ex_obj=%p), " - "private_1=%ld\n", + "private_1=%ld", exception_object, exception_object->private_1); // If this is non-forced and a stopping place was found, then this is a // re-throw. @@ -350,7 +350,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; _LIBUNWIND_TRACE_API("_Unwind_GetLanguageSpecificData(context=%p) " - "=> 0x%0lX\n", context, ufc->lsda); + "=> 0x%0lX", context, ufc->lsda); return ufc->lsda; } @@ -358,7 +358,7 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { /// Called by personality handler during phase 2 to get register values. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { - _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)\n", + _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d)", context, index); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; return ufc->resumeParameters[index]; @@ -368,7 +368,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, /// Called by personality handler during phase 2 to alter register values. _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, uintptr_t new_value) { - _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0lX)\n" + _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0lX)" , context, index, new_value); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; ufc->resumeParameters[index] = new_value; @@ -378,7 +378,7 @@ _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, /// Called by personality handler during phase 2 to get instruction pointer. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; - _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX\n", context, + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%lX", context, ufc->resumeLocation + 1); return ufc->resumeLocation + 1; } @@ -391,7 +391,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, int *ipBefore) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; *ipBefore = 0; - _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX\n", + _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p, %p) => 0x%lX", context, ipBefore, ufc->resumeLocation + 1); return ufc->resumeLocation + 1; } @@ -400,7 +400,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, /// Called by personality handler during phase 2 to alter instruction pointer. _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t new_value) { - _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0lX)\n", + _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0lX)", context, new_value); _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; ufc->resumeLocation = new_value - 1; @@ -413,7 +413,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context) { // Not supported or needed for sjlj based unwinding (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)\n", context); + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p)", context); return 0; } @@ -422,7 +422,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { /// is caught. _LIBUNWIND_EXPORT void _Unwind_DeleteException(struct _Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", exception_object); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, @@ -437,7 +437,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) { // Not supported or needed for sjlj based unwinding (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", context); + _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", context); _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); } @@ -448,14 +448,14 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) { // Not supported or needed for sjlj based unwinding (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", context); + _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", context); _LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented"); } /// Called by personality handler to get "Call Frame Area" for current frame. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { - _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)\n", context); + _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p)", context); if (context != NULL) { _Unwind_FunctionContext_t ufc = (_Unwind_FunctionContext_t) context; // Setjmp/longjmp based exceptions don't have a true CFA. diff --git a/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp b/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp index 7c217e1c1a01..6d1cfaa03003 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp +++ b/contrib/llvm/projects/libunwind/src/UnwindCursor.hpp @@ -6,7 +6,7 @@ // Source Licenses. See LICENSE.TXT for details. // // -// C++ interface to lower levels of libuwind +// C++ interface to lower levels of libunwind //===----------------------------------------------------------------------===// #ifndef __UNWINDCURSOR_HPP__ @@ -935,7 +935,7 @@ bool UnwindCursor::getInfoFromDwarfSection(pint_t pc, return true; } } - //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc); + //_LIBUNWIND_DEBUG_LOG("can't find/use FDE for pc=0x%llX", (uint64_t)pc); return false; } #endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND @@ -1092,13 +1092,13 @@ bool UnwindCursor::getInfoFromCompactEncodingSection(pint_t pc, funcEnd = firstLevelNextPageFunctionOffset + sects.dso_base; if (pc < funcStart) { _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second " - "level compressed unwind table. funcStart=0x%llX\n", + "level compressed unwind table. funcStart=0x%llX", (uint64_t) pc, (uint64_t) funcStart); return false; } if (pc > funcEnd) { _LIBUNWIND_DEBUG_LOG("malformed __unwind_info, pc=0x%llX not in second " - "level compressed unwind table. funcEnd=0x%llX\n", + "level compressed unwind table. funcEnd=0x%llX", (uint64_t) pc, (uint64_t) funcEnd); return false; } @@ -1119,7 +1119,7 @@ bool UnwindCursor::getInfoFromCompactEncodingSection(pint_t pc, } } else { _LIBUNWIND_DEBUG_LOG("malformed __unwind_info at 0x%0llX bad second " - "level page\n", + "level page", (uint64_t) sects.compact_unwind_section); return false; } @@ -1149,7 +1149,7 @@ bool UnwindCursor::getInfoFromCompactEncodingSection(pint_t pc, } if (lsda == 0) { _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with HAS_LSDA bit set for " - "pc=0x%0llX, but lsda table has no entry\n", + "pc=0x%0llX, but lsda table has no entry", encoding, (uint64_t) pc); return false; } @@ -1162,7 +1162,7 @@ bool UnwindCursor::getInfoFromCompactEncodingSection(pint_t pc, --personalityIndex; // change 1-based to zero-based index if (personalityIndex > sectionHeader.personalityArrayCount()) { _LIBUNWIND_DEBUG_LOG("found encoding 0x%08X with personality index %d, " - "but personality table has only %d entires\n", + "but personality table has only %d entires", encoding, personalityIndex, sectionHeader.personalityArrayCount()); return false; diff --git a/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c b/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c index 28ba0928121f..61af9e8eade8 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c +++ b/contrib/llvm/projects/libunwind/src/UnwindLevel1-gcc-ext.c @@ -29,11 +29,11 @@ _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) { #if _LIBUNWIND_ARM_EHABI - _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n", + _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld", (void *)exception_object, (long)exception_object->unwinder_cache.reserved1); #else - _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld\n", + _LIBUNWIND_TRACE_API("_Unwind_Resume_or_Rethrow(ex_obj=%p), private_1=%ld", (void *)exception_object, (long)exception_object->private_1); #endif @@ -66,7 +66,7 @@ _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object) { _LIBUNWIND_EXPORT uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) { (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)\n", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetDataRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetDataRelBase() not implemented"); } @@ -76,7 +76,7 @@ _Unwind_GetDataRelBase(struct _Unwind_Context *context) { _LIBUNWIND_EXPORT uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) { (void)context; - _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)\n", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetTextRelBase(context=%p)", (void *)context); _LIBUNWIND_ABORT("_Unwind_GetTextRelBase() not implemented"); } @@ -84,7 +84,7 @@ _Unwind_GetTextRelBase(struct _Unwind_Context *context) { /// Scans unwind information to find the function that contains the /// specified code address "pc". _LIBUNWIND_EXPORT void *_Unwind_FindEnclosingFunction(void *pc) { - _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)\n", pc); + _LIBUNWIND_TRACE_API("_Unwind_FindEnclosingFunction(pc=%p)", pc); // This is slow, but works. // We create an unwind cursor then alter the IP to be pc unw_cursor_t cursor; @@ -108,7 +108,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { unw_getcontext(&uc); unw_init_local(&cursor, &uc); - _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_Backtrace(callback=%p)", (void *)(uintptr_t)callback); #if _LIBUNWIND_ARM_EHABI @@ -123,11 +123,11 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { _Unwind_Reason_Code result; #if !_LIBUNWIND_ARM_EHABI - // ask libuwind to get next frame (skip over first frame which is + // ask libunwind to get next frame (skip over first frame which is // _Unwind_Backtrace()) if (unw_step(&cursor) <= 0) { _LIBUNWIND_TRACE_UNWINDING(" _backtrace: ended because cursor reached " - "bottom of stack, returning %d\n", + "bottom of stack, returning %d", _URC_END_OF_STACK); return _URC_END_OF_STACK; } @@ -164,7 +164,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { unw_get_proc_name(&cursor, functionName, 512, &offset); unw_get_proc_info(&cursor, &frame); _LIBUNWIND_TRACE_UNWINDING( - " _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p\n", + " _backtrace: start_ip=0x%llX, func=%s, lsda=0x%llX, context=%p", (long long)frame.start_ip, functionName, (long long)frame.lsda, (void *)&cursor); } @@ -173,7 +173,7 @@ _Unwind_Backtrace(_Unwind_Trace_Fn callback, void *ref) { result = (*callback)((struct _Unwind_Context *)(&cursor), ref); if (result != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING( - " _backtrace: ended because callback returned %d\n", result); + " _backtrace: ended because callback returned %d", result); return result; } } @@ -195,7 +195,7 @@ _LIBUNWIND_EXPORT const void *_Unwind_Find_FDE(const void *pc, bases->tbase = (uintptr_t)info.extra; bases->dbase = 0; // dbase not used on Mac OS X bases->func = (uintptr_t)info.start_ip; - _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p\n", pc, + _LIBUNWIND_TRACE_API("_Unwind_Find_FDE(pc=%p) => %p", pc, (void *)(long) info.unwind_info); return (void *)(long) info.unwind_info; } @@ -206,7 +206,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_word_t result; unw_get_reg(cursor, UNW_REG_SP, &result); - _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64 "\n", + _LIBUNWIND_TRACE_API("_Unwind_GetCFA(context=%p) => 0x%" PRIx64, (void *)context, (uint64_t)result); return (uintptr_t)result; } @@ -217,7 +217,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetCFA(struct _Unwind_Context *context) { /// site address. Normally IP is the return address. _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, int *ipBefore) { - _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)\n", (void *)context); + _LIBUNWIND_TRACE_API("_Unwind_GetIPInfo(context=%p)", (void *)context); *ipBefore = 0; return _Unwind_GetIP(context); } @@ -229,7 +229,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, /// This function has existed on Mac OS X since 10.4, but /// was broken until 10.6. _LIBUNWIND_EXPORT void __register_frame(const void *fde) { - _LIBUNWIND_TRACE_API("__register_frame(%p)\n", fde); + _LIBUNWIND_TRACE_API("__register_frame(%p)", fde); _unw_add_dynamic_fde((unw_word_t)(uintptr_t) fde); } @@ -239,7 +239,7 @@ _LIBUNWIND_EXPORT void __register_frame(const void *fde) { /// This function has existed on Mac OS X since 10.4, but /// was broken until 10.6. _LIBUNWIND_EXPORT void __deregister_frame(const void *fde) { - _LIBUNWIND_TRACE_API("__deregister_frame(%p)\n", fde); + _LIBUNWIND_TRACE_API("__deregister_frame(%p)", fde); _unw_remove_dynamic_fde((unw_word_t)(uintptr_t) fde); } @@ -259,7 +259,7 @@ _LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob, (void)ob; (void)tb; (void)db; - _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)\n", + _LIBUNWIND_TRACE_API("__register_frame_info_bases(%p,%p, %p, %p)", fde, ob, tb, db); // do nothing, this function never worked in Mac OS X } @@ -267,7 +267,7 @@ _LIBUNWIND_EXPORT void __register_frame_info_bases(const void *fde, void *ob, _LIBUNWIND_EXPORT void __register_frame_info(const void *fde, void *ob) { (void)fde; (void)ob; - _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)\n", fde, ob); + _LIBUNWIND_TRACE_API("__register_frame_info(%p, %p)", fde, ob); // do nothing, this function never worked in Mac OS X } @@ -279,33 +279,33 @@ _LIBUNWIND_EXPORT void __register_frame_info_table_bases(const void *fde, (void)tb; (void)db; _LIBUNWIND_TRACE_API("__register_frame_info_table_bases" - "(%p,%p, %p, %p)\n", fde, ob, tb, db); + "(%p,%p, %p, %p)", fde, ob, tb, db); // do nothing, this function never worked in Mac OS X } _LIBUNWIND_EXPORT void __register_frame_info_table(const void *fde, void *ob) { (void)fde; (void)ob; - _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)\n", fde, ob); + _LIBUNWIND_TRACE_API("__register_frame_info_table(%p, %p)", fde, ob); // do nothing, this function never worked in Mac OS X } _LIBUNWIND_EXPORT void __register_frame_table(const void *fde) { (void)fde; - _LIBUNWIND_TRACE_API("__register_frame_table(%p)\n", fde); + _LIBUNWIND_TRACE_API("__register_frame_table(%p)", fde); // do nothing, this function never worked in Mac OS X } _LIBUNWIND_EXPORT void *__deregister_frame_info(const void *fde) { (void)fde; - _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)\n", fde); + _LIBUNWIND_TRACE_API("__deregister_frame_info(%p)", fde); // do nothing, this function never worked in Mac OS X return NULL; } _LIBUNWIND_EXPORT void *__deregister_frame_info_bases(const void *fde) { (void)fde; - _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)\n", fde); + _LIBUNWIND_TRACE_API("__deregister_frame_info_bases(%p)", fde); // do nothing, this function never worked in Mac OS X return NULL; } diff --git a/contrib/llvm/projects/libunwind/src/UnwindLevel1.c b/contrib/llvm/projects/libunwind/src/UnwindLevel1.c index 7294f255407e..3f89e9c521cf 100644 --- a/contrib/llvm/projects/libunwind/src/UnwindLevel1.c +++ b/contrib/llvm/projects/libunwind/src/UnwindLevel1.c @@ -39,17 +39,17 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except // Walk each frame looking for a place to stop. bool handlerNotFound = true; while (handlerNotFound) { - // Ask libuwind to get next frame (skip over first which is + // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException). int stepResult = unw_step(cursor); if (stepResult == 0) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached " - "bottom => _URC_END_OF_STACK\n", + "bottom => _URC_END_OF_STACK", (void *)exception_object); return _URC_END_OF_STACK; } else if (stepResult < 0) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step failed => " - "_URC_FATAL_PHASE1_ERROR\n", + "_URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -59,7 +59,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_word_t sp; if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase1(ex_ojb=%p): unw_get_proc_info " - "failed => _URC_FATAL_PHASE1_ERROR\n", + "failed => _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -77,7 +77,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_get_reg(cursor, UNW_REG_IP, &pc); _LIBUNWIND_TRACE_UNWINDING( "unwind_phase1(ex_ojb=%p): pc=0x%" PRIx64 ", start_ip=0x%" PRIx64 - ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n", + ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "", (void *)exception_object, pc, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler); } @@ -88,7 +88,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except __personality_routine p = (__personality_routine)(long)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): calling personality function %p\n", + "unwind_phase1(ex_ojb=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); _Unwind_Reason_Code personalityResult = (*p)(1, _UA_SEARCH_PHASE, exception_object->exception_class, @@ -101,13 +101,13 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_get_reg(cursor, UNW_REG_SP, &sp); exception_object->private_2 = (uintptr_t)sp; _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND \n", + "unwind_phase1(ex_ojb=%p): _URC_HANDLER_FOUND", (void *)exception_object); return _URC_NO_REASON; case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", + "unwind_phase1(ex_ojb=%p): _URC_CONTINUE_UNWIND", (void *)exception_object); // continue unwinding break; @@ -115,7 +115,7 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except default: // something went wrong _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR\n", + "unwind_phase1(ex_ojb=%p): _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE1_ERROR; } @@ -129,23 +129,23 @@ static _Unwind_Reason_Code unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) { unw_init_local(cursor, uc); - _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)\n", + _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p)", (void *)exception_object); // Walk each frame until we reach where search phase said to stop. while (true) { - // Ask libuwind to get next frame (skip over first which is + // Ask libunwind to get next frame (skip over first which is // _Unwind_RaiseException). int stepResult = unw_step(cursor); if (stepResult == 0) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step() reached " - "bottom => _URC_END_OF_STACK\n", + "bottom => _URC_END_OF_STACK", (void *)exception_object); return _URC_END_OF_STACK; } else if (stepResult < 0) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_step failed => " - "_URC_FATAL_PHASE1_ERROR\n", + "_URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -156,7 +156,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_get_reg(cursor, UNW_REG_SP, &sp); if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): unw_get_proc_info " - "failed => _URC_FATAL_PHASE1_ERROR\n", + "failed => _URC_FATAL_PHASE1_ERROR", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -172,7 +172,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): start_ip=0x%" PRIx64 ", func=%s, sp=0x%" PRIx64 ", lsda=0x%" PRIx64 - ", personality=0x%" PRIx64 "\n", + ", personality=0x%" PRIx64, (void *)exception_object, frameInfo.start_ip, functionName, sp, frameInfo.lsda, frameInfo.handler); @@ -194,7 +194,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except case _URC_CONTINUE_UNWIND: // Continue unwinding _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND\n", + "unwind_phase2(ex_ojb=%p): _URC_CONTINUE_UNWIND", (void *)exception_object); if (sp == exception_object->private_2) { // Phase 1 said we would stop at this frame, but we did not... @@ -204,7 +204,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT\n", + "unwind_phase2(ex_ojb=%p): _URC_INSTALL_CONTEXT", (void *)exception_object); // Personality routine says to transfer control to landing pad. // We may get control back if landing pad calls _Unwind_Resume(). @@ -214,7 +214,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except unw_get_reg(cursor, UNW_REG_SP, &sp); _LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_ojb=%p): re-entering " "user code with ip=0x%" PRIx64 - ", sp=0x%" PRIx64 "\n", + ", sp=0x%" PRIx64, (void *)exception_object, pc, sp); } unw_resume(cursor); @@ -247,7 +247,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, unw_proc_info_t frameInfo; if (unw_get_proc_info(cursor, &frameInfo) != UNW_ESUCCESS) { _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): unw_step " - "failed => _URC_END_OF_STACK\n", + "failed => _URC_END_OF_STACK", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -263,7 +263,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, functionName = ".anonymous."; _LIBUNWIND_TRACE_UNWINDING( "unwind_phase2_forced(ex_ojb=%p): start_ip=0x%" PRIx64 - ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64 "\n", + ", func=%s, lsda=0x%" PRIx64 ", personality=0x%" PRIx64, (void *)exception_object, frameInfo.start_ip, functionName, frameInfo.lsda, frameInfo.handler); } @@ -275,11 +275,11 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, (*stop)(1, action, exception_object->exception_class, exception_object, (struct _Unwind_Context *)(cursor), stop_parameter); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stop function returned %d\n", + "unwind_phase2_forced(ex_ojb=%p): stop function returned %d", (void *)exception_object, stopResult); if (stopResult != _URC_NO_REASON) { _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): stopped by stop function\n", + "unwind_phase2_forced(ex_ojb=%p): stopped by stop function", (void *)exception_object); return _URC_FATAL_PHASE2_ERROR; } @@ -289,7 +289,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, __personality_routine p = (__personality_routine)(long)(frameInfo.handler); _LIBUNWIND_TRACE_UNWINDING( - "unwind_phase2_forced(ex_ojb=%p): calling personality function %p\n", + "unwind_phase2_forced(ex_ojb=%p): calling personality function %p", (void *)exception_object, (void *)(uintptr_t)p); _Unwind_Reason_Code personalityResult = (*p)(1, action, exception_object->exception_class, exception_object, @@ -298,14 +298,14 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, case _URC_CONTINUE_UNWIND: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned " - "_URC_CONTINUE_UNWIND\n", + "_URC_CONTINUE_UNWIND", (void *)exception_object); // Destructors called, continue unwinding break; case _URC_INSTALL_CONTEXT: _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned " - "_URC_INSTALL_CONTEXT\n", + "_URC_INSTALL_CONTEXT", (void *)exception_object); // We may get control back if landing pad calls _Unwind_Resume(). unw_resume(cursor); @@ -314,7 +314,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // Personality routine returned an unknown result code. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): " "personality returned %d, " - "_URC_FATAL_PHASE2_ERROR\n", + "_URC_FATAL_PHASE2_ERROR", (void *)exception_object, personalityResult); return _URC_FATAL_PHASE2_ERROR; } @@ -324,7 +324,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, // Call stop function one last time and tell it we've reached the end // of the stack. _LIBUNWIND_TRACE_UNWINDING("unwind_phase2_forced(ex_ojb=%p): calling stop " - "function with _UA_END_OF_STACK\n", + "function with _UA_END_OF_STACK", (void *)exception_object); _Unwind_Action lastAction = (_Unwind_Action)(_UA_FORCE_UNWIND | _UA_CLEANUP_PHASE | _UA_END_OF_STACK); @@ -340,7 +340,7 @@ unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor, /// Called by __cxa_throw. Only returns if there is a fatal error. _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_RaiseException(ex_obj=%p)", (void *)exception_object); unw_context_t uc; unw_cursor_t cursor; @@ -375,7 +375,7 @@ _Unwind_RaiseException(_Unwind_Exception *exception_object) { /// in turn calls _Unwind_Resume_or_Rethrow(). _LIBUNWIND_EXPORT void _Unwind_Resume(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)\n", (void *)exception_object); + _LIBUNWIND_TRACE_API("_Unwind_Resume(ex_obj=%p)", (void *)exception_object); unw_context_t uc; unw_cursor_t cursor; unw_getcontext(&uc); @@ -399,7 +399,7 @@ _Unwind_Resume(_Unwind_Exception *exception_object) { _LIBUNWIND_EXPORT _Unwind_Reason_Code _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, _Unwind_Stop_Fn stop, void *stop_parameter) { - _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_ForcedUnwind(ex_obj=%p, stop=%p)", (void *)exception_object, (void *)(uintptr_t)stop); unw_context_t uc; unw_cursor_t cursor; @@ -424,11 +424,11 @@ _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context) { if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.lsda; _LIBUNWIND_TRACE_API( - "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR "\n", + "_Unwind_GetLanguageSpecificData(context=%p) => 0x%" PRIxPTR, (void *)context, result); if (result != 0) { if (*((uint8_t *)result) != 0xFF) - _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF\n", + _LIBUNWIND_DEBUG_LOG("lsda at 0x%" PRIxPTR " does not start with 0xFF", result); } return result; @@ -444,7 +444,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { uintptr_t result = 0; if (unw_get_proc_info(cursor, &frameInfo) == UNW_ESUCCESS) result = (uintptr_t)frameInfo.start_ip; - _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR "\n", + _LIBUNWIND_TRACE_API("_Unwind_GetRegionStart(context=%p) => 0x%" PRIxPTR, (void *)context, result); return result; } @@ -454,7 +454,7 @@ _Unwind_GetRegionStart(struct _Unwind_Context *context) { // is caught. _LIBUNWIND_EXPORT void _Unwind_DeleteException(_Unwind_Exception *exception_object) { - _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)\n", + _LIBUNWIND_TRACE_API("_Unwind_DeleteException(ex_obj=%p)", (void *)exception_object); if (exception_object->exception_cleanup != NULL) (*exception_object->exception_cleanup)(_URC_FOREIGN_EXCEPTION_CAUGHT, @@ -467,7 +467,7 @@ _Unwind_GetGR(struct _Unwind_Context *context, int index) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_word_t result; unw_get_reg(cursor, index, &result); - _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64 "\n", + _LIBUNWIND_TRACE_API("_Unwind_GetGR(context=%p, reg=%d) => 0x%" PRIx64, (void *)context, index, (uint64_t)result); return (uintptr_t)result; } @@ -476,7 +476,7 @@ _Unwind_GetGR(struct _Unwind_Context *context, int index) { _LIBUNWIND_EXPORT void _Unwind_SetGR(struct _Unwind_Context *context, int index, uintptr_t value) { _LIBUNWIND_TRACE_API("_Unwind_SetGR(context=%p, reg=%d, value=0x%0" PRIx64 - ")\n", + ")", (void *)context, index, (uint64_t)value); unw_cursor_t *cursor = (unw_cursor_t *)context; unw_set_reg(cursor, index, value); @@ -487,7 +487,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { unw_cursor_t *cursor = (unw_cursor_t *)context; unw_word_t result; unw_get_reg(cursor, UNW_REG_IP, &result); - _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64 "\n", + _LIBUNWIND_TRACE_API("_Unwind_GetIP(context=%p) => 0x%" PRIx64, (void *)context, (uint64_t)result); return (uintptr_t)result; } @@ -497,7 +497,7 @@ _LIBUNWIND_EXPORT uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { /// start executing in the landing pad. _LIBUNWIND_EXPORT void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) { - _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")\n", + _LIBUNWIND_TRACE_API("_Unwind_SetIP(context=%p, value=0x%0" PRIx64 ")", (void *)context, (uint64_t)value); unw_cursor_t *cursor = (unw_cursor_t *)context; unw_set_reg(cursor, UNW_REG_IP, value); diff --git a/contrib/llvm/projects/libunwind/src/config.h b/contrib/llvm/projects/libunwind/src/config.h index 74c63f0cebf7..48bf0c519376 100644 --- a/contrib/llvm/projects/libunwind/src/config.h +++ b/contrib/llvm/projects/libunwind/src/config.h @@ -6,7 +6,7 @@ // Source Licenses. See LICENSE.TXT for details. // // -// Defines macros used within libuwind project. +// Defines macros used within libunwind project. // //===----------------------------------------------------------------------===// @@ -84,7 +84,7 @@ fflush(stderr); \ abort(); \ } while (0) -#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libuwind: " msg, __VA_ARGS__) +#define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) // Macros that define away in non-Debug builds #ifdef NDEBUG diff --git a/contrib/llvm/projects/libunwind/src/libunwind.cpp b/contrib/llvm/projects/libunwind/src/libunwind.cpp index f8a4e9144b76..f1c29f2d1022 100644 --- a/contrib/llvm/projects/libunwind/src/libunwind.cpp +++ b/contrib/llvm/projects/libunwind/src/libunwind.cpp @@ -1,4 +1,4 @@ -//===--------------------------- libuwind.cpp -----------------------------===// +//===--------------------------- libunwind.cpp ----------------------------===// // // The LLVM Compiler Infrastructure // @@ -42,7 +42,7 @@ extern int unw_getcontext(unw_context_t *); /// unw_getcontext(). _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor, unw_context_t *context) { - _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)\n", + _LIBUNWIND_TRACE_API("unw_init_local(cursor=%p, context=%p)", static_cast(cursor), static_cast(context)); #if defined(__i386__) @@ -159,7 +159,7 @@ _LIBUNWIND_EXPORT void unw_destroy_addr_space(unw_addr_space_t asp) { /// Get value of specified register at cursor position in stack frame. _LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_word_t *value) { - _LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)\n", + _LIBUNWIND_TRACE_API("unw_get_reg(cursor=%p, regNum=%d, &value=%p)", static_cast(cursor), regNum, static_cast(value)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -174,7 +174,7 @@ _LIBUNWIND_EXPORT int unw_get_reg(unw_cursor_t *cursor, unw_regnum_t regNum, /// Set value of specified register at cursor position in stack frame. _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_word_t value) { - _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)\n", + _LIBUNWIND_TRACE_API("unw_set_reg(cursor=%p, regNum=%d, value=0x%llX)", static_cast(cursor), regNum, (long long)value); typedef LocalAddressSpace::pint_t pint_t; AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -193,7 +193,7 @@ _LIBUNWIND_EXPORT int unw_set_reg(unw_cursor_t *cursor, unw_regnum_t regNum, /// Get value of specified float register at cursor position in stack frame. _LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_fpreg_t *value) { - _LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)\n", + _LIBUNWIND_TRACE_API("unw_get_fpreg(cursor=%p, regNum=%d, &value=%p)", static_cast(cursor), regNum, static_cast(value)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -209,10 +209,10 @@ _LIBUNWIND_EXPORT int unw_get_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, unw_fpreg_t value) { #if _LIBUNWIND_ARM_EHABI - _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)\n", + _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%llX)", static_cast(cursor), regNum, value); #else - _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)\n", + _LIBUNWIND_TRACE_API("unw_set_fpreg(cursor=%p, regNum=%d, value=%g)", static_cast(cursor), regNum, value); #endif AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -226,7 +226,7 @@ _LIBUNWIND_EXPORT int unw_set_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum, /// Move cursor to next frame. _LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_step(cursor=%p)\n", static_cast(cursor)); + _LIBUNWIND_TRACE_API("unw_step(cursor=%p)", static_cast(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->step(); } @@ -235,7 +235,7 @@ _LIBUNWIND_EXPORT int unw_step(unw_cursor_t *cursor) { /// Get unwind info at cursor position in stack frame. _LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor, unw_proc_info_t *info) { - _LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)\n", + _LIBUNWIND_TRACE_API("unw_get_proc_info(cursor=%p, &info=%p)", static_cast(cursor), static_cast(info)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->getInfo(info); @@ -248,7 +248,7 @@ _LIBUNWIND_EXPORT int unw_get_proc_info(unw_cursor_t *cursor, /// Resume execution at cursor position (aka longjump). _LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)\n", static_cast(cursor)); + _LIBUNWIND_TRACE_API("unw_resume(cursor=%p)", static_cast(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; co->jumpto(); return UNW_EUNSPEC; @@ -258,7 +258,7 @@ _LIBUNWIND_EXPORT int unw_resume(unw_cursor_t *cursor) { /// Get name of function at cursor position in stack frame. _LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf, size_t bufLen, unw_word_t *offset) { - _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)\n", + _LIBUNWIND_TRACE_API("unw_get_proc_name(cursor=%p, &buf=%p, bufLen=%lu)", static_cast(cursor), static_cast(buf), static_cast(bufLen)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; @@ -271,7 +271,7 @@ _LIBUNWIND_EXPORT int unw_get_proc_name(unw_cursor_t *cursor, char *buf, /// Checks if a register is a floating-point register. _LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) { - _LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)\n", + _LIBUNWIND_TRACE_API("unw_is_fpreg(cursor=%p, regNum=%d)", static_cast(cursor), regNum); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->validFloatReg(regNum); @@ -281,7 +281,7 @@ _LIBUNWIND_EXPORT int unw_is_fpreg(unw_cursor_t *cursor, unw_regnum_t regNum) { /// Checks if a register is a floating-point register. _LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor, unw_regnum_t regNum) { - _LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)\n", + _LIBUNWIND_TRACE_API("unw_regname(cursor=%p, regNum=%d)", static_cast(cursor), regNum); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->getRegisterName(regNum); @@ -290,7 +290,7 @@ _LIBUNWIND_EXPORT const char *unw_regname(unw_cursor_t *cursor, /// Checks if current frame is signal trampoline. _LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)\n", + _LIBUNWIND_TRACE_API("unw_is_signal_frame(cursor=%p)", static_cast(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->isSignalFrame(); @@ -299,7 +299,7 @@ _LIBUNWIND_EXPORT int unw_is_signal_frame(unw_cursor_t *cursor) { #ifdef __arm__ // Save VFP registers d0-d15 using FSTMIADX instead of FSTMIADD _LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) { - _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)\n", + _LIBUNWIND_TRACE_API("unw_fpreg_save_vfp_as_X(cursor=%p)", static_cast(cursor)); AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor; return co->saveVFPAsX(); @@ -311,7 +311,7 @@ _LIBUNWIND_EXPORT void unw_save_vfp_as_X(unw_cursor_t *cursor) { /// SPI: walks cached dwarf entries _LIBUNWIND_EXPORT void unw_iterate_dwarf_unwind_cache(void (*func)( unw_word_t ip_start, unw_word_t ip_end, unw_word_t fde, unw_word_t mh)) { - _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)\n", + _LIBUNWIND_TRACE_API("unw_iterate_dwarf_unwind_cache(func=%p)", reinterpret_cast(func)); DwarfFDECache::iterateCacheEntries(func); } From 020fe0de155dbdd602029ec16c5b118065ca7824 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 28 Oct 2016 02:09:45 +0000 Subject: [PATCH 154/235] [net80211] don't abort a background scan upon reception of a single packet. Full offload drivers don't need this behaviour - they do it in firmware. --- sys/net80211/ieee80211_scan_sw.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/net80211/ieee80211_scan_sw.c b/sys/net80211/ieee80211_scan_sw.c index 6313d46177dc..33e28868f97d 100644 --- a/sys/net80211/ieee80211_scan_sw.c +++ b/sys/net80211/ieee80211_scan_sw.c @@ -467,6 +467,11 @@ ieee80211_swscan_cancel_scan(struct ieee80211vap *vap) static void ieee80211_swscan_cancel_anyscan(struct ieee80211vap *vap) { + + /* XXX for now - just don't do this per packet. */ + if (vap->iv_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) + return; + cancel_scan(vap, 1, __func__); } From f6c2cdb12f02dd6bf5518fcd0da93263ff54c063 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Fri, 28 Oct 2016 02:10:07 +0000 Subject: [PATCH 155/235] [net80211] add comments! --- sys/net80211/ieee80211_scan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index 11cc8d992b41..c972e82b6fd1 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -443,6 +443,9 @@ ieee80211_cancel_scan(struct ieee80211vap *vap) /* * Cancel any scan currently going on. + * + * This is called during normal 802.11 data path to cancel + * a scan so a newly arrived normal data packet can be sent. */ void ieee80211_cancel_anyscan(struct ieee80211vap *vap) From 0cf2aff4fa3c5180fb756f72b12bbc70b28b21c5 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 05:31:34 +0000 Subject: [PATCH 156/235] hyperv/hn: Change header guardian; in preparation for the upcoming rename. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8352 --- sys/dev/hyperv/netvsc/hv_net_vsc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hv_net_vsc.h index 037d7f1f0a88..49b03e09b808 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.h +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.h @@ -28,8 +28,8 @@ * $FreeBSD$ */ -#ifndef __HV_NET_VSC_H__ -#define __HV_NET_VSC_H__ +#ifndef _HN_NVS_H_ +#define _HN_NVS_H_ struct hn_nvs_sendctx; struct vmbus_channel; @@ -103,4 +103,4 @@ int hn_nvs_send_rndis_ctrl(struct vmbus_channel *chan, extern struct hn_nvs_sendctx hn_nvs_sendctx_none; -#endif /* __HV_NET_VSC_H__ */ +#endif /* !_HN_NVS_H_ */ From e61005fedc45e5f75d00473f072506f563e6d3d0 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 05:56:23 +0000 Subject: [PATCH 157/235] hyperv/hn: Rename cleaned up NVS header file. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8353 --- sys/dev/hyperv/netvsc/{hv_net_vsc.h => hn_nvs.h} | 0 sys/dev/hyperv/netvsc/hv_net_vsc.c | 2 +- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 2 +- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename sys/dev/hyperv/netvsc/{hv_net_vsc.h => hn_nvs.h} (100%) diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.h b/sys/dev/hyperv/netvsc/hn_nvs.h similarity index 100% rename from sys/dev/hyperv/netvsc/hv_net_vsc.h rename to sys/dev/hyperv/netvsc/hn_nvs.h diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hv_net_vsc.c index 657c90b61236..0d8c75cbc079 100644 --- a/sys/dev/hyperv/netvsc/hv_net_vsc.c +++ b/sys/dev/hyperv/netvsc/hv_net_vsc.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include static int hn_nvs_conn_chim(struct hn_softc *); static int hn_nvs_conn_rxbuf(struct hn_softc *); diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index df3822031a5b..f34ed18e50c8 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -124,7 +124,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include "vmbus_if.h" diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index dead3a3f3826..d3ddc38d23a7 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #define HV_RF_RECVINFO_VLAN 0x1 From 68468712a76687af02803b52641122d4b2c79b2a Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 07:48:17 +0000 Subject: [PATCH 158/235] hyperv/hn: Rename cleaned up NVS source file. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8354 --- sys/conf/files.amd64 | 2 +- sys/conf/files.i386 | 2 +- sys/dev/hyperv/netvsc/{hv_net_vsc.c => hn_nvs.c} | 0 sys/modules/hyperv/netvsc/Makefile | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename sys/dev/hyperv/netvsc/{hv_net_vsc.c => hn_nvs.c} (100%) diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index be421d3d4581..40d185037f95 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -291,7 +291,7 @@ dev/hwpmc/hwpmc_uncore.c optional hwpmc dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc -dev/hyperv/netvsc/hv_net_vsc.c optional hyperv +dev/hyperv/netvsc/hn_nvs.c optional hyperv dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index cdf851a4bc3d..ba9622dc6b58 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -248,7 +248,7 @@ dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_ppro.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc -dev/hyperv/netvsc/hv_net_vsc.c optional hyperv +dev/hyperv/netvsc/hn_nvs.c optional hyperv dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv diff --git a/sys/dev/hyperv/netvsc/hv_net_vsc.c b/sys/dev/hyperv/netvsc/hn_nvs.c similarity index 100% rename from sys/dev/hyperv/netvsc/hv_net_vsc.c rename to sys/dev/hyperv/netvsc/hn_nvs.c diff --git a/sys/modules/hyperv/netvsc/Makefile b/sys/modules/hyperv/netvsc/Makefile index f28a59c8affe..ab8082096e66 100644 --- a/sys/modules/hyperv/netvsc/Makefile +++ b/sys/modules/hyperv/netvsc/Makefile @@ -4,7 +4,7 @@ ${.CURDIR}/../../../dev/hyperv/vmbus KMOD= hv_netvsc -SRCS= hv_net_vsc.c \ +SRCS= hn_nvs.c \ hv_netvsc_drv_freebsd.c \ hv_rndis_filter.c SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h vmbus_if.h From 96a98cbf141c199bd2cf30330a3db284258995b9 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 07:59:02 +0000 Subject: [PATCH 159/235] hyperv/hn: Nuke unnecessary indirection. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8355 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 5 +++-- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 7 ------- sys/dev/hyperv/netvsc/hv_rndis_filter.h | 2 -- sys/dev/hyperv/netvsc/if_hnvar.h | 1 - 4 files changed, 3 insertions(+), 12 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index f34ed18e50c8..026af419cafd 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -358,6 +358,7 @@ static void hn_chan_detach(struct hn_softc *, struct vmbus_channel *); static int hn_attach_subchans(struct hn_softc *); static void hn_detach_allchans(struct hn_softc *); static void hn_chan_callback(struct vmbus_channel *chan, void *xrxr); +static void hn_chan_rollup(struct hn_rx_ring *, struct hn_tx_ring *); static void hn_set_ring_inuse(struct hn_softc *, int); static int hn_synth_attach(struct hn_softc *, int); static void hn_synth_detach(struct hn_softc *); @@ -1188,7 +1189,7 @@ hn_tx_done(struct hn_nvs_sendctx *sndc, struct hn_softc *sc, } } -void +static void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) { #if defined(INET) || defined(INET6) @@ -4213,7 +4214,7 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) if (bufferlen > HN_PKTBUF_LEN) free(buffer, M_DEVBUF); - hv_rf_channel_rollup(rxr, rxr->hn_txr); + hn_chan_rollup(rxr, rxr->hn_txr); } static void diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index d3ddc38d23a7..8f77129696de 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -1352,10 +1352,3 @@ hn_rndis_detach(struct hn_softc *sc) /* Halt the RNDIS. */ hn_rndis_halt(sc); } - -void -hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr) -{ - - hn_chan_rollup(rxr, txr); -} diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hv_rndis_filter.h index 3ecda3b80d03..80d8183eef97 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.h @@ -42,7 +42,5 @@ struct hn_rx_ring; void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, const void *data, int dlen); -void hv_rf_channel_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); #endif /* __HV_RNDIS_FILTER_H__ */ - diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index a22197a138d1..abd18d565fcd 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -258,7 +258,6 @@ int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, const struct hn_recvinfo *info); -void hn_chan_rollup(struct hn_rx_ring *rxr, struct hn_tx_ring *txr); void hn_link_status_update(struct hn_softc *sc); void hn_network_change(struct hn_softc *sc); From 91938ebba8e201b4c18aeb1d38094cae6d7ead12 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 08:08:46 +0000 Subject: [PATCH 160/235] hyperv/hn: Reorganize RX path; mainly pull non-control code path up MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8356 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 372 +++++++++++++++++- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 342 +--------------- sys/dev/hyperv/netvsc/hv_rndis_filter.h | 13 +- sys/dev/hyperv/netvsc/if_hnvar.h | 16 - 4 files changed, 364 insertions(+), 379 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 026af419cafd..83907b1f09bc 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -166,6 +166,16 @@ __FBSDID("$FreeBSD$"); #define HN_EARLY_TXEOF_THRESH 8 +#define HN_RXINFO_VLAN 0x0001 +#define HN_RXINFO_CSUM 0x0002 +#define HN_RXINFO_HASHINF 0x0004 +#define HN_RXINFO_HASHVAL 0x0008 +#define HN_RXINFO_ALL \ + (HN_RXINFO_VLAN | \ + HN_RXINFO_CSUM | \ + HN_RXINFO_HASHINF | \ + HN_RXINFO_HASHVAL) + struct hn_txdesc { #ifndef HN_USE_TXDESC_BUFRING SLIST_ENTRY(hn_txdesc) link; @@ -188,6 +198,17 @@ struct hn_txdesc { #define HN_TXD_FLAG_ONLIST 0x1 #define HN_TXD_FLAG_DMAMAP 0x2 +#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff +#define HN_NDIS_RXCSUM_INFO_INVALID 0 +#define HN_NDIS_HASH_INFO_INVALID 0 + +struct hn_rxinfo { + uint32_t vlan_info; + uint32_t csum_info; + uint32_t hash_info; + uint32_t hash_value; +}; + #define HN_LRO_LENLIM_MULTIRX_DEF (12 * ETHERMTU) #define HN_LRO_LENLIM_DEF (25 * ETHERMTU) /* YYY 2*MTU is a bit rough, but should be good enough. */ @@ -377,12 +398,18 @@ static void hn_link_status(struct hn_softc *); static int hn_sendpkt_rndis_sglist(struct hn_tx_ring *, struct hn_txdesc *); static int hn_sendpkt_rndis_chim(struct hn_tx_ring *, struct hn_txdesc *); static int hn_set_rxfilter(struct hn_softc *); +static void hn_link_status_update(struct hn_softc *); +static void hn_network_change(struct hn_softc *); + +static int hn_rndis_rxinfo(const void *, int, struct hn_rxinfo *); +static void hn_rndis_rx_data(struct hn_rx_ring *, const void *, int); +static void hn_rndis_rx_status(struct hn_softc *, const void *, int); static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt); static void hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkt); -static void hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr, +static void hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr); static void hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid); @@ -1006,7 +1033,7 @@ hn_netchg_status_taskfunc(void *xsc, int pending __unused) hn_link_status(sc); } -void +static void hn_link_status_update(struct hn_softc *sc) { @@ -1014,7 +1041,7 @@ hn_link_status_update(struct hn_softc *sc) taskqueue_enqueue(sc->hn_mgmt_taskq, &sc->hn_link_task); } -void +static void hn_network_change(struct hn_softc *sc) { @@ -1615,15 +1642,9 @@ hn_lro_rx(struct lro_ctrl *lc, struct mbuf *m) } #endif -/* - * Called when we receive a data packet from the "wire" on the - * specified device - * - * Note: This is no longer used as a callback - */ -int +static int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, - const struct hn_recvinfo *info) + const struct hn_rxinfo *info) { struct ifnet *ifp = rxr->hn_ifp; struct mbuf *m_new; @@ -4025,6 +4046,325 @@ hn_resume(struct hn_softc *sc) hn_resume_mgmt(sc); } +static void +hn_rndis_rx_status(struct hn_softc *sc, const void *data, int dlen) +{ + const struct rndis_status_msg *msg; + int ofs; + + if (dlen < sizeof(*msg)) { + if_printf(sc->hn_ifp, "invalid RNDIS status\n"); + return; + } + msg = data; + + switch (msg->rm_status) { + case RNDIS_STATUS_MEDIA_CONNECT: + case RNDIS_STATUS_MEDIA_DISCONNECT: + hn_link_status_update(sc); + break; + + case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG: + /* Not really useful; ignore. */ + break; + + case RNDIS_STATUS_NETWORK_CHANGE: + ofs = RNDIS_STBUFOFFSET_ABS(msg->rm_stbufoffset); + if (dlen < ofs + msg->rm_stbuflen || + msg->rm_stbuflen < sizeof(uint32_t)) { + if_printf(sc->hn_ifp, "network changed\n"); + } else { + uint32_t change; + + memcpy(&change, ((const uint8_t *)msg) + ofs, + sizeof(change)); + if_printf(sc->hn_ifp, "network changed, change %u\n", + change); + } + hn_network_change(sc); + break; + + default: + if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n", + msg->rm_status); + break; + } +} + +static int +hn_rndis_rxinfo(const void *info_data, int info_dlen, struct hn_rxinfo *info) +{ + const struct rndis_pktinfo *pi = info_data; + uint32_t mask = 0; + + while (info_dlen != 0) { + const void *data; + uint32_t dlen; + + if (__predict_false(info_dlen < sizeof(*pi))) + return (EINVAL); + if (__predict_false(info_dlen < pi->rm_size)) + return (EINVAL); + info_dlen -= pi->rm_size; + + if (__predict_false(pi->rm_size & RNDIS_PKTINFO_SIZE_ALIGNMASK)) + return (EINVAL); + if (__predict_false(pi->rm_size < pi->rm_pktinfooffset)) + return (EINVAL); + dlen = pi->rm_size - pi->rm_pktinfooffset; + data = pi->rm_data; + + switch (pi->rm_type) { + case NDIS_PKTINFO_TYPE_VLAN: + if (__predict_false(dlen < NDIS_VLAN_INFO_SIZE)) + return (EINVAL); + info->vlan_info = *((const uint32_t *)data); + mask |= HN_RXINFO_VLAN; + break; + + case NDIS_PKTINFO_TYPE_CSUM: + if (__predict_false(dlen < NDIS_RXCSUM_INFO_SIZE)) + return (EINVAL); + info->csum_info = *((const uint32_t *)data); + mask |= HN_RXINFO_CSUM; + break; + + case HN_NDIS_PKTINFO_TYPE_HASHVAL: + if (__predict_false(dlen < HN_NDIS_HASH_VALUE_SIZE)) + return (EINVAL); + info->hash_value = *((const uint32_t *)data); + mask |= HN_RXINFO_HASHVAL; + break; + + case HN_NDIS_PKTINFO_TYPE_HASHINF: + if (__predict_false(dlen < HN_NDIS_HASH_INFO_SIZE)) + return (EINVAL); + info->hash_info = *((const uint32_t *)data); + mask |= HN_RXINFO_HASHINF; + break; + + default: + goto next; + } + + if (mask == HN_RXINFO_ALL) { + /* All found; done */ + break; + } +next: + pi = (const struct rndis_pktinfo *) + ((const uint8_t *)pi + pi->rm_size); + } + + /* + * Final fixup. + * - If there is no hash value, invalidate the hash info. + */ + if ((mask & HN_RXINFO_HASHVAL) == 0) + info->hash_info = HN_NDIS_HASH_INFO_INVALID; + return (0); +} + +static __inline bool +hn_rndis_check_overlap(int off, int len, int check_off, int check_len) +{ + + if (off < check_off) { + if (__predict_true(off + len <= check_off)) + return (false); + } else if (off > check_off) { + if (__predict_true(check_off + check_len <= off)) + return (false); + } + return (true); +} + +static void +hn_rndis_rx_data(struct hn_rx_ring *rxr, const void *data, int dlen) +{ + const struct rndis_packet_msg *pkt; + struct hn_rxinfo info; + int data_off, pktinfo_off, data_len, pktinfo_len; + + /* + * Check length. + */ + if (__predict_false(dlen < sizeof(*pkt))) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg\n"); + return; + } + pkt = data; + + if (__predict_false(dlen < pkt->rm_len)) { + if_printf(rxr->hn_ifp, "truncated RNDIS packet msg, " + "dlen %d, msglen %u\n", dlen, pkt->rm_len); + return; + } + if (__predict_false(pkt->rm_len < + pkt->rm_datalen + pkt->rm_oobdatalen + pkt->rm_pktinfolen)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msglen, " + "msglen %u, data %u, oob %u, pktinfo %u\n", + pkt->rm_len, pkt->rm_datalen, pkt->rm_oobdatalen, + pkt->rm_pktinfolen); + return; + } + if (__predict_false(pkt->rm_datalen == 0)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, no data\n"); + return; + } + + /* + * Check offests. + */ +#define IS_OFFSET_INVALID(ofs) \ + ((ofs) < RNDIS_PACKET_MSG_OFFSET_MIN || \ + ((ofs) & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK)) + + /* XXX Hyper-V does not meet data offset alignment requirement */ + if (__predict_false(pkt->rm_dataoffset < RNDIS_PACKET_MSG_OFFSET_MIN)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "data offset %u\n", pkt->rm_dataoffset); + return; + } + if (__predict_false(pkt->rm_oobdataoffset > 0 && + IS_OFFSET_INVALID(pkt->rm_oobdataoffset))) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob offset %u\n", pkt->rm_oobdataoffset); + return; + } + if (__predict_true(pkt->rm_pktinfooffset > 0) && + __predict_false(IS_OFFSET_INVALID(pkt->rm_pktinfooffset))) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "pktinfo offset %u\n", pkt->rm_pktinfooffset); + return; + } + +#undef IS_OFFSET_INVALID + + data_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_dataoffset); + data_len = pkt->rm_datalen; + pktinfo_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_pktinfooffset); + pktinfo_len = pkt->rm_pktinfolen; + + /* + * Check OOB coverage. + */ + if (__predict_false(pkt->rm_oobdatalen != 0)) { + int oob_off, oob_len; + + if_printf(rxr->hn_ifp, "got oobdata\n"); + oob_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_oobdataoffset); + oob_len = pkt->rm_oobdatalen; + + if (__predict_false(oob_off + oob_len > pkt->rm_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob overflow, msglen %u, oob abs %d len %d\n", + pkt->rm_len, oob_off, oob_len); + return; + } + + /* + * Check against data. + */ + if (hn_rndis_check_overlap(oob_off, oob_len, + data_off, data_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob overlaps data, oob abs %d len %d, " + "data abs %d len %d\n", + oob_off, oob_len, data_off, data_len); + return; + } + + /* + * Check against pktinfo. + */ + if (pktinfo_len != 0 && + hn_rndis_check_overlap(oob_off, oob_len, + pktinfo_off, pktinfo_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "oob overlaps pktinfo, oob abs %d len %d, " + "pktinfo abs %d len %d\n", + oob_off, oob_len, pktinfo_off, pktinfo_len); + return; + } + } + + /* + * Check per-packet-info coverage and find useful per-packet-info. + */ + info.vlan_info = HN_NDIS_VLAN_INFO_INVALID; + info.csum_info = HN_NDIS_RXCSUM_INFO_INVALID; + info.hash_info = HN_NDIS_HASH_INFO_INVALID; + if (__predict_true(pktinfo_len != 0)) { + bool overlap; + int error; + + if (__predict_false(pktinfo_off + pktinfo_len > pkt->rm_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "pktinfo overflow, msglen %u, " + "pktinfo abs %d len %d\n", + pkt->rm_len, pktinfo_off, pktinfo_len); + return; + } + + /* + * Check packet info coverage. + */ + overlap = hn_rndis_check_overlap(pktinfo_off, pktinfo_len, + data_off, data_len); + if (__predict_false(overlap)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "pktinfo overlap data, pktinfo abs %d len %d, " + "data abs %d len %d\n", + pktinfo_off, pktinfo_len, data_off, data_len); + return; + } + + /* + * Find useful per-packet-info. + */ + error = hn_rndis_rxinfo(((const uint8_t *)pkt) + pktinfo_off, + pktinfo_len, &info); + if (__predict_false(error)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg " + "pktinfo\n"); + return; + } + } + + if (__predict_false(data_off + data_len > pkt->rm_len)) { + if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " + "data overflow, msglen %u, data abs %d len %d\n", + pkt->rm_len, data_off, data_len); + return; + } + hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); +} + +static __inline void +hn_rndis_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen) +{ + const struct rndis_msghdr *hdr; + + if (__predict_false(dlen < sizeof(*hdr))) { + if_printf(rxr->hn_ifp, "invalid RNDIS msg\n"); + return; + } + hdr = data; + + if (__predict_true(hdr->rm_type == REMOTE_NDIS_PACKET_MSG)) { + /* Hot data path. */ + hn_rndis_rx_data(rxr, data, dlen); + /* Done! */ + return; + } + + if (hdr->rm_type == REMOTE_NDIS_INDICATE_STATUS_MSG) + hn_rndis_rx_status(rxr->hn_ifp->if_softc, data, dlen); + else + hn_rndis_rx_ctrl(rxr->hn_ifp->if_softc, data, dlen); +} + static void hn_nvs_handle_notify(struct hn_softc *sc, const struct vmbus_chanpkt_hdr *pkt) { @@ -4060,8 +4400,8 @@ hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan, } static void -hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr, - struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr) +hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan, + const struct vmbus_chanpkt_hdr *pkthdr) { const struct vmbus_chanpkt_rxbuf *pkt; const struct hn_nvs_hdr *nvs_hdr; @@ -4111,9 +4451,9 @@ hn_nvs_handle_rxbuf(struct hn_softc *sc, struct hn_rx_ring *rxr, "ofs %d, len %d\n", i, ofs, len); continue; } - hv_rf_on_receive(sc, rxr, rxr->hn_rxbuf + ofs, len); + hn_rndis_rxpkt(rxr, rxr->hn_rxbuf + ofs, len); } - + /* * Moved completion call back here so that all received * messages (not just data messages) will trigger a response @@ -4177,7 +4517,7 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) hn_nvs_handle_comp(sc, chan, pkt); break; case VMBUS_CHANPKT_TYPE_RXBUF: - hn_nvs_handle_rxbuf(sc, rxr, chan, pkt); + hn_nvs_handle_rxbuf(rxr, chan, pkt); break; case VMBUS_CHANPKT_TYPE_INBAND: hn_nvs_handle_notify(sc, pkt); diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index 8f77129696de..119f1efbac12 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -59,16 +59,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define HV_RF_RECVINFO_VLAN 0x1 -#define HV_RF_RECVINFO_CSUM 0x2 -#define HV_RF_RECVINFO_HASHINF 0x4 -#define HV_RF_RECVINFO_HASHVAL 0x8 -#define HV_RF_RECVINFO_ALL \ - (HV_RF_RECVINFO_VLAN | \ - HV_RF_RECVINFO_CSUM | \ - HV_RF_RECVINFO_HASHINF | \ - HV_RF_RECVINFO_HASHVAL) - #define HN_RNDIS_RID_COMPAT_MASK 0xffff #define HN_RNDIS_RID_COMPAT_MAX HN_RNDIS_RID_COMPAT_MASK @@ -89,11 +79,6 @@ __FBSDID("$FreeBSD$"); /* * Forward declarations */ -static void hv_rf_receive_indicate_status(struct hn_softc *sc, - const void *data, int dlen); -static void hv_rf_receive_data(struct hn_rx_ring *rxr, - const void *data, int dlen); - static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, const void *idata, size_t idlen, void *odata, size_t *odlen0); static int hn_rndis_query2(struct hn_softc *sc, uint32_t oid, @@ -155,335 +140,22 @@ hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, return (pi->rm_data); } -/* - * RNDIS filter receive indicate status - */ -static void -hv_rf_receive_indicate_status(struct hn_softc *sc, const void *data, int dlen) -{ - const struct rndis_status_msg *msg; - int ofs; - - if (dlen < sizeof(*msg)) { - if_printf(sc->hn_ifp, "invalid RNDIS status\n"); - return; - } - msg = data; - - switch (msg->rm_status) { - case RNDIS_STATUS_MEDIA_CONNECT: - case RNDIS_STATUS_MEDIA_DISCONNECT: - hn_link_status_update(sc); - break; - - case RNDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG: - /* Not really useful; ignore. */ - break; - - case RNDIS_STATUS_NETWORK_CHANGE: - ofs = RNDIS_STBUFOFFSET_ABS(msg->rm_stbufoffset); - if (dlen < ofs + msg->rm_stbuflen || - msg->rm_stbuflen < sizeof(uint32_t)) { - if_printf(sc->hn_ifp, "network changed\n"); - } else { - uint32_t change; - - memcpy(&change, ((const uint8_t *)msg) + ofs, - sizeof(change)); - if_printf(sc->hn_ifp, "network changed, change %u\n", - change); - } - hn_network_change(sc); - break; - - default: - /* TODO: */ - if_printf(sc->hn_ifp, "unknown RNDIS status 0x%08x\n", - msg->rm_status); - break; - } -} - -static int -hn_rndis_rxinfo(const void *info_data, int info_dlen, struct hn_recvinfo *info) -{ - const struct rndis_pktinfo *pi = info_data; - uint32_t mask = 0; - - while (info_dlen != 0) { - const void *data; - uint32_t dlen; - - if (__predict_false(info_dlen < sizeof(*pi))) - return (EINVAL); - if (__predict_false(info_dlen < pi->rm_size)) - return (EINVAL); - info_dlen -= pi->rm_size; - - if (__predict_false(pi->rm_size & RNDIS_PKTINFO_SIZE_ALIGNMASK)) - return (EINVAL); - if (__predict_false(pi->rm_size < pi->rm_pktinfooffset)) - return (EINVAL); - dlen = pi->rm_size - pi->rm_pktinfooffset; - data = pi->rm_data; - - switch (pi->rm_type) { - case NDIS_PKTINFO_TYPE_VLAN: - if (__predict_false(dlen < NDIS_VLAN_INFO_SIZE)) - return (EINVAL); - info->vlan_info = *((const uint32_t *)data); - mask |= HV_RF_RECVINFO_VLAN; - break; - - case NDIS_PKTINFO_TYPE_CSUM: - if (__predict_false(dlen < NDIS_RXCSUM_INFO_SIZE)) - return (EINVAL); - info->csum_info = *((const uint32_t *)data); - mask |= HV_RF_RECVINFO_CSUM; - break; - - case HN_NDIS_PKTINFO_TYPE_HASHVAL: - if (__predict_false(dlen < HN_NDIS_HASH_VALUE_SIZE)) - return (EINVAL); - info->hash_value = *((const uint32_t *)data); - mask |= HV_RF_RECVINFO_HASHVAL; - break; - - case HN_NDIS_PKTINFO_TYPE_HASHINF: - if (__predict_false(dlen < HN_NDIS_HASH_INFO_SIZE)) - return (EINVAL); - info->hash_info = *((const uint32_t *)data); - mask |= HV_RF_RECVINFO_HASHINF; - break; - - default: - goto next; - } - - if (mask == HV_RF_RECVINFO_ALL) { - /* All found; done */ - break; - } -next: - pi = (const struct rndis_pktinfo *) - ((const uint8_t *)pi + pi->rm_size); - } - - /* - * Final fixup. - * - If there is no hash value, invalidate the hash info. - */ - if ((mask & HV_RF_RECVINFO_HASHVAL) == 0) - info->hash_info = HN_NDIS_HASH_INFO_INVALID; - return (0); -} - -static __inline bool -hn_rndis_check_overlap(int off, int len, int check_off, int check_len) -{ - - if (off < check_off) { - if (__predict_true(off + len <= check_off)) - return (false); - } else if (off > check_off) { - if (__predict_true(check_off + check_len <= off)) - return (false); - } - return (true); -} - -/* - * RNDIS filter receive data - */ -static void -hv_rf_receive_data(struct hn_rx_ring *rxr, const void *data, int dlen) -{ - const struct rndis_packet_msg *pkt; - struct hn_recvinfo info; - int data_off, pktinfo_off, data_len, pktinfo_len; - - /* - * Check length. - */ - if (__predict_false(dlen < sizeof(*pkt))) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg\n"); - return; - } - pkt = data; - - if (__predict_false(dlen < pkt->rm_len)) { - if_printf(rxr->hn_ifp, "truncated RNDIS packet msg, " - "dlen %d, msglen %u\n", dlen, pkt->rm_len); - return; - } - if (__predict_false(pkt->rm_len < - pkt->rm_datalen + pkt->rm_oobdatalen + pkt->rm_pktinfolen)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msglen, " - "msglen %u, data %u, oob %u, pktinfo %u\n", - pkt->rm_len, pkt->rm_datalen, pkt->rm_oobdatalen, - pkt->rm_pktinfolen); - return; - } - if (__predict_false(pkt->rm_datalen == 0)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, no data\n"); - return; - } - - /* - * Check offests. - */ -#define IS_OFFSET_INVALID(ofs) \ - ((ofs) < RNDIS_PACKET_MSG_OFFSET_MIN || \ - ((ofs) & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK)) - - /* XXX Hyper-V does not meet data offset alignment requirement */ - if (__predict_false(pkt->rm_dataoffset < RNDIS_PACKET_MSG_OFFSET_MIN)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "data offset %u\n", pkt->rm_dataoffset); - return; - } - if (__predict_false(pkt->rm_oobdataoffset > 0 && - IS_OFFSET_INVALID(pkt->rm_oobdataoffset))) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "oob offset %u\n", pkt->rm_oobdataoffset); - return; - } - if (__predict_true(pkt->rm_pktinfooffset > 0) && - __predict_false(IS_OFFSET_INVALID(pkt->rm_pktinfooffset))) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "pktinfo offset %u\n", pkt->rm_pktinfooffset); - return; - } - -#undef IS_OFFSET_INVALID - - data_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_dataoffset); - data_len = pkt->rm_datalen; - pktinfo_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_pktinfooffset); - pktinfo_len = pkt->rm_pktinfolen; - - /* - * Check OOB coverage. - */ - if (__predict_false(pkt->rm_oobdatalen != 0)) { - int oob_off, oob_len; - - if_printf(rxr->hn_ifp, "got oobdata\n"); - oob_off = RNDIS_PACKET_MSG_OFFSET_ABS(pkt->rm_oobdataoffset); - oob_len = pkt->rm_oobdatalen; - - if (__predict_false(oob_off + oob_len > pkt->rm_len)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "oob overflow, msglen %u, oob abs %d len %d\n", - pkt->rm_len, oob_off, oob_len); - return; - } - - /* - * Check against data. - */ - if (hn_rndis_check_overlap(oob_off, oob_len, - data_off, data_len)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "oob overlaps data, oob abs %d len %d, " - "data abs %d len %d\n", - oob_off, oob_len, data_off, data_len); - return; - } - - /* - * Check against pktinfo. - */ - if (pktinfo_len != 0 && - hn_rndis_check_overlap(oob_off, oob_len, - pktinfo_off, pktinfo_len)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "oob overlaps pktinfo, oob abs %d len %d, " - "pktinfo abs %d len %d\n", - oob_off, oob_len, pktinfo_off, pktinfo_len); - return; - } - } - - /* - * Check per-packet-info coverage and find useful per-packet-info. - */ - info.vlan_info = HN_NDIS_VLAN_INFO_INVALID; - info.csum_info = HN_NDIS_RXCSUM_INFO_INVALID; - info.hash_info = HN_NDIS_HASH_INFO_INVALID; - if (__predict_true(pktinfo_len != 0)) { - bool overlap; - int error; - - if (__predict_false(pktinfo_off + pktinfo_len > pkt->rm_len)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "pktinfo overflow, msglen %u, " - "pktinfo abs %d len %d\n", - pkt->rm_len, pktinfo_off, pktinfo_len); - return; - } - - /* - * Check packet info coverage. - */ - overlap = hn_rndis_check_overlap(pktinfo_off, pktinfo_len, - data_off, data_len); - if (__predict_false(overlap)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "pktinfo overlap data, pktinfo abs %d len %d, " - "data abs %d len %d\n", - pktinfo_off, pktinfo_len, data_off, data_len); - return; - } - - /* - * Find useful per-packet-info. - */ - error = hn_rndis_rxinfo(((const uint8_t *)pkt) + pktinfo_off, - pktinfo_len, &info); - if (__predict_false(error)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg " - "pktinfo\n"); - return; - } - } - - if (__predict_false(data_off + data_len > pkt->rm_len)) { - if_printf(rxr->hn_ifp, "invalid RNDIS packet msg, " - "data overflow, msglen %u, data abs %d len %d\n", - pkt->rm_len, data_off, data_len); - return; - } - hn_rxpkt(rxr, ((const uint8_t *)pkt) + data_off, data_len, &info); -} - -/* - * RNDIS filter on receive - */ void -hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, - const void *data, int dlen) +hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, int dlen) { const struct rndis_comp_hdr *comp; const struct rndis_msghdr *hdr; - if (__predict_false(dlen < sizeof(*hdr))) { - if_printf(rxr->hn_ifp, "invalid RNDIS msg\n"); - return; - } + KASSERT(dlen >= sizeof(*hdr), ("invalid RNDIS msg\n")); hdr = data; switch (hdr->rm_type) { - case REMOTE_NDIS_PACKET_MSG: - hv_rf_receive_data(rxr, data, dlen); - break; - case REMOTE_NDIS_INITIALIZE_CMPLT: case REMOTE_NDIS_QUERY_CMPLT: case REMOTE_NDIS_SET_CMPLT: case REMOTE_NDIS_KEEPALIVE_CMPLT: /* unused */ if (dlen < sizeof(*comp)) { - if_printf(rxr->hn_ifp, "invalid RNDIS cmplt\n"); + if_printf(sc->hn_ifp, "invalid RNDIS cmplt\n"); return; } comp = data; @@ -493,10 +165,6 @@ hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, vmbus_xact_ctx_wakeup(sc->hn_xact, comp, dlen); break; - case REMOTE_NDIS_INDICATE_STATUS_MSG: - hv_rf_receive_indicate_status(sc, data, dlen); - break; - case REMOTE_NDIS_RESET_CMPLT: /* * Reset completed, no rid. @@ -505,11 +173,11 @@ hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, * RESET is not issued by hn(4), so this message should * _not_ be observed. */ - if_printf(rxr->hn_ifp, "RESET cmplt received\n"); + if_printf(sc->hn_ifp, "RESET cmplt received\n"); break; default: - if_printf(rxr->hn_ifp, "unknown RNDIS msg 0x%x\n", + if_printf(sc->hn_ifp, "unknown RNDIS msg 0x%x\n", hdr->rm_type); break; } diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hv_rndis_filter.h index 80d8183eef97..cba4ae255e2f 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.h @@ -31,16 +31,9 @@ #ifndef __HV_RNDIS_FILTER_H__ #define __HV_RNDIS_FILTER_H__ -#include -#include -#include +struct hn_softc; -/* - * Externs - */ -struct hn_rx_ring; - -void hv_rf_on_receive(struct hn_softc *sc, struct hn_rx_ring *rxr, - const void *data, int dlen); +void hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, + int dlen); #endif /* __HV_RNDIS_FILTER_H__ */ diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index abd18d565fcd..86ab9719866e 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -51,17 +51,6 @@ #define HN_GPACNT_MAX 32 -#define HN_NDIS_VLAN_INFO_INVALID 0xffffffff -#define HN_NDIS_RXCSUM_INFO_INVALID 0 -#define HN_NDIS_HASH_INFO_INVALID 0 - -struct hn_recvinfo { - uint32_t vlan_info; - uint32_t csum_info; - uint32_t hash_info; - uint32_t hash_value; -}; - struct hn_txdesc; #ifndef HN_USE_TXDESC_BUFRING SLIST_HEAD(hn_txdesc_list, hn_txdesc); @@ -256,9 +245,4 @@ int hn_rndis_get_linkstatus(struct hn_softc *sc, /* filter: NDIS_PACKET_TYPE_. */ int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); -int hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, - const struct hn_recvinfo *info); -void hn_link_status_update(struct hn_softc *sc); -void hn_network_change(struct hn_softc *sc); - #endif /* !_IF_HNVAR_H_ */ From 8ef7124558d1348ca7e7059a1a0279449070b971 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 08:18:49 +0000 Subject: [PATCH 161/235] hyperv/hn: Pull data path code up. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8357 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 36 +++++++++++++++++++ sys/dev/hyperv/netvsc/hv_rndis_filter.c | 36 ------------------- sys/dev/hyperv/netvsc/if_hnvar.h | 4 --- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 83907b1f09bc..5a95a2e57707 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -1244,6 +1244,42 @@ hn_rndis_pktmsg_offset(uint32_t ofs) return (ofs - __offsetof(struct rndis_packet_msg, rm_dataoffset)); } +static __inline void * +hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, + size_t pi_dlen, uint32_t pi_type) +{ + const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen); + struct rndis_pktinfo *pi; + + KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0, + ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen)); + + /* + * Per-packet-info does not move; it only grows. + * + * NOTE: + * rm_pktinfooffset in this phase counts from the beginning + * of rndis_packet_msg. + */ + KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize, + ("%u pktinfo overflows RNDIS packet msg", pi_type)); + pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset + + pkt->rm_pktinfolen); + pkt->rm_pktinfolen += pi_size; + + pi->rm_size = pi_size; + pi->rm_type = pi_type; + pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET; + + /* Data immediately follow per-packet-info. */ + pkt->rm_dataoffset += pi_size; + + /* Update RNDIS packet msg length */ + pkt->rm_len += pi_size; + + return (pi->rm_data); +} + /* * NOTE: * If this function fails, then both txd and m_head0 will be freed. diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index 119f1efbac12..b8463be1069e 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -104,42 +104,6 @@ hn_rndis_rid(struct hn_softc *sc) return ((rid & 0xffff) << 16); } -void * -hn_rndis_pktinfo_append(struct rndis_packet_msg *pkt, size_t pktsize, - size_t pi_dlen, uint32_t pi_type) -{ - const size_t pi_size = HN_RNDIS_PKTINFO_SIZE(pi_dlen); - struct rndis_pktinfo *pi; - - KASSERT((pi_size & RNDIS_PACKET_MSG_OFFSET_ALIGNMASK) == 0, - ("unaligned pktinfo size %zu, pktinfo dlen %zu", pi_size, pi_dlen)); - - /* - * Per-packet-info does not move; it only grows. - * - * NOTE: - * rm_pktinfooffset in this phase counts from the beginning - * of rndis_packet_msg. - */ - KASSERT(pkt->rm_pktinfooffset + pkt->rm_pktinfolen + pi_size <= pktsize, - ("%u pktinfo overflows RNDIS packet msg", pi_type)); - pi = (struct rndis_pktinfo *)((uint8_t *)pkt + pkt->rm_pktinfooffset + - pkt->rm_pktinfolen); - pkt->rm_pktinfolen += pi_size; - - pi->rm_size = pi_size; - pi->rm_type = pi_type; - pi->rm_pktinfooffset = RNDIS_PKTINFO_OFFSET; - - /* Data immediately follow per-packet-info. */ - pkt->rm_dataoffset += pi_size; - - /* Update RNDIS packet msg length */ - pkt->rm_len += pi_size; - - return (pi->rm_data); -} - void hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, int dlen) { diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 86ab9719866e..9f10184f0a69 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -231,13 +231,9 @@ struct hn_softc { #define HN_LINK_FLAG_LINKUP 0x0001 #define HN_LINK_FLAG_NETCHG 0x0002 -struct rndis_packet_msg; - int hn_rndis_attach(struct hn_softc *sc, int mtu); void hn_rndis_detach(struct hn_softc *sc); int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); -void *hn_rndis_pktinfo_append(struct rndis_packet_msg *, - size_t pktsize, size_t pi_dlen, uint32_t pi_type); int hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt); int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr); int hn_rndis_get_linkstatus(struct hn_softc *sc, From d568f3ecfafd150db60b3a12e2fb4ff97ee18046 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 08:32:54 +0000 Subject: [PATCH 162/235] hyperv/hn: Cleanup RNDIS related files. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8358 --- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 37 ++++++++++++++----------- sys/dev/hyperv/netvsc/hv_rndis_filter.h | 10 +++++++ sys/dev/hyperv/netvsc/if_hnvar.h | 10 ------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index b8463be1069e..1895a429d269 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -29,11 +29,12 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_inet6.h" +#include "opt_inet.h" + #include -#include #include -#include -#include +#include #include #include @@ -76,19 +77,23 @@ __FBSDID("$FreeBSD$"); #define HN_NDIS_LSOV2_CAP_IP6 \ (NDIS_LSOV2_CAP_IP6EXT | NDIS_LSOV2_CAP_TCP6OPT) -/* - * Forward declarations - */ -static int hn_rndis_query(struct hn_softc *sc, uint32_t oid, - const void *idata, size_t idlen, void *odata, size_t *odlen0); -static int hn_rndis_query2(struct hn_softc *sc, uint32_t oid, - const void *idata, size_t idlen, void *odata, size_t *odlen0, - size_t min_odlen); -static int hn_rndis_set(struct hn_softc *sc, uint32_t oid, const void *data, - size_t dlen); -static int hn_rndis_conf_offload(struct hn_softc *sc, int mtu); -static int hn_rndis_query_hwcaps(struct hn_softc *sc, - struct ndis_offload *caps); +static const void *hn_rndis_xact_exec1(struct hn_softc *, + struct vmbus_xact *, size_t, + struct hn_nvs_sendctx *, size_t *); +static const void *hn_rndis_xact_execute(struct hn_softc *, + struct vmbus_xact *, uint32_t, size_t, size_t *, + uint32_t); +static int hn_rndis_query(struct hn_softc *, uint32_t, + const void *, size_t, void *, size_t *); +static int hn_rndis_query2(struct hn_softc *, uint32_t, + const void *, size_t, void *, size_t *, size_t); +static int hn_rndis_set(struct hn_softc *, uint32_t, + const void *, size_t); +static int hn_rndis_init(struct hn_softc *); +static int hn_rndis_halt(struct hn_softc *); +static int hn_rndis_conf_offload(struct hn_softc *, int); +static int hn_rndis_query_hwcaps(struct hn_softc *, + struct ndis_offload *); static __inline uint32_t hn_rndis_rid(struct hn_softc *sc) diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hv_rndis_filter.h index cba4ae255e2f..6dc78544b6ea 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.h @@ -33,6 +33,16 @@ struct hn_softc; +int hn_rndis_attach(struct hn_softc *sc, int mtu); +void hn_rndis_detach(struct hn_softc *sc); +int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); +int hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt); +int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr); +/* link_status: NDIS_MEDIA_STATE_ */ +int hn_rndis_get_linkstatus(struct hn_softc *sc, + uint32_t *link_status); +/* filter: NDIS_PACKET_TYPE_. */ +int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); void hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, int dlen); diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 9f10184f0a69..c4d94d040ae8 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -231,14 +231,4 @@ struct hn_softc { #define HN_LINK_FLAG_LINKUP 0x0001 #define HN_LINK_FLAG_NETCHG 0x0002 -int hn_rndis_attach(struct hn_softc *sc, int mtu); -void hn_rndis_detach(struct hn_softc *sc); -int hn_rndis_conf_rss(struct hn_softc *sc, uint16_t flags); -int hn_rndis_query_rsscaps(struct hn_softc *sc, int *rxr_cnt); -int hn_rndis_get_eaddr(struct hn_softc *sc, uint8_t *eaddr); -int hn_rndis_get_linkstatus(struct hn_softc *sc, - uint32_t *link_status); -/* filter: NDIS_PACKET_TYPE_. */ -int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); - #endif /* !_IF_HNVAR_H_ */ From ec60eff9ab41986d0202bc7c4a83aeaef5cacb2a Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 08:41:30 +0000 Subject: [PATCH 163/235] hyperv/hn: Change header guardian; in preparation for the upcoming rename. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8359 --- sys/dev/hyperv/netvsc/hv_rndis_filter.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hv_rndis_filter.h index 6dc78544b6ea..736df341f642 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.h +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.h @@ -28,8 +28,8 @@ * $FreeBSD$ */ -#ifndef __HV_RNDIS_FILTER_H__ -#define __HV_RNDIS_FILTER_H__ +#ifndef _HN_RNDIS_H_ +#define _HN_RNDIS_H_ struct hn_softc; @@ -46,4 +46,4 @@ int hn_rndis_set_rxfilter(struct hn_softc *sc, uint32_t filter); void hn_rndis_rx_ctrl(struct hn_softc *sc, const void *data, int dlen); -#endif /* __HV_RNDIS_FILTER_H__ */ +#endif /* !_HN_RNDIS_H_ */ From fb448904d9712086329bcbc032adbf396eb9403f Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 28 Oct 2016 08:53:18 +0000 Subject: [PATCH 164/235] hyeprv/hn: Rename cleaned up RNDIS header file. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8360 --- sys/dev/hyperv/netvsc/{hv_rndis_filter.h => hn_rndis.h} | 0 sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 2 +- sys/dev/hyperv/netvsc/hv_rndis_filter.c | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename sys/dev/hyperv/netvsc/{hv_rndis_filter.h => hn_rndis.h} (100%) diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.h b/sys/dev/hyperv/netvsc/hn_rndis.h similarity index 100% rename from sys/dev/hyperv/netvsc/hv_rndis_filter.h rename to sys/dev/hyperv/netvsc/hn_rndis.h diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 5a95a2e57707..c54acb73cc3e 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -125,7 +125,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include "vmbus_if.h" diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hv_rndis_filter.c index 1895a429d269..08314a25e290 100644 --- a/sys/dev/hyperv/netvsc/hv_rndis_filter.c +++ b/sys/dev/hyperv/netvsc/hv_rndis_filter.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #define HN_RNDIS_RID_COMPAT_MASK 0xffff #define HN_RNDIS_RID_COMPAT_MAX HN_RNDIS_RID_COMPAT_MASK From 8b3c8abc45840543c16fd0c1fd8b453ef5d7b162 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 10:57:41 +0000 Subject: [PATCH 165/235] Remove useless NULL check. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_vfsops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 9b42b20e1610..63d2de9b9ea9 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -760,8 +760,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) } if (pmp) { lockdestroy(&pmp->pm_fatlock); - if (pmp->pm_inusemap) - free(pmp->pm_inusemap, M_MSDOSFSFAT); + free(pmp->pm_inusemap, M_MSDOSFSFAT); free(pmp, M_MSDOSFSMNT); mp->mnt_data = NULL; } From f220587d0348b455ae43de4243a9da1874d71d5f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 10:59:34 +0000 Subject: [PATCH 166/235] Fix comment formatting. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_fat.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index cdfc9b022487..3a82e7356ba1 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -972,12 +972,14 @@ extendfile(struct denode *dep, u_long count, struct buf **bpp, u_long *ncp, while (count > 0) { /* * Allocate a new cluster chain and cat onto the end of the - * file. * If the file is empty we make de_StartCluster point - * to the new block. Note that de_StartCluster being 0 is - * sufficient to be sure the file is empty since we exclude - * attempts to extend the root directory above, and the root - * dir is the only file with a startcluster of 0 that has - * blocks allocated (sort of). + * file. + * If the file is empty we make de_StartCluster point + * to the new block. Note that de_StartCluster being + * 0 is sufficient to be sure the file is empty since + * we exclude attempts to extend the root directory + * above, and the root dir is the only file with a + * startcluster of 0 that has blocks allocated (sort + * of). */ if (dep->de_StartCluster == 0) cn = 0; From 1c4ec415e2052abf8535e5d06248441e4f8d95b0 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:01:49 +0000 Subject: [PATCH 167/235] Use symbolic name for the free cluster number. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_fat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 3a82e7356ba1..464c1052b87a 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -908,7 +908,7 @@ fillinusemap(struct msdosfsmount *pmp) readcn >>= 4; readcn &= pmp->pm_fatmask; - if (readcn == 0) + if (readcn == CLUST_FREE) usemap_free(pmp, cn); } if (bp != NULL) From f33d62b2d2a3ce833f26c1cfeaf7fea57ad78e62 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:23:36 +0000 Subject: [PATCH 168/235] Use symbolic name for the value of fully free word in pm_inusemap. Explicitely mention every bit in the value. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_fat.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 464c1052b87a..96c9f187fdcb 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -60,6 +60,8 @@ #include #include +#define FULL_RUN ((u_int)0xffffffff) + static int chainalloc(struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, u_long *got); @@ -752,8 +754,8 @@ clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count, idx = cn / N_INUSEBITS; map = pmp->pm_inusemap[idx]; map |= (1 << (cn % N_INUSEBITS)) - 1; - if (map != (u_int)-1) { - cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1; + if (map != FULL_RUN) { + cn = idx * N_INUSEBITS + ffs(map ^ FULL_RUN) - 1; if ((l = chainlength(pmp, cn, count)) >= count) return (chainalloc(pmp, cn, count, fillwith, retcluster, got)); if (l > foundl) { @@ -769,8 +771,8 @@ clusteralloc1(struct msdosfsmount *pmp, u_long start, u_long count, idx = cn / N_INUSEBITS; map = pmp->pm_inusemap[idx]; map |= (1 << (cn % N_INUSEBITS)) - 1; - if (map != (u_int)-1) { - cn = idx * N_INUSEBITS + ffs(map^(u_int)-1) - 1; + if (map != FULL_RUN) { + cn = idx * N_INUSEBITS + ffs(map ^ FULL_RUN) - 1; if ((l = chainlength(pmp, cn, count)) >= count) return (chainalloc(pmp, cn, count, fillwith, retcluster, got)); if (l > foundl) { @@ -878,7 +880,7 @@ fillinusemap(struct msdosfsmount *pmp) * loop further down. */ for (cn = 0; cn < (pmp->pm_maxcluster + N_INUSEBITS) / N_INUSEBITS; cn++) - pmp->pm_inusemap[cn] = (u_int)-1; + pmp->pm_inusemap[cn] = FULL_RUN; /* * Figure how many free clusters are in the filesystem by ripping From 03b8a419e4b6e33f6a6f2765d4dda879b31ad5c1 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:26:44 +0000 Subject: [PATCH 169/235] If the fatchain() call in chainalloc() returned an error, revert marking the cluster run as in-use. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_fat.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 96c9f187fdcb..7a3ade3a3d2d 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -691,8 +691,11 @@ chainalloc(struct msdosfsmount *pmp, u_long start, u_long count, pmp->pm_nxtfree = CLUST_FIRST; pmp->pm_flags |= MSDOSFS_FSIMOD; error = fatchain(pmp, start, count, fillwith); - if (error != 0) + if (error != 0) { + for (cl = start, n = count; n-- > 0;) + usemap_free(pmp, cl++); return (error); + } #ifdef MSDOSFS_DEBUG printf("clusteralloc(): allocated cluster chain at %lu (%lu clusters)\n", start, count); From b05088aeeb58388932a1b529b575ae253d50459f Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:34:32 +0000 Subject: [PATCH 170/235] Ensure that cluster allocations never allocate clusters outside the volume limits. In particular: - Assert that usemap_alloc() and usemap_free() cluster number argument is valid. - In chainlength(), return 0 if cluster start is after the max cluster. - In chainlength(), cut the calculated cluster chain length at the max cluster. - For true paranoia, after the pm_inusemap is calculated in fillinusemap(), reset all bits in the array for clusters after the max cluster, as in-use. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_fat.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 7a3ade3a3d2d..4bceeba537d1 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -382,6 +382,8 @@ usemap_alloc(struct msdosfsmount *pmp, u_long cn) MSDOSFS_ASSERT_MP_LOCKED(pmp); + KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn, + pmp->pm_maxcluster)); KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0, ("usemap_alloc on ro msdosfs mount")); KASSERT((pmp->pm_inusemap[cn / N_INUSEBITS] & (1 << (cn % N_INUSEBITS))) @@ -398,6 +400,9 @@ usemap_free(struct msdosfsmount *pmp, u_long cn) { MSDOSFS_ASSERT_MP_LOCKED(pmp); + + KASSERT(cn <= pmp->pm_maxcluster, ("cn too large %lu %lu", cn, + pmp->pm_maxcluster)); KASSERT((pmp->pm_flags & MSDOSFSMNT_RONLY) == 0, ("usemap_free on ro msdosfs mount")); pmp->pm_freeclustercount++; @@ -637,6 +642,8 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count) MSDOSFS_ASSERT_MP_LOCKED(pmp); + if (start > pmp->pm_maxcluster) + return (0); max_idx = pmp->pm_maxcluster / N_INUSEBITS; idx = start / N_INUSEBITS; start %= N_INUSEBITS; @@ -644,11 +651,18 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count) map &= ~((1 << start) - 1); if (map) { len = ffs(map) - 1 - start; - return (len > count ? count : len); + len = MIN(len, count); + if (start + len > pmp->pm_maxcluster) + len = pmp->pm_maxcluster - start + 1; + return (len); } len = N_INUSEBITS - start; - if (len >= count) - return (count); + if (len >= count) { + len = count; + if (start + len > pmp->pm_maxcluster) + len = pmp->pm_maxcluster - start + 1; + return (len); + } while (++idx <= max_idx) { if (len >= count) break; @@ -659,7 +673,10 @@ chainlength(struct msdosfsmount *pmp, u_long start, u_long count) } len += N_INUSEBITS; } - return (len > count ? count : len); + len = MIN(len, count); + if (start + len > pmp->pm_maxcluster) + len = pmp->pm_maxcluster - start + 1; + return (len); } /* @@ -918,6 +935,11 @@ fillinusemap(struct msdosfsmount *pmp) } if (bp != NULL) brelse(bp); + + for (cn = pmp->pm_maxcluster + 1; cn < (pmp->pm_maxcluster + + N_INUSEBITS) / N_INUSEBITS; cn++) + pmp->pm_inusemap[cn / N_INUSEBITS] |= 1 << (cn % N_INUSEBITS); + return (0); } From 2aa3944510b50cbe6999344985a5a9c3208063b2 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:35:06 +0000 Subject: [PATCH 171/235] Enable vn_io_fault() deadlock avoidance for msdosfs. Reported and tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_vfsops.c | 2 +- sys/fs/msdosfs/msdosfs_vnops.c | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 63d2de9b9ea9..4c122bfb5942 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -742,7 +742,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; MNT_ILOCK(mp); mp->mnt_flag |= MNT_LOCAL; - mp->mnt_kern_flag |= MNTK_USES_BCACHE; + mp->mnt_kern_flag |= MNTK_USES_BCACHE | MNTK_NO_IOPF; MNT_IUNLOCK(mp); if (pmp->pm_flags & MSDOSFS_LARGEFS) diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index 9ab5db614ded..b7de76e3211f 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -593,7 +593,7 @@ msdosfs_read(struct vop_read_args *ap) diff = blsize - bp->b_resid; if (diff < n) n = diff; - error = uiomove(bp->b_data + on, (int) n, uio); + error = vn_io_fault_uiomove(bp->b_data + on, (int) n, uio); brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); if (!isadir && (error == 0 || uio->uio_resid != orig_resid) && @@ -723,6 +723,12 @@ msdosfs_write(struct vop_write_args *ap) * then no need to read data from disk. */ bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0, 0); + /* + * This call to vfs_bio_clrbuf() ensures that + * even if vn_io_fault_uiomove() below faults, + * garbage from the newly instantiated buffer + * is not exposed to the userspace via mmap(). + */ vfs_bio_clrbuf(bp); /* * Do the bmap now, since pcbmap needs buffers @@ -760,7 +766,7 @@ msdosfs_write(struct vop_write_args *ap) /* * Copy the data from user space into the buf header. */ - error = uiomove(bp->b_data + croffset, n, uio); + error = vn_io_fault_uiomove(bp->b_data + croffset, n, uio); if (error) { brelse(bp); break; From c39baa74808828a263ab219fab40777aad1229d1 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:43:59 +0000 Subject: [PATCH 172/235] Generalize UFS buffer pager to allow it serving other filesystems which also use buffer cache. Most important addition to the code is the handling of filesystems where the block size is less than the machine page size, which might require reading several buffers to validate single page. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/kern/vfs_bio.c | 160 +++++++++++++++++++++++++++++++++++++- sys/sys/buf.h | 7 ++ sys/ufs/ffs/ffs_vnops.c | 166 +++++----------------------------------- 3 files changed, 184 insertions(+), 149 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index c70366fbb54d..51e9cf2f738e 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -75,9 +75,10 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include +#include +#include +#include #include #include #include @@ -4636,6 +4637,161 @@ bdata2bio(struct buf *bp, struct bio *bip) } } +static int buf_pager_relbuf; +SYSCTL_INT(_vfs, OID_AUTO, buf_pager_relbuf, CTLFLAG_RWTUN, + &buf_pager_relbuf, 0, + "Make buffer pager release buffers after reading"); + +/* + * The buffer pager. It uses buffer reads to validate pages. + * + * In contrast to the generic local pager from vm/vnode_pager.c, this + * pager correctly and easily handles volumes where the underlying + * device block size is greater than the machine page size. The + * buffer cache transparently extends the requested page run to be + * aligned at the block boundary, and does the necessary bogus page + * replacements in the addends to avoid obliterating already valid + * pages. + * + * The only non-trivial issue is that the exclusive busy state for + * pages, which is assumed by the vm_pager_getpages() interface, is + * incompatible with the VMIO buffer cache's desire to share-busy the + * pages. This function performs a trivial downgrade of the pages' + * state before reading buffers, and a less trivial upgrade from the + * shared-busy to excl-busy state after the read. + */ +int +vfs_bio_getpages(struct vnode *vp, vm_page_t *ma, int count, + int *rbehind, int *rahead, vbg_get_lblkno_t get_lblkno, + vbg_get_blksize_t get_blksize) +{ + vm_page_t m; + vm_object_t object; + struct buf *bp; + daddr_t lbn, lbnp; + vm_ooffset_t la, lb, poff, poffe; + long bsize; + int bo_bs, error, i; + bool redo, lpart; + + object = vp->v_object; + la = IDX_TO_OFF(ma[count - 1]->pindex); + if (la >= object->un_pager.vnp.vnp_size) + return (VM_PAGER_BAD); + lpart = la + PAGE_SIZE > object->un_pager.vnp.vnp_size; + bo_bs = get_blksize(vp, get_lblkno(vp, IDX_TO_OFF(ma[0]->pindex))); + if (rbehind != NULL) { + lb = IDX_TO_OFF(ma[0]->pindex); + *rbehind = OFF_TO_IDX(lb - rounddown2(lb, bo_bs)); + } + if (rahead != NULL) { + *rahead = OFF_TO_IDX(roundup2(la, bo_bs) - la); + if (la + IDX_TO_OFF(*rahead) >= object->un_pager.vnp.vnp_size) { + *rahead = OFF_TO_IDX(roundup2(object->un_pager. + vnp.vnp_size, PAGE_SIZE) - la); + } + } + VM_OBJECT_WLOCK(object); +again: + for (i = 0; i < count; i++) + vm_page_busy_downgrade(ma[i]); + VM_OBJECT_WUNLOCK(object); + + lbnp = -1; + for (i = 0; i < count; i++) { + m = ma[i]; + + /* + * Pages are shared busy and the object lock is not + * owned, which together allow for the pages' + * invalidation. The racy test for validity avoids + * useless creation of the buffer for the most typical + * case when invalidation is not used in redo or for + * parallel read. The shared->excl upgrade loop at + * the end of the function catches the race in a + * reliable way (protected by the object lock). + */ + if (m->valid == VM_PAGE_BITS_ALL) + continue; + + poff = IDX_TO_OFF(m->pindex); + poffe = MIN(poff + PAGE_SIZE, object->un_pager.vnp.vnp_size); + for (; poff < poffe; poff += bsize) { + lbn = get_lblkno(vp, poff); + if (lbn == lbnp) + goto next_page; + lbnp = lbn; + + bsize = get_blksize(vp, lbn); + error = bread_gb(vp, lbn, bsize, NOCRED, GB_UNMAPPED, + &bp); + if (error != 0) + goto end_pages; + if (LIST_EMPTY(&bp->b_dep)) { + /* + * Invalidation clears m->valid, but + * may leave B_CACHE flag if the + * buffer existed at the invalidation + * time. In this case, recycle the + * buffer to do real read on next + * bread() after redo. + * + * Otherwise B_RELBUF is not strictly + * necessary, enable to reduce buf + * cache pressure. + */ + if (buf_pager_relbuf || + m->valid != VM_PAGE_BITS_ALL) + bp->b_flags |= B_RELBUF; + + bp->b_flags &= ~B_NOCACHE; + brelse(bp); + } else { + bqrelse(bp); + } + } + KASSERT(1 /* racy, enable for debugging */ || + m->valid == VM_PAGE_BITS_ALL || i == count - 1, + ("buf %d %p invalid", i, m)); + if (i == count - 1 && lpart) { + VM_OBJECT_WLOCK(object); + if (m->valid != 0 && + m->valid != VM_PAGE_BITS_ALL) + vm_page_zero_invalid(m, TRUE); + VM_OBJECT_WUNLOCK(object); + } +next_page:; + } +end_pages: + + VM_OBJECT_WLOCK(object); + redo = false; + for (i = 0; i < count; i++) { + vm_page_sunbusy(ma[i]); + ma[i] = vm_page_grab(object, ma[i]->pindex, VM_ALLOC_NORMAL); + + /* + * Since the pages were only sbusy while neither the + * buffer nor the object lock was held by us, or + * reallocated while vm_page_grab() slept for busy + * relinguish, they could have been invalidated. + * Recheck the valid bits and re-read as needed. + * + * Note that the last page is made fully valid in the + * read loop, and partial validity for the page at + * index count - 1 could mean that the page was + * invalidated or removed, so we must restart for + * safety as well. + */ + if (ma[i]->valid != VM_PAGE_BITS_ALL) + redo = true; + } + if (redo && error == 0) + goto again; + VM_OBJECT_WUNLOCK(object); + return (error != 0 ? VM_PAGER_ERROR : VM_PAGER_OK); +} + #include "opt_ddb.h" #ifdef DDB #include diff --git a/sys/sys/buf.h b/sys/sys/buf.h index e5607b54e267..034671e794d1 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -68,6 +68,7 @@ extern struct bio_ops { } bioops; struct vm_object; +struct vm_page; typedef unsigned char b_xflags_t; @@ -537,6 +538,12 @@ struct buf *trypbuf(int *); void bwait(struct buf *, u_char, const char *); void bdone(struct buf *); +typedef daddr_t (vbg_get_lblkno_t)(struct vnode *, vm_ooffset_t); +typedef int (vbg_get_blksize_t)(struct vnode *, daddr_t); +int vfs_bio_getpages(struct vnode *vp, struct vm_page **ma, int count, + int *rbehind, int *rahead, vbg_get_lblkno_t get_lblkno, + vbg_get_blksize_t get_blksize); + #endif /* _KERNEL */ #endif /* !_SYS_BUF_H_ */ diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 9e841f072d6a..cfd4616a87af 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -87,7 +87,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -1791,160 +1790,33 @@ SYSCTL_DECL(_vfs_ffs); static int use_buf_pager = 1; SYSCTL_INT(_vfs_ffs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN, &use_buf_pager, 0, "Always use buffer pager instead of bmap"); -static int buf_pager_relbuf; -SYSCTL_INT(_vfs_ffs, OID_AUTO, buf_pager_relbuf, CTLFLAG_RWTUN, - &buf_pager_relbuf, 0, - "Make buffer pager release buffers after reading"); -/* - * The FFS pager. It uses buffer reads to validate pages. - * - * In contrast to the generic local pager from vm/vnode_pager.c, this - * pager correctly and easily handles volumes where the underlying - * device block size is greater than the machine page size. The - * buffer cache transparently extends the requested page run to be - * aligned at the block boundary, and does the necessary bogus page - * replacements in the addends to avoid obliterating already valid - * pages. - * - * The only non-trivial issue is that the exclusive busy state for - * pages, which is assumed by the vm_pager_getpages() interface, is - * incompatible with the VMIO buffer cache's desire to share-busy the - * pages. This function performs a trivial downgrade of the pages' - * state before reading buffers, and a less trivial upgrade from the - * shared-busy to excl-busy state after the read. - */ +static daddr_t +ffs_gbp_getblkno(struct vnode *vp, vm_ooffset_t off) +{ + + return (lblkno(VFSTOUFS(vp->v_mount)->um_fs, off)); +} + +static int +ffs_gbp_getblksz(struct vnode *vp, daddr_t lbn) +{ + + return (blksize(VFSTOUFS(vp->v_mount)->um_fs, VTOI(vp), lbn)); +} + static int ffs_getpages(struct vop_getpages_args *ap) { struct vnode *vp; - vm_page_t *ma, m; - vm_object_t object; - struct buf *bp; struct ufsmount *um; - ufs_lbn_t lbn, lbnp; - vm_ooffset_t la, lb; - long bsize; - int bo_bs, count, error, i; - bool redo, lpart; vp = ap->a_vp; - ma = ap->a_m; - count = ap->a_count; + um = VFSTOUFS(vp->v_mount); - um = VFSTOUFS(ap->a_vp->v_mount); - bo_bs = um->um_devvp->v_bufobj.bo_bsize; - if (!use_buf_pager && bo_bs <= PAGE_SIZE) - return (vnode_pager_generic_getpages(vp, ma, count, + if (!use_buf_pager && um->um_devvp->v_bufobj.bo_bsize <= PAGE_SIZE) + return (vnode_pager_generic_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind, ap->a_rahead, NULL, NULL)); - - object = vp->v_object; - la = IDX_TO_OFF(ma[count - 1]->pindex); - if (la >= object->un_pager.vnp.vnp_size) - return (VM_PAGER_BAD); - lpart = la + PAGE_SIZE > object->un_pager.vnp.vnp_size; - if (ap->a_rbehind != NULL) { - lb = IDX_TO_OFF(ma[0]->pindex); - *ap->a_rbehind = OFF_TO_IDX(lb - rounddown2(lb, bo_bs)); - } - if (ap->a_rahead != NULL) { - *ap->a_rahead = OFF_TO_IDX(roundup2(la, bo_bs) - la); - if (la + IDX_TO_OFF(*ap->a_rahead) >= - object->un_pager.vnp.vnp_size) { - *ap->a_rahead = OFF_TO_IDX(roundup2(object->un_pager. - vnp.vnp_size, PAGE_SIZE) - la); - } - } - VM_OBJECT_WLOCK(object); -again: - for (i = 0; i < count; i++) - vm_page_busy_downgrade(ma[i]); - VM_OBJECT_WUNLOCK(object); - - lbnp = -1; - for (i = 0; i < count; i++) { - m = ma[i]; - - /* - * Pages are shared busy and the object lock is not - * owned, which together allow for the pages' - * invalidation. The racy test for validity avoids - * useless creation of the buffer for the most typical - * case when invalidation is not used in redo or for - * parallel read. The shared->excl upgrade loop at - * the end of the function catches the race in a - * reliable way (protected by the object lock). - */ - if (m->valid == VM_PAGE_BITS_ALL) - continue; - - lbn = lblkno(um->um_fs, IDX_TO_OFF(m->pindex)); - if (lbn != lbnp) { - bsize = blksize(um->um_fs, VTOI(vp), lbn); - error = bread_gb(vp, lbn, bsize, NOCRED, GB_UNMAPPED, - &bp); - if (error != 0) - break; - KASSERT(1 /* racy, enable for debugging */ || - m->valid == VM_PAGE_BITS_ALL || i == count - 1, - ("buf %d %p invalid", i, m)); - if (i == count - 1 && lpart) { - VM_OBJECT_WLOCK(object); - if (m->valid != 0 && - m->valid != VM_PAGE_BITS_ALL) - vm_page_zero_invalid(m, TRUE); - VM_OBJECT_WUNLOCK(object); - } - if (LIST_EMPTY(&bp->b_dep)) { - /* - * Invalidation clears m->valid, but - * may leave B_CACHE flag if the - * buffer existed at the invalidation - * time. In this case, recycle the - * buffer to do real read on next - * bread() after redo. - * - * Otherwise B_RELBUF is not strictly - * necessary, enable to reduce buf - * cache pressure. - */ - if (buf_pager_relbuf || - m->valid != VM_PAGE_BITS_ALL) - bp->b_flags |= B_RELBUF; - - bp->b_flags &= ~B_NOCACHE; - brelse(bp); - } else { - bqrelse(bp); - } - lbnp = lbn; - } - } - - VM_OBJECT_WLOCK(object); - redo = false; - for (i = 0; i < count; i++) { - vm_page_sunbusy(ma[i]); - ma[i] = vm_page_grab(object, ma[i]->pindex, VM_ALLOC_NORMAL); - - /* - * Since the pages were only sbusy while neither the - * buffer nor the object lock was held by us, or - * reallocated while vm_page_grab() slept for busy - * relinguish, they could have been invalidated. - * Recheck the valid bits and re-read as needed. - * - * Note that the last page is made fully valid in the - * read loop, and partial validity for the page at - * index count - 1 could mean that the page was - * invalidated or removed, so we must restart for - * safety as well. - */ - if (ma[i]->valid != VM_PAGE_BITS_ALL) - redo = true; - } - if (redo && error == 0) - goto again; - VM_OBJECT_WUNLOCK(object); - return (error != 0 ? VM_PAGER_ERROR : VM_PAGER_OK); + return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind, + ap->a_rahead, ffs_gbp_getblkno, ffs_gbp_getblksz)); } From 06965e96b3cff524e1cc76ed4cacfa18db7e3566 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:46:15 +0000 Subject: [PATCH 173/235] Use buffer pager for msdosfs. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/msdosfs/msdosfs_vnops.c | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/sys/fs/msdosfs/msdosfs_vnops.c b/sys/fs/msdosfs/msdosfs_vnops.c index b7de76e3211f..4f53bbc3eb6f 100644 --- a/sys/fs/msdosfs/msdosfs_vnops.c +++ b/sys/fs/msdosfs/msdosfs_vnops.c @@ -62,11 +62,13 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -97,6 +99,7 @@ static vop_rmdir_t msdosfs_rmdir; static vop_symlink_t msdosfs_symlink; static vop_readdir_t msdosfs_readdir; static vop_bmap_t msdosfs_bmap; +static vop_getpages_t msdosfs_getpages; static vop_strategy_t msdosfs_strategy; static vop_print_t msdosfs_print; static vop_pathconf_t msdosfs_pathconf; @@ -1798,6 +1801,38 @@ msdosfs_bmap(struct vop_bmap_args *ap) return (0); } +SYSCTL_NODE(_vfs, OID_AUTO, msdosfs, CTLFLAG_RW, 0, "msdos filesystem"); +static int use_buf_pager = 1; +SYSCTL_INT(_vfs_msdosfs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN, + &use_buf_pager, 0, + "Use buffer pager instead of bmap"); + +static daddr_t +msdosfs_gbp_getblkno(struct vnode *vp, vm_ooffset_t off) +{ + + return (de_cluster(VTODE(vp)->de_pmp, off)); +} + +static int +msdosfs_gbp_getblksz(struct vnode *vp, daddr_t lbn) +{ + + return (VTODE(vp)->de_pmp->pm_bpcluster); +} + +static int +msdosfs_getpages(struct vop_getpages_args *ap) +{ + + if (use_buf_pager) + return (vfs_bio_getpages(ap->a_vp, ap->a_m, ap->a_count, + ap->a_rbehind, ap->a_rahead, msdosfs_gbp_getblkno, + msdosfs_gbp_getblksz)); + return (vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count, + ap->a_rbehind, ap->a_rahead, NULL, NULL)); +} + static int msdosfs_strategy(struct vop_strategy_args *ap) { @@ -1898,6 +1933,7 @@ struct vop_vector msdosfs_vnodeops = { .vop_access = msdosfs_access, .vop_bmap = msdosfs_bmap, + .vop_getpages = msdosfs_getpages, .vop_cachedlookup = msdosfs_lookup, .vop_open = msdosfs_open, .vop_close = msdosfs_close, From c329ee711b9bd315d19d706745ac98ad90c27420 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:46:39 +0000 Subject: [PATCH 174/235] Use buffer pager for cd9660. Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks --- sys/fs/cd9660/cd9660_vnops.c | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/sys/fs/cd9660/cd9660_vnops.c b/sys/fs/cd9660/cd9660_vnops.c index cab8db7e39dc..04c0ff5ceeb4 100644 --- a/sys/fs/cd9660/cd9660_vnops.c +++ b/sys/fs/cd9660/cd9660_vnops.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -74,6 +75,7 @@ static vop_readdir_t cd9660_readdir; static vop_readlink_t cd9660_readlink; static vop_strategy_t cd9660_strategy; static vop_vptofh_t cd9660_vptofh; +static vop_getpages_t cd9660_getpages; /* * Setattr call. Only allowed for block and character special devices. @@ -836,6 +838,45 @@ cd9660_vptofh(ap) return (0); } +SYSCTL_NODE(_vfs, OID_AUTO, cd9660, CTLFLAG_RW, 0, "cd9660 filesystem"); +static int use_buf_pager = 1; +SYSCTL_INT(_vfs_cd9660, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN, + &use_buf_pager, 0, + "Use buffer pager instead of bmap"); + +static daddr_t +cd9660_gbp_getblkno(struct vnode *vp, vm_ooffset_t off) +{ + + return (lblkno(VTOI(vp)->i_mnt, off)); +} + +static int +cd9660_gbp_getblksz(struct vnode *vp, daddr_t lbn) +{ + struct iso_node *ip; + + ip = VTOI(vp); + return (blksize(ip->i_mnt, ip, lbn)); +} + +static int +cd9660_getpages(struct vop_getpages_args *ap) +{ + struct vnode *vp; + + vp = ap->a_vp; + if (vp->v_type == VCHR || vp->v_type == VBLK) + return (EOPNOTSUPP); + + if (use_buf_pager) + return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, + ap->a_rbehind, ap->a_rahead, cd9660_gbp_getblkno, + cd9660_gbp_getblksz)); + return (vnode_pager_generic_getpages(vp, ap->a_m, ap->a_count, + ap->a_rbehind, ap->a_rahead, NULL, NULL)); +} + /* * Global vfs data structures for cd9660 */ @@ -857,6 +898,7 @@ struct vop_vector cd9660_vnodeops = { .vop_setattr = cd9660_setattr, .vop_strategy = cd9660_strategy, .vop_vptofh = cd9660_vptofh, + .vop_getpages = cd9660_getpages, }; /* From d3e4d71f1dbe57d2779a96ec2d4f4f09f8a8bb5c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 11:53:22 +0000 Subject: [PATCH 175/235] Handle pmap_enter() over an existing 4/2M page in KVA on i386. The userspace case was already handled by pmap_allocpte(). For kernel VA, page table page must exist, and demote cannot fail, so we need to just call pmap_demote_pde(). Also note that due to the machine AS layout, promotions in the KVA on i386 are highly unlikely, so this change is mostly for completeness. Reviewed by: alc, markj Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D8323 --- sys/i386/i386/pmap.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 7c2d56abac91..765ff8bec511 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -3466,11 +3466,14 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, PMAP_LOCK(pmap); sched_pin(); - /* - * In the case that a page table page is not - * resident, we are creating it here. - */ + pde = pmap_pde(pmap, va); if (va < VM_MAXUSER_ADDRESS) { + /* + * va is for UVA. + * In the case that a page table page is not resident, + * we are creating it here. pmap_allocpte() handles + * demotion. + */ mpte = pmap_allocpte(pmap, va, flags); if (mpte == NULL) { KASSERT((flags & PMAP_ENTER_NOSLEEP) != 0, @@ -3480,19 +3483,28 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot, PMAP_UNLOCK(pmap); return (KERN_RESOURCE_SHORTAGE); } + } else { + /* + * va is for KVA, so pmap_demote_pde() will never fail + * to install a page table page. PG_V is also + * asserted by pmap_demote_pde(). + */ + KASSERT(pde != NULL && (*pde & PG_V) != 0, + ("KVA %#x invalid pde pdir %#jx", va, + (uintmax_t)pmap->pm_pdir[PTDPTDI])); + if ((*pde & PG_PS) != 0) + pmap_demote_pde(pmap, pde, va); } - - pde = pmap_pde(pmap, va); - if ((*pde & PG_PS) != 0) - panic("pmap_enter: attempted pmap_enter on 4MB page"); pte = pmap_pte_quick(pmap, va); /* - * Page Directory table entry not valid, we need a new PT page + * Page Directory table entry is not valid, which should not + * happen. We should have either allocated the page table + * page or demoted the existing mapping above. */ if (pte == NULL) { panic("pmap_enter: invalid page directory pdir=%#jx, va=%#x", - (uintmax_t)pmap->pm_pdir[PTDPTDI], va); + (uintmax_t)pmap->pm_pdir[PTDPTDI], va); } pa = VM_PAGE_TO_PHYS(m); From 1d6dfd1230e61b5dfe6910bffa5e5115ce051d68 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 28 Oct 2016 12:27:05 +0000 Subject: [PATCH 176/235] Use correct cpu id in the banner. Fix style. Noted by: avg Sponsored by: The FreeBSD Foundation MFC after: 9 days --- sys/x86/x86/cpu_machdep.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/x86/x86/cpu_machdep.c b/sys/x86/x86/cpu_machdep.c index c1740ee8dfb3..f28ca6d89831 100644 --- a/sys/x86/x86/cpu_machdep.c +++ b/sys/x86/x86/cpu_machdep.c @@ -551,7 +551,7 @@ nmi_call_kdb(u_int cpu, u_int type, struct trapframe *frame) * NMI can be hooked up to a pushbutton for debugging. */ if (kdb_on_nmi) { - printf ("NMI/cpu%d ... going to debugger\n", cpu); + printf("NMI/cpu%d ... going to debugger\n", cpu); kdb_trap(type, 0, frame); } #endif /* KDB */ @@ -572,6 +572,6 @@ nmi_handle_intr(u_int type, struct trapframe *frame) return; } #endif - nmi_call_kdb(0, type, frame); + nmi_call_kdb(PCPU_GET(cpuid), type, frame); #endif } From b133b473425e28cda8955194d30e562bd2fe26c7 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Fri, 28 Oct 2016 12:36:59 +0000 Subject: [PATCH 177/235] Fix indentation and remove duplicate queue stopped stats increment. Found by: Ryan Stone Sponsored by: Mellanox Technologies MFC after: 1 week --- sys/dev/mlx4/mlx4_en/mlx4_en_tx.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c b/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c index d415ab65f790..9f83500314ac 100644 --- a/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c +++ b/sys/dev/mlx4/mlx4_en/mlx4_en_tx.c @@ -707,20 +707,19 @@ static int mlx4_en_xmit(struct mlx4_en_priv *priv, int tx_ind, struct mbuf **mbp /* check if TX ring is full */ if (unlikely(mlx4_en_tx_ring_is_full(ring))) { - /* every full native Tx ring stops queue */ - if (ring->blocked == 0) - atomic_add_int(&priv->blocked, 1); - /* Set HW-queue-is-full flag */ - atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); - priv->port_stats.queue_stopped++; - ring->blocked = 1; + /* every full native Tx ring stops queue */ + if (ring->blocked == 0) + atomic_add_int(&priv->blocked, 1); + /* Set HW-queue-is-full flag */ + atomic_set_int(&ifp->if_drv_flags, IFF_DRV_OACTIVE); priv->port_stats.queue_stopped++; + ring->blocked = 1; ring->queue_stopped++; /* Use interrupts to find out when queue opened */ mlx4_en_arm_cq(priv, priv->tx_cq[tx_ind]); return (ENOBUFS); - } + } /* sanity check we are not wrapping around */ KASSERT(((~ring->prod) & ring->size_mask) >= From c371f1143c121c50191c8f735e935e2389e3985a Mon Sep 17 00:00:00 2001 From: Sean Bruno Date: Fri, 28 Oct 2016 13:37:58 +0000 Subject: [PATCH 178/235] The buffer address is always overwritten in the extended descriptor format, we have to refresh it ... always. This fixes problems reported in NetMap with em(4) devices after conversion to extended descriptor format in svn r293331. Submitted by: luigi@ Reported by: franco@opnsense.org MFC after: 2 days --- sys/dev/netmap/if_em_netmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/netmap/if_em_netmap.h b/sys/dev/netmap/if_em_netmap.h index 28f2dd4bbc64..1fe7563348c6 100644 --- a/sys/dev/netmap/if_em_netmap.h +++ b/sys/dev/netmap/if_em_netmap.h @@ -277,9 +277,9 @@ em_netmap_rxsync(struct netmap_kring *kring, int flags) if (addr == NETMAP_BUF_BASE(na)) /* bad buf */ goto ring_reset; + curr->read.buffer_addr = htole64(paddr); if (slot->flags & NS_BUF_CHANGED) { /* buffer has changed, reload map */ - curr->read.buffer_addr = htole64(paddr); netmap_reload_map(na, rxr->rxtag, rxbuf->map, addr); slot->flags &= ~NS_BUF_CHANGED; } From 211029ce84f018ee836ee4713df6b9540db45682 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Fri, 28 Oct 2016 14:38:01 +0000 Subject: [PATCH 179/235] vmm: another take at maximmum address passed to contigmalloc Just using vm_paddr_t value with all bits set. That should work as long as the type is unsigned. While there, fix a couple of whitespace issues nearby. MFC after: 1 week X-MFC with: r307903 --- sys/amd64/vmm/amd/svm.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index 2b29d061e020..654c7ccedb37 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include "vmm_lapic.h" #include "vmm_stat.h" @@ -515,11 +514,11 @@ svm_vminit(struct vm *vm, pmap_t pmap) { struct svm_softc *svm_sc; struct svm_vcpu *vcpu; - vm_paddr_t msrpm_pa, iopm_pa, pml4_pa; + vm_paddr_t msrpm_pa, iopm_pa, pml4_pa int i; svm_sc = contigmalloc(sizeof (*svm_sc), M_SVM, M_WAITOK | M_ZERO, - 0, VM_MAX_ADDRESS, PAGE_SIZE, 0); + 0, ~(vm_paddr_t)0, PAGE_SIZE, 0); svm_sc->vm = vm; svm_sc->nptp = (vm_offset_t)vtophys(pmap->pm_pml4); @@ -536,7 +535,7 @@ svm_vminit(struct vm *vm, pmap_t pmap) svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_GSBASE); svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_FSBASE); svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_KGSBASE); - + svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_STAR); svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_LSTAR); svm_msr_rw_ok(svm_sc->msr_bitmap, MSR_CSTAR); From 9cb44c5d21db996025a30cfd088559ddad844882 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Fri, 28 Oct 2016 14:49:54 +0000 Subject: [PATCH 180/235] nap time between pats is forced to be at most half of the timeout Previously, if the timeout was less than 10 seconds, for example, about 8 seconds, then the watchdog timer would be let to expire before patting the watchdog. MFC after: 2 weeks --- usr.sbin/watchdogd/watchdogd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/usr.sbin/watchdogd/watchdogd.c b/usr.sbin/watchdogd/watchdogd.c index 55210d612df6..9ed9de31683d 100644 --- a/usr.sbin/watchdogd/watchdogd.c +++ b/usr.sbin/watchdogd/watchdogd.c @@ -80,7 +80,8 @@ static u_int timeout = WD_TO_128SEC; static u_int exit_timeout = WD_TO_NEVER; static u_int pretimeout = 0; static u_int timeout_sec; -static u_int passive = 0; +static u_int nap = 10; +static int passive = 0; static int is_daemon = 0; static int is_dry_run = 0; /* do not arm the watchdog, only report on timing of the watch @@ -88,7 +89,6 @@ static int is_dry_run = 0; /* do not arm the watchdog, only static int do_timedog = 0; static int do_syslog = 1; static int fd = -1; -static int nap = 10; static int carp_thresh_seconds = -1; static char *test_cmd = NULL; @@ -771,6 +771,9 @@ parseargs(int argc, char *argv[]) } } + if (nap > timeout_sec / 2) + nap = timeout_sec / 2; + if (carp_thresh_seconds == -1) carp_thresh_seconds = nap; From 4be4cba04855edf5f9fd6fa672647e85684875a2 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 28 Oct 2016 15:30:10 +0000 Subject: [PATCH 181/235] Improve few debugging log messages. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index 818052ba577e..fa2db4548862 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -223,7 +223,7 @@ vdev_geom_attach(struct g_provider *pp, vdev_t *vd) } error = g_access(cp, 1, 0, 1); if (error != 0) { - ZFS_LOG(1, "%s(%d): g_access failed: %d\n", __func__, + ZFS_LOG(1, "%s(%d): g_access failed: %d", __func__, __LINE__, error); vdev_geom_detach(cp, B_FALSE); return (NULL); @@ -293,7 +293,7 @@ vdev_geom_detach(struct g_consumer *cp, boolean_t open_for_read) g_topology_assert(); - ZFS_LOG(1, "Detaching consumer. Provider %s.", + ZFS_LOG(1, "Detaching from %s.", cp->provider && cp->provider->name ? cp->provider->name : "NULL"); vd = cp->private; @@ -307,7 +307,7 @@ vdev_geom_detach(struct g_consumer *cp, boolean_t open_for_read) if (cp->acw > 0) g_access(cp, 0, -cp->acw, 0); if (cp->provider != NULL) { - ZFS_LOG(1, "Destroying consumer to %s.", + ZFS_LOG(1, "Destroying consumer for %s.", cp->provider->name ? cp->provider->name : "NULL"); g_detach(cp); } From 2f4c43215e5cae3a4c8cd54e396958fbfa8b6903 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Fri, 28 Oct 2016 15:57:55 +0000 Subject: [PATCH 182/235] fix a syntax error in r308039 ... that I somehow introduced between testing the change iand committing it. MFC after: 1 week X-MFC with: r307903 --- sys/amd64/vmm/amd/svm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amd64/vmm/amd/svm.c b/sys/amd64/vmm/amd/svm.c index 654c7ccedb37..5aa17d0fbb1e 100644 --- a/sys/amd64/vmm/amd/svm.c +++ b/sys/amd64/vmm/amd/svm.c @@ -514,7 +514,7 @@ svm_vminit(struct vm *vm, pmap_t pmap) { struct svm_softc *svm_sc; struct svm_vcpu *vcpu; - vm_paddr_t msrpm_pa, iopm_pa, pml4_pa + vm_paddr_t msrpm_pa, iopm_pa, pml4_pa; int i; svm_sc = contigmalloc(sizeof (*svm_sc), M_SVM, M_WAITOK | M_ZERO, From f106f43aa2538574a728470768ae6c6935c84208 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 28 Oct 2016 16:21:31 +0000 Subject: [PATCH 183/235] Matching GUIDs, handle possible race on vdev detach. In case of vdev detach, causing top level mirror vdev destruction, leaf vdev changes its GUID to one of the destroyed mirror, that creates race condition when GUID in vdev label may not match one in the pool config. This change replicates logic nuance of vdev_validate() by adding special exception, matching the vdev GUID against the top level vdev GUID. Since this exception is not completely reliable (may give false positives if we fail to erase label on detached vdev), use it only as last resort. Quick way to reproduce this scenario now is detach vdev from a pool with enabled autoextend. During vdev detach autoextend logic tries to reopen remaining vdev, that always fails now since in-memory configuration is already updated, while on-disk labels are not yet. MFC after: 2 weeks --- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 125 +++++++++--------- 1 file changed, 66 insertions(+), 59 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index fa2db4548862..fb0df0a847e6 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -338,14 +338,6 @@ vdev_geom_close_locked(vdev_t *vd) vdev_geom_detach(cp, B_TRUE); } -static void -nvlist_get_guids(nvlist_t *list, uint64_t *pguid, uint64_t *vguid) -{ - - (void) nvlist_lookup_uint64(list, ZPOOL_CONFIG_GUID, vguid); - (void) nvlist_lookup_uint64(list, ZPOOL_CONFIG_POOL_GUID, pguid); -} - /* * Issue one or more bios to the vdev in parallel * cmds, datas, offsets, errors, and sizes are arrays of length ncmds. Each IO @@ -606,58 +598,69 @@ vdev_geom_read_pool_label(const char *name, return (*count > 0 ? 0 : ENOENT); } -static void -vdev_geom_read_guids(struct g_consumer *cp, uint64_t *pguid, uint64_t *vguid) -{ - nvlist_t *config; +enum match { + NO_MATCH, + TOP_MATCH, + FULL_MATCH +}; - g_topology_assert_not(); - - *pguid = 0; - *vguid = 0; - if (vdev_geom_read_config(cp, &config) == 0) { - nvlist_get_guids(config, pguid, vguid); - nvlist_free(config); - } -} - -static boolean_t +static enum match vdev_attach_ok(vdev_t *vd, struct g_provider *pp) { - uint64_t pool_guid; - uint64_t vdev_guid; - struct g_consumer *zcp; - boolean_t pool_ok; - boolean_t vdev_ok; + nvlist_t *config; + uint64_t pool_guid, top_guid, vdev_guid; + struct g_consumer *cp; - zcp = vdev_geom_attach(pp, NULL); - if (zcp == NULL) { + cp = vdev_geom_attach(pp, NULL); + if (cp == NULL) { ZFS_LOG(1, "Unable to attach tasting instance to %s.", pp->name); - return (B_FALSE); + return (NO_MATCH); } g_topology_unlock(); - vdev_geom_read_guids(zcp, &pool_guid, &vdev_guid); - g_topology_lock(); - vdev_geom_detach(zcp, B_TRUE); - - /* - * Check that the label's vdev guid matches the desired guid. If the - * label has a pool guid, check that it matches too. (Inactive spares - * and L2ARCs do not have any pool guid in the label.) - */ - if ((pool_guid == 0 || pool_guid == spa_guid(vd->vdev_spa)) && - vdev_guid == vd->vdev_guid) { - ZFS_LOG(1, "guids match for provider %s.", vd->vdev_path); - return (B_TRUE); - } else { - ZFS_LOG(1, "guid mismatch for provider %s: " - "%ju:%ju != %ju:%ju.", vd->vdev_path, - (uintmax_t)spa_guid(vd->vdev_spa), - (uintmax_t)vd->vdev_guid, - (uintmax_t)pool_guid, (uintmax_t)vdev_guid); - return (B_FALSE); + if (vdev_geom_read_config(cp, &config) != 0) { + g_topology_lock(); + vdev_geom_detach(cp, B_TRUE); + ZFS_LOG(1, "Unable to read config from %s.", pp->name); + return (NO_MATCH); } + g_topology_lock(); + vdev_geom_detach(cp, B_TRUE); + + pool_guid = 0; + (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &pool_guid); + top_guid = 0; + (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_TOP_GUID, &top_guid); + vdev_guid = 0; + (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid); + nvlist_free(config); + + /* + * Check that the label's pool guid matches the desired guid. + * Inactive spares and L2ARCs do not have any pool guid in the label. + */ + if (pool_guid != 0 && pool_guid != spa_guid(vd->vdev_spa)) { + ZFS_LOG(1, "pool guid mismatch for provider %s: %ju != %ju.", + pp->name, + (uintmax_t)spa_guid(vd->vdev_spa), (uintmax_t)pool_guid); + return (NO_MATCH); + } + + /* + * Check that the label's vdev guid matches the desired guid. + * The second condition handles possible race on vdev detach, when + * remaining vdev receives GUID of destroyed top level mirror vdev. + */ + if (vdev_guid == vd->vdev_guid) { + ZFS_LOG(1, "guids match for provider %s.", pp->name); + return (FULL_MATCH); + } else if (top_guid == vd->vdev_guid && vd == vd->vdev_top) { + ZFS_LOG(1, "top vdev guid match for provider %s.", pp->name); + return (TOP_MATCH); + } + ZFS_LOG(1, "vdev guid mismatch for provider %s: %ju != %ju.", + pp->name, (uintmax_t)vd->vdev_guid, (uintmax_t)vdev_guid); + return (NO_MATCH); } static struct g_consumer * @@ -667,6 +670,7 @@ vdev_geom_attach_by_guids(vdev_t *vd) struct g_geom *gp; struct g_provider *pp; struct g_consumer *cp; + enum match m; g_topology_assert(); @@ -678,23 +682,26 @@ vdev_geom_attach_by_guids(vdev_t *vd) if (gp->flags & G_GEOM_WITHER) continue; LIST_FOREACH(pp, &gp->provider, provider) { - if (!vdev_attach_ok(vd, pp)) + m = vdev_attach_ok(vd, pp); + if (m == NO_MATCH) continue; + if (cp != NULL) { + if (m == FULL_MATCH) + vdev_geom_detach(cp, B_TRUE); + else + continue; + } cp = vdev_geom_attach(pp, vd); if (cp == NULL) { printf("ZFS WARNING: Unable to " "attach to %s.\n", pp->name); continue; } - break; + if (m == FULL_MATCH) + return (cp); } - if (cp != NULL) - break; } - if (cp != NULL) - break; } -end: return (cp); } @@ -742,7 +749,7 @@ vdev_geom_open_by_path(vdev_t *vd, int check_guid) pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1); if (pp != NULL) { ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path); - if (!check_guid || vdev_attach_ok(vd, pp)) + if (!check_guid || vdev_attach_ok(vd, pp) == FULL_MATCH) cp = vdev_geom_attach(pp, vd); } From 471cf6ce7dbc635710a83edf1d99bdb80875e2c0 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 28 Oct 2016 17:05:14 +0000 Subject: [PATCH 184/235] Add vdev_reopening support to vdev_geom. It allows to avoid extra GEOM providers flapping without significant need. Since GEOM got resize support, we don't need to reopen provider to get new size. If provider was orphaned and no longer valid, ZFS should already know that, and in such case reopen should be done in full as expected. MFC after: 2 weeks --- .../opensolaris/uts/common/fs/zfs/vdev_geom.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c index fb0df0a847e6..2529487789e1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c @@ -776,7 +776,14 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, return (EINVAL); } - vd->vdev_tsd = NULL; + /* + * Reopen the device if it's not currently open. Otherwise, + * just update the physical size of the device. + */ + if ((cp = vd->vdev_tsd) != NULL) { + ASSERT(vd->vdev_reopening); + goto skip_open; + } DROP_GIANT(); g_topology_lock(); @@ -861,6 +868,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize, vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; return (error); } +skip_open: pp = cp->provider; /* @@ -896,6 +904,9 @@ static void vdev_geom_close(vdev_t *vd) { + if (vd->vdev_reopening) + return; + DROP_GIANT(); g_topology_lock(); vdev_geom_close_locked(vd); From ab1b41edb58483c2ad143e096e8d252146ec8863 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 28 Oct 2016 18:09:08 +0000 Subject: [PATCH 185/235] Fix formatting of tables. Specifically, use .Ta instead of tabs to separate column entries. While here fix a few other things: - Use .Sy for all column headers (previously only the first column header was bold) - Use .Dv to markup constants used for MIB names. - Use "1234" and "4321" for the byte order descriptions without thousands separators. - Mark up header files in the first table with .In. MFC after: 2 weeks --- lib/libc/gen/sysctl.3 | 242 +++++++++++++++++++++--------------------- 1 file changed, 121 insertions(+), 121 deletions(-) diff --git a/lib/libc/gen/sysctl.3 b/lib/libc/gen/sysctl.3 index 4594d9af9a50..633f364b9f2a 100644 --- a/lib/libc/gen/sysctl.3 +++ b/lib/libc/gen/sysctl.3 @@ -183,16 +183,16 @@ The top level names are defined with a CTL_ prefix in and are as follows. The next and subsequent levels down are found in the include files listed here, and described in separate sections below. -.Bl -column CTLXMACHDEPXXX "Next level namesXXXXXX" -offset indent -.It Sy "Name Next level names Description" -.It "CTL_DEBUG sys/sysctl.h Debugging" -.It "CTL_VFS sys/mount.h File system" -.It "CTL_HW sys/sysctl.h Generic CPU, I/O" -.It "CTL_KERN sys/sysctl.h High kernel limits" -.It "CTL_MACHDEP sys/sysctl.h Machine dependent" -.It "CTL_NET sys/socket.h Networking" -.It "CTL_USER sys/sysctl.h User-level" -.It "CTL_VM vm/vm_param.h Virtual memory" +.Bl -column CTLXMACHDEPXXX "Next Level NamesXXXXXX" -offset indent +.It Sy Name Ta Sy Next Level Names Ta Sy Description +.It Dv CTL_DEBUG Ta In sys/sysctl.h Ta Debugging +.It Dv CTL_VFS Ta In sys/mount.h Ta File system +.It Dv CTL_HW Ta In sys/sysctl.h Ta Generic CPU, I/O +.It Dv CTL_KERN Ta In sys/sysctl.h Ta High kernel limits +.It Dv CTL_MACHDEP Ta In sys/sysctl.h Ta Machine dependent +.It Dv CTL_NET Ta In sys/socket.h Ta Networking +.It Dv CTL_USER Ta In sys/sysctl.h Ta User-level +.It Dv CTL_VM Ta In vm/vm_param.h Ta Virtual memory .El .Pp For example, the following retrieves the maximum number of processes allowed @@ -270,20 +270,20 @@ The string and integer information available for the CTL_HW level is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. -.Bl -column "Second level nameXXXXXX" integerXXX -offset indent -.It Sy "Second level name Type Changeable" -.It "HW_MACHINE string no" -.It "HW_MODEL string no" -.It "HW_NCPU integer no" -.It "HW_BYTEORDER integer no" -.It "HW_PHYSMEM integer no" -.It "HW_USERMEM integer no" -.It "HW_PAGESIZE integer no" -.\".It "HW_DISKNAMES integer no" -.\".It "HW_DISKSTATS integer no" -.It "HW_FLOATINGPT integer no" -.It "HW_MACHINE_ARCH string no" -.It "HW_REALMEM integer no" +.Bl -column "Second Level Name" integerXXX Changeable -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv HW_MACHINE Ta string Ta no +.It Dv HW_MODEL Ta string Ta no +.It Dv HW_NCPU Ta integer Ta no +.It Dv HW_BYTEORDER Ta integer Ta no +.It Dv HW_PHYSMEM Ta integer Ta no +.It Dv HW_USERMEM Ta integer Ta no +.It Dv HW_PAGESIZE Ta integer Ta no +.\".It Dv HW_DISKNAMES Ta integer Ta no +.\".It Dv HW_DISKSTATS Ta integer Ta no +.It Dv HW_FLOATINGPT Ta integer Ta no +.It Dv HW_MACHINE_ARCH Ta string Ta no +.It Dv HW_REALMEM Ta integer Ta no .El .Bl -tag -width 6n .It Li HW_MACHINE @@ -293,7 +293,7 @@ The machine model .It Li HW_NCPU The number of cpus. .It Li HW_BYTEORDER -The byteorder (4,321, or 1,234). +The byteorder (4321 or 1234). .It Li HW_PHYSMEM The bytes of physical memory. .It Li HW_USERMEM @@ -319,36 +319,36 @@ system vnodes, the open file entries, routing table entries, virtual memory statistics, load average history, and clock rate information. .Bl -column "KERNXMAXFILESPERPROCXXX" "struct clockrateXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "KERN_ARGMAX integer no" -.It "KERN_BOOTFILE string yes" -.It "KERN_BOOTTIME struct timeval no" -.It "KERN_CLOCKRATE struct clockinfo no" -.It "KERN_FILE struct xfile no" -.It "KERN_HOSTID integer yes" -.It "KERN_HOSTUUID string yes" -.It "KERN_HOSTNAME string yes" -.It "KERN_JOB_CONTROL integer no" -.It "KERN_MAXFILES integer yes" -.It "KERN_MAXFILESPERPROC integer yes" -.It "KERN_MAXPROC integer no" -.It "KERN_MAXPROCPERUID integer yes" -.It "KERN_MAXVNODES integer yes" -.It "KERN_NGROUPS integer no" -.It "KERN_NISDOMAINNAME string yes" -.It "KERN_OSRELDATE integer no" -.It "KERN_OSRELEASE string no" -.It "KERN_OSREV integer no" -.It "KERN_OSTYPE string no" -.It "KERN_POSIX1 integer no" -.It "KERN_PROC node not applicable" -.It "KERN_PROF node not applicable" -.It "KERN_QUANTUM integer yes" -.It "KERN_SAVED_IDS integer no" -.It "KERN_SECURELVL integer raise only" -.It "KERN_UPDATEINTERVAL integer no" -.It "KERN_VERSION string no" -.It "KERN_VNODE struct xvnode no" +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv KERN_ARGMAX Ta integer Ta no +.It Dv KERN_BOOTFILE Ta string Ta yes +.It Dv KERN_BOOTTIME Ta struct timeval Ta no +.It Dv KERN_CLOCKRATE Ta struct clockinfo Ta no +.It Dv KERN_FILE Ta struct xfile Ta no +.It Dv KERN_HOSTID Ta integer Ta yes +.It Dv KERN_HOSTUUID Ta string Ta yes +.It Dv KERN_HOSTNAME Ta string Ta yes +.It Dv KERN_JOB_CONTROL Ta integer Ta no +.It Dv KERN_MAXFILES Ta integer Ta yes +.It Dv KERN_MAXFILESPERPROC Ta integer Ta yes +.It Dv KERN_MAXPROC Ta integer Ta no +.It Dv KERN_MAXPROCPERUID Ta integer Ta yes +.It Dv KERN_MAXVNODES Ta integer Ta yes +.It Dv KERN_NGROUPS Ta integer Ta no +.It Dv KERN_NISDOMAINNAME Ta string Ta yes +.It Dv KERN_OSRELDATE Ta integer Ta no +.It Dv KERN_OSRELEASE Ta string Ta no +.It Dv KERN_OSREV Ta integer Ta no +.It Dv KERN_OSTYPE Ta string Ta no +.It Dv KERN_POSIX1 Ta integer Ta no +.It Dv KERN_PROC Ta node Ta not applicable +.It Dv KERN_PROF Ta node Ta not applicable +.It Dv KERN_QUANTUM Ta integer Ta yes +.It Dv KERN_SAVED_IDS Ta integer Ta no +.It Dv KERN_SECURELVL Ta integer Ta raise only +.It Dv KERN_UPDATEINTERVAL Ta integer Ta no +.It Dv KERN_VERSION Ta string Ta no +.It Dv KERN_VNODE Ta struct xvnode Ta no .El .Bl -tag -width 6n .It Li KERN_ARGMAX @@ -439,14 +439,14 @@ For the following names, an array of .Va struct kinfo_proc structures is returned, whose size depends on the current number of such objects in the system. -.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent -.It "Third level name Fourth level is:" -.It "KERN_PROC_ALL None" -.It "KERN_PROC_PID A process ID" -.It "KERN_PROC_PGRP A process group" -.It "KERN_PROC_TTY A tty device" -.It "KERN_PROC_UID A user ID" -.It "KERN_PROC_RUID A real user ID" +.Bl -column "Third Level NameXXXXXX" "Fourth LevelXXXXXX" -offset indent +.It Sy Third Level Name Ta Sy Fourth Level +.It Dv KERN_PROC_ALL Ta None +.It Dv KERN_PROC_PID Ta A process ID +.It Dv KERN_PROC_PGRP Ta A process group +.It Dv KERN_PROC_TTY Ta A tty device +.It Dv KERN_PROC_UID Ta A user ID +.It Dv KERN_PROC_RUID Ta A real user ID .El .Pp If the third level name is @@ -465,8 +465,8 @@ For a process ID of .Li \-1 implies the current process. -.Bl -column "Third level nameXXXXXX" "Fourth level is:XXXXXX" -offset indent -.It Sy "Third level name Fourth level is:" +.Bl -column "Third Level NameXXXXXX" "Fourth LevelXXXXXX" -offset indent +.It Sy Third Level Name Ta Sy Fourth Level .It Dv KERN_PROC_ARGS Ta "A process ID" .It Dv KERN_PROC_PATHNAME Ta "A process ID" .El @@ -481,12 +481,12 @@ is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. .Bl -column "GPROFXGMONPARAMXXX" "struct gmonparamXXX" -offset indent -.It Sy "Third level name Type Changeable" -.It "GPROF_STATE integer yes" -.It "GPROF_COUNT u_short[\|] yes" -.It "GPROF_FROMS u_short[\|] yes" -.It "GPROF_TOS struct tostruct yes" -.It "GPROF_GMONPARAM struct gmonparam no" +.It Sy Third Level Name Ta Sy Type Ta Sy Changeable +.It Dv GPROF_STATE Ta integer Ta yes +.It Dv GPROF_COUNT Ta u_short[\|] Ta yes +.It Dv GPROF_FROMS Ta u_short[\|] Ta yes +.It Dv GPROF_TOS Ta struct tostruct Ta yes +.It Dv GPROF_GMONPARAM Ta struct gmonparam Ta no .El .Pp The variables are as follows: @@ -530,11 +530,11 @@ The string and integer information available for the CTL_NET level is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. -.Bl -column "Second level nameXXXXXX" "routing messagesXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "PF_ROUTE routing messages no" -.It "PF_INET IPv4 values yes" -.It "PF_INET6 IPv6 values yes" +.Bl -column "Second Level NameXXXXXX" "routing messagesXXX" -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv PF_ROUTE Ta routing messages Ta no +.It Dv PF_INET Ta IPv4 values Ta yes +.It Dv PF_INET6 Ta IPv6 values Ta yes .El .Bl -tag -width 6n .It Li PF_ROUTE @@ -548,13 +548,13 @@ The third level name is a protocol number, which is currently always 0. The fourth level name is an address family, which may be set to 0 to select all address families. The fifth, sixth, and seventh level names are as follows: -.Bl -column -offset indent "Fifth level Sixth level" "Seventh level" -.It Sy "Fifth level Sixth level" Ta Sy "Seventh level" -.It "NET_RT_FLAGS rtflags" Ta "None" -.It "NET_RT_DUMP None" Ta "None or fib number" -.It "NET_RT_IFLIST 0 or if_index" Ta None -.It "NET_RT_IFMALIST 0 or if_index" Ta None -.It "NET_RT_IFLISTL 0 or if_index" Ta None +.Bl -column -offset indent "Fifth Level" "Sixth Level" "Seventh Level" +.It Sy Fifth level Ta Sy Sixth Level Ta Sy Seventh Level +.It Dv NET_RT_FLAGS Ta rtflags Ta None +.It Dv NET_RT_DUMP Ta None Ta None or fib number +.It Dv NET_RT_IFLIST Ta 0 or if_index Ta None +.It Dv NET_RT_IFMALIST Ta 0 or if_index Ta None +.It Dv NET_RT_IFLISTL Ta 0 or if_index Ta None .El .Pp The @@ -582,13 +582,13 @@ The third level name is the protocol. The fourth level name is the variable name. The currently defined protocols and names are: .Bl -column ProtocolXX VariableXX TypeXX ChangeableXX -.It Sy "Protocol Variable Type Changeable" -.It "icmp bmcastecho integer yes" -.It "icmp maskrepl integer yes" -.It "ip forwarding integer yes" -.It "ip redirect integer yes" -.It "ip ttl integer yes" -.It "udp checksum integer yes" +.It Sy Protocol Ta Sy Variable Ta Sy Type Ta Sy Changeable +.It icmp Ta bmcastecho Ta integer Ta yes +.It icmp Ta maskrepl Ta integer Ta yes +.It ip Ta forwarding Ta integer Ta yes +.It ip Ta redirect Ta integer Ta yes +.It ip Ta ttl Ta integer Ta yes +.It udp Ta checksum Ta integer Ta yes .El .Pp The variables are as follows: @@ -633,27 +633,27 @@ is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. .Bl -column "USER_COLL_WEIGHTS_MAXXXX" "integerXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "USER_BC_BASE_MAX integer no" -.It "USER_BC_DIM_MAX integer no" -.It "USER_BC_SCALE_MAX integer no" -.It "USER_BC_STRING_MAX integer no" -.It "USER_COLL_WEIGHTS_MAX integer no" -.It "USER_CS_PATH string no" -.It "USER_EXPR_NEST_MAX integer no" -.It "USER_LINE_MAX integer no" -.It "USER_POSIX2_CHAR_TERM integer no" -.It "USER_POSIX2_C_BIND integer no" -.It "USER_POSIX2_C_DEV integer no" -.It "USER_POSIX2_FORT_DEV integer no" -.It "USER_POSIX2_FORT_RUN integer no" -.It "USER_POSIX2_LOCALEDEF integer no" -.It "USER_POSIX2_SW_DEV integer no" -.It "USER_POSIX2_UPE integer no" -.It "USER_POSIX2_VERSION integer no" -.It "USER_RE_DUP_MAX integer no" -.It "USER_STREAM_MAX integer no" -.It "USER_TZNAME_MAX integer no" +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv USER_BC_BASE_MAX Ta integer Ta no +.It Dv USER_BC_DIM_MAX Ta integer Ta no +.It Dv USER_BC_SCALE_MAX Ta integer Ta no +.It Dv USER_BC_STRING_MAX Ta integer Ta no +.It Dv USER_COLL_WEIGHTS_MAX Ta integer Ta no +.It Dv USER_CS_PATH Ta string Ta no +.It Dv USER_EXPR_NEST_MAX Ta integer Ta no +.It Dv USER_LINE_MAX Ta integer Ta no +.It Dv USER_POSIX2_CHAR_TERM Ta integer Ta no +.It Dv USER_POSIX2_C_BIND Ta integer Ta no +.It Dv USER_POSIX2_C_DEV Ta integer Ta no +.It Dv USER_POSIX2_FORT_DEV Ta integer Ta no +.It Dv USER_POSIX2_FORT_RUN Ta integer Ta no +.It Dv USER_POSIX2_LOCALEDEF Ta integer Ta no +.It Dv USER_POSIX2_SW_DEV Ta integer Ta no +.It Dv USER_POSIX2_UPE Ta integer Ta no +.It Dv USER_POSIX2_VERSION Ta integer Ta no +.It Dv USER_RE_DUP_MAX Ta integer Ta no +.It Dv USER_STREAM_MAX Ta integer Ta no +.It Dv USER_TZNAME_MAX Ta integer Ta no .El .Bl -tag -width 6n .It Li USER_BC_BASE_MAX @@ -731,16 +731,16 @@ The string and integer information available for the CTL_VM level is detailed below. The changeable column shows whether a process with appropriate privilege may change the value. -.Bl -column "Second level nameXXXXXX" "struct loadavgXXX" -offset indent -.It Sy "Second level name Type Changeable" -.It "VM_LOADAVG struct loadavg no" -.It "VM_TOTAL struct vmtotal no" -.It "VM_SWAPPING_ENABLED integer maybe" -.It "VM_V_FREE_MIN integer yes" -.It "VM_V_FREE_RESERVED integer yes" -.It "VM_V_FREE_TARGET integer yes" -.It "VM_V_INACTIVE_TARGET integer yes" -.It "VM_V_PAGEOUT_FREE_MIN integer yes" +.Bl -column "Second Level NameXXXXXX" "struct loadavgXXX" -offset indent +.It Sy Second Level Name Ta Sy Type Ta Sy Changeable +.It Dv VM_LOADAVG Ta struct loadavg Ta no +.It Dv VM_TOTAL Ta struct vmtotal Ta no +.It Dv VM_SWAPPING_ENABLED Ta integer Ta maybe +.It Dv VM_V_FREE_MIN Ta integer Ta yes +.It Dv VM_V_FREE_RESERVED Ta integer Ta yes +.It Dv VM_V_FREE_TARGET Ta integer Ta yes +.It Dv VM_V_INACTIVE_TARGET Ta integer Ta yes +.It Dv VM_V_PAGEOUT_FREE_MIN Ta integer Ta yes .El .Bl -tag -width 6n .It Li VM_LOADAVG From ad544726aa68ae6f9a30f476e948912aeaa8164e Mon Sep 17 00:00:00 2001 From: Kirk McKusick Date: Fri, 28 Oct 2016 20:15:19 +0000 Subject: [PATCH 186/235] Avoid possible overflow when calclating malloc size for auxillary data structure sizes when mounting and reloading UFS/FFS filesystems by using a u_long rather than an int for the size. Reported by: Mariusz Zaborski MFC after: 1 week --- sys/ufs/ffs/ffs_vfsops.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 46dbdb151417..2520f007ec6e 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -588,7 +588,8 @@ ffs_reload(struct mount *mp, struct thread *td, int flags) struct fs *fs, *newfs; struct ufsmount *ump; ufs2_daddr_t sblockloc; - int i, blks, size, error; + int i, blks, error; + u_long size; int32_t *lp; ump = VFSTOUFS(mp); @@ -658,7 +659,7 @@ ffs_reload(struct mount *mp, struct thread *td, int flags) size += fs->fs_ncg * sizeof(int32_t); size += fs->fs_ncg * sizeof(u_int8_t); free(fs->fs_csp, M_UFSMNT); - space = malloc((u_long)size, M_UFSMNT, M_WAITOK); + space = malloc(size, M_UFSMNT, M_WAITOK); fs->fs_csp = space; for (i = 0; i < blks; i += fs->fs_frag) { size = fs->fs_bsize; @@ -751,7 +752,8 @@ ffs_mountfs(devvp, mp, td) struct cdev *dev; void *space; ufs2_daddr_t sblockloc; - int error, i, blks, size, ronly; + int error, i, blks, len, ronly; + u_long size; int32_t *lp; struct ucred *cred; struct g_consumer *cp; @@ -856,11 +858,11 @@ ffs_mountfs(devvp, mp, td) /* * Get journal provider name. */ - size = 1024; - mp->mnt_gjprovider = malloc(size, M_UFSMNT, M_WAITOK); - if (g_io_getattr("GJOURNAL::provider", cp, &size, + len = 1024; + mp->mnt_gjprovider = malloc((u_long)len, M_UFSMNT, M_WAITOK); + if (g_io_getattr("GJOURNAL::provider", cp, &len, mp->mnt_gjprovider) == 0) { - mp->mnt_gjprovider = realloc(mp->mnt_gjprovider, size, + mp->mnt_gjprovider = realloc(mp->mnt_gjprovider, len, M_UFSMNT, M_WAITOK); MNT_ILOCK(mp); mp->mnt_flag |= MNT_GJOURNAL; @@ -912,7 +914,7 @@ ffs_mountfs(devvp, mp, td) if (fs->fs_contigsumsize > 0) size += fs->fs_ncg * sizeof(int32_t); size += fs->fs_ncg * sizeof(u_int8_t); - space = malloc((u_long)size, M_UFSMNT, M_WAITOK); + space = malloc(size, M_UFSMNT, M_WAITOK); fs->fs_csp = space; for (i = 0; i < blks; i += fs->fs_frag) { size = fs->fs_bsize; @@ -997,8 +999,8 @@ ffs_mountfs(devvp, mp, td) #endif } if ((fs->fs_flags & FS_TRIM) != 0) { - size = sizeof(int); - if (g_io_getattr("GEOM::candelete", cp, &size, + len = sizeof(int); + if (g_io_getattr("GEOM::candelete", cp, &len, &ump->um_candelete) == 0) { if (!ump->um_candelete) printf("WARNING: %s: TRIM flag on fs but disk " From aee43414218ab1b066338f3f800c4c494cf503d6 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 28 Oct 2016 20:23:38 +0000 Subject: [PATCH 187/235] Remove a PCI ID for a raid controller from Adaptec that was planned, but never released. Since no real hardware was released with this ID, just drop it from the aacraid driver. This paves the path for future drivers for hardware that actually has this ID. Submitted by: Scott Benesh from Microsemi. Differential Revision: https://reviews.freebsd.org/D8377 MFC After: 3 days --- sys/dev/aacraid/aacraid_pci.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/aacraid/aacraid_pci.c b/sys/dev/aacraid/aacraid_pci.c index 46eb53c85aba..0f67c742be0b 100644 --- a/sys/dev/aacraid/aacraid_pci.c +++ b/sys/dev/aacraid/aacraid_pci.c @@ -102,8 +102,6 @@ struct aac_ident "Adaptec RAID Controller"}, {0x9005, 0x028d, 0, 0, AAC_HWIF_SRCV, 0, "Adaptec RAID Controller"}, - {0x9005, 0x028f, 0, 0, AAC_HWIF_SRCV, 0, - "Adaptec RAID Controller"}, {0, 0, 0, 0, 0, 0, 0} }; From 041e5aed6365f11008c37854433000312e4f18bd Mon Sep 17 00:00:00 2001 From: Navdeep Parhar Date: Fri, 28 Oct 2016 23:01:11 +0000 Subject: [PATCH 188/235] cxgbe(4): Accurate statistics for all chip settings. There are 4 independent knobs in T5+ chips to include or exclude PAUSE frames from the "total frames" and "multicast frames" counters in either direction. This change lets the driver deal with any combination of these settings. --- sys/dev/cxgbe/common/t4_hw.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c index 4a52139ac98c..9ba4b9566518 100644 --- a/sys/dev/cxgbe/common/t4_hw.c +++ b/sys/dev/cxgbe/common/t4_hw.c @@ -5870,10 +5870,13 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) p->tx_ppp6 = GET_STAT(TX_PORT_PPP6); p->tx_ppp7 = GET_STAT(TX_PORT_PPP7); - if (stat_ctl & F_COUNTPAUSESTATTX) { - p->tx_frames -= p->tx_pause; - p->tx_octets -= p->tx_pause * 64; - p->tx_mcast_frames -= p->tx_pause; + if (chip_id(adap) >= CHELSIO_T5) { + if (stat_ctl & F_COUNTPAUSESTATTX) { + p->tx_frames -= p->tx_pause; + p->tx_octets -= p->tx_pause * 64; + } + if (stat_ctl & F_COUNTPAUSEMCTX) + p->tx_mcast_frames -= p->tx_pause; } p->rx_pause = GET_STAT(RX_PORT_PAUSE); @@ -5904,10 +5907,13 @@ void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p) p->rx_ppp6 = GET_STAT(RX_PORT_PPP6); p->rx_ppp7 = GET_STAT(RX_PORT_PPP7); - if (stat_ctl & F_COUNTPAUSESTATRX) { - p->rx_frames -= p->rx_pause; - p->rx_octets -= p->rx_pause * 64; - p->rx_mcast_frames -= p->rx_pause; + if (chip_id(adap) >= CHELSIO_T5) { + if (stat_ctl & F_COUNTPAUSESTATRX) { + p->rx_frames -= p->rx_pause; + p->rx_octets -= p->rx_pause * 64; + } + if (stat_ctl & F_COUNTPAUSEMCRX) + p->rx_mcast_frames -= p->rx_pause; } p->rx_ovflow0 = (bgmap & 1) ? GET_STAT_COM(RX_BG_0_MAC_DROP_FRAME) : 0; From 05e4cffbb097511595a32b8d0d63dce71eb24be5 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 28 Oct 2016 23:53:33 +0000 Subject: [PATCH 189/235] ioat(4): Add additional tracing These probes help track down driver bugs. Sponsored by: Dell EMC Isilon --- sys/dev/ioat/ioat.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index ccf9166f8abb..26b465de69aa 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -693,8 +693,8 @@ ioat_process_events(struct ioat_softc *ioat) while (desc->hw_desc_bus_addr != status && ioat_get_active(ioat) > 0) { desc = ioat_get_ring_entry(ioat, ioat->tail); dmadesc = &desc->bus_dmadesc; - CTR4(KTR_IOAT, "channel=%u completing desc %u ok cb %p(%p)", - ioat->chan_idx, ioat->tail, dmadesc->callback_fn, + CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) ok cb %p(%p)", + ioat->chan_idx, ioat->tail, dmadesc, dmadesc->callback_fn, dmadesc->callback_arg); if (dmadesc->callback_fn != NULL) @@ -703,6 +703,8 @@ ioat_process_events(struct ioat_softc *ioat) completed++; ioat->tail++; } + CTR5(KTR_IOAT, "%s channel=%u head=%u tail=%u active=%u", __func__, + ioat->chan_idx, ioat->head, ioat->tail, ioat_get_active(ioat)); if (completed != 0) { ioat->last_seen = desc->hw_desc_bus_addr; @@ -760,8 +762,8 @@ ioat_process_events(struct ioat_softc *ioat) while (ioat_get_active(ioat) > 0) { desc = ioat_get_ring_entry(ioat, ioat->tail); dmadesc = &desc->bus_dmadesc; - CTR4(KTR_IOAT, "channel=%u completing desc %u err cb %p(%p)", - ioat->chan_idx, ioat->tail, dmadesc->callback_fn, + CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) err cb %p(%p)", + ioat->chan_idx, ioat->tail, dmadesc, dmadesc->callback_fn, dmadesc->callback_arg); if (dmadesc->callback_fn != NULL) @@ -773,6 +775,8 @@ ioat_process_events(struct ioat_softc *ioat) ioat->stats.descriptors_processed++; ioat->stats.descriptors_error++; } + CTR5(KTR_IOAT, "%s channel=%u head=%u tail=%u active=%u", __func__, + ioat->chan_idx, ioat->head, ioat->tail, ioat_get_active(ioat)); if (ioat->is_completion_pending) { ioat->is_completion_pending = FALSE; @@ -947,7 +951,8 @@ ioat_release(bus_dmaengine_t dmaengine) struct ioat_softc *ioat; ioat = to_ioat_softc(dmaengine); - CTR2(KTR_IOAT, "%s channel=%u", __func__, ioat->chan_idx); + CTR3(KTR_IOAT, "%s channel=%u dispatch hw_head=%u", __func__, + ioat->chan_idx, ioat->hw_head & UINT16_MAX); ioat_write_2(ioat, IOAT_DMACOUNT_OFFSET, (uint16_t)ioat->hw_head); if (!ioat->is_completion_pending) { @@ -1040,7 +1045,6 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst, struct ioat_softc *ioat; ioat = to_ioat_softc(dmaengine); - CTR2(KTR_IOAT, "%s channel=%u", __func__, ioat->chan_idx); if (((src | dst) & (0xffffull << 48)) != 0) { ioat_log_message(0, "%s: High 16 bits of src/dst invalid\n", @@ -1058,6 +1062,8 @@ ioat_copy(bus_dmaengine_t dmaengine, bus_addr_t dst, dump_descriptor(hw_desc); ioat_submit_single(ioat); + CTR6(KTR_IOAT, "%s channel=%u desc=%p dest=%lx src=%lx len=%lx", + __func__, ioat->chan_idx, &desc->bus_dmadesc, dst, src, len); return (&desc->bus_dmadesc); } @@ -1414,11 +1420,16 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags) if (ioat_get_ring_space(ioat) >= num_descs) goto out; + CTR3(KTR_IOAT, "%s channel=%u starved (%u)", __func__, + ioat->chan_idx, num_descs); + if (!dug && !ioat->is_submitter_processing && (1 << ioat->ring_size_order) > num_descs) { ioat->is_submitter_processing = TRUE; mtx_unlock(&ioat->submit_lock); + CTR2(KTR_IOAT, "%s channel=%u attempting to process events", + __func__, ioat->chan_idx); ioat_process_events(ioat); mtx_lock(&ioat->submit_lock); @@ -1433,6 +1444,8 @@ ioat_reserve_space(struct ioat_softc *ioat, uint32_t num_descs, int mflags) order = ioat->ring_size_order; if (ioat->is_resize_pending || order == IOAT_MAX_ORDER) { if ((mflags & M_WAITOK) != 0) { + CTR2(KTR_IOAT, "%s channel=%u blocking on completions", + __func__, ioat->chan_idx); msleep(&ioat->tail, &ioat->submit_lock, 0, "ioat_rsz", 0); continue; @@ -1794,6 +1807,9 @@ ioat_submit_single(struct ioat_softc *ioat) ioat_get(ioat, IOAT_ACTIVE_DESCR_REF); atomic_add_rel_int(&ioat->head, 1); atomic_add_rel_int(&ioat->hw_head, 1); + CTR5(KTR_IOAT, "%s channel=%u head=%u hw_head=%u tail=%u", __func__, + ioat->chan_idx, ioat->head, ioat->hw_head & UINT16_MAX, + ioat->tail); ioat->stats.descriptors_submitted++; } From 5a8af401ae16aacb3f2f85eda31c227ee65c8984 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 28 Oct 2016 23:53:35 +0000 Subject: [PATCH 190/235] ioat(4): Assert the submit lock in ioat_submit_single Sponsored by: Dell EMC Isilon --- sys/dev/ioat/ioat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 26b465de69aa..f7bb2c9bd26e 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -1804,6 +1804,8 @@ static void ioat_submit_single(struct ioat_softc *ioat) { + mtx_assert(&ioat->submit_lock, MA_OWNED); + ioat_get(ioat, IOAT_ACTIVE_DESCR_REF); atomic_add_rel_int(&ioat->head, 1); atomic_add_rel_int(&ioat->hw_head, 1); From 76305bb8650da7d69cd08eb2da87a18d63c78505 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 28 Oct 2016 23:53:36 +0000 Subject: [PATCH 191/235] ioat(4): Add failpoint for delay() in ioat_release Sponsored by: Dell EMC Isilon --- sys/dev/ioat/ioat.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index f7bb2c9bd26e..2fa4859fd136 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -33,6 +33,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -951,8 +952,12 @@ ioat_release(bus_dmaengine_t dmaengine) struct ioat_softc *ioat; ioat = to_ioat_softc(dmaengine); - CTR3(KTR_IOAT, "%s channel=%u dispatch hw_head=%u", __func__, - ioat->chan_idx, ioat->hw_head & UINT16_MAX); + CTR4(KTR_IOAT, "%s channel=%u dispatch1 hw_head=%u head=%u", __func__, + ioat->chan_idx, ioat->hw_head & UINT16_MAX, ioat->head); + KFAIL_POINT_CODE(DEBUG_FP, ioat_release, /* do nothing */); + CTR4(KTR_IOAT, "%s channel=%u dispatch2 hw_head=%u head=%u", __func__, + ioat->chan_idx, ioat->hw_head & UINT16_MAX, ioat->head); + ioat_write_2(ioat, IOAT_DMACOUNT_OFFSET, (uint16_t)ioat->hw_head); if (!ioat->is_completion_pending) { From 0d0f264099c43c3d510479271364a5326cef5ea0 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 28 Oct 2016 23:53:37 +0000 Subject: [PATCH 192/235] ioat(4): Use memory completion rather than device register The CHANSTS register is a split 64-bit register on CBDMA units before hardware v3.3. If a torn read happens during ioat_process_events(), software cannot know when to stop completing descriptors correctly. So, just use the device-pushed main memory channel status instead. Remove the ioat_get_active() seatbelt as well. It does nothing if the completion address is valid. Sponsored by: Dell EMC Isilon --- sys/dev/ioat/ioat.c | 4 ++-- sys/dev/ioat/ioat_internal.h | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/sys/dev/ioat/ioat.c b/sys/dev/ioat/ioat.c index 2fa4859fd136..21723b28f471 100644 --- a/sys/dev/ioat/ioat.c +++ b/sys/dev/ioat/ioat.c @@ -677,7 +677,7 @@ ioat_process_events(struct ioat_softc *ioat) } completed = 0; - comp_update = ioat_get_chansts(ioat); + comp_update = *ioat->comp_update; status = comp_update & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_MASK; if (status == ioat->last_seen) { @@ -691,7 +691,7 @@ ioat_process_events(struct ioat_softc *ioat) __func__, ioat->chan_idx, comp_update, ioat->last_seen); desc = ioat_get_ring_entry(ioat, ioat->tail - 1); - while (desc->hw_desc_bus_addr != status && ioat_get_active(ioat) > 0) { + while (desc->hw_desc_bus_addr != status) { desc = ioat_get_ring_entry(ioat, ioat->tail); dmadesc = &desc->bus_dmadesc; CTR5(KTR_IOAT, "channel=%u completing desc idx %u (%p) ok cb %p(%p)", diff --git a/sys/dev/ioat/ioat_internal.h b/sys/dev/ioat/ioat_internal.h index a8507609c11d..419b1fdba270 100644 --- a/sys/dev/ioat/ioat_internal.h +++ b/sys/dev/ioat/ioat_internal.h @@ -523,6 +523,15 @@ struct ioat_softc { void ioat_test_attach(void); void ioat_test_detach(void); +/* + * XXX DO NOT USE this routine for obtaining the current completed descriptor. + * + * The double_4 read on ioat<3.3 appears to result in torn reads. And v3.2 + * hardware is still commonplace (Broadwell Xeon has it). Instead, use the + * device-pushed *comp_update. + * + * It is safe to use ioat_get_chansts() for the low status bits. + */ static inline uint64_t ioat_get_chansts(struct ioat_softc *ioat) { From aab03089ee92dda64ca7b0856e9de8f554cd0c6a Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 29 Oct 2016 01:22:55 +0000 Subject: [PATCH 193/235] Fix a copy&paste-o causing a segfault with sigsetjmp. I'm not sure how this passed my code inspection and initial testing, it's obviously wrong. Found when debugging csh. --- lib/libc/powerpcspe/gen/setjmp.S | 46 ++++++++++++++--------------- lib/libc/powerpcspe/gen/sigsetjmp.S | 46 ++++++++++++++--------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/libc/powerpcspe/gen/setjmp.S b/lib/libc/powerpcspe/gen/setjmp.S index 3d70b5b4a419..7a93b2f883e8 100644 --- a/lib/libc/powerpcspe/gen/setjmp.S +++ b/lib/libc/powerpcspe/gen/setjmp.S @@ -95,29 +95,29 @@ END(setjmp) WEAK_REFERENCE(CNAME(__longjmp), longjmp) ENTRY(__longjmp) - evldd %r9,24+0*8(%r6) - evldd %r10,24+1*8(%r6) - evldd %r11,24+2*8(%r6) - evldd %r12,24+3*8(%r6) - evldd %r13,24+4*8(%r6) - evldd %r14,24+5*8(%r6) - evldd %r15,24+6*8(%r6) - evldd %r16,24+7*8(%r6) - evldd %r17,24+8*8(%r6) - evldd %r18,24+9*8(%r6) - evldd %r19,24+10*8(%r6) - evldd %r20,24+11*8(%r6) - evldd %r21,24+12*8(%r6) - evldd %r22,24+13*8(%r6) - evldd %r23,24+14*8(%r6) - evldd %r24,24+15*8(%r6) - evldd %r25,24+16*8(%r6) - evldd %r26,24+17*8(%r6) - evldd %r27,24+18*8(%r6) - evldd %r28,24+19*8(%r6) - evldd %r29,24+20*8(%r6) - evldd %r30,24+21*8(%r6) - evldd %r31,24+22*8(%r6) + evldd %r9,24+0*8(%r3) + evldd %r10,24+1*8(%r3) + evldd %r11,24+2*8(%r3) + evldd %r12,24+3*8(%r3) + evldd %r13,24+4*8(%r3) + evldd %r14,24+5*8(%r3) + evldd %r15,24+6*8(%r3) + evldd %r16,24+7*8(%r3) + evldd %r17,24+8*8(%r3) + evldd %r18,24+9*8(%r3) + evldd %r19,24+10*8(%r3) + evldd %r20,24+11*8(%r3) + evldd %r21,24+12*8(%r3) + evldd %r22,24+13*8(%r3) + evldd %r23,24+14*8(%r3) + evldd %r24,24+15*8(%r3) + evldd %r25,24+16*8(%r3) + evldd %r26,24+17*8(%r3) + evldd %r27,24+18*8(%r3) + evldd %r28,24+19*8(%r3) + evldd %r29,24+20*8(%r3) + evldd %r30,24+21*8(%r3) + evldd %r31,24+22*8(%r3) mr %r6,%r4 /* save val param */ mtlr %r11 /* r11 -> link reg */ diff --git a/lib/libc/powerpcspe/gen/sigsetjmp.S b/lib/libc/powerpcspe/gen/sigsetjmp.S index 31737e0d8558..0c12cc3f582b 100644 --- a/lib/libc/powerpcspe/gen/sigsetjmp.S +++ b/lib/libc/powerpcspe/gen/sigsetjmp.S @@ -103,29 +103,29 @@ END(sigsetjmp) ENTRY(siglongjmp) /* FPRs */ - evldd %r9,24+0*8(%r6) - evldd %r10,24+1*8(%r6) - evldd %r11,24+2*8(%r6) - evldd %r12,24+3*8(%r6) - evldd %r13,24+4*8(%r6) - evldd %r14,24+5*8(%r6) - evldd %r15,24+6*8(%r6) - evldd %r16,24+7*8(%r6) - evldd %r17,24+8*8(%r6) - evldd %r18,24+9*8(%r6) - evldd %r19,24+10*8(%r6) - evldd %r20,24+11*8(%r6) - evldd %r21,24+12*8(%r6) - evldd %r22,24+13*8(%r6) - evldd %r23,24+14*8(%r6) - evldd %r24,24+15*8(%r6) - evldd %r25,24+16*8(%r6) - evldd %r26,24+17*8(%r6) - evldd %r27,24+18*8(%r6) - evldd %r28,24+19*8(%r6) - evldd %r29,24+20*8(%r6) - evldd %r30,24+21*8(%r6) - evldd %r31,24+22*8(%r6) + evldd %r9,24+0*8(%r3) + evldd %r10,24+1*8(%r3) + evldd %r11,24+2*8(%r3) + evldd %r12,24+3*8(%r3) + evldd %r13,24+4*8(%r3) + evldd %r14,24+5*8(%r3) + evldd %r15,24+6*8(%r3) + evldd %r16,24+7*8(%r3) + evldd %r17,24+8*8(%r3) + evldd %r18,24+9*8(%r3) + evldd %r19,24+10*8(%r3) + evldd %r20,24+11*8(%r3) + evldd %r21,24+12*8(%r3) + evldd %r22,24+13*8(%r3) + evldd %r23,24+14*8(%r3) + evldd %r24,24+15*8(%r3) + evldd %r25,24+16*8(%r3) + evldd %r26,24+17*8(%r3) + evldd %r27,24+18*8(%r3) + evldd %r28,24+19*8(%r3) + evldd %r29,24+20*8(%r3) + evldd %r30,24+21*8(%r3) + evldd %r31,24+22*8(%r3) lwz %r7,0(%r3) mr %r6,%r4 From 512071de53a079b72e9f20333b2c2db2a5b59f5a Mon Sep 17 00:00:00 2001 From: Justin Hibbits Date: Sat, 29 Oct 2016 01:24:30 +0000 Subject: [PATCH 194/235] Add the SPE feature mask for e500v1 and e500v2 On e500v2 SoCs it will now print: cpu0: Features 84e08000 at bootup. --- sys/powerpc/include/cpu.h | 6 +++++- sys/powerpc/powerpc/cpu.c | 7 +++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/powerpc/include/cpu.h b/sys/powerpc/include/cpu.h index fffb2b4267ae..86bd607c2f38 100644 --- a/sys/powerpc/include/cpu.h +++ b/sys/powerpc/include/cpu.h @@ -56,6 +56,9 @@ extern int cpu_features2; #define PPC_FEATURE_HAS_FPU 0x08000000 #define PPC_FEATURE_HAS_MMU 0x04000000 #define PPC_FEATURE_UNIFIED_CACHE 0x01000000 +#define PPC_FEATURE_HAS_SPE 0x00800000 +#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 +#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 #define PPC_FEATURE_BOOKE 0x00008000 #define PPC_FEATURE_SMT 0x00004000 #define PPC_FEATURE_ARCH_2_05 0x00001000 @@ -70,7 +73,8 @@ extern int cpu_features2; #define PPC_FEATURE_BITMASK \ "\20" \ "\040PPC32\037PPC64\035ALTIVEC\034FPU\033MMU\031UNIFIEDCACHE" \ - "\020BOOKE\017SMT\015ARCH205\013DFP\011ARCH206\010VSX" + "\030SPE\027SPESFP\026DPESFP\020BOOKE\017SMT\015ARCH205\013DFP" \ + "\011ARCH206\010VSX" #define PPC_FEATURE2_BITMASK \ "\20" \ "\040ARCH207\037HTM\032VCRYPTO" diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index 859ff4aece41..c9592e0567f1 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -180,9 +180,12 @@ static const struct cputab models[] = { { "Motorola PowerPC 8245", MPC8245, REVFMT_MAJMIN, PPC_FEATURE_HAS_FPU, 0, cpu_6xx_setup }, { "Freescale e500v1 core", FSL_E500v1, REVFMT_MAJMIN, - PPC_FEATURE_BOOKE, 0, cpu_booke_setup }, + PPC_FEATURE_BOOKE | PPC_FEATURE_HAS_SPE | PPC_FEATURE_HAS_EFP_SINGLE, + 0, cpu_booke_setup }, { "Freescale e500v2 core", FSL_E500v2, REVFMT_MAJMIN, - PPC_FEATURE_BOOKE, 0, cpu_booke_setup }, + PPC_FEATURE_BOOKE | PPC_FEATURE_HAS_SPE | + PPC_FEATURE_HAS_EFP_SINGLE | PPC_FEATURE_HAS_EFP_DOUBLE, 0, + cpu_booke_setup }, { "Freescale e500mc core", FSL_E500mc, REVFMT_MAJMIN, PPC_FEATURE_BOOKE | PPC_FEATURE_HAS_FPU, 0, cpu_booke_setup }, { "Freescale e5500 core", FSL_E5500, REVFMT_MAJMIN, From 6eeff7a7b2f22e5363f5a3a6f595352111eba7eb Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 29 Oct 2016 12:38:30 +0000 Subject: [PATCH 195/235] Fix getfsstat(2) handling of flags. The 'flags' argument is an enum, not a bitfield. For the intended usage - being passed either MNT_WAIT, or MNT_NOWAIT - this shouldn't introduce any changes in behaviour. Reviewed by: jhb@ MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D8373 --- sys/kern/vfs_syscalls.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 49aba08ca4b1..03dc29eb8398 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -495,16 +495,16 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; /* * If MNT_NOWAIT or MNT_LAZY is specified, do not - * refresh the fsstat cache. MNT_NOWAIT or MNT_LAZY - * overrides MNT_WAIT. + * refresh the fsstat cache. */ - if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || - (flags & MNT_WAIT)) && - (error = VFS_STATFS(mp, sp))) { - mtx_lock(&mountlist_mtx); - nmp = TAILQ_NEXT(mp, mnt_list); - vfs_unbusy(mp); - continue; + if (flags != MNT_LAZY && flags != MNT_NOWAIT) { + error = VFS_STATFS(mp, sp); + if (error != 0) { + mtx_lock(&mountlist_mtx); + nmp = TAILQ_NEXT(mp, mnt_list); + vfs_unbusy(mp); + continue; + } } if (priv_check(td, PRIV_VFS_GENERATION)) { bcopy(sp, &sb, sizeof(sb)); From 97371ba2a9bd423f6a8742e06dc2b7c68b7cf5d2 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sat, 29 Oct 2016 14:09:32 +0000 Subject: [PATCH 196/235] zfsbootcfg: a simple tool to set next boot (one time) options for zfsboot (gpt)zfsboot will read one-time boot directives from a special ZFS pool area. The area was previously described as "Boot Block Header", but currently it is know as Pad2, marked as reserved and is zeroed out on pool creation. The new code interprets data in this area, if any, using the same format as boot.config. The area is immediately wiped out. Failure to parse the directives results in a reboot right after the cleanup. Otherwise the boot sequence proceeds as usual. zfsbootcfg writes zfsboot arguments specified on its command line to the Pad2 area of a disk identified by vfs.zfs.boot.primary_pool and vfs.zfs.boot.primary_vdev kenv variables that are set by loader during boot. Please see the manual page for more. Thanks to all who reviewed, contributed and made suggestions! There are many potential improvements to the feature, please see the review for details. Reviewed by: wblock (docs) Discussed with: jhb, tsoome MFC after: 3 weeks Relnotes: yes Differential Revision: https://reviews.freebsd.org/D7612 --- .../opensolaris/lib/libzfs/common/libzfs.h | 1 + .../lib/libzfs/common/libzfs_pool.c | 22 +++ sbin/Makefile | 1 + sbin/zfsbootcfg/Makefile | 27 ++++ sbin/zfsbootcfg/zfsbootcfg.8 | 112 +++++++++++++++ sbin/zfsbootcfg/zfsbootcfg.c | 98 ++++++++++++++ sys/boot/i386/common/drv.c | 4 +- sys/boot/i386/common/drv.h | 4 +- sys/boot/i386/gptzfsboot/Makefile | 2 +- sys/boot/i386/zfsboot/Makefile | 2 +- sys/boot/i386/zfsboot/zfsboot.c | 127 +++++++++++++++++- .../opensolaris/uts/common/fs/zfs/sys/vdev.h | 2 + .../uts/common/fs/zfs/vdev_label.c | 38 ++++++ .../opensolaris/uts/common/fs/zfs/zfs_ioctl.c | 50 +++++++ .../opensolaris/uts/common/sys/fs/zfs.h | 1 + 15 files changed, 482 insertions(+), 9 deletions(-) create mode 100644 sbin/zfsbootcfg/Makefile create mode 100644 sbin/zfsbootcfg/zfsbootcfg.8 create mode 100644 sbin/zfsbootcfg/zfsbootcfg.c diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h index c84124ea3af6..1aa64aab462a 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h @@ -213,6 +213,7 @@ extern int zpool_get_state(zpool_handle_t *); extern const char *zpool_state_to_name(vdev_state_t, vdev_aux_t); extern const char *zpool_pool_state_to_name(pool_state_t); extern void zpool_free_handles(libzfs_handle_t *); +extern int zpool_nextboot(libzfs_handle_t *, uint64_t, uint64_t, const char *); /* * Iterate over all active pools in the system. diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c index 035f028fa968..face63086888 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c @@ -4126,3 +4126,25 @@ zvol_check_dump_config(char *arg) libzfs_fini(hdl); return (ret); } + +int +zpool_nextboot(libzfs_handle_t *hdl, uint64_t pool_guid, uint64_t dev_guid, + const char *command) +{ + zfs_cmd_t zc = { 0 }; + nvlist_t *args; + char *packed; + size_t size; + int error; + + args = fnvlist_alloc(); + fnvlist_add_uint64(args, ZPOOL_CONFIG_POOL_GUID, pool_guid); + fnvlist_add_uint64(args, ZPOOL_CONFIG_GUID, dev_guid); + fnvlist_add_string(args, "command", command); + error = zcmd_write_src_nvlist(hdl, &zc, args); + if (error == 0) + error = ioctl(hdl->libzfs_fd, ZFS_IOC_NEXTBOOT, &zc); + zcmd_free_nvlists(&zc); + nvlist_free(args); + return (error); +} diff --git a/sbin/Makefile b/sbin/Makefile index affca8e19d91..4826bc09b26d 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -87,6 +87,7 @@ SUBDIR.${MK_PF}+= pfctl SUBDIR.${MK_PF}+= pflogd SUBDIR.${MK_QUOTAS}+= quotacheck SUBDIR.${MK_ROUTED}+= routed +SUBDIR.${MK_ZFS}+= zfsbootcfg SUBDIR.${MK_TESTS}+= tests diff --git a/sbin/zfsbootcfg/Makefile b/sbin/zfsbootcfg/Makefile new file mode 100644 index 000000000000..d485d8dad8dc --- /dev/null +++ b/sbin/zfsbootcfg/Makefile @@ -0,0 +1,27 @@ +# @(#)Makefile 8.4 (Berkeley) 6/22/95 +# $FreeBSD$ + +PROG= zfsbootcfg +WARNS?= 1 +MAN= zfsbootcfg.8 + +LIBADD+=zfs +LIBADD+=nvpair +LIBADD+=umem +LIBADD+=uutil +LIBADD+=geom + +CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/include +CFLAGS+= -I${SRCTOP}/cddl/compat/opensolaris/lib/libumem +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzfs_core/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libzpool/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/lib/libnvpair +CFLAGS+= -I${SRCTOP}/sys/cddl/compat/opensolaris +CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common/fs/zfs +CFLAGS+= -I${SRCTOP}/sys/cddl/contrib/opensolaris/uts/common +CFLAGS+= -I${SRCTOP}/cddl/contrib/opensolaris/head + +CFLAGS+= -DNEED_SOLARIS_BOOLEAN + +.include diff --git a/sbin/zfsbootcfg/zfsbootcfg.8 b/sbin/zfsbootcfg/zfsbootcfg.8 new file mode 100644 index 000000000000..aa6201da15fd --- /dev/null +++ b/sbin/zfsbootcfg/zfsbootcfg.8 @@ -0,0 +1,112 @@ +.\" Copyright (c) 2016 Andriy Gapon +.\" 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$ +.\" +.Dd October 12, 2016 +.Dt ZFSBOOTCFG 8 +.Os +.Sh NAME +.Nm zfsbootcfg +.Nd "specify zfsboot options for the next boot" +.Sh SYNOPSIS +.Nm +.Ao Ar options Ac +.Sh DESCRIPTION +.Nm +is used to set +.Xr boot.config 5 Ns -style +options to be used by +.Xr zfsboot 8 +or +.Xr gptzfsboot 8 +the next time the machine is booted. +Once +.Xr zfsboot 8 +or +.Xr gptzfsboot 8 +reads the information, it is deleted. +If booting fails, the machine automatically reverts to the previous +boot configuration. +The information is stored in a special reserved area of a ZFS pool. +.Xr zfsboot 8 +or +.Xr gptzfsboot 8 +read the boot option information from the first disk found in the first +ZFS pool found. +.Sh ENVIRONMENT +.Bl -tag -width vfs.zfs.boot.primary_pool -compact +.It Ev vfs.zfs.boot.primary_pool +The +.Xr kenv 1 +variable that identifies a pool for which the options are written. +.It Ev vfs.zfs.boot.primary_vdev +The +.Xr kenv 1 +variable that identifies a disk within the pool where the options +are written. +.El +.Sh EXAMPLES +Try to boot to a new +.Em boot environment +without changing the +.Cm bootfs +property of a pool: +.Pp +.Dl "zfsbootcfg ""zfs:tank/ROOT/newbe:"" +.Pp +To clear the boot options: +.Pp +.Dl "zfsbootcfg """" +.Sh SEE ALSO +.Xr boot.config 5 , +.Xr gptzfsboot 8 , +.Xr zfsboot 8 +.Sh HISTORY +.Nm +appeared in +.Fx 12.0 . +.Sh AUTHORS +This manual page was written by +.An Andriy Gapon Aq Mt avg@FreeBSD.org . +.Sh CAVEATS +At the moment, +.Nm +uses the +.Ev vfs.zfs.boot.primary_pool +and +.Ev vfs.zfs.boot.primary_vdev +.Xr kenv 1 +variables to determine a ZFS pool and a disk in it where the options +are to be stored. +The variables are set by the ZFS boot chain, so there is an assumption +that the same boot disk is going to be used for the next reboot. +There is no +.Nm +option to specify a different pool or a different disk. +.Pp +.Nm +should be extended to install new +.Xr zfsboot 8 +blocks in a ZFS pool. diff --git a/sbin/zfsbootcfg/zfsbootcfg.c b/sbin/zfsbootcfg/zfsbootcfg.c new file mode 100644 index 000000000000..096f1a4697e6 --- /dev/null +++ b/sbin/zfsbootcfg/zfsbootcfg.c @@ -0,0 +1,98 @@ +/*- + * Copyright (c) 2016 Andriy Gapon + * 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 ``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 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Keep in sync with zfsboot.c. */ +#define MAX_COMMAND_LEN 512 + +int main(int argc, const char * const *argv) +{ + char buf[32]; + libzfs_handle_t *hdl; + uint64_t pool_guid; + uint64_t vdev_guid; + int zfs_fd; + int len; + + if (argc != 2) { + fprintf(stderr, "usage: zfsbootcfg \n"); + return (1); + } + + len = strlen(argv[1]); + if (len >= MAX_COMMAND_LEN) { + fprintf(stderr, "options string is too long\n"); + return (1); + } + + if (kenv(KENV_GET, "vfs.zfs.boot.primary_pool", buf, sizeof(buf)) <= 0) { + perror("can't get vfs.zfs.boot.primary_pool"); + return (1); + } + pool_guid = strtoumax(buf, NULL, 10); + if (pool_guid == 0) { + perror("can't parse vfs.zfs.boot.primary_pool"); + return (1); + } + + if (kenv(KENV_GET, "vfs.zfs.boot.primary_vdev", buf, sizeof(buf)) <= 0) { + perror("can't get vfs.zfs.boot.primary_vdev"); + return (1); + } + vdev_guid = strtoumax(buf, NULL, 10); + if (vdev_guid == 0) { + perror("can't parse vfs.zfs.boot.primary_vdev"); + return (1); + } + + if ((hdl = libzfs_init()) == NULL) { + (void) fprintf(stderr, "internal error: failed to " + "initialize ZFS library\n"); + return (1); + } + + if (zpool_nextboot(hdl, pool_guid, vdev_guid, argv[1]) != 0) { + perror("ZFS_IOC_NEXTBOOT failed"); + libzfs_fini(hdl); + return (1); + } + + libzfs_fini(hdl); + printf("zfs next boot options are successfully written\n"); + return (0); +} diff --git a/sys/boot/i386/common/drv.c b/sys/boot/i386/common/drv.c index f5133debe982..cc75d1ba6d53 100644 --- a/sys/boot/i386/common/drv.c +++ b/sys/boot/i386/common/drv.c @@ -91,7 +91,7 @@ drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) return (0); } -#ifdef GPT +#if defined(GPT) || defined(ZFS) int drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) { @@ -114,4 +114,4 @@ drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) } return (0); } -#endif /* GPT */ +#endif /* GPT || ZFS */ diff --git a/sys/boot/i386/common/drv.h b/sys/boot/i386/common/drv.h index 8ad3c9cd1542..e437cb83bf91 100644 --- a/sys/boot/i386/common/drv.h +++ b/sys/boot/i386/common/drv.h @@ -40,9 +40,9 @@ struct dsk { }; int drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk); -#ifdef GPT +#if defined(GPT) || defined(ZFS) int drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk); -#endif /* GPT */ +#endif /* GPT || ZFS */ uint64_t drvsize(struct dsk *dskp); #endif /* !_DRV_H_ */ diff --git a/sys/boot/i386/gptzfsboot/Makefile b/sys/boot/i386/gptzfsboot/Makefile index bef6c62f7c7d..a1d2f93756e9 100644 --- a/sys/boot/i386/gptzfsboot/Makefile +++ b/sys/boot/i386/gptzfsboot/Makefile @@ -19,7 +19,7 @@ ORG2= 0x0 CFLAGS= -DBOOTPROG=\"gptzfsboot\" \ -O1 \ - -DGPT -DBOOT2 \ + -DGPT -DZFS -DBOOT2 \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ diff --git a/sys/boot/i386/zfsboot/Makefile b/sys/boot/i386/zfsboot/Makefile index 07bb7b7815d7..a4456b83bcba 100644 --- a/sys/boot/i386/zfsboot/Makefile +++ b/sys/boot/i386/zfsboot/Makefile @@ -18,7 +18,7 @@ ORG2= 0x2000 CFLAGS= -DBOOTPROG=\"zfsboot\" \ -O1 \ - -DBOOT2 \ + -DZFS -DBOOT2 \ -DSIOPRT=${BOOT_COMCONSOLE_PORT} \ -DSIOFMT=${B2SIOFMT} \ -DSIOSPD=${BOOT_COMCONSOLE_SPEED} \ diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index e372f14e7313..bb64384fadc9 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -119,6 +119,7 @@ struct dmadat { static struct dmadat *dmadat; void exit(int); +void reboot(void); static void load(void); static int parse(void); static void bios_getmem(void); @@ -175,7 +176,7 @@ zfs_read(spa_t *spa, const dnode_phys_t *dnode, off_t *offp, void *start, size_t n = size; if (*offp + n > zp->zp_size) n = zp->zp_size - *offp; - + rc = dnode_read(spa, dnode, *offp, start, n); if (rc) return (-1); @@ -259,6 +260,35 @@ vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) return 0; } +static int +vdev_write(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) +{ + char *p; + daddr_t lba; + unsigned int nb; + struct dsk *dsk = (struct dsk *) priv; + + if ((off & (DEV_BSIZE - 1)) || (bytes & (DEV_BSIZE - 1))) + return -1; + + p = buf; + lba = off / DEV_BSIZE; + lba += dsk->start; + while (bytes > 0) { + nb = bytes / DEV_BSIZE; + if (nb > READ_BUF_SIZE / DEV_BSIZE) + nb = READ_BUF_SIZE / DEV_BSIZE; + memcpy(dmadat->rdbuf, p, nb * DEV_BSIZE); + if (drvwrite(dsk, dmadat->rdbuf, lba, nb)) + return -1; + p += nb * DEV_BSIZE; + lba += nb; + bytes -= nb * DEV_BSIZE; + } + + return 0; +} + static int xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte) { @@ -269,6 +299,52 @@ xfsread(const dnode_phys_t *dnode, off_t *offp, void *buf, size_t nbyte) return 0; } +/* + * Read Pad2 (formerly "Boot Block Header") area of the first + * vdev label of the given vdev. + */ +static int +vdev_read_pad2(vdev_t *vdev, char *buf, size_t size) +{ + blkptr_t bp; + char *tmp = zap_scratch; + off_t off = offsetof(vdev_label_t, vl_pad2); + + if (size > VDEV_PAD_SIZE) + size = VDEV_PAD_SIZE; + + BP_ZERO(&bp); + BP_SET_LSIZE(&bp, VDEV_PAD_SIZE); + BP_SET_PSIZE(&bp, VDEV_PAD_SIZE); + BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL); + BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF); + DVA_SET_OFFSET(BP_IDENTITY(&bp), off); + if (vdev_read_phys(vdev, &bp, tmp, off, 0)) + return (EIO); + memcpy(buf, tmp, size); + return (0); +} + +static int +vdev_clear_pad2(vdev_t *vdev) +{ + char *zeroes = zap_scratch; + uint64_t *end; + off_t off = offsetof(vdev_label_t, vl_pad2); + + memset(zeroes, 0, VDEV_PAD_SIZE); + end = (uint64_t *)(zeroes + VDEV_PAD_SIZE); + /* ZIO_CHECKSUM_LABEL magic and pre-calcualted checksum for all zeros */ + end[-5] = 0x0210da7ab10c7a11; + end[-4] = 0x97f48f807f6e2a3f; + end[-3] = 0xaf909f1658aacefc; + end[-2] = 0xcbd1ea57ff6db48b; + end[-1] = 0x6ec692db0d465fab; + if (vdev_write(vdev, vdev->v_read_priv, off, zeroes, VDEV_PAD_SIZE)) + return (EIO); + return (0); +} + static void bios_getmem(void) { @@ -542,10 +618,12 @@ probe_drive(struct dsk *dsk) int main(void) { - int autoboot, i; dnode_phys_t dn; off_t off; struct dsk *dsk; + int autoboot, i; + int nextboot; + int rc; dmadat = (void *)(roundup2(__base + (int32_t)&_end, 0x10000) - __base); @@ -634,7 +712,39 @@ main(void) primary_spa = spa; primary_vdev = spa_get_primary_vdev(spa); - if (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0) { + nextboot = 0; + rc = vdev_read_pad2(primary_vdev, cmd, sizeof(cmd)); + if (vdev_clear_pad2(primary_vdev)) + printf("failed to clear pad2 area of primary vdev\n"); + if (rc == 0) { + if (*cmd) { + /* + * We could find an old-style ZFS Boot Block header here. + * Simply ignore it. + */ + if (*(uint64_t *)cmd != 0x2f5b007b10c) { + /* + * Note that parse() is destructive to cmd[] and we also want + * to honor RBX_QUIET option that could be present in cmd[]. + */ + nextboot = 1; + memcpy(cmddup, cmd, sizeof(cmd)); + if (parse()) { + printf("failed to parse pad2 area of primary vdev\n"); + reboot(); + } + if (!OPT_CHECK(RBX_QUIET)) + printf("zfs nextboot: %s\n", cmddup); + } + /* Do not process this command twice */ + *cmd = 0; + } + } else + printf("failed to read pad2 area of primary vdev\n"); + + /* Mount ZFS only if it's not already mounted via nextboot parsing. */ + if (zfsmount.spa == NULL && + (zfs_spa_init(spa) != 0 || zfs_mount(spa, 0, &zfsmount) != 0)) { printf("%s: failed to mount default pool %s\n", BOOTPROG, spa->spa_name); autoboot = 0; @@ -658,6 +768,10 @@ main(void) *cmd = 0; } + /* Do not risk waiting at the prompt forever. */ + if (nextboot && !autoboot) + reboot(); + /* * Try to exec /boot/loader. If interrupted by a keypress, * or in case of failure, try to load a kernel directly instead. @@ -707,6 +821,13 @@ main(void) void exit(int x) { + __exit(x); +} + +void +reboot(void) +{ + __exit(0); } static void diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h index 13442603e02e..d07b928a310a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev.h @@ -167,6 +167,8 @@ typedef enum { extern int vdev_label_init(vdev_t *vd, uint64_t txg, vdev_labeltype_t reason); +extern int vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size); + #ifdef __cplusplus } #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c index 7901115264b5..7e6ff2c688ff 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c @@ -871,6 +871,44 @@ vdev_label_init(vdev_t *vd, uint64_t crtxg, vdev_labeltype_t reason) return (error); } +int +vdev_label_write_pad2(vdev_t *vd, const char *buf, size_t size) +{ + spa_t *spa = vd->vdev_spa; + zio_t *zio; + char *pad2; + int flags = ZIO_FLAG_CONFIG_WRITER | ZIO_FLAG_CANFAIL; + int error; + + if (size > VDEV_PAD_SIZE) + return (EINVAL); + + if (!vd->vdev_ops->vdev_op_leaf) + return (ENODEV); + if (vdev_is_dead(vd)) + return (ENXIO); + + ASSERT(spa_config_held(spa, SCL_ALL, RW_WRITER) == SCL_ALL); + + pad2 = zio_buf_alloc(VDEV_PAD_SIZE); + bzero(pad2, VDEV_PAD_SIZE); + memcpy(pad2, buf, size); + +retry: + zio = zio_root(spa, NULL, NULL, flags); + vdev_label_write(zio, vd, 0, pad2, + offsetof(vdev_label_t, vl_pad2), + VDEV_PAD_SIZE, NULL, NULL, flags); + error = zio_wait(zio); + if (error != 0 && !(flags & ZIO_FLAG_TRYHARD)) { + flags |= ZIO_FLAG_TRYHARD; + goto retry; + } + + zio_buf_free(pad2, VDEV_PAD_SIZE); + return (error); +} + /* * ========================================================================== * uberblock load/sync diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c index 661e418e5ec4..36709af9c01a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c @@ -3472,6 +3472,53 @@ zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) return (error); } +#ifdef __FreeBSD__ +static int +zfs_ioc_nextboot(const char *unused, nvlist_t *innvl, nvlist_t *outnvl) +{ + char name[MAXNAMELEN]; + spa_t *spa; + vdev_t *vd; + char *command; + uint64_t pool_guid; + uint64_t vdev_guid; + int error; + + if (nvlist_lookup_uint64(innvl, + ZPOOL_CONFIG_POOL_GUID, &pool_guid) != 0) + return (EINVAL); + if (nvlist_lookup_uint64(innvl, + ZPOOL_CONFIG_GUID, &vdev_guid) != 0) + return (EINVAL); + if (nvlist_lookup_string(innvl, + "command", &command) != 0) + return (EINVAL); + + mutex_enter(&spa_namespace_lock); + spa = spa_by_guid(pool_guid, vdev_guid); + if (spa != NULL) + strcpy(name, spa_name(spa)); + mutex_exit(&spa_namespace_lock); + if (spa == NULL) + return (ENOENT); + + if ((error = spa_open(name, &spa, FTAG)) != 0) + return (error); + spa_vdev_state_enter(spa, SCL_ALL); + vd = spa_lookup_by_guid(spa, vdev_guid, B_TRUE); + if (vd == NULL) { + (void) spa_vdev_state_exit(spa, NULL, ENXIO); + spa_close(spa, FTAG); + return (ENODEV); + } + error = vdev_label_write_pad2(vd, command, strlen(command)); + (void) spa_vdev_state_exit(spa, NULL, 0); + txg_wait_synced(spa->spa_dsl_pool, 0); + spa_close(spa, FTAG); + return (error); +} +#endif + /* * The dp_config_rwlock must not be held when calling this, because the * unmount may need to write out data. @@ -6024,6 +6071,9 @@ zfs_ioctl_init(void) zfs_secpolicy_config, POOL_CHECK_NONE); zfs_ioctl_register_dataset_nolog(ZFS_IOC_UNJAIL, zfs_ioc_unjail, zfs_secpolicy_config, POOL_CHECK_NONE); + zfs_ioctl_register("fbsd_nextboot", ZFS_IOC_NEXTBOOT, + zfs_ioc_nextboot, zfs_secpolicy_config, NO_NAME, + POOL_CHECK_NONE, B_FALSE, B_FALSE); #endif } diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h index 8f5658d2e680..7c72c887d419 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h @@ -891,6 +891,7 @@ typedef enum zfs_ioc { ZFS_IOC_BOOKMARK, ZFS_IOC_GET_BOOKMARKS, ZFS_IOC_DESTROY_BOOKMARKS, + ZFS_IOC_NEXTBOOT, ZFS_IOC_LAST } zfs_ioc_t; From cfabea3d3af34cb986b6466af03f44cabdfe2f67 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sat, 29 Oct 2016 18:03:29 +0000 Subject: [PATCH 197/235] Add unlock_vp() helper. Trim space. Discussed with: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_fault.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 03c68dd23cba..ebaa56e0d4f5 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -152,6 +152,16 @@ unlock_map(struct faultstate *fs) } } +static void +unlock_vp(struct faultstate *fs) +{ + + if (fs->vp != NULL) { + vput(fs->vp); + fs->vp = NULL; + } +} + static void unlock_and_deallocate(struct faultstate *fs) { @@ -168,11 +178,8 @@ unlock_and_deallocate(struct faultstate *fs) fs->first_m = NULL; } vm_object_deallocate(fs->first_object); - unlock_map(fs); - if (fs->vp != NULL) { - vput(fs->vp); - fs->vp = NULL; - } + unlock_map(fs); + unlock_vp(fs); } static void @@ -339,10 +346,7 @@ RetryFault:; vm_map_lock(fs.map); if (vm_map_lookup_entry(fs.map, vaddr, &fs.entry) && (fs.entry->eflags & MAP_ENTRY_IN_TRANSITION)) { - if (fs.vp != NULL) { - vput(fs.vp); - fs.vp = NULL; - } + unlock_vp(&fs); fs.entry->eflags |= MAP_ENTRY_NEEDS_WAKEUP; vm_map_unlock_and_wait(fs.map, 0); } else @@ -642,10 +646,7 @@ RetryFault:; vp = fs.object->handle; if (vp == fs.vp) goto vnode_locked; - else if (fs.vp != NULL) { - vput(fs.vp); - fs.vp = NULL; - } + unlock_vp(&fs); locked = VOP_ISLOCKED(vp); if (locked != LK_EXCLUSIVE) From a9ee028d0448575f3351d52190a36f7fc753f674 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sat, 29 Oct 2016 18:47:28 +0000 Subject: [PATCH 198/235] Add one more use of unlock_vp(). Discussed with: kib X-MFC With: r308094 --- sys/vm/vm_fault.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index ebaa56e0d4f5..ed383bcf9740 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -328,8 +328,7 @@ RetryFault:; growstack = FALSE; goto RetryFault; } - if (fs.vp != NULL) - vput(fs.vp); + unlock_vp(&fs); return (result); } From 320023e286006f76c3dfa84412003d2ef901bd0a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 29 Oct 2016 19:22:38 +0000 Subject: [PATCH 199/235] With one exception, "hardfault" is used like a "bool". Change that exception and make it a "bool". Reviewed by: kib MFC after: 7 days --- sys/vm/vm_fault.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index ed383bcf9740..94f188163576 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -295,20 +295,20 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, boolean_t dead, growstack, is_first_object_locked, wired; int map_generation; vm_object_t next_object; - int hardfault; struct faultstate fs; struct vnode *vp; vm_offset_t e_end, e_start; vm_page_t m; int ahead, behind, cluster_offset, error, locked, rv; u_char behavior; + bool hardfault; - hardfault = 0; growstack = TRUE; PCPU_INC(cnt.v_vm_faults); fs.vp = NULL; faultcount = 0; nera = -1; + hardfault = false; RetryFault:; @@ -708,7 +708,7 @@ RetryFault:; &behind, &ahead); if (rv == VM_PAGER_OK) { faultcount = behind + 1 + ahead; - hardfault++; + hardfault = true; break; /* break to PAGE HAS BEEN FOUND */ } if (rv == VM_PAGER_ERROR) From ac91917211ebd9f2ae6e75bfd2cfbe6cc28f0327 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Sat, 29 Oct 2016 20:01:48 +0000 Subject: [PATCH 200/235] Fix WITNESS hints for pagequeue locks. MFC after: 1 week --- sys/kern/subr_witness.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index a916bdd4be8e..31ef942c43a1 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -599,7 +599,7 @@ static struct witness_order_list_entry order_lists[] = { * CDEV */ { "vm map (system)", &lock_class_mtx_sleep }, - { "vm page queue", &lock_class_mtx_sleep }, + { "vm pagequeue", &lock_class_mtx_sleep }, { "vnode interlock", &lock_class_mtx_sleep }, { "cdev", &lock_class_mtx_sleep }, { NULL, NULL }, @@ -609,7 +609,7 @@ static struct witness_order_list_entry order_lists[] = { { "vm map (user)", &lock_class_sx }, { "vm object", &lock_class_rw }, { "vm page", &lock_class_mtx_sleep }, - { "vm page queue", &lock_class_mtx_sleep }, + { "vm pagequeue", &lock_class_mtx_sleep }, { "pmap pv global", &lock_class_rw }, { "pmap", &lock_class_mtx_sleep }, { "pmap pv list", &lock_class_rw }, From cd8a6fe8e9eed2baa284fab17fe199c5d50c787b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 29 Oct 2016 21:01:49 +0000 Subject: [PATCH 201/235] The "lookup_is_valid" field is used as a "bool". Make it one. Convert vm_fault_hold()'s Boolean variables that are only used internally to "bool". Add a comment describing why the one remaining "boolean_t" was not converted. Reviewed by: kib MFC after: 8 days --- sys/vm/vm_fault.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 94f188163576..c41511e64856 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -122,7 +122,7 @@ struct faultstate { vm_pindex_t first_pindex; vm_map_t map; vm_map_entry_t entry; - int lookup_still_valid; + bool lookup_still_valid; struct vnode *vp; }; @@ -148,7 +148,7 @@ unlock_map(struct faultstate *fs) if (fs->lookup_still_valid) { vm_map_lookup_done(fs->map, fs->entry); - fs->lookup_still_valid = FALSE; + fs->lookup_still_valid = false; } } @@ -292,7 +292,6 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, { vm_prot_t prot; int alloc_req, era, faultcount, nera, result; - boolean_t dead, growstack, is_first_object_locked, wired; int map_generation; vm_object_t next_object; struct faultstate fs; @@ -301,13 +300,14 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, vm_page_t m; int ahead, behind, cluster_offset, error, locked, rv; u_char behavior; - bool hardfault; + boolean_t wired; /* Passed by reference. */ + bool dead, growstack, hardfault, is_first_object_locked; - growstack = TRUE; PCPU_INC(cnt.v_vm_faults); fs.vp = NULL; faultcount = 0; nera = -1; + growstack = true; hardfault = false; RetryFault:; @@ -325,7 +325,7 @@ RetryFault:; result = vm_map_growstack(curproc, vaddr); if (result != KERN_SUCCESS) return (KERN_FAILURE); - growstack = FALSE; + growstack = false; goto RetryFault; } unlock_vp(&fs); @@ -427,7 +427,7 @@ RetryFault:; vm_object_reference_locked(fs.first_object); vm_object_pip_add(fs.first_object, 1); - fs.lookup_still_valid = TRUE; + fs.lookup_still_valid = true; fs.first_m = NULL; @@ -836,7 +836,7 @@ RetryFault:; * dirty in the first object so that it will go out * to swap when needed. */ - is_first_object_locked = FALSE; + is_first_object_locked = false; if ( /* * Only one shadow object @@ -941,7 +941,7 @@ RetryFault:; unlock_and_deallocate(&fs); goto RetryFault; } - fs.lookup_still_valid = TRUE; + fs.lookup_still_valid = true; if (fs.map->timestamp != map_generation) { result = vm_map_lookup_locked(&fs.map, vaddr, fault_type, &fs.entry, &retry_object, &retry_pindex, &retry_prot, &wired); From 74a148f46f5d2a74ca4345b3799507b463370028 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Sat, 29 Oct 2016 23:25:12 +0000 Subject: [PATCH 202/235] Add sysctls for zfs_immediate_write_sz and zvol_immediate_write_sz. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c | 5 +++++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c index 6933ccdacd16..049b958605d8 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c @@ -454,6 +454,11 @@ zfs_log_rename(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, * Handles TX_WRITE transactions. */ ssize_t zfs_immediate_write_sz = 32768; +#ifdef _KERNEL +SYSCTL_DECL(_vfs_zfs); +SYSCTL_LONG(_vfs_zfs, OID_AUTO, immediate_write_sz, CTLFLAG_RWTUN, + &zfs_immediate_write_sz, 0, "Minimal size for indirect log write"); +#endif void zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype, diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c index 832847e30258..4965dde36f43 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c @@ -1375,6 +1375,10 @@ zvol_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) * Otherwise we will later flush the data out via dmu_sync(). */ ssize_t zvol_immediate_write_sz = 32768; +#ifdef _KERNEL +SYSCTL_LONG(_vfs_zfs_vol, OID_AUTO, immediate_write_sz, CTLFLAG_RWTUN, + &zvol_immediate_write_sz, 0, "Minimal size for indirect log write"); +#endif static void zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, offset_t off, ssize_t resid, From c82bd4484c36d6958eca247cd38559b1cbb4e409 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Sun, 30 Oct 2016 02:57:47 +0000 Subject: [PATCH 203/235] compile libunwind c source with -fexceptions When an exception is thrown the unwinder must unwind its own C source (starting with _Unwind_RaiseException in UnwindLevel1.c), so it needs to be built with unwinding data. --- lib/libgcc_eh/Makefile.inc | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/libgcc_eh/Makefile.inc b/lib/libgcc_eh/Makefile.inc index 85c77aae5d7b..6337f3890e18 100644 --- a/lib/libgcc_eh/Makefile.inc +++ b/lib/libgcc_eh/Makefile.inc @@ -8,15 +8,20 @@ STATIC_CFLAGS+=${PICFLAG} -fvisibility=hidden -DVISIBILITY_HIDDEN .PATH: ${COMPILERRTDIR}/lib/builtins .PATH: ${UNWINDSRCDIR} -SRCS+= gcc_personality_v0.c -SRCS+= int_util.c -SRCS+= Unwind-EHABI.cpp -SRCS+= Unwind-sjlj.c -SRCS+= UnwindLevel1-gcc-ext.c -SRCS+= UnwindLevel1.c -SRCS+= UnwindRegistersRestore.S -SRCS+= UnwindRegistersSave.S -SRCS+= libunwind.cpp +SRCS_EXC+= gcc_personality_v0.c +SRCS_EXC+= int_util.c +SRCS_EXC+= Unwind-EHABI.cpp +SRCS_EXC+= Unwind-sjlj.c +SRCS_EXC+= UnwindLevel1-gcc-ext.c +SRCS_EXC+= UnwindLevel1.c +SRCS_EXC+= UnwindRegistersRestore.S +SRCS_EXC+= UnwindRegistersSave.S +SRCS_EXC+= libunwind.cpp + +SRCS+= ${SRCS_EXC} +.for file in ${SRCS_EXC:M*.c} +CFLAGS.${file}+= -fexceptions +.endfor CFLAGS+= -I${UNWINDINCDIR} -I${.CURDIR} -D_LIBUNWIND_IS_NATIVE_ONLY .if empty(CXXFLAGS:M-std=*) From 3c1f73b18d318cc7be8c1b9c19933c2eaa1f1771 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sun, 30 Oct 2016 09:38:10 +0000 Subject: [PATCH 204/235] hwpmc: fix a race between amd_stop_pmc and amd_intr It is possible that wrmsr in amd_stop_pmc() causes an overflow in a counter that it disables. In that case a non-maskable interrupt is generated. The interrupt handler code was written in such a way that it would re-enable the counter. That would lead to an unexpected interrupt later on. This problem was easy to reproduce with $ pmcstat -T -P instructions -t $pid if the target process is sufficiently busy and there are context switches from time to time. There would be a lot of interrupts to "race" with amd_stop_pmc() called during the context switches. The problem affected only AMD processors. While there, trace whether amd_intr() claimed an interrupt. Reviewed by: jhb MFC after: 2 weeks --- sys/dev/hwpmc/hwpmc_amd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index 14d708aee949..7221071de0f8 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -689,12 +689,13 @@ amd_intr(int cpu, struct trapframe *tf) error = pmc_process_interrupt(cpu, PMC_HR, pm, tf, TRAPF_USERMODE(tf)); if (error == 0) - wrmsr(evsel, config | AMD_PMC_ENABLE); + wrmsr(evsel, config); } atomic_add_int(retval ? &pmc_stats.pm_intr_processed : &pmc_stats.pm_intr_ignored, 1); + PMCDBG1(MDP,INT,2, "retval=%d", retval); return (retval); } From 448897d366c218f9fd6208427eef1e6dd51f78d0 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Sun, 30 Oct 2016 12:15:33 +0000 Subject: [PATCH 205/235] add iic interface to ig4 driver, move isl and cyapa to iicbus Summary: The hardware does not expose a classic SMBus interface. Instead it has a lower level interface that can express a far richer I2C protocol than what smbus offers. However, the interface does not provide a way to explicitly generate the I2C stop and start conditions. It's only possible to request that the stop condition is generated after transferring the next byte in either direction. So, at least one data byte must always be transferred. Thus, some I2C sequences are impossible to generate, e.g., an equivalent of smbus quick command (---). At the same time isl(4) and cyapa(4) are moved to iicbus and now they use iicbus_transfer for communication. Previously they used smbus_trans() interface that is not defined by the SMBus protocol and was implemented only by ig4(4). In fact, that interface was impossible to implement for the typical SMBus controllers like intpm(4) or ichsmb(4) where a type of the SMBus command must be programmed. The plan is to remove smbus_trans() and all its uses. As an aside, the smbus_trans() method deviates from the standard, but perhaps backwards, FreeBSD convention of using 8-bit slave addresses (shifted by 1 bit to the left). The method expects 7-bit addresses. There is a user facing consequence of this change. A user must now provide device hints for isl and cyapa that specify an iicbus to use and a slave address on it. On Chromebook hardware where isl and cyapa devices are commonly found it is also possible to use a new chromebook_platform(4) driver that automatically configures isl and cyapa devices. There is no need to provide the device hints in that case, Right now smbus(4) driver tries to discover all slaves on the bus. That is very dangerous. Fortunately, the probing code uses smbus_trans() to do its job, so it is really enabled for ig4 only. The plan is to remove that auto-probing code and smbus_trans(). Tested by: grembo, Matthias Apitz (w/o chromebook_platform) Discussed with: grembo, imp Reviewed by: wblock (docs) MFC after: 1 month Relnotes: yes Differential Revision: https://reviews.freebsd.org/D8172 --- UPDATING | 6 + share/man/man4/chromebook_platform.4 | 68 +++++ share/man/man4/cyapa.4 | 29 +- share/man/man4/ig4.4 | 23 +- share/man/man4/isl.4 | 29 +- sys/conf/files | 9 +- .../chromebook_platform/chromebook_platform.c | 102 +++++++ sys/dev/cyapa/cyapa.c | 110 ++++---- sys/dev/ichiic/ig4_iic.c | 250 +++++++++++++++++- sys/dev/ichiic/ig4_pci.c | 9 +- sys/dev/ichiic/ig4_var.h | 5 +- sys/dev/iicbus/iicbus.c | 4 +- sys/dev/isl/isl.c | 147 +++++----- sys/modules/Makefile | 2 + sys/modules/chromebook_platform/Makefile | 7 + sys/modules/i2c/controllers/ichiic/Makefile | 2 +- sys/modules/i2c/cyapa/Makefile | 2 +- sys/modules/i2c/isl/Makefile | 2 +- 18 files changed, 640 insertions(+), 166 deletions(-) create mode 100644 share/man/man4/chromebook_platform.4 create mode 100644 sys/dev/chromebook_platform/chromebook_platform.c create mode 100644 sys/modules/chromebook_platform/Makefile diff --git a/UPDATING b/UPDATING index 71a952aff9ab..fb869480ebc9 100644 --- a/UPDATING +++ b/UPDATING @@ -51,6 +51,12 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 12.x IS SLOW: ****************************** SPECIAL WARNING: ****************************** +20161030: + isl(4) and cyapa(4) drivers now require a new driver, + chromebook_platform(4), to work properly on Chromebook-class hardware. + On other types of hardware the drivers may need to be configured using + device hints. Please see the corresponding manual pages for details. + 20161017: The urtwn(4) driver was merged into rtwn(4) and now consists of rtwn(4) main module + rtwn_usb(4) and rtwn_pci(4) bus-specific diff --git a/share/man/man4/chromebook_platform.4 b/share/man/man4/chromebook_platform.4 new file mode 100644 index 000000000000..d6998b23700a --- /dev/null +++ b/share/man/man4/chromebook_platform.4 @@ -0,0 +1,68 @@ +.\" Copyright (c) 2016 Andriy Gapon +.\" 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$ +.\" +.Dd October 13, 2016 +.Dt CHROMEBOOK_PLATFORM 4 +.Os +.Sh NAME +.Nm chromebook_platform +.Nd support driver for hardware on various Chromebook models +.Sh SYNOPSIS +To compile this driver into the kernel, place the following lines into +the kernel configuration file: +.Bd -ragged -offset indent +.Cd "device chromebook_platform" +.Ed +.Pp +Alternatively, to load the driver as a module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +chromebook_platform_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides automatic configuration for devices that cannot be enumerated +or safely probed. +In particular, I2C peripherals are different from model to model. +.Nm +has a model-specific information about the I2C peripherals, their drivers, +their bus attachments and slave addresses. +.Pp +Note that +.Nm +does not load driver modules for the peripherals. +Those have to be compiled into the kernel or loaded separately. +.Sh SEE ALSO +.Xr cyapa 4 , +.Xr iicbus 4 , +.Xr isl 4 , +.Sh AUTHORS +.An -nosplit +The +.Nm +driver and this manual page were written by +.An Andriy Gapon Aq Mt avg@FreeBSD.org . diff --git a/share/man/man4/cyapa.4 b/share/man/man4/cyapa.4 index dc312f490637..e1983ad13872 100644 --- a/share/man/man4/cyapa.4 +++ b/share/man/man4/cyapa.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2015 +.Dd October 03, 2016 .Dt CYAPA 4 .Os .Sh NAME @@ -36,7 +36,7 @@ the kernel configuration file: .Bd -ragged -offset indent .Cd "device cyapa" .Cd "device ig4" -.Cd "device smbus" +.Cd "device iicbus" .Ed .Pp Alternatively, to load the driver as a module at boot time, place the following line in @@ -45,6 +45,13 @@ Alternatively, to load the driver as a module at boot time, place the following cyapa_load="YES" ig4_load="YES" .Ed +.Pp +In +.Pa /boot/device.hints : +.Cd hint.cyapa.0.at="iicbus0" +.Cd hint.cyapa.0.addr="0xCE" +.Cd hint.cyapa.1.at="iicbus1" +.Cd hint.cyapa.1.addr="0xCE" .Sh DESCRIPTION The .Nm @@ -86,6 +93,20 @@ The upper right corner issues a MIDDLE button event. The lower right corner issues a RIGHT button. Optionally, tap to click can be enabled (see below). .El +.Pp +On a system using +.Xr device.hints 5 , +these values are configurable for +.Nm : +.Bl -tag -width "hint.cyapa.%d.addr" +.It Va hint.cyapa.%d.at +target +.Xr iicbus 4 . +.It Va hint.cyapa.%d.addr +.Nm +i2c address on the +.Xr iicbus 4 . +.El .Sh SYSCTL VARIABLES These .Xr sysctl 8 @@ -175,7 +196,7 @@ file: .Dl debug.cyapa_enable_tapclick=2 .Sh SEE ALSO .Xr ig4 4 , -.Xr smbus 4 , +.Xr iicbus 4 , .Xr sysmouse 4 , .Xr moused 8 .Sh AUTHORS @@ -195,6 +216,6 @@ This manual page was written by .Sh BUGS The .Nm -driver detects the device based on its I2C address (0x67). +driver detects the device from the I2C address. This might have unforeseen consequences if the initialization sequence is sent to an unknown device at that address. diff --git a/share/man/man4/ig4.4 b/share/man/man4/ig4.4 index d4d7300a5f89..9237b96635d7 100644 --- a/share/man/man4/ig4.4 +++ b/share/man/man4/ig4.4 @@ -24,18 +24,18 @@ .\" .\" $FreeBSD$ .\" -.Dd May 30, 2015 +.Dd October 03, 2016 .Dt IG4 4 .Os .Sh NAME .Nm ig4 -.Nd Intel(R) fourth generation mobile CPU integrated I2C SMBus driver +.Nd Intel(R) fourth generation mobile CPU integrated I2C driver .Sh SYNOPSIS To compile this driver into the kernel, place the following lines into the kernel configuration file: .Bd -ragged -offset indent .Cd "device ig4" -.Cd "device smbus" +.Cd "device iicbus" .Ed .Pp Alternatively, to load the driver as a module at boot time, place the following line in @@ -46,9 +46,10 @@ ig4_load="YES" .Sh DESCRIPTION The .Nm -driver provides access to peripherals attached to an I2C SMB controller. +driver provides access to peripherals attached to an I2C controller. +.Sh HARDWARE .Nm -supports the SMBus controller found in fourth generation Intel(R) Core(TM) +supports the I2C controllers found in fourth generation Intel(R) Core(TM) processors based on the mobile U-processor line for intelligent systems. This includes the i7-4650U, i5-4300U, i3-4010U, and 2980U. .Sh SYSCTL VARIABLES @@ -57,13 +58,15 @@ These variables are available: .Bl -tag -width "debug.ig4_dump" .It Va debug.ig4_dump -Setting this to a non-zero value dumps controller registers to console and -syslog once. -The sysctl resets to zero immediately. +This sysctl is a zero-based bit mask. +When any of the bits are set, a register dump is printed for +every I2C transfer on an +.Nm +device with the same unit number. .El .Sh SEE ALSO -.Xr smb 4 , -.Xr smbus 4 +.Xr iic 4 , +.Xr iicbus 4 .Sh AUTHORS .An -nosplit The diff --git a/share/man/man4/isl.4 b/share/man/man4/isl.4 index 56a0cc3c6dcf..f0535ba3eb6b 100644 --- a/share/man/man4/isl.4 +++ b/share/man/man4/isl.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2015 +.Dd October 03, 2016 .Dt ISL 4 .Os .Sh NAME @@ -36,7 +36,7 @@ the kernel configuration file: .Bd -ragged -offset indent .Cd "device isl" .Cd "device ig4" -.Cd "device smbus" +.Cd "device iicbus" .Ed .Pp Alternatively, to load the driver as a module at boot time, place the following line in @@ -45,6 +45,13 @@ Alternatively, to load the driver as a module at boot time, place the following isl_load="YES" ig4_load="YES" .Ed +.Pp +In +.Pa /boot/device.hints : +.Cd hint.isl.0.at="iicbus0" +.Cd hint.isl.0.addr="0x88" +.Cd hint.isl.1.at="iicbus1" +.Cd hint.isl.1.addr="0x88" .Sh DESCRIPTION The .Nm @@ -54,6 +61,20 @@ Function. Functionality is basic and provided through the .Xr sysctl 8 interface. +.Pp +On a system using +.Xr device.hints 5 , +these values are configurable for +.Nm : +.Bl -tag -width "hint.isl.%d.addr" +.It Va hint.isl.%d.at +target +.Xr iicbus 4 . +.It Va hint.isl.%d.addr +.Nm +i2c address on the +.Xr iicbus 4 . +.El .Sh SYSCTL VARIABLES The following .Xr sysctl 8 @@ -86,7 +107,7 @@ $ sh /usr/local/share/examples/intel-backlight/isl_backlight.sh .Ed .Sh SEE ALSO .Xr ig4 4 , -.Xr smbus 4 +.Xr iicbus 4 .Sh AUTHORS .An -nosplit The @@ -99,6 +120,6 @@ This manual page was written by .Sh BUGS The .Nm -driver detects the device based on its I2C address (0x44). +driver detects the device based from the I2C address. This might have unforeseen consequences if the initialization sequence is sent to an unknown device at that address. diff --git a/sys/conf/files b/sys/conf/files index a430fb4ca308..5dbd0cf19945 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1273,6 +1273,7 @@ dev/cfi/cfi_bus_nexus.c optional cfi dev/cfi/cfi_core.c optional cfi dev/cfi/cfi_dev.c optional cfi dev/cfi/cfi_disk.c optional cfid +dev/chromebook_platform/chromebook_platform.c optional chromebook_platform dev/ciss/ciss.c optional ciss dev/cm/smc90cx6.c optional cm dev/cmx/cmx.c optional cmx @@ -1389,7 +1390,7 @@ t5fw.fw optional cxgbe \ dev/cy/cy.c optional cy dev/cy/cy_isa.c optional cy isa dev/cy/cy_pci.c optional cy pci -dev/cyapa/cyapa.c optional cyapa smbus +dev/cyapa/cyapa.c optional cyapa iicbus dev/dc/if_dc.c optional dc pci dev/dc/dcphy.c optional dc pci dev/dc/pnphy.c optional dc pci @@ -1631,8 +1632,8 @@ dev/hptiop/hptiop.c optional hptiop scbus dev/hwpmc/hwpmc_logging.c optional hwpmc dev/hwpmc/hwpmc_mod.c optional hwpmc dev/hwpmc/hwpmc_soft.c optional hwpmc -dev/ichiic/ig4_iic.c optional ig4 smbus -dev/ichiic/ig4_pci.c optional ig4 pci smbus +dev/ichiic/ig4_iic.c optional ig4 iicbus +dev/ichiic/ig4_pci.c optional ig4 pci iicbus dev/ichsmb/ichsmb.c optional ichsmb dev/ichsmb/ichsmb_pci.c optional ichsmb pci dev/ida/ida.c optional ida @@ -1726,7 +1727,7 @@ dev/iscsi_initiator/isc_soc.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_sm.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_subr.c optional iscsi_initiator scbus dev/ismt/ismt.c optional ismt -dev/isl/isl.c optional isl smbus +dev/isl/isl.c optional isl iicbus dev/isp/isp.c optional isp dev/isp/isp_freebsd.c optional isp dev/isp/isp_library.c optional isp diff --git a/sys/dev/chromebook_platform/chromebook_platform.c b/sys/dev/chromebook_platform/chromebook_platform.c new file mode 100644 index 000000000000..5cfeb9cb1e4e --- /dev/null +++ b/sys/dev/chromebook_platform/chromebook_platform.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2016 The FreeBSD Project. + * 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 COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDERS 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * Driver that attaches I2C devices. + */ +static struct { + uint32_t pci_id; + const char *name; + uint8_t addr; +} slaves[] = { + { 0x9c628086, "isl", 0x88 }, + { 0x9c618086, "cyapa", 0xce }, +}; + +static void +chromebook_i2c_identify(driver_t *driver, device_t bus) +{ + device_t controller; + device_t child; + int i; + + /* + * A stopgap approach to preserve the status quo. + * A more intelligent approach is required to correctly + * identify a machine model and hardware available on it. + * For instance, DMI could be used. + * See http://lxr.free-electrons.com/source/drivers/platform/chrome/chromeos_laptop.c + */ + controller = device_get_parent(bus); + if (strcmp(device_get_name(controller), "ig4iic") != 0) + return; + + for (i = 0; i < nitems(slaves); i++) { + if (device_find_child(bus, slaves[i].name, -1) != NULL) + continue; + if (slaves[i].pci_id != pci_get_devid(controller)) + continue; + child = BUS_ADD_CHILD(bus, 0, slaves[i].name, -1); + if (child != NULL) + iicbus_set_addr(child, slaves[i].addr); + } +} + +static device_method_t chromebook_i2c_methods[] = { + DEVMETHOD(device_identify, chromebook_i2c_identify), + { 0, 0 } +}; + +static driver_t chromebook_i2c_driver = { + "chromebook_i2c", + chromebook_i2c_methods, + 0 /* no softc */ +}; + +static devclass_t chromebook_i2c_devclass; + +DRIVER_MODULE(chromebook_i2c, iicbus, chromebook_i2c_driver, + chromebook_i2c_devclass, 0, 0); +MODULE_VERSION(chromebook_i2c, 1); + diff --git a/sys/dev/cyapa/cyapa.c b/sys/dev/cyapa/cyapa.c index 035121d7468b..d3a0ef18d83e 100644 --- a/sys/dev/cyapa/cyapa.c +++ b/sys/dev/cyapa/cyapa.c @@ -122,11 +122,11 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include +#include +#include #include -#include "smbus_if.h" +#include "iicbus_if.h" #include "bus_if.h" #include "device_if.h" @@ -149,7 +149,6 @@ struct cyapa_fifo { struct cyapa_softc { device_t dev; int count; /* >0 if device opened */ - int addr; struct cdev *devnode; struct selinfo selinfo; struct mtx mutex; @@ -273,6 +272,30 @@ static int cyapa_reset = 0; SYSCTL_INT(_debug, OID_AUTO, cyapa_reset, CTLFLAG_RW, &cyapa_reset, 0, "Reset track pad"); +static int +cyapa_read_bytes(device_t dev, uint8_t reg, uint8_t *val, int cnt) +{ + uint16_t addr = iicbus_get_addr(dev); + struct iic_msg msgs[] = { + { addr, IIC_M_WR | IIC_M_NOSTOP, 1, ® }, + { addr, IIC_M_RD, cnt, val }, + }; + + return (iicbus_transfer(dev, msgs, nitems(msgs))); +} + +static int +cyapa_write_bytes(device_t dev, uint8_t reg, const uint8_t *val, int cnt) +{ + uint16_t addr = iicbus_get_addr(dev); + struct iic_msg msgs[] = { + { addr, IIC_M_WR | IIC_M_NOSTOP, 1, ® }, + { addr, IIC_M_WR | IIC_M_NOSTART, cnt, __DECONST(uint8_t *, val) }, + }; + + return (iicbus_transfer(dev, msgs, nitems(msgs))); +} + static void cyapa_lock(struct cyapa_softc *sc) { @@ -318,7 +341,7 @@ cyapa_notify(struct cyapa_softc *sc) * Initialize the device */ static int -init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe) +init_device(device_t dev, struct cyapa_cap *cap, int probe) { static char bl_exit[] = { 0x00, 0xff, 0xa5, 0x00, 0x01, @@ -326,17 +349,13 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe) static char bl_deactivate[] = { 0x00, 0xff, 0x3b, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; - device_t bus; struct cyapa_boot_regs boot; int error; int retries; - bus = device_get_parent(dev); /* smbus */ - /* Get status */ - error = smbus_trans(bus, addr, CMD_BOOT_STATUS, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, (void *)&boot, sizeof(boot), NULL); + error = cyapa_read_bytes(dev, CMD_BOOT_STATUS, + (void *)&boot, sizeof(boot)); if (error) goto done; @@ -350,25 +369,21 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe) /* Busy, wait loop. */ } else if (boot.error & CYAPA_ERROR_BOOTLOADER) { /* Magic */ - error = smbus_trans(bus, addr, CMD_BOOT_STATUS, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - bl_deactivate, sizeof(bl_deactivate), - NULL, 0, NULL); + error = cyapa_write_bytes(dev, CMD_BOOT_STATUS, + bl_deactivate, sizeof(bl_deactivate)); if (error) goto done; } else { /* Magic */ - error = smbus_trans(bus, addr, CMD_BOOT_STATUS, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - bl_exit, sizeof(bl_exit), NULL, 0, NULL); + error = cyapa_write_bytes(dev, CMD_BOOT_STATUS, + bl_exit, sizeof(bl_exit)); if (error) goto done; } pause("cyapab1", (hz * 2) / 10); --retries; - error = smbus_trans(bus, addr, CMD_BOOT_STATUS, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, (void *)&boot, sizeof(boot), NULL); + error = cyapa_read_bytes(dev, CMD_BOOT_STATUS, + (void *)&boot, sizeof(boot)); if (error) goto done; } @@ -381,9 +396,8 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe) /* Check identity */ if (cap) { - error = smbus_trans(bus, addr, CMD_QUERY_CAPABILITIES, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, (void *)cap, sizeof(*cap), NULL); + error = cyapa_read_bytes(dev, CMD_QUERY_CAPABILITIES, + (void *)cap, sizeof(*cap)); if (strncmp(cap->prod_ida, "CYTRA", 5) != 0) { device_printf(dev, "Product ID \"%5.5s\" mismatch\n", @@ -391,9 +405,8 @@ init_device(device_t dev, struct cyapa_cap *cap, int addr, int probe) error = ENXIO; } } - error = smbus_trans(bus, addr, CMD_BOOT_STATUS, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, (void *)&boot, sizeof(boot), NULL); + error = cyapa_read_bytes(dev, CMD_BOOT_STATUS, + (void *)&boot, sizeof(boot)); if (probe == 0) /* official init */ device_printf(dev, "cyapa init status %02x\n", boot.stat); @@ -452,16 +465,16 @@ cyapa_probe(device_t dev) int addr; int error; - addr = smbus_get_addr(dev); + addr = iicbus_get_addr(dev); /* * 0x67 - cypress trackpad on the acer c720 * (other devices might use other ids). */ - if (addr != 0x67) + if (addr != 0xce) return (ENXIO); - error = init_device(dev, &cap, addr, 1); + error = init_device(dev, &cap, 1); if (error != 0) return (ENXIO); @@ -482,15 +495,14 @@ cyapa_attach(device_t dev) sc->reporting_mode = 1; unit = device_get_unit(dev); - addr = smbus_get_addr(dev); + addr = iicbus_get_addr(dev); - if (init_device(dev, &cap, addr, 0)) + if (init_device(dev, &cap, 0)) return (ENXIO); mtx_init(&sc->mutex, "cyapa", NULL, MTX_DEF); sc->dev = dev; - sc->addr = addr; knlist_init_mtx(&sc->selinfo.si_note, &sc->mutex); @@ -1159,7 +1171,7 @@ cyapa_poll_thread(void *arg) { struct cyapa_softc *sc; struct cyapa_regs regs; - device_t bus; /* smbus */ + device_t bus; /* iicbus */ int error; int freq; int isidle; @@ -1180,12 +1192,10 @@ cyapa_poll_thread(void *arg) while (!sc->detaching) { cyapa_unlock(sc); - error = smbus_request_bus(bus, sc->dev, SMB_WAIT); + error = iicbus_request_bus(bus, sc->dev, IIC_WAIT); if (error == 0) { - error = smbus_trans(bus, sc->addr, CMD_DEV_STATUS, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, - (void *)®s, sizeof(regs), NULL); + error = cyapa_read_bytes(sc->dev, CMD_DEV_STATUS, + (void *)®s, sizeof(regs)); if (error == 0) { isidle = cyapa_raw_input(sc, ®s, freq); } @@ -1200,9 +1210,9 @@ cyapa_poll_thread(void *arg) (unsigned)(ticks - last_reset) > TIME_TO_RESET)) { cyapa_reset = 0; last_reset = ticks; - init_device(sc->dev, NULL, sc->addr, 2); + init_device(sc->dev, NULL, 2); } - smbus_release_bus(bus, sc->dev); + iicbus_release_bus(bus, sc->dev); } pause("cyapw", hz / freq); ++sc->poll_ticks; @@ -1531,18 +1541,16 @@ cyapa_set_power_mode(struct cyapa_softc *sc, int mode) int error; bus = device_get_parent(sc->dev); - error = smbus_request_bus(bus, sc->dev, SMB_WAIT); + error = iicbus_request_bus(bus, sc->dev, IIC_WAIT); if (error == 0) { - error = smbus_trans(bus, sc->addr, CMD_POWER_MODE, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, (void *)&data, 1, NULL); + error = cyapa_read_bytes(sc->dev, CMD_POWER_MODE, + &data, 1); data = (data & ~0xFC) | mode; if (error == 0) { - error = smbus_trans(bus, sc->addr, CMD_POWER_MODE, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - (void *)&data, 1, NULL, 0, NULL); + error = cyapa_write_bytes(sc->dev, CMD_POWER_MODE, + &data, 1); } - smbus_release_bus(bus, sc->dev); + iicbus_release_bus(bus, sc->dev); } } @@ -1697,6 +1705,6 @@ cyapa_fuzz(int delta, int *fuzzp) return (delta); } -DRIVER_MODULE(cyapa, smbus, cyapa_driver, cyapa_devclass, NULL, NULL); -MODULE_DEPEND(cyapa, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); +DRIVER_MODULE(cyapa, iicbus, cyapa_driver, cyapa_devclass, NULL, NULL); +MODULE_DEPEND(cyapa, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); MODULE_VERSION(cyapa, 1); diff --git a/sys/dev/ichiic/ig4_iic.c b/sys/dev/ichiic/ig4_iic.c index 44bc64ead3e9..87eee02ebe33 100644 --- a/sys/dev/ichiic/ig4_iic.c +++ b/sys/dev/ichiic/ig4_iic.c @@ -61,6 +61,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -120,7 +122,7 @@ set_controller(ig4iic_softc_t *sc, uint32_t ctl) reg_write(sc, IG4_REG_INTR_MASK, 0); reg_write(sc, IG4_REG_I2C_EN, ctl); - error = SMB_ETIMEOUT; + error = IIC_ETIMEOUT; for (retry = 100; retry > 0; --retry) { v = reg_read(sc, IG4_REG_ENABLE_STATUS); @@ -148,7 +150,7 @@ wait_status(ig4iic_softc_t *sc, uint32_t status) u_int count_us = 0; u_int limit_us = 25000; /* 25ms */ - error = SMB_ETIMEOUT; + error = IIC_ETIMEOUT; for (;;) { /* @@ -483,6 +485,236 @@ smb_transaction(ig4iic_softc_t *sc, char cmd, int op, return (error); } +/* + * IICBUS API FUNCTIONS + */ +static int +ig4iic_xfer_start(ig4iic_softc_t *sc, uint16_t slave) +{ + /* XXX 10-bit address support? */ + set_slave_addr(sc, slave >> 1, 0); + return (0); +} + +static int +ig4iic_read(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len, + bool repeated_start, bool stop) +{ + uint32_t cmd; + uint16_t i; + int error; + + if (len == 0) + return (0); + + cmd = IG4_DATA_COMMAND_RD; + cmd |= repeated_start ? IG4_DATA_RESTART : 0; + cmd |= stop && len == 1 ? IG4_DATA_STOP : 0; + + /* Issue request for the first byte (could be last as well). */ + reg_write(sc, IG4_REG_DATA_CMD, cmd); + + for (i = 0; i < len; i++) { + /* + * Maintain a pipeline by queueing the allowance for the next + * read before waiting for the current read. + */ + cmd = IG4_DATA_COMMAND_RD; + if (i < len - 1) { + cmd = IG4_DATA_COMMAND_RD; + cmd |= stop && i == len - 2 ? IG4_DATA_STOP : 0; + reg_write(sc, IG4_REG_DATA_CMD, cmd); + } + error = wait_status(sc, IG4_STATUS_RX_NOTEMPTY); + if (error) + break; + buf[i] = data_read(sc); + } + + (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE); + return (error); +} + +static int +ig4iic_write(ig4iic_softc_t *sc, uint8_t *buf, uint16_t len, + bool repeated_start, bool stop) +{ + uint32_t cmd; + uint16_t i; + int error; + + if (len == 0) + return (0); + + cmd = repeated_start ? IG4_DATA_RESTART : 0; + for (i = 0; i < len; i++) { + error = wait_status(sc, IG4_STATUS_TX_NOTFULL); + if (error) + break; + cmd |= buf[i]; + cmd |= stop && i == len - 1 ? IG4_DATA_STOP : 0; + reg_write(sc, IG4_REG_DATA_CMD, cmd); + cmd = 0; + } + + (void)reg_read(sc, IG4_REG_TX_ABRT_SOURCE); + return (error); +} + +int +ig4iic_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) +{ + ig4iic_softc_t *sc = device_get_softc(dev); + const char *reason = NULL; + uint32_t i; + int error; + int unit; + bool rpstart; + bool stop; + + /* + * The hardware interface imposes limits on allowed I2C messages. + * It is not possible to explicitly send a start or stop. + * They are automatically sent (or not sent, depending on the + * configuration) when a data byte is transferred. + * For this reason it's impossible to send a message with no data + * at all (like an SMBus quick message). + * The start condition is automatically generated after the stop + * condition, so it's impossible to not have a start after a stop. + * The repeated start condition is automatically sent if a change + * of the transfer direction happens, so it's impossible to have + * a change of direction without a (repeated) start. + * The repeated start can be forced even without the change of + * direction. + * Changing the target slave address requires resetting the hardware + * state, so it's impossible to do that without the stop followed + * by the start. + */ + for (i = 0; i < nmsgs; i++) { +#if 0 + if (i == 0 && (msgs[i].flags & IIC_M_NOSTART) != 0) { + reason = "first message without start"; + break; + } + if (i == nmsgs - 1 && (msgs[i].flags & IIC_M_NOSTOP) != 0) { + reason = "last message without stop"; + break; + } +#endif + if (msgs[i].len == 0) { + reason = "message with no data"; + break; + } + if (i > 0) { + if ((msgs[i].flags & IIC_M_NOSTART) != 0 && + (msgs[i - 1].flags & IIC_M_NOSTOP) == 0) { + reason = "stop not followed by start"; + break; + } + if ((msgs[i - 1].flags & IIC_M_NOSTOP) != 0 && + msgs[i].slave != msgs[i - 1].slave) { + reason = "change of slave without stop"; + break; + } + if ((msgs[i].flags & IIC_M_NOSTART) != 0 && + (msgs[i].flags & IIC_M_RD) != + (msgs[i - 1].flags & IIC_M_RD)) { + reason = "change of direction without repeated" + " start"; + break; + } + } + } + if (reason != NULL) { + if (bootverbose) + device_printf(dev, "%s\n", reason); + return (IIC_ENOTSUPP); + } + + sx_xlock(&sc->call_lock); + mtx_lock(&sc->io_lock); + + /* Debugging - dump registers. */ + if (ig4_dump) { + unit = device_get_unit(dev); + if (ig4_dump & (1 << unit)) { + ig4_dump &= ~(1 << unit); + ig4iic_dump(sc); + } + } + + /* + * Clear any previous abort condition that may have been holding + * the txfifo in reset. + */ + reg_read(sc, IG4_REG_CLR_TX_ABORT); + + /* + * Clean out any previously received data. + */ + if (sc->rpos != sc->rnext && bootverbose) { + device_printf(sc->dev, "discarding %d bytes of spurious data\n", + sc->rnext - sc->rpos); + } + sc->rpos = 0; + sc->rnext = 0; + + rpstart = false; + error = 0; + for (i = 0; i < nmsgs; i++) { + if ((msgs[i].flags & IIC_M_NOSTART) == 0) { + error = ig4iic_xfer_start(sc, msgs[i].slave); + } else { + if (!sc->slave_valid || + (msgs[i].slave >> 1) != sc->last_slave) { + device_printf(dev, "start condition suppressed" + "but slave address is not set up"); + error = EINVAL; + break; + } + rpstart = false; + } + if (error != 0) + break; + + stop = (msgs[i].flags & IIC_M_NOSTOP) == 0; + if (msgs[i].flags & IIC_M_RD) + error = ig4iic_read(sc, msgs[i].buf, msgs[i].len, + rpstart, stop); + else + error = ig4iic_write(sc, msgs[i].buf, msgs[i].len, + rpstart, stop); + if (error != 0) + break; + + rpstart = !stop; + } + + mtx_unlock(&sc->io_lock); + sx_unlock(&sc->call_lock); + return (error); +} + +int +ig4iic_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) +{ + ig4iic_softc_t *sc = device_get_softc(dev); + + sx_xlock(&sc->call_lock); + mtx_lock(&sc->io_lock); + + /* TODO handle speed configuration? */ + if (oldaddr != NULL) + *oldaddr = sc->last_slave << 1; + set_slave_addr(sc, addr >> 1, 0); + if (addr == IIC_UNKNOWN) + sc->slave_valid = false; + + mtx_unlock(&sc->io_lock); + sx_unlock(&sc->call_lock); + return (0); +} + /* * SMBUS API FUNCTIONS * @@ -549,9 +781,9 @@ ig4iic_attach(ig4iic_softc_t *sc) IG4_CTL_RESTARTEN | IG4_CTL_SPEED_STD); - sc->smb = device_add_child(sc->dev, "smbus", -1); - if (sc->smb == NULL) { - device_printf(sc->dev, "smbus driver not found\n"); + sc->iicbus = device_add_child(sc->dev, "iicbus", -1); + if (sc->iicbus == NULL) { + device_printf(sc->dev, "iicbus driver not found\n"); error = ENXIO; goto done; } @@ -624,15 +856,15 @@ ig4iic_detach(ig4iic_softc_t *sc) if (error) return (error); } - if (sc->smb) - device_delete_child(sc->dev, sc->smb); + if (sc->iicbus) + device_delete_child(sc->dev, sc->iicbus); if (sc->intr_handle) bus_teardown_intr(sc->dev, sc->intr_res, sc->intr_handle); sx_xlock(&sc->call_lock); mtx_lock(&sc->io_lock); - sc->smb = NULL; + sc->iicbus = NULL; sc->intr_handle = NULL; reg_write(sc, IG4_REG_INTR_MASK, 0); set_controller(sc, 0); @@ -976,4 +1208,4 @@ ig4iic_dump(ig4iic_softc_t *sc) } #undef REGDUMP -DRIVER_MODULE(smbus, ig4iic, smbus_driver, smbus_devclass, NULL, NULL); +DRIVER_MODULE(iicbus, ig4iic, iicbus_driver, iicbus_devclass, NULL, NULL); diff --git a/sys/dev/ichiic/ig4_pci.c b/sys/dev/ichiic/ig4_pci.c index 7038cae6478f..0d796e5980d7 100644 --- a/sys/dev/ichiic/ig4_pci.c +++ b/sys/dev/ichiic/ig4_pci.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include "smbus_if.h" @@ -180,6 +181,10 @@ static device_method_t ig4iic_pci_methods[] = { DEVMETHOD(smbus_bread, ig4iic_smb_bread), DEVMETHOD(smbus_trans, ig4iic_smb_trans), + DEVMETHOD(iicbus_transfer, ig4iic_transfer), + DEVMETHOD(iicbus_reset, ig4iic_reset), + DEVMETHOD(iicbus_callback, iicbus_null_callback), + DEVMETHOD_END }; @@ -191,7 +196,9 @@ static driver_t ig4iic_pci_driver = { static devclass_t ig4iic_pci_devclass; -DRIVER_MODULE(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0); +DRIVER_MODULE_ORDERED(ig4iic, pci, ig4iic_pci_driver, ig4iic_pci_devclass, 0, 0, + SI_ORDER_ANY); MODULE_DEPEND(ig4iic, pci, 1, 1, 1); MODULE_DEPEND(ig4iic, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); +MODULE_DEPEND(ig4iic, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); MODULE_VERSION(ig4iic, 1); diff --git a/sys/dev/ichiic/ig4_var.h b/sys/dev/ichiic/ig4_var.h index bb1a357e2c32..b35f2f97296f 100644 --- a/sys/dev/ichiic/ig4_var.h +++ b/sys/dev/ichiic/ig4_var.h @@ -42,6 +42,7 @@ #include "device_if.h" #include "pci_if.h" #include "smbus_if.h" +#include "iicbus_if.h" #define IG4_RBUFSIZE 128 #define IG4_RBUFMASK (IG4_RBUFSIZE - 1) @@ -51,7 +52,7 @@ enum ig4_op { IG4_IDLE, IG4_READ, IG4_WRITE }; struct ig4iic_softc { device_t dev; struct intr_config_hook enum_hook; - device_t smb; + device_t iicbus; struct resource *regs_res; int regs_rid; struct resource *intr_res; @@ -115,5 +116,7 @@ extern smbus_pcall_t ig4iic_smb_pcall; extern smbus_bwrite_t ig4iic_smb_bwrite; extern smbus_bread_t ig4iic_smb_bread; extern smbus_trans_t ig4iic_smb_trans; +extern iicbus_transfer_t ig4iic_transfer; +extern iicbus_reset_t ig4iic_reset; #endif diff --git a/sys/dev/iicbus/iicbus.c b/sys/dev/iicbus/iicbus.c index 0e529fd2499b..8cb7383df243 100644 --- a/sys/dev/iicbus/iicbus.c +++ b/sys/dev/iicbus/iicbus.c @@ -208,7 +208,9 @@ iicbus_write_ivar(device_t bus, device_t child, int which, uintptr_t value) default: return (EINVAL); case IICBUS_IVAR_ADDR: - return (EINVAL); + if (devi->addr != 0) + return (EINVAL); + devi->addr = value; case IICBUS_IVAR_NOSTOP: devi->nostop = value; break; diff --git a/sys/dev/isl/isl.c b/sys/dev/isl/isl.c index 5531ee948125..ef77985df19c 100644 --- a/sys/dev/isl/isl.c +++ b/sys/dev/isl/isl.c @@ -52,14 +52,12 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include -#include -#include +#include +#include #include -#include "smbus_if.h" +#include "iicbus_if.h" #include "bus_if.h" #include "device_if.h" @@ -71,46 +69,58 @@ __FBSDID("$FreeBSD$"); struct isl_softc { device_t dev; - int addr; - struct sx isl_sx; }; /* Returns < 0 on problem. */ -static int isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask); +static int isl_read_sensor(device_t dev, uint8_t cmd_mask); + +static int +isl_read_byte(device_t dev, uint8_t reg, uint8_t *val) +{ + uint16_t addr = iicbus_get_addr(dev); + struct iic_msg msgs[] = { + { addr, IIC_M_WR | IIC_M_NOSTOP, 1, ® }, + { addr, IIC_M_RD, 1, val }, + }; + + return (iicbus_transfer(dev, msgs, nitems(msgs))); +} + +static int +isl_write_byte(device_t dev, uint8_t reg, uint8_t val) +{ + uint16_t addr = iicbus_get_addr(dev); + uint8_t bytes[] = { reg, val }; + struct iic_msg msgs[] = { + { addr, IIC_M_WR, nitems(bytes), bytes }, + }; + + return (iicbus_transfer(dev, msgs, nitems(msgs))); +} /* * Initialize the device */ static int -init_device(device_t dev, int addr, int probe) +init_device(device_t dev, int probe) { - static char bl_init[] = { 0x00 }; - - device_t bus; int error; - bus = device_get_parent(dev); /* smbus */ - /* * init procedure: send 0x00 to test ref and cmd reg 1 */ - error = smbus_trans(bus, addr, REG_TEST, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - bl_init, sizeof(bl_init), NULL, 0, NULL); + error = isl_write_byte(dev, REG_TEST, 0); if (error) goto done; - - error = smbus_trans(bus, addr, REG_CMD1, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - bl_init, sizeof(bl_init), NULL, 0, NULL); + error = isl_write_byte(dev, REG_CMD1, 0); if (error) goto done; pause("islinit", hz/100); done: - if (error) + if (error && !probe) device_printf(dev, "Unable to initialize\n"); return (error); } @@ -138,27 +148,33 @@ static driver_t isl_driver = { sizeof(struct isl_softc), }; +#if 0 +static void +isl_identify(driver_t *driver, device_t parent) +{ + + if (device_find_child(parent, "asl", -1)) { + if (bootverbose) + printf("asl: device(s) already created\n"); + return; + } + + /* Check if we can communicate to our slave. */ + if (init_device(dev, 0x88, 1) == 0) + BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "isl", -1); +} +#endif + static int isl_probe(device_t dev) { - int addr; - int error; + uint32_t addr = iicbus_get_addr(dev); - addr = smbus_get_addr(dev); - - /* - * 0x44 - isl ambient light sensor on the acer c720. - * (other devices might use other ids). - */ - if (addr != 0x44) + if (addr != 0x88) return (ENXIO); - - error = init_device(dev, addr, 1); - if (error) + if (init_device(dev, 1) != 0) return (ENXIO); - device_set_desc(dev, "ISL Digital Ambient Light Sensor"); - return (BUS_PROBE_VENDOR); } @@ -168,36 +184,28 @@ isl_attach(device_t dev) struct isl_softc *sc; struct sysctl_ctx_list *sysctl_ctx; struct sysctl_oid *sysctl_tree; - int addr; int use_als; int use_ir; int use_prox; sc = device_get_softc(dev); + sc->dev = dev; - if (!sc) - return (ENOMEM); - - addr = smbus_get_addr(dev); - - if (init_device(dev, addr, 0)) + if (init_device(dev, 0) != 0) return (ENXIO); sx_init(&sc->isl_sx, "ISL read lock"); - sc->dev = dev; - sc->addr = addr; - sysctl_ctx = device_get_sysctl_ctx(dev); sysctl_tree = device_get_sysctl_tree(dev); - use_als = isl_read_sensor(dev, addr, CMD1_MASK_ALS_ONCE) >= 0; - use_ir = isl_read_sensor(dev, addr, CMD1_MASK_IR_ONCE) >= 0; - use_prox = isl_read_sensor(dev, addr, CMD1_MASK_PROX_ONCE) >= 0; + use_als = isl_read_sensor(dev, CMD1_MASK_ALS_ONCE) >= 0; + use_ir = isl_read_sensor(dev, CMD1_MASK_IR_ONCE) >= 0; + use_prox = isl_read_sensor(dev, CMD1_MASK_PROX_ONCE) >= 0; if (use_als) { SYSCTL_ADD_PROC(sysctl_ctx, - SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, + SYSCTL_CHILDREN(sysctl_tree), OID_AUTO, "als", CTLTYPE_INT | CTLFLAG_RD, sc, ISL_METHOD_ALS, isl_sysctl, "I", "Current ALS sensor read-out"); @@ -252,7 +260,6 @@ isl_sysctl(SYSCTL_HANDLER_ARGS) static int ranges[] = { 1000, 4000, 16000, 64000}; struct isl_softc *sc; - device_t bus; uint8_t rbyte; int arg; int resolution; @@ -262,10 +269,7 @@ isl_sysctl(SYSCTL_HANDLER_ARGS) arg = -1; sx_xlock(&sc->isl_sx); - bus = device_get_parent(sc->dev); /* smbus */ - if (smbus_trans(bus, sc->addr, REG_CMD2, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, &rbyte, sizeof(rbyte), NULL)) { + if (isl_read_byte(sc->dev, REG_CMD2, &rbyte) != 0) { sx_xunlock(&sc->isl_sx); return (-1); } @@ -275,16 +279,14 @@ isl_sysctl(SYSCTL_HANDLER_ARGS) switch (oidp->oid_arg2) { case ISL_METHOD_ALS: - arg = (isl_read_sensor(sc->dev, sc->addr, + arg = (isl_read_sensor(sc->dev, CMD1_MASK_ALS_ONCE) * range) >> resolution; break; case ISL_METHOD_IR: - arg = isl_read_sensor(sc->dev, sc->addr, - CMD1_MASK_IR_ONCE); + arg = isl_read_sensor(sc->dev, CMD1_MASK_IR_ONCE); break; case ISL_METHOD_PROX: - arg = isl_read_sensor(sc->dev, sc->addr, - CMD1_MASK_PROX_ONCE); + arg = isl_read_sensor(sc->dev, CMD1_MASK_PROX_ONCE); break; case ISL_METHOD_RESOLUTION: arg = (1 << resolution); @@ -300,18 +302,13 @@ isl_sysctl(SYSCTL_HANDLER_ARGS) } static int -isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask) +isl_read_sensor(device_t dev, uint8_t cmd_mask) { - device_t bus; uint8_t rbyte; uint8_t cmd; int ret; - bus = device_get_parent(dev); /* smbus */ - - if (smbus_trans(bus, addr, REG_CMD1, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, &rbyte, sizeof(rbyte), NULL)) { + if (isl_read_byte(dev, REG_CMD1, &rbyte) != 0) { device_printf(dev, "Couldn't read first byte before issuing command %d\n", cmd_mask); @@ -319,27 +316,21 @@ isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask) } cmd = (rbyte & 0x1f) | cmd_mask; - if (smbus_trans(bus, addr, REG_CMD1, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - &cmd, sizeof(cmd), NULL, 0, NULL)) { + if (isl_write_byte(dev, REG_CMD1, cmd) != 0) { device_printf(dev, "Couldn't write command %d\n", cmd_mask); return (-1); } pause("islconv", hz/10); - if (smbus_trans(bus, addr, REG_DATA1, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, &rbyte, sizeof(rbyte), NULL)) { + if (isl_read_byte(dev, REG_DATA1, &rbyte) != 0) { device_printf(dev, "Couldn't read first byte after command %d\n", cmd_mask); return (-1); } ret = rbyte; - if (smbus_trans(bus, addr, REG_DATA2, - SMB_TRANS_NOCNT | SMB_TRANS_7BIT, - NULL, 0, &rbyte, sizeof(rbyte), NULL)) { + if (isl_read_byte(dev, REG_DATA2, &rbyte) != 0) { device_printf(dev, "Couldn't read second byte after command %d\n", cmd_mask); return (-1); } @@ -348,6 +339,6 @@ isl_read_sensor(device_t dev, int addr, uint8_t cmd_mask) return (ret); } -DRIVER_MODULE(isl, smbus, isl_driver, isl_devclass, NULL, NULL); -MODULE_DEPEND(isl, smbus, SMBUS_MINVER, SMBUS_PREFVER, SMBUS_MAXVER); +DRIVER_MODULE(isl, iicbus, isl_driver, isl_devclass, NULL, NULL); +MODULE_DEPEND(isl, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); MODULE_VERSION(isl, 1); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index dc8a7cf36961..b5ac84dbabb3 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -73,6 +73,7 @@ SUBDIR= \ cd9660_iconv \ ${_ce} \ ${_cfi} \ + ${_chromebook_platform} \ ${_ciss} \ cloudabi \ ${_cloudabi32} \ @@ -604,6 +605,7 @@ _amdtemp= amdtemp _arcmsr= arcmsr _asmc= asmc _ciss= ciss +_chromebook_platform= chromebook_platform _cmx= cmx _coretemp= coretemp .if ${MK_SOURCELESS_HOST} != "no" diff --git a/sys/modules/chromebook_platform/Makefile b/sys/modules/chromebook_platform/Makefile new file mode 100644 index 000000000000..640c536abd9a --- /dev/null +++ b/sys/modules/chromebook_platform/Makefile @@ -0,0 +1,7 @@ +#$FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/chromebook_platform +KMOD = chromebook_platform +SRCS = chromebook_platform.c bus_if.h device_if.h pci_if.h + +.include diff --git a/sys/modules/i2c/controllers/ichiic/Makefile b/sys/modules/i2c/controllers/ichiic/Makefile index 288a79e450bd..1cebbebad59d 100644 --- a/sys/modules/i2c/controllers/ichiic/Makefile +++ b/sys/modules/i2c/controllers/ichiic/Makefile @@ -2,7 +2,7 @@ .PATH: ${.CURDIR}/../../../../dev/ichiic KMOD = ig4 -SRCS = device_if.h bus_if.h iicbb_if.h pci_if.h smbus_if.h \ +SRCS = device_if.h bus_if.h iicbus_if.h pci_if.h smbus_if.h \ ig4_iic.c ig4_pci.c ig4_reg.h ig4_var.h .include diff --git a/sys/modules/i2c/cyapa/Makefile b/sys/modules/i2c/cyapa/Makefile index 80f5fbac2372..eee4a62cde43 100644 --- a/sys/modules/i2c/cyapa/Makefile +++ b/sys/modules/i2c/cyapa/Makefile @@ -2,6 +2,6 @@ .PATH: ${.CURDIR}/../../../dev/cyapa KMOD = cyapa -SRCS = cyapa.c device_if.h bus_if.h smbus_if.h vnode_if.h +SRCS = cyapa.c device_if.h bus_if.h iicbus_if.h vnode_if.h .include diff --git a/sys/modules/i2c/isl/Makefile b/sys/modules/i2c/isl/Makefile index a9fac280216d..697fdeab7862 100644 --- a/sys/modules/i2c/isl/Makefile +++ b/sys/modules/i2c/isl/Makefile @@ -2,6 +2,6 @@ .PATH: ${.CURDIR}/../../../dev/isl KMOD = isl -SRCS = isl.c device_if.h bus_if.h smbus_if.h vnode_if.h +SRCS = isl.c device_if.h bus_if.h iicbus_if.h .include From bd95d8610a0ca9cd3b17afe2b708cecec5d7d479 Mon Sep 17 00:00:00 2001 From: Jared McNeill Date: Sun, 30 Oct 2016 14:39:33 +0000 Subject: [PATCH 206/235] Fix H3 temperature reporting. The formula in for V1.0 of the H3 datasheet seems to be incorrect, so use the same method of conversion as the H3 BSP instead. --- sys/arm/allwinner/aw_thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm/allwinner/aw_thermal.c b/sys/arm/allwinner/aw_thermal.c index c4c8bc1035ce..12146afd968d 100644 --- a/sys/arm/allwinner/aw_thermal.c +++ b/sys/arm/allwinner/aw_thermal.c @@ -109,9 +109,9 @@ __FBSDID("$FreeBSD$"); #define H3_ADC_ACQUIRE_TIME 0x3f #define H3_FILTER 0x6 #define H3_INTC 0x191000 -#define H3_TEMP_BASE 2794000 +#define H3_TEMP_BASE 1794000 #define H3_TEMP_MUL 1000 -#define H3_TEMP_DIV -14882 +#define H3_TEMP_DIV -8253 #define H3_CLK_RATE 4000000 #define TEMP_C_TO_K 273 From 49b53bee5ab3107261bfae9363e8ad08f4880571 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Sun, 30 Oct 2016 15:46:24 +0000 Subject: [PATCH 207/235] - Use virtualbox-ose-additions-nox11 for vagrant image to reduce size Reviewed by: brd, gjb, swills Approved by: gjb --- release/tools/vagrant-virtualbox.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/release/tools/vagrant-virtualbox.conf b/release/tools/vagrant-virtualbox.conf index ff14674ca708..772068befd30 100644 --- a/release/tools/vagrant-virtualbox.conf +++ b/release/tools/vagrant-virtualbox.conf @@ -5,11 +5,11 @@ . ${WORLDDIR}/release/tools/vagrant.conf -export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} virtualbox-ose-additions" +export VM_EXTRA_PACKAGES="${VM_EXTRA_PACKAGES} virtualbox-ose-additions-nox11" vm_extra_pre_umount () { # VirtualBox first boot pkgs - echo 'firstboot_pkgs_list="sudo rsync virtualbox-ose-additions"' >> ${DESTDIR}/etc/rc.conf + echo 'firstboot_pkgs_list="sudo rsync virtualbox-ose-additions-nox11"' >> ${DESTDIR}/etc/rc.conf echo 'vboxguest_enable="YES"' >> ${DESTDIR}/etc/rc.conf echo 'vboxservice_enable="YES"' >> ${DESTDIR}/etc/rc.conf From 5dae51da3da0cc94d17bd67b308fad304ebec7e0 Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Sun, 30 Oct 2016 15:56:42 +0000 Subject: [PATCH 208/235] - Fix `make` in sys/modules/bhnd Approved by: landonf Differential Revision: https://reviews.freebsd.org/D7774 --- sys/modules/bhnd/Makefile | 2 ++ sys/modules/bhnd/bcma/Makefile | 2 +- sys/modules/bhnd/bcma_bhndb/Makefile | 2 +- sys/modules/bhnd/bhndb/Makefile | 2 +- sys/modules/bhnd/bhndb_pci/Makefile | 2 +- sys/modules/bhnd/cores/bhnd_pci/Makefile | 2 +- sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile | 2 +- sys/modules/bhnd/cores/bhnd_pcib/Makefile | 2 +- sys/modules/bhnd/siba/Makefile | 2 +- sys/modules/bhnd/siba_bhndb/Makefile | 2 +- 10 files changed, 11 insertions(+), 9 deletions(-) diff --git a/sys/modules/bhnd/Makefile b/sys/modules/bhnd/Makefile index 9c99afd6eaa2..583075be9430 100644 --- a/sys/modules/bhnd/Makefile +++ b/sys/modules/bhnd/Makefile @@ -37,6 +37,8 @@ SRCS+= bhnd_nvram_if.c bhnd_nvram_if.h SRCS+= device_if.h bus_if.h +SRCS+= opt_global.h + SUBDIR= bcma \ bcma_bhndb \ bhndb \ diff --git a/sys/modules/bhnd/bcma/Makefile b/sys/modules/bhnd/bcma/Makefile index 8b86c3e6500e..5dff47005b12 100644 --- a/sys/modules/bhnd/bcma/Makefile +++ b/sys/modules/bhnd/bcma/Makefile @@ -6,6 +6,6 @@ KMOD= bcma SRCS= bcma.c bcma_subr.c bcma_erom.c SRCS+= device_if.h bus_if.h -SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h +SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h opt_global.h .include diff --git a/sys/modules/bhnd/bcma_bhndb/Makefile b/sys/modules/bhnd/bcma_bhndb/Makefile index e069cb5bdc30..82b96004f57d 100644 --- a/sys/modules/bhnd/bcma_bhndb/Makefile +++ b/sys/modules/bhnd/bcma_bhndb/Makefile @@ -7,6 +7,6 @@ SRCS= bcma_bhndb.c SRCS+= bhnd_bus_if.h bhnd_erom_if.h SRCS+= bhndb_bus_if.h bhndb_if.h -SRCS+= device_if.h bus_if.h +SRCS+= device_if.h bus_if.h opt_global.h .include diff --git a/sys/modules/bhnd/bhndb/Makefile b/sys/modules/bhnd/bhndb/Makefile index 04297f101c5b..5b856f8494f9 100644 --- a/sys/modules/bhnd/bhndb/Makefile +++ b/sys/modules/bhnd/bhndb/Makefile @@ -12,6 +12,6 @@ SRCS+= bhnd_bus_if.h \ bhnd_erom_if.h \ bhnd_nvram_if.h -SRCS+= device_if.h bus_if.h pci_if.h +SRCS+= device_if.h bus_if.h pci_if.h opt_global.h .include diff --git a/sys/modules/bhnd/bhndb_pci/Makefile b/sys/modules/bhnd/bhndb_pci/Makefile index f10845a8386d..ea3aadf859ea 100644 --- a/sys/modules/bhnd/bhndb_pci/Makefile +++ b/sys/modules/bhnd/bhndb_pci/Makefile @@ -8,6 +8,6 @@ SRCS= bhndb_pci.c bhndb_pci_hwdata.c \ SRCS+= bhnd_bus_if.h bhndb_bus_if.h bhndb_if.h SRCS+= bhnd_nvram_if.h -SRCS+= device_if.h bus_if.h pci_if.h +SRCS+= device_if.h bus_if.h pci_if.h opt_global.h .include diff --git a/sys/modules/bhnd/cores/bhnd_pci/Makefile b/sys/modules/bhnd/cores/bhnd_pci/Makefile index fb6ce438779b..df0b36381d1e 100644 --- a/sys/modules/bhnd/cores/bhnd_pci/Makefile +++ b/sys/modules/bhnd/cores/bhnd_pci/Makefile @@ -5,6 +5,6 @@ KMOD= bhnd_pci SRCS= bhnd_pci.c bhnd_pcie2.c -SRCS+= device_if.h bus_if.h bhnd_bus_if.h +SRCS+= device_if.h bus_if.h bhnd_bus_if.h opt_global.h .include diff --git a/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile b/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile index bbfa7b272103..697da7bd7e1c 100644 --- a/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile +++ b/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile @@ -6,6 +6,6 @@ KMOD= bhnd_pci_hostb SRCS= bhnd_pci_hostb.c bhnd_pcie2_hostb.c SRCS+= device_if.h bus_if.h pci_if.h \ - bhnd_bus_if.h bhnd_chipc_if.h + bhnd_bus_if.h bhnd_chipc_if.h opt_global.h .include diff --git a/sys/modules/bhnd/cores/bhnd_pcib/Makefile b/sys/modules/bhnd/cores/bhnd_pcib/Makefile index c9bb61d423e8..322b244b0b93 100644 --- a/sys/modules/bhnd/cores/bhnd_pcib/Makefile +++ b/sys/modules/bhnd/cores/bhnd_pcib/Makefile @@ -6,6 +6,6 @@ KMOD= bhnd_pcib SRCS= bhnd_pcib.c bhnd_pcie2b.c SRCS+= device_if.h bus_if.h pci_if.h \ - bhnd_bus_if.h + bhnd_bus_if.h opt_global.h .include diff --git a/sys/modules/bhnd/siba/Makefile b/sys/modules/bhnd/siba/Makefile index 7c6a69272ae0..03106eab5317 100644 --- a/sys/modules/bhnd/siba/Makefile +++ b/sys/modules/bhnd/siba/Makefile @@ -7,6 +7,6 @@ SRCS= siba.c siba_subr.c \ siba_erom.c SRCS+= device_if.h bus_if.h -SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h +SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h opt_global.h .include diff --git a/sys/modules/bhnd/siba_bhndb/Makefile b/sys/modules/bhnd/siba_bhndb/Makefile index bd9e6c28e4ce..e494645762aa 100644 --- a/sys/modules/bhnd/siba_bhndb/Makefile +++ b/sys/modules/bhnd/siba_bhndb/Makefile @@ -7,6 +7,6 @@ SRCS= siba_bhndb.c SRCS+= bhnd_bus_if.h bhnd_erom_if.h SRCS+= bhndb_bus_if.h bhndb_if.h -SRCS+= device_if.h bus_if.h +SRCS+= device_if.h bus_if.h opt_global.h .include From 1be02479bec1609228b067000e535d1185a7aaa8 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 30 Oct 2016 18:04:11 +0000 Subject: [PATCH 209/235] Split long line instead of unindenting it. Add KASSERT() verifying that a device object with the same handle has the same ops vector. Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/device_pager.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c index 2080fdf963ad..bce8b125bdb1 100644 --- a/sys/vm/device_pager.c +++ b/sys/vm/device_pager.c @@ -169,7 +169,10 @@ cdev_pager_allocate(void *handle, enum obj_type tp, struct cdev_pager_ops *ops, if (pindex > object->size) object->size = pindex; KASSERT(object->type == tp, - ("Inconsistent device pager type %p %d", object, tp)); + ("Inconsistent device pager type %p %d", + object, tp)); + KASSERT(object->un_pager.devp.ops == ops, + ("Inconsistent devops %p %p", object, ops)); } else { object = object1; object1 = NULL; From 022dfd690c9b550711955d0f8fbdfed41d6131ad Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 30 Oct 2016 18:05:18 +0000 Subject: [PATCH 210/235] Remove vnode_locked label and goto, by collapsing vp calculation into the conditional. Suggested and reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_fault.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index c41511e64856..f89466e51185 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -641,10 +641,8 @@ RetryFault:; */ unlock_map(&fs); - if (fs.object->type == OBJT_VNODE) { - vp = fs.object->handle; - if (vp == fs.vp) - goto vnode_locked; + if (fs.object->type == OBJT_VNODE && + (vp = fs.object->handle) != fs.vp) { unlock_vp(&fs); locked = VOP_ISLOCKED(vp); @@ -667,7 +665,6 @@ RetryFault:; } fs.vp = vp; } -vnode_locked: KASSERT(fs.vp == NULL || !fs.map->system_map, ("vm_fault: vnode-backed object mapped by system map")); From f994b2077bcd7616ff6715982f17fec780a1e6c8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 30 Oct 2016 19:15:59 +0000 Subject: [PATCH 211/235] Merge and sort vm_fault_hold()'s "int" variable definitions. Reviewed by: kib MFC after: 7 days --- sys/vm/vm_fault.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index f89466e51185..5571963a6874 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -291,14 +291,13 @@ vm_fault_hold(vm_map_t map, vm_offset_t vaddr, vm_prot_t fault_type, int fault_flags, vm_page_t *m_hold) { vm_prot_t prot; - int alloc_req, era, faultcount, nera, result; - int map_generation; vm_object_t next_object; struct faultstate fs; struct vnode *vp; vm_offset_t e_end, e_start; vm_page_t m; - int ahead, behind, cluster_offset, error, locked, rv; + int ahead, alloc_req, behind, cluster_offset, error, era, faultcount; + int locked, map_generation, nera, result, rv; u_char behavior; boolean_t wired; /* Passed by reference. */ bool dead, growstack, hardfault, is_first_object_locked; From 1dcadc022f0b4dbec3eb6928564610ce873f7b9e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 30 Oct 2016 20:38:57 +0000 Subject: [PATCH 212/235] Remove vm_pager_has_page() declaration. It is not too useful since static inline definition appears later in the file. Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_pager.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h index 4b7d100a94aa..f73cd004425b 100644 --- a/sys/vm/vm_pager.h +++ b/sys/vm/vm_pager.h @@ -109,7 +109,6 @@ void vm_pager_deallocate(vm_object_t); int vm_pager_get_pages(vm_object_t, vm_page_t *, int, int *, int *); int vm_pager_get_pages_async(vm_object_t, vm_page_t *, int, int *, int *, pgo_getpages_iodone_t, void *); -static __inline boolean_t vm_pager_has_page(vm_object_t, vm_pindex_t, int *, int *); void vm_pager_init(void); vm_object_t vm_pager_object_lookup(struct pagerlst *, void *); From e26236e9f37ed7da6d5acf433a55b4403d050fa3 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 30 Oct 2016 20:39:38 +0000 Subject: [PATCH 213/235] Change remained internal uses of boolean_t to bool in vm/vm_fault.c. Reviewed by: alc Sponsored by: The FreeBSD Foundation MFC after: 1 week --- sys/vm/vm_fault.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 5571963a6874..67f8c754a9a0 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -184,9 +184,9 @@ unlock_and_deallocate(struct faultstate *fs) static void vm_fault_dirty(vm_map_entry_t entry, vm_page_t m, vm_prot_t prot, - vm_prot_t fault_type, int fault_flags, boolean_t set_wd) + vm_prot_t fault_type, int fault_flags, bool set_wd) { - boolean_t need_dirty; + bool need_dirty; if (((prot & VM_PROT_WRITE) == 0 && (fault_flags & VM_FAULT_DIRTY) == 0) || @@ -397,7 +397,7 @@ RetryFault:; vm_page_unlock(m); } vm_fault_dirty(fs.entry, m, prot, fault_type, fault_flags, - FALSE); + false); VM_OBJECT_RUNLOCK(fs.first_object); if (!wired) vm_fault_prefault(&fs, vaddr, PFBAK, PFFOR); @@ -987,7 +987,7 @@ RetryFault:; if (hardfault) fs.entry->next_read = vaddr + ptoa(ahead) + PAGE_SIZE; - vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, TRUE); + vm_fault_dirty(fs.entry, fs.m, prot, fault_type, fault_flags, true); vm_page_assert_xbusied(fs.m); /* From dc88573ff1e6670d828a1412cde16941579a2f7c Mon Sep 17 00:00:00 2001 From: Li-Wen Hsu Date: Sun, 30 Oct 2016 22:18:22 +0000 Subject: [PATCH 214/235] Revert r308107 Requested by: jhb --- sys/modules/bhnd/Makefile | 2 -- sys/modules/bhnd/bcma/Makefile | 2 +- sys/modules/bhnd/bcma_bhndb/Makefile | 2 +- sys/modules/bhnd/bhndb/Makefile | 2 +- sys/modules/bhnd/bhndb_pci/Makefile | 2 +- sys/modules/bhnd/cores/bhnd_pci/Makefile | 2 +- sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile | 2 +- sys/modules/bhnd/cores/bhnd_pcib/Makefile | 2 +- sys/modules/bhnd/siba/Makefile | 2 +- sys/modules/bhnd/siba_bhndb/Makefile | 2 +- 10 files changed, 9 insertions(+), 11 deletions(-) diff --git a/sys/modules/bhnd/Makefile b/sys/modules/bhnd/Makefile index 583075be9430..9c99afd6eaa2 100644 --- a/sys/modules/bhnd/Makefile +++ b/sys/modules/bhnd/Makefile @@ -37,8 +37,6 @@ SRCS+= bhnd_nvram_if.c bhnd_nvram_if.h SRCS+= device_if.h bus_if.h -SRCS+= opt_global.h - SUBDIR= bcma \ bcma_bhndb \ bhndb \ diff --git a/sys/modules/bhnd/bcma/Makefile b/sys/modules/bhnd/bcma/Makefile index 5dff47005b12..8b86c3e6500e 100644 --- a/sys/modules/bhnd/bcma/Makefile +++ b/sys/modules/bhnd/bcma/Makefile @@ -6,6 +6,6 @@ KMOD= bcma SRCS= bcma.c bcma_subr.c bcma_erom.c SRCS+= device_if.h bus_if.h -SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h opt_global.h +SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h .include diff --git a/sys/modules/bhnd/bcma_bhndb/Makefile b/sys/modules/bhnd/bcma_bhndb/Makefile index 82b96004f57d..e069cb5bdc30 100644 --- a/sys/modules/bhnd/bcma_bhndb/Makefile +++ b/sys/modules/bhnd/bcma_bhndb/Makefile @@ -7,6 +7,6 @@ SRCS= bcma_bhndb.c SRCS+= bhnd_bus_if.h bhnd_erom_if.h SRCS+= bhndb_bus_if.h bhndb_if.h -SRCS+= device_if.h bus_if.h opt_global.h +SRCS+= device_if.h bus_if.h .include diff --git a/sys/modules/bhnd/bhndb/Makefile b/sys/modules/bhnd/bhndb/Makefile index 5b856f8494f9..04297f101c5b 100644 --- a/sys/modules/bhnd/bhndb/Makefile +++ b/sys/modules/bhnd/bhndb/Makefile @@ -12,6 +12,6 @@ SRCS+= bhnd_bus_if.h \ bhnd_erom_if.h \ bhnd_nvram_if.h -SRCS+= device_if.h bus_if.h pci_if.h opt_global.h +SRCS+= device_if.h bus_if.h pci_if.h .include diff --git a/sys/modules/bhnd/bhndb_pci/Makefile b/sys/modules/bhnd/bhndb_pci/Makefile index ea3aadf859ea..f10845a8386d 100644 --- a/sys/modules/bhnd/bhndb_pci/Makefile +++ b/sys/modules/bhnd/bhndb_pci/Makefile @@ -8,6 +8,6 @@ SRCS= bhndb_pci.c bhndb_pci_hwdata.c \ SRCS+= bhnd_bus_if.h bhndb_bus_if.h bhndb_if.h SRCS+= bhnd_nvram_if.h -SRCS+= device_if.h bus_if.h pci_if.h opt_global.h +SRCS+= device_if.h bus_if.h pci_if.h .include diff --git a/sys/modules/bhnd/cores/bhnd_pci/Makefile b/sys/modules/bhnd/cores/bhnd_pci/Makefile index df0b36381d1e..fb6ce438779b 100644 --- a/sys/modules/bhnd/cores/bhnd_pci/Makefile +++ b/sys/modules/bhnd/cores/bhnd_pci/Makefile @@ -5,6 +5,6 @@ KMOD= bhnd_pci SRCS= bhnd_pci.c bhnd_pcie2.c -SRCS+= device_if.h bus_if.h bhnd_bus_if.h opt_global.h +SRCS+= device_if.h bus_if.h bhnd_bus_if.h .include diff --git a/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile b/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile index 697da7bd7e1c..bbfa7b272103 100644 --- a/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile +++ b/sys/modules/bhnd/cores/bhnd_pci_hostb/Makefile @@ -6,6 +6,6 @@ KMOD= bhnd_pci_hostb SRCS= bhnd_pci_hostb.c bhnd_pcie2_hostb.c SRCS+= device_if.h bus_if.h pci_if.h \ - bhnd_bus_if.h bhnd_chipc_if.h opt_global.h + bhnd_bus_if.h bhnd_chipc_if.h .include diff --git a/sys/modules/bhnd/cores/bhnd_pcib/Makefile b/sys/modules/bhnd/cores/bhnd_pcib/Makefile index 322b244b0b93..c9bb61d423e8 100644 --- a/sys/modules/bhnd/cores/bhnd_pcib/Makefile +++ b/sys/modules/bhnd/cores/bhnd_pcib/Makefile @@ -6,6 +6,6 @@ KMOD= bhnd_pcib SRCS= bhnd_pcib.c bhnd_pcie2b.c SRCS+= device_if.h bus_if.h pci_if.h \ - bhnd_bus_if.h opt_global.h + bhnd_bus_if.h .include diff --git a/sys/modules/bhnd/siba/Makefile b/sys/modules/bhnd/siba/Makefile index 03106eab5317..7c6a69272ae0 100644 --- a/sys/modules/bhnd/siba/Makefile +++ b/sys/modules/bhnd/siba/Makefile @@ -7,6 +7,6 @@ SRCS= siba.c siba_subr.c \ siba_erom.c SRCS+= device_if.h bus_if.h -SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h opt_global.h +SRCS+= bhnd_bus_if.h bhnd_erom_if.h bhnd_pmu_if.h .include diff --git a/sys/modules/bhnd/siba_bhndb/Makefile b/sys/modules/bhnd/siba_bhndb/Makefile index e494645762aa..bd9e6c28e4ce 100644 --- a/sys/modules/bhnd/siba_bhndb/Makefile +++ b/sys/modules/bhnd/siba_bhndb/Makefile @@ -7,6 +7,6 @@ SRCS= siba_bhndb.c SRCS+= bhnd_bus_if.h bhnd_erom_if.h SRCS+= bhndb_bus_if.h bhndb_if.h -SRCS+= device_if.h bus_if.h opt_global.h +SRCS+= device_if.h bus_if.h .include From e6ed06f9041d01c58d2feafcdeaa5a7fd91a81fd Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 31 Oct 2016 01:36:28 +0000 Subject: [PATCH 215/235] hyperv/hn: Rename cleaned up RNDIS source file. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8361 --- sys/conf/files.amd64 | 2 +- sys/conf/files.i386 | 2 +- sys/dev/hyperv/netvsc/{hv_rndis_filter.c => hn_rndis.c} | 0 sys/modules/hyperv/netvsc/Makefile | 4 +--- 4 files changed, 3 insertions(+), 5 deletions(-) rename sys/dev/hyperv/netvsc/{hv_rndis_filter.c => hn_rndis.c} (100%) diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 40d185037f95..5b699a08120a 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -292,8 +292,8 @@ dev/hwpmc/hwpmc_piv.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/netvsc/hn_nvs.c optional hyperv +dev/hyperv/netvsc/hn_rndis.c optional hyperv dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv -dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_heartbeat.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index ba9622dc6b58..42962548a36a 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -249,8 +249,8 @@ dev/hwpmc/hwpmc_ppro.c optional hwpmc dev/hwpmc/hwpmc_tsc.c optional hwpmc dev/hwpmc/hwpmc_x86.c optional hwpmc dev/hyperv/netvsc/hn_nvs.c optional hyperv +dev/hyperv/netvsc/hn_rndis.c optional hyperv dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c optional hyperv -dev/hyperv/netvsc/hv_rndis_filter.c optional hyperv dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c optional hyperv dev/hyperv/utilities/hv_heartbeat.c optional hyperv dev/hyperv/utilities/hv_kvp.c optional hyperv diff --git a/sys/dev/hyperv/netvsc/hv_rndis_filter.c b/sys/dev/hyperv/netvsc/hn_rndis.c similarity index 100% rename from sys/dev/hyperv/netvsc/hv_rndis_filter.c rename to sys/dev/hyperv/netvsc/hn_rndis.c diff --git a/sys/modules/hyperv/netvsc/Makefile b/sys/modules/hyperv/netvsc/Makefile index ab8082096e66..b27ea406c9cc 100644 --- a/sys/modules/hyperv/netvsc/Makefile +++ b/sys/modules/hyperv/netvsc/Makefile @@ -4,9 +4,7 @@ ${.CURDIR}/../../../dev/hyperv/vmbus KMOD= hv_netvsc -SRCS= hn_nvs.c \ - hv_netvsc_drv_freebsd.c \ - hv_rndis_filter.c +SRCS= hn_nvs.c hn_rndis.c hv_netvsc_drv_freebsd.c SRCS+= bus_if.h device_if.h opt_inet.h opt_inet6.h vmbus_if.h CFLAGS+= -I${.CURDIR}/../../../dev/hyperv/netvsc From 8ff20a73f6ac1fb4e25d69b9b00109e16d42e4cf Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 31 Oct 2016 04:46:02 +0000 Subject: [PATCH 216/235] hyperv/hn: Rework temporary channel packet buffer expanding. And use large default temporary channel packer buffer; we really don't want it to be expanded at run time. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8367 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 106 ++++++++++-------- sys/dev/hyperv/netvsc/if_hnvar.h | 3 +- 2 files changed, 59 insertions(+), 50 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index c54acb73cc3e..c584058290b5 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -176,6 +176,8 @@ __FBSDID("$FreeBSD$"); HN_RXINFO_HASHINF | \ HN_RXINFO_HASHVAL) +#define HN_PKTBUF_LEN_DEF (16 * 1024) + struct hn_txdesc { #ifndef HN_USE_TXDESC_BUFRING SLIST_ENTRY(hn_txdesc) link; @@ -2720,7 +2722,8 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) rxr->hn_ifp = sc->hn_ifp; if (i < sc->hn_tx_ring_cnt) rxr->hn_txr = &sc->hn_tx_ring[i]; - rxr->hn_pktbuf = malloc(HN_PKTBUF_LEN, M_DEVBUF, M_WAITOK); + rxr->hn_pktbuf_len = HN_PKTBUF_LEN_DEF; + rxr->hn_pktbuf = malloc(rxr->hn_pktbuf_len, M_DEVBUF, M_WAITOK); rxr->hn_rx_idx = i; rxr->hn_rxbuf = sc->hn_rxbuf; @@ -2763,6 +2766,11 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) OID_AUTO, "rss_pkts", CTLFLAG_RW, &rxr->hn_rss_pkts, "# of packets w/ RSS info received"); + SYSCTL_ADD_INT(ctx, + SYSCTL_CHILDREN(rxr->hn_rx_sysctl_tree), + OID_AUTO, "pktbuf_len", CTLFLAG_RD, + &rxr->hn_pktbuf_len, 0, + "Temporary channel packet buffer length"); } } } @@ -4536,60 +4544,62 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) { struct hn_rx_ring *rxr = xrxr; struct hn_softc *sc = rxr->hn_ifp->if_softc; - void *buffer; - int bufferlen = HN_PKTBUF_LEN; - buffer = rxr->hn_pktbuf; - do { - struct vmbus_chanpkt_hdr *pkt = buffer; - uint32_t bytes_rxed; - int ret; + for (;;) { + struct vmbus_chanpkt_hdr *pkt = rxr->hn_pktbuf; + int error, pktlen; - bytes_rxed = bufferlen; - ret = vmbus_chan_recv_pkt(chan, pkt, &bytes_rxed); - if (ret == 0) { - switch (pkt->cph_type) { - case VMBUS_CHANPKT_TYPE_COMP: - hn_nvs_handle_comp(sc, chan, pkt); - break; - case VMBUS_CHANPKT_TYPE_RXBUF: - hn_nvs_handle_rxbuf(rxr, chan, pkt); - break; - case VMBUS_CHANPKT_TYPE_INBAND: - hn_nvs_handle_notify(sc, pkt); - break; - default: - if_printf(rxr->hn_ifp, - "unknown chan pkt %u\n", - pkt->cph_type); - break; - } - } else if (ret == ENOBUFS) { - /* Handle large packet */ - if (bufferlen > HN_PKTBUF_LEN) { - free(buffer, M_DEVBUF); - buffer = NULL; - } + pktlen = rxr->hn_pktbuf_len; + error = vmbus_chan_recv_pkt(chan, pkt, &pktlen); + if (__predict_false(error == ENOBUFS)) { + void *nbuf; + int nlen; - /* alloc new buffer */ - buffer = malloc(bytes_rxed, M_DEVBUF, M_NOWAIT); - if (buffer == NULL) { - if_printf(rxr->hn_ifp, - "hv_cb malloc buffer failed, len=%u\n", - bytes_rxed); - bufferlen = 0; - break; - } - bufferlen = bytes_rxed; - } else { - /* No more packets */ + /* + * Expand channel packet buffer. + * + * XXX + * Use M_WAITOK here, since allocation failure + * is fatal. + */ + nlen = rxr->hn_pktbuf_len * 2; + while (nlen < pktlen) + nlen *= 2; + nbuf = malloc(nlen, M_DEVBUF, M_WAITOK); + + if_printf(rxr->hn_ifp, "expand pktbuf %d -> %d\n", + rxr->hn_pktbuf_len, nlen); + + free(rxr->hn_pktbuf, M_DEVBUF); + rxr->hn_pktbuf = nbuf; + rxr->hn_pktbuf_len = nlen; + /* Retry! */ + continue; + } else if (__predict_false(error == EAGAIN)) { + /* No more channel packets; done! */ break; } - } while (1); + KASSERT(!error, ("vmbus_chan_recv_pkt failed: %d", error)); - if (bufferlen > HN_PKTBUF_LEN) - free(buffer, M_DEVBUF); + switch (pkt->cph_type) { + case VMBUS_CHANPKT_TYPE_COMP: + hn_nvs_handle_comp(sc, chan, pkt); + break; + case VMBUS_CHANPKT_TYPE_RXBUF: + hn_nvs_handle_rxbuf(rxr, chan, pkt); + break; + + case VMBUS_CHANPKT_TYPE_INBAND: + hn_nvs_handle_notify(sc, pkt); + break; + + default: + if_printf(rxr->hn_ifp, "unknown chan pkt %u\n", + pkt->cph_type); + break; + } + } hn_chan_rollup(rxr, rxr->hn_txr); } diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index c4d94d040ae8..66b8c412b9de 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -39,8 +39,6 @@ /* Claimed to be 12232B */ #define HN_MTU_MAX (9 * 1024) -#define HN_PKTBUF_LEN 4096 - #define HN_TXBR_SIZE (128 * PAGE_SIZE) #define HN_RXBR_SIZE (128 * PAGE_SIZE) @@ -63,6 +61,7 @@ struct hn_rx_ring { struct ifnet *hn_ifp; struct hn_tx_ring *hn_txr; void *hn_pktbuf; + int hn_pktbuf_len; uint8_t *hn_rxbuf; /* shadow sc->hn_rxbuf */ int hn_rx_idx; From 7ccc20da6a3f05f3ef21e269d60c1a7df4e470aa Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 31 Oct 2016 04:54:15 +0000 Subject: [PATCH 217/235] hyperv/hn: Cleanup RXBUF ack processing. - Increase the # of retries. - Add comment. - Log error, if RXBUF ack fails. - Add stat for RXBUF ack failures. RXBUF ack really should _not_ fail... MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8368 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 53 ++++++++++--------- sys/dev/hyperv/netvsc/if_hnvar.h | 1 + 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index c584058290b5..318fcb4eb70e 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -414,7 +414,8 @@ static void hn_nvs_handle_comp(struct hn_softc *sc, struct vmbus_channel *chan, static void hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan, const struct vmbus_chanpkt_hdr *pkthdr); -static void hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid); +static void hn_nvs_ack_rxbuf(struct hn_rx_ring *, struct vmbus_channel *, + uint64_t); static int hn_transmit(struct ifnet *, struct mbuf *); static void hn_xmit_qflush(struct ifnet *); @@ -2843,6 +2844,10 @@ hn_create_rx_data(struct hn_softc *sc, int ring_cnt) CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, __offsetof(struct hn_rx_ring, hn_small_pkts), hn_rx_stat_ulong_sysctl, "LU", "# of small packets received"); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "rx_ack_failed", + CTLTYPE_ULONG | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, + __offsetof(struct hn_rx_ring, hn_ack_failed), + hn_rx_stat_ulong_sysctl, "LU", "# of RXBUF ack failures"); SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_ring_cnt", CTLFLAG_RD, &sc->hn_rx_ring_cnt, 0, "# created RX rings"); SYSCTL_ADD_INT(ctx, child, OID_AUTO, "rx_ring_inuse", @@ -4499,43 +4504,43 @@ hn_nvs_handle_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan, } /* - * Moved completion call back here so that all received - * messages (not just data messages) will trigger a response - * message back to the host. + * Ack the consumed RXBUF associated w/ this channel packet, + * so that this RXBUF can be recycled by the hypervisor. */ - hn_nvs_ack_rxbuf(chan, pkt->cp_hdr.cph_xactid); + hn_nvs_ack_rxbuf(rxr, chan, pkt->cp_hdr.cph_xactid); } -/* - * Net VSC on receive completion - * - * Send a receive completion packet to RNDIS device (ie NetVsp) - */ static void -hn_nvs_ack_rxbuf(struct vmbus_channel *chan, uint64_t tid) +hn_nvs_ack_rxbuf(struct hn_rx_ring *rxr, struct vmbus_channel *chan, + uint64_t tid) { struct hn_nvs_rndis_ack ack; - int retries = 0; - int ret = 0; + int retries, error; ack.nvs_type = HN_NVS_TYPE_RNDIS_ACK; ack.nvs_status = HN_NVS_STATUS_OK; -retry_send_cmplt: - /* Send the completion */ - ret = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, + retries = 0; +again: + error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_COMP, VMBUS_CHANPKT_FLAG_NONE, &ack, sizeof(ack), tid); - if (ret == 0) { - /* success */ - /* no-op */ - } else if (ret == EAGAIN) { - /* no more room... wait a bit and attempt to retry 3 times */ + if (__predict_false(error == EAGAIN)) { + /* + * NOTE: + * This should _not_ happen in real world, since the + * consumption of the TX bufring from the TX path is + * controlled. + */ + if (rxr->hn_ack_failed == 0) + if_printf(rxr->hn_ifp, "RXBUF ack retry\n"); + rxr->hn_ack_failed++; retries++; - - if (retries < 4) { + if (retries < 10) { DELAY(100); - goto retry_send_cmplt; + goto again; } + /* RXBUF leaks! */ + if_printf(rxr->hn_ifp, "RXBUF ack failed\n"); } } diff --git a/sys/dev/hyperv/netvsc/if_hnvar.h b/sys/dev/hyperv/netvsc/if_hnvar.h index 66b8c412b9de..ea47be85848a 100644 --- a/sys/dev/hyperv/netvsc/if_hnvar.h +++ b/sys/dev/hyperv/netvsc/if_hnvar.h @@ -77,6 +77,7 @@ struct hn_rx_ring { u_long hn_small_pkts; u_long hn_pkts; u_long hn_rss_pkts; + u_long hn_ack_failed; /* Rarely used stuffs */ struct sysctl_oid *hn_rx_sysctl_tree; From 82d71ca917b2631bcf31848d39b589ed432d5b35 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 31 Oct 2016 05:05:12 +0000 Subject: [PATCH 218/235] hyperv/hn: Reset do_lro, if the hash types are not TCP related. Mainly because the host side only set TCPCS and IPCS even for UDP datagrams. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8369 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 318fcb4eb70e..88f1834a5e15 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -1754,6 +1754,13 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, rxr->hn_csum_udp++; } + /* + * XXX + * As of this write (Oct 28th, 2016), host side will turn + * on only TCPCS_OK and IPCS_OK even for UDP datagrams, so + * the do_lro setting here is actually _not_ accurate. We + * depend on the RSS hash type check to reset do_lro. + */ if ((info->csum_info & (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) == (NDIS_RXCSUM_INFO_TCPCS_OK | NDIS_RXCSUM_INFO_IPCS_OK)) @@ -1828,9 +1835,16 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, NDIS_HASH_FUNCTION_TOEPLITZ) { uint32_t type = (info->hash_info & NDIS_HASH_TYPE_MASK); + /* + * NOTE: + * do_lro is resetted, if the hash types are not TCP + * related. See the comment in the above csum_flags + * setup section. + */ switch (type) { case NDIS_HASH_IPV4: hash_type = M_HASHTYPE_RSS_IPV4; + do_lro = 0; break; case NDIS_HASH_TCP_IPV4: @@ -1839,10 +1853,12 @@ hn_rxpkt(struct hn_rx_ring *rxr, const void *data, int dlen, case NDIS_HASH_IPV6: hash_type = M_HASHTYPE_RSS_IPV6; + do_lro = 0; break; case NDIS_HASH_IPV6_EX: hash_type = M_HASHTYPE_RSS_IPV6_EX; + do_lro = 0; break; case NDIS_HASH_TCP_IPV6: From 427e366e4369b0a9ddad5250990b55b61abacab0 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Mon, 31 Oct 2016 05:22:00 +0000 Subject: [PATCH 219/235] hyperv/hn: Don't start shared TX taskq, if the hypervisor is not Hyper-V. - Move the SYSINIT to DRIVER/SECOND, i.e. after the vm_guest becomes determistic. - Minor style changes. MFC after: 1 week Sponsored by: Microsoft Differential Revision: https://reviews.freebsd.org/D8370 --- sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c index 88f1834a5e15..6e2fb28ab380 100644 --- a/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c +++ b/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c @@ -4627,6 +4627,10 @@ hn_chan_callback(struct vmbus_channel *chan, void *xrxr) static void hn_tx_taskq_create(void *arg __unused) { + + if (vm_guest != VM_GUEST_HV) + return; + if (!hn_share_tx_taskq) return; @@ -4645,16 +4649,17 @@ hn_tx_taskq_create(void *arg __unused) taskqueue_start_threads(&hn_tx_taskq, 1, PI_NET, "hn tx"); } } -SYSINIT(hn_txtq_create, SI_SUB_DRIVERS, SI_ORDER_FIRST, +SYSINIT(hn_txtq_create, SI_SUB_DRIVERS, SI_ORDER_SECOND, hn_tx_taskq_create, NULL); static void hn_tx_taskq_destroy(void *arg __unused) { + if (hn_tx_taskq != NULL) taskqueue_free(hn_tx_taskq); } -SYSUNINIT(hn_txtq_destroy, SI_SUB_DRIVERS, SI_ORDER_FIRST, +SYSUNINIT(hn_txtq_destroy, SI_SUB_DRIVERS, SI_ORDER_SECOND, hn_tx_taskq_destroy, NULL); static device_method_t netvsc_methods[] = { From a24d62b5334c3fc0aad6460d3cc74c8e4179720a Mon Sep 17 00:00:00 2001 From: Kevin Lo Date: Mon, 31 Oct 2016 05:58:11 +0000 Subject: [PATCH 220/235] Add preliminary support for the RTL8153. Reviewed by: hselasky --- etc/devd/usb.conf | 2 +- share/man/man4/ure.4 | 19 ++- sys/conf/NOTES | 2 +- sys/dev/mii/miidevs | 2 +- sys/dev/mii/rgephy.c | 12 +- sys/dev/mii/rgephyreg.h | 3 + sys/dev/usb/net/if_ure.c | 279 ++++++++++++++++++++++++++++++------ sys/dev/usb/net/if_urereg.h | 9 +- 8 files changed, 268 insertions(+), 60 deletions(-) diff --git a/etc/devd/usb.conf b/etc/devd/usb.conf index 3d8858b95d7a..3c6e560810d1 100644 --- a/etc/devd/usb.conf +++ b/etc/devd/usb.conf @@ -2713,7 +2713,7 @@ nomatch 32 { match "bus" "uhub[0-9]+"; match "mode" "host"; match "vendor" "0x0bda"; - match "product" "0x8152"; + match "product" "(0x8152|0x8153)"; action "kldload -n if_ure"; }; diff --git a/share/man/man4/ure.4 b/share/man/man4/ure.4 index 1b2ebb885d79..cf483dca9d11 100644 --- a/share/man/man4/ure.4 +++ b/share/man/man4/ure.4 @@ -1,5 +1,5 @@ .\" -.\" Copyright (c) 2015 Kevin Lo +.\" Copyright (c) 2015-2016 Kevin Lo .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,12 +25,12 @@ .\" .\" $FreeBSD$ .\" -.Dd December 1, 2015 +.Dd October 31, 2016 .Dt URE 4 .Os .Sh NAME .Nm ure -.Nd "RealTek RTL8152 USB to Fast Ethernet controller driver" +.Nd "RealTek RTL8152/RTL8153 USB to Ethernet controller driver" .Sh SYNOPSIS To compile this driver into the kernel, place the following lines in your @@ -54,10 +54,10 @@ if_ure_load="YES" The .Nm driver provides support for USB Ethernet adapters based on the RealTek -RTL8152 USB to Fast Ethernet controller chip. +RealTek RTL8152 and RTL8153 USB Ethernet controllers. .Pp -The RTL8152 contains an integrated Fast Ethernet MAC, which supports -both 10 and 100Mbps speeds in either full or half duplex. +NICs based on the RTL8152 are capable of 10 and 100Mbps speeds. +NICs based on the RTL8153 are capable of 10, 100 and 1000Mbps operation. .Pp The .Nm @@ -87,12 +87,17 @@ option can also be used to select either or .Cm half-duplex modes. +.It Cm 1000baseTX +Set 1000baseTX operation over twisted pair. +The RealTek gigE chips support 1000Mbps in +.Cm full-duplex +mode only. .El .Pp The .Nm driver supports the following media options: -.Bl -tag -width ".Cm 10baseT/UTP" +.Bl -tag -width ".Cm full-duplex" .It Cm full-duplex Force full duplex operation. .It Cm half-duplex diff --git a/sys/conf/NOTES b/sys/conf/NOTES index af8bf72cabb8..f964d256a61b 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2788,7 +2788,7 @@ device rue # Davicom DM9601E USB to fast ethernet. Supports the Corega FEther USB-TXC. device udav # -# RealTek RTL8152 USB to fast ethernet. +# RealTek RTL8152/RTL8153 USB Ethernet driver device ure # # Moschip MCS7730/MCS7840 USB to fast ethernet. Supports the Sitecom LN030. diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs index cdb02894192e..64818be60f19 100644 --- a/sys/dev/mii/miidevs +++ b/sys/dev/mii/miidevs @@ -316,7 +316,7 @@ model yyREALTEK RTL8201L 0x0020 RTL8201L 10/100 media interface model xxREALTEK RTL8169S 0x0011 RTL8169S/8110S/8211 1000BASE-T media interface model REALTEK RTL8305SC 0x0005 RTL8305SC 10/100 802.1q switch model REALTEK RTL8201E 0x0008 RTL8201E 10/100 media interface -model REALTEK RTL8251 0x0000 RTL8251 1000BASE-T media interface +model REALTEK RTL8251 0x0000 RTL8251/8153 1000BASE-T media interface model REALTEK RTL8169S 0x0011 RTL8169S/8110S/8211 1000BASE-T media interface /* Seeq Seeq PHYs */ diff --git a/sys/dev/mii/rgephy.c b/sys/dev/mii/rgephy.c index bb60fa92fe17..25cea3abdbaf 100644 --- a/sys/dev/mii/rgephy.c +++ b/sys/dev/mii/rgephy.c @@ -121,6 +121,8 @@ rgephy_attach(device_t dev) flags = 0; if (mii_dev_mac_match(dev, "re")) flags |= MIIF_PHYPRIV0; + else if (mii_dev_mac_match(dev, "ure")) + flags |= MIIF_PHYPRIV1; mii_phy_dev_attach(dev, flags, &rgephy_funcs, 0); /* RTL8169S do not report auto-sense; add manually. */ @@ -293,7 +295,10 @@ rgephy_linkup(struct mii_softc *sc) linkup++; } } else { - reg = PHY_READ(sc, RL_GMEDIASTAT); + if (sc->mii_flags & MIIF_PHYPRIV1) + reg = PHY_READ(sc, URE_GMEDIASTAT); + else + reg = PHY_READ(sc, RL_GMEDIASTAT); if (reg & RL_GMEDIASTAT_LINK) linkup++; } @@ -378,7 +383,10 @@ rgephy_status(struct mii_softc *sc) mii->mii_media_active |= IFM_HDX; } } else { - bmsr = PHY_READ(sc, RL_GMEDIASTAT); + if (sc->mii_flags & MIIF_PHYPRIV1) + bmsr = PHY_READ(sc, URE_GMEDIASTAT); + else + bmsr = PHY_READ(sc, RL_GMEDIASTAT); if (bmsr & RL_GMEDIASTAT_1000MBPS) mii->mii_media_active |= IFM_1000_T; else if (bmsr & RL_GMEDIASTAT_100MBPS) diff --git a/sys/dev/mii/rgephyreg.h b/sys/dev/mii/rgephyreg.h index 7c24a1f7cbb5..35917daa69c9 100644 --- a/sys/dev/mii/rgephyreg.h +++ b/sys/dev/mii/rgephyreg.h @@ -199,4 +199,7 @@ #define EEELPAR_1000T 0x0004 /* link partner 1000baseT EEE capable */ #define EEELPAR_100TX 0x0002 /* link partner 100baseTX EEE capable */ +/* RTL8153 */ +#define URE_GMEDIASTAT 0xe908 /* media status register */ + #endif /* _DEV_RGEPHY_MIIREG_H_ */ diff --git a/sys/dev/usb/net/if_ure.c b/sys/dev/usb/net/if_ure.c index 9d7f47a576ee..59fa71f215d6 100644 --- a/sys/dev/usb/net/if_ure.c +++ b/sys/dev/usb/net/if_ure.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Kevin Lo + * Copyright (c) 2015-2016 Kevin Lo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,8 +66,9 @@ SYSCTL_INT(_hw_usb_ure, OID_AUTO, debug, CTLFLAG_RWTUN, &ure_debug, 0, * Various supported device vendors/products. */ static const STRUCT_USB_HOST_ID ure_devs[] = { -#define URE_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } - URE_DEV(REALTEK, RTL8152), +#define URE_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } + URE_DEV(REALTEK, RTL8152, URE_FLAG_8152), + URE_DEV(REALTEK, RTL8153, 0), #undef URE_DEV }; @@ -87,8 +88,7 @@ static uether_fn_t ure_init; static uether_fn_t ure_stop; static uether_fn_t ure_start; static uether_fn_t ure_tick; -static uether_fn_t ure_setmulti; -static uether_fn_t ure_setpromisc; +static uether_fn_t ure_rxfilter; static int ure_ctl(struct ure_softc *, uint8_t, uint16_t, uint16_t, void *, int); @@ -112,6 +112,7 @@ static int ure_ifmedia_upd(struct ifnet *); static void ure_ifmedia_sts(struct ifnet *, struct ifmediareq *); static int ure_ioctl(struct ifnet *, u_long, caddr_t); static void ure_rtl8152_init(struct ure_softc *); +static void ure_rtl8153_init(struct ure_softc *); static void ure_disable_teredo(struct ure_softc *); static void ure_init_fifo(struct ure_softc *); @@ -129,7 +130,7 @@ static const struct usb_config ure_config[URE_N_TRANSFER] = { .type = UE_BULK, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, - .bufsize = MCLBYTES, + .bufsize = 16384, .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, .callback = ure_bulk_read_callback, .timeout = 0, /* no timeout */ @@ -173,8 +174,8 @@ static const struct usb_ether_methods ure_ue_methods = { .ue_init = ure_init, .ue_stop = ure_stop, .ue_tick = ure_tick, - .ue_setmulti = ure_setmulti, - .ue_setpromisc = ure_setpromisc, + .ue_setmulti = ure_rxfilter, + .ue_setpromisc = ure_rxfilter, .ue_mii_upd = ure_ifmedia_upd, .ue_mii_sts = ure_ifmedia_sts, }; @@ -343,6 +344,13 @@ ure_miibus_readreg(device_t dev, int phy, int reg) if (!locked) URE_LOCK(sc); + /* Let the rgephy driver read the URE_GMEDIASTAT register. */ + if (reg == URE_GMEDIASTAT) { + if (!locked) + URE_UNLOCK(sc); + return (ure_read_1(sc, URE_GMEDIASTAT, URE_MCU_TYPE_PLA)); + } + val = ure_ocp_reg_read(sc, URE_OCP_BASE_MII + reg * 2); if (!locked) @@ -398,6 +406,11 @@ ure_miibus_statchg(device_t dev) case IFM_100_TX: sc->sc_flags |= URE_FLAG_LINK; break; + case IFM_1000_T: + if ((sc->sc_flags & URE_FLAG_8152) != 0) + break; + sc->sc_flags |= URE_FLAG_LINK; + break; default: break; } @@ -412,7 +425,7 @@ ure_miibus_statchg(device_t dev) } /* - * Probe for a RTL8152 chip. + * Probe for a RTL8152/RTL8153 chip. */ static int ure_probe(device_t dev) @@ -443,6 +456,7 @@ ure_attach(device_t dev) uint8_t iface_index; int error; + sc->sc_flags = USB_GET_DRIVER_INFO(uaa); device_set_usb_desc(dev); mtx_init(&sc->sc_mtx, device_get_nameunit(dev), NULL, MTX_DEF); @@ -617,6 +631,18 @@ ure_read_chipver(struct ure_softc *sc) case 0x4c10: sc->sc_chip |= URE_CHIP_VER_4C10; break; + case 0x5c00: + sc->sc_chip |= URE_CHIP_VER_5C00; + break; + case 0x5c10: + sc->sc_chip |= URE_CHIP_VER_5C10; + break; + case 0x5c20: + sc->sc_chip |= URE_CHIP_VER_5C20; + break; + case 0x5c30: + sc->sc_chip |= URE_CHIP_VER_5C30; + break; default: device_printf(sc->sc_ue.ue_dev, "unknown version 0x%04x\n", ver); @@ -635,7 +661,10 @@ ure_attach_post(struct usb_ether *ue) ure_read_chipver(sc); /* Initialize controller and get station address. */ - ure_rtl8152_init(sc); + if (sc->sc_flags & URE_FLAG_8152) + ure_rtl8152_init(sc); + else + ure_rtl8153_init(sc); if (sc->sc_chip & URE_CHIP_VER_4C00) ure_read_mem(sc, URE_PLA_IDR, URE_MCU_TYPE_PLA, @@ -676,7 +705,6 @@ ure_init(struct usb_ether *ue) { struct ure_softc *sc = uether_getsc(ue); struct ifnet *ifp = uether_getifp(ue); - uint32_t rxmode; URE_LOCK_ASSERT(sc, MA_OWNED); @@ -709,20 +737,8 @@ ure_init(struct usb_ether *ue) ure_read_2(sc, URE_PLA_MISC_1, URE_MCU_TYPE_PLA) & ~URE_RXDY_GATED_EN); - /* Set Rx mode. */ - rxmode = URE_RCR_APM; - - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) - rxmode |= URE_RCR_AAP; - - if (ifp->if_flags & IFF_BROADCAST) - rxmode |= URE_RCR_AB; - - ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); - - /* Load the multicast filter. */ - ure_setmulti(ue); + /* Configure RX filters. */ + ure_rxfilter(ue); usbd_xfer_set_stall(sc->sc_xfer[URE_BULK_DT_WR]); @@ -750,30 +766,11 @@ ure_tick(struct usb_ether *ue) } } -static void -ure_setpromisc(struct usb_ether *ue) -{ - struct ure_softc *sc = uether_getsc(ue); - struct ifnet *ifp = uether_getifp(ue); - uint32_t rxmode; - - rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA); - - if (ifp->if_flags & IFF_PROMISC) - rxmode |= URE_RCR_AAP; - else - rxmode &= ~URE_RCR_AAP; - - ure_write_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA, rxmode); - - ure_setmulti(ue); -} - /* * Program the 64-bit multicast hash filter. */ static void -ure_setmulti(struct usb_ether *ue) +ure_rxfilter(struct usb_ether *ue) { struct ure_softc *sc = uether_getsc(ue); struct ifnet *ifp = uether_getifp(ue); @@ -783,7 +780,9 @@ ure_setmulti(struct usb_ether *ue) URE_LOCK_ASSERT(sc, MA_OWNED); - rxmode = ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA); + rxmode = URE_RCR_APM; + if (ifp->if_flags & IFF_BROADCAST) + rxmode |= URE_RCR_AB; if (ifp->if_flags & (IFF_ALLMULTI | IFF_PROMISC)) { if (ifp->if_flags & IFF_PROMISC) rxmode |= URE_RCR_AAP; @@ -792,6 +791,7 @@ ure_setmulti(struct usb_ether *ue) goto done; } + rxmode |= URE_RCR_AM; if_maddr_rlock(ifp); TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) @@ -964,6 +964,156 @@ ure_rtl8152_init(struct ure_softc *sc) URE_TEST_MODE_DISABLE | URE_TX_SIZE_ADJUST1); } +static void +ure_rtl8153_init(struct ure_softc *sc) +{ + uint16_t val; + uint8_t u1u2[8]; + int i; + + /* Disable ALDPS. */ + ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); + uether_pause(&sc->sc_ue, hz / 50); + + memset(u1u2, 0x00, sizeof(u1u2)); + ure_write_mem(sc, URE_USB_TOLERANCE, + URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); + + for (i = 0; i < URE_TIMEOUT; i++) { + if (ure_read_2(sc, URE_PLA_BOOT_CTRL, URE_MCU_TYPE_PLA) & + URE_AUTOLOAD_DONE) + break; + uether_pause(&sc->sc_ue, hz / 100); + } + if (i == URE_TIMEOUT) + device_printf(sc->sc_ue.ue_dev, + "timeout waiting for chip autoload\n"); + + for (i = 0; i < URE_TIMEOUT; i++) { + val = ure_ocp_reg_read(sc, URE_OCP_PHY_STATUS) & + URE_PHY_STAT_MASK; + if (val == URE_PHY_STAT_LAN_ON || val == URE_PHY_STAT_PWRDN) + break; + uether_pause(&sc->sc_ue, hz / 100); + } + if (i == URE_TIMEOUT) + device_printf(sc->sc_ue.ue_dev, + "timeout waiting for phy to stabilize\n"); + + ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, + ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB) & + ~URE_U2P3_ENABLE); + + if (sc->sc_chip & URE_CHIP_VER_5C10) { + val = ure_read_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB); + val &= ~URE_PWD_DN_SCALE_MASK; + val |= URE_PWD_DN_SCALE(96); + ure_write_2(sc, URE_USB_SSPHYLINK2, URE_MCU_TYPE_USB, val); + + ure_write_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB, + ure_read_1(sc, URE_USB_USB2PHY, URE_MCU_TYPE_USB) | + URE_USB2PHY_L1 | URE_USB2PHY_SUSPEND); + } else if (sc->sc_chip & URE_CHIP_VER_5C20) { + ure_write_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA, + ure_read_1(sc, URE_PLA_DMY_REG0, URE_MCU_TYPE_PLA) & + ~URE_ECM_ALDPS); + } + if (sc->sc_chip & (URE_CHIP_VER_5C20 | URE_CHIP_VER_5C30)) { + val = ure_read_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB); + if (ure_read_2(sc, URE_USB_BURST_SIZE, URE_MCU_TYPE_USB) == + 0) + val &= ~URE_DYNAMIC_BURST; + else + val |= URE_DYNAMIC_BURST; + ure_write_1(sc, URE_USB_CSR_DUMMY1, URE_MCU_TYPE_USB, val); + } + + ure_write_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB, + ure_read_1(sc, URE_USB_CSR_DUMMY2, URE_MCU_TYPE_USB) | + URE_EP4_FULL_FC); + + ure_write_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB, + ure_read_2(sc, URE_USB_WDT11_CTRL, URE_MCU_TYPE_USB) & + ~URE_TIMER11_EN); + + ure_write_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA, + ure_read_2(sc, URE_PLA_LED_FEATURE, URE_MCU_TYPE_PLA) & + ~URE_LED_MODE_MASK); + + if ((sc->sc_chip & URE_CHIP_VER_5C10) && + usbd_get_speed(sc->sc_ue.ue_udev) != USB_SPEED_SUPER) + val = URE_LPM_TIMER_500MS; + else + val = URE_LPM_TIMER_500US; + ure_write_1(sc, URE_USB_LPM_CTRL, URE_MCU_TYPE_USB, + val | URE_FIFO_EMPTY_1FB | URE_ROK_EXIT_LPM); + + val = ure_read_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB); + val &= ~URE_SEN_VAL_MASK; + val |= URE_SEN_VAL_NORMAL | URE_SEL_RXIDLE; + ure_write_2(sc, URE_USB_AFE_CTRL2, URE_MCU_TYPE_USB, val); + + ure_write_2(sc, URE_USB_CONNECT_TIMER, URE_MCU_TYPE_USB, 0x0001); + + ure_write_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB, + ure_read_2(sc, URE_USB_POWER_CUT, URE_MCU_TYPE_USB) & + ~(URE_PWR_EN | URE_PHASE2_EN)); + ure_write_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB, + ure_read_2(sc, URE_USB_MISC_0, URE_MCU_TYPE_USB) & + ~URE_PCUT_STATUS); + + memset(u1u2, 0xff, sizeof(u1u2)); + ure_write_mem(sc, URE_USB_TOLERANCE, + URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); + + ure_write_2(sc, URE_PLA_MAC_PWR_CTRL, URE_MCU_TYPE_PLA, + URE_ALDPS_SPDWN_RATIO); + ure_write_2(sc, URE_PLA_MAC_PWR_CTRL2, URE_MCU_TYPE_PLA, + URE_EEE_SPDWN_RATIO); + ure_write_2(sc, URE_PLA_MAC_PWR_CTRL3, URE_MCU_TYPE_PLA, + URE_PKT_AVAIL_SPDWN_EN | URE_SUSPEND_SPDWN_EN | + URE_U1U2_SPDWN_EN | URE_L1_SPDWN_EN); + ure_write_2(sc, URE_PLA_MAC_PWR_CTRL4, URE_MCU_TYPE_PLA, + URE_PWRSAVE_SPDWN_EN | URE_RXDV_SPDWN_EN | URE_TX10MIDLE_EN | + URE_TP100_SPDWN_EN | URE_TP500_SPDWN_EN | URE_TP1000_SPDWN_EN | + URE_EEE_SPDWN_EN); + + val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); + if (!(sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10))) + val |= URE_U2P3_ENABLE; + else + val &= ~URE_U2P3_ENABLE; + ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); + + memset(u1u2, 0x00, sizeof(u1u2)); + ure_write_mem(sc, URE_USB_TOLERANCE, + URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); + + /* Disable ALDPS. */ + ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) & ~URE_EN_ALDPS); + uether_pause(&sc->sc_ue, hz / 50); + + ure_init_fifo(sc); + + /* Disable Rx aggregation. */ + ure_write_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB, + ure_read_2(sc, URE_USB_USB_CTRL, URE_MCU_TYPE_USB) | + URE_RX_AGG_DISABLE); + + val = ure_read_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB); + if (!(sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10))) + val |= URE_U2P3_ENABLE; + else + val &= ~URE_U2P3_ENABLE; + ure_write_2(sc, URE_USB_U2P3_CTRL, URE_MCU_TYPE_USB, val); + + memset(u1u2, 0xff, sizeof(u1u2)); + ure_write_mem(sc, URE_USB_TOLERANCE, + URE_MCU_TYPE_USB | URE_BYTE_EN_SIX_BYTES, u1u2, sizeof(u1u2)); +} + static void ure_stop(struct usb_ether *ue) { @@ -1011,6 +1161,43 @@ ure_init_fifo(struct ure_softc *sc) ure_read_4(sc, URE_PLA_RCR, URE_MCU_TYPE_PLA) & ~URE_RCR_ACPT_ALL); + if (!(sc->sc_flags & URE_FLAG_8152)) { + if (sc->sc_chip & (URE_CHIP_VER_5C00 | URE_CHIP_VER_5C10 | + URE_CHIP_VER_5C20)) { + ure_ocp_reg_write(sc, URE_OCP_ADC_CFG, + URE_CKADSEL_L | URE_ADC_EN | URE_EN_EMI_L); + } + if (sc->sc_chip & URE_CHIP_VER_5C00) { + ure_ocp_reg_write(sc, URE_OCP_EEE_CFG, + ure_ocp_reg_read(sc, URE_OCP_EEE_CFG) & + ~URE_CTAP_SHORT_EN); + } + ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | + URE_EEE_CLKDIV_EN); + ure_ocp_reg_write(sc, URE_OCP_DOWN_SPEED, + ure_ocp_reg_read(sc, URE_OCP_DOWN_SPEED) | + URE_EN_10M_BGOFF); + ure_ocp_reg_write(sc, URE_OCP_POWER_CFG, + ure_ocp_reg_read(sc, URE_OCP_POWER_CFG) | + URE_EN_10M_PLLOFF); + ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_IMPEDANCE); + ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0b13); + ure_write_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA, + ure_read_2(sc, URE_PLA_PHY_PWR, URE_MCU_TYPE_PLA) | + URE_PFM_PWM_SWITCH); + + /* Enable LPF corner auto tune. */ + ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_LPF_CFG); + ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0xf70f); + + /* Adjust 10M amplitude. */ + ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP1); + ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x00af); + ure_ocp_reg_write(sc, URE_OCP_SRAM_ADDR, URE_SRAM_10M_AMP2); + ure_ocp_reg_write(sc, URE_OCP_SRAM_DATA, 0x0208); + } + ure_reset(sc); ure_write_1(sc, URE_PLA_CR, URE_MCU_TYPE_PLA, 0); diff --git a/sys/dev/usb/net/if_urereg.h b/sys/dev/usb/net/if_urereg.h index 89c34f5a64ca..8eff1c25db4f 100644 --- a/sys/dev/usb/net/if_urereg.h +++ b/sys/dev/usb/net/if_urereg.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2015 Kevin Lo + * Copyright (c) 2015-2016 Kevin Lo * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -86,7 +86,7 @@ #define URE_PLA_OCP_GPHY_BASE 0xe86c #define URE_PLA_TELLYCNT 0xe890 #define URE_PLA_SFF_STS_7 0xe8de -#define URE_PLA_PHYSTATUS 0xe908 +#define URE_GMEDIASTAT 0xe908 #define URE_USB_USB2PHY 0xb41e #define URE_USB_SSPHYLINK2 0xb428 @@ -424,10 +424,15 @@ struct ure_softc { u_int sc_flags; #define URE_FLAG_LINK 0x0001 +#define URE_FLAG_8152 0x1000 /* RTL8152 */ u_int sc_chip; #define URE_CHIP_VER_4C00 0x01 #define URE_CHIP_VER_4C10 0x02 +#define URE_CHIP_VER_5C00 0x04 +#define URE_CHIP_VER_5C10 0x08 +#define URE_CHIP_VER_5C20 0x10 +#define URE_CHIP_VER_5C30 0x20 }; #define URE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) From 0362dbbd683bdb6a18828784371f1693fd2018e3 Mon Sep 17 00:00:00 2001 From: Andrew Turner Date: Mon, 31 Oct 2016 11:13:36 +0000 Subject: [PATCH 221/235] On arm64 build the efi loader with -fPIC. Without this clang 3.9 will generate relocation in the self relocation code. MFC after: 1 week Sponsored by: ABT Systems Ltd --- sys/boot/efi/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/boot/efi/Makefile.inc b/sys/boot/efi/Makefile.inc index 9d457f4a1055..671033c58e80 100644 --- a/sys/boot/efi/Makefile.inc +++ b/sys/boot/efi/Makefile.inc @@ -20,6 +20,7 @@ CFLAGS+= -mno-aes .if ${MACHINE_CPUARCH} == "aarch64" CFLAGS+= -fshort-wchar +CFLAGS+= -fPIC .endif .include "../Makefile.inc" From 69804fa204098f46f728b66ed7e34075b930d761 Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Mon, 31 Oct 2016 11:30:01 +0000 Subject: [PATCH 222/235] In loader.efi, instead of exiting directly, try to fallback on the first EFI device if we can't find the one from which the image was loaded. Reviewed by: allanjude,imp,jhb MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D6780 --- sys/boot/efi/loader/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/boot/efi/loader/main.c b/sys/boot/efi/loader/main.c index c6f30a9e4229..8bc85d077d3e 100644 --- a/sys/boot/efi/loader/main.c +++ b/sys/boot/efi/loader/main.c @@ -237,6 +237,11 @@ find_currdev(EFI_LOADED_IMAGE *img, struct devsw **dev, int *unit, } } + /* Try to fallback on first device */ + if (devsw[0] != NULL) { + *dev = devsw[0]; + return (0); + } return (ENOENT); } From b2fd6999db269fd54228068dd0a719f86c4e002d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Mon, 31 Oct 2016 11:31:11 +0000 Subject: [PATCH 223/235] xen/netfront: fix statistics Fix the statistics used by netfront. Reported by: Trond.Endrestol@ximalas.info Submitted by: ae Reviewed by: royger, Wei Liu MFC after: 4 weeks PR: 213439 --- sys/dev/xen/netfront/netfront.c | 38 ++++++--------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index a68bc9675da5..3c080ef817f7 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -156,21 +156,6 @@ static int xn_get_responses(struct netfront_rxq *, #define virt_to_mfn(x) (vtophys(x) >> PAGE_SHIFT) #define INVALID_P2M_ENTRY (~0UL) - -struct xn_rx_stats -{ - u_long rx_packets; /* total packets received */ - u_long rx_bytes; /* total bytes received */ - u_long rx_errors; /* bad packets received */ -}; - -struct xn_tx_stats -{ - u_long tx_packets; /* total packets transmitted */ - u_long tx_bytes; /* total bytes transmitted */ - u_long tx_errors; /* packet transmit problems */ -}; - #define XN_QUEUE_NAME_LEN 8 /* xn{t,r}x_%u, allow for two digits */ struct netfront_rxq { struct netfront_info *info; @@ -190,8 +175,6 @@ struct netfront_rxq { struct lro_ctrl lro; struct callout rx_refill; - - struct xn_rx_stats stats; }; struct netfront_txq { @@ -215,8 +198,6 @@ struct netfront_txq { struct task defrtask; bool full; - - struct xn_tx_stats stats; }; struct netfront_info { @@ -1191,7 +1172,7 @@ xn_rxeof(struct netfront_rxq *rxq) if (__predict_false(err)) { if (m) (void )mbufq_enqueue(&mbufq_errq, m); - rxq->stats.rx_errors++; + if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1); continue; } @@ -1216,9 +1197,6 @@ xn_rxeof(struct netfront_rxq *rxq) m->m_pkthdr.csum_flags |= CSUM_TSO; } - rxq->stats.rx_packets++; - rxq->stats.rx_bytes += m->m_pkthdr.len; - (void )mbufq_enqueue(&mbufq_rxq, m); rxq->ring.rsp_cons = i; } @@ -1304,12 +1282,6 @@ xn_txeof(struct netfront_txq *txq) "trying to free it again!")); M_ASSERTVALID(m); - /* - * Increment packet count if this is the last - * mbuf of the chain. - */ - if (!m->m_next) - if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); if (__predict_false(gnttab_query_foreign_access( txq->grant_ref[id]) != 0)) { panic("%s: grant id %u still in use by the " @@ -1701,10 +1673,12 @@ xn_assemble_tx_request(struct netfront_txq *txq, struct mbuf *m_head) } BPF_MTAP(ifp, m_head); - xn_txeof(txq); + if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); + if_inc_counter(ifp, IFCOUNTER_OBYTES, m_head->m_pkthdr.len); + if (m_head->m_flags & M_MCAST) + if_inc_counter(ifp, IFCOUNTER_OMCASTS, 1); - txq->stats.tx_bytes += m_head->m_pkthdr.len; - txq->stats.tx_packets++; + xn_txeof(txq); return (0); } From 0f4d7d9fd78bd396c1c768bdcc2a298991115433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Mon, 31 Oct 2016 13:00:53 +0000 Subject: [PATCH 224/235] xen/intr: add reference counts to event channels Add a reference count to xenisrc. This is required for implementation of unmap-notifications in the grant table userspace device (gntdev). We need to hold a reference to the event channel port, in case the user deallocates the port before we send the notification. Submitted by: jaggi Reviewed by: royger Differential review: https://reviews.freebsd.org/D7429 --- sys/x86/xen/xen_intr.c | 41 +++++++++++++++++++++++++++++++++++++---- sys/xen/xen_intr.h | 12 ++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/sys/x86/xen/xen_intr.c b/sys/x86/xen/xen_intr.c index 13ada84a2b34..66870b4c37f2 100644 --- a/sys/x86/xen/xen_intr.c +++ b/sys/x86/xen/xen_intr.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -128,6 +129,7 @@ struct xenisrc { u_int xi_activehi:1; u_int xi_edgetrigger:1; u_int xi_masked:1; + volatile u_int xi_refcount; }; static void xen_intr_suspend(struct pic *); @@ -343,10 +345,8 @@ xen_intr_release_isrc(struct xenisrc *isrc) { mtx_lock(&xen_intr_isrc_lock); - if (isrc->xi_intsrc.is_handlers != 0) { - mtx_unlock(&xen_intr_isrc_lock); - return (EBUSY); - } + KASSERT(isrc->xi_intsrc.is_handlers == 0, + ("Release called, but xenisrc still in use")); evtchn_mask_port(isrc->xi_port); evtchn_clear_port(isrc->xi_port); @@ -417,6 +417,7 @@ xen_intr_bind_isrc(struct xenisrc **isrcp, evtchn_port_t local_port, } isrc->xi_port = local_port; xen_intr_port_to_isrc[local_port] = isrc; + refcount_init(&isrc->xi_refcount, 1); mtx_unlock(&xen_intr_isrc_lock); /* Assign the opaque handler (the event channel port) */ @@ -1508,6 +1509,13 @@ xen_intr_unbind(xen_intr_handle_t *port_handlep) if (isrc == NULL) return; + mtx_lock(&xen_intr_isrc_lock); + if (refcount_release(&isrc->xi_refcount) == 0) { + mtx_unlock(&xen_intr_isrc_lock); + return; + } + mtx_unlock(&xen_intr_isrc_lock); + if (isrc->xi_cookie != NULL) intr_remove_handler(isrc->xi_cookie); xen_intr_release_isrc(isrc); @@ -1563,6 +1571,31 @@ xen_intr_add_handler(device_t dev, driver_filter_t filter, return (error); } +int +xen_intr_get_evtchn_from_port(evtchn_port_t port, xen_intr_handle_t *handlep) +{ + + if (!is_valid_evtchn(port) || port >= NR_EVENT_CHANNELS) + return (EINVAL); + + if (handlep == NULL) { + return (EINVAL); + } + + mtx_lock(&xen_intr_isrc_lock); + if (xen_intr_port_to_isrc[port] == NULL) { + mtx_unlock(&xen_intr_isrc_lock); + return (EINVAL); + } + refcount_acquire(&xen_intr_port_to_isrc[port]->xi_refcount); + mtx_unlock(&xen_intr_isrc_lock); + + /* Assign the opaque handler (the event channel port) */ + *handlep = &xen_intr_port_to_isrc[port]->xi_vector; + + return (0); +} + #ifdef DDB static const char * xen_intr_print_type(enum evtchn_type type) diff --git a/sys/xen/xen_intr.h b/sys/xen/xen_intr.h index 5b2f60804eac..fc419d65ef0e 100644 --- a/sys/xen/xen_intr.h +++ b/sys/xen/xen_intr.h @@ -263,4 +263,16 @@ int xen_intr_add_handler(device_t dev, driver_filter_t filter, driver_intr_t handler, void *arg, enum intr_type flags, xen_intr_handle_t handle); +/** + * Get a reference to an event channel port + * + * \param port Event channel port to which we get a reference. + * \param handlep Pointer to an opaque handle used to manage this + * registration. + * + * \returns 0 on success, otherwise an errno. + */ +int xen_intr_get_evtchn_from_port(evtchn_port_t port, + xen_intr_handle_t *handlep); + #endif /* _XEN_INTR_H_ */ From 78eb32933bb31254ca8d28f8597702ea4deb3e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= Date: Mon, 31 Oct 2016 13:12:58 +0000 Subject: [PATCH 225/235] xen: add a grant-table user-space device A grant-table user-space device will allow user-space applications to map and share grants (Xen way to share memory) among Xen domains. This grant table user-space device has been tested with the QEMU Qdisk Xen backed. Submitted by: jaggi Reviewed by: royger Differential review: https://reviews.freebsd.org/D7293 --- sys/conf/files | 1 + sys/dev/xen/gntdev/gntdev.c | 1275 +++++++++++++++++++++++++++++++++++ sys/xen/gntdev.h | 192 ++++++ 3 files changed, 1468 insertions(+) create mode 100644 sys/dev/xen/gntdev/gntdev.c create mode 100644 sys/xen/gntdev.h diff --git a/sys/conf/files b/sys/conf/files index 5dbd0cf19945..a154b803bb65 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -3183,6 +3183,7 @@ dev/xen/xenstore/xenstore_dev.c optional xenhvm dev/xen/xenstore/xenstored_dev.c optional xenhvm dev/xen/evtchn/evtchn_dev.c optional xenhvm dev/xen/privcmd/privcmd.c optional xenhvm +dev/xen/gntdev/gntdev.c optional xenhvm dev/xen/debug/debug.c optional xenhvm dev/xl/if_xl.c optional xl pci dev/xl/xlphy.c optional xl pci diff --git a/sys/dev/xen/gntdev/gntdev.c b/sys/dev/xen/gntdev/gntdev.c new file mode 100644 index 000000000000..467a0c05df85 --- /dev/null +++ b/sys/dev/xen/gntdev/gntdev.c @@ -0,0 +1,1275 @@ +/*- + * Copyright (c) 2016 Akshay Jaggi + * 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. + * + * gntdev.c + * + * Interface to /dev/xen/gntdev. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +MALLOC_DEFINE(M_GNTDEV, "gntdev", "Xen grant-table user-space device"); + +#define MAX_OFFSET_COUNT ((0xffffffffffffffffull >> PAGE_SHIFT) + 1) + +static d_open_t gntdev_open; +static d_ioctl_t gntdev_ioctl; +static d_mmap_single_t gntdev_mmap_single; + +static struct cdevsw gntdev_devsw = { + .d_version = D_VERSION, + .d_open = gntdev_open, + .d_ioctl = gntdev_ioctl, + .d_mmap_single = gntdev_mmap_single, + .d_name = "gntdev", +}; + +static device_t gntdev_dev = NULL; + +struct gntdev_gref; +struct gntdev_gmap; +STAILQ_HEAD(gref_list_head, gntdev_gref); +STAILQ_HEAD(gmap_list_head, gntdev_gmap); +RB_HEAD(gref_tree_head, gntdev_gref); +RB_HEAD(gmap_tree_head, gntdev_gmap); + +struct file_offset_struct { + RB_ENTRY(file_offset_struct) next; + uint64_t file_offset; + uint64_t count; +}; + +static int +offset_cmp(struct file_offset_struct *f1, struct file_offset_struct *f2) +{ + return (f1->file_offset - f2->file_offset); +} + +RB_HEAD(file_offset_head, file_offset_struct); +RB_GENERATE_STATIC(file_offset_head, file_offset_struct, next, offset_cmp); + +struct per_user_data { + struct mtx user_data_lock; + struct gref_tree_head gref_tree; + struct gmap_tree_head gmap_tree; + struct file_offset_head file_offset; +}; + +/* + * Get offset into the file which will be used while mmapping the + * appropriate pages by the userspace program. + */ +static int +get_file_offset(struct per_user_data *priv_user, uint32_t count, + uint64_t *file_offset) +{ + struct file_offset_struct *offset, *offset_tmp; + + if (count == 0) + return (EINVAL); + mtx_lock(&priv_user->user_data_lock); + RB_FOREACH_SAFE(offset, file_offset_head, &priv_user->file_offset, + offset_tmp) { + if (offset->count >= count) { + offset->count -= count; + *file_offset = offset->file_offset + offset->count * + PAGE_SIZE; + if (offset->count == 0) { + RB_REMOVE(file_offset_head, + &priv_user->file_offset, offset); + free(offset, M_GNTDEV); + } + mtx_unlock(&priv_user->user_data_lock); + return (0); + } + } + mtx_unlock(&priv_user->user_data_lock); + + return (ENOSPC); +} + +static void +put_file_offset(struct per_user_data *priv_user, uint32_t count, + uint64_t file_offset) +{ + struct file_offset_struct *offset, *offset_nxt, *offset_prv; + + offset = malloc(sizeof(*offset), M_GNTDEV, M_WAITOK | M_ZERO); + offset->file_offset = file_offset; + offset->count = count; + + mtx_lock(&priv_user->user_data_lock); + RB_INSERT(file_offset_head, &priv_user->file_offset, offset); + offset_nxt = RB_NEXT(file_offset_head, &priv_user->file_offset, offset); + offset_prv = RB_PREV(file_offset_head, &priv_user->file_offset, offset); + if (offset_nxt != NULL && + offset_nxt->file_offset == offset->file_offset + offset->count * + PAGE_SIZE) { + offset->count += offset_nxt->count; + RB_REMOVE(file_offset_head, &priv_user->file_offset, + offset_nxt); + free(offset_nxt, M_GNTDEV); + } + if (offset_prv != NULL && + offset->file_offset == offset_prv->file_offset + offset_prv->count * + PAGE_SIZE) { + offset_prv->count += offset->count; + RB_REMOVE(file_offset_head, &priv_user->file_offset, offset); + free(offset, M_GNTDEV); + } + mtx_unlock(&priv_user->user_data_lock); +} + +static int gntdev_gmap_pg_ctor(void *handle, vm_ooffset_t size, + vm_prot_t prot, vm_ooffset_t foff, struct ucred *cred, u_short *color); +static void gntdev_gmap_pg_dtor(void *handle); +static int gntdev_gmap_pg_fault(vm_object_t object, vm_ooffset_t offset, + int prot, vm_page_t *mres); + +static struct cdev_pager_ops gntdev_gmap_pg_ops = { + .cdev_pg_fault = gntdev_gmap_pg_fault, + .cdev_pg_ctor = gntdev_gmap_pg_ctor, + .cdev_pg_dtor = gntdev_gmap_pg_dtor, +}; + +struct cleanup_data_struct { + struct mtx to_kill_grefs_mtx; + struct mtx to_kill_gmaps_mtx; + struct gref_list_head to_kill_grefs; + struct gmap_list_head to_kill_gmaps; +}; + +static struct cleanup_data_struct cleanup_data = { + .to_kill_grefs = STAILQ_HEAD_INITIALIZER(cleanup_data.to_kill_grefs), + .to_kill_gmaps = STAILQ_HEAD_INITIALIZER(cleanup_data.to_kill_gmaps), +}; +MTX_SYSINIT(to_kill_grefs_mtx, &cleanup_data.to_kill_grefs_mtx, + "gntdev to_kill_grefs mutex", MTX_DEF); +MTX_SYSINIT(to_kill_gmaps_mtx, &cleanup_data.to_kill_gmaps_mtx, + "gntdev to_kill_gmaps mutex", MTX_DEF); + +static void cleanup_function(void *arg, __unused int pending); +static struct task cleanup_task = TASK_INITIALIZER(0, cleanup_function, + &cleanup_data); + +struct notify_data { + uint64_t index; + uint32_t action; + uint32_t event_channel_port; + xen_intr_handle_t notify_evtchn_handle; +}; + +static void notify(struct notify_data *notify, vm_page_t page); + +/*-------------------- Grant Allocation Methods -----------------------------*/ + +struct gntdev_gref { + union gref_next_union { + STAILQ_ENTRY(gntdev_gref) list; + RB_ENTRY(gntdev_gref) tree; + } gref_next; + uint64_t file_index; + grant_ref_t gref_id; + vm_page_t page; + struct notify_data *notify; +}; + +static int +gref_cmp(struct gntdev_gref *g1, struct gntdev_gref *g2) +{ + return (g1->file_index - g2->file_index); +} + +RB_GENERATE_STATIC(gref_tree_head, gntdev_gref, gref_next.tree, gref_cmp); + +/* + * Traverse over the device-list of to-be-deleted grants allocated, and + * if all accesses, both local mmaps and foreign maps, to them have ended, + * destroy them. + */ +static void +gref_list_dtor(struct cleanup_data_struct *cleanup_data) +{ + struct gref_list_head tmp_grefs; + struct gntdev_gref *gref, *gref_tmp, *gref_previous; + + STAILQ_INIT(&tmp_grefs); + mtx_lock(&cleanup_data->to_kill_grefs_mtx); + STAILQ_SWAP(&cleanup_data->to_kill_grefs, &tmp_grefs, gntdev_gref); + mtx_unlock(&cleanup_data->to_kill_grefs_mtx); + + gref_previous = NULL; + STAILQ_FOREACH_SAFE(gref, &tmp_grefs, gref_next.list, gref_tmp) { + if (gref->page && gref->page->object == NULL) { + if (gref->notify) { + notify(gref->notify, gref->page); + } + if (gref->gref_id != GRANT_REF_INVALID) { + if (gnttab_query_foreign_access(gref->gref_id)) + continue; + if (gnttab_end_foreign_access_ref(gref->gref_id) + == 0) + continue; + gnttab_free_grant_reference(gref->gref_id); + } + vm_page_unwire(gref->page, PQ_NONE); + vm_page_free(gref->page); + gref->page = NULL; + } + if (gref->page == NULL) { + if (gref_previous == NULL) + STAILQ_REMOVE_HEAD(&tmp_grefs, gref_next.list); + else + STAILQ_REMOVE_AFTER(&tmp_grefs, gref_previous, + gref_next.list); + if (gref->notify) + free(gref->notify, M_GNTDEV); + free(gref, M_GNTDEV); + } + else + gref_previous = gref; + } + + if (!STAILQ_EMPTY(&tmp_grefs)) { + mtx_lock(&cleanup_data->to_kill_grefs_mtx); + STAILQ_CONCAT(&cleanup_data->to_kill_grefs, &tmp_grefs); + mtx_unlock(&cleanup_data->to_kill_grefs_mtx); + } +} + +/* + * Find count number of contiguous allocated grants for a given userspace + * program by file-offset (index). + */ +static struct gntdev_gref* +gntdev_find_grefs(struct per_user_data *priv_user, + uint64_t index, uint32_t count) +{ + struct gntdev_gref find_gref, *gref, *gref_start = NULL; + + find_gref.file_index = index; + + mtx_lock(&priv_user->user_data_lock); + gref_start = RB_FIND(gref_tree_head, &priv_user->gref_tree, &find_gref); + for (gref = gref_start; gref != NULL && count > 0; gref = + RB_NEXT(gref_tree_head, &priv_user->gref_tree, gref)) { + if (index != gref->file_index) + break; + index += PAGE_SIZE; + count--; + } + mtx_unlock(&priv_user->user_data_lock); + + if (count) + return (NULL); + return (gref_start); +} + +/* + * IOCTL_GNTDEV_ALLOC_GREF + * Allocate required number of wired pages for the request, grant foreign + * access to the physical frames for these pages, and add details about + * this allocation to the per user private data, so that these pages can + * be mmapped by the userspace program. + */ +static int +gntdev_alloc_gref(struct ioctl_gntdev_alloc_gref *arg) +{ + uint32_t i; + int error, readonly; + uint64_t file_offset; + struct gntdev_gref *grefs; + struct per_user_data *priv_user; + + readonly = !(arg->flags & GNTDEV_ALLOC_FLAG_WRITABLE); + + error = devfs_get_cdevpriv((void**) &priv_user); + if (error != 0) + return (EINVAL); + + /* Cleanup grefs and free pages. */ + taskqueue_enqueue(taskqueue_thread, &cleanup_task); + + /* Get file offset for this request. */ + error = get_file_offset(priv_user, arg->count, &file_offset); + if (error != 0) + return (error); + + /* Allocate grefs. */ + grefs = malloc(sizeof(*grefs) * arg->count, M_GNTDEV, M_WAITOK); + + for (i = 0; i < arg->count; i++) { + grefs[i].file_index = file_offset + i * PAGE_SIZE; + grefs[i].gref_id = GRANT_REF_INVALID; + grefs[i].notify = NULL; + grefs[i].page = vm_page_alloc(NULL, 0, VM_ALLOC_NORMAL + | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED | VM_ALLOC_ZERO); + if (grefs[i].page == NULL) { + log(LOG_ERR, "Page allocation failed."); + error = ENOMEM; + break; + } + if ((grefs[i].page->flags & PG_ZERO) == 0) { + /* + * Zero the allocated page, as we don't want to + * leak our memory to other domains. + */ + pmap_zero_page(grefs[i].page); + } + grefs[i].page->valid = VM_PAGE_BITS_ALL; + + error = gnttab_grant_foreign_access(arg->domid, + (VM_PAGE_TO_PHYS(grefs[i].page) >> PAGE_SHIFT), + readonly, &grefs[i].gref_id); + if (error != 0) { + log(LOG_ERR, "Grant Table Hypercall failed."); + break; + } + } + + if (error != 0) { + /* + * If target domain maps the gref (by guessing the gref-id), + * then we can't clean it up yet and we have to leave the + * page in place so as to not leak our memory to that domain. + * Add it to a global list to be cleaned up later. + */ + mtx_lock(&cleanup_data.to_kill_grefs_mtx); + for (i = 0; i < arg->count; i++) + STAILQ_INSERT_TAIL(&cleanup_data.to_kill_grefs, + &grefs[i], gref_next.list); + mtx_unlock(&cleanup_data.to_kill_grefs_mtx); + + taskqueue_enqueue(taskqueue_thread, &cleanup_task); + + return (error); + } + + /* Copy the output values. */ + arg->index = file_offset; + for (i = 0; i < arg->count; i++) + arg->gref_ids[i] = grefs[i].gref_id; + + /* Modify the per user private data. */ + mtx_lock(&priv_user->user_data_lock); + for (i = 0; i < arg->count; i++) + RB_INSERT(gref_tree_head, &priv_user->gref_tree, &grefs[i]); + mtx_unlock(&priv_user->user_data_lock); + + return (error); +} + +/* + * IOCTL_GNTDEV_DEALLOC_GREF + * Remove grant allocation information from the per user private data, so + * that it can't be mmapped anymore by the userspace program, and add it + * to the to-be-deleted grants global device-list. + */ +static int +gntdev_dealloc_gref(struct ioctl_gntdev_dealloc_gref *arg) +{ + int error; + uint32_t count; + struct gntdev_gref *gref, *gref_tmp; + struct per_user_data *priv_user; + + error = devfs_get_cdevpriv((void**) &priv_user); + if (error != 0) + return (EINVAL); + + gref = gntdev_find_grefs(priv_user, arg->index, arg->count); + if (gref == NULL) { + log(LOG_ERR, "Can't find requested grant-refs."); + return (EINVAL); + } + + /* Remove the grefs from user private data. */ + count = arg->count; + mtx_lock(&priv_user->user_data_lock); + mtx_lock(&cleanup_data.to_kill_grefs_mtx); + for (; gref != NULL && count > 0; gref = gref_tmp) { + gref_tmp = RB_NEXT(gref_tree_head, &priv_user->gref_tree, gref); + RB_REMOVE(gref_tree_head, &priv_user->gref_tree, gref); + STAILQ_INSERT_TAIL(&cleanup_data.to_kill_grefs, gref, + gref_next.list); + count--; + } + mtx_unlock(&cleanup_data.to_kill_grefs_mtx); + mtx_unlock(&priv_user->user_data_lock); + + taskqueue_enqueue(taskqueue_thread, &cleanup_task); + put_file_offset(priv_user, arg->count, arg->index); + + return (0); +} + +/*-------------------- Grant Mapping Methods --------------------------------*/ + +struct gntdev_gmap_map { + vm_object_t mem; + struct resource *pseudo_phys_res; + int pseudo_phys_res_id; + vm_paddr_t phys_base_addr; +}; + +struct gntdev_gmap { + union gmap_next_union { + STAILQ_ENTRY(gntdev_gmap) list; + RB_ENTRY(gntdev_gmap) tree; + } gmap_next; + uint64_t file_index; + uint32_t count; + struct gnttab_map_grant_ref *grant_map_ops; + struct gntdev_gmap_map *map; + struct notify_data *notify; +}; + +static int +gmap_cmp(struct gntdev_gmap *g1, struct gntdev_gmap *g2) +{ + return (g1->file_index - g2->file_index); +} + +RB_GENERATE_STATIC(gmap_tree_head, gntdev_gmap, gmap_next.tree, gmap_cmp); + +/* + * Traverse over the device-list of to-be-deleted grant mappings, and if + * the region is no longer mmapped by anyone, free the memory used to + * store information about the mapping. + */ +static void +gmap_list_dtor(struct cleanup_data_struct *cleanup_data) +{ + struct gmap_list_head tmp_gmaps; + struct gntdev_gmap *gmap, *gmap_tmp, *gmap_previous; + + STAILQ_INIT(&tmp_gmaps); + mtx_lock(&cleanup_data->to_kill_gmaps_mtx); + STAILQ_SWAP(&cleanup_data->to_kill_gmaps, &tmp_gmaps, gntdev_gmap); + mtx_unlock(&cleanup_data->to_kill_gmaps_mtx); + + gmap_previous = NULL; + STAILQ_FOREACH_SAFE(gmap, &tmp_gmaps, gmap_next.list, gmap_tmp) { + if (gmap->map == NULL) { + if (gmap_previous == NULL) + STAILQ_REMOVE_HEAD(&tmp_gmaps, gmap_next.list); + else + STAILQ_REMOVE_AFTER(&tmp_gmaps, gmap_previous, + gmap_next.list); + + if (gmap->notify) + free(gmap->notify, M_GNTDEV); + free(gmap->grant_map_ops, M_GNTDEV); + free(gmap, M_GNTDEV); + } + else + gmap_previous = gmap; + } + + if (!STAILQ_EMPTY(&tmp_gmaps)) { + mtx_lock(&cleanup_data->to_kill_gmaps_mtx); + STAILQ_CONCAT(&cleanup_data->to_kill_gmaps, &tmp_gmaps); + mtx_unlock(&cleanup_data->to_kill_gmaps_mtx); + } +} + +/* + * Find mapped grants for a given userspace program, by file-offset (index) + * and count, as supplied during the map-ioctl. + */ +static struct gntdev_gmap* +gntdev_find_gmap(struct per_user_data *priv_user, + uint64_t index, uint32_t count) +{ + struct gntdev_gmap find_gmap, *gmap; + + find_gmap.file_index = index; + + mtx_lock(&priv_user->user_data_lock); + gmap = RB_FIND(gmap_tree_head, &priv_user->gmap_tree, &find_gmap); + mtx_unlock(&priv_user->user_data_lock); + + if (gmap != NULL && gmap->count == count) + return (gmap); + return (NULL); +} + +/* + * Remove the pages from the mgtdevice pager, call the unmap hypercall, + * free the xenmem resource. This function is called during the + * destruction of the mgtdevice pager, which happens when all mmaps to + * it have been removed, and the unmap-ioctl has been performed. + */ +static int +notify_unmap_cleanup(struct gntdev_gmap *gmap) +{ + uint32_t i; + int error, count; + vm_page_t m; + struct gnttab_unmap_grant_ref *unmap_ops; + + unmap_ops = malloc(sizeof(struct gnttab_unmap_grant_ref) * gmap->count, + M_GNTDEV, M_WAITOK); + + /* Enumerate freeable maps. */ + count = 0; + for (i = 0; i < gmap->count; i++) { + if (gmap->grant_map_ops[i].handle != -1) { + unmap_ops[count].handle = gmap->grant_map_ops[i].handle; + unmap_ops[count].host_addr = + gmap->grant_map_ops[i].host_addr; + unmap_ops[count].dev_bus_addr = 0; + count++; + } + } + + /* Perform notification. */ + if (count > 0 && gmap->notify) { + vm_page_t page; + uint64_t page_offset; + + page_offset = gmap->notify->index - gmap->file_index; + page = PHYS_TO_VM_PAGE(gmap->map->phys_base_addr + page_offset); + notify(gmap->notify, page); + } + + /* Free the pages. */ + VM_OBJECT_WLOCK(gmap->map->mem); +retry: + for (i = 0; i < gmap->count; i++) { + m = vm_page_lookup(gmap->map->mem, i); + if (m == NULL) + continue; + if (vm_page_sleep_if_busy(m, "pcmdum")) + goto retry; + cdev_pager_free_page(gmap->map->mem, m); + } + VM_OBJECT_WUNLOCK(gmap->map->mem); + + /* Perform unmap hypercall. */ + error = HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, + unmap_ops, count); + + for (i = 0; i < gmap->count; i++) { + gmap->grant_map_ops[i].handle = -1; + gmap->grant_map_ops[i].host_addr = 0; + } + + if (gmap->map) { + error = xenmem_free(gntdev_dev, gmap->map->pseudo_phys_res_id, + gmap->map->pseudo_phys_res); + KASSERT(error == 0, + ("Unable to release memory resource: %d", error)); + + free(gmap->map, M_GNTDEV); + gmap->map = NULL; + } + + free(unmap_ops, M_GNTDEV); + + return (error); +} + +/* + * IOCTL_GNTDEV_MAP_GRANT_REF + * Populate structures for mapping the grant reference in the per user + * private data. Actual resource allocation and map hypercall is performed + * during the mmap. + */ +static int +gntdev_map_grant_ref(struct ioctl_gntdev_map_grant_ref *arg) +{ + uint32_t i; + int error; + struct gntdev_gmap *gmap; + struct per_user_data *priv_user; + + error = devfs_get_cdevpriv((void**) &priv_user); + if (error != 0) + return (EINVAL); + + gmap = malloc(sizeof(*gmap), M_GNTDEV, M_WAITOK | M_ZERO); + gmap->count = arg->count; + gmap->grant_map_ops = + malloc(sizeof(struct gnttab_map_grant_ref) * arg->count, + M_GNTDEV, M_WAITOK | M_ZERO); + + error = get_file_offset(priv_user, arg->count, &gmap->file_index); + if (error != 0) + return (error); + + for (i = 0; i < arg->count; i++) { + gmap->grant_map_ops[i].dom = arg->refs[i].domid; + gmap->grant_map_ops[i].ref = arg->refs[i].ref; + gmap->grant_map_ops[i].handle = -1; + gmap->grant_map_ops[i].flags = GNTMAP_host_map; + } + + mtx_lock(&priv_user->user_data_lock); + RB_INSERT(gmap_tree_head, &priv_user->gmap_tree, gmap); + mtx_unlock(&priv_user->user_data_lock); + + arg->index = gmap->file_index; + + return (error); +} + +/* + * IOCTL_GNTDEV_UNMAP_GRANT_REF + * Remove the map information from the per user private data and add it + * to the global device-list of mappings to be deleted. A reference to + * the mgtdevice pager is also decreased, the reason for which is + * explained in mmap_gmap(). + */ +static int +gntdev_unmap_grant_ref(struct ioctl_gntdev_unmap_grant_ref *arg) +{ + int error; + struct gntdev_gmap *gmap; + struct per_user_data *priv_user; + + error = devfs_get_cdevpriv((void**) &priv_user); + if (error != 0) + return (EINVAL); + + gmap = gntdev_find_gmap(priv_user, arg->index, arg->count); + if (gmap == NULL) { + log(LOG_ERR, "Can't find requested grant-map."); + return (EINVAL); + } + + mtx_lock(&priv_user->user_data_lock); + mtx_lock(&cleanup_data.to_kill_gmaps_mtx); + RB_REMOVE(gmap_tree_head, &priv_user->gmap_tree, gmap); + STAILQ_INSERT_TAIL(&cleanup_data.to_kill_gmaps, gmap, gmap_next.list); + mtx_unlock(&cleanup_data.to_kill_gmaps_mtx); + mtx_unlock(&priv_user->user_data_lock); + + if (gmap->map) + vm_object_deallocate(gmap->map->mem); + + taskqueue_enqueue(taskqueue_thread, &cleanup_task); + put_file_offset(priv_user, arg->count, arg->index); + + return (0); +} + +/* + * IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR + * Get file-offset and count for a given mapping, from the virtual address + * where the mapping is mmapped. + * Please note, this only works for grants mapped by this domain, and not + * grants allocated. Count doesn't make much sense in reference to grants + * allocated. Also, because this function is present in the linux gntdev + * device, but not in the linux gntalloc one, most userspace code only use + * it for mapped grants. + */ +static int +gntdev_get_offset_for_vaddr(struct ioctl_gntdev_get_offset_for_vaddr *arg, + struct thread *td) +{ + int error; + vm_map_t map; + vm_map_entry_t entry; + vm_object_t mem; + vm_pindex_t pindex; + vm_prot_t prot; + boolean_t wired; + struct gntdev_gmap *gmap; + + map = &td->td_proc->p_vmspace->vm_map; + error = vm_map_lookup(&map, arg->vaddr, VM_PROT_NONE, &entry, + &mem, &pindex, &prot, &wired); + if (error != KERN_SUCCESS) + return (EINVAL); + vm_map_lookup_done(map, entry); + + if ((mem->type != OBJT_MGTDEVICE) || + (mem->un_pager.devp.ops != &gntdev_gmap_pg_ops)) + return (EINVAL); + + gmap = mem->handle; + if (gmap == NULL || + (entry->end - entry->start) != (gmap->count * PAGE_SIZE)) + return (EINVAL); + + arg->count = gmap->count; + arg->offset = gmap->file_index; + return (0); +} + +/*-------------------- Grant Mapping Pager ----------------------------------*/ + +static int +gntdev_gmap_pg_ctor(void *handle, vm_ooffset_t size, vm_prot_t prot, + vm_ooffset_t foff, struct ucred *cred, u_short *color) +{ + + return (0); +} + +static void +gntdev_gmap_pg_dtor(void *handle) +{ + + notify_unmap_cleanup((struct gntdev_gmap *)handle); +} + +static int +gntdev_gmap_pg_fault(vm_object_t object, vm_ooffset_t offset, int prot, + vm_page_t *mres) +{ + struct gntdev_gmap *gmap = object->handle; + vm_pindex_t pidx, ridx; + vm_page_t page, oldm; + vm_ooffset_t relative_offset; + + if (gmap->map == NULL) + return (VM_PAGER_FAIL); + + relative_offset = offset - gmap->file_index; + + pidx = OFF_TO_IDX(offset); + ridx = OFF_TO_IDX(relative_offset); + if (ridx >= gmap->count || + gmap->grant_map_ops[ridx].status != GNTST_okay) + return (VM_PAGER_FAIL); + + page = PHYS_TO_VM_PAGE(gmap->map->phys_base_addr + relative_offset); + if (page == NULL) + return (VM_PAGER_FAIL); + + KASSERT((page->flags & PG_FICTITIOUS) != 0, + ("not fictitious %p", page)); + KASSERT(page->wire_count == 1, ("wire_count not 1 %p", page)); + KASSERT(vm_page_busied(page) == 0, ("page %p is busy", page)); + + if (*mres != NULL) { + oldm = *mres; + vm_page_lock(oldm); + vm_page_free(oldm); + vm_page_unlock(oldm); + *mres = NULL; + } + + vm_page_insert(page, object, pidx); + page->valid = VM_PAGE_BITS_ALL; + vm_page_xbusy(page); + *mres = page; + return (VM_PAGER_OK); +} + +/*------------------ Grant Table Methods ------------------------------------*/ + +static void +notify(struct notify_data *notify, vm_page_t page) +{ + if (notify->action & UNMAP_NOTIFY_CLEAR_BYTE) { + uint8_t *mem; + uint64_t offset; + + offset = notify->index & PAGE_MASK; + mem = (uint8_t *)pmap_quick_enter_page(page); + mem[offset] = 0; + pmap_quick_remove_page((vm_offset_t)mem); + } + if (notify->action & UNMAP_NOTIFY_SEND_EVENT) { + xen_intr_signal(notify->notify_evtchn_handle); + xen_intr_unbind(¬ify->notify_evtchn_handle); + } + notify->action = 0; +} + +/* + * Helper to copy new arguments from the notify ioctl into + * the existing notify data. + */ +static int +copy_notify_helper(struct notify_data *destination, + struct ioctl_gntdev_unmap_notify *source) +{ + xen_intr_handle_t handlep = NULL; + + /* + * "Get" before "Put"ting previous reference, as we might be + * holding the last reference to the event channel port. + */ + if (source->action & UNMAP_NOTIFY_SEND_EVENT) + if (xen_intr_get_evtchn_from_port(source->event_channel_port, + &handlep) != 0) + return (EINVAL); + + if (destination->action & UNMAP_NOTIFY_SEND_EVENT) + xen_intr_unbind(&destination->notify_evtchn_handle); + + destination->action = source->action; + destination->event_channel_port = source->event_channel_port; + destination->index = source->index; + destination->notify_evtchn_handle = handlep; + + return (0); +} + +/* + * IOCTL_GNTDEV_SET_UNMAP_NOTIFY + * Set unmap notification inside the appropriate grant. It sends a + * notification when the grant is completely munmapped by this domain + * and ready for destruction. + */ +static int +gntdev_set_unmap_notify(struct ioctl_gntdev_unmap_notify *arg) +{ + int error; + uint64_t index; + struct per_user_data *priv_user; + struct gntdev_gref *gref = NULL; + struct gntdev_gmap *gmap; + + error = devfs_get_cdevpriv((void**) &priv_user); + if (error != 0) + return (EINVAL); + + if (arg->action & ~(UNMAP_NOTIFY_CLEAR_BYTE|UNMAP_NOTIFY_SEND_EVENT)) + return (EINVAL); + + index = arg->index & ~PAGE_MASK; + gref = gntdev_find_grefs(priv_user, index, 1); + if (gref) { + if (gref->notify == NULL) + gref->notify = malloc(sizeof(*arg), M_GNTDEV, + M_WAITOK | M_ZERO); + return (copy_notify_helper(gref->notify, arg)); + } + + error = EINVAL; + mtx_lock(&priv_user->user_data_lock); + RB_FOREACH(gmap, gmap_tree_head, &priv_user->gmap_tree) { + if (arg->index >= gmap->file_index && + arg->index < gmap->file_index + gmap->count * PAGE_SIZE) { + if (gmap->notify == NULL) + gmap->notify = malloc(sizeof(*arg), M_GNTDEV, + M_WAITOK | M_ZERO); + error = copy_notify_helper(gmap->notify, arg); + break; + } + } + mtx_unlock(&priv_user->user_data_lock); + + return (error); +} + +/*------------------ Gntdev Char Device Methods -----------------------------*/ + +static void +cleanup_function(void *arg, __unused int pending) +{ + + gref_list_dtor((struct cleanup_data_struct *) arg); + gmap_list_dtor((struct cleanup_data_struct *) arg); +} + +static void +per_user_data_dtor(void *arg) +{ + struct gntdev_gref *gref, *gref_tmp; + struct gntdev_gmap *gmap, *gmap_tmp; + struct file_offset_struct *offset, *offset_tmp; + struct per_user_data *priv_user; + + priv_user = (struct per_user_data *) arg; + + mtx_lock(&priv_user->user_data_lock); + + mtx_lock(&cleanup_data.to_kill_grefs_mtx); + RB_FOREACH_SAFE(gref, gref_tree_head, &priv_user->gref_tree, gref_tmp) { + RB_REMOVE(gref_tree_head, &priv_user->gref_tree, gref); + STAILQ_INSERT_TAIL(&cleanup_data.to_kill_grefs, gref, + gref_next.list); + } + mtx_unlock(&cleanup_data.to_kill_grefs_mtx); + + mtx_lock(&cleanup_data.to_kill_gmaps_mtx); + RB_FOREACH_SAFE(gmap, gmap_tree_head, &priv_user->gmap_tree, gmap_tmp) { + RB_REMOVE(gmap_tree_head, &priv_user->gmap_tree, gmap); + STAILQ_INSERT_TAIL(&cleanup_data.to_kill_gmaps, gmap, + gmap_next.list); + if (gmap->map) + vm_object_deallocate(gmap->map->mem); + } + mtx_unlock(&cleanup_data.to_kill_gmaps_mtx); + + RB_FOREACH_SAFE(offset, file_offset_head, &priv_user->file_offset, + offset_tmp) { + RB_REMOVE(file_offset_head, &priv_user->file_offset, offset); + free(offset, M_GNTDEV); + } + + mtx_unlock(&priv_user->user_data_lock); + + taskqueue_enqueue(taskqueue_thread, &cleanup_task); + + mtx_destroy(&priv_user->user_data_lock); + free(priv_user, M_GNTDEV); +} + +static int +gntdev_open(struct cdev *dev, int flag, int otyp, struct thread *td) +{ + int error; + struct per_user_data *priv_user; + struct file_offset_struct *offset; + + priv_user = malloc(sizeof(*priv_user), M_GNTDEV, M_WAITOK | M_ZERO); + RB_INIT(&priv_user->gref_tree); + RB_INIT(&priv_user->gmap_tree); + RB_INIT(&priv_user->file_offset); + offset = malloc(sizeof(*offset), M_GNTDEV, M_WAITOK | M_ZERO); + offset->file_offset = 0; + offset->count = MAX_OFFSET_COUNT; + RB_INSERT(file_offset_head, &priv_user->file_offset, offset); + mtx_init(&priv_user->user_data_lock, + "per user data mutex", NULL, MTX_DEF); + + error = devfs_set_cdevpriv(priv_user, per_user_data_dtor); + if (error != 0) + per_user_data_dtor(priv_user); + + return (error); +} + +static int +gntdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, + int fflag, struct thread *td) +{ + int error; + + switch (cmd) { + case IOCTL_GNTDEV_SET_UNMAP_NOTIFY: + error = gntdev_set_unmap_notify( + (struct ioctl_gntdev_unmap_notify*) data); + break; + case IOCTL_GNTDEV_ALLOC_GREF: + error = gntdev_alloc_gref( + (struct ioctl_gntdev_alloc_gref*) data); + break; + case IOCTL_GNTDEV_DEALLOC_GREF: + error = gntdev_dealloc_gref( + (struct ioctl_gntdev_dealloc_gref*) data); + break; + case IOCTL_GNTDEV_MAP_GRANT_REF: + error = gntdev_map_grant_ref( + (struct ioctl_gntdev_map_grant_ref*) data); + break; + case IOCTL_GNTDEV_UNMAP_GRANT_REF: + error = gntdev_unmap_grant_ref( + (struct ioctl_gntdev_unmap_grant_ref*) data); + break; + case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR: + error = gntdev_get_offset_for_vaddr( + (struct ioctl_gntdev_get_offset_for_vaddr*) data, td); + break; + default: + error = ENOSYS; + break; + } + + return (error); +} + +/* + * MMAP an allocated grant into user memory. + * Please note, that the grants must not already be mmapped, otherwise + * this function will fail. + */ +static int +mmap_gref(struct per_user_data *priv_user, struct gntdev_gref *gref_start, + uint32_t count, vm_size_t size, struct vm_object **object) +{ + vm_object_t mem_obj; + struct gntdev_gref *gref; + + mem_obj = vm_object_allocate(OBJT_PHYS, size); + if (mem_obj == NULL) + return (ENOMEM); + + mtx_lock(&priv_user->user_data_lock); + VM_OBJECT_WLOCK(mem_obj); + for (gref = gref_start; gref != NULL && count > 0; gref = + RB_NEXT(gref_tree_head, &priv_user->gref_tree, gref)) { + if (gref->page->object) + break; + + vm_page_insert(gref->page, mem_obj, + OFF_TO_IDX(gref->file_index)); + + count--; + } + VM_OBJECT_WUNLOCK(mem_obj); + mtx_unlock(&priv_user->user_data_lock); + + if (count) { + vm_object_deallocate(mem_obj); + return (EINVAL); + } + + *object = mem_obj; + + return (0); + +} + +/* + * MMAP a mapped grant into user memory. + */ +static int +mmap_gmap(struct per_user_data *priv_user, struct gntdev_gmap *gmap_start, + vm_ooffset_t *offset, vm_size_t size, struct vm_object **object, int nprot) +{ + uint32_t i; + int error; + + /* + * The grant map hypercall might already be done. + * If that is the case, increase a reference to the + * vm object and return the already allocated object. + */ + if (gmap_start->map) { + vm_object_reference(gmap_start->map->mem); + *object = gmap_start->map->mem; + return (0); + } + + gmap_start->map = malloc(sizeof(*(gmap_start->map)), M_GNTDEV, + M_WAITOK | M_ZERO); + + /* Allocate the xen pseudo physical memory resource. */ + gmap_start->map->pseudo_phys_res_id = 0; + gmap_start->map->pseudo_phys_res = xenmem_alloc(gntdev_dev, + &gmap_start->map->pseudo_phys_res_id, size); + if (gmap_start->map->pseudo_phys_res == NULL) { + free(gmap_start->map, M_GNTDEV); + gmap_start->map = NULL; + return (ENOMEM); + } + gmap_start->map->phys_base_addr = + rman_get_start(gmap_start->map->pseudo_phys_res); + + /* Allocate the mgtdevice pager. */ + gmap_start->map->mem = cdev_pager_allocate(gmap_start, OBJT_MGTDEVICE, + &gntdev_gmap_pg_ops, size, nprot, *offset, NULL); + if (gmap_start->map->mem == NULL) { + xenmem_free(gntdev_dev, gmap_start->map->pseudo_phys_res_id, + gmap_start->map->pseudo_phys_res); + free(gmap_start->map, M_GNTDEV); + gmap_start->map = NULL; + return (ENOMEM); + } + + for (i = 0; i < gmap_start->count; i++) { + gmap_start->grant_map_ops[i].host_addr = + gmap_start->map->phys_base_addr + i * PAGE_SIZE; + + if ((nprot & PROT_WRITE) == 0) + gmap_start->grant_map_ops[i].flags |= GNTMAP_readonly; + } + /* Make the MAP hypercall. */ + error = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, + gmap_start->grant_map_ops, gmap_start->count); + if (error != 0) { + /* + * Deallocate pager. + * Pager deallocation will automatically take care of + * xenmem deallocation, etc. + */ + vm_object_deallocate(gmap_start->map->mem); + + return (EINVAL); + } + + /* Retry EAGAIN maps. */ + for (i = 0; i < gmap_start->count; i++) { + int delay = 1; + while (delay < 256 && + gmap_start->grant_map_ops[i].status == GNTST_eagain) { + HYPERVISOR_grant_table_op( GNTTABOP_map_grant_ref, + &gmap_start->grant_map_ops[i], 1); + pause(("gntmap"), delay * SBT_1MS); + delay++; + } + if (gmap_start->grant_map_ops[i].status == GNTST_eagain) + gmap_start->grant_map_ops[i].status = GNTST_bad_page; + + if (gmap_start->grant_map_ops[i].status != GNTST_okay) { + /* + * Deallocate pager. + * Pager deallocation will automatically take care of + * xenmem deallocation, notification, unmap hypercall, + * etc. + */ + vm_object_deallocate(gmap_start->map->mem); + + return (EINVAL); + } + } + + /* + * Add a reference to the vm object. We do not want + * the vm object to be deleted when all the mmaps are + * unmapped, because it may be re-mmapped. Instead, + * we want the object to be deleted, when along with + * munmaps, we have also processed the unmap-ioctl. + */ + vm_object_reference(gmap_start->map->mem); + + *object = gmap_start->map->mem; + + return (0); +} + +static int +gntdev_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size, + struct vm_object **object, int nprot) +{ + int error; + uint32_t count; + struct gntdev_gref *gref_start; + struct gntdev_gmap *gmap_start; + struct per_user_data *priv_user; + + error = devfs_get_cdevpriv((void**) &priv_user); + if (error != 0) + return (EINVAL); + + count = OFF_TO_IDX(size); + + gref_start = gntdev_find_grefs(priv_user, *offset, count); + if (gref_start) { + error = mmap_gref(priv_user, gref_start, count, size, object); + return (error); + } + + gmap_start = gntdev_find_gmap(priv_user, *offset, count); + if (gmap_start) { + error = mmap_gmap(priv_user, gmap_start, offset, size, object, + nprot); + return (error); + } + + return (EINVAL); +} + +/*------------------ Private Device Attachment Functions --------------------*/ +static void +gntdev_identify(driver_t *driver, device_t parent) +{ + + KASSERT((xen_domain()), + ("Trying to attach gntdev device on non Xen domain")); + + if (BUS_ADD_CHILD(parent, 0, "gntdev", 0) == NULL) + panic("unable to attach gntdev user-space device"); +} + +static int +gntdev_probe(device_t dev) +{ + + gntdev_dev = dev; + device_set_desc(dev, "Xen grant-table user-space device"); + return (BUS_PROBE_NOWILDCARD); +} + +static int +gntdev_attach(device_t dev) +{ + + make_dev_credf(MAKEDEV_ETERNAL, &gntdev_devsw, 0, NULL, UID_ROOT, + GID_WHEEL, 0600, "xen/gntdev"); + return (0); +} + +/*-------------------- Private Device Attachment Data -----------------------*/ +static device_method_t gntdev_methods[] = { + DEVMETHOD(device_identify, gntdev_identify), + DEVMETHOD(device_probe, gntdev_probe), + DEVMETHOD(device_attach, gntdev_attach), + DEVMETHOD_END +}; + +static driver_t gntdev_driver = { + "gntdev", + gntdev_methods, + 0, +}; + +devclass_t gntdev_devclass; + +DRIVER_MODULE(gntdev, xenpv, gntdev_driver, gntdev_devclass, 0, 0); +MODULE_DEPEND(gntdev, xenpv, 1, 1, 1); diff --git a/sys/xen/gntdev.h b/sys/xen/gntdev.h new file mode 100644 index 000000000000..a364e85f7781 --- /dev/null +++ b/sys/xen/gntdev.h @@ -0,0 +1,192 @@ +/*- + * Copyright (c) 2016 Akshay Jaggi + * 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. + * + * gntdev.h + * + * Interface to /dev/xen/gntdev. + * + * This device provides the user with two kinds of functionalities: + * 1. Grant Allocation + * Allocate a page of our own memory, and share it with a foreign domain. + * 2. Grant Mapping + * Map a grant allocated by a foreign domain, into our own memory. + * + * + * Grant Allocation + * + * Steps to allocate a grant: + * 1. Do an `IOCTL_GNTDEV_ALLOC_GREF ioctl`, with + * - `domid`, as the domain-id of the foreign domain + * - `flags`, ORed with GNTDEV_ALLOC_FLAG_WRITABLE if you want the foreign + * domain to have write access to the shared memory + * - `count`, with the number of pages to share with the foreign domain + * + * Ensure that the structure you allocate has enough memory to store + * all the allocated grant-refs, i.e., you need to allocate + * (sizeof(struct ioctl_gntdev_alloc_gref) + (count - 1)*sizeof(uint32_t)) + * bytes of memory. + * + * 2. Mmap the address given in `index` after a successful ioctl. + * This will give you access to the granted pages. + * + * Note: + * 1. The grant is not removed until all three of the following conditions + * are met + * - The region is not mmaped. That is, munmap() has been called if + * the region was mmapped previously. + * - IOCTL_GNTDEV_DEALLOC_GREF ioctl has been performed. After you + * perform this ioctl, you can no longer mmap or set notify on + * the grant. + * - The foreign domain has stopped using the grant. + * 2. Granted pages can only belong to one mmap region. + * 3. Every page of granted memory is a unit in itself. What this means + * is that you can set a unmap notification for each of the granted + * pages, individually; you can mmap and dealloc-ioctl a contiguous + * range of allocated grants (even if alloc-ioctls were performed + * individually), etc. + * + * + * Grant Mapping + * + * Steps to map a grant: + * 1. Do a `IOCTL_GNTDEV_MAP_GRANT_REF` ioctl, with + * - `count`, as the number of foreign grants to map + * - `refs[i].domid`, as the domain id of the foreign domain + * - `refs[i].ref`, as the grant-ref for the grant to be mapped + * + * 2. Mmap the address given in `index` after a successful ioctl. + * This will give you access to the mapped pages. + * + * Note: + * 1. The map hypercall is not made till the region is mmapped. + * 2. The unit is defined by the map ioctl. This means that only one + * unmap notification can be set on a group of pages that were + * mapped together in one ioctl, and also no single mmaping of contiguous + * grant-maps is possible. + * 3. You can mmap the same grant-map region multiple times. + * 4. The grant is not unmapped until both of the following conditions are met + * - The region is not mmaped. That is, munmap() has been called for + * as many times as the grant was mmapped. + * - IOCTL_GNTDEV_UNMAP_GRANT_REF ioctl has been called. + * 5. IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR ioctl gives index and count of + * a grant-map from the virtual address of the location where the grant + * is mmapped. + * + * + * IOCTL_GNTDEV_SET_UNMAP_NOTIFY + * This ioctl allows us to set notifications to be made when the grant is + * either unmapped (in case of a mapped grant), or when it is ready to be + * deallocated by us, ie, the grant is no more mmapped, and the dealloc + * ioctl has been called (in case of an allocated grant). OR `action` with + * the required notification masks, and fill in the appropriate fields. + * - UNMAP_NOTIFY_CLEAR_BYTE clears the byte at `index`, where index is + * the address of the byte in file address space. + * - UNMAP_NOTIFY_SEND_EVENT sends an event channel notification on + * `event_channel_port` + * In case of multiple notify ioctls, only the last one survives. + * + * $FreeBSD$ + */ + +#ifndef __XEN_GNTDEV_H__ +#define __XEN_GNTDEV_H__ + +#include + +#define IOCTL_GNTDEV_SET_UNMAP_NOTIFY \ + _IOW('E', 0, struct ioctl_gntdev_unmap_notify) +struct ioctl_gntdev_unmap_notify { + /* IN parameters */ + uint64_t index; + uint32_t action; + uint32_t event_channel_port; +}; + +#define UNMAP_NOTIFY_CLEAR_BYTE 0x1 +#define UNMAP_NOTIFY_SEND_EVENT 0x2 + +/*-------------------- Grant Allocation IOCTLs ------------------------------*/ + +#define IOCTL_GNTDEV_ALLOC_GREF \ + _IOWR('E', 1, struct ioctl_gntdev_alloc_gref) +struct ioctl_gntdev_alloc_gref { + /* IN parameters */ + uint16_t domid; + uint16_t flags; + uint32_t count; + /* OUT parameters */ + uint64_t index; + /* Variable OUT parameter */ + uint32_t gref_ids[1]; +}; + +#define GNTDEV_ALLOC_FLAG_WRITABLE 1 + +#define IOCTL_GNTDEV_DEALLOC_GREF \ + _IOW('E', 2, struct ioctl_gntdev_dealloc_gref) +struct ioctl_gntdev_dealloc_gref { + /* IN parameters */ + uint64_t index; + uint32_t count; +}; + +/*-------------------- Grant Mapping IOCTLs ---------------------------------*/ + +struct ioctl_gntdev_grant_ref { + uint32_t domid; + uint32_t ref; +}; + +#define IOCTL_GNTDEV_MAP_GRANT_REF \ + _IOWR('E', 3, struct ioctl_gntdev_map_grant_ref) +struct ioctl_gntdev_map_grant_ref { + /* IN parameters */ + uint32_t count; + uint32_t pad0; + /* OUT parameters */ + uint64_t index; + /* Variable IN parameter */ + struct ioctl_gntdev_grant_ref refs[1]; +}; + +#define IOCTL_GNTDEV_UNMAP_GRANT_REF \ + _IOW('E', 4, struct ioctl_gntdev_unmap_grant_ref) +struct ioctl_gntdev_unmap_grant_ref { + /* IN parameters */ + uint64_t index; + uint32_t count; +}; + +#define IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR \ + _IOWR('E', 5, struct ioctl_gntdev_get_offset_for_vaddr) +struct ioctl_gntdev_get_offset_for_vaddr { + /* IN parameters */ + uint64_t vaddr; + /* OUT parameters */ + uint64_t offset; + uint32_t count; +}; + +#endif /* __XEN_GNTDEV_H__ */ From ad9f2cecd74098261d39c1b2a0e85908fa9e122f Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Mon, 31 Oct 2016 15:11:55 +0000 Subject: [PATCH 226/235] When issuing a PXE dhcp request, always issue a param request (DHCP option 55) with all dhcp parameters we might be interested in. Some DHCP server like the new kea (by ISC) expect it. This makes pxeboot functional with ISC kea. Submitted by: Vincent Legout MFC after: 1 month Sponsored by: Gandi.net --- lib/libstand/bootp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/libstand/bootp.c b/lib/libstand/bootp.c index 7474f8f971d5..0c48748ddd1a 100644 --- a/lib/libstand/bootp.c +++ b/lib/libstand/bootp.c @@ -148,7 +148,17 @@ bootp(sock, flag) bp->bp_vend[7] = TAG_CLASSID; bp->bp_vend[8] = 9; bcopy("PXEClient", &bp->bp_vend[9], 9); - bp->bp_vend[18] = TAG_END; + bp->bp_vend[18] = TAG_PARAM_REQ; + bp->bp_vend[19] = 8; + bp->bp_vend[20] = TAG_ROOTPATH; + bp->bp_vend[21] = TAG_TFTP_SERVER; + bp->bp_vend[22] = TAG_HOSTNAME; + bp->bp_vend[23] = TAG_SWAPSERVER; + bp->bp_vend[24] = TAG_GATEWAY; + bp->bp_vend[25] = TAG_SUBNET_MASK; + bp->bp_vend[26] = TAG_INTF_MTU; + bp->bp_vend[27] = TAG_SERVERID; + bp->bp_vend[28] = TAG_END; } else bp->bp_vend[7] = TAG_END; #else From 5bca221511e448277905383c6c08180e624c7460 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 31 Oct 2016 15:33:58 +0000 Subject: [PATCH 227/235] Add full softfloat and hardfloat support for MIPS. This adds new target architectures for hardfloat: mipselhf mipshf mips64elhf mips64hf. Tested in QEMU only. Sponsored by: DARPA, AFRL Sponsored by: HEIF5 Differential Revision: https://reviews.freebsd.org/D8376 --- Makefile | 4 +- Makefile.inc1 | 4 + gnu/lib/libgcc/Makefile | 2 +- gnu/usr.bin/binutils/Makefile.inc0 | 4 +- gnu/usr.bin/binutils/ld/Makefile.mips | 2 +- gnu/usr.bin/binutils/libbfd/Makefile.mips | 2 +- gnu/usr.bin/cc/Makefile.inc | 2 +- gnu/usr.bin/cc/Makefile.tgt | 4 +- gnu/usr.bin/gdb/Makefile.inc | 2 +- gnu/usr.bin/gdb/libgdb/Makefile | 2 +- lib/libc/Makefile | 2 +- lib/libc/mips/Makefile.inc | 2 + lib/libc/mips/Symbol.map | 4 + lib/libc/mips/gen/Makefile.inc | 2 +- lib/libc/mips/gen/flt_rounds.c | 20 ++- lib/msun/mips/Makefile.inc | 4 + lib/msun/mips/Symbol.map | 8 ++ lib/msun/mips/fenv.c | 14 ++ lib/msun/mips/fenv.h | 166 ++++++++++++++-------- share/man/man7/arch.7 | 22 ++- share/mk/bsd.cpu.mk | 3 + share/mk/bsd.endian.mk | 2 +- share/mk/sys.mk | 2 +- sys/boot/Makefile.ficl | 2 +- sys/boot/common/Makefile.inc | 2 +- sys/boot/mips/uboot/Makefile | 2 +- sys/conf/kern.mk | 3 + sys/mips/include/float.h | 4 - sys/mips/mips/exception.S | 6 + sys/mips/mips/locore.S | 2 +- sys/mips/mips/swtch.S | 16 ++- sys/mips/mips/trap.c | 7 +- 32 files changed, 235 insertions(+), 88 deletions(-) diff --git a/Makefile b/Makefile index b5d51341135e..5904a3f967e3 100644 --- a/Makefile +++ b/Makefile @@ -239,7 +239,7 @@ _MAKE+= MK_META_MODE=no _TARGET_ARCH= ${TARGET:S/pc98/i386/:S/arm64/aarch64/} .elif !defined(TARGET) && defined(TARGET_ARCH) && \ ${TARGET_ARCH} != ${MACHINE_ARCH} -_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64/riscv/} +_TARGET= ${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/aarch64/arm64/:C/powerpc64/powerpc/:C/powerpcspe/powerpc/:C/riscv64/riscv/} .endif .if defined(TARGET) && !defined(_TARGET) _TARGET=${TARGET} @@ -421,7 +421,7 @@ TARGETS?=amd64 arm arm64 i386 mips pc98 powerpc sparc64 _UNIVERSE_TARGETS= ${TARGETS} TARGET_ARCHES_arm?= arm armeb armv6 TARGET_ARCHES_arm64?= aarch64 -TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 +TARGET_ARCHES_mips?= mipsel mips mips64el mips64 mipsn32 mipselhf mipshf mips64elhf mips64hf TARGET_ARCHES_powerpc?= powerpc powerpc64 powerpcspe TARGET_ARCHES_pc98?= i386 .for target in ${TARGETS} diff --git a/Makefile.inc1 b/Makefile.inc1 index 476c05431d2a..931af3134669 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -356,6 +356,10 @@ KNOWN_ARCHES?= aarch64/arm64 \ mipsn32el/mips \ mips64/mips \ mipsn32/mips \ + mipshf/mips \ + mipselhf/mips \ + mips64elhf/mips \ + mips64hf/mips \ powerpc \ powerpc64/powerpc \ powerpcspe/powerpc \ diff --git a/gnu/lib/libgcc/Makefile b/gnu/lib/libgcc/Makefile index 3186458f0866..fba02ed935df 100644 --- a/gnu/lib/libgcc/Makefile +++ b/gnu/lib/libgcc/Makefile @@ -165,7 +165,7 @@ LIBADD+= compiler_rt .if ${TARGET_CPUARCH} == mips LIB2FUNCS_EXTRA = floatunsidf.c floatunsisf.c # ABIs other than o32 need this -.if ${TARGET_ARCH} != "mips" && ${TARGET_ARCH} != "mipsel" +.if ${TARGET_ARCH:Mmips64*} != "" || ${TARGET_ARCH:Mmipsn32*} != "" LIB2FUNCS_EXTRA+= floatdidf.c fixunsdfsi.c LIB2FUNCS_EXTRA+= floatdisf.c floatundidf.c LIB2FUNCS_EXTRA+= fixsfdi.c floatundisf.c diff --git a/gnu/usr.bin/binutils/Makefile.inc0 b/gnu/usr.bin/binutils/Makefile.inc0 index 597d451c8a10..62d03cd0a461 100644 --- a/gnu/usr.bin/binutils/Makefile.inc0 +++ b/gnu/usr.bin/binutils/Makefile.inc0 @@ -7,7 +7,7 @@ VERSION= "2.17.50 [FreeBSD] 2007-07-03" .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif @@ -17,7 +17,7 @@ TARGET_OS?= freebsd BINUTILS_ARCH=${TARGET_ARCH:C/amd64/x86_64/} TARGET_TUPLE?= ${BINUTILS_ARCH}-${TARGET_VENDOR}-${TARGET_OS} .if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \ - (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el} == "") + (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el*} == "") TARGET_BIG_ENDIAN=t .endif diff --git a/gnu/usr.bin/binutils/ld/Makefile.mips b/gnu/usr.bin/binutils/ld/Makefile.mips index 8a7dfbb5f116..afc651cfca9d 100644 --- a/gnu/usr.bin/binutils/ld/Makefile.mips +++ b/gnu/usr.bin/binutils/ld/Makefile.mips @@ -1,6 +1,6 @@ # $FreeBSD$ -.if ${TARGET_ARCH:Mmips*el} != "" +.if ${TARGET_ARCH:Mmips*el*} != "" _EMULATION_ENDIAN=l .else _EMULATION_ENDIAN=b diff --git a/gnu/usr.bin/binutils/libbfd/Makefile.mips b/gnu/usr.bin/binutils/libbfd/Makefile.mips index 02026ba5c087..9a2781a410e2 100644 --- a/gnu/usr.bin/binutils/libbfd/Makefile.mips +++ b/gnu/usr.bin/binutils/libbfd/Makefile.mips @@ -1,6 +1,6 @@ # $FreeBSD$ -.if ${TARGET_ARCH:Mmips*el} != "" +.if ${TARGET_ARCH:Mmips*el*} != "" _EMULATION_ENDIAN=little .else _EMULATION_ENDIAN=big diff --git a/gnu/usr.bin/cc/Makefile.inc b/gnu/usr.bin/cc/Makefile.inc index 1d66b3dee7ff..3f053948bada 100644 --- a/gnu/usr.bin/cc/Makefile.inc +++ b/gnu/usr.bin/cc/Makefile.inc @@ -39,7 +39,7 @@ CFLAGS += -DFREEBSD_ARCH_armv6 .endif .if ${TARGET_CPUARCH} == "mips" -.if ${TARGET_ARCH:Mmips*el} != "" +.if ${TARGET_ARCH:Mmips*el*} != "" CFLAGS += -DTARGET_ENDIAN_DEFAULT=0 .endif diff --git a/gnu/usr.bin/cc/Makefile.tgt b/gnu/usr.bin/cc/Makefile.tgt index ca2d2ed43e26..3acd4d7c9295 100644 --- a/gnu/usr.bin/cc/Makefile.tgt +++ b/gnu/usr.bin/cc/Makefile.tgt @@ -4,7 +4,7 @@ # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif @@ -15,7 +15,7 @@ GCC_CPU=${TARGET_CPUARCH:C/amd64/i386/:C/powerpc/rs6000/:C/sparc64/sparc/} TARGET_CPU_DEFAULT= TARGET_CPU_ultrasparc .endif .if ${TARGET_ARCH} == "armeb" || ${TARGET_ARCH} == "armv6eb" || \ - (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el} == "") + (${TARGET_CPUARCH} == "mips" && ${TARGET_ARCH:Mmips*el*} == "") TARGET_BIG_ENDIAN=t .endif .if ${TARGET_ARCH} == "powerpc64" diff --git a/gnu/usr.bin/gdb/Makefile.inc b/gnu/usr.bin/gdb/Makefile.inc index 5bce6a91f01e..c9b6603f1992 100644 --- a/gnu/usr.bin/gdb/Makefile.inc +++ b/gnu/usr.bin/gdb/Makefile.inc @@ -23,7 +23,7 @@ OBJ_RL= ${OBJ_ROOT}/../lib/libreadline/readline # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif diff --git a/gnu/usr.bin/gdb/libgdb/Makefile b/gnu/usr.bin/gdb/libgdb/Makefile index 71bb9ff494da..272ede7ded4b 100644 --- a/gnu/usr.bin/gdb/libgdb/Makefile +++ b/gnu/usr.bin/gdb/libgdb/Makefile @@ -4,7 +4,7 @@ # MACHINE_CPUARCH, but there's no easy way to export make functions... .if defined(TARGET_ARCH) -TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} +TARGET_CPUARCH=${TARGET_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb)?/arm/:C/powerpc(64|spe)/powerpc/} .else TARGET_CPUARCH=${MACHINE_CPUARCH} .endif diff --git a/lib/libc/Makefile b/lib/libc/Makefile index a97b6fcdedb4..99ddfc2e8f7f 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -111,7 +111,7 @@ NOASM= .include "${LIBC_SRCTOP}/xdr/Makefile.inc" .if (${LIBC_ARCH} == "arm" && \ (${MACHINE_ARCH:Marmv6*} == "" || (defined(CPUTYPE) && ${CPUTYPE:M*soft*}))) || \ - ${LIBC_ARCH} == "mips" + (${LIBC_ARCH} == "mips" && ${MACHINE_ARCH:Mmips*hf} == "") .include "${LIBC_SRCTOP}/softfloat/Makefile.inc" .endif .if ${LIBC_ARCH} == "i386" || ${LIBC_ARCH} == "amd64" diff --git a/lib/libc/mips/Makefile.inc b/lib/libc/mips/Makefile.inc index 4ec20d47d1dd..54ce38e49bfa 100644 --- a/lib/libc/mips/Makefile.inc +++ b/lib/libc/mips/Makefile.inc @@ -1,7 +1,9 @@ # $NetBSD: Makefile.inc,v 1.7 2005/09/17 11:49:39 tsutsui Exp $ # $FreeBSD$ +.if ${MACHINE_ARCH:Mmips*hf} == "" CFLAGS+=-DSOFTFLOAT +.endif MDSRCS+= machdep_ldisd.c SYM_MAPS+= ${LIBC_SRCTOP}/mips/Symbol.map diff --git a/lib/libc/mips/Symbol.map b/lib/libc/mips/Symbol.map index 38680807adc4..9791359c93f6 100644 --- a/lib/libc/mips/Symbol.map +++ b/lib/libc/mips/Symbol.map @@ -31,6 +31,10 @@ FBSD_1.0 { sbrk; }; +FBSD_1.3 { + __flt_rounds; +}; + FBSDprivate_1.0 { /* PSEUDO syscalls */ __sys_getlogin; diff --git a/lib/libc/mips/gen/Makefile.inc b/lib/libc/mips/gen/Makefile.inc index a186fda62036..56fa380f7777 100644 --- a/lib/libc/mips/gen/Makefile.inc +++ b/lib/libc/mips/gen/Makefile.inc @@ -1,7 +1,7 @@ # $NetBSD: Makefile.inc,v 1.27 2005/10/07 17:16:40 tsutsui Exp $ # $FreeBSD$ -SRCS+= infinity.c fabs.c ldexp.c +SRCS+= infinity.c fabs.c ldexp.c flt_rounds.c # SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ # fpsetround.c fpsetsticky.c diff --git a/lib/libc/mips/gen/flt_rounds.c b/lib/libc/mips/gen/flt_rounds.c index 9fc64a537053..73428d907d11 100644 --- a/lib/libc/mips/gen/flt_rounds.c +++ b/lib/libc/mips/gen/flt_rounds.c @@ -11,7 +11,14 @@ __FBSDID("$FreeBSD$"); __RCSID("$NetBSD: flt_rounds.c,v 1.5 2005/12/24 23:10:08 perry Exp $"); #endif /* LIBC_SCCS and not lint */ -#include +#include +#include + +#ifdef SOFTFLOAT +#include "softfloat-for-gcc.h" +#include "milieu.h" +#include "softfloat.h" +#endif static const int map[] = { 1, /* round to nearest */ @@ -23,8 +30,13 @@ static const int map[] = { int __flt_rounds() { - int x; + int mode; - __asm("cfc1 %0,$31" : "=r" (x)); - return map[x & 0x03]; +#ifdef SOFTFLOAT + mode = __softfloat_float_rounding_mode; +#else + __asm __volatile("cfc1 %0,$31" : "=r" (mode)); +#endif + + return map[mode & 0x03]; } diff --git a/lib/msun/mips/Makefile.inc b/lib/msun/mips/Makefile.inc index 8c1a4864f4cf..b05f4fa3812b 100644 --- a/lib/msun/mips/Makefile.inc +++ b/lib/msun/mips/Makefile.inc @@ -1,4 +1,8 @@ # $FreeBSD$ +.if ${MACHINE_ARCH:Mmips*hf} == "" +CFLAGS+=-DSOFTFLOAT +.endif + LDBL_PREC = 53 SYM_MAPS += ${.CURDIR}/mips/Symbol.map diff --git a/lib/msun/mips/Symbol.map b/lib/msun/mips/Symbol.map index 971112e30c8a..081294cf5562 100644 --- a/lib/msun/mips/Symbol.map +++ b/lib/msun/mips/Symbol.map @@ -5,9 +5,17 @@ FBSD_1.0 { }; FBSD_1.3 { + feclearexcept; + fegetexceptflag; fesetexceptflag; feraiseexcept; + fetestexcept; + fegetround; + fesetround; fegetenv; feholdexcept; feupdateenv; + feenableexcept; + fedisableexcept; + fegetexcept; }; diff --git a/lib/msun/mips/fenv.c b/lib/msun/mips/fenv.c index a5a5c03d3a74..64beb704c74e 100644 --- a/lib/msun/mips/fenv.c +++ b/lib/msun/mips/fenv.c @@ -39,6 +39,17 @@ */ const fenv_t __fe_dfl_env = 0; +#ifdef SOFTFLOAT +#define __set_env(env, flags, mask, rnd) env = ((flags) \ + | (mask)<<_FPUSW_SHIFT \ + | (rnd) << 24) +#define __env_flags(env) ((env) & FE_ALL_EXCEPT) +#define __env_mask(env) (((env) >> _FPUSW_SHIFT) \ + & FE_ALL_EXCEPT) +#define __env_round(env) (((env) >> 24) & _ROUND_MASK) +#include "fenv-softfloat.h" +#endif + extern inline int feclearexcept(int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); @@ -50,3 +61,6 @@ extern inline int fegetenv(fenv_t *__envp); extern inline int feholdexcept(fenv_t *__envp); extern inline int fesetenv(const fenv_t *__envp); extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); diff --git a/lib/msun/mips/fenv.h b/lib/msun/mips/fenv.h index f11499806bea..498af3471b5d 100644 --- a/lib/msun/mips/fenv.h +++ b/lib/msun/mips/fenv.h @@ -39,11 +39,21 @@ typedef __uint32_t fenv_t; typedef __uint32_t fexcept_t; /* Exception flags */ +#ifdef SOFTFLOAT +#define _FPUSW_SHIFT 16 #define FE_INVALID 0x0001 #define FE_DIVBYZERO 0x0002 #define FE_OVERFLOW 0x0004 #define FE_UNDERFLOW 0x0008 #define FE_INEXACT 0x0010 +#else +#define _FCSR_CAUSE_SHIFT 10 +#define FE_INVALID 0x0040 +#define FE_DIVBYZERO 0x0020 +#define FE_OVERFLOW 0x0010 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0004 +#endif #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) @@ -61,104 +71,135 @@ extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) /* We need to be able to map status flag positions to mask flag positions */ -#define _FPUSW_SHIFT 16 -#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) +#define _ENABLE_SHIFT 5 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _ENABLE_SHIFT) -#ifdef ARM_HARD_FLOAT -#define __rfs(__fpsr) __asm __volatile("rfs %0" : "=r" (*(__fpsr))) -#define __wfs(__fpsr) __asm __volatile("wfs %0" : : "r" (__fpsr)) -#else -#define __rfs(__fpsr) -#define __wfs(__fpsr) +#ifndef SOFTFLOAT +#define __cfc1(__fcsr) __asm __volatile("cfc1 %0, $31" : "=r" (__fcsr)) +#define __ctc1(__fcsr) __asm __volatile("ctc1 %0, $31" :: "r" (__fcsr)) #endif +#ifdef SOFTFLOAT +int feclearexcept(int __excepts); +int fegetexceptflag(fexcept_t *__flagp, int __excepts); +int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int feraiseexcept(int __excepts); +int fetestexcept(int __excepts); +int fegetround(void); +int fesetround(int __round); +int fegetenv(fenv_t *__envp); +int feholdexcept(fenv_t *__envp); +int fesetenv(const fenv_t *__envp); +int feupdateenv(const fenv_t *__envp); +#else __fenv_static inline int feclearexcept(int __excepts) { - fexcept_t __fpsr; + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr &= ~(__excepts | (__excepts << _FCSR_CAUSE_SHIFT)); + __ctc1(fcsr); - __rfs(&__fpsr); - __fpsr &= ~__excepts; - __wfs(__fpsr); return (0); } __fenv_static inline int fegetexceptflag(fexcept_t *__flagp, int __excepts) { - fexcept_t __fpsr; + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + *__flagp = fcsr & __excepts; - __rfs(&__fpsr); - *__flagp = __fpsr & __excepts; return (0); } __fenv_static inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts) { - fexcept_t __fpsr; + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr &= ~__excepts; + fcsr |= *__flagp & __excepts; + __ctc1(fcsr); - __rfs(&__fpsr); - __fpsr &= ~__excepts; - __fpsr |= *__flagp & __excepts; - __wfs(__fpsr); return (0); } __fenv_static inline int feraiseexcept(int __excepts) { - fexcept_t __ex = __excepts; + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr |= __excepts | (__excepts << _FCSR_CAUSE_SHIFT); + __ctc1(fcsr); - fesetexceptflag(&__ex, __excepts); /* XXX */ return (0); } __fenv_static inline int fetestexcept(int __excepts) { - fexcept_t __fpsr; + fexcept_t fcsr; - __rfs(&__fpsr); - return (__fpsr & __excepts); + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + + return (fcsr & __excepts); } __fenv_static inline int fegetround(void) { + fexcept_t fcsr; - /* - * Apparently, the rounding mode is specified as part of the - * instruction format on ARM, so the dynamic rounding mode is - * indeterminate. Some FPUs may differ. - */ - return (-1); + __cfc1(fcsr); + + return (fcsr & _ROUND_MASK); } __fenv_static inline int fesetround(int __round) { + fexcept_t fcsr; - return (-1); + if (__round & ~_ROUND_MASK) + return (-1); + + __cfc1(fcsr); + fcsr &= ~_ROUND_MASK; + fcsr |= __round; + __ctc1(fcsr); + + return (0); } __fenv_static inline int fegetenv(fenv_t *__envp) { - __rfs(__envp); + __cfc1(*__envp); + return (0); } __fenv_static inline int feholdexcept(fenv_t *__envp) { - fenv_t __env; + fexcept_t fcsr; + + __cfc1(fcsr); + *__envp = fcsr; + fcsr &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __ctc1(fcsr); - __rfs(&__env); - *__envp = __env; - __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); - __wfs(__env); return (0); } @@ -166,56 +207,69 @@ __fenv_static inline int fesetenv(const fenv_t *__envp) { - __wfs(*__envp); + __ctc1(*__envp); + return (0); } __fenv_static inline int feupdateenv(const fenv_t *__envp) { - fexcept_t __fpsr; + fexcept_t fcsr; + + __cfc1(fcsr); + fesetenv(__envp); + feraiseexcept(fcsr); - __rfs(&__fpsr); - __wfs(*__envp); - feraiseexcept(__fpsr & FE_ALL_EXCEPT); return (0); } +#endif /* !SOFTFLOAT */ #if __BSD_VISIBLE /* We currently provide no external definitions of the functions below. */ +#ifdef SOFTFLOAT +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#else static inline int feenableexcept(int __mask) { - fenv_t __old_fpsr, __new_fpsr; + fenv_t __old_fcsr, __new_fcsr; - __rfs(&__old_fpsr); - __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; - __wfs(__new_fpsr); - return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); + __cfc1(__old_fcsr); + __new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT; + __ctc1(__new_fcsr); + + return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT); } static inline int fedisableexcept(int __mask) { - fenv_t __old_fpsr, __new_fpsr; + fenv_t __old_fcsr, __new_fcsr; - __rfs(&__old_fpsr); - __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); - __wfs(__new_fpsr); - return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); + __cfc1(__old_fcsr); + __new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT); + __ctc1(__new_fcsr); + + return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT); } static inline int fegetexcept(void) { - fenv_t __fpsr; + fexcept_t fcsr; - __rfs(&__fpsr); - return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); + __cfc1(fcsr); + + return ((fcsr & _ENABLE_MASK) >> _ENABLE_SHIFT); } +#endif /* !SOFTFLOAT */ + #endif /* __BSD_VISIBLE */ __END_DECLS diff --git a/share/man/man7/arch.7 b/share/man/man7/arch.7 index 488cd05b1f90..d198c98665bf 100644 --- a/share/man/man7/arch.7 +++ b/share/man/man7/arch.7 @@ -57,9 +57,13 @@ On all supported architectures, .It i386 Ta 4 Ta 12 .It mips Ta 4 Ta 8 .It mipsel Ta 4 Ta 8 +.It mipselhf Ta 4 Ta 8 +.It mipshf Ta 4 Ta 8 .It mipsn32 Ta 4 Ta 8 .It mips64 Ta 8 Ta 8 .It mips64el Ta 8 Ta 8 +.It mips64elhf Ta 8 Ta 8 +.It mips64hf Ta 8 Ta 8 .It powerpc Ta 4 Ta 8 .It powerpc64 Ta 8 Ta 8 .It riscv Ta 8 Ta @@ -76,9 +80,13 @@ On all supported architectures, .It i386 Ta little Ta signed .It mips Ta big Ta signed .It mipsel Ta little Ta signed +.It mipselhf Ta little Ta signed +.It mipshf Ta big Ta signed .It mipsn32 Ta big Ta signed .It mips64 Ta big Ta signed .It mips64el Ta little Ta signed +.It mips64elhf Ta little Ta signed +.It mips64hf Ta big Ta signed .It powerpc Ta big Ta unsigned .It powerpc64 Ta big Ta unsigned .It riscv Ta little Ta signed @@ -95,9 +103,13 @@ On all supported architectures, .It i386 Ta 4K, 2M (PAE), 4M .It mips Ta 4K .It mipsel Ta 4K +.It mipselhf Ta 4K +.It mipshf Ta 4K .It mipsn32 Ta 4K .It mips64 Ta 4K .It mips64el Ta 4K +.It mips64elhf Ta 4K +.It mips64hf Ta 4K .It powerpc Ta 4K .It powerpc64 Ta 4K .It riscv Ta 4K @@ -114,9 +126,13 @@ On all supported architectures, .It i386 Ta hard Ta hard, 80 bit .It mips Ta soft Ta identical to double .It mipsel Ta soft Ta identical to double -.It mipsn32 Ta soft Ta identical to double +.It mipselhf Ta hard Ta identical to double +.It mipshf Ta hard Ta identical to double +.It mipsn32 Ta soft Ta identical to double .It mips64 Ta soft Ta identical to double .It mips64el Ta soft Ta identical to double +.It mips64elhf Ta hard Ta identical to double +.It mips64hf Ta hard Ta identical to double .It powerpc Ta hard Ta hard, double precision .It powerpc64 Ta hard Ta hard, double precision .It riscv Ta @@ -155,9 +171,13 @@ Architecture-specific macros: .It i386 Ta Dv __i386__ .It mips Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32 .It mipsel Ta Dv __mips__, Dv __mips_o32 +.It mipselhf Ta Dv __mips__, Dv __mips_o32 +.It mipshf Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_o32 .It mipsn32 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n32 .It mips64 Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64 .It mips64el Ta Dv __mips__, Dv __mips_n64 +.It mips64elhf Ta Dv __mips__, Dv __mips_n64 +.It mips64hf Ta Dv __mips__, Dv __MIPSEB__, Dv __mips_n64 .It powerpc Ta Dv __powerpc__ .It powerpc64 Ta Dv __powerpc__, Dv __powerpc64__ .It riscv Ta Dv __riscv__, Dv __riscv64 diff --git a/share/mk/bsd.cpu.mk b/share/mk/bsd.cpu.mk index 211b6fc87723..5ccfe548cbc1 100644 --- a/share/mk/bsd.cpu.mk +++ b/share/mk/bsd.cpu.mk @@ -303,6 +303,9 @@ MACHINE_CPU = v9 ultrasparc ultrasparc3 .if ${MACHINE_CPUARCH} == "mips" CFLAGS += -G0 +.if ${TARGET_ARCH:Mmips*hf} +CFLAGS += -mhard-float +.endif .endif ########## arm diff --git a/share/mk/bsd.endian.mk b/share/mk/bsd.endian.mk index a264b67e0407..eac92c6838f7 100644 --- a/share/mk/bsd.endian.mk +++ b/share/mk/bsd.endian.mk @@ -5,7 +5,7 @@ ${MACHINE_ARCH} == "i386" || \ (${MACHINE} == "arm" && ${MACHINE_ARCH:Marm*eb*} == "") || \ ${MACHINE_CPUARCH} == "riscv" || \ - ${MACHINE_ARCH:Mmips*el} != "" + ${MACHINE_ARCH:Mmips*el*} != "" TARGET_ENDIANNESS= 1234 .elif ${MACHINE_ARCH} == "powerpc" || \ ${MACHINE_ARCH} == "powerpc64" || \ diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 6efa99410d0a..cc4a1feb61bb 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -13,7 +13,7 @@ unix ?= We run FreeBSD, not UNIX. # and/or endian. This is called MACHINE_CPU in NetBSD, but that's used # for something different in FreeBSD. # -MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64/riscv/} +MACHINE_CPUARCH=${MACHINE_ARCH:C/mips(n32|64)?(el)?(hf)?/mips/:C/arm(v6)?(eb|hf)?/arm/:C/powerpc(64|spe)/powerpc/:C/riscv64/riscv/} .endif diff --git a/sys/boot/Makefile.ficl b/sys/boot/Makefile.ficl index de1427aa4285..ef9a11de347a 100644 --- a/sys/boot/Makefile.ficl +++ b/sys/boot/Makefile.ficl @@ -6,7 +6,7 @@ FICLDIR?= ${SRCTOP}/sys/boot/ficl .if ${MACHINE_CPUARCH} == "amd64" && defined(FICL32) FICL_CPUARCH= i386 -.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" +.elif ${MACHINE_ARCH:Mmips64*} != "" FICL_CPUARCH= mips64 .else FICL_CPUARCH= ${MACHINE_CPUARCH} diff --git a/sys/boot/common/Makefile.inc b/sys/boot/common/Makefile.inc index 6086a3b22fa0..a7e8ea75561b 100644 --- a/sys/boot/common/Makefile.inc +++ b/sys/boot/common/Makefile.inc @@ -18,7 +18,7 @@ SRCS+= load_elf32.c reloc_elf32.c SRCS+= load_elf64.c reloc_elf64.c .elif ${MACHINE_CPUARCH} == "sparc64" SRCS+= load_elf64.c reloc_elf64.c -.elif ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" +.elif ${MACHINE_ARCH:Mmips64*} != "" SRCS+= load_elf64.c reloc_elf64.c .elif ${MACHINE} == "mips" SRCS+= load_elf32.c reloc_elf32.c diff --git a/sys/boot/mips/uboot/Makefile b/sys/boot/mips/uboot/Makefile index 6be362c86564..05761b099b6b 100644 --- a/sys/boot/mips/uboot/Makefile +++ b/sys/boot/mips/uboot/Makefile @@ -85,7 +85,7 @@ LIBFDT= ${.OBJDIR}/../../fdt/libfdt.a # Enable BootForth BOOT_FORTH= yes CFLAGS+= -DBOOT_FORTH -I${.CURDIR}/../../ficl -.if ${MACHINE_ARCH} == "mips64" || ${MACHINE_ARCH} == "mips64el" +.if ${MACHINE_ARCH:Mmips64*} != "" CFLAGS+= -I${.CURDIR}/../../ficl/mips64 .else CFLAGS+= -I${.CURDIR}/../../ficl/mips diff --git a/sys/conf/kern.mk b/sys/conf/kern.mk index 15a6bf557013..fb8ade289c8b 100644 --- a/sys/conf/kern.mk +++ b/sys/conf/kern.mk @@ -184,6 +184,9 @@ CFLAGS.gcc+= -mcall-aixdesc .if ${MACHINE_CPUARCH} == "mips" CFLAGS+= -msoft-float INLINE_LIMIT?= 8000 +.if ${TARGET_ARCH:Mmips*hf} != "" +CFLAGS+= -DCPU_HAVEFPU +.endif .endif # diff --git a/sys/mips/include/float.h b/sys/mips/include/float.h index 86efd02b975c..93a9d5c2fd50 100644 --- a/sys/mips/include/float.h +++ b/sys/mips/include/float.h @@ -42,11 +42,7 @@ extern int __flt_rounds(void); __END_DECLS #define FLT_RADIX 2 /* b */ -#ifdef CPU_HAVEFPU #define FLT_ROUNDS __flt_rounds() /* FP addition rounds to nearest */ -#else -#define FLT_ROUNDS (-1) -#endif #if __ISO_C_VISIBLE >= 1999 #define FLT_EVAL_METHOD 0 diff --git a/sys/mips/mips/exception.S b/sys/mips/mips/exception.S index 725ae65eaaa2..04614737ab99 100644 --- a/sys/mips/mips/exception.S +++ b/sys/mips/mips/exception.S @@ -1098,11 +1098,17 @@ END(MipsTLBMissException) NESTED(MipsFPTrap, CALLFRAME_SIZ, ra) PTR_SUBU sp, sp, CALLFRAME_SIZ mfc0 t0, MIPS_COP_0_STATUS + HAZARD_DELAY REG_S ra, CALLFRAME_RA(sp) .mask 0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ) +#if defined(__mips_n64) + or t1, t0, MIPS_SR_COP_1_BIT | MIPS_SR_FR +#else or t1, t0, MIPS_SR_COP_1_BIT +#endif mtc0 t1, MIPS_COP_0_STATUS + HAZARD_DELAY ITLBNOPFIX cfc1 t1, MIPS_FPU_CSR # stall til FP done cfc1 t1, MIPS_FPU_CSR # now get status diff --git a/sys/mips/mips/locore.S b/sys/mips/mips/locore.S index 4e2173c583d3..37421d8f5003 100644 --- a/sys/mips/mips/locore.S +++ b/sys/mips/mips/locore.S @@ -118,7 +118,7 @@ VECTOR(_locore, unknown) */ li t1, MIPS_SR_COP_1_BIT #ifdef __mips_n64 - or t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX + or t1, MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX | MIPS_SR_FR #endif #endif /* diff --git a/sys/mips/mips/swtch.S b/sys/mips/mips/swtch.S index aff18acb36cc..ae33c39edd46 100644 --- a/sys/mips/mips/swtch.S +++ b/sys/mips/mips/swtch.S @@ -415,8 +415,14 @@ LEAF(MipsSwitchFPState) .set push .set hardfloat mfc0 t1, MIPS_COP_0_STATUS # Save old SR - li t0, MIPS_SR_COP_1_BIT # enable the coprocessor + HAZARD_DELAY +#if defined(__mips_n64) + or t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR # enable the coprocessor +#else + or t0, t1, MIPS_SR_COP_1_BIT # enable the coprocessor +#endif mtc0 t0, MIPS_COP_0_STATUS + HAZARD_DELAY ITLBNOPFIX beq a0, zero, 1f # skip save if NULL pointer @@ -540,8 +546,14 @@ LEAF(MipsSaveCurFPState) .set hardfloat PTR_L a0, TD_PCB(a0) # get pointer to pcb for thread mfc0 t1, MIPS_COP_0_STATUS # Disable interrupts and - li t0, MIPS_SR_COP_1_BIT # enable the coprocessor + HAZARD_DELAY +#if defined(__mips_n64) + or t0, t1, MIPS_SR_COP_1_BIT | MIPS_SR_FR # enable the coprocessor +#else + or t0, t1, MIPS_SR_COP_1_BIT # enable the coprocessor +#endif mtc0 t0, MIPS_COP_0_STATUS + HAZARD_DELAY ITLBNOPFIX GET_CPU_PCPU(a1) PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index e14b12be2139..05789ae7e4da 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -590,7 +590,8 @@ trap(struct trapframe *trapframe) break; } if ((last_badvaddr == this_badvaddr) && - ((type & ~T_USER) != T_SYSCALL)) { + ((type & ~T_USER) != T_SYSCALL) && + ((type & ~T_USER) != T_COP_UNUSABLE)) { if (++count == 3) { trap_frame_dump(trapframe); panic("too many faults at %p\n", (void *)last_badvaddr); @@ -980,7 +981,11 @@ trap(struct trapframe *trapframe) addr = trapframe->pc; MipsSwitchFPState(PCPU_GET(fpcurthread), td->td_frame); PCPU_SET(fpcurthread, td); +#if defined(__mips_n64) + td->td_frame->sr |= MIPS_SR_COP_1_BIT | MIPS_SR_FR; +#else td->td_frame->sr |= MIPS_SR_COP_1_BIT; +#endif td->td_md.md_flags |= MDTD_FPUSED; goto out; #endif From a2aa0aae078f2ede6a08612648a9cdf2b2b15150 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 31 Oct 2016 15:49:41 +0000 Subject: [PATCH 228/235] Use correct signal number for floating point exceptions. Sponsored by: DARPA, AFRL Sponsored by: HEIF5 --- sys/mips/mips/trap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/trap.c b/sys/mips/mips/trap.c index 05789ae7e4da..33874a8d6c0c 100644 --- a/sys/mips/mips/trap.c +++ b/sys/mips/mips/trap.c @@ -1033,7 +1033,7 @@ trap(struct trapframe *trapframe) case T_FPE + T_USER: if (!emulate_fp) { - i = SIGILL; + i = SIGFPE; addr = trapframe->pc; break; } From 42f97fac5d4090300b00383853f1d750c00e42af Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 31 Oct 2016 16:01:22 +0000 Subject: [PATCH 229/235] Fix wrong copy/paste in error message. Submitted by: Dmitry Luhtionov MFC after: 2 weeks --- usr.sbin/ctld/ctld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index 82bd88a46080..599f8eb681cf 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -198,7 +198,7 @@ auth_check_secret_length(struct auth *auth) auth->a_auth_group->ag_name); else log_warnx("secret for user \"%s\", target \"%s\", " - "is too short; it should be at least 16 characters " + "is too short; it should be at least 12 characters " "long", auth->a_user, auth->a_auth_group->ag_target->t_name); } From 2668ec0761a2d536161c5c6cef99159c8c09c212 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Mon, 31 Oct 2016 16:06:57 +0000 Subject: [PATCH 230/235] There appeared to be even more copy/pastes. :) Submitted by: Dmitry Luhtionov MFC after: 2 weeks --- usr.sbin/ctld/ctld.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/ctld/ctld.c b/usr.sbin/ctld/ctld.c index 599f8eb681cf..490a07021161 100644 --- a/usr.sbin/ctld/ctld.c +++ b/usr.sbin/ctld/ctld.c @@ -227,7 +227,7 @@ auth_check_secret_length(struct auth *auth) else log_warnx("mutual secret for user \"%s\", " "target \"%s\", is too short; it should be " - "at least 16 characters long", + "at least 12 characters long", auth->a_user, auth->a_auth_group->ag_target->t_name); } From ae8b1f90fecd606bbf17c74500fec4f91a3c8c04 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 31 Oct 2016 16:55:14 +0000 Subject: [PATCH 231/235] Fix alignment issues on MIPS: align the pointers properly. All the 5520 GEOM_ELI tests passed successfully on MIPS64EB. Sponsored by: DARPA, AFRL Sponsored by: HEIF5 Differential Revision: https://reviews.freebsd.org/D7905 --- sbin/geom/class/eli/geom_eli.c | 2 +- sys/geom/eli/g_eli.h | 12 +++++++++--- sys/geom/eli/g_eli_integrity.c | 5 +++++ sys/modules/geom/Makefile | 6 +----- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/sbin/geom/class/eli/geom_eli.c b/sbin/geom/class/eli/geom_eli.c index c804622ddbe2..fe7d1974ba48 100644 --- a/sbin/geom/class/eli/geom_eli.c +++ b/sbin/geom/class/eli/geom_eli.c @@ -666,7 +666,7 @@ static void eli_init(struct gctl_req *req) { struct g_eli_metadata md; - unsigned char sector[sizeof(struct g_eli_metadata)]; + unsigned char sector[sizeof(struct g_eli_metadata)] __aligned(4); unsigned char key[G_ELI_USERKEYLEN]; char backfile[MAXPATHLEN]; const char *str, *prov; diff --git a/sys/geom/eli/g_eli.h b/sys/geom/eli/g_eli.h index 13e780762549..b6a28d05a9a6 100644 --- a/sys/geom/eli/g_eli.h +++ b/sys/geom/eli/g_eli.h @@ -289,6 +289,7 @@ eli_metadata_encode_v1v2v3v4v5v6v7(struct g_eli_metadata *md, u_char **datap) static __inline void eli_metadata_encode(struct g_eli_metadata *md, u_char *data) { + uint32_t hash[4]; MD5_CTX ctx; u_char *p; @@ -320,12 +321,14 @@ eli_metadata_encode(struct g_eli_metadata *md, u_char *data) } MD5Init(&ctx); MD5Update(&ctx, data, p - data); - MD5Final(md->md_hash, &ctx); + MD5Final((void *)hash, &ctx); + bcopy(hash, md->md_hash, sizeof(md->md_hash)); bcopy(md->md_hash, p, sizeof(md->md_hash)); } static __inline int eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) { + uint32_t hash[4]; MD5_CTX ctx; const u_char *p; @@ -341,7 +344,8 @@ eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); MD5Init(&ctx); MD5Update(&ctx, data, p - data); - MD5Final(md->md_hash, &ctx); + MD5Final((void *)hash, &ctx); + bcopy(hash, md->md_hash, sizeof(md->md_hash)); if (bcmp(md->md_hash, p, 16) != 0) return (EINVAL); return (0); @@ -350,6 +354,7 @@ eli_metadata_decode_v0(const u_char *data, struct g_eli_metadata *md) static __inline int eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md) { + uint32_t hash[4]; MD5_CTX ctx; const u_char *p; @@ -366,7 +371,8 @@ eli_metadata_decode_v1v2v3v4v5v6v7(const u_char *data, struct g_eli_metadata *md bcopy(p, md->md_mkeys, sizeof(md->md_mkeys)); p += sizeof(md->md_mkeys); MD5Init(&ctx); MD5Update(&ctx, data, p - data); - MD5Final(md->md_hash, &ctx); + MD5Final((void *)hash, &ctx); + bcopy(hash, md->md_hash, sizeof(md->md_hash)); if (bcmp(md->md_hash, p, 16) != 0) return (EINVAL); return (0); diff --git a/sys/geom/eli/g_eli_integrity.c b/sys/geom/eli/g_eli_integrity.c index f68800197eda..6ff0d18566ee 100644 --- a/sys/geom/eli/g_eli_integrity.c +++ b/sys/geom/eli/g_eli_integrity.c @@ -444,6 +444,7 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) size += sizeof(*crde) * nsec; size += sizeof(*crda) * nsec; size += G_ELI_AUTH_SECKEYLEN * nsec; + size += sizeof(uintptr_t); /* Space for alignment. */ data = malloc(size, M_ELI, M_WAITOK); bp->bio_driver2 = data; p = data + encr_secsize * nsec; @@ -451,6 +452,10 @@ g_eli_auth_run(struct g_eli_worker *wr, struct bio *bp) bp->bio_inbed = 0; bp->bio_children = nsec; +#if defined(__mips_n64) || defined(__mips_o64) + p = (char *)roundup((uintptr_t)p, sizeof(uintptr_t)); +#endif + for (i = 1; i <= nsec; i++, dstoff += encr_secsize) { crp = (struct cryptop *)p; p += sizeof(*crp); crde = (struct cryptodesc *)p; p += sizeof(*crde); diff --git a/sys/modules/geom/Makefile b/sys/modules/geom/Makefile index 3ea398958aab..8d7e3c6deb3f 100644 --- a/sys/modules/geom/Makefile +++ b/sys/modules/geom/Makefile @@ -6,6 +6,7 @@ SYSDIR?=${.CURDIR}/../.. SUBDIR= geom_bde \ geom_cache \ geom_concat \ + geom_eli \ geom_gate \ geom_journal \ geom_label \ @@ -29,9 +30,4 @@ SUBDIR= geom_bde \ SUBDIR+= geom_ccd .endif -# Alignment issues in g_eli_auth_run() on MIPS64 causes kernel panic -.if ${MACHINE_ARCH} != "mips64" && ${MACHINE_ARCH} != "mips64el" -SUBDIR+= geom_eli -.endif - .include From b2fd8384ffdd8ecba4fbf12670ff2e2247d560d9 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Mon, 31 Oct 2016 18:20:12 +0000 Subject: [PATCH 232/235] cron(8): add support for /etc/cron.d and /usr/local/etc/cron.d For automation tools it is way easier to maintain files in directories rather than modifying /etc/crontab. The files in those directories are in the same format as /etc/crontab Reviewed by: adrian MFC after: 2 weeks Relnotes: yes Sponsored by: Gandi.net Differential Revision: https://reviews.freebsd.org/D8400 --- etc/mtree/BSD.root.dist | 2 ++ usr.sbin/cron/cron/cron.8 | 8 ++++-- usr.sbin/cron/cron/cron.h | 2 +- usr.sbin/cron/cron/database.c | 46 ++++++++++++++++++++++++++++++++-- usr.sbin/cron/cron/pathnames.h | 2 ++ usr.sbin/cron/lib/misc.c | 6 +---- 6 files changed, 56 insertions(+), 10 deletions(-) diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist index 1c1a1ddad177..3a7bdeb6d4a8 100644 --- a/etc/mtree/BSD.root.dist +++ b/etc/mtree/BSD.root.dist @@ -32,6 +32,8 @@ .. casper .. + cron.d + .. defaults .. devd diff --git a/usr.sbin/cron/cron/cron.8 b/usr.sbin/cron/cron/cron.8 index b765c64abafd..dc53101cf677 100644 --- a/usr.sbin/cron/cron/cron.8 +++ b/usr.sbin/cron/cron/cron.8 @@ -17,7 +17,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 21, 2016 +.Dd Octobre 31, 2016 .Dt CRON 8 .Os .Sh NAME @@ -53,7 +53,11 @@ The .Nm utility also searches for .Pa /etc/crontab -which is in a different format (see +and files in +.Pa /etc/cron.d +and +.Pa /usr/local/etc/cron.d +which are in a different format (see .Xr crontab 5 ) . .Pp The diff --git a/usr.sbin/cron/cron/cron.h b/usr.sbin/cron/cron/cron.h index 60b2a90819e2..a6810be84005 100644 --- a/usr.sbin/cron/cron/cron.h +++ b/usr.sbin/cron/cron/cron.h @@ -218,7 +218,7 @@ void set_cron_uid(void), unget_char(int, FILE *), free_entry(entry *), skip_comments(FILE *), - log_it(char *, int, char *, char *), + log_it(char *, int, char *, const char *), log_close(void); int job_runqueue(void), diff --git a/usr.sbin/cron/cron/database.c b/usr.sbin/cron/cron/database.c index 7a44d1429646..2ac7113c1171 100644 --- a/usr.sbin/cron/cron/database.c +++ b/usr.sbin/cron/cron/database.c @@ -45,9 +45,18 @@ load_database(old_db) DIR *dir; struct stat statbuf; struct stat syscron_stat; + time_t maxmtime; DIR_T *dp; cron_db new_db; user *u, *nu; + struct { + const char *name; + struct stat st; + } syscrontabs [] = { + { SYSCRONTABS }, + { LOCALSYSCRONTABS } + }; + int i; Debug(DLOAD, ("[%d] load_database()\n", getpid())) @@ -65,6 +74,16 @@ load_database(old_db) if (stat(SYSCRONTAB, &syscron_stat) < OK) syscron_stat.st_mtime = 0; + maxmtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime); + + for (i = 0; i < nitems(syscrontabs); i++) { + if (stat(syscrontabs[i].name, &syscrontabs[i].st) != -1) { + maxmtime = TMAX(syscrontabs[i].st.st_mtime, maxmtime); + } else { + syscrontabs[i].st.st_mtime = 0; + } + } + /* if spooldir's mtime has not changed, we don't need to fiddle with * the database. * @@ -72,7 +91,7 @@ load_database(old_db) * so is guaranteed to be different than the stat() mtime the first * time this function is called. */ - if (old_db->mtime == TMAX(statbuf.st_mtime, syscron_stat.st_mtime)) { + if (old_db->mtime == maxmtime) { Debug(DLOAD, ("[%d] spool dir mtime unch, no load needed.\n", getpid())) return; @@ -83,7 +102,7 @@ load_database(old_db) * actually changed. Whatever is left in the old database when * we're done is chaff -- crontabs that disappeared. */ - new_db.mtime = TMAX(statbuf.st_mtime, syscron_stat.st_mtime); + new_db.mtime = maxmtime; new_db.head = new_db.tail = NULL; if (syscron_stat.st_mtime) { @@ -92,6 +111,29 @@ load_database(old_db) &new_db, old_db); } + for (i = 0; i < nitems(syscrontabs); i++) { + char tabname[MAXPATHLEN]; + if (syscrontabs[i].st.st_mtime == 0) + continue; + if (!(dir = opendir(syscrontabs[i].name))) { + log_it("CRON", getpid(), "OPENDIR FAILED", + syscrontabs[i].name); + (void) exit(ERROR_EXIT); + } + + while (NULL != (dp = readdir(dir))) { + if (dp->d_name[0] == '.') + continue; + if (dp->d_type != DT_REG) + continue; + snprintf(tabname, sizeof(tabname), "%s/%s", + syscrontabs[i].name, dp->d_name); + process_crontab("root", SYS_NAME, tabname, + &syscrontabs[i].st, &new_db, old_db); + } + closedir(dir); + } + /* we used to keep this dir open all the time, for the sake of * efficiency. however, we need to close it in every fork, and * we fork a lot more often than the mtime of the dir changes. diff --git a/usr.sbin/cron/cron/pathnames.h b/usr.sbin/cron/cron/pathnames.h index ba91bfdc61f9..fe3ebf55da45 100644 --- a/usr.sbin/cron/cron/pathnames.h +++ b/usr.sbin/cron/cron/pathnames.h @@ -62,6 +62,8 @@ /* 4.3BSD-style crontab */ #define SYSCRONTAB "/etc/crontab" +#define SYSCRONTABS "/etc/cron.d" +#define LOCALSYSCRONTABS "/usr/local/etc/cron.d" /* what editor to use if no EDITOR or VISUAL * environment variable specified. diff --git a/usr.sbin/cron/lib/misc.c b/usr.sbin/cron/lib/misc.c index afed07f3ee83..6a0b8acbd742 100644 --- a/usr.sbin/cron/lib/misc.c +++ b/usr.sbin/cron/lib/misc.c @@ -385,11 +385,7 @@ out: if (allow) void -log_it(username, xpid, event, detail) - char *username; - int xpid; - char *event; - char *detail; +log_it(char *username, int xpid, char *event, const char *detail) { #if defined(LOG_FILE) || DEBUGGING PID_T pid = xpid; From 0a4c51f4234f19c90c95f0cc2796ae2c6417b72c Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 31 Oct 2016 18:37:05 +0000 Subject: [PATCH 233/235] Move declarations of invpcid_works and pmap_pcid_enabled to pmap.h. Previously these were only declared under #ifdef SMP in . However, these variables are defind in pmap.c unconditionally, and efirt.c references them unconditionally. This fixes non-SMP kernel builds. Discussed with: kib MFC after: 1 week --- sys/amd64/include/pmap.h | 2 ++ sys/amd64/include/smp.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h index 4d924bdbf31e..99285a99e1d9 100644 --- a/sys/amd64/include/pmap.h +++ b/sys/amd64/include/pmap.h @@ -382,6 +382,8 @@ extern vm_paddr_t dump_avail[]; extern vm_offset_t virtual_avail; extern vm_offset_t virtual_end; extern vm_paddr_t dmaplimit; +extern int pmap_pcid_enabled; +extern int invpcid_works; #define pmap_page_get_memattr(m) ((vm_memattr_t)(m)->md.pat_mode) #define pmap_page_is_write_mapped(m) (((m)->aflags & PGA_WRITEABLE) != 0) diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 212d1ee50f23..d97c7304f204 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -21,9 +21,6 @@ #include -extern int pmap_pcid_enabled; -extern int invpcid_works; - /* global symbols in mpboot.S */ extern char mptramp_start[]; extern char mptramp_end[]; From e2efc9becbf29d9f4a4102d080a4ab2b18f36a34 Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Mon, 31 Oct 2016 18:38:50 +0000 Subject: [PATCH 234/235] Make sure the virtual T-axis buttons gets cleared for USB mice which has less than 6 buttons. PR: 213919 MFC after: 3 days --- sys/dev/usb/input/ums.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c index 6679ea31734a..757a96a8b831 100644 --- a/sys/dev/usb/input/ums.c +++ b/sys/dev/usb/input/ums.c @@ -295,8 +295,11 @@ ums_intr_callback(struct usb_xfer *xfer, usb_error_t error) } if ((info->sc_flags & UMS_FLAG_T_AXIS) && - (id == info->sc_iid_t)) + (id == info->sc_iid_t)) { dt -= hid_get_data(buf, len, &info->sc_loc_t); + /* T-axis is translated into button presses */ + buttons_found |= (1UL << 5) | (1UL << 6); + } for (i = 0; i < info->sc_buttons; i++) { uint32_t mask; From 130a08a362287342b83f8a78914db38a325145a3 Mon Sep 17 00:00:00 2001 From: Ruslan Bukin Date: Mon, 31 Oct 2016 18:38:58 +0000 Subject: [PATCH 235/235] Detect integer overflow and limit the number of positional arguments in the string format. Sponsored by: DARPA, AFRL Sponsored by: HEIF5 Differential Revision: https://reviews.freebsd.org/D8286 --- .../netbsd-tests/lib/libc/stdio/t_printf.c | 6 --- include/limits.h | 2 +- lib/libc/stdio/printf-pos.c | 45 ++++++++++++++----- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c index 5ef58f2fc627..d6ca662273fc 100644 --- a/contrib/netbsd-tests/lib/libc/stdio/t_printf.c +++ b/contrib/netbsd-tests/lib/libc/stdio/t_printf.c @@ -120,12 +120,6 @@ ATF_TC_BODY(snprintf_posarg_error, tc) { char s[16], fmt[32]; -#ifndef __NetBSD__ - atf_tc_expect_signal(SIGSEGV, - "some non-NetBSD platforms including FreeBSD don't validate " - "negative size; testcase blows up with SIGSEGV"); -#endif - snprintf(fmt, sizeof(fmt), "%%%zu$d", SIZE_MAX / sizeof(size_t)); ATF_CHECK(snprintf(s, sizeof(s), fmt, -23) == -1); diff --git a/include/limits.h b/include/limits.h index a1e1b9820821..0d37af4014cc 100644 --- a/include/limits.h +++ b/include/limits.h @@ -120,7 +120,7 @@ #endif #if __XSI_VISIBLE || __POSIX_VISIBLE >= 200809 -#define NL_ARGMAX 99 /* max # of position args for printf */ +#define NL_ARGMAX 65536 /* max # of position args for printf */ #define NL_MSGMAX 32767 #define NL_SETMAX 255 #define NL_TEXTMAX 2048 diff --git a/lib/libc/stdio/printf-pos.c b/lib/libc/stdio/printf-pos.c index 3a476496219c..9c38c2add343 100644 --- a/lib/libc/stdio/printf-pos.c +++ b/lib/libc/stdio/printf-pos.c @@ -44,6 +44,7 @@ __FBSDID("$FreeBSD$"); #include "namespace.h" #include +#include #include #include #include @@ -55,6 +56,12 @@ __FBSDID("$FreeBSD$"); #include "un-namespace.h" #include "printflocal.h" +#ifdef NL_ARGMAX +#define MAX_POSARG NL_ARGMAX +#else +#define MAX_POSARG 65536 +#endif + /* * Type ids for argument type table. */ @@ -70,9 +77,9 @@ enum typeid { struct typetable { enum typeid *table; /* table of types */ enum typeid stattable[STATIC_ARG_TBL_SIZE]; - int tablesize; /* current size of type table */ - int tablemax; /* largest used index in table */ - int nextarg; /* 1-based argument index */ + u_int tablesize; /* current size of type table */ + u_int tablemax; /* largest used index in table */ + u_int nextarg; /* 1-based argument index */ }; static int __grow_type_table(struct typetable *); @@ -84,7 +91,7 @@ static void build_arg_table (struct typetable *, va_list, union arg **); static inline void inittypes(struct typetable *types) { - int n; + u_int n; types->table = types->stattable; types->tablesize = STATIC_ARG_TBL_SIZE; @@ -185,7 +192,7 @@ static inline int addaster(struct typetable *types, char **fmtp) { char *cp; - int n2; + u_int n2; n2 = 0; cp = *fmtp; @@ -194,7 +201,7 @@ addaster(struct typetable *types, char **fmtp) cp++; } if (*cp == '$') { - int hold = types->nextarg; + u_int hold = types->nextarg; types->nextarg = n2; if (addtype(types, T_INT)) return (-1); @@ -211,7 +218,7 @@ static inline int addwaster(struct typetable *types, wchar_t **fmtp) { wchar_t *cp; - int n2; + u_int n2; n2 = 0; cp = *fmtp; @@ -220,7 +227,7 @@ addwaster(struct typetable *types, wchar_t **fmtp) cp++; } if (*cp == '$') { - int hold = types->nextarg; + u_int hold = types->nextarg; types->nextarg = n2; if (addtype(types, T_INT)) return (-1); @@ -245,7 +252,7 @@ __find_arguments (const char *fmt0, va_list ap, union arg **argtable) { char *fmt; /* format string */ int ch; /* character from fmt */ - int n; /* handy integer (short term usage) */ + u_int n; /* handy integer (short term usage) */ int error; int flags; /* flags as above */ struct typetable types; /* table of types */ @@ -296,6 +303,11 @@ reswitch: switch (ch) { n = 0; do { n = 10 * n + to_digit(ch); + /* Detect overflow */ + if (n > MAX_POSARG) { + error = -1; + goto error; + } ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { @@ -433,7 +445,7 @@ __find_warguments (const wchar_t *fmt0, va_list ap, union arg **argtable) { wchar_t *fmt; /* format string */ wchar_t ch; /* character from fmt */ - int n; /* handy integer (short term usage) */ + u_int n; /* handy integer (short term usage) */ int error; int flags; /* flags as above */ struct typetable types; /* table of types */ @@ -484,6 +496,11 @@ reswitch: switch (ch) { n = 0; do { n = 10 * n + to_digit(ch); + /* Detect overflow */ + if (n > MAX_POSARG) { + error = -1; + goto error; + } ch = *fmt++; } while (is_digit(ch)); if (ch == '$') { @@ -624,7 +641,11 @@ __grow_type_table(struct typetable *types) enum typeid *const oldtable = types->table; const int oldsize = types->tablesize; enum typeid *newtable; - int n, newsize = oldsize * 2; + u_int n, newsize = oldsize * 2; + + /* Detect overflow */ + if (types->nextarg > NL_ARGMAX) + return (-1); if (newsize < types->nextarg + 1) newsize = types->nextarg + 1; @@ -653,7 +674,7 @@ __grow_type_table(struct typetable *types) static void build_arg_table(struct typetable *types, va_list ap, union arg **argtable) { - int n; + u_int n; if (types->tablemax >= STATIC_ARG_TBL_SIZE) { *argtable = (union arg *)